on Slot Changed
abstract fun onSlotChanged(player: Player, slot: Int, item: ItemStack, wasPlaced: Boolean): EffectiveMenu.SlotChangeResult
Called before a free-slot change is applied. React to it and/or veto it: return SlotChangeResult.CANCEL to block the change (the Bukkit interaction is cancelled, so the item stays put), or SlotChangeResult.ALLOW to let it through. Use it as a slot filter (reject certain items), a read-only guard, or just to persist/update on change.
Fired on every free-slot mutation path — direct click, number-key swap, shift-click from the player inventory, and drag. On a swap it's called twice: once for the outgoing item (wasPlaced = false) and once for the incoming one (wasPlaced = true). For bulk paths (shift-click / drag) the target slot isn't resolved yet, so slot is -1 — filter by item.