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

This commit is contained in:
OniBait 2013-10-03 01:46:17 -05:00
parent 7d5d191fc2
commit 296a484f4b
5 changed files with 179 additions and 24 deletions

View file

@ -1,16 +1,19 @@
package net.minecraftforge.common; package net.minecraftforge.common;
import net.minecraft.entity.player.EntityPlayer; import cpw.mods.fml.common.FMLCommonHandler;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemInWorldManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatMessageComponent; import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World; import net.minecraft.world.World;
//Preliminary, simple Fake Player class //Preliminary, simple Fake Player class
public class FakePlayer extends EntityPlayer public class FakePlayer extends EntityPlayerMP
{ {
public FakePlayer(World world, String name) public FakePlayer(World world, String name)
{ {
super(world, name); super(FMLCommonHandler.instance().getMinecraftServerInstance(), world, name, new ItemInWorldManager(world));
} }
public void sendChatToPlayer(String s){} public void sendChatToPlayer(String s){}

View file

@ -5,14 +5,30 @@ import net.minecraft.world.World;
//To be expanded for generic Mod fake players? //To be expanded for generic Mod fake players?
public class FakePlayerFactory public class FakePlayerFactory
{ {
// Map of all active fake player usernames to their entities
private static java.util.Map<String, FakePlayer> fakePlayers = new java.util.HashMap<String, FakePlayer>();
private static FakePlayer MINECRAFT_PLAYER = null; private static FakePlayer MINECRAFT_PLAYER = null;
public static FakePlayer getMinecraft(World world) public static FakePlayer getMinecraft(World world)
{ {
if (MINECRAFT_PLAYER == null) if (MINECRAFT_PLAYER == null)
{ {
MINECRAFT_PLAYER = new FakePlayer(world, "[Minecraft]"); MINECRAFT_PLAYER = FakePlayerFactory.get(world, "[Minecraft]");
} }
return MINECRAFT_PLAYER; return MINECRAFT_PLAYER;
} }
/**
* Get a fake player with a given username
*/
public static FakePlayer get(World world, String username)
{
if (!fakePlayers.containsKey(username))
{
FakePlayer fakePlayer = new FakePlayer(world, username);
fakePlayers.put(username, fakePlayer);
}
return fakePlayers.get(username);
}
} }

View file

@ -6,6 +6,7 @@ import net.minecraft.block.Block;
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;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event; import net.minecraftforge.event.Event;
public class BlockEvent extends Event { public class BlockEvent extends Event {
@ -54,4 +55,58 @@ public class BlockEvent extends Event {
} }
} }
/**
* Fired when a block is broken and about to drop experience
* The amount of experience that is dropped can be retrieved or set
*/
public static class ExperienceDropsEvent extends BlockEvent
{
private int exp;
public ExperienceDropsEvent(int x, int y, int z, World world, Block block, int blockMetadata, int exp)
{
super(x, y, z, world, block, blockMetadata);
this.exp = exp;
}
/**
* Get the experience dropped by the block after the event has processed
*
* @return The experience to drop
*/
public int getExpToDrop()
{
return exp;
}
/**
* Set the amount of experience dropped by the block after the event has processed
*
* @param exp 1 or higher to drop experience, else nothing will drop
*/
public void setExpToDrop(int 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,20 @@ @@ -35,9 +44,22 @@
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,8 +45,10 @@
+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;
@ -57,7 +59,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 +480,10 @@ @@ -460,9 +482,10 @@
return this.needsRandomTick; return this.needsRandomTick;
} }
@ -69,7 +71,7 @@
} }
/** /**
@@ -485,7 +506,7 @@ @@ -485,7 +508,7 @@
*/ */
public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{ {
@ -78,7 +80,7 @@
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@@ -495,7 +516,7 @@ @@ -495,7 +518,7 @@
*/ */
public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{ {
@ -87,7 +89,7 @@
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@@ -648,7 +669,13 @@ @@ -648,7 +671,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
*/ */
@ -102,7 +104,7 @@
/** /**
* Returns the quantity of items to drop on block destruction. * Returns the quantity of items to drop on block destruction.
@@ -673,7 +700,7 @@ @@ -673,7 +702,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);
@ -111,7 +113,7 @@
} }
/** /**
@@ -691,18 +718,14 @@ @@ -691,18 +720,14 @@
{ {
if (!par1World.isRemote) if (!par1World.isRemote)
{ {
@ -135,7 +137,18 @@
} }
} }
} }
@@ -935,7 +958,8 @@ @@ -732,6 +757,10 @@
{
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);
@ -145,7 +158,7 @@
} }
/** /**
@@ -1086,6 +1110,7 @@ @@ -1086,6 +1116,7 @@
*/ */
public void setBlockBoundsForItemRender() {} public void setBlockBoundsForItemRender() {}
@ -153,7 +166,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 +1120,37 @@ @@ -1095,28 +1126,37 @@
par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1);
par2EntityPlayer.addExhaustion(0.025F); par2EntityPlayer.addExhaustion(0.025F);
@ -198,7 +211,7 @@
} }
/** /**
@@ -1457,4 +1491,993 @@ @@ -1457,4 +1497,993 @@
canBlockGrass[0] = true; canBlockGrass[0] = true;
StatList.initBreakableStats(); StatList.initBreakableStats();
} }

View file

@ -1,6 +1,11 @@
--- ../src_base/minecraft/net/minecraft/item/ItemInWorldManager.java --- ../src_base/minecraft/net/minecraft/item/ItemInWorldManager.java
+++ ../src_work/minecraft/net/minecraft/item/ItemInWorldManager.java +++ ../src_work/minecraft/net/minecraft/item/ItemInWorldManager.java
@@ -8,8 +8,19 @@ @@ -4,12 +4,25 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.packet.Packet53BlockChange;
+import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.EnumGameType;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
@ -11,6 +16,7 @@
+import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; +import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; +import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
+import net.minecraftforge.event.world.BlockEvent;
+ +
public class ItemInWorldManager public class ItemInWorldManager
{ {
@ -20,7 +26,7 @@
/** The world object that this object is connected to. */ /** The world object that this object is connected to. */
public World theWorld; public World theWorld;
@@ -145,6 +156,13 @@ @@ -145,6 +158,13 @@
{ {
if (!this.gameType.isAdventure() || this.thisPlayerMP.isCurrentToolAdventureModeExempt(par1, par2, par3)) if (!this.gameType.isAdventure() || this.thisPlayerMP.isCurrentToolAdventureModeExempt(par1, par2, par3))
{ {
@ -34,7 +40,7 @@
if (this.isCreative()) if (this.isCreative())
{ {
if (!this.theWorld.extinguishFire((EntityPlayer)null, par1, par2, par3, par4)) if (!this.theWorld.extinguishFire((EntityPlayer)null, par1, par2, par3, par4))
@@ -154,15 +172,33 @@ @@ -154,15 +174,33 @@
} }
else else
{ {
@ -73,7 +79,7 @@
} }
if (i1 > 0 && f >= 1.0F) if (i1 > 0 && f >= 1.0F)
@@ -236,7 +272,7 @@ @@ -236,7 +274,7 @@
block.onBlockHarvested(this.theWorld, par1, par2, par3, l, this.thisPlayerMP); block.onBlockHarvested(this.theWorld, par1, par2, par3, l, this.thisPlayerMP);
} }
@ -82,8 +88,20 @@
if (block != null && flag) if (block != null && flag)
{ {
@@ -261,19 +297,30 @@ @@ -251,29 +289,37 @@
*/
public boolean tryHarvestBlock(int par1, int par2, int par3)
{
- if (this.gameType.isAdventure() && !this.thisPlayerMP.isCurrentToolAdventureModeExempt(par1, par2, par3))
+ BlockEvent.BreakEvent event = triggerBlockBreakEvent(par1, par2, par3);
+ if (event.isCanceled())
{
return false;
} }
- else if (this.gameType.isCreative() && this.thisPlayerMP.getHeldItem() != null && this.thisPlayerMP.getHeldItem().getItem() instanceof ItemSword)
- {
- return false;
- }
else else
{ {
+ ItemStack stack = thisPlayerMP.getCurrentEquippedItem(); + ItemStack stack = thisPlayerMP.getCurrentEquippedItem();
@ -115,7 +133,7 @@
if (itemstack != null) if (itemstack != null)
{ {
@@ -285,6 +332,7 @@ @@ -285,6 +331,7 @@
} }
} }
@ -123,7 +141,57 @@
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);
@@ -325,6 +373,7 @@ @@ -293,6 +340,49 @@
return flag;
}
+ }
+
+ 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;
@ -131,7 +199,7 @@
} }
if (!par1EntityPlayer.isUsingItem()) if (!par1EntityPlayer.isUsingItem())
@@ -342,35 +391,56 @@ @@ -342,35 +433,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)
{ {
@ -215,7 +283,7 @@
} }
/** /**
@@ -380,4 +450,13 @@ @@ -380,4 +492,13 @@
{ {
this.theWorld = par1WorldServer; this.theWorld = par1WorldServer;
} }