azalea_inventory/
lib.rs

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