Skip to content

Commit

Permalink
Refactors CustomItemStack to not extend ItemStack (#275)
Browse files Browse the repository at this point in the history
  • Loading branch information
md5sha256 authored Oct 25, 2024
1 parent 35144c2 commit 7d5738e
Show file tree
Hide file tree
Showing 8 changed files with 897 additions and 95 deletions.
Original file line number Diff line number Diff line change
@@ -1,121 +1,68 @@
package io.github.bakedlibs.dough.items;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;

public class CustomItemStack extends ItemStack {

public CustomItemStack(ItemStack item) {
super(item);
}

public CustomItemStack(Material type) {
super(type);
}

public CustomItemStack(ItemStack item, Consumer<ItemMeta> meta) {
super(item);
ItemMeta im = getItemMeta();
meta.accept(im);
setItemMeta(im);
}
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
import java.util.function.Consumer;

public CustomItemStack(Material type, Consumer<ItemMeta> meta) {
this(new ItemStack(type), meta);
@ParametersAreNonnullByDefault
public final class CustomItemStack {

private CustomItemStack() {
throw new IllegalStateException("Cannot instantiate CustomItemStack");
}

public CustomItemStack(ItemStack item, String name, String... lore) {
this(item, im -> {
if (name != null) {
im.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
}

if (lore.length > 0) {
List<String> lines = new ArrayList<>();

for (String line : lore) {
lines.add(ChatColor.translateAlternateColorCodes('&', line));
}
im.setLore(lines);
}
});
public static ItemStack create(ItemStack itemStack, Consumer<ItemMeta> metaConsumer) {
return new ItemStackEditor(itemStack).andMetaConsumer(metaConsumer).create();
}

public CustomItemStack(ItemStack item, Color color, String name, String... lore) {
this(item, im -> {
if (name != null) {
im.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
}

if (lore.length > 0) {
List<String> lines = new ArrayList<>();

for (String line : lore) {
lines.add(ChatColor.translateAlternateColorCodes('&', line));
}
im.setLore(lines);
}

if (im instanceof LeatherArmorMeta) {
((LeatherArmorMeta) im).setColor(color);
}
if (im instanceof PotionMeta) {
((PotionMeta) im).setColor(color);
}
});
public static ItemStack create(Material material, Consumer<ItemMeta> metaConsumer) {
return new ItemStackEditor(material).andMetaConsumer(metaConsumer).create();
}

public CustomItemStack addFlags(ItemFlag... flags) {
ItemMeta im = getItemMeta();
im.addItemFlags(flags);
setItemMeta(im);

return this;
public static ItemStack create(ItemStack item, @Nullable String name, String... lore) {
return new ItemStackEditor(item)
.setDisplayName(name)
.setLore(lore)
.create();
}

public CustomItemStack setCustomModel(int data) {
ItemMeta im = getItemMeta();
im.setCustomModelData(data == 0 ? null : data);
setItemMeta(im);

return this;
public static ItemStack create(Material material, @Nullable String name, String... lore) {
return create(new ItemStack(material), name, lore);
}

public CustomItemStack(Material type, String name, String... lore) {
this(new ItemStack(type), name, lore);
public static ItemStack create(Material type, @Nullable String name, List<String> lore) {
return create(new ItemStack(type), name, lore.toArray(String[]::new));
}

public CustomItemStack(Material type, String name, List<String> lore) {
this(new ItemStack(type), name, lore.toArray(new String[lore.size()]));
}

public CustomItemStack(ItemStack item, List<String> list) {
this(item, list.get(0), list.subList(1, list.size()).toArray(new String[0]));
public static ItemStack create(ItemStack item, List<String> list) {
return create(new ItemStack(item), list.get(0), list.subList(1, list.size()).toArray(String[]::new));
}

public CustomItemStack(Material type, List<String> list) {
this(new ItemStack(type), list);
public static ItemStack create(Material type, List<String> list) {
return create(new ItemStack(type), list);
}

public CustomItemStack(ItemStack item, int amount) {
super(item);
setAmount(amount);
public static ItemStack create(ItemStack item, int amount) {
return new ItemStackEditor(item).setAmount(amount).create();
}

public CustomItemStack(ItemStack item, Material type) {
super(item);
setType(type);
/**
* Clones the item stack and sets its type
*
* @param itemStack The item
* @param type The new type
* @return Returns the item with a new type
* @deprecated Setting the type via {@link ItemStack#setType(Material)} will not be supported soon.
*/
@Deprecated(forRemoval = true)
public static ItemStack create(ItemStack itemStack, Material type) {
return new ItemStackEditor(itemStack).andStackConsumer(item -> item.setType(type)).create();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package io.github.bakedlibs.dough.items;

import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;

import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

/**
* Fluent class to apply edits/transformations to an {@link ItemStack} and it's {@link ItemMeta} instance
* <p>
* This class is immutable.
* The {@link ItemStack} instance which this class holds on to is never mutated.
*
* @see #create()
* @see #applyTo(ItemStack)
*/
@ParametersAreNonnullByDefault
public class ItemStackEditor {

private final ItemStack itemStack;
private final Consumer<ItemMeta> metaTransform;
private final Consumer<ItemStack> stackTransform;

private ItemStackEditor(ItemStack itemStack,
@Nullable Consumer<ItemMeta> metaTransform,
@Nullable Consumer<ItemStack> stackTransform) {
this.itemStack = itemStack;
this.metaTransform = metaTransform;
this.stackTransform = stackTransform;
}

public ItemStackEditor(ItemStack item) {
this(item.clone(), null, null);
}

public ItemStackEditor(Material type) {
this(new ItemStack(type));
}

public ItemStackEditor addFlags(ItemFlag... flags) {
return andMetaConsumer(ItemStackUtil.appendItemFlags(flags));
}

public ItemStackEditor setCustomModel(int data) {
return andMetaConsumer(ItemStackUtil.editCustomModelData(data));
}

public ItemStackEditor setCustomModel(@Nullable Integer data) {
return andMetaConsumer(ItemStackUtil.editCustomModelData(data));
}

public ItemStackEditor setAmount(int amount) {
return andStackConsumer(stack -> stack.setAmount(amount));
}

public ItemStackEditor setColor(Color color) {
return andMetaConsumer(meta -> {
if (meta instanceof LeatherArmorMeta) {
((LeatherArmorMeta) meta).setColor(color);
}
if (meta instanceof PotionMeta) {
((PotionMeta) meta).setColor(color);
}
});
}

public ItemStackEditor setLore(String... lore) {
return setLore(Arrays.asList(lore));
}

public ItemStackEditor setLore(List<String> list) {
return andMetaConsumer(ItemStackUtil.editLore(list));
}

public ItemStackEditor setDisplayName(@Nullable String name) {
return andMetaConsumer(ItemStackUtil.editDisplayName(name));
}

public ItemStackEditor andMetaConsumer(Consumer<ItemMeta> consumer) {
if (this.metaTransform == null) {
return withMetaConsumer(consumer);
}
return withMetaConsumer(this.metaTransform.andThen(consumer));
}

public ItemStackEditor withMetaConsumer(@Nullable Consumer<ItemMeta> consumer) {
return new ItemStackEditor(this.itemStack, consumer, this.stackTransform);
}

public ItemStackEditor withStackConsumer(@Nullable Consumer<ItemStack> consumer) {
return new ItemStackEditor(this.itemStack, this.metaTransform, consumer);
}

public ItemStackEditor andStackConsumer(Consumer<ItemStack> consumer) {
if (this.stackTransform == null) {
return withStackConsumer(consumer);
}
return withStackConsumer(this.stackTransform.andThen(consumer));
}

public ItemStack create() {
ItemStack cloned = this.itemStack.clone();
applyTo(cloned);
return cloned;
}

public void applyTo(ItemStack itemStack) {
if (this.stackTransform != null) {
this.stackTransform.accept(itemStack);
}
if (this.metaTransform != null) {
ItemStackUtil.editMeta(itemStack, this.metaTransform);
}
}

}
Loading

0 comments on commit 7d5738e

Please sign in to comment.