use crate::entity::mob::Mob; use std::{any::TypeId, ops::BitOr, pin::Pin, ptr}; pub mod active_target; pub mod ambient_stand; pub mod avoid_entity; pub mod beg; pub mod blaze_attack; pub mod breed; pub mod chase_player; pub mod creeper_ignite; pub mod destroy_egg; pub mod eat_grass; pub mod escape_danger; pub mod follow_owner; pub mod follow_parent; pub mod goal_selector; pub mod look_around; pub mod look_at_entity; pub mod melee_attack; pub mod move_to_target_pos; pub mod owner_hurt_by_target; pub mod owner_hurt_target; pub mod pick_up_block; pub mod place_block; pub mod revenge; pub mod step_and_destroy_block; pub mod swim; pub mod teleport_towards_player; pub mod tempt; pub(crate) mod track_target; pub mod wander_around; pub mod zombie_attack; #[must_use] pub const fn to_goal_ticks(server_ticks: i32) -> i32 { -(-server_ticks).div_euclid(2) } pub type GoalFuture<'a, T> = Pin + Send + 'a>>; pub trait Goal: Send + Sync { /// How should the `Goal` initially start? fn can_start<'a>(&'a mut self, _mob: &'a dyn Mob) -> GoalFuture<'a, bool> { Box::pin(async { false }) } /// When it's started, how should it continue to run? fn should_continue<'a>(&'a self, _mob: &'a dyn Mob) -> GoalFuture<'a, bool> { Box::pin(async { false }) } /// Call when goal start fn start<'a>(&'a mut self, _: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async {}) } /// Call when goal stop fn stop<'a>(&'a mut self, _: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async {}) } /// If the `Goal` is running, this gets called every tick. fn tick<'a>(&'a mut self, _: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async {}) } fn should_run_every_tick(&self) -> bool { false } fn can_stop(&self) -> bool { true } fn get_tick_count(&self, ticks: i32) -> i32 { if self.should_run_every_tick() { ticks } else { to_goal_ticks(ticks) } } fn controls(&self) -> Controls { Controls::empty() } } #[derive(Clone, Copy, Default)] // We actually only use the first 4 bits ;) pub struct Controls(u8); impl Controls { pub const MOVE: Self = Self(1); pub const LOOK: Self = Self(2); pub const JUMP: Self = Self(4); pub const TARGET: Self = Self(8); pub const ITER: [Self; 4] = [Self::MOVE, Self::LOOK, Self::JUMP, Self::TARGET]; #[must_use] pub fn empty() -> Self { Self::default() } pub const fn set(&mut self, control: Self, val: bool) { if val { self.0 |= control.0; } else { self.0 &= !control.0; } } #[must_use] pub const fn get(&self, control: Self) -> bool { self.0 & control.0 != 0 } #[must_use] pub fn idx(&self) -> usize { for (i, control) in Self::ITER.into_iter().enumerate() { if self.get(control) { return i; } } tracing::error!("Controls::idx called with no controls set"); 0 } } impl BitOr for Controls { type Output = Self; fn bitor(self, rhs: Self) -> Self::Output { Self(self.0 | rhs.0) } } pub struct PrioritizedGoal { pub goal: Box, pub running: bool, pub priority: u8, /// Used to compare goals of the same type. /// Always set to `TypeId::of::()` where `G: Goal`. type_id: TypeId, } impl PrioritizedGoal { #[must_use] pub fn new(type_id: TypeId, priority: u8, goal: Box) -> Self { Self { goal, running: false, priority, type_id, } } fn can_be_replaced_by(&self, goal: &Self) -> bool { self.can_stop() && goal.priority < self.priority } } impl Goal for PrioritizedGoal { fn can_start<'a>(&'a mut self, mob: &'a dyn Mob) -> GoalFuture<'a, bool> { Box::pin(async { self.goal.can_start(mob).await }) } fn should_continue<'a>(&'a self, mob: &'a dyn Mob) -> GoalFuture<'a, bool> { Box::pin(async { self.goal.should_continue(mob).await }) } fn start<'a>(&'a mut self, mob: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async { if !self.running { self.running = true; self.goal.start(mob).await; } }) } fn stop<'a>(&'a mut self, mob: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async { if self.running { self.running = false; self.goal.stop(mob).await; } }) } fn tick<'a>(&'a mut self, mob: &'a dyn Mob) -> GoalFuture<'a, ()> { Box::pin(async { self.goal.tick(mob).await; }) } fn should_run_every_tick(&self) -> bool { self.goal.should_run_every_tick() } fn get_tick_count(&self, ticks: i32) -> i32 { self.goal.get_tick_count(ticks) } fn controls(&self) -> Controls { self.goal.controls() } } #[derive(Clone)] pub struct ParentHandle

{ ptr: *const P, } impl

ParentHandle

{ /// This wrapper allows a child struct to hold a reference to its parent /// without making the code overly verbose. /// /// # Safety /// - The parent must outlive this handle. /// - The parent must be inside a smart pointer; otherwise it /// will move in memory and cause undefined behavior! /// /// # Example /// ``` /// use pumpkin::entity::ai::goal::ParentHandle; /// /// struct Parent { /// child: Child, /// value: i32 /// } /// /// struct Child { /// parent: ParentHandle, /// } /// /// impl Child { /// fn value(&self) -> i32 { /// self.parent.get().unwrap().value /// } /// } /// /// let mut parent = Box::new(Parent { /// child: Child {parent: ParentHandle::none()}, /// value: 7, /// }); /// parent.child.parent = unsafe { ParentHandle::new(&parent) }; /// /// assert_eq!(parent.child.value(), 7); /// ``` pub const unsafe fn new(parent: &P) -> Self { Self { ptr: ptr::from_ref(parent), } } #[must_use] /// Creates an empty handle (equivalent to `Option::None`). // We can use null as None because we handle it in get. pub const fn none() -> Self { Self { ptr: ptr::null() } } #[must_use] /// Returns a reference to the parent if available. /// This will cause undefined behavior if #Safety rules in new aren't followed pub const fn get(&self) -> Option<&P> { if self.ptr.is_null() { None } else { unsafe { Some(&*self.ptr) } } } } impl

Default for ParentHandle

{ fn default() -> Self { Self::none() } } // This is safe since we own everything. unsafe impl

Sync for ParentHandle

{} unsafe impl

Send for ParentHandle

{}