From 1d065645e1f176f4fa03f09c2cacd36b16874c7c Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Sat, 31 Aug 2024 13:24:58 +0200 Subject: [PATCH] add state id --- pumpkin-inventory/src/lib.rs | 46 ++++++++----------------- pumpkin-inventory/src/open_container.rs | 37 +++++++++++++++++--- pumpkin-inventory/src/player.rs | 9 ++++- pumpkin/src/client/container.rs | 41 ++++++++++++++-------- 4 files changed, 81 insertions(+), 52 deletions(-) diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index 3f854db60..a019c298c 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -75,6 +75,8 @@ pub trait Container: Sync + Send { fn all_slots(&mut self) -> Vec<&mut Option>; fn all_slots_ref(&self) -> Vec>; + + fn state_id(&mut self) -> i32; } pub fn handle_item_take( @@ -104,6 +106,12 @@ pub fn handle_item_change( current_slot: &mut Option, mouse_click: MouseClick, ) { + if let Some(carried) = carried_slot.as_ref() { + dbg!(carried); + } + if let Some(current) = current_slot.as_ref() { + dbg!(current); + } match (current_slot.as_mut(), carried_slot.as_mut()) { // Swap or combine current and carried (Some(current), Some(carried)) => { @@ -162,40 +170,10 @@ pub fn combine_stacks( } } -pub struct ContainerStruct { - slots: [Option; SLOTS], - _state_id: usize, - _open_by: Option>, - window_type: WindowType, -} - -impl Container for ContainerStruct { - fn window_type(&self) -> &WindowType { - &self.window_type - } - - fn handle_item_change( - &mut self, - carried_slot: &mut Option, - slot: usize, - mouse_click: MouseClick, - ) { - let current_slot = &mut self.slots[slot]; - handle_item_change(carried_slot, current_slot, mouse_click) - } - - fn all_slots(&mut self) -> Vec<&mut Option> { - self.slots.iter_mut().collect() - } - - fn all_slots_ref(&self) -> Vec> { - self.slots.iter().map(|slot| slot.as_ref()).collect() - } -} - pub struct OptionallyCombinedContainer<'a> { container: Option<&'a mut Box>, inventory: &'a mut PlayerInventory, + state_id: i32, } impl<'a> OptionallyCombinedContainer<'a> { pub fn new( @@ -205,6 +183,7 @@ impl<'a> OptionallyCombinedContainer<'a> { Self { inventory: player_inventory, container, + state_id: 0, } } } @@ -237,4 +216,9 @@ impl<'a> Container for OptionallyCombinedContainer<'a> { slots.extend(self.inventory.all_slots_ref()); slots } + + fn state_id(&mut self) -> i32 { + self.state_id += 1; + self.state_id - 1 + } } diff --git a/pumpkin-inventory/src/open_container.rs b/pumpkin-inventory/src/open_container.rs index 985d483a8..895f92f08 100644 --- a/pumpkin-inventory/src/open_container.rs +++ b/pumpkin-inventory/src/open_container.rs @@ -12,7 +12,23 @@ impl OpenContainer { if !self.players.contains(&player_id) { return None; } - Some(self.container.lock().unwrap()) + let container = self.container.lock().unwrap(); + container + .all_slots_ref() + .iter() + .enumerate() + .for_each(|(slot, item)| { + if let Some(item) = item { + dbg!(slot, item); + } + }); + Some(container) + } + + pub fn add_player(&mut self, player_id: i32) { + if !self.players.contains(&player_id) { + self.players.push(player_id); + } } pub fn empty(player_id: i32) -> Self { @@ -23,11 +39,17 @@ impl OpenContainer { } } -struct Chest([Option; 27]); +struct Chest { + slots: [Option; 27], + state_id: i32, +} impl Chest { pub fn new() -> Self { - Self([None; 27]) + Self { + slots: [None; 27], + state_id: 0, + } } } impl Container for Chest { @@ -36,10 +58,15 @@ impl Container for Chest { } fn all_slots(&mut self) -> Vec<&mut Option> { - self.0.iter_mut().collect() + self.slots.iter_mut().collect() } fn all_slots_ref(&self) -> Vec> { - self.0.iter().map(|slot| slot.as_ref()).collect() + self.slots.iter().map(|slot| slot.as_ref()).collect() + } + + fn state_id(&mut self) -> i32 { + self.state_id += 1; + self.state_id - 1 } } diff --git a/pumpkin-inventory/src/player.rs b/pumpkin-inventory/src/player.rs index ca7150920..b84a4acc7 100644 --- a/pumpkin-inventory/src/player.rs +++ b/pumpkin-inventory/src/player.rs @@ -13,6 +13,7 @@ pub struct PlayerInventory { offhand: Option, // current selected slot in hotbar selected: usize, + state_id: i32, } impl Default for PlayerInventory { @@ -31,6 +32,7 @@ impl PlayerInventory { offhand: None, // TODO: What when player spawns in with an different index ? selected: 0, + state_id: 0, } } @@ -131,7 +133,7 @@ impl PlayerInventory { } impl Container for PlayerInventory { - fn window_type(&self) -> &WindowType { + fn window_type(&self) -> &'static WindowType { &WindowType::Generic9x1 } @@ -152,4 +154,9 @@ impl Container for PlayerInventory { fn all_slots_ref(&self) -> Vec> { self.slots() } + + fn state_id(&mut self) -> i32 { + self.state_id += 1; + self.state_id - 1 + } } diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index b03ae01de..f5f1edde7 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -22,6 +22,7 @@ impl Player { window_title: Option<&str>, items: Option>>, carried_item: Option<&ItemStack>, + state_id: i32, ) { let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY .get("minecraft:menu") @@ -32,27 +33,30 @@ impl Player { .get("protocol_id") .unwrap()) .into(); + let window_type = container.window_type(); let title = TextComponent::text(window_title.unwrap_or(window_type.default_title())); self.client.send_packet(&COpenScreen::new( (*window_type as u8 + 1).into(), menu_protocol_id, title, )); - self.set_container_content(window_type, items, carried_item); + + self.set_container_content(Some(container), carried_item, state_id); } pub fn set_container_content<'a>( &mut self, - window_type: &WindowType, - items: Option>>, + container: Option<&Box>, carried_item: Option<&'a ItemStack>, + state_id: i32, ) { let slots: Vec = { + let items = container.map(|container| container.all_slots_ref()); if let Some(mut items) = items { - items.extend(self.inventory.slots()); + items.extend(self.inventory.all_slots_ref()); items } else { - self.inventory.slots() + self.inventory.all_slots_ref() } .into_iter() .map(|item| { @@ -72,8 +76,13 @@ impl Player { Slot::empty() } }; - let packet = - CSetContainerContent::new(*window_type as u8 + 1, 0.into(), &slots, &carried_item); + + let window_type = match container { + Some(container) => *container.window_type() as u8, + None => 0, + }; + + let packet = CSetContainerContent::new(window_type, state_id.into(), &slots, &carried_item); self.client.send_packet(&packet); } @@ -82,10 +91,11 @@ impl Player { window_type: WindowType, slot: usize, item: Option<&ItemStack>, + state_id: i32, ) { self.client.send_packet(&CSetContainerSlot::new( window_type as i8, - 0, + state_id, slot, &item.into(), )) @@ -130,7 +140,12 @@ impl Player { } }) .collect::>(), - window_type: WindowType::from_u8(packet.window_id).unwrap(), + window_type: WindowType::from_u8(if packet.window_id == 0 { + 0 + } else { + packet.window_id - 1 + }) + .unwrap(), carried_item: packet.carried_item.to_item(), mode: ClickMode::new( packet @@ -173,12 +188,8 @@ impl Player { ClickType::MouseDrag { drag_state: _, drag_type: _, - } => { - todo!() - } - ClickType::DropType(_drop_type) => { - todo!() - } + } => (), + ClickType::DropType(_drop_type) => (), } }