Add block break events based on @bloodmc's initial 1.5.2 Pull Request

This commit is contained in:
OniBait 2013-10-08 19:00:02 -05:00
parent 296a484f4b
commit eb5940664c
8 changed files with 208 additions and 103 deletions

View file

@ -47,6 +47,7 @@ public aqz.a(F)Laqz; #MD:Block/func_71900_a #setLightValue
public aqz.r()Laqz; #MD:Block/func_71875_q #setBlockUnbreakable public aqz.r()Laqz; #MD:Block/func_71875_q #setBlockUnbreakable
public aqz.b(Z)Laqz; #MD:Block/func_71907_b #setTickRandomly public aqz.b(Z)Laqz; #MD:Block/func_71907_b #setTickRandomly
public aqz.a(FFFFFF)V #MD:Block/func_71905_a #setBlockBounds public aqz.a(FFFFFF)V #MD:Block/func_71905_a #setBlockBounds
public aqz.j(Labw;IIII)V #MD:Block/func_71923_g #dropXpOnBlockBreak
# NetServerHandler # NetServerHandler
public ka.f #FD:NetServerHandler/field_72572_g #playerInAirTime public ka.f #FD:NetServerHandler/field_72572_g #playerInAirTime
# TileEntity # TileEntity

View file

@ -7,17 +7,23 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemAxe;
import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemSpade; import net.minecraft.item.ItemSpade;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.network.NetServerHandler; import net.minecraft.network.NetServerHandler;
import net.minecraft.network.packet.Packet53BlockChange;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChatMessageComponent; import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.DamageSource; import net.minecraft.util.DamageSource;
@ -26,7 +32,9 @@ import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.WeightedRandom; import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomItem; import net.minecraft.util.WeightedRandomItem;
import net.minecraft.world.EnumGameType;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.event.Event;
import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.ServerChatEvent; import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.item.ItemTossEvent;
@ -38,6 +46,7 @@ import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent; import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
import net.minecraftforge.event.world.BlockEvent;
public class ForgeHooks public class ForgeHooks
{ {
@ -430,4 +439,49 @@ public class ForgeHooks
} }
return event.component; return event.component;
} }
public static BlockEvent.BreakEvent onBlockBreakEvent(World world, EnumGameType gameType, EntityPlayerMP entityPlayer, int x, int y, int z)
{
// Logic from tryHarvestBlock for pre-canceling the event
boolean preCancelEvent = false;
if (gameType.isAdventure() && !entityPlayer.isCurrentToolAdventureModeExempt(x, y, z))
{
preCancelEvent = true;
}
else if (gameType.isCreative() && entityPlayer.getHeldItem() != null && entityPlayer.getHeldItem().getItem() instanceof ItemSword)
{
preCancelEvent = true;
}
// Tell client the block is gone immediately then process events
if (world.getBlockTileEntity(x, y, z) == null)
{
Packet53BlockChange packet = new Packet53BlockChange(x, y, z, world);
packet.type = 0;
packet.metadata = 0;
entityPlayer.playerNetServerHandler.sendPacketToPlayer(packet);
}
// Post the block break event
Block block = Block.blocksList[world.getBlockId(x, y, z)];
int blockMetadata = world.getBlockMetadata(x, y, z);
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(x, y, z, world, block, blockMetadata, entityPlayer);
event.setCanceled(preCancelEvent);
MinecraftForge.EVENT_BUS.post(event);
// Handle if the event is canceled
if (event.isCanceled())
{
// Let the client know the block still exists
entityPlayer.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(x, y, z, world));
// Update any tile entity data for this block
TileEntity tileentity = world.getBlockTileEntity(x, y, z);
if (tileentity != null)
{
entityPlayer.playerNetServerHandler.sendPacketToPlayer(tileentity.getDescriptionPacket());
}
}
return event;
}
} }

View file

