mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
* chore(bedrock): Update most of the packets to mirror the official docs more closely. * Fix typo * Fix CCreativeContent * Undo unrelated `registry.rs` change * Update WIT to merged PR --------- Signed-off-by: Demetrius Kanios <demetrius@kanios.net>
91 lines
2.7 KiB
Rust
91 lines
2.7 KiB
Rust
use std::sync::Arc;
|
|
use std::sync::atomic::AtomicBool;
|
|
|
|
use crate::entity::projectile::ProjectileHit;
|
|
use crate::{
|
|
entity::{Entity, EntityBase, EntityBaseFuture, projectile::ThrownItemEntity},
|
|
server::Server,
|
|
};
|
|
use pumpkin_data::damage::DamageType;
|
|
use pumpkin_data::entity::{EntityStatus, EntityType};
|
|
use pumpkin_protocol::bedrock::server::actor_event::ActorEventID;
|
|
use pumpkin_util::math::vector3::Vector3;
|
|
|
|
const GRAVITY: f64 = 0.03;
|
|
|
|
pub struct SnowballEntity {
|
|
pub thrown: ThrownItemEntity,
|
|
}
|
|
|
|
impl SnowballEntity {
|
|
pub fn new(entity: Entity) -> Self {
|
|
// Keep the velocity initialization
|
|
entity.set_velocity(Vector3::new(0.0, 0.1, 0.0));
|
|
|
|
// Initialize without owner
|
|
let thrown = ThrownItemEntity {
|
|
entity,
|
|
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, GRAVITY);
|
|
thrown.entity.set_velocity(Vector3::new(0.0, 0.1, 0.0));
|
|
Self { thrown }
|
|
}
|
|
}
|
|
|
|
impl EntityBase for SnowballEntity {
|
|
fn tick<'a>(
|
|
&'a self,
|
|
caller: &'a Arc<dyn EntityBase>,
|
|
server: &'a Server,
|
|
) -> EntityBaseFuture<'a, ()> {
|
|
Box::pin(async move { self.thrown.process_tick(caller, server).await })
|
|
}
|
|
|
|
fn get_entity(&self) -> &Entity {
|
|
self.thrown.get_entity()
|
|
}
|
|
|
|
fn get_living_entity(&self) -> Option<&crate::entity::living::LivingEntity> {
|
|
None
|
|
}
|
|
fn cast_any(&self) -> &dyn std::any::Any {
|
|
self
|
|
}
|
|
|
|
fn on_hit(&self, hit: crate::entity::projectile::ProjectileHit) -> EntityBaseFuture<'_, ()> {
|
|
Box::pin(async move {
|
|
let world = self.get_entity().world.load();
|
|
|
|
// Always send particle status regardless of what was hit
|
|
world.send_entity_status(
|
|
self.get_entity(),
|
|
EntityStatus::Death,
|
|
Some(ActorEventID::Death),
|
|
);
|
|
|
|
// Handle entity-specific damage
|
|
if let ProjectileHit::Entity { ref entity, .. } = hit {
|
|
let entity_clone = entity.clone();
|
|
|
|
tokio::spawn(async move {
|
|
let is_blaze = entity_clone.get_entity().entity_type.id == EntityType::BLAZE.id;
|
|
let damage = if is_blaze { 3.0 } else { 0.0 }; // Only damage blazes
|
|
|
|
entity_clone
|
|
.damage(entity_clone.as_ref(), damage, DamageType::THROWN)
|
|
.await;
|
|
});
|
|
}
|
|
})
|
|
}
|
|
}
|