azalea_inventory/
lib.rs

1//! Representations of various inventory data structures in Minecraft.
2
3#![feature(min_specialization)]
4
5pub mod components;
6pub mod default_components;
7pub mod item;
8pub mod operations;
9mod slot;
10
11use std::ops::{Deref, DerefMut, RangeInclusive};
12
13use azalea_inventory_macros::declare_menus;
14pub use slot::{DataComponentPatch, ItemStack, ItemStackData};
15
16// TODO: remove this here and in azalea-inventory-macros when rust makes
17// Default be implemented for all array sizes
18// https://github.com/rust-lang/rust/issues/61415
19
20/// A fixed-size list of [`ItemStack`]s.
21#[derive(Debug, Clone)]
22pub struct SlotList<const N: usize>([ItemStack; N]);
23impl<const N: usize> Deref for SlotList<N> {
24    type Target = [ItemStack; N];
25    fn deref(&self) -> &Self::Target {
26        &self.0
27    }
28}
29impl<const N: usize> DerefMut for SlotList<N> {
30    fn deref_mut(&mut self) -> &mut Self::Target {
31        &mut self.0
32    }
33}
34impl<const N: usize> Default for SlotList<N> {
35    fn default() -> Self {
36        SlotList([(); N].map(|_| ItemStack::Empty))
37    }
38}
39impl<const N: usize> SlotList<N> {
40    pub fn new(items: [ItemStack; N]) -> Self {
41        SlotList(items)
42    }
43}
44
45impl Menu {
46    /// Get the [`Player`] from this [`Menu`].
47    ///
48    /// # Panics
49    ///
50    /// Will panic if the menu isn't `Menu::Player`.
51    pub fn as_player(&self) -> &Player {
52        if let Menu::Player(player) = &self {
53            player
54        } else {
55            unreachable!("Called `Menu::as_player` on a menu that wasn't `Player`.")
56        }
57    }
58
59    /// Same as [`Menu::as_player`], but returns a mutable reference to the
60    /// [`Player`].
61    ///
62    /// # Panics
63    ///
64    /// Will panic if the menu isn't `Menu::Player`.
65    pub fn as_player_mut(&mut self) -> &mut Player {
66        if let Menu::Player(player) = self {
67            player
68        } else {
69            unreachable!("Called `Menu::as_player_mut` on a menu that wasn't `Player`.")
70        }
71    }
72}
73
74// the player inventory part is always the last 36 slots (except in the Player
75// menu), so we don't have to explicitly specify it
76
77// Client {
78//     ...
79//     pub menu: Menu,
80//     pub inventory: Arc<[Slot; 36]>
81// }
82
83// Generate a `struct Player`, `enum Menu`, and `impl Menu`.
84// a "player" field gets implicitly added with the player inventory
85
86declare_menus! {
87    Player {
88        craft_result: 1,
89        craft: 4,
90        armor: 4,
91        inventory: 36,
92        offhand: 1,
93    },
94    Generic9x1 {
95        contents: 9,
96    },
97    Generic9x2 {
98        contents: 18,
99    },
100    Generic9x3 {
101        contents: 27,
102    },
103    Generic9x4 {
104        contents: 36,
105    },
106    Generic9x5 {
107        contents: 45,
108    },
109    Generic9x6 {
110        contents: 54,
111    },
112    Generic3x3 {
113        contents: 9,
114    },
115    Crafter3x3 {
116        contents: 9,
117    },
118    Anvil {
119        first: 1,
120        second: 1,
121        result: 1,
122    },
123    Beacon {
124        payment: 1,
125    },
126    BlastFurnace {
127        ingredient: 1,
128        fuel: 1,
129        result: 1,
130    },
131    BrewingStand {
132        bottles: 3,
133        ingredient: 1,
134        fuel: 1,
135    },
136    Crafting {
137        result: 1,
138        grid: 9,
139    },
140    Enchantment {
141        item: 1,
142        lapis: 1,
143    },
144    Furnace {
145        ingredient: 1,
146        fuel: 1,
147        result: 1,
148    },
149    Grindstone {
150        input: 1,
151        additional: 1,
152        result: 1,
153    },
154    Hopper {
155        contents: 5,
156    },
157    Lectern {
158        book: 1,
159    },
160    Loom {
161        banner: 1,
162        dye: 1,
163        pattern: 1,
164        result: 1,
165    },
166    Merchant {
167        payments: 2,
168        result: 1,
169    },
170    ShulkerBox {
171        contents: 27,
172    },
173    Smithing {
174        template: 1,
175        base: 1,
176        additional: 1,
177        result: 1,
178    },
179    Smoker {
180        ingredient: 1,
181        fuel: 1,
182        result: 1,
183    },
184    CartographyTable {
185        map: 1,
186        additional: 1,
187        result: 1,
188    },
189    Stonecutter {
190        input: 1,
191        result: 1,
192    },
193}