Fixed EntityDamageByEntityEvent to call for every attackable entity. Fixes BUKKIT-1129, Fixes BUKKIT-1054 and Fixes BUKKIT-147.

This commit is contained in:
feildmaster 2012-03-12 17:55:02 -05:00 committed by EvilSeph
parent c625d00351
commit 4503167283
11 changed files with 72 additions and 185 deletions

View File

@ -221,8 +221,8 @@ public class EntityArrow extends Entity {
}
// CraftBukkit end
}
// CraftBukkit - entity.damageEntity -> event function
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleProjectileEvent(projectile, entity, damagesource, l)) {
if (movingobjectposition.entity.damageEntity(damagesource, l)) {
if (movingobjectposition.entity instanceof EntityLiving) {
++((EntityLiving) movingobjectposition.entity).aI;
if (this.n > 0) {

View File

@ -23,13 +23,11 @@ public class EntityEgg extends EntityProjectile {
}
protected void a(MovingObjectPosition movingobjectposition) {
// CraftBukkit start
if (movingobjectposition.entity != null) {
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleProjectileEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), movingobjectposition.entity, DamageSource.projectile(this, this.shooter), 0)) {
; // Original code does nothing *yet*
}
if (movingobjectposition.entity != null && movingobjectposition.entity.damageEntity(DamageSource.projectile(this, this.shooter), 0)) {
;
}
// CraftBukkit start
boolean hatching = !this.world.isStatic && this.random.nextInt(8) == 0;
int numHatching = (this.random.nextInt(32) == 0) ? 4 : 1;
if (!hatching) {

View File

@ -50,6 +50,11 @@ public class EntityEnderCrystal extends Entity {
this.b = 0;
if (this.b <= 0) {
if (!this.world.isStatic) {
// CraftBukkit start - All non-living entities need this
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, i)) {
return false;
}
// CraftBukkit end
this.die();
this.world.explode(this, this.locX, this.locY, this.locZ, 6.0F); // CraftBukkit - (Entity) null -> this.
} else {

View File

@ -5,7 +5,6 @@ import java.util.List;
// CraftBukkit start
import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.entity.Explosive;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
// CraftBukkit end
@ -137,6 +136,12 @@ public class EntityFireball extends Entity {
if (movingobjectposition != null) {
this.a(movingobjectposition);
// CraftBukkit start
if (this.dead) {
ProjectileHitEvent phe = new ProjectileHitEvent((org.bukkit.entity.Projectile) this.getBukkitEntity());
this.world.getServer().getPluginManager().callEvent(phe);
}
// CraftBukkit end
}
this.locX += this.motX;
@ -189,30 +194,18 @@ public class EntityFireball extends Entity {
protected void a(MovingObjectPosition movingobjectposition) {
if (!this.world.isStatic) {
// CraftBukkit start
Projectile projectile = (Projectile) this.getBukkitEntity();
ProjectileHitEvent phe = new ProjectileHitEvent(projectile);
this.world.getServer().getPluginManager().callEvent(phe);
// CraftBukkit end
if (!this.world.isStatic) {
// CraftBukkit start
if (movingobjectposition.entity != null) {
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleProjectileEvent(projectile, movingobjectposition.entity, DamageSource.projectile(this, this.shooter), 0)) {
;
}
}
ExplosionPrimeEvent event = new ExplosionPrimeEvent((Explosive) CraftEntity.getEntity(this.world.getServer(), this));
this.world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
// give 'this' instead of (Entity) null so we know what causes the damage
this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire());
}
// CraftBukkit end
if (movingobjectposition.entity != null && movingobjectposition.entity.damageEntity(DamageSource.fireball(this, this.shooter), 4)) {
;
}
// CraftBukkit start
ExplosionPrimeEvent event = new ExplosionPrimeEvent((Explosive) CraftEntity.getEntity(this.world.getServer(), this));
this.world.getServer().getPluginManager().callEvent(event);
// this.world.createExplosion((Entity) null, this.locX, this.locY, this.locZ, 1.0F, true); // CraftBukkit
if (!event.isCancelled()) {
// give 'this' instead of (Entity) null so we know what causes the damage
this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire());
}
// CraftBukkit end
this.die();
}
}

View File

@ -184,8 +184,7 @@ public class EntityFishingHook extends Entity {
if (movingobjectposition != null) {
if (movingobjectposition.entity != null) {
// CraftBukkit - entity.damageEntity -> event function
if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleProjectileEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), entity, DamageSource.projectile(this, this.owner), 0)) {
if (movingobjectposition.entity.damageEntity(DamageSource.projectile(this, this.owner), 0)) {
this.hooked = movingobjectposition.entity;
}
} else {

View File

@ -9,15 +9,10 @@ import org.bukkit.craftbukkit.entity.CraftItem;
import org.bukkit.craftbukkit.TrigMath;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerBedLeaveEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
// CraftBukkit end
public abstract class EntityHuman extends EntityLiving {
@ -309,7 +304,7 @@ public abstract class EntityHuman extends EntityLiving {
if (this.world.difficulty == 0 && this.getHealth() < this.getMaxHealth() && this.ticksLived % 20 * 12 == 0) {
// CraftBukkit - added regain reason of "REGEN" for filtering purposes.
this.heal(1, RegainReason.REGEN);
this.heal(1, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN);
}
this.inventory.i();
@ -593,27 +588,6 @@ public abstract class EntityHuman extends EntityLiving {
}
if (entity1 instanceof EntityLiving) {
// CraftBukkit start - this is here instead of EntityMonster because EntityLiving(s) that aren't monsters
// also damage the player in this way. For example, EntitySlime.
// We handle projectiles in their individual classes!
boolean isProjectile = damagesource instanceof EntityDamageSourceIndirect && ((EntityDamageSourceIndirect) damagesource).getProximateDamageSource().getBukkitEntity() instanceof Projectile;
if (!isProjectile) {
org.bukkit.entity.Entity damager = ((Entity) entity1).getBukkitEntity();
org.bukkit.entity.Entity damagee = this.getBukkitEntity();
EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK, i);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled() || event.getDamage() == 0) {
return false;
}
i = event.getDamage();
}
// CraftBukkit end
this.a((EntityLiving) entity1, false);
}
@ -771,22 +745,6 @@ public abstract class EntityHuman extends EntityLiving {
i += this.random.nextInt(i / 2 + 2);
}
// CraftBukkit start - Don't call the event when the entity is human since it will be called with damageEntity
if ((entity instanceof EntityLiving || entity instanceof EntityComplexPart || entity instanceof EntityEnderCrystal) && !(entity instanceof EntityHuman)) {
org.bukkit.entity.Entity damager = this.getBukkitEntity();
org.bukkit.entity.Entity damagee = (entity == null) ? null : entity.getBukkitEntity();
EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK, i);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled() || event.getDamage() == 0) {
return;
}
i = event.getDamage();
}
// CraftBukkit end
i += k;
boolean flag1 = entity.damageEntity(DamageSource.playerAttack(this), i);

View File

@ -602,6 +602,16 @@ public abstract class EntityLiving extends Entity {
this.aE = 1.5F;
boolean flag = true;
// CraftBukkit start
if (damagesource instanceof EntityDamageSource) {
org.bukkit.event.entity.EntityDamageEvent event = CraftEventFactory.handleEntityDamageEvent(this, damagesource, i);
if (event.isCancelled()) {
return false;
}
i = event.getDamage();
}
// CraftBukkit end
if ((float) this.noDamageTicks > (float) this.maxNoDamageTicks / 2.0F) {
if (i <= this.lastDamage) {
return false;
@ -829,7 +839,6 @@ public abstract class EntityLiving extends Entity {
this.damageEntity(DamageSource.FALL, i);
}
// CraftBukkit end
int j = this.world.getTypeId(MathHelper.floor(this.locX), MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height), MathHelper.floor(this.locZ));

View File

@ -1,11 +1,6 @@
package net.minecraft.server;
// CraftBukkit start
import org.bukkit.Bukkit;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityTargetEvent;
// CraftBukkit end
import org.bukkit.event.entity.EntityTargetEvent; // CraftBukkit
public abstract class EntityMonster extends EntityCreature implements IMonster {
@ -82,24 +77,6 @@ public abstract class EntityMonster extends EntityCreature implements IMonster {
i -= 2 << this.getEffect(MobEffectList.WEAKNESS).getAmplifier();
}
// CraftBukkit start - this is still duplicated here and EntityHuman because it's possible for lastDamage EntityMonster
// to damage another EntityMonster, and we want to catch those events.
// This does not fire events for slime attacks, av they're not lastDamage EntityMonster.
if (entity instanceof EntityLiving && !(entity instanceof EntityHuman)) {
org.bukkit.entity.Entity damagee = (entity == null) ? null : entity.getBukkitEntity();
EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(this.getBukkitEntity(), damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK, this.damage);
Bukkit.getPluginManager().callEvent(event);
i = event.getDamage();
if (!event.isCancelled()) {
return entity.damageEntity(DamageSource.mobAttack(this), i);
}
return false;
}
// CraftBukkit end
return entity.damageEntity(DamageSource.mobAttack(this), i);
}

View File

@ -1,12 +1,6 @@
package net.minecraft.server;
// CraftBukkit start
import org.bukkit.Bukkit;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.plugin.PluginManager;
// CraftBukkit end
import org.bukkit.event.entity.EntityCombustByEntityEvent; // CraftBukkit
public class EntitySmallFireball extends EntityFireball {
@ -27,26 +21,14 @@ public class EntitySmallFireball extends EntityFireball {
protected void a(MovingObjectPosition movingobjectposition) {
if (!this.world.isStatic) {
// CraftBukkit start - projectile hit event
Projectile projectile = (Projectile) this.getBukkitEntity();
ProjectileHitEvent phe = new ProjectileHitEvent(projectile);
final PluginManager pluginManager = Bukkit.getPluginManager();
pluginManager.callEvent(phe);
// CraftBukkit end
final Entity movingEntity = movingobjectposition.entity;
if (movingEntity != null) {
// CraftBukkit start - entity damage by entity event + combust event
if (!movingEntity.isFireproof()) { // check if not fireproof
org.bukkit.entity.Entity damagee = movingEntity.getBukkitEntity();
if (movingobjectposition.entity != null) {
if (!movingobjectposition.entity.isFireproof() && movingobjectposition.entity.damageEntity(DamageSource.fireball(this, this.shooter), 5)) {
// CraftBukkit start - entity damage by entity event + combust event
EntityCombustByEntityEvent event = new EntityCombustByEntityEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), movingobjectposition.entity.getBukkitEntity(), 5);
movingobjectposition.entity.world.getServer().getPluginManager().callEvent(event);
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleProjectileEvent(projectile, movingobjectposition.entity, DamageSource.projectile(this, this.shooter), 0)) {
// if the fireball 'sticks', ignite the target
EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(projectile, damagee, 5);
pluginManager.callEvent(combustEvent);
if (!combustEvent.isCancelled()) {
movingEntity.setOnFire(combustEvent.getDuration());
}
if (!event.isCancelled()) {
movingobjectposition.entity.setOnFire(event.getDuration());
}
// CraftBukkit end
}

View File

@ -1,38 +0,0 @@
package net.minecraft.server;
public class EntitySnowball extends EntityProjectile {
public EntitySnowball(World world) {
super(world);
}
public EntitySnowball(World world, EntityLiving entityliving) {
super(world, entityliving);
}
public EntitySnowball(World world, double d0, double d1, double d2) {
super(world, d0, d1, d2);
}
protected void a(MovingObjectPosition movingobjectposition) {
if (movingobjectposition.entity != null) {
int b0 = 0; // CraftBukkit - byte -> int
if (movingobjectposition.entity instanceof EntityBlaze) {
b0 = 3;
}
// CraftBukkit - entity.damageEntity -> event function
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleProjectileEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), movingobjectposition.entity, DamageSource.projectile(this, this.shooter), b0)) {
;
}
}
for (int i = 0; i < 8; ++i) {
this.world.a("snowballpoof", this.locX, this.locY, this.locZ, 0.0D, 0.0D, 0.0D);
}
if (!this.world.isStatic) {
this.die();
}
}
}

View File

@ -9,8 +9,8 @@ import net.minecraft.server.Container;
import net.minecraft.server.DamageSource;
import net.minecraft.server.Entity;
import net.minecraft.server.EntityArrow;
import net.minecraft.server.EntityComplexPart;
import net.minecraft.server.EntityEnderCrystal;
import net.minecraft.server.EntityDamageSource;
import net.minecraft.server.EntityDamageSourceIndirect;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.EntityItem;
import net.minecraft.server.EntityLiving;
@ -348,7 +348,7 @@ public class CraftEventFactory {
/**
* EntityDamage(ByEntityEvent)
*/
public static EntityDamageEvent callEntityDamageEvent(Entity damager, EntityLiving damagee, DamageCause cause, int damage) {
public static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, int damage) {
EntityDamageEvent event;
if (damager != null) {
event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, damage);
@ -360,6 +360,28 @@ public class CraftEventFactory {
return event;
}
public static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, int damage) {
Entity damager = source.getEntity();
EntityDamageEvent.DamageCause cause = EntityDamageEvent.DamageCause.ENTITY_ATTACK;
if (source instanceof EntityDamageSourceIndirect) {
damager = ((EntityDamageSourceIndirect) source).getProximateDamageSource();
if (damager.getBukkitEntity() instanceof Projectile) {
cause = EntityDamageEvent.DamageCause.PROJECTILE;
} // Else, magic..?
}
return callEntityDamageEvent(damager, entity, cause, damage);
}
// Non-Living Entities such as EntityEnderCrystal need to call this
public static boolean handleNonLivingEntityDamageEvent(Entity entity, DamageSource source, int damage) {
if (!(source instanceof EntityDamageSource)) {
return false;
}
EntityDamageEvent event = handleEntityDamageEvent(entity, source, damage);
return event.isCancelled() || event.getDamage() == 0;
}
public static PlayerLevelChangeEvent callPlayerLevelChangeEvent(Player player, int oldLevel, int newLevel) {
PlayerLevelChangeEvent event = new PlayerLevelChangeEvent(player, oldLevel, newLevel);
Bukkit.getPluginManager().callEvent(event);
@ -373,24 +395,6 @@ public class CraftEventFactory {
return event;
}
public static boolean handleProjectileEvent(Projectile projectile, Entity target, DamageSource damagesource, int damage) {
if (target instanceof EntityLiving || target instanceof EntityComplexPart || target instanceof EntityEnderCrystal) {
org.bukkit.entity.Entity damagee = target.getBukkitEntity();
EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(projectile, damagee, EntityDamageEvent.DamageCause.PROJECTILE, damage);
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
return target.damageEntity(damagesource, event.getDamage());
}
} else {
// Other entities have their events (if any) handled in damageEntity
return target.damageEntity(damagesource, damage);
}
return !projectile.doesBounce();
}
public static void handleBlockGrowEvent(World world, int x, int y, int z, int type, int data) {
Block block = world.getWorld().getBlockAt(x, y, z);
CraftBlockState state = (CraftBlockState) block.getState();