diff --git a/build.gradle.kts b/build.gradle.kts index e5c337b..7bb5262 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { } group = "io.github.cccm5" -version = "2.0.0_beta-4" +version = "2.0.0_beta-5" description = "Cargo" java.toolchain.languageVersion = JavaLanguageVersion.of(21) diff --git a/src/main/java/io/github/cccm5/CargoMain.java b/src/main/java/io/github/cccm5/CargoMain.java index 22d8d83..3ff5132 100644 --- a/src/main/java/io/github/cccm5/CargoMain.java +++ b/src/main/java/io/github/cccm5/CargoMain.java @@ -7,11 +7,23 @@ import com.degitise.minevid.dtlTraders.guis.items.AGUIItem; import com.degitise.minevid.dtlTraders.guis.items.TradableGUIItem; import com.degitise.minevid.dtlTraders.utils.citizens.TraderTrait; +import io.github.cccm5.async.LoadTask; +import io.github.cccm5.async.ProcessingTask; +import io.github.cccm5.async.UnloadTask; +import io.github.cccm5.commands.CargoCommand; +import io.github.cccm5.commands.LoadCommand; +import io.github.cccm5.commands.UnloadCommand; +import io.github.cccm5.config.Config; +import io.github.cccm5.listener.SignClickListener; +import io.github.cccm5.listener.SignPlaceListener; +import io.github.cccm5.util.CraftInventoryUtil; +import io.github.cccm5.util.NPCUtil; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.npc.NPC; import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.craft.CraftManager; import net.countercraft.movecraft.MovecraftLocation; +import net.countercraft.movecraft.craft.PlayerCraft; import net.milkbowl.vault.economy.Economy; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -30,37 +42,21 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.util.Set; + public class CargoMain extends JavaPlugin implements Listener { - public static final String ERROR_TAG = ChatColor.RED + "Error: " + ChatColor.DARK_RED; - public static final String SUCCESS_TAG = ChatColor.DARK_AQUA + "Cargo: " + ChatColor.WHITE; - public static Logger logger; private static Economy economy; private static ArrayList playersInQue; - private static double unloadTax,loadTax; private static CargoMain instance; - private static int delay;//ticks - private static Material SIGN_POST = Material.getMaterial("SIGN_POST"); private static Main dtlTradersPlugin; - private CraftManager craftManager; - private FileConfiguration config; - private boolean cardinalDistance; - private static boolean debug; - private double scanRange; - public void onEnable() { - logger = this.getLogger(); - this.getServer().getPluginManager().registerEvents(this, this); - playersInQue = new ArrayList(); - instance = this; - //************************ - //* Configs * - //************************ - config = getConfig(); + private void loadConfig() { + FileConfiguration config = getConfig(); + config.addDefault("Scan range",100.0); config.addDefault("Transfer delay ticks",300); config.addDefault("Load tax percent", 0.01D); @@ -68,27 +64,34 @@ public void onEnable() { config.addDefault("Cardinal distance",true); config.addDefault("Debug mode",false); config.options().copyDefaults(true); - this.saveConfig(); - scanRange = config.getDouble("Scan range") >= 1.0 ? config.getDouble("Scan range") : 100.0; - delay = config.getInt("Transfer delay ticks"); - loadTax = config.getDouble("Load tax percent")<=1.0 && config.getDouble("Load tax percent")>=0.0 ? config.getDouble("Load tax percent") : 0.01; - unloadTax = config.getDouble("Unload tax percent")<=1.0 && config.getDouble("Unload tax percent")>=0.0 ? config.getDouble("Unload tax percent") : 0.01; - cardinalDistance = config.getBoolean("Cardinal distance"); - debug = config.getBoolean("Debug mode"); + saveConfig(); + + Config.scanRange = config.getDouble("Scan range") >= 1.0 ? config.getDouble("Scan range") : 100.0; + Config.delay = config.getInt("Transfer delay ticks"); + Config.loadTax = config.getDouble("Load tax percent")<=1.0 && config.getDouble("Load tax percent")>=0.0 ? config.getDouble("Load tax percent") : 0.01; + Config.unloadTax = config.getDouble("Unload tax percent")<=1.0 && config.getDouble("Unload tax percent")>=0.0 ? config.getDouble("Unload tax percent") : 0.01; + Config.cardinalDistance = config.getBoolean("Cardinal distance"); + Config.debug = config.getBoolean("Debug mode"); + } + + public void onEnable() { + playersInQue = new ArrayList<>(); + instance = this; + + loadConfig(); //************************ //* Load Movecraft * //************************ if(getServer().getPluginManager().getPlugin("Movecraft") == null || !getServer().getPluginManager().getPlugin("Movecraft").isEnabled()) { - logger.log(Level.SEVERE, "Movecraft not found or not enabled"); + getLogger().severe("Movecraft not found or not enabled"); getServer().getPluginManager().disablePlugin(this); return; } - craftManager = CraftManager.getInstance(); //************************ //* Load Citizens * //************************ if(getServer().getPluginManager().getPlugin("Citizens") == null || !getServer().getPluginManager().getPlugin("Citizens").isEnabled()) { - logger.log(Level.SEVERE, "Citizens 2.0 not found or not enabled"); + getLogger().severe("Citizens 2.0 not found or not enabled"); getServer().getPluginManager().disablePlugin(this); return; } @@ -98,94 +101,35 @@ public void onEnable() { //* Load Vault * //************************ if (getServer().getPluginManager().getPlugin("Vault") == null || !getServer().getPluginManager().getPlugin("Vault").isEnabled()) { - logger.log(Level.SEVERE, "Vault not found or not enabled"); + getLogger().severe("Vault not found or not enabled"); getServer().getPluginManager().disablePlugin(this); return; } + //************************ + //* Load dtlTraders * + //************************ Plugin traders = getServer().getPluginManager().getPlugin("dtlTraders"); - if (traders == null || !(traders instanceof Main)){ + if (!(traders instanceof Main)){ + getLogger().severe("dtlTraders not found or not enabled"); getServer().getPluginManager().disablePlugin(this); + return; } dtlTradersPlugin = (Main) traders; economy = getServer().getServicesManager().getRegistration(Economy.class).getProvider(); + + getServer().getPluginManager().registerEvents(new SignClickListener(), this); + getServer().getPluginManager().registerEvents(new SignPlaceListener(), this); + + getCommand("cargo").setExecutor(new CargoCommand()); + getCommand("load").setExecutor(new LoadCommand()); + getCommand("unload").setExecutor(new UnloadCommand()); } public void onDisable() { - logger = null; economy = null; instance = null; } - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { // Plugin - if (command.getName().equalsIgnoreCase("unload")) { - if(!(sender instanceof Player)){ - sender.sendMessage(ERROR_TAG + "You need to be a player to execute that command!"); - return true; - } - unload((Player) sender); - return true; - } - - if (command.getName().equalsIgnoreCase("load")) { - if(!(sender instanceof Player)){ - sender.sendMessage(ERROR_TAG + "You need to be a player to execute that command!"); - return true; - } - load((Player) sender); - return true; - } - - if (command.getName().equalsIgnoreCase("cargo")) { - if(!sender.hasPermission("Cargo.cargo")){ - sender.sendMessage(ERROR_TAG + "You don't have permission to do that!"); - return true; - } - sender.sendMessage(ChatColor.WHITE + "--[ " + ChatColor.DARK_AQUA + " Movecraft Cargo " + ChatColor.WHITE + " ]--"); - sender.sendMessage(ChatColor.DARK_AQUA + "Scan Range: " + ChatColor.WHITE + scanRange + " Blocks"); - sender.sendMessage(ChatColor.DARK_AQUA + "Transfer Delay: " + ChatColor.WHITE + delay + " ticks"); - sender.sendMessage(ChatColor.DARK_AQUA + "Unload Tax: " + ChatColor.WHITE + String.format("%.2f",100*unloadTax) + "%"); - sender.sendMessage(ChatColor.DARK_AQUA + "Load Tax: " + ChatColor.WHITE + String.format("%.2f",100*loadTax) + "%"); - sender.sendMessage(ChatColor.DARK_AQUA + "Distance Type: " + ChatColor.WHITE + (cardinalDistance ? "Cardinal" : "Direct")); - return true; - } - return false; - - } - - @EventHandler - public void onSignClick(PlayerInteractEvent e) { - if (e.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; - } - if (!e.getClickedBlock().getType().name().equals("SIGN_POST") && !e.getClickedBlock().getType().name().endsWith("SIGN") && !e.getClickedBlock().getType().name().endsWith("WALL_SIGN")) { - return; - } - Sign sign = (Sign) e.getClickedBlock().getState(); - if (sign.getLine(0).equals(ChatColor.DARK_AQUA + "[UnLoad]")) { - unload(e.getPlayer()); - return; - } - if (sign.getLine(0).equals(ChatColor.DARK_AQUA + "[Load]")) { - load(e.getPlayer()); - } - - } - - @EventHandler - public void onSignPlace(SignChangeEvent e){ - if(!e.getBlock().getType().name().equals("SIGN_POST") && !e.getBlock().getType().name().endsWith("SIGN") && !e.getBlock().getType().name().endsWith("WALL_SIGN")){ - return; - } - if(ChatColor.stripColor(e.getLine(0)).equalsIgnoreCase("[Load]") || ChatColor.stripColor(e.getLine(0)).equalsIgnoreCase("[UnLoad]")){ - e.setLine(0,ChatColor.DARK_AQUA + (ChatColor.stripColor(e.getLine(0))).replaceAll("u","U").replaceAll("l","L")); - } - - } - - public static boolean isDebug(){ - return debug; - } - public static Economy getEconomy(){ return economy; } @@ -194,191 +138,124 @@ public static List getQue(){ return playersInQue; } - public static double getLoadTax(){ - return loadTax; - } - - public static double getUnloadTax(){ - return unloadTax; - } - - public static int getDelay(){ - return delay; - } - public static CargoMain getInstance(){ return instance; } - private void unload(Player player){ - if(!player.hasPermission("Cargo.unload")){ - player.sendMessage(ERROR_TAG + "You don't have permission to do that!"); + public void unload(@NotNull Player player){ + if (!player.hasPermission("Cargo.unload")) { + player.sendMessage(Config.ERROR_TAG + "You don't have permission to do that!"); return; } - Craft playerCraft = craftManager.getCraftByPlayer(player); - if(playersInQue.contains(player)){ - player.sendMessage(ERROR_TAG + "You're already moving cargo!"); + if (playersInQue.contains(player)) { + player.sendMessage(Config.ERROR_TAG + "You're already moving cargo!"); return; } - - if(playerCraft == null){ - player.sendMessage(ERROR_TAG + "You need to be piloting a craft to do that!"); + if (player.getInventory().getItemInMainHand().getType() == Material.AIR) { + player.sendMessage(Config.ERROR_TAG + "You need to be holding a cargo item to do that!"); return; } - //NPC cargoMerchant=null; - List nearbyMerchants = new ArrayList<>(); - double distance;//, lastScan = scanRange; - MovecraftLocation loc = playerCraft.getHitBox().getMidPoint(); - for(NPC npc :Utils.getNPCsWithTrait(CargoTrait.class)){ - if(!npc.isSpawned()) - continue; - distance = cardinalDistance ? Math.abs(loc.getX()-npc.getEntity().getLocation().getX()) + Math.abs(loc.getZ()-npc.getEntity().getLocation().getZ()) : Math.sqrt(Math.pow(loc.getX()-npc.getEntity().getLocation().getX(),2) + Math.pow(loc.getZ()-npc.getEntity().getLocation().getZ(),2)); - if( distance <= scanRange){ - nearbyMerchants.add(npc); - } - } - if(nearbyMerchants.size()==0){ - player.sendMessage(ERROR_TAG + "You need to be within " + scanRange + " blocks of a merchant to use that command!"); + + PlayerCraft playerCraft = CraftManager.getInstance().getCraftByPlayer(player); + if(playerCraft == null) { + player.sendMessage(Config.ERROR_TAG + "You need to be piloting a craft to do that!"); return; } - if(player.getInventory().getItemInMainHand() == null || player.getInventory().getItemInMainHand().getType() == Material.AIR){ - player.sendMessage(ERROR_TAG + "You need to be holding a cargo item to do that!"); + List nearbyMerchants = NPCUtil.getNPCsInRange(playerCraft.getHitBox().getMidPoint()); + if (nearbyMerchants.isEmpty()) { + player.sendMessage(Config.ERROR_TAG + "You need to be within " + Config.scanRange + " blocks of a merchant to use that command!"); return; } - String guiName; - TradableGUIItem finalItem = null; - for(NPC cargoMerchant : nearbyMerchants) { - if(finalItem!=null) - break; - guiName = cargoMerchant.getTrait(TraderTrait.class).getGUIName(); - AGUI gui = dtlTradersPlugin.getGuiListService().getGUI(guiName); - TradeGUI tradeGUI = (TradeGUI) gui; - ItemStack compareItem = player.getInventory().getItemInMainHand().clone(); - finalItem = null; - for (TradeGUIPage page : tradeGUI.getPages()) { - if (page == null) continue; - for (AGUIItem tempItem : page.getItems("sell")) { - if (!(tempItem instanceof TradableGUIItem)) continue; - if (tempItem.getMainItem().isSimilar(compareItem)) { - if (tempItem.getMainItem().getAmount() > 1) - continue; - finalItem = (TradableGUIItem) tempItem; - break; - } - } - if (finalItem == null || finalItem.getTradePrice() == 0.0) { - player.sendMessage(ERROR_TAG + "You need to be holding a cargo item to do that!"); - return; - } + Set items = NPCUtil.getItems(nearbyMerchants, player.getInventory().getItemInMainHand(), dtlTradersPlugin, "sell"); + TradableGUIItem finalItem = null; + for (TradableGUIItem item : items) { + if (finalItem == null) { + finalItem = item; + continue; } + + if (item.getTradePrice() > finalItem.getTradePrice()) + finalItem = item; + } + if (finalItem == null || finalItem.getTradePrice() <= 0.0) { + player.sendMessage(Config.ERROR_TAG + "You need to be holding a cargo item to do that!"); + return; } - assert finalItem!=null; - String itemName = finalItem.getMainItem().getItemMeta().getDisplayName() != null && finalItem.getMainItem().getItemMeta().getDisplayName().length() > 0 ? finalItem.getMainItem().getItemMeta().getDisplayName() : finalItem.getMainItem().getType().name().toLowerCase(); - List invs = Utils.getInventories(playerCraft, finalItem.getMainItem(), Material.CHEST, Material.TRAPPED_CHEST, Material.BARREL); - int size = invs.size(); - if(size <=0 ){ - player.sendMessage(CargoMain.ERROR_TAG + "You have no " + itemName + " on this craft!"); + String itemName = finalItem.getMainItem().getItemMeta().getDisplayName() != null && finalItem.getMainItem().getItemMeta().getDisplayName().length() > 0 ? finalItem.getMainItem().getItemMeta().getDisplayName() : finalItem.getMainItem().getType().name().toLowerCase(); + List inventories = CraftInventoryUtil.getInventories(playerCraft, finalItem.getMainItem(), Material.CHEST, Material.TRAPPED_CHEST, Material.BARREL); + if (inventories.isEmpty()) { + player.sendMessage(Config.ERROR_TAG + "You have no " + itemName + ChatColor.RESET + " on this craft!"); return; } - player.sendMessage(SUCCESS_TAG + "Started unloading cargo"); + player.sendMessage(Config.SUCCESS_TAG + "Started unloading cargo"); playersInQue.add(player); - new UnloadTask(craftManager.getCraftByPlayer(player),finalItem ).runTaskTimer(this,delay,delay); - new ProcessingTask(player, finalItem,size).runTaskTimer(this,0,20); + new UnloadTask(playerCraft, finalItem).runTaskTimer(this, Config.delay, Config.delay); + new ProcessingTask(player, finalItem, inventories.size()).runTaskTimer(this, 0, 20); } - private void load(Player player){ - if(!player.hasPermission("Cargo.load")){ - player.sendMessage(ERROR_TAG + "You don't have permission to do that!"); + public void load(@NotNull Player player){ + if (!player.hasPermission("Cargo.load")) { + player.sendMessage(Config.ERROR_TAG + "You don't have permission to do that!"); return; } - Craft playerCraft = craftManager.getCraftByPlayer(player); - if(playersInQue.contains(player)){ - player.sendMessage(ERROR_TAG + "You're already moving cargo!"); + if (playersInQue.contains(player)) { + player.sendMessage(Config.ERROR_TAG + "You're already moving cargo!"); return; } - - if(playerCraft == null){ - player.sendMessage(ERROR_TAG + "You need to be piloting a craft to do that!"); + if (player.getInventory().getItemInMainHand().getType() == Material.AIR) { + getLogger().info(player.getInventory().getItemInMainHand().getType().name()); + player.sendMessage(Config.ERROR_TAG + "You need to be holding a cargo item to do that!"); return; } - //NPC cargoMerchant=null; - List nearbyMerchants = new ArrayList<>(); - double distance;//, lastScan = scanRange; - MovecraftLocation loc = playerCraft.getHitBox().getMidPoint(); - for(NPC npc :Utils.getNPCsWithTrait(CargoTrait.class)){ - if(!npc.isSpawned()) - continue; - distance = cardinalDistance ? Math.abs(loc.getX()-npc.getEntity().getLocation().getX()) + Math.abs(loc.getZ()-npc.getEntity().getLocation().getZ()) : Math.sqrt(Math.pow(loc.getX()-npc.getEntity().getLocation().getX(),2) + Math.pow(loc.getZ()-npc.getEntity().getLocation().getZ(),2)); - if( distance <= scanRange){ - nearbyMerchants.add(npc); - } - } - if(nearbyMerchants.size()==0){ - player.sendMessage(ERROR_TAG + "You need to be within " + scanRange + " blocks of a merchant to use that command!"); + + PlayerCraft playerCraft = CraftManager.getInstance().getCraftByPlayer(player); + if (playerCraft == null) { + player.sendMessage(Config.ERROR_TAG + "You need to be piloting a craft to do that!"); return; } - if(player.getInventory().getItemInMainHand() == null || player.getInventory().getItemInMainHand().getType() == Material.AIR){ - logger.info(player.getInventory().getItemInMainHand().getType().name()); - player.sendMessage(ERROR_TAG + "You need to be holding a cargo item to do that!"); + List nearbyMerchants = NPCUtil.getNPCsInRange(playerCraft.getHitBox().getMidPoint()); + if (nearbyMerchants.isEmpty()) { + player.sendMessage(Config.ERROR_TAG + "You need to be within " + Config.scanRange + " blocks of a merchant to use that command!"); return; } - String guiName; - TradableGUIItem finalItem = null; - for(NPC cargoMerchant : nearbyMerchants) { - guiName = cargoMerchant.getTrait(TraderTrait.class).getGUIName(); - AGUI gui = dtlTradersPlugin.getGuiListService().getGUI(guiName); - TradeGUI tradeGUI = (TradeGUI) gui; - ItemStack compareItem = player.getInventory().getItemInMainHand().clone(); - for (TradeGUIPage page : tradeGUI.getPages()) { - if (page == null) - continue; - - for (AGUIItem tempItem : page.getItems("buy")) { - if (!(tempItem instanceof TradableGUIItem)) - continue; - - TradableGUIItem tradeItem = (TradableGUIItem) tempItem; - if (tradeItem.getMainItem().isSimilar(compareItem)) { - if (tempItem.getMainItem().getAmount() > 1) - continue; - finalItem = tradeItem; - break; - } - } - if (finalItem != null) - break; + Set items = NPCUtil.getItems(nearbyMerchants, player.getInventory().getItemInMainHand(), dtlTradersPlugin, "buy"); + TradableGUIItem finalItem = null; + for (TradableGUIItem item : items) { + if (finalItem == null) { + finalItem = item; + continue; } - if (finalItem != null) - break; + + if (item.getTradePrice() < finalItem.getTradePrice()) + finalItem = item; } - if (finalItem == null || finalItem.getTradePrice() == 0.0) { - player.sendMessage(ERROR_TAG + "You need to be holding a cargo item to do that!"); + if (finalItem == null || finalItem.getTradePrice() <= 0.0) { + player.sendMessage(Config.ERROR_TAG + "You need to be holding a cargo item to do that!"); return; } - final ItemMeta meta = finalItem.getMainItem().getItemMeta(); - String itemName = meta.getDisplayName() != null && meta.getDisplayName().length() > 0 ? meta.getDisplayName() : finalItem.getMainItem().getType().name().toLowerCase(); - if(!economy.has(player,finalItem.getTradePrice()*(1+loadTax))){ - player.sendMessage(ERROR_TAG + "You don't have enough money to buy any " + itemName + "!"); + String itemName = finalItem.getMainItem().getItemMeta().getDisplayName() != null && finalItem.getMainItem().getItemMeta().getDisplayName().length() > 0 ? finalItem.getMainItem().getItemMeta().getDisplayName() : finalItem.getMainItem().getType().name().toLowerCase(); + if(!economy.has(player,finalItem.getTradePrice()*(1+Config.loadTax))){ + player.sendMessage(Config.ERROR_TAG + "You don't have enough money to buy any " + itemName + ChatColor.RESET + "!"); return; } - List invs = Utils.getInventoriesWithSpace(playerCraft, finalItem.getMainItem(), Material.CHEST, Material.TRAPPED_CHEST, Material.BARREL); + List invs = CraftInventoryUtil.getInventoriesWithSpace(playerCraft, finalItem.getMainItem(), Material.CHEST, Material.TRAPPED_CHEST, Material.BARREL); int size = invs.size(); if(size <=0 ){ - player.sendMessage(CargoMain.ERROR_TAG + "You don't have any space for " + itemName + " on this craft!"); + player.sendMessage(Config.ERROR_TAG + "You don't have any space for " + itemName + ChatColor.RESET + " on this craft!"); return; } playersInQue.add(player); - new LoadTask(craftManager.getCraftByPlayer(player),finalItem ).runTaskTimer(this,delay,delay); + new LoadTask(playerCraft,finalItem).runTaskTimer(this,Config.delay,Config.delay); new ProcessingTask(player, finalItem,size).runTaskTimer(this,0,20); - player.sendMessage(SUCCESS_TAG + "Started loading cargo"); + player.sendMessage(Config.SUCCESS_TAG + "Started loading cargo"); } } diff --git a/src/main/java/io/github/cccm5/CargoTask.java b/src/main/java/io/github/cccm5/async/CargoTask.java similarity index 68% rename from src/main/java/io/github/cccm5/CargoTask.java rename to src/main/java/io/github/cccm5/async/CargoTask.java index de0e1d1..4fe58c7 100644 --- a/src/main/java/io/github/cccm5/CargoTask.java +++ b/src/main/java/io/github/cccm5/async/CargoTask.java @@ -1,6 +1,8 @@ -package io.github.cccm5; +package io.github.cccm5.async; import com.degitise.minevid.dtlTraders.guis.items.TradableGUIItem; +import io.github.cccm5.CargoMain; +import io.github.cccm5.config.Config; import net.countercraft.movecraft.craft.PlayerCraft; import net.countercraft.movecraft.craft.type.CraftType; import net.countercraft.movecraft.util.hitboxes.HitBox; @@ -15,48 +17,44 @@ public abstract class CargoTask extends BukkitRunnable { protected final Player originalPilot; protected TradableGUIItem item; - // protected Stock stock; - // protected final StockItem item; protected CargoTask(PlayerCraft craft, TradableGUIItem guiItem) { if (craft == null) { throw new IllegalArgumentException("craft must not be null"); - } else if (!(craft instanceof PlayerCraft)) { - throw new IllegalArgumentException("craft must not be a player craft"); - } else - this.craft = (PlayerCraft) craft; + } + this.craft = craft; if (guiItem == null) throw new IllegalArgumentException("item must not be null"); else - this.item = guiItem; - this.originalLocations = craft.getHitBox(); - this.originalPilot = this.craft.getPilot(); + item = guiItem; + originalLocations = craft.getHitBox(); + originalPilot = craft.getPilot(); } @Override public void run() { if (CraftManager.getInstance().getCraftByPlayer(originalPilot) == null) { - if (CargoMain.isDebug()) - CargoMain.logger.info("canceling CargoTask due to missing player/craft"); + if (Config.debug) + CargoMain.getInstance().getLogger().info("canceling CargoTask due to missing player/craft"); CargoMain.getQue().remove(originalPilot); - this.cancel(); + cancel(); return; } - if (this.craft.getPilot() != originalPilot) { + if (craft.getPilot() != originalPilot) { originalPilot.sendMessage("Pilots changed!"); CargoMain.getQue().remove(originalPilot); - this.cancel(); + cancel(); return; } if (craft.getHitBox() != originalLocations) { originalPilot.sendMessage("Blocks moved/changed!"); CargoMain.getQue().remove(originalPilot); - this.cancel(); + cancel(); return; } - if (CargoMain.isDebug()) - CargoMain.logger.info("Running execute method for CargoTask with address " + this + ". Pilot: " + if (Config.debug) + CargoMain.getInstance().getLogger().info("Running execute method for CargoTask with address " + this + ". Pilot: " + originalPilot.getName() + " CraftSize: " + originalLocations.size() + " CraftType: " + craft.getType().getStringProperty(CraftType.NAME) + " StockItem: " + (item.getDisplayName().length() > 0 ? item.getDisplayName() diff --git a/src/main/java/io/github/cccm5/LoadTask.java b/src/main/java/io/github/cccm5/async/LoadTask.java similarity index 67% rename from src/main/java/io/github/cccm5/LoadTask.java rename to src/main/java/io/github/cccm5/async/LoadTask.java index 9db44bf..b1539f7 100644 --- a/src/main/java/io/github/cccm5/LoadTask.java +++ b/src/main/java/io/github/cccm5/async/LoadTask.java @@ -1,6 +1,9 @@ -package io.github.cccm5; +package io.github.cccm5.async; import com.degitise.minevid.dtlTraders.guis.items.TradableGUIItem; +import io.github.cccm5.CargoMain; +import io.github.cccm5.config.Config; +import io.github.cccm5.util.CraftInventoryUtil; import net.countercraft.movecraft.craft.PlayerCraft; import org.bukkit.Material; @@ -15,7 +18,7 @@ public LoadTask(PlayerCraft craft, TradableGUIItem item) { } protected void execute() { - List invs = Utils.getInventoriesWithSpace(craft, item.getMainItem(), Material.CHEST, + List invs = CraftInventoryUtil.getInventoriesWithSpace(craft, item.getMainItem(), Material.CHEST, Material.TRAPPED_CHEST, Material.BARREL); Inventory inv = invs.get(0); @@ -27,7 +30,7 @@ protected void execute() { ? item.getMainItem().getMaxStackSize() : inv.getItem(i).getMaxStackSize() - inv.getItem(i).getAmount(); if (CargoMain.getEconomy().getBalance(originalPilot) > item.getTradePrice() * maxCount - * (1 + CargoMain.getLoadTax())) { + * (1 + Config.loadTax)) { loaded += maxCount; ItemStack tempItem = item.getMainItem().clone(); tempItem.setAmount(tempItem.getMaxStackSize()); @@ -35,18 +38,18 @@ protected void execute() { } else { maxCount = (int) (CargoMain.getEconomy().getBalance(originalPilot) - / (item.getTradePrice() * (1 + CargoMain.getLoadTax()))); + / (item.getTradePrice() * (1 + Config.loadTax))); this.cancel(); CargoMain.getQue().remove(originalPilot); - originalPilot.sendMessage(CargoMain.SUCCESS_TAG + "You ran out of money!"); + originalPilot.sendMessage(Config.SUCCESS_TAG + "You ran out of money!"); if (maxCount <= 0) { - if (CargoMain.isDebug()) { - CargoMain.logger.info("Balance: " + CargoMain.getEconomy().getBalance(originalPilot) + if (Config.debug) { + CargoMain.getInstance().getLogger().info("Balance: " + CargoMain.getEconomy().getBalance(originalPilot) + ". maxCount: " + maxCount + "."); } - originalPilot.sendMessage(CargoMain.SUCCESS_TAG + "Loaded " + loaded + " items worth $" + originalPilot.sendMessage(Config.SUCCESS_TAG + "Loaded " + loaded + " items worth $" + String.format("%.2f", loaded * item.getTradePrice()) + " took a tax of " - + String.format("%.2f", CargoMain.getLoadTax() * loaded * item.getTradePrice())); + + String.format("%.2f", Config.loadTax * loaded * item.getTradePrice())); return; } ItemStack tempItem = item.getMainItem().clone(); @@ -56,29 +59,29 @@ protected void execute() { tempItem.setAmount(inv.getItem(i).getAmount() + maxCount); inv.setItem(i, tempItem); loaded += maxCount; - if (CargoMain.isDebug()) { - CargoMain.logger.info("Balance: " + CargoMain.getEconomy().getBalance(originalPilot) + if (Config.debug) { + CargoMain.getInstance().getLogger().info("Balance: " + CargoMain.getEconomy().getBalance(originalPilot) + ". maxCount: " + maxCount + ". Actual stack-size: " + tempItem.getAmount()); } - originalPilot.sendMessage(CargoMain.SUCCESS_TAG + "Loaded " + loaded + " items worth $" + originalPilot.sendMessage(Config.SUCCESS_TAG + "Loaded " + loaded + " items worth $" + String.format("%.2f", loaded * item.getTradePrice()) + " took a tax of " - + String.format("%.2f", CargoMain.getLoadTax() * loaded * item.getTradePrice())); + + String.format("%.2f", Config.loadTax * loaded * item.getTradePrice())); CargoMain.getEconomy().withdrawPlayer(originalPilot, - loaded * item.getTradePrice() * (1 + CargoMain.getLoadTax())); + loaded * item.getTradePrice() * (1 + Config.loadTax)); return; } CargoMain.getEconomy().withdrawPlayer(originalPilot, - maxCount * item.getTradePrice() * (1 + CargoMain.getLoadTax())); + maxCount * item.getTradePrice() * (1 + Config.loadTax)); } - originalPilot.sendMessage(CargoMain.SUCCESS_TAG + "Loaded " + loaded + " items worth $" + originalPilot.sendMessage(Config.SUCCESS_TAG + "Loaded " + loaded + " items worth $" + String.format("%.2f", loaded * item.getTradePrice()) + " took a tax of " - + String.format("%.2f", CargoMain.getLoadTax() * loaded * item.getTradePrice())); + + String.format("%.2f", Config.loadTax * loaded * item.getTradePrice())); if (invs.size() <= 1) { this.cancel(); CargoMain.getQue().remove(originalPilot); - originalPilot.sendMessage(CargoMain.SUCCESS_TAG + "All cargo loaded"); + originalPilot.sendMessage(Config.SUCCESS_TAG + "All cargo loaded"); return; } new ProcessingTask(originalPilot, item, invs.size()).runTaskTimer(CargoMain.getInstance(), 0, 20); diff --git a/src/main/java/io/github/cccm5/ProcessingTask.java b/src/main/java/io/github/cccm5/async/ProcessingTask.java similarity index 76% rename from src/main/java/io/github/cccm5/ProcessingTask.java rename to src/main/java/io/github/cccm5/async/ProcessingTask.java index a748938..edac0d9 100644 --- a/src/main/java/io/github/cccm5/ProcessingTask.java +++ b/src/main/java/io/github/cccm5/async/ProcessingTask.java @@ -1,6 +1,8 @@ -package io.github.cccm5; +package io.github.cccm5.async; import com.degitise.minevid.dtlTraders.guis.items.TradableGUIItem; +import io.github.cccm5.CargoMain; +import io.github.cccm5.config.Config; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; @@ -18,23 +20,20 @@ public class ProcessingTask extends BukkitRunnable implements Listener { private static final int DELAY_BETWEEN_DISPLAY = 1; - private int remainingTime,remainingChests; + private int remainingTime; + private final int remainingChests; private final Player player; - private final TradableGUIItem item; - private final String itemDisplayName; - private Scoreboard board; - private Objective objective; + private final Objective objective; public ProcessingTask(Player player, TradableGUIItem item, int remainingChests){//, int remainingChests){ if (item == null) throw new IllegalArgumentException("item must not be null"); if (player == null) throw new IllegalArgumentException("player must not be null"); this.player = player; - this.item = item; - this.remainingTime = CargoMain.getDelay()/20; + this.remainingTime = Config.delay/20; this.remainingChests = remainingChests; - board = Bukkit.getScoreboardManager().getNewScoreboard(); - itemDisplayName = item.getMainItem().getItemMeta().getDisplayName() != null && item.getMainItem().getItemMeta().getDisplayName().length() > 0 ? item.getMainItem().getItemMeta().getDisplayName() : item.getMainItem().getType().name().toLowerCase(); + Scoreboard board = Bukkit.getScoreboardManager().getNewScoreboard(); + String itemDisplayName = item.getMainItem().getItemMeta().getDisplayName() != null && item.getMainItem().getItemMeta().getDisplayName().length() > 0 ? item.getMainItem().getItemMeta().getDisplayName() : item.getMainItem().getType().name().toLowerCase(); objective = itemDisplayName.length() <=14 ? board.registerNewObjective(ChatColor.DARK_AQUA + itemDisplayName, "dummy") : board.registerNewObjective(ChatColor.DARK_AQUA + "Cargo", "dummy","Cargo"); objective.setDisplaySlot(DisplaySlot.SIDEBAR); player.setScoreboard(board); diff --git a/src/main/java/io/github/cccm5/UnloadTask.java b/src/main/java/io/github/cccm5/async/UnloadTask.java similarity index 63% rename from src/main/java/io/github/cccm5/UnloadTask.java rename to src/main/java/io/github/cccm5/async/UnloadTask.java index a5f34fd..b4a6979 100644 --- a/src/main/java/io/github/cccm5/UnloadTask.java +++ b/src/main/java/io/github/cccm5/async/UnloadTask.java @@ -1,6 +1,9 @@ -package io.github.cccm5; +package io.github.cccm5.async; import com.degitise.minevid.dtlTraders.guis.items.TradableGUIItem; +import io.github.cccm5.CargoMain; +import io.github.cccm5.config.Config; +import io.github.cccm5.util.CraftInventoryUtil; import net.countercraft.movecraft.craft.PlayerCraft; import org.bukkit.Material; @@ -14,7 +17,7 @@ public UnloadTask(PlayerCraft craft, TradableGUIItem item) { } public void execute() { - List invs = Utils.getInventories(craft, item.getMainItem(), Material.CHEST, Material.TRAPPED_CHEST, Material.BARREL); + List invs = CraftInventoryUtil.getInventories(craft, item.getMainItem(), Material.CHEST, Material.TRAPPED_CHEST, Material.BARREL); Inventory inv = invs.get(0); int count = 0; for (int i = 0; i < inv.getSize(); i++) { @@ -23,16 +26,16 @@ public void execute() { inv.setItem(i, null); } } - originalPilot.sendMessage(CargoMain.SUCCESS_TAG + "Unloaded " + count + " worth $" + originalPilot.sendMessage(Config.SUCCESS_TAG + "Unloaded " + count + " worth $" + String.format("%.2f", count * item.getTradePrice()) + " took a tax of " - + String.format("%.2f", CargoMain.getUnloadTax() * count * item.getTradePrice())); + + String.format("%.2f", Config.unloadTax * count * item.getTradePrice())); CargoMain.getEconomy().depositPlayer(originalPilot, - count * item.getTradePrice() * (1 - CargoMain.getUnloadTax())); + count * item.getTradePrice() * (1 - Config.unloadTax)); if (invs.size() <= 1) { this.cancel(); CargoMain.getQue().remove(originalPilot); - originalPilot.sendMessage(CargoMain.SUCCESS_TAG + "All cargo unloaded"); + originalPilot.sendMessage(Config.SUCCESS_TAG + "All cargo unloaded"); return; } new ProcessingTask(originalPilot, item, invs.size()).runTaskTimer(CargoMain.getInstance(), 0, 20); diff --git a/src/main/java/io/github/cccm5/commands/CargoCommand.java b/src/main/java/io/github/cccm5/commands/CargoCommand.java new file mode 100644 index 0000000..b0821c4 --- /dev/null +++ b/src/main/java/io/github/cccm5/commands/CargoCommand.java @@ -0,0 +1,30 @@ +package io.github.cccm5.commands; + +import io.github.cccm5.config.Config; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class CargoCommand implements CommandExecutor { + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (command.getName().equalsIgnoreCase("cargo")) + return false; + + if (!sender.hasPermission("Cargo.cargo")) { + sender.sendMessage(Config.ERROR_TAG + "You don't have permission to do that!"); + return true; + } + + sender.sendMessage(ChatColor.WHITE + "--[ " + ChatColor.DARK_AQUA + " Movecraft Cargo " + ChatColor.WHITE + " ]--"); + sender.sendMessage(ChatColor.DARK_AQUA + "Scan Range: " + ChatColor.WHITE + Config.scanRange + " Blocks"); + sender.sendMessage(ChatColor.DARK_AQUA + "Transfer Delay: " + ChatColor.WHITE + Config.delay + " ticks"); + sender.sendMessage(ChatColor.DARK_AQUA + "Unload Tax: " + ChatColor.WHITE + String.format("%.2f",100*Config.unloadTax) + "%"); + sender.sendMessage(ChatColor.DARK_AQUA + "Load Tax: " + ChatColor.WHITE + String.format("%.2f",100*Config.loadTax) + "%"); + sender.sendMessage(ChatColor.DARK_AQUA + "Distance Type: " + ChatColor.WHITE + (Config.cardinalDistance ? "Cardinal" : "Direct")); + + return true; + } +} diff --git a/src/main/java/io/github/cccm5/commands/LoadCommand.java b/src/main/java/io/github/cccm5/commands/LoadCommand.java new file mode 100644 index 0000000..d5c1fb7 --- /dev/null +++ b/src/main/java/io/github/cccm5/commands/LoadCommand.java @@ -0,0 +1,25 @@ +package io.github.cccm5.commands; + +import io.github.cccm5.CargoMain; +import io.github.cccm5.config.Config; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public class LoadCommand implements CommandExecutor { + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { // Plugin + if (!command.getName().equalsIgnoreCase("load")) + return false; + + if (!(sender instanceof Player)) { + sender.sendMessage(Config.ERROR_TAG + "You need to be a player to execute that command!"); + return true; + } + + CargoMain.getInstance().load((Player) sender); + return true; + } +} diff --git a/src/main/java/io/github/cccm5/commands/UnloadCommand.java b/src/main/java/io/github/cccm5/commands/UnloadCommand.java new file mode 100644 index 0000000..de7a003 --- /dev/null +++ b/src/main/java/io/github/cccm5/commands/UnloadCommand.java @@ -0,0 +1,25 @@ +package io.github.cccm5.commands; + +import io.github.cccm5.CargoMain; +import io.github.cccm5.config.Config; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public class UnloadCommand implements CommandExecutor { + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (!command.getName().equalsIgnoreCase("unload")) + return false; + + if (!(sender instanceof Player)) { + sender.sendMessage(Config.ERROR_TAG + "You need to be a player to execute that command!"); + return true; + } + + CargoMain.getInstance().unload((Player) sender); + return true; + } +} diff --git a/src/main/java/io/github/cccm5/config/Config.java b/src/main/java/io/github/cccm5/config/Config.java new file mode 100644 index 0000000..137273e --- /dev/null +++ b/src/main/java/io/github/cccm5/config/Config.java @@ -0,0 +1,15 @@ +package io.github.cccm5.config; + +import org.bukkit.ChatColor; + +public class Config { + public static final String ERROR_TAG = ChatColor.RED + "Error: " + ChatColor.DARK_RED; + public static final String SUCCESS_TAG = ChatColor.DARK_AQUA + "Cargo: " + ChatColor.WHITE; + + public static double scanRange = 100.0; + public static int delay; + public static double loadTax = 0.01D; + public static double unloadTax = 0.01D; + public static boolean cardinalDistance = true; + public static boolean debug = false; +} diff --git a/src/main/java/io/github/cccm5/listener/SignClickListener.java b/src/main/java/io/github/cccm5/listener/SignClickListener.java new file mode 100644 index 0000000..3cc91cd --- /dev/null +++ b/src/main/java/io/github/cccm5/listener/SignClickListener.java @@ -0,0 +1,31 @@ +package io.github.cccm5.listener; + +import io.github.cccm5.CargoMain; +import org.bukkit.ChatColor; +import org.bukkit.block.BlockState; +import org.bukkit.block.Sign; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.jetbrains.annotations.NotNull; + +public class SignClickListener implements Listener { + @EventHandler + public void onSignClick(@NotNull PlayerInteractEvent e) { + if (e.getAction() != Action.RIGHT_CLICK_BLOCK) + return; + BlockState state = e.getClickedBlock().getState(); + if (!(state instanceof Sign)) + return; + + Sign sign = (Sign) e.getClickedBlock().getState(); + if (sign.getLine(0).equals(ChatColor.DARK_AQUA + "[UnLoad]")) { + CargoMain.getInstance().unload(e.getPlayer()); + return; + } + if (sign.getLine(0).equals(ChatColor.DARK_AQUA + "[Load]")) { + CargoMain.getInstance().load(e.getPlayer()); + } + } +} diff --git a/src/main/java/io/github/cccm5/listener/SignPlaceListener.java b/src/main/java/io/github/cccm5/listener/SignPlaceListener.java new file mode 100644 index 0000000..3680b42 --- /dev/null +++ b/src/main/java/io/github/cccm5/listener/SignPlaceListener.java @@ -0,0 +1,18 @@ +package io.github.cccm5.listener; + +import org.bukkit.ChatColor; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.SignChangeEvent; +import org.jetbrains.annotations.NotNull; + +public class SignPlaceListener implements Listener { + @EventHandler + public void onSignPlace(@NotNull SignChangeEvent e) { + String header = ChatColor.stripColor(e.getLine(0)); + if (!header.equalsIgnoreCase("[Load]") && !header.equalsIgnoreCase("[UnLoad]")) + return; + + e.setLine(0,ChatColor.DARK_AQUA + (ChatColor.stripColor(e.getLine(0))).replaceAll("u","U").replaceAll("l","L")); + } +} diff --git a/src/main/java/io/github/cccm5/Utils.java b/src/main/java/io/github/cccm5/util/CraftInventoryUtil.java similarity index 87% rename from src/main/java/io/github/cccm5/Utils.java rename to src/main/java/io/github/cccm5/util/CraftInventoryUtil.java index d8e09a9..3dda55f 100644 --- a/src/main/java/io/github/cccm5/Utils.java +++ b/src/main/java/io/github/cccm5/util/CraftInventoryUtil.java @@ -1,10 +1,7 @@ -package io.github.cccm5; +package io.github.cccm5.util; -import net.citizensnpcs.api.npc.NPC; -import net.citizensnpcs.api.npc.NPCRegistry; -import net.citizensnpcs.api.trait.Trait; -import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.MovecraftLocation; +import net.countercraft.movecraft.craft.Craft; import net.countercraft.movecraft.util.hitboxes.HitBox; import org.bukkit.Location; import org.bukkit.Material; @@ -16,30 +13,28 @@ import java.util.ArrayList; import java.util.List; - -public class Utils -{ +public class CraftInventoryUtil { private static final Material[] INVENTORY_MATERIALS = new Material[]{Material.CHEST, Material.TRAPPED_CHEST, Material.FURNACE, Material.HOPPER, Material.DROPPER, Material.DISPENSER, Material.BREWING_STAND, Material.BARREL}; /** * Converts a movecraftLocation Object to a bukkit Location Object - * + * * @param movecraftLoc the movecraft location to be converted * @param world the world of the location * @return the converted location */ - public static Location movecraftLocationToBukkitLocation(MovecraftLocation movecraftLoc, World world){ + private static Location movecraftLocationToBukkitLocation(MovecraftLocation movecraftLoc, World world){ return new Location(world,movecraftLoc.getX(),movecraftLoc.getY(),movecraftLoc.getZ()); } /** * Converts a list of movecraftLocation Object to a bukkit Location Object - * + * * @param movecraftLocations the movecraftLocations to be converted * @param world the world of the location * @return the converted location */ - public static ArrayList movecraftLocationToBukkitLocation(HitBox movecraftLocations, World world){ + private static ArrayList movecraftLocationToBukkitLocation(HitBox movecraftLocations, World world){ ArrayList locations = new ArrayList<>(); for(MovecraftLocation movecraftLoc : movecraftLocations){ locations.add(movecraftLocationToBukkitLocation(movecraftLoc,world)); @@ -47,19 +42,10 @@ public static ArrayList movecraftLocationToBukkitLocation(HitBox movec return locations; } - public static ArrayList getNPCsWithTrait(Class c){ - ArrayList npcs = new ArrayList<>(); - for(NPCRegistry registry : net.citizensnpcs.api.CitizensAPI.getNPCRegistries()) - for(NPC npc : registry) - if(npc.hasTrait(c)) - npcs.add(npc); - return npcs; - } - /** * Gets the first inventory of a lookup material type on a craft holding a specific item, returns null if none found * an input of null for item searches without checking inventory contents - * + * * @param craft the craft to scan * @param item the item to look for during the scan * @param lookup the materials to compare against while scanning @@ -111,7 +97,7 @@ public static List getInventoriesWithSpace(Craft craft, ItemStack ite * Gets the first inventory of a lookup material type on a craft holding a specific item, returns null if none found * an input of null for item searches without checking inventory contents * an input of an ItemStack with type set to Material.AIR for searches for empty space in an inventory - * + * * @param craft the craft to scan * @param item the item to look for during the scan * @param lookup the materials to compare against while scanning @@ -129,7 +115,7 @@ public static List getInventories(Craft craft, ItemStack item, Materi } if(craft == null) throw new IllegalArgumentException("craft must not be null"); - ArrayList invs = new ArrayList(); + ArrayList invs = new ArrayList(); for(Location loc : movecraftLocationToBukkitLocation(craft.getHitBox(),craft.getWorld())) for(Material m : lookup){ boolean foundStack=false; @@ -152,7 +138,4 @@ public static List getInventories(Craft craft, ItemStack item, Materi } return invs; } - - - } diff --git a/src/main/java/io/github/cccm5/util/NPCUtil.java b/src/main/java/io/github/cccm5/util/NPCUtil.java new file mode 100644 index 0000000..c0e6fc2 --- /dev/null +++ b/src/main/java/io/github/cccm5/util/NPCUtil.java @@ -0,0 +1,93 @@ +package io.github.cccm5.util; + +import com.degitise.minevid.dtlTraders.Main; +import com.degitise.minevid.dtlTraders.guis.AGUI; +import com.degitise.minevid.dtlTraders.guis.gui.TradeGUI; +import com.degitise.minevid.dtlTraders.guis.gui.TradeGUIPage; +import com.degitise.minevid.dtlTraders.guis.items.AGUIItem; +import com.degitise.minevid.dtlTraders.guis.items.TradableGUIItem; +import com.degitise.minevid.dtlTraders.utils.citizens.TraderTrait; +import io.github.cccm5.CargoMain; +import io.github.cccm5.CargoTrait; +import io.github.cccm5.config.Config; +import net.citizensnpcs.api.npc.NPC; +import net.citizensnpcs.api.npc.NPCRegistry; +import net.citizensnpcs.api.trait.Trait; +import net.countercraft.movecraft.MovecraftLocation; +import net.countercraft.movecraft.util.MathUtils; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class NPCUtil { + @NotNull + public static List getNPCsWithTrait(Class c){ + List npcs = new ArrayList<>(); + for(NPCRegistry registry : net.citizensnpcs.api.CitizensAPI.getNPCRegistries()) + for(NPC npc : registry) + if(npc.hasTrait(c)) + npcs.add(npc); + return npcs; + } + + @NotNull + public static List getNPCsInRange(MovecraftLocation center) { + List result = new ArrayList<>(); + for (NPC npc :NPCUtil.getNPCsWithTrait(CargoTrait.class)) { + if (!npc.isSpawned()) + continue; + + MovecraftLocation npcLocation = MathUtils.bukkit2MovecraftLoc(npc.getEntity().getLocation()); + double distanceSquared; + if (Config.cardinalDistance) { + distanceSquared = Math.abs(center.getX() - npcLocation.getX()) + Math.abs(center.getZ() - npcLocation.getZ()); + distanceSquared *= distanceSquared; + } + else { + distanceSquared = center.distanceSquared(npcLocation); + } + + if (distanceSquared <= (Config.scanRange * Config.scanRange)) { + result.add(npc); + } + } + if (Config.debug) { + CargoMain.getInstance().getLogger().info("Found " + result.size() + " merchants:"); + for (NPC npc : result) { + CargoMain.getInstance().getLogger().info("- " + npc.getId() + ": " + npc.getName()); + } + } + return result; + } + + @NotNull + public static Set getItems(@NotNull List merchants, ItemStack item, Main dtlTradersPlugin, String shopMode) { + Set result = new HashSet<>(); + for (NPC merchant : merchants) { + String guiName = merchant.getTrait(TraderTrait.class).getGUIName(); + AGUI gui = dtlTradersPlugin.getGuiListService().getGUI(guiName); + if (!(gui instanceof TradeGUI)) + continue; + + for (TradeGUIPage page : ((TradeGUI) gui).getPages()) { + for (AGUIItem guiItem : page.getItems(shopMode)) { + if (!(guiItem instanceof TradableGUIItem tradableItem)) + continue; + if (!guiItem.getMainItem().isSimilar(item) || guiItem.getMainItem().getAmount() > 1) + continue; + + result.add(tradableItem); + if (Config.debug) { + CargoMain.getInstance().getLogger().info("Found for $" + tradableItem.getTradePrice() + " in " + merchant.getId() + "/" + page.getPageName()); + } + } + } + } + return result; + } +}