diff options
| author | mat <git@matdoes.dev> | 2024-01-04 01:55:00 -0600 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2024-01-04 01:55:00 -0600 |
| commit | 1347f3549282397be6a46b8b7cb76a7900d0690a (patch) | |
| tree | d3d468db0c9947f2914b6d0d71dc299c1b3e2634 /azalea/src | |
| parent | 13e6421cf5aeeddc035f42141da776d09d177e33 (diff) | |
| download | azalea-drasl-1347f3549282397be6a46b8b7cb76a7900d0690a.tar.xz | |
rename open_container to open_container_at and add get_open_container
Diffstat (limited to 'azalea/src')
| -rw-r--r-- | azalea/src/container.rs | 116 |
1 files changed, 89 insertions, 27 deletions
diff --git a/azalea/src/container.rs b/azalea/src/container.rs index 0f417061..c354390e 100644 --- a/azalea/src/container.rs +++ b/azalea/src/container.rs @@ -23,11 +23,12 @@ impl Plugin for ContainerPlugin { } pub trait ContainerClientExt { - fn open_container( + fn open_container_at( &mut self, pos: BlockPos, ) -> impl Future<Output = Option<ContainerHandle>> + Send; fn open_inventory(&mut self) -> Option<ContainerHandle>; + fn get_open_container(&self) -> Option<ContainerHandleRef>; } impl ContainerClientExt for Client { @@ -45,10 +46,10 @@ impl ContainerClientExt for Client { /// bot.chat("no chest found"); /// return; /// }; - /// let container = bot.open_container(target_pos).await; + /// let container = bot.open_container_at(target_pos).await; /// # } /// ``` - async fn open_container(&mut self, pos: BlockPos) -> Option<ContainerHandle> { + async fn open_container_at(&mut self, pos: BlockPos) -> Option<ContainerHandle> { self.ecs .lock() .entity_mut(self.entity) @@ -70,10 +71,7 @@ impl ContainerClientExt for Client { if inventory.id == 0 { None } else { - Some(ContainerHandle { - id: inventory.id, - client: self.clone(), - }) + Some(ContainerHandle::new(inventory.id, self.clone())) } } @@ -94,40 +92,55 @@ impl ContainerClientExt for Client { .expect("no inventory"); if inventory.id == 0 { - Some(ContainerHandle { - id: 0, - client: self.clone(), - }) + Some(ContainerHandle::new(0, self.clone())) } else { None } } + + /// Get a handle to the open container. This will return None if no + /// container is open. This will not close the container when it's dropped. + /// + /// See [`Client::open_inventory`] or [`Client::menu`] if you want to open + /// your own inventory. + fn get_open_container(&self) -> Option<ContainerHandleRef> { + let ecs = self.ecs.lock(); + let inventory = ecs + .get::<InventoryComponent>(self.entity) + .expect("no inventory"); + + if inventory.id == 0 { + None + } else { + Some(ContainerHandleRef { + id: inventory.id, + client: self.clone(), + }) + } + } } -/// A handle to the open container. The container will be closed once this is -/// dropped. -pub struct ContainerHandle { - /// The id of the container. If this is 0, that means it's the player's - /// inventory. +/// A handle to a container that may be open. This does not close the container +/// when it's dropped. See [`ContainerHandle`] if that behavior is desired. +pub struct ContainerHandleRef { id: u8, client: Client, } -impl Drop for ContainerHandle { - fn drop(&mut self) { - self.client.ecs.lock().send_event(CloseContainerEvent { - entity: self.client.entity, - id: self.id, - }); - } -} -impl Debug for ContainerHandle { +impl Debug for ContainerHandleRef { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("ContainerHandle") - .field("id", &self.id) + .field("id", &self.id()) .finish() } } -impl ContainerHandle { +impl ContainerHandleRef { + pub fn close(&self) { + self.client.ecs.lock().send_event(CloseContainerEvent { + entity: self.client.entity, + id: self.id, + }); + } + /// Get the id of the container. If this is 0, that means it's the player's /// inventory. Otherwise, the number isn't really meaningful since only one /// container can be open at a time. @@ -175,6 +188,55 @@ impl ContainerHandle { } } +/// A handle to the open container. The container will be closed once this is +/// dropped. +pub struct ContainerHandle(ContainerHandleRef); + +impl Drop for ContainerHandle { + fn drop(&mut self) { + self.0.close(); + } +} +impl Debug for ContainerHandle { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ContainerHandle") + .field("id", &self.id()) + .finish() + } +} +impl ContainerHandle { + fn new(id: u8, client: Client) -> Self { + Self(ContainerHandleRef { id, client }) + } + + /// Get the id of the container. If this is 0, that means it's the player's + /// inventory. Otherwise, the number isn't really meaningful since only one + /// container can be open at a time. + pub fn id(&self) -> u8 { + self.0.id() + } + + /// Returns the menu of the container. If the container is closed, this + /// will return `None`. + /// + /// Note that any modifications you make to the `Menu` you're given will not + /// actually cause any packets to be sent. If you're trying to modify your + /// inventory, use [`ContainerHandle::click`] instead + pub fn menu(&self) -> Option<Menu> { + self.0.menu() + } + + /// Returns the item slots in the container, not including the player's + /// inventory. If the container is closed, this will return `None`. + pub fn contents(&self) -> Option<Vec<ItemSlot>> { + self.0.contents() + } + + pub fn click(&self, operation: impl Into<ClickOperation>) { + self.0.click(operation); + } +} + #[derive(Component, Debug)] pub struct WaitingForInventoryOpen; |
