Why
Give an item without losing it when the inventory is full. Check that a player has five custom items and take them. Draw a box with particles for one player. Fill a chest with loot. Not subsystems, but functions every plugin has, each time slightly different.
Minimal example
val result = EffectiveInventoryUtils.giveItem(RubyItem.createItemStack(), player)
if (result == GiveResult.DROPPED) player.sendMessage("inventory full")
if (EffectiveInventoryUtils.hasItems(player.inventory, RubyItem.createItemStack(), 5)) {
EffectiveInventoryUtils.removeItems(player.inventory, RubyItem.createItemStack(), 5)
}
val held = EffectiveInventoryUtils.getUsedItemFromHands(player)Matching is by EffectiveItem key, by material for vanilla items; meta is ignored.
val red = Particle.DustOptions(Color.RED, 1f)
EffectiveParticles.drawBox(listOf(player), 0.0, 64.0, 0.0, 10.0, 70.0, 10.0, red)
EffectiveParticles.drawLine(listOf(player), 0.0, 64.0, 0.0, 10.0, 64.0, 0.0, red, step = 0.25)Dust particles visible only to the listed players. drawLine — point to point with a step of step blocks, drawBox — the 12 edges of a box by its min/max corners.
import ru.hukm.effectiveSpigot.minecraft.utils.plus
val line = Component.text("Ruby: ").color(NamedTextColor.RED) + count.toString()
'#' to SlotData(EffectiveItems.EMPTY(), emptyList())CustomLootable — loot tables
val CHEST_LOOT = arrayListOf(
CustomLootable.ItemCellData(RubyItem.createItemStack(), 0.3),
CustomLootable.ItemCellData(ItemStack(Material.BREAD, 3), 0.8),
CustomLootable.ItemCellData(ItemStack(Material.DIAMOND), 0.05),
)
CustomLootable.putLootToContainer(chest.state as Container, CHEST_LOOT)
CustomLootable.spawnLootAtLocation(boss.location, CHEST_LOOT)
override fun getDrop() = CHEST_LOOTItemCellData is an item and its chance 0.0..1.0; every cell rolls independently, so a table may yield everything, nothing or any subset. putLootToContainer spreads the winners over random free slots of a chest/barrel/shulker (throws IllegalStateException if slots run out), spawnLootAtLocation drops them on the ground. EffectiveBlock.getDrop() takes the same list.
Pitfalls
- The + operator for Component is an extension — import …minecraft.utils.plus, otherwise "Unresolved reference".
- CustomLootable chances are independent — every item rolls on its own, it is not "one of".
- drawBox / drawLine draw once — for a persistent frame call them in a launch loop with delay.