Search in sources :

Example 1 with Block

use of net.minecraft.world.level.block.Block in project MinecraftForge by MinecraftForge.

the class GameData method injectSnapshot.

@SuppressWarnings({ "unchecked", "rawtypes" })
public static Multimap<ResourceLocation, ResourceLocation> injectSnapshot(Map<ResourceLocation, ForgeRegistry.Snapshot> snapshot, boolean injectFrozenData, boolean isLocalWorld) {
    LOGGER.info(REGISTRIES, "Injecting existing registry data into this {} instance", EffectiveSide.get());
    RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.validateContent(name));
    RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.dump(name));
    RegistryManager.ACTIVE.registries.forEach((name, reg) -> reg.resetDelegates());
    // Update legacy names
    snapshot = snapshot.entrySet().stream().sorted(// FIXME Registries need dependency ordering, this makes sure blocks are done before items (for ItemCallbacks) but it's lazy as hell
    Map.Entry.comparingByKey()).collect(Collectors.toMap(e -> RegistryManager.ACTIVE.updateLegacyName(e.getKey()), Map.Entry::getValue, (k1, k2) -> k1, LinkedHashMap::new));
    if (isLocalWorld) {
        List<ResourceLocation> missingRegs = snapshot.keySet().stream().filter(name -> !RegistryManager.ACTIVE.registries.containsKey(name)).collect(Collectors.toList());
        if (missingRegs.size() > 0) {
            String header = "Forge Mod Loader detected missing/unknown registrie(s).\n\n" + "There are " + missingRegs.size() + " missing registries in this save.\n" + "If you continue the missing registries will get removed.\n" + "This may cause issues, it is advised that you create a world backup before continuing.\n\n";
            StringBuilder text = new StringBuilder("Missing Registries:\n");
            for (ResourceLocation s : missingRegs) text.append(s).append("\n");
            LOGGER.warn(REGISTRIES, header);
            LOGGER.warn(REGISTRIES, text.toString());
        }
    }
    RegistryManager STAGING = new RegistryManager("STAGING");
    final Map<ResourceLocation, Map<ResourceLocation, Integer[]>> remaps = Maps.newHashMap();
    final LinkedHashMap<ResourceLocation, Map<ResourceLocation, Integer>> missing = Maps.newLinkedHashMap();
    // Load the snapshot into the "STAGING" registry
    snapshot.forEach((key, value) -> {
        final Class<? extends IForgeRegistryEntry> clazz = RegistryManager.ACTIVE.getSuperType(key);
        remaps.put(key, Maps.newLinkedHashMap());
        missing.put(key, Maps.newLinkedHashMap());
        loadPersistentDataToStagingRegistry(RegistryManager.ACTIVE, STAGING, remaps.get(key), missing.get(key), key, value, clazz);
    });
    snapshot.forEach((key, value) -> {
        value.dummied.forEach(dummy -> {
            Map<ResourceLocation, Integer> m = missing.get(key);
            ForgeRegistry<?> reg = STAGING.getRegistry(key);
            // Currently missing locally, we just inject and carry on
            if (m.containsKey(dummy)) {
                if (reg.markDummy(dummy, m.get(dummy)))
                    m.remove(dummy);
            } else if (isLocalWorld) {
                LOGGER.debug(REGISTRIES, "Registry {}: Resuscitating dummy entry {}", key, dummy);
            } else {
                // The server believes this is a dummy block identity, but we seem to have one locally. This is likely a conflict
                // in mod setup - Mark this entry as a dummy
                int id = reg.getID(dummy);
                LOGGER.warn(REGISTRIES, "Registry {}: The ID {} @ {} is currently locally mapped - it will be replaced with a dummy for this session", dummy, key, id);
                reg.markDummy(dummy, id);
            }
        });
    });
    int count = missing.values().stream().mapToInt(Map::size).sum();
    if (count > 0) {
        LOGGER.debug(REGISTRIES, "There are {} mappings missing - attempting a mod remap", count);
        Multimap<ResourceLocation, ResourceLocation> defaulted = ArrayListMultimap.create();
        Multimap<ResourceLocation, ResourceLocation> failed = ArrayListMultimap.create();
        missing.entrySet().stream().filter(e -> e.getValue().size() > 0).forEach(m -> {
            ResourceLocation name = m.getKey();
            ForgeRegistry<?> reg = STAGING.getRegistry(name);
            RegistryEvent.MissingMappings<?> event = reg.getMissingEvent(name, m.getValue());
            MinecraftForge.EVENT_BUS.post(event);
            List<MissingMappings.Mapping<?>> lst = event.getAllMappings().stream().filter(e -> e.getAction() == MissingMappings.Action.DEFAULT).sorted((a, b) -> a.toString().compareTo(b.toString())).collect(Collectors.toList());
            if (!lst.isEmpty()) {
                LOGGER.error(REGISTRIES, () -> LogMessageAdapter.adapt(sb -> {
                    sb.append("Unidentified mapping from registry ").append(name).append('\n');
                    lst.stream().sorted().forEach(map -> sb.append('\t').append(map.key).append(": ").append(map.id).append('\n'));
                }));
            }
            event.getAllMappings().stream().filter(e -> e.getAction() == MissingMappings.Action.FAIL).forEach(fail -> failed.put(name, fail.key));
            final Class<? extends IForgeRegistryEntry> clazz = RegistryManager.ACTIVE.getSuperType(name);
            processMissing(clazz, name, STAGING, event, m.getValue(), remaps.get(name), defaulted.get(name), failed.get(name), !isLocalWorld);
        });
        if (!defaulted.isEmpty() && !isLocalWorld)
            return defaulted;
        if (!defaulted.isEmpty()) {
            String header = "Forge Mod Loader detected missing registry entries.\n\n" + "There are " + defaulted.size() + " missing entries in this save.\n" + "If you continue the missing entries will get removed.\n" + "A world backup will be automatically created in your saves directory.\n\n";
            StringBuilder buf = new StringBuilder();
            defaulted.asMap().forEach((name, entries) -> {
                buf.append("Missing ").append(name).append(":\n");
                entries.stream().sorted((o1, o2) -> o1.compareNamespaced(o2)).forEach(rl -> buf.append("    ").append(rl).append("\n"));
                buf.append("\n");
            });
            LOGGER.warn(REGISTRIES, header);
            LOGGER.warn(REGISTRIES, buf.toString());
        }
        if (!defaulted.isEmpty()) {
            if (isLocalWorld)
                LOGGER.error(REGISTRIES, "There are unidentified mappings in this world - we are going to attempt to process anyway");
        }
    }
    if (injectFrozenData) {
        // If we're loading from disk, we can actually substitute air in the block map for anything that is otherwise "missing". This keeps the reference in the map, in case
        // the block comes back later
        missing.forEach((name, m) -> {
            if (m.isEmpty())
                return;
            ForgeRegistry<?> reg = STAGING.getRegistry(name);
            m.forEach((rl, id) -> reg.markDummy(rl, id));
        });
        // If we're loading up the world from disk, we want to add in the new data that might have been provisioned by mods
        // So we load it from the frozen persistent registry
        RegistryManager.ACTIVE.registries.forEach((name, reg) -> {
            final Class<? extends IForgeRegistryEntry> clazz = RegistryManager.ACTIVE.getSuperType(name);
            loadFrozenDataToStagingRegistry(STAGING, name, remaps.get(name), clazz);
        });
    }
    // Validate that all the STAGING data is good
    STAGING.registries.forEach((name, reg) -> reg.validateContent(name));
    // Load the STAGING registry into the ACTIVE registry
    // for (Map.Entry<ResourceLocation, IForgeRegistry<? extends IForgeRegistryEntry<?>>> r : RegistryManager.ACTIVE.registries.entrySet())
    RegistryManager.ACTIVE.registries.forEach((key, value) -> {
        final Class<? extends IForgeRegistryEntry> registrySuperType = RegistryManager.ACTIVE.getSuperType(key);
        loadRegistry(key, STAGING, RegistryManager.ACTIVE, registrySuperType, true);
    });
    RegistryManager.ACTIVE.registries.forEach((name, reg) -> {
        reg.bake();
        // Dump the active registry
        reg.dump(name);
    });
    // Tell mods that the ids have changed
    fireRemapEvent(remaps, false);
    // The id map changed, ensure we apply object holders
    ObjectHolderRegistry.applyObjectHolders();
    // Return an empty list, because we're good
    return ArrayListMultimap.create();
}
Also used : ResourceLocation(net.minecraft.resources.ResourceLocation) SensorType(net.minecraft.world.entity.ai.sensing.SensorType) EffectiveSide(net.minecraftforge.fml.util.thread.EffectiveSide) TreeDecoratorType(net.minecraft.world.level.levelgen.feature.treedecorators.TreeDecoratorType) Item(net.minecraft.world.item.Item) IModStateTransition(net.minecraftforge.fml.IModStateTransition) MenuType(net.minecraft.world.inventory.MenuType) FoliagePlacerType(net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacerType) Activity(net.minecraft.world.entity.schedule.Activity) Registry(net.minecraft.core.Registry) RegistryEvent(net.minecraftforge.event.RegistryEvent) StatType(net.minecraft.stats.StatType) ModLoadingContext(net.minecraftforge.fml.ModLoadingContext) com.google.common.collect(com.google.common.collect) StateDefinition(net.minecraft.world.level.block.state.StateDefinition) DefaultedRegistry(net.minecraft.core.DefaultedRegistry) MemoryModuleType(net.minecraft.world.entity.ai.memory.MemoryModuleType) StaticTags(net.minecraft.tags.StaticTags) PoiType(net.minecraft.world.entity.ai.village.poi.PoiType) DefaultAttributes(net.minecraft.world.entity.ai.attributes.DefaultAttributes) LogMessageAdapter(net.minecraftforge.common.util.LogMessageAdapter) Collectors(java.util.stream.Collectors) Potion(net.minecraft.world.item.alchemy.Potion) Schedule(net.minecraft.world.entity.schedule.Schedule) IdMapper(net.minecraft.core.IdMapper) DebugLevelSource(net.minecraft.world.level.levelgen.DebugLevelSource) Logger(org.apache.logging.log4j.Logger) Stream(java.util.stream.Stream) BlockEntityType(net.minecraft.world.level.block.entity.BlockEntityType) MappedRegistry(net.minecraft.core.MappedRegistry) SoundEvent(net.minecraft.sounds.SoundEvent) AirBlock(net.minecraft.world.level.block.AirBlock) Motive(net.minecraft.world.entity.decoration.Motive) Enchantment(net.minecraft.world.item.enchantment.Enchantment) java.util(java.util) ForgeWorldPreset(net.minecraftforge.common.world.ForgeWorldPreset) EntityType(net.minecraft.world.entity.EntityType) BlockState(net.minecraft.world.level.block.state.BlockState) CompletableFuture(java.util.concurrent.CompletableFuture) Biome(net.minecraft.world.level.biome.Biome) Function(java.util.function.Function) GlobalLootModifierSerializer(net.minecraftforge.common.loot.GlobalLootModifierSerializer) BlockStateProviderType(net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProviderType) StructureFeature(net.minecraft.world.level.levelgen.feature.StructureFeature) VillagerProfession(net.minecraft.world.entity.npc.VillagerProfession) BiConsumer(java.util.function.BiConsumer) Fluid(net.minecraft.world.level.material.Fluid) EntityDataSerializer(net.minecraft.network.syncher.EntityDataSerializer) EnhancedRuntimeException(net.minecraftforge.fml.util.EnhancedRuntimeException) Nullable(javax.annotation.Nullable) Keys(net.minecraftforge.registries.ForgeRegistries.Keys) BlockItem(net.minecraft.world.item.BlockItem) Executor(java.util.concurrent.Executor) RecipeSerializer(net.minecraft.world.item.crafting.RecipeSerializer) ParticleType(net.minecraft.core.particles.ParticleType) WorldCarver(net.minecraft.world.level.levelgen.carver.WorldCarver) Lifecycle(com.mojang.serialization.Lifecycle) MissingMappings(net.minecraftforge.event.RegistryEvent.MissingMappings) Field(java.lang.reflect.Field) REGISTRIES(net.minecraftforge.registries.ForgeRegistry.REGISTRIES) ResourceKey(net.minecraft.resources.ResourceKey) Material(net.minecraft.world.level.material.Material) Attribute(net.minecraft.world.entity.ai.attributes.Attribute) Feature(net.minecraft.world.level.levelgen.feature.Feature) MinecraftForge(net.minecraftforge.common.MinecraftForge) Validate(org.apache.commons.lang3.Validate) StartupMessageManager(net.minecraftforge.fml.StartupMessageManager) ForgeTagHandler(net.minecraftforge.common.ForgeTagHandler) Block(net.minecraft.world.level.block.Block) ChunkStatus(net.minecraft.world.level.chunk.ChunkStatus) LogManager(org.apache.logging.log4j.LogManager) MobEffect(net.minecraft.world.effect.MobEffect) RegistryEvent(net.minecraftforge.event.RegistryEvent) ResourceLocation(net.minecraft.resources.ResourceLocation)

