Skip to content

Commit

Permalink
Implement custom item support
Browse files Browse the repository at this point in the history
Adds support for use of custom items in BattleArena.
  • Loading branch information
Redned235 committed Jan 6, 2025
1 parent be664e9 commit 8331b95
Show file tree
Hide file tree
Showing 17 changed files with 377 additions and 16 deletions.
17 changes: 17 additions & 0 deletions module/items-integration/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
repositories {
maven("https://repo.oraxen.com/releases")
maven("https://repo.codemc.io/repository/maven-public/")
maven("https://jitpack.io")
maven("https://mvn.lumine.io/repository/maven-public/") {
metadataSources {
artifact()
}
}
}

dependencies {
compileOnly("io.th0rgal:oraxen:1.173.0")
compileOnly("me.zombie_striker:QualityArmory:2.0.17")
compileOnly("com.github.LoneDev6:api-itemsadder:3.6.1")
compileOnly("io.lumine:Mythic-Dist:5.6.1")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.battleplugins.arena.module.items;

import org.battleplugins.arena.event.BattleArenaPostInitializeEvent;
import org.battleplugins.arena.feature.items.Items;
import org.battleplugins.arena.module.ArenaModule;
import org.battleplugins.arena.module.ArenaModuleInitializer;
import org.battleplugins.arena.module.items.itemsadder.ItemsAdderFeature;
import org.battleplugins.arena.module.items.mythiccrucible.MythicCrucibleFeature;
import org.battleplugins.arena.module.items.oraxen.OraxenFeature;
import org.battleplugins.arena.module.items.qualityarmory.QualityArmoryFeature;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;

/**
* A module that allows for hooking into various item provider plugins.
*/
@ArenaModule(id = ItemsIntegration.ID, priority = 100, name = "Items", description = "Adds support for hooking into various item provider plugins.", authors = "BattlePlugins")
public class ItemsIntegration implements ArenaModuleInitializer {
public static final String ID = "items";

@EventHandler(priority = EventPriority.LOWEST) // Load before all other modules listening on this event
public void onPostInitialize(BattleArenaPostInitializeEvent event) {
if (Bukkit.getPluginManager().isPluginEnabled("QualityArmory")) {
Items.register(new QualityArmoryFeature());

event.getBattleArena().info("QualityArmory found. Registering item integration.");
}

if (Bukkit.getPluginManager().isPluginEnabled("Oraxen")) {
Items.register(new OraxenFeature());

event.getBattleArena().info("Oraxen found. Registering item integration.");
}

if (Bukkit.getPluginManager().isPluginEnabled("ItemsAdder")) {
Items.register(new ItemsAdderFeature());

event.getBattleArena().info("ItemsAdder found. Registering item integration.");
}

if (Bukkit.getPluginManager().isPluginEnabled("MythicCrucible")) {
Items.register(new MythicCrucibleFeature());

event.getBattleArena().info("MythicCrucible found. Registering item integration.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.battleplugins.arena.module.items.itemsadder;

import dev.lone.itemsadder.api.CustomStack;
import org.battleplugins.arena.feature.PluginFeature;
import org.battleplugins.arena.feature.items.ItemsFeature;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;

public class ItemsAdderFeature extends PluginFeature<ItemsFeature> implements ItemsFeature {

public ItemsAdderFeature() {
super("ItemsAdder");
}

@Override
public ItemStack createItem(NamespacedKey key) {
CustomStack customStack = CustomStack.getInstance(key.value());
return customStack == null ? null : customStack.getItemStack();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.battleplugins.arena.module.items.mythiccrucible;

import io.lumine.mythic.bukkit.BukkitAdapter;
import io.lumine.mythic.bukkit.MythicBukkit;
import org.battleplugins.arena.feature.PluginFeature;
import org.battleplugins.arena.feature.items.ItemsFeature;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;

public class MythicCrucibleFeature extends PluginFeature<ItemsFeature> implements ItemsFeature {

public MythicCrucibleFeature() {
super("MythicCrucible");
}

@Override
public ItemStack createItem(NamespacedKey key) {
return MythicBukkit.inst().getItemManager().getItem(key.value())
.map(item -> BukkitAdapter.adapt(item.generateItemStack(1)))
.orElse(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.battleplugins.arena.module.items.oraxen;

import io.th0rgal.oraxen.api.OraxenItems;
import io.th0rgal.oraxen.items.ItemBuilder;
import org.battleplugins.arena.feature.PluginFeature;
import org.battleplugins.arena.feature.items.ItemsFeature;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;

public class OraxenFeature extends PluginFeature<ItemsFeature> implements ItemsFeature {

public OraxenFeature() {
super("Oraxen");
}

@Override
public ItemStack createItem(NamespacedKey key) {
return OraxenItems.getOptionalItemById(key.value())
.map(ItemBuilder::build)
.orElse(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.battleplugins.arena.module.items.qualityarmory;

import me.zombie_striker.qg.api.QualityArmory;
import org.battleplugins.arena.feature.PluginFeature;
import org.battleplugins.arena.feature.items.ItemsFeature;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;

public class QualityArmoryFeature extends PluginFeature<ItemsFeature> implements ItemsFeature {

public QualityArmoryFeature() {
super("QualityArmory");
}

@Override
public ItemStack createItem(NamespacedKey key) {
return QualityArmory.getCustomItemAsItemStack(key.value());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.battleplugins.arena.feature.items.Items;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
Expand All @@ -15,12 +16,14 @@
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.function.BiConsumer;

@DocumentationSource("https://docs.battleplugins.org/books/user-guide/page/item-syntax")
public final class ItemStackParser implements ArenaConfigParser.Parser<ItemStack> {
Expand All @@ -43,8 +46,6 @@ public ItemStack parse(Object object) throws ParseException {
}

public static ItemStack deserializeSingular(String contents) throws ParseException {
ItemStack itemStack;

SingularValueParser.ArgumentBuffer buffer;
try {
buffer = SingularValueParser.parseNamed(contents, SingularValueParser.BraceStyle.CURLY, ';');
Expand All @@ -67,21 +68,32 @@ public static ItemStack deserializeSingular(String contents) throws ParseExcepti

SingularValueParser.Argument root = buffer.pop();
if (root.key().equals("root")) {
Material material = Material.matchMaterial(root.value());
if (material == null) {
throw new ParseException("Invalid material " + root.value())
.cause(ParseException.Cause.INVALID_VALUE)
.type(ItemStackParser.class)
.userError();
}

itemStack = new ItemStack(material);
return Items.createItem(NamespacedKey.fromString(root.value()), buffer);
} else {
throw new ParseException("Invalid ItemStack root tag " + root.key())
.cause(ParseException.Cause.INTERNAL_ERROR)
.type(ItemStackParser.class);
}
}

public static ItemStack deserializeSingularVanilla(NamespacedKey itemType, SingularValueParser.ArgumentBuffer buffer) throws ParseException {
Material material = Material.matchMaterial(itemType.toString());
if (material == null) {
throw new ParseException("Invalid material " + itemType)
.cause(ParseException.Cause.INVALID_VALUE)
.type(ItemStackParser.class)
.userError();
}

ItemStack itemStack = new ItemStack(material);
return applyItemProperties(itemStack, buffer);
}

public static ItemStack applyItemProperties(ItemStack itemStack, SingularValueParser.ArgumentBuffer buffer) throws ParseException {
return applyItemProperties(itemStack, buffer, null);
}

public static ItemStack applyItemProperties(ItemStack itemStack, SingularValueParser.ArgumentBuffer buffer, @Nullable BiConsumer<ItemMeta, SingularValueParser.Argument> unknownArgumentConsumer) throws ParseException {
ItemMeta itemMeta = itemStack.getItemMeta();
while (buffer.hasNext()) {
SingularValueParser.Argument argument = buffer.pop();
Expand Down Expand Up @@ -151,6 +163,12 @@ public static ItemStack deserializeSingular(String contents) throws ParseExcepti
potionMeta.addCustomEffect(potionEffect, true);
}
}

default -> {
if (unknownArgumentConsumer != null) {
unknownArgumentConsumer.accept(itemMeta, argument);
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ private static <T extends FeatureInstance> T getBestFeature(Class<T> clazz) {
}

@SuppressWarnings("unchecked")
private static <T extends FeatureInstance> List<T> getFeatures(Class<T> clazz) {
protected static <T extends FeatureInstance> List<T> getFeatures(Class<T> clazz) {
return (List<T>) FEATURES.getOrDefault(clazz, List.of());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,13 @@ public PluginFeature(Plugin plugin) {
public boolean isEnabled() {
return this.plugin.isEnabled();
}

/**
* Gets the plugin that this feature is implemented by.
*
* @return the plugin that this feature is implemented by
*/
public Plugin getPlugin() {
return this.plugin;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* API for holograms used in BattleArena.
*/
@ApiStatus.Experimental
public class Holograms extends FeatureController<HologramFeature> {
public final class Holograms extends FeatureController<HologramFeature> {
private static HologramFeature instance;

/**
Expand Down Expand Up @@ -42,6 +42,11 @@ public static void removeHologram(Hologram hologram) {
}
}

/**
* Gets the instance of the {@link HologramFeature}.
*
* @return the instance of the {@link HologramFeature}
*/
@Nullable
private static HologramFeature instance() {
if (instance == null) {
Expand All @@ -51,6 +56,11 @@ private static HologramFeature instance() {
return instance;
}

/**
* Registers a {@link HologramFeature} to the feature controller.
*
* @param feature the feature to register
*/
public static void register(HologramFeature feature) {
registerFeature(HologramFeature.class, feature);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.battleplugins.arena.feature.items;

import org.battleplugins.arena.config.SingularValueParser;
import org.battleplugins.arena.feature.FeatureController;
import org.battleplugins.arena.feature.PluginFeature;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;

import java.util.List;
import java.util.Locale;

/**
* API for items used in BattleArena.
* <p>
* This API serves as a service provider to allow for
* accessing and creating items from Minecraft as well
* as third parties.
*/
@ApiStatus.Experimental
public final class Items extends FeatureController<PluginFeature<ItemsFeature>> {

/**
* Creates an {@link ItemStack} from the given key and arguments.
*
* @param key the key of the item
* @param arguments the arguments to create the item with
* @return the created item
*/
public static ItemStack createItem(NamespacedKey key, SingularValueParser.ArgumentBuffer arguments) {
return getFeature(key).createItem(key, arguments);
}

/**
* Registers a {@link ItemsFeature} to the feature controller.
*
* @param feature the feature to register
*/
public static <T extends PluginFeature<ItemsFeature> & ItemsFeature> void register(T feature) {
registerFeature(ItemsFeature.class, feature);
}

@SuppressWarnings({ "rawtypes", "unchecked" })
private static <T extends PluginFeature<ItemsFeature> & ItemsFeature> ItemsFeature getFeature(NamespacedKey key) {
// Fast-track vanilla
if (key.getNamespace().equals(NamespacedKey.MINECRAFT)) {
return VanillaItemsFeature.INSTANCE;
}

List<T> features = (List) getFeatures(ItemsFeature.class);
for (T feature : features) {
if (!feature.isEnabled()) {
continue;
}

String pluginNamespace = feature.getPlugin().getName().toLowerCase(Locale.ROOT);
if (key.getNamespace().equals(pluginNamespace)) {
return feature;
}
}

return VanillaItemsFeature.INSTANCE;
}
}
Loading

0 comments on commit 8331b95

Please sign in to comment.