@ -3,6 +3,7 @@ package net.minecraftforge.event.world;
import java.util.ArrayList; import java.util.ArrayList;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -56,27 +57,47 @@ public class BlockEvent extends Event {
} }
/** /**
* Fired when a block is broken and about to drop experience * Event that is fired when an Block is about to be broken by a player
* The amount of experience that is dropped can be retrieved or set * Canceling this event will prevent the Block from being broken.
*/ */
public static class ExperienceDropsEvent extends BlockEvent @Cancelable
public static class BreakEvent extends BlockEvent
{ {
/** Reference to the Player who broke the block. If no player is available, use a EntityFakePlayer */
private final EntityPlayer player;
private int exp; private int exp;
public ExperienceDropsEvent(int x, int y, int z, World world, Block block, int blockMetadata, int exp) public BreakEvent(int x, int y, int z, World world, Block block, int blockMetadata, EntityPlayer player)
{ {
super(x, y, z, world, block, blockMetadata); super(x, y, z, world, block, blockMetadata);
this.exp = exp; this.player = player;
if (block == null || !player.canHarvestBlock(block) || // Handle empty block or player unable to break block scenario
block.canSilkHarvest(world, player, x, y, z, blockMetadata) && EnchantmentHelper.getSilkTouchModifier(player)) // If the block is being silk harvested, the exp dropped is 0
{
this.exp = 0;
}
else
{
int meta = block.getDamageValue(world, x, y, z);
int bonusLevel = EnchantmentHelper.getFortuneModifier(player);
this.exp = block.getExpDrop(world, meta, bonusLevel);
}
}
public EntityPlayer getPlayer()
{
return player;
} }
/** /**
* Get the experience dropped by the block after the event has processed * Get the experience dropped by the block after the event has processed
* *
* @return The experience to drop * @return The experience to drop or 0 if the event was canceled
*/ */
public int getExpToDrop() public int getExpToDrop()
{ {
return exp; return this.isCanceled() ? 0 : exp;
} }
/** /**
@ -89,24 +110,4 @@ public class BlockEvent extends Event {
this.exp = exp; this.exp = exp;
} }
} }
/**
* Event that is fired when an Block is about to be broken by a player
* Canceling this event will prevent the Block from being broken.
*/
@Cancelable
public static class BreakEvent extends BlockEvent
{
/** Reference to the Player who broke the block. If no player is available, use a EntityFakePlayer */
private final EntityPlayer player;
public BreakEvent(int x, int y, int z, World world, Block block, int blockMetadata, EntityPlayer player) {
super(x, y, z, world, block, blockMetadata);
this.player = player;
}
public EntityPlayer getPlayer()
{
return player;
}
}
} }

View file

