pub enum ItemStack {
Empty,
Present(ItemStackData),
}Expand description
Either an item in an inventory or nothing.
Variants§
Empty
Present(ItemStackData)
Implementations§
Source§impl ItemStack
impl ItemStack
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Check if the slot is ItemStack::Empty, if the count is <= 0, or if the item is air.
This is the opposite of ItemStack::is_present.
Sourcepub fn is_present(&self) -> bool
pub fn is_present(&self) -> bool
Check if the slot is not ItemStack::Empty, if the count is > 0, and if the item is not air.
This is the opposite of ItemStack::is_empty.
Sourcepub fn count(&self) -> i32
pub fn count(&self) -> i32
Return the amount of the item in the slot, or 0 if the slot is empty.
Note that it’s possible for the count to be zero or negative when the slot is present.
Sourcepub fn split(&mut self, count: u32) -> ItemStack
pub fn split(&mut self, count: u32) -> ItemStack
Remove count items from this slot, returning the removed items.
Sourcepub fn kind(&self) -> ItemKind
pub fn kind(&self) -> ItemKind
Get the kind of the item in this slot, or ItemKind::Air
Examples found in repository?
63fn log_nearby_item_drops(
64 bots: Query<Entity, With<Bot>>,
65 entities: EntityFinder<With<ItemItem>>,
66 item_drops: Query<&ItemItem>,
67) {
68 for bot_id in bots.iter() {
69 for (entity, distance) in entities.nearby_entities_to_entity(bot_id, 8.0) {
70 let item_drop = item_drops.get(entity).unwrap();
71 let kind = item_drop.kind();
72
73 println!("Bot {bot_id:?} can see an {kind:?} {distance:.1} meters away.");
74 }
75 }
76}Sourcepub fn update_empty(&mut self)
pub fn update_empty(&mut self)
Update whether this slot is empty, based on the count.
Sourcepub fn as_present(&self) -> Option<&ItemStackData>
pub fn as_present(&self) -> Option<&ItemStackData>
Convert this slot into an ItemStackData, if it’s present.
pub fn as_present_mut(&mut self) -> Option<&mut ItemStackData>
Sourcepub fn get_component<'a, T>(&'a self) -> Option<Cow<'a, T>>where
T: DataComponentTrait,
pub fn get_component<'a, T>(&'a self) -> Option<Cow<'a, T>>where
T: DataComponentTrait,
Get the value of a data component for this item.
This is used for things like getting the damage of an item, or seeing how much food it replenishes.
Examples found in repository?
25pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
26 commands.register(literal("ping").executes(|ctx: &Ctx| {
27 let source = ctx.source.lock();
28 source.reply("pong!");
29 1
30 }));
31
32 commands.register(literal("disconnect").executes(|ctx: &Ctx| {
33 let source = ctx.source.lock();
34 source.bot.disconnect();
35 1
36 }));
37
38 commands.register(literal("whereami").executes(|ctx: &Ctx| {
39 let source = ctx.source.lock();
40 let Some(entity) = source.entity() else {
41 source.reply("You aren't in render distance!");
42 return 0;
43 };
44 let position = entity.position();
45 source.reply(format!(
46 "You are at {}, {}, {}",
47 position.x, position.y, position.z
48 ));
49 1
50 }));
51
52 commands.register(literal("entityid").executes(|ctx: &Ctx| {
53 let source = ctx.source.lock();
54 let Some(entity) = source.entity() else {
55 source.reply("You aren't in render distance!");
56 return 0;
57 };
58 let entity_id = entity.minecraft_id();
59 source.reply(format!(
60 "Your Minecraft ID is {} and your ECS ID is {entity:?}",
61 *entity_id
62 ));
63 1
64 }));
65
66 let whereareyou = |ctx: &Ctx| {
67 let source = ctx.source.lock();
68 let position = source.bot.position();
69 source.reply(format!(
70 "I'm at {}, {}, {}",
71 position.x, position.y, position.z
72 ));
73 1
74 };
75 commands.register(literal("whereareyou").executes(whereareyou));
76 commands.register(literal("pos").executes(whereareyou));
77
78 commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
79 let source = ctx.source.lock();
80 source.reply(format!(
81 "I am {} ({}, {})",
82 source.bot.username(),
83 source.bot.uuid(),
84 source.bot.entity
85 ));
86 1
87 }));
88
89 commands.register(literal("getdirection").executes(|ctx: &Ctx| {
90 let source = ctx.source.lock();
91 let direction = source.bot.direction();
92 source.reply(format!(
93 "I'm looking at {}, {}",
94 direction.y_rot(),
95 direction.x_rot()
96 ));
97 1
98 }));
99
100 commands.register(literal("health").executes(|ctx: &Ctx| {
101 let source = ctx.source.lock();
102
103 let health = source.bot.health();
104 source.reply(format!("I have {health} health"));
105 1
106 }));
107
108 commands.register(literal("lookingat").executes(|ctx: &Ctx| {
109 let source = ctx.source.lock();
110
111 let hit_result = source.bot.hit_result();
112
113 match &hit_result {
114 HitResult::Block(r) => {
115 if r.miss {
116 source.reply("I'm not looking at anything");
117 return 0;
118 }
119 let block_pos = r.block_pos;
120 let block = source.bot.world().read().get_block_state(block_pos);
121 source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
122 }
123 HitResult::Entity(r) => {
124 let entity_kind = **source.bot.entity_component::<EntityKindComponent>(r.entity);
125 source.reply(format!(
126 "I'm looking at {entity_kind} ({:?}) at {}",
127 r.entity, r.location
128 ));
129 }
130 }
131
132 1
133 }));
134
135 commands.register(literal("getblock").then(argument("x", integer()).then(
136 argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
137 let source = ctx.source.lock();
138 let x = get_integer(ctx, "x").unwrap();
139 let y = get_integer(ctx, "y").unwrap();
140 let z = get_integer(ctx, "z").unwrap();
141 println!("getblock xyz {x} {y} {z}");
142 let block_pos = BlockPos::new(x, y, z);
143 let block = source.bot.world().read().get_block_state(block_pos);
144 source.reply(format!("BlockKind at {block_pos} is {block:?}"));
145 1
146 })),
147 )));
148 commands.register(literal("getfluid").then(argument("x", integer()).then(
149 argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
150 let source = ctx.source.lock();
151 let x = get_integer(ctx, "x").unwrap();
152 let y = get_integer(ctx, "y").unwrap();
153 let z = get_integer(ctx, "z").unwrap();
154 println!("getfluid xyz {x} {y} {z}");
155 let block_pos = BlockPos::new(x, y, z);
156 let block = source.bot.world().read().get_fluid_state(block_pos);
157 source.reply(format!("Fluid at {block_pos} is {block:?}"));
158 1
159 })),
160 )));
161
162 commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
163 let source = ctx.source.lock();
164 let pathfinder = source.bot.get_component::<Pathfinder>();
165 let Some(pathfinder) = pathfinder else {
166 source.reply("I don't have the Pathfinder component");
167 return 1;
168 };
169 source.reply(format!(
170 "pathfinder.is_calculating: {}",
171 pathfinder.is_calculating
172 ));
173
174 let executing_path = source.bot.get_component::<ExecutingPath>();
175 let Some(executing_path) = executing_path else {
176 source.reply("I'm not executing a path");
177 return 1;
178 };
179 source.reply(format!(
180 "is_path_partial: {}, path.len: {}, queued_path.len: {}",
181 executing_path.is_path_partial,
182 executing_path.path.len(),
183 if let Some(queued) = &executing_path.queued_path {
184 queued.len().to_string()
185 } else {
186 "n/a".to_owned()
187 },
188 ));
189 1
190 }));
191 commands.register(literal("pathfindermoves").executes(|ctx: &Ctx| {
192 let source = ctx.source.lock();
193
194 let Some(entity) = source.entity() else {
195 source.reply("You aren't in render distance!");
196 return 0;
197 };
198 let position = entity.position();
199 let position = BlockPos::from(position);
200
201 let mut edges = Vec::new();
202 let cached_world = CachedWorld::new(source.bot.world(), position);
203 let mining_cache = MiningCache::new(None);
204 let custom_state = CustomPathfinderStateRef::default();
205
206 azalea::pathfinder::moves::default_move(
207 &mut PathfinderCtx {
208 edges: &mut edges,
209 world: &cached_world,
210 mining_cache: &mining_cache,
211 custom_state: &custom_state,
212 },
213 RelBlockPos::from_origin(position, position),
214 );
215
216 if edges.is_empty() {
217 source.reply("No possible moves.");
218 } else {
219 source.reply("Moves:");
220 for (i, edge) in edges.iter().enumerate() {
221 source.reply(format!("{}) {edge:?}", i + 1));
222 }
223 }
224
225 1
226 }));
227
228 commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
229 let source = ctx.source.lock();
230 source.bot.start_use_item();
231 source.reply("Ok!");
232 1
233 }));
234 commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
235 let source = ctx.source.lock();
236 let max_stack_size = source
237 .bot
238 .get_held_item()
239 .get_component::<MaxStackSize>()
240 .map_or(-1, |s| s.count);
241 source.reply(format!("{max_stack_size}"));
242 1
243 }));
244
245 commands.register(literal("dimensions").executes(|ctx: &Ctx| {
246 let source = ctx.source.lock();
247 let bot_dimensions = source.bot.dimensions();
248 source.reply(format!("{bot_dimensions:?}"));
249 1
250 }));
251
252 commands.register(literal("players").executes(|ctx: &Ctx| {
253 let source = ctx.source.lock();
254 let player_entities = source
255 .bot
256 .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
257 let tab_list = source.bot.tab_list();
258 for player_entity in player_entities {
259 let uuid = player_entity.uuid();
260 source.reply(format!(
261 "{} - {} ({:?})",
262 player_entity.id(),
263 tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
264 uuid
265 ));
266 }
267 1
268 }));
269
270 commands.register(literal("enchants").executes(|ctx: &Ctx| {
271 let source = ctx.source.lock();
272 source.bot.with_registry_holder(|r| {
273 let enchants = &r.enchantment;
274 println!("enchants: {enchants:?}");
275 });
276 1
277 }));
278
279 commands.register(literal("attributes").executes(|ctx: &Ctx| {
280 let source = ctx.source.lock();
281 let attributes = source.bot.attributes();
282 println!("attributes: {attributes:?}");
283 1
284 }));
285
286 commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
287 let source = ctx.source.lock();
288
289 source.reply("Ok!");
290
291
292
293 source.bot.disconnect();
294
295 let ecs = source.bot.ecs.clone();
296 thread::spawn(move || {
297 thread::sleep(Duration::from_secs(1));
298 // dump the ecs
299
300 let mut ecs = ecs.write();
301
302 let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
303 let mut report = File::create(&report_path).unwrap();
304
305 let mut query = ecs.query::<EntityRef>();
306 for entity in query.iter(& ecs) {
307 writeln!(report, "Entity: {}", entity.id()).unwrap();
308 let archetype = entity.archetype();
309 let component_count = archetype.component_count();
310
311 let component_names = archetype
312 .components()
313 .iter()
314 .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
315 .collect::<Vec<_>>();
316 writeln!(
317 report,
318 "- {component_count} components: {}",
319 component_names.join(", ")
320 )
321 .unwrap();
322 }
323
324 writeln!(report).unwrap();
325
326
327 for (info, _) in ecs.iter_resources() {
328 let name = info.name().to_string();
329 writeln!(report, "Resource: {name}").unwrap();
330 // writeln!(report, "- Size: {} bytes",
331 // info.layout().size()).unwrap();
332
333 match name.as_ref() {
334 "azalea_world::container::InstanceContainer" => {
335 let instance_container = ecs.resource::<InstanceContainer>();
336
337 for (instance_name, instance) in &instance_container.instances {
338 writeln!(report, "- Name: {instance_name}").unwrap();
339 writeln!(report, "- Reference count: {}", instance.strong_count())
340 .unwrap();
341 if let Some(instance) = instance.upgrade() {
342 let instance = instance.read();
343 let strong_chunks = instance
344 .chunks
345 .map
346 .iter()
347 .filter(|(_, v)| v.strong_count() > 0)
348 .count();
349 writeln!(
350 report,
351 "- Chunks: {} strongly referenced, {} in map",
352 strong_chunks,
353 instance.chunks.map.len()
354 )
355 .unwrap();
356 writeln!(
357 report,
358 "- Entities: {}",
359 instance.entities_by_chunk.len()
360 )
361 .unwrap();
362 }
363 }
364 }
365 "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
366 let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
367 writeln!(report, "- Event count: {}", events.len()).unwrap();
368 }
369 "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
370 let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
371 writeln!(report, "- Event count: {}", events.len()).unwrap();
372 }
373
374 _ => {}
375 }
376 }
377
378 println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
379 });
380
381 1
382 }));
383
384 commands.register(literal("exit").executes(|ctx: &Ctx| {
385 let source = ctx.source.lock();
386 source.reply("bye!");
387
388 source.bot.disconnect();
389
390 let source = ctx.source.clone();
391 thread::spawn(move || {
392 thread::sleep(Duration::from_secs(1));
393
394 source
395 .lock()
396 .bot
397 .ecs
398 .write()
399 .write_message(AppExit::Success);
400 });
401
402 1
403 }));
404}pub fn with_component<T>(self, component: impl Into<Option<T>>) -> ItemStackwhere
T: EncodableDataComponent + DataComponentTrait,
Trait Implementations§
Source§impl AzaleaRead for ItemStack
impl AzaleaRead for ItemStack
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<ItemStack, BufReadError>
Source§impl AzaleaWrite for ItemStack
impl AzaleaWrite for ItemStack
Source§impl From<ItemStackData> for ItemStack
impl From<ItemStackData> for ItemStack
Source§fn from(item: ItemStackData) -> ItemStack
fn from(item: ItemStackData) -> ItemStack
Source§impl Serialize for ItemStack
impl Serialize for ItemStack
Source§fn serialize<S>(
&self,
serializer: S,
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where
S: Serializer,
fn serialize<S>(
&self,
serializer: S,
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where
S: Serializer,
impl StructuralPartialEq for ItemStack
Auto Trait Implementations§
impl Freeze for ItemStack
impl RefUnwindSafe for ItemStack
impl Send for ItemStack
impl Sync for ItemStack
impl Unpin for ItemStack
impl UnwindSafe for ItemStack
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().