azalea/pathfinder/
goto_event.rs

1use std::{sync::Arc, time::Duration};
2
3use bevy_ecs::{entity::Entity, event::Event};
4
5use crate::pathfinder::{
6    astar::PathfinderTimeout,
7    goals::Goal,
8    moves::{self, SuccessorsFn},
9};
10
11/// Send this event to start pathfinding to the given goal.
12///
13/// Also see [`PathfinderClientExt::goto`].
14///
15/// This event is read by [`goto_listener`].
16#[derive(Event)]
17#[non_exhaustive]
18pub struct GotoEvent {
19    /// The local bot entity that will do the pathfinding and execute the path.
20    pub entity: Entity,
21    pub goal: Arc<dyn Goal>,
22    /// The function that's used for checking what moves are possible. Usually
23    /// [`moves::default_move`].
24    pub successors_fn: SuccessorsFn,
25
26    /// Whether the bot is allowed to break blocks while pathfinding.
27    pub allow_mining: bool,
28
29    /// Whether we should recalculate the path when the pathfinder timed out and
30    /// there's no partial path to try.
31    ///
32    /// Should usually be set to true.
33    pub retry_on_no_path: bool,
34
35    /// The minimum amount of time that should pass before the A* pathfinder
36    /// function can return a timeout. It may take up to [`Self::max_timeout`]
37    /// if it can't immediately find a usable path.
38    ///
39    /// A good default value for this is
40    /// `PathfinderTimeout::Time(Duration::from_secs(1))`.
41    ///
42    /// Also see [`PathfinderTimeout::Nodes`]
43    pub min_timeout: PathfinderTimeout,
44    /// The absolute maximum amount of time that the pathfinder function can
45    /// take to find a path. If it takes this long, it means no usable path was
46    /// found (so it might be impossible).
47    ///
48    /// A good default value for this is
49    /// `PathfinderTimeout::Time(Duration::from_secs(5))`.
50    pub max_timeout: PathfinderTimeout,
51}
52impl GotoEvent {
53    pub fn new(entity: Entity, goal: impl Goal + 'static) -> Self {
54        Self {
55            entity,
56            goal: Arc::new(goal),
57            successors_fn: moves::default_move,
58            allow_mining: true,
59            retry_on_no_path: true,
60            min_timeout: PathfinderTimeout::Time(Duration::from_secs(1)),
61            max_timeout: PathfinderTimeout::Time(Duration::from_secs(5)),
62        }
63    }
64    pub fn with_successors_fn(mut self, successors_fn: SuccessorsFn) -> Self {
65        self.successors_fn = successors_fn;
66        self
67    }
68    pub fn with_allow_mining(mut self, allow_mining: bool) -> Self {
69        self.allow_mining = allow_mining;
70        self
71    }
72    pub fn with_retry_on_no_path(mut self, retry_on_no_path: bool) -> Self {
73        self.retry_on_no_path = retry_on_no_path;
74        self
75    }
76    pub fn with_min_timeout(mut self, min_timeout: PathfinderTimeout) -> Self {
77        self.min_timeout = min_timeout;
78        self
79    }
80    pub fn with_max_timeout(mut self, max_timeout: PathfinderTimeout) -> Self {
81        self.max_timeout = max_timeout;
82        self
83    }
84}