mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 16:27:47 +00:00
Added PlaceEvent and MultiPlaceEvent which fires before placing a block.
Before calling "ItemStack.tryPlaceItemInWorld", a recording flag is turned on for setBlock to capture a blocksnapshot for each block that attempts to be placed. If 1 block is captured, a "BlockEvent.PlaceEvent" is fired to notify mods. If 2 or more blocks are captured, a "BlockEvent.PlaceEvent" is fired first with the first block captured followed by a "BlockEvent.MultiPlaceEvent" with all captured blocks. This extra event is required for items that have the ability to place 2 or more blocks such as a BlockBed. If either event is cancelled, the recorded block snapshot(s), item stacksize, and item meta will revert back to the captured snapshot(s). If the events are not cancelled, a notification will be sent to clients and block physics will be updated. What this means for mods is Forge will be able to capture all player block placement automatically and fire a PlaceEvent and/or MultiPlaceEvent. If for whatever reason your mod does not use the standard placement methods then you will need to fire the appropriate placement events in order to notify mods/servers. This commit also includes a new utility class called BlockSnapshot which is serializable. This new class is used in conjunction with both PlaceEvent and MultiPlaceEvent in order to record a snapshot of block space before it is altered. This allows us to restore the block(s) if an event is cancelled. The class also provides the ability to restore a snapshot to any location using the restoreToLocation method. This should be helpful to many mods that are looking to be able to capture block data then restore it to back to any location required.
This commit is contained in:
1 parent
9ccf454b88
commit
37f91681d9
9 files changed
+719
-72
No files matched your search
@@ -16,15 +16,19 @@ import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.ContainerRepair;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemArmor;
|
||||
import net.minecraft.item.ItemAxe;
|
||||
import net.minecraft.item.ItemBucket;
|
||||
import net.minecraft.item.ItemPickaxe;
|
||||
import net.minecraft.item.ItemSpade;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemSword;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.play.server.S23PacketBlockChange;
|
||||
import net.minecraft.stats.StatList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityNote;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
@@ -37,6 +41,7 @@ import net.minecraft.util.WeightedRandom;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldSettings.GameType;
|
||||
import net.minecraftforge.event.AnvilUpdateEvent;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
import net.minecraftforge.event.ServerChatEvent;
|
||||
import net.minecraftforge.event.entity.item.ItemTossEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingAttackEvent;
|
||||
@@ -430,6 +435,100 @@ public class ForgeHooks
|
||||
return event;
|
||||
}
|
||||
|
||||
public static boolean onPlaceItemIntoWorld(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
// handle all placement events here
|
||||
int meta = itemstack.getItemDamage();
|
||||
int size = itemstack.stackSize;
|
||||
NBTTagCompound nbt = null;
|
||||
if (itemstack.getTagCompound() != null)
|
||||
{
|
||||
nbt = (NBTTagCompound)itemstack.getTagCompound().copy();
|
||||
}
|
||||
|
||||
if (!(itemstack.getItem() instanceof ItemBucket)) // if not bucket
|
||||
{
|
||||
world.captureBlockSnapshots = true;
|
||||
}
|
||||
|
||||
boolean flag = itemstack.getItem().onItemUse(itemstack, player, world, x, y, z, side, hitX, hitY, hitZ);
|
||||
world.captureBlockSnapshots = false;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
// save new item data
|
||||
int newMeta = itemstack.getItemDamage();
|
||||
int newSize = itemstack.stackSize;
|
||||
NBTTagCompound newNBT = null;
|
||||
if (itemstack.getTagCompound() != null)
|
||||
{
|
||||
newNBT = (NBTTagCompound)itemstack.getTagCompound().copy();
|
||||
}
|
||||
net.minecraftforge.event.world.BlockEvent.PlaceEvent placeEvent = null;
|
||||
List<net.minecraftforge.common.util.BlockSnapshot> blockSnapshots = (List<net.minecraftforge.common.util.BlockSnapshot>) world.capturedBlockSnapshots.clone();
|
||||
world.capturedBlockSnapshots.clear();
|
||||
|
||||
// make sure to set pre-placement item data for event
|
||||
itemstack.setItemDamage(meta);
|
||||
itemstack.stackSize = size;
|
||||
if (nbt != null)
|
||||
{
|
||||
itemstack.setTagCompound(nbt);
|
||||
}
|
||||
if (blockSnapshots.size() > 1)
|
||||
{
|
||||
placeEvent = ForgeEventFactory.onPlayerMultiBlockPlace(player, blockSnapshots, net.minecraftforge.common.util.ForgeDirection.getOrientation(side));
|
||||
}
|
||||
else if (blockSnapshots.size() == 1)
|
||||
{
|
||||
placeEvent = ForgeEventFactory.onPlayerBlockPlace(player, blockSnapshots.get(0), net.minecraftforge.common.util.ForgeDirection.getOrientation(side));
|
||||
}
|
||||
|
||||
if (placeEvent != null && (placeEvent.isCanceled()))
|
||||
{
|
||||
flag = false; // cancel placement
|
||||
// revert back all captured blocks
|
||||
for (net.minecraftforge.common.util.BlockSnapshot blocksnapshot : blockSnapshots)
|
||||
{
|
||||
world.restoringBlockSnapshots = true;
|
||||
blocksnapshot.restore(true, false);
|
||||
world.restoringBlockSnapshots = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Change the stack to its new content
|
||||
itemstack.setItemDamage(newMeta);
|
||||
itemstack.stackSize = newSize;
|
||||
if (nbt != null)
|
||||
{
|
||||
itemstack.setTagCompound(newNBT);
|
||||
}
|
||||
|
||||
for (net.minecraftforge.common.util.BlockSnapshot blocksnapshot : blockSnapshots)
|
||||
{
|
||||
int blockX = blocksnapshot.x;
|
||||
int blockY = blocksnapshot.y;
|
||||
int blockZ = blocksnapshot.z;
|
||||
int metadata = world.getBlockMetadata(blockX, blockY, blockZ);
|
||||
int updateFlag = blocksnapshot.flag;
|
||||
Block oldBlock = blocksnapshot.replacedBlock;
|
||||
Block newBlock = world.getBlock(blockX, blockY, blockZ);
|
||||
if (newBlock != null && !(newBlock.hasTileEntity(metadata))) // Containers get placed automatically
|
||||
{
|
||||
newBlock.onBlockAdded(world, blockX, blockY, blockZ);
|
||||
}
|
||||
|
||||
world.markAndNotifyBlock(blockX, blockY, blockZ, null, oldBlock, newBlock, updateFlag);
|
||||
}
|
||||
player.addStat(StatList.objectUseStats[Item.getIdFromItem(itemstack.getItem())], 1);
|
||||
}
|
||||
}
|
||||
world.capturedBlockSnapshots.clear();
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
public static boolean onAnvilChange(ContainerRepair container, ItemStack left, ItemStack right, IInventory outputSlot, String name, int baseCost)
|
||||
{
|
||||
AnvilUpdateEvent e = new AnvilUpdateEvent(left, right, name, baseCost);
|
||||
|
||||
@@ -0,0 +1,312 @@
|
||||
package net.minecraftforge.common.util;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier;
|
||||
|
||||
/**
|
||||
* Represents a captured snapshot of a block which will not change
|
||||
* automatically.
|
||||
* <p>
|
||||
* Unlike Block, which only one object can exist per coordinate, BlockSnapshot
|
||||
* can exist multiple times for any given Block.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class BlockSnapshot implements Serializable
|
||||
{
|
||||
private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("forge.debugBlockSnapshot", "false"));
|
||||
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
public final int dimId;
|
||||
public transient Block replacedBlock;
|
||||
public final int meta;
|
||||
public int flag;
|
||||
private final NBTTagCompound nbt;
|
||||
public transient World world;
|
||||
public final UniqueIdentifier blockIdentifier;
|
||||
|
||||
public BlockSnapshot(World world, int x, int y, int z, Block block, int meta)
|
||||
{
|
||||
this.world = world;
|
||||
this.dimId = world.provider.dimensionId;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.replacedBlock = block;
|
||||
this.blockIdentifier = GameRegistry.findUniqueIdentifierFor(block);
|
||||
this.meta = meta;
|
||||
this.flag = 3;
|
||||
TileEntity te = world.getTileEntity(x, y, z);
|
||||
if (te != null)
|
||||
{
|
||||
nbt = new NBTTagCompound();
|
||||
te.writeToNBT(nbt);
|
||||
}
|
||||
else nbt = null;
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Created BlockSnapshot - [World: %s ][Location: %d,%d,%d ][Block: %s ][Meta: %d ]", world.getWorldInfo().getWorldName(), x, y, z, block, meta);
|
||||
}
|
||||
}
|
||||
|
||||
public BlockSnapshot(World world, int x, int y, int z, Block block, int meta, NBTTagCompound nbt)
|
||||
{
|
||||
this.world = world;
|
||||
this.dimId = world.provider.dimensionId;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.replacedBlock = block;
|
||||
this.blockIdentifier = GameRegistry.findUniqueIdentifierFor(block);
|
||||
this.meta = meta;
|
||||
this.flag = 3;
|
||||
this.nbt = nbt;
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Created BlockSnapshot - [World: %s ][Location: %d,%d,%d ][Block: %s ][Meta: %d ]", world.getWorldInfo().getWorldName(), x, y, z, block, meta);
|
||||
}
|
||||
}
|
||||
|
||||
public BlockSnapshot(World world, int x, int y, int z, Block block, int meta, int flag)
|
||||
{
|
||||
this(world, x, y, z, block, meta);
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw constructor designed for serialization usages.
|
||||
*/
|
||||
public BlockSnapshot(int dimension, int x, int y, int z, String modid, String blockName, int meta, int flag, NBTTagCompound nbt)
|
||||
{
|
||||
this.dimId = dimension;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.meta = meta;
|
||||
this.flag = flag;
|
||||
this.blockIdentifier = new UniqueIdentifier(modid + ":" + blockName);
|
||||
this.nbt = nbt;
|
||||
}
|
||||
|
||||
public static BlockSnapshot getBlockSnapshot(World world, int x, int y, int z)
|
||||
{
|
||||
return new BlockSnapshot(world, x, y, z, world.getBlock(x, y, z), world.getBlockMetadata(x, y,z));
|
||||
}
|
||||
|
||||
public static BlockSnapshot getBlockSnapshot(World world, int x, int y, int z, int flag)
|
||||
{
|
||||
return new BlockSnapshot(world, x, y, z, world.getBlock(x, y, z), world.getBlockMetadata(x, y,z), flag);
|
||||
}
|
||||
|
||||
public static BlockSnapshot readFromNBT(NBTTagCompound tag)
|
||||
{
|
||||
NBTTagCompound nbt = tag.getBoolean("hasTE") ? null : tag.getCompoundTag("tileEntity");
|
||||
|
||||
return new BlockSnapshot(
|
||||
tag.getInteger("dimension"),
|
||||
tag.getInteger("posX"),
|
||||
tag.getInteger("posY"),
|
||||
tag.getInteger("posZ"),
|
||||
tag.getString("blockMod"),
|
||||
tag.getString("blockName"),
|
||||
tag.getInteger("metadata"),
|
||||
tag.getInteger("flag"),
|
||||
nbt);
|
||||
}
|
||||
|
||||
public Block getCurrentBlock()
|
||||
{
|
||||
return world.getBlock(x, y, z);
|
||||
}
|
||||
|
||||
public World getWorld()
|
||||
{
|
||||
if (this.world == null)
|
||||
{
|
||||
this.world = DimensionManager.getWorld(dimId);
|
||||
}
|
||||
return this.world;
|
||||
}
|
||||
|
||||
public Block getReplacedBlock()
|
||||
{
|
||||
if (this.replacedBlock == null)
|
||||
{
|
||||
this.replacedBlock = GameRegistry.findBlock(this.blockIdentifier.modId, this.blockIdentifier.name);
|
||||
}
|
||||
return this.replacedBlock;
|
||||
}
|
||||
|
||||
public TileEntity getTileEntity()
|
||||
{
|
||||
if (nbt != null)
|
||||
return TileEntity.createAndLoadEntity(nbt);
|
||||
else return null;
|
||||
}
|
||||
|
||||
public boolean restore()
|
||||
{
|
||||
return restore(false);
|
||||
}
|
||||
|
||||
public boolean restore(boolean force)
|
||||
{
|
||||
return restore(force, true);
|
||||
}
|
||||
|
||||
public boolean restore(boolean force, boolean applyPhysics)
|
||||
{
|
||||
if (getCurrentBlock() != getReplacedBlock() || world.getBlockMetadata(x & 15, y, z & 15) != meta)
|
||||
{
|
||||
if (force)
|
||||
{
|
||||
world.setBlock(x, y, z, getReplacedBlock(), meta, applyPhysics ? 3 : 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
world.setBlockMetadataWithNotify(x, y, z, meta, applyPhysics ? 3 : 2);
|
||||
world.markBlockForUpdate(x, y, z);
|
||||
TileEntity te = null;
|
||||
if (nbt != null)
|
||||
{
|
||||
te = world.getTileEntity(x, y, z);
|
||||
if (te != null)
|
||||
{
|
||||
te.readFromNBT(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Restored BlockSnapshot with data [World: %s ][Location: %d,%d,%d ][Meta: %d ][Block: %s ][TileEntity: %s ][force: %s ][applyPhysics: %s]", world.getWorldInfo().getWorldName(), x, y, z, meta, getReplacedBlock(), te, force, applyPhysics);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean restoreToLocation(World world, int x, int y, int z, boolean force, boolean applyPhysics)
|
||||
{
|
||||
if (getCurrentBlock() != getReplacedBlock() || world.getBlockMetadata(x & 15, y, z & 15) != meta)
|
||||
{
|
||||
if (force)
|
||||
{
|
||||
world.setBlock(x, y, z, getReplacedBlock(), meta, applyPhysics ? 3 : 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
world.setBlockMetadataWithNotify(x, y, z, meta, applyPhysics ? 3 : 2);
|
||||
world.markBlockForUpdate(x, y, z);
|
||||
TileEntity te = null;
|
||||
if (nbt != null)
|
||||
{
|
||||
te = world.getTileEntity(x, y, z);
|
||||
if (te != null)
|
||||
{
|
||||
te.readFromNBT(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Restored BlockSnapshot with data [World: %s ][Location: %d,%d,%d ][Meta: %d ][Block: %s ][TileEntity: %s ][force: %s ][applyPhysics: %s]", world.getWorldInfo().getWorldName(), x, y, z, meta, getReplacedBlock(), te, force, applyPhysics);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void writeToNBT(NBTTagCompound compound)
|
||||
{
|
||||
compound.setString("blockMod", blockIdentifier.modId);
|
||||
compound.setString("blockName", blockIdentifier.name);
|
||||
compound.setInteger("posX", x);
|
||||
compound.setInteger("posY", y);
|
||||
compound.setInteger("posZ", z);
|
||||
compound.setInteger("flag", flag);
|
||||
compound.setInteger("dimension", dimId);
|
||||
compound.setInteger("metadata", meta);
|
||||
|
||||
compound.setBoolean("hasTE", nbt != null);
|
||||
|
||||
if (nbt != null)
|
||||
{
|
||||
compound.setTag("tileEntity", nbt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final BlockSnapshot other = (BlockSnapshot) obj;
|
||||
if (this.x != other.x)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.y != other.y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.z != other.z)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.meta != other.meta)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.dimId != other.dimId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.nbt != other.nbt && (this.nbt == null || !this.nbt.equals(other.nbt)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.world != other.world && (this.world == null || !this.world.equals(other.world)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.blockIdentifier != other.blockIdentifier && (this.blockIdentifier == null || !this.blockIdentifier.equals(other.blockIdentifier)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = 7;
|
||||
hash = 73 * hash + this.x;
|
||||
hash = 73 * hash + this.y;
|
||||
hash = 73 * hash + this.z;
|
||||
hash = 73 * hash + this.meta;
|
||||
hash = 73 * hash + this.dimId;
|
||||
hash = 73 * hash + (this.nbt != null ? this.nbt.hashCode() : 0);
|
||||
hash = 73 * hash + (this.world != null ? this.world.hashCode() : 0);
|
||||
hash = 73 * hash + (this.blockIdentifier != null ? this.blockIdentifier.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import net.minecraft.entity.effect.EntityLightningBolt;
|
||||
import net.minecraft.entity.monster.EntityZombie;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
@@ -21,6 +22,8 @@ import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.world.storage.IPlayerFileData;
|
||||
import net.minecraft.world.storage.SaveHandler;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.util.BlockSnapshot;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import net.minecraftforge.event.entity.EntityStruckByLightningEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingPackSizeEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingSpawnEvent;
|
||||
@@ -33,10 +36,31 @@ import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
|
||||
import net.minecraftforge.event.entity.player.PlayerUseItemEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent.MultiPlaceEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent.PlaceEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
|
||||
public class ForgeEventFactory
|
||||
{
|
||||
|
||||
public static MultiPlaceEvent onPlayerMultiBlockPlace(EntityPlayer player, List<BlockSnapshot> blockSnapshots, ForgeDirection direction)
|
||||
{
|
||||
Block placedAgainst = blockSnapshots.get(0).world.getBlock(blockSnapshots.get(0).x + direction.getOpposite().offsetX, blockSnapshots.get(0).y + direction.getOpposite().offsetY, blockSnapshots.get(0).z + direction.getOpposite().offsetZ);
|
||||
|
||||
MultiPlaceEvent event = new MultiPlaceEvent(blockSnapshots, placedAgainst, player);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
public static PlaceEvent onPlayerBlockPlace(EntityPlayer player, BlockSnapshot blockSnapshot, ForgeDirection direction)
|
||||
{
|
||||
Block placedAgainst = blockSnapshot.world.getBlock(blockSnapshot.x + direction.getOpposite().offsetX, blockSnapshot.y + direction.getOpposite().offsetY, blockSnapshot.z + direction.getOpposite().offsetZ);
|
||||
|
||||
PlaceEvent event = new PlaceEvent(blockSnapshot, placedAgainst, player);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
public static boolean doPlayerHarvestCheck(EntityPlayer player, Block block, boolean success)
|
||||
{
|
||||
PlayerEvent.HarvestCheck event = new PlayerEvent.HarvestCheck(player, block, success);
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
package net.minecraftforge.event.world;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.Cancelable;
|
||||
import cpw.mods.fml.common.eventhandler.Event;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.util.BlockSnapshot;
|
||||
|
||||
public class BlockEvent extends Event {
|
||||
private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("forge.debugBlockEvent", "false"));
|
||||
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
@@ -111,4 +118,63 @@ public class BlockEvent extends Event {
|
||||
this.exp = exp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a block is placed by a player.
|
||||
*
|
||||
* If a Block Place event is cancelled, the block will not be placed.
|
||||
*/
|
||||
@Cancelable
|
||||
public static class PlaceEvent extends BlockEvent {
|
||||
|
||||
public final EntityPlayer player;
|
||||
public final ItemStack itemInHand;
|
||||
public final BlockSnapshot blockSnapshot;
|
||||
public final Block placedBlock;
|
||||
public final Block placedAgainst;
|
||||
|
||||
public PlaceEvent(BlockSnapshot blockSnapshot, Block placedAgainst, EntityPlayer player) {
|
||||
super(blockSnapshot.x, blockSnapshot.y, blockSnapshot.z, blockSnapshot.world, blockSnapshot.getCurrentBlock(), blockSnapshot.meta);
|
||||
this.player = player;
|
||||
this.itemInHand = player.getCurrentEquippedItem();
|
||||
this.blockSnapshot = blockSnapshot;
|
||||
this.placedBlock = blockSnapshot.getCurrentBlock();
|
||||
this.placedAgainst = placedAgainst;
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Created PlaceEvent - [PlacedBlock: %s ][PlacedAgainst: %s ][ItemStack: %s ][Player: %s ]\n", placedBlock, placedAgainst, player.getCurrentEquippedItem(), player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a single block placement action of a player triggers the
|
||||
* creation of multiple blocks(e.g. placing a bed block). The block returned
|
||||
* by {@link #block} and its related methods is the block where
|
||||
* the placed block would exist if the placement only affected a single
|
||||
* block.
|
||||
*/
|
||||
@Cancelable
|
||||
public static class MultiPlaceEvent extends PlaceEvent {
|
||||
private final List<BlockSnapshot> blockSnapshots;
|
||||
|
||||
public MultiPlaceEvent(List<BlockSnapshot> blockSnapshots, Block placedAgainst, EntityPlayer player) {
|
||||
super(blockSnapshots.get(0), placedAgainst, player);
|
||||
this.blockSnapshots = ImmutableList.copyOf(blockSnapshots);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Created MultiPlaceEvent - [PlacedAgainst: %s ][ItemInHand: %s ][Player: %s ]\n", placedAgainst, this.itemInHand, player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of blocksnapshots for all blocks which were replaced by the
|
||||
* placement of the new blocks. Most of these blocks will just be of type AIR.
|
||||
*
|
||||
* @return immutable list of replaced BlockSnapshots
|
||||
*/
|
||||
public List<BlockSnapshot> getReplacedBlockSnapshots() {
|
||||
return blockSnapshots;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user