Fix oversights in explosive crossbow weapon (#9)

* Finalize Explosive Crossbow class

* Unwrap ternary for better code readability

* Don't process cancelled projectile spawns

This fixes a bug caused by an edge-case in which an explosive arrow's particles lingered forever when an explosive crossbow was fired from a chunk that is at/exceeds the entity limit.

Extras cancels the EntitySpawnEvent to enforce its entity limit; which does not call EntityRemoveFromWorldEvent on cancellation, thus causing this issue.
This commit is contained in:
Allink 2023-02-27 01:46:19 +00:00 committed by GitHub
parent 17b34d3bdf
commit 6b339700fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 7 deletions

View File

@ -5,6 +5,8 @@ import com.destroystokyo.paper.event.server.ServerTickEndEvent;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Location;
@ -26,14 +28,18 @@ import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.projectiles.ProjectileSource;
public class WeaponExplosiveCrossbow implements Listener {
public final class WeaponExplosiveCrossbow implements Listener {
private static final int PARTICLE_OFFSET = 2;
private final List<Projectile> explosiveProjectiles = new ArrayList<>();
private final SecureRandom secureRandom = new SecureRandom();
@EventHandler
@EventHandler(priority = EventPriority.MONITOR)
public void onShootArrow(ProjectileLaunchEvent event) {
if (event.isCancelled()) {
return;
}
final Projectile projectile = event.getEntity();
final ProjectileSource source = projectile.getShooter();
@ -87,12 +93,15 @@ public class WeaponExplosiveCrossbow implements Listener {
final Entity hitEntity = event.getHitEntity();
final Block hitBlock = event.getHitBlock();
final Location explosionLocation;
final Location explosionLocation =
(hitBlock != null || hitEntity != null) ?
(hitEntity != null
? hitEntity.getLocation() : hitBlock.getLocation())
: projectile.getLocation();
if (hitBlock != null) {
explosionLocation = hitBlock.getLocation();
} else if (hitEntity != null) {
explosionLocation = hitEntity.getLocation();
} else {
explosionLocation = projectile.getLocation();
}
final World world = projectile.getWorld();