From 72408a15c78c7f601caaeeb49c7a85cbb9d7f484 Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Fri, 26 May 2023 22:00:25 +0200 Subject: [PATCH] feat: implement generator --- build.gradle | 21 +- .../net/anvilcraft/thaummach/ClientProxy.java | 7 + .../net/anvilcraft/thaummach/CommonProxy.java | 13 + .../java/net/anvilcraft/thaummach/GuiID.java | 1 + .../net/anvilcraft/thaummach/ITileGui.java | 8 + .../thaummach/blocks/BlockApparatus.java | 3 + .../thaummach/blocks/BlockApparatusMetal.java | 66 ++- .../thaummach/blocks/BlockApparatusWood.java | 4 +- .../thaummach/gui/GuiGenerator.java | 50 ++ .../metal/GeneratorApparatusRenderer.java | 95 ++++ ...er.java => RepairerApparatusRenderer.java} | 6 +- .../thaummach/render/model/ModelGenCore.java | 38 ++ .../render/tile/TileGeneratorRenderer.java | 37 ++ .../thaummach/tiles/TileGenerator.java | 457 ++++++++++++++++++ .../anvilcraft/thaummach/utils/UtilsFX.java | 4 +- .../resources/assets/thaummach/sounds.json | 9 + .../assets/thaummach/sounds/alecloop.ogg | Bin 0 -> 20757 bytes .../thaummach/textures/blocks/generator_4.png | Bin 0 -> 593 bytes .../thaummach/textures/guis/generator.png | Bin 0 -> 7255 bytes .../thaummach/textures/models/gencore.png | Bin 0 -> 1695 bytes 20 files changed, 776 insertions(+), 43 deletions(-) create mode 100644 src/main/java/net/anvilcraft/thaummach/gui/GuiGenerator.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/GeneratorApparatusRenderer.java rename src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/wood/{RepairerAparatusRenderer.java => RepairerApparatusRenderer.java} (95%) create mode 100644 src/main/java/net/anvilcraft/thaummach/render/model/ModelGenCore.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/tile/TileGeneratorRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TileGenerator.java create mode 100644 src/main/resources/assets/thaummach/sounds/alecloop.ogg create mode 100644 src/main/resources/assets/thaummach/textures/blocks/generator_4.png create mode 100644 src/main/resources/assets/thaummach/textures/guis/generator.png create mode 100644 src/main/resources/assets/thaummach/textures/models/gencore.png diff --git a/build.gradle b/build.gradle index de3b245..aac442b 100644 --- a/build.gradle +++ b/build.gradle @@ -34,12 +34,29 @@ minecraft { repositories { maven { url = "https://maven.tilera.xyz" } + maven { + name = "ic2" + url = "https://maven.ic2.player.to/" + metadataSources { + artifact() + } + } + maven { + name 'central' + url 'https://maven.thorfusion.com/artifactory/central/' + } } dependencies { - implementation "thaumcraft:Thaumcraft:1.7.10-4.2.3.5:deobf" - implementation "dev.tilera:auracore:1.9.0:deobf" + //implementation "codechicken:CodeChickenCore:1.7.10-1.0.7.48:dev" + //implementation "codechicken:CodeChickenLib:1.7.10-1.1.3.141:dev" + //implementation "codechicken:NotEnoughItems:1.7.10-1.0.5.120:dev" + //implementation "com.eloraam.redpower:redpower:2.0pr10-dirty:deobf" implementation "com.github.tox1cozZ:mixin-booter-legacy:1.1.2" + implementation "dev.tilera:auracore:1.9.0:deobf" + implementation "net.industrial-craft:industrialcraft-2:2.2.660-experimental:dev" + implementation "thaumcraft:Thaumcraft:1.7.10-4.2.3.5:deobf" + implementation "universalelectricity:universalelectricity:5.2.2:deobf" } processResources { diff --git a/src/main/java/net/anvilcraft/thaummach/ClientProxy.java b/src/main/java/net/anvilcraft/thaummach/ClientProxy.java index 083c3dc..00d48d7 100644 --- a/src/main/java/net/anvilcraft/thaummach/ClientProxy.java +++ b/src/main/java/net/anvilcraft/thaummach/ClientProxy.java @@ -9,6 +9,7 @@ import net.anvilcraft.thaummach.gui.GuiArcaneFurnace; import net.anvilcraft.thaummach.gui.GuiBore; import net.anvilcraft.thaummach.gui.GuiCondenser; import net.anvilcraft.thaummach.gui.GuiCrystallizer; +import net.anvilcraft.thaummach.gui.GuiGenerator; import net.anvilcraft.thaummach.gui.GuiRepairer; import net.anvilcraft.thaummach.gui.GuiSoulBrazier; import net.anvilcraft.thaummach.gui.GuiVoidChest; @@ -19,6 +20,7 @@ import net.anvilcraft.thaummach.render.tile.TileBoreRenderer; import net.anvilcraft.thaummach.render.tile.TileCondenserRenderer; import net.anvilcraft.thaummach.render.tile.TileConduitPumpRenderer; import net.anvilcraft.thaummach.render.tile.TileCrystallizerRenderer; +import net.anvilcraft.thaummach.render.tile.TileGeneratorRenderer; import net.anvilcraft.thaummach.render.tile.TileRepairerRenderer; import net.anvilcraft.thaummach.render.tile.TileSealRenderer; import net.anvilcraft.thaummach.render.tile.TileVoidChestRenderer; @@ -34,6 +36,7 @@ import net.anvilcraft.thaummach.tiles.TileConduitValveAdvanced; import net.anvilcraft.thaummach.tiles.TileCrucible; import net.anvilcraft.thaummach.tiles.TileCrystallizer; import net.anvilcraft.thaummach.tiles.TileFilter; +import net.anvilcraft.thaummach.tiles.TileGenerator; import net.anvilcraft.thaummach.tiles.TilePurifier; import net.anvilcraft.thaummach.tiles.TileRepairer; import net.anvilcraft.thaummach.tiles.TileSeal; @@ -79,6 +82,7 @@ public class ClientProxy extends CommonProxy { ClientRegistry.registerTileEntity(TileCondenser.class, "condenser", new TileCondenserRenderer()); ClientRegistry.registerTileEntity(TileConduitPump.class, "conduit_pump", new TileConduitPumpRenderer()); ClientRegistry.registerTileEntity(TileCrystallizer.class, "crystallizer", new TileCrystallizerRenderer()); + ClientRegistry.registerTileEntity(TileGenerator.class, "generator", new TileGeneratorRenderer()); ClientRegistry.registerTileEntity(TileRepairer.class, "repairer", new TileRepairerRenderer()); ClientRegistry.registerTileEntity(TileSeal.class, "seal", new TileSealRenderer()); ClientRegistry.registerTileEntity(TileVoidChest.class, "voidChest", new TileVoidChestRenderer()); @@ -103,6 +107,9 @@ public class ClientProxy extends CommonProxy { case CRYSTALLIZER: return new GuiCrystallizer(player.inventory, (TileCrystallizer) te); + case GENERATOR: + return new GuiGenerator((TileGenerator) te); + case REPAIRER: return new GuiRepairer(player.inventory, (TileRepairer) te); diff --git a/src/main/java/net/anvilcraft/thaummach/CommonProxy.java b/src/main/java/net/anvilcraft/thaummach/CommonProxy.java index b4b5ed5..7c29a4d 100644 --- a/src/main/java/net/anvilcraft/thaummach/CommonProxy.java +++ b/src/main/java/net/anvilcraft/thaummach/CommonProxy.java @@ -21,13 +21,16 @@ import net.anvilcraft.thaummach.tiles.TileConduitValveAdvanced; import net.anvilcraft.thaummach.tiles.TileCrucible; import net.anvilcraft.thaummach.tiles.TileCrystallizer; import net.anvilcraft.thaummach.tiles.TileFilter; +import net.anvilcraft.thaummach.tiles.TileGenerator; import net.anvilcraft.thaummach.tiles.TilePurifier; import net.anvilcraft.thaummach.tiles.TileRepairer; import net.anvilcraft.thaummach.tiles.TileSeal; import net.anvilcraft.thaummach.tiles.TileSoulBrazier; import net.anvilcraft.thaummach.tiles.TileVoidChest; import net.anvilcraft.thaummach.tiles.TileVoidInterface; +import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; @@ -49,6 +52,7 @@ public class CommonProxy implements IGuiHandler { GameRegistry.registerTileEntity(TileCrucible.class, "crucible"); GameRegistry.registerTileEntity(TileCrystallizer.class, "crystallizer"); GameRegistry.registerTileEntity(TileFilter.class, "filter"); + GameRegistry.registerTileEntity(TileGenerator.class, "generator"); GameRegistry.registerTileEntity(TilePurifier.class, "purifier"); GameRegistry.registerTileEntity(TileRepairer.class, "repairer"); GameRegistry.registerTileEntity(TileSeal.class, "seal"); @@ -91,6 +95,15 @@ public class CommonProxy implements IGuiHandler { player.inventory, (TileVoidInterface) te ); + // GUIs with no meaningful container + case GENERATOR: + return new Container() { + @Override + public boolean canInteractWith(EntityPlayer player) { + return true; + } + }; + default: throw new IllegalArgumentException("ALEC"); } diff --git a/src/main/java/net/anvilcraft/thaummach/GuiID.java b/src/main/java/net/anvilcraft/thaummach/GuiID.java index 58f1db0..254829f 100644 --- a/src/main/java/net/anvilcraft/thaummach/GuiID.java +++ b/src/main/java/net/anvilcraft/thaummach/GuiID.java @@ -5,6 +5,7 @@ public enum GuiID { BORE, CONDENSER, CRYSTALLIZER, + GENERATOR, REPAIRER, SOUL_BRAZIER, VOID_CHEST, diff --git a/src/main/java/net/anvilcraft/thaummach/ITileGui.java b/src/main/java/net/anvilcraft/thaummach/ITileGui.java index 7f4332b..cc38824 100644 --- a/src/main/java/net/anvilcraft/thaummach/ITileGui.java +++ b/src/main/java/net/anvilcraft/thaummach/ITileGui.java @@ -1,5 +1,13 @@ package net.anvilcraft.thaummach; +/** + * Implemented by Apparatus {@link net.minecraft.tileentity.TileEntity}s which have a GUI that's + * opened on right-click. + */ public interface ITileGui { + /** + * Get the GUI ID {@link net.anvilcraft.thaummach.blocks.BlockApparatus} + * will use to determine a GUI to open on right-click. + */ public GuiID getGuiID(); } diff --git a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java index 8f5ac70..507e8dc 100644 --- a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java +++ b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java @@ -2,6 +2,7 @@ package net.anvilcraft.thaummach.blocks; import java.util.Random; +import cpw.mods.fml.common.FMLCommonHandler; import net.anvilcraft.thaummach.AuraUtils; import net.anvilcraft.thaummach.GuiID; import net.anvilcraft.thaummach.ITileGui; @@ -19,6 +20,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.World; +import net.minecraftforge.client.MinecraftForgeClient; public abstract class BlockApparatus extends BlockContainer { protected int currentPass; @@ -74,6 +76,7 @@ public abstract class BlockApparatus extends BlockContainer { if (te instanceof ITileGui) { if (world.isRemote) return true; + GuiID id = ((ITileGui) te).getGuiID(); entityplayer.openGui( diff --git a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java index 5b1f508..50831a8 100644 --- a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java +++ b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusMetal.java @@ -5,13 +5,13 @@ import java.util.Random; import java.util.stream.IntStream; import dev.tilera.auracore.client.FXSparkle; -import net.anvilcraft.thaummach.AuraUtils; import net.anvilcraft.thaummach.render.BlockApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.apparati.metal.ArcaneFurnaceApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.apparati.metal.BoreApparatusRenderer; 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.GeneratorApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.apparati.metal.SoulBrazierApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.apparati.metal.TankApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.apparati.metal.VoidChestApparatusRenderer; @@ -21,6 +21,7 @@ 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.TileGenerator; import net.anvilcraft.thaummach.tiles.TileSoulBrazier; import net.anvilcraft.thaummach.tiles.TileVoidChest; import net.anvilcraft.thaummach.tiles.TileVoidInterface; @@ -62,6 +63,7 @@ public class BlockApparatusMetal extends BlockApparatus { public IIcon iconGenerator1; public IIcon iconGenerator2; public IIcon iconGenerator3; + public IIcon iconGenerator4; public IIcon iconSoulBrazierBottom; public IIcon iconSoulBrazierSide; public IIcon iconSoulCrucibleBottom; @@ -108,6 +110,7 @@ public class BlockApparatusMetal extends BlockApparatus { this.iconGenerator1 = reg.registerIcon("thaummach:generator_1"); this.iconGenerator2 = reg.registerIcon("thaummach:generator_2"); this.iconGenerator3 = reg.registerIcon("thaummach:generator_3"); + this.iconGenerator4 = reg.registerIcon("thaummach:generator_4"); this.iconSoulBrazierBottom = reg.registerIcon("thaummach:soul_brazier_bottom"); this.iconSoulBrazierSide = reg.registerIcon("thaummach:soul_brazier_side"); this.iconSoulCrucibleBottom = reg.registerIcon("thaummach:soul_crucible_bottom"); @@ -168,6 +171,9 @@ public class BlockApparatusMetal extends BlockApparatus { case BORE: return BoreApparatusRenderer.INSTANCE; + case GENERATOR: + return GeneratorApparatusRenderer.INSTANCE; + case VOID_CHEST: return VoidChestApparatusRenderer.INSTANCE; @@ -181,7 +187,7 @@ public class BlockApparatusMetal extends BlockApparatus { return TankApparatusRenderer.INSTANCE; default: - return null; + throw new IllegalArgumentException("ALEC"); } } @@ -195,7 +201,7 @@ public class BlockApparatusMetal extends BlockApparatus { } else if (md == MetaVals.ARCANE_FURNACE) { return new TileArcaneFurnace(); } else if (md == MetaVals.GENERATOR) { - //return new TileGenerator(); + return new TileGenerator(); } else if (md == MetaVals.CRYSTALLIZER) { return new TileCrystallizer(); } else if (md == MetaVals.BORE) { @@ -327,11 +333,9 @@ public class BlockApparatusMetal extends BlockApparatus { } else if (meta == MetaVals.SOUL_BRAZIER) { return side == 0 || side == 1 ? this.iconSoulBrazierBottom : this.iconSoulBrazierSide; - } - //else if (meta == 5) { - // return 144; - //} - else if (meta == MetaVals.CRYSTALLIZER) { + } else if (meta == MetaVals.GENERATOR) { + return this.iconGenerator1; + } else if (meta == MetaVals.CRYSTALLIZER) { if (side == 1) { return this.iconCrystallizerTop; } else if (side == 0) { @@ -652,33 +656,27 @@ public class BlockApparatusMetal extends BlockApparatus { } if (meta == MetaVals.GENERATOR) { - // TODO: generator - //TileGenerator tg = (TileGenerator) w.getTileEntity(i, j, k); - //int arcs = 20; - //if (!ModLoader.getMinecraftInstance().gameSettings.fancyGraphics - // || Config.lowGfx) { - // arcs = 10; - //} + TileGenerator tg = (TileGenerator) w.getTileEntity(i, j, k); + arcs = 20; - //arcs = arcs * tg.storedEnergy / tg.energyMax; - //if (w.rand.nextInt(20) < arcs) { - // LightningBolt bolt = new LightningBolt( - // w, - // (double) i + 0.5, - // (double) j + 0.5, - // (double) k + 0.5, - // (double) i + 0.1 + (double) w.rand.nextFloat() * 0.8, - // (double) j + 0.1 + (double) w.rand.nextFloat() * 0.8, - // (double) k + 0.1 + (double) w.rand.nextFloat() * 0.8, - // w.rand.nextLong(), - // 6, - // 9.0F - // ); - // bolt.defaultFractal(); - // bolt.setType(0); - // bolt.setNonLethal(); - // bolt.finalizeBolt(); - //} + arcs = arcs * tg.storedEnergy / tg.energyMax; + if (w.rand.nextInt(20) < arcs) { + FXLightningBolt bolt = new FXLightningBolt( + w, + (double) i + 0.5, + (double) j + 0.5, + (double) k + 0.5, + (double) i + 0.1 + (double) w.rand.nextFloat() * 0.8, + (double) j + 0.1 + (double) w.rand.nextFloat() * 0.8, + (double) k + 0.1 + (double) w.rand.nextFloat() * 0.8, + w.rand.nextLong(), + 6, + 9.0F + ); + bolt.defaultFractal(); + bolt.setType(0); + bolt.finalizeBolt(); + } } if (meta == MetaVals.CRYSTALLIZER) { diff --git a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusWood.java b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusWood.java index e435b3b..06e4a62 100644 --- a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusWood.java +++ b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusWood.java @@ -11,7 +11,7 @@ import net.anvilcraft.thaummach.particles.FXWisp; import net.anvilcraft.thaummach.render.BlockApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.apparati.wood.CondenserApparatusRenderer; -import net.anvilcraft.thaummach.render.apparatus.apparati.wood.RepairerAparatusRenderer; +import net.anvilcraft.thaummach.render.apparatus.apparati.wood.RepairerApparatusRenderer; import net.anvilcraft.thaummach.tiles.TileCondenser; import net.anvilcraft.thaummach.tiles.TileRepairer; import net.minecraft.block.Block; @@ -96,7 +96,7 @@ public class BlockApparatusWood extends BlockApparatus { return CondenserApparatusRenderer.INSTANCE; case REPAIRER: - return RepairerAparatusRenderer.INSTANCE; + return RepairerApparatusRenderer.INSTANCE; default: return null; diff --git a/src/main/java/net/anvilcraft/thaummach/gui/GuiGenerator.java b/src/main/java/net/anvilcraft/thaummach/gui/GuiGenerator.java new file mode 100644 index 0000000..b7cd0f4 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/gui/GuiGenerator.java @@ -0,0 +1,50 @@ +package net.anvilcraft.thaummach.gui; + +import net.anvilcraft.thaummach.tiles.TileGenerator; +import net.anvilcraft.thaummach.utils.UtilsFX; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class GuiGenerator extends GuiScreen { + private TileGenerator generator; + + public GuiGenerator(TileGenerator tileGenerator) { + this.generator = tileGenerator; + } + + @Override + public void drawScreen(int i, int j, float f) { + super.drawScreen(i, j, f); + int xSize = 176; + int ySize = 82; + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + super.mc.renderEngine.bindTexture( + new ResourceLocation("thaummach", "textures/guis/generator.png") + ); + int l = (super.width - xSize) / 2; + int i1 = (super.height - ySize) / 2; + this.drawTexturedModalRect(l, i1, 0, 0, xSize, ySize); + int k1 = (int + ) (46.0F * (float) this.generator.storedEnergy / (float) this.generator.energyMax + ); + this.drawTexturedModalRect(l + 84, i1 + 68 - k1, 176, 46 - k1, 9, k1); + int moon = super.mc.theWorld.getMoonPhase(); + this.drawTexturedModalRect(l + 108, i1 + 41, 192, moon * 8, 8, 8); + + super.mc.renderEngine.bindTexture(TextureMap.locationItemsTexture); + for (int k = 0; k <= 1; k++) { + UtilsFX.renderUpgradeIntoGUI( + this, (int)this.generator.getUpgrades()[k], l + 56, i1 + 25 + 22 * k + ); + } + + super.fontRendererObj.drawString("Thaumic Generator", l + 42, i1 + 5, 0x404040); + } + + @Override + public boolean doesGuiPauseGame() { + return false; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/GeneratorApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/GeneratorApparatusRenderer.java new file mode 100644 index 0000000..a1bc3a9 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/metal/GeneratorApparatusRenderer.java @@ -0,0 +1,95 @@ +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.init.Blocks; +import net.minecraft.world.IBlockAccess; + +public class GeneratorApparatusRenderer implements IApparatusRenderer { + public static final GeneratorApparatusRenderer INSTANCE + = new GeneratorApparatusRenderer(); + + @Override + public void renderApparatus( + IBlockAccess w, + RenderBlocks rb, + int x, + int y, + int z, + Block block_, + int meta, + boolean inv + ) { + BlockApparatusMetal block = (BlockApparatusMetal) block_; + float w2 = 0.125F; + float w4 = 0.25F; + if (block.getRenderBlockPass() == 0 || inv) { + rb.setRenderBounds(w4, 0.0F, w4, 1.0F - w4, w2, 1.0F - w4); + if (inv) { + ApparatusRenderingHelper.drawFaces(rb, block, block.iconGenerator1, true); + } else { + rb.renderStandardBlock(block, x, y, z); + } + + rb.setRenderBounds(w4, 1.0F - w2, w4, 1.0F - w4, 1.0F, 1.0F - w4); + if (inv) { + ApparatusRenderingHelper.drawFaces(rb, block, block.iconGenerator1, true); + } else { + rb.renderStandardBlock(block, x, y, z); + } + + rb.setRenderBounds( + 1.0F - w2, 0.5F - w4, 0.5F - w4, 1.0F, 0.5F + w4, 0.5F + w4 + ); + if (inv) { + ApparatusRenderingHelper.drawFaces(rb, block, block.iconGenerator1, true); + } else { + rb.renderStandardBlock(block, x, y, z); + } + + rb.setRenderBounds(0.0F, 0.5F - w4, 0.5F - w4, w2, 0.5F + w4, 0.5F + w4); + if (inv) { + ApparatusRenderingHelper.drawFaces(rb, block, block.iconGenerator1, true); + } else { + rb.renderStandardBlock(block, x, y, z); + } + + rb.setRenderBounds( + 0.5F - w4, 0.5F - w4, 1.0F - w2, 0.5F + w4, 0.5F + w4, 1.0F + ); + if (inv) { + ApparatusRenderingHelper.drawFaces(rb, block, block.iconGenerator1, true); + } else { + rb.renderStandardBlock(block, x, y, z); + } + + rb.setRenderBounds(0.5F - w4, 0.5F - w4, 0.0F, 0.5F + w4, 0.5F + w4, w2); + if (inv) { + ApparatusRenderingHelper.drawFaces(rb, block, block.iconGenerator1, true); + } else { + rb.renderStandardBlock(block, x, y, z); + } + } + + if (block.getRenderBlockPass() == 1 || inv) { + rb.overrideBlockTexture = null; + rb.setRenderBounds(w2, w2, w2, 1.0F - w2, 1.0F - w2, 1.0F - w2); + if (inv) { + ApparatusRenderingHelper.drawFaces(rb, block, block.iconGenerator4, true); + } else { + rb.renderFaceYNeg(block, x, y, z, block.iconGenerator4); + rb.renderFaceYPos(block, x, y, z, block.iconGenerator4); + rb.renderFaceXNeg(block, x, y, z, block.iconGenerator4); + rb.renderFaceXPos(block, x, y, z, block.iconGenerator4); + rb.renderFaceZNeg(block, x, y, z, block.iconGenerator4); + rb.renderFaceZPos(block, x, y, z, block.iconGenerator4); + } + } + + 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/apparatus/apparati/wood/RepairerAparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/wood/RepairerApparatusRenderer.java similarity index 95% rename from src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/wood/RepairerAparatusRenderer.java rename to src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/wood/RepairerApparatusRenderer.java index 0a33bf9..a5ae96d 100644 --- a/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/wood/RepairerAparatusRenderer.java +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/apparati/wood/RepairerApparatusRenderer.java @@ -9,9 +9,9 @@ import net.minecraft.block.Block; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.world.IBlockAccess; -public class RepairerAparatusRenderer implements IApparatusRenderer { - public static final RepairerAparatusRenderer INSTANCE - = new RepairerAparatusRenderer(); +public class RepairerApparatusRenderer implements IApparatusRenderer { + public static final RepairerApparatusRenderer INSTANCE + = new RepairerApparatusRenderer(); @Override public void renderApparatus( diff --git a/src/main/java/net/anvilcraft/thaummach/render/model/ModelGenCore.java b/src/main/java/net/anvilcraft/thaummach/render/model/ModelGenCore.java new file mode 100644 index 0000000..5eeb462 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/model/ModelGenCore.java @@ -0,0 +1,38 @@ +package net.anvilcraft.thaummach.render.model; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import org.lwjgl.opengl.GL11; + +public class ModelGenCore extends ModelBase { + private ModelRenderer cube; + private ModelRenderer outer = new ModelRenderer(this, "glass"); + + public ModelGenCore(float f) { + this.outer.setTextureOffset(0, 0).addBox(-4.0F, -4.0F, -4.0F, 8, 8, 8); + this.cube = new ModelRenderer(this, "cube"); + this.cube.setTextureOffset(32, 0).addBox(-4.0F, -4.0F, -4.0F, 8, 8, 8); + } + + @Override + public void + render(Entity e, float f, float f1, float f2, float f3, float f4, float f5) { + GL11.glPushMatrix(); + GL11.glScalef(0.8F, 0.8F, 0.8F); + GL11.glTranslatef(0.0F, -1.0F, 0.0F); + GL11.glRotatef(f1, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(60.0F, 0.7071F, 0.0F, 0.7071F); + this.outer.render(f5); + float f6 = 0.75F; + GL11.glScalef(f6, f6, f6); + GL11.glRotatef(60.0F, 0.7071F, 0.0F, 0.7071F); + GL11.glRotatef(f1, 0.0F, 1.0F, 0.0F); + this.outer.render(f5); + GL11.glScalef(f6, f6, f6); + GL11.glRotatef(60.0F, 0.7071F, 0.0F, 0.7071F); + GL11.glRotatef(f1, 0.0F, 1.0F, 0.0F); + this.cube.render(f5); + GL11.glPopMatrix(); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/tile/TileGeneratorRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/tile/TileGeneratorRenderer.java new file mode 100644 index 0000000..3974618 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/tile/TileGeneratorRenderer.java @@ -0,0 +1,37 @@ +package net.anvilcraft.thaummach.render.tile; + +import net.anvilcraft.thaummach.render.model.ModelGenCore; +import net.anvilcraft.thaummach.tiles.TileGenerator; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class TileGeneratorRenderer extends TileEntitySpecialRenderer { + private int modelLoaded = -1; + private ModelGenCore model; + + public void renderCore(TileGenerator gen, double x, double y, double z, float f) { + if (this.modelLoaded != 1) { + this.model = new ModelGenCore(0.0F); + this.modelLoaded = 1; + } + + float f2 = gen.rotation + f; + GL11.glPushMatrix(); + GL11.glTranslatef((float) x + 0.5F, (float) y + 1.3F, (float) z + 0.5F); + this.bindTexture(new ResourceLocation("thaummach", "textures/models/gencore.png") + ); + float f3 = MathHelper.sin(f2 * 0.2F) / 2.0F + 0.5F; + f3 += f3 * f3; + this.model.render(null, 0.0F, f2 * 1.0F, f3 * 0.01F, 0.0F, 0.0F, 0.0625F); + GL11.glPopMatrix(); + } + + @Override + public void + renderTileEntityAt(TileEntity tileentity, double x, double y, double z, float f) { + this.renderCore((TileGenerator) tileentity, x, y, z, f); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileGenerator.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileGenerator.java new file mode 100644 index 0000000..d8f307f --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileGenerator.java @@ -0,0 +1,457 @@ +package net.anvilcraft.thaummach.tiles; + +import dev.tilera.auracore.api.machine.IUpgradable; +import dev.tilera.auracore.api.machine.TileVisUser; +import dev.tilera.auracore.aura.AuraManager; +import ic2.api.energy.event.EnergyTileLoadEvent; +import ic2.api.energy.event.EnergyTileUnloadEvent; +import ic2.api.energy.tile.IEnergySource; +import net.anvilcraft.thaummach.GuiID; +import net.anvilcraft.thaummach.ITileGui; +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.Direction; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.ForgeDirection; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; + +public class TileGenerator + extends TileVisUser implements IEnergySource, IUpgradable, ITileGui { + public float rotation = 0.0F; + public int storedEnergy = 0; + + public int energyMax = 5000; + private int genloop; + private byte[] upgrades = new byte[] { -1, -1 }; + private boolean emitPower = false; + + private boolean isInit = false; + + @Override + public GuiID getGuiID() { + return GuiID.GENERATOR; + } + + public void updateEntity() { + super.updateEntity(); + if (!super.worldObj.isRemote) { + if (!this.isInit) { + this.isInit = true; + + MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this)); + } + + if (this.hasUpgrade((byte) 5)) { + this.energyMax = 10000; + } + + int emit; + int ret; + if (!this.gettingPower()) { + if (this.storedEnergy < this.energyMax) { + float moon = (float) (2 + Math.abs(super.worldObj.getMoonPhase() - 4)) + * 0.2F; + if (this.hasUpgrade((byte) 0)) { + moon += 0.2F; + } + + float mod = this.hasUpgrade((byte) 1) ? 0.8F : 1.0F; + float visperunit = 6.6666666E-4F * mod; + float suck = visperunit + * Math.min( + 75.0F * moon, (float) (this.energyMax - this.storedEnergy) + ); + if (suck > 0.006666667F && this.getExactPureVis(suck)) { + float add = suck * 150.0F; + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + this.storedEnergy += Math.round(add); + } + } + + if (this.storedEnergy > this.energyMax) { + this.storedEnergy = this.energyMax; + } + + emit = 2; + + // === BUILDCRAFT === + //int arcs; + //FXLightningBolt bolt; + //Position ourbp; + //for (ret = 0; ret < 6; ++ret) { + // Orientations o = Orientations.values()[ret]; + // ourbp = new Position(this); + // Position bp = new Position(ourbp); + // bp.orientation = o; + // bp.moveForwards(1.0); + // TileEntity te = super.worldObj.getBlockTileEntity( + // (int) bp.x, (int) bp.y, (int) bp.z + // ); + // if (te != null && te instanceof IPowerReceptor) { + // PowerProvider pp = ((IPowerReceptor) te).getPowerProvider(); + // if (pp != null && pp.preConditions((IPowerReceptor) te) + // && pp.minEnergyReceived <= this.storedEnergy / 3) { + // int energyUsed = Math.min( + // (int) Math.min( + // (float) Math.min( + // pp.maxEnergyReceived, this.storedEnergy / 3 + // ), + // (float) pp.maxEnergyStored - pp.energyStored + // ), + // emit + // ); + // pp.receiveEnergy((float) energyUsed, o); + // this.storedEnergy -= energyUsed * 3; + // emitpower = true; + // arcs = energyUsed / 2; + // if (!ModLoader.getMinecraftInstance() + // .gameSettings.fancyGraphics + // || Config.lowGfx) { + // arcs = energyUsed / 3; + // } + + // if (super.worldObj.rand.nextInt(6) < arcs && energyUsed > 0) + // { + // bolt = new LightningBolt( + // super.worldObj, + // (double) super.xCoord + 0.5, + // (double) super.yCoord + 0.5, + // (double) super.zCoord + 0.5, + // (double) te.xCoord + 0.5, + // (double) te.yCoord + 0.5, + // (double) te.zCoord + 0.5, + // super.worldObj.rand.nextLong(), + // 6, + // 9.0F + // ); + // bolt.defaultFractal(); + // bolt.setType(0); + // bolt.setNonLethal(); + // bolt.finalizeBolt(); + // } + // break; + // } + // } + //} + + // TODO: IC2 + //try { + // if (!this.isAddedToEnergyNet) { + // EnergyNet.getForWorld(super.worldObj).addTileEntity(this); + // this.isAddedToEnergyNet = true; + // } + + // emit = 15; + // if (this.storedEnergy >= emit) { + // this.storedEnergy -= emit; + // } else { + // emit = this.storedEnergy; + // this.storedEnergy = 0; + // } + + // ret = EnergyNet.getForWorld(super.worldObj) + // .emitEnergyFrom(this, emit); + // this.storedEnergy += ret; + // emit -= ret; + // Position ourbp = new Position(this); + + // for (int i = 0; i < 6; ++i) { + // Orientations o = Orientations.values()[i]; + // Position bp = new Position(ourbp); + // bp.orientation = o; + // bp.moveForwards(1.0); + // TileEntity te = super.worldObj.getBlockTileEntity( + // (int) bp.x, (int) bp.y, (int) bp.z + // ); + // if (te != null && te instanceof IEnergyAcceptor) { + // IEnergyAcceptor es = (IEnergyAcceptor) te; + // if (es.isAddedToEnergyNet()) { + // if (emit > 0) { + // emitpower = true; + // } + + // arcs = emit; + // if (!ModLoader.getMinecraftInstance() + // .gameSettings.fancyGraphics + // || Config.lowGfx) { + // arcs = emit / 2; + // } + + // if (super.worldObj.rand.nextInt(45) < arcs) { + // bolt = new LightningBolt( + // super.worldObj, + // (double) super.xCoord + 0.5, + // (double) super.yCoord + 0.5, + // (double) super.zCoord + 0.5, + // (double) te.xCoord + 0.5, + // (double) te.yCoord + 0.5, + // (double) te.zCoord + 0.5, + // super.worldObj.rand.nextLong(), + // 6, + // 9.0F + // ); + // bolt.defaultFractal(); + // bolt.setType(0); + // bolt.setNonLethal(); + // bolt.finalizeBolt(); + // } + // } + // } + // } + //} catch (Exception var17) {} + + // _____ ___ ____ ___ __ _______ _____ + // |_ _/ _ \| _ \ / _ \ _ \ \ / /_ _| ___| + // | || | | | | | | | | (_) \ \ /\ / / | | | |_ + // | || |_| | |_| | |_| |_ \ V V / | | | _| + // |_| \___/|____/ \___/(_) \_/\_/ |_| |_| + //try { + // Class cls = Class.forName("eloraam.core.IBluePowerConnectable"); + // Class bpc = Class.forName("eloraam.core.BluePowerConductor"); + // ourbp = new Position(this); + + // for (int i = 0; i < 6; ++i) { + // Orientations o = Orientations.values()[i]; + // Position bp = new Position(ourbp); + // bp.orientation = o; + // bp.moveForwards(1.0); + // TileEntity te = super.worldObj.getBlockTileEntity( + // (int) bp.x, (int) bp.y, (int) bp.z + // ); + // if (te != null) { + // arcs = Math.min(this.storedEnergy, 8); + // if (arcs < 1) { + // break; + // } + + // try { + // double voltage = (Double + // ) ((Double) bpc.getMethod("getVoltage", (Class[]) null) + // .invoke( + // bpc.cast( + // cls.getMethod( + // "getBlueConductor", (Class[]) null + // ) + // .invoke(cls.cast(te), (Object[]) + // null) + // ), + // (Object[]) null + // )); + // if (!(voltage > 100.0)) { + // bpc.getMethod("applyDirect", Double.TYPE) + // .invoke( + // bpc.cast( + // cls.getMethod( + // "getBlueConductor", (Class[]) + // null + // ) + // .invoke(cls.cast(te), (Object[]) + // null) + // ), + // (double) arcs + // ); + // this.storedEnergy -= arcs; + // emitpower = true; + // int arcs = 2; + // if (!ModLoader.getMinecraftInstance() + // .gameSettings.fancyGraphics + // || Config.lowGfx) { + // arcs = 1; + // } + + // if (super.worldObj.rand.nextInt(45) < arcs) { + // LightningBolt bolt = new LightningBolt( + // super.worldObj, + // (double) super.xCoord + 0.5, + // (double) super.yCoord + 0.5, + // (double) super.zCoord + 0.5, + // (double) te.xCoord + 0.5, + // (double) te.yCoord + 0.5, + // (double) te.zCoord + 0.5, + // super.worldObj.rand.nextLong(), + // 6, + // 9.0F + // ); + // bolt.defaultFractal(); + // bolt.setType(0); + // bolt.setNonLethal(); + // bolt.finalizeBolt(); + // } + // break; + // } + // } catch (Exception var15) {} + // } + // } + //} catch (Exception var16) {} + } + + if (this.genloop == 0 && this.emitPower) { + this.emitPower = false; + super.worldObj.playSoundEffect( + (double) ((float) super.xCoord + 0.5F), + (double) ((float) super.yCoord + 0.5F), + (double) ((float) super.zCoord + 0.5F), + "thaummach:alecloop", + 0.05F, + 1.0F + ); + + AuraManager.addFluxToClosest( + this.worldObj, + this.xCoord, + this.yCoord, + this.zCoord, + new AspectList().add(Aspect.ENERGY, 2) + ); + } + + ++this.genloop; + if (this.genloop >= 70) { + this.genloop = 0; + } + } else { + if (this.rotation == -1.0F) { + this.rotation = (float) super.worldObj.rand.nextInt(360); + } + + ++this.rotation; + if (this.rotation > 360.0F) { + this.rotation -= 360.0F; + } + } + } + + @Override + public void invalidate() { + super.invalidate(); + MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this)); + } + + @Override + public void onChunkUnload() { + super.onChunkUnload(); + MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this)); + } + + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.storedEnergy = nbttagcompound.getShort("Energy"); + this.upgrades = nbttagcompound.getByteArray("upgrades"); + } + + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setShort("Energy", (short) this.storedEnergy); + nbttagcompound.setByteArray("upgrades", this.upgrades); + } + + public boolean emitsEnergyTo(TileEntity receiver, Direction direction) { + return true; + } + + public int getMaxEnergyOutput() { + return 15; + } + + public boolean getConnectable(ForgeDirection face) { + return true; + } + + public boolean canAcceptUpgrade(byte upgrade) { + if (upgrade != 0 && upgrade != 1 && upgrade != 5) { + return false; + } else { + return !this.hasUpgrade(upgrade); + } + } + + public int getUpgradeLimit() { + return 2; + } + + public byte[] getUpgrades() { + return this.upgrades; + } + + public boolean hasUpgrade(byte upgrade) { + if (this.upgrades.length < 1) { + return false; + } else { + for (int a = 0; a < this.getUpgradeLimit(); ++a) { + if (this.upgrades[a] == upgrade) { + return true; + } + } + + return false; + } + } + + public boolean setUpgrade(byte upgrade) { + for (int a = 0; a < this.getUpgradeLimit(); ++a) { + if (this.upgrades[a] < 0 && this.canAcceptUpgrade(upgrade)) { + this.upgrades[a] = upgrade; + return true; + } + } + + return false; + } + + public boolean clearUpgrade(int index) { + if (this.upgrades[index] >= 0) { + this.upgrades[index] = -1; + return true; + } else { + return false; + } + } + + @Override + public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction) { + return true; + } + + @Override + public double getOfferedEnergy() { + return Math.min(this.storedEnergy, 32); + } + + @Override + public void drawEnergy(double amount) { + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + this.emitPower = true; + this.storedEnergy -= amount; + } + + @Override + public int getSourceTier() { + return 1; + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound nbt = pkt.func_148857_g(); + + this.storedEnergy = nbt.getInteger("storedEnergy"); + this.energyMax = nbt.getInteger("energyMax"); + this.upgrades = nbt.getByteArray("upgrades"); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setInteger("storedEnergy", this.storedEnergy); + nbt.setInteger("energyMax", this.energyMax); + nbt.setByteArray("upgrades", this.upgrades); + + return new S35PacketUpdateTileEntity( + this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt + ); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/utils/UtilsFX.java b/src/main/java/net/anvilcraft/thaummach/utils/UtilsFX.java index 75e8090..fbe8b74 100644 --- a/src/main/java/net/anvilcraft/thaummach/utils/UtilsFX.java +++ b/src/main/java/net/anvilcraft/thaummach/utils/UtilsFX.java @@ -3,7 +3,7 @@ package net.anvilcraft.thaummach.utils; import dev.tilera.auracore.client.FXSparkle; import net.anvilcraft.thaummach.TMItems; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.gui.Gui; import net.minecraft.client.renderer.Tessellator; import net.minecraft.world.World; import thaumcraft.client.fx.particles.FXWisp; @@ -279,7 +279,7 @@ public class UtilsFX { * Draws an upgrade into the GuiContainer. */ public static void - renderUpgradeIntoGUI(GuiContainer gui, int upgrade, int x, int y) { + renderUpgradeIntoGUI(Gui gui, int upgrade, int x, int y) { if (upgrade < 0) return; diff --git a/src/main/resources/assets/thaummach/sounds.json b/src/main/resources/assets/thaummach/sounds.json index 97a99d3..53fe8f3 100644 --- a/src/main/resources/assets/thaummach/sounds.json +++ b/src/main/resources/assets/thaummach/sounds.json @@ -53,6 +53,15 @@ } ] }, + "alecloop": { + "category": "block", + "sounds": [ + { + "name": "alecloop", + "stream": false + } + ] + }, "upgrade": { "category": "master", "sounds": [ diff --git a/src/main/resources/assets/thaummach/sounds/alecloop.ogg b/src/main/resources/assets/thaummach/sounds/alecloop.ogg new file mode 100644 index 0000000000000000000000000000000000000000..413281e3790b6d83a38ae511e91c4a17d48b9c63 GIT binary patch literal 20757 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/generator_4.png b/src/main/resources/assets/thaummach/textures/blocks/generator_4.png new file mode 100644 index 0000000000000000000000000000000000000000..16a4a7e42a724187e133de2c53fa94320ec72637 GIT binary patch literal 593 zcmV-X0gA;^q07;V}s})*-7t2WJDO6KK z;CS@RA5C$2boTlm0cAzQ?(;{u>I`6?ccEETNL3m0AjYt5W6~QD;R-5buWvV50@cuf z9B8&~q5b(B&R~pmmcU%MVBN06?F-1#loCc>un<`EprO}cC_17zg5EGlB?Tp}ggBgG z=0z~pOl&-8L9B=vUiMjnPwzis9>v(&yF(sZM8rhrq)n z=bvX8nme1=BKSA&Z9*|s2&8c+fqM6UO-UYnmcR)eH1BSJ<9SG`^ye`N3|HmQXkEv2 z;9$}nAxkn!#|V5sKBIn6NuUIpn8I#MGb zy@S#rp%X&6`Op8kGxK5Qulns4mb~C8ljm8^#QBM~BaFFv*@Td@}i0DfoDYtG`+3ap0 zZQGPFi6aXS>V$SZb~WnPgM*~V`+ek@dt)5e4>GZY2g<)LRJ zze{{@7ZUzg`?19+t)LR8LxLqptkQU=`I;vKiV3X4L8J!V9h8 zDQV)v|J3c@(6N}RgK?2OdHS?F^^~2B)4+c8;^0;mzQ>>@RVu-u|0as-@S1`O){3)R z;u=oXPE39RyWT9r-oVZ{S2SE%HhMTNQPjJK6}Eh~@LBL?IMZtD`N(E|EzeH-Lt8^5 z=ll0Z&z?VLNAwOysc*`3zWBc4nAJdU$dH(l68^p?)8`lj>$xGsZd_{2#xqWI7obog ziUa=hVWrQ9yu-kSJ?Gd)l`J6k|GJLE()p}Ta6t+t$WB^xjzs9DEQ#R;M0m3{im4`V z5e|sI%o4E&U2ORmv?aA7sL30Xe}3+Je4XyS0~WsC2R z$nM7^;l6$LEA+==3r^IrA^P34O;0+fHVF?d|PtpsA^;ME2ug6$3k9<-*R$mzS1O z7Z3Ok2-Tg@bQ33m+k42Oi9>w-yU706V*kDLOA7LOz1uDZiYE1Ztv0>1s3E`Jv0+zu@Vtn8!2b4RMmHao!;tx39#5K@6s2E(2EX3bK0YEkeguWdwVYU@C~(`> zBH(-`ebUplw+H61j6$4=4(acSiP0j10*5zmx^^$^Gv9@2r^_h&o$N&TlTsfW_@-BJ zvfkF}jPP}mc`y8@g36hgrZ>t*0i>o|T6g@;gp6)q{n@j(Exo+LGPxak$;->jzsMjp zQX|W5Ht$~_eZ9sX8+Z1jD<4@k#{sbiqH4aWUkeHh)YQVyvwB-4q@?s=FxanN4>$bh z)f3)79#>ZdTfjTRsj~aXXFbDP_3{sI;0gAtn{@?G2(=O^H#iRT6LcxynhUpkG_E_JxXlvhfaw?5a07aPX*>9Ou;K?qpRc!Qam7Li1 zF47-OZgb39=+*t~exuZ!gG{V1d7cyB~>mp)jO3af@L0o+7hii8vla1;J6-v&J5>^eH&9(z$ZcsPM;Tnwur+JPmz!V&4`BCi`u5&yAP(U{#Luwv8P% zT`FY~XR^}axMl4A8Mly4NV3qY{97;|+D|Kt!~OlaJ3B6thWS5!BsDfRKGqaPxUP+d z(M?|44!F_Ef^)5dGLN&wk!0%o^&JTUI{HpdPCo@V#EO;PE{yZY`jeb3LU(Cp%Xl6j z!<+YiNlSGQc4-XG=-WDQpHs{3k*KJsox5$e3u@whh)F#qxhyz_Q?a<`d_Q6ij#hlO z@S;?330X{F ziAeoschEql!%i!HFR!EHvE

H&0eWfr2#Y9F%7Si4y*Sj8% zcwJcP9tUb<%w~Io+#}u~WzCicH7b*CXd~VJUv_udD}4>`@42Xdb!Dz16DxMubJ^SX z&JDR?C9SvUx`%pK?0RRtKuwKH@N79e>1a+zdRER(ZUxHx;Y5LIB#g_W${%-tTzgAS z+A`in;5r?pz#!npG|<^kP{E2Duta_eUR{uEO{#_5BM zVVAw}V_No(_Or(RH*VlU`zL%&R7egaI@BJZu)h_jJ8}oOx|D$?{k(AWw6`ztb-kjU zXVX#G4>@nYtV3P8IypP%xz5&Zs{3N8V>8EYKB<_ym7N2s8`^bc-iVdIQaYy5GG$lN zWJB7UJ2*M%6D>Wq|65J7;D>3kv9l8G`}s3_Zq7^+PlRr}(bq?o`^+*$@Ju3)C{bkL6;5!0HV+tfGt6{aH_h^e6r2Y_lnswK5 z5|KF;A@F^fZ0;qOQ!nF0rE}%RPTKgBk;x~)s@)hH?<^xH@;h=mtW-=wMD;kk)9C=B zjMrVWo%mAsKmh@P2YMN@@E+IMxd!-nv*cWi70(oZP^(*7ywdL}9mB*lr2@Zsj<)kS zrPiBMT7zAn3#L{aYx(}d!^LKgsgH+cDTcWmrwH`s+*Nw87iy<=-dFaEW$n+CBS!`R z{jl@JVC`T+(Y}ZO_C%S%k1;spF=I7W=#VWo(D?^$L%X#Z`xhym65HKEyXW7D#%)NHk3q*pSrV$w`$uI^Nl)n3$FNQ=SUb#fF-MRaTJ zy|Z-TA$|)w`|2$E7MZ937Y9aTXhHPVfdZ4QrDfJ^Vqz8bS#OSLkw-BboZn%%g-atB7=}#aK!W(e@ ze6tM{0tS(j5z*5UbF-5x$&)nkXqnVsYXyp@$>9Dk2 zCd-Wy_x3uvScqKmRxB&xMZGIxXGAOUvtq_@y6e~{hy+m{webbCT&DtCF<^G(;aB z8AQ)y+5Nt%>5|E<4-uP1`JhS1NjF?j*?jLEz$&Z(UXGu5f{Ij)w$(M*sxQ?R@wdO( zYv&~h#1xZh%+j!P_g8}7+#cUaySW<53^Ke}u}yoWuhJlXQ0UUGFgr#@_TiCPrwQ>K z{nwDMVzUi2y8nje(PRky)0OBTF0n?U`HPK}KSegRa5kmMrx%;+*UT)wwfB!UQ-f@!_<3Y~Mn9h8+jS}>?IJ-VvM{jGtXscgA#ZWK&hFE=`xy1&0)zv5k%Nnph_MHo6Cj?ksBvVPqJoXOR>&PpA#oY6rqbjuoE zREs{-)a;!Pe;SvXS_m1~HVF)FN}*w(t|FnPiJpd_To@$NA?tEFO;wj49335N2+YlB z$?WX8lapZC%WAv1_bV$aW*_fbu+zSReGVsK4p^@o`LN4dk+Za=6RWHDI@5GGcgt$b1DeNxM{ z$YnYMWMpJW*blRtR#}Ihqsq%;-ooL86;dh0&7esJNnCG1qM}8_=MGs|Sah8^wBsBM ztE0PQoDOeLPJG-YS}NxfskTRZwFrxdoHoSX2Q2(QzLs!?)`{!u>nF090A^>+yQAMU zom>mZO={!CmlXhl|ktdfLRyk54W3-<%$8tcRu zC~K{07f(V^;mpwQa0*}Es0XVob|(#w8;c)tCZP~H5~I$=vEzZvU0H(e&E5m4*p z4oNnD{~>9%K(jM{GYcJwvl+B1-?)V~*8>Di7X!^rmU(qHP3fL}ByOC@Hzr%^e(A+uXd-LC^S* z;=S*Y=-)TrW&(CnDM;X}F%`QHkr7jAbV*}cLWTij&t~diP}_XIU%S#t)4ms}~t5qV~o}#2w|GK+XRag!pfTr~m8ZF`b(pTiU^=A+j=#jN-1JMEe7y-@0#Thc9|S zuweUUZ$ZkAUMz9j!As zT{wj!keP(~{$1buQST^k*B9rC!MeBWj^<_};5p37j;8bI}Cj1Jg5v%d7zV69Zo~{&<_kd)PrDV0X)iu{VP>?oK1w#Cg}2%OC6|Oal{t;| zd}zh&$7FNA@t{i8ed+j)U_zwv_jok(7tgoL#o__ROAE z0C%m%vlmIw5tGsAiL1Grxg9&yxzUa)_lv@m?~+~^O|T$u(u092Ei;8~SylYy9MRGm zA}nVs|9L0SC|rCiNaX4q0UMcyuj6RR%(wQki!@R;kL-Kz!|WhQLa7CWh|p34T~exC zSzoGLfCyD8BseHkH3OC^m*m@UfOiDVy_>x4>paP3cswF@e4db(rQf*;m#~eD?x~8d zCQe8Rd1HKyn0hO%L_#tR+uCy4+T6?;9DHtC z@6N--%=|!4tE=5uY#>p_lW8@y;tHIih9SPo67#E941jurO4aKz7z%3cj(^D~p;XKp z3~Jbt|{3|Ir)_hPu9+OO)|zTpnn$5L94_|lw?o~*8{{7yoZmPViK&6k)G z(6OFI$6-Lau^Y*E5Y`7s8t^|xDeS;cYdogy9(Dj{ z&nzu0w2zOEf6vaA2%i1=6*p@?$Zu(Cn$~z;P*6bjo?QyK;w(RE#yVTD94d}cD}{)b zWBoJM_^;#kbxz6k67(<)=}91Jn)A7qO77Ub#Y#QatNpz2LfpmEV~917KwchVR)s58 zc=YIz8{czvbzKI$)t9S@RV-6LbEq;EcSkgJ2@6n1|pE|QCti;c!{zz z9!C(n#ssqbA9ML*K}<|cMJ0+bXM#wXbk(?Bo|p8%xcIuEf%9Q}YvY%sg+{3+))$PT zgeaTszgtFs<`*p*YOC+4PAZW>Rt-x<3Ox`HmLok-L(oeo+}vZ}m%KyG&ByoD$crAils;Cqt6_k;#8<^X|>?FqePAZ<(PnJkko=guL%RH!;RY&pIT z4jt=O?V?&VUy`H~JRpgcU6Q|TM-_OTRg+}7Y?yZ?bB?aN^0DKlC6`-a{P|hjV4nZz zX@D{hhn#;`8NMs5@@P$dBkj|jc>!k6H_={|5$YuP!3PQ=E*AcOrM23)^7VXbZc!oufyTl*!ZNQ@|fgQbnQM}nam z&GmCb0*%%_X`)qFwl|WM%?!98tEmev9CrYvqo!0nQGOGf&8Vqm=f}DTbrxRkTq-Mp z_+oeVDe+)GI~0T-EQ-Hwj>UEIQa~YZTd$(|R^cD^E(4VC=H9zRNfma?R%_9Y9=jcU z#q3lE_8XA0Lf#Hw=Qia|#7kVMCU-P*i+%iCu0@v_KT^;TPp=CA27{f3FkfcdO^Thh z>#c#gQxTLSljkw@SR_-OuC`tA-k+z04QMr~yQD5vSH_e)X03WymbB;u5Viq^+yp}l zV0=!l(RJzH=2&rCtRS$eGt%L$4kQ1+=hdk92A2wfEPN2#mxyf{0PZSq-~doOlG9)`Dv#hsXJcFwlRUlNQDJy z{v@!M*VG(L53!?07J#Jj*Vjisr8my11iJu!DuSyMuVXq%dh(sXiVHIw?j;~l49)*Y z2hCkjqqe%iu$$9nRx|`@Wv#3xU97i#EnFX@V>Z|uwBM=xubR#YVo)Zpp{EuCQt`W2 zDS5Bgo3Xy6-2m~qcP$cKfqUPoNXAdg4la~34ZL^=z^U6}Tr28(K-{DNkzG&pNFc8Z zQCV48@hF@*muc*t>(4!_5r6cx$=+;TGf=f4c4h~^#RXxYB+Ngy{wmuUb3S0sSw|MuPg ibnyR;|GKaoUUSuW-9Ex+sS-{A0gb2HD&>!@g8l=YY89OT literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/models/gencore.png b/src/main/resources/assets/thaummach/textures/models/gencore.png new file mode 100644 index 0000000000000000000000000000000000000000..b32b69b5bdc415679a84bfaabd7dc62d598cc3a9 GIT binary patch literal 1695 zcmbtVdoo zepaWg0N_cs%vQFQqiu6)&7VcKyoC!lN#H^9&K>(`u$&w@ zh;f%t=;W=&_9T&sB&U}JlRZh2!pV~WILTgJYwzTLwM zXw9yLfny_mGaN&nkilDyE91@$mJEx;n1ssDYd8sr>E+yAN=}mX_v4bSd<$ax1EQ?H zX!0AbLdu!acWR$_Y#(o5AiENcaqUepfvH@&b{$`3V?$?N3v{camv4AU$`8^!q!b{z zWqt?~VnC~!$iOUgXE{)8RRK6tV;!p-wRJO4(sqhcO2E9=Is zLUeg;O3agsJ|4C7W4-e-+_ihQRGL^(9=@-b)}JcfisT^L-p_2|=2oYvZqU1PDZ@+o zk3>923^0+#9%$C7!U@oo7HEtZzZKe9T&xm9cpR~i7d+szKZVLeRdGsYTv}h3aTw4K zfsTVR&@^cWIEm}9E@W7v?Vp~Toyt-h7{!Ja;yBjFDrpV}sPjcTO+z!8POB27AGoQT zwcYse0hJQ3qx3#>4MX=V2xhgi^Xlq@N9cZ&Dh9q2QN%J(FybkK94_BmuBTIj_h75L z@yQ{|@aGv4a`0>xWmNZ#ldx<7F&$#0c}1jQoB&h7)yaD!)0wK+Pg14JZt+(`=f!nG z?Z@&JDxj)L8d(>8+s;vJN`)VO4Bf2o5OA+p^)3oHhfG-IcX=SO1vsnrkABxboxA~{n@*D;*}*EEWHuJDMq)=E3NZNiGQ)a8 zkGVuotETw547~DaV)bxVD8C}m3`}mtyMxNn6}{8EQk6B;zi!IgD3L77j?Dh-NYLrC;MKvut%1~5)%e#1J0Ga?&(?Zj^S8^(jw8Xl zefO`_3Sq+CCwqN8dea7r-=oRY*)JXsKQH!*$`;aye&8V&;?r{#cfSlK$x50IJ=4a8 zA5045qJ)>Qt-(PgbpY+Z8e`1%X49ruqkaIqZLik8-0N*| z?0DYTmi*&E-Ph$4dZ_ekZE^YnzL*sUD6JHDeBpravOtNe@w^603M}n^iqU|pAajEQ zt}g^7a^rasg3R>q;=cy{)45G$ZZ!+*Zwvp_