From c81bd4f7465e926c19e7ef6d5cef433bdf15f7c0 Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Fri, 18 Nov 2022 20:08:58 +0100 Subject: [PATCH] fix: alembic and infusion crafter work now --- .../classiccasting/ClassicCasting.java | 10 + .../classiccasting/ClientProxy.java | 33 ++ .../classiccasting/CommonProxy.java | 28 +- .../anvilcraft/classiccasting/GuiType.java | 12 + .../anvilcraft/classiccasting/UtilsFX.java | 293 ++++++++++++++++++ .../classiccasting/WandManager.java | 119 ++++--- .../classiccasting/blocks/BlockAlembic.java | 19 +- .../blocks/BlockInfusionWorkbench.java | 50 ++- .../container/ContainerInfusionWorkbench.java | 186 +++++++++++ .../SlotCraftingInfusionWorkbench.java | 96 ++++++ .../classiccasting/container/SlotWand.java | 31 ++ .../gui/GuiInfusionWorkbench.java | 204 ++++++++++++ .../items/wands/ItemWandCasting.java | 13 +- .../recipes/InfusionCraftingManager.java | 75 +++++ .../render/BlockAlembicRenderer.java | 73 +++++ .../BlockInfusionWorkbenchRenderer.java | 90 ++++++ .../render/TileInfusionWorkbenchRenderer.java | 75 +++++ .../classiccasting/tiles/TileAlembic.java | 123 ++++++-- .../tiles/TileInfusionWorkbench.java | 40 +-- .../assets/classiccasting/lang/en_US.lang | 1 + .../textures/blocks/animatedglow.png | Bin 0 -> 5229 bytes .../textures/blocks/animatedglow.png.mcmeta | 45 +++ .../textures/blocks/infusion1.png | Bin 0 -> 797 bytes .../textures/blocks/infusion2.png | Bin 0 -> 791 bytes .../textures/blocks/infusion3.png | Bin 0 -> 806 bytes .../textures/blocks/infusion4.png | Bin 0 -> 830 bytes .../textures/blocks/infusion5.png | Bin 0 -> 837 bytes .../textures/blocks/infusion6.png | Bin 0 -> 833 bytes .../textures/blocks/infusionbase.png | Bin 0 -> 768 bytes .../textures/gui/gui_infusionworkbench.png | Bin 0 -> 19989 bytes 30 files changed, 1498 insertions(+), 118 deletions(-) create mode 100644 src/main/java/net/anvilcraft/classiccasting/GuiType.java create mode 100644 src/main/java/net/anvilcraft/classiccasting/UtilsFX.java create mode 100644 src/main/java/net/anvilcraft/classiccasting/container/ContainerInfusionWorkbench.java create mode 100644 src/main/java/net/anvilcraft/classiccasting/container/SlotCraftingInfusionWorkbench.java create mode 100644 src/main/java/net/anvilcraft/classiccasting/container/SlotWand.java create mode 100644 src/main/java/net/anvilcraft/classiccasting/gui/GuiInfusionWorkbench.java create mode 100644 src/main/java/net/anvilcraft/classiccasting/recipes/InfusionCraftingManager.java create mode 100644 src/main/java/net/anvilcraft/classiccasting/render/BlockAlembicRenderer.java create mode 100644 src/main/java/net/anvilcraft/classiccasting/render/BlockInfusionWorkbenchRenderer.java create mode 100644 src/main/java/net/anvilcraft/classiccasting/render/TileInfusionWorkbenchRenderer.java create mode 100644 src/main/resources/assets/classiccasting/textures/blocks/animatedglow.png create mode 100644 src/main/resources/assets/classiccasting/textures/blocks/animatedglow.png.mcmeta create mode 100644 src/main/resources/assets/classiccasting/textures/blocks/infusion1.png create mode 100644 src/main/resources/assets/classiccasting/textures/blocks/infusion2.png create mode 100644 src/main/resources/assets/classiccasting/textures/blocks/infusion3.png create mode 100644 src/main/resources/assets/classiccasting/textures/blocks/infusion4.png create mode 100644 src/main/resources/assets/classiccasting/textures/blocks/infusion5.png create mode 100644 src/main/resources/assets/classiccasting/textures/blocks/infusion6.png create mode 100644 src/main/resources/assets/classiccasting/textures/blocks/infusionbase.png create mode 100644 src/main/resources/assets/classiccasting/textures/gui/gui_infusionworkbench.png diff --git a/src/main/java/net/anvilcraft/classiccasting/ClassicCasting.java b/src/main/java/net/anvilcraft/classiccasting/ClassicCasting.java index 728a684..c63b6da 100644 --- a/src/main/java/net/anvilcraft/classiccasting/ClassicCasting.java +++ b/src/main/java/net/anvilcraft/classiccasting/ClassicCasting.java @@ -2,7 +2,9 @@ package net.anvilcraft.classiccasting; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.network.NetworkRegistry; @Mod( modid = "classiccasting", @@ -11,6 +13,9 @@ import cpw.mods.fml.common.event.FMLPreInitializationEvent; dependencies = "required-after:Thaumcraft" ) public class ClassicCasting { + @Mod.Instance + public static ClassicCasting INSTANCE; + @SidedProxy( modId = "classiccasting", clientSide = "net.anvilcraft.classiccasting.ClientProxy", @@ -28,4 +33,9 @@ public class ClassicCasting { proxy.preInit(); } + + @Mod.EventHandler + public void init(FMLInitializationEvent ev) { + NetworkRegistry.INSTANCE.registerGuiHandler(this, proxy); + } } diff --git a/src/main/java/net/anvilcraft/classiccasting/ClientProxy.java b/src/main/java/net/anvilcraft/classiccasting/ClientProxy.java index 19f7394..6b47226 100644 --- a/src/main/java/net/anvilcraft/classiccasting/ClientProxy.java +++ b/src/main/java/net/anvilcraft/classiccasting/ClientProxy.java @@ -1,9 +1,17 @@ package net.anvilcraft.classiccasting; import cpw.mods.fml.client.registry.ClientRegistry; +import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.common.FMLCommonHandler; +import net.anvilcraft.classiccasting.gui.GuiInfusionWorkbench; +import net.anvilcraft.classiccasting.render.BlockAlembicRenderer; +import net.anvilcraft.classiccasting.render.BlockInfusionWorkbenchRenderer; import net.anvilcraft.classiccasting.render.TileAlembicRenderer; +import net.anvilcraft.classiccasting.render.TileInfusionWorkbenchRenderer; import net.anvilcraft.classiccasting.tiles.TileAlembic; +import net.anvilcraft.classiccasting.tiles.TileInfusionWorkbench; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; public class ClientProxy extends CommonProxy { @Override @@ -11,6 +19,12 @@ public class ClientProxy extends CommonProxy { super.preInit(); FMLCommonHandler.instance().bus().register(new GuiTicker()); + + BlockAlembicRenderer.RI = RenderingRegistry.getNextAvailableRenderId(); + RenderingRegistry.registerBlockHandler(new BlockAlembicRenderer()); + + BlockInfusionWorkbenchRenderer.RI = RenderingRegistry.getNextAvailableRenderId(); + RenderingRegistry.registerBlockHandler(new BlockInfusionWorkbenchRenderer()); } @Override @@ -18,5 +32,24 @@ public class ClientProxy extends CommonProxy { ClientRegistry.registerTileEntity( TileAlembic.class, "alembic", new TileAlembicRenderer() ); + ClientRegistry.registerTileEntity( + TileInfusionWorkbench.class, + "infusionWorkbench", + new TileInfusionWorkbenchRenderer() + ); + } + + @Override + public Object + getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + switch (GuiType.get(id)) { + case INFUSION_WORKBENCH: + return new GuiInfusionWorkbench( + player.inventory, (TileInfusionWorkbench) world.getTileEntity(x, y, z) + ); + + default: + return null; + } } } diff --git a/src/main/java/net/anvilcraft/classiccasting/CommonProxy.java b/src/main/java/net/anvilcraft/classiccasting/CommonProxy.java index 4333001..0931e1f 100644 --- a/src/main/java/net/anvilcraft/classiccasting/CommonProxy.java +++ b/src/main/java/net/anvilcraft/classiccasting/CommonProxy.java @@ -1,10 +1,15 @@ package net.anvilcraft.classiccasting; import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.network.IGuiHandler; import cpw.mods.fml.common.registry.GameRegistry; +import net.anvilcraft.classiccasting.container.ContainerInfusionWorkbench; import net.anvilcraft.classiccasting.tiles.TileAlembic; +import net.anvilcraft.classiccasting.tiles.TileInfusionWorkbench; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; -public class CommonProxy { +public class CommonProxy implements IGuiHandler { public void preInit() { FMLCommonHandler.instance().bus().register(new WorldTicker()); } @@ -15,5 +20,26 @@ public class CommonProxy { public void registerTileEntities() { GameRegistry.registerTileEntity(TileAlembic.class, "alembic"); + GameRegistry.registerTileEntity(TileInfusionWorkbench.class, "infusionWorkbench"); + } + + @Override + public Object + getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + switch (GuiType.get(id)) { + case INFUSION_WORKBENCH: + return new ContainerInfusionWorkbench( + player.inventory, (TileInfusionWorkbench) world.getTileEntity(x, y, z) + ); + + default: + return null; + } + } + + @Override + public Object + getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { + return null; } } diff --git a/src/main/java/net/anvilcraft/classiccasting/GuiType.java b/src/main/java/net/anvilcraft/classiccasting/GuiType.java new file mode 100644 index 0000000..2b91017 --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/GuiType.java @@ -0,0 +1,12 @@ +package net.anvilcraft.classiccasting; + +public enum GuiType { + INFUSION_WORKBENCH; + + public static GuiType get(int id) { + if (id < 0 || id >= GuiType.values().length) + return null; + + return GuiType.values()[id]; + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/UtilsFX.java b/src/main/java/net/anvilcraft/classiccasting/UtilsFX.java new file mode 100644 index 0000000..2d2ade9 --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/UtilsFX.java @@ -0,0 +1,293 @@ +package net.anvilcraft.classiccasting; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class UtilsFX { + public static void render3DItem( + final ItemStack par2ItemStack, + final int par3, + final float scale, + final int brightness + ) { + final Minecraft mc = Minecraft.getMinecraft(); + GL11.glPushMatrix(); + Block block = null; + if (par2ItemStack.getItem() instanceof ItemBlock) { + block = Block.getBlockFromItem(par2ItemStack.getItem()); + } + if (block != null && par2ItemStack.getItemSpriteNumber() == 0 + && RenderBlocks.renderItemIn3d(block.getRenderType())) { + mc.renderEngine.bindTexture(TextureMap.locationBlocksTexture); + RenderBlocks.getInstance().renderBlockAsItem( + block, par2ItemStack.getItemDamage(), 1.0f + ); + } else { + final IIcon icon = Minecraft.getMinecraft().renderViewEntity.getItemIcon( + par2ItemStack, par3 + ); + if (icon == null) { + GL11.glPopMatrix(); + return; + } + if (par2ItemStack.getItemSpriteNumber() == 0) { + mc.renderEngine.bindTexture(TextureMap.locationBlocksTexture); + } else { + mc.renderEngine.bindTexture(TextureMap.locationItemsTexture); + } + final Tessellator tessellator = Tessellator.instance; + final float f = icon.getMinU(); + final float f2 = icon.getMaxU(); + final float f3 = icon.getMinV(); + final float f4 = icon.getMaxV(); + GL11.glEnable(32826); + final float f7 = scale; + GL11.glScalef(f7, f7, f7); + renderItemIn2D( + tessellator, + f2, + f3, + f, + f4, + icon.getIconWidth(), + icon.getIconHeight(), + 0.0625f, + brightness + ); + if (par2ItemStack != null && par2ItemStack.hasEffect(0) && par3 == 0) { + GL11.glDepthFunc(514); + GL11.glDisable(2896); + // TODO: WTF + mc.renderEngine.bindTexture(new ResourceLocation("%blur%/misc/glint.png") + ); + GL11.glEnable(3042); + GL11.glBlendFunc(768, 1); + final float f8 = 0.76f; + GL11.glColor4f(0.5f * f8, 0.25f * f8, 0.8f * f8, 1.0f); + GL11.glMatrixMode(5890); + GL11.glPushMatrix(); + final float f9 = 0.125f; + GL11.glScalef(f9, f9, f9); + float f10 = Minecraft.getSystemTime() % 3000L / 3000.0f * 8.0f; + GL11.glTranslatef(f10, 0.0f, 0.0f); + GL11.glRotatef(-50.0f, 0.0f, 0.0f, 1.0f); + renderItemIn2D( + tessellator, 0.0f, 0.0f, 1.0f, 1.0f, 256, 256, 0.0625f, brightness + ); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glScalef(f9, f9, f9); + f10 = Minecraft.getSystemTime() % 4873L / 4873.0f * 8.0f; + GL11.glTranslatef(-f10, 0.0f, 0.0f); + GL11.glRotatef(10.0f, 0.0f, 0.0f, 1.0f); + renderItemIn2D( + tessellator, 0.0f, 0.0f, 1.0f, 1.0f, 256, 256, 0.0625f, brightness + ); + GL11.glPopMatrix(); + GL11.glMatrixMode(5888); + GL11.glDisable(3042); + GL11.glEnable(2896); + GL11.glDepthFunc(515); + } + GL11.glDisable(32826); + } + GL11.glPopMatrix(); + } + + public static void renderItemIn2D( + Tessellator tes, + float p_78439_1_, + float p_78439_2_, + float p_78439_3_, + float p_78439_4_, + int p_78439_5_, + int p_78439_6_, + float p_78439_7_, + int brightness + ) { + tes.startDrawingQuads(); + tes.setBrightness(brightness); + tes.setNormal(0.0F, 0.0F, 1.0F); + tes.addVertexWithUV( + 0.0D, 0.0D, 0.0D, (double) p_78439_1_, (double) p_78439_4_ + ); + tes.addVertexWithUV( + 1.0D, 0.0D, 0.0D, (double) p_78439_3_, (double) p_78439_4_ + ); + tes.addVertexWithUV( + 1.0D, 1.0D, 0.0D, (double) p_78439_3_, (double) p_78439_2_ + ); + tes.addVertexWithUV( + 0.0D, 1.0D, 0.0D, (double) p_78439_1_, (double) p_78439_2_ + ); + tes.draw(); + tes.startDrawingQuads(); + tes.setBrightness(brightness); + tes.setNormal(0.0F, 0.0F, -1.0F); + tes.addVertexWithUV( + 0.0D, + 1.0D, + (double) (0.0F - p_78439_7_), + (double) p_78439_1_, + (double) p_78439_2_ + ); + tes.addVertexWithUV( + 1.0D, + 1.0D, + (double) (0.0F - p_78439_7_), + (double) p_78439_3_, + (double) p_78439_2_ + ); + tes.addVertexWithUV( + 1.0D, + 0.0D, + (double) (0.0F - p_78439_7_), + (double) p_78439_3_, + (double) p_78439_4_ + ); + tes.addVertexWithUV( + 0.0D, + 0.0D, + (double) (0.0F - p_78439_7_), + (double) p_78439_1_, + (double) p_78439_4_ + ); + tes.draw(); + float f5 = 0.5F * (p_78439_1_ - p_78439_3_) / (float) p_78439_5_; + float f6 = 0.5F * (p_78439_4_ - p_78439_2_) / (float) p_78439_6_; + tes.startDrawingQuads(); + tes.setBrightness(brightness); + tes.setNormal(-1.0F, 0.0F, 0.0F); + int k; + float f7; + float f8; + + for (k = 0; k < p_78439_5_; ++k) { + f7 = (float) k / (float) p_78439_5_; + f8 = p_78439_1_ + (p_78439_3_ - p_78439_1_) * f7 - f5; + tes.addVertexWithUV( + (double) f7, + 0.0D, + (double) (0.0F - p_78439_7_), + (double) f8, + (double) p_78439_4_ + ); + tes.addVertexWithUV( + (double) f7, 0.0D, 0.0D, (double) f8, (double) p_78439_4_ + ); + tes.addVertexWithUV( + (double) f7, 1.0D, 0.0D, (double) f8, (double) p_78439_2_ + ); + tes.addVertexWithUV( + (double) f7, + 1.0D, + (double) (0.0F - p_78439_7_), + (double) f8, + (double) p_78439_2_ + ); + } + + tes.draw(); + tes.startDrawingQuads(); + tes.setBrightness(brightness); + tes.setNormal(1.0F, 0.0F, 0.0F); + float f9; + + for (k = 0; k < p_78439_5_; ++k) { + f7 = (float) k / (float) p_78439_5_; + f8 = p_78439_1_ + (p_78439_3_ - p_78439_1_) * f7 - f5; + f9 = f7 + 1.0F / (float) p_78439_5_; + tes.addVertexWithUV( + (double) f9, + 1.0D, + (double) (0.0F - p_78439_7_), + (double) f8, + (double) p_78439_2_ + ); + tes.addVertexWithUV( + (double) f9, 1.0D, 0.0D, (double) f8, (double) p_78439_2_ + ); + tes.addVertexWithUV( + (double) f9, 0.0D, 0.0D, (double) f8, (double) p_78439_4_ + ); + tes.addVertexWithUV( + (double) f9, + 0.0D, + (double) (0.0F - p_78439_7_), + (double) f8, + (double) p_78439_4_ + ); + } + + tes.draw(); + tes.startDrawingQuads(); + tes.setBrightness(brightness); + tes.setNormal(0.0F, 1.0F, 0.0F); + + for (k = 0; k < p_78439_6_; ++k) { + f7 = (float) k / (float) p_78439_6_; + f8 = p_78439_4_ + (p_78439_2_ - p_78439_4_) * f7 - f6; + f9 = f7 + 1.0F / (float) p_78439_6_; + tes.addVertexWithUV( + 0.0D, (double) f9, 0.0D, (double) p_78439_1_, (double) f8 + ); + tes.addVertexWithUV( + 1.0D, (double) f9, 0.0D, (double) p_78439_3_, (double) f8 + ); + tes.addVertexWithUV( + 1.0D, + (double) f9, + (double) (0.0F - p_78439_7_), + (double) p_78439_3_, + (double) f8 + ); + tes.addVertexWithUV( + 0.0D, + (double) f9, + (double) (0.0F - p_78439_7_), + (double) p_78439_1_, + (double) f8 + ); + } + + tes.draw(); + tes.startDrawingQuads(); + tes.setBrightness(brightness); + tes.setNormal(0.0F, -1.0F, 0.0F); + + for (k = 0; k < p_78439_6_; ++k) { + f7 = (float) k / (float) p_78439_6_; + f8 = p_78439_4_ + (p_78439_2_ - p_78439_4_) * f7 - f6; + tes.addVertexWithUV( + 1.0D, (double) f7, 0.0D, (double) p_78439_3_, (double) f8 + ); + tes.addVertexWithUV( + 0.0D, (double) f7, 0.0D, (double) p_78439_1_, (double) f8 + ); + tes.addVertexWithUV( + 0.0D, + (double) f7, + (double) (0.0F - p_78439_7_), + (double) p_78439_1_, + (double) f8 + ); + tes.addVertexWithUV( + 1.0D, + (double) f7, + (double) (0.0F - p_78439_7_), + (double) p_78439_3_, + (double) f8 + ); + } + + tes.draw(); + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/WandManager.java b/src/main/java/net/anvilcraft/classiccasting/WandManager.java index 9a2bd37..edfa701 100644 --- a/src/main/java/net/anvilcraft/classiccasting/WandManager.java +++ b/src/main/java/net/anvilcraft/classiccasting/WandManager.java @@ -2,6 +2,7 @@ package net.anvilcraft.classiccasting; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import cpw.mods.fml.common.registry.LanguageRegistry; +import dev.tilera.auracore.api.IWand; import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; @@ -42,54 +43,37 @@ public class WandManager { ) { final int discount = 100 - Math.min(50, getTotalVisDiscount(player)); amount = Math.round(amount * (discount / 100.0f)); - if (itemstack.hasTagCompound() && itemstack.stackTagCompound.hasKey("vis")) { - final int charge = itemstack.stackTagCompound.getShort("vis"); - if (world.isRemote) { - if (charge >= amount) { - player.swingItem(); - return true; - } - return false; - } else { - if (charge >= amount) { - if (!player.capabilities.isCreativeMode) { - itemstack.setTagInfo( - "vis", new NBTTagShort((short) (charge - amount)) - ); - } - world.playSoundAtEntity( - (Entity) player, "thaumcraft:wand", 0.5f, 1.0f - ); - return true; - } - if (amount > 0) { - player.addChatMessage(new ChatComponentText( - LanguageRegistry.instance().getStringLocalization( - "tc.wandnocharge" - ) - )); - } + final int charge = ((IWand) itemstack.getItem()).getVis(itemstack); + if (world.isRemote) { + if (charge >= amount) { + player.swingItem(); + return true; } + return false; + } else { + if (player.capabilities.isCreativeMode + || ((IWand) itemstack.getItem()).consumeVis(itemstack, amount)) { + world.playSoundAtEntity((Entity) player, "thaumcraft:wand", 0.5f, 1.0f); + return true; + } + player.addChatMessage(new ChatComponentText( + LanguageRegistry.instance().getStringLocalization("tc.wandnocharge") + )); } return false; } + public static boolean hasCharge(ItemStack is, EntityPlayer pl, int c) { + final int discount = 100 - Math.min(50, getTotalVisDiscount(pl)); + c = Math.round(c * (discount / 100.0f)); + return ((IWand) is.getItem()).getVis(is) >= c; + } + public static boolean spendCharge(final ItemStack itemstack, final EntityPlayer player, int amount) { final int discount = 100 - Math.min(50, getTotalVisDiscount(player)); amount = Math.round(amount * (discount / 100.0f)); - if (itemstack.hasTagCompound() && itemstack.stackTagCompound.hasKey("vis")) { - final int charge = itemstack.stackTagCompound.getShort("vis"); - if (charge >= amount) { - if (!player.capabilities.isCreativeMode) { - itemstack.setTagInfo( - "vis", new NBTTagShort((short) (charge - amount)) - ); - } - return true; - } - } - return false; + return ((IWand) itemstack.getItem()).consumeVis(itemstack, amount); } public static boolean @@ -226,4 +210,61 @@ public class WandManager { } return fencefound; } + + public static boolean createInfusionWorkbench( + final ItemStack itemstack, + final EntityPlayer player, + final World world, + final int x, + final int y, + final int z + ) { + for (int xx = x - 1; xx <= x; ++xx) { + int zz = z - 1; + while (zz <= z) { + if (fitInfusionWorkbench(world, xx, y, zz) + && spendCharge(world, itemstack, player, 25)) { + if (!world.isRemote) { + world.setBlock(xx, y, zz, CCBlocks.infusionWorkbench, 1, 0); + world.setBlock(xx + 1, y, zz, CCBlocks.infusionWorkbench, 2, 0); + world.setBlock(xx, y, zz + 1, CCBlocks.infusionWorkbench, 3, 0); + world.setBlock( + xx + 1, y, zz + 1, CCBlocks.infusionWorkbench, 4, 0 + ); + world.addBlockEvent(xx, y, zz, CCBlocks.infusionWorkbench, 1, 0); + world.addBlockEvent( + xx + 1, y, zz, CCBlocks.infusionWorkbench, 1, 0 + ); + world.addBlockEvent( + xx, y, zz + 1, CCBlocks.infusionWorkbench, 1, 0 + ); + world.addBlockEvent( + xx + 1, y, zz + 1, CCBlocks.infusionWorkbench, 1, 0 + ); + world.markBlockForUpdate(xx, y, zz); + world.markBlockForUpdate(xx + 1, y, zz); + world.markBlockForUpdate(xx, y, zz + 1); + world.markBlockForUpdate(xx + 1, y, zz + 1); + return true; + } + return false; + } else { + ++zz; + } + } + } + return false; + } + + public static boolean + fitInfusionWorkbench(final World world, final int x, final int y, final int z) { + return world.getBlock(x, y, z) == CCBlocks.infusionWorkbench + && world.getBlockMetadata(x, y, z) == 0 + && world.getBlock(x + 1, y, z) == CCBlocks.infusionWorkbench + && world.getBlockMetadata(x + 1, y, z) == 0 + && world.getBlock(x, y, z + 1) == CCBlocks.infusionWorkbench + && world.getBlockMetadata(x, y, z + 1) == 0 + && world.getBlock(x + 1, y, z + 1) == CCBlocks.infusionWorkbench + && world.getBlockMetadata(x + 1, y, z + 1) == 0; + } } diff --git a/src/main/java/net/anvilcraft/classiccasting/blocks/BlockAlembic.java b/src/main/java/net/anvilcraft/classiccasting/blocks/BlockAlembic.java index 499f074..6066de0 100644 --- a/src/main/java/net/anvilcraft/classiccasting/blocks/BlockAlembic.java +++ b/src/main/java/net/anvilcraft/classiccasting/blocks/BlockAlembic.java @@ -4,35 +4,44 @@ import java.util.List; import dev.tilera.auracore.aura.AuraManager; import net.anvilcraft.classiccasting.ClassicCastingTab; +import net.anvilcraft.classiccasting.render.BlockAlembicRenderer; import net.anvilcraft.classiccasting.tiles.TileAlembic; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; 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; import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.lib.CustomSoundType; import thaumcraft.common.tiles.TileCrucible; public class BlockAlembic extends BlockContainer { + public IIcon iconGlow; + public BlockAlembic() { super(Material.iron); this.setHardness(3.0f); this.setResistance(17.0f); - this.setStepSound(Block.soundTypeMetal); + this.setStepSound(new CustomSoundType("jar", 1.0f, 1.0f)); this.setBlockName("classiccasting:alembic"); this.setBlockBounds(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); this.setCreativeTab(ClassicCastingTab.INSTANCE); } + @Override + public void registerBlockIcons(IIconRegister ir) { + this.iconGlow = ir.registerIcon("thaumcraft:animatedglow"); + } + @Override public int getRenderType() { - // TODO: WTF - //return Config.blockCrucibleRI; - return 0; + return BlockAlembicRenderer.RI; } @Override @@ -122,7 +131,7 @@ public class BlockAlembic extends BlockContainer { par2 + 0.5f, par3 + 0.5f, par4 + 0.5f, - new AspectList().add(((TileAlembic) te).tag, ((TileAlembic) te).amount) + new AspectList().add(((TileAlembic) te).aspect, ((TileAlembic) te).amount) ); } super.breakBlock(par1World, par2, par3, par4, par5, par6); diff --git a/src/main/java/net/anvilcraft/classiccasting/blocks/BlockInfusionWorkbench.java b/src/main/java/net/anvilcraft/classiccasting/blocks/BlockInfusionWorkbench.java index 0593219..9af09a2 100644 --- a/src/main/java/net/anvilcraft/classiccasting/blocks/BlockInfusionWorkbench.java +++ b/src/main/java/net/anvilcraft/classiccasting/blocks/BlockInfusionWorkbench.java @@ -5,6 +5,10 @@ import java.util.Random; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import net.anvilcraft.classiccasting.ClassicCasting; +import net.anvilcraft.classiccasting.ClassicCastingTab; +import net.anvilcraft.classiccasting.GuiType; +import net.anvilcraft.classiccasting.render.BlockInfusionWorkbenchRenderer; import net.anvilcraft.classiccasting.tiles.TileInfusionWorkbench; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; @@ -25,6 +29,7 @@ import net.minecraft.world.World; import thaumcraft.common.Thaumcraft; public class BlockInfusionWorkbench extends BlockContainer { + public IIcon iconGlow; public IIcon[] icon; public BlockInfusionWorkbench() { @@ -33,16 +38,18 @@ public class BlockInfusionWorkbench extends BlockContainer { this.setHardness(4.0f); this.setResistance(100.0f); this.setStepSound(BlockInfusionWorkbench.soundTypeStone); - this.setBlockName("blockInfusionWorkbench"); + this.setBlockName("classiccasting:infusionWorkbench"); + this.setCreativeTab(ClassicCastingTab.INSTANCE); } @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(final IIconRegister ir) { - this.icon[0] = ir.registerIcon("thaumcraft:infusionbase"); + this.icon[0] = ir.registerIcon("classiccasting:infusionbase"); for (int a = 1; a <= 6; ++a) { - this.icon[a] = ir.registerIcon("thaumcraft:infusion" + a); + this.icon[a] = ir.registerIcon("classiccasting:infusion" + a); } + this.iconGlow = ir.registerIcon("classiccasting:animatedglow"); } @Override @@ -158,9 +165,7 @@ public class BlockInfusionWorkbench extends BlockContainer { @Override public int getRenderType() { - // TODO: WTF - //return Config.blockInfusionWorkbenchRI; - return 0; + return BlockInfusionWorkbenchRenderer.RI; } @Override @@ -311,7 +316,14 @@ public class BlockInfusionWorkbench extends BlockContainer { return true; } if (tileEntity != null && tileEntity instanceof TileInfusionWorkbench) { - player.openGui((Object) Thaumcraft.instance, 14, world, x, y, z); + player.openGui( + ClassicCasting.INSTANCE, + GuiType.INFUSION_WORKBENCH.ordinal(), + world, + x, + y, + z + ); return true; } switch (md) { @@ -319,6 +331,14 @@ public class BlockInfusionWorkbench extends BlockContainer { tileEntity = world.getTileEntity(x - 1, y, z); if (tileEntity != null && tileEntity instanceof TileInfusionWorkbench) { player.openGui((Object) Thaumcraft.instance, 14, world, x - 1, y, z); + player.openGui( + ClassicCasting.INSTANCE, + GuiType.INFUSION_WORKBENCH.ordinal(), + world, + x - 1, + y, + z + ); return true; } return false; @@ -326,7 +346,14 @@ public class BlockInfusionWorkbench extends BlockContainer { case 3: { tileEntity = world.getTileEntity(x, y, z - 1); if (tileEntity != null && tileEntity instanceof TileInfusionWorkbench) { - player.openGui((Object) Thaumcraft.instance, 14, world, x, y, z - 1); + player.openGui( + ClassicCasting.INSTANCE, + GuiType.INFUSION_WORKBENCH.ordinal(), + world, + x, + y, + z - 1 + ); return true; } return false; @@ -335,7 +362,12 @@ public class BlockInfusionWorkbench extends BlockContainer { tileEntity = world.getTileEntity(x - 1, y, z - 1); if (tileEntity != null && tileEntity instanceof TileInfusionWorkbench) { player.openGui( - (Object) Thaumcraft.instance, 14, world, x - 1, y, z - 1 + ClassicCasting.INSTANCE, + GuiType.INFUSION_WORKBENCH.ordinal(), + world, + x - 1, + y, + z - 1 ); return true; } diff --git a/src/main/java/net/anvilcraft/classiccasting/container/ContainerInfusionWorkbench.java b/src/main/java/net/anvilcraft/classiccasting/container/ContainerInfusionWorkbench.java new file mode 100644 index 0000000..c83b891 --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/container/ContainerInfusionWorkbench.java @@ -0,0 +1,186 @@ +package net.anvilcraft.classiccasting.container; + +import dev.tilera.auracore.api.crafting.IInfusionRecipe; +import net.anvilcraft.classiccasting.WandManager; +import net.anvilcraft.classiccasting.recipes.InfusionCraftingManager; +import net.anvilcraft.classiccasting.tiles.TileInfusionWorkbench; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.container.ContainerDummy; +import thaumcraft.common.items.wands.ItemWandCasting; + +public class ContainerInfusionWorkbench extends Container { + private TileInfusionWorkbench tileEntity; + private InventoryPlayer ip; + + public ContainerInfusionWorkbench( + final InventoryPlayer par1InventoryPlayer, final TileInfusionWorkbench e + ) { + this.tileEntity = e; + this.tileEntity.eventHandler = this; + this.ip = par1InventoryPlayer; + this.addSlotToContainer((Slot) new SlotCraftingInfusionWorkbench( + par1InventoryPlayer.player, + (IInventory) this.tileEntity, + (IInventory) this.tileEntity, + 9, + 132, + 28 + )); + this.addSlotToContainer((Slot + ) new SlotWand((IInventory) this.tileEntity, 10, 132, 61)); + for (int var6 = 0; var6 < 3; ++var6) { + for (int var7 = 0; var7 < 3; ++var7) { + this.addSlotToContainer(new Slot( + (IInventory) this.tileEntity, + var7 + var6 * 3, + 36 + var7 * 20, + 8 + var6 * 20 + )); + } + } + for (int var6 = 0; var6 < 3; ++var6) { + for (int var7 = 0; var7 < 9; ++var7) { + this.addSlotToContainer(new Slot( + (IInventory) par1InventoryPlayer, + var7 + var6 * 9 + 9, + 8 + var7 * 18, + 106 + var6 * 18 + )); + } + } + for (int var6 = 0; var6 < 9; ++var6) { + this.addSlotToContainer( + new Slot((IInventory) par1InventoryPlayer, var6, 8 + var6 * 18, 164) + ); + } + this.onCraftMatrixChanged((IInventory) this.tileEntity); + } + + public void onCraftMatrixChanged(final IInventory par1IInventory) { + this.tileEntity.dispTags = new AspectList(); + final InventoryCrafting ic + = new InventoryCrafting((Container) new ContainerDummy(), 3, 3); + for (int a = 0; a < 9; ++a) { + ic.setInventorySlotContents(a, this.tileEntity.getStackInSlot(a)); + } + this.tileEntity.setInventorySlotContentsSoftly( + 9, + CraftingManager.getInstance().findMatchingRecipe( + ic, this.tileEntity.getWorldObj() + ) + ); + + // TODO: need arcane crafting stuff for this + //if (this.tileEntity.getStackInSlot(9) == null + // && this.tileEntity.getStackInSlot(10) != null + // && this.tileEntity.getStackInSlot(10).getItem() instanceof ItemWandCasting + // && WandManager.hasCharge( + // this.tileEntity.getStackInSlot(10), + // this.ip.player, + // ThaumcraftCraftingManager.findMatchingArcaneRecipeCost( + // (IInventory) this.tileEntity, this.ip.player + // ) + // )) { + // this.tileEntity.setInventorySlotContentsSoftly( + // 9, + // ThaumcraftCraftingManager.findMatchingArcaneRecipe( + // (IInventory) this.tileEntity, this.ip.player + // ) + // ); + //} + + if (this.tileEntity.getStackInSlot(9) == null + && this.tileEntity.getStackInSlot(10) != null) { + IInfusionRecipe rec + = InfusionCraftingManager.INSTANCE.findMatchingInfusionRecipe( + this.tileEntity, this.ip.player + ); + + if (rec != null + && WandManager.hasCharge( + this.tileEntity.getStackInSlot(10), this.ip.player, rec.getCost() + ) + && this.tileEntity.doSourcesMatch(rec.getAspects())) { + this.tileEntity.setInventorySlotContentsSoftly(9, rec.getRecipeOutput()); + } + } + } + + public void onContainerClosed(final EntityPlayer par1EntityPlayer) { + super.onContainerClosed(par1EntityPlayer); + if (!this.tileEntity.getWorldObj().isRemote) { + this.tileEntity.eventHandler = null; + } + } + + public boolean canInteractWith(final EntityPlayer par1EntityPlayer) { + return this.tileEntity.getWorldObj().getTileEntity( + this.tileEntity.xCoord, this.tileEntity.yCoord, this.tileEntity.zCoord + ) + == this.tileEntity + && par1EntityPlayer.getDistanceSq( + this.tileEntity.xCoord + 0.5, + this.tileEntity.yCoord + 0.5, + this.tileEntity.zCoord + 0.5 + ) + <= 64.0; + } + + public ItemStack + transferStackInSlot(final EntityPlayer par1EntityPlayer, final int par1) { + ItemStack var2 = null; + final Slot var3 = (Slot) super.inventorySlots.get(par1); + if (var3 != null && var3.getHasStack()) { + final ItemStack var4 = var3.getStack(); + var2 = var4.copy(); + if (par1 == 0) { + if (!this.mergeItemStack(var4, 11, 47, true)) { + return null; + } + var3.onSlotChange(var4, var2); + } else if (par1 >= 11 && par1 < 38) { + if (var4.getItem() instanceof ItemWandCasting) { + if (!this.mergeItemStack(var4, 1, 2, false)) { + return null; + } + var3.onSlotChange(var4, var2); + } else if (!this.mergeItemStack(var4, 38, 47, false)) { + return null; + } + } else if (par1 >= 38 && par1 < 47) { + if (!this.mergeItemStack(var4, 11, 38, false)) { + return null; + } + } else if (!this.mergeItemStack(var4, 11, 47, false)) { + return null; + } + if (var4.stackSize == 0) { + var3.putStack((ItemStack) null); + } else { + var3.onSlotChanged(); + } + if (var4.stackSize == var2.stackSize) { + return null; + } + var3.onPickupFromSlot(this.ip.player, var4); + } + return var2; + } + + public ItemStack slotClick( + final int par1, + final int par2, + final int par3, + final EntityPlayer par4EntityPlayer + ) { + return super.slotClick(par1, par2, par3, par4EntityPlayer); + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/container/SlotCraftingInfusionWorkbench.java b/src/main/java/net/anvilcraft/classiccasting/container/SlotCraftingInfusionWorkbench.java new file mode 100644 index 0000000..fbab436 --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/container/SlotCraftingInfusionWorkbench.java @@ -0,0 +1,96 @@ +package net.anvilcraft.classiccasting.container; + +import cpw.mods.fml.common.FMLCommonHandler; +import dev.tilera.auracore.api.crafting.IInfusionRecipe; +import net.anvilcraft.classiccasting.WandManager; +import net.anvilcraft.classiccasting.recipes.InfusionCraftingManager; +import net.anvilcraft.classiccasting.tiles.TileInfusionWorkbench; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.SlotCrafting; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.aspects.IAspectSource; + +public class SlotCraftingInfusionWorkbench extends SlotCrafting { + private final IInventory craftMatrix; + private EntityPlayer thePlayer; + + public SlotCraftingInfusionWorkbench( + final EntityPlayer par1EntityPlayer, + final IInventory par2IInventory, + final IInventory par3IInventory, + final int par4, + final int par5, + final int par6 + ) { + super(par1EntityPlayer, par2IInventory, par3IInventory, par4, par5, par6); + this.thePlayer = par1EntityPlayer; + this.craftMatrix = par2IInventory; + } + + @Override + public void + onPickupFromSlot(final EntityPlayer par1EntityPlayer, final ItemStack par1ItemStack) { + FMLCommonHandler.instance().firePlayerCraftingEvent( + this.thePlayer, par1ItemStack, this.craftMatrix + ); + this.onCrafting(par1ItemStack); + int cost; + //int cost = ThaumcraftCraftingManager.findMatchingArcaneRecipeCost( + // this.craftMatrix, this.thePlayer + //); + //if (cost == 0) { + IInfusionRecipe rec = InfusionCraftingManager.INSTANCE.findMatchingInfusionRecipe( + this.craftMatrix, this.thePlayer + ); + if (rec != null) { + cost = rec.getCost(); + final AspectList tags = rec.getAspects(); + if (tags != null && tags.size() > 0) { + final TileInfusionWorkbench tiwb + = (TileInfusionWorkbench) this.craftMatrix; + for (final Aspect tag : tags.getAspects()) { + final IAspectSource as = tiwb.foundAspects.getSource(tag); + if (as != null) { + as.takeFromContainer(tag, tags.getAmount(tag)); + } + } + } + //} + if (cost > 0) { + WandManager.spendCharge( + this.craftMatrix.getStackInSlot(10), par1EntityPlayer, cost + ); + } + } + for (int var2 = 0; var2 < 9; ++var2) { + final ItemStack var3 = this.craftMatrix.getStackInSlot(var2); + if (var3 != null) { + this.craftMatrix.decrStackSize(var2, 1); + if (var3.getItem().hasContainerItem(var3)) { + ItemStack var4 = var3.getItem().getContainerItem(var3); + if (var4.isItemStackDamageable() + && var4.getItemDamage() > var4.getMaxDamage()) { + MinecraftForge.EVENT_BUS.post( + new PlayerDestroyItemEvent(this.thePlayer, var4) + ); + var4 = null; + } + if (var4 != null + && (!var3.getItem().doesContainerItemLeaveCraftingGrid(var3) + || !this.thePlayer.inventory.addItemStackToInventory(var4))) { + if (this.craftMatrix.getStackInSlot(var2) == null) { + this.craftMatrix.setInventorySlotContents(var2, var4); + } else { + this.thePlayer.entityDropItem(var4, 1.5f); + } + } + } + } + } + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/container/SlotWand.java b/src/main/java/net/anvilcraft/classiccasting/container/SlotWand.java new file mode 100644 index 0000000..94cedb6 --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/container/SlotWand.java @@ -0,0 +1,31 @@ +package net.anvilcraft.classiccasting.container; + +import dev.tilera.auracore.api.IWand; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +public class SlotWand extends Slot { + public SlotWand(IInventory par2IInventory, int par3, int par4, int par5) { + super(par2IInventory, par3, par4, par5); + } + + @Override + public boolean isItemValid(ItemStack stack) { + return stack != null && stack.getItem() != null + && stack.getItem() instanceof IWand + // This is so vanilla thaumcraft wands don't work. + && ((IWand) stack.getItem()).getMaxVis(stack) > 0; + } + + @Override + public int getSlotStackLimit() { + return 1; + } + + @Override + public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack) { + super.onPickupFromSlot(par1EntityPlayer, par2ItemStack); + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/gui/GuiInfusionWorkbench.java b/src/main/java/net/anvilcraft/classiccasting/gui/GuiInfusionWorkbench.java new file mode 100644 index 0000000..445206e --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/gui/GuiInfusionWorkbench.java @@ -0,0 +1,204 @@ +package net.anvilcraft.classiccasting.gui; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import dev.tilera.auracore.api.IWand; +import dev.tilera.auracore.api.crafting.IInfusionRecipe; +import net.anvilcraft.classiccasting.WandManager; +import net.anvilcraft.classiccasting.container.ContainerInfusionWorkbench; +import net.anvilcraft.classiccasting.recipes.InfusionCraftingManager; +import net.anvilcraft.classiccasting.tiles.TileInfusionWorkbench; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.client.lib.UtilsFX; +import thaumcraft.codechicken.lib.math.MathHelper; + +@SideOnly(Side.CLIENT) +public class GuiInfusionWorkbench extends GuiContainer { + private TileInfusionWorkbench tileEntity; + private InventoryPlayer ip; + + public GuiInfusionWorkbench( + final InventoryPlayer par1InventoryPlayer, final TileInfusionWorkbench e + ) { + super((Container) new ContainerInfusionWorkbench(par1InventoryPlayer, e)); + this.tileEntity = e; + this.ip = par1InventoryPlayer; + this.ySize += 21; + } + + @Override + protected void drawGuiContainerForegroundLayer(final int par1, final int par2) {} + + @Override + public void drawScreen(final int par1, final int par2, final float par3) { + super.drawScreen(par1, par2, par3); + // TODO: crafting + //if (ThaumcraftCraftingManager.findMatchingInfusionRecipe( + // (IInventory) this.tileEntity, this.ip.player + // ) + // != null) { + // final ObjectTags reqs + // = ThaumcraftCraftingManager.findMatchingInfusionRecipeTags( + // (IInventory) this.tileEntity, this.ip.player + // ); + // int count = 0; + // if (reqs != null && reqs.size() > 0) { + // for (final EnumTag tag : reqs.getAspects()) { + // mposx = par1 - (var5 + 24 + 16 * count + (5 - reqs.size()) * 8); + // mposy = par2 - (var6 + 72); + // if (mposx >= 0 && mposy >= 0 && mposx < 16 && mposy < 16) { + // UtilsFX.drawCustomTooltip( + // (GuiScreen) this, + // GuiInfusionWorkbench.field_74196_a, + // this.field_73886_k, + // Arrays.asList(tag.name, tag.meaning), + // par1, + // par2, + // 11 + // ); + // } + // ++count; + // } + // } + //} + } + + @Override + protected void + drawGuiContainerBackgroundLayer(final float par1, final int par2, final int par3) { + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + GL11.glEnable(3042); + this.mc.renderEngine.bindTexture(new ResourceLocation( + "classiccasting", "textures/gui/gui_infusionworkbench.png" + )); + final int var5 = (this.width - this.xSize) / 2; + final int var6 = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(var5, var6, 0, 0, this.xSize, this.ySize); + GL11.glDisable(3042); + ItemStack result = null; + // TODO: arcane crafting + //if (ThaumcraftCraftingManager.findMatchingArcaneRecipe( + // (IInventory) this.tileEntity, this.ip.player + // ) + // != null) { + // result = ThaumcraftCraftingManager.findMatchingArcaneRecipe( + // (IInventory) this.tileEntity, this.ip.player + // ); + //} else + IInfusionRecipe rec = InfusionCraftingManager.INSTANCE.findMatchingInfusionRecipe( + this.tileEntity, this.ip.player + ); + if (rec != null) { + result = rec.getRecipeOutput(); + final AspectList reqs = rec.getAspects(); + int count = 0; + if (reqs != null && reqs.size() > 0) { + for (final Aspect tag : reqs.getAspects()) { + float op = 1.0f; + if (this.tileEntity.foundAspects.getAmount(tag) + < reqs.getAmount(tag)) { + op = (float + ) (MathHelper.sin(this.ip.player.ticksExisted - count * 10) + / 8.0f) + * 0.125f + + 0.25f; + } + UtilsFX.drawTag( + var5 + 24 + 16 * count + (5 - reqs.size()) * 8, + var6 + 72, + tag, + reqs.getAmount(tag), + 0, + op + ); + ++count; + } + } + } + if (this.tileEntity.getStackInSlot(10) != null) { + final int charge = ((IWand)this.tileEntity.getStackInSlot(10).getItem()).getVis(this.tileEntity.getStackInSlot(10)); + if (charge > 0) { + GL11.glPushMatrix(); + GL11.glTranslatef((float) (var5 + 140), (float) (var6 + 85), 505.0f); + GL11.glScalef(0.5f, 0.5f, 0.0f); + final String text = charge + " vis"; + final int ll = this.fontRendererObj.getStringWidth(text) / 2; + this.fontRendererObj.drawStringWithShadow(text, -ll, -16, 16777215); + GL11.glScalef(1.0f, 1.0f, 1.0f); + GL11.glPopMatrix(); + } + if (result != null) { + final int discount + = 100 - Math.min(50, WandManager.getTotalVisDiscount(this.ip.player)); + //int cost1 = ThaumcraftCraftingManager.findMatchingArcaneRecipeCost( + // this.tileEntity, this.ip.player + //); + //cost1 = Math.round(cost1 * (discount / 100.0f)); + int cost2 = rec.getCost(); + cost2 = Math.round(cost2 * (discount / 100.0f)); + if (/*charge < cost1 ||*/ charge < cost2) { + GL11.glPushMatrix(); + RenderHelper.enableGUIStandardItemLighting(); + GL11.glDisable(2896); + GL11.glEnable(32826); + GL11.glEnable(2903); + GL11.glEnable(2896); + RenderItem.getInstance().renderItemIntoGUI( + this.mc.fontRenderer, + this.mc.renderEngine, + result, + var5 + 132, + var6 + 28 + ); + RenderItem.getInstance().renderItemOverlayIntoGUI( + this.mc.fontRenderer, + this.mc.renderEngine, + result, + var5 + 132, + var6 + 28 + ); + GL11.glDisable(2896); + GL11.glDepthMask(true); + GL11.glEnable(2929); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glTranslatef((float) (var5 + 140), (float) (var6 + 85), 0.0f); + GL11.glScalef(0.5f, 0.5f, 0.0f); + String text2 = "Insufficient charge"; + if (/*cost1 > ((ItemWandCasting) this.tileEntity.getStackInSlot(10) + .getItem()) + .getMaxVis() + ||*/ cost2 > ((IWand) this.tileEntity.getStackInSlot(10) + .getItem()) + .getMaxVis(this.tileEntity.getStackInSlot(10))) { + text2 = "This wand is too weak"; + } + final int ll2 = this.fontRendererObj.getStringWidth(text2) / 2; + this.fontRendererObj.drawString(text2, -ll2, 0, 15625838); + GL11.glScalef(1.0f, 1.0f, 1.0f); + GL11.glPopMatrix(); + } + if (/*cost1 > 0 ||*/ cost2 > 0) { + GL11.glPushMatrix(); + GL11.glTranslatef((float) (var5 + 140), (float) (var6 + 81), 0.0f); + GL11.glScalef(0.5f, 0.5f, 0.0f); + //final String text2 = Math.max(cost1, cost2) + " vis"; + final String text2 = cost2 + " vis"; + final int ll2 = this.fontRendererObj.getStringWidth(text2) / 2; + this.fontRendererObj.drawStringWithShadow(text2, -ll2, -64, 15658734); + GL11.glScalef(1.0f, 1.0f, 1.0f); + GL11.glPopMatrix(); + } + } + } + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/items/wands/ItemWandCasting.java b/src/main/java/net/anvilcraft/classiccasting/items/wands/ItemWandCasting.java index 72089ca..9d80361 100644 --- a/src/main/java/net/anvilcraft/classiccasting/items/wands/ItemWandCasting.java +++ b/src/main/java/net/anvilcraft/classiccasting/items/wands/ItemWandCasting.java @@ -5,6 +5,7 @@ import java.util.List; import cpw.mods.fml.common.registry.LanguageRegistry; import dev.tilera.auracore.api.IWand; import dev.tilera.auracore.aura.AuraManager; +import net.anvilcraft.classiccasting.CCBlocks; import net.anvilcraft.classiccasting.ClassicCastingTab; import net.anvilcraft.classiccasting.WandManager; import net.minecraft.block.Block; @@ -310,13 +311,11 @@ public abstract class ItemWandCasting extends Item implements IWand { // result = WandManager.createNodeMagnet(itemstack, player, world, x, y, z); //} - // TODO: implement infusion workbench - //if (bi == ConfigBlocks.blockInfusionWorkbench - // && ResearchManager.isResearchComplete(player.getDisplayName(), "MAGBLOCK")) - // { result - // = WandManager.createInfusionWorkbench(itemstack, player, world, x, y, - // z); - //} + if (bi == CCBlocks.infusionWorkbench + /*&& ResearchManager.isResearchComplete(player.getDisplayName(), "MAGBLOCK")*/) { + result + = WandManager.createInfusionWorkbench(itemstack, player, world, x, y, z); + } // TODO: need alembics for this //if (bi == ConfigBlocks.blockMetalDevice && md >= 1 && md <= 4) { diff --git a/src/main/java/net/anvilcraft/classiccasting/recipes/InfusionCraftingManager.java b/src/main/java/net/anvilcraft/classiccasting/recipes/InfusionCraftingManager.java new file mode 100644 index 0000000..710a66c --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/recipes/InfusionCraftingManager.java @@ -0,0 +1,75 @@ +package net.anvilcraft.classiccasting.recipes; + +import java.util.ArrayList; +import java.util.List; + +import dev.tilera.auracore.api.crafting.IInfusionRecipe; +import net.anvilcraft.classiccasting.CCBlocks; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; + +public class InfusionCraftingManager { + public static InfusionCraftingManager INSTANCE = new InfusionCraftingManager(); + public List recipes = new ArrayList<>(); + + public InfusionCraftingManager() { + this.recipes.add(new IInfusionRecipe() { + @Override + public boolean matches(IInventory var1, World var2, EntityPlayer var3) { + return var1.getStackInSlot(0) != null + && var1.getStackInSlot(0).getItem() + == Items.gold_nugget; + } + + @Override + public ItemStack getCraftingResult(IInventory var1) { + return this.getRecipeOutput(); + } + + @Override + public int getRecipeSize() { + return 9; + } + + @Override + public ItemStack getRecipeOutput() { + return new ItemStack(CCBlocks.alembic); + } + + @Override + public int getCost() { + return 10; + } + + @Override + public AspectList getAspects() { + return new AspectList().add(Aspect.GREED, 8); + } + + @Override + public String getKey() { + return "alembus"; + } + + @Override + public String getResearch() { + return null; + } + }); + } + + public IInfusionRecipe findMatchingInfusionRecipe(IInventory inv, EntityPlayer pl) { + for (IInfusionRecipe recipe : this.recipes) { + if (recipe.matches(inv, pl.worldObj, pl)) { + return recipe; + } + } + + return null; + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/render/BlockAlembicRenderer.java b/src/main/java/net/anvilcraft/classiccasting/render/BlockAlembicRenderer.java new file mode 100644 index 0000000..dba7899 --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/render/BlockAlembicRenderer.java @@ -0,0 +1,73 @@ +package net.anvilcraft.classiccasting.render; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; +import net.anvilcraft.classiccasting.blocks.BlockAlembic; +import net.anvilcraft.classiccasting.tiles.TileAlembic; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.IBlockAccess; +import org.lwjgl.opengl.GL11; +import thaumcraft.client.renderers.block.BlockRenderer; + +public class BlockAlembicRenderer + extends BlockRenderer implements ISimpleBlockRenderingHandler { + public static int RI; + + @Override + public void renderInventoryBlock( + final Block block, + final int metadata, + final int modelID, + final RenderBlocks renderer + ) { + GL11.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + GL11.glTranslatef(-0.3f, -0.75f, -0.5f); + TileEntityRendererDispatcher.instance.renderTileEntityAt( + (TileEntity) new TileAlembic(), 0.0, 0.0, 0.0, 0.0f + ); + GL11.glEnable(32826); + } + + @Override + public boolean renderWorldBlock( + final IBlockAccess world, + final int x, + final int y, + final int z, + final Block block, + final int modelId, + final RenderBlocks renderer + ) { + final TileEntity te2 = world.getTileEntity(x, y, z); + if (te2 != null && te2 instanceof TileAlembic && ((TileAlembic) te2).amount > 0) { + final float level = ((TileAlembic) te2).amount + / (float) ((TileAlembic) te2).maxAmount * 0.5625f; + final Tessellator t = Tessellator.instance; + t.setColorOpaque_I(((TileAlembic) te2).aspect.getColor()); + t.setBrightness(200); + block.setBlockBounds(0.275f, 0.25f, 0.275f, 0.725f, 0.25f + level, 0.725f); + renderer.setRenderBoundsFromBlock(block); + BlockRenderer.renderAllSides( + world, x, y, z, block, renderer, ((BlockAlembic) block).iconGlow, true + ); + GL11.glColor3f(1.0f, 1.0f, 1.0f); + } + renderer.clearOverrideBlockTexture(); + block.setBlockBounds(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); + renderer.setRenderBoundsFromBlock(block); + return true; + } + + @Override + public boolean shouldRender3DInInventory(int meta) { + return true; + } + + @Override + public int getRenderId() { + return RI; + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/render/BlockInfusionWorkbenchRenderer.java b/src/main/java/net/anvilcraft/classiccasting/render/BlockInfusionWorkbenchRenderer.java new file mode 100644 index 0000000..62d57a0 --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/render/BlockInfusionWorkbenchRenderer.java @@ -0,0 +1,90 @@ +package net.anvilcraft.classiccasting.render; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; +import net.anvilcraft.classiccasting.blocks.BlockInfusionWorkbench; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.world.IBlockAccess; +import org.lwjgl.opengl.GL11; +import thaumcraft.client.renderers.block.BlockRenderer; + +public class BlockInfusionWorkbenchRenderer + extends BlockRenderer implements ISimpleBlockRenderingHandler { + public static int RI; + + @Override + public void renderInventoryBlock( + final Block block, + final int metadata, + final int modelID, + final RenderBlocks renderer + ) { + if (metadata == 0) { + block.setBlockBounds(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); + renderer.setRenderBoundsFromBlock(block); + BlockRenderer.drawFaces( + renderer, block, block.getBlockTextureFromSide(0), false + ); + } + } + + @Override + public boolean renderWorldBlock( + final IBlockAccess world, + final int x, + final int y, + final int z, + final Block block, + final int modelId, + final RenderBlocks renderer + ) { + BlockRenderer.setBrightness(world, x, y, z, block); + final int metadata = world.getBlockMetadata(x, y, z); + block.setBlockBounds(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); + renderer.setRenderBoundsFromBlock(block); + renderer.renderStandardBlock(block, x, y, z); + if (metadata != 0 && metadata != 7) { + final Tessellator t = Tessellator.instance; + t.setColorOpaque_I(12583104); + t.setBrightness(180); + BlockRenderer.renderAllSidesInverted( + world, + x, + y, + z, + block, + renderer, + ((BlockInfusionWorkbench) block).iconGlow, + false + ); + block.setBlockBounds(0.02f, 0.02f, 0.02f, 0.98f, 0.98f, 0.98f); + renderer.setRenderBoundsFromBlock(block); + BlockRenderer.renderAllSides( + world, + x, + y, + z, + block, + renderer, + ((BlockInfusionWorkbench) block).iconGlow, + false + ); + GL11.glColor3f(1.0f, 1.0f, 1.0f); + } + renderer.clearOverrideBlockTexture(); + block.setBlockBounds(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); + renderer.setRenderBoundsFromBlock(block); + return true; + } + + @Override + public boolean shouldRender3DInInventory(int meta) { + return true; + } + + @Override + public int getRenderId() { + return RI; + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/render/TileInfusionWorkbenchRenderer.java b/src/main/java/net/anvilcraft/classiccasting/render/TileInfusionWorkbenchRenderer.java new file mode 100644 index 0000000..756e51b --- /dev/null +++ b/src/main/java/net/anvilcraft/classiccasting/render/TileInfusionWorkbenchRenderer.java @@ -0,0 +1,75 @@ +package net.anvilcraft.classiccasting.render; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.anvilcraft.classiccasting.CCBlocks; +import net.anvilcraft.classiccasting.UtilsFX; +import net.anvilcraft.classiccasting.items.wands.ItemWandCasting; +import net.anvilcraft.classiccasting.tiles.TileInfusionWorkbench; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.entity.RenderItem; +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.world.IBlockAccess; +import org.lwjgl.opengl.GL11; + +@SideOnly(Side.CLIENT) +public class TileInfusionWorkbenchRenderer extends TileEntitySpecialRenderer { + public void renderTileEntityAt( + final TileInfusionWorkbench table, + final double par2, + final double par4, + final double par6, + final float par8 + ) { + if (table.getWorldObj() != null && table.getStackInSlot(10) != null) { + final float bob + = MathHelper.sin( + ((Entity) Minecraft.getMinecraft().renderViewEntity).ticksExisted + / 14.0f + ) * 0.03f + + 0.03f; + final float weave + = MathHelper.sin( + ((Entity) Minecraft.getMinecraft().renderViewEntity).ticksExisted + / 10.0f + ) * 0.5f + + 0.5f; + GL11.glPushMatrix(); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + GL11.glTranslatef( + (float) par2 + 0.625f, (float) par4 + 1.1f + bob, (float) par6 + 0.625f + ); + GL11.glRotatef(85.0f + weave * 10.0f, 1.0f, 0.0f, 0.0f); + UtilsFX.render3DItem( + table.getStackInSlot(10), + 0, + 0.75f, + CCBlocks.infusionWorkbench.getMixedBrightnessForBlock( + (IBlockAccess) table.getWorldObj(), + table.xCoord, + table.yCoord + 1, + table.zCoord + ) + ); + GL11.glPopMatrix(); + } + } + + @Override + public void renderTileEntityAt( + final TileEntity par1TileEntity, + final double par2, + final double par4, + final double par6, + final float par8 + ) { + this.renderTileEntityAt( + (TileInfusionWorkbench) par1TileEntity, par2, par4, par6, par8 + ); + } +} diff --git a/src/main/java/net/anvilcraft/classiccasting/tiles/TileAlembic.java b/src/main/java/net/anvilcraft/classiccasting/tiles/TileAlembic.java index 247aabf..ad5e3e9 100644 --- a/src/main/java/net/anvilcraft/classiccasting/tiles/TileAlembic.java +++ b/src/main/java/net/anvilcraft/classiccasting/tiles/TileAlembic.java @@ -1,5 +1,7 @@ package net.anvilcraft.classiccasting.tiles; +import dev.tilera.auracore.api.IAlembic; +import dev.tilera.auracore.api.IEssenceContainer; import dev.tilera.auracore.aura.AuraManager; import net.anvilcraft.classiccasting.ClassicCasting; import net.minecraft.nbt.NBTTagCompound; @@ -7,17 +9,19 @@ import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; import thaumcraft.api.aspects.Aspect; import thaumcraft.api.aspects.AspectList; -import thaumcraft.api.aspects.IAspectSource; +import thaumcraft.api.aspects.IEssentiaTransport; -public class TileAlembic extends TileEntity implements IAspectSource { - public Aspect tag; +public class TileAlembic + extends TileEntity implements IAlembic, IEssenceContainer, IEssentiaTransport { + public Aspect aspect; public int amount; public int maxAmount; public TileAlembic() { - this.tag = null; + this.aspect = null; this.amount = 0; this.maxAmount = 16; } @@ -26,15 +30,15 @@ public class TileAlembic extends TileEntity implements IAspectSource { public void readFromNBT(final NBTTagCompound nbttagcompound) { super.readFromNBT(nbttagcompound); if (nbttagcompound.hasKey("tag")) - this.tag = Aspect.getAspect(nbttagcompound.getString("tag")); + this.aspect = Aspect.getAspect(nbttagcompound.getString("tag")); this.amount = nbttagcompound.getShort("amount"); } @Override public void writeToNBT(final NBTTagCompound nbttagcompound) { super.writeToNBT(nbttagcompound); - if (this.tag != null) - nbttagcompound.setString("tag", this.tag.getTag()); + if (this.aspect != null) + nbttagcompound.setString("tag", this.aspect.getTag()); nbttagcompound.setShort("amount", (short) this.amount); } @@ -45,8 +49,8 @@ public class TileAlembic extends TileEntity implements IAspectSource { @Override public int addToContainer(final Aspect tt, int am) { - if ((this.amount < this.maxAmount && tt == this.tag) || this.amount == 0) { - this.tag = tt; + if ((this.amount < this.maxAmount && tt == this.aspect) || this.amount == 0) { + this.aspect = tt; final int added = Math.min(am, this.maxAmount - this.amount); this.amount += added; am -= added; @@ -57,8 +61,12 @@ public class TileAlembic extends TileEntity implements IAspectSource { @Override public boolean takeFromContainer(final Aspect tt, final int am) { - if (this.amount >= am && tt == this.tag) { + if (this.amount >= am && tt == this.aspect) { this.amount -= am; + + if (this.amount == 0) + this.aspect = null; + this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); return true; } @@ -68,7 +76,7 @@ public class TileAlembic extends TileEntity implements IAspectSource { @Override public boolean doesContainerContain(final AspectList ot) { for (final Aspect tt : ot.getAspects()) { - if (this.amount > 0 && tt == this.tag) { + if (this.amount > 0 && tt == this.aspect) { return true; } } @@ -77,25 +85,28 @@ public class TileAlembic extends TileEntity implements IAspectSource { @Override public boolean doesContainerContainAmount(final Aspect tt, final int am) { - return this.amount >= am && tt == this.tag; + return this.amount >= am && tt == this.aspect; } @Override public int containerContains(final Aspect tt) { - return (tt == this.tag) ? this.amount : 0; + return (tt == this.aspect) ? this.amount : 0; } @Override public AspectList getAspects() { - return new AspectList().add(this.tag, this.amount); + AspectList l = new AspectList(); + if (this.aspect != null) + l.add(this.aspect, this.amount); + return l; } @Override public Packet getDescriptionPacket() { NBTTagCompound nbt = new NBTTagCompound(); - if (this.tag != null) - nbt.setString("tag", this.tag.getTag()); + if (this.aspect != null) + nbt.setString("tag", this.aspect.getTag()); nbt.setInteger("amount", this.amount); @@ -109,9 +120,15 @@ public class TileAlembic extends TileEntity implements IAspectSource { NBTTagCompound nbt = pkt.func_148857_g(); if (nbt.hasKey("tag")) - this.tag = Aspect.getAspect(nbt.getString("tag")); + this.aspect = Aspect.getAspect(nbt.getString("tag")); + else + this.aspect = null; this.amount = nbt.getInteger("amount"); + + this.worldObj.markBlockRangeForRenderUpdate( + this.xCoord, this.yCoord, this.zCoord, this.xCoord, this.yCoord, this.zCoord + ); } @Override @@ -125,9 +142,9 @@ public class TileAlembic extends TileEntity implements IAspectSource { this.xCoord + 0.5f, this.yCoord + 0.5f, this.zCoord + 0.5f, - new AspectList().add(this.tag, this.amount) + new AspectList().add(this.aspect, this.amount) ); - this.takeFromContainer(this.tag, this.amount); + this.takeFromContainer(this.aspect, this.amount); this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord); } @@ -149,4 +166,72 @@ public class TileAlembic extends TileEntity implements IAspectSource { @Override public void setAspects(AspectList arg0) {} + + @Override + public Aspect getAspect() { + return this.aspect; + } + + @Override + public int getAmount() { + return this.amount; + } + + @Override + public int addEssentia(Aspect arg0, int arg1, ForgeDirection arg2) { + return 0; + } + + @Override + public boolean canInputFrom(ForgeDirection arg0) { + return false; + } + + @Override + public boolean canOutputTo(ForgeDirection arg0) { + return this.isConnectable(arg0); + } + + @Override + public int getEssentiaAmount(ForgeDirection arg0) { + return this.amount; + } + + @Override + public Aspect getEssentiaType(ForgeDirection arg0) { + return this.aspect; + } + + @Override + public int getMinimumSuction() { + return 0; + } + + @Override + public int getSuctionAmount(ForgeDirection arg0) { + return 0; + } + + @Override + public Aspect getSuctionType(ForgeDirection arg0) { + return null; + } + + @Override + public boolean isConnectable(ForgeDirection arg0) { + return arg0 != ForgeDirection.UP; + } + + @Override + public boolean renderExtendedTube() { + return true; + } + + @Override + public void setSuction(Aspect arg0, int arg1) {} + + @Override + public int takeEssentia(Aspect arg0, int arg1, ForgeDirection arg2) { + return this.canOutputTo(arg2) && this.takeFromContainer(arg0, arg1) ? arg1 : 0; + } } diff --git a/src/main/java/net/anvilcraft/classiccasting/tiles/TileInfusionWorkbench.java b/src/main/java/net/anvilcraft/classiccasting/tiles/TileInfusionWorkbench.java index 4bc0cd9..f6c858a 100644 --- a/src/main/java/net/anvilcraft/classiccasting/tiles/TileInfusionWorkbench.java +++ b/src/main/java/net/anvilcraft/classiccasting/tiles/TileInfusionWorkbench.java @@ -107,10 +107,10 @@ public class TileInfusionWorkbench extends TileMagicWorkbench { if (te != null && te instanceof IAspectSource) { final IAspectSource ts = (IAspectSource) te; for (final Aspect tag2 : ts.getAspects().getAspects()) { - if (ts.containerContains(tag2) + if (ts.getAspects().getAmount(tag2) > this.foundAspects.getAmount(tag2)) { this.foundAspects.merge( - tag2, ts.containerContains(tag2) + tag2, ts.getAspects().getAmount(tag2) ); this.foundAspects.linkSource(tag2, ts); } @@ -169,42 +169,6 @@ public class TileInfusionWorkbench extends TileMagicWorkbench { this.foundAspects.readFromNBT(nbt.getCompoundTag("aspects")); } - //public static void handlePacket(final ByteArrayDataInput dat) { - // final World world = Thaumcraft.proxy.getClientWorld(); - // final int x = dat.readInt(); - // final int y = dat.readInt(); - // final int z = dat.readInt(); - // final short id = dat.readShort(); - // final short dmg = dat.readShort(); - // final InfuserAspectList ot = new InfuserAspectList(); - // try { - // while (true) { - // final int tid = dat.readByte(); - // final int tam = dat.readShort(); - // final int sx = dat.readInt(); - // final int sy = dat.readInt(); - // final int sz = dat.readInt(); - // final TileEntity te = world.getTileEntity(sx, sy, sz); - // if (te != null && te instanceof IAspectSource) { - // ot.merge(Aspect.get(tid), tam); - // ot.linkSource(Aspect.get(tid), (IAspectSource) te); - // } - // } - // } catch (final Exception e) { - // final TileEntity te2 = world.getTileEntity(x, y, z); - // if (te2 instanceof TileInfusionWorkbench && id != 0) { - // ((TileInfusionWorkbench) te2) - // .setInventorySlotContentsSoftly(10, new ItemStack(id, 1, (int) - // dmg)); - // ((TileInfusionWorkbench) te2).foundAspects = ot; - // if (((TileInfusionWorkbench) te2).eventHandler != null) { - // ((TileInfusionWorkbench) te2) - // .eventHandler.onCraftMatrixChanged((IInventory) te2); - // } - // } - // } - //} - @Override public void openInventory() {} diff --git a/src/main/resources/assets/classiccasting/lang/en_US.lang b/src/main/resources/assets/classiccasting/lang/en_US.lang index cd11e76..ed93ef2 100644 --- a/src/main/resources/assets/classiccasting/lang/en_US.lang +++ b/src/main/resources/assets/classiccasting/lang/en_US.lang @@ -18,3 +18,4 @@ item.classiccasting:wandTrade.name=Wand of Equal Trade # ---- BLOCKS ---- tile.classiccasting:alembic.name=Arcane Alembic +tile.classiccasting:infusionWorkbench.name=Arcane Stone diff --git a/src/main/resources/assets/classiccasting/textures/blocks/animatedglow.png b/src/main/resources/assets/classiccasting/textures/blocks/animatedglow.png new file mode 100644 index 0000000000000000000000000000000000000000..ff3eb5e80b332872eea18fffa8d1292f5e186ea1 GIT binary patch literal 5229 zcmV-z6q4(SP)2e&!5(VJV(Cn*i1TsrF0)n@IAG{&Y$1fsS!XS_@`)cW)>aY4tOVAOPd#NQW zGf!?+bN1P1pZ)&(?}x+Tg%@6U^UXK^`RAWsfBp66pMU=2k3XJSujBFf?6c42=IPU? z&p-eClDp@gdoB-u{q$-8Tjn%EUhy{#><3xxvbY4Z@iJ# z>AYm5tReHHXIh8cS6_WKe=~c!Wrz@&_xYRtdB0?gJf}mxrO!(*y_B~ZDMaQ?22RhP ze)=iH=W7}t^DV72Y1(DT*I$1<>kE;YHne5k`J_#V3^|K|bC;V8|JrM>AAFFT3=wKG;xQj|%d6ank}NduGo*#(edx(>gRMgr%aT#^9My<`zxwK{ zF!8uv>G}ERpNAd-4Z9XhFnbo0@%Ac|H}r+Dhb}#O^yq)G$omIxVX3& z>_0z0&y49ET?!49$1*}g8id!mNt-bDnNL3XBs@u@a3Et~_RV@xmdGv(%gf9>v^D+0 z^?c4vn43P4aTrB~@;+l{VA5DhVm^cw+T}4XvwCx8d0|Oz!hoR~xzaVGhN{SwMDr$% z=!@35!k){^%M%{bp?DzmtPQ)Gx7^UHEM};acCLH~ z>A0SSrggv+@-kJ3$;-?<22ML_lW%E}fir5RC22Mx!=-iRnKR@rZ^QD)2;CV42GTiS z!#z4bftGK1j@rzBx1WG5@7qx)l$R zNm>^VSr{bb(_m`^nRdZLXt;m>e&%6+XlrEm#TQ?|Lq^QZL((i<#$&%&9TZ0&x3HMWzy#=!P@gHa#DPj25J63>jwU-YWB+$;wy} z*AN_;6U`s%WqrBQUn5omg$r+h=(MJ}!|1L)m%QO27T|;j3JVY7rSvZzqCO`);A7s> z1qz$L8HIyF439dfrMk7GOf3$ke>l#yg_#`H5eND3w2o*3nye(Oo8imqg*oVit)L}qP$^0$#mc$d=$-aa8+#P zo_~P{ZgyC{^nqidfovU2n{FW+)0VQ5&H_7W(o=ZIeMC9pB?Ci!1VXnlgr}myEaFfN zA2j`Iz3`Mkb8)z+9qO3zv=-*WLk2UC*6@%BD3)_!L!qh0D_7dZGBlJAe}ozH+z}c}C>$kmvM?{2MQ&QMei1VFibFHeTW~I81R~y$+?2 zO%COYIN(75Doe{^M5u8W7(<#1O6n&C;+e6Z+rCMo7nT*vJL-6Dt~ zJHj#;uQNcr;!b!m%sscs5M_W4X2nK@JHg|^1Mp7yP+QNaWFC1&E#ks)P|xb0yn1dr)h1Z)-7aC|d9 zWsHf2Z^lQZfZ}0L@y~i;jszOqxFsB;+pO^P_*IRlkap4-aL*8o+QdU^3=xQ^y?7|o z=*zI8882icnr>#rTa$?@K^j=$QVt51_rYKBkjp4+^CG?sB}`pfTW#iKRpV+P4qzR6kH#(c|t5sPdP9|Umy^04NC%mgrGW)?nw7txJ~NEwF9 zLW7(R9>U^*CsBOpsgg4pP){9XuszifIPNL?&d!A_=Z30jn&@Hr06B=m_;dWBABN&=EZFW=C;#lNs6} zvZ%G?hgh9s?IcSh60LO8QwV6F|*E zOy#U#LFyh4z`&20CsK<{*wUdq@E}NJ#`8CGW>ncbJY*$<-Gb<9uL6Y(m&4tMI0Fx) zBO{O^5s);Gs+VJfts%}}@P&Hf7YVTHGNgeAA;R?XYgkcjv+jNDJ{mAS#I7{~%Xyj5 zGz|~bTo&a7rmA5z8UT<|g^edXL~sF=biJg5I2PS(*FYOQUZM zIKoXmh-A8);fwVF^hHpg4hd)=L4mdbiE9)c*Ett~xX=MZR7e`stN-P3vLq9MrSN-d z*s{F+_S61XL#Xt5U%Ns@@tAV}3 zTBE<$%c_J$lUjxI=0s8e%7?9tCtlC;skx*8jkLuV3~q)C53pzA!TQuO#V3s$n25{E zOL&;2Q9})OENVljiF?czkKe=KXht=vPEkhmPDOpbAyLsUw9D1iqY!Z!|RNa zJ`+ZYKIssl7&{}`<w3p|IiM!-si{Ixl>E@y-UTZ?=q?u^&HvJn@iA zY8RrTVNw8E-HJK#e46<*UP;f1o}p0z{?_beJ%RDC-pxU5QENf@_IL=F>D#O?MT+bX z$Hi0HjxcAFsio1;VcU~|m8Kd^Z{}WX(L{w>;j0P@XcTBq@sb((x%JInY0Xe9_|;7u zcq*g3uha%fdpxK~&C2a@?(K!4EdvZ@bnK2KW9k~xRMDF+UI>Vj#d}*KbtwDt_FyYz zEJNkv5L5Qs|DOR?rpq@QZPdiZY-sp(y=0IOKa!znfoJTZ*b4tP1FJZ;LZsFs1d4LgelXXS9iEC?=H|@Gk70~4F5{VsH7Jr=5AV&=aJ6Nn2E^*&AZlBC zY|7(TYq^K5n7m)BNR*?R=QScbCRrcUs|OW>)M??HyOAkp5H;Pw1A#0AZlsohTDPvk zXAQG(QTtV`<{$3F-dO<5ELF@_x6ojc+VCR#7F=4I=pN@`t^SC6C#H)j-S{4Q)v=Ye zDEVTHjI9XDYmt{x*c5Y4x7&hU3vM$x-=bWFVEq^QBP}8wWfw)v-?^c6Dq_RY;4h{)veaLJ12cZnBpea&sRAJ&wNUNE2DV1`<$uhb z^;Wd@%1gy6%&GetFEK80S@fc=EjMzBY7~A9EWo~ysd%VSYTQfhM;OXa#yFF_o?T*( zCm?C2W&g%QImV2uxo{Utw{+_iIe^+$cCE4U#Dj_tf2=6mu&=eri3bJ5;)X85!<|DM zvs_gDag|H8*oR#~YTO&9M@@XTMZK4U^KSD*2zrcXYz~T9s4nB@(s{jVfJTnOXHD^N zX`%xF-PGLIq+0Zxcu>{rk-ToC*2SRN$(37pAQKTQ>GGExfR>B8%N`HzwN{;D&rkIw z(m}nVO~KIG11grD8;ILePHSM;Jfqy3hkF!*8KONNdh&CRmVt-Ew!Lq72jPl`!>;T+ zNzzZ=TS&Ob+ai%Ln)TQRO}1hwdab-|yy+iW%~t=QJar|^X18&Mddp2(ya1G@iH+kM z3r_!Ffa1ZT%VnUQMx=O9;yi3g@*V$RxAxkJ!Pa0fkzFwg2_kjwPZtl(*h#cmXm4iH zw3mFhpqwmg$gh$(YbgNf6^GsJ;o_ki5ra!5Mu#4TI;<5I1qpjsMp^6+&XUM7dC<+* zMw?bOs=&G)w(6FAZ{K;3hoKXP?PQ;G3wXfyH1BRydcwnh`iDIp==|i;{%8j-)#6Ki z$dQuIvp>p8ZFjbv1(9^ut;~}M9(rDz>94<|AVR}2A=Ooca?1H^J32$1_QlN67}jpK zW2raW>7@U}!?r-y2L8aaLzo%)BNLB&H4 zqcFgHGq>B=^5D!#Mcb5G5Ph=P%iKvEc9krJJcL?1XRO8$lDnns>uFX7iiLi<9-@{1 zP76YfZRuO6&`gjhUgGMf8)%X%MCj=SfgHi#!ozVpS}P~2dp+CEpx$hU#-?ON3IE1J zp>wt!cH_|IqPuNXuYA}JenU^|Q>T4j%%-`AUCqQ%r9MuurZq}o$Yyva2-@CL?DPlR{ zK^95F9m3FPpNPz;a-S2?^L&5@Ol#%j79Pq6oVn!)S5oI$swQDQtR{eLJlPn)hQL&f z9xq@DvYvEP49{%r;`MfH{**TnJ~?zZi000cbc2{CXG-ZhaJ4nHP`>m`4y+Xq6=h3> z6y(_5)*8d(b|AZUMDR9GwNwZuwUgJ1k=ATGnJo4Aa17#m^}KiQ-b`j3uq)8Wg>7Ui z4_lqDyQ?#QuuA7t;9(zKJ$dqEzkN0K`uZDz!&V6@9@_MjJ+(Ae7*wM5TFi?5uNg%h z*As-Cd`o8g{J}=$wO<_7;B`YVotZXLs(dCM_9Z>A&Ih)-b?Te#Ovcg$H6PA|;S9Q) z15vgihXP0hEZ1)5eT+4aX*RC6!5*Jrn>{3*pPxT?@SxkVx5Ch#m9NgIL)GG2{ZLyG z^84d08huWX6RsX1_oq~ynv)zWN&28(^ zP5G+_Q%94?~xSlPbbwHeGN!{TN;DuNr#eQu%-%3RKSAaCNqTDgyUc)$3l5TSgb zZOxS`;Nn4G*c`0V5MGZ|k`o}x$48&>R-D|>iz)1?~bCwqh)hP<<0)K0#6WdKHUX&^NqL2z;)GB7bSATcyLGdMahG9W83GB7ZeCC^>}000McNliru z-2?>;CJbX(#mE2v010qNS#tmY9>D+r9>D>_X;f1H000DMK}|sb0I`n?{9y$E00MPM zL_t(|+C7s?OB-PnhTj<{F%y$$yx|p8LP^v`!G&~F*9A*|MECv+H;TVO+=$@DU(toT z6iY#n2tma}swPe@lT4;Qr=$ZP`L6GI&vQ`}_Mb=X-m5F>6wD zK7aZeV=oBrwZ6Wtv9U3;>ifRUA0HnT$FX*IchzV#bbWno&OFaEJ|^HK8`|95wCKHF zPv__7?@;@SqDYBELRckV#>&cyZf|dm2~b@>7ixQZ+lX@E<>kc=`7)V|*(Wl4%gf7} zo13%93|x3XAqtC|n;UZw1cA|BT3RxZ*Vk9emsAkq7sv$lh&n$%ZxI(377SjwT-M^^ zqUFjrK0a=99#Y!L$;tmh9v7(T-QAtu-rfu(xz}nnO-)VNgCTL&KxAGl7H!`R!%$aO zS7x1BvnCzX0a>k9jSCKNM|FV82OAG7Jf=C=oS2xfvAViyB9Ml`@Zr|hmX#K6l-VO% zp-`|U0T_q*eBO9)1}uaCj0j@DrP)Z`qbzJ59v+&5gM)*(QmI&4L?jXeE(p?{mzS3& z3^Ny4P(3<2vi9VF+7ktfWdKHUX&^NqL2z;)GB7bSATcyLGdMaiHXti7GB7Z$!0Xch000McNliru z-2?>;CK!2w5w!pS010qNS#tmY9>D+r9>D>_X;f1H000DMK}|sb0I`n?{9y$E00M7G zL_t(|+C7uKPGV6Mh1b0Tf}n_sFb2$^h4Gh)#+r_Y;1zrl6Dt#`>8z~u3G7TXW2}&< z5XY!QeiTsQ4&R>OZq7dU?6dY-YoF^Bi$$;7?aK2!rPFB*1_L#lO?`fTDjtv9{`U4( zK{usNrzs*5iE20;s@Hp$8xDs@Nl$BQYnq&#)XU3@t-HIsT3A@n*4CD?*{s_A>gan& zz5cs_RH}b$b-%yAb#ijzu%T%2dvg9l}cVRnbi6DxnL6tg{-sB=hMf> zhn}9EF<)y;@^nVYgr>7N-My-$ua4{B(jogmd1#~YhE&b$+i;G%WSy8iFm2Y-- z)+1p#4>FmItpse?BZtvqI3Cf+ zM*)a*rUM6z6SKw_2+SO7UtV4|zmV!u+-|oGfWSPof{s5A4-aZI8YYGO?Ci{8oYb^h zEx8<^pOG=^xw$!emD}6fN+c2{4Ve^EOYH6KIe1_aFbYbT!#KxA;S0}vW@g6LTCHaJ z{{Ft#@Ar)gr0>YV~L4_yDVXKChdb8{OUA>EPhNIXpb{i~)tb0qF7y zF^vlZjEM2Sfmi%1e8U&O%>!sdi3u=&9ut1Rh;yjl-`{I>bydg5$KL7bsRsx?`~!%2 VS{13(VPOCO002ovPDHLkV1lz~YYYGY literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/classiccasting/textures/blocks/infusion3.png b/src/main/resources/assets/classiccasting/textures/blocks/infusion3.png new file mode 100644 index 0000000000000000000000000000000000000000..30f02d3bdc059b5c41e6e5bead4fe8e89214dc6c GIT binary patch literal 806 zcmV+>1KIqEP)WdKHUX&^NqL2z;)GB7bSATcyLGdMajIUp-AGB7aJ2b|de000McNliru z-2?>;CL~tvZ887=010qNS#tmY9>D+r9>D>_X;f1H000DMK}|sb0I`n?{9y$E00MqV zL_t(|+C5X-N}^#DU7!BuDJe}nUualVh=EMEzQDl149s;`1I{aW-JLJso!|@Tl{Y;_ zUQ9$ZF)600c|N9n^RErHLH_Tw_gZ`HrMkSl)T`AB0pxIE>rdTO1u7!D_Yg%)nqUK&@6&Fr!o|>GgVzU@(ZuWP<(ueJRG@X0wqZ zUauF!;gHW^u=?5A88VrSjz*)H&*yl1dy_<`(<#VyyIm5wcDYPn|lDYV;d5szp#n@tcO9v-B3CU3V}X?HXlNgD>MQe6sneSIxoR_0|q9>?zPt~_Q@ zw!(eC-xn4X)}XTNj}eJP(ChVZb8`bugh-6Ny**j8C|US?J}D*)SncugQ67;VN5(HT zpgufja8Es+o}MJ}P)WdKHUX&^NqL2z;)GB7bSATcyLGdMalFd!>1GB7ZP@X(C_000McNliru z-2?>;CNIH1w7LKQ010qNS#tmY9>D+r9>D>_X;f1H000DMK}|sb0I`n?{9y$E00Ndt zL_t(|+C5TBOL9>ZUH5u@mhVSO1}0P(iO|4_H0>t@{)<2V$;vkwfZV=Rzo}R*FGGQ+9>P)oQ_D(&FNxATq(>a7ZDy+YO7w0+RgB{n29J-AFq_S|y}gy-%gaj%Bs%x! z=cj1i+}uRF-NwVigA`{D`({wv>+7p%PN&oO{{9vgl}bfq@w~daD%78!pK)+-AU)XM z-&aphPcRyd#-CPhHjxF{3!bU{?(Por^Yd6MXMxjs;0E3O__xnQg{{9|s zZ*S5QTIu)u!C)345Z?&${{Ai!xb>f(9|@%Ai9|wdBO@a6pUdm@$~O}Nfq+;}t4E^| zbRzITCe-iq`6Te;gBoFY{F@cVQd~vs1MK|_Tcx0p-q1O0rr4udr#PF>;M1&07*qo IM6N<$f~O#SZ~y=R literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/classiccasting/textures/blocks/infusion5.png b/src/main/resources/assets/classiccasting/textures/blocks/infusion5.png new file mode 100644 index 0000000000000000000000000000000000000000..b12d4f91202c4b2ba1c69b14e629e9b7eeddf972 GIT binary patch literal 837 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 literal 0 HcmV?d00001