Damage protection is now extended to being set on fire (by flaming arrows, for instance) and receiving harmful splash potion effects. Beneficial splash potion effects are unaffected, and prevention of harmful splash potion effects is handled on a player-by-player basis, so you can still be harmed if you're not careful where you throw them.
This commit is contained in:
parent
a0fa3863d4
commit
2a667a294d
@ -1,14 +1,19 @@
|
|||||||
package com.massivecraft.factions.listeners;
|
package com.massivecraft.factions.listeners;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Enderman;
|
import org.bukkit.entity.Enderman;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.Projectile;
|
import org.bukkit.entity.Projectile;
|
||||||
import org.bukkit.entity.TNTPrimed;
|
import org.bukkit.entity.TNTPrimed;
|
||||||
@ -17,15 +22,19 @@ import org.bukkit.event.EventPriority;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||||
|
import org.bukkit.event.entity.EntityCombustByEntityEvent;
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
import org.bukkit.event.entity.EntityDeathEvent;
|
import org.bukkit.event.entity.EntityDeathEvent;
|
||||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
import org.bukkit.event.entity.EntityTargetEvent;
|
import org.bukkit.event.entity.EntityTargetEvent;
|
||||||
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||||
|
import org.bukkit.event.entity.PotionSplashEvent;
|
||||||
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
|
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
|
||||||
import org.bukkit.event.painting.PaintingBreakEvent;
|
import org.bukkit.event.painting.PaintingBreakEvent;
|
||||||
import org.bukkit.event.painting.PaintingPlaceEvent;
|
import org.bukkit.event.painting.PaintingPlaceEvent;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
|
||||||
import com.massivecraft.factions.Board;
|
import com.massivecraft.factions.Board;
|
||||||
import com.massivecraft.factions.Conf;
|
import com.massivecraft.factions.Conf;
|
||||||
@ -81,7 +90,7 @@ public class FactionsEntityListener implements Listener
|
|||||||
if (event instanceof EntityDamageByEntityEvent)
|
if (event instanceof EntityDamageByEntityEvent)
|
||||||
{
|
{
|
||||||
EntityDamageByEntityEvent sub = (EntityDamageByEntityEvent)event;
|
EntityDamageByEntityEvent sub = (EntityDamageByEntityEvent)event;
|
||||||
if ( ! this.canDamagerHurtDamagee(sub))
|
if ( ! this.canDamagerHurtDamagee(sub, true))
|
||||||
{
|
{
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
@ -111,7 +120,62 @@ public class FactionsEntityListener implements Listener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mainly for flaming arrows; don't want allies or people in safe zones to be ignited even after damage event is cancelled
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL)
|
||||||
|
public void onEntityCombustByEntity(EntityCombustByEntityEvent event)
|
||||||
|
{
|
||||||
|
if (event.isCancelled()) return;
|
||||||
|
|
||||||
|
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(event.getCombuster(), event.getEntity(), EntityDamageEvent.DamageCause.FIRE, 0);
|
||||||
|
if ( ! this.canDamagerHurtDamagee(sub, false))
|
||||||
|
event.setCancelled(true);
|
||||||
|
sub = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Set<PotionEffectType> badPotionEffects = new LinkedHashSet<PotionEffectType>(Arrays.asList(
|
||||||
|
PotionEffectType.BLINDNESS, PotionEffectType.CONFUSION, PotionEffectType.HARM, PotionEffectType.HUNGER,
|
||||||
|
PotionEffectType.POISON, PotionEffectType.SLOW, PotionEffectType.SLOW_DIGGING, PotionEffectType.WEAKNESS
|
||||||
|
));
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL)
|
||||||
|
public void onPotionSplashEvent(PotionSplashEvent event)
|
||||||
|
{
|
||||||
|
if (event.isCancelled()) return;
|
||||||
|
|
||||||
|
// see if the potion has a harmful effect
|
||||||
|
boolean badjuju = false;
|
||||||
|
for (PotionEffect effect : event.getPotion().getEffects())
|
||||||
|
{
|
||||||
|
if (badPotionEffects.contains(effect.getType()))
|
||||||
|
{
|
||||||
|
badjuju = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! badjuju) return;
|
||||||
|
|
||||||
|
Entity thrower = event.getEntity();
|
||||||
|
if (thrower instanceof Projectile)
|
||||||
|
thrower = ((Projectile)thrower).getShooter();
|
||||||
|
|
||||||
|
// scan through affected entities to make sure they're all valid targets
|
||||||
|
Iterator<LivingEntity> iter = event.getAffectedEntities().iterator();
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
LivingEntity target = iter.next();
|
||||||
|
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(thrower, target, EntityDamageEvent.DamageCause.CUSTOM, 0);
|
||||||
|
if ( ! this.canDamagerHurtDamagee(sub, true))
|
||||||
|
event.setIntensity(target, 0.0); // affected entity list doesn't accept modification (iter.remove() is a no-go), but this works
|
||||||
|
sub = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean canDamagerHurtDamagee(EntityDamageByEntityEvent sub)
|
public boolean canDamagerHurtDamagee(EntityDamageByEntityEvent sub)
|
||||||
|
{
|
||||||
|
return canDamagerHurtDamagee(sub, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canDamagerHurtDamagee(EntityDamageByEntityEvent sub, boolean notify)
|
||||||
{
|
{
|
||||||
Entity damager = sub.getDamager();
|
Entity damager = sub.getDamager();
|
||||||
Entity damagee = sub.getEntity();
|
Entity damagee = sub.getEntity();
|
||||||
@ -140,9 +204,12 @@ public class FactionsEntityListener implements Listener
|
|||||||
if (defLocFaction.getFlag(FFlag.PVP) == false)
|
if (defLocFaction.getFlag(FFlag.PVP) == false)
|
||||||
{
|
{
|
||||||
if (damager instanceof Player)
|
if (damager instanceof Player)
|
||||||
|
{
|
||||||
|
if (notify)
|
||||||
{
|
{
|
||||||
FPlayer attacker = FPlayers.i.get((Player)damager);
|
FPlayer attacker = FPlayers.i.get((Player)damager);
|
||||||
attacker.msg("<i>PVP is disabled in %s.", defLocFaction.describeTo(attacker));
|
attacker.msg("<i>PVP is disabled in %s.", defLocFaction.describeTo(attacker));
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return defLocFaction.getFlag(FFlag.MONSTERS);
|
return defLocFaction.getFlag(FFlag.MONSTERS);
|
||||||
@ -158,7 +225,7 @@ public class FactionsEntityListener implements Listener
|
|||||||
|
|
||||||
if (attacker.hasLoginPvpDisabled())
|
if (attacker.hasLoginPvpDisabled())
|
||||||
{
|
{
|
||||||
attacker.msg("<i>You can't hurt other players for " + Conf.noPVPDamageToOthersForXSecondsAfterLogin + " seconds after logging in.");
|
if (notify) attacker.msg("<i>You can't hurt other players for " + Conf.noPVPDamageToOthersForXSecondsAfterLogin + " seconds after logging in.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +234,7 @@ public class FactionsEntityListener implements Listener
|
|||||||
// so we know from above that the defender isn't in a safezone... what about the attacker, sneaky dog that he might be?
|
// 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.getFlag(FFlag.PVP) == false)
|
if (locFaction.getFlag(FFlag.PVP) == false)
|
||||||
{
|
{
|
||||||
attacker.msg("<i>PVP is disabled in %s.", locFaction.describeTo(attacker));
|
if (notify) attacker.msg("<i>PVP is disabled in %s.", locFaction.describeTo(attacker));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +246,7 @@ public class FactionsEntityListener implements Listener
|
|||||||
|
|
||||||
if (attackFaction.isNone() && Conf.disablePVPForFactionlessPlayers)
|
if (attackFaction.isNone() && Conf.disablePVPForFactionlessPlayers)
|
||||||
{
|
{
|
||||||
attacker.msg("<i>You can't hurt other players until you join a faction.");
|
if (notify) attacker.msg("<i>You can't hurt other players until you join a faction.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (defendFaction.isNone())
|
else if (defendFaction.isNone())
|
||||||
@ -191,7 +258,7 @@ public class FactionsEntityListener implements Listener
|
|||||||
}
|
}
|
||||||
else if (Conf.disablePVPForFactionlessPlayers)
|
else if (Conf.disablePVPForFactionlessPlayers)
|
||||||
{
|
{
|
||||||
attacker.msg("<i>You can't hurt players who are not currently in a faction.");
|
if (notify) attacker.msg("<i>You can't hurt players who are not currently in a faction.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,29 +268,35 @@ public class FactionsEntityListener implements Listener
|
|||||||
// Check the relation
|
// Check the relation
|
||||||
if (relation.isAtLeast(Conf.friendlyFireFromRel) && defLocFaction.getFlag(FFlag.FRIENDLYFIRE) == false)
|
if (relation.isAtLeast(Conf.friendlyFireFromRel) && defLocFaction.getFlag(FFlag.FRIENDLYFIRE) == false)
|
||||||
{
|
{
|
||||||
attacker.msg("<i>You can't hurt %s<i>.", relation.getDescPlayerMany());
|
if (notify) attacker.msg("<i>You can't hurt %s<i>.", relation.getDescPlayerMany());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can not hurt neutrals in their own territory.
|
// You can not hurt neutrals in their own territory.
|
||||||
boolean ownTerritory = defender.isInOwnTerritory();
|
boolean ownTerritory = defender.isInOwnTerritory();
|
||||||
if (defender.hasFaction() && ownTerritory && relation == Rel.NEUTRAL)
|
if (defender.hasFaction() && ownTerritory && relation == Rel.NEUTRAL)
|
||||||
|
{
|
||||||
|
if (notify)
|
||||||
{
|
{
|
||||||
attacker.msg("<i>You can't hurt %s<i> in their own territory unless you declare them as an enemy.", defender.describeTo(attacker));
|
attacker.msg("<i>You can't hurt %s<i> in their own territory unless you declare them as an enemy.", defender.describeTo(attacker));
|
||||||
defender.msg("%s<i> tried to hurt you.", attacker.describeTo(defender, true));
|
defender.msg("%s<i> tried to hurt you.", attacker.describeTo(defender, true));
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Damage will be dealt. However check if the damage should be reduced.
|
// Damage will be dealt. However check if the damage should be reduced.
|
||||||
if (ownTerritory && Conf.territoryShieldFactor > 0)
|
if (damage > 0.0 && ownTerritory && Conf.territoryShieldFactor > 0)
|
||||||
{
|
{
|
||||||
int newDamage = (int)Math.ceil(damage * (1D - Conf.territoryShieldFactor));
|
int newDamage = (int)Math.ceil(damage * (1D - Conf.territoryShieldFactor));
|
||||||
sub.setDamage(newDamage);
|
sub.setDamage(newDamage);
|
||||||
|
|
||||||
// Send message
|
// Send message
|
||||||
|
if (notify)
|
||||||
|
{
|
||||||
String perc = MessageFormat.format("{0,number,#%}", (Conf.territoryShieldFactor)); // TODO does this display correctly??
|
String perc = MessageFormat.format("{0,number,#%}", (Conf.territoryShieldFactor)); // TODO does this display correctly??
|
||||||
defender.msg("<i>Enemy damage reduced by <rose>%s<i>.", perc);
|
defender.msg("<i>Enemy damage reduced by <rose>%s<i>.", perc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user