steel_core/inventory/menu/kinds/
chest_menu.rs1use steel_registry::menu_type::MenuTypeRef;
9use steel_registry::vanilla_menu_types;
10
11use crate::inventory::prelude::*;
12use crate::player::player_inventory::PlayerInventory;
13
14#[must_use]
19pub fn chest(
20 inventory: Shared<PlayerInventory>,
21 container_id: u8,
22 container: impl Into<ContainerRef>,
23 rows: usize,
24) -> Menu {
25 let container = container.into();
26 assert!(
27 (1..=6).contains(&rows),
28 "Chest rows must be between 1 and 6"
29 );
30
31 let mut builder = MenuBuilder::new(menu_type_for_rows(rows), container_id);
32 let chest = builder.section(&container, rows * 9);
33 let player = builder.player_inventory(&inventory);
34
35 builder.route(chest, player.all(), FillDirection::Backward);
36 builder.route(player.all(), chest, FillDirection::Forward);
37
38 builder.build(ChestKind { container })
39}
40
41#[must_use]
46pub fn menu_type_for_rows(rows: usize) -> MenuTypeRef {
47 match rows {
48 1 => &vanilla_menu_types::GENERIC_9X1,
49 2 => &vanilla_menu_types::GENERIC_9X2,
50 3 => &vanilla_menu_types::GENERIC_9X3,
51 4 => &vanilla_menu_types::GENERIC_9X4,
52 5 => &vanilla_menu_types::GENERIC_9X5,
53 6 => &vanilla_menu_types::GENERIC_9X6,
54 _ => panic!("Invalid row count: {rows}"),
55 }
56}
57
58pub struct ChestKind {
60 container: ContainerRef,
62}
63
64unsafe impl steel_utils::DowncastType for ChestKind {
67 const TYPE_KEY: steel_utils::DowncastTypeKey =
68 steel_utils::DowncastTypeKey::new("steel:menu/chest");
69}
70
71impl MenuKind for ChestKind {
72 fn still_valid(&self, _behavior: &MenuBehavior, player: &Player) -> bool {
74 self.container.still_valid(player)
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use steel_utils::locks::IntoShared as _;
81
82 use super::*;
83 use crate::inventory::container::SimpleContainer;
84
85 #[test]
86 fn chest_uses_exactly_the_rows_requested_from_oversized_container() {
87 let inventory = PlayerInventory::new().into_shared();
88 let container = SimpleContainer::new(18).into_shared();
89
90 let menu = chest(inventory, 1, container, 1);
91
92 assert_eq!(menu.behavior().slot_count(), 9 + 36);
93 }
94}