Example 2 with Block

use of net.minecraft.world.level.block.Block in project MinecraftForge by MinecraftForge.

the class FluidUtil method tryPickUpFluid.

/**
 * Attempts to pick up a fluid in the world and put it in an empty container item.
 *
 * @param emptyContainer The empty container to fill.
 *                       Will not be modified directly, if modifications are necessary a modified copy is returned in the result.
 * @param playerIn       The player filling the container. Optional.
 * @param worldIn        The world the fluid is in.
 * @param pos            The position of the fluid in the world.
 * @param side           The side of the fluid that is being drained.
 * @return a {@link FluidActionResult} holding the result and the resulting container.
 */
@Nonnull
public static FluidActionResult tryPickUpFluid(@Nonnull ItemStack emptyContainer, @Nullable Player playerIn, Level worldIn, BlockPos pos, Direction side) {
    if (emptyContainer.isEmpty() || worldIn == null || pos == null) {
        return FluidActionResult.FAILURE;
    }
    BlockState state = worldIn.getBlockState(pos);
    Block block = state.getBlock();
    IFluidHandler targetFluidHandler;
    if (block instanceof IFluidBlock) {
        targetFluidHandler = new FluidBlockWrapper((IFluidBlock) block, worldIn, pos);
    } else if (block instanceof BucketPickup) {
        targetFluidHandler = new BucketPickupHandlerWrapper((BucketPickup) block, worldIn, pos);
    } else {
        Optional<IFluidHandler> fluidHandler = getFluidHandler(worldIn, pos, side).resolve();
        if (!fluidHandler.isPresent()) {
            return FluidActionResult.FAILURE;
        }
        targetFluidHandler = fluidHandler.get();
    }
    return tryFillContainer(emptyContainer, targetFluidHandler, Integer.MAX_VALUE, playerIn, true);
}
Also used : FluidBlockWrapper(net.minecraftforge.fluids.capability.wrappers.FluidBlockWrapper) BucketPickup(net.minecraft.world.level.block.BucketPickup) BucketPickupHandlerWrapper(net.minecraftforge.fluids.capability.wrappers.BucketPickupHandlerWrapper) BlockState(net.minecraft.world.level.block.state.BlockState) LazyOptional(net.minecraftforge.common.util.LazyOptional) Optional(java.util.Optional) Block(net.minecraft.world.level.block.Block) IFluidHandler(net.minecraftforge.fluids.capability.IFluidHandler) Nonnull(javax.annotation.Nonnull)

