pub struct LookDirection { /* private fields */ }Expand description
The direction that an entity is looking, in degrees.
To avoid flagging anticheats, consider using Self::update when updating
the values of this struct.
Implementations§
Source§impl LookDirection
impl LookDirection
Sourcepub fn new(y_rot: f32, x_rot: f32) -> Self
pub fn new(y_rot: f32, x_rot: f32) -> Self
Create a new look direction and clamp the x_rot to the allowed values.
Sourcepub fn y_rot(&self) -> f32
pub fn y_rot(&self) -> f32
Returns yaw (left and right) in degrees.
Minecraft allows this to go outside of ±360°, so it won’t necessarily be in any range.
Examples found in repository?
26pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
27 commands.register(literal("ping").executes(|ctx: &Ctx| {
28 let source = ctx.source.lock();
29 source.reply("pong!");
30 1
31 }));
32 commands.register(
33 literal("say").then(argument("message", greedy_string()).executes(|ctx: &Ctx| {
34 let source = ctx.source.lock();
35 let message = get_string(ctx, "message").unwrap();
36 source.bot.chat(message);
37 1
38 })),
39 );
40
41 commands.register(literal("disconnect").executes(|ctx: &Ctx| {
42 let source = ctx.source.lock();
43 source.bot.disconnect();
44 1
45 }));
46
47 commands.register(literal("whereami").executes(|ctx: &Ctx| {
48 let source = ctx.source.lock();
49 let Some(entity) = source.entity() else {
50 source.reply("You aren't in render distance!");
51 return 0;
52 };
53 let position = entity.position();
54 source.reply(format!(
55 "You are at {}, {}, {}",
56 position.x, position.y, position.z
57 ));
58 1
59 }));
60
61 commands.register(literal("entityid").executes(|ctx: &Ctx| {
62 let source = ctx.source.lock();
63 let Some(entity) = source.entity() else {
64 source.reply("You aren't in render distance!");
65 return 0;
66 };
67 let entity_id = entity.minecraft_id();
68 source.reply(format!(
69 "Your Minecraft ID is {} and your ECS ID is {entity:?}",
70 *entity_id
71 ));
72 1
73 }));
74
75 let whereareyou = |ctx: &Ctx| {
76 let source = ctx.source.lock();
77 let position = source.bot.position();
78 source.reply(format!(
79 "I'm at {}, {}, {}",
80 position.x, position.y, position.z
81 ));
82 1
83 };
84 commands.register(literal("whereareyou").executes(whereareyou));
85 commands.register(literal("pos").executes(whereareyou));
86
87 commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
88 let source = ctx.source.lock();
89 source.reply(format!(
90 "I am {} ({}, {})",
91 source.bot.username(),
92 source.bot.uuid(),
93 source.bot.entity
94 ));
95 1
96 }));
97
98 commands.register(literal("getdirection").executes(|ctx: &Ctx| {
99 let source = ctx.source.lock();
100 let direction = source.bot.direction();
101 source.reply(format!(
102 "I'm looking at {}, {}",
103 direction.y_rot(),
104 direction.x_rot()
105 ));
106 1
107 }));
108
109 commands.register(literal("health").executes(|ctx: &Ctx| {
110 let source = ctx.source.lock();
111
112 let health = source.bot.health();
113 source.reply(format!("I have {health} health"));
114 1
115 }));
116
117 commands.register(literal("lookingat").executes(|ctx: &Ctx| {
118 let source = ctx.source.lock();
119
120 let hit_result = source.bot.hit_result();
121
122 match &hit_result {
123 HitResult::Block(r) => {
124 if r.miss {
125 source.reply("I'm not looking at anything");
126 return 0;
127 }
128 let block_pos = r.block_pos;
129 let block = source.bot.world().read().get_block_state(block_pos);
130 source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
131 }
132 HitResult::Entity(r) => {
133 let entity_kind = **source.bot.entity_component::<EntityKindComponent>(r.entity);
134 source.reply(format!(
135 "I'm looking at {entity_kind} ({:?}) at {}",
136 r.entity, r.location
137 ));
138 }
139 }
140
141 1
142 }));
143
144 commands.register(literal("getblock").then(argument("x", integer()).then(
145 argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
146 let source = ctx.source.lock();
147 let x = get_integer(ctx, "x").unwrap();
148 let y = get_integer(ctx, "y").unwrap();
149 let z = get_integer(ctx, "z").unwrap();
150 println!("getblock xyz {x} {y} {z}");
151 let block_pos = BlockPos::new(x, y, z);
152 let block = source.bot.world().read().get_block_state(block_pos);
153 source.reply(format!("BlockKind at {block_pos} is {block:?}"));
154 1
155 })),
156 )));
157 commands.register(literal("getfluid").then(argument("x", integer()).then(
158 argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
159 let source = ctx.source.lock();
160 let x = get_integer(ctx, "x").unwrap();
161 let y = get_integer(ctx, "y").unwrap();
162 let z = get_integer(ctx, "z").unwrap();
163 println!("getfluid xyz {x} {y} {z}");
164 let block_pos = BlockPos::new(x, y, z);
165 let block = source.bot.world().read().get_fluid_state(block_pos);
166 source.reply(format!("Fluid at {block_pos} is {block:?}"));
167 1
168 })),
169 )));
170
171 commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
172 let source = ctx.source.lock();
173 let pathfinder = source.bot.get_component::<Pathfinder>();
174 let Some(pathfinder) = pathfinder else {
175 source.reply("I don't have the Pathfinder component");
176 return 1;
177 };
178 source.reply(format!(
179 "pathfinder.is_calculating: {}",
180 pathfinder.is_calculating
181 ));
182
183 let executing_path = source.bot.get_component::<ExecutingPath>();
184 let Some(executing_path) = executing_path else {
185 source.reply("I'm not executing a path");
186 return 1;
187 };
188 source.reply(format!(
189 "is_path_partial: {}, path.len: {}, queued_path.len: {}",
190 executing_path.is_path_partial,
191 executing_path.path.len(),
192 if let Some(queued) = &executing_path.queued_path {
193 queued.len().to_string()
194 } else {
195 "n/a".to_owned()
196 },
197 ));
198 1
199 }));
200 commands.register(literal("pathfindermoves").executes(|ctx: &Ctx| {
201 let source = ctx.source.lock();
202
203 let Some(entity) = source.entity() else {
204 source.reply("You aren't in render distance!");
205 return 0;
206 };
207 let position = entity.position();
208 let position = BlockPos::from(position);
209
210 let mut edges = Vec::new();
211 let cached_world = CachedWorld::new(source.bot.world(), position);
212 let mining_cache = MiningCache::new(Some(Menu::Player(inventory::Player::default())));
213 let custom_state = CustomPathfinderStateRef::default();
214
215 azalea::pathfinder::moves::default_move(
216 &mut MovesCtx {
217 edges: &mut edges,
218 world: &cached_world,
219 mining_cache: &mining_cache,
220 custom_state: &custom_state,
221 },
222 RelBlockPos::from_origin(position, position),
223 );
224
225 if edges.is_empty() {
226 source.reply("No possible moves.");
227 } else {
228 source.reply("Moves:");
229 for (i, edge) in edges.iter().enumerate() {
230 source.reply(format!("{}) {edge:?}", i + 1));
231 }
232 }
233
234 1
235 }));
236
237 commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
238 let source = ctx.source.lock();
239 source.bot.start_use_item();
240 source.reply("Ok!");
241 1
242 }));
243 commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
244 let source = ctx.source.lock();
245 let max_stack_size = source
246 .bot
247 .get_held_item()
248 .get_component::<MaxStackSize>()
249 .map_or(-1, |s| s.count);
250 source.reply(format!("{max_stack_size}"));
251 1
252 }));
253
254 commands.register(literal("dimensions").executes(|ctx: &Ctx| {
255 let source = ctx.source.lock();
256 let bot_dimensions = source.bot.dimensions();
257 source.reply(format!("{bot_dimensions:?}"));
258 1
259 }));
260
261 commands.register(literal("players").executes(|ctx: &Ctx| {
262 let source = ctx.source.lock();
263 let player_entities = source
264 .bot
265 .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
266 let tab_list = source.bot.tab_list();
267 for player_entity in player_entities {
268 let uuid = player_entity.uuid();
269 source.reply(format!(
270 "{} - {} ({:?})",
271 player_entity.id(),
272 tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
273 uuid
274 ));
275 }
276 1
277 }));
278
279 commands.register(literal("enchants").executes(|ctx: &Ctx| {
280 let source = ctx.source.lock();
281 source.bot.with_registry_holder(|r| {
282 let enchants = &r.enchantment;
283 println!("enchants: {enchants:?}");
284 });
285 1
286 }));
287
288 commands.register(literal("attributes").executes(|ctx: &Ctx| {
289 let source = ctx.source.lock();
290 let attributes = source.bot.attributes();
291 println!("attributes: {attributes:?}");
292 1
293 }));
294
295 commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
296 let source = ctx.source.lock();
297
298 source.reply("Ok!");
299
300
301
302 source.bot.disconnect();
303
304 let ecs = source.bot.ecs.clone();
305 thread::spawn(move || {
306 thread::sleep(Duration::from_secs(1));
307 // dump the ecs
308
309 let mut ecs = ecs.write();
310
311 let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
312 let mut report = File::create(&report_path).unwrap();
313
314 let mut query = ecs.query::<EntityRef>();
315 for entity in query.iter(& ecs) {
316 writeln!(report, "Entity: {}", entity.id()).unwrap();
317 let archetype = entity.archetype();
318 let component_count = archetype.component_count();
319
320 let component_names = archetype
321 .components()
322 .iter()
323 .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
324 .collect::<Vec<_>>();
325 writeln!(
326 report,
327 "- {component_count} components: {}",
328 component_names.join(", ")
329 )
330 .unwrap();
331 }
332
333 writeln!(report).unwrap();
334
335
336 for (info, _) in ecs.iter_resources() {
337 let name = info.name().to_string();
338 writeln!(report, "Resource: {name}").unwrap();
339 // writeln!(report, "- Size: {} bytes",
340 // info.layout().size()).unwrap();
341
342 match name.as_ref() {
343 "azalea_world::container::Worlds" => {
344 let worlds = ecs.resource::<Worlds>();
345
346 for (world_name, world) in &worlds.map {
347 writeln!(report, "- Name: {world_name}").unwrap();
348 writeln!(report, "- Reference count: {}", world.strong_count())
349 .unwrap();
350 if let Some(world) = world.upgrade() {
351 let world = world.read();
352 let strong_chunks = world
353 .chunks
354 .map
355 .iter()
356 .filter(|(_, v)| v.strong_count() > 0)
357 .count();
358 writeln!(
359 report,
360 "- Chunks: {} strongly referenced, {} in map",
361 strong_chunks,
362 world.chunks.map.len()
363 )
364 .unwrap();
365 writeln!(
366 report,
367 "- Entities: {}",
368 world.entities_by_chunk.len()
369 )
370 .unwrap();
371 }
372 }
373 }
374 "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
375 let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
376 writeln!(report, "- Event count: {}", events.len()).unwrap();
377 }
378 "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
379 let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
380 writeln!(report, "- Event count: {}", events.len()).unwrap();
381 }
382
383 _ => {}
384 }
385 }
386
387 println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
388 });
389
390 1
391 }));
392
393 commands.register(literal("exit").executes(|ctx: &Ctx| {
394 let source = ctx.source.lock();
395 source.reply("bye!");
396
397 source.bot.disconnect();
398
399 let source = ctx.source.clone();
400 thread::spawn(move || {
401 thread::sleep(Duration::from_secs(1));
402
403 source
404 .lock()
405 .bot
406 .ecs
407 .write()
408 .write_message(AppExit::Success);
409 });
410
411 1
412 }));
413}Sourcepub fn x_rot(&self) -> f32
pub fn x_rot(&self) -> f32
Returns pitch (up and down) in degrees.
Clamped to ±90°.
Examples found in repository?
26pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
27 commands.register(literal("ping").executes(|ctx: &Ctx| {
28 let source = ctx.source.lock();
29 source.reply("pong!");
30 1
31 }));
32 commands.register(
33 literal("say").then(argument("message", greedy_string()).executes(|ctx: &Ctx| {
34 let source = ctx.source.lock();
35 let message = get_string(ctx, "message").unwrap();
36 source.bot.chat(message);
37 1
38 })),
39 );
40
41 commands.register(literal("disconnect").executes(|ctx: &Ctx| {
42 let source = ctx.source.lock();
43 source.bot.disconnect();
44 1
45 }));
46
47 commands.register(literal("whereami").executes(|ctx: &Ctx| {
48 let source = ctx.source.lock();
49 let Some(entity) = source.entity() else {
50 source.reply("You aren't in render distance!");
51 return 0;
52 };
53 let position = entity.position();
54 source.reply(format!(
55 "You are at {}, {}, {}",
56 position.x, position.y, position.z
57 ));
58 1
59 }));
60
61 commands.register(literal("entityid").executes(|ctx: &Ctx| {
62 let source = ctx.source.lock();
63 let Some(entity) = source.entity() else {
64 source.reply("You aren't in render distance!");
65 return 0;
66 };
67 let entity_id = entity.minecraft_id();
68 source.reply(format!(
69 "Your Minecraft ID is {} and your ECS ID is {entity:?}",
70 *entity_id
71 ));
72 1
73 }));
74
75 let whereareyou = |ctx: &Ctx| {
76 let source = ctx.source.lock();
77 let position = source.bot.position();
78 source.reply(format!(
79 "I'm at {}, {}, {}",
80 position.x, position.y, position.z
81 ));
82 1
83 };
84 commands.register(literal("whereareyou").executes(whereareyou));
85 commands.register(literal("pos").executes(whereareyou));
86
87 commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
88 let source = ctx.source.lock();
89 source.reply(format!(
90 "I am {} ({}, {})",
91 source.bot.username(),
92 source.bot.uuid(),
93 source.bot.entity
94 ));
95 1
96 }));
97
98 commands.register(literal("getdirection").executes(|ctx: &Ctx| {
99 let source = ctx.source.lock();
100 let direction = source.bot.direction();
101 source.reply(format!(
102 "I'm looking at {}, {}",
103 direction.y_rot(),
104 direction.x_rot()
105 ));
106 1
107 }));
108
109 commands.register(literal("health").executes(|ctx: &Ctx| {
110 let source = ctx.source.lock();
111
112 let health = source.bot.health();
113 source.reply(format!("I have {health} health"));
114 1
115 }));
116
117 commands.register(literal("lookingat").executes(|ctx: &Ctx| {
118 let source = ctx.source.lock();
119
120 let hit_result = source.bot.hit_result();
121
122 match &hit_result {
123 HitResult::Block(r) => {
124 if r.miss {
125 source.reply("I'm not looking at anything");
126 return 0;
127 }
128 let block_pos = r.block_pos;
129 let block = source.bot.world().read().get_block_state(block_pos);
130 source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
131 }
132 HitResult::Entity(r) => {
133 let entity_kind = **source.bot.entity_component::<EntityKindComponent>(r.entity);
134 source.reply(format!(
135 "I'm looking at {entity_kind} ({:?}) at {}",
136 r.entity, r.location
137 ));
138 }
139 }
140
141 1
142 }));
143
144 commands.register(literal("getblock").then(argument("x", integer()).then(
145 argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
146 let source = ctx.source.lock();
147 let x = get_integer(ctx, "x").unwrap();
148 let y = get_integer(ctx, "y").unwrap();
149 let z = get_integer(ctx, "z").unwrap();
150 println!("getblock xyz {x} {y} {z}");
151 let block_pos = BlockPos::new(x, y, z);
152 let block = source.bot.world().read().get_block_state(block_pos);
153 source.reply(format!("BlockKind at {block_pos} is {block:?}"));
154 1
155 })),
156 )));
157 commands.register(literal("getfluid").then(argument("x", integer()).then(
158 argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
159 let source = ctx.source.lock();
160 let x = get_integer(ctx, "x").unwrap();
161 let y = get_integer(ctx, "y").unwrap();
162 let z = get_integer(ctx, "z").unwrap();
163 println!("getfluid xyz {x} {y} {z}");
164 let block_pos = BlockPos::new(x, y, z);
165 let block = source.bot.world().read().get_fluid_state(block_pos);
166 source.reply(format!("Fluid at {block_pos} is {block:?}"));
167 1
168 })),
169 )));
170
171 commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
172 let source = ctx.source.lock();
173 let pathfinder = source.bot.get_component::<Pathfinder>();
174 let Some(pathfinder) = pathfinder else {
175 source.reply("I don't have the Pathfinder component");
176 return 1;
177 };
178 source.reply(format!(
179 "pathfinder.is_calculating: {}",
180 pathfinder.is_calculating
181 ));
182
183 let executing_path = source.bot.get_component::<ExecutingPath>();
184 let Some(executing_path) = executing_path else {
185 source.reply("I'm not executing a path");
186 return 1;
187 };
188 source.reply(format!(
189 "is_path_partial: {}, path.len: {}, queued_path.len: {}",
190 executing_path.is_path_partial,
191 executing_path.path.len(),
192 if let Some(queued) = &executing_path.queued_path {
193 queued.len().to_string()
194 } else {
195 "n/a".to_owned()
196 },
197 ));
198 1
199 }));
200 commands.register(literal("pathfindermoves").executes(|ctx: &Ctx| {
201 let source = ctx.source.lock();
202
203 let Some(entity) = source.entity() else {
204 source.reply("You aren't in render distance!");
205 return 0;
206 };
207 let position = entity.position();
208 let position = BlockPos::from(position);
209
210 let mut edges = Vec::new();
211 let cached_world = CachedWorld::new(source.bot.world(), position);
212 let mining_cache = MiningCache::new(Some(Menu::Player(inventory::Player::default())));
213 let custom_state = CustomPathfinderStateRef::default();
214
215 azalea::pathfinder::moves::default_move(
216 &mut MovesCtx {
217 edges: &mut edges,
218 world: &cached_world,
219 mining_cache: &mining_cache,
220 custom_state: &custom_state,
221 },
222 RelBlockPos::from_origin(position, position),
223 );
224
225 if edges.is_empty() {
226 source.reply("No possible moves.");
227 } else {
228 source.reply("Moves:");
229 for (i, edge) in edges.iter().enumerate() {
230 source.reply(format!("{}) {edge:?}", i + 1));
231 }
232 }
233
234 1
235 }));
236
237 commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
238 let source = ctx.source.lock();
239 source.bot.start_use_item();
240 source.reply("Ok!");
241 1
242 }));
243 commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
244 let source = ctx.source.lock();
245 let max_stack_size = source
246 .bot
247 .get_held_item()
248 .get_component::<MaxStackSize>()
249 .map_or(-1, |s| s.count);
250 source.reply(format!("{max_stack_size}"));
251 1
252 }));
253
254 commands.register(literal("dimensions").executes(|ctx: &Ctx| {
255 let source = ctx.source.lock();
256 let bot_dimensions = source.bot.dimensions();
257 source.reply(format!("{bot_dimensions:?}"));
258 1
259 }));
260
261 commands.register(literal("players").executes(|ctx: &Ctx| {
262 let source = ctx.source.lock();
263 let player_entities = source
264 .bot
265 .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
266 let tab_list = source.bot.tab_list();
267 for player_entity in player_entities {
268 let uuid = player_entity.uuid();
269 source.reply(format!(
270 "{} - {} ({:?})",
271 player_entity.id(),
272 tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
273 uuid
274 ));
275 }
276 1
277 }));
278
279 commands.register(literal("enchants").executes(|ctx: &Ctx| {
280 let source = ctx.source.lock();
281 source.bot.with_registry_holder(|r| {
282 let enchants = &r.enchantment;
283 println!("enchants: {enchants:?}");
284 });
285 1
286 }));
287
288 commands.register(literal("attributes").executes(|ctx: &Ctx| {
289 let source = ctx.source.lock();
290 let attributes = source.bot.attributes();
291 println!("attributes: {attributes:?}");
292 1
293 }));
294
295 commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
296 let source = ctx.source.lock();
297
298 source.reply("Ok!");
299
300
301
302 source.bot.disconnect();
303
304 let ecs = source.bot.ecs.clone();
305 thread::spawn(move || {
306 thread::sleep(Duration::from_secs(1));
307 // dump the ecs
308
309 let mut ecs = ecs.write();
310
311 let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
312 let mut report = File::create(&report_path).unwrap();
313
314 let mut query = ecs.query::<EntityRef>();
315 for entity in query.iter(& ecs) {
316 writeln!(report, "Entity: {}", entity.id()).unwrap();
317 let archetype = entity.archetype();
318 let component_count = archetype.component_count();
319
320 let component_names = archetype
321 .components()
322 .iter()
323 .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
324 .collect::<Vec<_>>();
325 writeln!(
326 report,
327 "- {component_count} components: {}",
328 component_names.join(", ")
329 )
330 .unwrap();
331 }
332
333 writeln!(report).unwrap();
334
335
336 for (info, _) in ecs.iter_resources() {
337 let name = info.name().to_string();
338 writeln!(report, "Resource: {name}").unwrap();
339 // writeln!(report, "- Size: {} bytes",
340 // info.layout().size()).unwrap();
341
342 match name.as_ref() {
343 "azalea_world::container::Worlds" => {
344 let worlds = ecs.resource::<Worlds>();
345
346 for (world_name, world) in &worlds.map {
347 writeln!(report, "- Name: {world_name}").unwrap();
348 writeln!(report, "- Reference count: {}", world.strong_count())
349 .unwrap();
350 if let Some(world) = world.upgrade() {
351 let world = world.read();
352 let strong_chunks = world
353 .chunks
354 .map
355 .iter()
356 .filter(|(_, v)| v.strong_count() > 0)
357 .count();
358 writeln!(
359 report,
360 "- Chunks: {} strongly referenced, {} in map",
361 strong_chunks,
362 world.chunks.map.len()
363 )
364 .unwrap();
365 writeln!(
366 report,
367 "- Entities: {}",
368 world.entities_by_chunk.len()
369 )
370 .unwrap();
371 }
372 }
373 }
374 "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
375 let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
376 writeln!(report, "- Event count: {}", events.len()).unwrap();
377 }
378 "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
379 let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
380 writeln!(report, "- Event count: {}", events.len()).unwrap();
381 }
382
383 _ => {}
384 }
385 }
386
387 println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
388 });
389
390 1
391 }));
392
393 commands.register(literal("exit").executes(|ctx: &Ctx| {
394 let source = ctx.source.lock();
395 source.reply("bye!");
396
397 source.bot.disconnect();
398
399 let source = ctx.source.clone();
400 thread::spawn(move || {
401 thread::sleep(Duration::from_secs(1));
402
403 source
404 .lock()
405 .bot
406 .ecs
407 .write()
408 .write_message(AppExit::Success);
409 });
410
411 1
412 }));
413}Sourcepub fn update(&mut self, new: LookDirection)
pub fn update(&mut self, new: LookDirection)
Update this look direction to the new value.
This handles relative rotations correctly and with the default Minecraft sensitivity to avoid triggering anticheats.
Sourcepub fn update_y_rot(&mut self, new_y_rot: f32)
pub fn update_y_rot(&mut self, new_y_rot: f32)
Update the y_rot (yaw) to the given value, in degrees.
This is a shortcut for Self::update while keeping the x_rot the
same.
Sourcepub fn update_x_rot(&mut self, new_x_rot: f32)
pub fn update_x_rot(&mut self, new_x_rot: f32)
Update the x_rot (pitch) to the given value, in degrees.
This is a shortcut for Self::update while keeping the y_rot the
same.
Sourcepub fn update_with_sensitivity(&mut self, new: LookDirection, sensitivity: f32)
pub fn update_with_sensitivity(&mut self, new: LookDirection, sensitivity: f32)
Update this look direction to the new value, using the given sensitivity value.
Consider using Self::update instead, which uses 1.0 as the
sensitivity (equivalent to 100% sensitivity in Minecraft).
Sourcepub fn clamped(self) -> Self
pub fn clamped(self) -> Self
Force the Self::x_rot to be between -90 and 90 degrees, and return
the new look direction.
Trait Implementations§
Source§impl AzBuf for LookDirection
impl AzBuf for LookDirection
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), Error>
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError>
Source§impl Clone for LookDirection
impl Clone for LookDirection
Source§fn clone(&self) -> LookDirection
fn clone(&self) -> LookDirection
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Component for LookDirection
impl Component for LookDirection
Source§const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::Table
const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::Table
Source§type Mutability = Mutable
type Mutability = Mutable
Component<Mutability = Mutable>],
while immutable components will instead have [Component<Mutability = Immutable>]. Read moreSource§fn register_required_components(
_requiree: ComponentId,
required_components: &mut RequiredComponentsRegistrator<'_, '_>,
)
fn register_required_components( _requiree: ComponentId, required_components: &mut RequiredComponentsRegistrator<'_, '_>, )
Source§fn clone_behavior() -> ComponentCloneBehavior
fn clone_behavior() -> ComponentCloneBehavior
Source§fn relationship_accessor() -> Option<ComponentRelationshipAccessor<Self>>
fn relationship_accessor() -> Option<ComponentRelationshipAccessor<Self>>
ComponentRelationshipAccessor] required for working with relationships in dynamic contexts. Read more§fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_add [ComponentHook] for this [Component] if one is defined.§fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_insert [ComponentHook] for this [Component] if one is defined.§fn on_replace() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_replace() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_replace [ComponentHook] for this [Component] if one is defined.§fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_remove [ComponentHook] for this [Component] if one is defined.§fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>
on_despawn [ComponentHook] for this [Component] if one is defined.§fn map_entities<E>(_this: &mut Self, _mapper: &mut E)where
E: EntityMapper,
fn map_entities<E>(_this: &mut Self, _mapper: &mut E)where
E: EntityMapper,
EntityMapper]. This is used to remap entities in contexts like scenes and entity cloning.
When deriving [Component], this is populated by annotating fields containing entities with #[entities] Read moreSource§impl Debug for LookDirection
impl Debug for LookDirection
Source§impl Default for LookDirection
impl Default for LookDirection
Source§fn default() -> LookDirection
fn default() -> LookDirection
Source§impl From<LookDirection> for (f32, f32)
impl From<LookDirection> for (f32, f32)
Source§fn from(value: LookDirection) -> Self
fn from(value: LookDirection) -> Self
Source§impl Hash for LookDirection
impl Hash for LookDirection
Source§impl PartialEq for LookDirection
impl PartialEq for LookDirection
impl Copy for LookDirection
impl Eq for LookDirection
impl StructuralPartialEq for LookDirection
Auto Trait Implementations§
impl Freeze for LookDirection
impl RefUnwindSafe for LookDirection
impl Send for LookDirection
impl Sync for LookDirection
impl Unpin for LookDirection
impl UnsafeUnpin for LookDirection
impl UnwindSafe for LookDirection
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
§impl<C> Bundle for Cwhere
C: Component,
impl<C> Bundle for Cwhere
C: Component,
fn component_ids( components: &mut ComponentsRegistrator<'_>, ) -> impl Iterator<Item = ComponentId> + use<C>
§fn get_component_ids(
components: &Components,
) -> impl Iterator<Item = Option<ComponentId>>
fn get_component_ids( components: &Components, ) -> impl Iterator<Item = Option<ComponentId>>
Bundle]’s component ids. This will be None if the component has not been registered.§impl<C> BundleFromComponents for Cwhere
C: Component,
impl<C> BundleFromComponents for Cwhere
C: Component,
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§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> DynEq for T
impl<T> DynEq for T
§impl<C> DynamicBundle for Cwhere
C: Component,
impl<C> DynamicBundle for Cwhere
C: Component,
§unsafe fn get_components(
ptr: MovingPtr<'_, C>,
func: &mut impl FnMut(StorageType, OwningPtr<'_>),
) -> <C as DynamicBundle>::Effect
unsafe fn get_components( ptr: MovingPtr<'_, C>, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect
§unsafe fn apply_effect(
_ptr: MovingPtr<'_, MaybeUninit<C>>,
_entity: &mut EntityWorldMut<'_>,
)
unsafe fn apply_effect( _ptr: MovingPtr<'_, MaybeUninit<C>>, _entity: &mut EntityWorldMut<'_>, )
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§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().