diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2f7896d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+target/
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..d51ac91
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,51 @@
+
+ 4.0.0
+
+ com.zivilon
+ ItemEffects
+ 1.0
+ jar
+
+ CraftBukkitTemplate
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+ org.bukkit
+ bukkit
+ 1.7.10-R0.1-SNAPSHOT
+ provided
+
+
+ com.github.flinbein
+ PowerNBT
+ 0.8.9.2
+
+
+
+
+ package
+
+
+ src/main/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+ 1.8
+ 1.8
+
+
+
+
+
diff --git a/src/main/java/com/zivilon/itemeffects/Aura.java b/src/main/java/com/zivilon/itemeffects/Aura.java
new file mode 100644
index 0000000..59bc06d
--- /dev/null
+++ b/src/main/java/com/zivilon/itemeffects/Aura.java
@@ -0,0 +1,53 @@
+package com.zivilon.itemeffects;
+
+import org.bukkit.entity.Player;
+import org.bukkit.potion.PotionEffect;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public class Aura {
+ private final Player owner;
+ private final List effectSets;
+
+ public Aura(Player owner) {
+ this.owner = owner;
+ this.effectSets = new ArrayList<>();
+ }
+
+ public void addEffectSet(PotionEffect effect, double radius) {
+ this.effectSets.add(new AuraEffectSet(effect, radius));
+ }
+
+ public void addEffectSets(List effects, double radius) {
+ for (PotionEffect effect : effects) {
+ this.effectSets.add(new AuraEffectSet(effect, radius));
+ }
+ }
+
+ public Player getOwner() {
+ return owner;
+ }
+
+ public List getEffectSets() {
+ return effectSets;
+ }
+
+ public static class AuraEffectSet {
+ private final PotionEffect effect;
+ private final double radius;
+
+ public AuraEffectSet(PotionEffect effect, double radius) {
+ this.effect = effect;
+ this.radius = radius;
+ }
+
+ public PotionEffect getEffect() {
+ return effect;
+ }
+
+ public double getRadius() {
+ return radius;
+ }
+ }
+}
diff --git a/src/main/java/com/zivilon/itemeffects/AuraEffect.java b/src/main/java/com/zivilon/itemeffects/AuraEffect.java
new file mode 100644
index 0000000..2f6edbc
--- /dev/null
+++ b/src/main/java/com/zivilon/itemeffects/AuraEffect.java
@@ -0,0 +1,21 @@
+package com.zivilon.itemeffects;
+
+import org.bukkit.potion.PotionEffect;
+
+public class AuraEffect {
+ private PotionEffect effect;
+ private int radius;
+
+ public AuraEffect(PotionEffect effect, int radius) {
+ this.effect = effect;
+ this.radius = radius;
+ }
+
+ public PotionEffect getEffect() {
+ return effect;
+ }
+
+ public int getRadius() {
+ return radius;
+ }
+}
diff --git a/src/main/java/com/zivilon/itemeffects/AuraManager.java b/src/main/java/com/zivilon/itemeffects/AuraManager.java
new file mode 100644
index 0000000..661a35b
--- /dev/null
+++ b/src/main/java/com/zivilon/itemeffects/AuraManager.java
@@ -0,0 +1,130 @@
+package com.zivilon.itemeffects;
+
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitTask;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.UUID;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+import com.zivilon.itemeffects.ItemEffects;
+
+public class AuraManager {
+
+ private final ItemEffects plugin;
+ private final Map runningAuras = new HashMap<>();
+ private Map> originalEffects = new HashMap<>();
+
+
+ public AuraManager(ItemEffects plugin) {
+ this.plugin = plugin;
+ }
+
+ // Please don't break, this thing was a hell to set up and I don't want to ever look at it again
+
+ public void startAuraTask(Aura aura) {
+ // Cancel the old task if it exists
+ BukkitTask oldTask = null;
+ if (runningAuras.containsKey(aura.getOwner().getUniqueId())) {
+ oldTask = runningAuras.get(aura.getOwner().getUniqueId()).getTask();
+ }
+ if (oldTask != null) {
+ oldTask.cancel();
+ }
+
+ // Start a new repeating task
+ BukkitTask newTask = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
+ World world = aura.getOwner().getWorld();
+
+ for (Aura.AuraEffectSet effectSet : aura.getEffectSets()) {
+ for (Player nearbyPlayer : world.getPlayers()) {
+ if (nearbyPlayer.equals(aura.getOwner())) continue; // Skip the aura owner
+
+ double distance = nearbyPlayer.getLocation().distance(aura.getOwner().getLocation());
+ // Check player distance within the task
+ if (distance <= effectSet.getRadius()) {
+
+ // 1. If player already has an effect of the same type and it's not ambient
+ if (nearbyPlayer.hasPotionEffect(effectSet.getEffect().getType()) && !getPotionEffectOfType(nearbyPlayer, effectSet.getEffect().getType()).isAmbient()) {
+ originalEffects.put(nearbyPlayer.getUniqueId(), new ArrayList<>(Collections.singletonList(getPotionEffectOfType(nearbyPlayer, effectSet.getEffect().getType()))));
+ }
+
+ // 2. Remove any existing conflicting effects
+ nearbyPlayer.removePotionEffect(effectSet.getEffect().getType());
+
+ // 3. Apply the aura effect
+ nearbyPlayer.addPotionEffect(effectSet.getEffect());
+
+ }
+ }
+ }
+ }, 0L, 40L); // Run every 2 seconds (40 ticks)
+
+ // Store the new task in our map
+ runningAuras.put(aura.getOwner().getUniqueId(), new PlayerAuraTask(aura, newTask));
+}
+ private PotionEffect getPotionEffectOfType(Player player, PotionEffectType type) {
+ for (PotionEffect effect : player.getActivePotionEffects()) {
+ if (effect.getType().equals(type)) {
+ return effect;
+ }
+ }
+ return null;
+ }
+
+ public void stopAuraTask(Player player) {
+ PlayerAuraTask auraTask = runningAuras.remove(player.getUniqueId());
+
+ if (auraTask == null) {
+ return;
+ }
+
+ BukkitTask task = auraTask.getTask();
+ if (task != null) {
+ task.cancel();
+ }
+
+ // Immediately restore original effects to the aura owner
+ if (originalEffects.containsKey(player.getUniqueId())) {
+ List storedEffects = originalEffects.remove(player.getUniqueId());
+ for (PotionEffect effect : storedEffects) {
+ player.addPotionEffect(effect, true);
+ }
+ }
+
+ // Restore effects to all players affected by this aura
+ restoreEffectsOnAuraEnd(auraTask.getAura());
+ }
+ public void restoreEffectsOnAuraEnd(Aura aura) {
+ // Iterate over all players in the aura's world
+ for (Player player : aura.getOwner().getWorld().getPlayers()) {
+
+ // Check if we stored any original effects for the player
+ if (originalEffects.containsKey(player.getUniqueId())) {
+
+ List storedEffects = originalEffects.get(player.getUniqueId()); // Just get the effects without removing them
+
+ if(storedEffects != null) {
+ // Iterate over each of the effect sets in the aura
+ for (Aura.AuraEffectSet effectSet : aura.getEffectSets()) {
+
+ for (PotionEffect effect : storedEffects) {
+ player.removePotionEffect(effect.getType()); // Remove the current effect
+ player.addPotionEffect(effect, true); // Apply the stored effect
+ }
+ }
+ originalEffects.remove(player.getUniqueId()); // Now remove it after processing all effect sets
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/zivilon/itemeffects/ItemEffects.java b/src/main/java/com/zivilon/itemeffects/ItemEffects.java
new file mode 100644
index 0000000..4cf6103
--- /dev/null
+++ b/src/main/java/com/zivilon/itemeffects/ItemEffects.java
@@ -0,0 +1,34 @@
+package com.zivilon.itemeffects;
+
+import org.bukkit.plugin.java.JavaPlugin;
+
+import me.dpohvar.powernbt.api.NBTCompound;
+import me.dpohvar.powernbt.api.NBTManager;
+import me.dpohvar.powernbt.api.NBTList;
+import me.dpohvar.powernbt.PowerNBT;
+
+import com.zivilon.itemeffects.AuraManager;
+import com.zivilon.itemeffects.commands.itemeffect_command;
+import com.zivilon.itemeffects.listeners.itemeffect_listener;
+
+
+public class ItemEffects extends JavaPlugin {
+ public static final NBTManager nbtManager = PowerNBT.getApi();
+ private AuraManager auraManager;
+
+ @Override
+ public void onEnable() {
+ auraManager = new AuraManager(this);
+ this.getServer().getPluginManager().registerEvents(new itemeffect_listener(this), this);
+ this.getCommand("itemeffect").setExecutor(new itemeffect_command(this));
+ getLogger().info("ItemEffects enabled!");
+ }
+
+ @Override
+ public void onDisable() {
+ getLogger().info("ItemEffects disabled!");
+ }
+ public AuraManager getAuraManager() {
+ return auraManager;
+ }
+}
diff --git a/src/main/java/com/zivilon/itemeffects/PlayerAuraTask.java b/src/main/java/com/zivilon/itemeffects/PlayerAuraTask.java
new file mode 100644
index 0000000..9c05183
--- /dev/null
+++ b/src/main/java/com/zivilon/itemeffects/PlayerAuraTask.java
@@ -0,0 +1,22 @@
+package com.zivilon.itemeffects;
+
+import org.bukkit.scheduler.BukkitTask;
+import com.zivilon.itemeffects.Aura;
+
+public class PlayerAuraTask {
+ private final Aura aura;
+ private final BukkitTask task;
+
+ public PlayerAuraTask(Aura aura, BukkitTask task) {
+ this.aura = aura;
+ this.task = task;
+ }
+
+ public Aura getAura() {
+ return aura;
+ }
+
+ public BukkitTask getTask() {
+ return task;
+ }
+}
diff --git a/src/main/java/com/zivilon/itemeffects/commands/itemeffect_command.java b/src/main/java/com/zivilon/itemeffects/commands/itemeffect_command.java
new file mode 100644
index 0000000..6103193
--- /dev/null
+++ b/src/main/java/com/zivilon/itemeffects/commands/itemeffect_command.java
@@ -0,0 +1,223 @@
+package com.zivilon.itemeffects.commands;
+
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.potion.PotionEffectType;
+
+import me.dpohvar.powernbt.api.NBTCompound;
+import me.dpohvar.powernbt.api.NBTManager;
+import me.dpohvar.powernbt.api.NBTList;
+import me.dpohvar.powernbt.PowerNBT;
+
+import java.util.Arrays;
+
+import com.zivilon.itemeffects.ItemEffects;
+
+public class itemeffect_command implements CommandExecutor {
+ private final ItemEffects plugin;
+
+ public itemeffect_command(ItemEffects plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
+ if (cmd.getName().equalsIgnoreCase("itemeffect")) {
+ if (!sender.hasPermission("admin")) {
+ sender.sendMessage(ChatColor.RED + "You do not have permission to use this command.");
+ return true;
+ }
+
+ if (!(sender instanceof Player)) {
+ sender.sendMessage("This command can only be used by players.");
+ return true;
+ }
+ Player player = (Player) sender;
+
+ if (args.length < 1) {
+ sender.sendMessage("Invalid usage. Correct usage: /itemeffect ");
+ return true;
+ }
+
+ String subcommand = args[0].toLowerCase();
+
+ switch (subcommand) {
+ case "add":
+ if (args.length < 4) {
+ player.sendMessage("Usage: /itemeffect add ");
+ return true;
+ }
+
+ String type = args[1].toUpperCase();
+ String effect = args[2].toUpperCase();
+ int level;
+ try {
+ level = Integer.parseInt(args[3]);
+ } catch (NumberFormatException e) {
+ player.sendMessage("Invalid level. Please enter a number.");
+ return true;
+ }
+ Integer radius = null; // We use Integer to allow for null checks
+ if (type.equals("HELD_AURA") || type.equals("INVENTORY_AURA") || type.equals("WORN_AURA")) {
+ if (args.length < 5) {
+ player.sendMessage("Aura type effects require a radius. Usage: /itemeffect add ");
+ return true;
+ }
+ try {
+ radius = Integer.parseInt(args[4]);
+ } catch (NumberFormatException e) {
+ player.sendMessage("Invalid radius. Please enter a number.");
+ return true;
+ }
+ }
+ if (!isValidType(type)) {
+ player.sendMessage("Invalid type. Valid types are: HELD, WORN, INVENTORY.");
+ return true;
+ }
+
+ if (!isValidEffect(effect)) {
+ player.sendMessage("Invalid effect. Provide a valid potion effect.");
+ return true;
+ }
+
+ ItemStack item = player.getInventory().getItemInHand();
+
+ addEffectToItem(item, type, effect, level, radius);
+ player.sendMessage("Effect added to item!");
+ break;
+ case "addaura":
+ // Not sure why this is here, regular add should work.
+ // Will remove later once I work out why this is here in the first place
+ break;
+ case "remove":
+ if (args.length < 3) {
+ player.sendMessage("Usage: /itemeffect remove ");
+ return true;
+ }
+
+ String typeToRemove = args[1].toUpperCase();
+ String effectToRemove = args[2].toUpperCase();
+
+ if (removeEffectFromItem(player.getInventory().getItemInHand(), typeToRemove, effectToRemove)) {
+ player.sendMessage("Effect removed from item!");
+ } else {
+ player.sendMessage("Specified effect not found on item.");
+ }
+ break;
+ case "removeaura":
+ // Not sure why this is here, regular remove should work.
+ // Will remove later once I work out why this is here in the first place
+ break;
+ case "list":
+ listEffectsOnItem(player.getInventory().getItemInHand(), player);
+ break;
+
+ default:
+ sender.sendMessage("Unknown subcommand. Correct usage: /itemeffect ");
+ break;
+ }
+ }
+ return true;
+ }
+ private boolean isValidType(String type) {
+ return Arrays.asList("HELD", "WORN", "INVENTORY", "HELD_AURA", "WORN_AURA", "INVENTORY_AURA").contains(type);
+ }
+
+ private boolean isValidEffect(String effect) {
+ if (effect == null || effect.isEmpty()) {
+ return false;
+ }
+
+ PotionEffectType potionType = PotionEffectType.getByName(effect.toUpperCase());
+ return potionType != null;
+ }
+
+
+ private void addEffectToItem(ItemStack item, String type, String effect, int level, Integer radius) {
+ // Fetch current item's NBT data
+ NBTCompound itemData = plugin.nbtManager.read(item);
+ NBTCompound newEffect = new NBTCompound();
+
+ if (radius != null) {
+ newEffect.put("radius", radius.intValue());
+ }
+
+ // Get the "ItemEffects" list from the NBT data, or create one if it doesn't exist
+ NBTList itemEffects = itemData.getList("ItemEffects");
+ if (itemEffects == null) {
+ itemEffects = new NBTList();
+ itemData.put("ItemEffects", itemEffects);
+
+ plugin.nbtManager.write(item, itemData);
+
+ itemData = plugin.nbtManager.read(item);
+ itemEffects = itemData.getList("ItemEffects");
+ }
+
+ boolean effectFound = false;
+ for (Object obj : itemEffects) {
+ if (obj instanceof NBTCompound) {
+ NBTCompound currentEffect = (NBTCompound) obj;
+ String currentType = currentEffect.getString("type");
+ String currentEffectName = currentEffect.getString("effect");
+ if (type.equals(currentType) && effect.equals(currentEffectName)) {
+ // Found the existing effect. Overwrite its attributes.
+ currentEffect.put("level", level);
+ effectFound = true;
+ break;
+ }
+ }
+ }
+
+ if (!effectFound) {
+ newEffect.put("type", type);
+ newEffect.put("effect", effect);
+ newEffect.put("level", level);
+ itemEffects.add(newEffect);
+ }
+
+ plugin.nbtManager.write(item, itemData);
+ }
+ private boolean removeEffectFromItem(ItemStack item, String type, String effect) {
+ NBTCompound itemData = plugin.nbtManager.read(item);
+ NBTList itemEffects = itemData.getList("ItemEffects");
+ if (itemEffects == null) return false;
+
+ for (Object obj : itemEffects) {
+ if (obj instanceof NBTCompound) {
+ NBTCompound currentEffect = (NBTCompound) obj;
+ String currentType = currentEffect.getString("type");
+ String currentEffectName = currentEffect.getString("effect");
+ if (type.equals(currentType) && effect.equals(currentEffectName)) {
+ itemEffects.remove(currentEffect);
+ plugin.nbtManager.write(item, itemData);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ private void listEffectsOnItem(ItemStack item, Player player) {
+ NBTCompound itemData = plugin.nbtManager.read(item);
+ NBTList itemEffects = itemData.getList("ItemEffects");
+ if (itemEffects == null || itemEffects.isEmpty()) {
+ player.sendMessage("No effects found on this item.");
+ return;
+ }
+
+ player.sendMessage(ChatColor.GOLD + "Item Effects:");
+ for (Object obj : itemEffects) {
+ if (obj instanceof NBTCompound) {
+ NBTCompound currentEffect = (NBTCompound) obj;
+ String currentType = currentEffect.getString("type");
+ String currentEffectName = currentEffect.getString("effect");
+ int currentLevel = currentEffect.getInt("level");
+ player.sendMessage(ChatColor.YELLOW + "- Type: " + currentType + ", Effect: " + currentEffectName + ", Level: " + currentLevel);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/zivilon/itemeffects/listeners/itemeffect_listener.java b/src/main/java/com/zivilon/itemeffects/listeners/itemeffect_listener.java
new file mode 100644
index 0000000..61dce17
--- /dev/null
+++ b/src/main/java/com/zivilon/itemeffects/listeners/itemeffect_listener.java
@@ -0,0 +1,289 @@
+package com.zivilon.itemeffects.listeners;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerItemHeldEvent;
+import org.bukkit.event.player.PlayerRespawnEvent;
+import org.bukkit.event.player.PlayerPickupItemEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+
+import me.dpohvar.powernbt.api.NBTCompound;
+import me.dpohvar.powernbt.api.NBTManager;
+import me.dpohvar.powernbt.api.NBTList;
+import me.dpohvar.powernbt.PowerNBT;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.UUID;
+import java.util.Iterator;
+
+import com.zivilon.itemeffects.ItemEffects;
+import com.zivilon.itemeffects.Aura;
+import com.zivilon.itemeffects.AuraEffect;
+
+public class itemeffect_listener implements Listener {
+ private final ItemEffects plugin;
+ private Map> overwrittenEffects = new HashMap<>();
+ private List auraEffectsList = new ArrayList<>();
+ private boolean debug = false;
+
+
+ public itemeffect_listener(ItemEffects plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler
+ public void onPlayerItemHeld(PlayerItemHeldEvent event) {
+ Player player = event.getPlayer();
+ ItemStack newItem = player.getInventory().getItem(event.getNewSlot());
+
+ checkAndApplyEffects(player, newItem);
+ }
+
+
+ @EventHandler
+ public void onPlayerJoin(PlayerJoinEvent event) {
+ Player player = event.getPlayer();
+ ItemStack heldItem = player.getItemInHand();
+ checkAndApplyEffects(player, heldItem);
+ }
+
+ @EventHandler
+ public void onPlayerRespawn(PlayerRespawnEvent event) {
+ Player player = event.getPlayer();
+ ItemStack heldItem = player.getItemInHand();
+ checkAndApplyEffects(player, heldItem);
+ }
+
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent event) {
+ if (event.getPlayer() instanceof Player) {
+ Player player = (Player) event.getPlayer();
+ ItemStack heldItem = player.getItemInHand();
+ checkAndApplyEffects(player, heldItem);
+ }
+ }
+
+ @EventHandler
+ public void onItemPickup(PlayerPickupItemEvent event) {
+ Bukkit.getScheduler().runTaskLater(plugin, () -> {
+ Player player = event.getPlayer();
+ ItemStack heldItem = player.getItemInHand();
+ checkAndApplyEffects(player, heldItem);
+ }, 1L);
+ }
+
+ private void checkAndApplyEffects(Player player, ItemStack helditem) {
+ List currentEffectsList = new ArrayList<>();
+ List newEffectsList = new ArrayList<>();
+ List auraEffectsList = new ArrayList<>();
+ saveCustomEffects(currentEffectsList, player);
+ plugin.getAuraManager().stopAuraTask(player);
+ auraEffectsList.clear();
+
+ // Scan the player's inventory
+ List allItems = new ArrayList<>();
+ allItems.addAll(Arrays.asList(player.getInventory().getContents()));
+ allItems.addAll(Arrays.asList(player.getInventory().getArmorContents()));
+
+ for (ItemStack item : allItems) {
+ if (item != null && item.getType() != Material.AIR) {
+ // Check for NBT data and apply effects accordingly
+ NBTCompound itemData = null;
+ try {
+ itemData = plugin.nbtManager.read(item);
+ } catch (Exception e) {
+ e.printStackTrace();
+ continue;
+ }
+
+ if (itemData == null) {
+ continue; // Skip to the next iteration if there's no NBT data
+ }
+
+ NBTList itemEffects = itemData.getList("ItemEffects");
+ if (itemEffects != null) {
+ for (Object effectObj : itemEffects) {
+ if (effectObj instanceof NBTCompound) {
+ NBTCompound effect = (NBTCompound) effectObj;
+ // Apply the effect based on its data
+ applyEffect(newEffectsList, player, effect, item, helditem, auraEffectsList);
+ }
+ }
+ }
+ }
+ }
+ if (debug) System.out.println("New effects:");
+ if (debug) for (PotionEffect effect : player.getActivePotionEffects()) {
+ System.out.println("- " + effect.getType().getName());
+ }
+
+ // Remove unwanted effects
+ if (debug) System.out.println("Current effects:");
+ for (PotionEffect currentEffect : currentEffectsList) {
+ if (!containsEffect(newEffectsList, currentEffect)) {
+ if (debug) System.out.println("Effect " + currentEffect.getType().getName() + " not found in new effects list, removing...");
+ player.removePotionEffect(currentEffect.getType());
+ }
+ }
+
+ // Add new effects
+ for (PotionEffect newEffect : newEffectsList) {
+ boolean effectFound = false;
+ for (PotionEffect activeEffect : player.getActivePotionEffects()) {
+ if (activeEffect.getType().equals(newEffect.getType())) {
+ effectFound = true;
+ if (activeEffect.getAmplifier() < newEffect.getAmplifier()) {
+ player.addPotionEffect(newEffect, true);
+ }
+ break;
+ }
+ }
+ if (!effectFound) {
+ player.addPotionEffect(newEffect, true);
+ }
+ }
+
+
+ createAndStartAura(player, auraEffectsList);
+ // After scanning inventory and applying all effects, restore saved non-ambient effects if needed
+ List storedEffects = overwrittenEffects.get(player.getUniqueId());
+ if (storedEffects != null) {
+ Iterator iterator = storedEffects.iterator();
+ while (iterator.hasNext()) {
+ PotionEffect storedEffect = iterator.next();
+ if (!hasActiveEffect(player, storedEffect.getType())) {
+ // The effect was removed, so restore it
+ player.addPotionEffect(storedEffect);
+ iterator.remove();
+ }
+ }
+ // If there are no more stored effects for this player, remove the player's entry from the map
+ if (storedEffects.isEmpty()) {
+ overwrittenEffects.remove(player.getUniqueId());
+ }
+ }
+
+ }
+
+ private boolean containsEffect(List list, PotionEffect effect) {
+ for (PotionEffect listEffect : list) {
+ if (listEffect.getType().equals(effect.getType())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean hasActiveEffect(Player player, PotionEffectType effectType) {
+ for (PotionEffect effect : player.getActivePotionEffects()) {
+ if (effect.getType().equals(effectType)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void saveCustomEffects(List effects, Player player) {
+ for (PotionEffect effect : player.getActivePotionEffects()) {
+ // Check if the effect is ambient
+ if (effect.isAmbient()) {
+ effects.add(effect);
+ }
+ }
+ }
+ private void applyEffect(List effects, Player player, NBTCompound effect, ItemStack item, ItemStack helditem, List auraEffectsList) {
+ String type = effect.getString("type");
+ String potionEffectType = effect.getString("effect");
+ int level = effect.getInt("level");
+ int radius;
+ if (effect.get("radius") != null) {
+ radius = effect.getInt("radius");
+ } else {
+ radius = 10;
+ }
+ PotionEffectType potionType = PotionEffectType.getByName(potionEffectType);
+
+ if (potionType == null) {
+ return;
+ }
+
+ AuraEffect auraEffect = new AuraEffect(new PotionEffect(potionType, 200, level - 1, true), radius);
+
+ // Check if the item type and its inventory position match
+ if (type.equals("HELD")) {
+ if (helditem == null || !helditem.equals(item)) {
+ return;
+ }
+ storeOverwrittenEffect(player, potionType);
+ effects.add(new PotionEffect(potionType, Integer.MAX_VALUE, level - 1, true));
+ }
+ if (type.equals("INVENTORY")) {
+ storeOverwrittenEffect(player, potionType);
+ effects.add(new PotionEffect(potionType, Integer.MAX_VALUE, level - 1, true));
+ }
+ if (type.equals("WORN")) {
+ ItemStack[] armor = player.getInventory().getArmorContents();
+ boolean isWearing = Arrays.asList(armor).contains(item);
+
+ if (!isWearing) {
+ return;
+ }
+ storeOverwrittenEffect(player, potionType);
+ effects.add(new PotionEffect(potionType, Integer.MAX_VALUE, level - 1, true));
+ }
+
+ if (type.equals("HELD_AURA")) {
+ if (helditem == null || !helditem.equals(item)) {
+ return;
+ }
+ auraEffectsList.add(auraEffect);
+ }
+ else if (type.equals("INVENTORY_AURA")) {
+ auraEffectsList.add(auraEffect);
+ }
+ else if (type.equals("WORN_AURA")) {
+ ItemStack[] armor = player.getInventory().getArmorContents();
+ boolean isWearing = Arrays.asList(armor).contains(item);
+ if (!isWearing) {
+ return;
+ }
+ auraEffectsList.add(auraEffect);
+ }
+ }
+ private void storeOverwrittenEffect(Player player, PotionEffectType potionType) {
+ for (PotionEffect effect : player.getActivePotionEffects()) {
+ if (effect.getType().equals(potionType) && !effect.isAmbient() && effect.getDuration() < 720000) {
+ // Store this effect
+ overwrittenEffects.computeIfAbsent(player.getUniqueId(), k -> new ArrayList<>()).add(effect);
+ return;
+ }
+ }
+ }
+
+ private void createAndStartAura(Player player, List auraEffectsList) {
+ if (auraEffectsList == null || auraEffectsList.isEmpty()) {
+ return; // No aura effects to apply
+ }
+
+ // Create a new Aura for the player
+ Aura aura = new Aura(player);
+
+ for (AuraEffect auraEffect : auraEffectsList) {
+ aura.addEffectSet(auraEffect.getEffect(), auraEffect.getRadius());
+ }
+
+ plugin.getAuraManager().startAuraTask(aura);
+ }
+}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
new file mode 100644
index 0000000..cd22f2e
--- /dev/null
+++ b/src/main/resources/plugin.yml
@@ -0,0 +1,10 @@
+main: com.zivilon.itemeffects.ItemEffects
+name: ItemEffects
+author: Shinare
+version: 1.0
+commands:
+ itemeffect:
+ description: Manage custom item effects
+ usage: /itemeffect
+load: startup
+depend: [PowerNBT]
\ No newline at end of file