mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
* replace slot with ItemStackSeralizer * Dismantle current inv logic * Disassemble even more, items need fixing markd with TODO: Inv * Player inventory methods implmented * make some fields private * remove invalid comment * Partial screen handler and slot * Add armorslot * prepare for crafting * implement some more crafting traits * Fix ItemStack * Fix pickup and remove faulty crafting (getting reworked in inv revamp) * fix * fix error * add readme * move readme file * asd * remove readme * add uppsercase readme * Some more work * merge * Move from generics to dynamics * fix * move to same impl * Some changes * add player open logic * Basic impl of sync and listeners * Why did mojang complicate it so much * bruh * Simplify things with DefaultScreenHandlerBehaviour * Implement partial slot clicks * add * itemhashes are broken * Start implementing packets * fix deadlock * new vanilla update * Use static item refs and use Arc Mutex on invs * working normal click * fix deadlock * implement sync handler * small patch * Implement quick_move * Implement Swap click type * pickup, update bug * start fixing updates * fix pickup desync * Make Inventories non mutexes * Implement some finishing stuff * close screen on player leave * fix pick item * Move to item hashes * remove some logs * begin implementing barrels * Begin implementing barrel * implement barrels * fix clippy + typos * Fix merge conflicts * Fix lint error * don't use unwrap when getting equipment slot * Fix typo and single threaded * Accidentally removed tokio completley * Fix crash when opening barrel holding item * Add support for marking block entities dirty * Player Equipment changes * Make ScreenHandlerFactory own inventory instead of passing in optional * remove log * replace todo's * fix clippy --------- Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
171 lines
5.4 KiB
Rust
171 lines
5.4 KiB
Rust
use std::{any::Any, sync::Arc};
|
|
|
|
use crate::{
|
|
crafting::{
|
|
crafting_inventory::CraftingInventory,
|
|
crafting_screen_handler::CraftingScreenHandler,
|
|
recipes::{RecipeFinderScreenHandler, RecipeInputInventory},
|
|
},
|
|
equipment_slot::EquipmentSlot,
|
|
screen_handler::{InventoryPlayer, ScreenHandler, ScreenHandlerBehaviour},
|
|
slot::{ArmorSlot, NormalSlot, Slot},
|
|
};
|
|
use async_trait::async_trait;
|
|
use pumpkin_data::screen::WindowType;
|
|
use pumpkin_world::inventory::Inventory;
|
|
use pumpkin_world::item::ItemStack;
|
|
|
|
use super::player_inventory::PlayerInventory;
|
|
|
|
pub struct PlayerScreenHandler {
|
|
behaviour: ScreenHandlerBehaviour,
|
|
crafting_inventory: Arc<dyn RecipeInputInventory>,
|
|
}
|
|
|
|
impl RecipeFinderScreenHandler for PlayerScreenHandler {}
|
|
|
|
impl CraftingScreenHandler<CraftingInventory> for PlayerScreenHandler {}
|
|
|
|
// TODO: Fully implement this
|
|
impl PlayerScreenHandler {
|
|
const EQUIPMENT_SLOT_ORDER: [EquipmentSlot; 4] = [
|
|
EquipmentSlot::HEAD,
|
|
EquipmentSlot::CHEST,
|
|
EquipmentSlot::LEGS,
|
|
EquipmentSlot::FEET,
|
|
];
|
|
|
|
pub fn is_in_hotbar(slot: u8) -> bool {
|
|
(36..45).contains(&slot) || slot == 45
|
|
}
|
|
|
|
pub async fn get_slot(&self, slot: usize) -> Arc<dyn Slot> {
|
|
self.behaviour.slots[slot].clone()
|
|
}
|
|
|
|
pub async fn new(
|
|
player_inventory: &Arc<PlayerInventory>,
|
|
window_type: Option<WindowType>,
|
|
sync_id: u8,
|
|
) -> Self {
|
|
let crafting_inventory: Arc<dyn RecipeInputInventory> =
|
|
Arc::new(CraftingInventory::new(2, 2));
|
|
|
|
let mut player_screen_handler = PlayerScreenHandler {
|
|
behaviour: ScreenHandlerBehaviour::new(sync_id, window_type),
|
|
crafting_inventory: crafting_inventory.clone(),
|
|
};
|
|
|
|
player_screen_handler
|
|
.add_result_slot(&crafting_inventory)
|
|
.await;
|
|
|
|
player_screen_handler
|
|
.add_input_slots(&crafting_inventory)
|
|
.await;
|
|
|
|
for i in 0..4 {
|
|
player_screen_handler.add_slot(Arc::new(ArmorSlot::new(
|
|
player_inventory.clone(),
|
|
39 - i,
|
|
Self::EQUIPMENT_SLOT_ORDER[i].clone(),
|
|
)));
|
|
}
|
|
|
|
let player_inventory: Arc<dyn Inventory> = player_inventory.clone();
|
|
|
|
player_screen_handler.add_player_slots(&player_inventory);
|
|
|
|
// Offhand
|
|
// TODO: public void setStack(ItemStack stack, ItemStack previousStack) { owner.onEquipStack(EquipmentSlot.OFFHAND, previousStack, stack);
|
|
player_screen_handler.add_slot(Arc::new(NormalSlot::new(player_inventory.clone(), 40)));
|
|
|
|
player_screen_handler
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl ScreenHandler for PlayerScreenHandler {
|
|
async fn on_closed(&mut self, player: &dyn InventoryPlayer) {
|
|
self.default_on_closed(player).await;
|
|
//TODO: this.craftingResultInventory.clear();
|
|
self.drop_inventory(player, self.crafting_inventory.clone())
|
|
.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;
|
|
let slot = self.get_behaviour().slots[slot_index as usize].clone();
|
|
|
|
// TODO: Equippable component
|
|
|
|
if slot.has_stack().await {
|
|
let slot_stack = slot.get_stack().await;
|
|
let mut slot_stack = slot_stack.lock().await;
|
|
stack_left = *slot_stack;
|
|
|
|
#[allow(clippy::if_same_then_else)]
|
|
if slot_index == 0 {
|
|
if !self.insert_item(&mut slot_stack, 9, 45, true).await {
|
|
return ItemStack::EMPTY;
|
|
}
|
|
|
|
slot.on_quick_transfer(*slot_stack, stack_left);
|
|
} else if (1..5).contains(&slot_index) {
|
|
if !self.insert_item(&mut slot_stack, 9, 45, false).await {
|
|
return ItemStack::EMPTY;
|
|
}
|
|
} else if (5..9).contains(&slot_index) {
|
|
if !self.insert_item(&mut slot_stack, 9, 45, false).await {
|
|
return ItemStack::EMPTY;
|
|
}
|
|
} else if (9..36).contains(&slot_index) {
|
|
if !self.insert_item(&mut slot_stack, 36, 45, false).await {
|
|
return ItemStack::EMPTY;
|
|
}
|
|
} else if (36..45).contains(&slot_index) {
|
|
if !self.insert_item(&mut slot_stack, 9, 36, false).await {
|
|
return ItemStack::EMPTY;
|
|
}
|
|
} else if !self.insert_item(&mut slot_stack, 9, 45, false).await {
|
|
return ItemStack::EMPTY;
|
|
}
|
|
|
|
if slot_stack.is_empty() {
|
|
drop(slot_stack);
|
|
slot.set_stack_prev(ItemStack::EMPTY, stack_left).await;
|
|
} else {
|
|
drop(slot_stack);
|
|
slot.mark_dirty().await;
|
|
}
|
|
|
|
let slot_stack = slot.get_stack().await;
|
|
let slot_stack = slot_stack.lock().await;
|
|
|
|
if slot_stack.item_count == stack_left.item_count {
|
|
return ItemStack::EMPTY;
|
|
}
|
|
|
|
slot.on_take_item(player, &slot_stack).await;
|
|
|
|
if slot_index == 0 {
|
|
player.drop_item(*slot_stack, false).await;
|
|
}
|
|
}
|
|
|
|
return stack_left;
|
|
}
|
|
}
|