From c8147acd3f120d5eda92f1df5ddca1c518adfc3c Mon Sep 17 00:00:00 2001 From: Intybyte Date: Tue, 6 Jan 2026 18:26:08 +0100 Subject: [PATCH 1/3] Use entity --- .../cannons/dao/wrappers/FireTaskWrapper.java | 2 +- .../cannons/projectile/FlyingProjectile.java | 6 +-- .../cannons/projectile/ProjectileManager.java | 38 +++++++------------ 3 files changed, 17 insertions(+), 29 deletions(-) diff --git a/cannons-bukkit/src/main/java/at/pavlov/cannons/dao/wrappers/FireTaskWrapper.java b/cannons-bukkit/src/main/java/at/pavlov/cannons/dao/wrappers/FireTaskWrapper.java index 1f5687eb..59687ba1 100644 --- a/cannons-bukkit/src/main/java/at/pavlov/cannons/dao/wrappers/FireTaskWrapper.java +++ b/cannons-bukkit/src/main/java/at/pavlov/cannons/dao/wrappers/FireTaskWrapper.java @@ -139,7 +139,7 @@ public void fireProjectiles(Projectile projectile, Player onlinePlayer) { Vector vect = cannon.getFiringVector(true, true); - org.bukkit.entity.Projectile projectileEntity = ProjectileManager.getInstance().spawnProjectile(projectile, shooter, source, playerLoc, firingLoc, vect, cannon.getUID(), projectileCause); + Entity projectileEntity = ProjectileManager.getInstance().spawnProjectile(projectile, shooter, source, playerLoc, firingLoc, vect, cannon.getUID(), projectileCause); if (i == 0 && projectile.hasProperty(ProjectileProperties.SHOOTER_AS_PASSENGER) && onlinePlayer != null) projectileEntity.setPassenger(onlinePlayer); diff --git a/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/FlyingProjectile.java b/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/FlyingProjectile.java index 7d68c024..3ecd093c 100644 --- a/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/FlyingProjectile.java +++ b/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/FlyingProjectile.java @@ -40,7 +40,7 @@ public class FlyingProjectile private final MovingObject predictor; - public FlyingProjectile(Projectile projectile, org.bukkit.entity.Projectile projectile_entity, UUID shooterUID, org.bukkit.projectiles.ProjectileSource source, Location playerLoc, UUID cannonId, ProjectileCause projectileCause) + public FlyingProjectile(Projectile projectile, org.bukkit.entity.Entity projectile_entity, UUID shooterUID, org.bukkit.projectiles.ProjectileSource source, Location playerLoc, UUID cannonId, ProjectileCause projectileCause) { //Validate.notNull(shooterUID, "shooterUID for the projectile can't be null"); this.entityUID = projectile_entity.getUniqueId(); @@ -52,8 +52,8 @@ public FlyingProjectile(Projectile projectile, org.bukkit.entity.Projectile proj this.shooterUID = shooterUID; this.playerlocation = playerLoc; this.source = source; - if (source != null) - projectile_entity.setShooter(source); + if (source != null && projectile_entity instanceof org.bukkit.entity.Projectile pe) + pe.setShooter(source); this.projectileCause = projectileCause; this.spawnTime = System.currentTimeMillis(); diff --git a/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/ProjectileManager.java b/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/ProjectileManager.java index 76ecd588..50a5b4d5 100644 --- a/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/ProjectileManager.java +++ b/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/ProjectileManager.java @@ -51,7 +51,7 @@ private ProjectileManager(Cannons plugin) { this.plugin = plugin; } - public org.bukkit.entity.Projectile spawnProjectile(Projectile projectile, @NotNull UUID shooter, org.bukkit.projectiles.ProjectileSource source, Location playerLoc, Location spawnLoc, Vector velocity, UUID cannonId, ProjectileCause projectileCause) { + public Entity spawnProjectile(Projectile projectile, @NotNull UUID shooter, org.bukkit.projectiles.ProjectileSource source, Location playerLoc, Location spawnLoc, Vector velocity, UUID cannonId, ProjectileCause projectileCause) { Preconditions.checkNotNull(shooter, "shooter for the projectile can't be null"); World world = spawnLoc.getWorld(); @@ -60,18 +60,15 @@ public org.bukkit.entity.Projectile spawnProjectile(Projectile projectile, @NotN spawnLoc.setPitch((float) (Math.acos(velocity.getY()/v)*180.0/Math.PI - 90)); spawnLoc.setYaw((float) (Math.atan2(velocity.getZ(),velocity.getX())*180.0/Math.PI - 90)); - org.bukkit.entity.Projectile projectileEntity = spawnProjectile(projectile, spawnLoc, velocity, world); + Entity projectileEntity = spawnProjectile(projectile, spawnLoc, velocity, world); if (projectile.isProjectileOnFire()) projectileEntity.setFireTicks(100); //projectileEntity.setTicksLived(2); - - //create a new flying projectile container FlyingProjectile cannonball = new FlyingProjectile(projectile, projectileEntity, shooter, source, playerLoc, cannonId, projectileCause); - flyingProjectilesMap.put(cannonball.getUID(), cannonball); //detonate timefused projectiles @@ -80,28 +77,19 @@ public org.bukkit.entity.Projectile spawnProjectile(Projectile projectile, @NotN return projectileEntity; } - private org.bukkit.entity.@NotNull Projectile spawnProjectile(Projectile projectile, Location spawnLoc, Vector velocity, World world) { - Entity pEntity = world.spawnEntity(spawnLoc, projectile.getProjectileEntity()); + private @NotNull Entity spawnProjectile(Projectile projectile, Location spawnLoc, Vector velocity, World world) { + Entity entity = world.spawnEntity(spawnLoc, projectile.getProjectileEntity()); //calculate firing vector - pEntity.setVelocity(velocity); - - org.bukkit.entity.Projectile projectileEntity; - try { - projectileEntity = (org.bukkit.entity.Projectile) pEntity; - } catch(Exception e) { - plugin.logDebug("Can't convert EntityType " + pEntity.getType() + " to projectile. Using additional Snowball"); - projectileEntity = (org.bukkit.entity.Projectile) world.spawnEntity(spawnLoc, EntityType.SNOWBALL); - projectileEntity.setVelocity(velocity); - } + entity.setVelocity(velocity); CustomProjectileDefinition definition = Registries.CUSTOM_PROJECTILE_DEFINITION.of(projectile.getProjectileDefinitionKey()); if (definition == null) { - return projectileEntity; + return entity; } - projectileEntity.setVisualFire(definition.isOnFire()); - projectileEntity.setGlowing(definition.isGlowing()); + entity.setVisualFire(definition.isOnFire()); + entity.setGlowing(definition.isGlowing()); ProjectilePhysics defaultCase = Registries.DEFAULT_PROJECTILE_DEFINITION_REGISTRY.of(definition.getEntityKey()); if (defaultCase == null) { @@ -109,14 +97,14 @@ public org.bukkit.entity.Projectile spawnProjectile(Projectile projectile, @NotN } if (!defaultCase.matches(definition)) { - projectileEntity.setGravity(false); + entity.setGravity(false); } - if (projectileEntity instanceof WitherSkull witherSkull) { + if (entity instanceof WitherSkull witherSkull) { witherSkull.setCharged(definition.isCharged()); - } else if (projectileEntity instanceof AbstractArrow arrow) { + } else if (entity instanceof AbstractArrow arrow) { arrow.setCritical(definition.isCritical()); - } else if (projectileEntity instanceof ThrowableProjectile throwable) { + } else if (entity instanceof ThrowableProjectile throwable) { Material material = Material.matchMaterial(definition.getMaterial().full()); if (material == null) { plugin.logSevere("In custom projectile: " + definition.getKey().full() + " the material key is invalid."); @@ -132,7 +120,7 @@ public org.bukkit.entity.Projectile spawnProjectile(Projectile projectile, @NotN throwable.setItem(stack); } - return projectileEntity; + return entity; } From bf0812891e16b07866f4562ed6c01ed2e17814d1 Mon Sep 17 00:00:00 2001 From: Intybyte Date: Tue, 6 Jan 2026 18:38:25 +0100 Subject: [PATCH 2/3] Allow entity handling --- .../java/at/pavlov/cannons/CreateExplosion.java | 10 +++++----- .../cannons/projectile/FlyingProjectile.java | 14 +++++++------- .../cannons/projectile/ProjectileManager.java | 4 ++-- .../cannons/scheduler/ProjectileObserver.java | 11 ++++++----- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/cannons-bukkit/src/main/java/at/pavlov/cannons/CreateExplosion.java b/cannons-bukkit/src/main/java/at/pavlov/cannons/CreateExplosion.java index 218f3239..6f76f8f6 100644 --- a/cannons-bukkit/src/main/java/at/pavlov/cannons/CreateExplosion.java +++ b/cannons-bukkit/src/main/java/at/pavlov/cannons/CreateExplosion.java @@ -161,7 +161,7 @@ private boolean breakBlock(Block block, List blocklist, Boolean superBrea * @param cannonball * @return the location after the piercing event */ - private Location blockBreaker(FlyingProjectile cannonball, org.bukkit.entity.Projectile projectile_entity) { + private Location blockBreaker(FlyingProjectile cannonball, Entity projectile_entity) { Projectile projectile = cannonball.getProjectile(); @@ -757,7 +757,7 @@ private void addAffectedEntity(Entity entity) { * @param cannonball cannonball which hit the entity * @param entity entity hit */ - public void directHit(FlyingProjectile cannonball, org.bukkit.entity.Projectile projectile_entity, Entity entity) { + public void directHit(FlyingProjectile cannonball, Entity projectile_entity, Entity entity) { // add damage to map - it will be applied later to the player double directHit = this.getDirectHitDamage(cannonball, entity); this.damageMap.put(entity, directHit); @@ -772,7 +772,7 @@ public void directHit(FlyingProjectile cannonball, org.bukkit.entity.Projectile * * @param cannonball cannonball which will explode */ - public void detonate(FlyingProjectile cannonball, org.bukkit.entity.Projectile projectile_entity) { + public void detonate(FlyingProjectile cannonball, Entity projectile_entity) { this.plugin.logDebug("detonate cannonball"); Projectile projectile = cannonball.getProjectile().clone(); @@ -994,7 +994,7 @@ else if (projectile.hasProperty(ProjectileProperties.OBSERVER)) { * * @param cannonball the flying projectile */ - private void damageEntity(FlyingProjectile cannonball, org.bukkit.entity.Projectile projectile_entity) { + private void damageEntity(FlyingProjectile cannonball, Entity projectile_entity) { Projectile projectile = cannonball.getProjectile(); Location impactLoc = cannonball.getImpactLocation(); @@ -1159,7 +1159,7 @@ private void spawnProjectiles(FlyingProjectile cannonball) { * * @param cannonball the flying projectile */ - private void spawnFireworks(FlyingProjectile cannonball, org.bukkit.entity.Projectile projectile_entity) { + private void spawnFireworks(FlyingProjectile cannonball, Entity projectile_entity) { World world = cannonball.getWorld(); Projectile projectile = cannonball.getProjectile(); diff --git a/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/FlyingProjectile.java b/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/FlyingProjectile.java index 3ecd093c..448a97cd 100644 --- a/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/FlyingProjectile.java +++ b/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/FlyingProjectile.java @@ -78,12 +78,12 @@ public UUID getShooterUID() * * @return */ - public org.bukkit.entity.Projectile getProjectileEntity() { + public Entity getProjectileEntity() { Entity e = Bukkit.getEntity(entityUID); if (e == null) return null; - return (org.bukkit.entity.Projectile) Bukkit.getEntity(entityUID); + return Bukkit.getEntity(entityUID); } public Projectile getProjectile() @@ -104,7 +104,7 @@ public Location getPlayerlocation() { * check if the projectile in in a liquid * @return true if the projectile is in a liquid */ - private boolean isInWaterCheck(org.bukkit.entity.Projectile projectile_entity) + private boolean isInWaterCheck(Entity projectile_entity) { if(projectile_entity!=null) { @@ -122,7 +122,7 @@ public boolean isInWater() { * returns if the projectile has entered the water surface and updates also inWater * @return true if the projectile has entered water */ - public boolean updateWaterSurfaceCheck(org.bukkit.entity.Projectile projectile_entity) + public boolean updateWaterSurfaceCheck(Entity projectile_entity) { inWater = isInWaterCheck(projectile_entity); boolean isSurface = !wasInWater && inWater; @@ -153,7 +153,7 @@ public boolean isValid() * a projectile is valid if it has an entity, is not below -64 and younger than 1h (60*60*1000) * @return returns false if the projectile entity is null */ - public boolean isValid(org.bukkit.entity.Projectile projectile_entity) + public boolean isValid(Entity projectile_entity) { return (projectile_entity != null && projectile_entity.getLocation().getBlockY() > -64 && System.currentTimeMillis() < getSpawnTime() + 3600000); } @@ -196,7 +196,7 @@ public Location getActualLocation(org.bukkit.entity.Projectile projectile_entity * returns the distance of the projectile location to the calculated location * @return distance of the projectile location to the calculated location */ - public double distanceToProjectile(org.bukkit.entity.Projectile projectile_entity) + public double distanceToProjectile(Entity projectile_entity) { return projectile_entity.getLocation().toVector().distance(predictor.getLoc()); } @@ -204,7 +204,7 @@ public double distanceToProjectile(org.bukkit.entity.Projectile projectile_entit /** * teleports the projectile to the predicted location */ - public void teleportToPrediction(org.bukkit.entity.Projectile projectile_entity) + public void teleportToPrediction(Entity projectile_entity) { if (projectile_entity == null) return; diff --git a/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/ProjectileManager.java b/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/ProjectileManager.java index 50a5b4d5..da75221b 100644 --- a/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/ProjectileManager.java +++ b/cannons-bukkit/src/main/java/at/pavlov/cannons/projectile/ProjectileManager.java @@ -142,7 +142,7 @@ private void detonateTimefuse(final FlyingProjectile cannonball) { return; } //detonate timefuse - org.bukkit.entity.Projectile projectile_entity = fproj.getProjectileEntity(); + var projectile_entity = fproj.getProjectileEntity(); //the projectile might be null if (projectile_entity != null) { CreateExplosion.getInstance().detonate(cannonball, projectile_entity); @@ -184,7 +184,7 @@ public void directHitProjectile(Entity cannonball, Entity target) { return; } - org.bukkit.entity.Projectile projectile_entity = fproj.getProjectileEntity(); + Entity projectile_entity = fproj.getProjectileEntity(); if (!fproj.hasDetonated() && cannonball.isValid()) { fproj.setHasDetonated(true); CreateExplosion.getInstance().directHit(fproj, projectile_entity, target); diff --git a/cannons-bukkit/src/main/java/at/pavlov/cannons/scheduler/ProjectileObserver.java b/cannons-bukkit/src/main/java/at/pavlov/cannons/scheduler/ProjectileObserver.java index fb78cd52..e5db5aee 100644 --- a/cannons-bukkit/src/main/java/at/pavlov/cannons/scheduler/ProjectileObserver.java +++ b/cannons-bukkit/src/main/java/at/pavlov/cannons/scheduler/ProjectileObserver.java @@ -16,6 +16,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.block.Block; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; @@ -53,7 +54,7 @@ public void setupScheduler() for(var entry : projectiles.entrySet()) { FlyingProjectile cannonball = entry.getValue(); - org.bukkit.entity.Projectile projectile_entity = cannonball.getProjectileEntity(); + Entity projectile_entity = cannonball.getProjectileEntity(); Executor executor = (task) -> { if (plugin.isFolia()) { @@ -101,7 +102,7 @@ public void setupScheduler() * if cannonball enters water it will spawn a splash effect * @param cannonball the projectile to check */ - private void checkWaterImpact(FlyingProjectile cannonball, org.bukkit.entity.Projectile projectile_entity) { + private void checkWaterImpact(FlyingProjectile cannonball, Entity projectile_entity) { //the projectile has passed the water surface, make a splash if (!cannonball.updateWaterSurfaceCheck(projectile_entity)) { @@ -151,7 +152,7 @@ public void sendSplashToPlayers(Location loc, ItemHolder liquid, SoundHolder sou * teleports the player to new position of the cannonball * @param cannonball the FlyingProjectile to check */ - private void updateTeleporter(FlyingProjectile cannonball, org.bukkit.entity.Projectile projectile_entity) + private void updateTeleporter(FlyingProjectile cannonball, Entity projectile_entity) { //do nothing if the teleport was already performed if (cannonball.isTeleported()) @@ -197,7 +198,7 @@ private void updateTeleporter(FlyingProjectile cannonball, org.bukkit.entity.Pro * @param cannonball projectile to update * @return true if the projectile must be removed */ - private boolean updateProjectileLocation(FlyingProjectile cannonball, org.bukkit.entity.Projectile projectile_entity) + private boolean updateProjectileLocation(FlyingProjectile cannonball, Entity projectile_entity) { if (!plugin.getMyConfig().isKeepAliveEnabled()) return false; @@ -231,7 +232,7 @@ private boolean updateProjectileLocation(FlyingProjectile cannonball, org.bukkit * @param cannonball the cannonball entity entry of cannons * @param projectile_entity the entity of the projectile */ - private void updateSmokeTrail(FlyingProjectile cannonball, org.bukkit.entity.Projectile projectile_entity) { + private void updateSmokeTrail(FlyingProjectile cannonball, Entity projectile_entity) { Projectile proj = cannonball.getProjectile(); int maxDist = plugin.getMyConfig().getImitatedBlockMaximumDistance(); double smokeDist = proj.getSmokeTrailDistance()*(0.5 + random.nextDouble()); From a4c941f9b32c9fe1d0ac7e0543cdda7710cf8f56 Mon Sep 17 00:00:00 2001 From: Intybyte Date: Tue, 6 Jan 2026 19:02:57 +0100 Subject: [PATCH 3/3] Make proper init for DEFAULT_PROJECTILE_DEFINITION_REGISTRY --- .../internal/key/registries/Registries.java | 14 -------------- .../main/java/at/pavlov/cannons/Cannons.java | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/api-internal/src/main/java/at/pavlov/internal/key/registries/Registries.java b/api-internal/src/main/java/at/pavlov/internal/key/registries/Registries.java index 361f0140..50d6400b 100644 --- a/api-internal/src/main/java/at/pavlov/internal/key/registries/Registries.java +++ b/api-internal/src/main/java/at/pavlov/internal/key/registries/Registries.java @@ -72,20 +72,6 @@ public class Registries { .build() ); - Key.from( - List.of( - "minecraft:snowball", - "minecraft:egg", - "minecraft:ender_pearl", - "minecraft:experience_bottle", - "minecraft:potion", - "minecraft:lingering_potion", - "minecraft:llama_spit" - ) - ).forEach( entry -> toAdd.add( - new KeyedDefaultProjectile(entry) - )); - return toAdd; }); SharedRegistryKeyValidator validator = new SharedRegistryKeyValidator<>(CUSTOM_PROJECTILE_DEFINITION, DEFAULT_PROJECTILE_DEFINITION_REGISTRY); diff --git a/cannons-bukkit/src/main/java/at/pavlov/cannons/Cannons.java b/cannons-bukkit/src/main/java/at/pavlov/cannons/Cannons.java index 3d33b713..8d0ebc69 100644 --- a/cannons-bukkit/src/main/java/at/pavlov/cannons/Cannons.java +++ b/cannons-bukkit/src/main/java/at/pavlov/cannons/Cannons.java @@ -36,13 +36,18 @@ import at.pavlov.internal.CLogger; import at.pavlov.internal.Hook; import at.pavlov.internal.HookManager; +import at.pavlov.internal.Key; import at.pavlov.internal.ModrinthUpdateChecker; +import at.pavlov.internal.key.registries.Registries; +import at.pavlov.internal.projectile.definition.KeyedDefaultProjectile; import lombok.Getter; import org.bstats.bukkit.Metrics; import org.bstats.charts.AdvancedPie; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.PluginDescriptionFile; @@ -95,6 +100,20 @@ public static Logger logger() { } public void onLoad() { + Registries.DEFAULT_PROJECTILE_DEFINITION_REGISTRY.setFrozen(false); + for (EntityType type : EntityType.values()) { + if (!type.isSpawnable()) continue; + NamespacedKey key = type.getKey(); + Key cannonKey = Key.from(key.toString()); + + if (!Registries.DEFAULT_PROJECTILE_DEFINITION_REGISTRY.has(cannonKey)) { + Registries.DEFAULT_PROJECTILE_DEFINITION_REGISTRY.register( + new KeyedDefaultProjectile(cannonKey) + ); + } + } + Registries.DEFAULT_PROJECTILE_DEFINITION_REGISTRY.setFrozen(true); + CLogger.logger = this.getLogger(); // must be done in onLoad because "movecraft" AsyncTaskManager.initialize(this);