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;
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.ChunkCoordinates;
import net.minecraft.world.World;
//Preliminary, simple Fake Player class
public class FakePlayer extends EntityPlayer
public class FakePlayer extends EntityPlayerMP
{
public FakePlayer(World world, String name)
{
super(world, name);
super(FMLCommonHandler.instance().getMinecraftServerInstance(), world, name, new ItemInWorldManager(world));
}
public void sendChatToPlayer(String s){}

View file

@ -5,14 +5,30 @@ import net.minecraft.world.World;
//To be expanded for generic Mod fake players?
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;
public static FakePlayer getMinecraft(World world)
{
if (MINECRAFT_PLAYER == null)
{
MINECRAFT_PLAYER = new FakePlayer(world, "[Minecraft]");
MINECRAFT_PLAYER = FakePlayerFactory.get(world, "[Minecraft]");
}
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.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
public class BlockEvent extends Event {
@ -53,5 +54,59 @@ public class BlockEvent extends Event {
this.harvester = harvester;
}
}
/**
* 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.MovingObjectPosition;
import net.minecraft.util.StatCollector;
@@ -35,9 +44,20 @@
@@ -35,9 +44,22 @@
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
@ -45,8 +45,10 @@
+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.ForgeEventFactory;
+import net.minecraftforge.event.world.BlockEvent;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
@ -57,7 +59,7 @@
/**
* 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;
}
@ -69,7 +71,7 @@
}
/**
@@ -485,7 +506,7 @@
@@ -485,7 +508,7 @@
*/
public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
@ -78,7 +80,7 @@
}
@SideOnly(Side.CLIENT)
@@ -495,7 +516,7 @@
@@ -495,7 +518,7 @@
*/
public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
@ -87,7 +89,7 @@
}
@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
* metadata
*/
@ -102,7 +104,7 @@
/**
* 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)
{
float f = this.getBlockHardness(par2World, par3, par4, par5);
@ -111,7 +113,7 @@
}
/**
@@ -691,18 +718,14 @@
@@ -691,18 +720,14 @@
{
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)
{
int l = par1World.getBlockId(par2, par3, par4);
@ -145,7 +158,7 @@
}
/**
@@ -1086,6 +1110,7 @@
@@ -1086,6 +1116,7 @@
*/
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
* 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.addExhaustion(0.025F);
@ -198,7 +211,7 @@
}
/**
@@ -1457,4 +1491,993 @@
@@ -1457,4 +1497,993 @@
canBlockGrass[0] = true;
StatList.initBreakableStats();
}

View file

@ -1,6 +1,11 @@
--- ../src_base/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.WorldServer;
@ -11,6 +16,7 @@
+import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent;
+import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
+import net.minecraftforge.event.world.BlockEvent;
+
public class ItemInWorldManager
{
@ -20,7 +26,7 @@
/** The world object that this object is connected to. */
public World theWorld;
@@ -145,6 +156,13 @@
@@ -145,6 +158,13 @@
{
if (!this.gameType.isAdventure() || this.thisPlayerMP.isCurrentToolAdventureModeExempt(par1, par2, par3))
{
@ -34,7 +40,7 @@
if (this.isCreative())
{
if (!this.theWorld.extinguishFire((EntityPlayer)null, par1, par2, par3, par4))
@@ -154,15 +172,33 @@
@@ -154,15 +174,33 @@
}
else
{
@ -73,7 +79,7 @@
}
if (i1 > 0 && f >= 1.0F)
@@ -236,7 +272,7 @@
@@ -236,7 +274,7 @@
block.onBlockHarvested(this.theWorld, par1, par2, par3, l, this.thisPlayerMP);
}
@ -82,8 +88,20 @@
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
{
+ ItemStack stack = thisPlayerMP.getCurrentEquippedItem();
@ -115,7 +133,7 @@
if (itemstack != null)
{
@@ -285,6 +332,7 @@
@@ -285,6 +331,7 @@
}
}
@ -123,7 +141,57 @@
if (flag && flag1)
{
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)
{
par1EntityPlayer.inventory.mainInventory[par1EntityPlayer.inventory.currentItem] = null;
@ -131,7 +199,7 @@
}
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)
{
@ -215,7 +283,7 @@
}
/**
@@ -380,4 +450,13 @@
@@ -380,4 +492,13 @@
{
this.theWorld = par1WorldServer;
}