Essentials icon indicating copy to clipboard operation
Essentials copied to clipboard

Implement kits placing items in specific slots

Open TiagoFar78 opened this issue 1 year ago • 2 comments

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: image

Execute createkit command: image

Remove everything from inventory: image

Retrieving the kit: image

Inventory result: image

After:

Inventory before creating kit: image

Execute createkit command: image

Remove everything from inventory: image

Retrieving the kit: image

Inventory result: image

TiagoFar78 avatar May 07 '24 08:05 TiagoFar78

we should be adding a slot:<number> into MetaItemStack

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 expandItems will 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.

TiagoFar78 avatar Nov 18 '25 01:11 TiagoFar78

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

JRoy avatar Dec 07 '25 22:12 JRoy