Parcourir la source

Migration to the official API

Jan il y a 1 mois
Parent
commit
61e86dff7c
93 fichiers modifiés avec 885 ajouts et 1611 suppressions
  1. 28 1
      pom.xml
  2. 0 36
      src/main/java/me/lethunderhawk/bazaarflux/service/Services.java
  3. 0 66
      src/main/java/me/lethunderhawk/bazaarflux/util/CustomHeadCreator.java
  4. 0 12
      src/main/java/me/lethunderhawk/bazaarflux/util/MessageSender.java
  5. 0 53
      src/main/java/me/lethunderhawk/bazaarflux/util/animation/Animation.java
  6. 0 71
      src/main/java/me/lethunderhawk/bazaarflux/util/command/CommandNode.java
  7. 0 141
      src/main/java/me/lethunderhawk/bazaarflux/util/command/CustomCommand.java
  8. 0 46
      src/main/java/me/lethunderhawk/bazaarflux/util/gui/ConfirmationMenu.java
  9. 0 28
      src/main/java/me/lethunderhawk/bazaarflux/util/gui/GoBackItem.java
  10. 0 152
      src/main/java/me/lethunderhawk/bazaarflux/util/gui/InventoryGUI.java
  11. 0 115
      src/main/java/me/lethunderhawk/bazaarflux/util/gui/InventoryManager.java
  12. 0 55
      src/main/java/me/lethunderhawk/bazaarflux/util/gui/PlayerHeadListGUI.java
  13. 0 137
      src/main/java/me/lethunderhawk/bazaarflux/util/gui/input/SignMenuFactory.java
  14. 0 27
      src/main/java/me/lethunderhawk/bazaarflux/util/interfaces/BazaarFluxModule.java
  15. 0 254
      src/main/java/me/lethunderhawk/bazaarflux/util/itemdesign/LoreDesigner.java
  16. 0 25
      src/main/java/me/lethunderhawk/bazaarflux/util/lang/RomanNumbers.java
  17. 0 142
      src/main/java/me/lethunderhawk/bazaarflux/util/loottables/RiggedChanceGenerator.java
  18. 2 2
      src/main/java/me/lethunderhawk/clans/Clan.java
  19. 11 9
      src/main/java/me/lethunderhawk/clans/ClanModule.java
  20. 2 2
      src/main/java/me/lethunderhawk/clans/claim/Claim.java
  21. 3 3
      src/main/java/me/lethunderhawk/clans/claim/ClaimListener.java
  22. 3 3
      src/main/java/me/lethunderhawk/clans/claim/ClaimManager.java
  23. 9 9
      src/main/java/me/lethunderhawk/clans/command/ClanCommand.java
  24. 8 8
      src/main/java/me/lethunderhawk/clans/gui/AdminMenuGUI.java
  25. 7 7
      src/main/java/me/lethunderhawk/clans/gui/ClaimSettingsGUI.java
  26. 2 2
      src/main/java/me/lethunderhawk/clans/gui/ClanMenu.java
  27. 2 2
      src/main/java/me/lethunderhawk/clans/gui/ClanSettingsGUI.java
  28. 1 1
      src/main/java/me/lethunderhawk/clans/gui/MemberListGUI.java
  29. 2 2
      src/main/java/me/lethunderhawk/clans/placeholder/ClanPlaceHolder.java
  30. 2 2
      src/main/java/me/lethunderhawk/clans/settings/ClanSettings.java
  31. 2 2
      src/main/java/me/lethunderhawk/custom/block/registry/BlockRegistry.java
  32. 15 12
      src/main/java/me/lethunderhawk/custom/item/CustomItemModule.java
  33. 1 1
      src/main/java/me/lethunderhawk/custom/item/abstraction/ability/AbilityDefinition.java
  34. 4 4
      src/main/java/me/lethunderhawk/custom/item/abstraction/definition/ItemDefinitionLoader.java
  35. 1 1
      src/main/java/me/lethunderhawk/custom/item/abstraction/definition/ItemVisualDefinition.java
  36. 0 3
      src/main/java/me/lethunderhawk/custom/item/abstraction/instance/ItemInstanceReader.java
  37. 2 2
      src/main/java/me/lethunderhawk/custom/item/abstraction/instance/ItemPersistentData.java
  38. 2 2
      src/main/java/me/lethunderhawk/custom/item/abstraction/migration/MigrationService.java
  39. 2 2
      src/main/java/me/lethunderhawk/custom/item/abstraction/registry/CustomItemRegistry.java
  40. 2 2
      src/main/java/me/lethunderhawk/custom/item/abstraction/visual/ItemRenderer.java
  41. 4 4
      src/main/java/me/lethunderhawk/custom/item/command/CustomItemCommand.java
  42. 5 5
      src/main/java/me/lethunderhawk/custom/item/concrete/ability/ClaimToolAbility.java
  43. 2 2
      src/main/java/me/lethunderhawk/custom/item/concrete/ability/RegeneratingBlockAbility.java
  44. 4 4
      src/main/java/me/lethunderhawk/custom/item/concrete/ability/RollingDiceAbility.java
  45. 2 2
      src/main/java/me/lethunderhawk/custom/item/concrete/dice/RollingDiceAnimation.java
  46. 11 6
      src/main/java/me/lethunderhawk/dungeon/DungeonModule.java
  47. 8 8
      src/main/java/me/lethunderhawk/dungeon/command/DungeonCommand.java
  48. 7 7
      src/main/java/me/lethunderhawk/dungeon/generation/DungeonGridGenerator.java
  49. 3 3
      src/main/java/me/lethunderhawk/dungeon/generation/DungeonWorld.java
  50. 1 1
      src/main/java/me/lethunderhawk/dungeon/gui/DungeonGUI.java
  51. 2 0
      src/main/java/me/lethunderhawk/dungeon/placement/RoomMetadata.java
  52. 1 0
      src/main/java/me/lethunderhawk/dungeon/placement/RotatableBoundingBox.java
  53. 2 0
      src/main/java/me/lethunderhawk/dungeon/placement/SchematicRoomPlacer.java
  54. 0 3
      src/main/java/me/lethunderhawk/dungeon/placement/Vector3i.java
  55. 6 4
      src/main/java/me/lethunderhawk/economy/EconomyModule.java
  56. 2 2
      src/main/java/me/lethunderhawk/economy/command/EcoCommand.java
  57. 2 2
      src/main/java/me/lethunderhawk/economy/currency/EconomyManager.java
  58. 8 7
      src/main/java/me/lethunderhawk/main/Main.java
  59. 0 36
      src/main/java/me/lethunderhawk/main/util/UnItalic.java
  60. 7 4
      src/main/java/me/lethunderhawk/minion/MinionModule.java
  61. 2 2
      src/main/java/me/lethunderhawk/minion/api/MinionLevel.java
  62. 3 3
      src/main/java/me/lethunderhawk/minion/command/MinionCommand.java
  63. 3 3
      src/main/java/me/lethunderhawk/minion/enchantedVariant/item/abstraction/EnchantedItem.java
  64. 2 2
      src/main/java/me/lethunderhawk/minion/enchantedVariant/recipe/EnchantedItemRecipe.java
  65. 3 4
      src/main/java/me/lethunderhawk/minion/impl/behavior/CobbleMinionBehavior.java
  66. 1 2
      src/main/java/me/lethunderhawk/minion/impl/behavior/RedstoneMinionBehavior.java
  67. 5 5
      src/main/java/me/lethunderhawk/minion/item/MinionItem.java
  68. 1 1
      src/main/java/me/lethunderhawk/minion/listener/MinionListener.java
  69. 1 1
      src/main/java/me/lethunderhawk/minion/runtime/PlacedMinion.java
  70. 5 6
      src/main/java/me/lethunderhawk/minion/ui/MinionMenu.java
  71. 2 2
      src/main/java/me/lethunderhawk/minion/ui/minionList/MinionLevelListMenu.java
  72. 1 1
      src/main/java/me/lethunderhawk/minion/ui/minionList/MinionListMenu.java
  73. 4 2
      src/main/java/me/lethunderhawk/tradeplugin/TradeModule.java
  74. 2 2
      src/main/java/me/lethunderhawk/tradeplugin/command/TradeAcceptCommand.java
  75. 2 2
      src/main/java/me/lethunderhawk/tradeplugin/command/TradeCommand.java
  76. 2 2
      src/main/java/me/lethunderhawk/tradeplugin/input/player/NumberInputGUI.java
  77. 7 7
      src/main/java/me/lethunderhawk/tradeplugin/listener/TradeInventoryListener.java
  78. 2 2
      src/main/java/me/lethunderhawk/tradeplugin/trade/TradeInventory.java
  79. 8 8
      src/main/java/me/lethunderhawk/tradeplugin/trade/TradeRequestManager.java
  80. 9 9
      src/main/java/me/lethunderhawk/tradeplugin/trade/TradeSession.java
  81. 68 0
      src/main/java/me/lethunderhawk/world/WorldModule.java
  82. 92 0
      src/main/java/me/lethunderhawk/world/command/WorldCommand.java
  83. 48 0
      src/main/java/me/lethunderhawk/world/island/IslandBootstrapListener.java
  84. 73 0
      src/main/java/me/lethunderhawk/world/island/IslandWorld.java
  85. 84 0
      src/main/java/me/lethunderhawk/world/util/WorldManager.java
  86. 23 0
      src/main/java/me/lethunderhawk/world/util/WorldUtils.java
  87. 1 1
      src/main/java/me/lethunderhawk/world/util/schematic/Rotation.java
  88. 8 0
      src/main/java/me/lethunderhawk/world/util/schematic/SchematicMetadata.java
  89. 145 0
      src/main/java/me/lethunderhawk/world/util/schematic/SchematicPlacer.java
  90. 3 0
      src/main/java/me/lethunderhawk/world/util/schematic/Vector3i.java
  91. 69 0
      src/main/java/me/lethunderhawk/world/wrapper/CustomWorld.java
  92. BIN
      src/main/resources/island/default_island.schem
  93. 16 0
      src/main/resources/plugin.yml

+ 28 - 1
pom.xml

@@ -15,7 +15,6 @@
         <java.version>21</java.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
-
     <build>
         <plugins>
             <plugin>
@@ -58,6 +57,10 @@
             <id>papermc</id>
             <url>https://repo.papermc.io/repository/maven-public/</url>
         </repository>
+        <repository>
+            <id>enginehub-repo</id>
+            <url>https://maven.enginehub.org/repo/</url>
+        </repository>
         <repository>
             <id>sonatype</id>
             <url>https://oss.sonatype.org/content/groups/public/</url>
@@ -66,6 +69,11 @@
             <id>placeholderapi</id>
             <url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
         </repository>
+        <repository>
+            <id>fluxapi</id>
+            <name>Flux API</name>
+            <url>https://git.famrupp.de/jan/FluxAPI_v1/</url>
+        </repository>
     </repositories>
 
     <dependencies>
@@ -75,6 +83,13 @@
             <version>1.21.10-R0.1-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.spigotmc</groupId>
+            <artifactId>spigot</artifactId>
+            <version>1.21.10-R0.1-SNAPSHOT</version>
+            <classifier>remapped-mojang</classifier>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>me.clip</groupId>
             <artifactId>placeholderapi</artifactId>
@@ -86,5 +101,17 @@
             <artifactId>ProtocolLib</artifactId>
             <version>5.4.0</version>
         </dependency>
+        <dependency>
+            <groupId>com.sk89q.worldedit</groupId>
+            <artifactId>worldedit-bukkit</artifactId>
+            <version>7.4.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>me.lethunderhawk</groupId>
+            <artifactId>FluxAPI</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 </project>

+ 0 - 36
src/main/java/me/lethunderhawk/bazaarflux/service/Services.java

@@ -1,36 +0,0 @@
-package me.lethunderhawk.bazaarflux.service;
-
-import me.lethunderhawk.bazaarflux.util.interfaces.BazaarFluxModule;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-public final class Services {
-
-    private static final Map<Class<?>, Object> services = new ConcurrentHashMap<>();
-
-    public static <T> T register(Class<T> type, T service) {
-        services.put(type, service);
-        return service;
-    }
-    public static <T> void registerModule(Class<? extends BazaarFluxModule> type, T service) {
-        services.put(type, service);
-    }
-
-    @SuppressWarnings("unchecked")
-    public static <T> T get(Class<T> type) {
-        T service = (T) services.get(type);
-        if(service == null) {
-            throw new RuntimeException("No service registered for " + type);
-        }
-        return service;
-    }
-    @SuppressWarnings("unchecked")
-    public static <T> T unregister(Class<T> type) {
-        return (T) services.remove(type);
-    }
-
-    public static <T> void unregisterModule(Class<? extends BazaarFluxModule> type) {
-        services.remove(type);
-    }
-}

+ 0 - 66
src/main/java/me/lethunderhawk/bazaarflux/util/CustomHeadCreator.java

@@ -1,66 +0,0 @@
-package me.lethunderhawk.bazaarflux.util;
-
-import com.destroystokyo.paper.profile.PlayerProfile;
-import com.destroystokyo.paper.profile.ProfileProperty;
-import me.lethunderhawk.main.util.UnItalic;
-import net.kyori.adventure.text.Component;
-import org.bukkit.Bukkit;
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.SkullMeta;
-
-import java.util.List;
-import java.util.UUID;
-
-public class CustomHeadCreator {
-
-    public static ItemStack createCustomHead(String textureValue, Component displayName, Component loreText) {
-        ItemStack playerHead = createCustomHead(textureValue);
-        SkullMeta meta = (SkullMeta) playerHead.getItemMeta();
-
-        meta.displayName(displayName);
-        meta.lore(List.of(loreText));
-
-        playerHead.setItemMeta(meta);
-
-        return playerHead;
-    }
-    public static ItemStack createCustomHead(String textureValue, Component displayName, List<Component> loreText) {
-        ItemStack playerHead = createCustomHead(textureValue);
-        SkullMeta meta = (SkullMeta) playerHead.getItemMeta();
-
-        meta.displayName(displayName);
-        meta.lore(loreText);
-
-        playerHead.setItemMeta(meta);
-
-        return playerHead;
-    }
-    public static ItemStack createCustomHead(Player player, Component displayName, List<Component> loreText) {
-
-        ItemStack playerHead = new ItemStack(Material.PLAYER_HEAD);
-        SkullMeta meta = (SkullMeta) playerHead.getItemMeta();
-
-        meta.setOwningPlayer(player);
-        meta.displayName(displayName);
-        meta.lore(loreText);
-
-        playerHead.setItemMeta(UnItalic.removeItalicFromMeta(meta));
-        return playerHead;
-    }
-
-    public static ItemStack createCustomHead(String textureValue) {
-        ItemStack head = new ItemStack(Material.PLAYER_HEAD);
-        SkullMeta meta = (SkullMeta) head.getItemMeta();
-
-        if (meta != null) {
-            PlayerProfile profile = Bukkit.createProfile(UUID.randomUUID(), null);
-            profile.setProperty(new ProfileProperty("textures", textureValue));
-            meta.setPlayerProfile(profile);
-            head.setItemMeta(meta);
-        }
-
-        return head;
-    }
-}

+ 0 - 12
src/main/java/me/lethunderhawk/bazaarflux/util/MessageSender.java

@@ -1,12 +0,0 @@
-package me.lethunderhawk.bazaarflux.util;
-
-import net.kyori.adventure.audience.Audience;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
-
-public class MessageSender {
-    public static void sendText(Audience receiver, Component message, String prefix) {
-        receiver.sendMessage(Component.text(prefix + " ", NamedTextColor.GOLD)
-                .append(message));
-    }
-}

+ 0 - 53
src/main/java/me/lethunderhawk/bazaarflux/util/animation/Animation.java

@@ -1,53 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.animation;
-
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.main.Main;
-import org.bukkit.Bukkit;
-import org.bukkit.World;
-import org.bukkit.plugin.java.JavaPlugin;
-import org.bukkit.scheduler.BukkitTask;
-
-public abstract class Animation {
-
-    protected final JavaPlugin plugin;
-    protected final World world;
-    protected int tick = 0;
-    protected int duration;
-
-    private BukkitTask task;
-    private Runnable onComplete;
-
-    protected Animation(World world, int duration) {
-        this.plugin = Services.get(Main.class);
-        this.world = world;
-        this.duration = duration;
-    }
-
-    public final void start() {
-        onStart();
-        task = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
-            if (tick >= duration) {
-                stop(true);
-                return;
-            }
-            onTick(tick);
-            tick++;
-        }, 0L, 1L);
-    }
-
-    public final void stop(boolean completed) {
-        if (task != null) task.cancel();
-        onEnd();
-        if (completed && onComplete != null) {
-            onComplete.run();
-        }
-    }
-
-    public void onComplete(Runnable runnable) {
-        this.onComplete = runnable;
-    }
-
-    protected abstract void onStart();
-    protected abstract void onTick(int tick);
-    protected abstract void onEnd();
-}

+ 0 - 71
src/main/java/me/lethunderhawk/bazaarflux/util/command/CommandNode.java

@@ -1,71 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.command;
-
-import org.bukkit.command.CommandSender;
-
-import java.util.*;
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-
-public class CommandNode {
-    private final String name;
-    private final String description;
-    private BiConsumer<CommandSender, String[]> executor;
-    private BiFunction<CommandSender, String[], List<String>> tabCompleter;
-    private Map<String, CommandNode> subCommands = new HashMap<>();
-    private CommandNode parent;
-
-    public CommandNode(String name, String description, BiConsumer<CommandSender, String[]> executor) {
-        this.name = name;
-        this.description = description;
-        this.executor = executor;
-    }
-
-    public CommandNode registerSubCommand(String name, String description, BiConsumer<CommandSender, String[]> executor) {
-        CommandNode subCommand = new CommandNode(name, description, executor);
-        subCommand.parent = this;
-        subCommands.put(name.toLowerCase(), subCommand);
-        return subCommand;
-    }
-
-    public void addSubCommand(CommandNode subCommand) {
-        subCommand.parent = this;
-        subCommands.put(subCommand.getName().toLowerCase(), subCommand);
-    }
-    public void addSubCommands(CommandNode... subCommandNodes) {
-        for(CommandNode subCommand : subCommandNodes) {
-            subCommand.parent = this;
-            subCommands.put(subCommand.getName().toLowerCase(), subCommand);
-        }
-    }
-
-    public CommandNode getSubCommand(String name) {
-        return subCommands.get(name.toLowerCase());
-    }
-
-    public boolean hasSubCommand(String name) {
-        return subCommands.containsKey(name.toLowerCase());
-    }
-
-    public Collection<CommandNode> getSubCommands() {
-        return subCommands.values();
-    }
-
-    public List<String> getSubCommandNames() {
-        return new ArrayList<>(subCommands.keySet());
-    }
-
-    public void setTabCompleter(BiFunction<CommandSender, String[], List<String>> tabCompleter) {
-        this.tabCompleter = tabCompleter;
-    }
-
-    // Getters
-    public String getName() { return name; }
-    public String getDescription() { return description; }
-    public BiConsumer<CommandSender, String[]> getExecutor() { return executor; }
-    public BiFunction<CommandSender, String[], List<String>> getTabCompleter() { return tabCompleter; }
-    public CommandNode getParent() { return parent; }
-
-    public void setExecutor(BiConsumer<CommandSender, String[]> executor) {
-        this.executor = executor;
-    }
-}

+ 0 - 141
src/main/java/me/lethunderhawk/bazaarflux/util/command/CustomCommand.java

@@ -1,141 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.command;
-
-import me.lethunderhawk.bazaarflux.util.interfaces.BazaarFluxModule;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.command.TabCompleter;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.BiConsumer;
-import java.util.stream.Collectors;
-
-public abstract class CustomCommand implements CommandExecutor, TabCompleter {
-
-    protected final CommandNode rootCommand;
-    protected final BazaarFluxModule module;
-    public CustomCommand(CommandNode rootCommand, BazaarFluxModule module) {
-        this.rootCommand = rootCommand;
-        this.module = module;
-        createHelpCommand();
-        createCommands();
-    }
-
-    private void createHelpCommand() {
-        rootCommand.addSubCommand(new CommandNode("help", "Displays this help menu", this::sendHelp));
-    }
-
-    public abstract void createCommands();
-
-    @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (args.length == 0) {
-            sendHelp(sender);
-            return true;
-        }
-
-        List<String> argList = new ArrayList<>(Arrays.asList(args));
-        CommandNode currentNode = rootCommand;
-        CommandNode targetNode = null;
-
-        // Traverse the command tree
-        while (!argList.isEmpty()) {
-            String nextArg = argList.get(0);
-            CommandNode nextNode = currentNode.getSubCommand(nextArg);
-
-            if (nextNode == null) {
-                // No matching subcommand found, use current node if it has an executor
-                targetNode = currentNode.getExecutor() != null ? currentNode : null;
-                break;
-            }
-
-            currentNode = nextNode;
-            argList.remove(0);
-
-            // If this is the last argument or node has no further subcommands
-            if (argList.isEmpty() || nextNode.getSubCommands().isEmpty()) {
-                targetNode = nextNode;
-                break;
-            }
-        }
-
-        if (targetNode == null) {
-            module.sendText(sender, Component.text("Unknown command. Use /" +rootCommand.getName() +" help for available commands.", NamedTextColor.RED));
-            return true;
-        }
-
-        if (targetNode.getExecutor() == null) {
-            module.sendText(sender,Component.text("This command requires additional arguments.", NamedTextColor.RED));
-            sendSubCommands(sender, targetNode);
-            return true;
-        }
-
-        // Execute the command with remaining arguments
-        String[] remainingArgs = argList.toArray(new String[0]);
-        targetNode.getExecutor().accept(sender, remainingArgs);
-        return true;
-    }
-    private void sendHelp(CommandSender sender, String[] strings) {
-        sendHelp(sender);
-    }
-    protected void sendHelp(CommandSender sender) {
-        sender.sendMessage("§6=== Available Commands ===");
-        for (CommandNode cmd : rootCommand.getSubCommands()) {
-            sender.sendMessage("/" + rootCommand.getName() + " " + cmd.getName() + " §7- " + cmd.getDescription());
-        }
-    }
-
-    private void sendSubCommands(CommandSender sender, CommandNode node) {
-        sender.sendMessage("§6Available subcommands:");
-        for (CommandNode subCmd : node.getSubCommands()) {
-            sender.sendMessage("§e" + subCmd.getName() + " §7- " + subCmd.getDescription());
-        }
-    }
-
-    public CommandNode registerCommand(String name, String description, BiConsumer<CommandSender, String[]> executor) {
-        return rootCommand.registerSubCommand(name, description, executor);
-    }
-
-    @Override
-    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
-        List<String> suggestions = new ArrayList<>();
-
-        if (args.length == 0) {
-            return suggestions;
-        }
-
-        // Start at root and traverse
-        CommandNode currentNode = rootCommand;
-        List<String> argList = new ArrayList<>(Arrays.asList(args));
-        String lastArg = args[args.length - 1].toLowerCase();
-
-        // Try to traverse as far as possible
-        for (int i = 0; i < argList.size() - 1; i++) {
-            String arg = argList.get(i);
-            CommandNode nextNode = currentNode.getSubCommand(arg);
-            if (nextNode == null) {
-                break;
-            }
-            currentNode = nextNode;
-        }
-
-        // Get suggestions from current node
-        if (currentNode.getTabCompleter() != null) {
-            suggestions.addAll(currentNode.getTabCompleter().apply(sender, args));
-        } else {
-            // Suggest subcommands
-            suggestions.addAll(currentNode.getSubCommandNames().stream()
-                    .filter(name -> name.toLowerCase().startsWith(lastArg))
-                    .collect(Collectors.toList()));
-        }
-
-        return suggestions;
-    }
-    public void reload(){
-        createCommands();
-    }
-}

+ 0 - 46
src/main/java/me/lethunderhawk/bazaarflux/util/gui/ConfirmationMenu.java

@@ -1,46 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.gui;
-
-import me.lethunderhawk.main.util.UnItalic;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import java.util.function.Consumer;
-
-public class ConfirmationMenu extends InventoryGUI {
-    private final Consumer<Player> callback;
-
-    public ConfirmationMenu(String title, Consumer<Player> callback ) {
-        super(title, 27);
-        this.callback = callback;
-        setupItems();
-    }
-
-    private void setupItems() {
-        fillGlassPaneBackground();
-
-        ItemStack IAmSure = new ItemStack(Material.LIME_STAINED_GLASS_PANE);
-        ItemMeta meta = IAmSure.getItemMeta();
-        meta.displayName(Component.text("Yes, i am sure", NamedTextColor.GREEN));
-        IAmSure.setItemMeta(UnItalic.removeItalicFromMeta(meta));
-        setItemWithClickAction(11, IAmSure, (p, type)->{
-            callback.accept(p);
-            openPrevious(p);
-        });
-        ItemStack NoPleaseNot = new ItemStack(Material.BARRIER);
-        ItemMeta noMeta = NoPleaseNot.getItemMeta();
-        noMeta.displayName(Component.text("No, i changed my mind", NamedTextColor.RED));
-        NoPleaseNot.setItemMeta(UnItalic.removeItalicFromMeta(noMeta));
-        setItemWithClickAction(15, NoPleaseNot, (p, type)->{
-            openPrevious(p);
-        });
-    }
-
-    @Override
-    public void update() {
-
-    }
-}

+ 0 - 28
src/main/java/me/lethunderhawk/bazaarflux/util/gui/GoBackItem.java

@@ -1,28 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.gui;
-
-import me.lethunderhawk.main.util.UnItalic;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
-import org.bukkit.Material;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import java.util.List;
-
-public class GoBackItem extends ItemStack {
-    public GoBackItem() {
-        super(Material.ARROW);
-
-        setItemMeta(buildItemMeta());
-    }
-
-    private ItemMeta buildItemMeta() {
-        ItemMeta meta = getItemMeta();
-        meta.displayName(Component.text("Go back", NamedTextColor.RED));
-        meta.lore(List.of(
-                Component.text("Go back to the previous menu!", NamedTextColor.GRAY)
-        ));
-        UnItalic.removeItalicFromMeta(meta);
-        return meta;
-    }
-}

+ 0 - 152
src/main/java/me/lethunderhawk/bazaarflux/util/gui/InventoryGUI.java

@@ -1,152 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.gui;
-
-import me.lethunderhawk.main.util.UnItalic;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
-import org.bukkit.Bukkit;
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.ClickType;
-import org.bukkit.inventory.Inventory;
-import org.bukkit.inventory.InventoryHolder;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-import java.util.function.BiConsumer;
-
-/**
- * Generic, reusable Inventory GUI.
- */
-public abstract class InventoryGUI implements InventoryHolder {
-
-    private final String title;
-    private final int size;
-    private final Inventory inventory;
-
-    private final Map<Integer, BiConsumer<Player, ClickType>> slotActions = new HashMap<>();
-    private final Stack<InventoryGUI> previousGuis = new Stack<>();
-
-    public InventoryGUI(String title, int size) {
-        this.title = title;
-        this.size = size;
-        this.inventory = Bukkit.createInventory(this, size, title);
-    }
-
-    public void handleClick(Player player, int slot, ClickType type) {
-        BiConsumer<Player, ClickType> action = slotActions.get(slot);
-        if (action != null) {
-            action.accept(player, type);
-        }
-    }
-    /**
-     * Sets an item in a specific slot.
-     */
-    public void setItem(int slot, ItemStack item) {
-        inventory.setItem(slot, item);
-    }
-
-    /**
-     * Sets an item and assigns a click action for that slot.
-     */
-    public void setItemWithClickAction(int slot, ItemStack item, BiConsumer<Player, ClickType> action) {
-        inventory.setItem(slot, item);
-        slotActions.put(slot, action);
-    }
-
-    /**
-     * Fills all empty slots with a background item.
-     */
-    public void fillGlassPaneBackground(){
-        ItemStack background = new ItemStack(Material.GRAY_STAINED_GLASS_PANE);
-        ItemMeta meta = background.getItemMeta();
-        meta.displayName(Component.text(" "));
-        meta.setHideTooltip(true);
-        background.setItemMeta(meta);
-        for (int i = 0; i < size; i++) {
-            if (inventory.getItem(i) == null) {
-                inventory.setItem(i, background);
-            }
-        }
-    }
-    public void fillBackground(Material material, String displayName) {
-        ItemStack background = new ItemStack(material);
-        ItemMeta meta = background.getItemMeta();
-        meta.displayName(Component.text(displayName));
-        meta.setHideTooltip(true);
-        background.setItemMeta(meta);
-        for (int i = 0; i < size; i++) {
-            if (inventory.getItem(i) == null) {
-                inventory.setItem(i, background);
-            }
-        }
-    }
-    public void openWithListener(Player player){
-        InventoryManager.openFor(player, this);
-    }
-    /**
-     * Opens this GUI for a player.
-     */
-    public void open(Player player) {
-        player.openInventory(inventory);
-    }
-
-    /**
-     * Opens another GUI and remembers this one for navigation.
-     */
-    public void openNext(Player player, InventoryGUI nextGui) {
-        nextGui.previousGuis.push(this);
-        InventoryManager.openFor(player, nextGui);
-    }
-    public boolean hasPreviousGUI() {
-        return !previousGuis.isEmpty();
-    }
-
-    /**
-     * Opens the previous GUI if available.
-     */
-    public void openPrevious(Player player) {
-        if (!previousGuis.isEmpty()) {
-            InventoryGUI previousGui = previousGuis.pop();
-            previousGui.update();
-            InventoryManager.openFor(player, previousGui);
-        }
-    }
-    public void setBackButton(int slot){
-        ItemStack item = new ItemStack(Material.ARROW);
-        ItemMeta meta = item.getItemMeta();
-        meta.displayName(Component.text("Go Back", NamedTextColor.GREEN));
-        item.setItemMeta(UnItalic.removeItalicFromMeta(meta));
-        setItemWithClickAction(slot, item, (p, type) -> {
-            openPrevious(p);
-        });
-    }
-    public void setCloseButton(int slot){
-        ItemStack item = new ItemStack(Material.BARRIER);
-        ItemMeta meta = item.getItemMeta();
-        meta.displayName(Component.text("Close", NamedTextColor.RED));
-        item.setItemMeta(UnItalic.removeItalicFromMeta(meta));
-        setItemWithClickAction(slot, item, (p, type) -> {
-            InventoryManager.close(p.getUniqueId());
-        });
-    }
-
-    // Also need to update the overloaded version:
-    public void openPrevious(Player player, ClickType type) {
-        openPrevious(player);
-    }
-
-    @Override
-    public @NotNull Inventory getInventory() {
-        return inventory;
-    }
-
-    public abstract void update();
-
-    public interface AutoCloseHandler {
-        void onClosedByPlayer(Player player);
-    }
-}

+ 0 - 115
src/main/java/me/lethunderhawk/bazaarflux/util/gui/InventoryManager.java

@@ -1,115 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.gui;
-
-import me.lethunderhawk.minion.ui.MinionMenu;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.inventory.InventoryClickEvent;
-import org.bukkit.event.inventory.InventoryCloseEvent;
-import org.bukkit.plugin.Plugin;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Central registry & listener for open InventoryGUI instances.
- * Register once: InventoryManager.register(plugin);
- */
-public final class InventoryManager implements Listener {
-    private static final Map<UUID, InventoryGUI> openGuis = new ConcurrentHashMap<>();
-    private static volatile boolean registered = false;
-    private static Plugin providerPlugin;
-
-    public static void register(Plugin plugin) {
-        if (registered) return;
-        providerPlugin = plugin;
-        Bukkit.getPluginManager().registerEvents(new InventoryManager(), plugin);
-        registered = true;
-    }
-
-    public static void openFor(Player player, InventoryGUI gui) {
-        // ensure main thread
-        if (!Bukkit.isPrimaryThread()) {
-            Bukkit.getScheduler().runTask(providerPlugin, () -> openFor(player, gui));
-            return;
-        }
-
-        // Close current inventory if open
-        InventoryGUI current = openGuis.get(player.getUniqueId());
-        if (current != null) {
-            openGuis.remove(player.getUniqueId());
-        }
-
-        // Open new GUI
-        openGuis.put(player.getUniqueId(), gui);
-        gui.open(player);
-    }
-
-    public static InventoryGUI getOpen(UUID playerId) {
-        return openGuis.get(playerId);
-    }
-
-    public static void close(@NotNull UUID playerId) {
-        InventoryGUI gui = openGuis.remove(playerId);
-        if (gui != null) {
-            Player p = Bukkit.getPlayer(playerId);
-            if(p!= null) p.closeInventory();
-        }
-    }
-
-    public static void refreshMinionMenuForPlayer(UUID ownerId, UUID minionId) {
-        if(openGuis.containsKey(ownerId)) {
-            InventoryGUI gui = openGuis.get(ownerId);
-            if(!(gui instanceof MinionMenu minionMenu)) return;
-            if(!minionMenu.getMinionId().equals(minionId)) return;
-            minionMenu.update();
-            Objects.requireNonNull(Bukkit.getPlayer(ownerId)).updateInventory();
-        }
-    }
-
-    @EventHandler
-    public void onInventoryClick(InventoryClickEvent event) {
-        if (!(event.getWhoClicked() instanceof Player player)) return;
-        if (!(event.getView().getTopInventory().getHolder() instanceof InventoryGUI gui)) return;
-
-        // ignore clicks outside top inventory
-        if (event.getRawSlot() >= event.getView().getTopInventory().getSize()) return;
-
-        InventoryGUI open = openGuis.get(player.getUniqueId());
-        if (open == null || open != gui) return; // ensure it's the tracked instance
-
-        event.setCancelled(true);
-        gui.handleClick(player, event.getRawSlot(), event.getClick());
-    }
-
-    @EventHandler
-    public void onInventoryClose(InventoryCloseEvent event) {
-        if (!(event.getPlayer() instanceof Player player)) return;
-        InventoryGUI gui = openGuis.get(player.getUniqueId());
-        if (gui == null) return;
-
-        // If the closed inventory is the tracked GUI
-        if (event.getView().getTopInventory().getHolder() == gui) {
-            // Check if this is an intentional navigation (opening a new GUI)
-            // If the player is opening a new GUI, it will be handled by openFor
-            // We should only treat it as accidental if reason is not OPEN_NEW
-            // and the player doesn't have another GUI queued up
-            if (event.getReason() != InventoryCloseEvent.Reason.OPEN_NEW) {
-                // Small delay to check if another GUI is being opened
-                Bukkit.getScheduler().runTask(providerPlugin, () -> {
-                    // If still the same GUI (no new GUI was opened), treat as accidental close
-                    if (openGuis.get(player.getUniqueId()) == gui) {
-                        if (gui instanceof InventoryGUI.AutoCloseHandler handler) {
-                            handler.onClosedByPlayer(player);
-                        }
-                        openGuis.remove(player.getUniqueId());
-                    }
-                });
-            }
-        }
-    }
-}

+ 0 - 55
src/main/java/me/lethunderhawk/bazaarflux/util/gui/PlayerHeadListGUI.java

