Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
266 changes: 86 additions & 180 deletions docs/core-features/item-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,234 +4,140 @@ description: Fluent API for creating ItemStacks.

# ItemBuilder

## Basic Usage
`ItemBuilder` wraps Bukkit's `ItemStack` and `ItemMeta` manipulation into a chainable builder. Call `.get()` to retrieve the final `ItemStack`.

```java
import dev.demeng.pluginbase.item.ItemBuilder;
## Creating a builder

| Factory method | Description |
|---|---|
| `ItemBuilder.create(ItemStack stack)` | Clones an existing item stack (null defaults to `STONE`) |
| `ItemBuilder.create(Material material)` | Creates a new stack with amount 1 |
| `ItemBuilder.create(Material material, int amount)` | Creates a new stack with the given amount |
| `ItemBuilder.create(Material material, int amount, short damage)` | Creates a new stack with amount and damage value |

ItemStack item = ItemBuilder.create(Material.DIAMOND_SWORD)
All `Material` parameters default to `STONE` if null.

```java
ItemBuilder.create(Material.DIAMOND_SWORD)
.name("&bLegendary Sword")
.lore("&7Line 1", "&7Line 2")
.amount(1)
.durability((short) 100)
.lore("&7A powerful weapon")
.enchant(Enchantment.DAMAGE_ALL, 5)
.enchant(Enchantment.FIRE_ASPECT, 2)
.flags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_ATTRIBUTES)
.flags(ItemFlag.HIDE_ATTRIBUTES)
.unbreakable(true)
.glow(true) // Adds enchantment glow without visible enchants
.glow(true)
.get();
```

## Player Heads
## Builder methods

### General

| Method | Parameters | Description |
|---|---|---|
| `name(String)` | Display name (color codes auto-applied) | Sets the display name |
| `amount(int)` | Stack size | Sets the stack amount |
| `durability(short)` | Durability value | Sets the item durability |
| `lore(String...)` | Lore lines (color codes auto-applied) | Replaces lore; each string is one line |
| `lore(List<String>)` | Lore lines | Same as above, from a list |
| `addLore(String)` | Single line | Appends one line to existing lore |
| `clearLore()` | | Removes all lore |
| `enchant(Enchantment, int)` | Enchantment, level | Adds a safe enchantment |
| `enchant(Enchantment, int, boolean)` | Enchantment, level, safe | Adds an enchantment; `safe=false` allows unsafe levels |
| `enchant(Map<Enchantment, Integer>)` | Enchantment map | Adds all enchantments from the map |
| `unenchant(Enchantment)` | Enchantment to remove | Removes a specific enchantment |
| `clearEnchants()` | | Removes all enchantments |
| `flags(ItemFlag...)` | Flags to add | Adds item flags |
| `clearFlags()` | | Removes all item flags |
| `unbreakable(boolean)` | true/false | Sets unbreakable state |
| `glow(boolean)` | true/false | Adds Unbreaking I + `HIDE_ENCHANTS` for a visual glow effect |
| `modelData(Integer)` | Custom model data (1.14+, ignored on older versions) | Sets custom model data for resource packs |

### Item-specific

| Method | Parameters | Description |
|---|---|---|
| `skullOwner(String)` | Player name | Sets skull owner by name (player heads only) |
| `skullOwner(UUID)` | Player UUID | Sets skull owner by UUID (player heads only) |
| `skullTexture(String)` | Base64-encoded texture | Sets a custom skull texture (player heads only) |
| `armorColor(Color)` | Bukkit `Color` | Sets leather armor color (leather armor only) |

### Utilities

| Method | Returns | Description |
|---|---|---|
| `get()` | `ItemStack` | Returns the built item stack |
| `copy()` | `ItemBuilder` | Returns a new builder sharing the same `ItemStack` reference (not a deep clone) |

## Player heads

```java
// Player head by name
ItemStack head = ItemBuilder.create(Material.PLAYER_HEAD)
.skullOwner(player.getName())
.name("&e" + player.getName())
ItemBuilder.create(Material.PLAYER_HEAD)
.skullOwner("Notch")
.name("&eNotch's Head")
.get();

// Player head by UUID
ItemStack head2 = ItemBuilder.create(Material.PLAYER_HEAD)
ItemBuilder.create(Material.PLAYER_HEAD)
.skullOwner(player.getUniqueId())
.name("&e" + player.getName())
.get();

// Custom texture (base64)
ItemStack customHead = ItemBuilder.create(Material.PLAYER_HEAD)
.skullTexture("texture_base64_here")
ItemBuilder.create(Material.PLAYER_HEAD)
.skullTexture("eyJ0ZXh0dXJlcyI6ey...")
.name("&6Custom Head")
.get();
```

## Clone and Modify Existing Item
## Modifying an existing item

`create(ItemStack)` clones the input, so the original is not modified.

```java
ItemStack existing = player.getInventory().getItemInMainHand();
ItemStack modified = ItemBuilder.create(existing)
.name("&aModified Item")
.lore("&7Added lore")
.addLore("&7New line")
.get();
```

## Lore Management
## Leather armor color

```java
ItemBuilder builder = ItemBuilder.create(Material.DIAMOND)
.name("&bDiamond");

// Set lore
builder.lore("&7Line 1", "&7Line 2");

// Add to lore
builder.addLore("&7Additional line");

// Clear lore
builder.clearLore();

