diff --git a/src/main/java/dev/tilera/classiccasting/ClassicCasting.java b/src/main/java/dev/tilera/classiccasting/ClassicCasting.java index 1b70de9..70ee418 100644 --- a/src/main/java/dev/tilera/classiccasting/ClassicCasting.java +++ b/src/main/java/dev/tilera/classiccasting/ClassicCasting.java @@ -1,6 +1,7 @@ package dev.tilera.classiccasting; import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLPreInitializationEvent; @Mod( @@ -10,9 +11,17 @@ import cpw.mods.fml.common.event.FMLPreInitializationEvent; dependencies = "required-after:Thaumcraft" ) public class ClassicCasting { + @SidedProxy( + modId = "classiccasting", + clientSide = "dev.tilera.classiccasting.ClientProxy", + serverSide = "dev.tilera.classiccasting.CommonProxy" + ) + public static CommonProxy proxy; + @Mod.EventHandler public void preInit(FMLPreInitializationEvent ev) { ClassicCastingTab.INSTANCE = new ClassicCastingTab(); Items.init(); + proxy.preInit(); } } diff --git a/src/main/java/dev/tilera/classiccasting/ClientProxy.java b/src/main/java/dev/tilera/classiccasting/ClientProxy.java new file mode 100644 index 0000000..eff9983 --- /dev/null +++ b/src/main/java/dev/tilera/classiccasting/ClientProxy.java @@ -0,0 +1,12 @@ +package dev.tilera.classiccasting; + +import cpw.mods.fml.common.FMLCommonHandler; + +public class ClientProxy extends CommonProxy { + @Override + public void preInit() { + super.preInit(); + + FMLCommonHandler.instance().bus().register(new GuiTicker()); + } +} diff --git a/src/main/java/dev/tilera/classiccasting/CommonProxy.java b/src/main/java/dev/tilera/classiccasting/CommonProxy.java new file mode 100644 index 0000000..a019abc --- /dev/null +++ b/src/main/java/dev/tilera/classiccasting/CommonProxy.java @@ -0,0 +1,9 @@ +package dev.tilera.classiccasting; + +import cpw.mods.fml.common.FMLCommonHandler; + +public class CommonProxy { + public void preInit() { + FMLCommonHandler.instance().bus().register(new WorldTicker()); + } +} diff --git a/src/main/java/dev/tilera/classiccasting/GuiTicker.java b/src/main/java/dev/tilera/classiccasting/GuiTicker.java new file mode 100644 index 0000000..23cb956 --- /dev/null +++ b/src/main/java/dev/tilera/classiccasting/GuiTicker.java @@ -0,0 +1,291 @@ +package dev.tilera.classiccasting; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import cpw.mods.fml.common.gameevent.TickEvent.RenderTickEvent; +import dev.tilera.classiccasting.items.wands.ItemHellrod; +import dev.tilera.classiccasting.items.wands.ItemWandCasting; +import dev.tilera.classiccasting.items.wands.ItemWandTrade; +import net.minecraft.block.material.Material; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; +import thaumcraft.client.lib.UtilsFX; + +public class GuiTicker { + private int lastCount; + private ItemStack lastItem; + + @SubscribeEvent + public void onRenderTick(RenderTickEvent ev) { + if (ev.phase == TickEvent.Phase.END) + tickEnd(ev.renderTickTime); + } + + private void tickEnd(float partialTicks) { + final Minecraft mc = Minecraft.getMinecraft(); + if (Minecraft.getMinecraft().renderViewEntity instanceof EntityPlayer) { + final EntityPlayer player + = (EntityPlayer) Minecraft.getMinecraft().renderViewEntity; + final long time = System.currentTimeMillis(); + if (player != null && mc.inGameHasFocus && Minecraft.isGuiEnabled()) { + if (player.inventory.getCurrentItem() != null) { + if (player.inventory.getCurrentItem().getItem() + instanceof ItemWandTrade) { + final ItemWandTrade wt + = (ItemWandTrade) player.inventory.getCurrentItem().getItem(); + if (wt.getPickedBlock(player.inventory.getCurrentItem()) + != null) { + this.renderWandTradeHud( + partialTicks, + player, + time, + wt.getPickedBlock(player.inventory.getCurrentItem()) + ); + } + } else if (player.inventory.getCurrentItem().getItem() instanceof ItemHellrod) { + final ItemStack stack = player.inventory.getCurrentItem(); + if (stack.hasTagCompound() + && stack.stackTagCompound.hasKey("charges")) { + final short charges + = stack.stackTagCompound.getShort("charges"); + this.renderWandHellrodHud( + partialTicks, player, time, charges + ); + } + } else if (player.inventory.getCurrentItem().getItem() instanceof ItemWandCasting) { + final ItemStack stack = player.inventory.getCurrentItem(); + if (stack.hasTagCompound() + && stack.stackTagCompound.hasKey("vis")) { + final short charges = stack.stackTagCompound.getShort("vis"); + final int maxCharges + = ((ItemWandCasting) player.inventory.getCurrentItem() + .getItem()) + .getMaxVis(player.inventory.getCurrentItem()); + this.renderCastingWandHud( + partialTicks, player, time, charges, maxCharges + ); + } + } + } + } + } + } + + private void renderWandTradeHud( + final float partialTicks, + final EntityPlayer player, + final long time, + final ItemStack stack + ) { + final Minecraft mc = Minecraft.getMinecraft(); + final int loc = player.inventory.currentItem * 20; + final int shift = player.capabilities.isCreativeMode ? 0 : 20; + int amount = this.lastCount; + if (player.inventory.inventoryChanged || !stack.isItemEqual(this.lastItem)) { + amount = 0; + for (final ItemStack is : player.inventory.mainInventory) { + if (is != null && is.isItemEqual(stack)) { + amount += is.stackSize; + } + } + this.lastItem = stack; + player.inventory.inventoryChanged = false; + } + this.lastCount = amount; + GL11.glPushMatrix(); + final ScaledResolution sr + = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + GL11.glClear(256); + GL11.glMatrixMode(5889); + GL11.glLoadIdentity(); + GL11.glOrtho( + 0.0, + sr.getScaledWidth_double(), + sr.getScaledHeight_double(), + 0.0, + 1000.0, + 3000.0 + ); + GL11.glMatrixMode(5888); + GL11.glLoadIdentity(); + GL11.glTranslatef(0.0f, 0.0f, -2000.0f); + final int k = sr.getScaledWidth(); + final int l = sr.getScaledHeight(); + GL11.glPushMatrix(); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + GL11.glEnable(3042); + GL11.glBlendFunc(770, 1); + mc.renderEngine.bindTexture( + new ResourceLocation("auracore", "textures/misc/particles.png") + ); + final int px = 32 * (mc.thePlayer.ticksExisted % 16); + final int py = 32 * (mc.thePlayer.ticksExisted % 32 / 16); + UtilsFX.drawTexturedQuad( + k / 2 - 96 + loc, l - 58 - shift, px, 96 + py, 32, 32, -90.0 + ); + GL11.glDisable(3042); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + RenderHelper.enableGUIStandardItemLighting(); + GL11.glDisable(2896); + GL11.glEnable(32826); + GL11.glEnable(2903); + GL11.glEnable(2896); + final RenderItem itemRenderer = new RenderItem(); + try { + itemRenderer.renderItemIntoGUI( + mc.fontRenderer, + mc.renderEngine, + stack, + k / 2 - 96 + 8 + loc, + l - 50 - shift + ); + } catch (final Exception ex) {} + GL11.glDisable(2896); + GL11.glPushMatrix(); + final String am = "" + amount; + final int sw = mc.fontRenderer.getStringWidth(am); + GL11.glTranslatef( + (float) (k / 2 - 96 + 24 + loc), + (float) (l - 30 - shift - mc.fontRenderer.FONT_HEIGHT), + 500.0f + ); + GL11.glScalef(0.5f, 0.5f, 0.5f); + for (int a = -1; a <= 1; ++a) { + for (int b = -1; b <= 1; ++b) { + if ((a == 0 || b == 0) && (a != 0 || b != 0)) { + mc.fontRenderer.drawString(am, a - sw, b, 0); + } + } + } + mc.fontRenderer.drawString(am, -sw, 0, 16777215); + GL11.glPopMatrix(); + GL11.glPopMatrix(); + GL11.glPopMatrix(); + } + + private void renderWandHellrodHud( + final float partialTicks, + final EntityPlayer player, + final long time, + final short charges + ) { + final Minecraft mc = Minecraft.getMinecraft(); + final int shift = player.capabilities.isCreativeMode + ? 6 + : (player.isInsideOfMaterial(Material.water) ? 29 : 20); + GL11.glPushMatrix(); + final ScaledResolution sr + = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + GL11.glClear(256); + GL11.glMatrixMode(5889); + GL11.glLoadIdentity(); + GL11.glOrtho( + 0.0, + sr.getScaledWidth_double(), + sr.getScaledHeight_double(), + 0.0, + 1000.0, + 3000.0 + ); + GL11.glMatrixMode(5888); + GL11.glLoadIdentity(); + final int k = sr.getScaledWidth(); + final int l = sr.getScaledHeight(); + GL11.glTranslatef((float) (k / 2 + 10), l - 29.0f - shift, -2000.0f); + GL11.glPushMatrix(); + GL11.glScalef(0.525f, 0.525f, 0.525f); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + mc.renderEngine.bindTexture( + new ResourceLocation("auracore", "textures/misc/particles.png") + ); + for (int a = 0; a < 9; ++a) { + GL11.glPushMatrix(); + final float bob + = MathHelper.sin((player.ticksExisted + a * 10) / 5.0f) * 1.0f + 1.0f; + GL11.glTranslatef(0.0f, bob, 0.0f); + UtilsFX.drawTexturedQuad( + a * 17, 0, 160 + ((a >= charges) ? 16 : 0), 0, 16, 16, -90.0 + ); + GL11.glPopMatrix(); + } + GL11.glDisable(3042); + GL11.glScalef(1.0f, 1.0f, 1.0f); + GL11.glPopMatrix(); + GL11.glPopMatrix(); + } + + private void renderCastingWandHud( + final Float partialTicks, + final EntityPlayer player, + final long time, + final short charges, + final int maxCharges + ) { + final Minecraft mc = Minecraft.getMinecraft(); + final int shift = player.capabilities.isCreativeMode + ? 6 + : (player.isInsideOfMaterial(Material.water) ? 29 : 20); + final int size = (int) (charges / (float) maxCharges * 80.0f); + GL11.glPushMatrix(); + final ScaledResolution sr + = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + GL11.glClear(256); + GL11.glMatrixMode(5889); + GL11.glLoadIdentity(); + GL11.glOrtho( + 0.0, + sr.getScaledWidth_double(), + sr.getScaledHeight_double(), + 0.0, + 1000.0, + 3000.0 + ); + GL11.glMatrixMode(5888); + GL11.glLoadIdentity(); + final int k = sr.getScaledWidth(); + final int l = sr.getScaledHeight(); + GL11.glTranslatef((float) (k / 2 + 10), l - 28.5f - shift, -2000.0f); + GL11.glPushMatrix(); + GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + GL11.glEnable(3042); + GL11.glBlendFunc(770, 771); + mc.renderEngine.bindTexture( + new ResourceLocation("auracore", "textures/misc/particles.png") + ); + UtilsFX.drawTexturedQuad(0, 0, 0, 248, size, 8, -90.0); + UtilsFX.drawTexturedQuad(size, 0, size, 240, 80 - size, 8, -90.0); + GL11.glDisable(3042); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glTranslatef(40.0f, 1.5f, 0.0f); + GL11.glScalef(0.5f, 0.5f, 0.5f); + String msg = charges + " vis"; + mc.ingameGUI.drawString( + mc.fontRenderer, msg, -mc.fontRenderer.getStringWidth(msg) / 2, 1, 16777215 + ); + final int discount = WandManager.getTotalVisDiscount(player); + if (discount > 0) { + msg = "-" + discount + "%"; + mc.ingameGUI.drawString( + mc.fontRenderer, + msg, + 75 - mc.fontRenderer.getStringWidth(msg), + 1, + 16777215 + ); + } + GL11.glScalef(1.0f, 1.0f, 1.0f); + GL11.glPopMatrix(); + GL11.glPopMatrix(); + } +} diff --git a/src/main/java/dev/tilera/classiccasting/Utils.java b/src/main/java/dev/tilera/classiccasting/Utils.java index 2100e7e..a550601 100644 --- a/src/main/java/dev/tilera/classiccasting/Utils.java +++ b/src/main/java/dev/tilera/classiccasting/Utils.java @@ -4,6 +4,7 @@ import java.util.List; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.MathHelper; import net.minecraft.util.MovingObjectPosition; @@ -197,4 +198,24 @@ public class Utils { final Vec3 var21 = var13.addVector(var18 * var20, var17 * var20, var19 * var20); return world.rayTraceBlocks(var13, var21, par3); } + + public static int isPlayerCarrying(final EntityPlayer player, final ItemStack stack) { + for (int var2 = 0; var2 < player.inventory.mainInventory.length; ++var2) { + if (player.inventory.mainInventory[var2] != null + && player.inventory.mainInventory[var2].isItemEqual(stack)) { + return var2; + } + } + return -1; + } + + public static boolean + isBlockExposed(final World world, final int x, final int y, final int z) { + return !world.getBlock(x, y, z + 1).isOpaqueCube() + || !world.getBlock(x, y, z - 1).isOpaqueCube() + || !world.getBlock(x + 1, y, z).isOpaqueCube() + || !world.getBlock(x - 1, y, z).isOpaqueCube() + || !world.getBlock(x, y + 1, z).isOpaqueCube() + || !world.getBlock(x, y - 1, z).isOpaqueCube(); + } } diff --git a/src/main/java/dev/tilera/classiccasting/WandManager.java b/src/main/java/dev/tilera/classiccasting/WandManager.java new file mode 100644 index 0000000..1de95f5 --- /dev/null +++ b/src/main/java/dev/tilera/classiccasting/WandManager.java @@ -0,0 +1,229 @@ +package dev.tilera.classiccasting; + +import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; +import cpw.mods.fml.common.registry.LanguageRegistry; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagShort; +import net.minecraft.util.ChatComponentText; +import net.minecraft.world.World; +import thaumcraft.api.IVisDiscountGear; +import thaumcraft.common.config.ConfigBlocks; +import thaumcraft.common.config.ConfigItems; +import thaumcraft.common.entities.EntitySpecialItem; +import thaumcraft.common.lib.network.PacketHandler; +import thaumcraft.common.lib.network.fx.PacketFXBlockSparkle; + +public class WandManager { + public static int getTotalVisDiscount(final EntityPlayer player) { + int total = 0; + for (int a = 0; a < 4; ++a) { + if (player.inventory.armorItemInSlot(a) != null + && player.inventory.armorItemInSlot(a).getItem() + instanceof IVisDiscountGear) { + total + += ((IVisDiscountGear) player.inventory.armorItemInSlot(a).getItem()) + .getVisDiscount( + player.inventory.armorItemInSlot(a), player, null + ); + } + } + return total; + } + + public static boolean spendCharge( + final World world, + 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 (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" + ) + )); + } + } + } + return false; + } + + 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; + } + + public static boolean + createThaumonomicon(ItemStack is, EntityPlayer p, World w, int x, int y, int z) { + if (!spendCharge(is, p, 25) || w.isRemote) + return false; + + w.setBlockToAir(x, y, z); + + EntitySpecialItem entityItem = new EntitySpecialItem( + w, + (double) (x + 0.5D), + (double) (y + 0.3D), + (double) (z + 0.5D), + new ItemStack(ConfigItems.itemThaumonomicon) + ); + + entityItem.motionY = 0.0D; + entityItem.motionX = 0.0D; + entityItem.motionZ = 0.0D; + + w.spawnEntityInWorld(entityItem); + PacketHandler.INSTANCE.sendToAllAround( + new PacketFXBlockSparkle(x, y, z, -9999), + new TargetPoint(w.provider.dimensionId, x, y, z, 32) + ); + w.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "thaumcraft:wand", 1.0F, 1.0F); + return true; + } + + public static boolean + createCrucible(ItemStack is, EntityPlayer p, World w, int x, int y, int z) { + if (!spendCharge(is, p, 25) || w.isRemote) + return false; + + w.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "thaumcraft:wand", 1.0F, 1.0F); + w.setBlock(x, y, z, ConfigBlocks.blockMetalDevice, 0, 3); + w.notifyBlocksOfNeighborChange(x, y, z, w.getBlock(x, y, z)); + w.markBlockForUpdate(x, y, z); + w.addBlockEvent(x, y, z, ConfigBlocks.blockMetalDevice, 1, 1); + return true; + } + + public static boolean createArcaneFurnace( + final ItemStack itemstack, + final EntityPlayer player, + final World world, + final int x, + final int y, + final int z + ) { + for (int xx = x - 2; xx <= x; ++xx) { + for (int yy = y - 2; yy <= y; ++yy) { + int zz = z - 2; + while (zz <= z) { + if (fitArcaneFurnace(world, xx, yy, zz) + && spendCharge(world, itemstack, player, 100)) { + if (!world.isRemote) { + replaceArcaneFurnace(world, xx, yy, zz); + return true; + } + return false; + } else { + ++zz; + } + } + } + } + return false; + } + + public static boolean + fitArcaneFurnace(final World world, final int x, final int y, final int z) { + final Block bo = Blocks.obsidian; + final Block bn = Blocks.nether_brick; + final Block bf = Blocks.iron_bars; + final Block bl = Blocks.lava; + final Block[][][] blueprint + = { { { bn, bo, bn }, { bo, Blocks.air, bo }, { bn, bo, bn } }, + { { bn, bo, bn }, { bo, bl, bo }, { bn, bo, bn } }, + { { bn, bo, bn }, { bo, bo, bo }, { bn, bo, bn } } }; + boolean fencefound = false; + for (int yy = 0; yy < 3; ++yy) { + for (int xx = 0; xx < 3; ++xx) { + for (int zz = 0; zz < 3; ++zz) { + final Block block = world.getBlock(x + xx, y - yy + 2, z + zz); + if (block != blueprint[yy][xx][zz]) { + if (yy != 1 || fencefound || block != bf || xx == zz + || (xx != 1 && zz != 1)) { + return false; + } + fencefound = true; + } + } + } + } + return fencefound; + } + + public static boolean + replaceArcaneFurnace(final World world, final int x, final int y, final int z) { + final boolean fencefound = false; + for (int yy = 0; yy < 3; ++yy) { + int step = 1; + for (int zz = 0; zz < 3; ++zz) { + for (int xx = 0; xx < 3; ++xx) { + int md = step; + if (world.getBlock(x + xx, y + yy, z + zz) == Blocks.lava + || world.getBlock(x + xx, y + yy, z + zz) + == Blocks.flowing_lava) { + md = 0; + } + if (world.getBlock(x + xx, y + yy, z + zz) == Blocks.iron_bars) { + md = 10; + } + if (!world.isAirBlock(x + xx, y + yy, z + zz)) { + world.setBlock( + x + xx, y + yy, z + zz, ConfigBlocks.blockArcaneFurnace, md, 0 + ); + world.addBlockEvent( + x + xx, y + yy, z + zz, ConfigBlocks.blockArcaneFurnace, 1, 4 + ); + } + ++step; + } + } + } + for (int yy = 0; yy < 3; ++yy) { + for (int zz2 = 0; zz2 < 3; ++zz2) { + for (int xx2 = 0; xx2 < 3; ++xx2) { + world.markBlockForUpdate(x + xx2, y + yy, z + zz2); + } + } + } + return fencefound; + } +} diff --git a/src/main/java/dev/tilera/classiccasting/WorldTicker.java b/src/main/java/dev/tilera/classiccasting/WorldTicker.java new file mode 100644 index 0000000..33f4526 --- /dev/null +++ b/src/main/java/dev/tilera/classiccasting/WorldTicker.java @@ -0,0 +1,223 @@ +package dev.tilera.classiccasting; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.LinkedBlockingQueue; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import cpw.mods.fml.common.gameevent.TickEvent.WorldTickEvent; +import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; +import cpw.mods.fml.relauncher.Side; +import dev.tilera.classiccasting.items.wands.ItemWandTrade; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import thaumcraft.common.lib.network.PacketHandler; +import thaumcraft.common.lib.network.fx.PacketFXBlockSparkle; + +public class WorldTicker { + long timeThisTick; + public static Map> swapList + = new HashMap<>(); + + @SubscribeEvent + public void onWorldTick(WorldTickEvent ev) { + if (ev.phase == TickEvent.Phase.END && ev.side == Side.SERVER) + this.tickEnd(ev.world); + } + + private void tickEnd(World world) { + this.swapTicks(world); + } + + private void swapTicks(World world) { + final int dim = ((World) world).provider.dimensionId; + final LinkedBlockingQueue queue = WorldTicker.swapList.get(dim); + if (queue != null) { + boolean didSomething = false; + while (!didSomething) { + final VirtualSwapper vs = queue.poll(); + if (vs != null) { + final Block bi = world.getBlock(vs.x, vs.y, vs.z); + final int md = world.getBlockMetadata(vs.x, vs.y, vs.z); + if ((bi == vs.bTarget && md == vs.mTarget) + || vs.player.inventory.getStackInSlot(vs.wand) == null + || !( + vs.player.inventory.getStackInSlot(vs.wand).getItem() + instanceof ItemWandTrade + ) + || vs.player.inventory.getStackInSlot(vs.wand).getItemDamage() + > vs.player.inventory.getStackInSlot(vs.wand).getMaxDamage( + )) { + continue; + } + final int slot = Utils.isPlayerCarrying( + vs.player, new ItemStack(vs.bTarget, 1, vs.mTarget) + ); + if (vs.bSource != bi || vs.mSource != md || slot < 0) { + continue; + } + didSomething = true; + final int fortune + = ((ItemWandTrade) vs.player.inventory.getStackInSlot(vs.wand) + .getItem()) + .getTreasure(vs.player.inventory.getStackInSlot(vs.wand)); + vs.player.inventory.decrStackSize(slot, 1); + final ArrayList ret + = bi.getDrops((World) world, vs.x, vs.y, vs.z, md, fortune); + if (ret.size() > 0) { + for (final ItemStack is : ret) { + if (!vs.player.inventory.addItemStackToInventory(is)) { + world.spawnEntityInWorld((Entity) new EntityItem( + (World) world, vs.x + 0.5, vs.y + 0.5, vs.z + 0.5, is + )); + } + } + } + ((ItemWandTrade) vs.player.inventory.getStackInSlot(vs.wand).getItem() + ) + .damageWand( + vs.player.inventory.getStackInSlot(vs.wand), vs.player, 1 + ); + if (vs.player.inventory.getStackInSlot(vs.wand).getItemDamage() + >= vs.player.inventory.getStackInSlot(vs.wand).getMaxDamage()) { + vs.player.renderBrokenItemStack( + vs.player.inventory.getStackInSlot(vs.wand) + ); + vs.player.inventory.setInventorySlotContents( + vs.wand, (ItemStack) null + ); + vs.player.inventoryContainer.detectAndSendChanges(); + } + world.setBlock(vs.x, vs.y, vs.z, vs.bTarget, vs.mTarget, 3); + PacketHandler.INSTANCE.sendToAllAround( + new PacketFXBlockSparkle(vs.x, vs.y, vs.z, -9999), + new TargetPoint(world.provider.dimensionId, vs.x, vs.y, vs.z, 32) + ); + world.playAuxSFX( + 2001, + vs.x, + vs.y, + vs.z, + Block.getIdFromBlock(vs.bSource) + (vs.mSource << 12) + ); + if (vs.lifespan <= 0) { + continue; + } + for (int xx = -1; xx <= 1; ++xx) { + for (int yy = -1; yy <= 1; ++yy) { + for (int zz = -1; zz <= 1; ++zz) { + if ((xx != 0 || yy != 0 || zz != 0) + && world.getBlock(vs.x + xx, vs.y + yy, vs.z + zz) + == vs.bSource + && world.getBlockMetadata( + vs.x + xx, vs.y + yy, vs.z + zz + ) == vs.mSource + && Utils.isBlockExposed( + (World) world, vs.x + xx, vs.y + yy, vs.z + zz + )) { + queue.offer(new VirtualSwapper( + vs.x + xx, + vs.y + yy, + vs.z + zz, + vs.bSource, + vs.mSource, + vs.bTarget, + vs.mTarget, + vs.lifespan - 1, + vs.player, + vs.wand + )); + } + } + } + } + } else { + didSomething = true; + } + } + WorldTicker.swapList.put(dim, queue); + } + } + + public static void addSwapper( + final World world, + final int x, + final int y, + final int z, + final Block bs, + final int ms, + final Block bt, + final int mt, + final int life, + final EntityPlayer player, + final int wand + ) { + final int dim = world.provider.dimensionId; + if (bs == Blocks.air || bs.getBlockHardness(world, x, y, z) < 0.0f + || (bs == bt && ms == mt)) { + return; + } + LinkedBlockingQueue queue = WorldTicker.swapList.get(dim); + if (queue == null) { + WorldTicker.swapList.put(dim, new LinkedBlockingQueue<>()); + queue = WorldTicker.swapList.get(dim); + } + queue.offer(new VirtualSwapper(x, y, z, bs, ms, bt, mt, life, player, wand)); + world.playSoundAtEntity((Entity) player, "thaumcraft:wand", 0.25f, 1.0f); + WorldTicker.swapList.put(dim, queue); + } + + public static class VirtualSwapper { + int lifespan; + int x; + int y; + int z; + Block bSource; + int mSource; + Block bTarget; + int mTarget; + int wand; + EntityPlayer player; + + VirtualSwapper( + int x, + int y, + int z, + Block bs, + int ms, + Block bt, + int mt, + int life, + EntityPlayer p, + int wand + ) { + this.lifespan = 0; + this.x = 0; + this.y = 0; + this.z = 0; + this.bSource = Blocks.air; + this.mSource = 0; + this.bTarget = Blocks.air; + this.mTarget = 0; + this.wand = 0; + this.player = null; + this.x = x; + this.y = y; + this.z = z; + this.bSource = bs; + this.mSource = ms; + this.bTarget = bt; + this.mTarget = mt; + this.lifespan = life; + this.player = p; + this.wand = wand; + } + } +} diff --git a/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandBasic.java b/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandBasic.java index d7a38db..9aff2f9 100644 --- a/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandBasic.java +++ b/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandBasic.java @@ -57,6 +57,7 @@ public class ItemWandBasic extends Item { // itemstack.damageItem(1, (EntityLiving) p); // } //} + itemstack.damageItem(1, p); return itemstack; } diff --git a/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandCasting.java b/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandCasting.java index b1fe388..e85cbc5 100644 --- a/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandCasting.java +++ b/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandCasting.java @@ -6,6 +6,7 @@ import cpw.mods.fml.common.registry.LanguageRegistry; import dev.tilera.auracore.api.IWand; import dev.tilera.auracore.aura.AuraManager; import dev.tilera.classiccasting.ClassicCastingTab; +import dev.tilera.classiccasting.WandManager; import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.item.EntityItem; @@ -21,7 +22,6 @@ import net.minecraftforge.common.util.ForgeDirection; import thaumcraft.common.config.Config; import thaumcraft.common.config.ConfigBlocks; import thaumcraft.common.config.ConfigItems; -import thaumcraft.common.items.wands.WandManager; import thaumcraft.common.lib.research.ResearchManager; import thaumcraft.common.tiles.TileArcaneBore; import thaumcraft.common.tiles.TileArcaneBoreBase; @@ -292,18 +292,15 @@ public abstract class ItemWandCasting extends Item implements IWand { } } if (bi == Blocks.bookshelf) { - // TODO: wrong WandManager, this is gonna throw a CCE result = WandManager.createThaumonomicon(itemstack, player, world, x, y, z); } if (bi == Blocks.cauldron) { - // TODO: same here result = WandManager.createCrucible(itemstack, player, world, x, y, z); } if ((bi == Blocks.obsidian || bi == Blocks.nether_brick || bi == Blocks.iron_bars) && ResearchManager.isResearchComplete( player.getDisplayName(), "INFERNALFURNACE" )) { - // TODO: you get the point result = WandManager.createArcaneFurnace(itemstack, player, world, x, y, z); } // TODO: WTF diff --git a/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandTrade.java b/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandTrade.java index fb02ea8..f345393 100644 --- a/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandTrade.java +++ b/src/main/java/dev/tilera/classiccasting/items/wands/ItemWandTrade.java @@ -3,17 +3,18 @@ package dev.tilera.classiccasting.items.wands; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import dev.tilera.auracore.aura.AuraManager; +import dev.tilera.classiccasting.WorldTicker; import net.minecraft.block.Block; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagInt; import net.minecraft.util.IIcon; import net.minecraft.world.World; -import thaumcraft.common.lib.events.ServerTickEventsFML; public class ItemWandTrade extends ItemWandBasic { public IIcon icon; @@ -49,7 +50,7 @@ public class ItemWandTrade extends ItemWandBasic { } if (!w.isRemote && e.ticksExisted % 50 == 0 && is.getItemDamage() > 0 && AuraManager.decreaseClosestAura(w, e.posX, e.posY, e.posZ, 1)) { - is.damageItem(-4, (EntityLiving) e); + is.damageItem(-4, (EntityLivingBase) e); if (is.getItemDamage() < 0) { is.setItemDamage(0); } @@ -84,14 +85,15 @@ public class ItemWandTrade extends ItemWandBasic { if (pb != null && world.isRemote) { player.swingItem(); } else if (pb != null && world.getTileEntity(x, y, z) == null) { - ServerTickEventsFML.addSwapper( + WorldTicker.addSwapper( world, x, y, z, world.getBlock(x, y, z), world.getBlockMetadata(x, y, z), - pb, + Block.getBlockFromItem(pb.getItem()), + pb.getItemDamage(), 3 + this.getPotency(itemstack), player, player.inventory.currentItem @@ -124,20 +126,26 @@ public class ItemWandTrade extends ItemWandBasic { final ItemStack pb = this.getPickedBlock(itemstack); if (pb == null || !((Entity) player).worldObj.isRemote) { if (pb != null && ((Entity) player).worldObj.getTileEntity(x, y, z) == null) { - ServerTickEventsFML.addSwapper( + WorldTicker.addSwapper( ((Entity) player).worldObj, x, y, z, ((Entity) player).worldObj.getBlock(x, y, z), ((Entity) player).worldObj.getBlockMetadata(x, y, z), - pb, + Block.getBlockFromItem(pb.getItem()), + pb.getItemDamage(), 0, player, player.inventory.currentItem ); } } + + // TODO: This is required because the game currently is too retarded to realize + // the block has, in fact, not been broken when it's instamined. Maybe theres a + // better workaround? + player.worldObj.markBlockForUpdate(x, y, z); return true; }