summaryrefslogtreecommitdiffstats
path: root/nms-patches/EntityEnderDragon.patch
diff options
context:
space:
mode:
authorThinkofdeath <thinkofdeath@spigotmc.org>2014-11-26 08:32:16 +1100
committermd_5 <git@md-5.net>2014-11-28 17:16:30 +1100
commit24557bc2b37deb6a0edf497d547471832457b1dd (patch)
treec560572889a3b0b34964a0cddb35dc87fda3c914 /nms-patches/EntityEnderDragon.patch
parenta4805dbd77da057cc1ea0bf344379bc6e53ca1f6 (diff)
downloadcraftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.tar
craftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.tar.gz
craftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.tar.lz
craftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.tar.xz
craftbukkit-24557bc2b37deb6a0edf497d547471832457b1dd.zip
Update to Minecraft 1.8
For more information please see http://www.spigotmc.org/
Diffstat (limited to 'nms-patches/EntityEnderDragon.patch')
-rw-r--r--nms-patches/EntityEnderDragon.patch330
1 files changed, 330 insertions, 0 deletions
diff --git a/nms-patches/EntityEnderDragon.patch b/nms-patches/EntityEnderDragon.patch
new file mode 100644
index 00000000..a58d2f8f
--- /dev/null
+++ b/nms-patches/EntityEnderDragon.patch
@@ -0,0 +1,330 @@
+--- ../work/decompile-bb26c12b/net/minecraft/server/EntityEnderDragon.java 2014-11-27 08:59:46.665422005 +1100
++++ src/main/java/net/minecraft/server/EntityEnderDragon.java 2014-11-27 08:42:10.116850981 +1100
+@@ -5,6 +5,17 @@
+ import java.util.Iterator;
+ 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.EntityExplodeEvent;
++import org.bukkit.event.entity.EntityRegainHealthEvent;
++import org.bukkit.event.entity.EntityTargetEvent;
++import org.bukkit.Bukkit;
++// CraftBukkit end
++
+ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMonster {
+
+ public double a;
+@@ -27,6 +38,7 @@
+ private Entity by;
+ public int bw;
+ public EntityEnderCrystal bx;
++ private Explosion explosionSource = new Explosion(null, this, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, true); // CraftBukkit - reusable source for CraftTNTPrimed.getSource()
+
+ public EntityEnderDragon(World world) {
+ super(world);
+@@ -120,21 +132,21 @@
+
+ if (this.world.isStatic) {
+ if (this.ba > 0) {
+- d3 = this.locX + (this.bb - this.locX) / (double) this.ba;
+- d0 = this.locY + (this.bc - this.locY) / (double) this.ba;
+- d1 = this.locZ + (this.bd - this.locZ) / (double) this.ba;
+- d2 = MathHelper.g(this.be - (double) this.yaw);
+- this.yaw = (float) ((double) this.yaw + d2 / (double) this.ba);
++ d0 = this.locX + (this.bb - this.locX) / (double) this.ba;
++ d1 = this.locY + (this.bc - this.locY) / (double) this.ba;
++ d2 = this.locZ + (this.bd - this.locZ) / (double) this.ba;
++ d3 = MathHelper.g(this.be - (double) this.yaw);
++ this.yaw = (float) ((double) this.yaw + d3 / (double) this.ba);
+ this.pitch = (float) ((double) this.pitch + (this.bf - (double) this.pitch) / (double) this.ba);
+ --this.ba;
+- this.setPosition(d3, d0, d1);
++ this.setPosition(d0, d1, d2);
+ this.setYawPitch(this.yaw, this.pitch);
+ }
+ } else {
+- d3 = this.a - this.locX;
+- d0 = this.b - this.locY;
+- d1 = this.c - this.locZ;
+- d2 = d3 * d3 + d0 * d0 + d1 * d1;
++ d0 = this.a - this.locX;
++ d1 = this.b - this.locY;
++ d2 = this.c - this.locZ;
++ d3 = d0 * d0 + d1 * d1 + d2 * d2;
+ double d4;
+
+ if (this.by != null) {
+@@ -155,16 +167,16 @@
+ this.c += this.random.nextGaussian() * 2.0D;
+ }
+
+- if (this.bu || d2 < 100.0D || d2 > 22500.0D || this.positionChanged || this.E) {
++ if (this.bu || d3 < 100.0D || d3 > 22500.0D || this.positionChanged || this.E) {
+ this.cd();
+ }
+
+- d0 /= (double) MathHelper.sqrt(d3 * d3 + d1 * d1);
++ d1 /= (double) MathHelper.sqrt(d0 * d0 + d2 * d2);
+ f3 = 0.6F;
+- d0 = MathHelper.a(d0, (double) (-f3), (double) f3);
+- this.motY += d0 * 0.10000000149011612D;
++ d1 = MathHelper.a(d1, (double) (-f3), (double) f3);
++ this.motY += d1 * 0.10000000149011612D;
+ this.yaw = MathHelper.g(this.yaw);
+- double d8 = 180.0D - Math.atan2(d3, d1) * 180.0D / 3.1415927410125732D;
++ double d8 = 180.0D - Math.atan2(d0, d2) * 180.0D / 3.1415927410125732D;
+ double d9 = MathHelper.g(d8 - (double) this.yaw);
+
+ if (d9 > 50.0D) {
+@@ -290,12 +302,21 @@
+ if (this.bx != null) {
+ if (this.bx.dead) {
+ if (!this.world.isStatic) {
++ CraftEventFactory.entityDamage = this.bx; // CraftBukkit
+ this.a(this.bl, DamageSource.explosion((Explosion) null), 10.0F);
++ CraftEventFactory.entityDamage = null; // CraftBukkit
+ }
+
+ this.bx = null;
+ } else if (this.ticksLived % 10 == 0 && this.getHealth() < this.getMaxHealth()) {
+- this.setHealth(this.getHealth() + 1.0F);
++ // CraftBukkit start
++ EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), 1.0D, EntityRegainHealthEvent.RegainReason.ENDER_CRYSTAL);
++ this.world.getServer().getPluginManager().callEvent(event);
++
++ if (!event.isCancelled()) {
++ this.setHealth((float) (this.getHealth() + event.getAmount()));
++ }
++ // CraftBukkit end
+ }
+ }
+
+@@ -364,7 +385,19 @@
+ }
+
+ if (this.random.nextInt(2) == 0 && !arraylist.isEmpty()) {
+- this.by = (Entity) arraylist.get(this.random.nextInt(arraylist.size()));
++ // CraftBukkit start
++ Entity target = (Entity) this.world.players.get(this.random.nextInt(this.world.players.size()));
++ EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), target.getBukkitEntity(), EntityTargetEvent.TargetReason.RANDOM_TARGET);
++ this.world.getServer().getPluginManager().callEvent(event);
++
++ if (!event.isCancelled()) {
++ if (event.getTarget() == null) {
++ this.by = null;
++ } else {
++ this.by = ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle();
++ }
++ }
++ // CraftBukkit end
+ } else {
+ boolean flag;
+
+@@ -399,6 +432,11 @@
+ int j1 = MathHelper.floor(axisalignedbb.f);
+ boolean flag = false;
+ boolean flag1 = false;
++
++ // CraftBukkit start - Create a list to hold all the destroyed blocks
++ List<org.bukkit.block.Block> destroyedBlocks = new java.util.ArrayList<org.bukkit.block.Block>();
++ org.bukkit.craftbukkit.CraftWorld craftWorld = this.world.getWorld();
++ // CraftBukkit end
+
+ for (int k1 = i; k1 <= l; ++k1) {
+ for (int l1 = j; l1 <= i1; ++l1) {
+@@ -407,7 +445,11 @@
+
+ if (block.getMaterial() != Material.AIR) {
+ if (block != Blocks.BARRIER && block != Blocks.OBSIDIAN && block != Blocks.END_STONE && block != Blocks.BEDROCK && block != Blocks.COMMAND_BLOCK && this.world.getGameRules().getBoolean("mobGriefing")) {
+- flag1 = this.world.setAir(new BlockPosition(k1, l1, i2)) || flag1;
++ // CraftBukkit start - Add blocks to list rather than destroying them
++ // flag1 = this.world.setAir(new BlockPosition(k1, l1, i2)) || flag1;
++ flag1 = true;
++ destroyedBlocks.add(craftWorld.getBlockAt(k1, l1, i2));
++ // CraftBukkit end
+ } else {
+ flag = true;
+ }
+@@ -417,6 +459,40 @@
+ }
+
+ if (flag1) {
++ // CraftBukkit start - Set off an EntityExplodeEvent for the dragon exploding all these blocks
++ org.bukkit.entity.Entity bukkitEntity = this.getBukkitEntity();
++ EntityExplodeEvent event = new EntityExplodeEvent(bukkitEntity, bukkitEntity.getLocation(), destroyedBlocks, 0F);
++ Bukkit.getPluginManager().callEvent(event);
++ if (event.isCancelled()) {
++ // This flag literally means 'Dragon hit something hard' (Obsidian, White Stone or Bedrock) and will cause the dragon to slow down.
++ // We should consider adding an event extension for it, or perhaps returning true if the event is cancelled.
++ return flag;
++ } else if (event.getYield() == 0F) {
++ // Yield zero ==> no drops
++ for (org.bukkit.block.Block block : event.blockList()) {
++ this.world.setAir(new BlockPosition(block.getX(), block.getY(), block.getZ()));
++ }
++ } else {
++ for (org.bukkit.block.Block block : event.blockList()) {
++ org.bukkit.Material blockId = block.getType();
++ if (blockId == org.bukkit.Material.AIR) {
++ continue;
++ }
++
++ int blockX = block.getX();
++ int blockY = block.getY();
++ int blockZ = block.getZ();
++
++ Block nmsBlock = org.bukkit.craftbukkit.util.CraftMagicNumbers.getBlock(blockId);
++ if (nmsBlock.a(explosionSource)) {
++ nmsBlock.dropNaturally(this.world, new BlockPosition(blockX, blockY, blockZ), nmsBlock.fromLegacyData(block.getData()), event.getYield(), 0);
++ }
++ nmsBlock.wasExploded(world, new BlockPosition(blockX, blockY, blockZ), explosionSource);
++
++ this.world.setAir(new BlockPosition(blockX, blockY, blockZ));
++ }
++ }
++ // CraftBukkit end
+ double d0 = axisalignedbb.a + (axisalignedbb.d - axisalignedbb.a) * (double) this.random.nextFloat();
+ double d1 = axisalignedbb.b + (axisalignedbb.e - axisalignedbb.b) * (double) this.random.nextFloat();
+ double d2 = axisalignedbb.c + (axisalignedbb.f - axisalignedbb.c) * (double) this.random.nextFloat();
+@@ -464,6 +540,7 @@
+ }
+
+ protected void aY() {
++ if (this.dead) return; // CraftBukkit - can't kill what's already dead
+ ++this.bw;
+ if (this.bw >= 180 && this.bw <= 200) {
+ float f = (this.random.nextFloat() - 0.5F) * 8.0F;
+@@ -478,7 +555,7 @@
+
+ if (!this.world.isStatic) {
+ if (this.bw > 150 && this.bw % 5 == 0 && this.world.getGameRules().getBoolean("doMobLoot")) {
+- i = 1000;
++ i = this.expToDrop / 12; // CraftBukkit - drop experience as dragon falls from sky. use experience drop from death event. This is now set in getExpReward()
+
+ while (i > 0) {
+ j = EntityExperienceOrb.getOrbValue(i);
+@@ -488,14 +565,30 @@
+ }
+
+ if (this.bw == 1) {
+- this.world.a(1018, new BlockPosition(this), 0);
++ // CraftBukkit start - Use relative location for far away sounds
++ // this.world.a(1018, new BlockPosition(this), 0);
++ int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16;
++ for (EntityPlayer player : (List<EntityPlayer>) this.world.players) {
++ double deltaX = this.locX - player.locX;
++ double deltaZ = this.locZ - player.locZ;
++ double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
++ if (distanceSquared > viewDistance * viewDistance) {
++ double deltaLength = Math.sqrt(distanceSquared);
++ double relativeX = player.locX + (deltaX / deltaLength) * viewDistance;
++ double relativeZ = player.locZ + (deltaZ / deltaLength) * viewDistance;
++ player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1018, new BlockPosition((int) relativeX, (int) this.locY, (int) relativeZ), 0, true));
++ } else {
++ player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1018, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0, true));
++ }
++ }
++ // CraftBukkit end
+ }
+ }
+
+ this.move(0.0D, 0.10000000149011612D, 0.0D);
+ this.aG = this.yaw += 20.0F;
+ if (this.bw == 200 && !this.world.isStatic) {
+- i = 2000;
++ i = this.expToDrop - (10 * this.expToDrop / 12); // CraftBukkit - drop the remaining experience
+
+ while (i > 0) {
+ j = EntityExperienceOrb.getOrbValue(i);
+@@ -513,6 +606,9 @@
+ boolean flag = true;
+ double d0 = 12.25D;
+ double d1 = 6.25D;
++
++ // CraftBukkit start - Replace any "this.world" in the following with just "world"!
++ BlockStateListPopulator world = new BlockStateListPopulator(this.world.getWorld());
+
+ for (int i = -1; i <= 32; ++i) {
+ for (int j = -4; j <= 4; ++j) {
+@@ -524,31 +620,51 @@
+
+ if (i < 0) {
+ if (d2 <= 6.25D) {
+- this.world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData());
++ world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData());
+ }
+ } else if (i > 0) {
+- this.world.setTypeUpdate(blockposition1, Blocks.AIR.getBlockData());
++ world.setTypeUpdate(blockposition1, Blocks.AIR.getBlockData());
+ } else if (d2 > 6.25D) {
+- this.world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData());
++ world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData());
+ } else {
+- this.world.setTypeUpdate(blockposition1, Blocks.END_PORTAL.getBlockData());
++ world.setTypeUpdate(blockposition1, Blocks.END_PORTAL.getBlockData());
+ }
+ }
+ }
+ }
+ }
+
+- this.world.setTypeUpdate(blockposition, Blocks.BEDROCK.getBlockData());
+- this.world.setTypeUpdate(blockposition.up(), Blocks.BEDROCK.getBlockData());
++ world.setTypeUpdate(blockposition, Blocks.BEDROCK.getBlockData());
++ world.setTypeUpdate(blockposition.up(), Blocks.BEDROCK.getBlockData());
+ BlockPosition blockposition2 = blockposition.up(2);
+
+- this.world.setTypeUpdate(blockposition2, Blocks.BEDROCK.getBlockData());
+- this.world.setTypeUpdate(blockposition2.west(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.EAST));
+- this.world.setTypeUpdate(blockposition2.east(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.WEST));
+- this.world.setTypeUpdate(blockposition2.north(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.SOUTH));
+- this.world.setTypeUpdate(blockposition2.south(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.NORTH));
+- this.world.setTypeUpdate(blockposition.up(3), Blocks.BEDROCK.getBlockData());
+- this.world.setTypeUpdate(blockposition.up(4), Blocks.DRAGON_EGG.getBlockData());
++ world.setTypeUpdate(blockposition2, Blocks.BEDROCK.getBlockData());
++ world.setTypeUpdate(blockposition2.west(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.EAST));
++ world.setTypeUpdate(blockposition2.east(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.WEST));
++ world.setTypeUpdate(blockposition2.north(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.SOUTH));
++ world.setTypeUpdate(blockposition2.south(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.NORTH));
++ world.setTypeUpdate(blockposition.up(3), Blocks.BEDROCK.getBlockData());
++ world.setTypeUpdate(blockposition.up(4), Blocks.DRAGON_EGG.getBlockData());
++
++ EntityCreatePortalEvent event = new EntityCreatePortalEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), java.util.Collections.unmodifiableList(world.getList()), org.bukkit.PortalType.ENDER);
++ this.world.getServer().getPluginManager().callEvent(event);
++
++ if (!event.isCancelled()) {
++ for (BlockState state : event.getBlocks()) {
++ state.update(true);
++ }
++ } else {
++ for (BlockState state : event.getBlocks()) {
++ PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(this.world, new BlockPosition(state.getX(), state.getY(), state.getZ()));
++ for (Iterator it = this.world.players.iterator(); it.hasNext();) {
++ EntityHuman entity = (EntityHuman) it.next();
++ if (entity instanceof EntityPlayer) {
++ ((EntityPlayer) entity).playerConnection.sendPacket(packet);
++ }
++ }
++ }
++ }
++ // CraftBukkit end
+ }
+
+ protected void D() {}
+@@ -576,4 +692,12 @@
+ protected float bA() {
+ return 5.0F;
+ }
++
++ // CraftBukkit start
++ public int getExpReward() {
++ // This value is equal to the amount of experience dropped while falling from the sky (10 * 1000)
++ // plus what is dropped when the dragon hits the ground (2000)
++ return 12000;
++ }
++ // CraftBukkit end
+ }