@@ -1,55 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.gui;
-
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.SkullMeta;
-
-import java.util.List;
-import java.util.function.BiConsumer;
-
-/**
- * GUI displaying a list of players as clickable heads.
- */
-public class PlayerHeadListGUI extends InventoryGUI {
-
-    public PlayerHeadListGUI(
-            String title,
-            int size,
-            List<Player> players,
-            BiConsumer<Player, Player> onHeadClick
-    ) {
-        super(title, size);
-
-        int slot = 0;
-        for (Player target : players) {
-            if (slot >= size) break;
-
-            ItemStack head = createPlayerHead(target);
-            int finalSlot = slot;
-
-            setItemWithClickAction(finalSlot, head, (clickingPlayer, type) ->
-                    onHeadClick.accept(clickingPlayer, target)
-            );
-
-            slot++;
-        }
-
-        fillBackground(Material.GRAY_STAINED_GLASS_PANE, " ");
-    }
-
-
-    private ItemStack createPlayerHead(Player player) {
-        ItemStack head = new ItemStack(Material.PLAYER_HEAD);
-        SkullMeta meta = (SkullMeta) head.getItemMeta();
-        meta.setOwningPlayer(player);
-        meta.setDisplayName(player.getName());
-        head.setItemMeta(meta);
-        return head;
-    }
-
-    @Override
-    public void update() {
-
-    }
-}

+ 0 - 137
src/main/java/me/lethunderhawk/bazaarflux/util/gui/input/SignMenuFactory.java

@@ -1,137 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.gui.input;
-
-import com.comphenix.protocol.PacketType;
-import com.comphenix.protocol.ProtocolLibrary;
-import com.comphenix.protocol.events.PacketAdapter;
-import com.comphenix.protocol.events.PacketContainer;
-import com.comphenix.protocol.events.PacketEvent;
-import com.comphenix.protocol.wrappers.BlockPosition;
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.plugin.Plugin;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.BiPredicate;
-
-public final class SignMenuFactory {
-
-    private final Plugin plugin;
-
-    private final Map<Player, Menu> inputs;
-
-    public SignMenuFactory(Plugin plugin) {
-        this.plugin = plugin;
-        this.inputs = new ConcurrentHashMap<>();
-        this.listen();
-    }
-
-    public Menu newMenu(List<String> text) {
-        return new Menu(text);
-    }
-
-    private void listen() {
-        ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this.plugin, PacketType.Play.Client.UPDATE_SIGN) {
-            @Override
-            public void onPacketReceiving(PacketEvent event) {
-                Player player = event.getPlayer();
-                Menu menu = inputs.remove(player);
-                if (menu == null) return;
-
-                event.setCancelled(true);
-
-                String[] lines = event.getPacket().getStringArrays().read(0);
-
-                Bukkit.getScheduler().runTask(plugin, () -> {
-                    boolean success = menu.response.test(player, lines);
-
-                    if (!success && menu.reopenIfFail && !menu.forceClose) {
-                        Bukkit.getScheduler().runTaskLater(plugin, () -> menu.open(player), 2L);
-                    }
-                    if (player.isOnline()) {
-                        player.sendBlockChange(
-                                menu.location,
-                                menu.location.getBlock().getBlockData()
-                        );
-                    }
-                });
-            }
-        });
-    }
-
-    public final class Menu {
-
-        private final List<String> text;
-
-        private BiPredicate<Player, String[]> response;
-        private boolean reopenIfFail;
-
-        private Location location;
-
-        private boolean forceClose;
-
-        Menu(List<String> text) {
-            this.text = text;
-        }
-
-        public Menu reopenIfFail(boolean value) {
-            this.reopenIfFail = value;
-            return this;
-        }
-
-        public Menu response(BiPredicate<Player, String[]> response) {
-            this.response = response;
-            return this;
-        }
-
-        public void open(Player player) {
-            Objects.requireNonNull(player, "player");
-            if (!player.isOnline()) {
-                return;
-            }
-            location = player.getLocation();
-            location.setY(location.getBlockY() - 4);
-
-            player.sendBlockChange(location, Material.OAK_SIGN.createBlockData());
-            player.sendSignChange(
-                    location,
-                    text.stream().map(this::color).toList().toArray(new String[4])
-            );
-
-            PacketContainer openSign = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.OPEN_SIGN_EDITOR);
-            BlockPosition position = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ());
-            openSign.getBlockPositionModifier().write(0, position);
-            openSign.getBooleans().write(0, true); // ADDED
-            ProtocolLibrary.getProtocolManager().sendServerPacket(player, openSign);
-
-            inputs.put(player, this);
-        }
-
-        /**
-         * closes the menu. if force is true, the menu will close and will ignore the reopen
-         * functionality. false by default.
-         *
-         * @param player the player
-         * @param force  decides whether it will reopen if reopen is enabled
-         */
-        public void close(Player player, boolean force) {
-            this.forceClose = force;
-            if (player.isOnline()) {
-                player.closeInventory();
-            }
-        }
-
-        public void close(Player player) {
-            close(player, false);
-        }
-
-        private String color(String input) {
-            return ChatColor.translateAlternateColorCodes('&', input);
-        }
-    }
-}

+ 0 - 27
src/main/java/me/lethunderhawk/bazaarflux/util/interfaces/BazaarFluxModule.java

@@ -1,27 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.interfaces;
-
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.MessageSender;
-import me.lethunderhawk.main.Main;
-import net.kyori.adventure.audience.Audience;
-import net.kyori.adventure.text.Component;
-import org.bukkit.command.CommandSender;
-import org.bukkit.plugin.java.JavaPlugin;
-
-public abstract class BazaarFluxModule{
-    protected JavaPlugin plugin;
-    public BazaarFluxModule() {
-        this.plugin = Services.get(Main.class);
-    }
-    public abstract String getPrefix();
-    public abstract void onEnable();
-    public abstract void onDisable();
-    public void sendText(Audience receiver, Component infoText){
-        MessageSender.sendText(receiver, infoText, getPrefix());
-    }
-
-    public void reload(CommandSender sender, String[] strings) {
-        onDisable();
-        onEnable();
-    }
-}

+ 0 - 254
src/main/java/me/lethunderhawk/bazaarflux/util/itemdesign/LoreDesigner.java

@@ -1,254 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.itemdesign;
-
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.ComponentBuilder;
-import net.kyori.adventure.text.TextComponent;
-import net.kyori.adventure.text.format.NamedTextColor;
-import net.kyori.adventure.text.format.TextDecoration;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-
-public final class LoreDesigner {
-
-    private LoreDesigner() {}
-    public static Component createSingle(String text) {
-        if (text == null || text.isBlank()) {
-            return Component.empty();
-        }
-
-        StyleState style = new StyleState();
-        ComponentBuilder<TextComponent, TextComponent.Builder> builder = Component.text();
-
-        int i = 0;
-        while (i < text.length()) {
-            if (text.charAt(i) == '<') {
-                int end = text.indexOf('>', i);
-                if (end != -1) {
-                    String token = text.substring(i + 1, end).toLowerCase();
-                    applyToken(style, token);
-                    i = end + 1;
-                    continue;
-                }
-            }
-
-            char c = text.charAt(i);
-            builder.append(Component.text(String.valueOf(c), style.toStyle()));
-            i++;
-        }
-
-        return builder.build();
-    }
-    public static List<Component> createLore(String text, String widthReference) {
-        int maxLength = widthReference.length();
-        if (text == null || text.isBlank() || maxLength <= 0) {
-            return List.of();
-        }
-
-        List<Component> lore = new ArrayList<>();
-
-        StyleState style = new StyleState();
-        ComponentBuilder<TextComponent, TextComponent.Builder> lineBuilder = Component.text();
-        int currentLength = 0;
-
-        String[] lines = text.split("<br>", -1);
-
-        for (int i = 0; i < lines.length; i++) {
-
-            String[] wrapParts = lines[i].split(" ");
-
-            for (int p = 0; p < wrapParts.length; p++) {
-
-                ParsedWord parsed = parseWord(wrapParts[p], style);
-                appendWord(
-                        lore,
-                        parsed,
-                        maxLength,
-                        style,
-                        Holder.of(lineBuilder, currentLength)
-                );
-
-                currentLength = Holder.length;
-                lineBuilder = Holder.builder;
-
-                // add space between parts
-                if (p < wrapParts.length - 1) {
-                    lineBuilder.append(Component.space());
-                    currentLength++;
-                }
-            }
-
-            currentLength = Holder.length;
-            lineBuilder = Holder.builder;
-
-            // force line break if <br> occurred
-            if (i < lines.length - 1) {
-                lore.add(lineBuilder.build());
-                lineBuilder = Component.text().style(style.toStyle());
-                currentLength = 0;
-            }
-        }
-
-        if (currentLength > 0) {
-            lore.add(lineBuilder.build());
-        }
-
-        return lore;
-    }
-
-    // -------------------- Append Logic --------------------
-
-    private static void appendWord(
-            List<Component> lore,
-            ParsedWord parsed,
-            int maxLength,
-            StyleState style,
-            Holder holder
-    ) {
-        int wordLength = parsed.visibleLength();
-
-        if (holder.length > 0 && holder.length + 1 + wordLength > maxLength) {
-            lore.add(holder.builder.build());
-            holder.builder = Component.text().style(style.toStyle());
-            holder.length = 0;
-        }
-
-        holder.builder.append(parsed.component());
-        holder.length += wordLength;
-    }
-
-    // -------------------- Parsing --------------------
-
-    private static ParsedWord parseWord(String raw, StyleState style) {
-        ComponentBuilder<TextComponent, TextComponent.Builder> builder = Component.text();
-        int visibleLength = 0;
-
-        int i = 0;
-        while (i < raw.length()) {
-            if (raw.charAt(i) == '<') {
-                int end = raw.indexOf('>', i);
-                if (end != -1) {
-                    String token = raw.substring(i + 1, end).toLowerCase();
-                    applyToken(style, token);
-                    i = end + 1;
-                    continue;
-                }
-            }
-
-            char c = raw.charAt(i);
-            builder.append(Component.text(String.valueOf(c), style.toStyle()));
-            visibleLength++;
-            i++;
-        }
-
-        return new ParsedWord(builder.build(), visibleLength);
-    }
-
-    private static void applyToken(StyleState style, String token) {
-
-        if (token.startsWith("/")) {
-            String closing = token.substring(1);
-
-            switch (closing) {
-                case "bold" -> style.undecorate(TextDecoration.BOLD);
-                case "italic" -> style.undecorate(TextDecoration.ITALIC);
-                case "underlined" -> style.undecorate(TextDecoration.UNDERLINED);
-                case "strikethrough" -> style.undecorate(TextDecoration.STRIKETHROUGH);
-                case "obfuscated" -> style.undecorate(TextDecoration.OBFUSCATED);
-                default -> {
-                    // closing color tag like </red>
-                    if (NAMED_COLORS.containsKey(closing)) {
-                        style.color(style.defaultColor);
-                    }
-                }
-            }
-            return;
-        }
-
-        switch (token) {
-            case "reset" -> style.reset();
-
-            case "bold" -> style.decorate(TextDecoration.BOLD);
-            case "italic" -> style.decorate(TextDecoration.ITALIC);
-            case "underlined" -> style.decorate(TextDecoration.UNDERLINED);
-            case "strikethrough" -> style.decorate(TextDecoration.STRIKETHROUGH);
-            case "obfuscated" -> style.decorate(TextDecoration.OBFUSCATED);
-
-            default -> {
-                NamedTextColor color = NAMED_COLORS.get(token);
-                if (color != null) {
-                    style.color(color);
-                }
-            }
-        }
-    }
-
-    // -------------------- Helpers --------------------
-
-    private static final Map<String, NamedTextColor> NAMED_COLORS = Map.ofEntries(
-            Map.entry("black", NamedTextColor.BLACK),
-            Map.entry("dark_blue", NamedTextColor.DARK_BLUE),
-            Map.entry("dark_green", NamedTextColor.DARK_GREEN),
-            Map.entry("dark_aqua", NamedTextColor.DARK_AQUA),
-            Map.entry("dark_red", NamedTextColor.DARK_RED),
-            Map.entry("dark_purple", NamedTextColor.DARK_PURPLE),
-            Map.entry("gold", NamedTextColor.GOLD),
-            Map.entry("gray", NamedTextColor.GRAY),
-            Map.entry("dark_gray", NamedTextColor.DARK_GRAY),
-            Map.entry("blue", NamedTextColor.BLUE),
-            Map.entry("green", NamedTextColor.GREEN),
-            Map.entry("aqua", NamedTextColor.AQUA),
-            Map.entry("red", NamedTextColor.RED),
-            Map.entry("light_purple", NamedTextColor.LIGHT_PURPLE),
-            Map.entry("yellow", NamedTextColor.YELLOW),
-            Map.entry("white", NamedTextColor.WHITE)
-    );
-
-    private record ParsedWord(Component component, int visibleLength) {}
-
-    private static final class StyleState {
-        private final NamedTextColor defaultColor = NamedTextColor.GRAY;
-
-        private NamedTextColor color = defaultColor;
-        private final EnumSet<TextDecoration> decorations = EnumSet.noneOf(TextDecoration.class);
-
-        void color(NamedTextColor color) {
-            this.color = color;
-        }
-        void undecorate(TextDecoration decoration) {
-            decorations.remove(decoration);
-        }
-        void decorate(TextDecoration decoration) {
-            decorations.add(decoration);
-        }
-
-        void reset() {
-            color = defaultColor;
-            decorations.clear();
-        }
-
-        net.kyori.adventure.text.format.Style toStyle() {
-            net.kyori.adventure.text.format.Style.Builder style =
-                    net.kyori.adventure.text.format.Style.style();
-            if (color != null) style.color(color);
-            for (TextDecoration d : decorations) style.decorate(d);
-            return style.build();
-        }
-    }
-
-    /**
-     * Mutable holder to avoid excessive object creation
-     */
-    private static final class Holder {
-        static ComponentBuilder builder;
-        static int length;
-
-        static Holder of(ComponentBuilder b, int l) {
-            builder = b;
-            length = l;
-            return null;
-        }
-    }
-}

+ 0 - 25
src/main/java/me/lethunderhawk/bazaarflux/util/lang/RomanNumbers.java

@@ -1,25 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.lang;
-
-public class RomanNumbers {
-    public static String intToRoman(int num) {
-        // Arrays to hold the Roman numeral symbols and their corresponding integer values
-        String[] romanSymbols = {
-                "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"
-        };
-        int[] romanValues = {
-                1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
-        };
-
-        StringBuilder result = new StringBuilder();
-
-        // Loop through the values to create the Roman numeral
-        for (int i = 0; i < romanValues.length; i++) {
-            while (num >= romanValues[i]) {
-                result.append(romanSymbols[i]);
-                num -= romanValues[i];
-            }
-        }
-
-        return result.toString();
-    }
-}

+ 0 - 142
src/main/java/me/lethunderhawk/bazaarflux/util/loottables/RiggedChanceGenerator.java

@@ -1,142 +0,0 @@
-package me.lethunderhawk.bazaarflux.util.loottables;
-
-import java.util.*;
-import java.util.function.Supplier;
-
-public class RiggedChanceGenerator<T> {
-
-    private static final Random RANDOM = new Random();
-
-    // Sequential rigged steps
-    private final List<ChanceStep<T>> steps = new ArrayList<>();
-
-    // Final weighted pool
-    private final List<WeightedChance<T>> finalChances = new ArrayList<>();
-
-    private Supplier<T> fallback;
-
-    /* =======================
-       PRE-STEPS (RIGGED)
-       ======================= */
-
-    public RiggedChanceGenerator<T> addStep(int numerator, int denominator, T result) {
-        steps.add(new ChanceStep<>(numerator, denominator, () -> result));
-        return this;
-    }
-
-    public RiggedChanceGenerator<T> addStep(int numerator, int denominator, Supplier<T> resultSupplier) {
-        steps.add(new ChanceStep<>(numerator, denominator, resultSupplier));
-        return this;
-    }
-
-    /* =======================
-       FINAL POOL (DICE)
-       ======================= */
-
-    /**
-     * Adds a weighted chance to the final roll.
-     * Weights do NOT need to sum to 100.
-     */
-    public RiggedChanceGenerator<T> addChance(int weight, T result) {
-        finalChances.add(new WeightedChance<>(weight, () -> result));
-        return this;
-    }
-
-    public RiggedChanceGenerator<T> addChance(int weight, Supplier<T> resultSupplier) {
-        finalChances.add(new WeightedChance<>(weight, resultSupplier));
-        return this;
-    }
-
-    /* =======================
-       FALLBACK
-       ======================= */
-
-    public RiggedChanceGenerator<T> fallback(T fallbackResult) {
-        this.fallback = () -> fallbackResult;
-        return this;
-    }
-
-    public RiggedChanceGenerator<T> fallback(Supplier<T> fallbackSupplier) {
-        this.fallback = fallbackSupplier;
-        return this;
-    }
-
-    /* =======================
-       EXECUTION
-       ======================= */
-
-    public T roll() {
-
-        // 1. Rigged pre-steps
-        for (ChanceStep<T> step : steps) {
-            if (step.roll()) {
-                return step.result();
-            }
-        }
-
-        // 2. Final weighted dice
-        if (!finalChances.isEmpty()) {
-            int totalWeight = finalChances.stream().mapToInt(c -> c.weight).sum();
-            int roll = RANDOM.nextInt(totalWeight);
-
-            int cumulative = 0;
-            for (WeightedChance<T> chance : finalChances) {
-                cumulative += chance.weight;
-                if (roll < cumulative) {
-                    return chance.result();
-                }
-            }
-        }
-
-        // 3. Fallback
-        if (fallback == null) {
-            throw new IllegalStateException("No fallback defined");
-        }
-        return fallback.get();
-    }
-
-    /* =======================
-       INTERNAL CLASSES
-       ======================= */
-
-    private static final class ChanceStep<T> {
-        private final int numerator;
-        private final int denominator;
-        private final Supplier<T> result;
-
-        private ChanceStep(int numerator, int denominator, Supplier<T> result) {
-            if (numerator <= 0 || denominator <= 0 || numerator > denominator) {
-                throw new IllegalArgumentException("Invalid chance: " + numerator + "/" + denominator);
-            }
-            this.numerator = numerator;
-            this.denominator = denominator;
-            this.result = result;
-        }
-
-        private boolean roll() {
-            return RANDOM.nextInt(denominator) < numerator;
-        }
-
-        private T result() {
-            return result.get();
-        }
-    }
-
-    private static final class WeightedChance<T> {
-        private final int weight;
-        private final Supplier<T> result;
-
-        private WeightedChance(int weight, Supplier<T> result) {
-            if (weight <= 0) {
-                throw new IllegalArgumentException("Weight must be > 0");
-            }
-            this.weight = weight;
-            this.result = result;
-        }
-
-        private T result() {
-            return result.get();
-        }
-    }
-}
-

