Search in sources :

Example 1 with ThreeState

use of pl.asie.charset.lib.utils.ThreeState in project Charset by CharsetMC.

the class CharsetTweakBlockCarrying method canCarry.

protected static boolean canCarry(World world, BlockPos pos) {
    IBlockState state = world.getBlockState(pos);
    Block block = state.getBlock();
    boolean hasTileEntity = state.getBlock().hasTileEntity(state);
    boolean isVanilla = "minecraft".equals(block.getRegistryName().getResourceDomain());
    // Set<String> names = new HashSet<>();
    Set<ResourceLocation> locs = new HashSet<>();
    locs.add(state.getBlock().getRegistryName());
    if (hasTileEntity) {
        TileEntity tile = world.getTileEntity(pos);
        if (tile != null) {
            Class<? extends TileEntity> tileClass = tile.getClass();
            locs.add(TileEntity.getKey(tileClass));
        // names.add(tileClass.getName());
        }
    }
    /* for (ResourceLocation r : locs)
            names.add(r.toString()); */
    ThreeState allowedIMC = CharsetIMC.INSTANCE.allows("carry", locs);
    if (allowedIMC == ThreeState.NO) {
        return false;
    } else if (allowedIMC == ThreeState.YES) {
        return true;
    }
    // We support all vanilla tile entities.
    if (!isVanilla && hasTileEntity)
        return false;
    // if (block instanceof IPlantable) return false;
    if (block instanceof BlockPistonExtension || block instanceof BlockPistonMoving)
        return false;
    if (block instanceof BlockPistonBase) {
        // uses foreign states - do not trust it!
        if (!state.getPropertyKeys().contains(BlockPistonBase.EXTENDED) || state.getValue(BlockPistonBase.EXTENDED)) {
            return false;
        }
    }
    if (block instanceof IFluidBlock || block instanceof BlockLiquid)
        return false;
    if (block instanceof BlockPortal || block instanceof BlockEndPortal)
        return false;
    return true;
}
Also used : IBlockState(net.minecraft.block.state.IBlockState) TileEntity(net.minecraft.tileentity.TileEntity) ThreeState(pl.asie.charset.lib.utils.ThreeState) ResourceLocation(net.minecraft.util.ResourceLocation) IFluidBlock(net.minecraftforge.fluids.IFluidBlock) IFluidBlock(net.minecraftforge.fluids.IFluidBlock) HashSet(java.util.HashSet)

Example 2 with ThreeState

use of pl.asie.charset.lib.utils.ThreeState in project Charset by CharsetMC.

the class CharsetTweakBonemeal method onApplyBonemeal.

