diff --git a/pumpkin/src/block/blocks/cactus.rs b/pumpkin/src/block/blocks/cactus.rs index a7500b616..7af84d131 100644 --- a/pumpkin/src/block/blocks/cactus.rs +++ b/pumpkin/src/block/blocks/cactus.rs @@ -1,11 +1,12 @@ use std::sync::Arc; use async_trait::async_trait; -use pumpkin_data::Block; use pumpkin_data::block_properties::{ BlockProperties, CactusLikeProperties, EnumVariants, Integer0To15, }; +use pumpkin_data::damage::DamageType; use pumpkin_data::tag::Tagable; +use pumpkin_data::{Block, BlockState}; use pumpkin_macros::pumpkin_block; use pumpkin_protocol::server::play::SUseItemOn; use pumpkin_util::math::position::BlockPos; @@ -15,6 +16,7 @@ use pumpkin_world::chunk::TickPriority; use pumpkin_world::world::BlockFlags; use crate::block::pumpkin_block::PumpkinBlock; +use crate::entity::EntityBase; use crate::entity::player::Player; use crate::server::Server; use crate::world::World; @@ -59,6 +61,17 @@ impl PumpkinBlock for CactusBlock { } } + async fn on_entity_collision( + &self, + _world: &Arc, + entity: &dyn EntityBase, + _pos: BlockPos, + _block: Block, + _state: BlockState, + ) { + entity.damage(1.0, DamageType::CACTUS).await; + } + async fn get_state_for_neighbor_update( &self, world: &World, diff --git a/pumpkin/src/block/blocks/redstone/pressure_plate/plate.rs b/pumpkin/src/block/blocks/redstone/pressure_plate/plate.rs index 50c67a39a..f080de4d0 100644 --- a/pumpkin/src/block/blocks/redstone/pressure_plate/plate.rs +++ b/pumpkin/src/block/blocks/redstone/pressure_plate/plate.rs @@ -11,7 +11,7 @@ use pumpkin_world::{BlockStateId, block::BlockDirection}; use crate::{ block::pumpkin_block::{BlockMetadata, PumpkinBlock}, - entity::Entity, + entity::EntityBase, world::World, }; @@ -44,7 +44,7 @@ impl PumpkinBlock for PressurePlateBlock { async fn on_entity_collision( &self, world: &Arc, - _entity: &Entity, + _entity: &dyn EntityBase, pos: BlockPos, block: Block, state: BlockState, diff --git a/pumpkin/src/block/blocks/redstone/pressure_plate/weighted.rs b/pumpkin/src/block/blocks/redstone/pressure_plate/weighted.rs index 7118d8eb8..52efc39ef 100644 --- a/pumpkin/src/block/blocks/redstone/pressure_plate/weighted.rs +++ b/pumpkin/src/block/blocks/redstone/pressure_plate/weighted.rs @@ -10,7 +10,7 @@ use pumpkin_world::{BlockStateId, block::BlockDirection}; use crate::{ block::pumpkin_block::{BlockMetadata, PumpkinBlock}, - entity::Entity, + entity::EntityBase, world::World, }; @@ -41,7 +41,7 @@ impl PumpkinBlock for WeightedPressurePlateBlock { async fn on_entity_collision( &self, world: &Arc, - _entity: &Entity, + _entity: &dyn EntityBase, pos: BlockPos, block: Block, state: BlockState, diff --git a/pumpkin/src/block/pumpkin_block.rs b/pumpkin/src/block/pumpkin_block.rs index 76fbdb291..0d63b5315 100644 --- a/pumpkin/src/block/pumpkin_block.rs +++ b/pumpkin/src/block/pumpkin_block.rs @@ -1,5 +1,5 @@ use crate::block::registry::BlockActionResult; -use crate::entity::Entity; +use crate::entity::EntityBase; use crate::entity::player::Player; use crate::server::Server; use crate::world::World; @@ -53,7 +53,7 @@ pub trait PumpkinBlock: Send + Sync { async fn on_entity_collision( &self, _world: &Arc, - _entity: &Entity, + _entity: &dyn EntityBase, _pos: BlockPos, _block: Block, _state: BlockState, diff --git a/pumpkin/src/block/registry.rs b/pumpkin/src/block/registry.rs index fabfea938..85ad20ce4 100644 --- a/pumpkin/src/block/registry.rs +++ b/pumpkin/src/block/registry.rs @@ -1,5 +1,5 @@ use crate::block::pumpkin_block::{BlockMetadata, PumpkinBlock}; -use crate::entity::Entity; +use crate::entity::EntityBase; use crate::entity::player::Player; use crate::server::Server; use crate::world::World; @@ -60,7 +60,7 @@ impl BlockRegistry { &self, block: Block, world: &Arc, - entity: &Entity, + entity: &dyn EntityBase, pos: BlockPos, state: BlockState, ) { diff --git a/pumpkin/src/entity/experience_orb.rs b/pumpkin/src/entity/experience_orb.rs index 74e2cf0bd..87fb23620 100644 --- a/pumpkin/src/entity/experience_orb.rs +++ b/pumpkin/src/entity/experience_orb.rs @@ -64,8 +64,8 @@ impl ExperienceOrbEntity { #[async_trait] impl EntityBase for ExperienceOrbEntity { - async fn tick(&self, server: &Server) { - self.entity.tick(server).await; + async fn tick(&self, caller: &dyn EntityBase, server: &Server) { + self.entity.tick(caller, server).await; let age = self .orb_age @@ -79,7 +79,7 @@ impl EntityBase for ExperienceOrbEntity { &self.entity } - async fn on_player_collision(&self, player: Arc) { + async fn on_player_collision(&self, player: &Arc) { let mut delay = player.experience_pick_up_delay.lock().await; if *delay == 0 { *delay = 2; diff --git a/pumpkin/src/entity/item.rs b/pumpkin/src/entity/item.rs index 14bb78e48..068461735 100644 --- a/pumpkin/src/entity/item.rs +++ b/pumpkin/src/entity/item.rs @@ -63,9 +63,9 @@ impl ItemEntity { #[async_trait] impl EntityBase for ItemEntity { - async fn tick(&self, server: &Server) { + async fn tick(&self, caller: &dyn EntityBase, server: &Server) { let entity = &self.entity; - entity.tick(server).await; + entity.tick(caller, server).await; { let mut delay = self.pickup_delay.lock().await; *delay = delay.saturating_sub(1); @@ -91,7 +91,7 @@ impl EntityBase for ItemEntity { false } - async fn on_player_collision(&self, player: Arc) { + async fn on_player_collision(&self, player: &Arc) { let can_pickup = { let delay = self.pickup_delay.lock().await; *delay == 0 diff --git a/pumpkin/src/entity/living.rs b/pumpkin/src/entity/living.rs index 43b430e8e..53a73a495 100644 --- a/pumpkin/src/entity/living.rs +++ b/pumpkin/src/entity/living.rs @@ -262,7 +262,7 @@ impl LivingEntity { .await; } - async fn tick_move(&self) { + async fn tick_move(&self, entity: &dyn EntityBase) { let velo = self.entity.velocity.load(); let pos = self.entity.pos.load(); self.entity @@ -272,7 +272,7 @@ impl LivingEntity { self.entity .velocity .store(velo.multiply(multiplier, 1.0, multiplier)); - self.entity.check_block_collision().await; + Entity::check_block_collision(entity).await; } async fn tick_effects(&self) { @@ -296,9 +296,9 @@ impl LivingEntity { #[async_trait] impl EntityBase for LivingEntity { - async fn tick(&self, server: &Server) { - self.entity.tick(server).await; - self.tick_move().await; + async fn tick(&self, caller: &dyn EntityBase, server: &Server) { + self.entity.tick(caller, server).await; + self.tick_move(caller).await; self.tick_effects().await; if self.time_until_regen.load(Relaxed) > 0 { self.time_until_regen.fetch_sub(1, Relaxed); diff --git a/pumpkin/src/entity/mob/mod.rs b/pumpkin/src/entity/mob/mod.rs index 6a938037a..5ed3026f9 100644 --- a/pumpkin/src/entity/mob/mod.rs +++ b/pumpkin/src/entity/mob/mod.rs @@ -24,8 +24,8 @@ pub struct MobEntity { #[async_trait] impl EntityBase for MobEntity { - async fn tick(&self, server: &Server) { - self.living_entity.tick(server).await; + async fn tick(&self, caller: &dyn EntityBase, server: &Server) { + self.living_entity.tick(caller, server).await; let mut goals = self.goals.lock().await; for (goal, running) in goals.iter_mut() { if *running { diff --git a/pumpkin/src/entity/mod.rs b/pumpkin/src/entity/mod.rs index 2cdfa10c4..4ab3f29af 100644 --- a/pumpkin/src/entity/mod.rs +++ b/pumpkin/src/entity/mod.rs @@ -57,12 +57,18 @@ pub type EntityId = i32; #[async_trait] pub trait EntityBase: Send + Sync { - /// Gets Called every tick - async fn tick(&self, server: &Server) { + /// Called every tick for this entity. + /// + /// The `caller` parameter is a reference to the entity that initiated the tick. + /// This can be the same entity the method is being called on (`self`), + /// but in some scenarios (e.g., interactions or events), it might be a different entity. + /// + /// The `server` parameter provides access to the game server instance. + async fn tick(&self, caller: &dyn EntityBase, server: &Server) { if let Some(living) = self.get_living_entity() { - living.tick(server).await; + living.tick(caller, server).await; } else { - self.get_entity().tick(server).await; + self.get_entity().tick(caller, server).await; } } @@ -78,7 +84,7 @@ pub trait EntityBase: Send + Sync { } /// Called when a player collides with a entity - async fn on_player_collision(&self, _player: Arc) {} + async fn on_player_collision(&self, _player: &Arc) {} fn get_entity(&self) -> &Entity; fn get_living_entity(&self) -> Option<&LivingEntity>; } @@ -485,8 +491,8 @@ impl Entity { // } } - pub async fn check_block_collision(&self) { - let aabb = self.bounding_box.load(); + pub async fn check_block_collision(entity: &dyn EntityBase) { + let aabb = entity.get_entity().bounding_box.load(); let blockpos = BlockPos::new( (aabb.min.x + 0.001).floor() as i32, (aabb.min.y + 0.001).floor() as i32, @@ -497,7 +503,7 @@ impl Entity { (aabb.max.y - 0.001).floor() as i32, (aabb.max.z - 0.001).floor() as i32, ); - let world = self.world.read().await; + let world = entity.get_entity().world.read().await; for x in blockpos.0.x..=blockpos1.0.x { for y in blockpos.0.y..=blockpos1.0.y { @@ -506,7 +512,7 @@ impl Entity { let (block, state) = world.get_block_and_block_state(&pos).await.unwrap(); world .block_registry - .on_entity_collision(block, &world, self, pos, state) + .on_entity_collision(block, &world, entity, pos, state) .await; } } @@ -520,8 +526,8 @@ impl EntityBase for Entity { false } - async fn tick(&self, _: &Server) { - //Todo! Tick + async fn tick(&self, _caller: &dyn EntityBase, _: &Server) { + // TODO: Tick } fn get_entity(&self) -> &Entity { diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 9c38a7c63..ce0e71304 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -663,7 +663,7 @@ impl Player { self.last_attacked_ticks.fetch_add(1, Relaxed); - self.living_entity.tick(server).await; + self.living_entity.tick(self, server).await; self.hunger_manager.tick(self).await; // experience handling @@ -1797,6 +1797,9 @@ impl NBTStorage for PlayerInventory { #[async_trait] impl EntityBase for Player { async fn damage(&self, amount: f32, damage_type: DamageType) -> bool { + if self.abilities.lock().await.invulnerable { + return false; + } self.world() .await .play_sound( diff --git a/pumpkin/src/entity/tnt.rs b/pumpkin/src/entity/tnt.rs index c9b47f82e..e78058476 100644 --- a/pumpkin/src/entity/tnt.rs +++ b/pumpkin/src/entity/tnt.rs @@ -31,7 +31,7 @@ impl TNTEntity { #[async_trait] impl EntityBase for TNTEntity { - async fn tick(&self, server: &Server) { + async fn tick(&self, _caller: &dyn EntityBase, server: &Server) { let fuse = self.fuse.fetch_sub(1, Relaxed); if fuse == 0 { self.entity.remove().await; diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 6cd4c99c2..f4040f532 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -400,7 +400,7 @@ impl World { // Entity ticks for entity in entities_to_tick { - entity.tick(server).await; + entity.tick(entity.as_ref(), server).await; for player in self.players.read().await.values() { if player .living_entity @@ -411,7 +411,7 @@ impl World { .expand(1.0, 0.5, 1.0) .intersects(&entity.get_entity().bounding_box.load()) { - entity.on_player_collision(player.clone()).await; + entity.on_player_collision(player).await; break; } }