Creating Accessories via API¶
This page shows practical examples of how to create, tag, manage, and query accessories from your own plugin.
Example 1: Tagging Existing Items¶
The simplest approach — take any ItemStack and tag it as an accessory:
import org.bg52.curiospaper.CuriosPaper;
import org.bg52.curiospaper.api.CuriosPaperAPI;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
public class AccessoryUtil {
private final CuriosPaperAPI api;
public AccessoryUtil() {
this.api = CuriosPaper.getInstance().getCuriosPaperAPI();
}
/**
* Creates a tagged ring accessory from scratch.
*/
public ItemStack createRing(String name, Material material) {
ItemStack ring = new ItemStack(material);
ItemMeta meta = ring.getItemMeta();
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
meta.setLore(Arrays.asList(
ChatColor.GRAY + "A custom ring accessory.",
ChatColor.GRAY + "Place in the ring slot."
));
ring.setItemMeta(meta);
// Tag it as a ring accessory — this adds the PDC tag
return api.tagAccessoryItem(ring, "ring");
}
/**
* Gives a player a tagged accessory and notifies them.
*/
public void giveAccessory(Player player, ItemStack accessory) {
player.getInventory().addItem(accessory);
String slotType = api.getAccessorySlotType(accessory);
player.sendMessage(ChatColor.GREEN + "Received a " + slotType + " accessory!");
}
}
Example 2: Full Custom Item with ItemData¶
For items that need recipes, abilities, mob drops, and full CuriosPaper integration:
import org.bg52.curiospaper.CuriosPaper;
import org.bg52.curiospaper.api.CuriosPaperAPI;
import org.bg52.curiospaper.data.ItemData;
import org.bg52.curiospaper.data.AbilityData;
import org.bg52.curiospaper.data.RecipeData;
import org.bg52.curiospaper.data.MobDropData;
import org.bukkit.entity.EntityType;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Arrays;
public class FireAmuletPlugin extends JavaPlugin {
@Override
public void onEnable() {
CuriosPaperAPI api = CuriosPaper.getInstance().getCuriosPaperAPI();
// Create the item (using 'this' tracks ownership to your plugin)
ItemData fireAmulet = api.createItem(this, "fire_amulet");
if (fireAmulet == null) {
getLogger().info("fire_amulet already exists, skipping creation.");
return;
}
// Set properties
fireAmulet.setDisplayName("&c&lAmulet of Fire");
fireAmulet.setMaterial("BLAZE_POWDER");
fireAmulet.setSlotType("necklace");
fireAmulet.setCustomModelData(30001);
fireAmulet.setItemModel("myplugin:fire_amulet");
fireAmulet.setLore(Arrays.asList(
"&7Forged in the heart of a volcano.",
"&7Protects the wearer from fire.",
"",
"&eBound to the Necklace slot"
));
// Add a WHILE_EQUIPPED fire resistance ability
AbilityData fireResist = new AbilityData();
fireResist.setTrigger(AbilityData.Trigger.WHILE_EQUIPPED);
fireResist.setEffectType(AbilityData.EffectType.POTION_EFFECT);
fireResist.setEffectName("FIRE_RESISTANCE");
fireResist.setAmplifier(0);
fireResist.setDuration(200);
fireAmulet.getAbilities().put("fire_resist", fireResist);
// Add a mob drop from Blazes
MobDropData blazeDrop = new MobDropData();
blazeDrop.setEntityType(EntityType.BLAZE.name());
blazeDrop.setChance(0.05);
blazeDrop.setMinAmount(1);
blazeDrop.setMaxAmount(1);
api.registerItemMobDrop("fire_amulet", blazeDrop);
// Save to disk
api.saveItemData("fire_amulet");
getLogger().info("Fire Amulet registered!");
}
}
Example 3: Registering Custom Slots at Runtime¶
Create entirely new accessory slot types from your plugin:
import org.bg52.curiospaper.CuriosPaper;
import org.bg52.curiospaper.api.CuriosPaperAPI;
import org.bukkit.Material;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Arrays;
public class EarringPlugin extends JavaPlugin {
@Override
public void onEnable() {
CuriosPaperAPI api = CuriosPaper.getInstance().getCuriosPaperAPI();
// Register a new "earring" slot type
boolean success = api.registerSlot(
"earring", // slot key
"&a✦ Earring Slots ✦", // display name
Material.DIAMOND, // icon material
"myplugin:earring_slot", // item model (1.21.3+)
10020, // custom model data (1.14-1.21.2)
2, // 2 earring slots per player
Arrays.asList("&7Sparkling earring slots.") // lore
);
if (success) {
getLogger().info("Earring slot type registered!");
} else {
getLogger().warning("Failed to register earring slot type.");
}
}
@Override
public void onDisable() {
// Optionally unregister when your plugin is disabled
CuriosPaperAPI api = CuriosPaper.getInstance().getCuriosPaperAPI();
api.unregisterSlot("earring");
}
}
Example 4: Querying Player Accessories¶
Check what a player has equipped — useful for RPG plugins, stat systems, etc:
import org.bg52.curiospaper.CuriosPaper;
import org.bg52.curiospaper.api.CuriosPaperAPI;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public class AccessoryInspector {
private final CuriosPaperAPI api;
public AccessoryInspector() {
this.api = CuriosPaper.getInstance().getCuriosPaperAPI();
}
/**
* Displays all equipped accessories to the player.
*/
public void showEquipment(Player player) {
player.sendMessage(ChatColor.GOLD + "=== Your Accessories ===");
List<String> slotTypes = api.getAllSlotTypes();
for (String slotType : slotTypes) {
if (!api.hasEquippedItems(player, slotType)) continue;
List<ItemStack> items = api.getEquippedItems(player, slotType);
for (int i = 0; i < items.size(); i++) {
ItemStack item = items.get(i);
if (item != null && item.hasItemMeta()) {
String name = item.getItemMeta().getDisplayName();
player.sendMessage(ChatColor.YELLOW + slotType + "[" + i + "]: "
+ ChatColor.WHITE + name);
}
}
}
}
/**
* Checks if a player has a specific custom item equipped anywhere.
*/
public boolean hasItemEquipped(Player player, String targetSlotType) {
return api.hasEquippedItems(player, targetSlotType)
&& api.countEquippedItems(player, targetSlotType) > 0;
}
/**
* Gets the total number of accessories a player has equipped.
*/
public int getTotalEquippedCount(Player player) {
int total = 0;
for (String slotType : api.getAllSlotTypes()) {
total += api.countEquippedItems(player, slotType);
}
return total;
}
/**
* Checks what type of accessory an item in the player's hand is.
*/
public void inspectHeldItem(Player player) {
ItemStack held = player.getInventory().getItemInMainHand();
if (api.isValidAccessory(held)) {
String slot = api.getAccessorySlotType(held);
player.sendMessage(ChatColor.GREEN + "This is a " + slot + " accessory!");
// Check if it fits a specific slot
if (api.isValidAccessory(held, "ring")) {
player.sendMessage(ChatColor.AQUA + "It can be equipped in the ring slot.");
}
} else {
player.sendMessage(ChatColor.RED + "This is not an accessory.");
}
}
}
Example 5: Programmatic Equip/Unequip¶
Set or clear accessories for a player directly:
import org.bg52.curiospaper.CuriosPaper;
import org.bg52.curiospaper.api.CuriosPaperAPI;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
public class AccessoryManager {
private final CuriosPaperAPI api;
public AccessoryManager() {
this.api = CuriosPaper.getInstance().getCuriosPaperAPI();
}
/**
* Force-equips an item in a player's first empty ring slot.
*/
public boolean equipInFirstEmptySlot(Player player, ItemStack accessory, String slotType) {
List<ItemStack> currentItems = api.getEquippedItems(player, slotType);
int slotCount = api.getSlotAmount(slotType);
for (int i = 0; i < slotCount; i++) {
if (i >= currentItems.size() || currentItems.get(i) == null) {
// Found an empty slot — set the item
List<ItemStack> updated = new ArrayList<>(currentItems);
// Ensure the list is big enough
while (updated.size() <= i) updated.add(null);
updated.set(i, accessory);
api.setEquippedItems(player, slotType, updated);
return true;
}
}
return false; // No empty slots
}
/**
* Clears all accessories from a player for a specific slot type.
*/
public void clearSlot(Player player, String slotType) {
api.clearEquippedItems(player.getUniqueId(), slotType);
}
/**
* Strips ALL accessories from a player (e.g., on death or jail).
*/
public List<ItemStack> stripAllAccessories(Player player) {
List<ItemStack> stripped = new ArrayList<>();
for (String slotType : api.getAllSlotTypes()) {
List<ItemStack> items = api.getEquippedItems(player, slotType);
for (ItemStack item : items) {
if (item != null) stripped.add(item);
}
api.clearEquippedItems(player.getUniqueId(), slotType);
}
return stripped; // Return removed items so caller can store/drop them
}
}
Example 6: Resource Pack Integration¶
Register your plugin's custom textures to be included in CuriosPaper's auto-generated resource pack:
import org.bg52.curiospaper.CuriosPaper;
import org.bg52.curiospaper.api.CuriosPaperAPI;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
public class TexturedAccessoryPlugin extends JavaPlugin {
@Override
public void onEnable() {
CuriosPaperAPI api = CuriosPaper.getInstance().getCuriosPaperAPI();
// Register your resource pack assets
// Your folder should contain: assets/myplugin/models/item/...
File rpFolder = new File(getDataFolder(), "resourcepack");
if (rpFolder.exists()) {
api.registerResourcePackAssets(this, rpFolder);
getLogger().info("Custom textures registered with CuriosPaper!");
}
}
}
Your resource pack folder structure: