Skip to content

ComposeContainerMenuBase

abstract class ComposeContainerMenuBase<SELF : ComposeContainerMenuBase<SELF>>(
    type: MenuType<SELF>, 
    id: Int, 
    playerInventory: Inventory
) : AbstractContainerMenu

Holder-agnostic base for Compose-backed container menus: everything about slot layout, registration, and vanilla-menu plumbing that doesn't care whether the menu is backed by a net.minecraft.world.level.block.entity.BlockEntity (ComposeBlockContainerMenu) or an net.minecraft.world.item.ItemStack (net.kernelpanicsoft.archie.gui.item.ComposeItemContainerMenu).

Slots are pre-registered at construction time with placeholder pixel positions so that AbstractContainerMenu.initializeContents (triggered by the server's slot-sync packet) always finds the correct number of slots. When the Compose layout runs and reports actual on-screen positions via updateSlotData, existing slot objects have their pixel coordinates updated in-place rather than the slot list being rebuilt from scratch.

Parameters

  • SELF: The concrete menu subclass (self-referential for the MenuType).

  • type: The registered MenuType for this menu.

  • id: The container id assigned by the server.

  • playerInventory: The opening player's inventory.

Inheritors

Constructors

ComposeContainerMenuBase

constructor(
    type: MenuType<SELF>, 
    id: Int, 
    playerInventory: Inventory
)

Parameters

  • SELF: The concrete menu subclass (self-referential for the MenuType).

  • type: The registered MenuType for this menu.

  • id: The container id assigned by the server.

  • playerInventory: The opening player's inventory.

Types

Companion

object Companion

SlotGridLocation

data class SlotGridLocation(
    val slot: Int, 
    val x: Int, 
    val y: Int
)

Properties

carried

open var carried: ItemStack?

containerId

items

open val items: NonNullList<ItemStack?>?

lastSlots

val lastSlots: NonNullList<ItemStack?>?

ready

var ready: Boolean

true once repositionSlots has run at least once and slot pixel positions are valid.

remoteSlots

val remoteSlots: NonNullList<ItemStack?>?

screenLeftPos

The screen's leftPos offset — set by ComposeContainerScreen so that absolute Compose coordinates can be converted to slot-relative coordinates that vanilla's item rendering expects (vanilla renders items at leftPos + slot.x).

screenTopPos

The screen's topPos offset — set by ComposeContainerScreen so that absolute Compose coordinates can be converted to slot-relative coordinates that vanilla's item rendering expects (vanilla renders items at topPos + slot.y).

slotData

The most recently reported SlotData from the Compose layout. On the server this is the authoritative source of slot group sizes. On the client it is received from the server via a net.kernelpanicsoft.archie.networking.NetworkChannel.

slots

val slots: NonNullList<Slot?>?

stateId

open val stateId: Int

type

open val type: MenuType<*>?

Functions

addSlotListener

open fun addSlotListener(listener: ContainerListener?)

broadcastChanges

open fun broadcastChanges()

broadcastFullState

open fun broadcastFullState()

canDragTo

open fun canDragTo(slot: Slot?): Boolean

canTakeItemForPickAll

open fun canTakeItemForPickAll(stack: ItemStack?, slot: Slot?): Boolean

clicked

open override fun clicked(
    slotId: Int, 
    button: Int, 
    clickType: ClickType, 
    player: Player
)

clickMenuButton

open fun clickMenuButton(player: Player?, id: Int): Boolean

findSlot

open fun findSlot(container: Container?, slotIndex: Int): OptionalInt?

getSlot

open fun getSlot(slotId: Int): Slot?

incrementStateId

open fun incrementStateId(): Int

initializeContents

open fun initializeContents(
    stateId: Int, 
    items: List<ItemStack?>?, 
    carried: ItemStack?
)

isSlotVisible

fun isSlotVisible(slotIndex: Int): Boolean

Whether the slot at slotIndex currently overlaps its group's clip bounds (if it has any, i.e. it sits inside a net.kernelpanicsoft.archie.gui.composables.containers.Scrollable).

Used as this slot's Slot.isActive - the same vanilla hook that hides the Donkey/Mule armor slot - so a slot scrolled out of view stops rendering its item icon and stops being hoverable/clickable, without needing to remove it from slots and break its identity. A slot with no clip bounds (not inside a scrollable) is always visible.

isValidSlotIndex

open fun isValidSlotIndex(slotIndex: Int): Boolean

quickMoveStack

open override fun quickMoveStack(player: Player, index: Int): ItemStack

Shift-click handling: menu slots move into the player inventory/hotbar, and player slots move into the menu, falling back between main inventory and hotbar when the menu has no room. Slot ranges are derived from slots.size rather than hardcoded, since the number of menu slots varies with which groups are enabled.

The player-inventory slot excluded via isPlayerSlotExcluded (if any) is special-cased to return ItemStack.EMPTY immediately - shift-clicking a backpack's own slot while its GUI is open must not be able to move the backpack into itself.

refreshSlotPositions

Re-derives every Slot's pixel position from the current slotData without touching slot identity or slotHandlers. Call after screenLeftPos/screenTopPos change - slot coordinates have the screen offset baked into their subtraction (see repositionSlots), so they go stale whenever the screen recenters, independent of whether Compose's own slot layout changed.

removed

open override fun removed(player: Player)

removeSlotListener

open fun removeSlotListener(listener: ContainerListener?)

resumeRemoteUpdates

open fun resumeRemoteUpdates()

sendAllDataToRemote

open fun sendAllDataToRemote()

setData

open fun setData(id: Int, data: Int)

setItem

open fun setItem(
    slotId: Int, 
    stateId: Int, 
    stack: ItemStack?
)

setRemoteCarried

open fun setRemoteCarried(remoteCarried: ItemStack?)

setRemoteSlot

open fun setRemoteSlot(slot: Int, stack: ItemStack?)

setRemoteSlotNoCopy

open fun setRemoteSlotNoCopy(slot: Int, stack: ItemStack?)

setSynchronizer

open fun setSynchronizer(synchronizer: ContainerSynchronizer?)

slotClipBounds

fun slotClipBounds(slotIndex: Int): IntRect?

slotLayerDepth

fun slotLayerDepth(slotIndex: Int): Int

slotsChanged

open fun slotsChanged(container: Container?)

stillValid

abstract fun stillValid(player: Player?): Boolean

suppressRemoteUpdates

transferState

open fun transferState(menu: AbstractContainerMenu?)

updateSlotData

Called by the Slot composable once its absolute screen position is known.

On the first call (before any slots exist) the full slot list is built. On subsequent calls (re-layout / window resize) existing slot objects have their pixel coordinates updated in-place so initializeContents is never broken.

Parameters

  • data: The updated SlotData from the Compose layout.