Refactor EntityDamageEvents. Adds BUKKIT-1944 & BUKKIT-3684

This commit is contained in:
feildmaster 2013-04-09 22:25:06 -05:00
parent 535a85a5b0
commit 77d1524b3d
8 changed files with 116 additions and 155 deletions

View File

@ -24,7 +24,6 @@ import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.event.entity.EntityCombustEvent; import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDamageByBlockEvent; import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
@ -325,19 +324,7 @@ public abstract class Entity {
} }
} else { } else {
if (this.fireTicks % 20 == 0) { if (this.fireTicks % 20 == 0) {
// CraftBukkit start - TODO: this event spams! this.damageEntity(DamageSource.BURN, 1);
if (this instanceof EntityLiving) {
EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.FIRE_TICK, 1);
this.world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
event.getEntity().setLastDamageCause(event);
this.damageEntity(DamageSource.BURN, event.getDamage());
}
} else {
this.damageEntity(DamageSource.BURN, 1);
}
// CraftBukkit end
} }
--this.fireTicks; --this.fireTicks;
@ -790,20 +777,6 @@ public abstract class Entity {
protected void burn(int i) { protected void burn(int i) {
if (!this.fireProof) { if (!this.fireProof) {
// CraftBukkit start
if (this instanceof EntityLiving) {
EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.FIRE, i);
this.world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
i = event.getDamage();
event.getEntity().setLastDamageCause(event);
}
// CraftBukkit end
this.damageEntity(DamageSource.FIRE, i); this.damageEntity(DamageSource.FIRE, i);
} }
} }
@ -1594,14 +1567,11 @@ public abstract class Entity {
} }
} }
EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(stormBukkitEntity, thisBukkitEntity, EntityDamageEvent.DamageCause.LIGHTNING, 5); EntityDamageEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDamageEvent(entitylightning, this, EntityDamageEvent.DamageCause.LIGHTNING, 5);
pluginManager.callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
} }
thisBukkitEntity.setLastDamageCause(event);
this.burn(event.getDamage()); this.burn(event.getDamage());
// CraftBukkit end // CraftBukkit end

View File

@ -7,7 +7,6 @@ import java.util.List;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.util.BlockStateListPopulator; import org.bukkit.craftbukkit.util.BlockStateListPopulator;
import org.bukkit.event.entity.EntityCreatePortalEvent; import org.bukkit.event.entity.EntityCreatePortalEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -363,20 +362,7 @@ public class EntityEnderDragon extends EntityLiving implements IComplex {
Entity entity = (Entity) list.get(i); Entity entity = (Entity) list.get(i);
if (entity instanceof EntityLiving) { if (entity instanceof EntityLiving) {
// CraftBukkit start - Throw damage events when the dragon attacks entity.damageEntity(DamageSource.mobAttack(this), 10);
// The EntityHuman case is handled in EntityHuman, so don't throw it here
if (!(entity instanceof EntityHuman)) {
EntityDamageByEntityEvent damageEvent = new EntityDamageByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), org.bukkit.event.entity.EntityDamageEvent.DamageCause.ENTITY_ATTACK, 10);
Bukkit.getPluginManager().callEvent(damageEvent);
if (!damageEvent.isCancelled()) {
entity.getBukkitEntity().setLastDamageCause(damageEvent);
entity.damageEntity(DamageSource.mobAttack(this), damageEvent.getDamage());
}
} else {
entity.damageEntity(DamageSource.mobAttack(this), 10);
}
// CraftBukkit end
} }
} }
} }

View File

