Skip to main content

Custom items

Let's talk about real examples with item and custom NBT.

Simple data​

Make simple items with NBT data.

Vouchers​

Save voucher information inside item tag instead of comparing it with a large amount of items.

private Map<String, List<String>> vouchers = new HashMap();

public ItemStack setVoucher(ItemStack item, String voucherId) {
return RtagItem.edit(item, tag -> {
tag.set(voucherId, "voucher");
});
}

public String getVoucherId(ItemStack item) {
return new RtagItem(item).get("voucher");
}

public boolean handleVoucher(Player player, ItemStack item) {
final String id = getVoucherId(item);
if (id == null || !vouchers.containsKey(id)) {
return false;
}
for (String cmd : vouchers.get(id)) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", player.getName));
}
return true;
}

Number count​

Count some number inside item tag.

public ItemStack addCount(ItemStack item, int amount) {
return RtagItem.edit(item, tag -> {
int i = tag.getOptional("myplugin", "count").or(0);
i = i + amount;
tag.set(i, "myplugin", "count");
});
}

public int getCount(ItemStack item) {
return new RtagItem(item).getOptional("myplugin", "count").or(0);
}

Item owner​

Save item owner as custom tag.

public ItemStack setOwner(ItemStack item, OfflinePlayer player) {
return RtagItem.edit(item, tag -> {
tag.set(player.getName(), "owner", "name");
tag.set(player.getUniqueId(), "owner", "uuid");
});
}

public String getOwnerName(ItemStack item) {
return new RtagItem(item).get("owner", "name");
}

public UUID getOwnerUuid(ItemStack item) {
return new RtagItem(item).getOptional("owner", "uuid").asUuid();
}

Interactions​

Modify item interactions using NBT data and event handling.

Save item on death​

Let's make a custom tag like keepItem, set to true to save that item on death.

public ItemStack setKeepItem(ItemStack item, boolean value) {
return RtagItem.edit(item, tag -> {
tag.set(value, "keepItem");
});
}

public boolean keepItem(ItemStack item) {
return new RtagItem(item).getOptional("keepItem").or(false);
}

And handle it with PlayerDeathEvent and PlayerRespawnEvent.

private final Map<String, List<ItemStack>> savedItems = new HashMap<>();

@EventHandler
public void onDeath(PlayerDeathEvent e) {
if (e.getKeepInventory()) {
return;
}

List<ItemStack> matches = new ArrayList<>();
e.getDrops().forEach(item -> {
if (keepItem(item)) {
matches.add(item);
}
});

if (matches.isEmpty()) {
return;
}

String name = e.getEntity().getName();
if (savedItems.containsKey(name)) {
savedItems.get(name).addAll(matches);
} else {
savedItems.put(name, matches);
}

e.getDrops().removeAll(matches);
}

@EventHandler
public void onRespawn(PlayerRespawnEvent e) {
String name = e.getPlayer().getName();
if (savedItems.containsKey(name)) {
e.getPlayer().getInventory().addItem(savedItems.get(name).toArray(new ItemStack[0]));
savedItems.remove(name);
}
}