From b74776dc05eab0177fa421d287667e186a804e07 Mon Sep 17 00:00:00 2001 From: Bernhard Bonigl Date: Wed, 17 Sep 2014 10:59:47 +0200 Subject: [PATCH] Backup Commit: HarvestTools and Hammer have exact vanilla blockbreaking behaviour, yay --- .../java/tconstruct/items/tools/Hammer.java | 259 ++++++++++++------ .../tconstruct/library/tools/HarvestTool.java | 35 ++- 2 files changed, 203 insertions(+), 91 deletions(-) diff --git a/src/main/java/tconstruct/items/tools/Hammer.java b/src/main/java/tconstruct/items/tools/Hammer.java index 871626fef78..645482fa264 100644 --- a/src/main/java/tconstruct/items/tools/Hammer.java +++ b/src/main/java/tconstruct/items/tools/Hammer.java @@ -5,7 +5,9 @@ import mantle.world.WorldHelper; import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.client.Minecraft; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.*; @@ -223,112 +225,192 @@ public void getSubItems (Item id, CreativeTabs tab, List list) list.add(tool); } - @Override - public boolean onBlockStartBreak (ItemStack stack, int x, int y, int z, EntityPlayer player) - { - if (!stack.hasTagCompound()) - return false; + //@Override + public boolean onBlockDestroyed2(ItemStack itemstack, World world, Block block, int x, int y, int z, EntityLivingBase player) { + int sideHit = Minecraft.getMinecraft().objectMouseOver.sideHit; + + // we successfully destroyed a block. time to do AOE! + int xRange = 1; + int yRange = 1; + int zRange = 1; + switch (sideHit) + { + case 0: + case 1: + yRange = 0; + break; + case 2: + case 3: + zRange = 0; + break; + case 4: + case 5: + xRange = 0; + break; + } + + for (int xPos = x - xRange; xPos <= x + xRange; xPos++) + for (int yPos = y - yRange; yPos <= y + yRange; yPos++) + for (int zPos = z - zRange; zPos <= z + zRange; zPos++) { + // don't break the originally already broken block, duh + if(xPos == x && yPos == y && zPos == z) + continue; + breakExtraBlock(world, xPos, yPos, zPos, sideHit, (EntityPlayer)player); // no player needed because it's local + } + + return super.onBlockDestroyed(itemstack, world, block, x,y,z, player); + } - World world = player.worldObj; - final Block block = world.getBlock(x, y, z); - final int meta = world.getBlockMetadata(x, y, z); - if (!stack.hasTagCompound()) - return false; - if (block == null) - return super.onBlockStartBreak(stack, x, y, z, player); + boolean antiRecurse; + + @Override + public boolean onBlockStartBreak(ItemStack stack, int x, int y, int z, EntityPlayer player) { + // the code below initiates block breaks, which again call this function. But we don't want to do the aoe-break-stuff again. This is to prevent recursive, infinite-range aoe blockbreaking. + if(!antiRecurse) { + antiRecurse = true; + int sideHit = Minecraft.getMinecraft().objectMouseOver.sideHit; + + // we successfully destroyed a block. time to do AOE! + int xRange = 1; + int yRange = 1; + int zRange = 1; + switch (sideHit) { + case 0: + case 1: + yRange = 0; + break; + case 2: + case 3: + zRange = 0; + break; + case 4: + case 5: + xRange = 0; + break; + } - float blockHardness = block.getBlockHardness(world, x, y, z); + for (int xPos = x - xRange; xPos <= x + xRange; xPos++) + for (int yPos = y - yRange; yPos <= y + yRange; yPos++) + for (int zPos = z - zRange; zPos <= z + zRange; zPos++) { + // don't break the originally already broken block, duh + if (xPos == x && yPos == y && zPos == z) + continue; + breakExtraBlock(player.worldObj, xPos, yPos, zPos, sideHit, player); + } + antiRecurse = false; + } + return super.onBlockStartBreak(stack, x, y, z, player); + } - boolean validStart = false; - for (int iter = 0; iter < materials.length; iter++) + /* + @Override + public boolean onBlockStartBreak (ItemStack stack, int x, int y, int z, EntityPlayer player) { - if (materials[iter] == block.getMaterial()) + if (!stack.hasTagCompound()) + return false; + + World world = player.worldObj; + final Block block = world.getBlock(x, y, z); + final int meta = world.getBlockMetadata(x, y, z); + if (!stack.hasTagCompound()) + return false; + + if (block == null) + return super.onBlockStartBreak(stack, x, y, z, player); + + float blockHardness = block.getBlockHardness(world, x, y, z); + + boolean validStart = false; + for (int iter = 0; iter < materials.length; iter++) { - validStart = true; - break; + if (materials[iter] == block.getMaterial()) + { + validStart = true; + break; + } } - } - if (block == Blocks.monster_egg) - validStart = true; + if (block == Blocks.monster_egg) + validStart = true; - MovingObjectPosition mop = AbilityHelper.raytraceFromEntity(world, player, false, 4.5D); - if (mop == null || !validStart) - return super.onBlockStartBreak(stack, x, y, z, player); + MovingObjectPosition mop = AbilityHelper.raytraceFromEntity(world, player, false, 4.5D); + if (mop == null || !validStart) + return super.onBlockStartBreak(stack, x, y, z, player); - int xRange = 1; - int yRange = 1; - int zRange = 1; - switch (mop.sideHit) - { - case 0: - case 1: - yRange = 0; - break; - case 2: - case 3: - zRange = 0; - break; - case 4: - case 5: - xRange = 0; - break; - } + int xRange = 1; + int yRange = 1; + int zRange = 1; + switch (mop.sideHit) + { + case 0: + case 1: + yRange = 0; + break; + case 2: + case 3: + zRange = 0; + break; + case 4: + case 5: + xRange = 0; + break; + } - NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); - int toolLevel = tags.getInteger("HarvestLevel"); - for (int xPos = x - xRange; xPos <= x + xRange; xPos++) - { - for (int yPos = y - yRange; yPos <= y + yRange; yPos++) + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + int toolLevel = tags.getInteger("HarvestLevel"); + for (int xPos = x - xRange; xPos <= x + xRange; xPos++) { - for (int zPos = z - zRange; zPos <= z + zRange; zPos++) + for (int yPos = y - yRange; yPos <= y + yRange; yPos++) { - if (!(tags.getBoolean("Broken"))) + for (int zPos = z - zRange; zPos <= z + zRange; zPos++) { - Block localBlock = world.getBlock(xPos, yPos, zPos); - int localMeta = world.getBlockMetadata(xPos, yPos, zPos); - int hlvl = -1; - if (localBlock.getHarvestTool(localMeta) != null && localBlock.getHarvestTool(localMeta).equals(this.getHarvestType())) - hlvl = localBlock.getHarvestLevel(localMeta); - float localHardness = localBlock.getBlockHardness(world, xPos, yPos, zPos); - - //Choose blocks that aren't too much harder than the first block. Stone: 2.0, Ores: 3.0 - if (hlvl <= toolLevel && localHardness - 1.5 <= blockHardness) + if (!(tags.getBoolean("Broken"))) { - boolean cancelHarvest = false; - for (ActiveToolMod mod : TConstructRegistry.activeModifiers) + Block localBlock = world.getBlock(xPos, yPos, zPos); + int localMeta = world.getBlockMetadata(xPos, yPos, zPos); + int hlvl = -1; + if (localBlock.getHarvestTool(localMeta) != null && localBlock.getHarvestTool(localMeta).equals(this.getHarvestType())) + hlvl = localBlock.getHarvestLevel(localMeta); + float localHardness = localBlock.getBlockHardness(world, xPos, yPos, zPos); + + //Choose blocks that aren't too much harder than the first block. Stone: 2.0, Ores: 3.0 + if (hlvl <= toolLevel && localHardness - 1.5 <= blockHardness) { - if (mod.beforeBlockBreak(this, stack, xPos, yPos, zPos, player)) - cancelHarvest = true; - } + boolean cancelHarvest = false; + for (ActiveToolMod mod : TConstructRegistry.activeModifiers) + { + if (mod.beforeBlockBreak(this, stack, xPos, yPos, zPos, player)) + cancelHarvest = true; + } - // send blockbreak event - BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(x, y, z, world, localBlock, localMeta, player); - event.setCanceled(cancelHarvest); - MinecraftForge.EVENT_BUS.post(event); - cancelHarvest = event.isCanceled(); + // send blockbreak event + BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(x, y, z, world, localBlock, localMeta, player); + event.setCanceled(cancelHarvest); + MinecraftForge.EVENT_BUS.post(event); + cancelHarvest = event.isCanceled(); - if (!cancelHarvest) - { - if (localBlock != null && !(localHardness < 0)) + if (!cancelHarvest) { - for (int iter = 0; iter < materials.length; iter++) + if (localBlock != null && !(localHardness < 0)) { - if (materials[iter] == localBlock.getMaterial() || localBlock == Blocks.monster_egg) + for (int iter = 0; iter < materials.length; iter++) { - if (!player.capabilities.isCreativeMode) + if (materials[iter] == localBlock.getMaterial() || localBlock == Blocks.monster_egg) { - mineBlock(world, xPos, yPos, zPos, localMeta, player, localBlock); - - if (blockHardness > 0f) - onBlockDestroyed(stack, world, localBlock, xPos, yPos, zPos, player); - world.func_147479_m(x, y, z); - } - else - { - WorldHelper.setBlockToAir(world, xPos, yPos, zPos); - world.func_147479_m(x, y, z); + if (!player.capabilities.isCreativeMode) + { + mineBlock(world, xPos, yPos, zPos, localMeta, player, localBlock); + + if (blockHardness > 0f) + onBlockDestroyed(stack, world, localBlock, xPos, yPos, zPos, player); + world.func_147479_m(x, y, z); + } + else + { + WorldHelper.setBlockToAir(world, xPos, yPos, zPos); + world.func_147479_m(x, y, z); + } } } } @@ -338,12 +420,11 @@ public boolean onBlockStartBreak (ItemStack stack, int x, int y, int z, EntityPl } } } + if (!world.isRemote) + world.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(block) + (meta << 12)); + return true; } - if (!world.isRemote) - world.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(block) + (meta << 12)); - return true; - } - + */ @Override public float breakSpeedModifier () { diff --git a/src/main/java/tconstruct/library/tools/HarvestTool.java b/src/main/java/tconstruct/library/tools/HarvestTool.java index 26da5e85957..c6185731eae 100644 --- a/src/main/java/tconstruct/library/tools/HarvestTool.java +++ b/src/main/java/tconstruct/library/tools/HarvestTool.java @@ -5,19 +5,24 @@ import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.PlayerControllerMP; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.item.*; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.INetHandler; import net.minecraft.network.play.client.C07PacketPlayerDigging; +import net.minecraft.network.play.server.S23PacketBlockChange; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.BlockEvent; import tconstruct.TConstruct; import tconstruct.library.*; +import tconstruct.util.network.AOEBlockBreakProgressPacket; +import tconstruct.util.network.PacketPipeline; /* Base class for tools that should be harvesting blocks */ @@ -219,6 +224,32 @@ public boolean onItemUse (ItemStack stack, EntityPlayer player, World world, int return used; } + protected void breakExtraBlock(World world, int x, int y, int z, int sidehit, EntityPlayer player) + { + // prevent calling that stuff for air blocks, could lead to unexpected behaviour since it fires events + if(world.isAirBlock(x,y,z)) + return; + + // check if the block can be broken, since extra block breaks shouldn't instantly break stuff like obsidian + // or precious ores you can't harvest while mining stone + + // this should only be called on the client + if(!world.isRemote) { + // serverside we + EntityPlayerMP mpPlayer = (EntityPlayerMP) player; + mpPlayer.theItemInWorldManager.tryHarvestBlock(x,y,z); + // send block update to client + mpPlayer.playerNetServerHandler.sendPacket(new S23PacketBlockChange(x, y, z, world)); + return; + } + + // and this is the reason why ;o + PlayerControllerMP pcmp = Minecraft.getMinecraft().playerController; + // clientside we do a "this clock has been clicked on long enough to be broken" call. This should not send any new packets + // the code above, executed on the server, sends a block-updates that give us the correct state of the block we destroy. + pcmp.onPlayerDestroyBlock(x, y, z, sidehit); + } + // The Scythe is not a HarvestTool and can't call this method, if you change something here you might change it there too. public void mineBlock (World world, int x, int y, int z, int meta, EntityPlayer player, Block block) { @@ -237,7 +268,7 @@ public void mineBlock (World world, int x, int y, int z, int meta, EntityPlayer if (!silktouch) block.dropXpOnBlockBreak(world, x, y, z, exp); - /* + if (world.isRemote) { INetHandler handler = FMLClientHandler.instance().getClientPlayHandler(); @@ -248,7 +279,7 @@ public void mineBlock (World world, int x, int y, int z, int meta, EntityPlayer handlerClient.addToSendQueue(new C07PacketPlayerDigging(2, x, y, z, Minecraft.getMinecraft().objectMouseOver.sideHit)); } } - */ + } } }