@ -36,7 +36,7 @@
import net.minecraft.util.Icon; import net.minecraft.util.Icon;
import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector; import net.minecraft.util.StatCollector;
@@ -35,9 +44,22 @@ @@ -35,9 +44,20 @@
import net.minecraft.world.Explosion; import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -45,10 +45,8 @@
+import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.common.ForgeHooks;
+import net.minecraftforge.common.IPlantable; +import net.minecraftforge.common.IPlantable;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.RotationHelper; +import net.minecraftforge.common.RotationHelper;
+import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.event.ForgeEventFactory;
+import net.minecraftforge.event.world.BlockEvent;
+import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly; +import cpw.mods.fml.relauncher.SideOnly;
@ -59,7 +57,7 @@
/** /**
* used as foreach item, if item.tab = current tab, display it on the screen * used as foreach item, if item.tab = current tab, display it on the screen
*/ */
@@ -460,9 +482,10 @@ @@ -460,9 +480,10 @@
return this.needsRandomTick; return this.needsRandomTick;
} }
@ -71,7 +69,7 @@
} }
/** /**
@@ -485,7 +508,7 @@ @@ -485,7 +506,7 @@
*/ */
public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{ {
@ -80,7 +78,7 @@
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@@ -495,7 +518,7 @@ @@ -495,7 +516,7 @@
*/ */
public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{ {
@ -89,7 +87,7 @@
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@@ -648,7 +671,13 @@ @@ -648,7 +669,13 @@
* different metadata value, but before the new metadata value is set. Args: World, x, y, z, old block ID, old * different metadata value, but before the new metadata value is set. Args: World, x, y, z, old block ID, old
* metadata * metadata
*/ */
@ -104,7 +102,7 @@
/** /**
* Returns the quantity of items to drop on block destruction. * Returns the quantity of items to drop on block destruction.
@@ -673,7 +702,7 @@ @@ -673,7 +700,7 @@
public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5) public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5)
{ {
float f = this.getBlockHardness(par2World, par3, par4, par5); float f = this.getBlockHardness(par2World, par3, par4, par5);
@ -113,7 +111,7 @@
} }
/** /**
@@ -691,18 +720,14 @@ @@ -691,18 +718,14 @@
{ {
if (!par1World.isRemote) if (!par1World.isRemote)
{ {
@ -137,18 +135,7 @@
} }
} }
} }
@@ -732,6 +757,10 @@ @@ -935,7 +958,8 @@
{
if (!par1World.isRemote)
{
+ BlockEvent.ExperienceDropsEvent event = new BlockEvent.ExperienceDropsEvent(par2, par3, par4, par1World, this, par1World.getBlockMetadata(par2, par3, par4), par5);
+ MinecraftForge.EVENT_BUS.post(event);
+ par5 = event.getExpToDrop();
+
while (par5 > 0)
{
int i1 = EntityXPOrb.getXPSplit(par5);
@@ -935,7 +964,8 @@
public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
{ {
int l = par1World.getBlockId(par2, par3, par4); int l = par1World.getBlockId(par2, par3, par4);
@ -158,7 +145,7 @@
} }
/** /**
@@ -1086,6 +1116,7 @@ @@ -1086,6 +1110,7 @@
*/ */
public void setBlockBoundsForItemRender() {} public void setBlockBoundsForItemRender() {}
@ -166,7 +153,7 @@
/** /**
* Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the * Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the
* block and l is the block's subtype/damage. * block and l is the block's subtype/damage.
@@ -1095,28 +1126,37 @@ @@ -1095,28 +1120,37 @@
par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1);
par2EntityPlayer.addExhaustion(0.025F); par2EntityPlayer.addExhaustion(0.025F);
@ -211,7 +198,7 @@
} }
/** /**
@@ -1457,4 +1497,993 @@ @@ -1457,4 +1491,1001 @@
canBlockGrass[0] = true; canBlockGrass[0] = true;
StatList.initBreakableStats(); StatList.initBreakableStats();
} }
@ -1166,6 +1153,14 @@
+ } + }
+ +
+ /** + /**
+ * @return the amount of XP that this block should drop when it is broken
+ */
+ public int getExpDrop(World world, int data, int enchantmentLevel)
+ {
+ return 0;
+ }
+
+ /**
+ * Called when a tile entity on a side of this block changes is created or is destroyed. + * Called when a tile entity on a side of this block changes is created or is destroyed.
+ * @param world The world + * @param world The world
+ * @param x The x position of this block instance + * @param x The x position of this block instance

View file

@ -0,0 +1,17 @@
--- ../src_base/minecraft/net/minecraft/block/BlockMobSpawner.java
+++ ../src_work/minecraft/net/minecraft/block/BlockMobSpawner.java
@@ -45,8 +45,12 @@
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, par7);
- int j1 = 15 + par1World.rand.nextInt(15) + par1World.rand.nextInt(15);
- this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1);
+ }
+
+ @Override
+ public int getExpDrop(World world, int data, int enchantmentLevel)
+ {
+ return 15 + world.rand.nextInt(15) + world.rand.nextInt(15);
}
/**

View file

@ -0,0 +1,50 @@
--- ../src_base/minecraft/net/minecraft/block/BlockOre.java
+++ ../src_work/minecraft/net/minecraft/block/BlockOre.java
@@ -59,34 +59,36 @@
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, par7);
-
- if (this.idDropped(par5, par1World.rand, par7) != this.blockID)
+ }
+
+ @Override
+ public int getExpDrop(World world, int data, int enchantmentLevel)
+ {
+ int j1 = 0;
+ if (this.idDropped(data, world.rand, enchantmentLevel) != this.blockID)
{
- int j1 = 0;
-
if (this.blockID == Block.oreCoal.blockID)
{
- j1 = MathHelper.getRandomIntegerInRange(par1World.rand, 0, 2);
+ j1 = MathHelper.getRandomIntegerInRange(world.rand, 0, 2);
}
else if (this.blockID == Block.oreDiamond.blockID)
{
- j1 = MathHelper.getRandomIntegerInRange(par1World.rand, 3, 7);
+ j1 = MathHelper.getRandomIntegerInRange(world.rand, 3, 7);
}
else if (this.blockID == Block.oreEmerald.blockID)
{
- j1 = MathHelper.getRandomIntegerInRange(par1World.rand, 3, 7);
+ j1 = MathHelper.getRandomIntegerInRange(world.rand, 3, 7);
}
else if (this.blockID == Block.oreLapis.blockID)
{
- j1 = MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5);
+ j1 = MathHelper.getRandomIntegerInRange(world.rand, 2, 5);
}
else if (this.blockID == Block.oreNetherQuartz.blockID)
{
- j1 = MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5);
+ j1 = MathHelper.getRandomIntegerInRange(world.rand, 2, 5);
}
-
- this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1);
}
+ return j1;
}
/**

View file

@ -0,0 +1,26 @@
--- ../src_base/minecraft/net/minecraft/block/BlockRedstoneOre.java
+++ ../src_work/minecraft/net/minecraft/block/BlockRedstoneOre.java
@@ -115,12 +115,17 @@
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, par7);
-
- if (this.idDropped(par5, par1World.rand, par7) != this.blockID)
- {
- int j1 = 1 + par1World.rand.nextInt(5);
- this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1);
- }
+ }
+
+ @Override
+ public int getExpDrop(World world, int data, int enchantmentLevel)
+ {
+ int j1 = 0;
+ if (this.idDropped(data, world.rand, enchantmentLevel) != this.blockID)
+ {
+ j1 = 1 + world.rand.nextInt(5);
+ }
+ return j1;
}
@SideOnly(Side.CLIENT)

View file

@ -93,7 +93,7 @@
public boolean tryHarvestBlock(int par1, int par2, int par3) public boolean tryHarvestBlock(int par1, int par2, int par3)
{ {
- if (this.gameType.isAdventure() && !this.thisPlayerMP.isCurrentToolAdventureModeExempt(par1, par2, par3)) - if (this.gameType.isAdventure() && !this.thisPlayerMP.isCurrentToolAdventureModeExempt(par1, par2, par3))
+ BlockEvent.BreakEvent event = triggerBlockBreakEvent(par1, par2, par3); + BlockEvent.BreakEvent event = ForgeHooks.onBlockBreakEvent(theWorld, gameType, thisPlayerMP, par1, par2, par3);
+ if (event.isCanceled()) + if (event.isCanceled())
{ {
return false; return false;
@ -133,7 +133,7 @@
if (itemstack != null) if (itemstack != null)
{ {
@@ -285,6 +331,7 @@ @@ -285,11 +331,18 @@
} }
} }
@ -141,57 +141,18 @@
if (flag && flag1) if (flag && flag1)
{ {
Block.blocksList[l].harvestBlock(this.theWorld, this.thisPlayerMP, par1, par2, par3, i1); Block.blocksList[l].harvestBlock(this.theWorld, this.thisPlayerMP, par1, par2, par3, i1);
@@ -293,6 +340,49 @@ }
}
+
+ // Drop experience
+ if (!this.isCreative() && flag && event != null)
+ {
+ Block.blocksList[l].dropXpOnBlockBreak(this.theWorld, par1, par2, par3, event.getExpToDrop());
+ }
return flag; return flag;
} }
+ } @@ -325,6 +378,7 @@
+
+ private BlockEvent.BreakEvent triggerBlockBreakEvent(int par1, int par2, int par3)
+ {
+ // Logic from tryHarvestBlock for pre-canceling the event
+ boolean preCancelEvent = false;
+ if (this.gameType.isAdventure() && !this.thisPlayerMP.isCurrentToolAdventureModeExempt(par1, par2, par3))
+ {
+ preCancelEvent = true;
+ }
+ else if (this.gameType.isCreative() && this.thisPlayerMP.getHeldItem() != null && this.thisPlayerMP.getHeldItem().getItem() instanceof ItemSword)
+ {
+ preCancelEvent = true;
+ }
+
+ // Tell client the block is gone immediately then process events
+ if (theWorld.getBlockTileEntity(par1, par2, par3) == null)
+ {
+ Packet53BlockChange packet = new Packet53BlockChange(par1, par2, par3, this.theWorld);
+ packet.type = 0;
+ packet.metadata = 0;
+ ((EntityPlayerMP) this.thisPlayerMP).playerNetServerHandler.sendPacketToPlayer(packet);
+ }
+
+ // Post the block break event
+ Block block = Block.blocksList[this.theWorld.getBlockId(par1, par2, par3)];
+ BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(par1, par2, par3, this.theWorld, block, this.theWorld.getBlockMetadata(par1, par2, par3), this.thisPlayerMP);
+ event.setCanceled(preCancelEvent);
+ MinecraftForge.EVENT_BUS.post(event);
+
+ // Handle if the event is canceled
+ if (event.isCanceled())
+ {
+ // Let the client know the block still exists
+ ((EntityPlayerMP) this.thisPlayerMP).playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(par1, par2, par3, this.theWorld));
+ // Update any tile entity data for this block
+ TileEntity tileentity = this.theWorld.getBlockTileEntity(par1, par2, par3);
+ if (tileentity != null)
+ {
+ this.thisPlayerMP.playerNetServerHandler.sendPacketToPlayer(tileentity.getDescriptionPacket());
+ }
+ }
+ return event;
}
/**
@@ -325,6 +415,7 @@
if (itemstack1.stackSize == 0) if (itemstack1.stackSize == 0)
{ {
par1EntityPlayer.inventory.mainInventory[par1EntityPlayer.inventory.currentItem] = null; par1EntityPlayer.inventory.mainInventory[par1EntityPlayer.inventory.currentItem] = null;
@ -199,7 +160,7 @@
} }
if (!par1EntityPlayer.isUsingItem()) if (!par1EntityPlayer.isUsingItem())
@@ -342,35 +433,56 @@ @@ -342,35 +396,56 @@
*/ */
public boolean activateBlockOrUseItem(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack, int par4, int par5, int par6, int par7, float par8, float par9, float par10) public boolean activateBlockOrUseItem(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
{ {
@ -283,7 +244,7 @@
} }
/** /**
@@ -380,4 +492,13 @@ @@ -380,4 +455,13 @@
{ {
this.theWorld = par1WorldServer; this.theWorld = par1WorldServer;
} }