Implement kits placing items in specific slots
Information
This PR closes #5535.
Details
Proposed feature:
Everytime you create a kit with gear (armor and offhand) equipped, the gear is placed in their respective slots once you retrieve the kit. For example, if you create the kit with a golden helmet equipped, it will be placed in your helmet slot when retrieving the kit.
Environments tested:
OS: Windows 11
Java version: 17
- [x] Most recent Paper version (1.20.4, git-Paper-BUILD)
- [ ] CraftBukkit/Spigot/Paper 1.12.2
- [ ] CraftBukkit 1.8.8
Demonstration:
Before:
Inventory before creating kit:
Execute createkit command:
Remove everything from inventory:
Retrieving the kit:
Inventory result:
After:
Inventory before creating kit:
Execute createkit command:
Remove everything from inventory:
Retrieving the kit:
Inventory result:
we should be adding a
slot:<number>intoMetaItemStack
I like the idea of storing the item slot like that, but it should not live in MetaItemStack. The slot is an inventory attribute, not an item attribute. If you put it in the item metadata, any serialization provider that saves only the item would lose the slot information and be unable to restore it later.
if (kitItem.startsWith("@")) {
if (serializationProvider == null) {
ess.getLogger().log(Level.WARNING, AdventureUtil.miniToLegacy(tlLiteral("kitError3", kitName, user.getName())));
continue;
}
stack = serializationProvider.deserializeItem(Base64Coder.decodeLines(kitItem.substring(1)));
} else {
final String[] parts = kitItem.split(" +");
final ItemStack parseStack = ess.getItemDb().get(parts[0], parts.length > 1 ? Integer.parseInt(parts[1]) : 1);
if (parseStack.getType() == Material.AIR) {
continue;
}
final MetaItemStack metaStack = new MetaItemStack(parseStack);
if (parts.length > 2) {
// We pass a null sender here because kits should not do perm checks
metaStack.parseStringMeta(null, allowUnsafe, parts, 2, ess);
}
stack = metaStack.getItemStack();
}
itemList.add(stack);
where
expandItemswill attempt to add the item to that slot if it is not full.
Should expandItems try to place every item from a kit into its assigned slot rather than only armor and offhand, and if it does, should the command include a flag to disable this behavior? Editing the config to remove slot data is technically possible.
hmm you're right, it should stay in expandItems.
Instead of an slotList tho, lets do a HashMap<Integer, ItemStack>, if during put() we get a return value (overlapping slot), add it to the regular itemList .
then we should do the Inventories#hasSpace check with all items (both regular and slotted) (or isDropItemsIfFull)
then we'll have a new method in Inventories that will check isSimilar and if the amount + new amount will be greater than the allowed max size. that method will return a boolean if it can be added to the slot or not.
then finally add all the non-slotted items + ones that couldn't be added to the slot they asked for in one go via Inventories#addItem