@ -322,17 +322,9 @@ public abstract class EntityLiving extends Entity {
this.aR(); this.aR();
} }
// CraftBukkit start if (this.isAlive() && this.inBlock()) {
if (this.isAlive() && this.inBlock() && !(this instanceof EntityEnderDragon)) { // EnderDragon's don't suffocate. this.damageEntity(DamageSource.STUCK, 1);
EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.SUFFOCATION, 1);
this.world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
event.getEntity().setLastDamageCause(event);
this.damageEntity(DamageSource.STUCK, event.getDamage());
}
} }
// CraftBukkit end
if (this.isFireproof() || this.world.isStatic) { if (this.isFireproof() || this.world.isStatic) {
this.extinguish(); this.extinguish();
@ -353,15 +345,7 @@ public abstract class EntityLiving extends Entity {
this.world.addParticle("bubble", this.locX + (double) f, this.locY + (double) f1, this.locZ + (double) f2, this.motX, this.motY, this.motZ); this.world.addParticle("bubble", this.locX + (double) f, this.locY + (double) f1, this.locZ + (double) f2, this.motX, this.motY, this.motZ);
} }
// CraftBukkit start this.damageEntity(DamageSource.DROWN, 2);
EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.DROWNING, 2);
this.world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled() && event.getDamage() != 0) {
event.getEntity().setLastDamageCause(event);
this.damageEntity(DamageSource.DROWN, event.getDamage());
}
// CraftBukkit end
} }
this.extinguish(); this.extinguish();
@ -690,8 +674,8 @@ public abstract class EntityLiving extends Entity {
boolean flag = true; boolean flag = true;
// CraftBukkit start // CraftBukkit start
if (damagesource instanceof EntityDamageSource) { EntityDamageEvent event = CraftEventFactory.handleEntityDamageEvent(this, damagesource, i);
EntityDamageEvent event = CraftEventFactory.handleEntityDamageEvent(this, damagesource, i); if (event != null) {
if (event.isCancelled()) { if (event.isCancelled()) {
return false; return false;
} }
@ -970,25 +954,26 @@ public abstract class EntityLiving extends Entity {
super.a(f); super.a(f);
int i = MathHelper.f(f - 3.0F); int i = MathHelper.f(f - 3.0F);
// CraftBukkit start
if (i > 0) { if (i > 0) {
// CraftBukkit start EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, this, EntityDamageEvent.DamageCause.FALL, i);
EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.FALL, i); if (!event.isCancelled()) {
this.world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled() && event.getDamage() != 0) {
i = event.getDamage(); i = event.getDamage();
if (i > 0) {
if (i > 4) { this.getBukkitEntity().setLastDamageCause(event);
this.makeSound("damage.fallbig", 1.0F, 1.0F);
} else {
this.makeSound("damage.fallsmall", 1.0F, 1.0F);
} }
this.getBukkitEntity().setLastDamageCause(event);
this.damageEntity(DamageSource.FALL, i);
} }
// CraftBukkit end }
// CraftBukkit end
if (i > 0) {
if (i > 4) {
this.makeSound("damage.fallbig", 1.0F, 1.0F);
} else {
this.makeSound("damage.fallsmall", 1.0F, 1.0F);
}
this.damageEntity(DamageSource.FALL, i);
int j = this.world.getTypeId(MathHelper.floor(this.locX), MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height), MathHelper.floor(this.locZ)); int j = this.world.getTypeId(MathHelper.floor(this.locX), MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height), MathHelper.floor(this.locZ));
if (j > 0) { if (j > 0) {
@ -1633,17 +1618,7 @@ public abstract class EntityLiving extends Entity {
} }
protected void B() { protected void B() {
// CraftBukkit start this.damageEntity(DamageSource.OUT_OF_WORLD, 4);
EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(null, this.getBukkitEntity(), EntityDamageEvent.DamageCause.VOID, 4);
this.world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled() || event.getDamage() == 0) {
return;
}
event.getEntity().setLastDamageCause(event);
this.damageEntity(DamageSource.OUT_OF_WORLD, event.getDamage());
// CraftBukkit end
} }
public Vec3D Y() { public Vec3D Y() {

View File

@ -1,8 +1,8 @@
package net.minecraft.server; package net.minecraft.server;
// CraftBukkit start // CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.block.EntityBlockFormEvent; import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.entity.EntityDamageEvent;
// CraftBukkit end // CraftBukkit end
public class EntitySnowman extends EntityGolem implements IRangedEntity { public class EntitySnowman extends EntityGolem implements IRangedEntity {
@ -30,30 +30,14 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity {
public void c() { public void c() {
super.c(); super.c();
if (this.F()) { if (this.F()) {
// CraftBukkit start this.damageEntity(DamageSource.DROWN, 1);
EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.DROWNING, 1);
this.world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
event.getEntity().setLastDamageCause(event);
this.damageEntity(DamageSource.DROWN, event.getDamage());
}
// CraftBukkit end
} }
int i = MathHelper.floor(this.locX); int i = MathHelper.floor(this.locX);
int j = MathHelper.floor(this.locZ); int j = MathHelper.floor(this.locZ);
if (this.world.getBiome(i, j).j() > 1.0F) { if (this.world.getBiome(i, j).j() > 1.0F) {
// CraftBukkit start this.damageEntity(CraftEventFactory.MELTING, 1); // CraftBukkit - DamageSource.BURN -> CraftEventFactory.MELTING
EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.MELTING, 1);
this.world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
event.getEntity().setLastDamageCause(event);
this.damageEntity(DamageSource.BURN, event.getDamage());
}
// CraftBukkit end
} }
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
@ -90,7 +74,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity {
loot.add(new org.bukkit.inventory.ItemStack(Item.SNOW_BALL.id, j)); loot.add(new org.bukkit.inventory.ItemStack(Item.SNOW_BALL.id, j));
} }
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, loot); CraftEventFactory.callEntityDeathEvent(this, loot);
// CraftBukkit end // CraftBukkit end
} }

View File

@ -55,15 +55,7 @@ public class FoodMetaData {
++this.foodTickTimer; ++this.foodTickTimer;
if (this.foodTickTimer >= 80) { if (this.foodTickTimer >= 80) {
if (entityhuman.getHealth() > 10 || i >= 3 || entityhuman.getHealth() > 1 && i >= 2) { if (entityhuman.getHealth() > 10 || i >= 3 || entityhuman.getHealth() > 1 && i >= 2) {
// CraftBukkit start entityhuman.damageEntity(DamageSource.STARVE, 1);
EntityDamageEvent event = new EntityDamageEvent(entityhuman.getBukkitEntity(), EntityDamageEvent.DamageCause.STARVATION, 1);
entityhuman.world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
event.getEntity().setLastDamageCause(event);
entityhuman.damageEntity(DamageSource.STARVE, event.getDamage());
}
// CraftBukkit end
} }
this.foodTickTimer = 0; this.foodTickTimer = 0;

View File

@ -2,7 +2,6 @@ package net.minecraft.server;
// CraftBukkit start // CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
// CraftBukkit end // CraftBukkit end
@ -80,33 +79,15 @@ public class MobEffectList {
} }
} else if (this.id == POISON.id) { } else if (this.id == POISON.id) {
if (entityliving.getHealth() > 1) { if (entityliving.getHealth() > 1) {
// CraftBukkit start entityliving.damageEntity(CraftEventFactory.POISON, 1); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON
EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, entityliving, EntityDamageEvent.DamageCause.POISON, 1);
if (!event.isCancelled() && event.getDamage() > 0) {
entityliving.damageEntity(DamageSource.MAGIC, event.getDamage());
}
// CraftBukkit end
} }
} else if (this.id == WITHER.id) { } else if (this.id == WITHER.id) {
// CraftBukkit start entityliving.damageEntity(DamageSource.WITHER, 1);
EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, entityliving, EntityDamageEvent.DamageCause.WITHER, 1);
if (!event.isCancelled() && event.getDamage() > 0) {
entityliving.damageEntity(DamageSource.WITHER, event.getDamage());
}
// CraftBukkit end
} else if (this.id == HUNGER.id && entityliving instanceof EntityHuman) { } else if (this.id == HUNGER.id && entityliving instanceof EntityHuman) {
((EntityHuman) entityliving).j(0.025F * (float) (i + 1)); ((EntityHuman) entityliving).j(0.025F * (float) (i + 1));
} else if ((this.id != HEAL.id || entityliving.bD()) && (this.id != HARM.id || !entityliving.bD())) { } else if ((this.id != HEAL.id || entityliving.bD()) && (this.id != HARM.id || !entityliving.bD())) {
if (this.id == HARM.id && !entityliving.bD() || this.id == HEAL.id && entityliving.bD()) { if (this.id == HARM.id && !entityliving.bD() || this.id == HEAL.id && entityliving.bD()) {
// CraftBukkit start entityliving.damageEntity(DamageSource.MAGIC, 6 << i);
EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, entityliving, EntityDamageEvent.DamageCause.MAGIC, 6 << i);
if (!event.isCancelled() && event.getDamage() > 0) {
entityliving.damageEntity(DamageSource.MAGIC, event.getDamage());
}
// CraftBukkit end
} }
} else { } else {
entityliving.heal(6 << i, RegainReason.MAGIC); // CraftBukkit entityliving.heal(6 << i, RegainReason.MAGIC); // CraftBukkit

View File

@ -39,6 +39,7 @@ import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting;
import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.util.CraftDamageSource;
import org.bukkit.entity.AnimalTamer; import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
import org.bukkit.entity.Creeper; import org.bukkit.entity.Creeper;
@ -64,6 +65,9 @@ import org.bukkit.event.server.ServerListPingEvent;
import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.InventoryView;
public class CraftEventFactory { public class CraftEventFactory {
public static final DamageSource MELTING = CraftDamageSource.copyOf(DamageSource.BURN);
public static final DamageSource POISON = CraftDamageSource.copyOf(DamageSource.MAGIC);
// helper methods // helper methods
private static boolean canBuild(CraftWorld world, Player player, int x, int z) { private static boolean canBuild(CraftWorld world, Player player, int x, int z) {
WorldServer worldServer = world.getHandle(); WorldServer worldServer = world.getHandle();
@ -379,21 +383,58 @@ public class CraftEventFactory {
} }
public static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, int damage) { public static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, int damage) {
Entity damager = source.getEntity(); if (source instanceof EntityDamageSource) {
DamageCause cause = DamageCause.ENTITY_ATTACK; Entity damager = source.getEntity();
DamageCause cause = DamageCause.ENTITY_ATTACK;
if (source instanceof EntityDamageSourceIndirect) { if (source instanceof EntityDamageSourceIndirect) {
damager = ((EntityDamageSourceIndirect) source).getProximateDamageSource(); damager = ((EntityDamageSourceIndirect) source).getProximateDamageSource();
if (damager.getBukkitEntity() instanceof ThrownPotion) { if (damager.getBukkitEntity() instanceof ThrownPotion) {
cause = DamageCause.MAGIC; cause = DamageCause.MAGIC;
} else if (damager.getBukkitEntity() instanceof Projectile) { } else if (damager.getBukkitEntity() instanceof Projectile) {
cause = DamageCause.PROJECTILE; cause = DamageCause.PROJECTILE;
}
} else if ("thorns".equals(source.translationIndex)) {
cause = DamageCause.THORNS;
} }
} else if ("thorns".equals(source.translationIndex)) {
cause = DamageCause.THORNS; return callEntityDamageEvent(damager, entity, cause, damage);
} else if (source == DamageSource.OUT_OF_WORLD) {
EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, damage));
if (!event.isCancelled()) {
event.getEntity().setLastDamageCause(event);
}
return event;
} }
return callEntityDamageEvent(damager, entity, cause, damage); DamageCause cause = null;
if (source == DamageSource.FIRE) {
cause = DamageCause.FIRE;
} else if (source == DamageSource.STARVE) {
cause = DamageCause.STARVATION;
} else if (source == DamageSource.WITHER) {
cause = DamageCause.WITHER;
} else if (source == DamageSource.STUCK) {
cause = DamageCause.SUFFOCATION;
} else if (source == DamageSource.DROWN) {
cause = DamageCause.DROWNING;
} else if (source == DamageSource.BURN) {
cause = DamageCause.FIRE_TICK;
} else if (source == MELTING) {
cause = DamageCause.MELTING;
} else if (source == POISON) {
cause = DamageCause.POISON;
} else if (source == DamageSource.MAGIC) {
cause = DamageCause.MAGIC;
}
if (cause != null) {
return callEntityDamageEvent(null, entity, cause, damage);
}
// If an event was called earlier, we return null.
// EG: Cactus, Lava, EntityEnderPearl "fall", FallingSand
return null;
} }
// Non-Living Entities such as EntityEnderCrystal need to call this // Non-Living Entities such as EntityEnderCrystal need to call this
@ -401,6 +442,7 @@ public class CraftEventFactory {
if (!(source instanceof EntityDamageSource)) { if (!(source instanceof EntityDamageSource)) {
return false; return false;
} }
// We don't need to check for null, since EntityDamageSource will always return an event
EntityDamageEvent event = handleEntityDamageEvent(entity, source, damage); EntityDamageEvent event = handleEntityDamageEvent(entity, source, damage);
return event.isCancelled() || event.getDamage() == 0; return event.isCancelled() || event.getDamage() == 0;
} }

View File

@ -0,0 +1,31 @@
package org.bukkit.craftbukkit.util;
import net.minecraft.server.DamageSource;
// Util class to create custom DamageSources.
public final class CraftDamageSource extends DamageSource {
public static DamageSource copyOf(final DamageSource original) {
CraftDamageSource newSource = new CraftDamageSource(original.translationIndex);
// Check ignoresArmor
if (original.ignoresArmor()) {
newSource.j();
}
// Check magic
if (original.q()) {
newSource.r();
}
// Check fire
if (original.c()) {
newSource.l();
}
return newSource;
}
private CraftDamageSource(String identifier) {
super(identifier);
}
}