Commits

FearThe1337 authored and Thinkofname committed e1070b9fbb5
SPIGOT-206 Further checks and fixes for Hanging entities.

Adds an check for existing entities before selecting the location allowing for hanging entities to be spawned in blocks where there already is an hanging entity at the default rotation. Fixes the CraftHanging setRotation function to use the new 1.8 logic.
No tags

nms-patches/EntityHanging.patch

Modified
1 ---- ../work/decompile-8eb82bde//net/minecraft/server/EntityHanging.java 2014-11-28 17:43:43.097707435 +0000
2 -+++ src/main/java/net/minecraft/server/EntityHanging.java 2014-11-28 17:38:18.000000000 +0000
1 +--- ../work/decompile-8eb82bde//net/minecraft/server/EntityHanging.java Mon Dec 15 15:33:27 2014
2 ++++ src/main/java/net/minecraft/server/EntityHanging.java Mon Dec 15 15:33:27 2014
3 3 @@ -4,6 +4,13 @@
4 4 import java.util.List;
5 5 import org.apache.commons.lang3.Validate;
6 6
7 7 +// CraftBukkit start
8 8 +import org.bukkit.entity.Hanging;
9 9 +import org.bukkit.entity.Painting;
10 10 +import org.bukkit.event.hanging.HangingBreakEvent;
11 11 +import org.bukkit.event.painting.PaintingBreakEvent;
12 12 +// CraftBukkit end
13 13 +
14 14 public abstract class EntityHanging extends Entity {
15 15
16 16 private int c;
17 -@@ -77,6 +84,33 @@
17 +@@ -30,30 +37,35 @@
18 + this.o();
19 + }
20 +
21 +- private void o() {
22 +- if (this.direction != null) {
23 +- double d0 = (double) this.blockPosition.getX() + 0.5D;
24 +- double d1 = (double) this.blockPosition.getY() + 0.5D;
25 +- double d2 = (double) this.blockPosition.getZ() + 0.5D;
26 ++ /* CraftBukkit start - bounding box calculation made static (for spawn usage)
27 ++
28 ++ l is from function l()
29 ++ m is from function m()
30 ++
31 ++ Placing here as it's more likely to be noticed as something which needs to be updated
32 ++ then something in a CraftBukkit file.
33 ++ */
34 ++ public static AxisAlignedBB calculateBoundingBox(BlockPosition blockPosition, EnumDirection direction, int width, int height) {
35 ++ double d0 = (double) blockPosition.getX() + 0.5D;
36 ++ double d1 = (double) blockPosition.getY() + 0.5D;
37 ++ double d2 = (double) blockPosition.getZ() + 0.5D;
38 + double d3 = 0.46875D;
39 +- double d4 = this.a(this.l());
40 +- double d5 = this.a(this.m());
41 ++ double d4 = width % 32 == 0 ? 0.5D : 0.0D;
42 ++ double d5 = height % 32 == 0 ? 0.5D : 0.0D;
43 +
44 +- d0 -= (double) this.direction.getAdjacentX() * 0.46875D;
45 +- d2 -= (double) this.direction.getAdjacentZ() * 0.46875D;
46 ++ d0 -= (double) direction.getAdjacentX() * 0.46875D;
47 ++ d2 -= (double) direction.getAdjacentZ() * 0.46875D;
48 + d1 += d5;
49 +- EnumDirection enumdirection = this.direction.f();
50 ++ EnumDirection enumdirection = direction.f();
51 +
52 + d0 += d4 * (double) enumdirection.getAdjacentX();
53 + d2 += d4 * (double) enumdirection.getAdjacentZ();
54 +- this.locX = d0;
55 +- this.locY = d1;
56 +- this.locZ = d2;
57 +- double d6 = (double) this.l();
58 +- double d7 = (double) this.m();
59 +- double d8 = (double) this.l();
60 +
61 +- if (this.direction.k() == EnumAxis.Z) {
62 ++ double d6 = (double) width;
63 ++ double d7 = (double) height;
64 ++ double d8 = (double) width;
65 ++
66 ++ if (direction.k() == EnumAxis.Z) {
67 + d8 = 1.0D;
68 + } else {
69 + d6 = 1.0D;
70 +@@ -62,7 +74,20 @@
71 + d6 /= 32.0D;
72 + d7 /= 32.0D;
73 + d8 /= 32.0D;
74 +- this.a(new AxisAlignedBB(d0 - d6, d1 - d7, d2 - d8, d0 + d6, d1 + d7, d2 + d8));
75 ++ return new AxisAlignedBB(d0 - d6, d1 - d7, d2 - d8, d0 + d6, d1 + d7, d2 + d8);
76 ++ }
77 ++ // CraftBukkit end
78 ++
79 ++ // PAIL: rename
80 ++ private void o() {
81 ++ if (this.direction != null) {
82 ++ // CraftBukkit start code moved in to calculateBoundingBox
83 ++ AxisAlignedBB bb = calculateBoundingBox(this.blockPosition,this.direction,this.l(),this.m());
84 ++ this.locX = (bb.a + bb.d) / 2.0D;
85 ++ this.locY = (bb.b + bb.e) / 2.0D;
86 ++ this.locZ = (bb.c + bb.f) / 2.0D;
87 ++ this.a(bb);
88 ++ // CraftBukkit end
89 + }
90 + }
91 +
92 +@@ -77,6 +102,33 @@
18 93 if (this.c++ == 100 && !this.world.isStatic) {
19 94 this.c = 0;
20 95 if (!this.dead && !this.survives()) {
21 96 + // CraftBukkit start - fire break events
22 97 + Material material = this.world.getType(new BlockPosition(this)).getBlock().getMaterial();
23 98 + HangingBreakEvent.RemoveCause cause;
24 99 +
25 100 + if (!material.equals(Material.AIR)) {
26 101 + // TODO: This feels insufficient to catch 100% of suffocation cases
27 102 + cause = HangingBreakEvent.RemoveCause.OBSTRUCTION;
41 116 + }
42 117 +
43 118 + if (dead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) {
44 119 + return;
45 120 + }
46 121 + // CraftBukkit end
47 122 +
48 123 this.die();
49 124 this.b((Entity) null);
50 125 }
51 -@@ -138,6 +172,32 @@
126 +@@ -138,6 +190,32 @@
52 127 return false;
53 128 } else {
54 129 if (!this.dead && !this.world.isStatic) {
55 130 + // CraftBukkit start - fire break events
56 131 + HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.DEFAULT);
57 132 + PaintingBreakEvent paintingEvent = null;
58 133 + if (damagesource.getEntity() != null) {
59 134 + event = new org.bukkit.event.hanging.HangingBreakByEntityEvent((Hanging) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity());
60 135 +
61 136 + if (this instanceof EntityPainting) {
74 149 + }
75 150 +
76 151 + if (this.dead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) {
77 152 + return true;
78 153 + }
79 154 + // CraftBukkit end
80 155 +
81 156 this.die();
82 157 this.ac();
83 158 this.b(damagesource.getEntity());
84 -@@ -149,6 +209,18 @@
159 +@@ -149,6 +227,18 @@
85 160
86 161 public void move(double d0, double d1, double d2) {
87 162 if (!this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) {
88 163 + if (this.dead) return; // CraftBukkit
89 164 +
90 165 + // CraftBukkit start - fire break events
91 166 + // TODO - Does this need its own cause? Seems to only be triggered by pistons
92 167 + HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.PHYSICS);
93 168 + this.world.getServer().getPluginManager().callEvent(event);
94 169 +
95 170 + if (this.dead || event.isCancelled()) {
96 171 + return;
97 172 + }
98 173 + // CraftBukkit end
99 174 +
100 175 this.die();
101 176 this.b((Entity) null);
102 177 }
103 -@@ -156,7 +228,7 @@
178 +@@ -156,7 +246,7 @@
104 179 }
105 180
106 181 public void g(double d0, double d1, double d2) {
107 182 - if (!this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) {
108 183 + if (false && !this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { // CraftBukkit - not needed
109 184 this.die();
110 185 this.b((Entity) null);
111 186 }

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut