Files
Pumpkin/pumpkin-inventory/src/generic_container_screen_handler.rs
spr-equinox 8ce65cc42d Refactor ItemStack to Support Vanilla-Like Data Components (#1059)
* improve tag v1

* improve tag v2

* fix typo and make BlockPredicate better

* improve get state from state id

* impl DataComponent

* make tag pub

* make component work

* apply clippy

* apply clippy

* remove unused crate

* apply to itemstack and no lifetime mark anymore

* Update tag.rs

* use Cow

* remove unnecessary lazy_static and Cow

* Update mod.rs

* Update mod.rs

* make DataComponent dyn

* remove unused crate

* fix error

* Update Cargo.toml

* Update Cargo.lock

* fix

* Update composter.rs

* update rust-version, remove unused crate, and merge

* Update furnace.rs
2025-07-28 12:24:40 +02:00

162 lines
4.2 KiB
Rust

use std::{any::Any, sync::Arc};
use async_trait::async_trait;
use pumpkin_data::screen::WindowType;
use pumpkin_world::{inventory::Inventory, item::ItemStack};
use crate::{
player::player_inventory::PlayerInventory,
screen_handler::{InventoryPlayer, ScreenHandler, ScreenHandlerBehaviour},
slot::NormalSlot,
};
pub fn create_generic_9x3(
sync_id: u8,
player_inventory: &Arc<PlayerInventory>,
inventory: Arc<dyn Inventory>,
) -> GenericContainerScreenHandler {
GenericContainerScreenHandler::new(
WindowType::Generic9x3,
sync_id,
player_inventory,
inventory,
3,
9,
)
}
pub fn create_generic_3x3(
sync_id: u8,
player_inventory: &Arc<PlayerInventory>,
inventory: Arc<dyn Inventory>,
) -> GenericContainerScreenHandler {
GenericContainerScreenHandler::new(
WindowType::Generic3x3,
sync_id,
player_inventory,
inventory,
3,
3,
)
}
pub fn create_hopper(
sync_id: u8,
player_inventory: &Arc<PlayerInventory>,
inventory: Arc<dyn Inventory>,
) -> GenericContainerScreenHandler {
GenericContainerScreenHandler::new(
WindowType::Hopper,
sync_id,
player_inventory,
inventory,
1,
5,
)
}
pub struct GenericContainerScreenHandler {
pub inventory: Arc<dyn Inventory>,
pub rows: u8,
pub columns: u8,
behaviour: ScreenHandlerBehaviour,
}
impl GenericContainerScreenHandler {
fn new(
screen_type: WindowType,
sync_id: u8,
player_inventory: &Arc<PlayerInventory>,
inventory: Arc<dyn Inventory>,
rows: u8,
columns: u8,
) -> Self {
let mut handler = Self {
inventory,
rows,
columns,
behaviour: ScreenHandlerBehaviour::new(sync_id, Some(screen_type)),
};
//inventory.onOpen(player);
handler.add_inventory_slots();
let player_inventory: Arc<dyn Inventory> = player_inventory.clone();
handler.add_player_slots(&player_inventory);
handler
}
fn add_inventory_slots(&mut self) {
for i in 0..self.rows {
for j in 0..self.columns {
self.add_slot(Arc::new(NormalSlot::new(
self.inventory.clone(),
(j + i * self.columns) as usize,
)));
}
}
}
}
#[async_trait]
impl ScreenHandler for GenericContainerScreenHandler {
async fn on_closed(&mut self, player: &dyn InventoryPlayer) {
self.default_on_closed(player).await;
//TODO: self.inventory.on_closed(player).await;
}
fn as_any(&self) -> &dyn Any {
self
}
fn get_behaviour(&self) -> &ScreenHandlerBehaviour {
&self.behaviour
}
fn get_behaviour_mut(&mut self) -> &mut ScreenHandlerBehaviour {
&mut self.behaviour
}
async fn quick_move(&mut self, _player: &dyn InventoryPlayer, slot_index: i32) -> ItemStack {
let mut stack_left = ItemStack::EMPTY.clone();
let slot = self.get_behaviour().slots[slot_index as usize].clone();
if slot.has_stack().await {
let slot_stack = slot.get_stack().await;
stack_left = slot_stack.lock().await.clone();
if slot_index < (self.rows * 9) as i32 {
if !self
.insert_item(
&mut *slot_stack.lock().await,
(self.rows * 9).into(),
self.get_behaviour().slots.len() as i32,
true,
)
.await
{
return ItemStack::EMPTY.clone();
}
} else if !self
.insert_item(
&mut *slot_stack.lock().await,
0,
(self.rows * 9).into(),
false,
)
.await
{
return ItemStack::EMPTY.clone();
}
if stack_left.is_empty() {
slot.set_stack(ItemStack::EMPTY.clone()).await;
} else {
slot.mark_dirty().await;
}
}
return stack_left;
}
}