From 780518051650f97230b9022ef151cdc6737b04d9 Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Thu, 1 Jun 2023 18:30:06 +0200 Subject: [PATCH] feat: implement enchanter --- .../net/anvilcraft/thaummach/ClientProxy.java | 7 + .../net/anvilcraft/thaummach/CommonProxy.java | 6 + .../java/net/anvilcraft/thaummach/GuiID.java | 1 + .../thaummach/ThaumicMachinery.java | 2 + .../thaummach/blocks/BlockApparatus.java | 2 + .../thaummach/blocks/BlockApparatusStone.java | 86 ++-- .../container/ContainerEnchanter.java | 87 ++++ .../thaummach/gui/GuiEnchanter.java | 249 ++++++++++ .../packets/PacketEnchanterStart.java | 55 +++ .../SimpleBlockApparatusRenderer.java | 2 + .../render/tile/TileEnchanterRenderer.java | 93 ++++ .../thaummach/tiles/TileEnchanter.java | 457 ++++++++++++++++++ .../textures/blocks/enchanter_side.png | Bin 0 -> 595 bytes .../textures/blocks/enchanter_top.png | Bin 0 -> 384 bytes .../textures/blocks/enchenter_bottom.png | Bin 0 -> 669 bytes .../thaummach/textures/guis/enchanter.png | Bin 0 -> 5434 bytes .../assets/thaummach/textures/models/book.png | Bin 0 -> 15928 bytes 17 files changed, 1016 insertions(+), 31 deletions(-) create mode 100644 src/main/java/net/anvilcraft/thaummach/container/ContainerEnchanter.java create mode 100644 src/main/java/net/anvilcraft/thaummach/gui/GuiEnchanter.java create mode 100644 src/main/java/net/anvilcraft/thaummach/packets/PacketEnchanterStart.java create mode 100644 src/main/java/net/anvilcraft/thaummach/render/tile/TileEnchanterRenderer.java create mode 100644 src/main/java/net/anvilcraft/thaummach/tiles/TileEnchanter.java create mode 100644 src/main/resources/assets/thaummach/textures/blocks/enchanter_side.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/enchanter_top.png create mode 100644 src/main/resources/assets/thaummach/textures/blocks/enchenter_bottom.png create mode 100644 src/main/resources/assets/thaummach/textures/guis/enchanter.png create mode 100644 src/main/resources/assets/thaummach/textures/models/book.png diff --git a/src/main/java/net/anvilcraft/thaummach/ClientProxy.java b/src/main/java/net/anvilcraft/thaummach/ClientProxy.java index f6e7af1..e3498c5 100644 --- a/src/main/java/net/anvilcraft/thaummach/ClientProxy.java +++ b/src/main/java/net/anvilcraft/thaummach/ClientProxy.java @@ -11,6 +11,7 @@ import net.anvilcraft.thaummach.gui.GuiBore; import net.anvilcraft.thaummach.gui.GuiCondenser; import net.anvilcraft.thaummach.gui.GuiCrystallizer; import net.anvilcraft.thaummach.gui.GuiDuplicator; +import net.anvilcraft.thaummach.gui.GuiEnchanter; import net.anvilcraft.thaummach.gui.GuiGenerator; import net.anvilcraft.thaummach.gui.GuiRepairer; import net.anvilcraft.thaummach.gui.GuiSoulBrazier; @@ -23,6 +24,7 @@ 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.TileDuplicatorRenderer; +import net.anvilcraft.thaummach.render.tile.TileEnchanterRenderer; import net.anvilcraft.thaummach.render.tile.TileGeneratorRenderer; import net.anvilcraft.thaummach.render.tile.TileRepairerRenderer; import net.anvilcraft.thaummach.render.tile.TileSealRenderer; @@ -39,6 +41,7 @@ import net.anvilcraft.thaummach.tiles.TileConduitValveAdvanced; import net.anvilcraft.thaummach.tiles.TileCrucible; import net.anvilcraft.thaummach.tiles.TileCrystallizer; import net.anvilcraft.thaummach.tiles.TileDuplicator; +import net.anvilcraft.thaummach.tiles.TileEnchanter; import net.anvilcraft.thaummach.tiles.TileFilter; import net.anvilcraft.thaummach.tiles.TileGenerator; import net.anvilcraft.thaummach.tiles.TilePurifier; @@ -82,6 +85,7 @@ public class ClientProxy extends CommonProxy { ClientRegistry.registerTileEntity(TileConduitPump.class, "conduit_pump", new TileConduitPumpRenderer()); ClientRegistry.registerTileEntity(TileCrystallizer.class, "crystallizer", new TileCrystallizerRenderer()); ClientRegistry.registerTileEntity(TileDuplicator.class, "duplicator", new TileDuplicatorRenderer()); + ClientRegistry.registerTileEntity(TileEnchanter.class, "enchanter", new TileEnchanterRenderer()); ClientRegistry.registerTileEntity(TileGenerator.class, "generator", new TileGeneratorRenderer()); ClientRegistry.registerTileEntity(TileRepairer.class, "repairer", new TileRepairerRenderer()); ClientRegistry.registerTileEntity(TileSeal.class, "seal", new TileSealRenderer()); @@ -110,6 +114,9 @@ public class ClientProxy extends CommonProxy { case DUPLICATOR: return new GuiDuplicator(player.inventory, (TileDuplicator) te); + case ENCHANTER: + return new GuiEnchanter(player.inventory, (TileEnchanter) te); + case GENERATOR: return new GuiGenerator((TileGenerator) te); diff --git a/src/main/java/net/anvilcraft/thaummach/CommonProxy.java b/src/main/java/net/anvilcraft/thaummach/CommonProxy.java index 4afce98..c1f8478 100644 --- a/src/main/java/net/anvilcraft/thaummach/CommonProxy.java +++ b/src/main/java/net/anvilcraft/thaummach/CommonProxy.java @@ -8,6 +8,7 @@ import net.anvilcraft.thaummach.container.ContainerBore; import net.anvilcraft.thaummach.container.ContainerCondenser; import net.anvilcraft.thaummach.container.ContainerCrystallizer; import net.anvilcraft.thaummach.container.ContainerDuplicator; +import net.anvilcraft.thaummach.container.ContainerEnchanter; import net.anvilcraft.thaummach.container.ContainerRepairer; import net.anvilcraft.thaummach.container.ContainerSoulBrazier; import net.anvilcraft.thaummach.container.ContainerVoidChest; @@ -23,6 +24,7 @@ import net.anvilcraft.thaummach.tiles.TileConduitValveAdvanced; import net.anvilcraft.thaummach.tiles.TileCrucible; import net.anvilcraft.thaummach.tiles.TileCrystallizer; import net.anvilcraft.thaummach.tiles.TileDuplicator; +import net.anvilcraft.thaummach.tiles.TileEnchanter; import net.anvilcraft.thaummach.tiles.TileFilter; import net.anvilcraft.thaummach.tiles.TileGenerator; import net.anvilcraft.thaummach.tiles.TilePurifier; @@ -54,6 +56,7 @@ public class CommonProxy implements IGuiHandler { GameRegistry.registerTileEntity(TileCrucible.class, "crucible"); GameRegistry.registerTileEntity(TileCrystallizer.class, "crystallizer"); GameRegistry.registerTileEntity(TileDuplicator.class, "duplicator"); + GameRegistry.registerTileEntity(TileEnchanter.class, "enchanter"); GameRegistry.registerTileEntity(TileFilter.class, "filter"); GameRegistry.registerTileEntity(TileGenerator.class, "generator"); GameRegistry.registerTileEntity(TilePurifier.class, "purifier"); @@ -85,6 +88,9 @@ public class CommonProxy implements IGuiHandler { case DUPLICATOR: return new ContainerDuplicator(player.inventory, (TileDuplicator) te); + case ENCHANTER: + return new ContainerEnchanter(player.inventory, (TileEnchanter) te); + case REPAIRER: return new ContainerRepairer(player.inventory, (TileRepairer) te); diff --git a/src/main/java/net/anvilcraft/thaummach/GuiID.java b/src/main/java/net/anvilcraft/thaummach/GuiID.java index 49f110b..5ca3951 100644 --- a/src/main/java/net/anvilcraft/thaummach/GuiID.java +++ b/src/main/java/net/anvilcraft/thaummach/GuiID.java @@ -6,6 +6,7 @@ public enum GuiID { CONDENSER, CRYSTALLIZER, DUPLICATOR, + ENCHANTER, GENERATOR, REPAIRER, SOUL_BRAZIER, diff --git a/src/main/java/net/anvilcraft/thaummach/ThaumicMachinery.java b/src/main/java/net/anvilcraft/thaummach/ThaumicMachinery.java index 77e3dec..72ee272 100644 --- a/src/main/java/net/anvilcraft/thaummach/ThaumicMachinery.java +++ b/src/main/java/net/anvilcraft/thaummach/ThaumicMachinery.java @@ -17,6 +17,7 @@ import net.anvilcraft.thaummach.packets.PacketChangeVoidInterfaceChannel; import net.anvilcraft.thaummach.packets.PacketChangeVoidInterfaceContainerPage; import net.anvilcraft.thaummach.packets.PacketDuplicatorPress; import net.anvilcraft.thaummach.packets.PacketDuplicatorSetRepeat; +import net.anvilcraft.thaummach.packets.PacketEnchanterStart; import net.anvilcraft.thaummach.packets.PacketFXSparkle; import net.anvilcraft.thaummach.packets.PacketFXWisp; import net.anvilcraft.thaummach.tiles.TileSeal; @@ -46,6 +47,7 @@ public class ThaumicMachinery { channel.registerMessage(new PacketChangeVoidInterfaceContainerPage.Handler(), PacketChangeVoidInterfaceContainerPage.class, pktid++, Side.SERVER); channel.registerMessage(new PacketDuplicatorPress.Handler(), PacketDuplicatorPress.class, pktid++, Side.CLIENT); channel.registerMessage(new PacketDuplicatorSetRepeat.Handler(), PacketDuplicatorSetRepeat.class, pktid++, Side.SERVER); + channel.registerMessage(new PacketEnchanterStart.Handler(), PacketEnchanterStart.class, pktid++, Side.SERVER); channel.registerMessage(new PacketFXSparkle.Handler(), PacketFXSparkle.class, pktid++, Side.CLIENT); channel.registerMessage(new PacketFXWisp.Handler(), PacketFXWisp.class, pktid++, Side.CLIENT); // clang-format on diff --git a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java index 65537ee..8a6d5c0 100644 --- a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java +++ b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatus.java @@ -41,6 +41,8 @@ public abstract class BlockApparatus extends BlockContainer { public abstract IApparatusRenderer getApparatusRenderer(int meta); + public void setBlockBoundsForItemRenderBasedOnMeta(int meta) {} + @Override public int quantityDropped(Random random) { return 1; diff --git a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusStone.java b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusStone.java index 4a824c9..73161eb 100644 --- a/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusStone.java +++ b/src/main/java/net/anvilcraft/thaummach/blocks/BlockApparatusStone.java @@ -9,6 +9,7 @@ import net.anvilcraft.alec.jalec.factories.AlecUnexpectedRuntimeErrorExceptionFa import net.anvilcraft.thaummach.render.BlockApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.IApparatusRenderer; import net.anvilcraft.thaummach.render.apparatus.SimpleBlockApparatusRenderer; +import net.anvilcraft.thaummach.tiles.TileEnchanter; import net.anvilcraft.thaummach.tiles.TileSeal; import net.minecraft.block.Block; import net.minecraft.block.material.Material; @@ -23,9 +24,13 @@ import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; public class BlockApparatusStone extends BlockApparatus { public IIcon iconEldritchStone; + public IIcon iconEnchanterBottom; + public IIcon iconEnchanterSide; + public IIcon iconEnchanterTop; public BlockApparatusStone() { super(Material.rock); @@ -39,6 +44,9 @@ public class BlockApparatusStone extends BlockApparatus { Function reg = (s) -> register.registerIcon("thaummach:" + s); this.iconEldritchStone = reg.apply("eldritch_stone"); + this.iconEnchanterBottom = reg.apply("enchanter_bottom"); + this.iconEnchanterSide = reg.apply("enchanter_side"); + this.iconEnchanterTop = reg.apply("enchanter_top"); } @Override @@ -46,6 +54,7 @@ public class BlockApparatusStone extends BlockApparatus { MetaVals meta = MetaVals.get(meta_); switch (meta) { case ELDRITCH_STONE: + case ENCHANTER: return SimpleBlockApparatusRenderer.INSTANCE; default: @@ -159,6 +168,9 @@ public class BlockApparatusStone extends BlockApparatus { case ELDRITCH_STONE: return null; + case ENCHANTER: + return new TileEnchanter(); + default: throw AlecUnexpectedRuntimeErrorExceptionFactory.PLAIN.createAlecException( "Invalid meta!" @@ -195,11 +207,30 @@ public class BlockApparatusStone extends BlockApparatus { @Override public IIcon getIcon(int i, int j) { MetaVals meta = MetaVals.get(j); + ForgeDirection side = ForgeDirection.getOrientation(i); switch (meta) { case ELDRITCH_STONE: return this.iconEldritchStone; + case ENCHANTER: + switch (side) { + case UP: + return this.iconEnchanterTop; + + case DOWN: + return this.iconEnchanterBottom; + + case NORTH: + case EAST: + case SOUTH: + case WEST: + return this.iconEnchanterSide; + + default: + return null; + } + default: return null; } @@ -386,37 +417,7 @@ public class BlockApparatusStone extends BlockApparatus { @Override public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) { int md = iblockaccess.getBlockMetadata(i, j, k); - if (md == 0) { - if (iblockaccess.getTileEntity(i, j, k) == null) { - return; - } - - int l = ((TileSeal) ((TileSeal) iblockaccess.getTileEntity(i, j, k))).orientation; - float thickness = 0.0625F; - if (l == 0) { - this.setBlockBounds(0.3F, 1.0F - thickness, 0.3F, 0.7F, 1.0F, 0.7F); - } - - if (l == 1) { - this.setBlockBounds(0.3F, 0.0F, 0.3F, 0.7F, thickness, 0.7F); - } - - if (l == 2) { - this.setBlockBounds(0.3F, 0.3F, 1.0F - thickness, 0.7F, 0.7F, 1.0F); - } - - if (l == 3) { - this.setBlockBounds(0.3F, 0.3F, 0.0F, 0.7F, 0.7F, thickness); - } - - if (l == 4) { - this.setBlockBounds(1.0F - thickness, 0.3F, 0.3F, 1.0F, 0.7F, 0.7F); - } - - if (l == 5) { - this.setBlockBounds(0.0F, 0.3F, 0.3F, thickness, 0.7F, 0.7F); - } - } else if (md == 3) { + if (md == 3) { this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); } else { float w1; @@ -466,6 +467,29 @@ public class BlockApparatusStone extends BlockApparatus { return super.getSelectedBoundingBoxFromPool(w, i, j, k); } + @Override + public void setBlockBoundsForItemRenderBasedOnMeta(int meta) { + MetaVals md = MetaVals.get(meta); + if (md == MetaVals.ENCHANTER) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); + } else { + float w1; + if (md != MetaVals.INFUSER && md != MetaVals.INFUSER_DARK) { + if (md == MetaVals.DARKNESS_GENERATOR) { + w1 = 0.0625F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F - w1, 1.0F); + } else if (md == MetaVals.URN) { + this.setBlockBounds(0.125F, 0.0F, 0.125F, 0.875F, 0.5625F, 0.875F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } else { + w1 = 0.0625F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F - w1, 1.0F); + } + } + } + @Override public void setBlockBoundsForItemRender() { this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); diff --git a/src/main/java/net/anvilcraft/thaummach/container/ContainerEnchanter.java b/src/main/java/net/anvilcraft/thaummach/container/ContainerEnchanter.java new file mode 100644 index 0000000..9569626 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/container/ContainerEnchanter.java @@ -0,0 +1,87 @@ +package net.anvilcraft.thaummach.container; + +import net.anvilcraft.thaummach.InventorySlot; +import net.anvilcraft.thaummach.tiles.TileEnchanter; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +public class ContainerEnchanter extends Container { + public TileEnchanter te; + + public ContainerEnchanter(InventoryPlayer inventoryplayer, TileEnchanter tile) { + this.te = tile; + this.addSlotToContainer(new InventorySlot(this.te, 0, 25, 47)); + + int i1; + for (i1 = 0; i1 < 3; ++i1) { + for (int j1 = 0; j1 < 9; ++j1) { + this.addSlotToContainer( + new Slot(inventoryplayer, j1 + i1 * 9 + 9, 8 + j1 * 18, 100 + i1 * 18) + ); + } + } + + for (i1 = 0; i1 < 9; ++i1) { + this.addSlotToContainer(new Slot(inventoryplayer, i1, 8 + i1 * 18, 158)); + } + } + + // TODO: WTF + //@Override + //public void updateCraftingResults() { + // super.updateCraftingResults(); + + // for (int i = 0; i < super.crafters.size(); ++i) { + // ICrafting icrafting = (ICrafting) super.crafters.get(i); + // icrafting.updateCraftingInventoryInfo(this, 0, this.te.enchantLevels[0]); + // icrafting.updateCraftingInventoryInfo(this, 1, this.te.enchantLevels[1]); + // icrafting.updateCraftingInventoryInfo(this, 2, this.te.enchantLevels[2]); + // } + //} + + @Override + public void updateProgressBar(int i, int j) { + if (i >= 0 && i <= 2) { + this.te.enchantLevels[i] = j; + } else { + super.updateProgressBar(i, j); + } + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer pl, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) super.inventorySlots.get(i); + if (slot != null && slot.getHasStack()) { + ItemStack itemstack1 = slot.getStack(); + itemstack = itemstack1.copy(); + if (i != 0) { + return null; + } + + if (!this.mergeItemStack(itemstack1, 1, 37, true)) { + return null; + } + + if (itemstack1.stackSize == 0) { + slot.putStack((ItemStack) null); + } else { + slot.onSlotChanged(); + } + + if (itemstack1.stackSize == itemstack.stackSize) { + return null; + } + } + + return itemstack; + } + + @Override + public boolean canInteractWith(EntityPlayer arg0) { + return true; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/gui/GuiEnchanter.java b/src/main/java/net/anvilcraft/thaummach/gui/GuiEnchanter.java new file mode 100644 index 0000000..9391d7c --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/gui/GuiEnchanter.java @@ -0,0 +1,249 @@ +package net.anvilcraft.thaummach.gui; + +import java.util.Random; + +import net.anvilcraft.thaummach.ThaumicMachinery; +import net.anvilcraft.thaummach.container.ContainerEnchanter; +import net.anvilcraft.thaummach.packets.PacketEnchanterStart; +import net.anvilcraft.thaummach.tiles.TileEnchanter; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.model.ModelBook; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnchantmentNameParts; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.GLU; + +public class GuiEnchanter extends GuiContainer { + private static ModelBook bookModel = new ModelBook(); + private Random field_40230_x = new Random(); + public int field_40227_h; + public float field_40229_i; + public float field_40225_j; + public float field_40226_k; + public float field_40223_l; + public float field_40224_m; + public float field_40221_n; + ItemStack field_40222_o; + public TileEnchanter te; + + public GuiEnchanter(InventoryPlayer inventoryplayer, TileEnchanter tile) { + super(new ContainerEnchanter(inventoryplayer, tile)); + this.te = tile; + super.ySize = 182; + } + + @Override + public void onGuiClosed() { + super.onGuiClosed(); + } + + @Override + protected void drawGuiContainerForegroundLayer(/* useless parameters: */ int alec1, int alec2) { + super.fontRendererObj.drawString("Thaumic Enchanter", 12, 6, 0x404040); + super.fontRendererObj.drawString("Inventory", 8, super.ySize - 96 + 2, 0x404040); + } + + @Override + public void updateScreen() { + super.updateScreen(); + this.doStuff(); + } + + @Override + protected void mouseClicked(int i, int j, int k) { + super.mouseClicked(i, j, k); + int l = (super.width - super.xSize) / 2; + int i1 = (super.height - super.ySize) / 2; + + for (int j1 = 0; j1 < 3; ++j1) { + int k1 = i - (l + 60); + int l1 = j - (i1 + 22 + 19 * j1); + if (k1 >= 0 && l1 >= 0 && k1 < 108 && l1 < 19 && this.te.enchantLevels[j1] > 0 + && this.te.getStackInSlot(0) != null) { + ThaumicMachinery.channel.sendToServer( + new PacketEnchanterStart(this.te.xCoord, this.te.yCoord, this.te.zCoord, j1) + ); + } + } + } + + @Override + protected void drawGuiContainerBackgroundLayer(float f, int i, int j) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.renderEngine.bindTexture( + new ResourceLocation("thaummach", "textures/guis/enchanter.png") + ); + int l = (super.width - super.xSize) / 2; + int i1 = (super.height - super.ySize) / 2; + this.drawTexturedModalRect(l, i1, 0, 0, super.xSize, super.ySize); + int p1 = this.te.getProgressScaled(25); + this.drawTexturedModalRect(l + 21, i1 + 71, 176, 0, p1, 3); + GL11.glPushMatrix(); + GL11.glMatrixMode(5889); + GL11.glPushMatrix(); + GL11.glLoadIdentity(); + ScaledResolution scaledresolution + = new ScaledResolution(super.mc, super.mc.displayWidth, super.mc.displayHeight); + GL11.glViewport( + (scaledresolution.getScaledWidth() - 320) / 2 * scaledresolution.getScaleFactor(), + (scaledresolution.getScaledHeight() - 240) / 2 * scaledresolution.getScaleFactor(), + 320 * scaledresolution.getScaleFactor(), + 240 * scaledresolution.getScaleFactor() + ); + GL11.glTranslatef(-0.34F, 0.28F, 0.0F); + GLU.gluPerspective(90.0F, 1.333333F, 9.0F, 80.0F); + float f1 = 1.0F; + GL11.glMatrixMode(5888); + GL11.glLoadIdentity(); + RenderHelper.enableStandardItemLighting(); + GL11.glTranslatef(0.0F, 3.3F, -16.0F); + GL11.glScalef(f1, f1, f1); + float f2 = 5.0F; + GL11.glScalef(f2, f2, f2); + GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + this.mc.renderEngine.bindTexture( + new ResourceLocation("thaummach", "textures/models/book.png") + ); + GL11.glRotatef(20.0F, 1.0F, 0.0F, 0.0F); + float f3 = this.field_40221_n + (this.field_40224_m - this.field_40221_n) * f; + GL11.glTranslatef((1.0F - f3) * 0.2F, (1.0F - f3) * 0.1F, (1.0F - f3) * 0.25F); + GL11.glRotatef(-(1.0F - f3) * 90.0F - 90.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(180.0F, 1.0F, 0.0F, 0.0F); + float f4 = this.field_40225_j + (this.field_40229_i - this.field_40225_j) * f + 0.25F; + float f5 = this.field_40225_j + (this.field_40229_i - this.field_40225_j) * f + 0.75F; + f4 = (f4 - (float) MathHelper.truncateDoubleToInt((double) f4)) * 1.6F - 0.3F; + f5 = (f5 - (float) MathHelper.truncateDoubleToInt((double) f5)) * 1.6F - 0.3F; + if (f4 < 0.0F) { + f4 = 0.0F; + } + + if (f5 < 0.0F) { + f5 = 0.0F; + } + + if (f4 > 1.0F) { + f4 = 1.0F; + } + + if (f5 > 1.0F) { + f5 = 1.0F; + } + + GL11.glEnable(32826); + bookModel.render((Entity) null, 0.0F, f4, f5, f3, 0.0F, 0.0625F); + GL11.glDisable(32826); + RenderHelper.disableStandardItemLighting(); + GL11.glMatrixMode(5889); + GL11.glViewport(0, 0, super.mc.displayWidth, super.mc.displayHeight); + GL11.glPopMatrix(); + GL11.glMatrixMode(5888); + GL11.glPopMatrix(); + RenderHelper.disableStandardItemLighting(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.renderEngine.bindTexture( + new ResourceLocation("thaummach", "textures/guis/enchanter.png") + ); + EnchantmentNameParts.instance.reseedRandomGenerator(this.te.nameSeed); + + for (int j1 = 0; j1 < 3; ++j1) { + String s = EnchantmentNameParts.instance.generateNewRandomName(); + super.zLevel = 0.0F; + this.mc.renderEngine.bindTexture( + new ResourceLocation("thaummach", "textures/guis/enchanter.png") + ); + int k1 = this.te.enchantLevels[j1] * 2 * (this.te.enchantLevels[j1] / 2); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + if (this.te.enchantLevels[j1] > 0) { + String s1 = "" + k1; + String s2 = "" + this.te.enchantLevels[j1]; + FontRenderer fontrenderer = super.mc.standardGalacticFontRenderer; + int l1 = 6839882; + int i2 = i - (l + 60); + int j2 = j - (i1 + 22 + 19 * j1); + if (i2 >= 0 && j2 >= 0 && i2 < 108 && j2 < 19) { + this.drawTexturedModalRect(l + 60, i1 + 22 + 19 * j1, 0, 220, 108, 19); + l1 = 16777088; + } else { + this.drawTexturedModalRect(l + 60, i1 + 22 + 19 * j1, 0, 182, 108, 19); + } + + if (this.te.enchantmentChoice == j1 && this.te.enchantmentCost > 0 + && this.te.progress < (float) this.te.enchantmentCost) { + this.drawTexturedModalRect(l + 60, i1 + 22 + 19 * j1, 0, 201, 108, 19); + } + + fontrenderer.drawSplitString(s, l + 62, i1 + 24 + 19 * j1, 104, l1); + fontrenderer = super.mc.fontRenderer; + l1 = 10764287; + fontrenderer.drawStringWithShadow( + s1, l + 166 - fontrenderer.getStringWidth(s1), i1 + 24 + 19 * j1 + 8, l1 + ); + l1 = 8453920; + fontrenderer.drawStringWithShadow( + s2, l + 166 - fontrenderer.getStringWidth(s2), i1 + 24 + 19 * j1 - 1, l1 + ); + } + } + } + + /** + * No one knows exactly what this function does. + */ + public void doStuff() { + ItemStack itemstack = super.inventorySlots.getSlot(0).getStack(); + if (!ItemStack.areItemStacksEqual(itemstack, this.field_40222_o)) { + this.field_40222_o = itemstack; + + do { + this.field_40226_k + += (float) (this.field_40230_x.nextInt(4) - this.field_40230_x.nextInt(4)); + } while (this.field_40229_i <= this.field_40226_k + 1.0F + && this.field_40229_i >= this.field_40226_k - 1.0F); + } + + ++this.field_40227_h; + this.field_40225_j = this.field_40229_i; + this.field_40221_n = this.field_40224_m; + boolean flag = false; + + for (int i = 0; i < 3; ++i) { + if (this.te.enchantLevels[i] != 0) { + flag = true; + } + } + + if (flag) { + this.field_40224_m += 0.2F; + } else { + this.field_40224_m -= 0.2F; + } + + if (this.field_40224_m < 0.0F) { + this.field_40224_m = 0.0F; + } + + if (this.field_40224_m > 1.0F) { + this.field_40224_m = 1.0F; + } + + float f = (this.field_40226_k - this.field_40229_i) * 0.4F; + float f1 = 0.2F; + if (f < -f1) { + f = -f1; + } + + if (f > f1) { + f = f1; + } + + this.field_40223_l += (f - this.field_40223_l) * 0.9F; + this.field_40229_i += this.field_40223_l; + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/packets/PacketEnchanterStart.java b/src/main/java/net/anvilcraft/thaummach/packets/PacketEnchanterStart.java new file mode 100644 index 0000000..5122614 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/packets/PacketEnchanterStart.java @@ -0,0 +1,55 @@ +package net.anvilcraft.thaummach.packets; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import io.netty.buffer.ByteBuf; +import net.anvilcraft.thaummach.tiles.TileEnchanter; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +public class PacketEnchanterStart implements IMessage { + int x; + int y; + int z; + int idx; + + public PacketEnchanterStart() {} + + public PacketEnchanterStart(int x, int y, int z, int idx) { + this.x = x; + this.y = y; + this.z = z; + this.idx = idx; + } + + @Override + public void fromBytes(ByteBuf buf) { + this.x = buf.readInt(); + this.y = buf.readInt(); + this.z = buf.readInt(); + this.idx = buf.readInt(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(this.x); + buf.writeInt(this.y); + buf.writeInt(this.z); + buf.writeInt(this.idx); + } + + public static class Handler implements IMessageHandler { + @Override + public IMessage onMessage(PacketEnchanterStart pkt, MessageContext ctx) { + World world = ctx.getServerHandler().playerEntity.worldObj; + TileEntity te = world.getTileEntity(pkt.x, pkt.y, pkt.z); + + if (te instanceof TileEnchanter) { + ((TileEnchanter) te).startEnchantingItem(pkt.idx); + } + + return null; + } + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/render/apparatus/SimpleBlockApparatusRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/apparatus/SimpleBlockApparatusRenderer.java index 4deaeac..0ba9c6a 100644 --- a/src/main/java/net/anvilcraft/thaummach/render/apparatus/SimpleBlockApparatusRenderer.java +++ b/src/main/java/net/anvilcraft/thaummach/render/apparatus/SimpleBlockApparatusRenderer.java @@ -1,5 +1,6 @@ package net.anvilcraft.thaummach.render.apparatus; +import net.anvilcraft.thaummach.blocks.BlockApparatus; import net.minecraft.block.Block; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.world.IBlockAccess; @@ -13,6 +14,7 @@ public class SimpleBlockApparatusRenderer implements IApparatusRenderer { IBlockAccess w, RenderBlocks rb, int x, int y, int z, Block block, int meta, boolean inv ) { if (inv) { + ((BlockApparatus) block).setBlockBoundsForItemRenderBasedOnMeta(meta); rb.setRenderBoundsFromBlock(block); BlockRenderer.drawFaces( rb, diff --git a/src/main/java/net/anvilcraft/thaummach/render/tile/TileEnchanterRenderer.java b/src/main/java/net/anvilcraft/thaummach/render/tile/TileEnchanterRenderer.java new file mode 100644 index 0000000..fd14ba4 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/render/tile/TileEnchanterRenderer.java @@ -0,0 +1,93 @@ +package net.anvilcraft.thaummach.render.tile; + +import net.anvilcraft.thaummach.tiles.TileEnchanter; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelBook; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class TileEnchanterRenderer extends TileEntitySpecialRenderer { + private ModelBook field_40450_a = new ModelBook(); + + private void drawDisk(double x, double y, double z) { + float angle = (float) Minecraft.getMinecraft().thePlayer.ticksExisted % 360.0F; + Tessellator tessellator = Tessellator.instance; + GL11.glPushMatrix(); + GL11.glTranslatef((float) x + 0.5F, (float) y, (float) z + 0.5F); + GL11.glPushMatrix(); + GL11.glRotatef(angle, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(-0.5F, 0.0F, -0.5F); + GL11.glDepthMask(false); + GL11.glEnable(3042); + GL11.glBlendFunc(770, 1); + this.bindTexture(new ResourceLocation("thaummach", "textures/misc/seal5.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tessellator.startDrawingQuads(); + tessellator.setBrightness(200); + tessellator.setColorRGBA_F(1.0F, 0.5F, 1.0F, 1.0F); + tessellator.addVertexWithUV(0.0, 0.0, 1.0, 0.0, 1.0); + tessellator.addVertexWithUV(1.0, 0.0, 1.0, 1.0, 1.0); + tessellator.addVertexWithUV(1.0, 0.0, 0.0, 1.0, 0.0); + tessellator.addVertexWithUV(0.0, 0.0, 0.0, 0.0, 0.0); + tessellator.draw(); + GL11.glDisable(3042); + GL11.glDepthMask(true); + GL11.glPopMatrix(); + GL11.glPopMatrix(); + } + + public void render(TileEnchanter te, double d, double d1, double d2, float f) { + GL11.glPushMatrix(); + GL11.glTranslatef((float) d + 0.5F, (float) d1 + 0.75F, (float) d2 + 0.5F); + float f1 = (float) te.tickCount + f; + GL11.glTranslatef(0.0F, 0.1F + MathHelper.sin(f1 * 0.1F) * 0.01F, 0.0F); + + float f2; + for (f2 = te.bookRotation2 - te.bookRotationPrev; f2 >= 3.141593F; f2 -= 6.283185F) {} + + while (f2 < -3.141593F) { + f2 += 6.283185F; + } + + float f3 = te.bookRotationPrev + f2 * f; + GL11.glRotatef(-f3 * 180.0F / 3.141593F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(80.0F, 0.0F, 0.0F, 1.0F); + this.bindTexture(new ResourceLocation("thaummach", "textures/models/book.png")); + float f4 = te.pageFlipPrev + (te.pageFlip - te.pageFlipPrev) * f + 0.25F; + float f5 = te.pageFlipPrev + (te.pageFlip - te.pageFlipPrev) * f + 0.75F; + f4 = (f4 - (float) MathHelper.truncateDoubleToInt((double) f4)) * 1.6F - 0.3F; + f5 = (f5 - (float) MathHelper.truncateDoubleToInt((double) f5)) * 1.6F - 0.3F; + if (f4 < 0.0F) { + f4 = 0.0F; + } + + if (f5 < 0.0F) { + f5 = 0.0F; + } + + if (f4 > 1.0F) { + f4 = 1.0F; + } + + if (f5 > 1.0F) { + f5 = 1.0F; + } + + float f6 = te.bookSpreadPrev + (te.bookSpread - te.bookSpreadPrev) * f; + this.field_40450_a.render((Entity) null, f1, f4, f5, f6, 0.0F, 0.0625F); + GL11.glPopMatrix(); + if (te.enchantmentChoice != -1 && te.enchantmentCost > 0) { + this.drawDisk(d, d1 + 0.7599999904632568, d2); + } + } + + @Override + public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, float f) { + this.render((TileEnchanter) tileentity, d, d1, d2, f); + } +} diff --git a/src/main/java/net/anvilcraft/thaummach/tiles/TileEnchanter.java b/src/main/java/net/anvilcraft/thaummach/tiles/TileEnchanter.java new file mode 100644 index 0000000..0526e04 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/tiles/TileEnchanter.java @@ -0,0 +1,457 @@ +package net.anvilcraft.thaummach.tiles; + +import java.util.List; +import java.util.Random; + +import dev.tilera.auracore.api.machine.TileVisUser; +import net.anvilcraft.thaummach.GuiID; +import net.anvilcraft.thaummach.ITileGui; +import net.minecraft.enchantment.EnchantmentData; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.common.util.ForgeDirection; + +public class TileEnchanter extends TileVisUser implements ISidedInventory, ITileGui { + public int tickCount; + public float pageFlip; + public float pageFlipPrev; + public float field_40061_d; + public float field_40062_e; + public float bookSpread; + public float bookSpreadPrev; + public float bookRotation2; + public float bookRotationPrev; + public float bookRotation; + private static Random RNG = new Random(); + private ItemStack[] itemStacks = new ItemStack[1]; + public int[] enchantLevels = new int[3]; + public long nameSeed; + private Random rand = new Random(); + public float progress = 0.0F; + public int enchantmentCost = 0; + public int enchantmentChoice = -1; + + @Override + public GuiID getGuiID() { + return GuiID.ENCHANTER; + } + + @Override + public void readFromNBT(NBTTagCompound nbttagcompound) { + super.readFromNBT(nbttagcompound); + this.progress = nbttagcompound.getFloat("progress"); + this.enchantmentCost = nbttagcompound.getInteger("enchantmentCost"); + this.enchantmentChoice = nbttagcompound.getInteger("enchantmentChoice"); + this.enchantLevels[0] = nbttagcompound.getInteger("enchantment0"); + this.enchantLevels[1] = nbttagcompound.getInteger("enchantment1"); + this.enchantLevels[2] = nbttagcompound.getInteger("enchantment2"); + NBTTagList nbttaglist = nbttagcompound.getTagList("Items", 10); + this.itemStacks = new ItemStack[this.getSizeInventory()]; + + for (int i = 0; i < nbttaglist.tagCount(); ++i) { + NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.getCompoundTagAt(i); + byte byte0 = nbttagcompound1.getByte("Slot"); + if (byte0 >= 0 && byte0 < this.itemStacks.length) { + this.itemStacks[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1); + } + } + } + + @Override + public void writeToNBT(NBTTagCompound nbttagcompound) { + super.writeToNBT(nbttagcompound); + nbttagcompound.setFloat("progress", this.progress); + nbttagcompound.setInteger("enchantmentCost", this.enchantmentCost); + nbttagcompound.setInteger("enchantmentChoice", this.enchantmentChoice); + nbttagcompound.setInteger("enchantment0", this.enchantLevels[0]); + nbttagcompound.setInteger("enchantment1", this.enchantLevels[1]); + nbttagcompound.setInteger("enchantment2", this.enchantLevels[2]); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.itemStacks.length; ++i) { + if (this.itemStacks[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte) i); + this.itemStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.appendTag(nbttagcompound1); + } + } + + nbttagcompound.setTag("Items", nbttaglist); + } + + @Override + public void updateEntity() { + super.updateEntity(); + if (this.worldObj.isRemote) { + this.rotateBook(); + + } else { + if (this.progress >= (float) this.enchantmentCost && this.enchantmentChoice != -1) { + this.enchantItem(this.enchantmentChoice); + this.progress = (float) (this.enchantmentCost = 0); + this.enchantmentChoice = -1; + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + } + + if (this.progress<(float) this.enchantmentCost&& this.enchantmentCost> 0 + && this.enchantmentChoice != -1) { + this.progress += this.getAvailablePureVis(10.0F); + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + } + } + } + + public int getProgressScaled(int i) { + return (int) (this.progress * (float) i / (float) this.enchantmentCost); + } + + private void rotateBook() { + this.bookSpreadPrev = this.bookSpread; + this.bookRotationPrev = this.bookRotation2; + EntityPlayer entityplayer = super.worldObj.getClosestPlayer( + (double) ((float) super.xCoord + 0.5F), + (double) ((float) super.yCoord + 0.5F), + (double) ((float) super.zCoord + 0.5F), + 3.0 + ); + if (entityplayer != null) { + double d = entityplayer.posX - (double) ((float) super.xCoord + 0.5F); + double d1 = entityplayer.posZ - (double) ((float) super.zCoord + 0.5F); + this.bookRotation = (float) Math.atan2(d1, d); + this.bookSpread += 0.1F; + if (this.bookSpread < 0.5F || RNG.nextInt(40) == 0) { + float f3 = this.field_40061_d; + + do { + this.field_40061_d += (float) (RNG.nextInt(4) - RNG.nextInt(4)); + } while (f3 == this.field_40061_d); + } + } else { + this.bookRotation += 0.02F; + this.bookSpread -= 0.1F; + } + + while (this.bookRotation2 >= 3.141593F) { + this.bookRotation2 -= 6.283185F; + } + + while (this.bookRotation2 < -3.141593F) { + this.bookRotation2 += 6.283185F; + } + + while (this.bookRotation >= 3.141593F) { + this.bookRotation -= 6.283185F; + } + + while (this.bookRotation < -3.141593F) { + this.bookRotation += 6.283185F; + } + + float f; + for (f = this.bookRotation - this.bookRotation2; f >= 3.141593F; f -= 6.283185F) {} + + while (f < -3.141593F) { + f += 6.283185F; + } + + this.bookRotation2 += f * 0.4F; + if (this.bookSpread < 0.0F) { + this.bookSpread = 0.0F; + } + + if (this.bookSpread > 1.0F) { + this.bookSpread = 1.0F; + } + + ++this.tickCount; + this.pageFlipPrev = this.pageFlip; + float f1 = (this.field_40061_d - this.pageFlip) * 0.4F; + float f2 = 0.2F; + if (f1 < -f2) { + f1 = -f2; + } + + if (f1 > f2) { + f1 = f2; + } + + this.field_40062_e += (f1 - this.field_40062_e) * 0.9F; + this.pageFlip += this.field_40062_e; + } + + @Override + public boolean getConnectable(ForgeDirection face) { + switch (face) { + case NORTH: + case EAST: + case SOUTH: + case WEST: + return true; + + default: + return false; + } + } + + // TODO: AZANOR, WTF + public void onCraftMatrixChanged(IInventory iinventory) { + if (this.worldObj.isRemote) + return; + + this.progress = (float) (this.enchantmentCost = 0); + this.enchantmentChoice = -1; + ItemStack itemstack = iinventory.getStackInSlot(0); + if (itemstack != null && itemstack.isItemEnchantable()) { + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); + this.nameSeed = this.rand.nextLong(); + float power = 0.0f; + + for (int j = -1; j <= 1; ++j) { + for (int k = -1; k <= 1; ++k) { + if ((j != 0 || k != 0) + && this.worldObj.isAirBlock(this.xCoord + k, this.yCoord, this.zCoord + j) + && this.worldObj.isAirBlock( + this.xCoord + k, this.yCoord + 1, this.zCoord + j + )) { + power += ForgeHooks.getEnchantPower( + this.worldObj, this.xCoord + k * 2, this.yCoord, this.zCoord + j * 2 + ); + power += ForgeHooks.getEnchantPower( + this.worldObj, this.xCoord + k * 2, this.yCoord + 1, this.zCoord + j * 2 + ); + if (k != 0 && j != 0) { + power += ForgeHooks.getEnchantPower( + this.worldObj, this.xCoord + k * 2, this.yCoord, this.zCoord + j + ); + power += ForgeHooks.getEnchantPower( + this.worldObj, this.xCoord + k * 2, this.yCoord + 1, this.zCoord + j + ); + power += ForgeHooks.getEnchantPower( + this.worldObj, this.xCoord + k, this.yCoord, this.zCoord + j * 2 + ); + power += ForgeHooks.getEnchantPower( + this.worldObj, this.xCoord + k, this.yCoord + 1, this.zCoord + j * 2 + ); + } + } + } + if (power > 40) { + power = 40; + } + + for (int l = 0; l < 3; ++l) { + this.enchantLevels[l] + = calcItemStackEnchantability(this.rand, l, (int) power, itemstack); + } + } + } else { + for (int i = 0; i < 3; ++i) { + this.enchantLevels[i] = 0; + } + } + } + + public static int + calcItemStackEnchantability(Random par0Random, int par1, int par2, ItemStack par3ItemStack) { + Item var4 = par3ItemStack.getItem(); + int var5 = var4.getItemEnchantability(); + if (var5 <= 0) { + return 0; + } else { + if (par2 > 40) { + par2 = 40; + } + + par2 = 1 + (par2 >> 1) + par0Random.nextInt(par2 + 1); + int var6 = par0Random.nextInt(5) + par2; + return par1 == 0 ? (var6 >> 1) + 1 : (par1 == 1 ? var6 * 2 / 3 + 1 : var6); + } + } + + public boolean startEnchantingItem(int i) { + ItemStack itemstack = this.getStackInSlot(0); + if (this.enchantLevels[i] > 0 && itemstack != null) { + this.enchantmentChoice = i; + this.enchantmentCost = this.enchantLevels[i] * 2 * (this.enchantLevels[i] / 2); + this.progress = 0.0F; + return true; + } else { + this.enchantmentChoice = -1; + return false; + } + } + + public boolean enchantItem(int i) { + ItemStack itemstack = this.itemStacks[0]; + if (this.enchantLevels[i] <= 0 || itemstack == null) { + return false; + } + if (!this.worldObj.isRemote) { + List list = EnchantmentHelper.buildEnchantmentList( + this.rand, itemstack, this.enchantLevels[i] + ); + boolean flag = itemstack.getItem() == Items.book; + if (list != null) { + if (flag) { + itemstack.func_150996_a(Items.enchanted_book); + } + + int j = flag && list.size() > 1 ? this.rand.nextInt(list.size()) : -1; + + for (int k = 0; k < list.size(); ++k) { + EnchantmentData enchantmentdata = (EnchantmentData) list.get(k); + if (!flag || k != j) { + if (flag) { + Items.enchanted_book.addEnchantment(itemstack, enchantmentdata); + } else { + itemstack.addEnchantment( + enchantmentdata.enchantmentobj, enchantmentdata.enchantmentLevel + ); + } + } + } + + this.onCraftMatrixChanged(this); + } + } + + return true; + } + + @Override + public ItemStack decrStackSize(int i, int j) { + this.markDirty(); + if (this.itemStacks[i] != null) { + ItemStack itemstack1; + if (this.itemStacks[i].stackSize <= j) { + itemstack1 = this.itemStacks[i]; + this.itemStacks[i] = null; + + this.onCraftMatrixChanged(this); + return itemstack1; + } else { + itemstack1 = this.itemStacks[i].splitStack(j); + if (this.itemStacks[i].stackSize == 0) { + this.itemStacks[i] = null; + } + + this.onCraftMatrixChanged(this); + return itemstack1; + } + } + return null; + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + this.markDirty(); + this.itemStacks[i] = itemstack; + if (itemstack != null && itemstack.stackSize > this.getInventoryStackLimit()) { + itemstack.stackSize = this.getInventoryStackLimit(); + } + this.onCraftMatrixChanged(this); + } + + @Override + public String getInventoryName() { + return "Thaumic Enchanter"; + } + + @Override + public boolean hasCustomInventoryName() { + return true; + } + + @Override + public int getInventoryStackLimit() { + return 1; + } + + @Override + public int getSizeInventory() { + return this.itemStacks.length; + } + + @Override + public ItemStack getStackInSlot(int i) { + return this.itemStacks[i]; + } + + @Override + public ItemStack getStackInSlotOnClosing(int var1) { + if (this.itemStacks[var1] != null) { + ItemStack var2 = this.itemStacks[var1]; + this.itemStacks[var1] = null; + return var2; + } else { + return null; + } + } + + @Override + public void closeInventory() {} + + @Override + public void openInventory() {} + + @Override + public boolean isItemValidForSlot(int slot, ItemStack stack) { + return stack.isItemEnchantable(); + } + + @Override + public boolean isUseableByPlayer(EntityPlayer arg0) { + return true; + } + + @Override + public boolean canExtractItem(int arg0, ItemStack arg1, int arg2) { + return arg1.getEnchantmentTagList() != null; + } + + @Override + public boolean canInsertItem(int slot, ItemStack stack, int side) { + return this.isItemValidForSlot(slot, stack); + } + + @Override + public int[] getAccessibleSlotsFromSide(int arg0) { + return new int[] { 0 }; + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setFloat("progress", this.progress); + nbt.setInteger("enchantmentCost", this.enchantmentCost); + nbt.setInteger("enchantmentChoice", this.enchantmentChoice); + nbt.setIntArray("enchantLevels", this.enchantLevels); + + return new S35PacketUpdateTileEntity( + this.xCoord, this.yCoord, this.zCoord, this.getBlockMetadata(), nbt + ); + } + + @Override + public void onDataPacket(NetworkManager arg0, S35PacketUpdateTileEntity pkt) { + NBTTagCompound nbt = pkt.func_148857_g(); + + this.progress = nbt.getFloat("progress"); + this.enchantmentCost = nbt.getInteger("enchantmentCost"); + this.enchantmentChoice = nbt.getInteger("enchantmentChoice"); + this.enchantLevels = nbt.getIntArray("enchantLevels"); + } +} diff --git a/src/main/resources/assets/thaummach/textures/blocks/enchanter_side.png b/src/main/resources/assets/thaummach/textures/blocks/enchanter_side.png new file mode 100644 index 0000000000000000000000000000000000000000..eb7fa0a6cf60a74b3c8e897d13cd2223084618fa GIT binary patch literal 595 zcmV-Z0<8UsP)vi#n?f4_I{cdRH1+(#VTQ~rMe)~;_B!u82$hyaf-cJcHd!KdaMtiHoUo|7$g z2yTAc(R5(0|3+=DNg z<;eVKyjNCRtS%u{Q-W?gmtBl*5tu8(LZyy_;pf{vfoj#iF$JJvLJ$N2I-L%L5b!(? zS(ee#mg=Uv%iuV!i3?G-VazcXmKrTb7=|>0g>9K?b$gMV*Dy)`m|_~0iaX0Q2nxm+ z!E;?(Z%%DSy4DJ7E6;Fobw+1ONjzD7j?2jqQE~;ozWkO}W98@dE@Bx`b*E@RBQf1V zlkk%Kwul|M&0eGZz-(<{2zSwY^l5YL19kJA76$PlL0)b&4N($_POSr1D<@1^^of^-1vZ&P@OS002ovPDHLkV1izf5nTWP literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/blocks/enchanter_top.png b/src/main/resources/assets/thaummach/textures/blocks/enchanter_top.png new file mode 100644 index 0000000000000000000000000000000000000000..3238a7fe514b1ef471f83a7c929c6b1328c8580c GIT binary patch literal 384 zcmV-`0e}99P)r8NWGvEbq z1x#==@N0l8U}7KUzFGQ)0puo9@kAbR1IF*5F9(_IyN=v|0g`Av#&c*5_pfZpj eNKM`V0R{juo`q#MOJ$D$0000T%=F~T z;_Z|V!jMvG9&A7Vdh!YBTrP~!y~T$$)&T}NiWey*3A-S49z_fwV~Fnu&gIrte4h!C zhkk%8Qd$cNxo3)v5SEYvZ$blz7)z`*N=e3I^h1clRmwa-9i@VhDr4sM=H7pQj=mo# zC3d#<55K*avY-?^{;~&13WB64#!xq$pQPz*kqrlIW3$sV43BAj8V&iD5?&oKZG`Tmk^r?UX5xvA(~RH zH3h{q8^B_%rB^D($edd;A#~0gEk>{oX~c2doEIadOo{aHH%%v;kA+Bacg|7@yCi0} zv-K3(2+25~v>WSATYv-X2__FH2A7MJF`wF+UHYr6we`3KwUE6*_crQ;C%^q_<>K}F z!=%z&@zziCLr8Ac+R_xpSkHs^U{!Y;uUc^jnBL;!vWHf3^Is<>j#tOLf3`m~&-3$} zTf$%*Kj^(F*Bg^6R}EI;9P?jiv4oP-^mDo1e+3u-3`A79<_nKI00000NkvXXu0mjf D;o2)f literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/guis/enchanter.png b/src/main/resources/assets/thaummach/textures/guis/enchanter.png new file mode 100644 index 0000000000000000000000000000000000000000..dcaa9353909167eb40864251dd54fd761a255717 GIT binary patch literal 5434 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 DB?6aR literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/models/book.png b/src/main/resources/assets/thaummach/textures/models/book.png new file mode 100644 index 0000000000000000000000000000000000000000..0e4c765a419bce7a85521ad07d3e145c72951f98 GIT binary patch literal 15928 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 XA{X21tNNc;ydh*Ize`k$8HM~0KvG0z literal 0 HcmV?d00001