Example 3 with Block

use of net.minecraft.world.level.block.Block in project MinecraftForge by MinecraftForge.

the class ForgeItemTagsProvider method copyColored.

private void copyColored(Tag.Named<Block> blockGroup, Tag.Named<Item> itemGroup) {
    String blockPre = blockGroup.getName().getPath().toUpperCase(Locale.ENGLISH) + '_';
    String itemPre = itemGroup.getName().getPath().toUpperCase(Locale.ENGLISH) + '_';
    for (DyeColor color : DyeColor.values()) {
        Tag.Named<Block> from = getForgeBlockTag(blockPre + color.getName());
        Tag.Named<Item> to = getForgeItemTag(itemPre + color.getName());
        copy(from, to);
    }
    copy(getForgeBlockTag(blockPre + "colorless"), getForgeItemTag(itemPre + "colorless"));
}
Also used : Item(net.minecraft.world.item.Item) Block(net.minecraft.world.level.block.Block) Tag(net.minecraft.tags.Tag) DyeColor(net.minecraft.world.item.DyeColor)

Example 4 with Block

use of net.minecraft.world.level.block.Block in project MinecraftForge by MinecraftForge.

the class RegistryCodecTest method commonSetup.

public void commonSetup(final FMLCommonSetupEvent event) {
    // Create our Json to decode
    JsonObject json = new JsonObject();
    json.addProperty("block", "minecraft:diamond_block");
    json.addProperty("item", "minecraft:diamond_pickaxe");
    // Decode our Json and log an info in case of success or a warning in case of error
    DataResult<Pair<Pair<Block, Item>, JsonElement>> result = CODEC.decode(JsonOps.INSTANCE, json);
    result.resultOrPartial(LOGGER::warn).ifPresent(pair -> LOGGER.info("Successfully decoded a diamond block and a diamond pickaxe from json to Block/Item"));
    // Create a Pair<Block, Item> to test the serialization of our codec
    Pair<Block, Item> pair = Pair.of(Blocks.DIAMOND_BLOCK, Items.DIAMOND_PICKAXE);
    // Serialize the Pair to NBT, and log an info in case of success or a warning in case of error
    DataResult<Tag> result2 = CODEC.encodeStart(NbtOps.INSTANCE, pair);
    result2.resultOrPartial(LOGGER::warn).ifPresent(tag -> LOGGER.info("Successfully encoded a Pair<Block, Item> to a nbt tag: {}", tag));
    // Serialize the Pair to JSON using the COMPRESSED JsonOps, this will use the int registry id instead of the ResourceLocation one,
    // This is not recommended because int IDs can change, so you should not rely on them
    DataResult<JsonElement> result3 = CODEC.encodeStart(JsonOps.COMPRESSED, pair);
    result3.resultOrPartial(LOGGER::warn).ifPresent(compressedJson -> LOGGER.info("Successfully encoded a Pair<Block, Item> to a compressed json: {}", compressedJson));
    // Create a json to decode using numerical IDs, to be decoded by JsonOps.COMPRESSED
    JsonArray jsonCompressed = new JsonArray();
    jsonCompressed.add(((ForgeRegistry<Block>) ForgeRegistries.BLOCKS).getID(Blocks.DIAMOND_BLOCK));
    jsonCompressed.add(((ForgeRegistry<Item>) ForgeRegistries.ITEMS).getID(Items.DIAMOND_PICKAXE));
    // Decode a compressed json to the corresponding Pair<Block, Item>, this time using Codec#parse
    DataResult<Pair<Block, Item>> result4 = CODEC.parse(JsonOps.COMPRESSED, jsonCompressed);
    result4.resultOrPartial(LOGGER::warn).ifPresent(pair2 -> LOGGER.info("Successfully decoded a diamond block and a diamond pickaxe from compressed json to Block/Item"));
}
Also used : JsonArray(com.google.gson.JsonArray) Item(net.minecraft.world.item.Item) JsonElement(com.google.gson.JsonElement) JsonObject(com.google.gson.JsonObject) Block(net.minecraft.world.level.block.Block) Tag(net.minecraft.nbt.Tag) Pair(com.mojang.datafixers.util.Pair)

