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

View File

@ -7,7 +7,6 @@ import java.util.List;
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.util.BlockStateListPopulator;
import org.bukkit.event.entity.EntityCreatePortalEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.Bukkit;
@ -363,20 +362,7 @@ public class EntityEnderDragon extends EntityLiving implements IComplex {
Entity entity = (Entity) list.get(i);
if (entity instanceof EntityLiving) {
// CraftBukkit start - Throw damage events when the dragon attacks
// 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
entity.damageEntity(DamageSource.mobAttack(this), 10);
}
}
}

View File

@ -322,17 +322,9 @@ public abstract class EntityLiving extends Entity {
this.aR();
}
// CraftBukkit start
if (this.isAlive() && this.inBlock() && !(this instanceof EntityEnderDragon)) { // EnderDragon's don't suffocate.
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());
}
if (this.isAlive() && this.inBlock()) {
this.damageEntity(DamageSource.STUCK, 1);
}
// CraftBukkit end
if (this.isFireproof() || this.world.isStatic) {
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);
}
// CraftBukkit start
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.damageEntity(DamageSource.DROWN, 2);
}
this.extinguish();
@ -690,8 +674,8 @@ public abstract class EntityLiving extends Entity {
boolean flag = true;
// 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()) {
return false;
}
@ -970,25 +954,26 @@ public abstract class EntityLiving extends Entity {
super.a(f);
int i = MathHelper.f(f - 3.0F);
// CraftBukkit start
if (i > 0) {
// CraftBukkit start
EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), EntityDamageEvent.DamageCause.FALL, i);
this.world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled() && event.getDamage() != 0) {
EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, this, EntityDamageEvent.DamageCause.FALL, i);
if (!event.isCancelled()) {
i = event.getDamage();
if (i > 4) {
this.makeSound("damage.fallbig", 1.0F, 1.0F);
} else {
this.makeSound("damage.fallsmall", 1.0F, 1.0F);
if (i > 0) {
this.getBukkitEntity().setLastDamageCause(event);
}
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));
if (j > 0) {
@ -1633,17 +1618,7 @@ public abstract class EntityLiving extends Entity {
}
protected void B() {
// CraftBukkit start
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
this.damageEntity(DamageSource.OUT_OF_WORLD, 4);
}
public Vec3D Y() {

View File

@ -1,8 +1,8 @@
package net.minecraft.server;
// CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.entity.EntityDamageEvent;
// CraftBukkit end
public class EntitySnowman extends EntityGolem implements IRangedEntity {
@ -30,30 +30,14 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity {
public void c() {
super.c();
if (this.F()) {
// CraftBukkit start
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
this.damageEntity(DamageSource.DROWN, 1);
}
int i = MathHelper.floor(this.locX);
int j = MathHelper.floor(this.locZ);
if (this.world.getBiome(i, j).j() > 1.0F) {
// CraftBukkit start
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
this.damageEntity(CraftEventFactory.MELTING, 1); // CraftBukkit - DamageSource.BURN -> CraftEventFactory.MELTING
}
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));
}
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, loot);
CraftEventFactory.callEntityDeathEvent(this, loot);
// CraftBukkit end
}

View File

@ -55,15 +55,7 @@ public class FoodMetaData {
++this.foodTickTimer;
if (this.foodTickTimer >= 80) {
if (entityhuman.getHealth() > 10 || i >= 3 || entityhuman.getHealth() > 1 && i >= 2) {
// CraftBukkit start
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
entityhuman.damageEntity(DamageSource.STARVE, 1);
}
this.foodTickTimer = 0;

View File

@ -2,7 +2,6 @@ package net.minecraft.server;
// CraftBukkit start
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
// CraftBukkit end
@ -80,33 +79,15 @@ public class MobEffectList {
}
} else if (this.id == POISON.id) {
if (entityliving.getHealth() > 1) {
// CraftBukkit start
EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, entityliving, EntityDamageEvent.DamageCause.POISON, 1);
if (!event.isCancelled() && event.getDamage() > 0) {
entityliving.damageEntity(DamageSource.MAGIC, event.getDamage());
}
// CraftBukkit end
entityliving.damageEntity(CraftEventFactory.POISON, 1); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON
}
} else if (this.id == WITHER.id) {
// CraftBukkit start
EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, entityliving, EntityDamageEvent.DamageCause.WITHER, 1);
if (!event.isCancelled() && event.getDamage() > 0) {
entityliving.damageEntity(DamageSource.WITHER, event.getDamage());
}
// CraftBukkit end
entityliving.damageEntity(DamageSource.WITHER, 1);
} else if (this.id == HUNGER.id && entityliving instanceof EntityHuman) {
((EntityHuman) entityliving).j(0.025F * (float) (i + 1));
} 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()) {
// CraftBukkit start
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
entityliving.damageEntity(DamageSource.MAGIC, 6 << i);
}
} else {
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.inventory.CraftInventoryCrafting;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.util.CraftDamageSource;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Creeper;
@ -64,6 +65,9 @@ import org.bukkit.event.server.ServerListPingEvent;
import org.bukkit.inventory.InventoryView;
public class CraftEventFactory {
public static final DamageSource MELTING = CraftDamageSource.copyOf(DamageSource.BURN);
public static final DamageSource POISON = CraftDamageSource.copyOf(DamageSource.MAGIC);
// helper methods
private static boolean canBuild(CraftWorld world, Player player, int x, int z) {
WorldServer worldServer = world.getHandle();
@ -379,21 +383,58 @@ public class CraftEventFactory {
}
public static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, int damage) {
Entity damager = source.getEntity();
DamageCause cause = DamageCause.ENTITY_ATTACK;
if (source instanceof EntityDamageSource) {
Entity damager = source.getEntity();
DamageCause cause = DamageCause.ENTITY_ATTACK;
if (source instanceof EntityDamageSourceIndirect) {
damager = ((EntityDamageSourceIndirect) source).getProximateDamageSource();
if (damager.getBukkitEntity() instanceof ThrownPotion) {
cause = DamageCause.MAGIC;
} else if (damager.getBukkitEntity() instanceof Projectile) {
cause = DamageCause.PROJECTILE;
if (source instanceof EntityDamageSourceIndirect) {
damager = ((EntityDamageSourceIndirect) source).getProximateDamageSource();
if (damager.getBukkitEntity() instanceof ThrownPotion) {
cause = DamageCause.MAGIC;
} else if (damager.getBukkitEntity() instanceof 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
@ -401,6 +442,7 @@ public class CraftEventFactory {
if (!(source instanceof EntityDamageSource)) {
return false;
}
// We don't need to check for null, since EntityDamageSource will always return an event
EntityDamageEvent event = handleEntityDamageEvent(entity, source, damage);
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);
}
}