@@ -140,7 +140,7 @@ protected function entityBaseTick(int $tickDiff = 1) : bool{
140140 }
141141
142142 public function explode () : void {
143- if (($ expCount = count ($ this ->explosions )) !== 0 ){
143+ if (($ explosionCount = count ($ this ->explosions )) !== 0 ){
144144 $ this ->broadcastAnimation (new FireworkParticlesAnimation ($ this ));
145145 foreach ($ this ->explosions as $ explosion ){
146146 $ this ->broadcastSound ($ explosion ->getType ()->getExplosionSound ());
@@ -149,29 +149,36 @@ public function explode() : void{
149149 }
150150 }
151151
152- $ force = ($ expCount * 2 ) + 5 ;
153- foreach ($ this ->getWorld ()->getCollidingEntities ($ this ->getBoundingBox ()->expandedCopy (5 , 5 , 5 ), $ this ) as $ entity ){
152+ $ force = ($ explosionCount * 2 ) + 5 ;
153+ $ world = $ this ->getWorld ();
154+ foreach ($ world ->getCollidingEntities ($ this ->getBoundingBox ()->expandedCopy (5 , 5 , 5 ), $ this ) as $ entity ){
154155 if (!$ entity instanceof Living){
155156 continue ;
156157 }
157158
158- $ position = $ entity ->getEyePos ();
159- $ distance = $ position ->distance ($ this ->location );
160- if ($ distance > 5 ){
159+ $ position = $ entity ->getPosition ();
160+ $ distance = $ position ->distanceSquared ($ this ->location );
161+ if ($ distance > 25 ){
161162 continue ;
162163 }
163164
164- $ world = $ this ->getWorld ();
165-
166- //check for obstructing blocks
167- foreach (VoxelRayTrace::betweenPoints ($ this ->location , $ position ) as $ pos ){
168- if ($ world ->getBlockAt ((int ) $ pos ->x , (int ) $ pos ->y , (int ) $ pos ->z )->isSolid ()){
169- continue 2 ;
165+ //cast two rays - one to the entity's feet and another to halfway up its body (according to Java, anyway)
166+ //this seems like it'd miss some cases but who am I to argue with vanilla logic :>
167+ $ height = $ entity ->getBoundingBox ()->getYLength ();
168+ for ($ i = 0 ; $ i < 2 ; $ i ++){
169+ $ target = $ position ->add (0 , 0.5 * $ i * $ height , 0 );
170+ foreach (VoxelRayTrace::betweenPoints ($ this ->location , $ target ) as $ blockPos ){
171+ if ($ world ->getBlock ($ blockPos )->calculateIntercept ($ this ->location , $ target ) !== null ){
172+ continue 2 ; //obstruction, try another path
173+ }
170174 }
171- }
172175
173- $ ev = new EntityDamageByEntityEvent ($ this , $ entity , EntityDamageEvent::CAUSE_ENTITY_EXPLOSION , $ force * sqrt ((5 - $ distance ) / 5 ));
174- $ entity ->attack ($ ev );
176+ //no obstruction
177+ $ damage = $ force * sqrt ((5 - $ position ->distance ($ this ->location )) / 5 );
178+ $ ev = new EntityDamageByEntityEvent ($ this , $ entity , EntityDamageEvent::CAUSE_ENTITY_EXPLOSION , $ damage );
179+ $ entity ->attack ($ ev );
180+ break ;
181+ }
175182 }
176183 }
177184 }
0 commit comments