diff --git a/src/main/java/net/minecraft/server/BlockCactus.java b/src/main/java/net/minecraft/server/BlockCactus.java index 57eb59d6bd..e920c6f48e 100644 --- a/src/main/java/net/minecraft/server/BlockCactus.java +++ b/src/main/java/net/minecraft/server/BlockCactus.java @@ -2,7 +2,7 @@ package net.minecraft.server; import java.util.Random; -import org.bukkit.event.entity.EntityDamageByBlockEvent; // CraftBukkit +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockCactus extends Block { @@ -24,7 +24,7 @@ public class BlockCactus extends Block { int i1 = world.getData(i, j, k); if (i1 == 15) { - org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this, 0); // CraftBukkit + CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this, 0); // CraftBukkit world.setData(i, j, k, 0, 4); this.doPhysics(world, i, j + 1, k, this); } else { @@ -79,22 +79,8 @@ public class BlockCactus extends Block { } public void a(World world, int i, int j, int k, Entity entity) { - // CraftBukkit start - EntityDamageByBlock event - if (entity instanceof EntityLiving) { - org.bukkit.block.Block damager = world.getWorld().getBlockAt(i, j, k); - org.bukkit.entity.Entity damagee = (entity == null) ? null : entity.getBukkitEntity(); - - EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee, org.bukkit.event.entity.EntityDamageEvent.DamageCause.CONTACT, 1D); - world.getServer().getPluginManager().callEvent(event); - - if (!event.isCancelled()) { - damagee.setLastDamageCause(event); - entity.damageEntity(DamageSource.CACTUS, (float) event.getDamage()); - } - return; - } - // CraftBukkit end - + CraftEventFactory.blockDamage = world.getWorld().getBlockAt(i, j, k); // CraftBukkit entity.damageEntity(DamageSource.CACTUS, 1.0F); + CraftEventFactory.blockDamage = null; // CraftBukkit } } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 04f5bc685a..7b975767a4 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -24,9 +24,8 @@ import org.bukkit.event.vehicle.VehicleExitEvent; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.entity.EntityCombustEvent; -import org.bukkit.event.entity.EntityDamageByBlockEvent; -import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.plugin.PluginManager; // CraftBukkit end @@ -349,26 +348,17 @@ public abstract class Entity { protected void D() { if (!this.fireProof) { + this.damageEntity(DamageSource.LAVA, 4); + // CraftBukkit start - Fallen in lava TODO: this event spams! if (this instanceof EntityLiving) { - Server server = this.world.getServer(); - - // TODO: shouldn't be sending null for the block. - org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k); - org.bukkit.entity.Entity damagee = this.getBukkitEntity(); - - EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee, EntityDamageEvent.DamageCause.LAVA, 4D); - server.getPluginManager().callEvent(event); - - if (!event.isCancelled()) { - damagee.setLastDamageCause(event); - this.damageEntity(DamageSource.LAVA, (float) event.getDamage()); - } - if (this.fireTicks <= 0) { // not on fire yet + // TODO: shouldn't be sending null for the block. + org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k); + org.bukkit.entity.Entity damagee = this.getBukkitEntity(); EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(damager, damagee, 15); - server.getPluginManager().callEvent(combustEvent); + this.world.getServer().getPluginManager().callEvent(combustEvent); if (!combustEvent.isCancelled()) { this.setOnFire(combustEvent.getDuration()); @@ -381,7 +371,6 @@ public abstract class Entity { } // CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls - this.damageEntity(DamageSource.LAVA, 4); this.setOnFire(15); } } @@ -1617,12 +1606,14 @@ public abstract class Entity { } } - EntityDamageEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDamageEvent(entitylightning, this, EntityDamageEvent.DamageCause.LIGHTNING, 5D); - if (event.isCancelled()) { + if (this.fireProof) { + return; + } + CraftEventFactory.entityDamage = entitylightning; + if (!this.damageEntity(DamageSource.FIRE, 5.0F)) { + CraftEventFactory.entityDamage = null; return; } - - this.burn((float) event.getDamage()); // CraftBukkit end ++this.fireTicks; diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java index dbf30cb8d8..f50d8f6805 100644 --- a/src/main/java/net/minecraft/server/EntityEnderDragon.java +++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -5,9 +5,9 @@ import java.util.List; // CraftBukkit start import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.util.BlockStateListPopulator; import org.bukkit.event.entity.EntityCreatePortalEvent; -import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.EntityTargetEvent; @@ -302,15 +302,9 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo if (this.bC != null) { if (this.bC.dead) { if (!this.world.isStatic) { - // CraftBukkit start - EntityDamageEvent event = new EntityDamageEvent(this.getBukkitEntity(), org.bukkit.event.entity.EntityDamageEvent.DamageCause.ENTITY_EXPLOSION, 10.0F); - Bukkit.getPluginManager().callEvent(event); - - if (!event.isCancelled()) { - getBukkitEntity().setLastDamageCause(event); - this.a(this.bq, DamageSource.explosion((Explosion) null), (float) event.getDamage()); - } - // CraftBukkit end + CraftEventFactory.entityDamage = this.bC; // CraftBukkit + this.a(this.bq, DamageSource.explosion((Explosion) null), 10.0F); + CraftEventFactory.entityDamage = null; // CraftBukkit } this.bC = null; diff --git a/src/main/java/net/minecraft/server/EntityEnderPearl.java b/src/main/java/net/minecraft/server/EntityEnderPearl.java index 9e4526e3ed..639066785f 100644 --- a/src/main/java/net/minecraft/server/EntityEnderPearl.java +++ b/src/main/java/net/minecraft/server/EntityEnderPearl.java @@ -2,7 +2,7 @@ package net.minecraft.server; // CraftBukkit start import org.bukkit.Bukkit; -import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.player.PlayerTeleportEvent; // CraftBukkit end @@ -42,15 +42,9 @@ public class EntityEnderPearl extends EntityProjectile { if (!teleEvent.isCancelled() && !entityplayer.playerConnection.isDisconnected()) { entityplayer.playerConnection.teleport(teleEvent.getTo()); this.getShooter().fallDistance = 0.0F; - - EntityDamageByEntityEvent damageEvent = new EntityDamageByEntityEvent(this.getBukkitEntity(), player, EntityDamageByEntityEvent.DamageCause.FALL, 5.0D); - Bukkit.getPluginManager().callEvent(damageEvent); - - if (!damageEvent.isCancelled() && !entityplayer.playerConnection.isDisconnected()) { - entityplayer.invulnerableTicks = -1; // Remove spawning invulnerability - player.setLastDamageCause(damageEvent); - entityplayer.damageEntity(DamageSource.FALL, (float) damageEvent.getDamage()); - } + CraftEventFactory.entityDamage = this; + this.getShooter().damageEntity(DamageSource.FALL, 5.0F); + CraftEventFactory.entityDamage = null; } // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java index bc512172a5..e0b99367c3 100644 --- a/src/main/java/net/minecraft/server/EntityFallingBlock.java +++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java @@ -3,10 +3,7 @@ package net.minecraft.server; import java.util.ArrayList; import java.util.Iterator; -// CraftBukkit start -import org.bukkit.craftbukkit.event.CraftEventFactory; -import org.bukkit.event.entity.EntityDamageEvent; -// CraftBukkit end +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class EntityFallingBlock extends Entity { @@ -156,16 +153,9 @@ public class EntityFallingBlock extends Entity { while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); - // CraftBukkit start - float damage = (float) Math.min(MathHelper.d((float) i * this.fallHurtAmount), this.fallHurtMax); - - EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(this, entity, EntityDamageEvent.DamageCause.FALLING_BLOCK, damage); - if (event.isCancelled()) { - continue; - } - - entity.damageEntity(damagesource, (float) event.getDamage()); - // CraftBukkit end + CraftEventFactory.entityDamage = this; // CraftBukkit + entity.damageEntity(damagesource, (float) Math.min(MathHelper.d((float) i * this.fallHurtAmount), this.fallHurtMax)); + CraftEventFactory.entityDamage = null; // CraftBukkit } if (flag && (double) this.random.nextFloat() < 0.05000000074505806D + (double) i * 0.05D) { diff --git a/src/main/java/net/minecraft/server/EntityFireball.java b/src/main/java/net/minecraft/server/EntityFireball.java index 0eecaad4bb..d30ef5b8de 100644 --- a/src/main/java/net/minecraft/server/EntityFireball.java +++ b/src/main/java/net/minecraft/server/EntityFireball.java @@ -2,7 +2,7 @@ package net.minecraft.server; import java.util.List; -import org.bukkit.event.entity.EntityDamageByEntityEvent; // CraftBukkit +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public abstract class EntityFireball extends Entity { @@ -132,7 +132,7 @@ public abstract class EntityFireball extends Entity { // CraftBukkit start - Fire ProjectileHitEvent if (this.dead) { - org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); + CraftEventFactory.callProjectileHitEvent(this); } // CraftBukkit end } @@ -235,11 +235,7 @@ public abstract class EntityFireball extends Entity { this.P(); if (damagesource.getEntity() != null) { // CraftBukkit start - EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(damagesource.getEntity().getBukkitEntity(), this.getBukkitEntity(), org.bukkit.event.entity.EntityDamageEvent.DamageCause.ENTITY_ATTACK, f); - - world.getServer().getPluginManager().callEvent(event); - - if (event.isCancelled()) { + if (!CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { return false; } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/EntityHorse.java b/src/main/java/net/minecraft/server/EntityHorse.java index 544c008295..7138862255 100644 --- a/src/main/java/net/minecraft/server/EntityHorse.java +++ b/src/main/java/net/minecraft/server/EntityHorse.java @@ -3,11 +3,7 @@ package net.minecraft.server; import java.util.Iterator; import java.util.List; -// CraftBukkit start -import org.bukkit.craftbukkit.event.CraftEventFactory; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; -// CraftBukkit end +import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; // CraftBukkit public class EntityHorse extends EntityAnimal implements IInventoryListener { @@ -294,26 +290,9 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { int i = MathHelper.f(f * 0.5F - 3.0F); if (i > 0) { - // CraftBukkit start - fire EntityDamageEvent - EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, this, EntityDamageEvent.DamageCause.FALL, i); - if (!event.isCancelled()) { - float damage = (float) event.getDamage(); - if (damage > 0) { - this.getBukkitEntity().setLastDamageCause(event); - this.damageEntity(DamageSource.FALL, damage); - } - } - + this.damageEntity(DamageSource.FALL, (float) i); if (this.passenger != null) { - EntityDamageEvent passengerEvent = CraftEventFactory.callEntityDamageEvent(null, this.passenger, EntityDamageEvent.DamageCause.FALL, i); - if (!passengerEvent.isCancelled() && this.passenger != null) { // Check again in case of plugin - float damage = (float) passengerEvent.getDamage(); - if (damage > 0) { - this.passenger.getBukkitEntity().setLastDamageCause(passengerEvent); - this.passenger.damageEntity(DamageSource.FALL, damage); - } - } - // CraftBukkit end + this.passenger.damageEntity(DamageSource.FALL, (float) i); } Block block = this.world.getType(MathHelper.floor(this.locX), MathHelper.floor(this.locY - 0.2D - (double) this.lastYaw), MathHelper.floor(this.locZ)); diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java index 381ba31653..a5dfcf4b1b 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -799,7 +799,12 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen return (float) i / (float) this.inventory.armor.length; } - protected void d(DamageSource damagesource, float f) { + // CraftBukkit start + protected boolean d(DamageSource damagesource, float f) { // void -> boolean + if (true) { + return super.d(damagesource, f); + } + // CraftBukkit end if (!this.isInvulnerable()) { if (!damagesource.ignoresArmor() && this.isBlocking() && f > 0.0F) { f = (1.0F + f) * 0.5F; @@ -819,6 +824,7 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen this.aV().a(damagesource, f2, f); } } + return false; // CraftBukkit } public void openFurnace(TileEntityFurnace tileentityfurnace) {} diff --git a/src/main/java/net/minecraft/server/EntityItemFrame.java b/src/main/java/net/minecraft/server/EntityItemFrame.java index 8d39f5f4ba..940e7c86a6 100644 --- a/src/main/java/net/minecraft/server/EntityItemFrame.java +++ b/src/main/java/net/minecraft/server/EntityItemFrame.java @@ -24,8 +24,7 @@ public class EntityItemFrame extends EntityHanging { } else if (this.getItem() != null) { if (!this.world.isStatic) { // CraftBukkit start - fire EntityDamageEvent - org.bukkit.event.entity.EntityDamageEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handleEntityDamageEvent(this, damagesource, f); - if ((event != null && event.isCancelled()) || this.dead) { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f) || this.dead) { return true; } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index b3bf43ae66..095a97f8d4 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -11,6 +11,7 @@ import java.util.UUID; import java.util.ArrayList; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; import org.bukkit.event.entity.EntityRegainHealthEvent; // CraftBukkit end @@ -646,7 +647,8 @@ public abstract class EntityLiving extends Entity { } else if (damagesource.o() && this.hasEffect(MobEffectList.FIRE_RESISTANCE)) { return false; } else { - if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { + // CraftBukkit - Moved into d(DamageSource, float) + if (false && (damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { this.getEquipment(4).damage((int) (f * 4.0F + this.random.nextFloat() * f * 2.0F), this); f *= 0.75F; } @@ -654,29 +656,28 @@ public abstract class EntityLiving extends Entity { this.aF = 1.5F; boolean flag = true; - // CraftBukkit start - EntityDamageEvent event = CraftEventFactory.handleEntityDamageEvent(this, damagesource, f); - if (event != null) { - if (event.isCancelled()) { - return false; - } - f = (float) event.getDamage(); - } - // CraftBukkit end - if ((float) this.noDamageTicks > (float) this.maxNoDamageTicks / 2.0F) { if (f <= this.lastDamage) { return false; } - this.d(damagesource, f - this.lastDamage); + // CraftBukkit start + if (!this.d(damagesource, f - this.lastDamage)) { + return false; + } + // CraftBukkit end this.lastDamage = f; flag = false; } else { + // CraftBukkit start + float previousHealth = this.getHealth(); + if (!this.d(damagesource, f)) { + return false; + } this.lastDamage = f; - this.aw = this.getHealth(); + this.aw = previousHealth; this.noDamageTicks = this.maxNoDamageTicks; - this.d(damagesource, f); + // CraftBukkit end this.hurtTicks = this.ay = 10; } @@ -856,25 +857,16 @@ public abstract class EntityLiving extends Entity { super.b(f); MobEffect mobeffect = this.getEffect(MobEffectList.JUMP); float f1 = mobeffect != null ? (float) (mobeffect.getAmplifier() + 1) : 0.0F; - // CraftBukkit start - float i = MathHelper.f(f - 3.0F - f1); + int i = MathHelper.f(f - 3.0F - f1); if (i > 0) { - EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, this, EntityDamageEvent.DamageCause.FALL, i); - if (event.isCancelled()) { + // CraftBukkit start + if (!this.damageEntity(DamageSource.FALL, (float) i)) { return; } - - i = (float) event.getDamage(); - if (i > 0) { - this.getBukkitEntity().setLastDamageCause(event); - } - } - // CraftBukkit end - - if (i > 0) { - this.makeSound(this.o(org.bukkit.util.NumberConversions.ceil(i)), 1.0F, 1.0F); // CraftBukkit - ceil - this.damageEntity(DamageSource.FALL, (float) i); + // CraftBukkit end + this.makeSound(this.o(i), 1.0F, 1.0F); + // this.damageEntity(DamageSource.FALL, (float) i); // CraftBukkit - moved up int j = MathHelper.floor(this.locX); int k = MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height); int l = MathHelper.floor(this.locZ); @@ -917,7 +909,7 @@ public abstract class EntityLiving extends Entity { int i = 25 - this.aU(); float f1 = f * (float) i; - this.h(f); + // this.h(f); // CraftBukkit - Moved into d(DamageSource, float) f = f1 / 25.0F; } @@ -936,7 +928,8 @@ public abstract class EntityLiving extends Entity { int j; float f1; - if (this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { + // CraftBukkit - Moved to d(DamageSource, float) + if (false && this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { i = (this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5; j = 25 - i; f1 = f * (float) j; @@ -962,22 +955,88 @@ public abstract class EntityLiving extends Entity { } } - protected void d(DamageSource damagesource, float f) { + // CraftBukkit start + protected boolean d(DamageSource damagesource, float f) { // void -> boolean if (!this.isInvulnerable()) { + boolean human = this instanceof EntityHuman; + float originalDamage = f; + float preDamage = f; + float hardHatModifier = 0; + if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { + f *= 0.75F; + hardHatModifier = preDamage - f; + preDamage = f; + } + float blockingModifier = 0; + if (human) { + if (!damagesource.ignoresArmor() && ((EntityHuman) this).isBlocking() && f > 0.0F) { + f = (1.0F + f) * 0.5F; + blockingModifier = preDamage - f; + preDamage = f; + } + } + // Armor modifier f = this.b(damagesource, f); + float armorModifier = preDamage - f; + preDamage = f; + // Resistance Potion Effect + if (!damagesource.h() && this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { + int i = (this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5; + int j = 25 - i; + float f1 = f * (float) j; + f = f1 / 25.0F; + } + float resistanceModifier = preDamage - f; + preDamage = f; + // Magic modifier f = this.c(damagesource, f); + float magicModifier = preDamage - f; float f1 = f; + // Absorption modifier f = Math.max(f - this.br(), 0.0F); - this.m(this.br() - (f1 - f)); + float absorptionModifier = Math.max(f1 - f, 0.0F); + + EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, -hardHatModifier, -blockingModifier, -armorModifier, -resistanceModifier, -magicModifier, -absorptionModifier); + + if (event.isCancelled()) { + return false; + } + + f = (float) event.getFinalDamage(); + + // Apply damage to helmet + if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { + this.getEquipment(4).damage((int) (event.getDamage() * 4.0F + this.random.nextFloat() * event.getDamage() * 2.0F), this); + } + + // Apply damage to armor + if (!damagesource.ignoresArmor()) { + float armorDamage = (float) (event.getDamage() + event.getDamage(DamageModifier.BLOCKING) + event.getDamage(DamageModifier.HARD_HAT)); + this.h(armorDamage); + } + + absorptionModifier = (float) -event.getDamage(DamageModifier.ABSORPTION); + this.m(Math.max(this.br() - absorptionModifier, 0.0F)); if (f != 0.0F) { + if (human) { + ((EntityHuman) this).a(damagesource.f()); + } + // CraftBukkit end float f2 = this.getHealth(); this.setHealth(f2 - f); this.aV().a(damagesource, f2, f); + // CraftBukkit start + if (human) { + return true; + } + // CraftBukkit end this.m(this.br() - f); } + return true; // CraftBukkit } + return false; // CraftBukkit } public CombatTracker aV() { diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java index 11007d40d0..56fa9998ca 100644 --- a/src/main/java/net/minecraft/server/Explosion.java +++ b/src/main/java/net/minecraft/server/Explosion.java @@ -9,10 +9,7 @@ import java.util.Map; import java.util.Random; // CraftBukkit start -import org.bukkit.Bukkit; -import org.bukkit.event.entity.EntityDamageByBlockEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.Location; // CraftBukkit end @@ -130,55 +127,21 @@ public class Explosion { double d9 = (double) this.world.a(vec3d, entity.boundingBox); double d10 = (1.0D - d7) * d9; - // CraftBukkit start - Explosion damage hook - org.bukkit.entity.Entity damagee = (entity == null) ? null : entity.getBukkitEntity(); - float damageDone = (float) ((int) ((d10 * d10 + d10) / 2.0D * 8.0D * (double) this.size + 1.0D)); - - if (damagee == null) { - // nothing was hurt - } else if (this.source == null) { // Block explosion (without an entity source; bed etc.) - EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(null, damagee, EntityDamageEvent.DamageCause.BLOCK_EXPLOSION, damageDone); - Bukkit.getPluginManager().callEvent(event); - - if (!event.isCancelled()) { - damagee.setLastDamageCause(event); - entity.damageEntity(DamageSource.explosion(this), (float) event.getDamage()); - double d11 = EnchantmentProtection.a(entity, d10); - - entity.motX += d0 * d11; - entity.motY += d1 * d11; - entity.motZ += d2 * d11; - if (entity instanceof EntityHuman) { - this.l.put((EntityHuman) entity, Vec3D.a(d0 * d10, d1 * d10, d2 * d10)); - } - } - } else { - final org.bukkit.entity.Entity damager = this.source.getBukkitEntity(); - final EntityDamageEvent.DamageCause damageCause; - - if (damager instanceof org.bukkit.entity.TNTPrimed) { - damageCause = EntityDamageEvent.DamageCause.BLOCK_EXPLOSION; - } else { - damageCause = EntityDamageEvent.DamageCause.ENTITY_EXPLOSION; - } - - EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(damager, damagee, damageCause, damageDone); - Bukkit.getPluginManager().callEvent(event); - - if (!event.isCancelled()) { - entity.getBukkitEntity().setLastDamageCause(event); - entity.damageEntity(DamageSource.explosion(this), (float) event.getDamage()); - double d11 = EnchantmentProtection.a(entity, d10); - - entity.motX += d0 * d11; - entity.motY += d1 * d11; - entity.motZ += d2 * d11; - if (entity instanceof EntityHuman) { - this.l.put((EntityHuman) entity, Vec3D.a(d0 * d10, d1 * d10, d2 * d10)); - } - } + // CraftBukkit start + CraftEventFactory.entityDamage = source; + if (!entity.damageEntity(DamageSource.explosion(this), (float) ((int) ((d10 * d10 + d10) / 2.0D * 8.0D * (double) this.size + 1.0D)))) { + CraftEventFactory.entityDamage = null; + continue; } // CraftBukkit end + double d11 = EnchantmentProtection.a(entity, d10); + + entity.motX += d0 * d11; + entity.motY += d1 * d11; + entity.motZ += d2 * d11; + if (entity instanceof EntityHuman) { + this.l.put((EntityHuman) entity, Vec3D.a(d0 * d10, d1 * d10, d2 * d10)); + } } } } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 522d6b036c..eda813ff8a 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -2,6 +2,8 @@ package org.bukkit.craftbukkit.event; import java.net.InetAddress; import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -12,6 +14,8 @@ import net.minecraft.server.Entity; import net.minecraft.server.EntityArrow; import net.minecraft.server.EntityDamageSource; import net.minecraft.server.EntityDamageSourceIndirect; +import net.minecraft.server.EntityEnderCrystal; +import net.minecraft.server.EntityEnderDragon; import net.minecraft.server.EntityHuman; import net.minecraft.server.EntityInsentient; import net.minecraft.server.EntityItem; @@ -41,6 +45,7 @@ import org.bukkit.craftbukkit.CraftStatistic; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftLivingEntity; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; @@ -66,6 +71,7 @@ import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; import org.bukkit.event.entity.*; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.PrepareItemCraftEvent; @@ -74,9 +80,13 @@ import org.bukkit.event.server.ServerListPingEvent; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.meta.BookMeta; +import com.google.common.collect.ImmutableMap; + public class CraftEventFactory { public static final DamageSource MELTING = CraftDamageSource.copyOf(DamageSource.BURN); public static final DamageSource POISON = CraftDamageSource.copyOf(DamageSource.MAGIC); + public static org.bukkit.block.Block blockDamage; // For use in EntityDamageByBlockEvent + public static Entity entityDamage; // For use in EntityDamageByEntityEvent // helper methods private static boolean canBuild(CraftWorld world, Player player, int x, int z) { @@ -393,29 +403,31 @@ public class CraftEventFactory { return event; } - /** - * EntityDamage(ByEntityEvent) - */ - public static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, double damage) { - EntityDamageEvent event; - if (damager != null) { - event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, damage); - } else { - event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, damage); - } - - callEvent(event); - - if (!event.isCancelled()) { - event.getEntity().setLastDamageCause(event); - } - - return event; - } - - public static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, float damage) { + private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map modifiers) { if (source.isExplosion()) { - return null; + DamageCause damageCause; + Entity damager = entityDamage; + entityDamage = null; + EntityDamageEvent event; + if (damager == null) { + event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers); + } else if (entity instanceof EntityEnderDragon && ((EntityEnderDragon) entity).bC == damager) { + event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers); + } else { + if (damager instanceof org.bukkit.entity.TNTPrimed) { + damageCause = DamageCause.BLOCK_EXPLOSION; + } else { + damageCause = DamageCause.ENTITY_EXPLOSION; + } + event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers); + } + + callEvent(event); + + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + return event; } else if (source instanceof EntityDamageSource) { Entity damager = source.getEntity(); DamageCause cause = DamageCause.ENTITY_ATTACK; @@ -431,9 +443,47 @@ public class CraftEventFactory { cause = DamageCause.THORNS; } - return callEntityDamageEvent(damager, entity, cause, damage); + return callEntityDamageEvent(damager, entity, cause, modifiers); } else if (source == DamageSource.OUT_OF_WORLD) { - EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, damage)); + EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers)); + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + return event; + } else if (source == DamageSource.LAVA) { + EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers)); + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + return event; + } else if (blockDamage != null) { + DamageCause cause = null; + Block damager = blockDamage; + blockDamage = null; + if (source == DamageSource.CACTUS) { + cause = DamageCause.CONTACT; + } else { + throw new RuntimeException("Unhandled entity damage"); + } + EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers)); + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + return event; + } else if (entityDamage != null) { + DamageCause cause = null; + CraftEntity damager = entityDamage.getBukkitEntity(); + entityDamage = null; + if (source == DamageSource.ANVIL || source == DamageSource.FALLING_BLOCK) { + cause = DamageCause.FALLING_BLOCK; + } else if (damager instanceof LightningStrike) { + cause = DamageCause.LIGHTNING; + } else if (source == DamageSource.FALL) { + cause = DamageCause.FALL; + } else { + throw new RuntimeException("Unhandled entity damage"); + } + EntityDamageEvent event = callEvent(new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers)); if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } @@ -459,23 +509,56 @@ public class CraftEventFactory { cause = DamageCause.POISON; } else if (source == DamageSource.MAGIC) { cause = DamageCause.MAGIC; + } else if (source == DamageSource.FALL) { + cause = DamageCause.FALL; } if (cause != null) { - return callEntityDamageEvent(null, entity, cause, damage); + return callEntityDamageEvent(null, entity, cause, modifiers); } - // If an event was called earlier, we return null. - // EG: Cactus, Lava, EntityEnderPearl "fall", FallingSand - return null; + throw new RuntimeException("Unhandled entity damage"); } - // Non-Living Entities such as EntityEnderCrystal need to call this - public static boolean handleNonLivingEntityDamageEvent(Entity entity, DamageSource source, float damage) { - if (!(source instanceof EntityDamageSource)) { + private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map modifiers) { + EntityDamageEvent event; + if (damager != null) { + event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers); + } else { + event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers); + } + + callEvent(event); + + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + + return event; + } + + public static EntityDamageEvent handleLivingEntityDamageEvent(Entity damagee, DamageSource source, double rawDamage, double hardHatModifier, double blockingModifier, double armorModifier, double resistanceModifier, double magicModifier, double absorptionModifier) { + Map modifiers = new HashMap(); + modifiers.put(DamageModifier.BASE, rawDamage); + if (source == DamageSource.FALLING_BLOCK || source == DamageSource.ANVIL) { + modifiers.put(DamageModifier.HARD_HAT, hardHatModifier); + } + if (damagee instanceof EntityHuman) { + modifiers.put(DamageModifier.BLOCKING, blockingModifier); + } + modifiers.put(DamageModifier.ARMOR, armorModifier); + modifiers.put(DamageModifier.RESISTANCE, resistanceModifier); + modifiers.put(DamageModifier.MAGIC, magicModifier); + modifiers.put(DamageModifier.ABSORPTION, absorptionModifier); + return handleEntityDamageEvent(damagee, source, new EnumMap(modifiers)); + } + + // Non-Living Entities such as EntityEnderCrystal, EntityItemFrame, and EntityFireball need to call this + public static boolean handleNonLivingEntityDamageEvent(Entity entity, DamageSource source, double damage) { + if (entity instanceof EntityEnderCrystal && !(source instanceof EntityDamageSource)) { return false; } - EntityDamageEvent event = handleEntityDamageEvent(entity, source, damage); + EntityDamageEvent event = handleEntityDamageEvent(entity, source, new EnumMap(ImmutableMap.of(DamageModifier.BASE, (double) damage))); if (event == null) { return false; }