From 6b7628962dcb94644db1f9b43cc0bf90a6e50aa1 Mon Sep 17 00:00:00 2001 From: Greened <108997309+GreenedDev@users.noreply.github.com> Date: Wed, 20 May 2026 13:24:12 +0400 Subject: [PATCH] fix: gravity for couple of projectile entities (#2161) * fix: gravity for couple of projectile entities * fix: clippy warning * fix: rerun actions --- pumpkin/src/entity/projectile/egg.rs | 4 +++- pumpkin/src/entity/projectile/ender_pearl.rs | 5 ++++- pumpkin/src/entity/projectile/fireball.rs | 4 +++- pumpkin/src/entity/projectile/firework_rocket.rs | 5 ++++- pumpkin/src/entity/projectile/lingering_potion.rs | 5 ++++- pumpkin/src/entity/projectile/mod.rs | 7 ++++--- pumpkin/src/entity/projectile/small_fireball.rs | 5 ++++- pumpkin/src/entity/projectile/snowball.rs | 5 ++++- pumpkin/src/entity/projectile/splash_potion.rs | 5 ++++- pumpkin/src/entity/projectile/wind_charge.rs | 1 + pumpkin/src/entity/type.rs | 4 +++- pumpkin/src/item/items/wind_charge.rs | 7 ++++--- 12 files changed, 42 insertions(+), 15 deletions(-) diff --git a/pumpkin/src/entity/projectile/egg.rs b/pumpkin/src/entity/projectile/egg.rs index 398476777..a2ece1019 100644 --- a/pumpkin/src/entity/projectile/egg.rs +++ b/pumpkin/src/entity/projectile/egg.rs @@ -21,6 +21,7 @@ use tokio::sync::RwLock; use uuid::Uuid; const MAX_EGG_HATCH_EVENT_SPAWNS: usize = 16; +const GRAVITY: f64 = 0.03; pub struct EggEntity { pub thrown: ThrownItemEntity, @@ -36,6 +37,7 @@ impl EggEntity { owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: GRAVITY, }; Self { @@ -45,7 +47,7 @@ impl EggEntity { } pub fn new_shot(entity: Entity, shooter: &Entity) -> Self { - let thrown = ThrownItemEntity::new(entity, shooter); + let thrown = ThrownItemEntity::new(entity, shooter, GRAVITY); // Default slight upward velocity thrown.entity.set_velocity(Vector3::new(0.0, 0.1, 0.0)); diff --git a/pumpkin/src/entity/projectile/ender_pearl.rs b/pumpkin/src/entity/projectile/ender_pearl.rs index 4992d88f4..b1343a9ae 100644 --- a/pumpkin/src/entity/projectile/ender_pearl.rs +++ b/pumpkin/src/entity/projectile/ender_pearl.rs @@ -10,6 +10,8 @@ use pumpkin_data::particle::Particle; use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_util::math::vector3::Vector3; +const GRAVITY: f64 = 0.03; + pub struct EnderPearlEntity { pub thrown: ThrownItemEntity, } @@ -23,13 +25,14 @@ impl EnderPearlEntity { owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: GRAVITY, }; Self { thrown } } pub fn new_shot(entity: Entity, shooter: &Entity) -> Self { - let thrown = ThrownItemEntity::new(entity, shooter); + let thrown = ThrownItemEntity::new(entity, shooter, GRAVITY); thrown.entity.set_velocity(Vector3::new(0.0, 0.1, 0.0)); Self { thrown } } diff --git a/pumpkin/src/entity/projectile/fireball.rs b/pumpkin/src/entity/projectile/fireball.rs index b298b3b21..678915050 100644 --- a/pumpkin/src/entity/projectile/fireball.rs +++ b/pumpkin/src/entity/projectile/fireball.rs @@ -10,6 +10,7 @@ use crate::{ }; const EXPLOSION_POWER: f32 = 1.0; +const GRAVITY: f64 = 0.0; pub struct FireballEntity { pub thrown: ThrownItemEntity, @@ -24,6 +25,7 @@ impl FireballEntity { owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: GRAVITY, }; Self { @@ -34,7 +36,7 @@ impl FireballEntity { #[must_use] pub fn new_shot(entity: Entity, shooter: &Entity) -> Self { - let thrown = ThrownItemEntity::new(entity, shooter); + let thrown = ThrownItemEntity::new(entity, shooter, GRAVITY); Self { thrown, explosion_power: EXPLOSION_POWER, diff --git a/pumpkin/src/entity/projectile/firework_rocket.rs b/pumpkin/src/entity/projectile/firework_rocket.rs index bc3591e82..50d0961f3 100644 --- a/pumpkin/src/entity/projectile/firework_rocket.rs +++ b/pumpkin/src/entity/projectile/firework_rocket.rs @@ -15,6 +15,8 @@ use std::sync::{ atomic::{AtomicU32, Ordering}, }; +const GRAVITY: f64 = 0.0; + pub struct FireworkRocketEntity { entity: ThrownItemEntity, shooter_id: Option, @@ -37,6 +39,7 @@ impl FireworkRocketEntity { owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: GRAVITY, }, shooter_id: None, life: 0.into(), @@ -51,7 +54,7 @@ impl FireworkRocketEntity { // Set random initial velocity // Set on the inner entity after constructing ThrownItemEntity - let thrown = ThrownItemEntity::new(entity, shooter); + let thrown = ThrownItemEntity::new(entity, shooter, GRAVITY); thrown.entity.set_velocity(Vector3::new( random.next_triangular(0.0, 0.002_297), 0.05, diff --git a/pumpkin/src/entity/projectile/lingering_potion.rs b/pumpkin/src/entity/projectile/lingering_potion.rs index 8119c5079..218f64d7c 100644 --- a/pumpkin/src/entity/projectile/lingering_potion.rs +++ b/pumpkin/src/entity/projectile/lingering_potion.rs @@ -14,6 +14,8 @@ use pumpkin_util::math::vector3::Vector3; use tokio::sync::RwLock; use uuid::Uuid; +const GRAVITY: f64 = 0.05; + pub struct LingeringPotionEntity { pub thrown: ThrownItemEntity, pub item_stack: RwLock, @@ -27,6 +29,7 @@ impl LingeringPotionEntity { owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: GRAVITY, }; Self { @@ -39,7 +42,7 @@ impl LingeringPotionEntity { } pub fn new_shot(entity: Entity, shooter: &Entity) -> Self { - let thrown = ThrownItemEntity::new(entity, shooter); + let thrown = ThrownItemEntity::new(entity, shooter, GRAVITY); thrown.entity.set_velocity(Vector3::new(0.0, 0.1, 0.0)); Self { thrown, diff --git a/pumpkin/src/entity/projectile/mod.rs b/pumpkin/src/entity/projectile/mod.rs index 8864c2fc5..6e83ae80d 100644 --- a/pumpkin/src/entity/projectile/mod.rs +++ b/pumpkin/src/entity/projectile/mod.rs @@ -44,10 +44,11 @@ pub struct ThrownItemEntity { pub owner_id: Option, pub collides_with_projectiles: bool, pub has_hit: AtomicBool, + pub gravity: f64, } impl ThrownItemEntity { - pub fn new(entity: Entity, owner: &Entity) -> Self { + pub fn new(entity: Entity, owner: &Entity, gravity: f64) -> Self { let mut owner_pos = owner.pos.load(); owner_pos.y += owner.get_eye_height() - 0.1; entity.pos.store(owner_pos); @@ -56,6 +57,7 @@ impl ThrownItemEntity { owner_id: Some(owner.entity_id), collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity, } } @@ -257,9 +259,8 @@ impl ThrownItemEntity { const fn as_nbt_storage(&self) -> &dyn NBTStorage { self } - #[allow(clippy::unused_self)] const fn get_gravity(&self) -> f64 { - 0.03 + self.gravity } } diff --git a/pumpkin/src/entity/projectile/small_fireball.rs b/pumpkin/src/entity/projectile/small_fireball.rs index 98b9f8abd..af58aff62 100644 --- a/pumpkin/src/entity/projectile/small_fireball.rs +++ b/pumpkin/src/entity/projectile/small_fireball.rs @@ -9,6 +9,8 @@ use crate::{ server::Server, }; +const GRAVITY: f64 = 0.0; + pub struct SmallFireballEntity { pub thrown: ThrownItemEntity, } @@ -21,6 +23,7 @@ impl SmallFireballEntity { owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: GRAVITY, }; Self { thrown } @@ -28,7 +31,7 @@ impl SmallFireballEntity { #[must_use] pub fn new_shot(entity: Entity, shooter: &Entity) -> Self { - let thrown = ThrownItemEntity::new(entity, shooter); + let thrown = ThrownItemEntity::new(entity, shooter, GRAVITY); Self { thrown } } } diff --git a/pumpkin/src/entity/projectile/snowball.rs b/pumpkin/src/entity/projectile/snowball.rs index 1944ee6c4..7070a1c36 100644 --- a/pumpkin/src/entity/projectile/snowball.rs +++ b/pumpkin/src/entity/projectile/snowball.rs @@ -10,6 +10,8 @@ use pumpkin_data::damage::DamageType; use pumpkin_data::entity::{EntityStatus, EntityType}; use pumpkin_util::math::vector3::Vector3; +const GRAVITY: f64 = 0.03; + pub struct SnowballEntity { pub thrown: ThrownItemEntity, } @@ -25,13 +27,14 @@ impl SnowballEntity { owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: GRAVITY, }; Self { thrown } } pub fn new_shot(entity: Entity, shooter: &Entity) -> Self { - let thrown = ThrownItemEntity::new(entity, shooter); + let thrown = ThrownItemEntity::new(entity, shooter, GRAVITY); thrown.entity.set_velocity(Vector3::new(0.0, 0.1, 0.0)); Self { thrown } } diff --git a/pumpkin/src/entity/projectile/splash_potion.rs b/pumpkin/src/entity/projectile/splash_potion.rs index b48e8e666..c67a1e4d3 100644 --- a/pumpkin/src/entity/projectile/splash_potion.rs +++ b/pumpkin/src/entity/projectile/splash_potion.rs @@ -14,6 +14,8 @@ use pumpkin_util::math::vector3::Vector3; use pumpkin_world::world::BlockFlags; use tokio::sync::RwLock; +const GRAVITY: f64 = 0.05; + pub struct SplashPotionEntity { pub thrown: ThrownItemEntity, pub item_stack: RwLock, @@ -27,6 +29,7 @@ impl SplashPotionEntity { owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: GRAVITY, }; Self { @@ -36,7 +39,7 @@ impl SplashPotionEntity { } pub fn new_shot(entity: Entity, shooter: &Entity) -> Self { - let thrown = ThrownItemEntity::new(entity, shooter); + let thrown = ThrownItemEntity::new(entity, shooter, GRAVITY); thrown.entity.set_velocity(Vector3::new(0.0, 0.1, 0.0)); Self { thrown, diff --git a/pumpkin/src/entity/projectile/wind_charge.rs b/pumpkin/src/entity/projectile/wind_charge.rs index dc614a070..492b016bc 100644 --- a/pumpkin/src/entity/projectile/wind_charge.rs +++ b/pumpkin/src/entity/projectile/wind_charge.rs @@ -17,6 +17,7 @@ use crate::{ const EXPLOSION_POWER: f32 = 1.2; const DEFAULT_DEFLECT_COOLDOWN: u8 = 5; +pub const WIND_CHARGE_GRAVITY: f64 = 0.0; pub struct WindChargeEntity { deflect_cooldown: AtomicU8, diff --git a/pumpkin/src/entity/type.rs b/pumpkin/src/entity/type.rs index 27170ff30..07e4074fc 100644 --- a/pumpkin/src/entity/type.rs +++ b/pumpkin/src/entity/type.rs @@ -105,7 +105,7 @@ use crate::entity::projectile::shulker_bullet::ShulkerBulletEntity; use crate::entity::projectile::small_fireball::SmallFireballEntity; use crate::entity::projectile::snowball::SnowballEntity; use crate::entity::projectile::splash_potion::SplashPotionEntity; -use crate::entity::projectile::wind_charge::WindChargeEntity; +use crate::entity::projectile::wind_charge::{WIND_CHARGE_GRAVITY, WindChargeEntity}; use crate::entity::tnt::TNTEntity; use crate::entity::vehicle::boat::BoatEntity; use crate::entity::{Entity, EntityBase, mob}; @@ -250,6 +250,7 @@ pub fn from_type( owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: WIND_CHARGE_GRAVITY, }; Arc::new(WindChargeEntity::new(thrown)) } @@ -259,6 +260,7 @@ pub fn from_type( owner_id: None, collides_with_projectiles: false, has_hit: AtomicBool::new(false), + gravity: WIND_CHARGE_GRAVITY, }; Arc::new(WindChargeEntity::new(thrown)) } diff --git a/pumpkin/src/item/items/wind_charge.rs b/pumpkin/src/item/items/wind_charge.rs index 411d50ec1..e86a9bc82 100644 --- a/pumpkin/src/item/items/wind_charge.rs +++ b/pumpkin/src/item/items/wind_charge.rs @@ -8,7 +8,7 @@ use pumpkin_data::sound::Sound; use crate::entity::Entity; use crate::entity::projectile::ThrownItemEntity; -use crate::entity::projectile::wind_charge::WindChargeEntity; +use crate::entity::projectile::wind_charge::{WIND_CHARGE_GRAVITY, WindChargeEntity}; use crate::item::{ItemBehaviour, ItemMetadata}; pub struct WindChargeItem; @@ -41,7 +41,8 @@ impl ItemBehaviour for WindChargeItem { let entity = Entity::new(world.clone(), position, &EntityType::WIND_CHARGE); - let wind_charge = ThrownItemEntity::new(entity, &player.living_entity.entity); + let wind_charge = + ThrownItemEntity::new(entity, &player.living_entity.entity, WIND_CHARGE_GRAVITY); let yaw = player.living_entity.entity.yaw.load(); let pitch = player.living_entity.entity.pitch.load(); @@ -55,7 +56,7 @@ impl ItemBehaviour for WindChargeItem { ); // TODO: player.incrementStat(Stats.USED) - // TODO: Implement that the projectile will explode on impact on ground + // TODO: Implement that the projectile will explode on impact world .spawn_entity(Arc::new(WindChargeEntity::new(wind_charge))) .await;