From ca0e32cfd2fb8bba5b1e857039087a54f6969be2 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 5 Sep 2013 10:48:20 -0400 Subject: [PATCH] Add a harvestblock event, to allow mods to intercept and change the drops for blocks. Don't abuse this, or we'll have to take safety measures. Fires for both silktouch and non-silktouch harvesting, and provides the player. Note, you may need to change your break overrides to pass on the player for best results. --- .../event/world/BlockEvent.java | 46 ++++++++ .../net/minecraft/block/Block.java.patch | 110 +++++++++++++----- .../net/minecraft/block/BlockCocoa.java.patch | 23 ++-- .../net/minecraft/block/BlockCrops.java.patch | 22 ++-- .../block/BlockMobSpawner.java.patch | 22 ++++ .../net/minecraft/block/BlockOre.java.patch | 22 ++++ 6 files changed, 205 insertions(+), 40 deletions(-) create mode 100644 common/net/minecraftforge/event/world/BlockEvent.java create mode 100644 patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockOre.java.patch diff --git a/common/net/minecraftforge/event/world/BlockEvent.java b/common/net/minecraftforge/event/world/BlockEvent.java new file mode 100644 index 0000000000..215e71e32c --- /dev/null +++ b/common/net/minecraftforge/event/world/BlockEvent.java @@ -0,0 +1,46 @@ +package net.minecraftforge.event.world; + +import java.util.ArrayList; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.event.Event; + +public class BlockEvent extends Event { + public final int x; + public final int y; + public final int z; + public final World world; + public final Block block; + public final int blockMetadata; + public BlockEvent(int x, int y, int z, World world, Block block, int blockMetadata) + { + this.x = x; + this.y = y; + this.z = z; + this.world = world; + this.block = block; + this.blockMetadata = blockMetadata; + } + + public static class HarvestDropsEvent extends BlockEvent { + public final int fortuneLevel; + public final ArrayList drops; + public final boolean isSilkTouching; + public float dropChance; // Change to e.g. 1.0f, if you manipulate the list and want to guarantee it always drops + public final EntityPlayer harvester; // May be null for non-player harvesting such as explosions or machines + + public HarvestDropsEvent(int x, int y, int z, World world, Block block, int blockMetadata, int fortuneLevel, float dropChance, ArrayList drops, EntityPlayer harvester, boolean isSilkTouching) + { + super(x, y, z, world, block, blockMetadata); + this.fortuneLevel = fortuneLevel; + this.dropChance = dropChance; + this.drops = drops; + this.isSilkTouching = isSilkTouching; + this.harvester = harvester; + } + } + +} diff --git a/patches/minecraft/net/minecraft/block/Block.java.patch b/patches/minecraft/net/minecraft/block/Block.java.patch index a8c9df8a47..3b14f8b78f 100644 --- a/patches/minecraft/net/minecraft/block/Block.java.patch +++ b/patches/minecraft/net/minecraft/block/Block.java.patch @@ -36,7 +36,7 @@ import net.minecraft.util.Icon; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.StatCollector; -@@ -35,9 +44,19 @@ +@@ -35,9 +44,21 @@ import net.minecraft.world.Explosion; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; @@ -45,7 +45,9 @@ +import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.common.IPlantable; ++import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.RotationHelper; ++import net.minecraftforge.event.world.BlockEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; @@ -56,7 +58,7 @@ /** * used as foreach item, if item.tab = current tab, display it on the screen */ -@@ -460,9 +479,10 @@ +@@ -460,9 +481,10 @@ return this.needsRandomTick; } @@ -68,7 +70,7 @@ } /** -@@ -485,7 +505,7 @@ +@@ -485,7 +507,7 @@ */ public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { @@ -77,7 +79,7 @@ } @SideOnly(Side.CLIENT) -@@ -495,7 +515,7 @@ +@@ -495,7 +517,7 @@ */ public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { @@ -86,7 +88,7 @@ } @SideOnly(Side.CLIENT) -@@ -648,7 +668,13 @@ +@@ -648,7 +670,13 @@ * different metadata value, but before the new metadata value is set. Args: World, x, y, z, old block ID, old * metadata */ @@ -101,7 +103,7 @@ /** * Returns the quantity of items to drop on block destruction. -@@ -673,7 +699,7 @@ +@@ -673,7 +701,7 @@ public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5) { float f = this.getBlockHardness(par2World, par3, par4, par5); @@ -110,30 +112,41 @@ } /** -@@ -691,18 +717,13 @@ +@@ -681,7 +709,7 @@ + */ + public final void dropBlockAsItem(World par1World, int par2, int par3, int par4, int par5, int par6) { - if (!par1World.isRemote) - { +- this.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, 1.0F, par6); ++ dropBlockAsItem(par1World, par2, par3, par4, par5, par6, null); + } + + /** +@@ -689,23 +717,7 @@ + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) + { +- if (!par1World.isRemote) +- { - int j1 = this.quantityDroppedWithBonus(par7, par1World.rand); - - for (int k1 = 0; k1 < j1; ++k1) -+ ArrayList items = getBlockDropped(par1World, par2, par3, par4, par5, par7); -+ -+ for (ItemStack item : items) - { - if (par1World.rand.nextFloat() <= par6) - { +- { +- if (par1World.rand.nextFloat() <= par6) +- { - int l1 = this.idDropped(par5, par1World.rand, par7); - - if (l1 > 0) - { - this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(l1, 1, this.damageDropped(par5))); - } -+ this.dropBlockAsItem_do(par1World, par2, par3, par4, item); - } - } - } -@@ -935,7 +956,8 @@ +- } +- } +- } ++ dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7, null); + } + + /** +@@ -935,7 +947,8 @@ public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { int l = par1World.getBlockId(par2, par3, par4); @@ -143,7 +156,7 @@ } /** -@@ -1095,7 +1117,7 @@ +@@ -1095,28 +1108,38 @@ par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); par2EntityPlayer.addExhaustion(0.025F); @@ -151,11 +164,35 @@ + if (this.canSilkHarvest(par1World, par2EntityPlayer, par3, par4, par5, par6) && EnchantmentHelper.getSilkTouchModifier(par2EntityPlayer)) { ItemStack itemstack = this.createStackedBlock(par6); - -@@ -1111,12 +1133,13 @@ +- +- if (itemstack != null) ++ ArrayList results = new ArrayList(); ++ if (itemstack!=null) + { +- this.dropBlockAsItem_do(par1World, par3, par4, par5, itemstack); ++ results.add(itemstack); + } ++ ++ MinecraftForge.EVENT_BUS.post(new BlockEvent.HarvestDropsEvent(par3, par4, par5, par1World, this, par6, 0, 1.0f, results, par2EntityPlayer, true)); ++ if (itemstack != null && !results.isEmpty()) ++ { ++ for (ItemStack is : results) ++ { ++ this.dropBlockAsItem_do(par1World, par3, par4, par5, is); ++ } ++ } } - } - + else + { + int i1 = EnchantmentHelper.getFortuneModifier(par2EntityPlayer); +- this.dropBlockAsItem(par1World, par3, par4, par5, par6, i1); +- } +- } +- ++ this.dropBlockAsItem(par1World, par3, par4, par5, par6, i1, par2EntityPlayer); ++ } ++ } ++ + private int silk_check_meta = -1; //Dirty hack to stop us from needing to special case the silk check hook. /** * Return true if a player with Silk Touch can harvest this block directly, and not its normal drops. @@ -167,7 +204,7 @@ } /** -@@ -1457,4 +1480,979 @@ +@@ -1457,4 +1480,1000 @@ canBlockGrass[0] = true; StatList.initBreakableStats(); } @@ -536,6 +573,27 @@ + return ret; + } + ++ public final void dropBlockAsItem(World par1World, int par2, int par3, int par4, int par5, int par6, EntityPlayer player) ++ { ++ this.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, 1.0F, par6, player); ++ } ++ ++ public void dropBlockAsItemWithChance(World world, int x, int y, int z, int metadata, float dropChance, int fortune, EntityPlayer player) ++ { ++ if (!world.isRemote) ++ { ++ ArrayList items = getBlockDropped(world, x, y, z, metadata, fortune); ++ MinecraftForge.EVENT_BUS.post(new BlockEvent.HarvestDropsEvent(x, y, z, world, this, metadata, fortune, dropChance, items, player, false)); ++ for (ItemStack item : items) ++ { ++ if (world.rand.nextFloat() <= dropChance) ++ { ++ this.dropBlockAsItem_do(world, x, y, z, item); ++ } ++ } ++ } ++ } ++ + /** + * Determines if a specified mob type can spawn on this block, returning false will + * prevent any mob from spawning on the block. diff --git a/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch b/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch index 5fd3e3401d..6580ca541a 100644 --- a/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch +++ b/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch @@ -1,6 +1,6 @@ --- ../src_base/minecraft/net/minecraft/block/BlockCocoa.java +++ ../src_work/minecraft/net/minecraft/block/BlockCocoa.java -@@ -2,6 +2,8 @@ +@@ -2,10 +2,13 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -9,12 +9,21 @@ import java.util.Random; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IconRegister; -@@ -201,7 +203,14 @@ + import net.minecraft.entity.EntityLivingBase; ++import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.Item; + import net.minecraft.item.ItemStack; + import net.minecraft.util.AxisAlignedBB; +@@ -199,9 +202,16 @@ + /** + * Drops the block items with a specified chance of dropping the specified items */ - public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) - { +- public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) +- { - int j1 = func_72219_c(par5); -+ super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); ++ public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7, EntityPlayer player) ++ { ++ super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0, player); + } + + @Override @@ -25,7 +34,7 @@ byte b0 = 1; if (j1 >= 2) -@@ -211,8 +220,9 @@ +@@ -211,8 +221,9 @@ for (int k1 = 0; k1 < b0; ++k1) { @@ -37,7 +46,7 @@ } @SideOnly(Side.CLIENT) -@@ -248,4 +258,10 @@ +@@ -248,4 +259,10 @@ this.iconArray[i] = par1IconRegister.registerIcon(this.getTextureName() + "_stage_" + i); } } diff --git a/patches/minecraft/net/minecraft/block/BlockCrops.java.patch b/patches/minecraft/net/minecraft/block/BlockCrops.java.patch index 66a57d1606..c72ff3ff6f 100644 --- a/patches/minecraft/net/minecraft/block/BlockCrops.java.patch +++ b/patches/minecraft/net/minecraft/block/BlockCrops.java.patch @@ -1,6 +1,6 @@ --- ../src_base/minecraft/net/minecraft/block/BlockCrops.java +++ ../src_work/minecraft/net/minecraft/block/BlockCrops.java -@@ -2,6 +2,7 @@ +@@ -2,14 +2,17 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -8,7 +8,9 @@ import java.util.Random; import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.creativetab.CreativeTabs; -@@ -10,6 +11,7 @@ ++import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.Item; + import net.minecraft.item.ItemStack; import net.minecraft.util.Icon; import net.minecraft.util.MathHelper; import net.minecraft.world.World; @@ -16,7 +18,7 @@ public class BlockCrops extends BlockFlower { -@@ -103,11 +105,11 @@ +@@ -103,11 +106,11 @@ int j3 = par1World.getBlockId(l2, par3 - 1, i3); float f1 = 0.0F; @@ -30,14 +32,20 @@ { f1 = 3.0F; } -@@ -175,22 +177,25 @@ - public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) - { - super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); +@@ -172,25 +175,28 @@ + /** + * Drops the block items with a specified chance of dropping the specified items + */ +- public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) +- { +- super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); - - if (!par1World.isRemote) - { - if (par5 >= 7) ++ public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7, EntityPlayer player) ++ { ++ super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0, player); + } + + @Override diff --git a/patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch b/patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch new file mode 100644 index 0000000000..6280e811a6 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch @@ -0,0 +1,22 @@ +--- ../src_base/minecraft/net/minecraft/block/BlockMobSpawner.java ++++ ../src_work/minecraft/net/minecraft/block/BlockMobSpawner.java +@@ -4,6 +4,7 @@ + import cpw.mods.fml.relauncher.SideOnly; + import java.util.Random; + import net.minecraft.block.material.Material; ++import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.tileentity.TileEntity; + import net.minecraft.tileentity.TileEntityMobSpawner; + import net.minecraft.world.World; +@@ -42,9 +43,9 @@ + /** + * Drops the block items with a specified chance of dropping the specified items + */ +- public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) ++ public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7, EntityPlayer player) + { +- super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); ++ super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7, player); + int j1 = 15 + par1World.rand.nextInt(15) + par1World.rand.nextInt(15); + this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1); + } diff --git a/patches/minecraft/net/minecraft/block/BlockOre.java.patch b/patches/minecraft/net/minecraft/block/BlockOre.java.patch new file mode 100644 index 0000000000..14e092029c --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockOre.java.patch @@ -0,0 +1,22 @@ +--- ../src_base/minecraft/net/minecraft/block/BlockOre.java ++++ ../src_work/minecraft/net/minecraft/block/BlockOre.java +@@ -3,6 +3,7 @@ + import java.util.Random; + import net.minecraft.block.material.Material; + import net.minecraft.creativetab.CreativeTabs; ++import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.Item; + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; +@@ -56,9 +57,9 @@ + /** + * Drops the block items with a specified chance of dropping the specified items + */ +- public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7) ++ public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7, EntityPlayer player) + { +- super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); ++ super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7, player); + + if (this.idDropped(par5, par1World.rand, par7) != this.blockID) + {