From 7a9de3159b2fc4b9436df5450d2cb78972444568 Mon Sep 17 00:00:00 2001 From: angelsl Date: Mon, 3 Jan 2011 19:24:25 +0800 Subject: [PATCH] Explosion damage entity hook. --- .../net/minecraft/server/BlockCactus.java | 9 +- .../java/net/minecraft/server/Explosion.java | 220 ++++++++++++++++++ 2 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/minecraft/server/Explosion.java diff --git a/src/main/java/net/minecraft/server/BlockCactus.java b/src/main/java/net/minecraft/server/BlockCactus.java index fb4d56ecfe..9a4d7b5b5c 100644 --- a/src/main/java/net/minecraft/server/BlockCactus.java +++ b/src/main/java/net/minecraft/server/BlockCactus.java @@ -4,7 +4,9 @@ import org.bukkit.LivingEntity; import org.bukkit.craftbukkit.CraftBlock; import org.bukkit.craftbukkit.CraftEntity; import org.bukkit.craftbukkit.CraftLivingEntity; +import org.bukkit.craftbukkit.CraftPlayer; import org.bukkit.event.entity.EntityDamagedByBlockEvent; +import org.bukkit.event.entity.EntityDamagedEvent; import java.util.Random; @@ -93,13 +95,16 @@ public class BlockCactus extends Block { public void a(World world, int i, int j, int k, Entity entity) { // Craftbukkit: ENTITY_DAMAGEBY_BLOCK event CraftEntity toPassIn = null; - if(entity instanceof EntityLiving) + if(entity instanceof EntityPlayerMP) + { + toPassIn = new CraftPlayer(((WorldServer)world).getServer(), (EntityPlayerMP)entity); + } else if(entity instanceof EntityLiving) { toPassIn = new CraftLivingEntity(((WorldServer)world).getServer(), (EntityLiving)entity); } if(toPassIn != null) { - EntityDamagedByBlockEvent edbbe = new EntityDamagedByBlockEvent(((WorldServer)world).getWorld().getBlockAt(i, j, k), toPassIn, 1); + EntityDamagedByBlockEvent edbbe = new EntityDamagedByBlockEvent(((WorldServer)world).getWorld().getBlockAt(i, j, k), toPassIn, EntityDamagedEvent.DamageCause.CONTACT, 1); ((WorldServer)world).getServer().getPluginManager().callEvent(edbbe); if(edbbe.isCancelled()) return; } diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java new file mode 100644 index 0000000000..b7fb45748b --- /dev/null +++ b/src/main/java/net/minecraft/server/Explosion.java @@ -0,0 +1,220 @@ +package net.minecraft.server; + + +import org.bukkit.craftbukkit.CraftEntity; +import org.bukkit.craftbukkit.CraftLivingEntity; +import org.bukkit.craftbukkit.CraftPlayer; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.event.entity.EntityDamagedByBlockEvent; +import org.bukkit.event.entity.EntityDamagedByEntityEvent; +import org.bukkit.event.entity.EntityDamagedEvent; + +import java.util.*; + + +public class Explosion { + + public boolean a; + private Random h; + private World i; + public double b; + public double c; + public double d; + public Entity e; + public float f; + public Set g; + + public Explosion(World world, Entity entity, double d1, double d2, double d3, float f1) { + a = false; + h = new Random(); + g = new HashSet(); + i = world; + e = entity; + f = f1; + b = d1; + c = d2; + d = d3; + } + + public void a() { + float f1 = f; + int j = 16; + + for (int k = 0; k < j; k++) { + for (int i1 = 0; i1 < j; i1++) { + label0: + for (int k1 = 0; k1 < j; k1++) { + if (k != 0 && k != j - 1 && i1 != 0 && i1 != j - 1 && k1 != 0 && k1 != j - 1) { + continue; + } + double d1 = ((float) k / ((float) j - 1.0F)) * 2.0F - 1.0F; + double d2 = ((float) i1 / ((float) j - 1.0F)) * 2.0F - 1.0F; + double d3 = ((float) k1 / ((float) j - 1.0F)) * 2.0F - 1.0F; + double d4 = Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3); + + d1 /= d4; + d2 /= d4; + d3 /= d4; + float f2 = f * (0.7F + i.l.nextFloat() * 0.6F); + double d5 = b; + double d7 = c; + double d9 = d; + float f3 = 0.3F; + + do { + if (f2 <= 0.0F) { + continue label0; + } + int j2 = MathHelper.b(d5); + int k2 = MathHelper.b(d7); + int l2 = MathHelper.b(d9); + int i3 = i.a(j2, k2, l2); + + if (i3 > 0) { + f2 -= (Block.m[i3].a(e) + 0.3F) * f3; + } + if (f2 > 0.0F) { + g.add(new ChunkPosition(j2, k2, l2)); + } + d5 += d1 * (double) f3; + d7 += d2 * (double) f3; + d9 += d3 * (double) f3; + f2 -= f3 * 0.75F; + } while (true); + } + + } + + } + + f *= 2.0F; + int l = MathHelper.b(b - (double) f - 1.0D); + int j1 = MathHelper.b(b + (double) f + 1.0D); + int l1 = MathHelper.b(c - (double) f - 1.0D); + int j3 = MathHelper.b(c + (double) f + 1.0D); + int k3 = MathHelper.b(d - (double) f - 1.0D); + int l3 = MathHelper.b(d + (double) f + 1.0D); + List list = i.b(e, AxisAlignedBB.b(l, l1, k3, j1, j3, l3)); + Vec3D vec3d = Vec3D.b(b, c, d); + + for (int i4 = 0; i4 < list.size(); i4++) { + Entity entity = (Entity) list.get(i4); + double d11 = entity.e(b, c, d) / (double) f; + + if (d11 <= 1.0D) { + double d6 = entity.p - b; + double d8 = entity.q - c; + double d10 = entity.r - d; + double d12 = MathHelper.a(d6 * d6 + d8 * d8 + d10 * d10); + + d6 /= d12; + d8 /= d12; + d10 /= d12; + double d13 = i.a(vec3d, entity.z); + double d14 = (1.0D - d11) * d13; + + // Craftbukkit: explosion damage hook + int damage = (int) (((d14 * d14 + d14) / 2D) * 8D * (double) f + 1.0D); + CraftServer servr = ((WorldServer)i).getServer(); + CraftEntity damagee = null; + if(entity instanceof EntityPlayerMP) + { + damagee = new CraftPlayer(servr, (EntityPlayerMP)entity); + } else if(entity instanceof EntityLiving) + { + damagee = new CraftLivingEntity(servr, (EntityLiving)entity); + } + if(e == null) { // Block explosion + // Craftbukkit TODO: get the x/y/z of the tnt block? + EntityDamagedByBlockEvent edbbe = new EntityDamagedByBlockEvent(null, damagee, EntityDamagedEvent.DamageCause.BLOCK_EXPLOSION, damage); + servr.getPluginManager().callEvent(edbbe); + if(!edbbe.isCancelled()) entity.a(e, damage); + } else { + CraftEntity damager = null; + if(e instanceof EntityPlayerMP) + { + // not possible in normal operations + damager = new CraftPlayer(servr, (EntityPlayerMP)e); + } else if(e instanceof EntityLiving) + { + damager = new CraftLivingEntity(servr, (EntityLiving) e); + } + EntityDamagedByEntityEvent edbbe = new EntityDamagedByEntityEvent(damager, damagee, EntityDamagedEvent.DamageCause.ENTITY_EXPLOSION, damage); + servr.getPluginManager().callEvent(edbbe); + if(!edbbe.isCancelled()) entity.a(e, damage); + } + // Craftbukkit: end + + double d15 = d14; + + entity.s += d6 * d15; + entity.t += d8 * d15; + entity.u += d10 * d15; + } + } + + f = f1; + ArrayList arraylist = new ArrayList(); + + arraylist.addAll(g); + if (a) { + for (int j4 = arraylist.size() - 1; j4 >= 0; j4--) { + ChunkPosition chunkposition = (ChunkPosition) arraylist.get(j4); + int i2 = chunkposition.a; + int k4 = chunkposition.b; + int l4 = chunkposition.c; + int i5 = i.a(i2, k4, l4); + int j5 = i.a(i2, k4 - 1, l4); + + if (i5 == 0 && Block.o[j5] && h.nextInt(3) == 0) { + i.d(i2, k4, l4, Block.ar.bh); + } + } + + } + } + + public void b() { + i.a(b, c, d, "random.explode", 4F, (1.0F + (i.l.nextFloat() - i.l.nextFloat()) * 0.2F) * 0.7F); + ArrayList arraylist = new ArrayList(); + + arraylist.addAll(g); + for (int j = arraylist.size() - 1; j >= 0; j--) { + ChunkPosition chunkposition = (ChunkPosition) arraylist.get(j); + int k = chunkposition.a; + int l = chunkposition.b; + int i1 = chunkposition.c; + int j1 = i.a(k, l, i1); + + for (int k1 = 0; k1 < 1; k1++) { + double d1 = (float) k + i.l.nextFloat(); + double d2 = (float) l + i.l.nextFloat(); + double d3 = (float) i1 + i.l.nextFloat(); + double d4 = d1 - b; + double d5 = d2 - c; + double d6 = d3 - d; + double d7 = MathHelper.a(d4 * d4 + d5 * d5 + d6 * d6); + + d4 /= d7; + d5 /= d7; + d6 /= d7; + double d8 = 0.5D / (d7 / (double) f + 0.10000000000000001D); + + d8 *= i.l.nextFloat() * i.l.nextFloat() + 0.3F; + d4 *= d8; + d5 *= d8; + d6 *= d8; + i.a("explode", (d1 + b * 1.0D) / 2D, (d2 + c * 1.0D) / 2D, (d3 + d * 1.0D) / 2D, d4, d5, d6); + i.a("smoke", d1, d2, d3, d4, d5, d6); + } + + if (j1 > 0) { + Block.m[j1].a(i, k, l, i1, i.b(k, l, i1), 0.3F); + i.d(k, l, i1, 0); + Block.m[j1].c(i, k, l, i1); + } + } + + } +} +