+ 2 - 2
src/main/java/me/lethunderhawk/clans/Clan.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.clans;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.clans.claim.Claim;
 import me.lethunderhawk.clans.settings.ClanSetting;
 import me.lethunderhawk.clans.settings.ClanSettings;
@@ -72,7 +72,7 @@ public class Clan {
         Player owner = Bukkit.getPlayer(getOwnerUUID());
         Player player = Bukkit.getPlayer(playerUUID);
         if(owner == null || player == null) return;
-        ClanModule module = Services.get(ClanModule.class);
+        ClanModule module = FluxService.get(ClanModule.class);
         module.sendText(owner, Component.text("=== Request to join ===", NamedTextColor.GOLD));
         module.sendText(owner, Component.text("The player " + player.getName() + " wants to join your clan!", NamedTextColor.GRAY));
         module.sendText(owner, Component.text("[Decline] ", NamedTextColor.RED).clickEvent(ClickEvent.runCommand("/clan declineRequest " + player.getName()))

+ 11 - 9
src/main/java/me/lethunderhawk/clans/ClanModule.java

@@ -1,17 +1,19 @@
 package me.lethunderhawk.clans;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.clans.claim.ClaimListener;
 import me.lethunderhawk.clans.claim.ClaimManager;
 import me.lethunderhawk.clans.command.ClanCommand;
 import me.lethunderhawk.clans.placeholder.ClanPlaceHolder;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.main.Main;
 import org.bukkit.event.HandlerList;
+import org.bukkit.plugin.java.JavaPlugin;
 
 public class ClanModule extends BazaarFluxModule {
 
-    public ClanModule() {
+    public ClanModule(JavaPlugin plugin) {
+        super(plugin);
     }
 
     public String getPrefix(){
@@ -19,17 +21,17 @@ public class ClanModule extends BazaarFluxModule {
     }
 
     public void onEnable(){
-        Main mainPlugin = Services.get(Main.class);
+        Main mainPlugin = FluxService.get(Main.class);
         ClaimManager claimManager = new ClaimManager();
         ClanManager clanManager = new ClanManager(mainPlugin, claimManager);
 
-        Services.register(ClaimManager.class, claimManager);
-        Services.register(ClanManager.class, clanManager);
+        FluxService.register(ClaimManager.class, claimManager);
+        FluxService.register(ClanManager.class, clanManager);
 
 
 
         ClaimListener claimListener = new ClaimListener(claimManager, clanManager);
-        Services.register(ClaimListener.class, claimListener);
+        FluxService.register(ClaimListener.class, claimListener);
 
         mainPlugin.getCommand("clan").setExecutor(new ClanCommand(clanManager));
         mainPlugin.getCommand("clan").setTabCompleter(new ClanCommand(clanManager));
@@ -43,7 +45,7 @@ public class ClanModule extends BazaarFluxModule {
     }
 
     public void onDisable(){
-        HandlerList.unregisterAll(Services.get(ClaimListener.class));
-        Services.get(ClanManager.class).saveClans();
+        HandlerList.unregisterAll(FluxService.get(ClaimListener.class));
+        FluxService.get(ClanManager.class).saveClans();
     }
 }

+ 2 - 2
src/main/java/me/lethunderhawk/clans/claim/Claim.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.clans.claim;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.clans.Clan;
 import me.lethunderhawk.clans.ClanManager;
 import org.bukkit.Chunk;
@@ -100,7 +100,7 @@ public class Claim {
     }
     public String getName() {
         if(name == null || name.isEmpty()) {
-            Clan clan = Services.get(ClanManager.class).getClanById(clanId);
+            Clan clan = FluxService.get(ClanManager.class).getClanById(clanId);
             if(clan == null) return "Unknown";
             else return clan.getName();
         }

+ 3 - 3
src/main/java/me/lethunderhawk/clans/claim/ClaimListener.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.clans.claim;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.clans.Clan;
 import me.lethunderhawk.clans.ClanManager;
 import me.lethunderhawk.clans.settings.ClanSetting;
@@ -115,7 +115,7 @@ public class ClaimListener implements Listener {
     private boolean preventForAll(Location location, ClanSetting setting){
         Claim claim = claimManager.getClaimAt(location);
         if(claim != null){
-            Clan clan = Services.get(ClanManager.class).getClanById(claim.getClanId());
+            Clan clan = FluxService.get(ClanManager.class).getClanById(claim.getClanId());
             if (clan != null) {
                 return !clan.allows(setting);
             }
@@ -125,7 +125,7 @@ public class ClaimListener implements Listener {
     private boolean preventChange(UUID playerUUID, Location location, ClanSetting setting){
         Claim claim = claimManager.getClaimAt(location);
         if(claim != null){
-            Clan clan = Services.get(ClanManager.class).getClanById(claim.getClanId());
+            Clan clan = FluxService.get(ClanManager.class).getClanById(claim.getClanId());
             if (clan != null && !clan.isInClan(playerUUID)) {
                 return !clan.allows(setting);
             }

+ 3 - 3
src/main/java/me/lethunderhawk/clans/claim/ClaimManager.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.clans.claim;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.clans.Clan;
 import me.lethunderhawk.clans.ClanManager;
 import org.bukkit.Location;
@@ -85,7 +85,7 @@ public final class ClaimManager {
         // Clean player cache
         playerClaimCache.values().removeIf(c -> c == claim);
 
-        Clan clan = Services.get(ClanManager.class).getClanById(claim.getClanId());
+        Clan clan = FluxService.get(ClanManager.class).getClanById(claim.getClanId());
         if (clan != null) {
             clan.removeClaim(claim);
         }
@@ -108,7 +108,7 @@ public final class ClaimManager {
             // Clean player cache
             playerClaimCache.values().removeIf(c -> c == claim);
 
-            Clan clan = Services.get(ClanManager.class).getClanById(claim.getClanId());
+            Clan clan = FluxService.get(ClanManager.class).getClanById(claim.getClanId());
             if (clan != null) {
                 clan.removeClaim(claim);
             }

+ 9 - 9
src/main/java/me/lethunderhawk/clans/command/ClanCommand.java

@@ -1,9 +1,5 @@
 package me.lethunderhawk.clans.command;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.command.CommandNode;
-import me.lethunderhawk.bazaarflux.util.command.CustomCommand;
-import me.lethunderhawk.bazaarflux.util.gui.InventoryManager;
 import me.lethunderhawk.clans.Clan;
 import me.lethunderhawk.clans.ClanManager;
 import me.lethunderhawk.clans.ClanModule;
@@ -12,6 +8,10 @@ import me.lethunderhawk.clans.claim.ClaimManager;
 import me.lethunderhawk.clans.gui.ClanMenu;
 import me.lethunderhawk.custom.item.abstraction.instance.ItemInstance;
 import me.lethunderhawk.custom.item.abstraction.registry.CustomItemRegistry;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.command.CommandNode;
+import me.lethunderhawk.fluxapi.util.command.CustomCommand;
+import me.lethunderhawk.fluxapi.util.gui.InventoryManager;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 import net.kyori.adventure.text.format.TextDecoration;
@@ -23,11 +23,11 @@ import java.util.List;
 import java.util.UUID;
 import java.util.stream.Collectors;
 
-public class ClanCommand extends CustomCommand{
+public class ClanCommand extends CustomCommand {
     private final ClanManager manager;
 
     public ClanCommand(ClanManager manager) {
-        super(new CommandNode("clan", "Main clan command", null), Services.get(ClanModule.class));
+        super(new CommandNode("clan", "Main clan command", null), FluxService.get(ClanModule.class));
         this.manager = manager;
     }
     @Override
@@ -59,19 +59,19 @@ public class ClanCommand extends CustomCommand{
 
     private void getClaimTool(CommandSender sender, String[] strings) {
         if(!(sender instanceof Player p)) return;
-        CustomItemRegistry registry = Services.get(CustomItemRegistry.class);
+        CustomItemRegistry registry = FluxService.get(CustomItemRegistry.class);
         p.getInventory().addItem(new ItemInstance(registry.get("claim_tool")).buildItemStack());
         module.sendText(p, Component.text("The tool magically appears in your inventory! How convenient!"));
     }
 
     private void handleSave(CommandSender sender, String[] strings) {
         if(!sender.isOp()) return;
-        Services.get(ClanManager.class).saveClans();
+        FluxService.get(ClanManager.class).saveClans();
     }
 
     private void removeAllClaims(CommandSender sender, String[] strings) {
         if(!(sender instanceof Player player) || !sender.isOp()) return;
-        Services.get(ClaimManager.class).removeAllClaims();
+        FluxService.get(ClaimManager.class).removeAllClaims();
     }
 
     private void infoClaims(CommandSender sender, String[] strings) {

+ 8 - 8
src/main/java/me/lethunderhawk/clans/gui/AdminMenuGUI.java

@@ -1,13 +1,13 @@
 package me.lethunderhawk.clans.gui;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.CustomHeadCreator;
-import me.lethunderhawk.bazaarflux.util.gui.ConfirmationMenu;
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
 import me.lethunderhawk.clans.Clan;
 import me.lethunderhawk.clans.ClanManager;
 import me.lethunderhawk.clans.ClanModule;
 import me.lethunderhawk.clans.claim.ClaimManager;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.CustomHeadCreator;
+import me.lethunderhawk.fluxapi.util.gui.ConfirmationMenu;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 import org.bukkit.entity.Player;
@@ -34,14 +34,14 @@ public class AdminMenuGUI extends InventoryGUI {
     }
 
     private void fillClansMenuWithClans() {
-        ArrayList<Clan> clans = Services.get(ClanManager.class).getClans();
+        ArrayList<Clan> clans = FluxService.get(ClanManager.class).getClans();
         for(int i = 0; i< clans.size(); i++){
             Clan clan = clans.get(i);
             ItemStack descriptor = buildItemStackFromClan(clan);
             setItemWithClickAction(i, descriptor, (p, type) ->{
                 if(type == ClickType.RIGHT){
                     ConfirmationMenu menu = new ConfirmationMenu("Remove clan " + clan.getName(), (player) -> {
-                        Services.get(ClanModule.class).sendText(player, Component.text("You removed the clan " + clan.getName()));
+                        FluxService.get(ClanModule.class).sendText(player, Component.text("You removed the clan " + clan.getName()));
                         removeClan(clan);
                         openPrevious(player);
                     });
@@ -60,8 +60,8 @@ public class AdminMenuGUI extends InventoryGUI {
     }
 
     private void removeClan(Clan clan) {
-        Services.get(ClaimManager.class).removeClaims(clan.getClaims());
-        Services.get(ClanManager.class).removeClan(clan.getName());
+        FluxService.get(ClaimManager.class).removeClaims(clan.getClaims());
+        FluxService.get(ClanManager.class).removeClan(clan.getName());
     }
 
     private ItemStack buildItemStackFromClan(Clan clan) {

+ 7 - 7
src/main/java/me/lethunderhawk/clans/gui/ClaimSettingsGUI.java

@@ -1,14 +1,14 @@
 package me.lethunderhawk.clans.gui;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.gui.ConfirmationMenu;
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
-import me.lethunderhawk.bazaarflux.util.gui.input.SignMenuFactory;
 import me.lethunderhawk.clans.Clan;
 import me.lethunderhawk.clans.claim.Claim;
 import me.lethunderhawk.clans.claim.ClaimManager;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.gui.ConfirmationMenu;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
+import me.lethunderhawk.fluxapi.util.gui.input.SignMenuFactory;
 import me.lethunderhawk.main.Main;
-import me.lethunderhawk.main.util.UnItalic;
+import me.lethunderhawk.fluxapi.util.UnItalic;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 import org.bukkit.Material;
@@ -61,11 +61,11 @@ public class ClaimSettingsGUI extends InventoryGUI {
     }
 
     private void removeClaim(Claim claim) {
-        Services.get(ClaimManager.class).removeClaim(claim);
+        FluxService.get(ClaimManager.class).removeClaim(claim);
     }
 
     private void renameClaim(Claim claim) {
-        SignMenuFactory.Menu menu = new SignMenuFactory(Services.get(Main.class)).newMenu(List.of("", "^^^^^^^^^^^^", "Enter the new", "name of the claim"))
+        SignMenuFactory.Menu menu = new SignMenuFactory(FluxService.get(Main.class)).newMenu(List.of("", "^^^^^^^^^^^^", "Enter the new", "name of the claim"))
                 .reopenIfFail(true)
                 .response((p, strings) -> {
                     rename(strings[0], claim);

+ 2 - 2
src/main/java/me/lethunderhawk/clans/gui/ClanMenu.java

@@ -1,8 +1,8 @@
 package me.lethunderhawk.clans.gui;
 
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
 import me.lethunderhawk.clans.Clan;
-import me.lethunderhawk.main.util.UnItalic;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
+import me.lethunderhawk.fluxapi.util.UnItalic;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 import org.bukkit.Material;

+ 2 - 2
src/main/java/me/lethunderhawk/clans/gui/ClanSettingsGUI.java

@@ -1,9 +1,9 @@
 package me.lethunderhawk.clans.gui;
 
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
 import me.lethunderhawk.clans.settings.ClanSetting;
 import me.lethunderhawk.clans.settings.ClanSettings;
-import me.lethunderhawk.main.util.UnItalic;
+import me.lethunderhawk.fluxapi.util.UnItalic;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 import org.bukkit.Material;

+ 1 - 1
src/main/java/me/lethunderhawk/clans/gui/MemberListGUI.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.clans.gui;
 
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
 import org.bukkit.entity.Player;
 
 public class MemberListGUI extends InventoryGUI {

+ 2 - 2
src/main/java/me/lethunderhawk/clans/placeholder/ClanPlaceHolder.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.clans.placeholder;
 
 import me.clip.placeholderapi.expansion.PlaceholderExpansion;
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.clans.Clan;
 import me.lethunderhawk.clans.ClanManager;
 import org.bukkit.entity.Player;
@@ -12,7 +12,7 @@ public class ClanPlaceHolder extends PlaceholderExpansion {
     private final ClanManager manager;
 
     public ClanPlaceHolder(){
-        this.manager = Services.get(ClanManager.class);
+        this.manager = FluxService.get(ClanManager.class);
     }
 
     @Override

+ 2 - 2
src/main/java/me/lethunderhawk/clans/settings/ClanSettings.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.clans.settings;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.main.Main;
 
 import java.util.EnumMap;
@@ -45,7 +45,7 @@ public final class ClanSettings {
                 ClanSetting key = ClanSetting.valueOf(entry.getKey());
                 s.set(key, (Boolean) entry.getValue());
             } catch (IllegalArgumentException e) {
-                Services.get(Main.class).getLogger().warning("Unknown ClanSetting: " + entry.getKey());
+                FluxService.get(Main.class).getLogger().warning("Unknown ClanSetting: " + entry.getKey());
             }
         }
         return s;

+ 2 - 2
src/main/java/me/lethunderhawk/custom/block/registry/BlockRegistry.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.custom.block.registry;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.main.Main;
 import org.bukkit.Bukkit;
 import org.bukkit.World;
@@ -97,7 +97,7 @@ public class BlockRegistry implements Listener {
             onDestroyLogic();
 
             regenTask = Bukkit.getScheduler().runTaskLater(
-                    Services.get(Main.class),
+                    FluxService.get(Main.class),
                     this::regenerate,
                     regenTimeSeconds * 20L
             );

+ 15 - 12
src/main/java/me/lethunderhawk/custom/item/CustomItemModule.java

@@ -1,7 +1,5 @@
 package me.lethunderhawk.custom.item;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.custom.block.registry.BlockRegistry;
 import me.lethunderhawk.custom.item.abstraction.definition.DefaultItemDefinitionValidator;
 import me.lethunderhawk.custom.item.abstraction.definition.ItemDefinition;
@@ -13,9 +11,12 @@ import me.lethunderhawk.custom.item.abstraction.runtime.AbilityDispatchService;
 import me.lethunderhawk.custom.item.command.CustomItemCommand;
 import me.lethunderhawk.custom.item.concrete.ability.*;
 import me.lethunderhawk.custom.item.listener.CustomItemListener;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.main.Main;
 import org.bukkit.command.CommandSender;
 import org.bukkit.event.HandlerList;
+import org.bukkit.plugin.java.JavaPlugin;
 
 import java.io.File;
 import java.util.Map;
@@ -23,9 +24,11 @@ import java.util.Map;
 public class CustomItemModule extends BazaarFluxModule {
     private CustomItemListener listener;
 
-    public CustomItemModule() {
+    public CustomItemModule(JavaPlugin plugin) {
+        super(plugin);
     }
 
+
     private static void registerAbilities(AbilityRegistry abilityRegistry) {
         abilityRegistry.register("test_handler", new TestAbilityHandler());
         abilityRegistry.register("rolling_dice", new RollingDiceAbility());
@@ -47,7 +50,7 @@ public class CustomItemModule extends BazaarFluxModule {
         ItemDefinitionValidator validator = new DefaultItemDefinitionValidator();
         ItemDefinitionLoader loader = new ItemDefinitionLoader(validator);
 
-        Main main = Services.get(Main.class);
+        Main main = FluxService.get(Main.class);
         File itemsDir = new File(main.getDataFolder(), "custom/items");
 
         // --- Load definitions from disk ---
@@ -64,21 +67,21 @@ public class CustomItemModule extends BazaarFluxModule {
 
         main.getServer().getPluginManager().registerEvents(listener, main);
 
-        // --- Services ---
-        Services.register(CustomItemRegistry.class, itemRegistry);
-        Services.register(ItemDefinitionLoader.class, loader);
-        Services.register(ItemDefinitionValidator.class, validator);
-        Services.register(AbilityRegistry.class, abilityRegistry);
+        // --- FluxService ---
+        FluxService.register(CustomItemRegistry.class, itemRegistry);
+        FluxService.register(ItemDefinitionLoader.class, loader);
+        FluxService.register(ItemDefinitionValidator.class, validator);
+        FluxService.register(AbilityRegistry.class, abilityRegistry);
         BlockRegistry blockRegistry = new BlockRegistry();
         main.getServer().getPluginManager().registerEvents(blockRegistry, main);
-        Services.register(BlockRegistry.class, blockRegistry);
+        FluxService.register(BlockRegistry.class, blockRegistry);
         registerCommands();
     }
 
     private void registerCommands() {
         CustomItemCommand customItemCommand = new CustomItemCommand(this);
-        Services.get(Main.class).getCommand("customItems").setExecutor(customItemCommand);
-        Services.get(Main.class).getCommand("customItems").setTabCompleter(customItemCommand);
+        FluxService.get(Main.class).getCommand("customItems").setExecutor(customItemCommand);
+        FluxService.get(Main.class).getCommand("customItems").setTabCompleter(customItemCommand);
     }
 
     @Override

+ 1 - 1
src/main/java/me/lethunderhawk/custom/item/abstraction/ability/AbilityDefinition.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.custom.item.abstraction.ability;
 
-import me.lethunderhawk.bazaarflux.util.itemdesign.LoreDesigner;
+import me.lethunderhawk.fluxapi.util.itemdesign.LoreDesigner;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 

+ 4 - 4
src/main/java/me/lethunderhawk/custom/item/abstraction/definition/ItemDefinitionLoader.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.custom.item.abstraction.definition;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.itemdesign.LoreDesigner;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.itemdesign.LoreDesigner;
 import me.lethunderhawk.custom.item.abstraction.ability.AbilityDefinition;
 import me.lethunderhawk.custom.item.abstraction.ability.AbilityTrigger;
 import me.lethunderhawk.main.Main;
@@ -160,12 +160,12 @@ public final class ItemDefinitionLoader {
                 }
 
                 if (abilityName == null) {
-                    Services.get(Main.class).getLogger().info("Missing ability Name in item " + id + ". Is this wanted? Using handler ID: " + handler_id + " as default.");
+                    FluxService.get(Main.class).getLogger().info("Missing ability Name in item " + id + ". Is this wanted? Using handler ID: " + handler_id + " as default.");
                     abilityName = handler_id;
                 }
 
                 if (abilityDescription == null) {
-                    Services.get(Main.class).getLogger().info("Missing ability Description in item " + id + ". Is this wanted?");
+                    FluxService.get(Main.class).getLogger().info("Missing ability Description in item " + id + ". Is this wanted?");
                 }
 
                 Map<String, String> params = new HashMap<>();

+ 1 - 1
src/main/java/me/lethunderhawk/custom/item/abstraction/definition/ItemVisualDefinition.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.custom.item.abstraction.definition;
 
-import me.lethunderhawk.bazaarflux.util.itemdesign.LoreDesigner;
+import me.lethunderhawk.fluxapi.util.itemdesign.LoreDesigner;
 import net.kyori.adventure.text.Component;
 import org.bukkit.Material;
 import org.bukkit.inventory.ItemFlag;

+ 0 - 3
src/main/java/me/lethunderhawk/custom/item/abstraction/instance/ItemInstanceReader.java

@@ -1,8 +1,5 @@
 package me.lethunderhawk.custom.item.abstraction.instance;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.custom.item.abstraction.definition.ItemDefinition;
-import me.lethunderhawk.custom.item.abstraction.registry.CustomItemRegistry;
 import me.lethunderhawk.custom.item.abstraction.util.JsonUtil;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.meta.ItemMeta;

+ 2 - 2
src/main/java/me/lethunderhawk/custom/item/abstraction/instance/ItemPersistentData.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.custom.item.abstraction.instance;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.custom.item.abstraction.util.JsonUtil;
 import me.lethunderhawk.main.Main;
 import org.bukkit.NamespacedKey;
@@ -9,7 +9,7 @@ import org.bukkit.persistence.PersistentDataContainer;
 import org.bukkit.persistence.PersistentDataType;
 
 public final class ItemPersistentData {
-    private static final Main main = Services.get(Main.class);
+    private static final Main main = FluxService.get(Main.class);
     static final NamespacedKey ITEM_ID =
             new NamespacedKey(main, "item_id");
 

+ 2 - 2
src/main/java/me/lethunderhawk/custom/item/abstraction/migration/MigrationService.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.custom.item.abstraction.migration;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.custom.item.abstraction.definition.ItemDefinition;
 import me.lethunderhawk.custom.item.abstraction.instance.ItemInstance;
 import me.lethunderhawk.custom.item.abstraction.instance.ItemInstanceReader;
@@ -21,7 +21,7 @@ public final class MigrationService {
         ItemInstance current = ItemInstanceReader.read(original);
         if (current == null) return original;
 
-        ItemDefinition latest = Services.get(CustomItemRegistry.class).get(current.itemId());
+        ItemDefinition latest = FluxService.get(CustomItemRegistry.class).get(current.itemId());
         if (latest == null) return original;
 
         if (current.version() == latest.version()) {

+ 2 - 2
src/main/java/me/lethunderhawk/custom/item/abstraction/registry/CustomItemRegistry.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.custom.item.abstraction.registry;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.custom.item.abstraction.definition.ItemDefinition;
 import me.lethunderhawk.main.Main;
 
@@ -23,7 +23,7 @@ public class CustomItemRegistry {
 
     public ItemDefinition get(String itemId) {
         ItemDefinition definition = definitions.get(itemId);
-        if(definition == null) Services.get(Main.class).getLogger().warning("Item " + itemId + " not found");
+        if(definition == null) FluxService.get(Main.class).getLogger().warning("Item " + itemId + " not found");
         return definition;
     }
 

+ 2 - 2
src/main/java/me/lethunderhawk/custom/item/abstraction/visual/ItemRenderer.java

@@ -1,11 +1,11 @@
 package me.lethunderhawk.custom.item.abstraction.visual;
 
-import me.lethunderhawk.bazaarflux.util.CustomHeadCreator;
+import me.lethunderhawk.fluxapi.util.CustomHeadCreator;
 import me.lethunderhawk.custom.item.abstraction.definition.ItemDefinition;
 import me.lethunderhawk.custom.item.abstraction.definition.ItemVisualDefinition;
 import me.lethunderhawk.custom.item.abstraction.instance.ItemInstance;
 import me.lethunderhawk.custom.item.abstraction.instance.ItemPersistentData;
-import me.lethunderhawk.main.util.UnItalic;
+import me.lethunderhawk.fluxapi.util.UnItalic;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 import org.bukkit.inventory.ItemFlag;

+ 4 - 4
src/main/java/me/lethunderhawk/custom/item/command/CustomItemCommand.java

@@ -1,13 +1,13 @@
 package me.lethunderhawk.custom.item.command;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.command.CommandNode;
-import me.lethunderhawk.bazaarflux.util.command.CustomCommand;
 import me.lethunderhawk.custom.item.CustomItemModule;
 import me.lethunderhawk.custom.item.abstraction.definition.ItemDefinition;
 import me.lethunderhawk.custom.item.abstraction.instance.ItemInstance;
 import me.lethunderhawk.custom.item.abstraction.migration.MigrationService;
 import me.lethunderhawk.custom.item.abstraction.registry.CustomItemRegistry;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.command.CommandNode;
+import me.lethunderhawk.fluxapi.util.command.CustomCommand;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
@@ -38,7 +38,7 @@ public class CustomItemCommand extends CustomCommand {
     }
 
     private void getAllItems(Player player) {
-        for (ItemDefinition definition : Services.get(CustomItemRegistry.class).getAll()) {
+        for (ItemDefinition definition : FluxService.get(CustomItemRegistry.class).getAll()) {
             ItemInstance instance = new ItemInstance(definition);
             player.getInventory().addItem(instance.buildItemStack());
         }

+ 5 - 5
src/main/java/me/lethunderhawk/custom/item/concrete/ability/ClaimToolAbility.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.custom.item.concrete.ability;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.clans.Clan;
 import me.lethunderhawk.clans.ClanManager;
 import me.lethunderhawk.clans.ClanModule;
@@ -37,7 +37,7 @@ public class ClaimToolAbility implements AbilityHandler {
     }
 
     private boolean hasEnoughClaimSpace(Player player, Clan clan, Claim claim) {
-        int maxBlocks = Services.get(Main.class).getConfig().getInt("claims.max-blocks");
+        int maxBlocks = FluxService.get(Main.class).getConfig().getInt("claims.max-blocks");
         int usedAfterClaim = clan.getUsedBlocks() + claim.getVolume();
 
         if (usedAfterClaim > maxBlocks) {
@@ -82,9 +82,9 @@ public class ClaimToolAbility implements AbilityHandler {
         UUID playerId = player.getUniqueId();
         Location clickedLocation = block.getLocation();
 
-        ClanModule clanModule = Services.get(ClanModule.class);
-        ClanManager clanManager = Services.get(ClanManager.class);
-        ClaimManager claimManager = Services.get(ClaimManager.class);
+        ClanModule clanModule = FluxService.get(ClanModule.class);
+        ClanManager clanManager = FluxService.get(ClanManager.class);
+        ClaimManager claimManager = FluxService.get(ClaimManager.class);
 
         Clan clan = clanManager.getMyClan(playerId);
         if (clan == null) {

+ 2 - 2
src/main/java/me/lethunderhawk/custom/item/concrete/ability/RegeneratingBlockAbility.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.custom.item.concrete.ability;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.custom.block.registry.BlockRegistry;
 import me.lethunderhawk.custom.item.abstraction.ability.AbilityContext;
 import me.lethunderhawk.custom.item.abstraction.handling.AbilityHandler;
@@ -28,7 +28,7 @@ public class RegeneratingBlockAbility implements AbilityHandler {
         
         Block clicked = event.getClickedBlock();
         clicked.setType(clicked.getType(), false);
-        BlockRegistry registry = Services.get(BlockRegistry.class);
+        BlockRegistry registry = FluxService.get(BlockRegistry.class);
 
 
         if (!registry.contains(clicked)) {

+ 4 - 4
src/main/java/me/lethunderhawk/custom/item/concrete/ability/RollingDiceAbility.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.custom.item.concrete.ability;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.loottables.RiggedChanceGenerator;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.loottables.RiggedChanceGenerator;
 import me.lethunderhawk.custom.item.abstraction.ability.AbilityContext;
 import me.lethunderhawk.custom.item.abstraction.handling.AbilityHandler;
 import me.lethunderhawk.custom.item.abstraction.handling.ResolvedParams;
@@ -39,7 +39,7 @@ public class RollingDiceAbility implements AbilityHandler {
 
 
     private boolean withdrawCost(Player player) {
-        EconomyAPI economy = Services.get(EconomyAPI.class);
+        EconomyAPI economy = FluxService.get(EconomyAPI.class);
         UUID uuid = player.getUniqueId();
 
         long balance = economy.getMoney(uuid);
@@ -51,7 +51,7 @@ public class RollingDiceAbility implements AbilityHandler {
 
     private void rollAndReward(Player player) {
         DiceReward result = rollDice();
-        EconomyAPI economy = Services.get(EconomyAPI.class);
+        EconomyAPI economy = FluxService.get(EconomyAPI.class);
 
         switch (result) {
             case SEVEN -> {

+ 2 - 2
src/main/java/me/lethunderhawk/custom/item/concrete/dice/RollingDiceAnimation.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.custom.item.concrete.dice;
 
-import me.lethunderhawk.bazaarflux.util.CustomHeadCreator;
-import me.lethunderhawk.bazaarflux.util.animation.Animation;
+import me.lethunderhawk.fluxapi.util.CustomHeadCreator;
+import me.lethunderhawk.fluxapi.util.animation.Animation;
 import org.bukkit.Location;
 import org.bukkit.entity.Display;
 import org.bukkit.entity.EntityType;

+ 11 - 6
src/main/java/me/lethunderhawk/dungeon/DungeonModule.java

@@ -1,13 +1,18 @@
 package me.lethunderhawk.dungeon;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.dungeon.command.DungeonCommand;
 import me.lethunderhawk.dungeon.manager.DungeonManager;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.main.Main;
+import org.bukkit.plugin.java.JavaPlugin;
 
 public class DungeonModule extends BazaarFluxModule {
 
+    public DungeonModule(JavaPlugin plugin) {
+        super(plugin);
+    }
+
     @Override
     public String getPrefix() {
         return "[Dungeons] ";
@@ -16,8 +21,8 @@ public class DungeonModule extends BazaarFluxModule {
     @Override
     public void onEnable() {
 
-        Main mainPlugin = Services.get(Main.class);
-        Services.register(DungeonManager.class, new DungeonManager());
+        Main mainPlugin = FluxService.get(Main.class);
+        FluxService.register(DungeonManager.class, new DungeonManager());
 
         mainPlugin.getCommand("dungeon").setExecutor(new DungeonCommand());
         mainPlugin.getCommand("dungeon").setTabCompleter(new DungeonCommand());
@@ -25,7 +30,7 @@ public class DungeonModule extends BazaarFluxModule {
 
     @Override
     public void onDisable() {
-        Services.get(DungeonManager.class).deleteAllDungeons();
-        Services.unregister(DungeonManager.class);
+        FluxService.get(DungeonManager.class).deleteAllDungeons();
+        FluxService.unregister(DungeonManager.class);
     }
 }

+ 8 - 8
src/main/java/me/lethunderhawk/dungeon/command/DungeonCommand.java

@@ -1,11 +1,11 @@
 package me.lethunderhawk.dungeon.command;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.command.CommandNode;
-import me.lethunderhawk.bazaarflux.util.command.CustomCommand;
 import me.lethunderhawk.dungeon.DungeonModule;
 import me.lethunderhawk.dungeon.generation.DungeonWorld;
 import me.lethunderhawk.dungeon.manager.DungeonManager;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.command.CommandNode;
+import me.lethunderhawk.fluxapi.util.command.CustomCommand;
 import me.lethunderhawk.main.Main;
 import org.bukkit.Bukkit;
 import org.bukkit.command.CommandSender;
@@ -16,7 +16,7 @@ public class DungeonCommand extends CustomCommand {
     public DungeonCommand() {
         super(
                 new CommandNode("dungeon", "Main Dungeon command", null),
-                Services.get(DungeonModule.class)
+                FluxService.get(DungeonModule.class)
         );
     }
 
@@ -41,12 +41,12 @@ public class DungeonCommand extends CustomCommand {
     }
 
     private void clearDungeons(CommandSender sender, String[] strings) {
-        Services.get(DungeonManager.class).deleteAllDungeons();
+        FluxService.get(DungeonManager.class).deleteAllDungeons();
     }
 
     private void testDungeon(CommandSender sender, String[] args) {
         if (!(sender instanceof Player player)) return;
-        DungeonManager manager = Services.get(DungeonManager.class);
+        DungeonManager manager = FluxService.get(DungeonManager.class);
         if(manager.isDungeonWorld(player.getWorld())) {
             backFromDungeon(sender, args);
         }
@@ -57,7 +57,7 @@ public class DungeonCommand extends CustomCommand {
     private void backFromDungeon(CommandSender sender, String[] args) {
         if (!(sender instanceof Player player)) return;
 
-        DungeonManager manager = Services.get(DungeonManager.class);
+        DungeonManager manager = FluxService.get(DungeonManager.class);
         DungeonWorld dungeon = manager.getDungeonByWorld(player.getWorld());
 
         if (dungeon == null) {
@@ -69,7 +69,7 @@ public class DungeonCommand extends CustomCommand {
 
         // Optional: auto-delete dungeon if empty
         Bukkit.getScheduler().runTaskLater(
-                Services.get(Main.class),
+                FluxService.get(Main.class),
                 () -> {
                     if (player.getWorld().getPlayers().isEmpty()) {
                         manager.deleteDungeon(dungeon.getUUID());

+ 7 - 7
src/main/java/me/lethunderhawk/dungeon/generation/DungeonGridGenerator.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.dungeon.generation;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.dungeon.placement.Rotation;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.world.util.schematic.Rotation;
 import me.lethunderhawk.dungeon.placement.SchematicRoomPlacer;
 import me.lethunderhawk.main.Main;
 import org.bukkit.Location;
@@ -804,15 +804,15 @@ public class DungeonGridGenerator {
         String strType = type.toString();
         int randomInt = random.nextInt(4);
         if(connectionType == ConnectionType.SINGLE){
-            return new File(Services.get(Main.class).getDataFolder(), "rooms/single_entrance/" + strType + randomInt +".schem");
+            return new File(FluxService.get(Main.class).getDataFolder(), "rooms/single_entrance/" + strType + randomInt +".schem");
         }else if(connectionType == ConnectionType.STRAIGHT){
-            return new File(Services.get(Main.class).getDataFolder(), "rooms/straight/" + strType + randomInt +".schem");
+            return new File(FluxService.get(Main.class).getDataFolder(), "rooms/straight/" + strType + randomInt +".schem");
         }else if(connectionType == ConnectionType.T){
-            return new File(Services.get(Main.class).getDataFolder(), "rooms/T_connection/" + strType + randomInt +".schem");
+            return new File(FluxService.get(Main.class).getDataFolder(), "rooms/T_connection/" + strType + randomInt +".schem");
         }else if(connectionType == ConnectionType.TURN_LEFT){
-            return new File(Services.get(Main.class).getDataFolder(), "rooms/turn_left/" + strType + randomInt +".schem");
+            return new File(FluxService.get(Main.class).getDataFolder(), "rooms/turn_left/" + strType + randomInt +".schem");
         }else if(connectionType == ConnectionType.HUB){
-            return new File(Services.get(Main.class).getDataFolder(), "rooms/hubs/" + strType + randomInt +".schem");
+            return new File(FluxService.get(Main.class).getDataFolder(), "rooms/hubs/" + strType + randomInt +".schem");
         }
         return null;
     }

+ 3 - 3
src/main/java/me/lethunderhawk/dungeon/generation/DungeonWorld.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.dungeon.generation;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.dungeon.manager.DungeonManager;
 import me.lethunderhawk.main.Main;
 import org.bukkit.*;
@@ -23,7 +23,7 @@ public class DungeonWorld implements Listener {
     private final Map<UUID, Location> returnLocations = new HashMap<>();
 
     public DungeonWorld() {
-        this.plugin = Services.get(Main.class);
+        this.plugin = FluxService.get(Main.class);
         this.uuid  = UUID.randomUUID();
 
         Bukkit.getPluginManager().registerEvents(this, plugin);
@@ -122,7 +122,7 @@ public class DungeonWorld implements Listener {
         // Delay teleport to avoid respawn conflicts
         Bukkit.getScheduler().runTask(plugin, () -> {
             returnPlayer(player);
-            Services.get(DungeonManager.class).deleteDungeon(this.uuid);
+            FluxService.get(DungeonManager.class).deleteDungeon(this.uuid);
         });
     }
 

+ 1 - 1
src/main/java/me/lethunderhawk/dungeon/gui/DungeonGUI.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.dungeon.gui;
 
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
 
 public class DungeonGUI extends InventoryGUI {
 

+ 2 - 0
src/main/java/me/lethunderhawk/dungeon/placement/RoomMetadata.java

@@ -1,5 +1,7 @@
 package me.lethunderhawk.dungeon.placement;
 
+import me.lethunderhawk.world.util.schematic.Vector3i;
+
 public class RoomMetadata {
     public String roomType;
     public Vector3i anchor;

+ 1 - 0
src/main/java/me/lethunderhawk/dungeon/placement/RotatableBoundingBox.java

@@ -1,4 +1,5 @@
 package me.lethunderhawk.dungeon.placement;
+import me.lethunderhawk.world.util.schematic.Rotation;
 import org.bukkit.util.BoundingBox;
 
 public class RotatableBoundingBox {

+ 2 - 0
src/main/java/me/lethunderhawk/dungeon/placement/SchematicRoomPlacer.java

@@ -13,6 +13,8 @@ import com.sk89q.worldedit.function.operation.Operations;
 import com.sk89q.worldedit.math.BlockVector3;
 import com.sk89q.worldedit.session.ClipboardHolder;
 import com.sk89q.worldedit.bukkit.BukkitAdapter;
+import me.lethunderhawk.world.util.schematic.Rotation;
+import me.lethunderhawk.world.util.schematic.Vector3i;
 import org.bukkit.Location;
 import org.bukkit.World;
 import org.bukkit.util.BoundingBox;

+ 0 - 3
src/main/java/me/lethunderhawk/dungeon/placement/Vector3i.java

@@ -1,3 +0,0 @@
-package me.lethunderhawk.dungeon.placement;
-
-public record Vector3i(int x, int y, int z) {}

+ 6 - 4
src/main/java/me/lethunderhawk/economy/EconomyModule.java

@@ -1,13 +1,13 @@
 package me.lethunderhawk.economy;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.economy.api.EconomyAPI;
 import me.lethunderhawk.economy.api.EconomyPlaceholder;
 import me.lethunderhawk.economy.command.EcoCommand;
 import me.lethunderhawk.economy.currency.EconomyManager;
 import me.lethunderhawk.economy.listener.PlayerJoinListener;
 import me.lethunderhawk.economy.scoreboard.ScoreboardManager;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.tradeplugin.api.TradePlaceholder;
 import org.bukkit.plugin.java.JavaPlugin;
 
@@ -15,7 +15,9 @@ public class EconomyModule extends BazaarFluxModule {
 
     private EconomyAPI economyAPI;
     private ScoreboardManager scoreboardManager;
-    public EconomyModule() {
+
+    public EconomyModule(JavaPlugin plugin) {
+        super(plugin);
     }
 
     @Override
@@ -31,7 +33,7 @@ public class EconomyModule extends BazaarFluxModule {
         EconomyManager economyManager = new EconomyManager();
 
         economyAPI = new EconomyAPI(economyManager);
-        Services.register(EconomyAPI.class, economyAPI);
+        FluxService.register(EconomyAPI.class, economyAPI);
         scoreboardManager = new ScoreboardManager(this);
 
         plugin.getCommand("eco").setExecutor(new EcoCommand(this));

+ 2 - 2
src/main/java/me/lethunderhawk/economy/command/EcoCommand.java

@@ -1,9 +1,9 @@
 package me.lethunderhawk.economy.command;
 
-import me.lethunderhawk.bazaarflux.util.command.CommandNode;
-import me.lethunderhawk.bazaarflux.util.command.CustomCommand;
 import me.lethunderhawk.economy.EconomyModule;
 import me.lethunderhawk.economy.api.EconomyAPI;
+import me.lethunderhawk.fluxapi.util.command.CommandNode;
+import me.lethunderhawk.fluxapi.util.command.CustomCommand;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 import org.bukkit.Bukkit;

+ 2 - 2
src/main/java/me/lethunderhawk/economy/currency/EconomyManager.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.economy.currency;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.economy.EconomyModule;
 import org.bukkit.configuration.file.FileConfiguration;
 
@@ -12,7 +12,7 @@ public class EconomyManager {
     private final FileConfiguration config;
 
     public EconomyManager() {
-        this.module = Services.get(EconomyModule.class);
+        this.module = FluxService.get(EconomyModule.class);
         this.config = module.getPlugin().getConfig();
     }
 

+ 8 - 7
src/main/java/me/lethunderhawk/main/Main.java

@@ -1,14 +1,15 @@
 package me.lethunderhawk.main;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.gui.InventoryManager;
-import me.lethunderhawk.bazaarflux.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.clans.ClanModule;
 import me.lethunderhawk.custom.item.CustomItemModule;
 import me.lethunderhawk.dungeon.DungeonModule;
 import me.lethunderhawk.economy.EconomyModule;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.gui.InventoryManager;
+import me.lethunderhawk.fluxapi.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.minion.MinionModule;
 import me.lethunderhawk.tradeplugin.TradeModule;
+import me.lethunderhawk.world.WorldModule;
 import org.bukkit.plugin.java.JavaPlugin;
 
 import java.util.ArrayList;
@@ -19,10 +20,10 @@ public class Main extends JavaPlugin{
     private final List<BazaarFluxModule> bazaarFluxModules = new ArrayList<>();
     @Override
     public void onEnable() {
-        Services.register(Main.class, this);
+        FluxService.register(Main.class, this);
 
         InventoryManager.register(this);
-        registerAllModules(new CustomItemModule(), new TradeModule(), new ClanModule(), new EconomyModule(), new MinionModule(), new DungeonModule());
+        registerAllModules(new CustomItemModule(this), new TradeModule(this), new ClanModule(this), new EconomyModule(this), new MinionModule(this), new DungeonModule(this), new WorldModule(this));
     }
     private void registerAllModules(BazaarFluxModule... modules){
         for(BazaarFluxModule module : modules){
@@ -31,7 +32,7 @@ public class Main extends JavaPlugin{
         }
     }
     private void registerModule(BazaarFluxModule module){
-        Services.registerModule(module.getClass(), module);
+        FluxService.registerModule(module.getClass(), module);
         module.onEnable();
     }
 
@@ -39,7 +40,7 @@ public class Main extends JavaPlugin{
     public void onDisable(){
         for(BazaarFluxModule module : bazaarFluxModules){
             module.onDisable();
-            Services.unregisterModule(module.getClass());
+            FluxService.unregisterModule(module.getClass());
         }
     }
 

+ 0 - 36
src/main/java/me/lethunderhawk/main/util/UnItalic.java

@@ -1,36 +0,0 @@
-package me.lethunderhawk.main.util;
-
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
-import net.kyori.adventure.text.format.TextDecoration;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class UnItalic {
-    public static Component removeItalic(Component component){
-        return component.decoration(TextDecoration.ITALIC, false);
-    }
-    public static List<Component> removeItalic(List<Component> components){
-        List<Component> newComponents = new ArrayList<>();
-        for(Component component : components){
-            newComponents.add(component.decoration(TextDecoration.ITALIC, false));
-        }
-        return newComponents;
-    }
-    public static Component text(String text){
-        return removeItalic(Component.text(text, NamedTextColor.GRAY));
-    }
-
-    /**
-     *
-     * @param itemMeta The {@link ItemMeta} you want to remove the Italic from
-     * @return The {@link ItemMeta} with Italic style removed from lore and displayName
-     */
-    public static ItemMeta removeItalicFromMeta(ItemMeta itemMeta) {
-        if(itemMeta.hasLore()) itemMeta.lore(removeItalic(itemMeta.lore()));
-        if(itemMeta.hasDisplayName()) itemMeta.displayName(removeItalic(itemMeta.displayName()));
-        return itemMeta;
-    }
-}

+ 7 - 4
src/main/java/me/lethunderhawk/minion/MinionModule.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.minion;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.interfaces.BazaarFluxModule;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.main.Main;
 import me.lethunderhawk.minion.command.MinionCommand;
 import me.lethunderhawk.minion.enchantedVariant.item.EnchantedCobblestone;
@@ -21,6 +21,7 @@ import me.lethunderhawk.minion.runtime.PlacedMinion;
 import org.bukkit.Material;
 import org.bukkit.event.HandlerList;
 import org.bukkit.inventory.ItemStack;
+import org.bukkit.plugin.java.JavaPlugin;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -33,9 +34,11 @@ public class MinionModule extends BazaarFluxModule {
     private MinionStorage storage;
     private RecipeManager recipeManager;
 
-    public MinionModule() {
+    public MinionModule(JavaPlugin plugin) {
+        super(plugin);
     }
 
+
     @Override
     public String getPrefix() {
         return "[Minions]";
@@ -60,7 +63,7 @@ public class MinionModule extends BazaarFluxModule {
 
     private void customRecipes() {
 
-        this.recipeManager = new RecipeManager(Services.get(Main.class));
+        this.recipeManager = new RecipeManager(FluxService.get(Main.class));
         plugin.getServer().getPluginManager().registerEvents(new DisableEnchantedItemPlacingListener(), plugin);
 
         registerRecipes();

+ 2 - 2
src/main/java/me/lethunderhawk/minion/api/MinionLevel.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.minion.api;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.main.Main;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
@@ -20,7 +20,7 @@ public class MinionLevel {
 
     public MinionLevelTable create() {
 
-        JavaPlugin plugin = Services.get(Main.class);
+        JavaPlugin plugin = FluxService.get(Main.class);
         // Return cached version if available
 
         Map<Integer, MinionLevelData> levelDataMap = new HashMap<>();

+ 3 - 3
src/main/java/me/lethunderhawk/minion/command/MinionCommand.java

@@ -1,8 +1,8 @@
 package me.lethunderhawk.minion.command;
 
-import me.lethunderhawk.bazaarflux.util.command.CommandNode;
-import me.lethunderhawk.bazaarflux.util.command.CustomCommand;
-import me.lethunderhawk.bazaarflux.util.gui.InventoryManager;
+import me.lethunderhawk.fluxapi.util.command.CommandNode;
+import me.lethunderhawk.fluxapi.util.command.CustomCommand;
+import me.lethunderhawk.fluxapi.util.gui.InventoryManager;
 import me.lethunderhawk.minion.MinionModule;
 import me.lethunderhawk.minion.manager.MinionManager;
 import me.lethunderhawk.minion.ui.minionList.MinionLevelListMenu;

+ 3 - 3
src/main/java/me/lethunderhawk/minion/enchantedVariant/item/abstraction/EnchantedItem.java

@@ -1,8 +1,8 @@
 package me.lethunderhawk.minion.enchantedVariant.item.abstraction;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.main.Main;
-import me.lethunderhawk.main.util.UnItalic;
+import me.lethunderhawk.fluxapi.util.UnItalic;
 import net.kyori.adventure.text.Component;
 import org.bukkit.Material;
 import org.bukkit.NamespacedKey;
@@ -31,7 +31,7 @@ public abstract class EnchantedItem {
         this.lore = lore;
         this.baseMaterial = baseMaterial;
         this.itemId = itemId;
-        this.itemIdKey = new NamespacedKey(Services.get(Main.class), itemId);
+        this.itemIdKey = new NamespacedKey(FluxService.get(Main.class), itemId);
         this.itemStack = createItem();
     }
 

+ 2 - 2
src/main/java/me/lethunderhawk/minion/enchantedVariant/recipe/EnchantedItemRecipe.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.minion.enchantedVariant.recipe;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.main.Main;
 import org.bukkit.Bukkit;
 import org.bukkit.Material;
@@ -106,7 +106,7 @@ public class EnchantedItemRecipe implements Recipe {
     }
 
     public static void register(Material ingredient, ItemStack result) {
-        Plugin plugin = Services.get(Main.class); // Replace with your plugin name
+        Plugin plugin = FluxService.get(Main.class); // Replace with your plugin name
 
         NamespacedKey key = new NamespacedKey(plugin,
                 "enchanted_" + ingredient.name().toLowerCase());

+ 3 - 4
src/main/java/me/lethunderhawk/minion/impl/behavior/CobbleMinionBehavior.java

@@ -1,11 +1,10 @@
 package me.lethunderhawk.minion.impl.behavior;
 
-import me.lethunderhawk.bazaarflux.util.gui.InventoryManager;
-import me.lethunderhawk.minion.api.NextActionState;
 import me.lethunderhawk.minion.api.MinionBehavior;
+import me.lethunderhawk.minion.api.NextActionState;
 import me.lethunderhawk.minion.runtime.PlacedMinion;
-import org.bukkit.inventory.ItemStack;
 import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
 
 public class CobbleMinionBehavior implements MinionBehavior {
     private NextActionState actionstate = NextActionState.PLACING;
@@ -13,7 +12,7 @@ public class CobbleMinionBehavior implements MinionBehavior {
     public void performAction(PlacedMinion minion) {
         ItemStack cobble = new ItemStack(Material.COBBLESTONE, 1);
         minion.addItem(cobble);
-        InventoryManager.refreshMinionMenuForPlayer(minion.getOwnerId(), minion.getMinionId());
+        //InventoryManager.refreshMinionMenuForPlayer(minion.getOwnerId(), minion.getMinionId());
     }
     private void breakBlock(){
         // choose a random cobblestone block

+ 1 - 2
src/main/java/me/lethunderhawk/minion/impl/behavior/RedstoneMinionBehavior.java

@@ -1,6 +1,5 @@
 package me.lethunderhawk.minion.impl.behavior;
 
-import me.lethunderhawk.bazaarflux.util.gui.InventoryManager;
 import me.lethunderhawk.minion.api.MinionBehavior;
 import me.lethunderhawk.minion.runtime.PlacedMinion;
 import org.bukkit.Material;
@@ -11,7 +10,7 @@ public class RedstoneMinionBehavior implements MinionBehavior {
     public void performAction(PlacedMinion minion) {
         ItemStack redstone = new ItemStack(Material.REDSTONE, 1);
         minion.addItem(redstone);
-        InventoryManager.refreshMinionMenuForPlayer(minion.getOwnerId(), minion.getMinionId());
+        //InventoryManager.refreshMinionMenuForPlayer(minion.getOwnerId(), minion.getMinionId());
     }
     private void breakBlock(){
 

+ 5 - 5
src/main/java/me/lethunderhawk/minion/item/MinionItem.java

@@ -1,10 +1,10 @@
 package me.lethunderhawk.minion.item;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.CustomHeadCreator;
-import me.lethunderhawk.bazaarflux.util.lang.RomanNumbers;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.CustomHeadCreator;
+import me.lethunderhawk.fluxapi.util.lang.RomanNumbers;
 import me.lethunderhawk.main.Main;
-import me.lethunderhawk.main.util.UnItalic;
+import me.lethunderhawk.fluxapi.util.UnItalic;
 import me.lethunderhawk.minion.api.MinionType;
 import me.lethunderhawk.minion.registry.MinionRegistry;
 import net.kyori.adventure.text.Component;
@@ -23,7 +23,7 @@ public class MinionItem {
     private final NamespacedKey levelKey;
 
     public MinionItem() {
-        Main plugin = Services.get(Main.class);
+        Main plugin = FluxService.get(Main.class);
         this.typeKey = new NamespacedKey(plugin, "minion_type");
         this.levelKey = new NamespacedKey(plugin, "minion_level");
     }

+ 1 - 1
src/main/java/me/lethunderhawk/minion/listener/MinionListener.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.minion.listener;
 
-import me.lethunderhawk.bazaarflux.util.gui.InventoryManager;
+import me.lethunderhawk.fluxapi.util.gui.InventoryManager;
 import me.lethunderhawk.minion.api.MinionType;
 import me.lethunderhawk.minion.item.MinionItem;
 import me.lethunderhawk.minion.manager.MinionManager;

+ 1 - 1
src/main/java/me/lethunderhawk/minion/runtime/PlacedMinion.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.minion.runtime;
 
-import me.lethunderhawk.bazaarflux.util.lang.RomanNumbers;
+import me.lethunderhawk.fluxapi.util.lang.RomanNumbers;
 import me.lethunderhawk.minion.api.MinionType;
 import me.lethunderhawk.minion.factory.MinionFactory;
 import org.bukkit.Bukkit;

+ 5 - 6
src/main/java/me/lethunderhawk/minion/ui/MinionMenu.java

@@ -1,10 +1,10 @@
 package me.lethunderhawk.minion.ui;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
-import me.lethunderhawk.bazaarflux.util.gui.InventoryManager;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
+import me.lethunderhawk.fluxapi.util.gui.InventoryManager;
 import me.lethunderhawk.main.Main;
-import me.lethunderhawk.main.util.UnItalic;
+import me.lethunderhawk.fluxapi.util.UnItalic;
 import me.lethunderhawk.minion.api.MinionLevelData;
 import me.lethunderhawk.minion.manager.MinionManager;
 import me.lethunderhawk.minion.registry.MinionRegistry;
@@ -52,14 +52,13 @@ public class MinionMenu extends InventoryGUI implements InventoryGUI.AutoCloseHa
         ItemStack collectItem = buildCollectResourcesItem();
         setItemWithClickAction(48, collectItem, (p, type) -> {
             minion.pickupAllItems();
-            InventoryManager.refreshMinionMenuForPlayer(p.getUniqueId(), minion.getMinionId());
         });
 
         // Quick upgrade button
         ItemStack upgradeItem = buildQuickUpgradeItem();
         setItemWithClickAction(50, upgradeItem, (p, type) -> {
 
-            JavaPlugin plugin = Services.get(Main.class);
+            JavaPlugin plugin = FluxService.get(Main.class);
             PlacedMinion newMinion = minion.getUpgrade(plugin);
             if(newMinion != null) {
                 MinionManager.stopAndUnregister(minion);

+ 2 - 2
src/main/java/me/lethunderhawk/minion/ui/minionList/MinionLevelListMenu.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.minion.ui.minionList;
 
-import me.lethunderhawk.bazaarflux.util.gui.GoBackItem;
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
+import me.lethunderhawk.fluxapi.util.gui.GoBackItem;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
 import me.lethunderhawk.minion.api.MinionLevelData;
 import me.lethunderhawk.minion.api.MinionLevelTable;
 import me.lethunderhawk.minion.factory.MinionFactory;

+ 1 - 1
src/main/java/me/lethunderhawk/minion/ui/minionList/MinionListMenu.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.minion.ui.minionList;
 
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
 import me.lethunderhawk.minion.api.MinionType;
 import me.lethunderhawk.minion.factory.MinionFactory;
 import me.lethunderhawk.minion.registry.MinionRegistry;

+ 4 - 2
src/main/java/me/lethunderhawk/tradeplugin/TradeModule.java

@@ -1,19 +1,21 @@
 package me.lethunderhawk.tradeplugin;
 
-import me.lethunderhawk.bazaarflux.util.interfaces.BazaarFluxModule;
+import me.lethunderhawk.fluxapi.util.interfaces.BazaarFluxModule;
 import me.lethunderhawk.tradeplugin.command.TradeAcceptCommand;
 import me.lethunderhawk.tradeplugin.command.TradeCommand;
 import me.lethunderhawk.tradeplugin.listener.PlayerInteractListener;
 import me.lethunderhawk.tradeplugin.listener.TradeInventoryListener;
 import me.lethunderhawk.tradeplugin.trade.TradeManager;
 import me.lethunderhawk.tradeplugin.trade.TradeRequestManager;
+import org.bukkit.plugin.java.JavaPlugin;
 
 public class TradeModule extends BazaarFluxModule {
 
     private static TradeManager tradeManager;
     private static TradeRequestManager requestManager;
 
-    public TradeModule() {
+    public TradeModule(JavaPlugin plugin) {
+        super(plugin);
     }
 
     @Override

+ 2 - 2
src/main/java/me/lethunderhawk/tradeplugin/command/TradeAcceptCommand.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.tradeplugin.command;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.tradeplugin.TradeModule;
 import me.lethunderhawk.tradeplugin.trade.TradeManager;
 import me.lethunderhawk.tradeplugin.trade.TradeRequestManager;
@@ -21,7 +21,7 @@ public class TradeAcceptCommand implements CommandExecutor {
     public TradeAcceptCommand() {
         this.requestManager = TradeModule.getRequestManager();
         this.tradeManager = TradeModule.getTradeManager();
-        this.tradeModule = Services.get(TradeModule.class);
+        this.tradeModule = FluxService.get(TradeModule.class);
     }
 
     @Override

+ 2 - 2
src/main/java/me/lethunderhawk/tradeplugin/command/TradeCommand.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.tradeplugin.command;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.tradeplugin.TradeModule;
 import me.lethunderhawk.tradeplugin.trade.TradeManager;
 import me.lethunderhawk.tradeplugin.trade.TradeRequestManager;
@@ -21,7 +21,7 @@ public class TradeCommand implements CommandExecutor {
     public TradeCommand() {
         this.tradeManager = TradeModule.getTradeManager();
         this.requestManager = TradeModule.getRequestManager();
-        this.tradeModule = Services.get(TradeModule.class);
+        this.tradeModule = FluxService.get(TradeModule.class);
     }
 
     @Override

+ 2 - 2
src/main/java/me/lethunderhawk/tradeplugin/input/player/NumberInputGUI.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.tradeplugin.input.player;
 
-import me.lethunderhawk.bazaarflux.util.gui.InventoryGUI;
-import me.lethunderhawk.bazaarflux.util.gui.InventoryManager;
+import me.lethunderhawk.fluxapi.util.gui.InventoryGUI;
+import me.lethunderhawk.fluxapi.util.gui.InventoryManager;
 import net.kyori.adventure.text.Component;
 import org.bukkit.Bukkit;
 import org.bukkit.Material;

+ 7 - 7
src/main/java/me/lethunderhawk/tradeplugin/listener/TradeInventoryListener.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.tradeplugin.listener;
 
-import me.lethunderhawk.bazaarflux.service.Services;
-import me.lethunderhawk.bazaarflux.util.gui.input.SignMenuFactory;
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.gui.input.SignMenuFactory;
 import me.lethunderhawk.economy.api.EconomyAPI;
 import me.lethunderhawk.economy.util.EconomyUtil;
 import me.lethunderhawk.main.Main;
@@ -107,27 +107,27 @@ public class TradeInventoryListener implements Listener {
     }
 
     private void openSignMenu(Player p) {
-        SignMenuFactory.Menu signInput = new SignMenuFactory(Services.get(Main.class)).newMenu(List.of("", "^^^^^^^^^^^^", "Input the amount", "to trade"))
+        SignMenuFactory.Menu signInput = new SignMenuFactory(FluxService.get(Main.class)).newMenu(List.of("", "^^^^^^^^^^^^", "Input the amount", "to trade"))
                 .reopenIfFail(true)
                 .response((player, input) -> {
                     long value = EconomyUtil.longFromString(input[0]);
                     TradeSession originalSession = manager.getSession(player);
                     if (value > 0) {
-                        if(Services.get(EconomyAPI.class).getMoney(player.getUniqueId()) >= originalSession.getMoneyFor(p) + value){
+                        if(FluxService.get(EconomyAPI.class).getMoney(player.getUniqueId()) >= originalSession.getMoneyFor(p) + value){
                             if(originalSession.addFluxValue(player, value)){
                                 player.openInventory(originalSession.getTradeInventory().getInventoryFor(player));
                             }else{
-                                Services.get(TradeModule.class).sendText(player, Component.text("No free space in menu!"));
+                                FluxService.get(TradeModule.class).sendText(player, Component.text("No free space in menu!"));
                                 return false;
                             }
                         }else{
-                            Services.get(TradeModule.class).sendText(player,Component.text("You don't have enough money!", NamedTextColor.RED));
+                            FluxService.get(TradeModule.class).sendText(player,Component.text("You don't have enough money!", NamedTextColor.RED));
                             return false;
                         }
                     } else if(value == 0) {
                         return true;
                     }else{
-                        Services.get(TradeModule.class).sendText(player,Component.text("You cant pay negative amounts!!", NamedTextColor.RED));
+                        FluxService.get(TradeModule.class).sendText(player,Component.text("You cant pay negative amounts!!", NamedTextColor.RED));
                         player.openInventory(originalSession.getTradeInventory().getInventoryFor(player));
                         return false;
                     }

+ 2 - 2
src/main/java/me/lethunderhawk/tradeplugin/trade/TradeInventory.java

@@ -1,7 +1,7 @@
 package me.lethunderhawk.tradeplugin.trade;
 
-import me.lethunderhawk.bazaarflux.util.CustomHeadCreator;
-import me.lethunderhawk.main.util.UnItalic;
+import me.lethunderhawk.fluxapi.util.CustomHeadCreator;
+import me.lethunderhawk.fluxapi.util.UnItalic;
 import net.kyori.adventure.text.Component;
 import net.kyori.adventure.text.format.NamedTextColor;
 import net.kyori.adventure.text.format.Style;

+ 8 - 8
src/main/java/me/lethunderhawk/tradeplugin/trade/TradeRequestManager.java

@@ -1,6 +1,6 @@
 package me.lethunderhawk.tradeplugin.trade;
 
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.main.Main;
 import me.lethunderhawk.tradeplugin.TradeModule;
 import net.kyori.adventure.key.Key;
@@ -35,8 +35,8 @@ public class TradeRequestManager {
                     ).append(
                             Component.text(" angenommen.").color(NamedTextColor.YELLOW)
                     );
-            Services.get(TradeModule.class).sendText(sender, sendermsg);
-            Services.get(TradeModule.class).sendText(target, targetmsg);
+            FluxService.get(TradeModule.class).sendText(sender, sendermsg);
+            FluxService.get(TradeModule.class).sendText(target, targetmsg);
 
             TradeModule.getTradeManager().startTrade(sender, target);
 
@@ -63,8 +63,8 @@ public class TradeRequestManager {
                     ).append(
                             Component.text(" gesendet").color(NamedTextColor.YELLOW)
                     );
-            Services.get(TradeModule.class).sendText(sender, sendermsg);
-            Services.get(TradeModule.class).sendText(target, targetmsg);
+            FluxService.get(TradeModule.class).sendText(sender, sendermsg);
+            FluxService.get(TradeModule.class).sendText(target, targetmsg);
 
             target.playSound(
                     Sound.sound()
@@ -77,12 +77,12 @@ public class TradeRequestManager {
             );
 
             int task = Bukkit.getScheduler().scheduleSyncDelayedTask(
-                    Services.get(Main.class),
+                    FluxService.get(Main.class),
                     () -> {
                         if (isPending(target, sender)) {
                             requests.remove(target.getUniqueId());
-                            Services.get(TradeModule.class).sendText(sender, Component.text("Deine Handelsanfrage an " + target.getName() + " ist abgelaufen.", NamedTextColor.RED));
-                            Services.get(TradeModule.class).sendText(target, Component.text("Die Handelsanfrage von " + sender.getName() + " ist abgelaufen.", NamedTextColor.RED));
+                            FluxService.get(TradeModule.class).sendText(sender, Component.text("Deine Handelsanfrage an " + target.getName() + " ist abgelaufen.", NamedTextColor.RED));
+                            FluxService.get(TradeModule.class).sendText(target, Component.text("Die Handelsanfrage von " + sender.getName() + " ist abgelaufen.", NamedTextColor.RED));
                         }
                     },
                     20L * 60 // 1 Minute

+ 9 - 9
src/main/java/me/lethunderhawk/tradeplugin/trade/TradeSession.java

@@ -1,10 +1,10 @@
 package me.lethunderhawk.tradeplugin.trade;
 
 import me.clip.placeholderapi.PlaceholderAPI;
-import me.lethunderhawk.bazaarflux.service.Services;
+import me.lethunderhawk.fluxapi.FluxService;
 import me.lethunderhawk.economy.api.EconomyAPI;
 import me.lethunderhawk.main.Main;
-import me.lethunderhawk.main.util.UnItalic;
+import me.lethunderhawk.fluxapi.util.UnItalic;
 import me.lethunderhawk.tradeplugin.TradeModule;
 import net.kyori.adventure.audience.Audience;
 import net.kyori.adventure.text.Component;
@@ -30,11 +30,11 @@ public class TradeSession {
     private final List<ItemStack> p1Items = new ArrayList<>();
     private final List<ItemStack> p2Items = new ArrayList<>();
     private static final NamespacedKey FLUX_KEY =
-            new NamespacedKey(Services.get(Main.class), "flux_item");
+            new NamespacedKey(FluxService.get(Main.class), "flux_item");
     private static final NamespacedKey OWNER_KEY =
-            new NamespacedKey(Services.get(Main.class), "flux_owner");
+            new NamespacedKey(FluxService.get(Main.class), "flux_owner");
     private static final NamespacedKey VALUE_KEY =
-            new NamespacedKey(Services.get(Main.class), "flux_value");
+            new NamespacedKey(FluxService.get(Main.class), "flux_value");
 
     private TradeState state = TradeState.WAITING;
     private long p1Flux = 0, p2Flux = 0;
@@ -132,12 +132,12 @@ public class TradeSession {
 
     }
     private void sendReceivingMsg(Audience receiver, Component itemName, int amount){
-        Services.get(TradeModule.class).sendText(receiver, Component.text("+ ", NamedTextColor.GREEN )
+        FluxService.get(TradeModule.class).sendText(receiver, Component.text("+ ", NamedTextColor.GREEN )
                 .append(itemName.color(NamedTextColor.GRAY))
                 .append(Component.text((amount> 1 ? " x" + amount : ""), NamedTextColor.GRAY)));
     }
     private void sendGivingMsg(Audience receiver, Component itemName, int amount){
-        Services.get(TradeModule.class).sendText(receiver, Component.text("- ", NamedTextColor.RED )
+        FluxService.get(TradeModule.class).sendText(receiver, Component.text("- ", NamedTextColor.RED )
                 .append(itemName.color(NamedTextColor.GRAY))
                 .append(Component.text((amount> 1 ? " x" + amount : ""), NamedTextColor.GRAY)));
     }
@@ -154,7 +154,7 @@ public class TradeSession {
     }
 
     private void sendTradeCompletedLine(Player receiver, Player other) {
-        Services.get(TradeModule.class).sendText(receiver,
+        FluxService.get(TradeModule.class).sendText(receiver,
                 Component.text("Handel mit ", NamedTextColor.GOLD)
                         .append(other.displayName().color(NamedTextColor.GRAY))
                         .append(Component.text(" abgeschlossen!", NamedTextColor.GOLD))
@@ -180,7 +180,7 @@ public class TradeSession {
     }
 
     private void transferFlux() {
-        EconomyAPI eco = Services.get(EconomyAPI.class);
+        EconomyAPI eco = FluxService.get(EconomyAPI.class);
         if(p2Flux > 0){
             eco.pay(p2.getUniqueId(), p1.getUniqueId(), p2Flux);
         }

+ 68 - 0
src/main/java/me/lethunderhawk/world/WorldModule.java

@@ -0,0 +1,68 @@
+package me.lethunderhawk.world;
+
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.interfaces.BazaarFluxModule;
+import me.lethunderhawk.main.Main;
+import me.lethunderhawk.world.command.WorldCommand;
+import me.lethunderhawk.world.island.IslandBootstrapListener;
+import me.lethunderhawk.world.util.WorldManager;
+import org.bukkit.event.HandlerList;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.io.File;
+import java.util.Objects;
+
+public class WorldModule extends BazaarFluxModule {
+
+    private IslandBootstrapListener bootstrapListener;
+
+    public WorldModule(JavaPlugin plugin) {
+        super(plugin);
+    }
+
+    @Override
+    public String getPrefix() {
+        return "[World]";
+    }
+
+    @Override
+    public void onEnable() {
+        // Ordner im Server-Verzeichnis erstellen
+        Main main = FluxService.get(Main.class);
+        //dungeonsFolder = new File(main.getServer().getWorldContainer(), "dungeons");
+        //private File dungeonsFolder;
+        File islandsFolder = new File(main.getServer().getWorldContainer(), "islands");
+
+        /*if (!dungeonsFolder.exists()) {
+            dungeonsFolder.mkdirs();
+        }*/
+
+        if (!islandsFolder.exists()) {
+            islandsFolder.mkdirs();
+        }
+        WorldManager worldManager = new WorldManager();
+        FluxService.register(WorldManager.class, worldManager);
+
+        main.getLogger().info("World folders initialized!");
+        registerCommands(main);
+
+        registerBootsTrapper(main);
+    }
+
+    private void registerBootsTrapper(Main main) {
+        File file = new File(main.getDataFolder() + "/island", "default_island.schem");
+        this.bootstrapListener = new IslandBootstrapListener(file);
+        main.getServer().getPluginManager().registerEvents(bootstrapListener, main);
+    }
+
+    private void registerCommands(Main main) {
+        WorldCommand worldCommand = new WorldCommand(this);
+        Objects.requireNonNull(main.getCommand("warp")).setExecutor(worldCommand);
+    }
+
+    @Override
+    public void onDisable() {
+        HandlerList.unregisterAll(bootstrapListener);
+    }
+
+}

+ 92 - 0
src/main/java/me/lethunderhawk/world/command/WorldCommand.java

@@ -0,0 +1,92 @@
+package me.lethunderhawk.world.command;
+
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.fluxapi.util.command.CommandNode;
+import me.lethunderhawk.fluxapi.util.command.CustomCommand;
+import me.lethunderhawk.fluxapi.util.interfaces.BazaarFluxModule;
+import me.lethunderhawk.main.Main;
+import me.lethunderhawk.world.util.WorldManager;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+
+public class WorldCommand extends CustomCommand {
+    private Map<String, Location> locations = new HashMap<>();
+
+    public WorldCommand(BazaarFluxModule module) {
+        super(new CommandNode("warp", "Hop between worlds!", null), module);
+        populateLocationMap();
+    }
+
+    private void populateLocationMap() {
+        locations.clear();
+        initMatchingWorldLocationFromSpawn("hub", "world");
+    }
+    private void initMatchingWorldLocationFromSpawn(String... worldNames){
+        for(String worldName : worldNames){
+            initMatchingWorldLocationFromSpawn(worldName);
+        }
+    }
+
+    private void initMatchingWorldLocationFromSpawn(String worldName) {
+        World world =  Bukkit.getWorld(worldName);
+        if(world == null){
+            FluxService.get(Main.class).getLogger().warning("World not found: " + worldName);
+            return;
+        }
+        Location worldLoc = world.getBlockAt(0,100,0).getLocation();
+        locations.put(worldName, worldLoc);
+    }
+
+
+    @Override
+    public void createCommands() {
+        registerCommand("island", "Warp to your island", this::warpToIsland);
+        registerCommand("back", "Warp back from the island", this::warpBack);
+        registerCommand("reload", "Reload this module", this::reload);
+        registerCommand("deleteIslands", "delete all worlds in island folder", this::deleteAllIslands);
+        registerAllDefaultWorldCommands();
+    }
+
+    private void deleteAllIslands(CommandSender sender, String[] strings) {
+    }
+
+    private void reload(CommandSender sender, String[] strings) {
+        module.reload(sender, strings);
+    }
+
+    private void registerAllDefaultWorldCommands() {
+        if(locations == null || locations.isEmpty()) return;
+        for(Map.Entry<String, Location> entry : locations.entrySet()){
+            String locationName = entry.getKey();
+            registerCommand(locationName, "Warp to " + locationName, warpToLocation(entry.getValue()));
+        }
+    }
+
+    private BiConsumer<CommandSender, String[]> warpToLocation(Location value) {
+        return (sender, args) -> {
+            warptoLocation(sender, args, value);
+        };
+    }
+
+    private void warptoLocation(CommandSender sender, String[] strings, Location location) {
+        if(!(sender instanceof Player p)) return;
+        p.teleport(location);
+    }
+
+    private void warpBack(CommandSender sender, String[] strings) {
+        if(!(sender instanceof Player player)) return;
+        FluxService.get(WorldManager.class).warpBackFromIsland(player);
+    }
+
+    private void warpToIsland(CommandSender sender, String[] strings) {
+        if(!(sender instanceof Player player)) return;
+        FluxService.get(WorldManager.class).warpToIsland(player);
+    }
+}

+ 48 - 0
src/main/java/me/lethunderhawk/world/island/IslandBootstrapListener.java

@@ -0,0 +1,48 @@
+package me.lethunderhawk.world.island;
+
+import me.lethunderhawk.world.util.schematic.Rotation;
+import me.lethunderhawk.world.util.schematic.SchematicPlacer;
+import org.bukkit.Location;
+import org.bukkit.NamespacedKey;
+import org.bukkit.World;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.world.WorldLoadEvent;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataType;
+
+import java.io.File;
+
+public final class IslandBootstrapListener implements Listener {
+
+    private static final NamespacedKey GENERATED_KEY =
+            new NamespacedKey("bazaarflux", "island_generated");
+
+    private final File schematicFile;
+
+    public IslandBootstrapListener(File schematicFile) {
+        this.schematicFile = schematicFile;
+    }
+
+    @EventHandler
+    public void onWorldLoad(WorldLoadEvent event) {
+        System.out.println("loading " + event.getWorld().getName());
+        World world = event.getWorld();
+
+        PersistentDataContainer pdc = world.getPersistentDataContainer();
+        //if (pdc.has(GENERATED_KEY, PersistentDataType.BYTE)) return;
+
+        Location spawn = new Location(world, 0, 100, 0);
+
+        boolean success = SchematicPlacer.place(
+                schematicFile,
+                world,
+                spawn,
+                Rotation.NONE
+        );
+
+        if (success) {
+            pdc.set(GENERATED_KEY, PersistentDataType.BYTE, (byte) 1);
+        }
+    }
+}

+ 73 - 0
src/main/java/me/lethunderhawk/world/island/IslandWorld.java

@@ -0,0 +1,73 @@
+package me.lethunderhawk.world.island;
+
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.main.Main;
+import org.bukkit.*;
+import org.bukkit.generator.ChunkGenerator;
+
+import java.util.Random;
+
+public final class IslandWorld {
+
+
+    public World createWorldInFolder(String worldName, String folderName,
+                                     World.Environment environment) {
+        String worldPath = folderName + "/" + worldName;
+
+        WorldCreator creator = new WorldCreator(worldPath);
+        creator.environment(environment);
+        creator.type(WorldType.NORMAL);
+        creator.generateStructures(false);
+
+        if (folderName.equals("islands")) {
+            creator.generator(new EmptyChunkGenerator());
+        }
+
+        World world = creator.createWorld();
+
+        if (world != null) {
+            FluxService.get(Main.class).getLogger().info("World " + worldName + " created in " + folderName);
+
+            world.setGameRule(GameRule.DO_MOB_SPAWNING, false);
+            world.setGameRule(GameRule.ANNOUNCE_ADVANCEMENTS, false);
+            world.setGameRule(GameRule.KEEP_INVENTORY, true);
+            world.setSpawnLocation(0,100,0);
+            world.setVoidDamageAmount(1000f);
+        }
+
+        return world;
+    }
+
+    public static final class EmptyChunkGenerator extends ChunkGenerator{
+        @Override
+        public ChunkData generateChunkData(
+                World world,
+                Random random,
+                int chunkX,
+                int chunkZ,
+                BiomeGrid biome
+        ) {
+            // Completely empty world
+            return createChunkData(world);
+        }
+
+        @Override
+        public boolean shouldGenerateNoise() { return false; }
+
+        @Override
+        public boolean shouldGenerateSurface() { return false; }
+
+        @Override
+        public boolean shouldGenerateBedrock() { return false; }
+
+        @Override
+        public boolean shouldGenerateCaves() { return false; }
+
+        @Override
+        public boolean shouldGenerateDecorations() { return false; }
+
+        @Override
+        public boolean shouldGenerateMobs() { return false; }
+    }
+}
+

+ 84 - 0
src/main/java/me/lethunderhawk/world/util/WorldManager.java

@@ -0,0 +1,84 @@
+package me.lethunderhawk.world.util;
+
+import me.lethunderhawk.fluxapi.FluxService;
+import me.lethunderhawk.main.Main;
+import me.lethunderhawk.world.wrapper.CustomWorld;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.WorldCreator;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+
+public class WorldManager {
+
+    private final Main plugin;
+
+    public WorldManager() {
+        this.plugin = FluxService.get(Main.class);
+    }
+
+    public CustomWorld getOrCreateIslandWorld(Player player) {
+        String worldName = "island_" + player.getUniqueId().toString();
+        String worldPath = "islands/" + worldName;
+
+        World world = Bukkit.getWorld(worldPath);
+
+        if (world == null) {
+            // Überprüfen, ob Weltdateien existieren
+            File worldFolder = new File(plugin.getServer().getWorldContainer(), worldPath);
+
+            if (worldFolder.exists()) {
+                // Existierende Welt laden
+                world = new WorldCreator(worldPath).createWorld();
+            } else {
+                // Neue Welt erstellen
+                world = WorldUtils.createIslandWorld(player.getUniqueId().toString());
+            }
+        }
+
+        return new CustomWorld(world);
+    }
+    public void warpToIsland(Player player) {
+        CustomWorld world = getOrCreateIslandWorld(player);
+        world.warpIntoWorld(player);
+    }
+
+    public void warpBackFromIsland(Player player) {
+        WorldManager manager = FluxService.get(WorldManager.class);
+        CustomWorld cWorld = manager.getOrCreateIslandWorld(player);
+
+        if(player.getWorld() != cWorld.getWorld()) {
+            player.sendMessage("§cYou are not on an island!");
+        }else returnPlayer(player, cWorld);
+    }
+
+    private void returnPlayer(Player player, CustomWorld cWorld) {
+        cWorld.warpBack(player);
+    }
+
+    /*public List<World> getDungeonWorlds() {
+        List<World> dungeons = new ArrayList<>();
+        File dungeonsDir = new File(plugin.getServer().getWorldContainer(), "dungeons");
+
+        if (dungeonsDir.exists() && dungeonsDir.isDirectory()) {
+            for (File worldDir : dungeonsDir.listFiles()) {
+                if (worldDir.isDirectory()) {
+                    String worldPath = "dungeons/" + worldDir.getName();
+                    World world = Bukkit.getWorld(worldPath);
+
+                    if (world == null) {
+                        // Welt laden, falls nicht bereits geladen
+                        world = new WorldCreator(worldPath).createWorld();
+                    }
+
+                    if (world != null) {
+                        dungeons.add(world);
+                    }
+                }
+            }
+        }
+
+        return dungeons;
+    }*/
+}

+ 23 - 0
src/main/java/me/lethunderhawk/world/util/WorldUtils.java

@@ -0,0 +1,23 @@
+package me.lethunderhawk.world.util;
+
+import me.lethunderhawk.world.island.IslandWorld;
+import org.bukkit.World;
+
+public class WorldUtils {
+
+//    public static World createDungeonWorld(String worldName) {
+//        return createWorldInFolder(worldName, "dungeons", World.Environment.NORMAL);
+//    }
+
+    public static World createIslandWorld(String playerName) {
+        String worldName = "island_" + playerName;
+        return createIslandWorldInFolder(worldName, "islands", World.Environment.NORMAL);
+    }
+
+    private static World createIslandWorldInFolder(String worldName, String folderName,
+                                             World.Environment environment) {
+
+        IslandWorld islandWorld = new IslandWorld();
+        return islandWorld.createWorldInFolder(worldName, folderName, environment);
+    }
+}

+ 1 - 1
src/main/java/me/lethunderhawk/dungeon/placement/Rotation.java → src/main/java/me/lethunderhawk/world/util/schematic/Rotation.java

@@ -1,4 +1,4 @@
-package me.lethunderhawk.dungeon.placement;
+package me.lethunderhawk.world.util.schematic;
 
 import com.sk89q.worldedit.math.transform.AffineTransform;
 

+ 8 - 0
src/main/java/me/lethunderhawk/world/util/schematic/SchematicMetadata.java

@@ -0,0 +1,8 @@
+package me.lethunderhawk.world.util.schematic;
+
+import org.bukkit.util.BoundingBox;
+
+public record SchematicMetadata(
+        Vector3i anchor,
+        BoundingBox boundingBox
+) {}

+ 145 - 0
src/main/java/me/lethunderhawk/world/util/schematic/SchematicPlacer.java

@@ -0,0 +1,145 @@
+package me.lethunderhawk.world.util.schematic;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonParseException;
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.bukkit.BukkitAdapter;
+import com.sk89q.worldedit.extent.clipboard.Clipboard;
+import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
+import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
+import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
+import com.sk89q.worldedit.function.operation.Operation;
+import com.sk89q.worldedit.function.operation.Operations;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.session.ClipboardHolder;
+import org.bukkit.Location;
+import org.bukkit.World;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+
+public final class SchematicPlacer {
+
+    private static final Gson GSON = new Gson();
+
+    private SchematicPlacer() {}
+
+    /**
+     * Places a schematic at a world location.
+     *
+     * @param schematicFile .schem file
+     * @param world target world
+     * @param anchor world-space anchor
+     * @param rotation rotation to apply
+     * @return true if placed successfully
+     */
+    public static boolean place(
+            File schematicFile,
+            World world,
+            Location anchor,
+            Rotation rotation
+    ) {
+        if (!isValidSchematic(schematicFile)) return false;
+
+        SchematicMetadata metadata = loadMetadata(schematicFile);
+        Clipboard clipboard = loadClipboard(schematicFile);
+
+        if (clipboard == null) return false;
+
+        if (metadata != null) {
+//            BoundingBox box = metadata
+//                    .boundingBox()
+//                    .shift(anchor.toVector());
+
+            // Optional validation
+            // if (!isAreaClear(world, box)) return false;
+        }
+
+        Vector3i schematicAnchor =
+                metadata != null ? metadata.anchor() : new Vector3i(0,0,0);
+
+        return paste(
+                clipboard,
+                world,
+                anchor,
+                schematicAnchor,
+                rotation
+        );
+    }
+
+    // ----------------------------------------------------------------
+
+    private static boolean isValidSchematic(File file) {
+        return file != null && file.exists() && file.getName().endsWith(".schem");
+    }
+
+    private static Clipboard loadClipboard(File file) {
+        ClipboardFormat format = ClipboardFormats.findByPath(file.toPath());
+        if (format == null) return null;
+
+        try (ClipboardReader reader =
+                     format.getReader(new FileInputStream(file))) {
+            return reader.read();
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    private static SchematicMetadata loadMetadata(File schematic) {
+        File meta = new File(
+                schematic.getParent(),
+                schematic.getName().replace(".schem", ".json")
+        );
+
+        if (!meta.exists()) return null;
+
+        try (FileReader reader = new FileReader(meta)) {
+            return GSON.fromJson(reader, SchematicMetadata.class);
+        } catch (IOException | JsonParseException e) {
+            return null;
+        }
+    }
+
+    private static boolean paste(
+            Clipboard clipboard,
+            World world,
+            Location anchor,
+            Vector3i schematicAnchor,
+            Rotation rotation
+    ) {
+        com.sk89q.worldedit.world.World weWorld =
+                BukkitAdapter.adapt(world);
+
+        BlockVector3 target = BlockVector3.at(
+                anchor.getBlockX() - schematicAnchor.x(),
+                anchor.getBlockY() - schematicAnchor.y(),
+                anchor.getBlockZ() - schematicAnchor.z()
+        );
+
+        try (EditSession session = WorldEdit.getInstance()
+                .newEditSessionBuilder()
+                .world(weWorld)
+                .build()) {
+
+            ClipboardHolder holder = new ClipboardHolder(clipboard);
+            holder.setTransform(
+                    holder.getTransform().combine(rotation.toTransform())
+            );
+
+            Operation operation = holder
+                    .createPaste(session)
+                    .to(target)
+                    .ignoreAirBlocks(true)
+                    .build();
+
+            Operations.complete(operation);
+            return true;
+
+        } catch (Exception e) {
+            return false;
+        }
+    }
+}

+ 3 - 0
src/main/java/me/lethunderhawk/world/util/schematic/Vector3i.java

@@ -0,0 +1,3 @@
+package me.lethunderhawk.world.util.schematic;
+
+public record Vector3i(int x, int y, int z) {}

+ 69 - 0
src/main/java/me/lethunderhawk/world/wrapper/CustomWorld.java

@@ -0,0 +1,69 @@
+package me.lethunderhawk.world.wrapper;
+
+import org.bukkit.*;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+public class CustomWorld {
+    private final Map<UUID, String> returnWorlds = new HashMap<>();
+    private final Map<UUID, Location> returnLocs = new HashMap<>();
+    private final World world;
+
+    public CustomWorld(World world) {
+        this.world = world;
+    }
+
+    public void warpIntoWorld(Player player) {
+        returnWorlds.put(player.getUniqueId(), player.getWorld().getName());
+        returnLocs.put(player.getUniqueId(), player.getLocation().clone());
+
+        Location spawn = new Location(world, 0.5, 100, 0.5);
+        player.teleport(spawn);
+        player.sendMessage(ChatColor.GREEN + "Teleportiert!");
+    }
+
+    public void warpBack(Player player) {
+        UUID uuid = player.getUniqueId();
+        String returnWorldName = returnWorlds.remove(uuid);
+        Location returnLoc = returnLocs.remove(uuid);
+
+        if (returnWorldName != null && returnLoc != null) {
+            World returnWorld = Bukkit.getWorld(returnWorldName);
+
+            if (returnWorld == null) {
+                // Versuche, die Welt zu laden
+                returnWorld = new WorldCreator(returnWorldName).createWorld();
+            }
+
+            if (returnWorld != null) {
+                returnLoc.setWorld(returnWorld);
+
+                player.sendMessage("§eKehre zurück...");
+                player.teleport(returnLoc);
+                return;
+            }
+        }
+
+        // Fallback
+        World mainWorld = Bukkit.getWorlds().getFirst();
+        player.teleport(mainWorld.getSpawnLocation());
+        player.sendMessage("§cRückkehr nicht möglich, teleportiere zur Hauptwelt.");
+    }
+
+    public void returnAllPlayers() {
+        List<UUID> toReturn = new ArrayList<>(returnWorlds.keySet());
+
+        for (UUID uuid : toReturn) {
+            Player player = Bukkit.getPlayer(uuid);
+            if (player != null) {
+                warpBack(player);
+            }
+        }
+    }
+
+    public @NotNull World getWorld() {
+        return world;
+    }
+}

BIN
src/main/resources/island/default_island.schem


+ 16 - 0
src/main/resources/plugin.yml

@@ -3,6 +3,8 @@ version: '${project.version}'
 main: me.lethunderhawk.main.Main
 api-version: 1.21.10
 prefix: BazaarFlux
+depend:
+  - FluxAPI
 commands:
   eco:
     description: Economy administration command
@@ -27,11 +29,25 @@ commands:
     description: Dungeons command
     usage: /dungeon
     permission: dungeons.commands
+  warp:
+    description: Warping between worlds
+    usage: /warp
+    permission: warp.commands
+  npc:
+    description: The base NPC command
+    usage: /npc
+    permission: npc.commands
 
 permissions:
   minion.commands:
     description: Allows use of Minion commands
     default: op
+  warp.commands:
+    description: Allows use of warping commands
+    default: op
+  npc.commands:
+    description: Allows use of npc commands
+    default: op
   customItem.commands:
     description: Allows use of custom Items commands
     default: op