Example 5 with Block

use of net.minecraft.world.level.block.Block in project Denizen-For-Bukkit by DenizenScript.

the class PacketHelperImpl method showBlockAction.

@Override
public void showBlockAction(Player player, Location location, int action, int state) {
    BlockPos position = new BlockPos(location.getX(), location.getY(), location.getZ());
    Block block = ((CraftWorld) location.getWorld()).getHandle().getBlockState(position).getBlock();
    send(player, new ClientboundBlockEventPacket(position, block, action, state));
}
Also used : FakeBlock(com.denizenscript.denizen.utilities.blocks.FakeBlock) Block(net.minecraft.world.level.block.Block) BlockPos(net.minecraft.core.BlockPos) CraftWorld(org.bukkit.craftbukkit.v1_17_R1.CraftWorld)

Aggregations

Block (net.minecraft.world.level.block.Block)14 Item (net.minecraft.world.item.Item)5 ResourceLocation (net.minecraft.resources.ResourceLocation)4 ItemStack (net.minecraft.world.item.ItemStack)3 WoolCarpetBlock (net.minecraft.world.level.block.WoolCarpetBlock)3 BlockState (net.minecraft.world.level.block.state.BlockState)3 CraftItemStack (org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack)3 FakeBlock (com.denizenscript.denizen.utilities.blocks.FakeBlock)2 BlockPos (net.minecraft.core.BlockPos)2 CompoundTag (net.minecraft.nbt.CompoundTag)2 Tag (net.minecraft.tags.Tag)2 CraftItemStack (org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack)2 ItemStack (org.bukkit.inventory.ItemStack)2 com.google.common.collect (com.google.common.collect)1 JsonArray (com.google.gson.JsonArray)1 JsonElement (com.google.gson.JsonElement)1 JsonObject (com.google.gson.JsonObject)1 Pair (com.mojang.datafixers.util.Pair)1 Lifecycle (com.mojang.serialization.Lifecycle)1 Field (java.lang.reflect.Field)1