ItemStack

Enum ItemStack 

Source
pub enum ItemStack {
    Empty,
    Present(ItemStackData),
}
Expand description

Either an item in an inventory or nothing.

Variants§

§

Empty

§

Present(ItemStackData)

Implementations§

Source§

impl ItemStack

Source

pub fn new(item: ItemKind, count: i32) -> ItemStack

Create a new ItemStack with the given number of ItemKinds.

If item is air or the count isn’t positive, then it’ll be set to an empty ItemStack.

Source

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.

Source

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.

Source

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.

Source

pub fn split(&mut self, count: u32) -> ItemStack

Remove count items from this slot, returning the removed items.

Source

pub fn kind(&self) -> ItemKind

Get the kind of the item in this slot, or ItemKind::Air

Examples found in repository?
azalea/examples/nearest_entity.rs (line 71)
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}
Source

pub fn update_empty(&mut self)

Update whether this slot is empty, based on the count.

Source

pub fn as_present(&self) -> Option<&ItemStackData>

Convert this slot into an ItemStackData, if it’s present.

Source

pub fn as_present_mut(&mut self) -> Option<&mut ItemStackData>

Source

pub fn get_component<'a, T>(&'a self) -> Option<Cow<'a, T>>

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?
azalea/examples/testbot/commands/debug.rs (line 239)
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}
Source

pub fn with_component<T>(self, component: impl Into<Option<T>>) -> ItemStack

Trait Implementations§

Source§

impl AzaleaRead for ItemStack

Source§

impl AzaleaWrite for ItemStack

Source§

fn azalea_write(&self, buf: &mut impl Write) -> Result<(), Error>

Source§

impl Clone for ItemStack

Source§

fn clone(&self) -> ItemStack

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ItemStack

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for ItemStack

Source§

fn default() -> ItemStack

Returns the “default value” for a type. Read more
Source§

impl From<(ItemKind, i32)> for ItemStack

Source§

fn from(item: (ItemKind, i32)) -> ItemStack

Converts to this type from the input type.
Source§

impl From<ItemKind> for ItemStack

Source§

fn from(item: ItemKind) -> ItemStack

Converts to this type from the input type.
Source§

impl From<ItemStackData> for ItemStack

Source§

fn from(item: ItemStackData) -> ItemStack

Converts to this type from the input type.
Source§

impl PartialEq for ItemStack

Source§

fn eq(&self, other: &ItemStack) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for ItemStack

Source§

fn serialize<S>( &self, serializer: S, ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for ItemStack

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> CompatExt for T

§

fn compat(self) -> Compat<T>

Applies the [Compat] adapter by value. Read more
§

fn compat_ref(&self) -> Compat<&T>

Applies the [Compat] adapter by shared reference. Read more
§

fn compat_mut(&mut self) -> Compat<&mut T>

Applies the [Compat] adapter by mutable reference. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts 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>

Converts 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)

Converts &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)

Converts &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
where T: Any + Send,

§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromWorld for T
where T: Default,

§

fn from_world(_world: &mut World) -> T

Creates Self using default().

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> IntoResult<T> for T

§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
§

impl<A> Is for A
where A: Any,

§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Serialize for T
where T: Serialize + ?Sized,

Source§

fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>

Source§

fn do_erased_serialize( &self, serializer: &mut dyn Serializer, ) -> Result<(), ErrorImpl>

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

§

fn clone_type_data(&self) -> Box<dyn TypeData>

Creates a type-erased clone of this value.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ConditionalSend for T
where T: Send,