Saber-Factions/src/org/mcteam/factions/listeners/FactionsEntityListener.java

339 lines
11 KiB
Java
Raw Normal View History

2011-04-08 15:51:07 +02:00
package org.mcteam.factions.listeners;
2011-02-06 13:36:11 +01:00
import java.text.MessageFormat;
2011-02-06 13:36:11 +01:00
import org.bukkit.ChatColor;
2011-03-22 17:20:21 +01:00
import org.bukkit.entity.Creeper;
2011-02-06 13:36:11 +01:00
import org.bukkit.entity.Entity;
import org.bukkit.entity.Fireball;
2011-02-06 13:36:11 +01:00
import org.bukkit.entity.Player;
2011-03-23 17:39:56 +01:00
import org.bukkit.event.entity.CreatureSpawnEvent;
2011-02-06 13:36:11 +01:00
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageByProjectileEvent;
2011-02-13 17:04:06 +01:00
import org.bukkit.event.entity.EntityDamageEvent;
2011-02-06 13:36:11 +01:00
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
2011-02-06 13:36:11 +01:00
import org.bukkit.event.entity.EntityListener;
2011-03-23 17:39:56 +01:00
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
import org.bukkit.event.painting.PaintingBreakEvent;
import org.bukkit.event.painting.PaintingPlaceEvent;
2011-04-08 15:51:07 +02:00
import org.mcteam.factions.Board;
import org.mcteam.factions.Conf;
import org.mcteam.factions.Factions;
2011-04-08 15:51:07 +02:00
import org.mcteam.factions.FLocation;
import org.mcteam.factions.FPlayer;
import org.mcteam.factions.Faction;
import org.mcteam.factions.struct.Relation;
import org.mcteam.factions.util.EntityUtil;
2011-02-06 13:36:11 +01:00
public class FactionsEntityListener extends EntityListener {
@Override
public void onEntityDeath(EntityDeathEvent event) {
Entity entity = event.getEntity();
if ( ! (entity instanceof Player)) {
return;
}
2011-02-06 13:36:11 +01:00
Player player = (Player) entity;
2011-03-23 17:39:56 +01:00
FPlayer fplayer = FPlayer.get(player);
Faction faction = Board.getFactionAt(new FLocation(player.getLocation()));
if (faction.isWarZone()) { // war zones always override worldsNoPowerLoss either way, thus this layout
if (! Conf.warZonePowerLoss) {
fplayer.sendMessage("You didn't lose any power since you were in a war zone.");
return;
}
if (Conf.worldsNoPowerLoss.contains(player.getWorld().getName())) {
fplayer.sendMessage("The world you are in has power loss normally disabled, but you still lost power since you were in a war zone.");
}
} else if (faction.isNone() && !Conf.wildernessPowerLoss) {
fplayer.sendMessage("You didn't lose any power since you were in the wilderness.");
return;
} else if (Conf.worldsNoPowerLoss.contains(player.getWorld().getName())) {
fplayer.sendMessage("You didn't lose any power due to the world you died in.");
return;
}
2011-03-23 17:39:56 +01:00
fplayer.onDeath();
fplayer.sendMessage("Your power is now "+fplayer.getPowerRounded()+" / "+fplayer.getPowerMaxRounded());
2011-02-06 13:36:11 +01:00
}
2011-02-13 17:04:06 +01:00
2011-02-06 13:36:11 +01:00
/**
* Who can I hurt?
* I can never hurt members or allies.
* I can always hurt enemies.
* I can hurt neutrals as long as they are outside their own territory.
*/
@Override
2011-02-13 17:04:06 +01:00
public void onEntityDamage(EntityDamageEvent event) {
if ( event.isCancelled()) {
2011-03-22 17:20:21 +01:00
return;
2011-02-06 13:36:11 +01:00
}
2011-02-13 17:04:06 +01:00
if (event instanceof EntityDamageByEntityEvent) {
EntityDamageByEntityEvent sub = (EntityDamageByEntityEvent)event;
if ( ! this.canDamagerHurtDamagee(sub)) {
2011-02-13 17:04:06 +01:00
event.setCancelled(true);
}
} else if (event instanceof EntityDamageByProjectileEvent) {
EntityDamageByProjectileEvent sub = (EntityDamageByProjectileEvent)event;
if ( ! this.canDamagerHurtDamagee(sub)) {
2011-02-13 17:04:06 +01:00
event.setCancelled(true);
}
}
}
2011-03-22 17:20:21 +01:00
@Override
public void onEntityExplode(EntityExplodeEvent event)
{
2011-03-22 17:20:21 +01:00
if ( event.isCancelled()) {
return;
}
2011-03-22 17:20:21 +01:00
2011-03-23 17:39:56 +01:00
Faction faction = Board.getFactionAt(new FLocation(event.getLocation()));
boolean online = faction.hasPlayersOnline();
2011-03-23 17:39:56 +01:00
if (event.getEntity() instanceof Creeper && (
(faction.isNone() && Conf.wildernessBlockCreepers) ||
(faction.isNormal() && online && Conf.territoryBlockCreepers) ||
(faction.isNormal() && !online && Conf.territoryBlockCreepersWhenOffline) ||
(faction.isWarZone() && Conf.warZoneBlockCreepers) ||
faction.isSafeZone()
)) {
// creeper which needs prevention
2011-03-22 17:20:21 +01:00
event.setCancelled(true);
} else if (event.getEntity() instanceof Fireball && (
(faction.isNone() && Conf.wildernessBlockFireballs) ||
(faction.isNormal() && online && Conf.territoryBlockFireballs) ||
(faction.isNormal() && !online && Conf.territoryBlockFireballsWhenOffline) ||
(faction.isWarZone() && Conf.warZoneBlockFireballs) ||
faction.isSafeZone()
)) {
// ghast fireball which needs prevention
2011-03-22 17:20:21 +01:00
event.setCancelled(true);
} else if (
(faction.isNone() && Conf.wildernessBlockTNT) ||
(faction.isNormal() && online && Conf.territoryBlockTNT) ||
(faction.isNormal() && !online && Conf.territoryBlockTNTWhenOffline) ||
(faction.isWarZone() && Conf.warZoneBlockTNT) ||
(faction.isSafeZone() && Conf.safeZoneBlockTNT)
) {
// we'll assume it's TNT, which needs prevention
event.setCancelled(true);
}
}
public boolean canDamagerHurtDamagee(EntityDamageByEntityEvent sub) {
Entity damager = sub.getDamager();
Entity damagee = sub.getEntity();
int damage = sub.getDamage();
2011-02-06 13:36:11 +01:00
if ( ! (damagee instanceof Player)) {
return true;
}
2011-02-06 13:36:11 +01:00
2011-03-18 17:33:23 +01:00
FPlayer defender = FPlayer.get((Player)damagee);
2011-03-23 17:39:56 +01:00
if (defender == null || defender.getPlayer() == null) {
return true;
}
2011-03-23 17:39:56 +01:00
// Players can not take attack damage in a SafeZone
if (Board.getFactionAt(new FLocation(defender)).isSafeZone()) {
if (damager instanceof Player) {
FPlayer attacker = FPlayer.get((Player)damager);
attacker.sendMessage("You can't hurt other players in a SafeZone.");
// defender.sendMessage(attacker.getNameAndRelevant(defender)+Conf.colorSystem+" tried to hurt you.");
2011-03-23 17:39:56 +01:00
}
return false;
}
if ( ! (damager instanceof Player)) {
return true;
}
2011-03-18 17:33:23 +01:00
FPlayer attacker = FPlayer.get((Player)damager);
if (attacker == null || attacker.getPlayer() == null) {
return true;
}
if (!attacker.hasFaction() && Conf.disablePVPForFactionlessPlayers) {
attacker.sendMessage("You can't hurt other players until you join a faction.");
return false;
}
else if (!defender.hasFaction() && Conf.disablePVPForFactionlessPlayers) {
attacker.sendMessage("You can't hurt players who are not currently in a faction.");
return false;
}
if (attacker.hasLoginPvpDisabled()) {
attacker.sendMessage("You can't hurt other players for " + Conf.noPVPDamageToOthersForXSecondsAfterLogin + " seconds after logging in.");
return false;
}
Faction locFaction = Board.getFactionAt(new FLocation(attacker));
// so we know from above that the defender isn't in a safezone... what about the attacker, sneaky dog that he might be?
if (locFaction.isSafeZone()) {
attacker.sendMessage("You can't hurt other players while you are in a SafeZone.");
return false;
}
else if (locFaction.isWarZone() && Conf.warZoneFriendlyFire) {
return true;
}
2011-02-06 13:36:11 +01:00
Relation relation = defender.getRelation(attacker);
// Players without faction may be hurt anywhere
2011-03-23 17:39:56 +01:00
if (defender.getFaction().isNone()) {
return true;
2011-02-06 13:36:11 +01:00
}
// You can never hurt faction members or allies
if (relation.isMember() || relation.isAlly()) {
attacker.sendMessage(Conf.colorSystem+"You can't hurt "+defender.getNameAndRelevant(attacker));
return false;
2011-02-06 13:36:11 +01:00
}
// You can not hurt neutrals in their own territory.
if (relation.isNeutral() && defender.isInOwnTerritory()) {
attacker.sendMessage(Conf.colorSystem+"You can't hurt "+relation.getColor()+defender.getNameAndRelevant(attacker)+Conf.colorSystem+" in their own territory.");
defender.sendMessage(attacker.getNameAndRelevant(defender)+Conf.colorSystem+" tried to hurt you.");
return false;
2011-02-06 13:36:11 +01:00
}
// Damage will be dealt. However check if the damage should be reduced.
if (defender.isInOwnTerritory() && Conf.territoryShieldFactor > 0) {
2011-03-23 17:39:56 +01:00
int newDamage = (int)Math.ceil(damage * (1D - Conf.territoryShieldFactor));
sub.setDamage(newDamage);
2011-02-06 13:36:11 +01:00
// Send message
2011-03-23 17:39:56 +01:00
String perc = MessageFormat.format("{0,number,#%}", (Conf.territoryShieldFactor)); // TODO does this display correctly??
defender.sendMessage("Enemy damage reduced by "+ChatColor.RED+perc+Conf.colorSystem+".");
2011-02-06 13:36:11 +01:00
}
return true;
2011-02-06 13:36:11 +01:00
}
2011-03-23 17:39:56 +01:00
public void onCreatureSpawn(CreatureSpawnEvent event) {
if (event.isCancelled()) {
return;
}
if (Conf.safeZoneNerfedCreatureTypes.contains(event.getCreatureType()) && Board.getFactionAt(new FLocation(event.getLocation())).isSafeZone()) {
event.setCancelled(true);
}
}
@Override
public void onEntityTarget(EntityTargetEvent event) {
if (event.isCancelled()) {
return;
}
// if there is a target
Entity target = event.getTarget();
if (target == null) {
return;
}
// We are interested in blocking targeting for certain mobs:
if ( ! Conf.safeZoneNerfedCreatureTypes.contains(EntityUtil.creatureTypeFromEntity(event.getEntity()))) {
return;
}
// in case the target is in a safe zone.
if (Board.getFactionAt(new FLocation(target.getLocation())).isSafeZone()) {
event.setCancelled(true);
}
}
@Override
public void onPaintingBreak(PaintingBreakEvent event)
{
if (event.isCancelled()) {
return;
}
if (! (event instanceof PaintingBreakByEntityEvent)) {
return;
}
Entity breaker = ((PaintingBreakByEntityEvent)event).getRemover();
if (! (breaker instanceof Player)) {
return;
}
FLocation loc = new FLocation(event.getPainting().getLocation());
if ( ! this.playerCanDoPaintings((Player)breaker, loc, "remove")) {
event.setCancelled(true);
}
}
@Override
public void onPaintingPlace(PaintingPlaceEvent event)
{
if (event.isCancelled()) {
return;
}
if ( ! this.playerCanDoPaintings(event.getPlayer(), new FLocation(event.getBlock()), "place")) {
event.setCancelled(true);
}
}
public boolean playerCanDoPaintings(Player player, FLocation loc, String action) {
if (Conf.adminBypassPlayers.contains(player.getName())) {
return true;
}
Faction otherFaction = Board.getFactionAt(loc);
FPlayer me = FPlayer.get(player);
if (otherFaction.isNone()) {
if (!Conf.wildernessDenyBuild || Factions.hasPermAdminBypass(player)) {
return true; // This is not faction territory. Use whatever you like here.
}
me.sendMessage("You can't "+action+" paintings in the wilderness.");
return false;
}
if (otherFaction.isSafeZone()) {
if (Factions.hasPermManageSafeZone(player) || !Conf.safeZoneDenyBuild) {
return true;
}
me.sendMessage("You can't "+action+" paintings in a safe zone.");
return false;
}
else if (otherFaction.isWarZone()) {
if (Factions.hasPermManageWarZone(player) || !Conf.warZoneDenyBuild) {
return true;
}
me.sendMessage("You can't "+action+" paintings in a war zone.");
return false;
}
Faction myFaction = me.getFaction();
boolean areEnemies = myFaction.getRelation(otherFaction).isEnemy();
// Cancel if we are not in our own territory
if (myFaction != otherFaction) {
boolean online = otherFaction.hasPlayersOnline();
if (
(online && (areEnemies ? Conf.territoryEnemyDenyBuild : Conf.territoryDenyBuild))
|| (!online && (areEnemies ? Conf.territoryEnemyDenyBuildWhenOffline : Conf.territoryDenyBuildWhenOffline))
) {
me.sendMessage("You can't "+action+" paintings in the territory of "+otherFaction.getTag(myFaction));
return false;
}
}
return true;
}
2011-02-06 13:36:11 +01:00
}