@SubscribeEvent
public void onApplyBonemeal(BonemealEvent event) {
    if (event.getWorld().isRemote) {
        return;
    }
    IBlockState state = event.getBlock();
    Block block = state.getBlock();
    IBlockState stateNew = null;
    ThreeState instantGrowth = CharsetIMC.INSTANCE.allows("instantBonemeal", block.getRegistryName());
    ThreeState growth = CharsetIMC.INSTANCE.allows("bonemeal", block.getRegistryName());
    if (instantGrowth == ThreeState.MAYBE) {
        instantGrowth = ThreeState.from(instantGrowthDefault);
    }
    if (growth == ThreeState.MAYBE) {
        growth = growthWhitelist ? ThreeState.NO : ThreeState.YES;
    }
    if (growth == ThreeState.NO) {
        event.setCanceled(true);
        return;
    } else if (instantGrowth == ThreeState.NO) {
        return;
    }
    if (block instanceof BlockCrops) {
        // crops
        stateNew = ((BlockCrops) block).withAge(((BlockCrops) block).getMaxAge());
    } else if (state.getPropertyKeys().contains(BlockCocoa.AGE)) {
        // cocoa
        stateNew = withMax(state, BlockCocoa.AGE);
    } else if (block instanceof BlockMushroom) {
        // mushroom
        ((BlockMushroom) block).grow(event.getWorld(), event.getWorld().rand, event.getPos(), state);
        event.setResult(Event.Result.ALLOW);
        return;
    } else if (block instanceof BlockSapling) {
        // saplings
        ((BlockSapling) block).generateTree(event.getWorld(), event.getPos(), state, event.getWorld().rand);
        event.setResult(Event.Result.ALLOW);
        return;
    } else if (state.getPropertyKeys().contains(BlockStem.AGE)) {
        // stem
        stateNew = withMax(state, BlockStem.AGE);
    } else if (block instanceof BlockDoublePlant || block instanceof BlockTallGrass) {
        // do nothing, they already grow instantly
        return;
    } else if (block instanceof BlockGrass) {
        return;
    } else if (block instanceof IGrowable && heuristicEnabled) {
        // heuristic
        int i = 128;
        boolean canGrow = true;
        while (i-- > 0 && canGrow) {
            IBlockState stateTmp = event.getWorld().getBlockState(event.getPos());
            Block blockTmp = stateTmp.getBlock();
            if (blockTmp instanceof IGrowable) {
                if (((IGrowable) blockTmp).canGrow(event.getWorld(), event.getPos(), event.getBlock(), false)) {
                    ((IGrowable) blockTmp).grow(event.getWorld(), event.getWorld().rand, event.getPos(), event.getBlock());
                    canGrow = ((IGrowable) blockTmp).canGrow(event.getWorld(), event.getPos(), event.getBlock(), false);
                }
            }
        }
        if (canGrow) {
            ModCharset.logger.warn("Found block " + block.getRegistryName() + " which insists on continuing to grow! Odd. Perhaps the Charset mod author would like to know more?");
        }
        event.setResult(Event.Result.ALLOW);
        return;
    } else {
        // no handler
        return;
    }
    if (stateNew != null) {
        if (stateNew != state) {
            event.getWorld().setBlockState(event.getPos(), stateNew, 2);
            event.setResult(Event.Result.ALLOW);
        } else {
            return;
        }
    }
}
Also used : ThreeState(pl.asie.charset.lib.utils.ThreeState) IBlockState(net.minecraft.block.state.IBlockState) SubscribeEvent(net.minecraftforge.fml.common.eventhandler.SubscribeEvent)

Example 3 with ThreeState

use of pl.asie.charset.lib.utils.ThreeState in project Charset by CharsetMC.

the class ModuleLoader method readDataTable.

