summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Ardill <andrew.ardill@gmail.com>2011-01-12 16:48:19 +1100
committerErik Broes <erikbroes@grum.nl>2011-01-16 14:14:30 +0100
commitceaf94d5bb761b54249d22de08226167319099be (patch)
tree0feb93042e96e0a5b3f74717e3b71ddb75a91069 /src
parent807de6ee22f665196adc48498a27223317973958 (diff)
downloadcraftbukkit-ceaf94d5bb761b54249d22de08226167319099be.tar
craftbukkit-ceaf94d5bb761b54249d22de08226167319099be.tar.gz
craftbukkit-ceaf94d5bb761b54249d22de08226167319099be.tar.lz
craftbukkit-ceaf94d5bb761b54249d22de08226167319099be.tar.xz
craftbukkit-ceaf94d5bb761b54249d22de08226167319099be.zip
Implementation of the EntityDamage*Events.
Many files were added to enable the correct hooking of these events, and a new event EntityDamageByProjectileEvent. EntityDamageByProjectileEvent adds the ability to get the projectile entity (such as an egg) and also set if the projectile 'bounces'. Only two projectiles currently respond to bouncing, Arrow and Fish - were if the fish bounces it means the fish is not hooked. Bouncing is independent of any damage caused via the event. In addition, the changes to EntityDamageEvent that enable setting post-event damage were implemented in all hooks. Finally, a bug in CraftArrow was fixed, where the constructor was not declared public.
Diffstat (limited to 'src')
-rw-r--r--src/main/java/net/minecraft/server/BlockCactus.java21
-rw-r--r--src/main/java/net/minecraft/server/Entity.java47
-rw-r--r--src/main/java/net/minecraft/server/EntityArrow.java293
-rw-r--r--src/main/java/net/minecraft/server/EntityEgg.java35
-rw-r--r--src/main/java/net/minecraft/server/EntityFireball.java245
-rw-r--r--src/main/java/net/minecraft/server/EntityFish.java367
-rw-r--r--src/main/java/net/minecraft/server/EntityMobs.java111
-rw-r--r--src/main/java/net/minecraft/server/EntityPlayer.java377
-rw-r--r--src/main/java/net/minecraft/server/EntitySnowball.java269
-rw-r--r--src/main/java/net/minecraft/server/Explosion.java5
-rw-r--r--src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java17
-rw-r--r--src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java17
12 files changed, 1784 insertions, 20 deletions
diff --git a/src/main/java/net/minecraft/server/BlockCactus.java b/src/main/java/net/minecraft/server/BlockCactus.java
index 57d83c0e..2f0aa35f 100644
--- a/src/main/java/net/minecraft/server/BlockCactus.java
+++ b/src/main/java/net/minecraft/server/BlockCactus.java
@@ -6,6 +6,7 @@ import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageEvent;
// CraftBukkit end
@@ -96,21 +97,19 @@ public class BlockCactus extends Block {
public void a(World world, int i, int j, int k, Entity entity) {
// CraftBukkit start - ENTITY_DAMAGEBY_BLOCK event
- CraftEntity toPassIn = null;
- 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) {
+ if(entity instanceof EntityLiving) {
+ CraftServer server = ((WorldServer) world).getServer();
+ CraftEntity toPassIn = new CraftLivingEntity(server, (EntityLiving) entity);
EntityDamageByBlockEvent edbbe = new EntityDamageByBlockEvent(((WorldServer) world).getWorld().getBlockAt(i, j, k), toPassIn, EntityDamageEvent.DamageCause.CONTACT, 1);
- ((WorldServer) world).getServer().getPluginManager().callEvent(edbbe);
+ server.getPluginManager().callEvent(edbbe);
- if (edbbe.isCancelled())
- return;
+ if (!edbbe.isCancelled()){
+ entity.a(((Entity) (null)), edbbe.getDamage());
+ }
+ return;
}
- // CraftBukkit end TODO: Other entities (when their respective classes are added) hitting a Cactus
+ // CraftBukkit end
entity.a(((Entity) (null)), 1);
}
}
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 212da33a..7f8aa434 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -5,6 +5,9 @@ import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.event.Event.Type;
+import org.bukkit.event.entity.EntityCombustEvent;
+import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageEvent;
// CraftBukkit end
@@ -212,7 +215,21 @@ public abstract class Entity {
}
} else {
if (Z % 20 == 0) {
- a(((Entity) (null)), 1);
+ // CraftBukkit start
+ if(this instanceof EntityLiving) {
+ CraftServer server = ((WorldServer)l).getServer();
+ CraftEntity damagee = new CraftLivingEntity(server, (EntityLiving)this);
+
+ EntityDamageEvent ede = new EntityDamageEvent(damagee, EntityDamageEvent.DamageCause.DROWNING, 1);
+ server.getPluginManager().callEvent(ede);
+
+ if (!ede.isCancelled()){
+ a(((Entity) (null)), ede.getDamage());
+ }
+ } else {
+ a(((Entity) (null)), 1);
+ }
+ // CraftBukkit end
}
Z--;
}
@@ -232,8 +249,27 @@ public abstract class Entity {
protected void s() {
if (!ae) {
- a(((Entity) (null)), 4);
- Z = 600;
+ // CraftBukkit start
+ if(this instanceof EntityLiving) {
+ CraftServer server = ((WorldServer)l).getServer();
+ CraftEntity defender = new CraftLivingEntity(server, (EntityLiving) this);
+
+ EntityDamageByBlockEvent ede = new EntityDamageByBlockEvent(null, defender, EntityDamageEvent.DamageCause.LAVA, 4);
+ server.getPluginManager().callEvent(ede);
+ if (!ede.isCancelled()){
+ a(((Entity) (null)), ede.getDamage());
+ }
+
+ EntityCombustEvent ece = new EntityCombustEvent(Type.ENTITY_COMBUST, defender);
+ server.getPluginManager().callEvent(ece);
+ if (!ece.isCancelled()){
+ Z = 600;
+ }
+ } else {
+ a(((Entity) (null)), 4);
+ Z = 600;
+ }
+ // CraftBukkit end
}
}
@@ -479,7 +515,10 @@ public abstract class Entity {
EntityDamageEvent ede = new EntityDamageEvent(defender, EntityDamageEvent.DamageCause.FIRE, i1);
server.getPluginManager().callEvent(ede);
- if (ede.isCancelled()) return;
+ if (!ede.isCancelled()){
+ a(((Entity) (null)), ede.getDamage());
+ }
+ return;
}
// CraftBukkit end
a(((Entity) (null)), i1);
diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java
new file mode 100644
index 00000000..e02cc6be
--- /dev/null
+++ b/src/main/java/net/minecraft/server/EntityArrow.java
@@ -0,0 +1,293 @@
+package net.minecraft.server;
+
+import java.util.List;
+import java.util.Random;
+
+//CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftArrow;
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.event.entity.EntityDamageByBlockEvent;
+import org.bukkit.event.entity.EntityDamageByProjectileEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+//CraftBukkit end
+
+public class EntityArrow extends Entity {
+
+ private int c;
+ private int d;
+ private int e;
+ private int f;
+ private boolean ak;
+ public int a;
+ public EntityLiving b;
+ private int al;
+ private int am;
+
+ public EntityArrow(World world) {
+ super(world);
+ c = -1;
+ d = -1;
+ e = -1;
+ f = 0;
+ ak = false;
+ a = 0;
+ am = 0;
+ a(0.5F, 0.5F);
+ }
+
+ public EntityArrow(World world, double d1, double d2, double d3) {
+ super(world);
+ c = -1;
+ d = -1;
+ e = -1;
+ f = 0;
+ ak = false;
+ a = 0;
+ am = 0;
+ a(0.5F, 0.5F);
+ a(d1, d2, d3);
+ H = 0.0F;
+ }
+
+ public EntityArrow(World world, EntityLiving entityliving) {
+ super(world);
+ c = -1;
+ d = -1;
+ e = -1;
+ f = 0;
+ ak = false;
+ a = 0;
+ am = 0;
+ b = entityliving;
+ a(0.5F, 0.5F);
+ c(entityliving.p, entityliving.q + (double) entityliving.w(), entityliving.r, entityliving.v, entityliving.w);
+ p -= MathHelper.b((v / 180F) * 3.141593F) * 0.16F;
+ q -= 0.10000000149011612D;
+ r -= MathHelper.a((v / 180F) * 3.141593F) * 0.16F;
+ a(p, q, r);
+ H = 0.0F;
+ s = -MathHelper.a((v / 180F) * 3.141593F) * MathHelper.b((w / 180F) * 3.141593F);
+ u = MathHelper.b((v / 180F) * 3.141593F) * MathHelper.b((w / 180F) * 3.141593F);
+ t = -MathHelper.a((w / 180F) * 3.141593F);
+ a(s, t, u, 1.5F, 1.0F);
+ }
+
+ protected void a() {}
+
+ public void a(double d1, double d2, double d3, float f1, float f2) {
+ float f3 = MathHelper.a(d1 * d1 + d2 * d2 + d3 * d3);
+
+ d1 /= f3;
+ d2 /= f3;
+ d3 /= f3;
+ d1 += W.nextGaussian() * 0.0074999998323619366D * (double) f2;
+ d2 += W.nextGaussian() * 0.0074999998323619366D * (double) f2;
+ d3 += W.nextGaussian() * 0.0074999998323619366D * (double) f2;
+ d1 *= f1;
+ d2 *= f1;
+ d3 *= f1;
+ s = d1;
+ t = d2;
+ u = d3;
+ float f4 = MathHelper.a(d1 * d1 + d3 * d3);
+
+ x = v = (float) ((Math.atan2(d1, d3) * 180D) / 3.1415927410125732D);
+ y = w = (float) ((Math.atan2(d2, f4) * 180D) / 3.1415927410125732D);
+ al = 0;
+ }
+
+ public void b_() {
+ super.b_();
+ if (y == 0.0F && x == 0.0F) {
+ float f1 = MathHelper.a(s * s + u * u);
+
+ x = v = (float) ((Math.atan2(s, u) * 180D) / 3.1415927410125732D);
+ y = w = (float) ((Math.atan2(t, f1) * 180D) / 3.1415927410125732D);
+ }
+ if (a > 0) {
+ a--;
+ }
+ if (ak) {
+ int i = l.a(c, d, e);
+
+ if (i != f) {
+ ak = false;
+ s *= W.nextFloat() * 0.2F;
+ t *= W.nextFloat() * 0.2F;
+ u *= W.nextFloat() * 0.2F;
+ al = 0;
+ am = 0;
+ } else {
+ al++;
+ if (al == 1200) {
+ q();
+ }
+ return;
+ }
+ } else {
+ am++;
+ }
+ Vec3D vec3d = Vec3D.b(p, q, r);
+ Vec3D vec3d1 = Vec3D.b(p + s, q + t, r + u);
+ MovingObjectPosition movingobjectposition = l.a(vec3d, vec3d1);
+
+ vec3d = Vec3D.b(p, q, r);
+ vec3d1 = Vec3D.b(p + s, q + t, r + u);
+ if (movingobjectposition != null) {
+ vec3d1 = Vec3D.b(movingobjectposition.f.a, movingobjectposition.f.b, movingobjectposition.f.c);
+ }
+ Entity entity = null;
+ List list = l.b(((Entity) (this)), z.a(s, t, u).b(1.0D, 1.0D, 1.0D));
+ double d1 = 0.0D;
+
+ for (int j = 0; j < list.size(); j++) {
+ Entity entity1 = (Entity) list.get(j);
+
+ if (!entity1.c_() || entity1 == b && am < 5) {
+ continue;
+ }
+ float f5 = 0.3F;
+ AxisAlignedBB axisalignedbb = entity1.z.b(f5, f5, f5);
+ MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1);
+
+ if (movingobjectposition1 == null) {
+ continue;
+ }
+ double d2 = vec3d.a(movingobjectposition1.f);
+
+ if (d2 < d1 || d1 == 0.0D) {
+ entity = entity1;
+ d1 = d2;
+ }
+ }
+
+ if (entity != null) {
+ movingobjectposition = new MovingObjectPosition(entity);
+ }
+ if (movingobjectposition != null) {
+ if (movingobjectposition.g != null) {
+ // CraftBukkit start
+ boolean bounce;
+ if (entity instanceof EntityLiving) {
+ CraftServer server = ((WorldServer) this.l).getServer();
+ CraftEntity damagee = new CraftLivingEntity(server, (EntityLiving) entity);
+ CraftEntity damager = new CraftLivingEntity(server, b);
+ CraftEntity projectile = new CraftArrow(server, (EntityArrow) this);
+
+ //TODO decide if we should create DamageCause.ARROW, DamageCause.PROJECTILE
+ // or leave as DamageCause.ENTITY_ATTACK
+ EntityDamageByProjectileEvent edbpe = new EntityDamageByProjectileEvent(
+ damager, damagee, projectile, EntityDamageEvent.DamageCause.ENTITY_ATTACK, 4);
+
+ server.getPluginManager().callEvent(edbpe);
+ if(!edbpe.isCancelled()) {
+ // this function returns if the arrow should stick in or not, i.e. !bounce
+ bounce = !movingobjectposition.g.a(((Entity) (b)), edbpe.getDamage());
+ } else {
+ // event was cancelled, get if the arrow should bounce or not
+ bounce = edbpe.getBounce();
+ }
+ } else {
+ bounce = !movingobjectposition.g.a(((Entity) (b)), 4);
+ }
+ if (!bounce) {
+ // CraftBukkit end
+ l.a(((Entity) (this)), "random.drr", 1.0F, 1.2F / (W.nextFloat() * 0.2F + 0.9F));
+ q();
+ } else {
+ s *= -0.10000000149011612D;
+ t *= -0.10000000149011612D;
+ u *= -0.10000000149011612D;
+ v += 180F;
+ x += 180F;
+ am = 0;
+ }
+ } else {
+ c = movingobjectposition.b;
+ d = movingobjectposition.c;
+ e = movingobjectposition.d;
+ f = l.a(c, d, e);
+ s = (float) (movingobjectposition.f.a - p);
+ t = (float) (movingobjectposition.f.b - q);
+ u = (float) (movingobjectposition.f.c - r);
+ float f2 = MathHelper.a(s * s + t * t + u * u);
+
+ p -= (s / (double) f2) * 0.05000000074505806D;
+ q -= (t / (double) f2) * 0.05000000074505806D;
+ r -= (u / (double) f2) * 0.05000000074505806D;
+ l.a(((Entity) (this)), "random.drr", 1.0F, 1.2F / (W.nextFloat() * 0.2F + 0.9F));
+ ak = true;
+ a = 7;
+ }
+ }
+ p += s;
+ q += t;
+ r += u;
+ float f3 = MathHelper.a(s * s + u * u);
+
+ v = (float) ((Math.atan2(s, u) * 180D) / 3.1415927410125732D);
+ for (w = (float) ((Math.atan2(t, f3) * 180D) / 3.1415927410125732D); w - y < -180F; y -= 360F) {
+ ;
+ }
+ for (; w - y >= 180F; y += 360F) {
+ ;
+ }
+ for (; v - x < -180F; x -= 360F) {
+ ;
+ }
+ for (; v - x >= 180F; x += 360F) {
+ ;
+ }
+ w = y + (w - y) * 0.2F;
+ v = x + (v - x) * 0.2F;
+ float f4 = 0.99F;
+ float f6 = 0.03F;
+
+ if (v()) {
+ for (int k = 0; k < 4; k++) {
+ float f7 = 0.25F;
+
+ l.a("bubble", p - s * (double) f7, q - t * (double) f7, r - u * (double) f7, s, t, u);
+ }
+
+ f4 = 0.8F;
+ }
+ s *= f4;
+ t *= f4;
+ u *= f4;
+ t -= f6;
+ a(p, q, r);
+ }
+
+ public void a(NBTTagCompound nbttagcompound) {
+ nbttagcompound.a("xTile", (short) c);
+ nbttagcompound.a("yTile", (short) d);
+ nbttagcompound.a("zTile", (short) e);
+ nbttagcompound.a("inTile", (byte) f);
+ nbttagcompound.a("shake", (byte) a);
+ nbttagcompound.a("inGround", (byte) (ak ? 1 : 0));
+ }
+
+ public void b(NBTTagCompound nbttagcompound) {
+ c = ((int) (nbttagcompound.c("xTile")));
+ d = ((int) (nbttagcompound.c("yTile")));
+ e = ((int) (nbttagcompound.c("zTile")));
+ f = nbttagcompound.b("inTile") & 0xff;
+ a = nbttagcompound.b("shake") & 0xff;
+ ak = nbttagcompound.b("inGround") == 1;
+ }
+
+ public void b(EntityPlayer entityplayer) {
+ if (l.z) {
+ return;
+ }
+ if (ak && b == entityplayer && a <= 0 && entityplayer.an.a(new ItemStack(Item.j, 1))) {
+ l.a(((Entity) (this)), "random.pop", 0.2F, ((W.nextFloat() - W.nextFloat()) * 0.7F + 1.0F) * 2.0F);
+ entityplayer.c(((Entity) (this)), 1);
+ q();
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/EntityEgg.java b/src/main/java/net/minecraft/server/EntityEgg.java
index bad76af2..ed244d26 100644
--- a/src/main/java/net/minecraft/server/EntityEgg.java
+++ b/src/main/java/net/minecraft/server/EntityEgg.java
@@ -2,11 +2,19 @@ package net.minecraft.server;
import java.util.List;
import java.util.Random;
+
+// CraftBukkit start
import org.bukkit.entity.MobType;
+import org.bukkit.craftbukkit.entity.CraftEgg;
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.event.Event.Type;
+import org.bukkit.event.entity.EntityDamageByProjectileEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerEggThrowEvent;
+// CraftBukkit end
public class EntityEgg extends Entity {
@@ -165,7 +173,30 @@ public class EntityEgg extends Entity {
}
if (movingobjectposition != null) {
if (movingobjectposition.g != null) {
- if (!movingobjectposition.g.a(((Entity) (ak)), 0)) {
+ // CraftBukkit start
+ boolean bounce;
+ if (movingobjectposition.g instanceof EntityLiving) {
+ CraftServer server = ((WorldServer) this.l).getServer();
+ CraftEntity damagee = new CraftLivingEntity(server, (EntityLiving) movingobjectposition.g);
+ CraftEntity damager = new CraftLivingEntity(server, ak);
+ CraftEntity projectile = new CraftEgg(server, (EntityEgg) this);
+
+ //TODO @see EntityArrow#162
+ EntityDamageByProjectileEvent edbpe = new EntityDamageByProjectileEvent( damager, damagee, projectile, EntityDamageEvent.DamageCause.ENTITY_ATTACK, 0);
+
+ server.getPluginManager().callEvent(edbpe);
+ if(!edbpe.isCancelled()) {
+ // this function returns if the egg should stick or not, i.e. !bounce
+ bounce = !movingobjectposition.g.a(((Entity) (ak)), edbpe.getDamage());
+ } else {
+ // event was cancelled, get if the egg should bounce or not
+ bounce = edbpe.getBounce();
+ }
+ } else {
+ bounce = !movingobjectposition.g.a(((Entity) (ak)), 0);
+ }
+ if (!bounce) {
+ // CraftBukkit end
;
}
}
@@ -230,7 +261,7 @@ public class EntityEgg extends Entity {
this.l.a(entity);
}
}
- // Craftbukkit stop
+ // CraftBukkit end
for (int j = 0; j < 8; j++) {
this.l.a("snowballpoof", p, q, r, 0.0D, 0.0D, 0.0D);
diff --git a/src/main/java/net/minecraft/server/EntityFireball.java b/src/main/java/net/minecraft/server/EntityFireball.java
new file mode 100644
index 00000000..6623f1e1
--- /dev/null
+++ b/src/main/java/net/minecraft/server/EntityFireball.java
@@ -0,0 +1,245 @@
+package net.minecraft.server;
+
+import java.util.List;
+import java.util.Random;
+
+//CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.craftbukkit.entity.CraftFireball;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.event.entity.EntityDamageByProjectileEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+//CraftBukkit end
+
+public class EntityFireball extends Entity {
+
+ private int e;
+ private int f;
+ private int ak;
+ private int al;
+ private boolean am;
+ public int a;
+ private EntityLiving an;
+ private int ao;
+ private int ap;
+ public double b;
+ public double c;
+ public double d;
+
+ public EntityFireball(World world) {
+ super(world);
+ e = -1;
+ f = -1;
+ ak = -1;
+ al = 0;
+ am = false;
+ a = 0;
+ ap = 0;
+ a(1.0F, 1.0F);
+ }
+
+ protected void a() {}
+
+ public EntityFireball(World world, EntityLiving entityliving, double d1, double d2, double d3) {
+ super(world);
+ e = -1;
+ f = -1;
+ ak = -1;
+ al = 0;
+ am = false;
+ a = 0;
+ ap = 0;
+ an = entityliving;
+ a(1.0F, 1.0F);
+ c(entityliving.p, entityliving.q, entityliving.r, entityliving.v, entityliving.w);
+ a(p, q, r);
+ H = 0.0F;
+ s = t = u = 0.0D;
+ d1 += W.nextGaussian() * 0.40000000000000002D;
+ d2 += W.nextGaussian() * 0.40000000000000002D;
+ d3 += W.nextGaussian() * 0.40000000000000002D;
+ double d4 = MathHelper.a(d1 * d1 + d2 * d2 + d3 * d3);
+
+ b = (d1 / d4) * 0.10000000000000001D;
+ c = (d2 / d4) * 0.10000000000000001D;
+ d = (d3 / d4) * 0.10000000000000001D;
+ }
+
+ public void b_() {
+ super.b_();
+ Z = 10;
+ if (a > 0) {
+ a--;
+ }
+ if (am) {
+ int i = l.a(e, f, ak);
+
+ if (i != al) {
+ am = false;
+ s *= W.nextFloat() * 0.2F;
+ t *= W.nextFloat() * 0.2F;
+ u *= W.nextFloat() * 0.2F;
+ ao = 0;
+ ap = 0;
+ } else {
+ ao++;
+ if (ao == 1200) {
+ q();
+ }
+ return;
+ }
+ } else {
+ ap++;
+ }
+ Vec3D vec3d = Vec3D.b(p, q, r);
+ Vec3D vec3d1 = Vec3D.b(p + s, q + t, r + u);
+ MovingObjectPosition movingobjectposition = l.a(vec3d, vec3d1);
+
+ vec3d = Vec3D.b(p, q, r);
+ vec3d1 = Vec3D.b(p + s, q + t, r + u);
+ if (movingobjectposition != null) {
+ vec3d1 = Vec3D.b(movingobjectposition.f.a, movingobjectposition.f.b, movingobjectposition.f.c);
+ }
+ Entity entity = null;
+ List list = l.b(((Entity) (this)), z.a(s, t, u).b(1.0D, 1.0D, 1.0D));
+ double d1 = 0.0D;
+
+ for (int j = 0; j < list.size(); j++) {
+ Entity entity1 = (Entity) list.get(j);
+
+ if (!entity1.c_() || entity1 == an && ap < 25) {
+ continue;
+ }
+ float f3 = 0.3F;
+ AxisAlignedBB axisalignedbb = entity1.z.b(f3, f3, f3);
+ MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1);
+
+ if (movingobjectposition1 == null) {
+ continue;
+ }
+ double d2 = vec3d.a(movingobjectposition1.f);
+
+ if (d2 < d1 || d1 == 0.0D) {
+ entity = entity1;
+ d1 = d2;
+ }
+ }
+
+ if (entity != null) {
+ movingobjectposition = new MovingObjectPosition(entity);
+ }
+ if (movingobjectposition != null) {
+ if (movingobjectposition.g != null) {
+ // CraftBukkit start
+ boolean bounce;
+ if (movingobjectposition.g instanceof EntityLiving) {
+ CraftServer server = ((WorldServer) this.l).getServer();
+ CraftEntity damagee = new CraftLivingEntity(server, (EntityLiving) movingobjectposition.g);
+ CraftEntity damager = new CraftLivingEntity(server, an);
+ CraftEntity projectile = new CraftFireball(server, (EntityFireball) this);
+
+ //TODO @see EntityArrow#162
+ EntityDamageByProjectileEvent edbpe = new EntityDamageByProjectileEvent( damager, damagee, projectile, EntityDamageEvent.DamageCause.ENTITY_ATTACK, 0);
+
+ server.getPluginManager().callEvent(edbpe);
+ if(!edbpe.isCancelled()) {
+ // this function returns if the fireball should stick or not, i.e. !bounce
+ bounce = !movingobjectposition.g.a(((Entity) (an)), edbpe.getDamage());
+ } else {
+ // event was cancelled, get if the fireball should bounce or not
+ bounce = edbpe.getBounce();
+ }
+ } else {
+ bounce = !movingobjectposition.g.a(((Entity) (an)), 0);
+ }
+ if (!bounce) {
+ // CraftBukkit end
+ ;
+ }
+ }
+ l.a(((Entity) (null)), p, q, r, 1.0F, true);
+ q();
+ }
+ p += s;
+ q += t;
+ r += u;
+ float f1 = MathHelper.a(s * s + u * u);
+
+ v = (float) ((Math.atan2(s, u) * 180D) / 3.1415927410125732D);
+ for (w = (float) ((Math.atan2(t, f1) * 180D) / 3.1415927410125732D); w - y < -180F; y -= 360F) {
+ ;
+ }
+ for (; w - y >= 180F; y += 360F) {
+ ;
+ }
+ for (; v - x < -180F; x -= 360F) {
+ ;
+ }
+ for (; v - x >= 180F; x += 360F) {
+ ;
+ }
+ w = y + (w - y) * 0.2F;
+ v = x + (v - x) * 0.2F;
+ float f2 = 0.95F;
+
+ if (v()) {
+ for (int k = 0; k < 4; k++) {
+ float f4 = 0.25F;
+
+ l.a("bubble", p - s * (double) f4, q - t * (double) f4, r - u * (double) f4, s, t, u);
+ }
+
+ f2 = 0.8F;
+ }
+ s += b;
+ t += c;
+ u += d;
+ s *= f2;
+ t *= f2;
+ u *= f2;
+ l.a("smoke", p, q + 0.5D, r, 0.0D, 0.0D, 0.0D);
+ a(p, q, r);
+ }
+
+ public void a(NBTTagCompound nbttagcompound) {
+ nbttagcompound.a("xTile", (short) e);
+ nbttagcompound.a("yTile", (short) f);
+ nbttagcompound.a("zTile", (short) ak);
+ nbttagcompound.a("inTile", (byte) al);
+ nbttagcompound.a("shake", (byte) a);
+ nbttagcompound.a("inGround", (byte) (am ? 1 : 0));
+ }
+
+ public void b(NBTTagCompound nbttagcompound) {
+ e = ((int) (nbttagcompound.c("xTile")));
+ f = ((int) (nbttagcompound.c("yTile")));
+ ak = ((int) (nbttagcompound.c("zTile")));
+ al = nbttagcompound.b("inTile") & 0xff;
+ a = nbttagcompound.b("shake") & 0xff;
+ am = nbttagcompound.b("inGround") == 1;
+ }
+
+ public boolean c_() {
+ return true;
+ }
+
+ public boolean a(Entity entity, int i) {
+ y();
+ if (entity != null) {
+ Vec3D vec3d = entity.G();
+
+ if (vec3d != null) {
+ s = vec3d.a;
+ t = vec3d.b;
+ u = vec3d.c;
+ b = s * 0.10000000000000001D;
+ c = t * 0.10000000000000001D;
+ d = u * 0.10000000000000001D;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/EntityFish.java b/src/main/java/net/minecraft/server/EntityFish.java
new file mode 100644
index 00000000..ed566928
--- /dev/null
+++ b/src/main/java/net/minecraft/server/EntityFish.java
@@ -0,0 +1,367 @@
+package net.minecraft.server;
+
+import java.util.List;
+import java.util.Random;
+
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.craftbukkit.entity.CraftFireball;
+import org.bukkit.craftbukkit.entity.CraftFish;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.event.entity.EntityDamageByProjectileEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+//CraftBukkit end
+
+public class EntityFish extends Entity {
+
+ private int d;
+ private int e;
+ private int f;
+ private int ak;
+ private boolean al;
+ public int a;
+ public EntityPlayer b;
+ private int am;
+ private int an;
+ private int ao;
+ public Entity c;
+ private int ap;
+ private double aq;
+ private double ar;
+ private double as;
+ private double at;
+ private double au;
+
+ public EntityFish(World world) {
+ super(world);
+ d = -1;
+ e = -1;
+ f = -1;
+ ak = 0;
+ al = false;
+ a = 0;
+ an = 0;
+ ao = 0;
+ c = null;
+ a(0.25F, 0.25F);
+ }
+
+ protected void a() {}
+
+ public EntityFish(World world, EntityPlayer entityplayer) {
+ super(world);
+ d = -1;
+ e = -1;
+ f = -1;
+ ak = 0;
+ al = false;
+ a = 0;
+ an = 0;
+ ao = 0;
+ c = null;
+ b = entityplayer;
+ b.aE = this;
+ a(0.25F, 0.25F);
+ c(entityplayer.p, (entityplayer.q + 1.6200000000000001D) - (double) entityplayer.H, entityplayer.r, entityplayer.v, entityplayer.w);
+ p -= MathHelper.b((v / 180F) * 3.141593F) * 0.16F;
+ q -= 0.10000000149011612D;
+ r -= MathHelper.a((v / 180F) * 3.141593F) * 0.16F;
+ a(p, q, r);
+ H = 0.0F;
+ float f1 = 0.4F;
+
+ s = -MathHelper.a((v / 180F) * 3.141593F) * MathHelper.b((w / 180F) * 3.141593F) * f1;
+ u = MathHelper.b((v / 180F) * 3.141593F) * MathHelper.b((w / 180F) * 3.141593F) * f1;
+ t = -MathHelper.a((w / 180F) * 3.141593F) * f1;
+ a(s, t, u, 1.5F, 1.0F);
+ }
+
+ public void a(double d1, double d2, double d3, float f1, float f2) {
+ float f3 = MathHelper.a(d1 * d1 + d2 * d2 + d3 * d3);
+
+ d1 /= f3;
+ d2 /= f3;
+ d3 /= f3;
+ d1 += W.nextGaussian() * 0.0074999998323619366D * (double) f2;
+ d2 += W.nextGaussian() * 0.0074999998323619366D * (double) f2;
+ d3 += W.nextGaussian() * 0.0074999998323619366D * (double) f2;
+ d1 *= f1;
+ d2 *= f1;
+ d3 *= f1;
+ s = d1;
+ t = d2;
+ u = d3;
+ float f4 = MathHelper.a(d1 * d1 + d3 * d3);
+
+ x = v = (float) ((Math.atan2(d1, d3) * 180D) / 3.1415927410125732D);
+ y = w = (float) ((Math.atan2(d2, f4) * 180D) / 3.1415927410125732D);
+ am = 0;
+ }
+
+ public void b_() {
+ super.b_();
+ if (ap > 0) {
+ double d1 = p + (aq - p) / (double) ap;
+ double d2 = q + (ar - q) / (double) ap;
+ double d3 = r + (as - r) / (double) ap;
+ double d4;
+
+ for (d4 = at - (double) v; d4 < -180D; d4 += 360D) {
+ ;
+ }
+ for (; d4 >= 180D; d4 -= 360D) {
+ ;
+ }
+ v += ((float) (d4 / (double) ap));
+ w += ((float) ((au - (double) w) / (double) ap));
+ ap--;
+ a(d1, d2, d3);
+ b(v, w);
+ return;
+ }
+ if (!this.l.z) {
+ ItemStack itemstack = b.P();
+
+ if (b.G || !b.B() || itemstack == null || itemstack.a() != Item.aP || b(((Entity) (b))) > 1024D) {
+ q();
+ b.aE = null;
+ return;
+ }
+ if (c != null) {
+ if (c.G) {
+ c = null;
+ } else {
+ p = c.p;
+ q = c.z.b + (double) c.J * 0.80000000000000004D;
+ r = c.r;
+ return;
+ }
+ }
+ }
+ if (a > 0) {
+ a--;
+ }
+ if (al) {
+ int i = this.l.a(d, e, f);
+
+ if (i != ak) {
+ al = false;
+ s *= W.nextFloat() * 0.2F;
+ t *= W.nextFloat() * 0.2F;
+ u *= W.nextFloat() * 0.2F;
+ am = 0;
+ an = 0;
+ } else {
+ am++;
+ if (am == 1200) {
+ q();
+ }
+ return;
+ }
+ } else {
+ an++;
+ }
+ Vec3D vec3d = Vec3D.b(p, q, r);
+ Vec3D vec3d1 = Vec3D.b(p + s, q + t, r + u);
+ MovingObjectPosition movingobjectposition = this.l.a(vec3d, vec3d1);
+
+ vec3d = Vec3D.b(p, q, r);
+ vec3d1 = Vec3D.b(p + s, q + t, r + u);
+ if (movingobjectposition != null) {
+ vec3d1 = Vec3D.b(movingobjectposition.f.a, movingobjectposition.f.b, movingobjectposition.f.c);
+ }
+ Entity entity = null;
+ List list = this.l.b(((Entity) (this)), z.a(s, t, u).b(1.0D, 1.0D, 1.0D));
+ double d5 = 0.0D;
+
+ for (int j = 0; j < list.size(); j++) {
+ Entity entity1 = (Entity) list.get(j);
+
+ if (!entity1.c_() || entity1 == b && an < 5) {
+ continue;
+ }
+ float f3 = 0.3F;
+ AxisAlignedBB axisalignedbb = entity1.z.b(f3, f3, f3);
+ MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1);
+
+ if (movingobjectposition1 == null) {
+ continue;
+ }
+ double d6 = vec3d.a(movingobjectposition1.f);
+
+ if (d6 < d5 || d5 == 0.0D) {
+ entity = entity1;
+ d5 = d6;
+ }
+ }
+
+ if (entity != null) {
+ movingobjectposition = new MovingObjectPosition(entity);
+ }
+ if (movingobjectposition != null) {
+ if (movingobjectposition.g != null) {
+ // CraftBukkit start
+ //TODO add EntityDamagedByProjectileEvent : fishing hook?
+ boolean bounce;
+ if (movingobjectposition.g instanceof EntityLiving) {
+ CraftServer server = ((WorldServer) this.l).getServer();
+ CraftEntity damagee = new CraftLivingEntity(server, (EntityLiving) movingobjectposition.g);
+ CraftEntity damager = new CraftLivingEntity(server, b);
+ CraftEntity projectile = new CraftFish(server, (EntityFish) this);
+
+ //TODO @see EntityArrow#162
+ EntityDamageByProjectileEvent edbpe = new EntityDamageByProjectileEvent( damager, damagee, projectile, EntityDamageEvent.DamageCause.ENTITY_ATTACK, 0);
+
+ server.getPluginManager().callEvent(edbpe);
+ if(!edbpe.isCancelled()) {
+ // this function returns if the fish should stick or not, i.e. !bounce
+ bounce = !movingobjectposition.g.a(((Entity) (b)), edbpe.getDamage());
+ } else {
+ // event was cancelled, get if the fish should bounce or not
+ bounce = edbpe.getBounce();
+ }
+ } else {
+ bounce = !movingobjectposition.g.a(((Entity) (b)), 0);
+ }
+ if (!bounce) {
+ // CraftBukkit end
+ c = movingobjectposition.g;
+ }
+ } else {
+ al = true;
+ }
+ }
+ if (al) {
+ return;
+ }
+ c(s, t, u);
+ float f1 = MathHelper.a(s * s + u * u);
+
+ v = (float) ((Math.atan2(s, u) * 180D) / 3.1415927410125732D);
+ for (w = (float) ((Math.atan2(t, f1) * 180D) / 3.1415927410125732D); w - y < -180F; y -= 360F) {
+ ;
+ }
+ for (; w - y >= 180F; y += 360F) {
+ ;
+ }
+ for (; v - x < -180F; x -= 360F) {
+ ;
+ }
+ for (; v - x >= 180F; x += 360F) {
+ ;
+ }
+ w = y + (w - y) * 0.2F;
+ v = x + (v - x) * 0.2F;
+ float f2 = 0.92F;
+
+ if (A || B) {
+ f2 = 0.5F;
+ }
+ int k = 5;
+ double d8 = 0.0D;
+
+ for (int l = 0; l < k; l++) {
+ double d9 = ((z.b + ((z.e - z.b) * (double) (l + 0)) / (double) k) - 0.125D) + 0.125D;
+ double d10 = ((z.b + ((z.e - z.b) * (double) (l + 1)) / (double) k) - 0.125D) + 0.125D;
+ AxisAlignedBB axisalignedbb1 = AxisAlignedBB.b(z.a, d9, z.c, z.d, d10, z.f);
+
+ if (this.l.b(axisalignedbb1, Material.f)) {
+ d8 += 1.0D / (double) k;
+ }
+ }
+
+ if (d8 > 0.0D) {
+ if (ao > 0) {
+ ao--;
+ } else if (W.nextInt(500) == 0) {
+ ao = W.nextInt(30) + 10;
+ t -= 0.20000000298023224D;
+ this.l.a(((Entity) (this)), "random.splash", 0.25F, 1.0F + (W.nextFloat() - W.nextFloat()) * 0.4F);
+ float f4 = MathHelper.b(z.b);
+
+ for (int i1 = 0; (float) i1 < 1.0F + I * 20F; i1++) {
+ float f5 = (W.nextFloat() * 2.0F - 1.0F) * I;
+ float f7 = (W.nextFloat() * 2.0F - 1.0F) * I;
+
+ this.l.a("bubble", p + (double) f5, f4 + 1.0F, r + (double) f7, s, t - (double) (W.nextFloat() * 0.2F), u);
+ }
+
+ for (int j1 = 0; (float) j1 < 1.0F + I * 20F; j1++) {
+ float f6 = (W.nextFloat() * 2.0F - 1.0F) * I;
+ float f8 = (W.nextFloat() * 2.0F - 1.0F) * I;
+
+ this.l.a("splash", p + (double) f6, f4 + 1.0F, r + (double) f8, s, t, u);
+ }
+ }
+ }
+ if (ao > 0) {
+ t -= (double) (W.nextFloat() * W.nextFloat() * W.nextFloat()) * 0.20000000000000001D;
+ }
+ double d7 = d8 * 2D - 1.0D;
+
+ t += 0.039999999105930328D * d7;
+ if (d8 > 0.0D) {
+ f2 = (float) ((double) f2 * 0.90000000000000002D);
+ t *= 0.80000000000000004D;
+ }
+ s *= f2;
+ t *= f2;
+ u *= f2;
+ a(p, q, r);
+ }
+
+ public void a(NBTTagCompound nbttagcompound) {
+ nbttagcompound.a("xTile", (short) d);
+ nbttagcompound.a("yTile", (short) e);
+ nbttagcompound.a("zTile", (short) f);
+ nbttagcompound.a("inTile", (byte) ak);
+ nbttagcompound.a("shake", (byte) a);
+ nbttagcompound.a("inGround", (byte) (al ? 1 : 0));
+ }
+
+ public void b(NBTTagCompound nbttagcompound) {
+ d = ((int) (nbttagcompound.c("xTile")));
+ e = ((int) (nbttagcompound.c("yTile")));
+ f = ((int) (nbttagcompound.c("zTile")));
+ ak = nbttagcompound.b("inTile") & 0xff;
+ a = nbttagcompound.b("shake") & 0xff;
+ al = nbttagcompound.b("inGround") == 1;
+ }
+
+ public int d() {
+ byte byte0 = 0;
+
+ if (c != null) {
+ double d1 = b.p - p;
+ double d2 = b.q - q;
+ double d3 = b.r - r;
+ double d4 = MathHelper.a(d1 * d1 + d2 * d2 + d3 * d3);
+ double d5 = 0.10000000000000001D;
+
+ c.s += d1 * d5;
+ c.t += d2 * d5 + (double) MathHelper.a(d4) * 0.080000000000000002D;
+ c.u += d3 * d5;
+ byte0 = 3;
+ } else if (ao > 0) {
+ EntityItem entityitem = new EntityItem(l, p, q, r, new ItemStack(Item.aS));
+ double d6 = b.p - p;
+ double d7 = b.q - q;
+ double d8 = b.r - r;
+ double d9 = MathHelper.a(d6 * d6 + d7 * d7 + d8 * d8);
+ double d10 = 0.10000000000000001D;
+
+ entityitem.s = d6 * d10;
+ entityitem.t = d7 * d10 + (double) MathHelper.a(d9) * 0.080000000000000002D;
+ entityitem.u = d8 * d10;
+ l.a(((Entity) (entityitem)));
+ byte0 = 1;
+ }
+ if (al) {
+ byte0 = 2;
+ }
+ q();
+ b.aE = null;
+ return ((int) (byte0));
+ }
+}
diff --git a/src/main/java/net/minecraft/server/EntityMobs.java b/src/main/java/net/minecraft/server/EntityMobs.java
new file mode 100644
index 00000000..633339a0
--- /dev/null
+++ b/src/main/java/net/minecraft/server/EntityMobs.java
@@ -0,0 +1,111 @@
+package net.minecraft.server;
+
+import java.util.Random;
+
+//CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.event.entity.EntityDamageByBlockEvent;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+//CraftBukkit end
+
+public class EntityMobs extends EntityCreature implements IMobs {
+
+ protected int c;
+
+ public EntityMobs(World world) {
+ super(world);
+ c = 2;
+ aZ = 20;
+ }
+
+ public void o() {
+ float f = b(1.0F);
+
+ if (f > 0.5F) {
+ bw += 2;
+ }
+ super.o();
+ }
+
+ public void b_() {
+ super.b_();
+ if (l.k == 0) {
+ q();
+ }
+ }
+
+ protected Entity l() {
+ EntityPlayer entityplayer = l.a(((Entity) (this)), 16D);
+
+ if (entityplayer != null && i(((Entity) (entityplayer)))) {
+ return ((Entity) (entityplayer));
+ } else {
+ return null;
+ }
+ }
+
+ public boolean a(Entity entity, int i) {
+ if (super.a(entity, i)) {
+ if (j == entity || k == entity) {
+ return true;
+ }
+ if (entity != this) {
+ d = entity;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected void a(Entity entity, float f) {
+ if ((double) f < 2.5D && entity.z.e > z.b && entity.z.b < z.e) {
+ bf = 20;
+ // CraftBukkit start
+ if(entity instanceof EntityLiving) {
+ CraftServer server = ((WorldServer) l).getServer();
+ CraftEntity damagee = new CraftLivingEntity(server, (EntityLiving) entity);
+ CraftEntity damager = new CraftLivingEntity(server, this);
+
+ EntityDamageByEntityEvent edbee = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK, c);
+ server.getPluginManager().callEvent(edbee);
+
+ if (!edbee.isCancelled()){
+ entity.a(((Entity) (null)), edbee.getDamage());
+ }
+ } else {
+ entity.a(((Entity) (this)), c);
+ }
+ // CraftBukkit end
+ }
+ }
+
+ protected float a(int i, int j, int k) {
+ return 0.5F - l.l(i, j, k);
+ }
+
+ public void a(NBTTagCompound nbttagcompound) {
+ super.a(nbttagcompound);
+ }
+
+ public void b(NBTTagCompound nbttagcompound) {
+ super.b(nbttagcompound);
+ }
+
+ public boolean b() {
+ int i = MathHelper.b(p);
+ int j = MathHelper.b(z.b);
+ int k = MathHelper.b(r);
+
+ if (l.a(EnumSkyBlock.a, i, j, k) > W.nextInt(32)) {
+ return false;
+ } else {
+ int i1 = l.j(i, j, k);
+
+ return i1 <= W.nextInt(8) && super.b();
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
new file mode 100644
index 00000000..96ba9630
--- /dev/null
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +1,377 @@
+package net.minecraft.server;
+
+import java.util.List;
+import java.util.Random;
+
+// CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+// CraftBukkit end
+
+public abstract class EntityPlayer extends EntityLiving {
+
+ public InventoryPlayer an;
+ public CraftingInventoryCB ao;
+ public CraftingInventoryCB ap;
+ public byte aq;
+ public int ar;
+ public float as;
+ public float at;
+ public boolean au;
+ public int av;
+ public String aw;
+ public int ax;
+ public double ay;
+ public double az;
+ public double aA;
+ public double aB;
+ public double aC;
+ public double aD;
+ private int a;
+ public EntityFish aE;
+
+ public EntityPlayer(World world) {
+ super(world);
+ an = new InventoryPlayer(this);
+ aq = 0;
+ ar = 0;
+ au = false;
+ av = 0;
+ a = 0;
+ aE = null;
+ ao = ((CraftingInventoryCB) (new CraftingInventoryPlayerCB(an, !world.z)));
+ ap = ao;
+ H = 1.62F;
+ c((double) world.m + 0.5D, world.n + 1, (double) world.o + 0.5D, 0.0F, 0.0F);
+ aZ = 20;
+ aS = "humanoid";
+ aR = 180F;
+ Y = 20;
+ aP = "/mob/char.png";
+ }
+
+ public void b_() {
+ super.b_();
+ if (!l.z && ap != null && !ap.b(this)) {
+ L();
+ ap = ao;
+ }
+ ay = aB;
+ az = aC;
+ aA = aD;
+ double d1 = p - aB;
+ double d2 = q - aC;
+ double d3 = r - aD;
+ double d4 = 10D;
+
+ if (d1 > d4) {
+ ay = aB = p;
+ }
+ if (d3 > d4) {
+ aA = aD = r;
+ }
+ if (d2 > d4) {
+ az = aC = q;
+ }
+ if (d1 < -d4) {
+ ay = aB = p;
+ }
+ if (d3 < -d4) {
+ aA = aD = r;
+ }
+ if (d2 < -d4) {
+ az = aC = q;
+ }
+ aB += d1 * 0.25D;
+ aD += d3 * 0.25D;
+ aC += d2 * 0.25D;
+ }
+
+ protected void L() {
+ ap = ao;
+ }
+
+ public void D() {
+ super.D();
+ as = at;
+ at = 0.0F;
+ }
+
+ protected void d() {
+ if (au) {
+ av++;
+ if (av == 8) {
+ av = 0;
+ au = false;
+ }
+ } else {
+ av = 0;
+ }
+ aY = (float) av / 8F;
+ }
+
+ public void o() {
+ if (l.k == 0 && aZ < 20 && (X % 20) * 12 == 0) {
+ d(1);
+ }
+ an.f();
+ as = at;
+ super.o();
+ float f1 = MathHelper.a(s * s + u * u);
+ float f2 = (float) Math.atan(-t * 0.20000000298023224D) * 15F;
+
+ if (f1 > 0.1F) {
+ f1 = 0.1F;
+ }
+ if (!A || aZ <= 0) {
+ f1 = 0.0F;
+ }
+ if (A || aZ <= 0) {
+ f2 = 0.0F;
+ }
+ at += (f1 - at) * 0.4F;
+ bh += (f2 - bh) * 0.8F;
+ if (aZ > 0) {
+ List list = l.b(((Entity) (this)), z.b(1.0D, 0.0D, 1.0D));
+
+ if (list != null) {
+ for (int i = 0; i < list.size(); i++) {
+ Entity entity = (Entity) list.get(i);
+
+ if (!entity.G) {
+ j(entity);
+ }
+ }
+ }
+ }
+ }
+
+ private void j(Entity entity) {
+ entity.b(this);
+ }
+
+ public void f(Entity entity) {
+ super.f(entity);
+ a(0.2F, 0.2F);
+ a(p, q, r);
+ t = 0.10000000149011612D;
+ if (aw.equals("Notch")) {
+ a(new ItemStack(Item.h, 1), true);
+ }
+ an.h();
+ if (entity != null) {
+ s = -MathHelper.b(((bd + v) * 3.141593F) / 180F) * 0.1F;
+ u = -MathHelper.a(((bd + v) * 3.141593F) / 180F) * 0.1F;
+ } else {
+ s = u = 0.0D;
+ }
+ H = 0.1F;
+ }
+
+ public void b(Entity entity, int i) {
+ ar += i;
+ }
+
+ public void O() {
+ a(an.b(an.c, 1), false);
+ }
+
+ public void b(ItemStack itemstack) {
+ a(itemstack, false);
+ }
+
+ public void a(ItemStack itemstack, boolean flag) {
+ if (itemstack == null) {
+ return;
+ }
+ EntityItem entityitem = new EntityItem(l, p, (q - 0.30000001192092896D) + (double) w(), r, itemstack);
+
+ entityitem.c = 40;
+ float f1 = 0.1F;
+
+ if (flag) {
+ float f3 = W.nextFloat() * 0.5F;
+ float f5 = W.nextFloat() * 3.141593F * 2.0F;
+
+ entityitem.s = -MathHelper.a(f5) * f3;
+ entityitem.u = MathHelper.b(f5) * f3;
+ entityitem.t = 0.20000000298023224D;
+ } else {
+ float f2 = 0.3F;
+
+ entityitem.s = -MathHelper.a((v / 180F) * 3.141593F) * MathHelper.b((w / 180F) * 3.141593F) * f2;
+ entityitem.u = MathHelper.b((v / 180F) * 3.141593F) * MathHelper.b((w / 180F) * 3.141593F) * f2;
+ entityitem.t = -MathHelper.a((w / 180F) * 3.141593F) * f2 + 0.1F;
+ f2 = 0.02F;
+ float f4 = W.nextFloat() * 3.141593F * 2.0F;
+
+ f2 *= W.nextFloat();
+ entityitem.s += Math.cos(f4) * (double) f2;
+ entityitem.t += (W.nextFloat() - W.nextFloat()) * 0.1F;
+ entityitem.u += Math.sin(f4) * (double) f2;
+ }
+ a(entityitem);
+ }
+
+ protected void a(EntityItem entityitem) {
+ l.a(((Entity) (entityitem)));
+ }
+
+ public float a(Block block) {
+ float f1 = an.a(block);
+
+ if (a(Material.f)) {
+ f1 /= 5F;
+ }
+ if (!A) {
+ f1 /= 5F;
+ }
+ return f1;
+ }
+
+ public boolean b(Block block) {
+ return an.b(block);
+ }
+
+ public void b(NBTTagCompound nbttagcompound) {
+ super.b(nbttagcompound);
+ NBTTagList nbttaglist = nbttagcompound.k("Inventory");
+
+ an.b(nbttaglist);
+ ax = nbttagcompound.d("Dimension");
+ }
+
+ public void a(NBTTagCompound nbttagcompound) {
+ super.a(nbttagcompound);
+ nbttagcompound.a("Inventory", ((NBTBase) (an.a(new NBTTagList()))));
+ nbttagcompound.a("Dimension", ax);
+ }
+
+ public void a(IInventory iinventory) {}
+
+ public void a(int i, int k, int l) {}
+
+ public void c(Entity entity, int i) {}
+
+ public float w() {
+ return 0.12F;
+ }
+
+ public boolean a(Entity entity, int i) {
+ bw = 0;
+ if (aZ <= 0) {
+ return false;
+ }
+ if ((entity instanceof EntityMobs) || (entity instanceof EntityArrow)) {
+ if (l.k == 0) {
+ i = 0;
+ }
+ if (l.k == 1) {
+ i = i / 3 + 1;
+ }
+ if (l.k == 3) {
+ i = (i * 3) / 2;
+ }
+ }
+ if (i == 0) {
+ return false;
+ } else {
+ return super.a(entity, i);
+ }
+ }
+
+ protected void e(int i) {
+ int k = 25 - an.g();
+ int l = i * k + a;
+
+ an.c(i);
+ i = l / 25;
+ a = l % 25;
+ super.e(i);
+ }
+
+ public void a(TileEntityFurnace tileentityfurnace) {}
+
+ public void a(TileEntityDispenser tileentitydispenser) {}
+
+ public void a(TileEntitySign tileentitysign) {}
+
+ public void g(Entity entity) {
+ if (entity.a(this)) {
+ return;
+ }
+ ItemStack itemstack = P();
+
+ if (itemstack != null && (entity instanceof EntityLiving)) {
+ itemstack.b((EntityLiving) entity);
+ if (itemstack.a <= 0) {
+ itemstack.a(this);
+ Q();
+ }
+ }
+ }
+
+ public ItemStack P() {
+ return an.e();
+ }
+
+ public void Q() {
+ an.a(an.c, ((ItemStack) (null)));
+ }
+
+ public double F() {
+ return (double) (H - 0.5F);
+ }
+
+ public void K() {
+ av = -1;
+ au = true;
+ }
+
+ public void h(Entity entity) {
+ int i = an.a(entity);
+
+ if (i > 0) {
+ // CraftBukkit start
+ if(entity instanceof EntityLiving) {
+ CraftServer server = ((WorldServer) l).getServer();
+ CraftEntity damagee = new CraftLivingEntity(server, (EntityLiving) entity);
+ CraftEntity damager = new CraftLivingEntity(server, this);
+
+ EntityDamageByEntityEvent edbee = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK, i);
+ server.getPluginManager().callEvent(edbee);
+
+ if (!edbee.isCancelled()){
+ entity.a(((Entity) (null)), edbee.getDamage());
+ } else {
+ return;
+ }
+ } else {
+ entity.a(((Entity) (this)), i);
+ }
+ // CraftBukkit end
+ ItemStack itemstack = P();
+
+ if (itemstack != null && (entity instanceof EntityLiving)) {
+ itemstack.a((EntityLiving) entity);
+ if (itemstack.a <= 0) {
+ itemstack.a(this);
+ Q();
+ }
+ }
+ }
+ }
+
+ public void a(ItemStack itemstack) {}
+
+ public void q() {
+ super.q();
+ ao.a(this);
+ if (ap != null) {
+ ap.a(this);
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/EntitySnowball.java b/src/main/java/net/minecraft/server/EntitySnowball.java
new file mode 100644
index 00000000..4e479d53
--- /dev/null
+++ b/src/main/java/net/minecraft/server/EntitySnowball.java
@@ -0,0 +1,269 @@
+package net.minecraft.server;
+
+import java.util.List;
+import java.util.Random;
+
+//CraftBukkit start
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.craftbukkit.entity.CraftSnowball;
+import org.bukkit.event.entity.EntityDamageByProjectileEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
+//CraftBukkit end
+
+public class EntitySnowball extends Entity {
+
+ private int b;
+ private int c;
+ private int d;
+ private int e;
+ private boolean f;
+ public int a;
+ private EntityLiving ak;
+ private int al;
+ private int am;
+
+ public EntitySnowball(World world) {
+ super(world);
+ b = -1;
+ c = -1;
+ d = -1;
+ e = 0;
+ f = false;
+ a = 0;
+ am = 0;
+ a(0.25F, 0.25F);
+ }
+
+ protected void a() {}
+
+ public EntitySnowball(World world, EntityLiving entityliving) {
+ super(world);
+ b = -1;
+ c = -1;
+ d = -1;
+ e = 0;
+ f = false;
+ a = 0;
+ am = 0;
+ ak = entityliving;
+ a(0.25F, 0.25F);
+ c(entityliving.p, entityliving.q + (double) entityliving.w(), entityliving.r, entityliving.v, entityliving.w);
+ p -= MathHelper.b((v / 180F) * 3.141593F) * 0.16F;
+ q -= 0.10000000149011612D;
+ r -= MathHelper.a((v / 180F) * 3.141593F) * 0.16F;
+ a(p, q, r);
+ H = 0.0F;
+ float f1 = 0.4F;
+
+ s = -MathHelper.a((v / 180F) * 3.141593F) * MathHelper.b((w / 180F) * 3.141593F) * f1;
+ u = MathHelper.b((v / 180F) * 3.141593F) * MathHelper.b((w / 180F) * 3.141593F) * f1;
+ t = -MathHelper.a((w / 180F) * 3.141593F) * f1;
+ a(s, t, u, 1.5F, 1.0F);
+ }
+
+ public EntitySnowball(World world, double d1, double d2, double d3) {
+ super(world);
+ b = -1;
+ c = -1;
+ d = -1;
+ e = 0;
+ f = false;
+ a = 0;
+ am = 0;
+ al = 0;
+ a(0.25F, 0.25F);
+ a(d1, d2, d3);
+ H = 0.0F;
+ }
+
+ public void a(double d1, double d2, double d3, float f1, float f2) {
+ float f3 = MathHelper.a(d1 * d1 + d2 * d2 + d3 * d3);
+
+ d1 /= f3;
+ d2 /= f3;
+ d3 /= f3;
+ d1 += W.nextGaussian() * 0.0074999998323619366D * (double) f2;
+ d2 += W.nextGaussian() * 0.0074999998323619366D * (double) f2;
+ d3 += W.nextGaussian() * 0.0074999998323619366D * (double) f2;
+ d1 *= f1;
+ d2 *= f1;
+ d3 *= f1;
+ s = d1;
+ t = d2;
+ u = d3;
+ float f4 = MathHelper.a(d1 * d1 + d3 * d3);
+
+ x = v = (float) ((Math.atan2(d1, d3) * 180D) / 3.1415927410125732D);
+ y = w = (float) ((Math.atan2(d2, f4) * 180D) / 3.1415927410125732D);
+ al = 0;
+ }
+
+ public void b_() {
+ O = p;
+ P = q;
+ Q = r;
+ super.b_();
+ if (a > 0) {
+ a--;
+ }
+ if (f) {
+ int i = this.l.a(b, c, d);
+
+ if (i != e) {
+ f = false;
+ s *= W.nextFloat() * 0.2F;
+ t *= W.nextFloat() * 0.2F;
+ u *= W.nextFloat() * 0.2F;
+ al = 0;
+ am = 0;
+ } else {
+ al++;
+ if (al == 1200) {
+ q();
+ }
+ return;
+ }
+ } else {
+ am++;
+ }
+ Vec3D vec3d = Vec3D.b(p, q, r);
+ Vec3D vec3d1 = Vec3D.b(p + s, q + t, r + u);
+ MovingObjectPosition movingobjectposition = this.l.a(vec3d, vec3d1);
+
+ vec3d = Vec3D.b(p, q, r);
+ vec3d1 = Vec3D.b(p + s, q + t, r + u);
+ if (movingobjectposition != null) {
+ vec3d1 = Vec3D.b(movingobjectposition.f.a, movingobjectposition.f.b, movingobjectposition.f.c);
+ }
+ if (!this.l.z) {
+ Entity entity = null;
+ List list = this.l.b(((Entity) (this)), z.a(s, t, u).b(1.0D, 1.0D, 1.0D));
+ double d1 = 0.0D;
+
+ for (int k = 0; k < list.size(); k++) {
+ Entity entity1 = (Entity) list.get(k);
+
+ if (!entity1.c_() || entity1 == ak && am < 5) {
+ continue;
+ }
+ float f4 = 0.3F;
+ AxisAlignedBB axisalignedbb = entity1.z.b(f4, f4, f4);
+ MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1);
+
+ if (movingobjectposition1 == null) {
+ continue;
+ }
+ double d2 = vec3d.a(movingobjectposition1.f);
+
+ if (d2 < d1 || d1 == 0.0D) {
+ entity = entity1;
+ d1 = d2;
+ }
+ }
+
+ if (entity != null) {
+ movingobjectposition = new MovingObjectPosition(entity);
+ }
+ }
+ if (movingobjectposition != null) {
+ if (movingobjectposition.g != null) {
+ // CraftBukkit start
+ boolean bounce;
+ if (movingobjectposition.g instanceof EntityLiving) {
+ CraftServer server = ((WorldServer) this.l).getServer();
+ CraftEntity damagee = new CraftLivingEntity(server, (EntityLiving) movingobjectposition.g);
+ CraftEntity damager = new CraftLivingEntity(server, ak);
+ CraftEntity projectile = new CraftSnowball(server, (EntitySnowball) this);
+
+ //TODO @see EntityArrow#162
+ EntityDamageByProjectileEvent edbpe = new EntityDamageByProjectileEvent( damager, damagee, projectile, EntityDamageEvent.DamageCause.ENTITY_ATTACK, 0);
+
+ server.getPluginManager().callEvent(edbpe);
+ if(!edbpe.isCancelled()) {
+ // this function returns if the snowball should stick or not, i.e. !bounce
+ bounce = !movingobjectposition.g.a(((Entity) (ak)), edbpe.getDamage());
+ } else {
+ // event was cancelled, get if the snowball should bounce or not
+ bounce = edbpe.getBounce();
+ }
+ } else {
+ bounce = !movingobjectposition.g.a(((Entity) (ak)), 0);
+ }
+ if (!bounce) {
+ // CraftBukkit end
+ ;
+ }
+ }
+ for (int j = 0; j < 8; j++) {
+ this.l.a("snowballpoof", p, q, r, 0.0D, 0.0D, 0.0D);
+ }
+
+ q();
+ }
+ p += s;
+ q += t;
+ r += u;
+ float f1 = MathHelper.a(s * s + u * u);
+
+ v = (float) ((Math.atan2(s, u) * 180D) / 3.1415927410125732D);
+ for (w = (float) ((Math.atan2(t, f1) * 180D) / 3.1415927410125732D); w - y < -180F; y -= 360F) {
+ ;
+ }
+ for (; w - y >= 180F; y += 360F) {
+ ;
+ }
+ for (; v - x < -180F; x -= 360F) {
+ ;
+ }
+ for (; v - x >= 180F; x += 360F) {
+ ;
+ }
+ w = y + (w - y) * 0.2F;
+ v = x + (v - x) * 0.2F;
+ float f2 = 0.99F;
+ float f5 = 0.03F;
+
+ if (v()) {
+ for (int l = 0; l < 4; l++) {
+ float f3 = 0.25F;
+
+ this.l.a("bubble", p - s * (double) f3, q - t * (double) f3, r - u * (double) f3, s, t, u);
+ }
+
+ f2 = 0.8F;
+ }
+ s *= f2;
+ t *= f2;
+ u *= f2;
+ t -= f5;
+ a(p, q, r);
+ }
+
+ public void a(NBTTagCompound nbttagcompound) {
+ nbttagcompound.a("xTile", (short) b);
+ nbttagcompound.a("yTile", (short) c);
+ nbttagcompound.a("zTile", (short) d);
+ nbttagcompound.a("inTile", (byte) e);
+ nbttagcompound.a("shake", (byte) a);
+ nbttagcompound.a("inGround", (byte) (f ? 1 : 0));
+ }
+
+ public void b(NBTTagCompound nbttagcompound) {
+ b = ((int) (nbttagcompound.c("xTile")));
+ c = ((int) (nbttagcompound.c("yTile")));
+ d = ((int) (nbttagcompound.c("zTile")));
+ e = nbttagcompound.b("inTile") & 0xff;
+ a = nbttagcompound.b("shake") & 0xff;
+ f = nbttagcompound.b("inGround") == 1;
+ }
+
+ public void b(EntityPlayer entityplayer) {
+ if (f && ak == entityplayer && a <= 0 && entityplayer.an.a(new ItemStack(Item.j, 1))) {
+ l.a(((Entity) (this)), "random.pop", 0.2F, ((W.nextFloat() - W.nextFloat()) * 0.7F + 1.0F) * 2.0F);
+ entityplayer.c(((Entity) (this)), 1);
+ q();
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
index f98fd302..ace0da6b 100644
--- a/src/main/java/net/minecraft/server/Explosion.java
+++ b/src/main/java/net/minecraft/server/Explosion.java
@@ -125,7 +125,7 @@ public class Explosion {
// Craftbukkit TODO: get the x/y/z of the tnt block?
EntityDamageByBlockEvent edbbe = new EntityDamageByBlockEvent(null, damagee, EntityDamageEvent.DamageCause.BLOCK_EXPLOSION, damage);
servr.getPluginManager().callEvent(edbbe);
- if(!edbbe.isCancelled()) entity.a(e, damage);
+ if(!edbbe.isCancelled()) entity.a(e, edbbe.getDamage());
} else {
CraftEntity damager = null;
if (e instanceof EntityPlayerMP) {
@@ -138,7 +138,7 @@ public class Explosion {
servr.getPluginManager().callEvent(edbbe);
if (!edbbe.isCancelled()) {
- entity.a(e, damage);
+ entity.a(e, edbbe.getDamage());
}
}
// Craftbukkit end
@@ -211,6 +211,5 @@ public class Explosion {
Block.m[j1].a_(i, k, l, i1);
}
}
-
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
new file mode 100644
index 00000000..688c43d1
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
@@ -0,0 +1,17 @@
+package org.bukkit.craftbukkit.entity;
+
+import net.minecraft.server.EntityFireball;
+
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.entity.Fireball;
+
+/**
+ * An egg.
+ *
+ * @author Cogito
+ */
+public class CraftFireball extends CraftEntity implements Fireball {
+ public CraftFireball(CraftServer server, EntityFireball ent) {
+ super(server, ent);
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java
new file mode 100644
index 00000000..ac832c13
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java
@@ -0,0 +1,17 @@
+package org.bukkit.craftbukkit.entity;
+
+import net.minecraft.server.EntityFish;
+
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.entity.Fish;
+
+/**
+ * An egg.
+ *
+ * @author Cogito
+ */
+public class CraftFish extends CraftEntity implements Fish {
+ public CraftFish(CraftServer server, EntityFish ent) {
+ super(server, ent);
+ }
+}