diff --git a/dependencies.gradle b/dependencies.gradle index 4f9733dc..213fc461 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -38,7 +38,7 @@ dependencies { // TODO: remove MUI1 dep when the implicit dependency // TODO: in IItemHandlerModifiable is removed api("com.github.GTNewHorizons:ModularUI:1.3.1:dev") - api("com.github.GTNewHorizons:ModularUI2:2.3.23-1.7.10:dev") + api("com.github.GTNewHorizons:ModularUI2:2.3.24-1.7.10:dev") api("com.github.GTNewHorizons:CraftTweaker:3.4.2:dev") api('curse.maven:cofh-lib-220333:2388748') compileOnly('thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev') @@ -46,15 +46,11 @@ dependencies { compileOnly("com.github.GTNewHorizons:FindIt:1.4.0:dev") compileOnly('com.github.GTNewHorizons:TinkersConstruct:1.14.14-GTNH:dev') - - devOnlyNonPublishable("com.github.GTNewHorizons:Baubles-Expanded:2.2.4-GTNH:dev") + devOnlyNonPublishable("com.github.GTNewHorizons:Baubles-Expanded:2.2.6-GTNH:dev") devOnlyNonPublishable("io.github.legacymoddingmc:unimixins:0.1.23:dev") - runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.8.40-GTNH:dev") - - // For testing NBT data (/nbtedit) - // runtimeOnlyNonPublishable("com.github.GTNewHorizons:ServerUtilities:2.2.6:dev") + runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.8.48-GTNH:dev" ) // For testing glove - // runtimeOnlyNonPublishable("com.github.GTNewHorizons:Translocators:1.4.0:dev") + // runtimeOnlyNonPublishable("com.github.GTNewHorizons:Translocators:1.4.3:dev") // runtimeOnlyNonPublishable("com.github.GTNewHorizons:Backhand:1.8.2:dev") } diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/ModBlocks.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/ModBlocks.java index 73d2eaa0..a87615b0 100644 --- a/src/main/java/com/fouristhenumber/utilitiesinexcess/ModBlocks.java +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/ModBlocks.java @@ -17,6 +17,7 @@ import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockDrum; import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockEnderLotus; import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockEtherealGlass; +import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockFilingCabinet; import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockFloating; import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockInverted; import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockLapisAetherius; @@ -53,6 +54,7 @@ import com.fouristhenumber.utilitiesinexcess.config.blocks.BlockConfig; import com.fouristhenumber.utilitiesinexcess.config.blocks.CursedEarthConfig; import com.fouristhenumber.utilitiesinexcess.config.blocks.EnderLotusConfig; +import com.fouristhenumber.utilitiesinexcess.config.blocks.FilingCabinetsConfig; import com.fouristhenumber.utilitiesinexcess.config.blocks.GeneratorConfig; import com.fouristhenumber.utilitiesinexcess.config.dimensions.EndOfTimeConfig; import com.fouristhenumber.utilitiesinexcess.config.dimensions.UnderWorldConfig; @@ -151,6 +153,7 @@ public enum ModBlocks { DECORATIVE_GLASS(BlockConfig.enableDecorativeGlass, new BlockDecorativeGlass(), BlockDecorativeGlass.ItemBlockDecorativeGlass.class, "decorative_glass"), PACIFISTS_BENCH(BlockConfig.enablePacifistsBench, new BlockPacifistsBench(), "pacifists_bench"), SMART_PUMP(BlockConfig.enableSmartPump, new BlockSmartPump(), "smart_pump"), + FILING_CABINET(FilingCabinetsConfig.enableFilingCabinets,new BlockFilingCabinet() , BlockFilingCabinet.ItemBlockFilingCabinet.class,"filing_cabinet"), TRADING_POST(BlockConfig.enableTradingPost, new BlockTradingPost(), "trading_post"), DECORATIVE_BLOCKS(BlockConfig.enableDecorativeBlocks, new BlockDecorative(), BlockDecorative.ItemBlockDecorative.class, "decorative_block"), ; // leave trailing semicolon diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/UtilitiesInExcess.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/UtilitiesInExcess.java index a4c9ea2f..f041a43f 100644 --- a/src/main/java/com/fouristhenumber/utilitiesinexcess/UtilitiesInExcess.java +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/UtilitiesInExcess.java @@ -14,6 +14,7 @@ import com.fouristhenumber.utilitiesinexcess.common.recipe.RecipeLoader; import com.fouristhenumber.utilitiesinexcess.common.renderers.BlackoutCurtainsRenderer; import com.fouristhenumber.utilitiesinexcess.common.renderers.LapisAetheriusRenderer; +import com.fouristhenumber.utilitiesinexcess.common.renderers.RotatableBlockRenderer; import com.fouristhenumber.utilitiesinexcess.common.renderers.SpikeRenderer; import com.fouristhenumber.utilitiesinexcess.common.tileentities.TileEntityBlockUpdateDetector; import com.fouristhenumber.utilitiesinexcess.common.tileentities.TileEntityConveyor; @@ -33,6 +34,9 @@ import com.fouristhenumber.utilitiesinexcess.common.tileentities.TileEntityTrashCanEnergy; import com.fouristhenumber.utilitiesinexcess.common.tileentities.TileEntityTrashCanFluid; import com.fouristhenumber.utilitiesinexcess.common.tileentities.TileEntityTrashCanItem; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.TileFilingCabinetAdvanced; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.TileFilingCabinetBasic; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.TileFilingCabinetElite; import com.fouristhenumber.utilitiesinexcess.common.tileentities.generators.TileEntityEnderGenerator; import com.fouristhenumber.utilitiesinexcess.common.tileentities.generators.TileEntityFoodGenerator; import com.fouristhenumber.utilitiesinexcess.common.tileentities.generators.TileEntityFurnaceGenerator; @@ -83,6 +87,7 @@ public class UtilitiesInExcess { public static int lapisAetheriusRenderID; public static int blackoutCurtainsRenderID; public static int spikeRenderID; + public static int rotatableblockRenderID; @SidedProxy( clientSide = "com.fouristhenumber.utilitiesinexcess.ClientProxy", @@ -143,6 +148,9 @@ public void init(FMLInitializationEvent event) { GameRegistry.registerTileEntity(TileEntityPinkGenerator.class, "TileEntityPinkGeneratorUIE"); GameRegistry.registerTileEntity(TileEntityNetherStarGenerator.class, "TileEntityNetherStarGeneratorUIE"); GameRegistry.registerTileEntity(TileEntityPacifistsBench.class, "TileEntityPacifistsBenchUIE"); + GameRegistry.registerTileEntity(TileFilingCabinetBasic.class, "TileFilingCabinetBasicUIE"); + GameRegistry.registerTileEntity(TileFilingCabinetAdvanced.class, "TileFilingCabinetAdvancedUIE"); + GameRegistry.registerTileEntity(TileFilingCabinetElite.class, "TileFilingCabinetEliteUIE"); GameRegistry.registerTileEntity(TileEntityTradingPost.class, "TileEntityTradingPostUIE"); lapisAetheriusRenderID = RenderingRegistry.getNextAvailableRenderId(); @@ -151,6 +159,8 @@ public void init(FMLInitializationEvent event) { RenderingRegistry.registerBlockHandler(new BlackoutCurtainsRenderer()); spikeRenderID = RenderingRegistry.getNextAvailableRenderId(); RenderingRegistry.registerBlockHandler(new SpikeRenderer()); + rotatableblockRenderID = RenderingRegistry.getNextAvailableRenderId(); + RenderingRegistry.registerBlockHandler(new RotatableBlockRenderer()); GameRegistry.registerWorldGenerator(new WorldGenEnderLotus(), 10); diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/blocks/BlockFilingCabinet.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/blocks/BlockFilingCabinet.java new file mode 100644 index 00000000..ef9e31b1 --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/blocks/BlockFilingCabinet.java @@ -0,0 +1,223 @@ +package com.fouristhenumber.utilitiesinexcess.common.blocks; + +import static com.fouristhenumber.utilitiesinexcess.render.FacingRotation.calculateFacingRotation; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import com.cleanroommc.modularui.factory.GuiFactories; +import com.fouristhenumber.utilitiesinexcess.UtilitiesInExcess; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.TileFilingCabinetAdvanced; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.TileFilingCabinetBasic; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.TileFilingCabinetElite; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.base.TileFilingCabinetBase; +import com.fouristhenumber.utilitiesinexcess.config.blocks.FilingCabinetsConfig; +import com.fouristhenumber.utilitiesinexcess.render.FacingRotation; +import com.mojang.realmsclient.gui.ChatFormatting; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +// Adapted from Filing Cabinets by phantamanta44 (MIT License) +// Source: https://github.com/phantamanta44/filing-cabinets + +public class BlockFilingCabinet extends BlockContainer { + + public enum Type { + + BASIC(TileFilingCabinetBasic::new, FilingCabinetsConfig.cabinetBasic.enable), + ADVANCED(TileFilingCabinetAdvanced::new, FilingCabinetsConfig.cabinetAdvanced.enable), + ELITE(TileFilingCabinetElite::new, FilingCabinetsConfig.cabinetElite.enable); + + private static final Type[] VALUES = values(); + + public static Type getForItemMeta(int meta) { + return VALUES[meta]; + } + + private final Supplier tileFactory; + private final boolean isEnabled; + + Type(Supplier tileFactory, boolean isEnabled) { + this.tileFactory = tileFactory; + this.isEnabled = isEnabled; + } + + TileEntity createTileEntity() { + return tileFactory.get(); + } + + public String getName() { + return name().toLowerCase(); + } + + public int getItemMeta() { + return ordinal(); + } + + } + + public BlockFilingCabinet() { + super(Material.iron); + this.setHardness(2F); + this.setBlockName("filing_cabinet"); + } + + @Override + public void getSubBlocks(Item itemIn, CreativeTabs tab, List items) { + for (Type type : Type.VALUES) { + if (type.isEnabled) { + items.add(new ItemStack(this, 1, type.getItemMeta())); + } + } + } + + @Override + public int damageDropped(int meta) { + return meta; + } + + @Override + public int getRenderType() { + return UtilitiesInExcess.rotatableblockRenderID; + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase placer, ItemStack stack) { + FacingRotation fr = calculateFacingRotation(placer); + TileEntity te = world.getTileEntity(x, y, z); + if (te instanceof TileFilingCabinetBase cabinet) { + cabinet.setFacing(fr.facing); + cabinet.setYaw(fr.yaw); + } + super.onBlockPlacedBy(world, x, y, z, placer, stack); + + } + + @Override + public boolean onBlockActivated(World worldIn, int x, int y, int z, EntityPlayer player, int side, float subX, + float subY, float subZ) { + + if (worldIn.isRemote) return true; + + TileEntity te = worldIn.getTileEntity(x, y, z); + if (!(te instanceof TileFilingCabinetBase cabinet)) { + return false; + } + + ItemStack held = player.getCurrentEquippedItem(); + + if (held != null && cabinet.installCapacityUpgrade(worldIn, player, held)) { + return true; + } + + GuiFactories.tileEntity() + .open(player, x, y, z); + return true; + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int meta) { + dropInventory(world, x, y, z); + super.breakBlock(world, x, y, z, block, meta); + } + + public static void dropInventory(World world, int x, int y, int z) { + if (world.isRemote) return; + + TileEntity te = world.getTileEntity(x, y, z); + if (te == null) return; + + if (te instanceof TileFilingCabinetBase inv) { + inv.dropInventory(world, x, y, z); + } + } + + @Override + public TileEntity createNewTileEntity(World worldIn, int meta) { + return Type.getForItemMeta(meta) + .createTileEntity(); + } + + @SideOnly(Side.CLIENT) + private Map icons; + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister reg) { + icons = new HashMap<>(); + for (Type type : Type.VALUES) { + String basePath = String.format("%s:filing_cabinet/%s/", UtilitiesInExcess.MODID, type.getName()); + IIcon side = reg.registerIcon(basePath + "side"); + IIcon front = reg.registerIcon(basePath + "front"); + icons.put(type, new IIcon[] { side, front }); + } + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int meta) { + return side == 3 ? getFrontIcon(meta) : getSideIcon(meta); + } + + @SideOnly(Side.CLIENT) + public IIcon getSideIcon(int meta) { + Type type = Type.getForItemMeta(meta); + return icons.get(type)[0]; // side + } + + @SideOnly(Side.CLIENT) + public IIcon getFrontIcon(int meta) { + Type type = Type.getForItemMeta(meta); + return icons.get(type)[1]; + } + + public static class ItemBlockFilingCabinet extends ItemBlock { + + public ItemBlockFilingCabinet(Block block) { + super(block); + setHasSubtypes(true); + } + + @Override + public int getMetadata(int damage) { + return damage; + } + + @Override + public String getUnlocalizedName(final ItemStack stack) { + return this.getUnlocalizedName() + "." + + Type.getForItemMeta(stack.getItemDamage()) + .getName(); + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean flags) { + switch (Type.getForItemMeta(stack.getItemDamage())) { + case BASIC: + tooltip.add(ChatFormatting.GRAY + I18n.format("tile.filing_cabinet.basic.desc")); + break; + case ADVANCED: + tooltip.add(ChatFormatting.GRAY + I18n.format("tile.filing_cabinet.advanced.desc")); + break; + } + } + } +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/renderers/RotatableBlockRenderer.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/renderers/RotatableBlockRenderer.java new file mode 100644 index 00000000..b4c07dda --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/renderers/RotatableBlockRenderer.java @@ -0,0 +1,102 @@ +package com.fouristhenumber.utilitiesinexcess.common.renderers; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.common.util.ForgeDirection; + +import org.lwjgl.opengl.GL11; + +import com.fouristhenumber.utilitiesinexcess.UtilitiesInExcess; +import com.fouristhenumber.utilitiesinexcess.render.HelperAO; +import com.fouristhenumber.utilitiesinexcess.render.IRotatableTile; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; + +// todo change it to use GTNHLib models instead +public class RotatableBlockRenderer implements ISimpleBlockRenderingHandler { + + @Override + public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { + Tessellator tess = Tessellator.instance; + renderer.setRenderBoundsFromBlock(block); + GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + + tess.startDrawingQuads(); + tess.setNormal(0.0F, -1.0F, 0.0F); + renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(0, metadata)); + + tess.setNormal(0.0F, 1.0F, 0.0F); + renderer.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(1, metadata)); + + tess.setNormal(0.0F, 0.0F, -1.0F); + renderer.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(2, metadata)); + + tess.setNormal(0.0F, 0.0F, 1.0F); + renderer.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(3, metadata)); + + tess.setNormal(-1.0F, 0.0F, 0.0F); + renderer.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, block.getIcon(4, metadata)); + + tess.setNormal(1.0F, 0.0F, 0.0F); + renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, block.getIcon(5, metadata)); + tess.draw(); + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, + RenderBlocks renderer) { + IRotatableTile tile = (IRotatableTile) world.getTileEntity(x, y, z); + if (tile == null) return false; + + int meta = world.getBlockMetadata(x, y, z); + for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) { + IIcon icon = tile.getIconForSide(block, side, meta); + ForgeDirection rotation = tile.getRotationForSide(side, meta); + renderFace(renderer, block, x, y, z, side, icon, rotation); + } + + return true; + } + + private void renderFace(RenderBlocks renderer, Block block, int x, int y, int z, ForgeDirection side, IIcon icon, + ForgeDirection rotation) { + renderer.setOverrideBlockTexture(icon); + float brightness = 1.0f; + switch (side) { + case DOWN: + HelperAO.RenderYNeg(renderer, block, x, y, z, brightness, brightness, brightness, icon, rotation); + break; + case UP: + HelperAO.RenderYPos(renderer, block, x, y, z, brightness, brightness, brightness, icon, rotation); + break; + case NORTH: + HelperAO.RenderZNeg(renderer, block, x, y, z, brightness, brightness, brightness, icon); + break; + case SOUTH: + HelperAO.RenderZPos(renderer, block, x, y, z, brightness, brightness, brightness, icon); + break; + case WEST: + HelperAO.RenderXNeg(renderer, block, x, y, z, brightness, brightness, brightness, icon); + break; + case EAST: + HelperAO.RenderXPos(renderer, block, x, y, z, brightness, brightness, brightness, icon); + break; + } + + renderer.clearOverrideBlockTexture(); + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return true; + } + + @Override + public int getRenderId() { + return UtilitiesInExcess.rotatableblockRenderID; + } +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/TileEntityTrashCanItem.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/TileEntityTrashCanItem.java index 0c8bd21e..fd2d5190 100644 --- a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/TileEntityTrashCanItem.java +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/TileEntityTrashCanItem.java @@ -21,7 +21,7 @@ import com.cleanroommc.modularui.widgets.slot.ItemSlot; import com.cleanroommc.modularui.widgets.slot.ModularSlot; import com.cleanroommc.modularui.widgets.slot.SlotGroup; -import com.fouristhenumber.utilitiesinexcess.utils.VoidingInventory; +import com.fouristhenumber.utilitiesinexcess.inventory.VoidingInventory; public class TileEntityTrashCanItem extends TileEntity implements IGuiHolder, ISidedInventory { diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/CabinetSetting.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/CabinetSetting.java new file mode 100644 index 00000000..792dbcd5 --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/CabinetSetting.java @@ -0,0 +1,122 @@ +package com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet; + +import java.util.Comparator; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.MathHelper; +import net.minecraftforge.oredict.OreDictionary; + +import com.cleanroommc.modularui.widget.scroll.HorizontalScrollData; +import com.cleanroommc.modularui.widget.scroll.ScrollData; +import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; + +import cpw.mods.fml.common.registry.GameData; +import it.unimi.dsi.fastutil.ints.IntUnaryOperator; + +public class CabinetSetting { + + public enum SortType { + + BY_NAME { + + @Override + public Comparator baseComparator() { + return Comparator + .comparing(SortType::getDisplayNameSafe, Comparator.nullsLast(Comparator.naturalOrder())); + } + }, + + BY_MOD_ID { + + @Override + public Comparator baseComparator() { + return Comparator.comparing(SortType::getModIdSafe, Comparator.nullsLast(Comparator.naturalOrder())); + } + }, + + BY_COUNT { + + @Override + public Comparator baseComparator() { + return Comparator + .comparing(s -> (s == null ? null : s.stackSize), Comparator.nullsLast(Comparator.reverseOrder())); + } + }, + + BY_ORE_DICT { + + @Override + public Comparator baseComparator() { + return Comparator.comparing(SortType::getOreDictSafe, Comparator.nullsLast(Comparator.naturalOrder())); + } + }; + + public Comparator stackComparator() { + return baseComparator() + .thenComparing(SortType::getModIdSafe, Comparator.nullsLast(Comparator.naturalOrder())) + .thenComparingInt(s -> (s == null ? 0 : s.stackSize)) + .thenComparing(SortType::getOreDictSafe, Comparator.nullsLast(Comparator.naturalOrder())) + .thenComparing(SortType::getDisplayNameSafe, Comparator.nullsLast(Comparator.naturalOrder())); + } + + public abstract Comparator baseComparator(); + + private static String getDisplayNameSafe(ItemStack stack) { + if (stack == null || stack.getItem() == null) return null; + return stack.getDisplayName(); + } + + private static String getModIdSafe(ItemStack stack) { + if (stack == null || stack.getItem() == null) return null; + String id = GameData.getItemRegistry() + .getNameForObject(stack.getItem()); + if (id == null) return "unknown"; + int i = id.indexOf(":"); + return i == -1 ? "minecraft" : id.substring(0, i); + } + + private static String getOreDictSafe(ItemStack stack) { + if (stack == null || stack.getItem() == null) return null; + int[] ids = OreDictionary.getOreIDs(stack); + if (ids.length == 0) return ""; + return OreDictionary.getOreName(ids[0]); + } + } + + public enum ScrollDirection { + + HORIZONTAL(slots -> MathHelper.ceiling_double_int(slots / 5.0D), new HorizontalScrollData(false, 10)), // max 5 + // rows + VERTICAL(slots -> 8, new VerticalScrollData(false, 10)); // max 9 columns + + private final IntUnaryOperator rowSizeCalculator; + private final ScrollData scrollData; + + ScrollDirection(IntUnaryOperator rowSizeCalculator, ScrollData scrollData) { + this.rowSizeCalculator = rowSizeCalculator; + this.scrollData = scrollData; + } + + public boolean isHorizontal() { + return this == HORIZONTAL; + } + + public int getRowSize(int slots) { + return rowSizeCalculator.apply(slots); + } + + public ScrollData getScrollData() { + return scrollData; + } + } + + public enum SlotDirection { + + HORIZONTAL, + VERTICAL; + + public boolean isHorizontal() { + return this == HORIZONTAL; + } + } +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/TileFilingCabinetAdvanced.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/TileFilingCabinetAdvanced.java new file mode 100644 index 00000000..86a4fe40 --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/TileFilingCabinetAdvanced.java @@ -0,0 +1,36 @@ +package com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet; + +import java.util.function.Predicate; + +import net.minecraft.item.ItemStack; + +import com.fouristhenumber.utilitiesinexcess.ModItems; +import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockFilingCabinet; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.base.TileFilingCabinetBaseItem; +import com.fouristhenumber.utilitiesinexcess.config.blocks.FilingCabinetsConfig; + +public class TileFilingCabinetAdvanced extends TileFilingCabinetBaseItem { + + public TileFilingCabinetAdvanced() { + super( + FilingCabinetsConfig.cabinetAdvanced, + is -> ModItems.INVERTED_INGOT.newItemStack() + .isItemEqual(is)); + } + + @Override + public BlockFilingCabinet.Type getCabinetType() { + return BlockFilingCabinet.Type.ADVANCED; + } + + @Override + public boolean isItemAllowed(ItemStack stack) { + return stack.getMaxStackSize() == 1; + } + + @Override + public Predicate extractMatcher(ItemStack stack) { + return is -> true; + } + +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/TileFilingCabinetBasic.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/TileFilingCabinetBasic.java new file mode 100644 index 00000000..81b82a9b --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/TileFilingCabinetBasic.java @@ -0,0 +1,37 @@ +package com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet; + +import java.util.function.Predicate; + +import net.minecraft.item.ItemStack; + +import com.fouristhenumber.utilitiesinexcess.ModItems; +import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockFilingCabinet; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.base.TileFilingCabinetBaseItem; +import com.fouristhenumber.utilitiesinexcess.config.blocks.FilingCabinetsConfig; + +public class TileFilingCabinetBasic extends TileFilingCabinetBaseItem { + + public TileFilingCabinetBasic() { + super( + FilingCabinetsConfig.cabinetBasic, + is -> ModItems.INVERTED_INGOT.newItemStack() + .isItemEqual(is)); + } + + @Override + public BlockFilingCabinet.Type getCabinetType() { + return BlockFilingCabinet.Type.BASIC; + } + + @Override + public boolean isItemAllowed(ItemStack stack) { + return stack.getMaxStackSize() != 1; + } + + @Override + public Predicate extractMatcher(ItemStack stack) { + return is -> stack.getItem() + .equals(is.getItem()); + } + +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/TileFilingCabinetElite.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/TileFilingCabinetElite.java new file mode 100644 index 00000000..9621ce4a --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/TileFilingCabinetElite.java @@ -0,0 +1,36 @@ +package com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet; + +import java.util.function.Predicate; + +import net.minecraft.item.ItemStack; + +import com.fouristhenumber.utilitiesinexcess.ModItems; +import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockFilingCabinet; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.base.TileFilingCabinetBaseItem; +import com.fouristhenumber.utilitiesinexcess.config.blocks.FilingCabinetsConfig; + +public class TileFilingCabinetElite extends TileFilingCabinetBaseItem { + + public TileFilingCabinetElite() { + super( + FilingCabinetsConfig.cabinetElite, + is -> ModItems.INVERTED_INGOT.newItemStack() + .isItemEqual(is)); + } + + @Override + public BlockFilingCabinet.Type getCabinetType() { + return BlockFilingCabinet.Type.ELITE; + } + + @Override + public boolean isItemAllowed(ItemStack stack) { + return true; + } + + @Override + public Predicate extractMatcher(ItemStack stack) { + return is -> true; + } + +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/base/TileFilingCabinetBase.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/base/TileFilingCabinetBase.java new file mode 100644 index 00000000..28e23297 --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/base/TileFilingCabinetBase.java @@ -0,0 +1,186 @@ +package com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.base; + +import java.util.function.Predicate; + +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import com.cleanroommc.modularui.api.IGuiHolder; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.UISettings; +import com.cleanroommc.modularui.utils.item.ItemHandlerHelper; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.fouristhenumber.utilitiesinexcess.ModItems; +import com.fouristhenumber.utilitiesinexcess.common.blocks.BlockFilingCabinet; +import com.fouristhenumber.utilitiesinexcess.config.blocks.FilingCabinetsConfig; +import com.fouristhenumber.utilitiesinexcess.render.IRotatableTile; + +public abstract class TileFilingCabinetBase extends TileEntity implements IGuiHolder, IRotatableTile { + + protected final Predicate upgradeMatcher; + private int upgradeCount; + + private ForgeDirection yaw = ForgeDirection.NORTH; // 4-way spin + private ForgeDirection facing = ForgeDirection.NORTH; // 6-way placement + + TileFilingCabinetBase(Predicate upgradeMatcher) { + this.upgradeMatcher = upgradeMatcher; + + } + + public abstract BlockFilingCabinet.Type getCabinetType(); + + public abstract Predicate extractMatcher(ItemStack stack); + + @Override + public void setFacing(ForgeDirection facing) { + if (facing != null && facing != ForgeDirection.UNKNOWN) { + this.facing = facing; + } + } + + @Override + public ForgeDirection getFacing() { + return this.facing; + } + + @Override + public void setYaw(ForgeDirection yaw) { + if (yaw != null && yaw.offsetY == 0) { + this.yaw = yaw; + } + } + + @Override + public ForgeDirection getYaw() { + return this.yaw; + } + + public int getNumberOfUpgrades() { + return upgradeCount; + } + + public boolean installCapacityUpgrade(World world, EntityPlayer player, ItemStack stack) { + if (stack != null && upgradeMatcher.test(stack)) { + IChatComponent msg; + if (upgradeCount < FilingCabinetsConfig.upgradeCountMax) { + if (!player.capabilities.isCreativeMode) { + stack.stackSize -= 1; + } + upgradeCount += 1; + markDirty(); + world.playSoundAtEntity(player, "random.levelup", 1F, 1F); + msg = new ChatComponentTranslation("tile.filing_cabinet.capacity_upgrade.success"); + msg.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GREEN)); + } else { + world.playSoundAtEntity(player, "random.levelup", 1F, 1F); + msg = new ChatComponentTranslation("tile.filing_cabinet.capacity_upgrade.maxed"); + msg.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.DARK_RED)); + } + player.addChatComponentMessage(msg); + return true; + } + return false; + } + + public void dropInventory(World world, int x, int y, int z) { + if (this instanceof TileFilingCabinetBaseItem item) for (int i = 0; i < item.inventory.getSlots(); i++) { + ItemStack stack = item.inventory.getStackInSlot(i); + if (stack != null) { + int maxSize = stack.getMaxStackSize(); + while (stack.stackSize > maxSize) { + dropItemStack(world, x, y, z, ItemHandlerHelper.copyStackWithSize(stack, maxSize)); + stack.stackSize -= maxSize; + } + dropItemStack(world, x, y, z, stack); + } + } + int upgrades = upgradeCount; + if (upgrades > 0) { + // WorldUtils.dropItem(world, pos, ModItems.Type.CAPACITY_UPGRADE.newStack(upgrades)); + // todo change to use a proper upgrade + dropItemStack(world, x, y, z, ModItems.INVERTED_INGOT.newItemStack(upgrades)); + } + } + + public static void dropItemStack(World world, int x, int y, int z, ItemStack stack) { + if (stack == null || stack.stackSize <= 0 || world.isRemote) return; + + float offsetX = world.rand.nextFloat() * 0.6F + 0.1F; + float offsetY = world.rand.nextFloat() * 0.6F + 0.1F; + float offsetZ = world.rand.nextFloat() * 0.6F + 0.1F; + + EntityItem entityItem = new EntityItem(world, x + offsetX, y + offsetY, z + offsetZ, stack.copy()); + + if (stack.hasTagCompound()) { + entityItem.getEntityItem() + .setTagCompound( + (NBTTagCompound) stack.getTagCompound() + .copy()); + } + + float factor = 0.025F; + entityItem.motionX = world.rand.nextGaussian() * factor; + entityItem.motionY = world.rand.nextGaussian() * factor + 0.1F; + entityItem.motionZ = world.rand.nextGaussian() * factor; + + world.spawnEntityInWorld(entityItem); + } + + @Override + public ModularPanel buildUI(PosGuiData data, PanelSyncManager syncManager, UISettings settings) { + return buildUICabinet(data, syncManager, settings); + } + + public abstract ModularPanel buildUICabinet(PosGuiData data, PanelSyncManager syncManager, UISettings settings); + + @Override + public void writeToNBT(NBTTagCompound compound) { + super.writeToNBT(compound); + compound.setInteger("UpgradeCount", upgradeCount); + compound.setByte("Yaw", (byte) this.yaw.ordinal()); + compound.setByte("Facing", (byte) this.facing.ordinal()); + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + super.readFromNBT(compound); + upgradeCount = compound.getInteger("UpgradeCount"); + this.yaw = ForgeDirection.getOrientation(compound.getByte("Yaw")); + this.facing = ForgeDirection.getOrientation(compound.getByte("Facing")); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound compound = new NBTTagCompound(); + this.writeToNBT(compound); + return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, compound); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + this.readFromNBT(pkt.func_148857_g()); + } + + @Override + public void markDirty() { + super.markDirty(); + if (this.worldObj != null && !this.worldObj.isRemote) { + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + } + } + +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/base/TileFilingCabinetBaseItem.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/base/TileFilingCabinetBaseItem.java new file mode 100644 index 00000000..c49898e6 --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/common/tileentities/cabinet/base/TileFilingCabinetBaseItem.java @@ -0,0 +1,463 @@ +package com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.base; + +import static com.fouristhenumber.utilitiesinexcess.utils.UIEUtils.formatNumber; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.function.Supplier; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.util.Constants; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.drawable.GuiTextures; +import com.cleanroommc.modularui.drawable.ItemDrawable; +import com.cleanroommc.modularui.drawable.UITexture; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.UISettings; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Interpolation; +import com.cleanroommc.modularui.value.sync.DoubleSyncValue; +import com.cleanroommc.modularui.value.sync.DynamicSyncHandler; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.value.sync.ItemSlotSH; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.CycleButtonWidget; +import com.cleanroommc.modularui.widgets.DynamicSyncedWidget; +import com.cleanroommc.modularui.widgets.Expandable; +import com.cleanroommc.modularui.widgets.ProgressWidget; +import com.cleanroommc.modularui.widgets.layout.Grid; +import com.cleanroommc.modularui.widgets.slot.ItemSlot; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import com.cleanroommc.modularui.widgets.slot.SlotGroup; +import com.fouristhenumber.utilitiesinexcess.UtilitiesInExcess; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.CabinetSetting; +import com.fouristhenumber.utilitiesinexcess.config.blocks.FilingCabinetsConfig; +import com.fouristhenumber.utilitiesinexcess.inventory.CabinetInventory; +import com.fouristhenumber.utilitiesinexcess.utils.NbtHelper; + +public abstract class TileFilingCabinetBaseItem extends TileFilingCabinetBase implements ISidedInventory { + + public CabinetInventory inventory; + + public CabinetSetting.SortType sortType = CabinetSetting.SortType.BY_NAME; + public CabinetSetting.ScrollDirection scrollDirection = CabinetSetting.ScrollDirection.VERTICAL; + public CabinetSetting.SlotDirection slotDirection = CabinetSetting.SlotDirection.HORIZONTAL; + + private static final String NBT_SORT_TYPE = "SortType"; + private static final String NBT_SCROLL_DIR = "ScrollDir"; + private static final String NBT_SLOT_DIR = "SlotDir"; + + private CycleButtonWidget SortButton; + private CycleButtonWidget ScrollButton; + private CycleButtonWidget SlotDirButton; + + public static final UITexture STORAGE_PROGRESS = UITexture.builder() + .location(UtilitiesInExcess.MODID, "gui/cabinet/progress_storage") + .adaptable(1) + .imageSize(32, 8) + .build(); + + public static final UITexture SLOT_PROGRESS = UITexture.builder() + .location(UtilitiesInExcess.MODID, "gui/cabinet/progress_slot_used") + .adaptable(1) + .imageSize(32, 8) + .build(); + + public abstract boolean isItemAllowed(ItemStack stack); + + public TileFilingCabinetBaseItem(FilingCabinetsConfig.CabinetConfig config, Predicate upgradeMatcher) { + super(upgradeMatcher); + this.inventory = new CabinetInventory( + this, + config.numSlots, + config.numItems, + FilingCabinetsConfig.upgradeCapacity); + + } + + @Override + public ModularPanel buildUICabinet(PosGuiData data, PanelSyncManager syncManager, UISettings settings) { + IntSyncValue capacity = new IntSyncValue(() -> inventory.getCapacity()); + IntSyncValue stored = new IntSyncValue(() -> inventory.getStoredQuantity()); + IntSyncValue slots = new IntSyncValue(() -> inventory.getSlots()); + IntSyncValue slotsUsed = new IntSyncValue(() -> inventory.getSlotsUsed()); + + syncManager.syncValue("capacity", capacity); + syncManager.syncValue("stored", stored); + syncManager.syncValue("slots", slots); + syncManager.syncValue("slotsUsed", slotsUsed); + + DynamicSyncHandler gridRefresher = new DynamicSyncHandler(); + + Runnable triggerRefresh = () -> { + gridRefresher.notifyUpdate(buf -> { + buf.writeInt(this.sortType.ordinal()); + buf.writeInt(this.scrollDirection.ordinal()); + buf.writeInt(this.slotDirection.ordinal()); + }); + }; + + List itemSlotList = new ArrayList<>(); + SlotGroup connected = new SlotGroup( + "cabinet_inventory", + scrollDirection.getRowSize(this.inventory.getSlots()), + true); + + syncManager.registerSlotGroup(connected); + + for (int i = 0; i < this.inventory.getSlots(); i++) { + int finalI = i; + ItemSlot slotWidget = new ItemSlot().syncHandler( + syncManager.getOrCreateSyncHandler( + "slot_" + i, + i, + ItemSlotSH.class, + () -> new ItemSlotSH( + new ModularSlot(this.inventory, finalI).slotGroup(connected) + .ignoreMaxStackSize(true) + .changeListener((newItem, onlyAmountChanged, client, init) -> { + inventory.updateCounts(); + triggerRefresh.run(); + })))); + itemSlotList.add(slotWidget); + } + + gridRefresher.widgetProvider((sm, buf) -> { + int sortOrd = buf.readInt(); + int scrollOrd = buf.readInt(); + int slotOrd = buf.readInt(); + + CabinetSetting.SortType sort = CabinetSetting.SortType.values()[sortOrd]; + CabinetSetting.ScrollDirection scroll = CabinetSetting.ScrollDirection.values()[scrollOrd]; + CabinetSetting.SlotDirection slotDir = CabinetSetting.SlotDirection.values()[slotOrd]; + + itemSlotList.sort((slotA, slotB) -> { + ItemStack stackA = slotA.getSlot() + .getStack(); + ItemStack stackB = slotB.getSlot() + .getStack(); + return sort.stackComparator() + .compare(stackA, stackB); + }); + + int slotSize = 18; + int cols = 9; + int rows = 5; + + int rowSize = scroll.getRowSize(this.inventory.getSlots()); + int slotsRow = slotSize * cols + (!scroll.isHorizontal() ? -8 : 0); + int slotsCol = slotSize * rows + (scroll.isHorizontal() ? 10 : 0); + + Grid inventoryGrid = new Grid().name("Grid") + .scrollable(scroll.getScrollData()) + .width(slotsRow) + .height(slotsCol) + .matrix(safeMatrix(rowSize, itemSlotList, slotDir.isHorizontal())); + + return inventoryGrid; + }); + + DynamicSyncedWidget dynamicGridWidget = new DynamicSyncedWidget<>(); + dynamicGridWidget.syncHandler(gridRefresher); + dynamicGridWidget.relativeToParent() + .align(Alignment.TopCenter) + .marginTop(20) + .coverChildren(); + + ModularPanel panel = new ModularPanel("Cabinet"); + panel.size(176, 217); + panel.bindPlayerInventory(); + + panel.child(dynamicGridWidget); + + setCabinetSettingButtons(triggerRefresh); + + // todo have a proper icon + Expandable expandable = new Expandable().name("expandable") + .top(0) + .leftRelOffset(1f, 1) + .background(GuiTextures.MC_BACKGROUND) + .excludeAreaInRecipeViewer() + .stencilTransform((r, expanded) -> { + r.width = Math.max(20, r.width - 5); + r.height = Math.max(20, r.height - 5); + }) + .animationDuration(500) + .interpolation(Interpolation.BOUNCE_OUT) + .collapsedView( + new ItemDrawable(Blocks.crafting_table).asIcon() + .asWidget() + .size(20) + .pos(0, 0)) + .expandedView( + new ParentWidget<>().name("crafting tab") + .child( + new ItemDrawable(Blocks.crafting_table).asIcon() + .asWidget() + .size(20) + .pos(0, -20)) + .child(SortButton) + .child(ScrollButton) + .child(SlotDirButton) + .size(20, 54) + .margin(0, 0, 20, 5)); + + panel.child(expandable); + + panel.child( + new ProgressWidget() + .value(new DoubleSyncValue(() -> (double) inventory.getSlotsUsed() / inventory.getSlots())) + .texture(SLOT_PROGRESS, 4) + .direction(ProgressWidget.Direction.RIGHT) + .size(32, 4) + .align(Alignment.TopRight) + .marginTop(6) + .marginRight(7) + .tooltipDynamic( + tt -> tt.add( + StatCollector.translateToLocalFormatted( + "gui.cabinet.slot", + formatNumber(slotsUsed.getIntValue()), + formatNumber(slots.getIntValue()))))); + + panel.child( + new ProgressWidget() + .value(new DoubleSyncValue(() -> (double) inventory.getStoredQuantity() / inventory.getCapacity())) + .texture(STORAGE_PROGRESS, 8) + .direction(ProgressWidget.Direction.RIGHT) + .size(32, 4) + .align(Alignment.TopRight) + .marginTop(10) + .marginRight(7) + .tooltipDynamic( + tt -> tt.add( + StatCollector.translateToLocalFormatted( + "gui.cabinet.storage", + formatNumber(stored.getIntValue()), + formatNumber(capacity.getIntValue()))))); + + panel.child( + new ParentWidget<>().coverChildren() + .align(Alignment.TopLeft) + .marginTop(6) + .marginLeft(7) + .child( + IKey.str(StatCollector.translateToLocal(getInventoryName())) + .asWidget())); + + triggerRefresh.run(); + return panel; + } + + private > EnumSyncValue syncEnum(Class Enum, Supplier supplier, Consumer consumer, + Runnable refresh) { + return new EnumSyncValue<>(Enum, supplier, value -> { + consumer.accept(value); + refresh.run(); + markDirty(); + }); + } + + public void setCabinetSettingButtons(Runnable triggerRefresh) { + var sortSync = syncEnum(CabinetSetting.SortType.class, () -> sortType, v -> sortType = v, triggerRefresh); + + var scrollSync = syncEnum( + CabinetSetting.ScrollDirection.class, + () -> scrollDirection, + v -> scrollDirection = v, + triggerRefresh); + + var slotSync = syncEnum( + CabinetSetting.SlotDirection.class, + () -> slotDirection, + v -> slotDirection = v, + triggerRefresh); + + // todo change the rich tooltip to use lang keys + SortButton = new CycleButtonWidget().value(sortSync) + .stateOverlay(CabinetSetting.SortType.BY_NAME, GuiTextures.ARROW_DOWN) + .stateOverlay(CabinetSetting.SortType.BY_MOD_ID, GuiTextures.ARROW_UP) + .stateOverlay(CabinetSetting.SortType.BY_COUNT, GuiTextures.ALL_DIRECTIONS) + .stateOverlay(CabinetSetting.SortType.BY_ORE_DICT, GuiTextures.BOOKMARK) + .tooltipBuilder(CabinetSetting.SortType.BY_NAME.ordinal(), tt -> tt.addLine("Sort: Name")) + .tooltipBuilder(CabinetSetting.SortType.BY_MOD_ID.ordinal(), tt -> tt.addLine("Sort: Mod ID")) + .tooltipBuilder(CabinetSetting.SortType.BY_COUNT.ordinal(), tt -> tt.addLine("Sort: Count")) + .tooltipBuilder(CabinetSetting.SortType.BY_ORE_DICT.ordinal(), tt -> tt.addLine("Sort: Ore Dictionary")) + .align(Alignment.TopCenter) + .size(12); + + ScrollButton = new CycleButtonWidget().value(scrollSync) + .stateOverlay(CabinetSetting.ScrollDirection.HORIZONTAL, GuiTextures.CHECK_BOX) + .stateOverlay(CabinetSetting.ScrollDirection.VERTICAL, GuiTextures.CHECK_BOX_FULL) + .tooltipBuilder(CabinetSetting.ScrollDirection.HORIZONTAL.ordinal(), tt -> tt.addLine("Sort: Name")) + .tooltipBuilder(CabinetSetting.ScrollDirection.VERTICAL.ordinal(), tt -> tt.addLine("Sort: Mod ID")) + .align(Alignment.Center) + .size(12); + + SlotDirButton = new CycleButtonWidget().value(slotSync) + .stateOverlay(CabinetSetting.SlotDirection.HORIZONTAL, GuiTextures.PROCESSOR) + .stateOverlay(CabinetSetting.SlotDirection.VERTICAL, GuiTextures.PASTE) + .tooltipBuilder(CabinetSetting.SlotDirection.HORIZONTAL.ordinal(), tt -> tt.addLine("Sort: Name")) + .tooltipBuilder(CabinetSetting.SlotDirection.VERTICAL.ordinal(), tt -> tt.addLine("Sort: Mod ID")) + .align(Alignment.BottomCenter) + .size(12); + } + + @Override + public void writeToNBT(NBTTagCompound compound) { + super.writeToNBT(compound); + NBTTagCompound inventoryTag = this.inventory.serializeNBT(); + compound.setTag("Inventory", inventoryTag); + + NbtHelper.writeEnumToNBT(compound, NBT_SORT_TYPE, sortType); + NbtHelper.writeEnumToNBT(compound, NBT_SCROLL_DIR, scrollDirection); + NbtHelper.writeEnumToNBT(compound, NBT_SLOT_DIR, slotDirection); + + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + super.readFromNBT(compound); + if (compound.hasKey("Inventory", Constants.NBT.TAG_COMPOUND)) { + this.inventory.deserializeNBT(compound.getCompoundTag("Inventory")); + } + + sortType = NbtHelper.readEnumFromNBT( + compound, + NBT_SORT_TYPE, + CabinetSetting.SortType.values(), + CabinetSetting.SortType.BY_NAME); + scrollDirection = NbtHelper.readEnumFromNBT( + compound, + NBT_SCROLL_DIR, + CabinetSetting.ScrollDirection.values(), + CabinetSetting.ScrollDirection.VERTICAL); + slotDirection = NbtHelper.readEnumFromNBT( + compound, + NBT_SLOT_DIR, + CabinetSetting.SlotDirection.values(), + CabinetSetting.SlotDirection.HORIZONTAL); + + } + + @Override + public int getSizeInventory() { + return inventory.getSlots(); + } + + @Override + public ItemStack getStackInSlot(int slot) { + return this.inventory.getStackInSlot(slot); + } + + @Override + public void setInventorySlotContents(int slot, ItemStack stack) { + this.inventory.setStackInSlot(slot, stack); + } + + @Override + public ItemStack decrStackSize(int slot, int count) { + return inventory.extractItem(slot, count, false); + } + + @Override + public int getInventoryStackLimit() { + return inventory.getRemainingCapacity(); + } + + @Override + public String getInventoryName() { + return "tile.filing_cabinet." + getCabinetType().getName() + ".name"; + } + + @Override + public boolean hasCustomInventoryName() { + return false; + } + + @Override + public ItemStack getStackInSlotOnClosing(int slot) { + return null; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer player) { + return true; + } + + @Override + public void openInventory() {} + + @Override + public void closeInventory() {} + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + return this.inventory.isItemValid(slot, stack); + } + + @Override + public int[] getAccessibleSlotsFromSide(int side) { + int[] slots = new int[getSizeInventory()]; + for (int i = 0; i < slots.length; i++) { + slots[i] = i; + } + return slots; + } + + @Override + public boolean canInsertItem(int slot, ItemStack stack, int side) { + return this.isItemValidForSlot(slot, stack); + } + + @Override + public boolean canExtractItem(int slot, ItemStack stack, int side) { + return this.inventory.getStackInSlot(slot) != null; + } + + public static List> safeMatrix(int rowLength, List list, boolean slotsHorizontal) { + List> matrix = new ArrayList<>(); + + if (slotsHorizontal) { + matrix = Grid.mapToMatrix(rowLength, list.size(), list::get); + } else { + int numCols = rowLength; + int numRows = (int) Math.ceil((double) list.size() / numCols); + + for (int r = 0; r < numRows; r++) { + matrix.add(new ArrayList<>()); + } + + for (int i = 0; i < list.size(); i++) { + int row = i % numRows; + matrix.get(row) + .add(list.get(i)); + } + } + + int maxCols = 0; + for (List row : matrix) { + maxCols = Math.max(maxCols, row.size()); + } + for (List row : matrix) { + while (row.size() < maxCols) { + row.add(null); + } + } + + return matrix; + } + +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/config/blocks/BlockConfig.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/config/blocks/BlockConfig.java index d06c02c4..93ea22a4 100644 --- a/src/main/java/com/fouristhenumber/utilitiesinexcess/config/blocks/BlockConfig.java +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/config/blocks/BlockConfig.java @@ -13,6 +13,7 @@ public static void registerConfig() throws ConfigException { ConfigurationManager.registerConfig(CursedEarthConfig.class); ConfigurationManager.registerConfig(EnderLotusConfig.class); ConfigurationManager.registerConfig(GeneratorConfig.class); + ConfigurationManager.registerConfig(FilingCabinetsConfig.class); } @Config.DefaultBoolean(true) diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/config/blocks/FilingCabinetsConfig.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/config/blocks/FilingCabinetsConfig.java new file mode 100644 index 00000000..4555ff1d --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/config/blocks/FilingCabinetsConfig.java @@ -0,0 +1,58 @@ +package com.fouristhenumber.utilitiesinexcess.config.blocks; + +import com.fouristhenumber.utilitiesinexcess.UtilitiesInExcess; +import com.gtnewhorizon.gtnhlib.config.Config; + +@Config(modid = UtilitiesInExcess.MODID, category = "blocks.filing_cabinets") +@Config.Comment("Filing Cabinet Configuration") +@Config.LangKey("utilitiesinexcess.config.block.filing_cabinets") +public class FilingCabinetsConfig { + + @Config.DefaultBoolean(true) + public static boolean enableFilingCabinets; + + @Config.Comment("Configuration for basic filing cabinets.") + public static final CabinetConfig cabinetBasic = new CabinetConfig(256, 8192, true); + + @Config.Comment("Configuration for advanced filing cabinets.") + public static final CabinetConfig cabinetAdvanced = new CabinetConfig(512, 8192, true); + + @Config.Comment("Configuration for elite filing cabinets.") + public static final CabinetConfig cabinetElite = new CabinetConfig(128, 8192, true); + + @Config.Comment({ "Amount of additional capacity added per capacity upgrade.", + "WARNING: Reducing this may cause data loss in filled filing cabinets!" }) + @Config.RangeInt(min = 1) + public static int upgradeCapacity = 4096; + + @Config.Comment({ "Maximum number of capacity upgrades that can be installed in a single filing cabinet.", + "If this is reduced, existing cabinets will retain all of their upgrades beyond the limit." }) + @Config.RangeInt(min = 0, max = 64) + public static int upgradeCountMax = 14; + + public static class CabinetConfig { + + CabinetConfig(int numSlots, int numItems, boolean enable) { + this.numSlots = numSlots; + this.numItems = numItems; + this.enable = enable; + } + + @Config.Comment({ + "The number of slots in the cabinet; corresponds to the number of distinct item types that can be held.", + "WARNING: Reducing this may cause data loss in filing cabinets with more than that many item types!", + "WARNING: Making this too large may make the cabinet GUI difficult to scroll through!" }) + @Config.RangeInt(min = 1) + public int numSlots; + + @Config.Comment({ + "The capacity of the cabinet; corresponds to the total number of items that can be held across all slots.", + "WARNING: Reducing this may cause data loss in filing cabinets with more than that many total items!" }) + @Config.RangeInt(min = 1) + public int numItems; + + @Config.Comment("To disable the cabinet") + public boolean enable; + + } +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/inventory/CabinetInventory.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/inventory/CabinetInventory.java new file mode 100644 index 00000000..78fa6e49 --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/inventory/CabinetInventory.java @@ -0,0 +1,125 @@ +package com.fouristhenumber.utilitiesinexcess.inventory; + +import java.util.function.Predicate; + +import javax.annotation.Nullable; + +import net.minecraft.item.ItemStack; + +import com.cleanroommc.modularui.utils.item.ItemHandlerHelper; +import com.cleanroommc.modularui.utils.item.ItemStackHandler; +import com.fouristhenumber.utilitiesinexcess.common.tileentities.cabinet.base.TileFilingCabinetBaseItem; + +public class CabinetInventory extends ItemStackHandler { + + private final TileFilingCabinetBaseItem cabinet; + private final int baseCapacity; + private final int capacityPerUpgrade; + private int usedSlotCount = 0; + private int itemCount = 0; + + @Nullable + private Predicate itemMatcher = null; + + public CabinetInventory(TileFilingCabinetBaseItem cabinet, int numSlots, int baseCapacity, int capacityPerUpgrade) { + super(numSlots); + this.cabinet = cabinet; + this.baseCapacity = baseCapacity; + this.capacityPerUpgrade = capacityPerUpgrade; + } + + @Override + public int getStackLimit(int slot, @Nullable ItemStack stack) { + return this.getSlotLimit(slot); + } + + @Override + public int getSlotLimit(int slot) { + ItemStack stack = getStackInSlot(slot); + return (stack != null) ? stack.stackSize + getRemainingCapacity() : getRemainingCapacity(); + } + + @Override + public void setStackInSlot(int slot, ItemStack stack) { + validateSlotIndex(slot); + + if (stack == null || stack.stackSize <= 0) { + super.setStackInSlot(slot, null); + onContentsChanged(slot); + return; + } + + // Merge with any compatible slot first + for (int i = 0; i < getSlots(); i++) { + if (i == slot) continue; + ItemStack existing = getStackInSlot(i); + if (existing != null && ItemHandlerHelper.canItemStacksStack(existing, stack)) { + long transferable = Math.min(stack.stackSize, getSlotLimit(i)); + transferable = Math.min(transferable, getRemainingCapacity()); + if (transferable > 0) { + existing.stackSize += transferable; + stack.stackSize -= transferable; + onContentsChanged(i); + } + if (stack.stackSize <= 0) return; + } + } + + // Place leftover in target slot + super.setStackInSlot(slot, stack.stackSize > 0 ? stack : null); + onContentsChanged(slot); + } + + @Override + public void onContentsChanged(int slot) { + updateCounts(); + cabinet.markDirty(); + } + + @Override + public void onLoad() { + updateCounts(); + } + + public void updateCounts() { + this.itemCount = 0; + this.usedSlotCount = 0; + ItemStack firstStack = null; + for (ItemStack stack : stacks) { + if (stack != null && stack.stackSize > 0) { + usedSlotCount++; + itemCount += stack.stackSize; + if (firstStack == null) firstStack = stack; + } + } + itemMatcher = (firstStack != null) ? cabinet.extractMatcher(firstStack) : null; + } + + public int getStoredQuantity() { + return itemCount; + } + + public int getCapacity() { + return baseCapacity + capacityPerUpgrade * cabinet.getNumberOfUpgrades(); + } + + public int getSlotsUsed() { + return usedSlotCount; + } + + public int getRemainingCapacity() { + return getCapacity() - getStoredQuantity(); + } + + @Override + public boolean isItemValid(int slot, ItemStack stack) { + boolean isItemNotNull = stack != null && stack.stackSize > 0; + if (!isItemNotNull) return false; + boolean itemMatches = itemMatcher == null || itemMatcher.test(stack); + if (!itemMatches) return false; + int remainingCapacity = getRemainingCapacity(); + if (remainingCapacity <= 0) return false; + + return cabinet.isItemAllowed(stack); + } +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/utils/VoidingInventory.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/inventory/VoidingInventory.java similarity index 96% rename from src/main/java/com/fouristhenumber/utilitiesinexcess/utils/VoidingInventory.java rename to src/main/java/com/fouristhenumber/utilitiesinexcess/inventory/VoidingInventory.java index 7012ac44..aa5adc59 100644 --- a/src/main/java/com/fouristhenumber/utilitiesinexcess/utils/VoidingInventory.java +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/inventory/VoidingInventory.java @@ -1,4 +1,4 @@ -package com.fouristhenumber.utilitiesinexcess.utils; +package com.fouristhenumber.utilitiesinexcess.inventory; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/render/FacingRotation.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/render/FacingRotation.java new file mode 100644 index 00000000..2c222849 --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/render/FacingRotation.java @@ -0,0 +1,49 @@ +package com.fouristhenumber.utilitiesinexcess.render; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.MathHelper; +import net.minecraftforge.common.util.ForgeDirection; + +public class FacingRotation { + + public final ForgeDirection facing; + public final ForgeDirection yaw; + + public FacingRotation(ForgeDirection facing, ForgeDirection yaw) { + this.facing = facing; + this.yaw = yaw; + } + + public static FacingRotation calculateFacingRotation(EntityLivingBase placer) { + ForgeDirection facing; + ForgeDirection yaw = ForgeDirection.NORTH; + + int yawByte = MathHelper.floor_double((placer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + + switch (yawByte) { + case 0: + yaw = ForgeDirection.NORTH; + break; + case 1: + yaw = ForgeDirection.EAST; + break; + case 2: + yaw = ForgeDirection.SOUTH; + break; + case 3: + yaw = ForgeDirection.WEST; + break; + } + + float pitch = placer.rotationPitch; + if (pitch > 55) { + facing = ForgeDirection.UP; + } else if (pitch < -45) { + facing = ForgeDirection.DOWN; + } else { + facing = yaw; + } + + return new FacingRotation(facing, yaw); + } +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/render/HelperAO.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/render/HelperAO.java new file mode 100644 index 00000000..dbcd2d0c --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/render/HelperAO.java @@ -0,0 +1,1032 @@ +package com.fouristhenumber.utilitiesinexcess.render; + +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.IIcon; +import net.minecraftforge.common.util.ForgeDirection; + +public class HelperAO { + + public static boolean RenderYNeg(RenderBlocks renderer, Block block, int x, int y, int z, float red, float green, + float blue, IIcon iicon, ForgeDirection rotation) { + renderer.enableAO = true; + boolean flag = false; + float f3 = 0.0F; + float f4 = 0.0F; + float f5 = 0.0F; + float f6 = 0.0F; + int l = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z); + Tessellator tessellator = Tessellator.instance; + tessellator.setBrightness(983055); + int i1; + float f7; + + if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x, y - 1, z, 0)) { + if (renderer.renderMinY <= 0.0D) { + --y; + } + + renderer.aoBrightnessXYNN = block.getMixedBrightnessForBlock(renderer.blockAccess, x - 1, y, z); + renderer.aoBrightnessYZNN = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z - 1); + renderer.aoBrightnessYZNP = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z + 1); + renderer.aoBrightnessXYPN = block.getMixedBrightnessForBlock(renderer.blockAccess, x + 1, y, z); + renderer.aoLightValueScratchXYNN = renderer.blockAccess.getBlock(x - 1, y, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchYZNN = renderer.blockAccess.getBlock(x, y, z - 1) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchYZNP = renderer.blockAccess.getBlock(x, y, z + 1) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXYPN = renderer.blockAccess.getBlock(x + 1, y, z) + .getAmbientOcclusionLightValue(); + + renderer.aoLightValueScratchXYZNNN = renderer.aoLightValueScratchXYNN; + renderer.aoBrightnessXYZNNN = renderer.aoBrightnessXYNN; + renderer.aoLightValueScratchXYZNNP = renderer.aoLightValueScratchXYNN; + renderer.aoBrightnessXYZNNP = renderer.aoBrightnessXYNN; + renderer.aoLightValueScratchXYZPNN = renderer.aoLightValueScratchXYPN; + renderer.aoBrightnessXYZPNN = renderer.aoBrightnessXYPN; + renderer.aoLightValueScratchXYZPNP = renderer.aoLightValueScratchXYPN; + renderer.aoBrightnessXYZPNP = renderer.aoBrightnessXYPN; + + if (renderer.renderMinY <= 0.0D) { + ++y; + } + + i1 = l; + + if (renderer.renderMinY <= 0.0D || !renderer.blockAccess.getBlock(x, y - 1, z) + .isOpaqueCube()) { + i1 = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y - 1, z); + } + + f7 = renderer.blockAccess.getBlock(x, y - 1, z) + .getAmbientOcclusionLightValue(); + f3 = (renderer.aoLightValueScratchXYZNNP + renderer.aoLightValueScratchXYNN + + renderer.aoLightValueScratchYZNP + + f7) / 4.0F; + f6 = (renderer.aoLightValueScratchYZNP + f7 + + renderer.aoLightValueScratchXYZPNP + + renderer.aoLightValueScratchXYPN) / 4.0F; + f5 = (f7 + renderer.aoLightValueScratchYZNN + + renderer.aoLightValueScratchXYPN + + renderer.aoLightValueScratchXYZPNN) / 4.0F; + f4 = (renderer.aoLightValueScratchXYNN + renderer.aoLightValueScratchXYZNNN + + f7 + + renderer.aoLightValueScratchYZNN) / 4.0F; + renderer.brightnessTopLeft = renderer + .getAoBrightness(renderer.aoBrightnessXYZNNP, renderer.aoBrightnessXYNN, renderer.aoBrightnessYZNP, i1); + renderer.brightnessTopRight = renderer + .getAoBrightness(renderer.aoBrightnessYZNP, renderer.aoBrightnessXYZPNP, renderer.aoBrightnessXYPN, i1); + renderer.brightnessBottomRight = renderer + .getAoBrightness(renderer.aoBrightnessYZNN, renderer.aoBrightnessXYPN, renderer.aoBrightnessXYZPNN, i1); + renderer.brightnessBottomLeft = renderer + .getAoBrightness(renderer.aoBrightnessXYNN, renderer.aoBrightnessXYZNNN, renderer.aoBrightnessYZNN, i1); + + renderer.colorRedTopLeft = renderer.colorRedBottomLeft = renderer.colorRedBottomRight = renderer.colorRedTopRight = red + * 0.5F; + renderer.colorGreenTopLeft = renderer.colorGreenBottomLeft = renderer.colorGreenBottomRight = renderer.colorGreenTopRight = green + * 0.5F; + renderer.colorBlueTopLeft = renderer.colorBlueBottomLeft = renderer.colorBlueBottomRight = renderer.colorBlueTopRight = blue + * 0.5F; + + renderer.colorRedTopLeft *= f3; + renderer.colorGreenTopLeft *= f3; + renderer.colorBlueTopLeft *= f3; + renderer.colorRedBottomLeft *= f4; + renderer.colorGreenBottomLeft *= f4; + renderer.colorBlueBottomLeft *= f4; + renderer.colorRedBottomRight *= f5; + renderer.colorGreenBottomRight *= f5; + renderer.colorBlueBottomRight *= f5; + renderer.colorRedTopRight *= f6; + renderer.colorGreenTopRight *= f6; + renderer.colorBlueTopRight *= f6; + renderFaceYNeg(renderer, block, (double) x, (double) y, (double) z, iicon, rotation); + flag = true; + } + + renderer.enableAO = false; + return flag; + } + + /** + * Renders the bottom face with optional UV rotation (0-3) for top/bottom fronts + */ + public static void renderFaceYNeg(RenderBlocks renderer, Block block, double x, double y, double z, IIcon icon, + ForgeDirection rotationDir) { + Tessellator tessellator = Tessellator.instance; + + if (renderer.hasOverrideBlockTexture()) { + icon = renderer.overrideBlockTexture; + } + + // Base UVs + double uMin = icon.getInterpolatedU(renderer.renderMinX * 16.0D); + double uMax = icon.getInterpolatedU(renderer.renderMaxX * 16.0D); + double vMin = icon.getInterpolatedV(renderer.renderMinZ * 16.0D); + double vMax = icon.getInterpolatedV(renderer.renderMaxZ * 16.0D); + + double[] u = new double[] { uMin, uMax, uMax, uMin }; + double[] v = new double[] { vMin, vMin, vMax, vMax }; + + int rotation = rotationFromDirection(rotationDir); + + // Apply rotation + int bottomRotation = (1 - rotation + 4) % 4; + if (bottomRotation != 0) { + double[] tmpU = u.clone(); + double[] tmpV = v.clone(); + for (int i = 0; i < 4; i++) { + u[i] = tmpU[(i + bottomRotation) % 4]; + v[i] = tmpV[(i + bottomRotation) % 4]; + } + } + + // Vertices positions + double x1 = x + renderer.renderMinX; + double x2 = x + renderer.renderMaxX; + double yPos = y + renderer.renderMinY; + double z1 = z + renderer.renderMinZ; + double z2 = z + renderer.renderMaxZ; + + if (renderer.renderFromInside) { + double tmp = x1; + x1 = x2; + x2 = tmp; + } + + if (renderer.enableAO) { + tessellator + .setColorOpaque_F(renderer.colorRedTopLeft, renderer.colorGreenTopLeft, renderer.colorBlueTopLeft); + tessellator.setBrightness(renderer.brightnessTopLeft); + tessellator.addVertexWithUV(x1, yPos, z2, u[0], v[0]); + + tessellator.setColorOpaque_F( + renderer.colorRedBottomLeft, + renderer.colorGreenBottomLeft, + renderer.colorBlueBottomLeft); + tessellator.setBrightness(renderer.brightnessBottomLeft); + tessellator.addVertexWithUV(x1, yPos, z1, u[1], v[1]); + + tessellator.setColorOpaque_F( + renderer.colorRedBottomRight, + renderer.colorGreenBottomRight, + renderer.colorBlueBottomRight); + tessellator.setBrightness(renderer.brightnessBottomRight); + tessellator.addVertexWithUV(x2, yPos, z1, u[2], v[2]); + + tessellator + .setColorOpaque_F(renderer.colorRedTopRight, renderer.colorGreenTopRight, renderer.colorBlueTopRight); + tessellator.setBrightness(renderer.brightnessTopRight); + tessellator.addVertexWithUV(x2, yPos, z2, u[3], v[3]); + } else { + tessellator.addVertexWithUV(x1, yPos, z2, u[0], v[0]); + tessellator.addVertexWithUV(x1, yPos, z1, u[1], v[1]); + tessellator.addVertexWithUV(x2, yPos, z1, u[2], v[2]); + tessellator.addVertexWithUV(x2, yPos, z2, u[3], v[3]); + } + } + + public static boolean RenderYPos(RenderBlocks renderer, Block block, int x, int y, int z, float red, float green, + float blue, IIcon iicon, ForgeDirection rotation) { + renderer.enableAO = true; + boolean flag = false; + float f3 = 0.0F; + float f4 = 0.0F; + float f5 = 0.0F; + float f6 = 0.0F; + int l = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z); + Tessellator tessellator = Tessellator.instance; + tessellator.setBrightness(983055); + int i1; + float f7; + + if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x, y + 1, z, 1)) { + if (renderer.renderMaxY >= 1.0D) { + ++y; + } + + renderer.aoBrightnessXYNP = block.getMixedBrightnessForBlock(renderer.blockAccess, x - 1, y, z); + renderer.aoBrightnessXYPP = block.getMixedBrightnessForBlock(renderer.blockAccess, x + 1, y, z); + renderer.aoBrightnessYZPN = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z - 1); + renderer.aoBrightnessYZPP = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z + 1); + renderer.aoLightValueScratchXYNP = renderer.blockAccess.getBlock(x - 1, y, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXYPP = renderer.blockAccess.getBlock(x + 1, y, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchYZPN = renderer.blockAccess.getBlock(x, y, z - 1) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchYZPP = renderer.blockAccess.getBlock(x, y, z + 1) + .getAmbientOcclusionLightValue(); + + renderer.aoLightValueScratchXYZNPN = renderer.aoLightValueScratchXYNP; + renderer.aoBrightnessXYZNPN = renderer.aoBrightnessXYNP; + renderer.aoLightValueScratchXYZPPN = renderer.aoLightValueScratchXYPP; + renderer.aoBrightnessXYZPPN = renderer.aoBrightnessXYPP; + renderer.aoLightValueScratchXYZNPP = renderer.aoLightValueScratchXYNP; + renderer.aoBrightnessXYZNPP = renderer.aoBrightnessXYNP; + renderer.aoLightValueScratchXYZPPP = renderer.aoLightValueScratchXYPP; + renderer.aoBrightnessXYZPPP = renderer.aoBrightnessXYPP; + + if (renderer.renderMaxY >= 1.0D) { + --y; + } + + i1 = l; + + if (renderer.renderMaxY >= 1.0D || !renderer.blockAccess.getBlock(x, y + 1, z) + .isOpaqueCube()) { + i1 = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y + 1, z); + } + + f7 = renderer.blockAccess.getBlock(x, y + 1, z) + .getAmbientOcclusionLightValue(); + f6 = (renderer.aoLightValueScratchXYZNPP + renderer.aoLightValueScratchXYNP + + renderer.aoLightValueScratchYZPP + + f7) / 4.0F; + f3 = (renderer.aoLightValueScratchYZPP + f7 + + renderer.aoLightValueScratchXYZPPP + + renderer.aoLightValueScratchXYPP) / 4.0F; + f4 = (f7 + renderer.aoLightValueScratchYZPN + + renderer.aoLightValueScratchXYPP + + renderer.aoLightValueScratchXYZPPN) / 4.0F; + f5 = (renderer.aoLightValueScratchXYNP + renderer.aoLightValueScratchXYZNPN + + f7 + + renderer.aoLightValueScratchYZPN) / 4.0F; + renderer.brightnessTopRight = renderer + .getAoBrightness(renderer.aoBrightnessXYZNPP, renderer.aoBrightnessXYNP, renderer.aoBrightnessYZPP, i1); + renderer.brightnessTopLeft = renderer + .getAoBrightness(renderer.aoBrightnessYZPP, renderer.aoBrightnessXYZPPP, renderer.aoBrightnessXYPP, i1); + renderer.brightnessBottomLeft = renderer + .getAoBrightness(renderer.aoBrightnessYZPN, renderer.aoBrightnessXYPP, renderer.aoBrightnessXYZPPN, i1); + renderer.brightnessBottomRight = renderer + .getAoBrightness(renderer.aoBrightnessXYNP, renderer.aoBrightnessXYZNPN, renderer.aoBrightnessYZPN, i1); + renderer.colorRedTopLeft = renderer.colorRedBottomLeft = renderer.colorRedBottomRight = renderer.colorRedTopRight = red; + renderer.colorGreenTopLeft = renderer.colorGreenBottomLeft = renderer.colorGreenBottomRight = renderer.colorGreenTopRight = green; + renderer.colorBlueTopLeft = renderer.colorBlueBottomLeft = renderer.colorBlueBottomRight = renderer.colorBlueTopRight = blue; + renderer.colorRedTopLeft *= f3; + renderer.colorGreenTopLeft *= f3; + renderer.colorBlueTopLeft *= f3; + renderer.colorRedBottomLeft *= f4; + renderer.colorGreenBottomLeft *= f4; + renderer.colorBlueBottomLeft *= f4; + renderer.colorRedBottomRight *= f5; + renderer.colorGreenBottomRight *= f5; + renderer.colorBlueBottomRight *= f5; + renderer.colorRedTopRight *= f6; + renderer.colorGreenTopRight *= f6; + renderer.colorBlueTopRight *= f6; + renderFaceYPos(renderer, block, (double) x, (double) y, (double) z, iicon, rotation); + flag = true; + } + + renderer.enableAO = false; + return flag; + } + + /** + * Renders the top face with optional UV rotation (0-3) for top/bottom fronts + */ + public static void renderFaceYPos(RenderBlocks renderer, Block block, double x, double y, double z, IIcon icon, + ForgeDirection rotationDir) { + Tessellator tessellator = Tessellator.instance; + + if (renderer.hasOverrideBlockTexture()) { + icon = renderer.overrideBlockTexture; + } + + // Base UVs + double uMin = icon.getInterpolatedU(renderer.renderMinX * 16.0D); + double uMax = icon.getInterpolatedU(renderer.renderMaxX * 16.0D); + double vMin = icon.getInterpolatedV(renderer.renderMinZ * 16.0D); + double vMax = icon.getInterpolatedV(renderer.renderMaxZ * 16.0D); + + int rotation = rotationFromDirection(rotationDir); + + double[] u = { uMin, uMax, uMax, uMin }; + double[] v = { vMin, vMin, vMax, vMax }; + + // Apply rotation + int rotationAdjusted = (rotation + 1) & 3; // rotate one step clockwise + if (rotationAdjusted != 0) { + double[] tmpU = u.clone(); + double[] tmpV = v.clone(); + for (int i = 0; i < 4; i++) { + u[i] = tmpU[(i + rotationAdjusted) % 4]; + v[i] = tmpV[(i + rotationAdjusted) % 4]; + } + } + + // Vertices positions + double x1 = x + renderer.renderMinX; + double x2 = x + renderer.renderMaxX; + double yPos = y + renderer.renderMaxY; + double z1 = z + renderer.renderMinZ; + double z2 = z + renderer.renderMaxZ; + + if (renderer.renderFromInside) { + double tmp = x1; + x1 = x2; + x2 = tmp; + } + + if (renderer.enableAO) { + tessellator + .setColorOpaque_F(renderer.colorRedTopLeft, renderer.colorGreenTopLeft, renderer.colorBlueTopLeft); + tessellator.setBrightness(renderer.brightnessTopLeft); + tessellator.addVertexWithUV(x2, yPos, z2, u[0], v[0]); + + tessellator.setColorOpaque_F( + renderer.colorRedBottomLeft, + renderer.colorGreenBottomLeft, + renderer.colorBlueBottomLeft); + tessellator.setBrightness(renderer.brightnessBottomLeft); + tessellator.addVertexWithUV(x2, yPos, z1, u[1], v[1]); + + tessellator.setColorOpaque_F( + renderer.colorRedBottomRight, + renderer.colorGreenBottomRight, + renderer.colorBlueBottomRight); + tessellator.setBrightness(renderer.brightnessBottomRight); + tessellator.addVertexWithUV(x1, yPos, z1, u[2], v[2]); + + tessellator + .setColorOpaque_F(renderer.colorRedTopRight, renderer.colorGreenTopRight, renderer.colorBlueTopRight); + tessellator.setBrightness(renderer.brightnessTopRight); + tessellator.addVertexWithUV(x1, yPos, z2, u[3], v[3]); + } else { + tessellator.addVertexWithUV(x2, yPos, z2, u[0], v[0]); + tessellator.addVertexWithUV(x2, yPos, z1, u[1], v[1]); + tessellator.addVertexWithUV(x1, yPos, z1, u[2], v[2]); + tessellator.addVertexWithUV(x1, yPos, z2, u[3], v[3]); + } + } + + public static boolean RenderXNeg(RenderBlocks renderer, Block block, int x, int y, int z, float red, float green, + float blue, IIcon iicon) { + renderer.enableAO = true; + boolean flag = false; + float f3 = 0.0F; + float f4 = 0.0F; + float f5 = 0.0F; + float f6 = 0.0F; + int l = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z); + Tessellator tessellator = Tessellator.instance; + tessellator.setBrightness(983055); + int i1; + float f7; + float f8; + float f9; + float f10; + float f11; + int j1; + int k1; + int l1; + int i2; + + if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x - 1, y, z, 4)) { + if (renderer.renderMinX <= 0.0D) { + --x; + } + + renderer.aoLightValueScratchXYNN = renderer.blockAccess.getBlock(x, y - 1, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXZNN = renderer.blockAccess.getBlock(x, y, z - 1) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXZNP = renderer.blockAccess.getBlock(x, y, z + 1) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXYNP = renderer.blockAccess.getBlock(x, y + 1, z) + .getAmbientOcclusionLightValue(); + renderer.aoBrightnessXYNN = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y - 1, z); + renderer.aoBrightnessXZNN = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z - 1); + renderer.aoBrightnessXZNP = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z + 1); + renderer.aoBrightnessXYNP = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y + 1, z); + + renderer.aoLightValueScratchXYZNNN = renderer.aoLightValueScratchXZNN; + renderer.aoBrightnessXYZNNN = renderer.aoBrightnessXZNN; + renderer.aoLightValueScratchXYZNNP = renderer.aoLightValueScratchXZNP; + renderer.aoBrightnessXYZNNP = renderer.aoBrightnessXZNP; + renderer.aoLightValueScratchXYZNPN = renderer.aoLightValueScratchXZNN; + renderer.aoBrightnessXYZNPN = renderer.aoBrightnessXZNN; + renderer.aoLightValueScratchXYZNPP = renderer.aoLightValueScratchXZNP; + renderer.aoBrightnessXYZNPP = renderer.aoBrightnessXZNP; + + if (renderer.renderMinX <= 0.0D) { + ++x; + } + + i1 = l; + + if (renderer.renderMinX <= 0.0D || !renderer.blockAccess.getBlock(x - 1, y, z) + .isOpaqueCube()) { + i1 = block.getMixedBrightnessForBlock(renderer.blockAccess, x - 1, y, z); + } + + f7 = renderer.blockAccess.getBlock(x - 1, y, z) + .getAmbientOcclusionLightValue(); + f8 = (renderer.aoLightValueScratchXYNN + renderer.aoLightValueScratchXYZNNP + + f7 + + renderer.aoLightValueScratchXZNP) / 4.0F; + f9 = (f7 + renderer.aoLightValueScratchXZNP + + renderer.aoLightValueScratchXYNP + + renderer.aoLightValueScratchXYZNPP) / 4.0F; + f10 = (renderer.aoLightValueScratchXZNN + f7 + + renderer.aoLightValueScratchXYZNPN + + renderer.aoLightValueScratchXYNP) / 4.0F; + f11 = (renderer.aoLightValueScratchXYZNNN + renderer.aoLightValueScratchXYNN + + renderer.aoLightValueScratchXZNN + + f7) / 4.0F; + f3 = (float) ((double) f9 * renderer.renderMaxY * renderer.renderMaxZ + + (double) f10 * renderer.renderMaxY * (1.0D - renderer.renderMaxZ) + + (double) f11 * (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMaxZ) + + (double) f8 * (1.0D - renderer.renderMaxY) * renderer.renderMaxZ); + f4 = (float) ((double) f9 * renderer.renderMaxY * renderer.renderMinZ + + (double) f10 * renderer.renderMaxY * (1.0D - renderer.renderMinZ) + + (double) f11 * (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMinZ) + + (double) f8 * (1.0D - renderer.renderMaxY) * renderer.renderMinZ); + f5 = (float) ((double) f9 * renderer.renderMinY * renderer.renderMinZ + + (double) f10 * renderer.renderMinY * (1.0D - renderer.renderMinZ) + + (double) f11 * (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMinZ) + + (double) f8 * (1.0D - renderer.renderMinY) * renderer.renderMinZ); + f6 = (float) ((double) f9 * renderer.renderMinY * renderer.renderMaxZ + + (double) f10 * renderer.renderMinY * (1.0D - renderer.renderMaxZ) + + (double) f11 * (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMaxZ) + + (double) f8 * (1.0D - renderer.renderMinY) * renderer.renderMaxZ); + j1 = renderer + .getAoBrightness(renderer.aoBrightnessXYNN, renderer.aoBrightnessXYZNNP, renderer.aoBrightnessXZNP, i1); + k1 = renderer + .getAoBrightness(renderer.aoBrightnessXZNP, renderer.aoBrightnessXYNP, renderer.aoBrightnessXYZNPP, i1); + l1 = renderer + .getAoBrightness(renderer.aoBrightnessXZNN, renderer.aoBrightnessXYZNPN, renderer.aoBrightnessXYNP, i1); + i2 = renderer + .getAoBrightness(renderer.aoBrightnessXYZNNN, renderer.aoBrightnessXYNN, renderer.aoBrightnessXZNN, i1); + renderer.brightnessTopLeft = renderer.mixAoBrightness( + k1, + l1, + i2, + j1, + renderer.renderMaxY * renderer.renderMaxZ, + renderer.renderMaxY * (1.0D - renderer.renderMaxZ), + (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMaxZ), + (1.0D - renderer.renderMaxY) * renderer.renderMaxZ); + renderer.brightnessBottomLeft = renderer.mixAoBrightness( + k1, + l1, + i2, + j1, + renderer.renderMaxY * renderer.renderMinZ, + renderer.renderMaxY * (1.0D - renderer.renderMinZ), + (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMinZ), + (1.0D - renderer.renderMaxY) * renderer.renderMinZ); + renderer.brightnessBottomRight = renderer.mixAoBrightness( + k1, + l1, + i2, + j1, + renderer.renderMinY * renderer.renderMinZ, + renderer.renderMinY * (1.0D - renderer.renderMinZ), + (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMinZ), + (1.0D - renderer.renderMinY) * renderer.renderMinZ); + renderer.brightnessTopRight = renderer.mixAoBrightness( + k1, + l1, + i2, + j1, + renderer.renderMinY * renderer.renderMaxZ, + renderer.renderMinY * (1.0D - renderer.renderMaxZ), + (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMaxZ), + (1.0D - renderer.renderMinY) * renderer.renderMaxZ); + + renderer.colorRedTopLeft = renderer.colorRedBottomLeft = renderer.colorRedBottomRight = renderer.colorRedTopRight = red + * 0.6F; + renderer.colorGreenTopLeft = renderer.colorGreenBottomLeft = renderer.colorGreenBottomRight = renderer.colorGreenTopRight = green + * 0.6F; + renderer.colorBlueTopLeft = renderer.colorBlueBottomLeft = renderer.colorBlueBottomRight = renderer.colorBlueTopRight = blue + * 0.6F; + + renderer.colorRedTopLeft *= f3; + renderer.colorGreenTopLeft *= f3; + renderer.colorBlueTopLeft *= f3; + renderer.colorRedBottomLeft *= f4; + renderer.colorGreenBottomLeft *= f4; + renderer.colorBlueBottomLeft *= f4; + renderer.colorRedBottomRight *= f5; + renderer.colorGreenBottomRight *= f5; + renderer.colorBlueBottomRight *= f5; + renderer.colorRedTopRight *= f6; + renderer.colorGreenTopRight *= f6; + renderer.colorBlueTopRight *= f6; + renderer.renderFaceXNeg(block, (double) x, (double) y, (double) z, iicon); + + flag = true; + } + + renderer.enableAO = false; + return flag; + } + + public static boolean RenderXPos(RenderBlocks renderer, Block block, int x, int y, int z, float red, float green, + float blue, IIcon iicon) { + renderer.enableAO = true; + boolean flag = false; + float f3 = 0.0F; + float f4 = 0.0F; + float f5 = 0.0F; + float f6 = 0.0F; + int l = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z); + Tessellator tessellator = Tessellator.instance; + tessellator.setBrightness(983055); + int i1; + float f7; + float f8; + float f9; + float f10; + float f11; + int j1; + int k1; + int l1; + int i2; + + if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x + 1, y, z, 5)) { + if (renderer.renderMaxX >= 1.0D) { + ++x; + } + + renderer.aoLightValueScratchXYPN = renderer.blockAccess.getBlock(x, y - 1, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXZPN = renderer.blockAccess.getBlock(x, y, z - 1) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXZPP = renderer.blockAccess.getBlock(x, y, z + 1) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXYPP = renderer.blockAccess.getBlock(x, y + 1, z) + .getAmbientOcclusionLightValue(); + renderer.aoBrightnessXYPN = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y - 1, z); + renderer.aoBrightnessXZPN = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z - 1); + renderer.aoBrightnessXZPP = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z + 1); + renderer.aoBrightnessXYPP = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y + 1, z); + + renderer.aoLightValueScratchXYZPNN = renderer.aoLightValueScratchXZPN; + renderer.aoBrightnessXYZPNN = renderer.aoBrightnessXZPN; + renderer.aoLightValueScratchXYZPNP = renderer.aoLightValueScratchXZPP; + renderer.aoBrightnessXYZPNP = renderer.aoBrightnessXZPP; + renderer.aoLightValueScratchXYZPPN = renderer.aoLightValueScratchXZPN; + renderer.aoBrightnessXYZPPN = renderer.aoBrightnessXZPN; + renderer.aoLightValueScratchXYZPPP = renderer.aoLightValueScratchXZPP; + renderer.aoBrightnessXYZPPP = renderer.aoBrightnessXZPP; + + if (renderer.renderMaxX >= 1.0D) { + --x; + } + + i1 = l; + + if (renderer.renderMaxX >= 1.0D || !renderer.blockAccess.getBlock(x + 1, y, z) + .isOpaqueCube()) { + i1 = block.getMixedBrightnessForBlock(renderer.blockAccess, x + 1, y, z); + } + + f7 = renderer.blockAccess.getBlock(x + 1, y, z) + .getAmbientOcclusionLightValue(); + f8 = (renderer.aoLightValueScratchXYPN + renderer.aoLightValueScratchXYZPNP + + f7 + + renderer.aoLightValueScratchXZPP) / 4.0F; + f9 = (renderer.aoLightValueScratchXYZPNN + renderer.aoLightValueScratchXYPN + + renderer.aoLightValueScratchXZPN + + f7) / 4.0F; + f10 = (renderer.aoLightValueScratchXZPN + f7 + + renderer.aoLightValueScratchXYZPPN + + renderer.aoLightValueScratchXYPP) / 4.0F; + f11 = (f7 + renderer.aoLightValueScratchXZPP + + renderer.aoLightValueScratchXYPP + + renderer.aoLightValueScratchXYZPPP) / 4.0F; + f3 = (float) ((double) f8 * (1.0D - renderer.renderMinY) * renderer.renderMaxZ + + (double) f9 * (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMaxZ) + + (double) f10 * renderer.renderMinY * (1.0D - renderer.renderMaxZ) + + (double) f11 * renderer.renderMinY * renderer.renderMaxZ); + f4 = (float) ((double) f8 * (1.0D - renderer.renderMinY) * renderer.renderMinZ + + (double) f9 * (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMinZ) + + (double) f10 * renderer.renderMinY * (1.0D - renderer.renderMinZ) + + (double) f11 * renderer.renderMinY * renderer.renderMinZ); + f5 = (float) ((double) f8 * (1.0D - renderer.renderMaxY) * renderer.renderMinZ + + (double) f9 * (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMinZ) + + (double) f10 * renderer.renderMaxY * (1.0D - renderer.renderMinZ) + + (double) f11 * renderer.renderMaxY * renderer.renderMinZ); + f6 = (float) ((double) f8 * (1.0D - renderer.renderMaxY) * renderer.renderMaxZ + + (double) f9 * (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMaxZ) + + (double) f10 * renderer.renderMaxY * (1.0D - renderer.renderMaxZ) + + (double) f11 * renderer.renderMaxY * renderer.renderMaxZ); + j1 = renderer + .getAoBrightness(renderer.aoBrightnessXYPN, renderer.aoBrightnessXYZPNP, renderer.aoBrightnessXZPP, i1); + k1 = renderer + .getAoBrightness(renderer.aoBrightnessXZPP, renderer.aoBrightnessXYPP, renderer.aoBrightnessXYZPPP, i1); + l1 = renderer + .getAoBrightness(renderer.aoBrightnessXZPN, renderer.aoBrightnessXYZPPN, renderer.aoBrightnessXYPP, i1); + i2 = renderer + .getAoBrightness(renderer.aoBrightnessXYZPNN, renderer.aoBrightnessXYPN, renderer.aoBrightnessXZPN, i1); + renderer.brightnessTopLeft = renderer.mixAoBrightness( + j1, + i2, + l1, + k1, + (1.0D - renderer.renderMinY) * renderer.renderMaxZ, + (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMaxZ), + renderer.renderMinY * (1.0D - renderer.renderMaxZ), + renderer.renderMinY * renderer.renderMaxZ); + renderer.brightnessBottomLeft = renderer.mixAoBrightness( + j1, + i2, + l1, + k1, + (1.0D - renderer.renderMinY) * renderer.renderMinZ, + (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMinZ), + renderer.renderMinY * (1.0D - renderer.renderMinZ), + renderer.renderMinY * renderer.renderMinZ); + renderer.brightnessBottomRight = renderer.mixAoBrightness( + j1, + i2, + l1, + k1, + (1.0D - renderer.renderMaxY) * renderer.renderMinZ, + (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMinZ), + renderer.renderMaxY * (1.0D - renderer.renderMinZ), + renderer.renderMaxY * renderer.renderMinZ); + renderer.brightnessTopRight = renderer.mixAoBrightness( + j1, + i2, + l1, + k1, + (1.0D - renderer.renderMaxY) * renderer.renderMaxZ, + (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMaxZ), + renderer.renderMaxY * (1.0D - renderer.renderMaxZ), + renderer.renderMaxY * renderer.renderMaxZ); + + renderer.colorRedTopLeft = renderer.colorRedBottomLeft = renderer.colorRedBottomRight = renderer.colorRedTopRight = red + * 0.6F; + renderer.colorGreenTopLeft = renderer.colorGreenBottomLeft = renderer.colorGreenBottomRight = renderer.colorGreenTopRight = green + * 0.6F; + renderer.colorBlueTopLeft = renderer.colorBlueBottomLeft = renderer.colorBlueBottomRight = renderer.colorBlueTopRight = blue + * 0.6F; + + renderer.colorRedTopLeft *= f3; + renderer.colorGreenTopLeft *= f3; + renderer.colorBlueTopLeft *= f3; + renderer.colorRedBottomLeft *= f4; + renderer.colorGreenBottomLeft *= f4; + renderer.colorBlueBottomLeft *= f4; + renderer.colorRedBottomRight *= f5; + renderer.colorGreenBottomRight *= f5; + renderer.colorBlueBottomRight *= f5; + renderer.colorRedTopRight *= f6; + renderer.colorGreenTopRight *= f6; + renderer.colorBlueTopRight *= f6; + renderer.renderFaceXPos(block, (double) x, (double) y, (double) z, iicon); + + flag = true; + } + + renderer.enableAO = false; + return flag; + } + + public static boolean RenderZNeg(RenderBlocks renderer, Block block, int x, int y, int z, float red, float green, + float blue, IIcon iicon) { + renderer.enableAO = true; + boolean flag = false; + float f3 = 0.0F; + float f4 = 0.0F; + float f5 = 0.0F; + float f6 = 0.0F; + int l = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z); + Tessellator tessellator = Tessellator.instance; + tessellator.setBrightness(983055); + int i1; + float f7; + float f8; + float f9; + float f10; + float f11; + int j1; + int k1; + int l1; + int i2; + + if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x, y, z - 1, 2)) { + if (renderer.renderMinZ <= 0.0D) { + --z; + } + + renderer.aoLightValueScratchXZNN = renderer.blockAccess.getBlock(x - 1, y, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchYZNN = renderer.blockAccess.getBlock(x, y - 1, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchYZPN = renderer.blockAccess.getBlock(x, y + 1, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXZPN = renderer.blockAccess.getBlock(x + 1, y, z) + .getAmbientOcclusionLightValue(); + renderer.aoBrightnessXZNN = block.getMixedBrightnessForBlock(renderer.blockAccess, x - 1, y, z); + renderer.aoBrightnessYZNN = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y - 1, z); + renderer.aoBrightnessYZPN = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y + 1, z); + renderer.aoBrightnessXZPN = block.getMixedBrightnessForBlock(renderer.blockAccess, x + 1, y, z); + + renderer.aoLightValueScratchXYZNNN = renderer.aoLightValueScratchXZNN; + renderer.aoBrightnessXYZNNN = renderer.aoBrightnessXZNN; + renderer.aoLightValueScratchXYZNPN = renderer.aoLightValueScratchXZNN; + renderer.aoBrightnessXYZNPN = renderer.aoBrightnessXZNN; + renderer.aoLightValueScratchXYZPNN = renderer.aoLightValueScratchXZPN; + renderer.aoBrightnessXYZPNN = renderer.aoBrightnessXZPN; + renderer.aoLightValueScratchXYZPPN = renderer.aoLightValueScratchXZPN; + renderer.aoBrightnessXYZPPN = renderer.aoBrightnessXZPN; + + if (renderer.renderMinZ <= 0.0D) { + ++z; + } + + i1 = l; + + if (renderer.renderMinZ <= 0.0D || !renderer.blockAccess.getBlock(x, y, z - 1) + .isOpaqueCube()) { + i1 = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z - 1); + } + + f7 = renderer.blockAccess.getBlock(x, y, z - 1) + .getAmbientOcclusionLightValue(); + f8 = (renderer.aoLightValueScratchXZNN + renderer.aoLightValueScratchXYZNPN + + f7 + + renderer.aoLightValueScratchYZPN) / 4.0F; + f9 = (f7 + renderer.aoLightValueScratchYZPN + + renderer.aoLightValueScratchXZPN + + renderer.aoLightValueScratchXYZPPN) / 4.0F; + f10 = (renderer.aoLightValueScratchYZNN + f7 + + renderer.aoLightValueScratchXYZPNN + + renderer.aoLightValueScratchXZPN) / 4.0F; + f11 = (renderer.aoLightValueScratchXYZNNN + renderer.aoLightValueScratchXZNN + + renderer.aoLightValueScratchYZNN + + f7) / 4.0F; + f3 = (float) ((double) f8 * renderer.renderMaxY * (1.0D - renderer.renderMinX) + + (double) f9 * renderer.renderMaxY * renderer.renderMinX + + (double) f10 * (1.0D - renderer.renderMaxY) * renderer.renderMinX + + (double) f11 * (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMinX)); + f4 = (float) ((double) f8 * renderer.renderMaxY * (1.0D - renderer.renderMaxX) + + (double) f9 * renderer.renderMaxY * renderer.renderMaxX + + (double) f10 * (1.0D - renderer.renderMaxY) * renderer.renderMaxX + + (double) f11 * (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMaxX)); + f5 = (float) ((double) f8 * renderer.renderMinY * (1.0D - renderer.renderMaxX) + + (double) f9 * renderer.renderMinY * renderer.renderMaxX + + (double) f10 * (1.0D - renderer.renderMinY) * renderer.renderMaxX + + (double) f11 * (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMaxX)); + f6 = (float) ((double) f8 * renderer.renderMinY * (1.0D - renderer.renderMinX) + + (double) f9 * renderer.renderMinY * renderer.renderMinX + + (double) f10 * (1.0D - renderer.renderMinY) * renderer.renderMinX + + (double) f11 * (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMinX)); + j1 = renderer + .getAoBrightness(renderer.aoBrightnessXZNN, renderer.aoBrightnessXYZNPN, renderer.aoBrightnessYZPN, i1); + k1 = renderer + .getAoBrightness(renderer.aoBrightnessYZPN, renderer.aoBrightnessXZPN, renderer.aoBrightnessXYZPPN, i1); + l1 = renderer + .getAoBrightness(renderer.aoBrightnessYZNN, renderer.aoBrightnessXYZPNN, renderer.aoBrightnessXZPN, i1); + i2 = renderer + .getAoBrightness(renderer.aoBrightnessXYZNNN, renderer.aoBrightnessXZNN, renderer.aoBrightnessYZNN, i1); + renderer.brightnessTopLeft = renderer.mixAoBrightness( + j1, + k1, + l1, + i2, + renderer.renderMaxY * (1.0D - renderer.renderMinX), + renderer.renderMaxY * renderer.renderMinX, + (1.0D - renderer.renderMaxY) * renderer.renderMinX, + (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMinX)); + renderer.brightnessBottomLeft = renderer.mixAoBrightness( + j1, + k1, + l1, + i2, + renderer.renderMaxY * (1.0D - renderer.renderMaxX), + renderer.renderMaxY * renderer.renderMaxX, + (1.0D - renderer.renderMaxY) * renderer.renderMaxX, + (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMaxX)); + renderer.brightnessBottomRight = renderer.mixAoBrightness( + j1, + k1, + l1, + i2, + renderer.renderMinY * (1.0D - renderer.renderMaxX), + renderer.renderMinY * renderer.renderMaxX, + (1.0D - renderer.renderMinY) * renderer.renderMaxX, + (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMaxX)); + renderer.brightnessTopRight = renderer.mixAoBrightness( + j1, + k1, + l1, + i2, + renderer.renderMinY * (1.0D - renderer.renderMinX), + renderer.renderMinY * renderer.renderMinX, + (1.0D - renderer.renderMinY) * renderer.renderMinX, + (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMinX)); + + renderer.colorRedTopLeft = renderer.colorRedBottomLeft = renderer.colorRedBottomRight = renderer.colorRedTopRight = red + * 0.8F; + renderer.colorGreenTopLeft = renderer.colorGreenBottomLeft = renderer.colorGreenBottomRight = renderer.colorGreenTopRight = green + * 0.8F; + renderer.colorBlueTopLeft = renderer.colorBlueBottomLeft = renderer.colorBlueBottomRight = renderer.colorBlueTopRight = blue + * 0.8F; + + renderer.colorRedTopLeft *= f3; + renderer.colorGreenTopLeft *= f3; + renderer.colorBlueTopLeft *= f3; + renderer.colorRedBottomLeft *= f4; + renderer.colorGreenBottomLeft *= f4; + renderer.colorBlueBottomLeft *= f4; + renderer.colorRedBottomRight *= f5; + renderer.colorGreenBottomRight *= f5; + renderer.colorBlueBottomRight *= f5; + renderer.colorRedTopRight *= f6; + renderer.colorGreenTopRight *= f6; + renderer.colorBlueTopRight *= f6; + renderer.renderFaceZNeg(block, (double) x, (double) y, (double) z, iicon); + + flag = true; + } + + renderer.enableAO = false; + return flag; + } + + public static boolean RenderZPos(RenderBlocks renderer, Block block, int x, int y, int z, float red, float green, + float blue, IIcon iicon) { + renderer.enableAO = true; + boolean flag = false; + float f3 = 0.0F; + float f4 = 0.0F; + float f5 = 0.0F; + float f6 = 0.0F; + int l = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z); + Tessellator tessellator = Tessellator.instance; + tessellator.setBrightness(983055); + int i1; + float f7; + float f8; + float f9; + float f10; + float f11; + int j1; + int k1; + int l1; + int i2; + + if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x, y, z + 1, 3)) { + if (renderer.renderMaxZ >= 1.0D) { + ++z; + } + + renderer.aoLightValueScratchXZNP = renderer.blockAccess.getBlock(x - 1, y, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchXZPP = renderer.blockAccess.getBlock(x + 1, y, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchYZNP = renderer.blockAccess.getBlock(x, y - 1, z) + .getAmbientOcclusionLightValue(); + renderer.aoLightValueScratchYZPP = renderer.blockAccess.getBlock(x, y + 1, z) + .getAmbientOcclusionLightValue(); + renderer.aoBrightnessXZNP = block.getMixedBrightnessForBlock(renderer.blockAccess, x - 1, y, z); + renderer.aoBrightnessXZPP = block.getMixedBrightnessForBlock(renderer.blockAccess, x + 1, y, z); + renderer.aoBrightnessYZNP = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y - 1, z); + renderer.aoBrightnessYZPP = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y + 1, z); + + renderer.aoLightValueScratchXYZNNP = renderer.aoLightValueScratchXZNP; + renderer.aoBrightnessXYZNNP = renderer.aoBrightnessXZNP; + renderer.aoLightValueScratchXYZNPP = renderer.aoLightValueScratchXZNP; + renderer.aoBrightnessXYZNPP = renderer.aoBrightnessXZNP; + renderer.aoLightValueScratchXYZPNP = renderer.aoLightValueScratchXZPP; + renderer.aoBrightnessXYZPNP = renderer.aoBrightnessXZPP; + renderer.aoLightValueScratchXYZPPP = renderer.aoLightValueScratchXZPP; + renderer.aoBrightnessXYZPPP = renderer.aoBrightnessXZPP; + + if (renderer.renderMaxZ >= 1.0D) { + --z; + } + + i1 = l; + + if (renderer.renderMaxZ >= 1.0D || !renderer.blockAccess.getBlock(x, y, z + 1) + .isOpaqueCube()) { + i1 = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z + 1); + } + + f7 = renderer.blockAccess.getBlock(x, y, z + 1) + .getAmbientOcclusionLightValue(); + f8 = (renderer.aoLightValueScratchXZNP + renderer.aoLightValueScratchXYZNPP + + f7 + + renderer.aoLightValueScratchYZPP) / 4.0F; + f9 = (f7 + renderer.aoLightValueScratchYZPP + + renderer.aoLightValueScratchXZPP + + renderer.aoLightValueScratchXYZPPP) / 4.0F; + f10 = (renderer.aoLightValueScratchYZNP + f7 + + renderer.aoLightValueScratchXYZPNP + + renderer.aoLightValueScratchXZPP) / 4.0F; + f11 = (renderer.aoLightValueScratchXYZNNP + renderer.aoLightValueScratchXZNP + + renderer.aoLightValueScratchYZNP + + f7) / 4.0F; + f3 = (float) ((double) f8 * renderer.renderMaxY * (1.0D - renderer.renderMinX) + + (double) f9 * renderer.renderMaxY * renderer.renderMinX + + (double) f10 * (1.0D - renderer.renderMaxY) * renderer.renderMinX + + (double) f11 * (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMinX)); + f4 = (float) ((double) f8 * renderer.renderMinY * (1.0D - renderer.renderMinX) + + (double) f9 * renderer.renderMinY * renderer.renderMinX + + (double) f10 * (1.0D - renderer.renderMinY) * renderer.renderMinX + + (double) f11 * (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMinX)); + f5 = (float) ((double) f8 * renderer.renderMinY * (1.0D - renderer.renderMaxX) + + (double) f9 * renderer.renderMinY * renderer.renderMaxX + + (double) f10 * (1.0D - renderer.renderMinY) * renderer.renderMaxX + + (double) f11 * (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMaxX)); + f6 = (float) ((double) f8 * renderer.renderMaxY * (1.0D - renderer.renderMaxX) + + (double) f9 * renderer.renderMaxY * renderer.renderMaxX + + (double) f10 * (1.0D - renderer.renderMaxY) * renderer.renderMaxX + + (double) f11 * (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMaxX)); + j1 = renderer + .getAoBrightness(renderer.aoBrightnessXZNP, renderer.aoBrightnessXYZNPP, renderer.aoBrightnessYZPP, i1); + k1 = renderer + .getAoBrightness(renderer.aoBrightnessYZPP, renderer.aoBrightnessXZPP, renderer.aoBrightnessXYZPPP, i1); + l1 = renderer + .getAoBrightness(renderer.aoBrightnessYZNP, renderer.aoBrightnessXYZPNP, renderer.aoBrightnessXZPP, i1); + i2 = renderer + .getAoBrightness(renderer.aoBrightnessXYZNNP, renderer.aoBrightnessXZNP, renderer.aoBrightnessYZNP, i1); + renderer.brightnessTopLeft = renderer.mixAoBrightness( + j1, + i2, + l1, + k1, + renderer.renderMaxY * (1.0D - renderer.renderMinX), + (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMinX), + (1.0D - renderer.renderMaxY) * renderer.renderMinX, + renderer.renderMaxY * renderer.renderMinX); + renderer.brightnessBottomLeft = renderer.mixAoBrightness( + j1, + i2, + l1, + k1, + renderer.renderMinY * (1.0D - renderer.renderMinX), + (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMinX), + (1.0D - renderer.renderMinY) * renderer.renderMinX, + renderer.renderMinY * renderer.renderMinX); + renderer.brightnessBottomRight = renderer.mixAoBrightness( + j1, + i2, + l1, + k1, + renderer.renderMinY * (1.0D - renderer.renderMaxX), + (1.0D - renderer.renderMinY) * (1.0D - renderer.renderMaxX), + (1.0D - renderer.renderMinY) * renderer.renderMaxX, + renderer.renderMinY * renderer.renderMaxX); + renderer.brightnessTopRight = renderer.mixAoBrightness( + j1, + i2, + l1, + k1, + renderer.renderMaxY * (1.0D - renderer.renderMaxX), + (1.0D - renderer.renderMaxY) * (1.0D - renderer.renderMaxX), + (1.0D - renderer.renderMaxY) * renderer.renderMaxX, + renderer.renderMaxY * renderer.renderMaxX); + + renderer.colorRedTopLeft = renderer.colorRedBottomLeft = renderer.colorRedBottomRight = renderer.colorRedTopRight = red + * 0.8F; + renderer.colorGreenTopLeft = renderer.colorGreenBottomLeft = renderer.colorGreenBottomRight = renderer.colorGreenTopRight = green + * 0.8F; + renderer.colorBlueTopLeft = renderer.colorBlueBottomLeft = renderer.colorBlueBottomRight = renderer.colorBlueTopRight = blue + * 0.8F; + + renderer.colorRedTopLeft *= f3; + renderer.colorGreenTopLeft *= f3; + renderer.colorBlueTopLeft *= f3; + renderer.colorRedBottomLeft *= f4; + renderer.colorGreenBottomLeft *= f4; + renderer.colorBlueBottomLeft *= f4; + renderer.colorRedBottomRight *= f5; + renderer.colorGreenBottomRight *= f5; + renderer.colorBlueBottomRight *= f5; + renderer.colorRedTopRight *= f6; + renderer.colorGreenTopRight *= f6; + renderer.colorBlueTopRight *= f6; + renderer.renderFaceZPos(block, (double) x, (double) y, (double) z, iicon); + + flag = true; + } + + renderer.enableAO = false; + return flag; + } + + private static int rotationFromDirection(ForgeDirection dir) { + switch (dir) { + case SOUTH: + return 0; // 0° + case WEST: + return 1; // 90° + case NORTH: + return 2; // 180° + case EAST: + return 3; // 270° + default: + return 0; + } + } +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/render/IRotatableTile.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/render/IRotatableTile.java new file mode 100644 index 00000000..bd340d13 --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/render/IRotatableTile.java @@ -0,0 +1,87 @@ +package com.fouristhenumber.utilitiesinexcess.render; + +import net.minecraft.block.Block; +import net.minecraft.util.IIcon; +import net.minecraftforge.common.util.ForgeDirection; + +// remove when GTNHLib models are ready +public interface IRotatableTile { + + /** + * Sets the primary block-facing direction. + * This is a full 6-way direction using ForgeDirection: + * UP, DOWN, NORTH, SOUTH, EAST, WEST. + */ + void setFacing(ForgeDirection facing); + + /** + * @return The primary 6-way facing direction. + */ + ForgeDirection getFacing(); + + /** + * Sets the secondary yaw direction. + * This must be one of the 4 horizontal ForgeDirections: + * NORTH, SOUTH, EAST, WEST. + * + * NOTE: + * These are NOT encoded as 0–3 like vanilla block rotations. + * ForgeDirection uses: + * NORTH = 2 + * SOUTH = 3 + * WEST = 4 + * EAST = 5 + * + * This interface converts yaw → 0–3 manually using convertYawToRotation(). + */ + void setYaw(ForgeDirection yaw); + + /** + * Gets the 4-way yaw direction (N, S, E, W). + */ + ForgeDirection getYaw(); + + /** + * Returns the Block icon for the given side. + * Override if the tile needs per-side icons. + */ + default IIcon getIconForSide(Block block, ForgeDirection side, int meta) { + return (side == this.getFacing()) ? block.getIcon(3, meta) : block.getIcon(0, meta); + } + + /** + * Computes the texture rotation for the given side. + * + * Only UP and DOWN faces are rotated, and only when the block-facing + * is vertical (UP or DOWN). When on the ceiling the yaw is inverted. + * + * The returned rotation is a 0–3 value suitable for texture rotation: + * 0 = no rotation + * 1 = 90° clockwise + * 2 = 180° + * 3 = 270° + * + * This rotation value is NOT based on ForgeDirection.ordinal(). + */ + default ForgeDirection getRotationForSide(ForgeDirection side, int meta) { + if (side != ForgeDirection.UP && side != ForgeDirection.DOWN) { + return ForgeDirection.NORTH; + } + + ForgeDirection facing = this.getFacing(); + ForgeDirection yaw = this.getYaw(); + + if (facing == ForgeDirection.UP || facing == ForgeDirection.DOWN) { + + ForgeDirection effectiveYaw = yaw; + + if (facing == ForgeDirection.UP) { + effectiveYaw = yaw.getOpposite(); + } + + return effectiveYaw; + } + + return ForgeDirection.NORTH; + } +} diff --git a/src/main/java/com/fouristhenumber/utilitiesinexcess/utils/NbtHelper.java b/src/main/java/com/fouristhenumber/utilitiesinexcess/utils/NbtHelper.java new file mode 100644 index 00000000..c64d86d4 --- /dev/null +++ b/src/main/java/com/fouristhenumber/utilitiesinexcess/utils/NbtHelper.java @@ -0,0 +1,17 @@ +package com.fouristhenumber.utilitiesinexcess.utils; + +import net.minecraft.nbt.NBTTagCompound; + +public class NbtHelper { + + public static void writeEnumToNBT(NBTTagCompound tag, String key, Enum value) { + tag.setInteger(key, value.ordinal()); + } + + public static > T readEnumFromNBT(NBTTagCompound tag, String key, T[] values, T defaultValue) { + if (!tag.hasKey(key)) return defaultValue; + int ordinal = tag.getInteger(key); + return ordinal >= 0 && ordinal < values.length ? values[ordinal] : defaultValue; + } + +} diff --git a/src/main/resources/assets/utilitiesinexcess/lang/en_US.lang b/src/main/resources/assets/utilitiesinexcess/lang/en_US.lang index f4ebab9a..92e70c88 100644 --- a/src/main/resources/assets/utilitiesinexcess/lang/en_US.lang +++ b/src/main/resources/assets/utilitiesinexcess/lang/en_US.lang @@ -482,6 +482,17 @@ nei.infopage.uie.trading_post.1=This block allows you to trade with every villag key.categories.uie=Utilities In Excess key.uie.glove=Activate Glove +tile.filing_cabinet.basic.name=Filing Cabinet +tile.filing_cabinet.basic.desc=Stores variants of one type of item. +tile.filing_cabinet.advanced.name=Adv. Filing Cabinet +tile.filing_cabinet.advanced.desc=Stores unstackable items. + +tile.filing_cabinet.capacity_upgrade.success=Installed capacity upgrade. +tile.filing_cabinet.capacity_upgrade.maxed=Cabinet already upgraded to max! + +gui.cabinet.storage=Storage: %s / %s +gui.cabinet.slot=Slot: %s / %s + uie.colored_blocks.color.0=Colored %s (White) uie.colored_blocks.color.1=Colored %s (Orange) uie.colored_blocks.color.2=Colored %s (Magenta) diff --git a/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/advanced/front.png b/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/advanced/front.png new file mode 100644 index 00000000..8455844c Binary files /dev/null and b/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/advanced/front.png differ diff --git a/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/advanced/side.png b/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/advanced/side.png new file mode 100644 index 00000000..398935e7 Binary files /dev/null and b/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/advanced/side.png differ diff --git a/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/basic/front.png b/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/basic/front.png new file mode 100644 index 00000000..4d08b368 Binary files /dev/null and b/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/basic/front.png differ diff --git a/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/basic/side.png b/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/basic/side.png new file mode 100644 index 00000000..bc325342 Binary files /dev/null and b/src/main/resources/assets/utilitiesinexcess/textures/blocks/filing_cabinet/basic/side.png differ diff --git a/src/main/resources/assets/utilitiesinexcess/textures/gui/cabinet/progress_slot_used.png b/src/main/resources/assets/utilitiesinexcess/textures/gui/cabinet/progress_slot_used.png new file mode 100644 index 00000000..687ea8a1 Binary files /dev/null and b/src/main/resources/assets/utilitiesinexcess/textures/gui/cabinet/progress_slot_used.png differ diff --git a/src/main/resources/assets/utilitiesinexcess/textures/gui/cabinet/progress_storage.png b/src/main/resources/assets/utilitiesinexcess/textures/gui/cabinet/progress_storage.png new file mode 100644 index 00000000..b91b0b55 Binary files /dev/null and b/src/main/resources/assets/utilitiesinexcess/textures/gui/cabinet/progress_storage.png differ