Skip to content

Commit

Permalink
updated CustomItem registry to use 100% nbt and not display names
Browse files Browse the repository at this point in the history
  • Loading branch information
ItziSpyder committed Jul 7, 2024
1 parent a7def5f commit fe325f1
Show file tree
Hide file tree
Showing 9 changed files with 483 additions and 121 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

# PDK
pdk_version= 1.3.5
pdk_version= 1.3.6

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.github.itzispyder.pdk.events.CustomListener;
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
import io.github.itzispyder.pdk.plugin.items.CustomItem;
import io.github.itzispyder.pdk.plugin.items.ItemManager;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
Expand All @@ -29,7 +30,9 @@ private void onClose(InventoryCloseEvent e) {
@EventHandler
private void onInteract(PlayerInteractEvent e) {
try {
CustomItem.handleInteraction(e);
CustomItem context = ItemManager.getItemContext(e.getItem(), CustomItem.class);
if (context != null)
context.onInteract(e);
}
catch (Exception ignore) {}
}
Expand Down
93 changes: 40 additions & 53 deletions src/main/java/io/github/itzispyder/pdk/plugin/items/CustomItem.java
Original file line number Diff line number Diff line change
@@ -1,62 +1,51 @@
package io.github.itzispyder.pdk.plugin.items;

import io.github.itzispyder.pdk.utils.misc.Voidable;
import org.bukkit.entity.Player;
import org.bukkit.event.block.Action;
import com.google.gson.Gson;
import io.github.itzispyder.pdk.Global;
import io.github.itzispyder.pdk.plugin.builders.ItemBuilder;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;

public interface CustomItem {
public abstract class CustomItem implements Global {

Map<Class<? extends CustomItem>, CustomItem> items = new HashMap<>();
Map<String, CustomItem> registry = new HashMap<>();
public abstract void createItem(ItemBuilder item);

ItemStack getItem();
void onInteract(Player player, Action action, ItemStack item, PlayerInteractEvent event);
public abstract void updateMeta(ItemMeta meta);

default ItemStack register() {
return register(this);
}

default String getName() {
String[] name = {"unnamed-custom-item"};
Voidable.of(this.getClass().getAnnotation(ItemRegistry.class)).accept(registry -> name[0] = registry.value());
return name[0];
}

static Map<String, CustomItem> getRegistry() {
return new HashMap<>(registry);
}

static boolean matchDisplay(ItemStack a, ItemStack b) {
return getDisplay(a).equals(getDisplay(b));
}

static boolean matchDisplay(String a, ItemStack b) {
return a.equals(getDisplay(b));
}
public abstract void onInteract(PlayerInteractEvent e);

static boolean matchDisplay(ItemStack a, String b) {
return getDisplay(a).equals(b);
public String serialize() {
try {
Gson gson = new Gson();
return gson.toJson(this);
}
catch (Exception ex) {
return "{}";
}
}

static <T extends CustomItem> T getItemByClass(Class<T> key) {
return (T)items.get(key);
public String getRegistryKey() {
ItemRegistry r = this.getClass().getAnnotation(ItemRegistry.class);
if (r == null)
throw new IllegalArgumentException("Custom items need to have @ItemRegistry annotation!");
return r.value();
}

static CustomItem getItemByName(String itemId) {
for (CustomItem value : registry.values()) {
if (value.getName().equalsIgnoreCase(itemId)) {
return value;
}
public void register(Object... initArgs) {
try {
Class<?>[] signature = Arrays.stream(initArgs).map(Object::getClass).toArray(Class<?>[]::new);
CustomItem item = this.getClass().getDeclaredConstructor(signature).newInstance(initArgs);
ItemManager.registerItem(getRegistryKey(), () -> item);
}
catch (Exception ex) {
throw new RuntimeException("Failed to register custom item: " + ex.getMessage());
}
return null;
}

static String getDisplay(ItemStack item) {
public static String getDisplay(ItemStack item) {
if (item == null) {
return "";
}
Expand All @@ -68,17 +57,15 @@ else if (item.hasItemMeta() && item.getItemMeta() != null && item.getItemMeta().
}
}

static void handleInteraction(PlayerInteractEvent event) {
String display = getDisplay(event.getItem());
if (registry.containsKey(display)) {
registry.get(display).onInteract(event.getPlayer(), event.getAction(), event.getItem(), event);
}
public static boolean matchDisplay(ItemStack a, ItemStack b) {
return getDisplay(a).equals(getDisplay(b));
}

private static ItemStack register(CustomItem customItem) {
ItemStack item = customItem.getItem();
items.put(customItem.getClass(), customItem);
registry.put(getDisplay(item), customItem);
return item;
public static boolean matchDisplay(String a, ItemStack b) {
return a.equals(getDisplay(b));
}

public static boolean matchDisplay(ItemStack a, String b) {
return getDisplay(a).equals(b);
}
}
}
131 changes: 131 additions & 0 deletions src/main/java/io/github/itzispyder/pdk/plugin/items/ItemManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package io.github.itzispyder.pdk.plugin.items;

import com.google.gson.Gson;
import io.github.itzispyder.pdk.Global;
import io.github.itzispyder.pdk.plugin.builders.ItemBuilder;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

public class ItemManager {

private static final Gson gson = new Gson();
private static final Map<NamespacedKey, Supplier<CustomItem>> itemRegistry = new HashMap<>();

public static NamespacedKey registerItem(String namespace, Supplier<CustomItem> context) {
NamespacedKey key = new NamespacedKey(Global.instance.getPlugin(), "items/" + namespace);
itemRegistry.put(key, context);
return key;
}

public static ItemStack createItemContext(NamespacedKey key) {
Supplier<CustomItem> registry = itemRegistry.get(key);
if (registry == null)
throw new IllegalArgumentException("context not found in item registry");

CustomItem context = registry.get();
ItemBuilder builder = ItemBuilder.create();
context.createItem(builder);

ItemStack result = builder.build();
if (result == null || !result.hasItemMeta())
throw new IllegalArgumentException("the result item cannot be used as a custom item");

ItemMeta meta = result.getItemMeta();
PersistentDataContainer data = meta.getPersistentDataContainer();

data.set(key, PersistentDataType.STRING, gson.toJson(context));
context.updateMeta(meta);
result.setItemMeta(meta);

return result;
}

public static void setItemContext(ItemStack item, CustomItem context) {
if (item == null || !item.hasItemMeta())
return;

ItemMeta meta = item.getItemMeta();
PersistentDataContainer data = meta.getPersistentDataContainer();

for (NamespacedKey key : data.getKeys()) {
Supplier<CustomItem> contextSupplier = itemRegistry.get(key);
if (contextSupplier == null)
continue;

CustomItem customItem = contextSupplier.get();
if (customItem != null && customItem.getClass() == context.getClass()) {
data.set(key, PersistentDataType.STRING, gson.toJson(context));
context.updateMeta(meta);
item.setItemMeta(meta);
return;
}
}
}

@SuppressWarnings({ "unchecked", "unused" })
public static <C extends CustomItem> C getItemContext(ItemStack item, Class<C> type) {
if (item == null || !item.hasItemMeta())
return null;

ItemMeta meta = item.getItemMeta();
PersistentDataContainer data = meta.getPersistentDataContainer();

for (NamespacedKey key : data.getKeys()) {
Supplier<CustomItem> contextSupplier = itemRegistry.get(key);
if (contextSupplier == null)
continue;

CustomItem customItem = contextSupplier.get();
if (customItem != null) {
CustomItem parsed = gson.fromJson(data.get(key, PersistentDataType.STRING), customItem.getClass());
if (parsed != null)
return (C)parsed;
}
}

return null;
}

public static CustomItem getItemContext(ItemStack item) {
return getItemContext(item, CustomItem.class);
}

public static boolean isHolding(Player player, NamespacedKey item) {
ItemStack stack = player.getInventory().getItemInMainHand();
return isItemMatching(item, stack);
}

public static boolean isOffHolding(Player player, NamespacedKey item) {
ItemStack stack = player.getInventory().getItemInOffHand();
return isItemMatching(item, stack);
}

public static boolean isHoldingAny(Player player, NamespacedKey item) {
return isHolding(player, item) || isOffHolding(player, item);
}

public static boolean isItemMatching(NamespacedKey key, ItemStack item) {
if (item == null || !item.hasItemMeta())
return false;

ItemMeta meta = item.getItemMeta();
PersistentDataContainer data = meta.getPersistentDataContainer();
return data.has(key);
}

public static String[] collectNames() {
String[] str = new String[itemRegistry.size()];
int i = 0;
for (NamespacedKey key : itemRegistry.keySet())
str[i++] = key.getKey().replaceFirst("items/", "");
return str;
}
}
8 changes: 8 additions & 0 deletions src/main/java/io/github/itzispyder/pdk/utils/MathUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ public static double clamp(double val, double min, double max) {
return Math.min(max, Math.max(min, val));
}

public static double clamp(double val) {
return clamp(val, 0, 1);
}

public static float clamp(float val) {
return (float) clamp(val, 0, 1);
}

public static float[] toPolar(double x, double y, double z) {
double pi2 = 2 * Math.PI;
float pitch, yaw;
Expand Down
Loading

0 comments on commit fe325f1

Please sign in to comment.