refactor to make SClickContainer work in containers other than inventory

This commit is contained in:
Edvin Bryntesson 2024-08-28 09:58:35 +02:00
parent 0f9ac2259c
commit d7e059cb86
No known key found for this signature in database
2 changed files with 134 additions and 90 deletions

View File

@ -1,4 +1,5 @@
use crate::container_click::MouseClick; use crate::container_click::MouseClick;
use crate::player::PlayerInventory;
use num_derive::{FromPrimitive, ToPrimitive}; use num_derive::{FromPrimitive, ToPrimitive};
use pumpkin_world::item::ItemStack; use pumpkin_world::item::ItemStack;
@ -180,3 +181,47 @@ impl<const T: usize> Container for ContainerStruct<T> {
self.slots.iter_mut().collect() self.slots.iter_mut().collect()
} }
} }
pub struct OptionallyCombinedContainer<'a> {
container: Option<&'a mut Box<dyn Container>>,
inventory: &'a mut PlayerInventory,
}
impl<'a> OptionallyCombinedContainer<'a> {
pub fn new(
player_inventory: &'a mut PlayerInventory,
container: Option<&'a mut Box<dyn Container>>,
) -> Self {
Self {
inventory: player_inventory,
container,
}
}
}
impl<'a> Container for OptionallyCombinedContainer<'a> {
fn window_type(&self) -> &WindowType {
if let Some(container) = &self.container {
container.window_type()
} else {
&WindowType::Generic9x1
}
}
fn all_slots(&mut self) -> Vec<&mut Option<ItemStack>> {
let mut slots = if let Some(container) = &mut self.container {
container.all_slots()
} else {
vec![]
};
slots.extend(self.inventory.all_slots());
slots
}
fn handle_item_change(
&mut self,
carried_item: &mut Option<ItemStack>,
slot: usize,
mouse_click: MouseClick,
) {
}
}

View File

