add state id

This commit is contained in:
Edvin Bryntesson 2024-08-31 13:24:58 +02:00
parent 909943bb5d
commit 1d065645e1
No known key found for this signature in database
4 changed files with 81 additions and 52 deletions

View File

@ -75,6 +75,8 @@ pub trait Container: Sync + Send {
fn all_slots(&mut self) -> Vec<&mut Option<ItemStack>>; fn all_slots(&mut self) -> Vec<&mut Option<ItemStack>>;
fn all_slots_ref(&self) -> Vec<Option<&ItemStack>>; fn all_slots_ref(&self) -> Vec<Option<&ItemStack>>;
fn state_id(&mut self) -> i32;
} }
pub fn handle_item_take( pub fn handle_item_take(
@ -104,6 +106,12 @@ pub fn handle_item_change(
current_slot: &mut Option<ItemStack>, current_slot: &mut Option<ItemStack>,
mouse_click: MouseClick, 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()) { match (current_slot.as_mut(), carried_slot.as_mut()) {
// Swap or combine current and carried // Swap or combine current and carried
(Some(current), Some(carried)) => { (Some(current), Some(carried)) => {
@ -162,40 +170,10 @@ pub fn combine_stacks(
} }
} }
pub struct ContainerStruct<const SLOTS: usize> {
slots: [Option<ItemStack>; SLOTS],
_state_id: usize,
_open_by: Option<Vec<i32>>,
window_type: WindowType,
}
impl<const T: usize> Container for ContainerStruct<T> {
fn window_type(&self) -> &WindowType {
&self.window_type
}
fn handle_item_change(
&mut self,
carried_slot: &mut Option<ItemStack>,
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<ItemStack>> {
self.slots.iter_mut().collect()
}
fn all_slots_ref(&self) -> Vec<Option<&ItemStack>> {
self.slots.iter().map(|slot| slot.as_ref()).collect()
}
}
pub struct OptionallyCombinedContainer<'a> { pub struct OptionallyCombinedContainer<'a> {
container: Option<&'a mut Box<dyn Container>>, container: Option<&'a mut Box<dyn Container>>,
inventory: &'a mut PlayerInventory, inventory: &'a mut PlayerInventory,
state_id: i32,
} }
impl<'a> OptionallyCombinedContainer<'a> { impl<'a> OptionallyCombinedContainer<'a> {
pub fn new( pub fn new(
@ -205,6 +183,7 @@ impl<'a> OptionallyCombinedContainer<'a> {
Self { Self {
inventory: player_inventory, inventory: player_inventory,
container, container,
state_id: 0,
} }
} }
} }
@ -237,4 +216,9 @@ impl<'a> Container for OptionallyCombinedContainer<'a> {
slots.extend(self.inventory.all_slots_ref()); slots.extend(self.inventory.all_slots_ref());
slots slots
} }
fn state_id(&mut self) -> i32 {
self.state_id += 1;
self.state_id - 1
}
} }

View File

@ -12,7 +12,23 @@ impl OpenContainer {
if !self.players.contains(&player_id) { if !self.players.contains(&player_id) {
return None; 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 { pub fn empty(player_id: i32) -> Self {
@ -23,11 +39,17 @@ impl OpenContainer {
} }
} }
struct Chest([Option<ItemStack>; 27]); struct Chest {
slots: [Option<ItemStack>; 27],
state_id: i32,
}
impl Chest { impl Chest {
pub fn new() -> Self { pub fn new() -> Self {
Self([None; 27]) Self {
slots: [None; 27],
state_id: 0,
}
} }
} }
impl Container for Chest { impl Container for Chest {
@ -36,10 +58,15 @@ impl Container for Chest {
} }
fn all_slots(&mut self) -> Vec<&mut Option<ItemStack>> { fn all_slots(&mut self) -> Vec<&mut Option<ItemStack>> {
self.0.iter_mut().collect() self.slots.iter_mut().collect()
} }
fn all_slots_ref(&self) -> Vec<Option<&ItemStack>> { fn all_slots_ref(&self) -> Vec<Option<&ItemStack>> {
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
} }
} }

View File

@ -13,6 +13,7 @@ pub struct PlayerInventory {
offhand: Option<ItemStack>, offhand: Option<ItemStack>,
// current selected slot in hotbar // current selected slot in hotbar
selected: usize, selected: usize,
state_id: i32,
} }
impl Default for PlayerInventory { impl Default for PlayerInventory {
@ -31,6 +32,7 @@ impl PlayerInventory {
offhand: None, offhand: None,
// TODO: What when player spawns in with an different index ? // TODO: What when player spawns in with an different index ?
selected: 0, selected: 0,
state_id: 0,
} }
} }
@ -131,7 +133,7 @@ impl PlayerInventory {
} }
impl Container for PlayerInventory { impl Container for PlayerInventory {
fn window_type(&self) -> &WindowType { fn window_type(&self) -> &'static WindowType {
&WindowType::Generic9x1 &WindowType::Generic9x1
} }
@ -152,4 +154,9 @@ impl Container for PlayerInventory {
fn all_slots_ref(&self) -> Vec<Option<&ItemStack>> { fn all_slots_ref(&self) -> Vec<Option<&ItemStack>> {
self.slots() self.slots()
} }
fn state_id(&mut self) -> i32 {
self.state_id += 1;
self.state_id - 1
}
} }

