/** * Tests the attacker against defender to see if we need to cancel the damage event due to world * PvP, Plot PvP or Friendly Fire settings. Only allow a Wolves owner to cause it damage, and * residents with destroy permissions to damage passive animals and villagers while in a town. * * @param attacker * @param defender * @return true if we should cancel. */ public static boolean preventDamageCall(Towny plugin, Entity attacker, Entity defender) { try { TownyWorld world = TownyUniverse.getDataSource().getWorld(defender.getWorld().getName()); // World using Towny if (!world.isUsingTowny()) return false; Player a = null; Player b = null; /* * Find the shooter if this is a projectile. */ if (attacker instanceof Projectile) { Projectile projectile = (Projectile) attacker; Object source = projectile.getShooter(); if (source instanceof Entity) { attacker = (Entity) source; } else { return false; // TODO: prevent damage from dispensers } } if (attacker instanceof Player) a = (Player) attacker; if (defender instanceof Player) b = (Player) defender; // Allow players to injure themselves if (a == b) return false; return preventDamageCall(plugin, world, attacker, defender, a, b); } catch (Exception e) { // Failed to fetch world } return false; }
/** * Tests the attacker against defender to see if we need to cancel the damage event due to world * PvP, Plot PvP or Friendly Fire settings. Only allow a Wolves owner to cause it damage, and * residents with destroy permissions to damage passive animals and villagers while in a town. * * @param world * @param attackingEntity * @param defendingEntity * @param attackingPlayer * @param defendingPlayer * @return true if we should cancel. */ public static boolean preventDamageCall( Towny plugin, TownyWorld world, Entity attackingEntity, Entity defendingEntity, Player attackingPlayer, Player defendingPlayer) { // World using Towny if (!world.isUsingTowny()) return false; /* * We have an attacking player */ if (attackingPlayer != null) { Coord coord = Coord.parseCoord(defendingEntity); TownBlock defenderTB = null; TownBlock attackerTB = null; try { attackerTB = world.getTownBlock(Coord.parseCoord(attackingEntity)); } catch (NotRegisteredException ex) { } try { defenderTB = world.getTownBlock(coord); } catch (NotRegisteredException ex) { } /* * If another player is the target * or * The target is in a TownBlock and... * the target is a tame wolf and we are not it's owner */ if ((defendingPlayer != null) || ((defenderTB != null) && ((defendingEntity instanceof Wolf) && ((Wolf) defendingEntity).isTamed() && !((Wolf) defendingEntity).getOwner().equals((AnimalTamer) attackingEntity)))) { /* * Defending player is in a warzone */ if (world.isWarZone(coord)) return false; /* * Check for special pvp plots (arena) */ if (isPvPPlot(attackingPlayer, defendingPlayer)) return false; /* * Check if we are preventing friendly fire between allies * Check the attackers TownBlock and it's Town for their PvP * status, else the world. * Check the defenders TownBlock and it's Town for their PvP * status, else the world. */ if (preventFriendlyFire(attackingPlayer, defendingPlayer) || preventPvP(world, attackerTB) || preventPvP(world, defenderTB)) { DisallowedPVPEvent event = new DisallowedPVPEvent(attackingPlayer, defendingPlayer); plugin.getServer().getPluginManager().callEvent(event); return !event.isCancelled(); } } else { /* * Remove animal killing prevention start */ /* * Defender is not a player so check for PvM */ if (defenderTB != null) { List<Class<?>> prots = EntityTypeUtil.parseLivingEntityClassNames( TownySettings.getEntityTypes(), "TownMobPVM:"); if (EntityTypeUtil.isInstanceOfAny(prots, defendingEntity)) { /* * Only allow the player to kill protected entities etc, * if they are from the same town * and have destroy permissions (grass) in the defending * TownBlock */ if (!PlayerCacheUtil.getCachePermission( attackingPlayer, attackingPlayer.getLocation(), 3, (byte) 0, ActionType.DESTROY)) return true; } } /* * Remove prevention end */ /* * Protect specific entity interactions (faked with block ID's). */ int blockID = 0; switch (defendingEntity.getType()) { case ITEM_FRAME: blockID = 389; break; case PAINTING: blockID = 321; break; case MINECART: if (defendingEntity instanceof org.bukkit.entity.minecart.StorageMinecart) { blockID = 342; } else if (defendingEntity instanceof org.bukkit.entity.minecart.RideableMinecart) { blockID = 328; } else if (defendingEntity instanceof org.bukkit.entity.minecart.PoweredMinecart) { blockID = 343; } else if (defendingEntity instanceof org.bukkit.entity.minecart.HopperMinecart) { blockID = 408; } else { blockID = 321; } default: break; } if (blockID != 0) { // Get permissions (updates if none exist) boolean bDestroy = PlayerCacheUtil.getCachePermission( attackingPlayer, defendingEntity.getLocation(), blockID, (byte) 0, TownyPermission.ActionType.DESTROY); if (!bDestroy) { /* * Fetch the players cache */ PlayerCache cache = plugin.getCache(attackingPlayer); if (cache.hasBlockErrMsg()) TownyMessaging.sendErrorMsg(attackingPlayer, cache.getBlockErrMsg()); return true; } } } } return false; }