@ -1,8 +1,11 @@
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use pumpkin_core::text::TextComponent; use pumpkin_core::text::TextComponent;
use pumpkin_inventory::container_click::{KeyClick, MouseClick}; use pumpkin_inventory::container_click::{KeyClick, MouseClick};
use pumpkin_inventory::player::PlayerInventory;
use pumpkin_inventory::window_property::{WindowProperty, WindowPropertyTrait}; use pumpkin_inventory::window_property::{WindowProperty, WindowPropertyTrait};
use pumpkin_inventory::{container_click, handle_item_change}; use pumpkin_inventory::{
container_click, handle_item_change, ContainerStruct, OptionallyCombinedContainer,
};
use pumpkin_inventory::{Container, WindowType}; use pumpkin_inventory::{Container, WindowType};
use pumpkin_protocol::client::play::{ use pumpkin_protocol::client::play::{
CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerProperty, CSetContainerSlot, CCloseContainer, COpenScreen, CSetContainerContent, CSetContainerProperty, CSetContainerSlot,
@ -160,8 +163,10 @@ impl Player {
} => { } => {
todo!() todo!()
} }
ClickType::DropType(drop_type) => {
todo!()
}
} }
dbg!(&self.carried_item);
let filled_inventory_slots = self let filled_inventory_slots = self
.inventory .inventory
.slots() .slots()
@ -169,37 +174,33 @@ impl Player {
.enumerate() .enumerate()
.filter_map(|(slot, item)| item.map(|item| (slot, item.item_count))) .filter_map(|(slot, item)| item.map(|item| (slot, item.item_count)))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
dbg!(filled_inventory_slots);
} }
pub fn mouse_click( fn mouse_click(
&mut self, &mut self,
mouse_click: MouseClick, mouse_click: MouseClick,
window_type: WindowType, window_type: WindowType,
slot: container_click::Slot, slot: container_click::Slot,
) { ) {
let Some(_) = &self.open_container else { let mut container = get_full_container(&mut self.inventory, self.open_container.as_mut());
// Inventory if container.window_type() != &window_type {
if window_type == WindowType::Generic9x1 { return;
}
match slot { match slot {
container_click::Slot::Normal(slot) => { container_click::Slot::Normal(slot) => {
self.inventory container.handle_item_change(&mut self.carried_item, slot, mouse_click)
.handle_item_change(&mut self.carried_item, slot, mouse_click)
} }
container_click::Slot::OutsideInventory => (), container_click::Slot::OutsideInventory => (),
}; };
return;
} else {
return;
}
};
} }
pub fn shift_mouse_click(&mut self, window_type: WindowType, slot: container_click::Slot) { fn shift_mouse_click(&mut self, window_type: WindowType, slot: container_click::Slot) {
let Some(_) = &self.open_container else { let mut container = get_full_container(&mut self.inventory, self.open_container.as_mut());
// Inventory if container.window_type() != &window_type {
if window_type == WindowType::Generic9x1 { return;
}
match slot { match slot {
container_click::Slot::Normal(slot) => { container_click::Slot::Normal(slot) => {
if let Some(item_in_pressed_slot) = self.inventory.slots()[slot] { if let Some(item_in_pressed_slot) = self.inventory.slots()[slot] {
@ -222,60 +223,51 @@ impl Player {
.map(|(slot_num, _)| slot_num) .map(|(slot_num, _)| slot_num)
}; };
if let Some(slot) = slots { if let Some(slot) = slots {
let mut item_slot = let mut item_slot = self.inventory.slots()[slot].map(|i| i.to_owned());
self.inventory.slots()[slot].map(|i| i.to_owned());
self.inventory.handle_item_change( self.inventory
&mut item_slot, .handle_item_change(&mut item_slot, slot, MouseClick::Left);
slot,
MouseClick::Left,
);
*self.inventory.slots_mut()[slot] = item_slot; *self.inventory.slots_mut()[slot] = item_slot;
} }
} }
} }
container_click::Slot::OutsideInventory => (), container_click::Slot::OutsideInventory => (),
}; };
return;
} else {
return;
}
};
} }
pub fn number_button_pressed( fn number_button_pressed(&mut self, window_type: WindowType, key_click: KeyClick, slot: usize) {
&mut self,
window_type: WindowType,
key_click: KeyClick,
slot: usize,
) {
if window_type == WindowType::Generic9x1 {
let changing_slot = match key_click { let changing_slot = match key_click {
KeyClick::Slot(slot) => slot, KeyClick::Slot(slot) => slot,
KeyClick::Offhand => 45, KeyClick::Offhand => 45,
}; };
let mut changing_item_slot = self.inventory.get_slot(changing_slot as usize).to_owned(); let mut changing_item_slot = self.inventory.get_slot(changing_slot as usize).to_owned();
let item_slot = self.inventory.get_slot(slot); let mut container = get_full_container(&mut self.inventory, self.open_container.as_mut());
if container.window_type() != &window_type {
return;
}
let item_slot = &mut container.all_slots()[slot];
if item_slot.is_some() { if item_slot.is_some() {
handle_item_change(&mut changing_item_slot, item_slot, MouseClick::Left); handle_item_change(&mut changing_item_slot, item_slot, MouseClick::Left);
*self.inventory.get_slot(changing_slot as usize) = changing_item_slot *self.inventory.get_slot(changing_slot as usize) = changing_item_slot
} }
} }
fn creative_pick_item(&mut self, slot: usize) {
let mut container = get_full_container(&mut self.inventory, self.open_container.as_mut());
if let Some(Some(item)) = container.all_slots().get_mut(slot) {
self.carried_item = Some(item.to_owned())
}
} }
pub fn creative_pick_item(&mut self, slot: usize) { fn double_click(&mut self, slot: usize) {}
let mut container = {
match &mut self.open_container { fn get_container_type(&mut self) -> &WindowType {
Some(container) => { match &self.open_container {
let mut out = container.all_slots(); Some(container) => container.window_type(),
out.extend(self.inventory.slots_mut()); // This is the one the inventory uses for some stupid reason
out None => &WindowType::Generic9x1,
}
None => self.inventory.slots_mut(),
}
};
if let Some(Some(item)) = container.get_mut(slot) {
self.carried_item = Some(item.to_owned())
} }
} }
} }
@ -285,3 +277,10 @@ impl Player {
} }
}*/ }*/
fn get_full_container<'a>(
inventory: &'a mut PlayerInventory,
open_container: Option<&'a mut Box<dyn Container>>,
) -> OptionallyCombinedContainer<'a> {
OptionallyCombinedContainer::new(inventory, open_container)
}