View File

@ -22,6 +22,7 @@ impl Player {
window_title: Option<&str>, window_title: Option<&str>,
items: Option<Vec<Option<&ItemStack>>>, items: Option<Vec<Option<&ItemStack>>>,
carried_item: Option<&ItemStack>, carried_item: Option<&ItemStack>,
state_id: i32,
) { ) {
let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY let menu_protocol_id = (*pumpkin_world::global_registry::REGISTRY
.get("minecraft:menu") .get("minecraft:menu")
@ -32,27 +33,30 @@ impl Player {
.get("protocol_id") .get("protocol_id")
.unwrap()) .unwrap())
.into(); .into();
let window_type = container.window_type();
let title = TextComponent::text(window_title.unwrap_or(window_type.default_title())); let title = TextComponent::text(window_title.unwrap_or(window_type.default_title()));
self.client.send_packet(&COpenScreen::new( self.client.send_packet(&COpenScreen::new(
(*window_type as u8 + 1).into(), (*window_type as u8 + 1).into(),
menu_protocol_id, menu_protocol_id,
title, 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>( pub fn set_container_content<'a>(
&mut self, &mut self,
window_type: &WindowType, container: Option<&Box<dyn Container>>,
items: Option<Vec<Option<&'a ItemStack>>>,
carried_item: Option<&'a ItemStack>, carried_item: Option<&'a ItemStack>,
state_id: i32,
) { ) {
let slots: Vec<Slot> = { let slots: Vec<Slot> = {
let items = container.map(|container| container.all_slots_ref());
if let Some(mut items) = items { if let Some(mut items) = items {
items.extend(self.inventory.slots()); items.extend(self.inventory.all_slots_ref());
items items
} else { } else {
self.inventory.slots() self.inventory.all_slots_ref()
} }
.into_iter() .into_iter()
.map(|item| { .map(|item| {
@ -72,8 +76,13 @@ impl Player {
Slot::empty() 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); self.client.send_packet(&packet);
} }
@ -82,10 +91,11 @@ impl Player {
window_type: WindowType, window_type: WindowType,
slot: usize, slot: usize,
item: Option<&ItemStack>, item: Option<&ItemStack>,
state_id: i32,
) { ) {
self.client.send_packet(&CSetContainerSlot::new( self.client.send_packet(&CSetContainerSlot::new(
window_type as i8, window_type as i8,
0, state_id,
slot, slot,
&item.into(), &item.into(),
)) ))
@ -130,7 +140,12 @@ impl Player {
} }
}) })
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
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(), carried_item: packet.carried_item.to_item(),
mode: ClickMode::new( mode: ClickMode::new(
packet packet
@ -173,12 +188,8 @@ impl Player {
ClickType::MouseDrag { ClickType::MouseDrag {
drag_state: _, drag_state: _,
drag_type: _, drag_type: _,
} => { } => (),
todo!() ClickType::DropType(_drop_type) => (),
}
ClickType::DropType(_drop_type) => {
todo!()
}
} }
} }