mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-11-23 19:16:40 +01:00
Improve level of event listening.
This commit is contained in:
parent
110aa2e56b
commit
26d3645f86
@ -33,6 +33,11 @@
|
||||
import com.sk89q.worldguard.bukkit.commands.GeneralCommands;
|
||||
import com.sk89q.worldguard.bukkit.commands.ProtectionCommands;
|
||||
import com.sk89q.worldguard.bukkit.commands.ToggleCommands;
|
||||
import com.sk89q.worldguard.bukkit.listener.BlacklistListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.BlockedPotionsListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.ChestProtectionListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.EventAbstractionListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.RegionProtectionListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardBlockListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardCommandBookListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardEntityListener;
|
||||
@ -42,10 +47,6 @@
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardVehicleListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardWeatherListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.WorldGuardWorldListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.BlacklistListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.BlockedPotionsListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.ChestProtectionListener;
|
||||
import com.sk89q.worldguard.bukkit.listener.RegionProtectionListener;
|
||||
import com.sk89q.worldguard.protection.GlobalRegionManager;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.util.FatalConfigurationLoadingException;
|
||||
@ -200,6 +201,7 @@ public void run() {
|
||||
(new ChestProtectionListener(this)).registerEvents();
|
||||
(new RegionProtectionListener(this)).registerEvents();
|
||||
(new BlockedPotionsListener(this)).registerEvents();
|
||||
(new EventAbstractionListener(this)).registerEvents();
|
||||
|
||||
configuration.updateCommandBookGodMode();
|
||||
|
||||
|
@ -71,21 +71,23 @@ public void onBreakBlock(BreakBlockEvent event) {
|
||||
Player player = Causes.getInvolvedPlayer(event.getCauses());
|
||||
Location target = event.getTarget();
|
||||
|
||||
WorldConfiguration wcfg = getWorldConfig(target.getWorld());
|
||||
|
||||
// Early guard
|
||||
if (!wcfg.signChestProtection) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player != null) {
|
||||
WorldConfiguration wcfg = getWorldConfig(player);
|
||||
|
||||
// Early guard
|
||||
if (!wcfg.signChestProtection) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.isChestProtected(target.getBlock(), player)) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "This chest is protected.");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else {
|
||||
// No player? Deny anyway
|
||||
event.setCancelled(true);
|
||||
if (wcfg.isChestProtected(target.getBlock())) {
|
||||
// No player? Deny anyway
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,21 +96,23 @@ public void onUseBlock(UseBlockEvent event) {
|
||||
Player player = Causes.getInvolvedPlayer(event.getCauses());
|
||||
Location target = event.getTarget();
|
||||
|
||||
WorldConfiguration wcfg = getWorldConfig(target.getWorld());
|
||||
|
||||
// Early guard
|
||||
if (!wcfg.signChestProtection) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player != null) {
|
||||
WorldConfiguration wcfg = getWorldConfig(player);
|
||||
|
||||
// Early guard
|
||||
if (!wcfg.signChestProtection) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.isChestProtected(target.getBlock(), player)) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "This chest is protected.");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else {
|
||||
// No player? Deny anyway
|
||||
event.setCancelled(true);
|
||||
if (wcfg.isChestProtected(target.getBlock())) {
|
||||
// No player? Deny anyway
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,6 @@
|
||||
package com.sk89q.worldguard.bukkit.listener;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.bukkit.util.Blocks;
|
||||
import com.sk89q.worldguard.bukkit.util.Materials;
|
||||
import com.sk89q.worldguard.bukkit.util.Events;
|
||||
import com.sk89q.worldguard.util.cause.Cause;
|
||||
import com.sk89q.worldguard.util.cause.Causes;
|
||||
import com.sk89q.worldguard.bukkit.event.block.BreakBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.block.PlaceBlockEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
|
||||
@ -32,16 +27,26 @@
|
||||
import com.sk89q.worldguard.bukkit.event.entity.SpawnEntityEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.entity.UseEntityEvent;
|
||||
import com.sk89q.worldguard.bukkit.event.inventory.UseItemEvent;
|
||||
import com.sk89q.worldguard.bukkit.util.Blocks;
|
||||
import com.sk89q.worldguard.bukkit.util.Events;
|
||||
import com.sk89q.worldguard.bukkit.util.Materials;
|
||||
import com.sk89q.worldguard.bukkit.util.WGMetadata;
|
||||
import com.sk89q.worldguard.util.cause.Cause;
|
||||
import com.sk89q.worldguard.util.cause.Causes;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.ThrownPotion;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -55,6 +60,7 @@
|
||||
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import org.bukkit.event.entity.EntityCombustByBlockEvent;
|
||||
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||
@ -80,6 +86,8 @@
|
||||
import org.bukkit.event.vehicle.VehicleDamageEvent;
|
||||
import org.bukkit.event.vehicle.VehicleDestroyEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Dispenser;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
@ -91,6 +99,13 @@
|
||||
|
||||
public class EventAbstractionListener implements Listener {
|
||||
|
||||
/**
|
||||
* Abstract {@link BlockFromToEvent}s into break and place events.
|
||||
* Currently disabled as it creates a lot of new events.
|
||||
*/
|
||||
public static final boolean ABSTRACT_FROM_TO_EVENTS = false;
|
||||
private static final String FALLING_SOURCE_KEY = "worldguard.fallingSource";
|
||||
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
public EventAbstractionListener(WorldGuardPlugin plugin) {
|
||||
@ -112,7 +127,14 @@ public void onBlockBreak(BlockBreakEvent event) {
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getPlayer()), event.getBlock()));
|
||||
BlockState previousState = event.getBlockReplacedState();
|
||||
|
||||
// Some blocks, like tall grass and fire, get replaced
|
||||
if (previousState.getType() != Material.AIR) {
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, create(event.getPlayer()), previousState.getLocation(), previousState.getType()));
|
||||
}
|
||||
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(event.getPlayer()), event.getBlock()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -124,15 +146,37 @@ public void onBlockBurn(BlockBurnEvent event) {
|
||||
|
||||
@EventHandler
|
||||
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
|
||||
Block block = event.getBlock();
|
||||
Entity entity = event.getEntity();
|
||||
Material to = event.getTo();
|
||||
|
||||
// Fire two events: one as BREAK and one as PLACE
|
||||
if (event.getTo() != Material.AIR && event.getBlock().getType() != Material.AIR) {
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, create(event.getEntity()), event.getBlock()));
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(event.getEntity()), event.getBlock()));
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, create(entity), block));
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(entity), block.getLocation(), to));
|
||||
} else {
|
||||
if (event.getTo() == Material.AIR) {
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, create(event.getEntity()), event.getBlock()));
|
||||
// Track the source so later we can create a proper chain of causes
|
||||
if (entity instanceof FallingBlock) {
|
||||
WGMetadata.put(entity, FALLING_SOURCE_KEY, block);
|
||||
|
||||
// Switch around the event
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, create(block), entity));
|
||||
} else {
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, create(entity), event.getBlock()));
|
||||
}
|
||||
} else {
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(event.getEntity()), event.getBlock()));
|
||||
List<? extends Cause<?>> causes;
|
||||
|
||||
// Return the source for falling blocks
|
||||
if (entity instanceof FallingBlock) {
|
||||
Block source = WGMetadata.getIfPresent(entity, FALLING_SOURCE_KEY, Block.class);
|
||||
causes = create(source, entity);
|
||||
} else {
|
||||
causes = create(entity);
|
||||
}
|
||||
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, causes, event.getBlock().getLocation(), to));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,69 +203,37 @@ public void onBlockDamage(BlockDamageEvent event) {
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
@Nullable ItemStack item = player.getItemInHand();
|
||||
Block block = event.getClickedBlock();
|
||||
Block clicked = event.getClickedBlock();
|
||||
Block placed;
|
||||
List<? extends Cause<?>> causes = create(player);
|
||||
|
||||
switch (event.getAction()) {
|
||||
case PHYSICAL:
|
||||
// TODO: Don't fire events for blocks that can't be interacted with using PHYSICAL
|
||||
if (Events.fireAndTestCancel(new UseBlockEvent(event, causes, block))) {
|
||||
if (Events.fireAndTestCancel(new UseBlockEvent(event, causes, clicked))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
if (item != null && item.getType() == Material.TNT) {
|
||||
// Workaround for a bug that allowed tnt to trigger instantly if placed
|
||||
// next to redstone, without plugins getting the block place event
|
||||
// (not sure if this actually still happens)
|
||||
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getPlayer()), block.getLocation(), Material.TNT));
|
||||
}
|
||||
placed = clicked.getRelative(event.getBlockFace());
|
||||
|
||||
// Handle created Minecarts
|
||||
if (item != null && Materials.isMinecart(item.getType())) {
|
||||
// TODO: Give a more specific minecart type
|
||||
Block placedBlock = block.getRelative(event.getBlockFace());
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, create(event.getPlayer()), placedBlock.getLocation().add(0.5, 0, 0.5), EntityType.MINECART));
|
||||
}
|
||||
|
||||
// Handle cocoa beans
|
||||
if (item != null && item.getType() == Material.INK_SACK && Materials.isDyeColor(item.getData(), DyeColor.BROWN)) {
|
||||
// CraftBukkit doesn't or didn't throw a block place for this
|
||||
if (!(event.getBlockFace() == BlockFace.DOWN || event.getBlockFace() == BlockFace.UP)) {
|
||||
Block placedBlock = block.getRelative(event.getBlockFace());
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(event.getPlayer()), placedBlock.getLocation(), Material.COCOA));
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for http://leaky.bukkit.org/issues/1034
|
||||
if (item != null && item.getType() == Material.TNT) {
|
||||
Block placedBlock = block.getRelative(event.getBlockFace());
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(event.getPlayer()), placedBlock.getLocation(), Material.TNT));
|
||||
}
|
||||
|
||||
// Handle flint and steel and fire charge as fire place
|
||||
if (item != null && (item.getType() == Material.FIREBALL || item.getType() == Material.FLINT_AND_STEEL)) {
|
||||
Block placedBlock = block.getRelative(event.getBlockFace());
|
||||
if (!Events.fireAndTestCancel(new PlaceBlockEvent(event, create(event.getPlayer()), placedBlock.getLocation(), Material.FIRE))) {
|
||||
event.setUseItemInHand(Result.DENY);
|
||||
}
|
||||
}
|
||||
// Re-used for dispensers
|
||||
handleBlockRightClick(event, create(event.getPlayer()), item, clicked, event.getBlockFace(), placed);
|
||||
|
||||
case LEFT_CLICK_BLOCK:
|
||||
// TODO: Don't fire events for blocks that can't be interacted with using clicks
|
||||
placed = clicked.getRelative(event.getBlockFace());
|
||||
|
||||
// As of MC ~1.6, sneaking blocks the use of blocks with right click
|
||||
if (!player.isSneaking() || event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
// Only fire events for blocks that are modified when right clicked
|
||||
if (isBlockModifiedOnClick(block.getType()) || (item != null && isItemAppliedToBlock(item.getType(), block.getType()))) {
|
||||
if (Events.fireAndTestCancel(new UseBlockEvent(event, causes, block))) {
|
||||
if (isBlockModifiedOnClick(clicked.getType()) || (item != null && isItemAppliedToBlock(item.getType(), clicked.getType()))) {
|
||||
if (Events.fireAndTestCancel(new UseBlockEvent(event, causes, clicked))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
}
|
||||
|
||||
// Handle connected blocks (i.e. beds, chests)
|
||||
for (Block connected : Blocks.getConnected(block)) {
|
||||
for (Block connected : Blocks.getConnected(clicked)) {
|
||||
if (Events.fireAndTestCancel(new UseBlockEvent(event, create(event.getPlayer()), connected))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
break;
|
||||
@ -230,8 +242,8 @@ public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
}
|
||||
|
||||
// Special handling of flint and steel on TNT
|
||||
if (block.getType() == Material.TNT && item != null && item.getType() == Material.FLINT_AND_STEEL) {
|
||||
if (Events.fireAndTestCancel(new BreakBlockEvent(event, create(event.getPlayer()), block))) {
|
||||
if (clicked.getType() == Material.TNT && item != null && item.getType() == Material.FLINT_AND_STEEL) {
|
||||
if (Events.fireAndTestCancel(new BreakBlockEvent(event, create(event.getPlayer()), clicked))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
break;
|
||||
}
|
||||
@ -239,8 +251,8 @@ public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
}
|
||||
|
||||
// Special handling of putting out fires
|
||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK && block.getType() == Material.FIRE) {
|
||||
if (Events.fireAndTestCancel(new BreakBlockEvent(event, create(event.getPlayer()), block))) {
|
||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK && placed.getType() == Material.FIRE) {
|
||||
if (Events.fireAndTestCancel(new BreakBlockEvent(event, create(event.getPlayer()), placed))) {
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
break;
|
||||
}
|
||||
@ -248,7 +260,7 @@ public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
|
||||
case LEFT_CLICK_AIR:
|
||||
case RIGHT_CLICK_AIR:
|
||||
if (item != null && Events.fireAndTestCancel(new UseItemEvent(event, causes, player.getWorld(), item))) {
|
||||
if (item != null && !item.getType().isBlock() && Events.fireAndTestCancel(new UseItemEvent(event, causes, player.getWorld(), item))) {
|
||||
event.setUseItemInHand(Result.DENY);
|
||||
}
|
||||
|
||||
@ -263,6 +275,7 @@ public void onEntityInteract(org.bukkit.event.entity.EntityInteractEvent event)
|
||||
|
||||
@EventHandler
|
||||
public void onBlockIgnite(BlockIgniteEvent event) {
|
||||
Block block = event.getBlock();
|
||||
List<? extends Cause<?>> causes;
|
||||
|
||||
// Find the cause
|
||||
@ -276,7 +289,9 @@ public void onBlockIgnite(BlockIgniteEvent event) {
|
||||
causes = Collections.emptyList();
|
||||
}
|
||||
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, causes, event.getBlock()));
|
||||
if (block.getType() != Material.AIR) {
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, causes, event.getBlock()));
|
||||
}
|
||||
|
||||
// This is also handled in the PlayerInteractEvent listener
|
||||
if (event.getCause() == IgniteCause.FLINT_AND_STEEL || event.getCause() == IgniteCause.FIREBALL) {
|
||||
@ -303,7 +318,8 @@ public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) {
|
||||
// Milk buckets can't be emptied as of writing
|
||||
if (event.getBucket() != Material.MILK_BUCKET) {
|
||||
ItemStack item = new ItemStack(event.getBucket(), 1);
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(player), blockAffected));
|
||||
Material blockMaterial = Materials.getBucketBlockMaterial(event.getBucket());
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(player), blockAffected.getLocation(), blockMaterial));
|
||||
Events.fireToCancel(event, new UseItemEvent(event, create(player), player.getWorld(), item));
|
||||
}
|
||||
}
|
||||
@ -329,13 +345,34 @@ public void onPlayerBucketFill(PlayerBucketFillEvent event) {
|
||||
|
||||
@EventHandler
|
||||
public void onBlockFromTo(BlockFromToEvent event) {
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, create(event.getBlock()), event.getToBlock()));
|
||||
if (ABSTRACT_FROM_TO_EVENTS) {
|
||||
Block from = event.getBlock();
|
||||
Block to = event.getToBlock();
|
||||
|
||||
// Liquids pass this event when flowing to solid blocks
|
||||
if (to.getType().isSolid() && Materials.isLiquid(from.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<? extends Cause<?>> causes = create(from);
|
||||
|
||||
if (from.getType() != Material.AIR) {
|
||||
Events.fireToCancel(event, new BreakBlockEvent(event, causes, to));
|
||||
}
|
||||
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, causes, to.getLocation(), from.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Entity break / place
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@EventHandler
|
||||
public void onCreatureSpawn(CreatureSpawnEvent event) {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, Collections.<Cause<?>>emptyList(), event.getEntity()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onHangingPlace(HangingPlaceEvent event) {
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, create(event.getPlayer()), event.getEntity()));
|
||||
@ -355,6 +392,8 @@ public void onVehicleDestroy(VehicleDestroyEvent event) {
|
||||
Events.fireToCancel(event, new DestroyEntityEvent(event, create(event.getAttacker()), event.getVehicle()));
|
||||
}
|
||||
|
||||
// TODO: XP pickup is an entity destroy event
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Entity external interaction
|
||||
//-------------------------------------------------------------------------
|
||||
@ -482,7 +521,59 @@ public void onPotionSplash(PotionSplashEvent event) {
|
||||
|
||||
@EventHandler
|
||||
public void onBlockDispense(BlockDispenseEvent event) {
|
||||
Events.fireToCancel(event, new UseItemEvent(event, create(event.getBlock()), event.getBlock().getWorld(), event.getItem()));
|
||||
List<? extends Cause<?>> causes = create(event.getBlock());
|
||||
Block dispenserBlock = event.getBlock();
|
||||
ItemStack item = event.getItem();
|
||||
MaterialData materialData = dispenserBlock.getState().getData();
|
||||
|
||||
Events.fireToCancel(event, new UseItemEvent(event, causes, dispenserBlock.getWorld(), item));
|
||||
|
||||
// Simulate right click event as players have it
|
||||
if (materialData instanceof Dispenser) {
|
||||
Dispenser dispenser = (Dispenser) materialData;
|
||||
Block placed = dispenserBlock.getRelative(dispenser.getFacing());
|
||||
Block clicked = placed.getRelative(dispenser.getFacing());
|
||||
handleBlockRightClick(event, causes, item, clicked, dispenser.getFacing().getOppositeFace(), placed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the right click of a block while an item is held.
|
||||
*
|
||||
* @param event the original event
|
||||
* @param causes the list of causes
|
||||
* @param item the item
|
||||
* @param clicked the clicked block
|
||||
* @param faceClicked the face of the clicked block
|
||||
* @param placed the placed block
|
||||
* @param <T> the event type
|
||||
*/
|
||||
private static <T extends Event & Cancellable> void handleBlockRightClick(T event, List<? extends Cause<?>> causes, @Nullable ItemStack item, Block clicked, BlockFace faceClicked, Block placed) {
|
||||
if (item != null && item.getType() == Material.TNT) {
|
||||
// Workaround for a bug that allowed TNT to trigger instantly if placed
|
||||
// next to redstone, without plugins getting the clicked place event
|
||||
// (not sure if this actually still happens)
|
||||
Events.fireToCancel(event, new UseBlockEvent(event, causes, clicked.getLocation(), Material.TNT));
|
||||
}
|
||||
|
||||
// Handle created Minecarts
|
||||
if (item != null && Materials.isMinecart(item.getType())) {
|
||||
// TODO: Give a more specific Minecart type
|
||||
Events.fireToCancel(event, new SpawnEntityEvent(event, causes, placed.getLocation().add(0.5, 0, 0.5), EntityType.MINECART));
|
||||
}
|
||||
|
||||
// Handle cocoa beans
|
||||
if (item != null && item.getType() == Material.INK_SACK && Materials.isDyeColor(item.getData(), DyeColor.BROWN)) {
|
||||
// CraftBukkit doesn't or didn't throw a clicked place for this
|
||||
if (!(faceClicked == BlockFace.DOWN || faceClicked == BlockFace.UP)) {
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, causes, placed.getLocation(), Material.COCOA));
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for http://leaky.bukkit.org/issues/1034
|
||||
if (item != null && item.getType() == Material.TNT) {
|
||||
Events.fireToCancel(event, new PlaceBlockEvent(event, causes, placed.getLocation(), Material.TNT));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Inventory events?
|
||||
|
@ -38,7 +38,7 @@ private Events() {
|
||||
*
|
||||
* @param eventToFire the event to fire
|
||||
* @param <T> an event that can be fired and is cancellable
|
||||
* @return true if the event was fired
|
||||
* @return true if the event was cancelled
|
||||
*/
|
||||
public static <T extends Event & Cancellable> boolean fireAndTestCancel( T eventToFire) {
|
||||
Bukkit.getServer().getPluginManager().callEvent(eventToFire);
|
||||
|
@ -36,8 +36,8 @@
|
||||
*/
|
||||
public final class Materials {
|
||||
|
||||
private static final int MODIFED_ON_CLICK = 1;
|
||||
private static final int MODIFIES_BLOCKS = 1;
|
||||
private static final int MODIFIED_ON_CLICK = 1;
|
||||
private static final int MODIFIES_BLOCKS = 2;
|
||||
|
||||
private static final BiMap<EntityType, Material> ENTITY_ITEMS = HashBiMap.create();
|
||||
private static final Map<Material, Integer> MATERIAL_FLAGS = new HashMap<Material, Integer>();
|
||||
@ -86,10 +86,10 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.GLASS, 0);
|
||||
MATERIAL_FLAGS.put(Material.LAPIS_ORE, 0);
|
||||
MATERIAL_FLAGS.put(Material.LAPIS_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.DISPENSER, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.DISPENSER, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.SANDSTONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.NOTE_BLOCK, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.BED_BLOCK, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.NOTE_BLOCK, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.BED_BLOCK, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.POWERED_RAIL, 0);
|
||||
MATERIAL_FLAGS.put(Material.DETECTOR_RAIL, 0);
|
||||
MATERIAL_FLAGS.put(Material.PISTON_STICKY_BASE, 0);
|
||||
@ -109,7 +109,7 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.DOUBLE_STEP, 0);
|
||||
MATERIAL_FLAGS.put(Material.STEP, 0);
|
||||
MATERIAL_FLAGS.put(Material.BRICK, 0);
|
||||
MATERIAL_FLAGS.put(Material.TNT, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.TNT, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.BOOKSHELF, 0);
|
||||
MATERIAL_FLAGS.put(Material.MOSSY_COBBLESTONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.OBSIDIAN, 0);
|
||||
@ -117,37 +117,37 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.FIRE, 0);
|
||||
MATERIAL_FLAGS.put(Material.MOB_SPAWNER, 0);
|
||||
MATERIAL_FLAGS.put(Material.WOOD_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.CHEST, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.CHEST, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_WIRE, 0);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_ORE, 0);
|
||||
MATERIAL_FLAGS.put(Material.DIAMOND_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.WORKBENCH, 0);
|
||||
MATERIAL_FLAGS.put(Material.CROPS, 0);
|
||||
MATERIAL_FLAGS.put(Material.SOIL, 0);
|
||||
MATERIAL_FLAGS.put(Material.FURNACE, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.BURNING_FURNACE, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.FURNACE, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.BURNING_FURNACE, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.SIGN_POST, 0);
|
||||
MATERIAL_FLAGS.put(Material.WOODEN_DOOR, 0);
|
||||
MATERIAL_FLAGS.put(Material.LADDER, 0);
|
||||
MATERIAL_FLAGS.put(Material.RAILS, 0);
|
||||
MATERIAL_FLAGS.put(Material.COBBLESTONE_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.WALL_SIGN, 0);
|
||||
MATERIAL_FLAGS.put(Material.LEVER, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.LEVER, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.STONE_PLATE, 0);
|
||||
MATERIAL_FLAGS.put(Material.IRON_DOOR_BLOCK, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.IRON_DOOR_BLOCK, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.WOOD_PLATE, 0);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_ORE, 0);
|
||||
MATERIAL_FLAGS.put(Material.GLOWING_REDSTONE_ORE, 0);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_TORCH_OFF, 0);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_TORCH_ON, 0);
|
||||
MATERIAL_FLAGS.put(Material.STONE_BUTTON, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.STONE_BUTTON, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.SNOW, 0);
|
||||
MATERIAL_FLAGS.put(Material.ICE, 0);
|
||||
MATERIAL_FLAGS.put(Material.SNOW_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.CACTUS, 0);
|
||||
MATERIAL_FLAGS.put(Material.CLAY, 0);
|
||||
MATERIAL_FLAGS.put(Material.SUGAR_CANE_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.JUKEBOX, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.JUKEBOX, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.FENCE, 0);
|
||||
MATERIAL_FLAGS.put(Material.PUMPKIN, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHERRACK, 0);
|
||||
@ -155,11 +155,11 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.GLOWSTONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.PORTAL, 0);
|
||||
MATERIAL_FLAGS.put(Material.JACK_O_LANTERN, 0);
|
||||
MATERIAL_FLAGS.put(Material.CAKE_BLOCK, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.DIODE_BLOCK_OFF, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.DIODE_BLOCK_ON, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.CAKE_BLOCK, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.DIODE_BLOCK_OFF, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.DIODE_BLOCK_ON, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.STAINED_GLASS, 0);
|
||||
MATERIAL_FLAGS.put(Material.TRAP_DOOR, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.TRAP_DOOR, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.MONSTER_EGGS, 0);
|
||||
MATERIAL_FLAGS.put(Material.SMOOTH_BRICK, 0);
|
||||
MATERIAL_FLAGS.put(Material.HUGE_MUSHROOM_1, 0);
|
||||
@ -170,7 +170,7 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.PUMPKIN_STEM, 0);
|
||||
MATERIAL_FLAGS.put(Material.MELON_STEM, 0);
|
||||
MATERIAL_FLAGS.put(Material.VINE, 0);
|
||||
MATERIAL_FLAGS.put(Material.FENCE_GATE, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.FENCE_GATE, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.BRICK_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.SMOOTH_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.MYCEL, 0);
|
||||
@ -180,12 +180,12 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.NETHER_BRICK_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.NETHER_WARTS, 0);
|
||||
MATERIAL_FLAGS.put(Material.ENCHANTMENT_TABLE, 0);
|
||||
MATERIAL_FLAGS.put(Material.BREWING_STAND, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.CAULDRON, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.BREWING_STAND, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.CAULDRON, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.ENDER_PORTAL, 0);
|
||||
MATERIAL_FLAGS.put(Material.ENDER_PORTAL_FRAME, 0);
|
||||
MATERIAL_FLAGS.put(Material.ENDER_STONE, 0);
|
||||
MATERIAL_FLAGS.put(Material.DRAGON_EGG, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.DRAGON_EGG, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_LAMP_OFF, 0);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_LAMP_ON, 0);
|
||||
MATERIAL_FLAGS.put(Material.WOOD_DOUBLE_STEP, 0);
|
||||
@ -200,28 +200,28 @@ public final class Materials {
|
||||
MATERIAL_FLAGS.put(Material.SPRUCE_WOOD_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.BIRCH_WOOD_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.JUNGLE_WOOD_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.COMMAND, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.BEACON, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.COMMAND, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.BEACON, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.COBBLE_WALL, 0);
|
||||
MATERIAL_FLAGS.put(Material.FLOWER_POT, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.FLOWER_POT, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.CARROT, 0);
|
||||
MATERIAL_FLAGS.put(Material.POTATO, 0);
|
||||
MATERIAL_FLAGS.put(Material.WOOD_BUTTON, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.WOOD_BUTTON, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.SKULL, 0);
|
||||
MATERIAL_FLAGS.put(Material.ANVIL, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.TRAPPED_CHEST, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.ANVIL, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.TRAPPED_CHEST, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.GOLD_PLATE, 0);
|
||||
MATERIAL_FLAGS.put(Material.IRON_PLATE, 0);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_COMPARATOR_OFF, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_COMPARATOR_ON, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.DAYLIGHT_DETECTOR, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_COMPARATOR_OFF, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_COMPARATOR_ON, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.DAYLIGHT_DETECTOR, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.REDSTONE_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.QUARTZ_ORE, 0);
|
||||
MATERIAL_FLAGS.put(Material.HOPPER, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.HOPPER, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.QUARTZ_BLOCK, 0);
|
||||
MATERIAL_FLAGS.put(Material.QUARTZ_STAIRS, 0);
|
||||
MATERIAL_FLAGS.put(Material.ACTIVATOR_RAIL, 0);
|
||||
MATERIAL_FLAGS.put(Material.DROPPER, MODIFED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.DROPPER, MODIFIED_ON_CLICK);
|
||||
MATERIAL_FLAGS.put(Material.STAINED_CLAY, 0);
|
||||
MATERIAL_FLAGS.put(Material.STAINED_GLASS_PANE, 0);
|
||||
MATERIAL_FLAGS.put(Material.LEAVES_2, 0);
|
||||
@ -422,6 +422,30 @@ public static Material getRelatedMaterial(EntityType type) {
|
||||
return ENTITY_ITEMS.get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the material of the block placed by the given bucket, defaulting
|
||||
* to water if the bucket type is not known.
|
||||
*
|
||||
* <p>If a non-bucket material is given, it will be assumed to be
|
||||
* an unknown bucket type. If the given bucket doesn't have a block form
|
||||
* (it can't be placed), then water will be returned (i.e. for milk).
|
||||
* Be aware that either the stationary or non-stationary material may be
|
||||
* returned.</p>
|
||||
*
|
||||
* @param type the bucket material
|
||||
* @return the block material
|
||||
*/
|
||||
public static Material getBucketBlockMaterial(Material type) {
|
||||
switch (type) {
|
||||
case LAVA_BUCKET:
|
||||
return Material.LAVA;
|
||||
case MILK_BUCKET:
|
||||
return Material.WATER;
|
||||
default:
|
||||
return Material.WATER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given material is a mushroom.
|
||||
*
|
||||
@ -442,6 +466,16 @@ public static boolean isLeaf(Material material) {
|
||||
return material == Material.LEAVES || material == Material.LEAVES_2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given material is a liquid block.
|
||||
*
|
||||
* @param material the material
|
||||
* @return true if a liquid block
|
||||
*/
|
||||
public static boolean isLiquid(Material material) {
|
||||
return isWater(material) || isLava(material);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given material is water.
|
||||
*
|
||||
@ -542,13 +576,13 @@ public static boolean isInventoryBlock(Material material) {
|
||||
*/
|
||||
public static boolean isBlockModifiedOnClick(Material material) {
|
||||
Integer flags = MATERIAL_FLAGS.get(material);
|
||||
return flags == null || (flags & MODIFED_ON_CLICK) == MODIFED_ON_CLICK;
|
||||
return flags == null || (flags & MODIFIED_ON_CLICK) == MODIFIED_ON_CLICK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given item modifies a given block when right clicked.
|
||||
*
|
||||
* <p>This test is conservative, returning true for blocks that it is not
|
||||
* <p>This test is conservative, returning true for items that it is not
|
||||
* aware of or does not have the details for.</p>
|
||||
*
|
||||
* @param item the item
|
||||
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* WorldGuard, a suite of tools for Minecraft
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldGuard team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.util;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.metadata.Metadatable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility methods for dealing with metadata on entities.
|
||||
*
|
||||
* <p>WorldGuard is placed as the owner of all values.</p>
|
||||
*/
|
||||
public final class WGMetadata {
|
||||
|
||||
private WGMetadata() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some metadata to a target.
|
||||
*
|
||||
* @param target the target
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
public static void put(Metadatable target, String key, Object value) {
|
||||
target.setMetadata(key, new FixedMetadataValue(WorldGuardPlugin.inst(), value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the (first) metadata value on the given target that has the given
|
||||
* key and is of the given class type.
|
||||
*
|
||||
* @param target the target
|
||||
* @param key the key
|
||||
* @param expected the type of the value
|
||||
* @param <T> the type of the value
|
||||
* @return a value, or {@code null} if one does not exists
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getIfPresent(Metadatable target, String key, Class<T> expected) {
|
||||
List<MetadataValue> values = target.getMetadata(key);
|
||||
WorldGuardPlugin owner = WorldGuardPlugin.inst();
|
||||
for (MetadataValue value : values) {
|
||||
if (value.getOwningPlugin() == owner) {
|
||||
Object v = value.value();
|
||||
if (expected.isInstance(v)) {
|
||||
return (T) v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -45,4 +45,9 @@ public Block get() {
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return block.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public static List<? extends Cause<?>> create(Object ... cause) {
|
||||
} else if (o instanceof Block) {
|
||||
causes.add(new BlockCause((Block) o));
|
||||
} else if (o instanceof Projectile) {
|
||||
causes.addAll(create(o));
|
||||
causes.addAll(create(((Projectile) o).getShooter()));
|
||||
causes.add(new EntityCause((Entity) o));
|
||||
} else if (o instanceof Entity) {
|
||||
causes.add(new EntityCause((Entity) o));
|
||||
|
@ -45,4 +45,8 @@ public Entity get() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return entity.toString();
|
||||
}
|
||||
}
|
||||
|
@ -45,4 +45,9 @@ public Player get() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return player.getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,4 +43,8 @@ public Object get() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "unknown(" + cause + ")";
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user