Skip to content

Commit 6ab56d2

Browse files
TiagoFar78JRoy
andauthored
Implement kits placing items in specific slots (#5794)
Closes #5535 --------- Co-authored-by: Josh Roy <[email protected]>
1 parent e5c9074 commit 6ab56d2

File tree

3 files changed

+65
-10
lines changed

3 files changed

+65
-10
lines changed

Essentials/src/main/java/com/earth2me/essentials/Kit.java

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.GregorianCalendar;
2727
import java.util.List;
2828
import java.util.Map;
29+
import java.util.HashMap;
2930
import java.util.logging.Level;
3031

3132
import static com.earth2me.essentials.I18n.tlLiteral;
@@ -174,10 +175,11 @@ public boolean expandItems(final User user, final List<String> items) throws Exc
174175
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
175176
final boolean autoEquip = ess.getSettings().isKitAutoEquip();
176177
final List<ItemStack> itemList = new ArrayList<>();
178+
final Map<Integer, ItemStack> itemsWithSlot = new HashMap<>();
177179
final List<String> commandQueue = new ArrayList<>();
178180
final List<String> moneyQueue = new ArrayList<>();
179181
final String currencySymbol = ess.getSettings().getCurrencySymbol().isEmpty() ? "$" : ess.getSettings().getCurrencySymbol();
180-
for (final String kitItem : output.getLines()) {
182+
for (String kitItem : output.getLines()) {
181183
if (kitItem.startsWith("$") || kitItem.startsWith(currencySymbol)) {
182184
moneyQueue.add(NumberUtil.sanitizeCurrencyString(kitItem, ess));
183185
continue;
@@ -191,6 +193,16 @@ public boolean expandItems(final User user, final List<String> items) throws Exc
191193
continue;
192194
}
193195

196+
int itemSlot = -1;
197+
if (kitItem.startsWith("slot:")) {
198+
final int spaceIndex = kitItem.indexOf(" ");
199+
if (spaceIndex != -1) {
200+
final String slotStr = kitItem.substring("slot:".length(), spaceIndex);
201+
itemSlot = NumberUtil.isInt(slotStr) ? Integer.parseInt(slotStr) : -1;
202+
kitItem = kitItem.substring(spaceIndex + 1);
203+
}
204+
}
205+
194206
final ItemStack stack;
195207
final SerializationProvider serializationProvider = ess.provider(SerializationProvider.class);
196208

@@ -218,22 +230,35 @@ public boolean expandItems(final User user, final List<String> items) throws Exc
218230
stack = metaStack.getItemStack();
219231
}
220232

221-
itemList.add(stack);
233+
if (itemSlot == -1 || itemsWithSlot.containsKey(itemSlot)) {
234+
itemList.add(stack);
235+
} else {
236+
itemsWithSlot.put(itemSlot, stack);
237+
}
222238
}
223239

224240
final int maxStackSize = user.isAuthorized("essentials.oversizedstacks") ? ess.getSettings().getOversizedStackSize() : 0;
225241
final boolean isDropItemsIfFull = ess.getSettings().isDropItemsIfFull();
226242

227-
final KitPreExpandItemsEvent itemsEvent = new KitPreExpandItemsEvent(user, kitName, itemList);
228-
Bukkit.getPluginManager().callEvent(itemsEvent);
243+
final List<ItemStack> totalItems = new ArrayList<>(itemList);
244+
totalItems.addAll(itemsWithSlot.values());
229245

230-
final ItemStack[] itemArray = itemList.toArray(new ItemStack[0]);
231-
232-
if (!isDropItemsIfFull && !Inventories.hasSpace(user.getBase(), maxStackSize, autoEquip, itemArray)) {
246+
final KitPreExpandItemsEvent itemsEvent = new KitPreExpandItemsEvent(user, kitName, totalItems);
247+
Bukkit.getPluginManager().callEvent(itemsEvent);
248+
final ItemStack[] totalItemsArray = totalItems.toArray(new ItemStack[0]);
249+
if (!isDropItemsIfFull && !Inventories.hasSpace(user.getBase(), maxStackSize, autoEquip, totalItemsArray)) {
233250
user.sendTl("kitInvFullNoDrop");
234251
return false;
235252
}
236253

254+
for (Map.Entry<Integer, ItemStack> itemWithSlot : itemsWithSlot.entrySet()) {
255+
final ItemStack leftover = Inventories.addItem(user.getBase(), maxStackSize, itemWithSlot.getValue(), itemWithSlot.getKey());
256+
if (leftover != null) {
257+
itemList.add(leftover);
258+
}
259+
}
260+
261+
final ItemStack[] itemArray = itemList.toArray(new ItemStack[0]);
237262
final Map<Integer, ItemStack> leftover = Inventories.addItem(user.getBase(), maxStackSize, autoEquip, itemArray);
238263
if (!isDropItemsIfFull && !leftover.isEmpty()) {
239264
// Inventories#hasSpace should prevent this state from EVER being reached; If it does, something has gone terribly wrong, and we should just give up and hope people report it :(

Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,14 @@ public void run(final Server server, final User user, final String commandLabel,
5151
useSerializationProvider = false;
5252
}
5353

54-
for (ItemStack is : items) {
54+
for (int i = 0; i < items.length; i++) {
55+
final ItemStack is = items[i];
5556
if (is != null && is.getType() != null && is.getType() != Material.AIR) {
5657
final String serialized;
5758
if (useSerializationProvider) {
58-
serialized = "@" + Base64Coder.encodeLines(serializationProvider.serializeItem(is));
59+
serialized = "slot:" + i + " @" + Base64Coder.encodeLines(serializationProvider.serializeItem(is));
5960
} else {
60-
serialized = ess.getItemDb().serialize(is);
61+
serialized = "slot:" + i + " " + ess.getItemDb().serialize(is);
6162
}
6263
list.add(serialized);
6364
}

Essentials/src/main/java/com/earth2me/essentials/craftbukkit/Inventories.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,35 @@ public static Map<Integer, ItemStack> addItem(final Player player, final int max
142142
return addItem(player, maxStack, false, items);
143143
}
144144

145+
public static ItemStack addItem(final Player player, final int maxStack, ItemStack item, int slot) {
146+
final int itemMax = Math.max(maxStack, item.getMaxStackSize());
147+
148+
ItemStack existing = player.getInventory().getItem(slot);
149+
final int existingAmount;
150+
if (isEmpty(existing)) {
151+
existing = item.clone();
152+
existingAmount = 0;
153+
} else {
154+
existingAmount = existing.getAmount();
155+
}
156+
157+
if (!item.isSimilar(existing)) {
158+
return item;
159+
}
160+
161+
final int amount = item.getAmount();
162+
if (amount + existingAmount <= itemMax) {
163+
existing.setAmount(amount + existingAmount);
164+
player.getInventory().setItem(slot, existing);
165+
return null;
166+
}
167+
168+
existing.setAmount(itemMax);
169+
player.getInventory().setItem(slot, existing);
170+
item.setAmount(amount + existingAmount - itemMax);
171+
return item;
172+
}
173+
145174
public static Map<Integer, ItemStack> addItem(final Player player, final int maxStack, final boolean allowArmor, ItemStack... items) {
146175
items = normalizeItems(cloneItems(items));
147176
final Map<Integer, ItemStack> leftover = new HashMap<>();

0 commit comments

Comments
 (0)