@SuppressWarnings("unchecked")
private void readDataTable(ASMDataTable table) {
    Multimap<String, String> unmetDependencies = HashMultimap.create();
    Set<String> enabledModules = new HashSet<>();
    Set<String> compatModules = new HashSet<>();
    Map<String, ASMDataTable.ASMData> moduleData = new HashMap<>();
    Property baseProfileProp = ModCharset.configGeneral.get("general", "profile", "DEFAULT");
    baseProfileProp.setValidValues(new String[] { "DEFAULT", "STABLE", "TESTING", "EXPERIMENTAL" });
    baseProfileProp.setLanguageKey("config.charset.profile.name");
    baseProfileProp.setRequiresMcRestart(true);
    ModuleProfile profile, defaultProfile;
    if (ModCharset.INDEV) {
        defaultProfile = ModuleProfile.INDEV;
    } else if (ModCharset.defaultOptions.containsKey("profile")) {
        defaultProfile = getProfileFromString(ModCharset.defaultOptions.get("profile"));
    } else {
        defaultProfile = ModuleProfile.STABLE;
    }
    baseProfileProp.setComment("Set the base profile for Charset.\nThis will give you a default set of modules based on stability.\nAllowed values: DEFAULT, STABLE, TESTING, EXPERIMENTAL (DEFAULT means " + defaultProfile.name() + ")\nFor fine-grained configuration, check modules.cfg!");
    if ("DEFAULT".equals(baseProfileProp.getString().toUpperCase())) {
        profile = defaultProfile;
    } else {
        profile = getProfileFromString(baseProfileProp.getString());
    }
    ModCharset.profile = profile;
    ModCharset.logger.info("Charset profile is " + ModCharset.profile);
    ConfigCategory category = ModCharset.configModules.getCategory("overrides");
    category.setComment("Overrides can have one of three values: DEFAULT, ENABLE, DISABLE\nDEFAULT will enable the module based on your profile settings and dependency availability.");
    category = ModCharset.configModules.getCategory("categories");
    category.setComment("This section allows you to disable certain categories of content, based on a tag system.");
    boolean configDirty = false;
    Map<String, Boolean> categoryMap = new HashMap<>();
    // Initialize categories
    for (ASMDataTable.ASMData data : table.getAll(CharsetModule.class.getName())) {
        Map<String, Object> info = data.getAnnotationInfo();
        List<String> tags = (List<String>) info.getOrDefault("categories", Collections.emptyList());
        for (String s : tags) {
            if (!categoryMap.containsKey(s)) {
                Property prop = ModCharset.configModules.get("categories", s, !CATEGORIES_OFF_BY_DEFAULT.contains(s));
                prop.setRequiresMcRestart(true);
                categoryMap.put(s, prop.getBoolean());
            }
        }
    }
    for (ASMDataTable.ASMData data : table.getAll(CharsetModule.class.getName())) {
        Map<String, Object> info = data.getAnnotationInfo();
        String name = (String) info.get("name");
        String desc = (String) info.get("description");
        if (desc == null)
            desc = "";
        ModuleProfile modProfile = ModuleProfile.valueOf(((ModAnnotation.EnumHolder) info.get("profile")).getValue());
        Boolean isDefault = (Boolean) info.getOrDefault("isDefault", true);
        Boolean compat = modProfile == ModuleProfile.COMPAT;
        Boolean clientOnly = (Boolean) info.getOrDefault("isClientOnly", false);
        Boolean serverOnly = (Boolean) info.getOrDefault("isServerOnly", false);
        List<String> tags = (List<String>) info.getOrDefault("categories", Collections.emptyList());
        String moduleGuiClass = (String) info.getOrDefault("moduleConfigGui", "");
        if (moduleGuiClass.length() > 0) {
            moduleGuiClasses.put(name, moduleGuiClass);
        }
        moduleData.put(name, data);
        ThreeState override = ThreeState.MAYBE;
        if ((Boolean) info.getOrDefault("isVisible", true)) {
            if (modProfile == ModuleProfile.INDEV && profile != ModuleProfile.INDEV) {
                override = ThreeState.NO;
            } else {
                if (compat) {
                    Property prop = ModCharset.configModules.get("compat", name, isDefault);
                    prop.setRequiresMcRestart(true);
                    if (!prop.getBoolean())
                        override = ThreeState.NO;
                } else {
                    Property prop = ModCharset.configModules.get("overrides", name, "DEFAULT");
                    prop.setValidValues(new String[] { "DEFAULT", "ENABLE", "DISABLE" });
                    prop.setRequiresMcRestart(true);
                    if (desc.length() > 0)
                        desc += " ";
                    desc += "[Profile: " + modProfile.name().toUpperCase() + "";
                    if (!isDefault) {
                        desc += ", off by default!";
                    }
                    desc += "]";
                    if (!desc.equals(prop.getComment())) {
                        prop.setComment(desc);
                        configDirty = true;
                    }
                    if (prop.getString().toUpperCase().startsWith("ENABLE")) {
                        override = ThreeState.YES;
                    } else if (prop.getString().toUpperCase().startsWith("DISABLE")) {
                        override = ThreeState.NO;
                    } else if (!"DEFAULT".equals(prop.getString().toUpperCase())) {
                        ModCharset.logger.warn("Invalid value for '" + name + "' override: '" + prop.getString() + ";");
                    }
                }
            }
        }
        if (clientOnly && !FMLCommonHandler.instance().getSide().isClient()) {
            continue;
        }
        if (serverOnly && !FMLCommonHandler.instance().getSide().isServer()) {
            continue;
        }
        if (compat) {
            compatModules.add(name);
        }
        if (override == ThreeState.MAYBE && isDefault) {
            List<String> antideps = (List<String>) info.get("antidependencies");
            if (antideps != null) {
                for (String dep : antideps) {
                    if (isDepPresent(dep, enabledModules)) {
                        ModCharset.logger.info("Antidependency " + dep + " is present - disabling otherwise not forced module " + name + ".");
                        isDefault = false;
                        break;
                    }
                }
            }
            for (String s : tags) {
                if (!categoryMap.get(s)) {
                    ModCharset.logger.info("Category " + s + " is disabled - disabling otherwise not forced module " + name + ".");
                    isDefault = false;
                }
            }
        }
        if (!compat && modProfile != ModuleProfile.FORCED && modProfile.ordinal() > profile.ordinal()) {
            isDefault = false;
        }
        EnableInformation enableInfo = new EnableInformation(isDefault, override);
        if (enableInfo.isEnabled()) {
            enabledModules.add(name);
            enableInfoMap.put(name, enableInfo);
            if (!"lib".equals(name))
                dependencies.put(name, "lib");
            List<String> deps = (List<String>) info.get("dependencies");
            if (deps != null) {
                dependencies.putAll(name, deps);
            }
        }
    }
    if (ModCharset.configGeneral.hasChanged()) {
        ModCharset.configGeneral.save();
    }
    if (ModCharset.configModules.hasChanged() || configDirty) {
        ModCharset.configModules.save();
        configDirty = false;
    }
    int removedCount = 1;
    while (removedCount > 0) {
        removedCount = 0;
        for (String name : enabledModules) {
            if (dependencies.containsKey(name)) {
                for (String dep : dependencies.get(name)) {
                    boolean optional = false;
                    if (dep.startsWith("optional:")) {
                        optional = true;
                        dep = dep.substring("optional:".length());
                    }
                    boolean met = optional || isDepPresent(dep, enabledModules);
                    if (!met) {
                        enableInfoMap.get(name).dependenciesMet = false;
                        unmetDependencies.put(name, dep);
                        break;
                    }
                }
            }
        }
        Iterator<String> unmetDepKey = unmetDependencies.keySet().iterator();
        while (unmetDepKey.hasNext()) {
            String depMod = unmetDepKey.next();
            EnableInformation enableInfo = enableInfoMap.get(depMod);
            if (!enableInfo.isEnabled()) {
                if (!compatModules.contains(depMod)) {
                    ModCharset.logger.info("Module " + depMod + " requires " + joinerComma.join(unmetDependencies.get(depMod)) + ", but is not force-enabled. You can ignore this - it is not an error, just information.");
                }
                removedCount++;
                enabledModules.remove(depMod);
                unmetDepKey.remove();
            }
        }
    }
    for (String name : enabledModules) {
        if (ModCharset.INDEV) {
            ModCharset.logger.info("Instantiating module " + name);
        }
        ASMDataTable.ASMData data = moduleData.get(name);
        try {
            Object o = getClass(data).newInstance();
            loadedModules.put(name, o);
            loadedModulesByClass.put(data.getClassName(), o);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    if (unmetDependencies.size() > 0) {
        List<String> depStrings = new ArrayList<>(unmetDependencies.size());
        for (String depMod : unmetDependencies.keys()) {
            depStrings.add(depMod + "<-[" + joinerComma.join(unmetDependencies.get(depMod)) + "]");
        }
        throw new RuntimeException("The following mandatory dependencies were not met: " + joinerComma.join(depStrings));
    }
    iterateModules(table, Mod.EventHandler.class.getName(), (data, instance) -> {
        String methodName = data.getObjectName().substring(0, data.getObjectName().indexOf('('));
        String methodDesc = data.getObjectName().substring(methodName.length());
        MethodType methodType = MethodType.fromMethodDescriptorString(methodDesc, classLoader);
        if (ModCharset.INDEV) {
            if (methodType.parameterCount() != 1) {
                throw new RuntimeException("Invalid parameter count " + methodType.parameterCount() + " for EventHandler in " + instance.getClass() + "!");
            }
        }
        try {
            MethodHandle methodHandle = MethodHandles.lookup().findVirtual(getClass(data), methodName, methodType);
            List<Pair<String, MethodHandle>> list = loaderHandles.computeIfAbsent(methodType.parameterType(0), k -> new ArrayList<>());
            list.sort(Comparator.comparing(Pair::getLeft));
            list.add(Pair.of(loadedModules.inverse().get(instance), methodHandle));
        } catch (NoSuchMethodException e) {
        // method has been annotated away, ignore
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    });
    iterateModules(table, CharsetModule.Instance.class.getName(), (data, instance) -> {
        try {
            String instString = (String) data.getAnnotationInfo().get("value");
            if (instString == null || instString.equals("")) {
                getField(data).set(instance, instance);
            } else {
                Object inst2 = loadedModules.get(instString);
                getField(data).set(instance, inst2);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    });
    iterateModules(table, CharsetModule.PacketRegistry.class.getName(), (data, instance) -> {
        String id = (String) data.getAnnotationInfo().get("value");
        if (id == null)
            id = loadedModules.inverse().get(instance);
        try {
            String channelName = "chrs:" + id.substring(id.lastIndexOf('.') + 1);
            getField(data).set(instance, new PacketRegistry(channelName));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    });
    iterateModules(table, CharsetModule.Configuration.class.getName(), (data, instance) -> {
        String id = (String) data.getAnnotationInfo().get("value");
        if (id == null)
            id = loadedModules.inverse().get(instance);
        try {
            Configuration config = new Configuration(ModCharset.getModuleConfigFile(id));
            getField(data).set(instance, config);
            moduleConfigs.put(id, config);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    });
    Side side = FMLCommonHandler.instance().getSide();
    for (ASMDataTable.ASMData data : table.getAll(CharsetModule.SidedProxy.class.getName())) {
        String clientSide = (String) data.getAnnotationInfo().get("clientSide");
        String serverSide = (String) data.getAnnotationInfo().get("serverSide");
        try {
            Field f = getField(data);
            f.set(null, Class.forName(side == Side.CLIENT ? clientSide : serverSide).newInstance());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    List<String> sortedModules = new ArrayList<>();
    Set<String> remainingModules = Sets.newHashSet(enabledModules);
    while (!remainingModules.isEmpty()) {
        Iterator<String> remainingIterator = remainingModules.iterator();
        boolean added = false;
        while (remainingIterator.hasNext()) {
            String s = remainingIterator.next();
            boolean canAdd = true;
            for (String dep : dependencies.get(s)) {
                if (!dep.startsWith("mod:") && !dep.startsWith("optional:") && !sortedModules.contains(dep)) {
                    canAdd = false;
                    break;
                }
            }
            if (canAdd) {
                added = true;
                sortedModules.add(s);
                remainingIterator.remove();
            }
        }
        if (!added) {
            throw new RuntimeException("Cyclic dependency within Charset modules! Report!");
        }
    }
    for (List<Pair<String, MethodHandle>> list : loaderHandles.values()) {
        list.sort(Comparator.comparingInt(a -> sortedModules.indexOf(a.getKey())));
    }
    for (String s : sortedModules) {
        MinecraftForge.EVENT_BUS.register(loadedModules.get(s));
    }
    for (ASMDataTable.ASMData data : table.getAll(CharsetCompatAnnotation.class.getName())) {
        String id = (String) data.getAnnotationInfo().get("value");
        try {
            addClassNames(table, Class.forName(data.getClassName()), id);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    passEvent(new CharsetLoadConfigEvent(true));
    if (ModCharset.configModules.hasChanged() || configDirty) {
        ModCharset.configModules.save();
        configDirty = false;
    }
}
Also used : CharsetMCMPAddon(pl.asie.charset.lib.modcompat.mcmultipart.CharsetMCMPAddon) MethodHandle(java.lang.invoke.MethodHandle) java.util(java.util) Loader(net.minecraftforge.fml.common.Loader) ModCharset(pl.asie.charset.ModCharset) CharsetChiselsAndBitsPlugin(pl.asie.charset.lib.modcompat.chiselsandbits.CharsetChiselsAndBitsPlugin) FMLCommonHandler(net.minecraftforge.fml.common.FMLCommonHandler) ASMDataTable(net.minecraftforge.fml.common.discovery.ASMDataTable) Pair(org.apache.commons.lang3.tuple.Pair) Side(net.minecraftforge.fml.relauncher.Side) BiConsumer(java.util.function.BiConsumer) CharsetJEIPlugin(pl.asie.charset.lib.modcompat.jei.CharsetJEIPlugin) Mod(net.minecraftforge.fml.common.Mod) com.google.common.collect(com.google.common.collect) FMLEvent(net.minecraftforge.fml.common.event.FMLEvent) PacketRegistry(pl.asie.charset.lib.network.PacketRegistry) ThreeState(pl.asie.charset.lib.utils.ThreeState) CharsetLoadConfigEvent(pl.asie.charset.lib.config.CharsetLoadConfigEvent) MethodHandles(java.lang.invoke.MethodHandles) Field(java.lang.reflect.Field) ModAnnotation(net.minecraftforge.fml.common.discovery.asm.ModAnnotation) MinecraftForge(net.minecraftforge.common.MinecraftForge) MethodType(java.lang.invoke.MethodType) Configuration(net.minecraftforge.common.config.Configuration) Property(net.minecraftforge.common.config.Property) ConfigCategory(net.minecraftforge.common.config.ConfigCategory) Joiner(com.google.common.base.Joiner) Configuration(net.minecraftforge.common.config.Configuration) Side(net.minecraftforge.fml.relauncher.Side) ThreeState(pl.asie.charset.lib.utils.ThreeState) Field(java.lang.reflect.Field) ASMDataTable(net.minecraftforge.fml.common.discovery.ASMDataTable) ConfigCategory(net.minecraftforge.common.config.ConfigCategory) ModAnnotation(net.minecraftforge.fml.common.discovery.asm.ModAnnotation) Property(net.minecraftforge.common.config.Property) Pair(org.apache.commons.lang3.tuple.Pair) MethodType(java.lang.invoke.MethodType) PacketRegistry(pl.asie.charset.lib.network.PacketRegistry) CharsetLoadConfigEvent(pl.asie.charset.lib.config.CharsetLoadConfigEvent) MethodHandle(java.lang.invoke.MethodHandle)

Example 4 with ThreeState

use of pl.asie.charset.lib.utils.ThreeState in project Charset by CharsetMC.

the class LockEventHandler method onAttachCapabilities.

@SubscribeEvent
public void onAttachCapabilities(AttachCapabilitiesEvent<TileEntity> event) {
    TileEntity tile = event.getObject();
    ResourceLocation location = TileEntity.getKey(tile.getClass());
    if (// f.e. IC2 energy net internals
    location == null)
        return;
    ThreeState state = CharsetIMC.INSTANCE.allows("lock", location);
    boolean hasCap = state == ThreeState.YES;
    if (state == ThreeState.MAYBE) {
        if (tile instanceof TileEntityLockable) {
            hasCap = true;
        }
    }
    if (hasCap) {
        if (PROVIDER == null) {
            PROVIDER = new CapabilityProviderFactory<>(Capabilities.LOCKABLE, Capabilities.LOCKABLE_STORAGE);
        }
        event.addCapability(LOCKABLE, PROVIDER.create(new Lockable(tile)));
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) ThreeState(pl.asie.charset.lib.utils.ThreeState) TileEntityLockable(net.minecraft.tileentity.TileEntityLockable) ResourceLocation(net.minecraft.util.ResourceLocation) TileEntityLockable(net.minecraft.tileentity.TileEntityLockable) Lockable(pl.asie.charset.api.locks.Lockable) SubscribeEvent(net.minecraftforge.fml.common.eventhandler.SubscribeEvent)

Example 5 with ThreeState

use of pl.asie.charset.lib.utils.ThreeState in project Charset by CharsetMC.

the class CharsetTweakBlockCarrying method canCarry.

protected static boolean canCarry(Entity entity) {
    Class<? extends Entity> entityClass = entity.getClass();
    EntityEntry entry = EntityRegistry.getEntry(entityClass);
    if (entry == null) {
        ModCharset.logger.warn(entityClass.getName() + " has no EntityEntry!");
    } else {
        ThreeState allowedIMC = CharsetIMC.INSTANCE.allows("carry", entry.getRegistryName());
        if (allowedIMC == ThreeState.NO) {
            return false;
        } else if (allowedIMC == ThreeState.YES) {
            return true;
        }
    }
    return true;
}
Also used : ThreeState(pl.asie.charset.lib.utils.ThreeState) EntityEntry(net.minecraftforge.fml.common.registry.EntityEntry)

Aggregations

ThreeState (pl.asie.charset.lib.utils.ThreeState)6 IBlockState (net.minecraft.block.state.IBlockState)2 TileEntity (net.minecraft.tileentity.TileEntity)2 ResourceLocation (net.minecraft.util.ResourceLocation)2 SubscribeEvent (net.minecraftforge.fml.common.eventhandler.SubscribeEvent)2 Joiner (com.google.common.base.Joiner)1 com.google.common.collect (com.google.common.collect)1 MethodHandle (java.lang.invoke.MethodHandle)1 MethodHandles (java.lang.invoke.MethodHandles)1 MethodType (java.lang.invoke.MethodType)1 Field (java.lang.reflect.Field)1 Method (java.lang.reflect.Method)1 java.util (java.util)1 HashSet (java.util.HashSet)1 BiConsumer (java.util.function.BiConsumer)1 Block (net.minecraft.block.Block)1 BlockDoor (net.minecraft.block.BlockDoor)1 IProperty (net.minecraft.block.properties.IProperty)1 TileEntityLockable (net.minecraft.tileentity.TileEntityLockable)1 MinecraftForge (net.minecraftforge.common.MinecraftForge)1