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_ref(&self) -> Vec<Option<&ItemStack>>;
fn state_id(&mut self) -> i32;
}
pub fn handle_item_take(
@ -104,6 +106,12 @@ pub fn handle_item_change(
current_slot: &mut Option<ItemStack>,
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<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> {
container: Option<&'a mut Box<dyn Container>>,
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
}
}

View File

@ -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<ItemStack>; 27]);
struct Chest {
slots: [Option<ItemStack>; 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<ItemStack>> {
self.0.iter_mut().collect()
self.slots.iter_mut().collect()
}
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>,
// 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<Option<&ItemStack>> {
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>,
items: Option<Vec<Option<&ItemStack>>>,
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<Vec<Option<&'a ItemStack>>>,
container: Option<&Box<dyn Container>>,
carried_item: Option<&'a ItemStack>,
state_id: i32,
) {
let slots: Vec<Slot> = {
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::<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(),
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) => (),
}
}