aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2024-01-04 01:55:00 -0600
committermat <git@matdoes.dev>2024-01-04 01:55:00 -0600
commit1347f3549282397be6a46b8b7cb76a7900d0690a (patch)
treed3d468db0c9947f2914b6d0d71dc299c1b3e2634
parent13e6421cf5aeeddc035f42141da776d09d177e33 (diff)
downloadazalea-drasl-1347f3549282397be6a46b8b7cb76a7900d0690a.tar.xz
rename open_container to open_container_at and add get_open_container
-rw-r--r--azalea-client/src/inventory.rs6
-rw-r--r--azalea-core/src/game_type.rs6
-rw-r--r--azalea/examples/steal.rs2
-rw-r--r--azalea/examples/testbot.rs2
-rw-r--r--azalea/examples/todo/craft_dig_straight_down.rs2
-rw-r--r--azalea/src/container.rs116
6 files changed, 101 insertions, 33 deletions
diff --git a/azalea-client/src/inventory.rs b/azalea-client/src/inventory.rs
index 527feae7..bf421bf4 100644
--- a/azalea-client/src/inventory.rs
+++ b/azalea-client/src/inventory.rs
@@ -90,6 +90,9 @@ pub struct InventoryComponent {
/// The current container menu that the player has open. If no container is
/// open, this will be `None`.
pub container_menu: Option<azalea_inventory::Menu>,
+ /// The custom name of the menu that's currently open. This is Some when
+ /// `container_menu` is Some.
+ pub container_menu_title: Option<FormattedText>,
/// The item that is currently held by the cursor. `Slot::Empty` if nothing
/// is currently being held.
///
@@ -566,6 +569,7 @@ impl Default for InventoryComponent {
inventory_menu: Menu::Player(azalea_inventory::Player::default()),
id: 0,
container_menu: None,
+ container_menu_title: None,
carried: ItemSlot::Empty,
state_id: 0,
quick_craft_status: QuickCraftStatusKind::Start,
@@ -593,6 +597,7 @@ fn handle_menu_opened_event(
let mut inventory = query.get_mut(event.entity).unwrap();
inventory.id = event.window_id as u8;
inventory.container_menu = Some(Menu::from_kind(event.menu_type));
+ inventory.container_menu_title = Some(event.title.clone());
}
}
@@ -651,6 +656,7 @@ pub fn handle_client_side_close_container_event(
let mut inventory = query.get_mut(event.entity).unwrap();
inventory.container_menu = None;
inventory.id = 0;
+ inventory.container_menu_title = None;
}
}
diff --git a/azalea-core/src/game_type.rs b/azalea-core/src/game_type.rs
index 99f0c0fe..7c7a43a8 100644
--- a/azalea-core/src/game_type.rs
+++ b/azalea-core/src/game_type.rs
@@ -1,6 +1,6 @@
use azalea_buf::{BufReadError, McBufReadable, McBufVarReadable, McBufWritable};
use std::io::{Cursor, Write};
-use tracing::warn;
+use tracing::debug;
/// A Minecraft gamemode, like survival or creative.
#[derive(Hash, Copy, Clone, Debug, Default, Eq, PartialEq)]
@@ -96,11 +96,11 @@ impl McBufReadable for GameMode {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let id = u32::var_read_from(buf)?;
let id = id.try_into().unwrap_or_else(|_| {
- warn!("Unknown game mode id {id}, defaulting to survival");
+ debug!("Unknown game mode id {id}, defaulting to survival");
0
});
Ok(GameMode::from_id(id).unwrap_or_else(|| {
- warn!("Unknown game mode id {id}, defaulting to survival");
+ debug!("Unknown game mode id {id}, defaulting to survival");
GameMode::Survival
}))
}
diff --git a/azalea/examples/steal.rs b/azalea/examples/steal.rs
index 408d7b9b..c6ab4639 100644
--- a/azalea/examples/steal.rs
+++ b/azalea/examples/steal.rs
@@ -45,7 +45,7 @@ async fn handle(mut bot: Client, event: Event, state: State) -> anyhow::Result<(
return Ok(());
};
// bot.goto(BlockPosGoal(chest_block));
- let Some(chest) = bot.open_container(chest_block).await else {
+ let Some(chest) = bot.open_container_at(chest_block).await else {
println!("Couldn't open chest");
return Ok(());
};
diff --git a/azalea/examples/testbot.rs b/azalea/examples/testbot.rs
index 7e7b2ca0..c9e64ef9 100644
--- a/azalea/examples/testbot.rs
+++ b/azalea/examples/testbot.rs
@@ -216,7 +216,7 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
return Ok(());
};
bot.look_at(target_pos.center());
- let container = bot.open_container(target_pos).await;
+ let container = bot.open_container_at(target_pos).await;
println!("container: {container:?}");
if let Some(container) = container {
if let Some(contents) = container.contents() {
diff --git a/azalea/examples/todo/craft_dig_straight_down.rs b/azalea/examples/todo/craft_dig_straight_down.rs
index 6672eaa4..7b75d2db 100644
--- a/azalea/examples/todo/craft_dig_straight_down.rs
+++ b/azalea/examples/todo/craft_dig_straight_down.rs
@@ -38,7 +38,7 @@ async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
bot.goto(pathfinder::Goals::NearXZ(5, azalea::BlockXZ(0, 0)))
.await;
let chest = bot
- .open_container(&bot.world().find_block(azalea::Block::Chest))
+ .open_container_at(&bot.world().find_block(azalea::Block::Chest))
.await
.unwrap();
bot.take_amount_from_container(&chest, 5, |i| i.id == "#minecraft:planks")
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;