#[non_exhaustive]pub struct PathfinderOpts { /* private fields */ }Expand description
Configuration options that the pathfinder will use when calculating and executing a path.
This can be passed into Client::goto_with_opts or
Client::start_goto_with_opts.
// example config to disallow mining blocks and to not do parkour
let opts = PathfinderOpts::new()
.allow_mining(false)
.successors_fn(moves::basic::basic_move);Implementations§
Source§impl PathfinderOpts
impl PathfinderOpts
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Examples found in repository?
132async fn handle(bot: Client, event: azalea::Event, state: State) -> eyre::Result<()> {
133 let swarm = bot.resource::<SwarmState>();
134
135 match event {
136 azalea::Event::Init => {
137 bot.set_client_information(ClientInformation {
138 view_distance: 32,
139 ..Default::default()
140 });
141 if swarm.args.pathfinder_debug_particles {
142 bot.ecs
143 .write()
144 .entity_mut(bot.entity)
145 .insert(PathfinderDebugParticles);
146 }
147 }
148 azalea::Event::Chat(chat) => {
149 let (Some(username), content) = chat.split_sender_and_content() else {
150 return Ok(());
151 };
152 if username != swarm.args.owner_username {
153 return Ok(());
154 }
155
156 println!("{:?}", chat.message());
157
158 let command = if chat.is_whisper() {
159 Some(content)
160 } else {
161 content.strip_prefix('!').map(|s| s.to_owned())
162 };
163 if let Some(command) = command {
164 match swarm.commands.execute(
165 command,
166 Mutex::new(CommandSource {
167 bot: bot.clone(),
168 chat: chat.clone(),
169 state: state.clone(),
170 }),
171 ) {
172 Ok(_) => {}
173 Err(err) => {
174 eprintln!("{err:?}");
175 let command_source = CommandSource {
176 bot,
177 chat: chat.clone(),
178 state: state.clone(),
179 };
180 command_source.reply(format!("{err:?}"));
181 }
182 }
183 }
184 }
185 azalea::Event::Tick => {
186 killaura::tick(bot.clone(), state.clone())?;
187
188 if bot.ticks_connected().is_multiple_of(5) {
189 if let Some(following) = &*state.following_entity.lock()
190 && following.is_alive()
191 {
192 let goal = RadiusGoal::new(following.position(), 3.);
193 if bot.is_calculating_path() {
194 // keep waiting
195 } else if !goal.success(bot.position().into()) || bot.is_executing_path() {
196 bot.start_goto_with_opts(
197 goal,
198 PathfinderOpts::new()
199 .retry_on_no_path(false)
200 .max_timeout(Duration::from_secs(1)),
201 );
202 } else {
203 following.look_at();
204 }
205 }
206 }
207 }
208 azalea::Event::Login => {
209 println!("Got login event")
210 }
211 _ => {}
212 }
213
214 Ok(())
215}Sourcepub fn successors_fn(self, successors_fn: SuccessorsFn) -> Self
pub fn successors_fn(self, successors_fn: SuccessorsFn) -> Self
Set the function that’s used for checking what moves are possible.
Defaults to moves::default_move.
Sourcepub fn allow_mining(self, allow_mining: bool) -> Self
pub fn allow_mining(self, allow_mining: bool) -> Self
Set whether the bot is allowed to break blocks while pathfinding.
Defaults to true.
Sourcepub fn retry_on_no_path(self, retry_on_no_path: bool) -> Self
pub fn retry_on_no_path(self, retry_on_no_path: bool) -> Self
Whether we should recalculate the path when the pathfinder timed out and there’s no partial path to try.
Defaults to true.
Examples found in repository?
132async fn handle(bot: Client, event: azalea::Event, state: State) -> eyre::Result<()> {
133 let swarm = bot.resource::<SwarmState>();
134
135 match event {
136 azalea::Event::Init => {
137 bot.set_client_information(ClientInformation {
138 view_distance: 32,
139 ..Default::default()
140 });
141 if swarm.args.pathfinder_debug_particles {
142 bot.ecs
143 .write()
144 .entity_mut(bot.entity)
145 .insert(PathfinderDebugParticles);
146 }
147 }
148 azalea::Event::Chat(chat) => {
149 let (Some(username), content) = chat.split_sender_and_content() else {
150 return Ok(());
151 };
152 if username != swarm.args.owner_username {
153 return Ok(());
154 }
155
156 println!("{:?}", chat.message());
157
158 let command = if chat.is_whisper() {
159 Some(content)
160 } else {
161 content.strip_prefix('!').map(|s| s.to_owned())
162 };
163 if let Some(command) = command {
164 match swarm.commands.execute(
165 command,
166 Mutex::new(CommandSource {
167 bot: bot.clone(),
168 chat: chat.clone(),
169 state: state.clone(),
170 }),
171 ) {
172 Ok(_) => {}
173 Err(err) => {
174 eprintln!("{err:?}");
175 let command_source = CommandSource {
176 bot,
177 chat: chat.clone(),
178 state: state.clone(),
179 };
180 command_source.reply(format!("{err:?}"));
181 }
182 }
183 }
184 }
185 azalea::Event::Tick => {
186 killaura::tick(bot.clone(), state.clone())?;
187
188 if bot.ticks_connected().is_multiple_of(5) {
189 if let Some(following) = &*state.following_entity.lock()
190 && following.is_alive()
191 {
192 let goal = RadiusGoal::new(following.position(), 3.);
193 if bot.is_calculating_path() {
194 // keep waiting
195 } else if !goal.success(bot.position().into()) || bot.is_executing_path() {
196 bot.start_goto_with_opts(
197 goal,
198 PathfinderOpts::new()
199 .retry_on_no_path(false)
200 .max_timeout(Duration::from_secs(1)),
201 );
202 } else {
203 following.look_at();
204 }
205 }
206 }
207 }
208 azalea::Event::Login => {
209 println!("Got login event")
210 }
211 _ => {}
212 }
213
214 Ok(())
215}Sourcepub fn min_timeout(self, min_timeout: impl Into<PathfinderTimeout>) -> Self
pub fn min_timeout(self, min_timeout: impl Into<PathfinderTimeout>) -> Self
The minimum amount of time that should pass before the A* pathfinder
function can return a timeout if it finds a path that seems good enough.
It may take up to Self::max_timeout if it can’t immediately find
a usable path.
Defaults to PathfinderTimeout::Time(Duration::from_secs(1)).
Also see PathfinderTimeout::Nodes
Sourcepub fn max_timeout(self, max_timeout: impl Into<PathfinderTimeout>) -> Self
pub fn max_timeout(self, max_timeout: impl Into<PathfinderTimeout>) -> Self
The absolute maximum amount of time that the pathfinder function can take to find a path.
If it takes this long, it means no usable path was found (so it might be impossible).
Defaults to PathfinderTimeout::Time(Duration::from_secs(5)).
Examples found in repository?
132async fn handle(bot: Client, event: azalea::Event, state: State) -> eyre::Result<()> {
133 let swarm = bot.resource::<SwarmState>();
134
135 match event {
136 azalea::Event::Init => {
137 bot.set_client_information(ClientInformation {
138 view_distance: 32,
139 ..Default::default()
140 });
141 if swarm.args.pathfinder_debug_particles {
142 bot.ecs
143 .write()
144 .entity_mut(bot.entity)
145 .insert(PathfinderDebugParticles);
146 }
147 }
148 azalea::Event::Chat(chat) => {
149 let (Some(username), content) = chat.split_sender_and_content() else {
150 return Ok(());
151 };
152 if username != swarm.args.owner_username {
153 return Ok(());
154 }
155
156 println!("{:?}", chat.message());
157
158 let command = if chat.is_whisper() {
159 Some(content)
160 } else {
161 content.strip_prefix('!').map(|s| s.to_owned())
162 };
163 if let Some(command) = command {
164 match swarm.commands.execute(
165 command,
166 Mutex::new(CommandSource {
167 bot: bot.clone(),
168 chat: chat.clone(),
169 state: state.clone(),
170 }),
171 ) {
172 Ok(_) => {}
173 Err(err) => {
174 eprintln!("{err:?}");
175 let command_source = CommandSource {
176 bot,
177 chat: chat.clone(),
178 state: state.clone(),
179 };
180 command_source.reply(format!("{err:?}"));
181 }
182 }
183 }
184 }
185 azalea::Event::Tick => {
186 killaura::tick(bot.clone(), state.clone())?;
187
188 if bot.ticks_connected().is_multiple_of(5) {
189 if let Some(following) = &*state.following_entity.lock()
190 && following.is_alive()
191 {
192 let goal = RadiusGoal::new(following.position(), 3.);
193 if bot.is_calculating_path() {
194 // keep waiting
195 } else if !goal.success(bot.position().into()) || bot.is_executing_path() {
196 bot.start_goto_with_opts(
197 goal,
198 PathfinderOpts::new()
199 .retry_on_no_path(false)
200 .max_timeout(Duration::from_secs(1)),
201 );
202 } else {
203 following.look_at();
204 }
205 }
206 }
207 }
208 azalea::Event::Login => {
209 println!("Got login event")
210 }
211 _ => {}
212 }
213
214 Ok(())
215}Trait Implementations§
Source§impl Clone for PathfinderOpts
impl Clone for PathfinderOpts
Source§fn clone(&self) -> PathfinderOpts
fn clone(&self) -> PathfinderOpts
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for PathfinderOpts
impl Debug for PathfinderOpts
Auto Trait Implementations§
impl Freeze for PathfinderOpts
impl RefUnwindSafe for PathfinderOpts
impl Send for PathfinderOpts
impl Sync for PathfinderOpts
impl Unpin for PathfinderOpts
impl UnsafeUnpin for PathfinderOpts
impl UnwindSafe for PathfinderOpts
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> CompatExt for T
impl<T> CompatExt for T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self using default().