Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Player Inventory #38

Merged
merged 16 commits into from
Aug 20, 2024
81 changes: 77 additions & 4 deletions pumpkin-inventory/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@ use pumpkin_world::item::Item;

pub struct PlayerInventory {
// Main Inventory + Hotbar
crafting: [Option<Item>; 4],
crafting_output: Option<Item>,
items: [Option<Item>; 36],
armor: [Option<Item>; 4],
offhand: Option<Item>,
// current selected slot in hortbar
selected: i16,
Snowiiii marked this conversation as resolved.
Show resolved Hide resolved
// current selected slot in hotbar
selected: usize,
}

pub struct Hotbar<'a>(&'a mut [Option<Item>;9]);

impl Hotbar<'_> {
fn get_mut(&mut self, index: usize) -> &mut Option<Item> {
&mut self.0[index]
}
}

pub struct Armor<'a>(&'a mut [Option<Item>; 4]);



impl Default for PlayerInventory {
fn default() -> Self {
Self::new()
Expand All @@ -18,6 +32,8 @@ impl Default for PlayerInventory {
impl PlayerInventory {
pub fn new() -> Self {
Self {
crafting: [None; 4],
crafting_output: None,
items: [None; 36],
armor: [None; 4],
offhand: None,
Expand All @@ -26,9 +42,66 @@ impl PlayerInventory {
}
}

pub fn set_slot(slot: u32, item: Item) {}
/// Set the contents of an item in a slot
///
/// ## Slot
/// The slot according to https://wiki.vg/Inventory#Player_Inventory
///
/// ## Item
/// The optional item to place in the slot
///
/// ## Item allowed override
/// An override, which when enabled, makes it so that invalid items, can be placed in slots they normally can't.
/// Useful functionality for plugins in the future.
pub fn set_slot(&mut self, slot: usize, item: Option<Item>, item_allowed_override: bool) {
match slot {
0 => {
// TODO: Add crafting check here
self.crafting_output = item
}
1..=4 => {
self.crafting[slot-1] = item
}
5..=8 => {
match item {
None => {
self.armor[slot-4] = None
},
Some(item) => {
// TODO: Replace asserts with error handling
match slot-5 {
0 => {
assert!(item.is_helmet() || item_allowed_override);
self.armor[0] = Some(item);
}
1 => {
assert!(item.is_chestplate() || item_allowed_override);
self.armor[1] = Some(item)
}
2 => {
assert!(item.is_leggings() || item_allowed_override);
self.armor[2] = Some(item);
}
3 => {
assert!(item.is_boots() || item_allowed_override);
self.armor[3] = Some(item)
}
_ => unreachable!()
}
}
}
}
9..=44 => {
self.items[slot-9] = item;
}
45 => {
self.offhand = item;
}
_ => unreachable!()
}
}

pub fn set_selected(&mut self, slot: i16) {
pub fn set_selected(&mut self, slot: usize) {
assert!((0..9).contains(&slot));
self.selected = slot;
}
Expand Down
75 changes: 75 additions & 0 deletions pumpkin-world/src/item/item_category_checks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use crate::item::Item;
Snowiiii marked this conversation as resolved.
Show resolved Hide resolved

impl Item {
pub fn is_helmet(&self) -> bool {
[
// Leather
856,
// Netherite
876,
// Turtle helmet
794,
// Chainmail
860,
// Diamond
868,
// Gold
872,
// Iron
864
].contains(&self.item_id)
}

pub fn is_chestplate(&self) -> bool {
[
// Leather
857,
// Netherite
877,
// Chainmail
861,
// Diamond
869,
// Gold
873,
// Iron
865,
// Elytra
773,
].contains(&self.item_id)
}

pub fn is_leggings(&self) -> bool {
[
// Leather
858,
// Netherite
878,
// Chainmail
862,
// Diamond
870,
// Gold
874,
// Iron
866
].contains(&self.item_id)
}

pub fn is_boots(&self) -> bool {
[
// Leather
859,
// Netherite
879,
// Chainmail
863,
// Diamond
871,
// Gold
875,
// Iron
867
].contains(&self.item_id)
}
}
4 changes: 2 additions & 2 deletions pumpkin-world/src/item/item_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use lazy_static::lazy_static;

use crate::global_registry::{self, ITEM_REGISTRY};

use super::Raritiy;
use super::Rarity;

const ITEMS_JSON: &str = include_str!("../../assets/items.json");

Expand All @@ -17,7 +17,7 @@ pub struct ItemComponents {
#[serde(rename = "minecraft:max_stack_size")]
max_stack_size: u32,
#[serde(rename = "minecraft:rarity")]
rarity: Raritiy,
rarity: Rarity,
#[serde(rename = "minecraft:repair_cost")]
repair_cost: u32,
}
Expand Down
12 changes: 9 additions & 3 deletions pumpkin-world/src/item/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
mod item_registry;
mod item_category_checks;

#[derive(serde::Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
/// Item Raritiy
pub enum Raritiy {
/// Item Rarity
pub enum Rarity {
Common,
UnCommon,
Rare,
Epic,
}

#[derive(Clone, Copy)]
pub struct Item {}
pub struct Item {
item_count: u32,
// This ID is the numerical protocol ID, not the usual minecraft::block ID.
item_id: u32,
// TODO: Add Item Components
}
2 changes: 1 addition & 1 deletion pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ impl Client {
self.kick("Invalid held slot")
}
let player = self.player.as_mut().unwrap();
player.inventory.set_selected(slot);
player.inventory.set_selected(slot as usize);
}

pub fn handle_set_creative_slot(&mut self, _server: &mut Server, packet: SSetCreativeSlot) {
Expand Down