Skip to main content

steel_core/inventory/menu/kinds/
shulker_box_menu.rs

1//! Shulker box menu.
2
3use steel_registry::vanilla_menu_types;
4use steel_utils::{DowncastType, DowncastTypeKey};
5
6use crate::behavior::ITEM_BEHAVIORS;
7use crate::block_entity::entities::SHULKER_BOX_SLOTS;
8use crate::inventory::prelude::*;
9use crate::player::player_inventory::PlayerInventory;
10
11/// Builds a shulker box menu with 3 rows of 9 slots plus the player inventory.
12#[must_use]
13pub fn shulker_box(
14    inventory: Shared<PlayerInventory>,
15    container_id: u8,
16    container: impl Into<ContainerRef>,
17) -> Menu {
18    let container = container.into();
19
20    let mut builder = MenuBuilder::new(&vanilla_menu_types::SHULKER_BOX, container_id);
21    let shulker_box = builder.section_with(
22        &container,
23        SHULKER_BOX_SLOTS,
24        SectionKind::restricted(|_slot, stack| {
25            ITEM_BEHAVIORS
26                .get_behavior(stack.item())
27                .can_fit_inside_container_items()
28        }),
29    );
30    let player = builder.player_inventory(&inventory);
31
32    builder.route(shulker_box, player.all(), FillDirection::Backward);
33    builder.route(player.all(), shulker_box, FillDirection::Forward);
34
35    builder.build(ShulkerBoxKind { container })
36}
37
38/// Per-menu shulker box state: just the backing container for the validity check.
39pub struct ShulkerBoxKind {
40    container: ContainerRef,
41}
42
43// SAFETY: This Steel-owned key uniquely identifies the concrete menu kind
44// within the process.
45unsafe impl DowncastType for ShulkerBoxKind {
46    const TYPE_KEY: DowncastTypeKey = DowncastTypeKey::new("steel:menu/shulker_box");
47}
48
49impl MenuKind for ShulkerBoxKind {
50    fn still_valid(&self, _behavior: &MenuBehavior, player: &Player) -> bool {
51        self.container.still_valid(player)
52    }
53}