ItemStack item = builder.get();
```

## Enchantments

```java
ItemBuilder.create(Material.DIAMOND_SWORD)
.enchant(Enchantment.DAMAGE_ALL, 5)
.enchant(Enchantment.FIRE_ASPECT, 2)
.enchant(Enchantment.KNOCKBACK, 2)
ItemBuilder.create(Material.LEATHER_CHESTPLATE)
.name("&cRed Armor")
.armorColor(Color.RED)
.get();

// Remove enchantment
builder.unenchant(Enchantment.DAMAGE_ALL);

// Clear all enchantments
builder.clearEnchants();
```

## Item Flags
## Custom model data

```java
// Add multiple flags at once
ItemBuilder.create(Material.DIAMOND_SWORD)
.flags(
ItemFlag.HIDE_ENCHANTS,
ItemFlag.HIDE_ATTRIBUTES,
ItemFlag.HIDE_UNBREAKABLE
)
.get();
```

## Custom Model Data
Requires Minecraft 1.14+. On older versions, the call is silently ignored.

```java
ItemBuilder.create(Material.STICK)
.modelData(1) // For custom resource packs
.modelData(1)
.get();
```

## Glow Effect
## Glow effect

`glow(true)` adds Unbreaking I and the `HIDE_ENCHANTS` flag. No need to add the flag separately. Best used for GUI items where the enchantment is purely visual.

```java
// Add glow without visible enchants
ItemBuilder.create(Material.DIAMOND)
.glow(true)
.flags(ItemFlag.HIDE_ENCHANTS)
.get();
```

## Leather Armor Color

```java
ItemBuilder.create(Material.LEATHER_CHESTPLATE)
.name("&cRed Armor")
.armorColor(Color.RED)
.get();
```

## Complete Example

```java
public class ItemFactory {

public static ItemStack createSword(int level) {
return ItemBuilder.create(Material.DIAMOND_SWORD)
.name("&b&lLegendary Sword &7(Level " + level + ")")
.lore(
"&7A powerful weapon forged by",
"&7ancient blacksmiths.",
"",
"&eStats:",
"&7▸ Damage: &c+" + (10 * level),
"&7▸ Attack Speed: &a+15%",
"",
"&6&lLEGENDARY"
)
.enchant(Enchantment.DAMAGE_ALL, level)
.enchant(Enchantment.FIRE_ASPECT, 2)
.enchant(Enchantment.KNOCKBACK, 1)
.flags(ItemFlag.HIDE_ATTRIBUTES)
.unbreakable(true)
.glow(true)
.get();
}

public static ItemStack createArmor(Player player) {
return ItemBuilder.create(Material.DIAMOND_CHESTPLATE)
.name("&b" + player.getName() + "'s Armor")
.lore(
"&7Soulbound to " + player.getName(),
"&7Cannot be traded or dropped"
)
.enchant(Enchantment.PROTECTION_ENVIRONMENTAL, 4)
.enchant(Enchantment.DURABILITY, 3)
.flags(ItemFlag.HIDE_ENCHANTS)
.unbreakable(true)
.get();
}

public static ItemStack createToken(int amount) {
return ItemBuilder.create(Material.SUNFLOWER)
.name("&6&lServer Token")
.lore(
"&7A valuable currency",
"&7Amount: &e" + amount
)
.amount(amount)
.glow(true)
.flags(ItemFlag.HIDE_ENCHANTS)
.get();
}

public static ItemStack createMenuButton(String name, Material icon) {
return ItemBuilder.create(icon)
.name(name)
.lore("&eClick to select")
.get();
}
}

// Usage
Events.subscribe(PlayerJoinEvent.class)
.handler(e -> {
Player player = e.getPlayer();
player.getInventory().addItem(
ItemFactory.createSword(1),
ItemFactory.createArmor(player),
ItemFactory.createToken(10)
);
})
.bindWith(this);
```

## Comparison: Traditional vs ItemBuilder
## Static material utilities

### Traditional
These methods parse a material string (using XMaterial for cross-version support) into an `ItemStack` with no meta:

```java
ItemStack item = new ItemStack(Material.DIAMOND_SWORD);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColor.BLUE + "Legendary Sword");
List<String> lore = new ArrayList<>();
lore.add(ChatColor.GRAY + "A powerful weapon");
meta.setLore(lore);
meta.addEnchant(Enchantment.DAMAGE_ALL, 5, true);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
meta.setUnbreakable(true);
item.setItemMeta(meta);
```

### ItemBuilder

```java
ItemStack item = ItemBuilder.create(Material.DIAMOND_SWORD)
.name("&bLegendary Sword")
.lore("&7A powerful weapon")
.enchant(Enchantment.DAMAGE_ALL, 5)
.flags(ItemFlag.HIDE_ENCHANTS)
.unbreakable(true)
.get();
```
| Method | Returns | On invalid input |
|---|---|---|
| `getMaterialSafe(String)` | `Optional<ItemStack>` | Returns empty optional |
| `getMaterial(String)` | `ItemStack` | Logs error, returns `STONE` |
| `getMaterialOrDef(String, ItemStack)` | `ItemStack` | Returns the provided default |

## Cross-Version Compatibility
## Cross-version compatibility

PluginBase uses [XSeries](https://github.com/cryptomorin/xseries) for cross-version compatibility. To learn more about cross-version materials (`XMaterial`), refer to XSeries' documentation.
PluginBase uses [XSeries](https://github.com/cryptomorin/xseries) for cross-version material and enchantment support. Refer to XSeries documentation for `XMaterial` mappings.
Loading
Loading