Skip to content

Commit 4072acd

Browse files
committed
Bring explosion damage logic in line with vanilla
with Java, anyway
1 parent fa5e0bb commit 4072acd

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

src/entity/object/FireworkRocket.php

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)