From 98c93662df9fcf6076a8c9144d19f672608cbad7 Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Tue, 16 May 2023 15:51:07 +0200 Subject: [PATCH] implement void chest and interface --- .../net/anvilcraft/thaummach/AuraUtils.java | 29 +- .../net/anvilcraft/thaummach/ClientProxy.java | 10 +- .../net/anvilcraft/thaummach/CommonProxy.java | 2 + .../{SealData.java => RuneTileData.java} | 21 +- .../thaummach/blocks/BlockApparatusMetal.java | 115 ++-- .../thaummach/render/PortalRenderer.java | 4 +- .../metal/VoidInterfaceApparatusRenderer.java | 104 +++ .../render/tile/TileVoidChestRenderer.java | 627 ++++++++++++++++++ .../tile/TileVoidInterfaceRenderer.java | 84 +++ .../anvilcraft/thaummach/tiles/TileSeal.java | 22 +- .../thaummach/tiles/TileVoidChest.java | 2 +- .../thaummach/tiles/TileVoidInterface.java | 240 +++++++ .../thaummach/utils/HelperFacing.java | 90 --- .../thaummach/utils/HelperLocation.java | 253 ------- .../assets/thaummach/textures/misc/i_0.png | Bin 0 -> 1500 bytes .../assets/thaummach/textures/misc/i_1.png | Bin 0 -> 1442 bytes .../assets/thaummach/textures/misc/i_2.png | Bin 0 -> 1497 bytes .../assets/thaummach/textures/misc/i_3.png | Bin 0 -> 1410 bytes .../assets/thaummach/textures/misc/i_4.png | Bin 0 -> 1586 bytes .../assets/thaummach/textures/misc/i_5.png | Bin 0 -> 1648 bytes .../thaummach/textures/misc/particlefield.png | Bin 0 -> 7709 bytes .../assets/thaummach/textures/misc/tunnel.png | Bin 0 -> 10020 bytes 22 files changed, 1161 insertions(+), 442 deletions(-) rename src/main/java/net/anvilcraft/thaummach/{SealData.java => RuneTileData.java} (79%) create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/VoidInterfaceApparatusRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/tile/TileVoidChestRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/tile/TileVoidInterfaceRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TileVoidInterface.java delete mode 100644 src/main/java/net/anvilcraft/thaummach/utils/HelperFacing.java delete mode 100644 src/main/java/net/anvilcraft/thaummach/utils/HelperLocation.java create mode 100644 src/main/resources/assets/thaummach/textures/misc/i_0.png create mode 100644 src/main/resources/assets/thaummach/textures/misc/i_1.png create mode 100644 src/main/resources/assets/thaummach/textures/misc/i_2.png create mode 100644 src/main/resources/assets/thaummach/textures/misc/i_3.png create mode 100644 src/main/resources/assets/thaummach/textures/misc/i_4.png create mode 100644 src/main/resources/assets/thaummach/textures/misc/i_5.png create mode 100644 src/main/resources/assets/thaummach/textures/misc/particlefield.png create mode 100644 src/main/resources/assets/thaummach/textures/misc/tunnel.png diff --git a/src/main/java/net/anvilcraft/thaummach/AuraUtils.java b/src/main/java/net/anvilcraft/thaummach/AuraUtils.java index c139b0a..b246fab 100644 --- a/src/main/java/net/anvilcraft/thaummach/AuraUtils.java +++ b/src/main/java/net/anvilcraft/thaummach/AuraUtils.java @@ -27,16 +27,25 @@ public class AuraUtils { } } - /*for(xx = 0; xx < 100; ++xx) { - FXWisp ef = new FXWisp(w, (double)((float)x + 0.5F), (double)((float)y + - 0.5F), (double)((float)z + 0.5F), (double)((float)x + 0.5F + - (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), (double)((float)y + 0.5F - + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), (double)((float)z + - 0.5F + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), 1.0F, 5); - ef.setGravity(0.02F); - ef.shrink = true; - ModLoader.getMinecraftInstance().effectRenderer.addEffect(ef); - }*/ + //for (xx = 0; xx < 100; ++xx) { + // FXWisp ef = new FXWisp( + // w, + // (double) ((float) x + 0.5F), + // (double) ((float) y + 0.5F), + // (double) ((float) z + 0.5F), + // (double + // ) ((float) x + 0.5F + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), + // (double + // ) ((float) y + 0.5F + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), + // (double + // ) ((float) z + 0.5F + (w.rand.nextFloat() - w.rand.nextFloat()) * 2.0F), + // 1.0F, + // 5 + // ); + // ef.setGravity(0.02F); + // ef.shrink = true; + // ModLoader.getMinecraftInstance().effectRenderer.addEffect(ef); + //} } public static void spillTaint(World world, int x, int y, int z) { diff --git a/src/main/java/net/anvilcraft/thaummach/ClientProxy.java b/src/main/java/net/anvilcraft/thaummach/ClientProxy.java index b242f82..328eb45 100644 --- a/src/main/java/net/anvilcraft/thaummach/ClientProxy.java +++ b/src/main/java/net/anvilcraft/thaummach/ClientProxy.java @@ -11,6 +11,8 @@ import net.anvilcraft.thaummach.render.entity.EntitySingularityRenderer; import net.anvilcraft.thaummach.render.tile.TileBoreRenderer; import net.anvilcraft.thaummach.render.tile.TileConduitPumpRenderer; import net.anvilcraft.thaummach.render.tile.TileCrystallizerRenderer; +import net.anvilcraft.thaummach.render.tile.TileVoidChestRenderer; +import net.anvilcraft.thaummach.render.tile.TileVoidInterfaceRenderer; import net.anvilcraft.thaummach.tiles.TileBore; import net.anvilcraft.thaummach.tiles.TileConduit; import net.anvilcraft.thaummach.tiles.TileConduitPump; @@ -23,6 +25,7 @@ import net.anvilcraft.thaummach.tiles.TileFilter; import net.anvilcraft.thaummach.tiles.TilePurifier; import net.anvilcraft.thaummach.tiles.TileSeal; import net.anvilcraft.thaummach.tiles.TileVoidChest; +import net.anvilcraft.thaummach.tiles.TileVoidInterface; public class ClientProxy extends CommonProxy { @Override @@ -53,7 +56,6 @@ public class ClientProxy extends CommonProxy { GameRegistry.registerTileEntity(TileCrucible.class, "crucible"); GameRegistry.registerTileEntity(TileFilter.class, "filter"); GameRegistry.registerTileEntity(TilePurifier.class, "purifier"); - GameRegistry.registerTileEntity(TileVoidChest.class, "voidChest"); ClientRegistry.registerTileEntity(TileBore.class, "bore", new TileBoreRenderer()); ClientRegistry.registerTileEntity( @@ -63,5 +65,11 @@ public class ClientProxy extends CommonProxy { TileCrystallizer.class, "crystallizer", new TileCrystallizerRenderer() ); ClientRegistry.registerTileEntity(TileSeal.class, "seal", new TileSealRenderer()); + ClientRegistry.registerTileEntity( + TileVoidChest.class, "voidChest", new TileVoidChestRenderer() + ); + ClientRegistry.registerTileEntity( + TileVoidInterface.class, "voidInterface", new TileVoidInterfaceRenderer() + ); } } diff --git a/src/main/java/net/anvilcraft/thaummach/CommonProxy.java b/src/main/java/net/anvilcraft/thaummach/CommonProxy.java index 6641ed5..5819768 100644 --- a/src/main/java/net/anvilcraft/thaummach/CommonProxy.java +++ b/src/main/java/net/anvilcraft/thaummach/CommonProxy.java @@ -13,6 +13,7 @@ import net.anvilcraft.thaummach.tiles.TileFilter; import net.anvilcraft.thaummach.tiles.TilePurifier; import net.anvilcraft.thaummach.tiles.TileSeal; import net.anvilcraft.thaummach.tiles.TileVoidChest; +import net.anvilcraft.thaummach.tiles.TileVoidInterface; public class CommonProxy { public void preInit() {} @@ -34,5 +35,6 @@ public class CommonProxy { GameRegistry.registerTileEntity(TilePurifier.class, "purifier"); GameRegistry.registerTileEntity(TileSeal.class, "seal"); GameRegistry.registerTileEntity(TileVoidChest.class, "voidChest"); + GameRegistry.registerTileEntity(TileVoidInterface.class, "voidInterface"); } } diff --git a/src/main/java/net/anvilcraft/thaummach/SealData.java b/src/main/java/net/anvilcraft/thaummach/RuneTileData.java similarity index 79% rename from src/main/java/net/anvilcraft/thaummach/SealData.java rename to src/main/java/net/anvilcraft/thaummach/RuneTileData.java index ed15820..9d9b138 100644 --- a/src/main/java/net/anvilcraft/thaummach/SealData.java +++ b/src/main/java/net/anvilcraft/thaummach/RuneTileData.java @@ -2,8 +2,9 @@ package net.anvilcraft.thaummach; import net.anvilcraft.thaummach.tiles.TileSeal; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; -public class SealData { +public class RuneTileData { public int dim; public int x; public int y; @@ -11,9 +12,17 @@ public class SealData { public short orientation; public byte rune; - public SealData() {} + public RuneTileData() {} - public SealData(TileSeal seal) { + public RuneTileData(TileEntity te, byte rune) { + this.dim = te.getWorldObj().provider.dimensionId; + this.x = te.xCoord; + this.y = te.yCoord; + this.z = te.zCoord; + this.rune = rune; + } + + public RuneTileData(TileSeal seal) { this.dim = seal.getWorldObj().provider.dimensionId; this.x = seal.xCoord; @@ -36,8 +45,8 @@ public class SealData { return nbt; } - public static SealData readFromNbt(NBTTagCompound nbt) { - SealData self = new SealData(); + public static RuneTileData readFromNbt(NBTTagCompound nbt) { + RuneTileData self = new RuneTileData(); self.dim = nbt.getInteger("dim"); self.x = nbt.getInteger("x"); @@ -70,7 +79,7 @@ public class SealData { return false; if (getClass() != obj.getClass()) return false; - SealData other = (SealData) obj; + RuneTileData other = (RuneTileData) obj; if (dim != other.dim) return false; if (x != other.x) diff --git a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java index 0866f54..15ad1a2 100644 --- a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java +++ b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java @@ -13,12 +13,14 @@ import net.anvilcraft.thaummach.render.apparatus.apparati.metal.BoreApparatusRen import net.anvilcraft.thaummach.render.apparatus.apparati.metal.CrucibleApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.apparati.metal.CrystallizerApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.apparati.metal.VoidChestApparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.metal.VoidInterfaceApparatusRenderer; import net.anvilcraft.thaummach.tiles.TileArcaneFurnace; import net.anvilcraft.thaummach.tiles.TileBore; import net.anvilcraft.thaummach.tiles.TileConduitTank; import net.anvilcraft.thaummach.tiles.TileCrucible; import net.anvilcraft.thaummach.tiles.TileCrystallizer; import net.anvilcraft.thaummach.tiles.TileVoidChest; +import net.anvilcraft.thaummach.tiles.TileVoidInterface; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; @@ -28,6 +30,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; +import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -38,6 +41,8 @@ import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; +import thaumcraft.client.fx.WRVector3; +import thaumcraft.client.fx.bolt.FXLightningBolt; import thaumcraft.common.entities.monster.EntityThaumicSlime; import thaumcraft.common.tiles.TileBellows; @@ -158,6 +163,9 @@ public class BlockApparatusMetal extends BlockApparatus { case VOID_CHEST: return VoidChestApparatusRenderer.INSTANCE; + + case VOID_INTERFACE: + return VoidInterfaceApparatusRenderer.INSTANCE; default: return null; } @@ -181,7 +189,7 @@ public class BlockApparatusMetal extends BlockApparatus { } else if (md == MetaVals.VOID_CHEST) { return new TileVoidChest(); } else if (md == MetaVals.VOID_INTERFACE) { - //return new TileVoidInterface(); + return new TileVoidInterface(); } else if (md == MetaVals.TANK) { return new TileConduitTank(); } else if (md == MetaVals.SOUL_BRAZIER) { @@ -247,7 +255,7 @@ public class BlockApparatusMetal extends BlockApparatus { } else if (meta == MetaVals.VOID_CHEST) { return i == 0 ? this.iconVoidChestBottom : i == 1 ? this.iconVoidChestTop - : this.iconVoidChestSide; + : this.iconVoidChestSideTransparent; } else if (meta == MetaVals.VOID_INTERFACE) { return i <= 1 ? this.iconVoidInterfaceBottom : this.iconVoidInterfaceSide; } else if (meta == MetaVals.SOUL_BRAZIER) { @@ -317,15 +325,16 @@ public class BlockApparatusMetal extends BlockApparatus { } else if (meta == MetaVals.VOID_CHEST) { return side == 0 ? this.iconVoidChestBottom : side == 1 ? this.iconVoidChestTop - : this.iconVoidChestSide; + : this.iconVoidChestSideTransparent; + } else if (meta == MetaVals.VOID_INTERFACE) { + if (side == 0) { + return this.iconVoidChestBottom; + } else { + return side == 1 ? this.iconVoidInterfaceBottom + : this.iconVoidInterfaceSide; + } } - //else if (meta == 8) { - // if (side == 0) { - // return 104; - // } else { - // return side == 1 ? 97 : 255; - // } - //} else if (meta == 10) { + // else if (meta == 10) { // return side <= 1 ? 78 : 79; //} else { // return super.getBlockTexture(iblockaccess, i, j, k, side); @@ -672,27 +681,25 @@ public class BlockApparatusMetal extends BlockApparatus { } if (meta == MetaVals.VOID_INTERFACE) { - // TODO: void interface - //TileVoidInterface tvi = (TileVoidInterface) w.getTileEntity(i, j, k); - //if (tvi != null && tvi.linked && w.rand.nextInt(10) == 0) { - // LightningBolt bolt = new LightningBolt( - // w, - // new WRVector3((double) i + 0.5, (double) j + 0.75, (double) k + - // 0.5), new WRVector3( - // (double) i + 0.5 + (double) w.rand.nextFloat() - // - (double) w.rand.nextFloat(), - // (double) (j + 2), - // (double) k + 0.5 + (double) w.rand.nextFloat() - // - (double) w.rand.nextFloat() - // ), - // w.rand.nextLong() - // ); - // bolt.setMultiplier(4.0F); - // bolt.defaultFractal(); - // bolt.setType(5); - // bolt.setNonLethal(); - // bolt.finalizeBolt(); - //} + TileVoidInterface tvi = (TileVoidInterface) w.getTileEntity(i, j, k); + if (tvi != null && tvi.linked && w.rand.nextInt(10) == 0) { + FXLightningBolt bolt = new FXLightningBolt( + w, + new WRVector3((double) i + 0.5, (double) j + 0.75, (double) k + 0.5), + new WRVector3( + (double) i + 0.5 + (double) w.rand.nextFloat() + - (double) w.rand.nextFloat(), + (double) (j + 2), + (double) k + 0.5 + (double) w.rand.nextFloat() + - (double) w.rand.nextFloat() + ), + w.rand.nextLong() + ); + bolt.setMultiplier(4.0F); + bolt.defaultFractal(); + bolt.setType(5); + bolt.finalizeBolt(); + } } } @@ -704,20 +711,10 @@ public class BlockApparatusMetal extends BlockApparatus { } if (meta == MetaVals.VOID_INTERFACE) { - // TODO: void interface - //TileVoidInterface ts = (TileVoidInterface) world.getTileEntity(i, j, - //k); if (ts != null) { - // ts.invalidateLinks(); - // SISpecialTile pd = new SISpecialTile( - // i, - // j, - // k, - // ts.network, - // (byte) ModLoader.getMinecraftInstance().thePlayer.dimension, - // (byte) 1 - // ); - // mod_ThaumCraft.DeleteSpecialTileFromList(pd); - //} + TileVoidInterface ts = (TileVoidInterface) world.getTileEntity(i, j, k); + if (ts != null) { + ts.invalidateLinks(); + } } else { super.breakBlock(world, i, j, k, block, meta_); @@ -737,29 +734,11 @@ public class BlockApparatusMetal extends BlockApparatus { ) { MetaVals md = MetaVals.get(world.getBlockMetadata(i, j, k)); if (md == MetaVals.VOID_INTERFACE) { - // TODO: void interface - //if (world.getBlock(i, j - 1, k) == this - // && world.getBlockMetadata(i, j - 1, k) == 8) { - // TileVoidInterface tvi - // = (TileVoidInterface) world.getTileEntity(i, j, k); - // if (tvi != null) { - // tvi.network = (byte) world.rand.nextInt(6); - // SISpecialTile pd = new SISpecialTile( - // i, - // j, - // k, - // tvi.network, - // (byte) ModLoader.getMinecraftInstance().thePlayer.dimension, - // (byte) 1 - // ); - // mod_ThaumCraft.AddSpecialTileToList(pd); - // tvi.invalidateLinks(); - // tvi.establishLinks(); - // } - //} else { - // this.dropBlockAsItem(world, i, j, k, md, 0); - // world.setBlock(i, j, k, 0); - //} + if (world.getBlock(i, j - 1, k) != this + || world.getBlockMetadata(i, j - 1, k) != MetaVals.VOID_CHEST.ordinal()) { + this.dropBlockAsItem(world, i, j, k, md.ordinal(), 0); + world.setBlock(i, j, k, Blocks.air); + } } else if (md == MetaVals.BORE) { TileBore tb = (TileBore) world.getTileEntity(i, j, k); if (MathHelper.abs((float) entityliving.posX - (float) i) < 1.0F diff --git a/src/main/java/net/anvilcraft/thaummach/render/PortalRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/PortalRenderer.java index 8bde86a..7e7c076 100644 --- a/src/main/java/net/anvilcraft/thaummach/render/PortalRenderer.java +++ b/src/main/java/net/anvilcraft/thaummach/render/PortalRenderer.java @@ -4,7 +4,7 @@ import java.nio.ByteBuffer; import java.util.HashSet; import java.util.Set; -import net.anvilcraft.thaummach.SealData; +import net.anvilcraft.thaummach.RuneTileData; import net.anvilcraft.thaummach.tiles.TileSeal; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; @@ -55,7 +55,7 @@ public class PortalRenderer { if (this.seal.otherSeal == null) return; - SealData target = this.seal.otherSeal; + RuneTileData target = this.seal.otherSeal; Minecraft mc = Minecraft.getMinecraft(); GL11.glPushMatrix(); GL11.glLoadIdentity(); diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/VoidInterfaceApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/VoidInterfaceApparatusRenderer.java new file mode 100644 index 0000000..dd41f04 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/VoidInterfaceApparatusRenderer.java @@ -0,0 +1,104 @@ +package net.anvilcraft.thaummach.render.apparatus.apparati.metal; + +import net.anvilcraft.thaummach.blocks.BlockApparatusMetal; +import net.anvilcraft.thaummach.render.apparatus.ApparatusRenderingHelper; +import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +public class VoidInterfaceApparatusRenderer implements IApparatusRenderer { + public static VoidInterfaceApparatusRenderer INSTANCE + = new VoidInterfaceApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int x, + int y, + int z, + Block block_, + int meta, + boolean inv + ) { + float t1x = 0.0625F; + float t3x = 0.1875F; + float t4x = 0.25F; + BlockApparatusMetal block = (BlockApparatusMetal) block_; + if (block.getRenderBlockPass() == 0 || inv) { + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, t3x, 1.0F); + if (inv) { + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconVoidInterfaceBottom, + block.iconVoidInterfaceBottom, + block.iconVoidInterfaceSide, + block.iconVoidInterfaceSide, + block.iconVoidInterfaceSide, + block.iconVoidInterfaceSide, + true + ); + } else { + rb.renderStandardBlock(block, x, y, z); + } + + rb.setRenderBounds(0.0F, 0.5F - t4x, 0.0F, 1.0F, 0.5F - t1x, 1.0F); + if (inv) { + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconVoidInterfaceBottom, + block.iconVoidInterfaceBottom, + block.iconVoidInterfaceSide, + block.iconVoidInterfaceSide, + block.iconVoidInterfaceSide, + block.iconVoidInterfaceSide, + true + ); + } else { + rb.renderStandardBlock(block, x, y, z); + } + + rb.setRenderBounds(t4x, 0.5F - t1x, t4x, 1.0F - t4x, 0.5F + t4x, 1.0F - t4x); + if (inv) { + ApparatusRenderingHelper.drawFaces( + rb, + block, + block.iconVoidInterfaceBottom, + block.iconVoidInterfaceBottom, + block.iconVoidInterfaceSide, + block.iconVoidInterfaceSide, + block.iconVoidInterfaceSide, + block.iconVoidInterfaceSide, + true + ); + } else { + rb.renderStandardBlock(block, x, y, z); + } + } + + rb.setRenderBounds(t1x, t3x, t1x, 1.0F - t1x, 0.5F - t4x, 1.0F - t1x); + if (!inv) { + rb.renderFaceXNeg( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + rb.renderFaceXPos( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + rb.renderFaceZNeg( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + rb.renderFaceZPos( + block, (double) x, (double) y, (double) z, block.iconTcubeanim + ); + } else { + rb.overrideBlockTexture = block.iconTcubeanim; + ApparatusRenderingHelper.drawFaces(rb, block, block.iconTcubeanim, true); + } + + rb.overrideBlockTexture = null; + rb.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/tile/TileVoidChestRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/tile/TileVoidChestRenderer.java new file mode 100644 index 0000000..d8e93dd --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/tile/TileVoidChestRenderer.java @@ -0,0 +1,627 @@ +package net.anvilcraft.thaummach.render.tile; + +import java.nio.FloatBuffer; +import java.util.Random; + +import cpw.mods.fml.client.FMLClientHandler; +import net.minecraft.client.entity.EntityClientPlayerMP; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class TileVoidChestRenderer extends TileEntitySpecialRenderer { + FloatBuffer fBuffer = GLAllocation.createDirectFloatBuffer(16); + + private FloatBuffer calcFloatBuffer(float f, float f1, float f2, float f3) { + this.fBuffer.clear(); + this.fBuffer.put(f).put(f1).put(f2).put(f3); + this.fBuffer.flip(); + return this.fBuffer; + } + + // _____ ___ ____ ___ __ _______ _____ + // |_ _/ _ \| _ \ / _ \ _ \ \ / /_ _| ___| + // | || | | | | | | | | (_) \ \ /\ / / | | | |_ + // | || |_| | |_| | |_| |_ \ V V / | | | _| + // |_| \___/|____/ \___/(_) \_/\_/ |_| |_| + + public void drawPlaneYNeg(double x, double y, double z, float f) { + EntityClientPlayerMP player = FMLClientHandler.instance().getClientPlayerEntity(); + float px = (float) player.posX; + float py = (float) player.posY; + float pz = (float) player.posZ; + GL11.glDisable(2896); + Random random = new Random(31100L); + float offset = 0.01F; + for (int i = 0; i < 16; ++i) { + GL11.glPushMatrix(); + float f5 = (float) (16 - i); + float f6 = 0.0625F; + float f7 = 1.0F / (f5 + 1.0F); + if (i == 0) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/tunnel.png") + ); + f7 = 0.1F; + f5 = 65.0F; + f6 = 0.125F; + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + } + + if (i == 1) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/particlefield.png") + ); + GL11.glEnable(3042); + GL11.glBlendFunc(1, 1); + f6 = 0.5F; + } + + float f8 = (float) (y + (double) offset); + float f9 = f8 - ActiveRenderInfo.objectY; + float f10 = f8 + f5 - ActiveRenderInfo.objectY; + float f11 = f9 / f10; + f11 += (float) (y + (double) offset); + GL11.glTranslatef(px, f11, pz); + GL11.glTexGeni(8192, 9472, 9217); + GL11.glTexGeni(8193, 9472, 9217); + GL11.glTexGeni(8194, 9472, 9217); + GL11.glTexGeni(8195, 9472, 9216); + GL11.glTexGen(8192, 9473, this.calcFloatBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + GL11.glTexGen(8193, 9473, this.calcFloatBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + GL11.glTexGen(8194, 9473, this.calcFloatBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GL11.glTexGen(8195, 9474, this.calcFloatBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GL11.glEnable(3168); + GL11.glEnable(3169); + GL11.glEnable(3170); + GL11.glEnable(3171); + GL11.glPopMatrix(); + GL11.glMatrixMode(5890); + GL11.glPushMatrix(); + GL11.glLoadIdentity(); + GL11.glTranslatef( + 0.0F, (float) (System.currentTimeMillis() % 700000L) / 250000.0F, 0.0F + ); + GL11.glScalef(f6, f6, f6); + GL11.glTranslatef(0.5F, 0.5F, 0.0F); + GL11.glRotatef((float) (i * i * 4321 + i * 9) * 2.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(-0.5F, -0.5F, 0.0F); + GL11.glTranslatef(-px, -pz, -py); + GL11.glTranslatef( + ActiveRenderInfo.objectX * f5 / f9, + ActiveRenderInfo.objectZ * f5 / f9, + -py + ); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + f11 = random.nextFloat() * 0.5F + 0.1F; + float f12 = random.nextFloat() * 0.5F + 0.4F; + float f13 = random.nextFloat() * 0.5F + 0.5F; + if (i == 0) { + f13 = 1.0F; + f12 = 1.0F; + f11 = 1.0F; + } + + tessellator.setBrightness(180); + tessellator.setColorRGBA_F(f11 * f7, f12 * f7, f13 * f7, 1.0F); + tessellator.addVertex(x, y + (double) offset, z + 1.0); + tessellator.addVertex(x, y + (double) offset, z); + tessellator.addVertex(x + 1.0, y + (double) offset, z); + tessellator.addVertex(x + 1.0, y + (double) offset, z + 1.0); + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glMatrixMode(5888); + } + + GL11.glDisable(3042); + GL11.glDisable(3168); + GL11.glDisable(3169); + GL11.glDisable(3170); + GL11.glDisable(3171); + GL11.glEnable(2896); + } + + public void drawPlaneYPos(double x, double y, double z, float f) { + EntityClientPlayerMP player = FMLClientHandler.instance().getClientPlayerEntity(); + float f1 = (float) player.posX; + float f2 = (float) player.posY; + float f3 = (float) player.posZ; + GL11.glDisable(2896); + Random random = new Random(31100L); + float offset = 0.99F; + for (int i = 0; i < 16; ++i) { + GL11.glPushMatrix(); + float f5 = (float) (16 - i); + float f6 = 0.0625F; + float f7 = 1.0F / (f5 + 1.0F); + if (i == 0) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/tunnel.png") + ); + f7 = 0.1F; + f5 = 65.0F; + f6 = 0.125F; + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + } + + if (i == 1) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/particlefield.png") + ); + GL11.glEnable(3042); + GL11.glBlendFunc(1, 1); + f6 = 0.5F; + } + + float f8 = (float) (-(y + (double) offset)); + float f9 = f8 + ActiveRenderInfo.objectY; + float f10 = f8 + f5 + ActiveRenderInfo.objectY; + float f11 = f9 / f10; + f11 += (float) (y + (double) offset); + GL11.glTranslatef(f1, f11, f3); + GL11.glTexGeni(8192, 9472, 9217); + GL11.glTexGeni(8193, 9472, 9217); + GL11.glTexGeni(8194, 9472, 9217); + GL11.glTexGeni(8195, 9472, 9216); + GL11.glTexGen(8192, 9473, this.calcFloatBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + GL11.glTexGen(8193, 9473, this.calcFloatBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + GL11.glTexGen(8194, 9473, this.calcFloatBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GL11.glTexGen(8195, 9474, this.calcFloatBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GL11.glEnable(3168); + GL11.glEnable(3169); + GL11.glEnable(3170); + GL11.glEnable(3171); + GL11.glPopMatrix(); + GL11.glMatrixMode(5890); + GL11.glPushMatrix(); + GL11.glLoadIdentity(); + GL11.glTranslatef( + 0.0F, (float) (System.currentTimeMillis() % 700000L) / 250000.0F, 0.0F + ); + GL11.glScalef(f6, f6, f6); + GL11.glTranslatef(0.5F, 0.5F, 0.0F); + GL11.glRotatef((float) (i * i * 4321 + i * 9) * 2.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(-0.5F, -0.5F, 0.0F); + GL11.glTranslatef(-f1, -f3, -f2); + GL11.glTranslatef( + ActiveRenderInfo.objectX * f5 / f9, + ActiveRenderInfo.objectZ * f5 / f9, + -f2 + ); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + f11 = random.nextFloat() * 0.5F + 0.1F; + float f12 = random.nextFloat() * 0.5F + 0.4F; + float f13 = random.nextFloat() * 0.5F + 0.5F; + if (i == 0) { + f13 = 1.0F; + f12 = 1.0F; + f11 = 1.0F; + } + + tessellator.setBrightness(180); + tessellator.setColorRGBA_F(f11 * f7, f12 * f7, f13 * f7, 1.0F); + tessellator.addVertex(x, y + (double) offset, z); + tessellator.addVertex(x, y + (double) offset, z + 1.0); + tessellator.addVertex(x + 1.0, y + (double) offset, z + 1.0); + tessellator.addVertex(x + 1.0, y + (double) offset, z); + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glMatrixMode(5888); + } + + GL11.glDisable(3042); + GL11.glDisable(3168); + GL11.glDisable(3169); + GL11.glDisable(3170); + GL11.glDisable(3171); + GL11.glEnable(2896); + } + + public void drawPlaneZPos(double x, double y, double z, float f) { + EntityClientPlayerMP player = FMLClientHandler.instance().getClientPlayerEntity(); + float px = (float) player.posX; + float py = (float) player.posY; + float pz = (float) player.posZ; + GL11.glDisable(2896); + Random random = new Random(31100L); + float offset = 0.99F; + for (int i = 0; i < 16; ++i) { + GL11.glPushMatrix(); + float f5 = (float) (16 - i); + float f6 = 0.0625F; + float f7 = 1.0F / (f5 + 1.0F); + if (i == 0) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/tunnel.png") + ); + f7 = 0.1F; + f5 = 65.0F; + f6 = 0.125F; + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + } + + if (i == 1) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/particlefield.png") + ); + GL11.glEnable(3042); + GL11.glBlendFunc(1, 1); + f6 = 0.5F; + } + + float f8 = (float) (-(z + (double) offset)); + float f9 = f8 + ActiveRenderInfo.objectZ; + float f10 = f8 + f5 + ActiveRenderInfo.objectZ; + float f11 = f9 / f10; + f11 += (float) (z + (double) offset); + GL11.glTranslatef(px, py, f11); + GL11.glTexGeni(8192, 9472, 9217); + GL11.glTexGeni(8193, 9472, 9217); + GL11.glTexGeni(8194, 9472, 9217); + GL11.glTexGeni(8195, 9472, 9216); + GL11.glTexGen(8192, 9473, this.calcFloatBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + GL11.glTexGen(8193, 9473, this.calcFloatBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GL11.glTexGen(8194, 9473, this.calcFloatBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GL11.glTexGen(8195, 9474, this.calcFloatBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + GL11.glEnable(3168); + GL11.glEnable(3169); + GL11.glEnable(3170); + GL11.glEnable(3171); + GL11.glPopMatrix(); + GL11.glMatrixMode(5890); + GL11.glPushMatrix(); + GL11.glLoadIdentity(); + GL11.glTranslatef( + 0.0F, (float) (System.currentTimeMillis() % 700000L) / 250000.0F, 0.0F + ); + GL11.glScalef(f6, f6, f6); + GL11.glTranslatef(0.5F, 0.5F, 0.0F); + GL11.glRotatef((float) (i * i * 4321 + i * 9) * 2.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(-0.5F, -0.5F, 0.0F); + GL11.glTranslatef(-px, -py, -pz); + GL11.glTranslatef( + ActiveRenderInfo.objectX * f5 / f9, + ActiveRenderInfo.objectY * f5 / f9, + -pz + ); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + f11 = random.nextFloat() * 0.5F + 0.1F; + float f12 = random.nextFloat() * 0.5F + 0.4F; + float f13 = random.nextFloat() * 0.5F + 0.5F; + if (i == 0) { + f13 = 1.0F; + f12 = 1.0F; + f11 = 1.0F; + } + + tessellator.setBrightness(180); + tessellator.setColorRGBA_F(f11 * f7, f12 * f7, f13 * f7, 1.0F); + tessellator.addVertex(x, y + 1.0, z + (double) offset); + tessellator.addVertex(x, y, z + (double) offset); + tessellator.addVertex(x + 1.0, y, z + (double) offset); + tessellator.addVertex(x + 1.0, y + 1.0, z + (double) offset); + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glMatrixMode(5888); + } + + GL11.glDisable(3042); + GL11.glDisable(3168); + GL11.glDisable(3169); + GL11.glDisable(3170); + GL11.glDisable(3171); + GL11.glEnable(2896); + } + + public void drawPlaneZNeg(double x, double y, double z, float f) { + EntityClientPlayerMP player = FMLClientHandler.instance().getClientPlayerEntity(); + float px = (float) player.posX; + float py = (float) player.posY; + float pz = (float) player.posZ; + GL11.glDisable(2896); + Random random = new Random(31100L); + float offset = 0.01F; + for (int i = 0; i < 16; ++i) { + GL11.glPushMatrix(); + float f5 = (float) (16 - i); + float f6 = 0.0625F; + float f7 = 1.0F / (f5 + 1.0F); + if (i == 0) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/tunnel.png") + ); + f7 = 0.1F; + f5 = 65.0F; + f6 = 0.125F; + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + } + + if (i == 1) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/particlefield.png") + ); + GL11.glEnable(3042); + GL11.glBlendFunc(1, 1); + f6 = 0.5F; + } + + float f8 = (float) (z + (double) offset); + float f9 = f8 - ActiveRenderInfo.objectZ; + float f10 = f8 + f5 - ActiveRenderInfo.objectZ; + float f11 = f9 / f10; + f11 += (float) (z + (double) offset); + GL11.glTranslatef(px, py, f11); + GL11.glTexGeni(8192, 9472, 9217); + GL11.glTexGeni(8193, 9472, 9217); + GL11.glTexGeni(8194, 9472, 9217); + GL11.glTexGeni(8195, 9472, 9216); + GL11.glTexGen(8192, 9473, this.calcFloatBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + GL11.glTexGen(8193, 9473, this.calcFloatBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GL11.glTexGen(8194, 9473, this.calcFloatBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GL11.glTexGen(8195, 9474, this.calcFloatBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + GL11.glEnable(3168); + GL11.glEnable(3169); + GL11.glEnable(3170); + GL11.glEnable(3171); + GL11.glPopMatrix(); + GL11.glMatrixMode(5890); + GL11.glPushMatrix(); + GL11.glLoadIdentity(); + GL11.glTranslatef( + 0.0F, (float) (System.currentTimeMillis() % 700000L) / 250000.0F, 0.0F + ); + GL11.glScalef(f6, f6, f6); + GL11.glTranslatef(0.5F, 0.5F, 0.0F); + GL11.glRotatef((float) (i * i * 4321 + i * 9) * 2.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(-0.5F, -0.5F, 0.0F); + GL11.glTranslatef(-px, -py, -pz); + GL11.glTranslatef( + ActiveRenderInfo.objectX * f5 / f9, + ActiveRenderInfo.objectY * f5 / f9, + -pz + ); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + f11 = random.nextFloat() * 0.5F + 0.1F; + float f12 = random.nextFloat() * 0.5F + 0.4F; + float f13 = random.nextFloat() * 0.5F + 0.5F; + if (i == 0) { + f13 = 1.0F; + f12 = 1.0F; + f11 = 1.0F; + } + + tessellator.setBrightness(180); + tessellator.setColorRGBA_F(f11 * f7, f12 * f7, f13 * f7, 1.0F); + tessellator.addVertex(x, y, z + (double) offset); + tessellator.addVertex(x, y + 1.0, z + (double) offset); + tessellator.addVertex(x + 1.0, y + 1.0, z + (double) offset); + tessellator.addVertex(x + 1.0, y, z + (double) offset); + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glMatrixMode(5888); + } + + GL11.glDisable(3042); + GL11.glDisable(3168); + GL11.glDisable(3169); + GL11.glDisable(3170); + GL11.glDisable(3171); + GL11.glEnable(2896); + } + + public void drawPlaneXPos(double x, double y, double z, float f) { + EntityClientPlayerMP player = FMLClientHandler.instance().getClientPlayerEntity(); + float px = (float) player.posX; + float py = (float) player.posY; + float pz = (float) player.posZ; + GL11.glDisable(2896); + Random random = new Random(31100L); + float offset = 0.99F; + for (int i = 0; i < 16; ++i) { + GL11.glPushMatrix(); + float f5 = (float) (16 - i); + float f6 = 0.0625F; + float f7 = 1.0F / (f5 + 1.0F); + if (i == 0) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/tunnel.png") + ); + f7 = 0.1F; + f5 = 65.0F; + f6 = 0.125F; + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + } + + if (i == 1) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/particlefield.png") + ); + GL11.glEnable(3042); + GL11.glBlendFunc(1, 1); + f6 = 0.5F; + } + + float f8 = (float) (-(x + (double) offset)); + float f9 = f8 + ActiveRenderInfo.objectX; + float f10 = f8 + f5 + ActiveRenderInfo.objectX; + float f11 = f9 / f10; + f11 += (float) (x + (double) offset); + GL11.glTranslatef(f11, py, pz); + GL11.glTexGeni(8192, 9472, 9217); + GL11.glTexGeni(8193, 9472, 9217); + GL11.glTexGeni(8194, 9472, 9217); + GL11.glTexGeni(8195, 9472, 9216); + GL11.glTexGen(8193, 9473, this.calcFloatBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GL11.glTexGen(8192, 9473, this.calcFloatBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + GL11.glTexGen(8194, 9473, this.calcFloatBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GL11.glTexGen(8195, 9474, this.calcFloatBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + GL11.glEnable(3168); + GL11.glEnable(3169); + GL11.glEnable(3170); + GL11.glEnable(3171); + GL11.glPopMatrix(); + GL11.glMatrixMode(5890); + GL11.glPushMatrix(); + GL11.glLoadIdentity(); + GL11.glTranslatef( + 0.0F, (float) (System.currentTimeMillis() % 700000L) / 250000.0F, 0.0F + ); + GL11.glScalef(f6, f6, f6); + GL11.glTranslatef(0.5F, 0.5F, 0.0F); + GL11.glRotatef((float) (i * i * 4321 + i * 9) * 2.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(-0.5F, -0.5F, 0.0F); + GL11.glTranslatef(-pz, -py, -px); + GL11.glTranslatef( + ActiveRenderInfo.objectZ * f5 / f9, + ActiveRenderInfo.objectY * f5 / f9, + -px + ); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + f11 = random.nextFloat() * 0.5F + 0.1F; + float f12 = random.nextFloat() * 0.5F + 0.4F; + float f13 = random.nextFloat() * 0.5F + 0.5F; + if (i == 0) { + f13 = 1.0F; + f12 = 1.0F; + f11 = 1.0F; + } + + tessellator.setBrightness(180); + tessellator.setColorRGBA_F(f11 * f7, f12 * f7, f13 * f7, 1.0F); + tessellator.addVertex(x + (double) offset, y + 1.0, z); + tessellator.addVertex(x + (double) offset, y + 1.0, z + 1.0); + tessellator.addVertex(x + (double) offset, y, z + 1.0); + tessellator.addVertex(x + (double) offset, y, z); + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glMatrixMode(5888); + } + + GL11.glDisable(3042); + GL11.glDisable(3168); + GL11.glDisable(3169); + GL11.glDisable(3170); + GL11.glDisable(3171); + GL11.glEnable(2896); + } + + public void drawPlaneXNeg(double x, double y, double z, float f) { + EntityClientPlayerMP player = FMLClientHandler.instance().getClientPlayerEntity(); + float px = (float) player.posX; + float py = (float) player.posY; + float pz = (float) player.posZ; + GL11.glDisable(2896); + Random random = new Random(31100L); + float offset = 0.01F; + for (int i = 0; i < 16; ++i) { + GL11.glPushMatrix(); + float f5 = (float) (16 - i); + float f6 = 0.0625F; + float f7 = 1.0F / (f5 + 1.0F); + if (i == 0) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/tunnel.png") + ); + f7 = 0.1F; + f5 = 65.0F; + f6 = 0.125F; + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + } + + if (i == 1) { + this.bindTexture( + new ResourceLocation("thaummach", "textures/misc/particlefield.png") + ); + GL11.glEnable(3042); + GL11.glBlendFunc(1, 1); + f6 = 0.5F; + } + + float f8 = (float) (x + (double) offset); + float f9 = f8 - ActiveRenderInfo.objectX; + float f10 = f8 + f5 - ActiveRenderInfo.objectX; + float f11 = f9 / f10; + f11 += (float) (x + (double) offset); + GL11.glTranslatef(f11, py, pz); + GL11.glTexGeni(8192, 9472, 9217); + GL11.glTexGeni(8193, 9472, 9217); + GL11.glTexGeni(8194, 9472, 9217); + GL11.glTexGeni(8195, 9472, 9216); + GL11.glTexGen(8193, 9473, this.calcFloatBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GL11.glTexGen(8192, 9473, this.calcFloatBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + GL11.glTexGen(8194, 9473, this.calcFloatBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GL11.glTexGen(8195, 9474, this.calcFloatBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + GL11.glEnable(3168); + GL11.glEnable(3169); + GL11.glEnable(3170); + GL11.glEnable(3171); + GL11.glPopMatrix(); + GL11.glMatrixMode(5890); + GL11.glPushMatrix(); + GL11.glLoadIdentity(); + GL11.glTranslatef( + 0.0F, (float) (System.currentTimeMillis() % 700000L) / 250000.0F, 0.0F + ); + GL11.glScalef(f6, f6, f6); + GL11.glTranslatef(0.5F, 0.5F, 0.0F); + GL11.glRotatef((float) (i * i * 4321 + i * 9) * 2.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(-0.5F, -0.5F, 0.0F); + GL11.glTranslatef(-pz, -py, -px); + GL11.glTranslatef( + ActiveRenderInfo.objectZ * f5 / f9, + ActiveRenderInfo.objectY * f5 / f9, + -px + ); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + f11 = random.nextFloat() * 0.5F + 0.1F; + float f12 = random.nextFloat() * 0.5F + 0.4F; + float f13 = random.nextFloat() * 0.5F + 0.5F; + if (i == 0) { + f13 = 1.0F; + f12 = 1.0F; + f11 = 1.0F; + } + + tessellator.setBrightness(180); + tessellator.setColorRGBA_F(f11 * f7, f12 * f7, f13 * f7, 1.0F); + tessellator.addVertex(x + (double) offset, y, z); + tessellator.addVertex(x + (double) offset, y, z + 1.0); + tessellator.addVertex(x + (double) offset, y + 1.0, z + 1.0); + tessellator.addVertex(x + (double) offset, y + 1.0, z); + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glMatrixMode(5888); + } + + GL11.glDisable(3042); + GL11.glDisable(3168); + GL11.glDisable(3169); + GL11.glDisable(3170); + GL11.glDisable(3171); + GL11.glEnable(2896); + } + + @Override + public void renderTileEntityAt(TileEntity te, double x, double y, double z, float f) { + this.drawPlaneZNeg(x, y, z, f); + this.drawPlaneZPos(x, y, z, f); + this.drawPlaneXNeg(x, y, z, f); + this.drawPlaneXPos(x, y, z, f); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/tile/TileVoidInterfaceRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/tile/TileVoidInterfaceRenderer.java new file mode 100644 index 0000000..614c767 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/tile/TileVoidInterfaceRenderer.java @@ -0,0 +1,84 @@ +package net.anvilcraft.thaummach.render.tile; + +import net.anvilcraft.thaummach.tiles.TileVoidInterface; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class TileVoidInterfaceRenderer extends TileEntitySpecialRenderer { + public void renderTileEntityAt(TileEntity te, double x, double y, double z, float f) { + for (int a = 0; a < 4; ++a) { + float xx = 0.0F; + float zz = 0.0F; + switch (a) { + case 0: + xx = 0.375F; + zz = 0.2F; + break; + case 1: + zz = -0.375F; + xx = 0.2F; + break; + case 2: + xx = -0.375F; + zz = -0.2F; + break; + case 3: + zz = 0.375F; + xx = -0.2F; + } + + GL11.glPushMatrix(); + GL11.glTranslatef( + (float) x + (float) (a != 2 && a != 3 ? 1 : 0), + (float) y + 0.44F, + (float) z + (float) (a != 1 && a != 2 ? 1 : 0) + ); + GL11.glTranslatef(xx, 0.0F, zz); + GL11.glRotatef(90.0F * (float) a, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(90.0F, 1.0f, 0.0f, 0.0f); + GL11.glTranslatef(-0.75f, -0.4f, 0.0f); + GL11.glScalef(-0.25f, 1.0f, -0.25f); + GL11.glPushMatrix(); + + //ThaumCraftRenderer.renderItemFromTexture( + // ModLoader.getMinecraftInstance(), + // "/thaumcraft/resources/particles.png", + // 8, + // 56 + ((TileVoidInterface) te).network, + // 0.25F, + // 0.0F, + // false, + // 1.0F, + // 1.0F, + // 1.0F, + // 220, + // 1 + //); + + Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation( + "thaummach", + "textures/misc/i_" + ((TileVoidInterface) te).network + + + ".png" + )); + + GL11.glEnable(3042); + GL11.glBlendFunc(770, 1); + Tessellator tess = Tessellator.instance; + tess.startDrawingQuads(); + tess.addVertexWithUV(0.0, 0.0, 1.0, 1.0, 0.0); + tess.addVertexWithUV(1.0, 0.0, 1.0, 0.0, 0.0); + tess.addVertexWithUV(1.0, 0.0, 0.0, 0.0, 1.0); + tess.addVertexWithUV(0.0, 0.0, 0.0, 1.0, 1.0); + tess.draw(); + GL11.glDisable(3042); + + GL11.glPopMatrix(); + GL11.glPopMatrix(); + } + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileSeal.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileSeal.java index 1ca078b..581b840 100644 --- a/src/main/java/net/anvilcraft/thaummach/tiles/TileSeal.java +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileSeal.java @@ -6,12 +6,12 @@ import java.util.List; import java.util.Set; import dev.tilera.auracore.api.AuraNode; +import dev.tilera.auracore.api.HelperLocation; import dev.tilera.auracore.aura.AuraManager; import dev.tilera.auracore.client.FXSparkle; import dev.tilera.auracore.helper.Utils; -import net.anvilcraft.thaummach.SealData; +import net.anvilcraft.thaummach.RuneTileData; import net.anvilcraft.thaummach.render.PortalRenderer; -import net.anvilcraft.thaummach.utils.HelperLocation; import net.anvilcraft.thaummach.utils.UtilsFX; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; @@ -52,8 +52,8 @@ import thaumcraft.client.fx.particles.FXScorch; import thaumcraft.client.fx.particles.FXWisp; public class TileSeal extends TileEntity { - public static Set SEALS = new HashSet<>(); - public SealData otherSeal; + public static Set SEALS = new HashSet<>(); + public RuneTileData otherSeal; public PortalRenderer renderer; public int delay = 0; @@ -198,7 +198,7 @@ public class TileSeal extends TileEntity { return; } case 1: - SealData sd = new SealData(this); + RuneTileData sd = new RuneTileData(this); if (!SEALS.contains(sd)) { SEALS.add(sd); this.worldObj.markBlockForUpdate( @@ -1513,11 +1513,11 @@ public class TileSeal extends TileEntity { } if (list.size() > 0) { - Iterator i$ = SEALS.iterator(); + Iterator i$ = SEALS.iterator(); boolean fs = false; label74: { - SealData pd; + RuneTileData pd; do { do { do { @@ -1650,7 +1650,7 @@ public class TileSeal extends TileEntity { if (this.otherSeal == null) { return false; } else { - SealData targetDest = this.otherSeal; + RuneTileData targetDest = this.otherSeal; TileEntity ts = super.worldObj.getTileEntity( targetDest.x, targetDest.y, targetDest.z ); @@ -2500,7 +2500,7 @@ public class TileSeal extends TileEntity { this.runes = nbt.getByteArray("runes"); this.portalWindow = nbt.getInteger("window"); if (nbt.hasKey("other")) - this.otherSeal = SealData.readFromNbt(nbt.getCompoundTag("other")); + this.otherSeal = RuneTileData.readFromNbt(nbt.getCompoundTag("other")); else this.otherSeal = null; } @@ -2540,7 +2540,7 @@ public class TileSeal extends TileEntity { this.runes = nbt.getByteArray("runes"); this.portalWindow = nbt.getInteger("window"); if (nbt.hasKey("other")) - this.otherSeal = SealData.readFromNbt(nbt.getCompoundTag("other")); + this.otherSeal = RuneTileData.readFromNbt(nbt.getCompoundTag("other")); else this.otherSeal = null; //this.pSize = nbt.getFloat("pSize"); @@ -2608,7 +2608,7 @@ public class TileSeal extends TileEntity { public void invalidate() { super.invalidate(); if (!this.worldObj.isRemote) - SEALS.remove(new SealData(this)); + SEALS.remove(new RuneTileData(this)); else if (this.renderer != null) this.renderer.deinit(); } diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileVoidChest.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileVoidChest.java index e8cd2f4..9826530 100644 --- a/src/main/java/net/anvilcraft/thaummach/tiles/TileVoidChest.java +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileVoidChest.java @@ -143,7 +143,7 @@ public class TileVoidChest extends TileEntity implements ISidedInventory { @Override public int[] getAccessibleSlotsFromSide(int p_94128_1_) { - return IntStream.rangeClosed(0, this.vcItemStacks.length - 1).toArray(); + return IntStream.range(0, this.vcItemStacks.length).toArray(); } @Override diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileVoidInterface.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileVoidInterface.java new file mode 100644 index 0000000..f6d9029 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileVoidInterface.java @@ -0,0 +1,240 @@ +package net.anvilcraft.thaummach.tiles; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.IntStream; + +import dev.tilera.auracore.api.HelperLocation; +import net.anvilcraft.thaummach.RuneTileData; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +public class TileVoidInterface extends TileEntity implements ISidedInventory { + // TODO: WTF + public static Set VOID_INTERFACES = new HashSet<>(); + public byte network = 0; + public ArrayList links = new ArrayList<>(); + public boolean linked = false; + public int current = 0; + public boolean init = false; + + public int getLinkedSize() { + return this.links.size(); + } + + @Override + public int getSizeInventory() { + return Math.max(72, 72 * this.links.size()); + } + + private IInventory getInventory(HelperLocation v3d) { + TileEntity te = v3d.getFacingTile(this.worldObj); + return te instanceof TileVoidChest ? (IInventory) te : null; + } + + @Override + public ItemStack getStackInSlot(int i) { + int inventory = i / 72; + int slot = i % 72; + + try { + return this.getInventory(this.links.get(inventory)).getStackInSlot(slot); + } catch (Exception var5) { + return null; + } + } + + @Override + public ItemStack getStackInSlotOnClosing(int i) { + int inventory = i / 72; + int slot = i % 72; + return this.getInventory(this.links.get(inventory)).getStackInSlotOnClosing(slot); + } + + @Override + public ItemStack decrStackSize(int i, int j) { + int inventory = i / 72; + int slot = i % 72; + return this.getInventory(this.links.get(inventory)).decrStackSize(slot, j); + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + int inventory = i / 72; + int slot = i % 72; + + try { + this.getInventory(this.links.get(inventory)) + .setInventorySlotContents(slot, itemstack); + } catch (Exception var6) {} + } + + // TODO: WTF + //@Override + //public ItemStack getStackInSlotVirtual(int i) { + // try { + // return this.getInventory(this.links.get(this.current)).getStackInSlot(i % + // 72); + // } catch (Exception var3) { + // return null; + // } + //} + + //@Override + //public ItemStack decrStackSizeVirtual(int i, int j) { + // try { + // return this.getInventory(this.links.get(this.current)) + // .decrStackSize(i % 72, j); + // } catch (Exception var4) { + // return null; + // } + //} + + //@Override + //public void setInventorySlotContentsVirtual(int i, ItemStack itemstack) { + // try { + // this.getInventory(this.links.get(this.current)) + // .setInventorySlotContents(i % 72, itemstack); + // } catch (Exception var4) {} + //} + + public void establishLinks() { + this.current = 0; + this.links.clear(); + ArrayList tiles = new ArrayList<>(); + + for (RuneTileData rtd : VOID_INTERFACES) { + if (rtd.rune == this.network + && rtd.dim == this.worldObj.provider.dimensionId) { + tiles.add(rtd); + } + } + + tiles.sort( + (a, b) + -> Double.compare( + this.getDistanceFrom(a.x, a.y, a.z), + this.getDistanceFrom(b.x, b.y, b.z) + ) + ); + + for (RuneTileData rtd : tiles) { + TileEntity te = this.worldObj.getTileEntity(rtd.x, rtd.y - 1, rtd.z); + if (te instanceof TileVoidChest) { + this.links.add(new HelperLocation(te)); + } + } + + this.linked = this.links.size() > 1; + } + + public void invalidateLinks() { + for (RuneTileData rtd : VOID_INTERFACES) { + if (rtd.rune != this.network) + continue; + + TileEntity te = this.worldObj.getTileEntity(rtd.x, rtd.y, rtd.z); + if (!(te instanceof TileVoidInterface)) { + VOID_INTERFACES.remove(rtd); + // TODO: WTF WTF WTF WTF + this.invalidateLinks(); + break; + } + + if (te != null) { + TileVoidInterface tvi = (TileVoidInterface) te; + tvi.markDirty(); + tvi.clearLinks(); + } + } + } + + public void clearLinks() { + this.current = 0; + this.links.clear(); + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.network = nbttagcompound.getByte("network"); + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setByte("network", this.network); + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public void updateEntity() { + super.updateEntity(); + if (!this.init) { + this.init = true; + + VOID_INTERFACES.add(new RuneTileData(this, this.network)); + } + + if (this.links.size() == 0) { + this.establishLinks(); + } + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public String getInventoryName() { + return "Void Interface"; + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public void openInventory() {} + + @Override + public void closeInventory() {} + + @Override + public boolean isItemValidForSlot(int p_94041_1_, ItemStack p_94041_2_) { + return true; + } + + @Override + public int[] getAccessibleSlotsFromSide(int p_94128_1_) { + return IntStream.range(0, this.getSizeInventory()).toArray(); + } + + @Override + public boolean canInsertItem(int slot, ItemStack otherStack, int side) { + ItemStack thisStack = this.getStackInSlot(slot); + return thisStack == null + || (thisStack.isItemEqual(otherStack) + && thisStack.stackSize + otherStack.stackSize + <= thisStack.getMaxStackSize()); + } + + @Override + public boolean canExtractItem(int slot, ItemStack otherStack, int side) { + ItemStack thisStack = this.getStackInSlot(slot); + + return thisStack != null && thisStack.isItemEqual(otherStack) + && thisStack.stackSize >= otherStack.stackSize; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/utils/HelperFacing.java b/src/main/java/net/anvilcraft/thaummach/utils/HelperFacing.java deleted file mode 100644 index f57bbc1..0000000 --- a/src/main/java/net/anvilcraft/thaummach/utils/HelperFacing.java +++ /dev/null @@ -1,90 +0,0 @@ -package net.anvilcraft.thaummach.utils; - -public enum HelperFacing { - NEGY, - POSY, - NEGZ, - POSZ, - NEGX, - POSX, - UNKNOWN; - - public HelperFacing turnAround() { - switch (this) { - case POSY: { - return HelperFacing.NEGY; - } - - case NEGY: { - return HelperFacing.POSY; - } - case POSZ: { - return HelperFacing.NEGZ; - } - case NEGZ: { - return HelperFacing.POSZ; - } - case POSX: { - return HelperFacing.NEGX; - } - case NEGX: { - return HelperFacing.POSX; - } - default: { - return HelperFacing.UNKNOWN; - } - } - } - - public HelperFacing turnLeft() { - switch (this) { - case POSY: { - return HelperFacing.POSY; - } - case NEGY: { - return HelperFacing.NEGY; - } - case POSZ: { - return HelperFacing.POSX; - } - case NEGZ: { - return HelperFacing.NEGX; - } - case POSX: { - return HelperFacing.NEGZ; - } - case NEGX: { - return HelperFacing.POSZ; - } - default: { - return HelperFacing.UNKNOWN; - } - } - } - - public HelperFacing turnRight() { - switch (this) { - case POSY: { - return HelperFacing.POSY; - } - case NEGY: { - return HelperFacing.NEGY; - } - case POSZ: { - return HelperFacing.NEGX; - } - case NEGZ: { - return HelperFacing.POSX; - } - case POSX: { - return HelperFacing.POSZ; - } - case NEGX: { - return HelperFacing.NEGZ; - } - default: { - return HelperFacing.UNKNOWN; - } - } - } -} diff --git a/src/main/java/net/anvilcraft/thaummach/utils/HelperLocation.java b/src/main/java/net/anvilcraft/thaummach/utils/HelperLocation.java deleted file mode 100644 index 27f764d..0000000 --- a/src/main/java/net/anvilcraft/thaummach/utils/HelperLocation.java +++ /dev/null @@ -1,253 +0,0 @@ -package net.anvilcraft.thaummach.utils; - -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; - -public class HelperLocation { - public double x; - public double y; - public double z; - public HelperFacing facing; - - public HelperLocation(final TileEntity tile) { - this.x = tile.xCoord; - this.y = tile.yCoord; - this.z = tile.zCoord; - this.facing = HelperFacing.UNKNOWN; - } - - public HelperLocation(final double x, final double y, final double z) { - this.x = x; - this.y = y; - this.z = z; - this.facing = HelperFacing.UNKNOWN; - } - - public HelperLocation( - final double x, final double y, final double z, final HelperFacing facing - ) { - this.x = x; - this.y = y; - this.z = z; - this.facing = facing; - } - - public HelperLocation(final TileEntity te, final HelperFacing facing) { - this.x = te.xCoord; - this.y = te.yCoord; - this.z = te.zCoord; - this.facing = facing; - } - - public HelperLocation(final TileEntity te, final int facing) { - this.x = te.xCoord; - this.y = te.yCoord; - this.z = te.zCoord; - switch (facing) { - case 0: { - this.facing = HelperFacing.NEGY; - break; - } - case 1: { - this.facing = HelperFacing.POSY; - break; - } - case 2: { - this.facing = HelperFacing.NEGZ; - break; - } - case 3: { - this.facing = HelperFacing.POSZ; - break; - } - case 4: { - this.facing = HelperFacing.NEGX; - break; - } - case 5: { - this.facing = HelperFacing.POSX; - break; - } - } - } - - public HelperLocation(final HelperLocation l) { - this.x = l.x; - this.y = l.y; - this.z = l.z; - this.facing = l.facing; - } - - public void moveUp(final double amount) { - switch (this.facing) { - case POSZ: - case NEGZ: - case POSX: - case NEGX: { - this.y += amount; - break; - } - default: - break; - } - } - - public void moveDown(final double amount) { - switch (this.facing) { - case POSZ: - case NEGZ: - case POSX: - case NEGX: { - this.y -= amount; - break; - } - default: - break; - } - } - - public void moveRight(final double amount) { - switch (this.facing) { - case POSZ: { - this.x -= amount; - break; - } - case NEGZ: { - this.x += amount; - break; - } - case POSX: { - this.z += amount; - break; - } - case NEGX: { - this.z -= amount; - break; - } - default: - break; - } - } - - public void moveLeft(final double amount) { - switch (this.facing) { - case POSZ: { - this.x += amount; - break; - } - case NEGZ: { - this.x -= amount; - break; - } - case POSX: { - this.z -= amount; - break; - } - case NEGX: { - this.z += amount; - break; - } - default: - break; - } - } - - public void moveForwards(final double amount) { - switch (this.facing) { - case POSY: { - this.y += amount; - break; - } - case NEGY: { - this.y -= amount; - break; - } - case POSZ: { - this.z += amount; - break; - } - case NEGZ: { - this.z -= amount; - break; - } - case POSX: { - this.x += amount; - break; - } - case NEGX: { - this.x -= amount; - break; - } - default: - break; - } - } - - public void moveBackwards(final double amount) { - switch (this.facing) { - case POSY: { - this.y -= amount; - break; - } - case NEGY: { - this.y += amount; - break; - } - case POSZ: { - this.z -= amount; - break; - } - case NEGZ: { - this.z += amount; - break; - } - case POSX: { - this.x -= amount; - break; - } - case NEGX: { - this.x += amount; - break; - } - default: - break; - } - } - - // TODO: waiting on auracore update - //public TileEntity getConnectableTile(final World w) { - // this.moveForwards(1.0); - // final TileEntity te - // = w.getTileEntity((int) this.x, (int) this.y, (int) this.z); - // if (te instanceof IConnection - // && ((IConnection) te).getConnectable(this.facing.turnAround())) { - // return te; - // } - // return null; - //} - - public TileEntity getFacingTile(final World w) { - this.moveForwards(1.0); - final TileEntity te - = w.getTileEntity((int) this.x, (int) this.y, (int) this.z); - if (te != null) { - return te; - } - return null; - } - - //public TileEntity getConnectableTile(final IBlockAccess ibc) { - // this.moveForwards(1.0); - // final TileEntity te - // = ibc.getTileEntity((int) this.x, (int) this.y, (int) this.z); - // if (te instanceof IConnection - // && ((IConnection) te).getConnectable(this.facing.turnAround())) { - // return te; - // } - // return null; - //} - - public boolean equals(final HelperLocation loc) { - return this.x == loc.x && this.y == loc.y && this.z == loc.z; - } -} diff --git a/src/main/resources/assets/thaummach/textures/misc/i_0.png b/src/main/resources/assets/thaummach/textures/misc/i_0.png new file mode 100644 index 0000000000000000000000000000000000000000..973901a65c13c8f98b0c6ceb4e63b7d94949adda GIT binary patch literal 1500 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/misc/i_2.png b/src/main/resources/assets/thaummach/textures/misc/i_2.png new file mode 100644 index 0000000000000000000000000000000000000000..e22c686820c49d7d8761edec60dd2efc7372dad4 GIT binary patch literal 1497 zcmV;~1t$85P)EX>4Tx04R}tkv&MmKpe$iTZ^5kwe+h+|A*ramW%X?TvWd-(Wz7vovp=l&c6O2K4+PasY(-LQx^h~t}< z&Uv3W!pf3Dd`>)R&;^Mfxh}i>#<}FMpJzslY-XM~LM)WJSngt0HdNvn;;5o(l<&{E ztZ?4qtXAu+eNX0S*p< zi4tY6d%U}^ySIPOwEO!3(_?bYd}4O300006VoOIv00000008+zyMF)x010qNS#tmY z9>D+r9>D>_X;f1H000McNliru=LHWF0Ua}IUJU>M02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00Xf}L_t(o!=2Ypj3jdu2k=jI_slS3?E1HinGFdRmrXcu zKqiq0R&e1;+_^~{B@QBSkl=vC!O@;1mK!o;1!2R*OdMjcB z&X8gkihG#GR7fwRQ}cWW+e!N9HyKe(P~HtCQ@AL}#kduhgaO;(@eu1cfpfTk^Vn)K zqG+Lf2D2dta3}WQ+J^5p@iRWbah#2{EtGX5dJO@na$R|T6CT1+tYyFrYgm}Y&A1+4 z=IOY4v+5@Ueu0_%@Kg844>x8YbYq_kVam zEzCtK&4YL*J$nn^MD6c{Vv}gOsSNW6cLiHmj7@i71y{2Jkc< z4RU*Yuj;;TP^G*d&x>eUhw)>rgeMYFrqH$E_W3Bg z0~1QP7oHxC9&kDVu{9I!3Dh2skI%*Z2=?N3?2BAiQMnNN{TzbUbEG=+yQYrmk4FIimjqkn>|84{L)(00000NkvXXu0mjf5An6Q literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/misc/i_3.png b/src/main/resources/assets/thaummach/textures/misc/i_3.png new file mode 100644 index 0000000000000000000000000000000000000000..358f30b11c3e41e68b7877be92f162819c7e96a1 GIT binary patch literal 1410 zcmV-|1%3L7P)EX>4Tx04R}tkv&MmKpe$iTZ^5kwe+h+|A*ramW%X?TvWd-(Wz7vovp=l&c6O2K4+PasY(-LQx^h~t}< z&Uv3W!pf3Dd`>)R&;^Mfxh}i>#<}FMpJzslY-XM~LM)WJSngt0HdNvn;;5o(l<&{E ztZ?4qtXAu+eNX0S*p< zi4tY6d%U}^ySIPOwEO!3(_?bYd}4O300006VoOIv00000008+zyMF)x010qNS#tmY z9>D+r9>D>_X;f1H000McNliru=LHWF0VDDXL#6-#02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00UY{L_t(o!?l-7YZO5gg};8xD<;Mli6i1;p$id3$wo2g z&V?YZT!?PPKj6ZjA>!VRAi5GaF5IgaP*6}5gNi1Kh$fj#=Go=u6kOZxNsoyQMO9bV z)ID|Xx%bvU!Kdz~0^j^Q>+l3c3{`6&F1URnwS)i$JeqCtXR8}9?-Bh#|0D(5G0O!O4KwopA z2}=)P0ywDeF%TAwk~{zrPzAP_d8fIu0T2Njfos53;GzK$6#q;Hi`MyQ*e;gFjewnDst^O-cnkOp%mKT# z)+d-r8R%**Fs+&)=o+w?1t2d9yvP=TMhTS54f-KvdIZOGcKi=8U8+y@pPr)CB^%k{8|-z+h{jZ}&|>YbVY0K65T6`j6gT0iTu zI;b4?Qph94xy#9H(?;>{fCs=Yb8#6e5jk_yiE{o=_ETU&iM9$HRciw`fM{!i zc|YHlxO_HCQp`BxDrfpg!fpK1zhm9)OQxLqJ7Qv*Gk`5CfAsUgOh3=gZ-!qZ|0hpG Q%>V!Z07*qoM6N<$f_8{;3jhEB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/misc/i_4.png b/src/main/resources/assets/thaummach/textures/misc/i_4.png new file mode 100644 index 0000000000000000000000000000000000000000..5eff289523c9d3b692997d9083ce240117415f08 GIT binary patch literal 1586 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