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}