feat(client): add menu field

This commit is contained in:
Ryan 2025-02-23 17:19:26 -05:00
parent 543f0af741
commit 9b0f8ec406
Signed by: ErrorNoInternet
GPG Key ID: 2486BFB7B1E6A4A3
4 changed files with 48 additions and 10 deletions

View File

@ -1,10 +1,12 @@
use super::{Client, Container, ContainerRef, ItemStack, Vec3}; use super::{Client, Container, ContainerRef, ItemStack, Vec3};
use azalea::{ use azalea::{
BlockPos, inventory::Inventory, prelude::ContainerClientExt, BlockPos,
inventory::{Inventory, Menu, Player, SlotList},
prelude::ContainerClientExt,
protocol::packets::game::ServerboundSetCarriedItem, protocol::packets::game::ServerboundSetCarriedItem,
}; };
use log::error; use log::error;
use mlua::{Lua, Result, UserDataRef}; use mlua::{Lua, Result, Table, UserDataRef};
pub fn container(_lua: &Lua, client: &Client) -> Result<Option<ContainerRef>> { pub fn container(_lua: &Lua, client: &Client) -> Result<Option<ContainerRef>> {
Ok(client Ok(client
@ -13,15 +15,46 @@ pub fn container(_lua: &Lua, client: &Client) -> Result<Option<ContainerRef>> {
} }
pub fn held_item(_lua: &Lua, client: &Client) -> Result<ItemStack> { pub fn held_item(_lua: &Lua, client: &Client) -> Result<ItemStack> {
Ok(ItemStack { Ok(ItemStack::from(client.component::<Inventory>().held_item()))
inner: client.component::<Inventory>().held_item(),
})
} }
pub fn held_slot(_lua: &Lua, client: &Client) -> Result<u8> { pub fn held_slot(_lua: &Lua, client: &Client) -> Result<u8> {
Ok(client.component::<Inventory>().selected_hotbar_slot) Ok(client.component::<Inventory>().selected_hotbar_slot)
} }
pub fn menu(lua: &Lua, client: &Client) -> Result<Table> {
fn from_slot_list<const N: usize>(s: SlotList<N>) -> Vec<ItemStack> {
s.iter()
.map(|i| ItemStack::from(i.to_owned()))
.collect::<Vec<_>>()
}
let table = lua.create_table()?;
match client.menu() {
Menu::Player(Player {
craft_result,
craft,
armor,
inventory,
offhand,
}) => {
table.set("type", 0)?;
table.set("craft_result", ItemStack::from(craft_result))?;
table.set("craft", from_slot_list(craft))?;
table.set("armor", from_slot_list(armor))?;
table.set("inventory", from_slot_list(inventory))?;
table.set("offhand", ItemStack::from(offhand))?;
}
Menu::Generic9x6 { contents, player } => {
table.set("type", 6)?;
table.set("contents", from_slot_list(contents))?;
table.set("player", from_slot_list(player))?;
}
_ => (),
}
Ok(table)
}
pub async fn open_container_at( pub async fn open_container_at(
_lua: Lua, _lua: Lua,
client: UserDataRef<Client>, client: UserDataRef<Client>,

View File

@ -49,6 +49,7 @@ impl UserData for Client {
f.add_field_method_get("held_slot", container::held_slot); f.add_field_method_get("held_slot", container::held_slot);
f.add_field_method_get("hunger", state::hunger); f.add_field_method_get("hunger", state::hunger);
f.add_field_method_get("looking_at", movement::looking_at); f.add_field_method_get("looking_at", movement::looking_at);
f.add_field_method_get("menu", container::menu);
f.add_field_method_get("pathfinder", movement::pathfinder); f.add_field_method_get("pathfinder", movement::pathfinder);
f.add_field_method_get("position", movement::position); f.add_field_method_get("position", movement::position);
f.add_field_method_get("score", state::score); f.add_field_method_get("score", state::score);

View File

@ -5,6 +5,12 @@ pub struct ItemStack {
pub inner: azalea::inventory::ItemStack, pub inner: azalea::inventory::ItemStack,
} }
impl From<azalea::inventory::ItemStack> for ItemStack {
fn from(inner: azalea::inventory::ItemStack) -> Self {
Self { inner }
}
}
impl UserData for ItemStack { impl UserData for ItemStack {
fn add_fields<F: UserDataFields<Self>>(f: &mut F) { fn add_fields<F: UserDataFields<Self>>(f: &mut F) {
f.add_field_method_get("is_empty", |_, this| Ok(this.inner.is_empty())); f.add_field_method_get("is_empty", |_, this| Ok(this.inner.is_empty()));
@ -38,9 +44,7 @@ impl UserData for ItemStack {
fn add_methods<M: UserDataMethods<Self>>(m: &mut M) { fn add_methods<M: UserDataMethods<Self>>(m: &mut M) {
m.add_method_mut("split", |_, this, count: u32| { m.add_method_mut("split", |_, this, count: u32| {
Ok(ItemStack { Ok(ItemStack::from(this.inner.split(count)))
inner: this.inner.split(count),
})
}); });
m.add_method_mut("update_empty", |_, this, (): ()| { m.add_method_mut("update_empty", |_, this, (): ()| {
this.inner.update_empty(); this.inner.update_empty();

View File

@ -25,7 +25,7 @@ impl UserData for Container {
f.add_field_method_get("contents", |_, this| { f.add_field_method_get("contents", |_, this| {
Ok(this.inner.contents().map(|v| { Ok(this.inner.contents().map(|v| {
v.iter() v.iter()
.map(|i| ItemStack { inner: i.clone() }) .map(|i| ItemStack::from(i.to_owned()))
.collect::<Vec<_>>() .collect::<Vec<_>>()
})) }))
}); });
@ -58,7 +58,7 @@ impl UserData for ContainerRef {
f.add_field_method_get("contents", |_, this| { f.add_field_method_get("contents", |_, this| {
Ok(this.inner.contents().map(|v| { Ok(this.inner.contents().map(|v| {
v.iter() v.iter()
.map(|i| ItemStack { inner: i.clone() }) .map(|i| ItemStack::from(i.to_owned()))
.collect::<Vec<_>>() .collect::<Vec<_>>()
})) }))
}); });