diff --git a/build.gradle b/build.gradle index 041741b32..ae2cdc125 100644 --- a/build.gradle +++ b/build.gradle @@ -90,7 +90,7 @@ java { } paperweight { - addServerDependencyTo = configurations.named(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME).map { [it] as Set } + addServerDependencyTo = configurations.named(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME).map { [it] as Set } } tasks.withType(JavaCompile).configureEach { @@ -136,4 +136,4 @@ tasks.shadowJar { tasks.test { useJUnitPlatform() -} +} \ No newline at end of file diff --git a/src/main/java/fr/openmc/api/input/location/ItemInteraction.java b/src/main/java/fr/openmc/api/input/location/ItemInteraction.java index 2e386dc46..5dbed38e0 100644 --- a/src/main/java/fr/openmc/api/input/location/ItemInteraction.java +++ b/src/main/java/fr/openmc/api/input/location/ItemInteraction.java @@ -171,12 +171,10 @@ void onPlayerDeath(PlayerDeathEvent event) { * Méthode qui permet de verifier si l'item est celui avec qui on interagit */ private static boolean isItemInteraction(ItemStack item) { - if (item == null || item.getType() == Material.AIR) - return false; + if (item == null || item.getType() == Material.AIR) return false; ItemMeta meta = item.getItemMeta(); - if (meta == null) - return false; + if (meta == null) return false; if (item.hasItemMeta()) { PersistentDataContainer data = item.getItemMeta().getPersistentDataContainer(); diff --git a/src/main/java/fr/openmc/core/OMCPlugin.java b/src/main/java/fr/openmc/core/OMCPlugin.java index d7e811557..f164afadc 100644 --- a/src/main/java/fr/openmc/core/OMCPlugin.java +++ b/src/main/java/fr/openmc/core/OMCPlugin.java @@ -45,6 +45,7 @@ import fr.openmc.core.features.quests.QuestProgressSaveManager; import fr.openmc.core.features.quests.QuestsManager; import fr.openmc.core.features.settings.PlayerSettingsManager; +import fr.openmc.core.features.shops.managers.ShopManager; import fr.openmc.core.features.tickets.TicketManager; import fr.openmc.core.features.tpa.TPAManager; import fr.openmc.core.features.updates.UpdateManager; @@ -118,6 +119,7 @@ public class OMCPlugin extends JavaPlugin { () -> new LeaderboardManager(), () -> new MainMenu(), () -> new HologramLoader(), + ShopManager::new, HomeIconCacheManager::new )); @@ -191,7 +193,7 @@ public void onEnable() { } }); - // * Si ItemsAdder est pas présent, alors on charge les dernieres features maintenant + // * Si ItemsAdder n'est pas présent, alors on charge les dernières features maintenant if (!ItemsAdderHook.isEnable()) { loadAfterItemsAdder(); } diff --git a/src/main/java/fr/openmc/core/bootstrap/features/Feature.java b/src/main/java/fr/openmc/core/bootstrap/features/Feature.java index e75700094..54dbaeb1a 100644 --- a/src/main/java/fr/openmc/core/bootstrap/features/Feature.java +++ b/src/main/java/fr/openmc/core/bootstrap/features/Feature.java @@ -20,7 +20,7 @@ public abstract class Feature { * Lance l'initialisation avec des règles en fonction des interfaces mises (NotUnitTest, LoadIfEnable) */ public final void startInit() { - // Condition d'initialisation (si feature ne doit pas etre lancé dans les tests ou que elle nécéssite un hook) + // Condition d'initialisation (si feature ne doit pas être lancée dans les tests ou qu'elle nécessite un hook) if (this instanceof NotInUnitTest && OMCPlugin.isUnitTestVersion()) { OMCLogger.errorFormatted("Feature " + this.getClass().getSimpleName() + " non initialisée dans les Unit Tests"); return; @@ -49,7 +49,7 @@ public final void startInit() { OMCPlugin.registerEvents(listener); } } - // Enregistre les commands + // Enregistre les commandes if (this instanceof HasCommands hasCommands) { for (Object command : hasCommands.getCommands()) { CommandsManager.getHandler().register(command); @@ -81,7 +81,7 @@ public final void startDB(ConnectionSource connectionSource) throws SQLException } /** - * Sauvegarde la feature si elle a ete initialisee. + * Sauvegarde la feature si elle a ete initialisée. */ public final void startSave() { if (!initialize) return; @@ -90,9 +90,9 @@ public final void startSave() { } /** - * Indique si la feature a ete initialisee avec succes. + * Indique si la feature a ete initialisée avec succès. * - * @return True si l'initialisation a reussi + * @return True si l'initialisation a réussi */ public final boolean isInitialized() { return initialize; diff --git a/src/main/java/fr/openmc/core/disabled/corporation/manager/CompanyManager.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/CompanyManager.java.bak similarity index 98% rename from src/main/java/fr/openmc/core/disabled/corporation/manager/CompanyManager.java.bak rename to src/main/java/fr/openmc/core/disabled/corporation/CompanyManager.java.bak index 3b5d7c474..826270a8a 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/manager/CompanyManager.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/CompanyManager.java.bak @@ -1,4 +1,4 @@ -package fr.openmc.core.disabled.corporation.manager; +package fr.openmc.core.disabled.corporation; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.dao.DaoManager; @@ -10,14 +10,18 @@ import fr.openmc.core.CommandsManager; import fr.openmc.core.OMCPlugin; import fr.openmc.core.disabled.corporation.CorpPermission; import fr.openmc.core.disabled.corporation.MethodState; +import fr.openmc.core.features.city.City; +import fr.openmc.core.features.city.CityManager; +import fr.openmc.core.features.shops.MethodState; import fr.openmc.core.disabled.corporation.commands.CompanyCommand; -import fr.openmc.core.disabled.corporation.commands.ShopCommand; +import fr.openmc.core.features.shops.commands.ShopCommand; import fr.openmc.core.disabled.corporation.company.Company; import fr.openmc.core.disabled.corporation.company.CompanyOwner; -import fr.openmc.core.disabled.corporation.data.MerchantData; -import fr.openmc.core.disabled.corporation.listener.CustomItemsCompanyListener; -import fr.openmc.core.disabled.corporation.listener.ShopListener; +import fr.openmc.core.features.shops.data.MerchantData; +import fr.openmc.core.features.shops.listener.ShopListener; import fr.openmc.core.disabled.corporation.models.*; +import fr.openmc.core.features.shops.managers.PlayerShopManager; +import fr.openmc.core.features.shops.managers.ShopManager; import fr.openmc.core.disabled.corporation.shops.Shop; import fr.openmc.core.disabled.corporation.shops.ShopItem; import fr.openmc.core.disabled.corporation.shops.Supply; diff --git a/src/main/java/fr/openmc/core/disabled/corporation/ItemsAdderIntegration.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/ItemsAdderIntegration.java.bak deleted file mode 100644 index 543bfbc51..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/ItemsAdderIntegration.java.bak +++ /dev/null @@ -1,32 +0,0 @@ -package fr.openmc.core.disabled.corporation; - -import dev.lone.itemsadder.api.CustomFurniture; -import dev.lone.itemsadder.api.CustomStack; -import org.bukkit.block.Block; - -public class ItemsAdderIntegration { - - public static boolean placeShopFurniture(Block block) { - CustomStack customFurniture = CustomFurniture.getInstance("omc_company:caisse"); - if (customFurniture == null || block.getType() != org.bukkit.Material.AIR) - return false; - - CustomFurniture.spawn("omc_company:caisse", block); - return true; - } - - public static boolean removeShopFurniture(Block block) { - CustomStack placed = CustomFurniture.byAlreadySpawned(block); - if (placed == null || !placed.getNamespacedID().equals("omc_company:caisse")) - return false; - - CustomFurniture.remove(CustomFurniture.byAlreadySpawned(block).getEntity(), false); - return true; - } - - public static boolean hasFurniture(Block block) { - CustomStack placed = CustomFurniture.byAlreadySpawned(block); - return placed != null && placed.getNamespacedID().equals("omc_company:caisse"); - } - -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/MethodState.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/MethodState.java.bak deleted file mode 100644 index daecc69cf..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/MethodState.java.bak +++ /dev/null @@ -1,14 +0,0 @@ -package fr.openmc.core.disabled.corporation; - -import lombok.Getter; - -@Getter -public enum MethodState { - SUCCESS, - WARNING, - ERROR, - FAILURE, - ESCAPE, - SPECIAL - -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/commands/CompanyCommand.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/commands/CompanyCommand.java.bak index 3af19adf6..28c726ee7 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/commands/CompanyCommand.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/commands/CompanyCommand.java.bak @@ -3,11 +3,11 @@ package fr.openmc.core.disabled.corporation.commands; import fr.openmc.core.features.city.City; import fr.openmc.core.features.city.CityManager; import fr.openmc.core.disabled.corporation.CorpPermission; -import fr.openmc.core.disabled.corporation.MethodState; +import fr.openmc.core.features.shops.MethodState; import fr.openmc.core.disabled.corporation.company.Company; import fr.openmc.core.disabled.corporation.company.CompanyOwner; -import fr.openmc.core.disabled.corporation.manager.CompanyManager; -import fr.openmc.core.disabled.corporation.manager.PlayerShopManager; +import fr.openmc.core.disabled.corporation.CompanyManager; +import fr.openmc.core.features.shops.managers.PlayerShopManager; import fr.openmc.core.disabled.corporation.menu.company.CompanyBaltopMenu; import fr.openmc.core.disabled.corporation.menu.company.CompanyMenu; import fr.openmc.core.disabled.corporation.menu.company.CompanySearchMenu; diff --git a/src/main/java/fr/openmc/core/disabled/corporation/commands/ShopCommand.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/commands/ShopCommand.java.bak index 8633a054e..ed1d099e4 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/commands/ShopCommand.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/commands/ShopCommand.java.bak @@ -13,7 +13,7 @@ import fr.openmc.core.disabled.corporation.shops.Shop; import fr.openmc.core.disabled.corporation.shops.ShopItem; import fr.openmc.core.disabled.corporation.shops.Supply; import fr.openmc.core.features.economy.EconomyManager; -import fr.openmc.core.utils.bukkit.ItemUtils; +import fr.openmc.core.utils.ItemUtils; import fr.openmc.core.utils.messages.MessageType; import fr.openmc.core.utils.messages.MessagesManager; import fr.openmc.core.utils.messages.Prefix; diff --git a/src/main/java/fr/openmc/core/disabled/corporation/company/Company.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/company/Company.java.bak index d161d5b77..8d1620ab4 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/company/Company.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/company/Company.java.bak @@ -2,17 +2,17 @@ package fr.openmc.core.disabled.corporation.company; import fr.openmc.core.OMCPlugin; import fr.openmc.core.disabled.corporation.CorpPermission; -import fr.openmc.core.disabled.corporation.MethodState; -import fr.openmc.core.disabled.corporation.data.MerchantData; -import fr.openmc.core.disabled.corporation.data.TransactionData; -import fr.openmc.core.disabled.corporation.manager.CompanyManager; -import fr.openmc.core.disabled.corporation.manager.ShopBlocksManager; +import fr.openmc.core.features.shops.MethodState; +import fr.openmc.core.features.shops.data.MerchantData; +import fr.openmc.core.features.shops.data.TransactionData; +import fr.openmc.core.disabled.corporation.CompanyManager; +import fr.openmc.core.features.shops.managers.ShopManager; import fr.openmc.core.disabled.corporation.models.DBCompany; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.disabled.corporation.shops.ShopOwner; import fr.openmc.core.features.city.City; import fr.openmc.core.features.city.CityManager; import fr.openmc.core.features.city.CityPermission; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.features.shops.shops.ShopOwner; import fr.openmc.core.features.economy.EconomyManager; import fr.openmc.core.utils.types.Queue; import fr.openmc.core.utils.bukkit.SkullUtils; @@ -62,7 +62,7 @@ public class Company { addPermission(owner.getPlayer(), CorpPermission.OWNER); addMerchant(owner.getPlayer(), new MerchantData()); } - + // à revoir, je l'utilisais pour les entreprises de ville public Company(String name, CompanyOwner owner, UUID company_uuid, boolean newMember) { this.name = name; @@ -255,7 +255,7 @@ public class Company { return false; } - Shop newShop = new Shop(new ShopOwner(this), shopCounter); + Shop newShop = new Shop(new ShopOwner(), shopCounter); EconomyManager.withdrawBalance(whoCreated.getUniqueId(), 100); shops.add(newShop); diff --git a/src/main/java/fr/openmc/core/disabled/corporation/listener/CustomItemsCompanyListener.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/listener/CustomItemsCompanyListener.java.bak deleted file mode 100644 index 76506afc1..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/listener/CustomItemsCompanyListener.java.bak +++ /dev/null @@ -1,45 +0,0 @@ -package fr.openmc.core.disabled.corporation.listener; - -import dev.lone.itemsadder.api.CustomFurniture; -import dev.lone.itemsadder.api.Events.FurnitureBreakEvent; -import dev.lone.itemsadder.api.Events.FurnitureInteractEvent; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.disabled.corporation.manager.ShopBlocksManager; -import fr.openmc.core.disabled.corporation.menu.shop.ShopMenu; -import org.bukkit.Location; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - -public class CustomItemsCompanyListener implements Listener { - - @EventHandler - public void onFurnitureBreak(FurnitureBreakEvent event){ - CustomFurniture furniture = event.getFurniture(); - - if (furniture!=null && furniture.getNamespacedID().equals("omc_company:caisse") && !event.getPlayer().isOp()){ - event.setCancelled(true); - } - } - - @EventHandler - public void onFurnitureInteract(FurnitureInteractEvent e){ - if (e.getFurniture() == null) { - return; - } - - if (e.getFurniture().getNamespacedID().equals("omc_company:caisse")){ - - double x = e.getFurniture().getEntity().getLocation().getBlockX(); - double y = e.getFurniture().getEntity().getLocation().getBlockY(); - double z = e.getFurniture().getEntity().getLocation().getBlockZ(); - - Shop shop = ShopBlocksManager.getShop(new Location(e.getFurniture().getEntity().getWorld(), x, y, z)); - if (shop == null) { - return; - } - e.setCancelled(true); - ShopMenu menu = new ShopMenu(e.getPlayer(), shop, 0); - menu.open(); - } - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/listener/ShopListener.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/listener/ShopListener.java.bak deleted file mode 100644 index 7b899a0f4..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/listener/ShopListener.java.bak +++ /dev/null @@ -1,209 +0,0 @@ -package fr.openmc.core.disabled.corporation.listener; - -import fr.openmc.core.disabled.corporation.CorpPermission; -import fr.openmc.core.disabled.corporation.company.Company; -import fr.openmc.core.disabled.corporation.manager.CompanyManager; -import fr.openmc.core.disabled.corporation.manager.ShopBlocksManager; -import fr.openmc.core.disabled.corporation.menu.shop.ShopMenu; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.utils.messages.MessageType; -import fr.openmc.core.utils.messages.MessagesManager; -import fr.openmc.core.utils.messages.Prefix; -import net.kyori.adventure.text.Component; -import org.bukkit.Material; -import org.bukkit.Tag; -import org.bukkit.block.Barrel; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockExplodeEvent; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryDragEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataType; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class ShopListener implements Listener { - - private final Map inShopBarrel = new HashMap<>(); - - @EventHandler - public void onShopBreak(BlockBreakEvent event) { - if (ShopBlocksManager.getShop(event.getBlock().getLocation()) != null) { - event.setCancelled(true); - } - } - - @EventHandler - public void onShopExplode(BlockExplodeEvent event){ - event.blockList().removeIf(block -> ShopBlocksManager.getShop(block.getLocation()) != null); - } - - @EventHandler - public void onEntityExplode(EntityExplodeEvent event) { - event.blockList().removeIf(block -> ShopBlocksManager.getShop(block.getLocation()) != null); - } - - @EventHandler - public void onShopClick(PlayerInteractEvent event) { - if (event.getClickedBlock() == null) { - return; - } - - // Check if the clicked block is a sign with tags - // Instead of getting the entire state of the block, - // This is much faster and avoids unnecessary overhead - if (!Tag.SIGNS.isTagged(event.getClickedBlock().getType())) - return; - - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) - return; - - Shop shop = ShopBlocksManager.getShop(event.getClickedBlock().getLocation()); - if (shop == null) - return; - - event.setCancelled(true); - ShopMenu menu = new ShopMenu(event.getPlayer(), shop, 0); - menu.open(); - } - - @EventHandler - public void onInteractWithBlock(PlayerInteractEvent e) { - Block block = e.getClickedBlock(); - if (block != null && block.getType() == Material.BARREL) { - Shop shop = ShopBlocksManager.getShop(block.getLocation()); - boolean isShop = shop!=null; - if (isShop){ - Company company = CompanyManager.getCompany(e.getPlayer().getUniqueId()); - if (company==null){ - if (shop.getOwner().getPlayer()==null){ - e.setCancelled(true); - return; - } - if (!shop.getOwner().getPlayer().equals(e.getPlayer().getUniqueId())){ - e.setCancelled(true); - return; - } - } else { - if (!company.hasShop(shop.getUuid())){ - e.setCancelled(true); - MessagesManager.sendMessage(e.getPlayer(), Component.text("Tu n'es pas dans l'entrprise possédant ce shop"), Prefix.SHOP, MessageType.INFO, false); - return; - } - - if (!company.hasPermission(e.getPlayer().getUniqueId(), CorpPermission.SUPPLY)){ - e.setCancelled(true); - MessagesManager.sendMessage(e.getPlayer(), Component.text("Tu n'as pas la permission de réapprovisionner le shop"), Prefix.SHOP, MessageType.INFO, false); - return; - } - } - } - inShopBarrel.put(e.getPlayer().getUniqueId(), isShop); - } - } - - @EventHandler - public void onShopPutItem(InventoryClickEvent e) { - UUID playerUUID = e.getWhoClicked().getUniqueId(); - if (inShopBarrel.getOrDefault(playerUUID, false)) { - Player player = (Player) e.getWhoClicked(); - Company company = CompanyManager.getCompany(playerUUID); - if (company!=null){ - if (!company.hasPermission(playerUUID, CorpPermission.SUPPLY)){ - MessagesManager.sendMessage(player, Component.text("Vous n'avez pas la permission de réapprovisionner les shops dans l'entreprise"), Prefix.SHOP, MessageType.INFO, false); - player.closeInventory(); - return; - } - } - - Inventory clickedInventory = e.getClickedInventory(); - - if (clickedInventory == null) return; - - if (clickedInventory.getHolder(false) instanceof Barrel) { - ItemStack currentItem = e.getCurrentItem(); - ItemStack cursorItem = e.getCursor(); - - if (e.isShiftClick() && isValidItem(currentItem)) { - removeSupplierKey(currentItem); - } - // Vérifier si un item est retiré - else if (e.getAction().name().contains("PICKUP") && isValidItem(currentItem)) { - removeSupplierKey(currentItem); - } - else if (e.getAction().name().contains("SWAP") && isValidItem(currentItem)) { - removeSupplierKey(currentItem); - } - // Vérifier si un item est placé avec la souris - else if (e.getAction().name().contains("PLACE") && isValidItem(cursorItem)) { - setSupplierKey(cursorItem, player.getUniqueId().toString()); - } - } else if (clickedInventory.getHolder(false) instanceof Player) { - ItemStack currentItem = e.getCurrentItem(); - - if (e.isShiftClick() && !e.getAction().name().contains("SWAP") && isValidItem(currentItem)) { - setSupplierKey(currentItem, player.getUniqueId().toString()); - } - } - } - } - - @EventHandler - public void onItemDrag(InventoryDragEvent e) { - UUID playerUUID = e.getWhoClicked().getUniqueId(); - if (inShopBarrel.getOrDefault(playerUUID, false) && e.getInventory().getHolder(false) instanceof Barrel) { - ItemStack item = e.getOldCursor(); - if (isValidItem(item)) { - removeSupplierKey(item); - } - } - } - - /** - * check if an item is valid - * - * @param item the item to check - * @return true if it's a valid item - */ - private boolean isValidItem(ItemStack item) { - return item != null && item.getType() != Material.AIR; - } - - /** - * add the SUPPLIER_KEY to an item - * - * @param item the item to add the key - * @param uuid the uuid of the player (the supplier_key) - */ - private void setSupplierKey(ItemStack item, String uuid) { - ItemMeta meta = item.getItemMeta(); - if (meta != null) { - meta.getPersistentDataContainer().set(CompanyManager.SUPPLIER_KEY, PersistentDataType.STRING, uuid); - item.setItemMeta(meta); - } - } - - /** - * remove the SUPPLIER_KEY to an item - * - * @param item the item to remove the key - */ - private void removeSupplierKey(ItemStack item) { - ItemMeta meta = item.getItemMeta(); - if (meta != null && meta.getPersistentDataContainer().has(CompanyManager.SUPPLIER_KEY)) { - meta.getPersistentDataContainer().remove(CompanyManager.SUPPLIER_KEY); - item.setItemMeta(meta); - } - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/manager/PlayerShopManager.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/manager/PlayerShopManager.java.bak deleted file mode 100644 index d893494e8..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/manager/PlayerShopManager.java.bak +++ /dev/null @@ -1,99 +0,0 @@ -package fr.openmc.core.disabled.corporation.manager; - -import fr.openmc.core.disabled.corporation.MethodState; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.disabled.corporation.shops.ShopOwner; -import fr.openmc.core.features.economy.EconomyManager; -import lombok.Getter; -import org.bukkit.Bukkit; -import org.bukkit.block.Block; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class PlayerShopManager { - - @Getter - private static final Map playerShops = new HashMap<>(); - - /** - * create a shop - * - * @param playerUUID the uuid of the player who creates it - * @param barrel the barrel block - * @param cashRegister the cash register - * @param shop_uuid the uuid of the shop if it already has one - * @return true if the shop has been created - */ - public static boolean createShop(UUID playerUUID, Block barrel, Block cashRegister, UUID shop_uuid) { - if (!EconomyManager.withdrawBalance(playerUUID, 500) && shop_uuid==null) { - return false; - } - Shop newShop; - if (shop_uuid != null) { - newShop = new Shop(new ShopOwner(playerUUID), 0, shop_uuid); - } else { - newShop = new Shop(new ShopOwner(playerUUID), 0); - } - - playerShops.put(playerUUID, newShop); - CompanyManager.shops.add(newShop); - ShopBlocksManager.registerMultiblock(newShop, - new Shop.Multiblock(barrel.getLocation(), cashRegister.getLocation())); - if (shop_uuid == null) { - ShopBlocksManager.placeShop(newShop, Bukkit.getPlayer(playerUUID), false); - } - return true; - } - - /** - * delete a shop - * - * @param playerUUID the uuid of the player who deletes the shop - * @return a Methode state - */ - public static MethodState deleteShop(UUID playerUUID) { - Shop shop = getPlayerShop(playerUUID); - if (!shop.getItems().isEmpty()) { - return MethodState.WARNING; - } - if (!ShopBlocksManager.removeShop(shop)) { - return MethodState.ESCAPE; - } - playerShops.remove(playerUUID); - CompanyManager.shops.remove(shop); - EconomyManager.addBalance(playerUUID, 400); - return MethodState.SUCCESS; - } - - /** - * get a shop from the uuid of a player - * - * @param playerUUID the uuid we check - * @return a shop if found - */ - public static Shop getPlayerShop(UUID playerUUID) { - return playerShops.get(playerUUID); - } - - /** - * get a shop from a shop uuid - * - * @param shop_uuid the uuid we check - * @return a shop if found - */ - public static Shop getShopByUUID(UUID shop_uuid) { - return playerShops.values().stream().filter(shop -> shop.getUuid().equals(shop_uuid)).findFirst().orElse(null); - } - - /** - * know if a player has a shop - * - * @param playerUUID the player to check - * @return true if a shop is found - */ - public static boolean hasShop(UUID playerUUID) { - return getPlayerShop(playerUUID) != null; - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/manager/ShopBlocksManager.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/manager/ShopBlocksManager.java.bak deleted file mode 100644 index bb3784ae4..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/manager/ShopBlocksManager.java.bak +++ /dev/null @@ -1,134 +0,0 @@ -package fr.openmc.core.disabled.corporation.manager; - -import fr.openmc.api.hooks.ItemsAdderHook; -import fr.openmc.core.OMCPlugin; -import fr.openmc.core.disabled.corporation.ItemsAdderIntegration; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.utils.world.WorldUtils; -import fr.openmc.core.utils.world.Yaw; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.Directional; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class ShopBlocksManager { - - private static final Map multiblocks = new HashMap<>(); - private static final Map shopsByLocation = new HashMap<>(); - - /** - * Registers a shop's multiblock structure and maps its key locations. - * - * @param shop The shop to register. - * @param multiblock The multiblock structure associated with the shop. - */ - public static void registerMultiblock(Shop shop, Shop.Multiblock multiblock) { - multiblocks.put(shop.getUuid(), multiblock); - Location stockLoc = multiblock.stockBlock(); - Location cashLoc = multiblock.cashBlock(); - shopsByLocation.put(stockLoc, shop); - shopsByLocation.put(cashLoc, shop); - } - - /** - * Retrieves the multiblock structure associated with a given UUID. - * - * @param uuid The UUID of the shop. - * @return The multiblock structure if it exists, otherwise null. - */ - public static Shop.Multiblock getMultiblock(UUID uuid) { - return multiblocks.get(uuid); - } - - /** - * Retrieves a shop located at a given location. - * - * @param location The location to check. - * @return The shop found at that location, or null if none exists. - */ - public static Shop getShop(Location location) { - return shopsByLocation.get(location); - } - - /** - * Places the shop block (sign or ItemsAdder furniture) in the world, - * oriented based on the player's direction. - * - * @param shop The shop to place. - * @param player The player placing the shop. - * @param isCompany Whether the shop belongs to a company (unused here but may be relevant elsewhere). - */ - public static void placeShop(Shop shop, Player player, boolean isCompany) { - Shop.Multiblock multiblock = multiblocks.get(shop.getUuid()); - if (multiblock == null) { - return; - } - Block cashBlock = multiblock.cashBlock().getBlock(); - Yaw yaw = WorldUtils.getYaw(player); - - if (ItemsAdderHook.isHasItemAdder()) { - boolean placed = ItemsAdderIntegration.placeShopFurniture(cashBlock); - if (!placed) { - cashBlock.setType(Material.OAK_SIGN); - } - } else { - cashBlock.setType(Material.OAK_SIGN); - } - - BlockData cashData = cashBlock.getBlockData(); - if (cashData instanceof Directional directional) { - directional.setFacing(yaw.getOpposite().toBlockFace()); - cashBlock.setBlockData(directional); - } - } - - /** - * Removes a shop from the world and unregisters its multiblock structure. - * Handles both ItemsAdder and fallback vanilla types. - * - * @param shop The shop to remove. - * @return True if successfully removed, false otherwise. - */ - public static boolean removeShop(Shop shop) { - Shop.Multiblock multiblock = multiblocks.get(shop.getUuid()); - if (multiblock == null) { - return false; - } - Block cashBlock = multiblock.cashBlock().getBlock(); - Block stockBlock = multiblock.stockBlock().getBlock(); - - if (ItemsAdderHook.isHasItemAdder()) { - - if (!ItemsAdderIntegration.hasFurniture(cashBlock)) { - return false; - } - if (!ItemsAdderIntegration.removeShopFurniture(cashBlock)){ - return false; - } - - } else { - if (cashBlock.getType() != Material.OAK_SIGN && cashBlock.getType() != Material.BARRIER || stockBlock.getType() != Material.BARREL) { - return false; - } - } - - // Async cleanup of location mappings - multiblocks.remove(shop.getUuid()); - cashBlock.setType(Material.AIR); - new BukkitRunnable() { - @Override - public void run() { - shopsByLocation.entrySet().removeIf(entry -> entry.getValue().getUuid().equals(shop.getUuid())); - } - }.runTaskAsynchronously(OMCPlugin.getInstance()); - return true; - } - -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyBaltopMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyBaltopMenu.java.bak index 02045a289..d2671d659 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyBaltopMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyBaltopMenu.java.bak @@ -5,8 +5,8 @@ import fr.openmc.api.menulib.Menu; import fr.openmc.api.menulib.utils.InventorySize; import fr.openmc.api.menulib.utils.ItemBuilder; import fr.openmc.core.disabled.corporation.company.Company; -import fr.openmc.core.disabled.corporation.data.MerchantData; -import fr.openmc.core.disabled.corporation.manager.CompanyManager; +import fr.openmc.core.features.shops.data.MerchantData; +import fr.openmc.core.disabled.corporation.CompanyManager; import fr.openmc.core.features.city.CityPermission; import fr.openmc.core.features.economy.EconomyManager; import fr.openmc.core.utils.bukkit.SkullUtils; diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyBankTransactionsMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyBankTransactionsMenu.java.bak index e2117629a..93a6fb520 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyBankTransactionsMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyBankTransactionsMenu.java.bak @@ -7,7 +7,7 @@ import fr.openmc.api.menulib.utils.InventorySize; import fr.openmc.api.menulib.utils.ItemBuilder; import fr.openmc.api.menulib.utils.StaticSlots; import fr.openmc.core.disabled.corporation.company.Company; -import fr.openmc.core.disabled.corporation.data.TransactionData; +import fr.openmc.core.features.shops.data.TransactionData; import fr.openmc.core.features.economy.EconomyManager; import fr.openmc.core.items.CustomItemRegistry; import org.bukkit.Bukkit; diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyMenu.java.bak index 1a3aa4924..88f962bd2 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanyMenu.java.bak @@ -6,7 +6,7 @@ import fr.openmc.api.menulib.utils.InventorySize; import fr.openmc.api.menulib.utils.ItemBuilder; import fr.openmc.api.menulib.utils.StaticSlots; import fr.openmc.core.disabled.corporation.company.Company; -import fr.openmc.core.disabled.corporation.data.MerchantData; +import fr.openmc.core.features.shops.data.MerchantData; import fr.openmc.core.features.economy.EconomyManager; import fr.openmc.core.items.CustomItemRegistry; import fr.openmc.core.utils.bukkit.SkullUtils; diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanySearchMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanySearchMenu.java.bak index ff6e0ab82..304d9c275 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanySearchMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/CompanySearchMenu.java.bak @@ -7,7 +7,7 @@ import fr.openmc.api.menulib.utils.InventorySize; import fr.openmc.api.menulib.utils.ItemBuilder; import fr.openmc.api.menulib.utils.StaticSlots; import fr.openmc.core.disabled.corporation.company.Company; -import fr.openmc.core.disabled.corporation.manager.CompanyManager; +import fr.openmc.core.disabled.corporation.CompanyManager; import fr.openmc.core.features.economy.EconomyManager; import fr.openmc.core.items.CustomItemRegistry; import org.bukkit.Material; diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/ShopManageMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/ShopManageMenu.java.bak index 81215150e..e20851452 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/company/ShopManageMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/company/ShopManageMenu.java.bak @@ -6,8 +6,8 @@ import fr.openmc.api.menulib.utils.InventorySize; import fr.openmc.api.menulib.utils.ItemBuilder; import fr.openmc.api.menulib.utils.StaticSlots; import fr.openmc.core.disabled.corporation.company.Company; -import fr.openmc.core.disabled.corporation.manager.ShopBlocksManager; -import fr.openmc.core.disabled.corporation.shops.Shop; +import fr.openmc.core.features.shops.managers.ShopManager; +import fr.openmc.core.features.shops.models.Shop; import fr.openmc.core.items.CustomItemRegistry; import net.kyori.adventure.text.Component; import org.bukkit.Material; diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopCatalogueMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopCatalogueMenu.java.bak index ceabba283..e69de29bb 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopCatalogueMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopCatalogueMenu.java.bak @@ -1,130 +0,0 @@ -package fr.openmc.core.disabled.corporation.menu.shop; - -import dev.lone.itemsadder.api.FontImages.FontImageWrapper; -import fr.openmc.api.menulib.PaginatedMenu; -import fr.openmc.api.menulib.utils.InventorySize; -import fr.openmc.api.menulib.utils.ItemBuilder; -import fr.openmc.api.menulib.utils.StaticSlots; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.disabled.corporation.shops.ShopItem; -import fr.openmc.core.items.CustomItemRegistry; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ShopCatalogueMenu extends PaginatedMenu { - private final Shop shop; - private final int itemIndex; - - public ShopCatalogueMenu(Player owner, Shop shop, int itemIndex) { - super(owner); - this.shop = shop; - this.itemIndex = itemIndex; - } - - @Override - public @NotNull InventorySize getInventorySize() { - return InventorySize.LARGEST; - } - - @Override - public int getSizeOfItems() { - return getItems().size(); - } - - @Override - public @Nullable Material getBorderMaterial() { - return null; - } - - @Override - public @NotNull List getStaticSlots() { - return StaticSlots.getStandardSlots(getInventorySize()); - } - - @Override - public List getItems() { - List items = new ArrayList<>(); - - for (ShopItem shopItem : shop.getItems()){ - items.add(new ItemBuilder(this, shopItem.getItem().getType(), itemMeta -> { - itemMeta.displayName(ShopItem.getItemName(shopItem.getItem()).color(NamedTextColor.GRAY).decorate(TextDecoration.BOLD)); - }).setOnClick(inventoryClickEvent -> { - new ShopMenu(getOwner(), shop, getIndex(shopItem)).open(); - })); - } - - return items; - } - - @Override - public Map getButtons() { - Map buttons = new HashMap<>(); - buttons.put(49, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_CANCEL, itemMeta -> itemMeta.setDisplayName("§7Fermer")) - .setCloseButton()); - ItemBuilder nextPageButton = new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_NEXT_ORANGE, itemMeta -> itemMeta.setDisplayName("§aPage suivante")); - if ((getPage() == 0 && isLastPage()) || shop.getItems().isEmpty()) { - buttons.put(48, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_BACK_ORANGE, itemMeta -> itemMeta.setDisplayName("§cRetour")) - .setOnClick(inventoryClickEvent -> new ShopMenu(getOwner(), shop, itemIndex).open())); - buttons.put(50, nextPageButton); - } else { - buttons.put(48, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_BACK_ORANGE, itemMeta -> itemMeta.setDisplayName("§cPage précédente")) - .setPreviousPageButton()); - buttons.put(50, nextPageButton.setNextPageButton()); - } - return buttons; - } - - @Override - public @NotNull String getName() { - return "Menu du shop " + shop.getName(); - } - - @Override - public String getTexture() { - return FontImageWrapper.replaceFontImages("§r§f:offset_-11::large_shop_menu:"); - } - - @Override - public void onInventoryClick(InventoryClickEvent inventoryClickEvent) { - - } - - @Override - public void onClose(InventoryCloseEvent event) { - - } - - @Override - public List getTakableSlot() { - return List.of(); - } - - /** - * get the index of a ShopItem - * - * @param shopItem the ShopItem - * @return the index of the ShopItem - */ - private int getIndex(ShopItem shopItem) { - int index = 0; - for (ShopItem items : shop.getItems()){ - if (items==shopItem){ - return index; - } - index ++; - } - return index; - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopMenu.java.bak index f60cb3767..e69de29bb 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopMenu.java.bak @@ -1,353 +0,0 @@ -package fr.openmc.core.disabled.corporation.menu.shop; - -import dev.lone.itemsadder.api.FontImages.FontImageWrapper; -import fr.openmc.api.menulib.Menu; -import fr.openmc.api.menulib.defaultmenu.ConfirmMenu; -import fr.openmc.api.menulib.utils.InventorySize; -import fr.openmc.api.menulib.utils.ItemBuilder; -import fr.openmc.core.disabled.corporation.MethodState; -import fr.openmc.core.disabled.corporation.company.Company; -import fr.openmc.core.disabled.corporation.manager.CompanyManager; -import fr.openmc.core.disabled.corporation.manager.PlayerShopManager; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.disabled.corporation.shops.ShopItem; -import fr.openmc.core.features.economy.EconomyManager; -import fr.openmc.core.items.CustomItemRegistry; -import fr.openmc.core.utils.bukkit.ItemUtils; -import fr.openmc.core.utils.messages.MessageType; -import fr.openmc.core.utils.messages.MessagesManager; -import fr.openmc.core.utils.messages.Prefix; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BookMeta; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ShopMenu extends Menu { - - private final List items = new ArrayList<>(); - private final Shop shop; - private final int itemIndex; - - private int amountToBuy = 1; - - public ShopMenu(Player owner, Shop shop, int itemIndex) { - super(owner); - this.shop = shop; - this.itemIndex = itemIndex; - items.addAll(shop.getItems()); - Shop.checkStock(shop); - } - - @Override - public @NotNull String getName() { - return "Menu du shop " + shop.getName(); - } - - @Override - public String getTexture() { - // if (shop.getOwner().isCompany()){ -// Company company = shop.getOwner().getCompany(); -// if (company.getAllMembers().contains(getOwner().getUniqueId())){ -// return FontImageWrapper.replaceFontImages("§r§f:offset_-11::shop_menu:"); -// } -// } -// if (!shop.isOwner(getOwner().getUniqueId())) -// return FontImageWrapper.replaceFontImages("§r§f:offset_-11::shop_menu:"); - return FontImageWrapper.replaceFontImages("§r§f:offset_-11::shop_menu:"); - } - - @Override - public @NotNull InventorySize getInventorySize() { - return InventorySize.LARGER; - } - - @Override - public void onInventoryClick(InventoryClickEvent inventoryClickEvent) { - - } - - @Override - public void onClose(InventoryCloseEvent event) { - - } - - @Override - public @NotNull Map getContent() { - Map content = new HashMap<>(); - Company company = null; - - if (shop.getOwner().isCompany()){ - company = shop.getOwner().getCompany(); - } - if ((company == null && shop.isOwner(getOwner().getUniqueId())) || (company != null && company.getAllMembers().contains(getOwner().getUniqueId()))) { - putOwnerItems(content); - } - - content.put(39, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_BACK_ORANGE, itemMeta -> { - itemMeta.setDisplayName("§cItem précédent"); - }).setOnClick(inventoryClickEvent -> new ShopMenu(getOwner(), shop, onFirstItem() ? itemIndex : itemIndex - 1).open())); - - content.put(41, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_NEXT_ORANGE, itemMeta -> { - itemMeta.setDisplayName("§aItem suivant"); - }).setOnClick(inventoryClickEvent -> new ShopMenu(getOwner(), shop, onLastItem() ? itemIndex : itemIndex + 1).open())); - - content.put(40, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_CANCEL, itemMeta -> { - itemMeta.setDisplayName("§7Fermer"); - }).setCloseButton()); - - content.put(19, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.MINUS_BTN, itemMeta -> { - itemMeta.setDisplayName("§5Définir à 1"); - }).setOnClick(inventoryClickEvent -> { - if (getCurrentItem() == null) return; - amountToBuy = 1; - open(); - })); - - content.put(20, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.get("omc_company:10_btn"), itemMeta -> { - itemMeta.setDisplayName("§cRetirer 10"); - }).setOnClick(inventoryClickEvent -> { - if (getCurrentItem() == null) return; - if (amountToBuy == 1) return; - if (amountToBuy - 10 < 1) { - amountToBuy = 1; - } else { - amountToBuy -= 10; - } - open(); - })); - content.put(21, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.BTN_1, itemMeta -> { - itemMeta.setDisplayName("§cRetirer 1"); - }).setOnClick(inventoryClickEvent -> { - if (getCurrentItem() == null) return; - if (amountToBuy == 1) return; - amountToBuy--; - open(); - })); - - if (getCurrentItem() != null) - content.put(22, new ItemBuilder(this, getCurrentItem().getItem(), itemMeta -> { - itemMeta.displayName(ItemUtils.getItemTranslation(getCurrentItem().getItem()).color(NamedTextColor.GRAY).decorate(TextDecoration.BOLD).decoration(TextDecoration.ITALIC, TextDecoration.State.FALSE)); - List lore = new ArrayList<>(); - lore.add("§7■ Prix: §c" + EconomyManager.getFormattedNumber(getCurrentItem().getPricePerItem() * amountToBuy)); - lore.add("§7■ En stock: " + EconomyManager.getFormattedSimplifiedNumber(getCurrentItem().getAmount())); - lore.add("§7■ Cliquez pour en acheter §f" + EconomyManager.getFormattedSimplifiedNumber(amountToBuy)); - itemMeta.setLore(lore); - }).setOnClick(inventoryClickEvent -> new ConfirmMenu(getOwner(), this::buyAccept, this::refuse, List.of(Component.text("§aAcheter")), List.of(Component.text("§cAnnuler l'achat"))).open())); - - content.put(23, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.BTN_1.getBest(), itemMeta -> { - itemMeta.setDisplayName("§aAjouter 1"); - }).setOnClick(inventoryClickEvent -> { - if (getCurrentItem() == null) return; - amountToBuy = getCurrentItem().getAmount()<=amountToBuy ? getCurrentItem().getAmount() : amountToBuy + 1; - open(); - })); - content.put(24, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.get("omc_company:10_btn").getBest(), itemMeta -> { - itemMeta.setDisplayName("§aAjouter 10"); - }).setOnClick(inventoryClickEvent -> { - if (getCurrentItem() == null) return; - amountToBuy = getCurrentItem().getAmount()<=amountToBuy ? getCurrentItem().getAmount() : amountToBuy + 10; - open(); - })); - - content.put(25, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.BTN_64.getBest(), itemMeta -> { - itemMeta.setDisplayName("§5Ajouter 64"); - }).setOnClick(inventoryClickEvent -> { - if (getCurrentItem() == null) return; - if (amountToBuy == 1) amountToBuy = 64; - else amountToBuy = getCurrentItem().getAmount()<=amountToBuy ? getCurrentItem().getAmount() : amountToBuy + 64; - open(); - })); - - content.put(44, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.COMPANY_BOX.getBest(), itemMeta -> { - itemMeta.setDisplayName("§7Catalogue"); - }).setOnClick(inventoryClickEvent -> new ShopCatalogueMenu(getOwner(), shop, itemIndex).open())); - - return content; - } - - @Override - public List getTakableSlot() { - return List.of(); - } - - private void putOwnerItems(Map content) { - - content.put(0, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.HOMES_ICON_BIN_RED.getBest(), itemMeta -> { - itemMeta.setDisplayName("§c§lSupprimer le shop"); - }).setOnClick(inventoryClickEvent -> new ConfirmMenu(getOwner(), this::accept, this::refuse, List.of(Component.text("§aSupprimer")), List.of(Component.text("§cAnnuler la suppression"))).open())); - - content.put(3, new ItemBuilder(this, Material.PAPER, itemMeta -> { - itemMeta.setDisplayName("§a§lVos ventes"); - List lore = new ArrayList<>(); - lore.add("§7■ Ventes: §f" + shop.getSales().size()); - lore.add("§7■ Cliquer pour voir vos ventes sur ce shop"); - itemMeta.setLore(lore); - }).setOnClick(inventoryClickEvent -> new ShopSalesMenu(getOwner(), shop, itemIndex).open())); - - content.put(4, shop.getIcon(this, true)); - - content.put(5, new ItemBuilder(this, Material.BARREL, itemMeta -> { - itemMeta.setDisplayName("§6§lVoir les stocks"); - List lore = new ArrayList<>(); - lore.add("§7■ Stocks: §f" + shop.getAllItemsAmount()); - lore.add("§7■ Cliquer pour voir les stocks de ce shop"); - itemMeta.setLore(lore); - }).setOnClick(inventoryClickEvent -> new ShopStocksMenu(getOwner(), shop, itemIndex).open())); - - content.put(8, new ItemBuilder(this, Material.LIME_WOOL, itemMeta -> { - itemMeta.setDisplayName("§aCe shop vous appartient"); - if (shop.getOwner().isCompany()) { - if (shop.getOwner().getCompany().getOwner().isCity()) { - itemMeta.setLore(List.of( - "§7■ Car vous faites partie de l'entreprise" - )); - } - } - })); - - content.put(36, new ItemBuilder(this, Material.WRITABLE_BOOK, itemMeta -> { - itemMeta.setDisplayName("§7Comment utiliser les shops"); - }).setOnClick(inventoryClickEvent -> { - - ItemStack book = new ItemStack(Material.WRITTEN_BOOK); - BookMeta meta = (BookMeta) book.getItemMeta(); - if (meta != null) { - meta.setTitle("Guide des Shop"); - meta.setAuthor("Nocolm"); - meta.addPage( - """ - Comment utiliser les shops ! - - §l§6Stock§r : - 1. Utilisez la commande §d§l/shop sell §r§7 §r en tenant l'item en main - 2. Ajoutez les items dans le barril §c§l* le raccourci avec les chiffres ne fonctionnera pas * - """ - ); - meta.addPage( - """ - 3. Ouvrez une fois le shop pour renouveler son stock - - Et voilà comment utiliser votre shops - - §6▪ Pour plus d'info : /shop help§r""" - ); - - book.setItemMeta(meta); - } - getOwner().closeInventory(); - getOwner().openBook(book); - - content.remove(44); - })); - } - - /** - * @return the current ShopItem - */ - private ShopItem getCurrentItem() { - if (itemIndex < 0 || itemIndex >= items.size()) { - return null; - } - return items.get(itemIndex); - } - - /** - * @return true if the menu is on the first item - */ - private boolean onFirstItem() { - return itemIndex == 0; - } - - /** - * @return true if the menu is on the last item - */ - private boolean onLastItem() { - return itemIndex == items.size() - 1; - } - - private void buyAccept() { - MethodState buyState = shop.buy(getCurrentItem(), amountToBuy, getOwner()); - if (buyState == MethodState.ERROR) { - MessagesManager.sendMessage(getOwner(), Component.text("§cVous n'avez pas assez d'argent pour acheter cet item"), Prefix.SHOP, MessageType.INFO, false); - getOwner().closeInventory(); - return; - } - - if (buyState == MethodState.FAILURE) { - MessagesManager.sendMessage(getOwner(), Component.text("§cVous ne pouvez pas acheter vos propres items"), Prefix.SHOP, MessageType.INFO, false); - getOwner().closeInventory(); - return; - } - - if (buyState == MethodState.WARNING) { - MessagesManager.sendMessage(getOwner(), Component.text("§cIl n'y a pas assez de stock pour acheter cet item"), Prefix.SHOP, MessageType.INFO, false); - getOwner().closeInventory(); - return; - } - if (buyState == MethodState.SPECIAL) { - MessagesManager.sendMessage(getOwner(), Component.text("§cVous n'avez pas assez de place dans votre inventaire"), Prefix.SHOP, MessageType.INFO, false); - getOwner().closeInventory(); - return; - } - if (buyState == MethodState.ESCAPE) { - MessagesManager.sendMessage(getOwner(), Component.text("§cErreur lors de l'achat"), Prefix.SHOP, MessageType.INFO, false); - getOwner().closeInventory(); - return; - } - MessagesManager.sendMessage(getOwner(), Component.text("§aVous avez bien acheté " + amountToBuy + " ").append( ItemUtils.getItemTranslation(getCurrentItem().getItem()).color(NamedTextColor.GREEN).decorate(TextDecoration.BOLD)).append(Component.text(" pour " + (getCurrentItem().getPricePerItem() * amountToBuy) + EconomyManager.getEconomyIcon())), Prefix.SHOP, MessageType.INFO, false); - getOwner().closeInventory(); - } - - private void accept () { - boolean isInCompany = CompanyManager.isInCompany(getOwner().getUniqueId()); - if (isInCompany) { - MethodState deleteState = CompanyManager.getCompany(getOwner().getUniqueId()).deleteShop(getOwner(), shop.getUuid()); - if (deleteState == MethodState.ERROR) { - MessagesManager.sendMessage(getOwner(), Component.text("§cCe shop n'existe pas dans votre entreprise"), Prefix.SHOP, MessageType.INFO, false); - return; - } - if (deleteState == MethodState.WARNING) { - MessagesManager.sendMessage(getOwner(), Component.text("§cCe shop n'est pas vide"), Prefix.SHOP, MessageType.INFO, false); - return; - } - if (deleteState == MethodState.SPECIAL) { - MessagesManager.sendMessage(getOwner(), Component.text("§cIl vous faut au minimum le nombre d'argent remboursable pour supprimer un shop et obtenir un remboursement dans la banque de votre entreprise"), Prefix.SHOP, MessageType.INFO, false); - return; - } - if (deleteState == MethodState.ESCAPE) { - MessagesManager.sendMessage(getOwner(), Component.text("§cCaisse introuvable (appelez un admin)"), Prefix.SHOP, MessageType.INFO, false); - } - MessagesManager.sendMessage(getOwner(), Component.text("§a" + shop.getName() + " a été supprimé !"), Prefix.SHOP, MessageType.INFO, false); - MessagesManager.sendMessage(getOwner(), Component.text("§6[Shop]§a +75" + EconomyManager.getEconomyIcon() + " de remboursés sur la banque de l'entreprise"), Prefix.SHOP, MessageType.INFO, false); - } - else { - MethodState methodState = PlayerShopManager.deleteShop(getOwner().getUniqueId()); - if (methodState == MethodState.WARNING) { - MessagesManager.sendMessage(getOwner(), Component.text("§cVotre shop n'est pas vide"), Prefix.SHOP, MessageType.INFO, false); - return; - } - if (methodState == MethodState.ESCAPE) { - MessagesManager.sendMessage(getOwner(), Component.text("§cCaisse introuvable (appelez un admin)"), Prefix.SHOP, MessageType.INFO, false); - return; - } - MessagesManager.sendMessage(getOwner(), Component.text("§aVotre shop a bien été supprimé !"), Prefix.SHOP, MessageType.INFO, false); - MessagesManager.sendMessage(getOwner(), Component.text("§6[Shop]§a +400" + EconomyManager.getEconomyIcon() + " de remboursés sur votre compte personnel"), Prefix.SHOP, MessageType.INFO, false); - } - getOwner().closeInventory(); - } - - private void refuse() { - getOwner().closeInventory(); - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopSalesMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopSalesMenu.java.bak index 4f2d258c9..e69de29bb 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopSalesMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopSalesMenu.java.bak @@ -1,114 +0,0 @@ -package fr.openmc.core.disabled.corporation.menu.shop; - -import dev.lone.itemsadder.api.FontImages.FontImageWrapper; -import fr.openmc.api.menulib.PaginatedMenu; -import fr.openmc.api.menulib.utils.InventorySize; -import fr.openmc.api.menulib.utils.ItemBuilder; -import fr.openmc.api.menulib.utils.StaticSlots; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.disabled.corporation.shops.ShopItem; -import fr.openmc.core.features.economy.EconomyManager; -import fr.openmc.core.items.CustomItemRegistry; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ShopSalesMenu extends PaginatedMenu { - - private final Shop shop; - private final int itemIndex; - - public ShopSalesMenu(Player owner, Shop shop, int itemIndex) { - super(owner); - this.shop = shop; - this.itemIndex = itemIndex; - } - - @Override - public @NotNull InventorySize getInventorySize() { - return InventorySize.LARGEST; - } - - @Override - public int getSizeOfItems() { - return getItems().size(); - } - - @Override - public @Nullable Material getBorderMaterial() { - return null; - } - - @Override - public @NotNull List getStaticSlots() { - return StaticSlots.getStandardSlots(getInventorySize()); - } - - @Override - public List getItems() { - List items = new java.util.ArrayList<>(); - for (ShopItem sale : shop.getSales()) { - items.add(new ItemBuilder(this, sale.getItem().getType(), itemMeta -> { - itemMeta.displayName(ShopItem.getItemName(sale.getItem()).color(NamedTextColor.YELLOW).decorate(TextDecoration.BOLD)); - itemMeta.setLore(List.of( - "§7■ Prix : §a" + sale.getPrice() + EconomyManager.getEconomyIcon(), - "§7■ Quantité : §a" + sale.getAmount() - )); - })); - } - return items; - } - - @Override - public Map getButtons() { - Map buttons = new HashMap<>(); - buttons.put(49, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_CANCEL.getBest(), itemMeta -> itemMeta.setDisplayName("§7Fermer")) - .setCloseButton()); - ItemBuilder nextPageButton = new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_NEXT_ORANGE, itemMeta -> itemMeta.setDisplayName("§aPage suivante")); - if ((getPage() == 0 && isLastPage()) || shop.getSales().isEmpty()) { - buttons.put(48, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_BACK_ORANGE, itemMeta -> itemMeta.setDisplayName("§cRetour")) - .setOnClick(inventoryClickEvent -> new ShopMenu(getOwner(), shop, itemIndex).open())); - buttons.put(50, nextPageButton); - } else { - buttons.put(48, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_BACK_ORANGE, itemMeta -> itemMeta.setDisplayName("§cPage précédente")) - .setPreviousPageButton()); - buttons.put(50, nextPageButton.setNextPageButton()); - } - return buttons; - } - - @Override - public @NotNull String getName() { - return "Ventes de " + shop.getName(); - } - - @Override - public String getTexture() { - return FontImageWrapper.replaceFontImages("§r§f:offset_-11::large_shop_menu:"); - } - - @Override - public void onClose(InventoryCloseEvent event) { - - } - - @Override - public List getTakableSlot() { - return List.of(); - } - - @Override - public void onInventoryClick(InventoryClickEvent inventoryClickEvent) { - - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopSearchMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopSearchMenu.java.bak index dc8f2502e..e69de29bb 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopSearchMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopSearchMenu.java.bak @@ -1,170 +0,0 @@ -package fr.openmc.core.disabled.corporation.menu.shop; - -import dev.lone.itemsadder.api.FontImages.FontImageWrapper; -import fr.openmc.api.input.dialog.DialogInput; -import fr.openmc.api.menulib.PaginatedMenu; -import fr.openmc.api.menulib.utils.InventorySize; -import fr.openmc.api.menulib.utils.ItemBuilder; -import fr.openmc.api.menulib.utils.StaticSlots; -import fr.openmc.core.disabled.corporation.company.Company; -import fr.openmc.core.disabled.corporation.manager.CompanyManager; -import fr.openmc.core.disabled.corporation.manager.ShopBlocksManager; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.items.CustomItemRegistry; -import fr.openmc.core.utils.bukkit.ItemUtils; -import fr.openmc.core.utils.messages.MessageType; -import fr.openmc.core.utils.messages.MessagesManager; -import fr.openmc.core.utils.messages.Prefix; -import net.kyori.adventure.text.Component; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static fr.openmc.core.utils.text.InputUtils.MAX_LENGTH; - -public class ShopSearchMenu extends PaginatedMenu { - - public ShopSearchMenu(Player owner) { - super(owner); - } - - @Override - public @NotNull InventorySize getInventorySize() { - return InventorySize.LARGEST; - } - - @Override - public int getSizeOfItems() { - return getItems().size(); - } - - @Override - public @Nullable Material getBorderMaterial() { - return null; - } - - @Override - public @NotNull List getStaticSlots() { - return StaticSlots.getStandardSlots(getInventorySize()); - } - - @Override - public List getItems() { - List items = new java.util.ArrayList<>(); - - for (Shop shops : CompanyManager.shops){ - - if (shops==null){continue;} - - List loc = new ArrayList<>(); - double x = ShopBlocksManager.getMultiblock(shops.getUuid()).stockBlock().getBlockX(); - double y = ShopBlocksManager.getMultiblock(shops.getUuid()).stockBlock().getBlockY(); - double z = ShopBlocksManager.getMultiblock(shops.getUuid()).stockBlock().getBlockZ(); - - loc.add(Component.text("§lLocation : §r x : " + x + " y : " + y + " z : " + z)); - - items.add(new ItemBuilder(this, ItemUtils.getPlayerHead(getOwner().getUniqueId()) ,itemMeta -> { - itemMeta.setDisplayName("§lshop :§r" + shops.getName()); - itemMeta.lore(loc); - })); - } - - return items; - } - - @Override - public Map getButtons() { - Map buttons = new HashMap<>(); - buttons.put(49, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_CANCEL.getBest(), itemMeta -> itemMeta.setDisplayName("§7Fermer")) - .setCloseButton()); - ItemBuilder nextPageButton = new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_NEXT_ORANGE.getBest(), itemMeta -> itemMeta.setDisplayName("§aPage suivante")); - ItemBuilder searchButton = new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_SEARCH.getType(), itemMeta -> - itemMeta.setDisplayName("Rechercher")); - if ((getPage() != 0 && !isLastPage()) || !CompanyManager.getShops().isEmpty()) { - buttons.put(48, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_BACK_ORANGE, itemMeta -> itemMeta.setDisplayName("§cPage précédente")) - .setPreviousPageButton()); - buttons.put(50, nextPageButton.setNextPageButton()); - buttons.put(45, searchButton.setOnClick(inventoryClick -> { - DialogInput.send(getOwner(), Component.text("Entrez le nom du shop ou bien du joueur pour le rechercher"), MAX_LENGTH, input -> { - if (input == null) return; - - boolean shopFind = false; - - for (Shop shop : CompanyManager.shops) { - double x = ShopBlocksManager.getMultiblock(shop.getUuid()).stockBlock().getBlockX(); - double y = ShopBlocksManager.getMultiblock(shop.getUuid()).stockBlock().getBlockY(); - double z = ShopBlocksManager.getMultiblock(shop.getUuid()).stockBlock().getBlockZ(); - - if (shop.getName().contains(input)) { - MessagesManager.sendMessage(getOwner(), Component.text("§lLocation du shop §a" + shop.getName() + " : §r x : " + x + " y : " + y + " z : " + z), Prefix.SHOP, MessageType.INFO, false); - shopFind = true; - break; - } - Player player = Bukkit.getPlayer(input); - if (player == null) continue; - if (shop.getOwner().isCompany()) { - Company company = shop.getOwner().getCompany(); - if (company.getAllMembers().contains(player.getUniqueId())) { - MessagesManager.sendMessage(getOwner(), Component.text("§lLocation du shop §a" + shop.getName() + " : §r x : " + x + " y : " + y + " z : " + z), Prefix.SHOP, MessageType.INFO, false); - shopFind = true; - break; - } - } - if (shop.getOwner().isPlayer()) { - Player shopPlayer = Bukkit.getPlayer(shop.getOwner().getPlayer()); - if (shopPlayer == null) { - continue; - } - if (shopPlayer.equals(player)) { - MessagesManager.sendMessage(getOwner(), Component.text("§lLocation du shop §a" + shop.getName() + " : §r x : " + x + " y : " + y + " z : " + z), Prefix.SHOP, MessageType.INFO, false); - shopFind = true; - break; - } - } - } - - if (!shopFind) { - MessagesManager.sendMessage(getOwner(), Component.text("§cAucun shop trouvé !"), Prefix.SHOP, MessageType.INFO, false); - } - - }); - })); - } - return buttons; - } - - @Override - public @NotNull String getName() { - return "§l§6Menu de Recherche de Shop"; - } - - @Override - public String getTexture() { - return FontImageWrapper.replaceFontImages("§r§f:offset_-11::large_shop_menu:"); - } - - @Override - public void onInventoryClick(InventoryClickEvent inventoryClickEvent) { - - } - - @Override - public void onClose(InventoryCloseEvent event) { - - } - - @Override - public List getTakableSlot() { - return List.of(); - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopStocksMenu.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopStocksMenu.java.bak index 080579e83..e69de29bb 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopStocksMenu.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/menu/shop/ShopStocksMenu.java.bak @@ -1,188 +0,0 @@ -package fr.openmc.core.disabled.corporation.menu.shop; - -import dev.lone.itemsadder.api.FontImages.FontImageWrapper; -import fr.openmc.api.menulib.PaginatedMenu; -import fr.openmc.api.menulib.defaultmenu.ConfirmMenu; -import fr.openmc.api.menulib.utils.InventorySize; -import fr.openmc.api.menulib.utils.ItemBuilder; -import fr.openmc.api.menulib.utils.StaticSlots; -import fr.openmc.core.disabled.corporation.shops.Shop; -import fr.openmc.core.disabled.corporation.shops.ShopItem; -import fr.openmc.core.disabled.corporation.shops.Supply; -import fr.openmc.core.features.economy.EconomyManager; -import fr.openmc.core.items.CustomItemRegistry; -import fr.openmc.core.utils.bukkit.ItemUtils; -import fr.openmc.core.utils.messages.MessageType; -import fr.openmc.core.utils.messages.MessagesManager; -import fr.openmc.core.utils.messages.Prefix; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -public class ShopStocksMenu extends PaginatedMenu { - - private final Shop shop; - private final int itemIndex; - private ShopItem stock; - private final List accetpMsg = new ArrayList<>(); - private final List denyMsg = new ArrayList<>(); - - public ShopStocksMenu(Player owner, Shop shop, int itemIndex) { - super(owner); - this.shop = shop; - this.itemIndex = itemIndex; - - accetpMsg.add(Component.text("§aRécupérer")); - denyMsg.add(Component.text("§cAnnuler")); - } - - @Override - public @NotNull InventorySize getInventorySize() { - return InventorySize.LARGEST; - } - - @Override - public int getSizeOfItems() { - return getItems().size(); - } - - @Override - public @Nullable Material getBorderMaterial() { - return null; - } - - @Override - public @NotNull List getStaticSlots() { - return StaticSlots.getStandardSlots(getInventorySize()); - } - - @Override - public List getItems() { - List items = new java.util.ArrayList<>(); - - for (ShopItem stock : shop.getItems()) { - items.add(new ItemBuilder(this, stock.getItem().getType(), itemMeta -> { - itemMeta.displayName(ShopItem.getItemName(stock.getItem()).color(NamedTextColor.GRAY).decorate(TextDecoration.BOLD)); - itemMeta.setLore(List.of( - "§7■ Quantité restante : " + EconomyManager.getFormattedSimplifiedNumber(stock.getAmount()), - "§7■ Prix de vente (par item) : " + EconomyManager.getFormattedNumber(stock.getPricePerItem()), - "§7" + (stock.getAmount() > 0 ? "■ Click gauche pour récupérer le stock" : "■ Click gauche pour retirer l'item de la vente") - )); - }).setOnClick(inventoryClickEvent -> { - this.stock = stock; - new ConfirmMenu(getOwner(),this::accept, this::refuse,accetpMsg, denyMsg).open(); - })); - } - return items; - } - - @Override - public Map getButtons() { - Map buttons = new HashMap<>(); - buttons.put(49, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_CANCEL, itemMeta -> itemMeta.setDisplayName("§7Fermer")) - .setCloseButton()); - ItemBuilder nextPageButton = new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_NEXT_ORANGE, itemMeta -> itemMeta.setDisplayName("§aPage suivante")); - if ((getPage() == 0 && isLastPage()) || shop.getSales().isEmpty()) { - buttons.put(48, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_BACK_ORANGE, itemMeta -> itemMeta.setDisplayName("§cRetour")) - .setOnClick(inventoryClickEvent -> new ShopMenu(getOwner(), shop, itemIndex).open())); - buttons.put(50, nextPageButton); - } else { - buttons.put(48, new ItemBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_BACK_ORANGE, itemMeta -> itemMeta.setDisplayName("§cPage précédente")) - .setPreviousPageButton()); - buttons.put(50, nextPageButton.setNextPageButton()); - } - return buttons; - } - - @Override - public @NotNull String getName() { - return "Menu des Stocks de " + shop.getName(); - } - - @Override - public String getTexture() { - return FontImageWrapper.replaceFontImages("§r§f:offset_-11::large_shop_menu:"); - } - - @Override - public void onInventoryClick(InventoryClickEvent inventoryClickEvent) { - - } - - @Override - public void onClose(InventoryCloseEvent event) { - - } - - @Override - public List getTakableSlot() { - return List.of(); - } - - private void accept() { - Player owner = getOwner(); - - if (stock.getAmount() <= 0) { - shop.removeItem(stock); - MessagesManager.sendMessage(owner, Component.text("§aL'item a bien été retiré du shop !"), Prefix.SHOP, MessageType.SUCCESS, false); - owner.closeInventory(); - return; - } - - int maxPlace = ItemUtils.getFreePlacesForItem(owner, stock.getItem()); - if (maxPlace <= 0) { - MessagesManager.sendMessage(owner, Component.text("§cVous n'avez pas assez de place"), Prefix.SHOP, MessageType.INFO, false); - owner.closeInventory(); - return; - } - - int toTake = Math.min(stock.getAmount(), maxPlace); - - ItemStack toGive = stock.getItem().clone(); - toGive.setAmount(toTake); - owner.getInventory().addItem(toGive); - stock.setAmount(stock.getAmount() - toTake); - - if (stock.getAmount() > 0) { - MessagesManager.sendMessage(owner, Component.text("§6Vous avez récupéré §a" + toTake + "§6 dans le stock de cet item"), Prefix.SHOP, MessageType.SUCCESS, false); - } else { - MessagesManager.sendMessage(owner, Component.text("§6Vous avez récupéré le stock restant de cet item"), Prefix.SHOP, MessageType.SUCCESS, false); - } - - // Mise à jour des suppliers - int toRemove = toTake; - Iterator> iterator = shop.getSuppliers().entrySet().iterator(); - while (iterator.hasNext() && toRemove > 0) { - Map.Entry entry = iterator.next(); - Supply supply = entry.getValue(); - - if (!supply.getItemId().equals(stock.getItemID())) continue; - - int supplyAmount = supply.getAmount(); - - if (supplyAmount <= toRemove) { - toRemove -= supplyAmount; - iterator.remove(); - } else { - supply.setAmount(supplyAmount - toRemove); - break; - } - } - - owner.closeInventory(); - } - - - private void refuse() { - getOwner().closeInventory(); - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/models/DBShop.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/models/DBShop.java.bak deleted file mode 100644 index 8c5301c88..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/models/DBShop.java.bak +++ /dev/null @@ -1,43 +0,0 @@ -package fr.openmc.core.disabled.corporation.models; - -import java.util.UUID; - -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - -import lombok.Getter; - -@Getter -@DatabaseTable(tableName = "shops") -public class DBShop { - @DatabaseField(id = true) - private UUID id; - - @DatabaseField - private UUID owner; - @DatabaseField - private UUID city; - @DatabaseField - private UUID company; - - @DatabaseField(canBeNull = false) - private double x; - @DatabaseField(canBeNull = false) - private double y; - @DatabaseField(canBeNull = false) - private double z; - - DBShop() { - // required for ORMLite - } - - public DBShop(UUID id, UUID owner, UUID city, UUID company, double x, double y, double z) { - this.id = id; - this.owner = owner; - this.city = city; - this.company = company; - this.x = x; - this.y = y; - this.z = z; - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/models/DBShopItem.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/models/DBShopItem.java.bak deleted file mode 100644 index 14dc7367d..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/models/DBShopItem.java.bak +++ /dev/null @@ -1,46 +0,0 @@ -package fr.openmc.core.disabled.corporation.models; - -import java.util.UUID; - -import org.bukkit.inventory.ItemStack; - -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - -import fr.openmc.core.disabled.corporation.shops.ShopItem; -import lombok.Getter; - -@Getter -@DatabaseTable(tableName = "shop_items") -public class DBShopItem { - @DatabaseField(canBeNull = false, dataType = DataType.BYTE_ARRAY) - private byte[] items; - @DatabaseField(canBeNull = false) - private UUID shop; - @DatabaseField(canBeNull = false) - private double price; - @DatabaseField(canBeNull = false) - private int amount; - @DatabaseField(canBeNull = false, columnName = "item_uuid") - private UUID itemUuid; - - DBShopItem() { - // required for ORMLite - } - - public DBShopItem(byte[] items, UUID shop, double price, int amount, UUID itemUuid) { - this.items = items; - this.shop = shop; - this.price = price; - this.amount = amount; - this.itemUuid = itemUuid; - } - - public ShopItem deserialize() { - ItemStack item = ItemStack.deserializeBytes(items); - ShopItem shopItem = new ShopItem(item, price, itemUuid); - shopItem.setAmount(amount); - return shopItem; - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/models/DBShopSale.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/models/DBShopSale.java.bak deleted file mode 100644 index 169c9b495..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/models/DBShopSale.java.bak +++ /dev/null @@ -1,46 +0,0 @@ -package fr.openmc.core.disabled.corporation.models; - -import java.util.UUID; - -import org.bukkit.inventory.ItemStack; - -import com.j256.ormlite.field.DataType; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; - -import fr.openmc.core.disabled.corporation.shops.ShopItem; -import lombok.Getter; - -@Getter -@DatabaseTable(tableName = "shop_sales") -public class DBShopSale { - @DatabaseField(canBeNull = false, dataType = DataType.BYTE_ARRAY) - private byte[] items; - @DatabaseField(canBeNull = false) - private UUID shop; - @DatabaseField(canBeNull = false, columnName = "sale_uuid") - private UUID saleUuid; - @DatabaseField(canBeNull = false) - private double price; - @DatabaseField(canBeNull = false) - private int amount; - - DBShopSale() { - // required for ORMLite - } - - public DBShopSale(byte[] items, UUID shop, double price, int amount, UUID saleUuid) { - this.items = items; - this.shop = shop; - this.price = price; - this.amount = amount; - this.saleUuid = saleUuid; - } - - public ShopItem deserialize() { - ItemStack item = ItemStack.deserializeBytes(items); - ShopItem shopItem = new ShopItem(item, price, saleUuid); - shopItem.setAmount(amount); - return shopItem; - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/models/Merchant.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/models/Merchant.java.bak index a300b4cac..574806b3d 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/models/Merchant.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/models/Merchant.java.bak @@ -1,13 +1,12 @@ package fr.openmc.core.disabled.corporation.models; -import java.util.UUID; - import com.j256.ormlite.field.DataType; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; - import lombok.Getter; +import java.util.UUID; + @DatabaseTable(tableName = "merchants") public class Merchant { @DatabaseField(id = true) diff --git a/src/main/java/fr/openmc/core/disabled/corporation/models/ShopSupplier.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/models/ShopSupplier.java.bak deleted file mode 100644 index 8ba709e38..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/models/ShopSupplier.java.bak +++ /dev/null @@ -1,37 +0,0 @@ -package fr.openmc.core.disabled.corporation.models; - -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.table.DatabaseTable; -import lombok.Getter; - -import java.util.UUID; - -@DatabaseTable(tableName = "shop_suppliers") -@Getter -public class ShopSupplier { - @DatabaseField(id = true) - private UUID id; // différencie les supplier (un joueur peut avoir plusieurs suppliers) - @DatabaseField(canBeNull = false) - private UUID shop; - @DatabaseField(canBeNull = false) - private UUID item; - @DatabaseField(canBeNull = false) - private UUID player; - @DatabaseField(defaultValue = "0") - private int amount; - @DatabaseField(defaultValue = "0") - private long time; - - ShopSupplier() { - // required for ORMLite - } - - public ShopSupplier(UUID id, UUID shop, UUID item, UUID player, int amount, long time) { - this.id = id; - this.shop = shop; - this.item = item; - this.player = player; - this.amount = amount; - this.time = time; - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/shops/Shop.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/shops/Shop.java.bak index 4b1f88b84..e69de29bb 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/shops/Shop.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/shops/Shop.java.bak @@ -1,447 +0,0 @@ -package fr.openmc.core.disabled.corporation.shops; - -import fr.openmc.api.menulib.Menu; -import fr.openmc.api.menulib.utils.ItemBuilder; -import fr.openmc.core.disabled.corporation.MethodState; -import fr.openmc.core.disabled.corporation.manager.CompanyManager; -import fr.openmc.core.disabled.corporation.manager.ShopBlocksManager; -import fr.openmc.core.features.economy.EconomyManager; -import fr.openmc.core.utils.cache.CacheOfflinePlayer; -import fr.openmc.core.utils.bukkit.ItemUtils; -import fr.openmc.core.utils.messages.MessageType; -import fr.openmc.core.utils.messages.MessagesManager; -import fr.openmc.core.utils.messages.Prefix; -import lombok.Getter; -import net.kyori.adventure.text.Component; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Barrel; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; - -import java.util.*; - -@Getter -public class Shop { - - private final ShopOwner owner; - private final List items = new ArrayList<>(); - private final List sales = new ArrayList<>(); - private final Map suppliers = new HashMap<>(); - private final int index; - private final UUID uuid; - - private double turnover = 0; - - public Shop(ShopOwner owner, int index) { - this.owner = owner; - this.index = index; - this.uuid = UUID.randomUUID(); - } - - public Shop(ShopOwner owner, int index, UUID uuid) { - this.owner = owner; - this.index = index; - this.uuid = uuid; - } - - /** - * requirement : item need the uuid of the player who restock the shop - - * quand un item est vendu un partie du profit reviens a celui qui a approvisionner - * @param shop the shop we want to check the stock - */ - public static void checkStock(Shop shop) { - Multiblock multiblock = ShopBlocksManager.getMultiblock(shop.getUuid()); - - if (multiblock == null) { - return; - } - - Block stockBlock = multiblock.stockBlock().getBlock(); - if (stockBlock.getType() != Material.BARREL) { - ShopBlocksManager.removeShop(shop); - return; - } - - if (stockBlock.getState(false) instanceof Barrel barrel) { - - Inventory inventory = barrel.getInventory(); - for (ItemStack item : inventory.getContents()) { - if (item == null || item.getType() == Material.AIR) { - continue; - } - - ItemMeta itemMeta = item.getItemMeta(); - if (itemMeta == null) { - continue; - } - - PersistentDataContainer dataContainer = itemMeta.getPersistentDataContainer(); - if (dataContainer.has(CompanyManager.SUPPLIER_KEY, PersistentDataType.STRING)) { - - String supplierUUID = dataContainer.get(CompanyManager.SUPPLIER_KEY, PersistentDataType.STRING); - if (supplierUUID == null) { - continue; - } - - List possibleSuppliers = new ArrayList<>(); - if (shop.getOwner().isCompany()) { - possibleSuppliers.addAll(shop.getOwner().getCompany().getAllMembers()); - } - - if (shop.getOwner().isPlayer()) { - possibleSuppliers.add(shop.getOwner().getPlayer()); - } - - if (!possibleSuppliers.contains(UUID.fromString(supplierUUID))) { - continue; - } - boolean supplied = shop.supply(item, UUID.fromString(supplierUUID)); - if (supplied) inventory.remove(item); - } - } - } - } - - - public String getName() { - return owner.isCompany() ? ("Shop #" + index) : CacheOfflinePlayer.getOfflinePlayer(owner.getPlayer()).getName() + "'s Shop"; - } - - public UUID getSupremeOwner() { - return owner.isCompany() ? owner.getCompany().getOwner().getPlayer() : owner.getPlayer(); - } - - /** - * know if the uuid is the shop owner - * - * @param uuid the uuid we check - */ - public boolean isOwner(UUID uuid) { - if (owner.isCompany()) { - return owner.getCompany().isOwner(uuid); - } - return owner.getPlayer().equals(uuid); - } - - /** - * add an item to the shop - * - * @param itemStack the item - * @param price the price - * @param amount the amount of it - */ - public boolean addItem(ItemStack itemStack, double price, int amount, UUID itemID) { - - ShopItem item = itemID == null ? new ShopItem(itemStack, price) : new ShopItem(itemStack, price, itemID); - for (ShopItem shopItem : items) { - if (shopItem.getItem().isSimilar(itemStack)) { - return true; - } - } - if (amount>1){ - item.setAmount(amount); - } - items.add(item); - return false; - } - - public void addItem(ShopItem item){ - items.add(item); - } - - public void addSales(ShopItem item){ - sales.add(item); - } - - /** - * get an item from the shop - * - * @param index index of the item - */ - public ShopItem getItem(int index) { - return items.get(index); - } - - /** - * remove an item from the shop - * - * @param item the item to remove - */ - public void removeItem(ShopItem item) { - items.remove(item); - suppliers.entrySet().removeIf(entry -> entry.getValue().getItemId().equals(item.getItemID())); - } - - public int recoverItemOf(ShopItem item, Player supplier) { - int amount = item.getAmount(); - - if (ItemUtils.getFreePlacesForItem(supplier,item.getItem()) < amount){ - MessagesManager.sendMessage(supplier, Component.text("§cVous n'avez pas assez de place"), Prefix.SHOP, MessageType.INFO, false); - return 0; - } - - int toRemove = 0; - - Iterator> iterator = suppliers.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - if (entry.getValue().getSupplierUUID().equals(supplier.getUniqueId())) { - if (entry.getValue().getItemId().equals(item.getItemID())){ - amount -= entry.getValue().getAmount(); - toRemove += entry.getValue().getAmount(); - if (amount >= 0){ - iterator.remove(); - } - else { - break; - } - } - } - } - - if (amount == 0){ - items.remove(item); - MessagesManager.sendMessage(supplier, Component.text("§aL'item a bien été retiré du shop !"), Prefix.SHOP, MessageType.SUCCESS, false); - } else { - item.setAmount(amount); - } - - return toRemove; - } - - /** - * update the amount of all the item in the shop according to the items in the barrel - */ - public boolean supply(ItemStack item, UUID supplier) { - for (ShopItem shopItem : items) { - if (shopItem.getItem().getType().equals(item.getType())) { - int delay = 0; - shopItem.setAmount(shopItem.getAmount() + item.getAmount()); - while (suppliers.containsKey(System.currentTimeMillis() + delay)){ - delay ++; - } - suppliers.put(System.currentTimeMillis() + delay, new Supply(supplier, shopItem.getItemID(), item.getAmount())); - return true; - } - } - return false; - } - - public void addSupply(long time, Supply supply){ - suppliers.put(time, supply); - } - - - /** - * buy an item in the shop - * - * @param item the item to buy - * @param amountToBuy the amount of it - * @param buyer the player who buys - * @return a MethodState - */ - public MethodState buy(ShopItem item, int amountToBuy, Player buyer) { - if (!ItemUtils.hasAvailableSlot(buyer)) { - return MethodState.SPECIAL; - } - if (amountToBuy > item.getAmount()) { - return MethodState.WARNING; - } - if (isOwner(buyer.getUniqueId())) { - return MethodState.FAILURE; - } - if (!EconomyManager.withdrawBalance(buyer.getUniqueId(), item.getPrice(amountToBuy))) return MethodState.ERROR; - double basePrice = item.getPrice(amountToBuy); - turnover += item.getPrice(amountToBuy); - - if (owner.isCompany()) { - - double price = item.getPrice(amountToBuy);// prix total - - double companyCut = price * owner.getCompany().getCut();// prix après cut - - double suppliersCut = price - companyCut;// prix restant - - boolean supplied = false; - - List supplies = new ArrayList<>(); - for (Map.Entry entry : suppliers.entrySet()) { - if (entry.getValue().getItemId().equals(item.getItemID())) { - supplies.add(entry.getValue()); - } - } - - Map forSupplies = new HashMap<>(); - - if (!supplies.isEmpty()) { - - supplied = true; - - for (Supply supply : supplies) { - int suppliesAmount = supply.getAmount(); - - if (amountToBuy == suppliesAmount){// si la quantité achetée correspond au suppliesAmount ( ex : 32 = 32 ) - EconomyManager.addBalance(supply.getSupplier(), suppliersCut);// ajoutez prix restant - - if (forSupplies.containsKey(supply.getSupplier())){ - double supCut = forSupplies.get(supply.getSupplier()); - forSupplies.replace(supply.getSupplier(), supCut + suppliersCut); - } else { - forSupplies.put(supply.getSupplier(), suppliersCut); - } - removeLatestSupply();// retirer le supplier - break;// arrêter la boucle - } - - if (amountToBuy < suppliesAmount){// si la quantité achetée est inférieure au suppliesAmount ( ex : 32 < 64 ) - EconomyManager.addBalance(supply.getSupplier(), suppliersCut); - suppliesAmount -= amountToBuy; - supply.setAmount(suppliesAmount); - - if (forSupplies.containsKey(supply.getSupplier())){ - double supCut = forSupplies.get(supply.getSupplier()); - forSupplies.replace(supply.getSupplier(), supCut + suppliersCut); - } else { - forSupplies.put(supply.getSupplier(), suppliersCut); - } - break; - } - - else {// si la quantité achetée est supérieur au suppliesAmount ( ex : 64 > 32 ) - double supplierCut = (suppliesAmount * suppliersCut) / amountToBuy; - suppliersCut -= supplierCut; - amountToBuy -= suppliesAmount; - EconomyManager.addBalance(supply.getSupplier(), supplierCut); - - if (forSupplies.containsKey(supply.getSupplier())){ - double supCut = forSupplies.get(supply.getSupplier()); - forSupplies.replace(supply.getSupplier(), supCut + supplierCut); - } else { - forSupplies.put(supply.getSupplier(), supplierCut); - } - removeLatestSupply(); - } - - } - } - - if (!supplied) { - return MethodState.ESCAPE; - } - - for (Map.Entry entry : forSupplies.entrySet()) { - UUID supplier = entry.getKey(); - double supplierCut = entry.getValue(); - - Player player = Bukkit.getPlayer(supplier); - if (player!=null){ - MessagesManager.sendMessage(player, Component.text(buyer.getName() + " a acheté " + amountToBuy + " " + item.getItem().getType() + " pour " + basePrice + EconomyManager.getEconomyIcon() + ", vous avez reçu : " + supplierCut + EconomyManager.getEconomyIcon()), Prefix.SHOP, MessageType.SUCCESS, false); - } - } - - owner.getCompany().depositWithoutWithdraw(companyCut, buyer, "Vente", getName()); - } - - else { - EconomyManager.addBalance(owner.getPlayer(), item.getPrice(amountToBuy)); - Player player = Bukkit.getPlayer(owner.getPlayer()); - if (player!=null){ - MessagesManager.sendMessage(player, Component.text(buyer.getName() + " a acheté " + amountToBuy + " " + item.getItem().getType() + " pour " + item.getPrice(amountToBuy) + EconomyManager.getEconomyIcon() + ", l'argent vous a été transféré !"), Prefix.SHOP, MessageType.SUCCESS, false); - } - } - - ItemStack toGive = item.getItem().clone(); - toGive.setAmount(amountToBuy); - - List stacks = ItemUtils.splitAmountIntoStack(toGive); - for (ItemStack stack : stacks) { - buyer.getInventory().addItem(stack); - } - - sales.add(item.copy().setAmount(amountToBuy)); - item.setAmount(item.getAmount() - amountToBuy); - - return MethodState.SUCCESS; - } - - private void removeLatestSupply() { - long latest = 0; - Supply supply = null; - for (Map.Entry entry : suppliers.entrySet()) { - if (entry.getKey() > latest) { - latest = entry.getKey(); - supply = entry.getValue(); - } - } - if (supply != null) { - suppliers.remove(latest); - } - } - - public boolean isSupplier(UUID playerUUID){ - for (Map.Entry entry : suppliers.entrySet()) { - if (entry.getValue().getSupplierUUID().equals(playerUUID)){ - return true; - } - } - return false; - } - - /** - * get the shop Icon - * - * @param menu the menu - * @param fromShopMenu know if it from shopMenu - */ - public ItemBuilder getIcon(Menu menu, boolean fromShopMenu) { - return new ItemBuilder(menu, fromShopMenu ? Material.GOLD_INGOT : Material.BARREL, itemMeta -> { - itemMeta.setDisplayName("§e§l" + (fromShopMenu ? "Informations" : getName())); - List lore = new ArrayList<>(); - lore.add("§7■ Chiffre d'affaire : " + EconomyManager.getFormattedNumber(turnover)); - lore.add("§7■ Ventes : §f" + sales.size()); - if (!fromShopMenu) - lore.add("§7■ Cliquez pour accéder au shop"); - itemMeta.setLore(lore); - }); - } - - public int getAllItemsAmount() { - int amount = 0; - for (ShopItem item : items) { - amount += item.getAmount(); - } - return amount; - } - - /** - * get the shop with what player looking - * - * @param player the player we check - * @param onlyCash if we only check the cach register - */ - public static UUID getShopPlayerLookingAt(Player player, boolean onlyCash) { - Block targetBlock = player.getTargetBlockExact(5); - - if (targetBlock == null) return null; - - if (targetBlock.getType() != Material.BARREL && targetBlock.getType() != Material.OAK_SIGN && targetBlock.getType() != Material.BARRIER) return null; - if (onlyCash) { - if (targetBlock.getType() != Material.OAK_SIGN && targetBlock.getType() != Material.BARRIER) return null; - } - Shop shop = ShopBlocksManager.getShop(targetBlock.getLocation()); - if (shop == null) return null; - return shop.getUuid(); - } - - public record Multiblock(Location stockBlock, Location cashBlock) { - - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/shops/ShopItem.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/shops/ShopItem.java.bak index dfd4fe628..e69de29bb 100644 --- a/src/main/java/fr/openmc/core/disabled/corporation/shops/ShopItem.java.bak +++ b/src/main/java/fr/openmc/core/disabled/corporation/shops/ShopItem.java.bak @@ -1,87 +0,0 @@ -package fr.openmc.core.disabled.corporation.shops; - -import fr.openmc.core.utils.bukkit.ItemUtils; -import lombok.Getter; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.kyori.adventure.text.format.TextDecoration; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.UUID; - -@Getter -public class ShopItem { - - private final UUID itemID; - private final ItemStack item; - private final double pricePerItem; - private double price; - private int amount; - - public ShopItem(ItemStack item, double pricePerItem) { - this.item = item.clone(); - this.pricePerItem = pricePerItem; - this.item.setAmount(1); - this.price = pricePerItem * amount; - this.amount = 0; - this.itemID = UUID.randomUUID(); - } - - public ShopItem(ItemStack item, double pricePerItem, UUID itemID) { - this.item = item.clone(); - this.pricePerItem = pricePerItem; - this.item.setAmount(1); - this.price = pricePerItem * amount; - this.amount = 0; - this.itemID = itemID; - } - - /** - * get the name of an item - * - * @param amount the new amount of the item - * @return default the ShopItem - */ - public ShopItem setAmount(int amount) { - this.amount = amount; - this.price = pricePerItem * amount; - return this; - } - - /** - * copy an ShopItem - * - * @return a copy of the ShopItem - */ - public ShopItem copy() { - return new ShopItem(item.clone(), pricePerItem); - } - - /** - * get the price of a certain amount of an item - * - * @param amount amount of item - * @return a price - */ - public double getPrice(int amount) { - return pricePerItem * amount; - } - - /** - * get the name of an item - * - * @param itemStack the item - * @return default name if the item has no custom name - */ - public static Component getItemName(ItemStack itemStack) { - if (itemStack.hasItemMeta()) { - ItemMeta itemMeta = itemStack.getItemMeta(); - if (itemMeta.hasDisplayName()) { - return itemMeta.displayName(); - } - } - // If no custom name, return default name - return ItemUtils.getItemTranslation(itemStack).color(NamedTextColor.GRAY).decorate(TextDecoration.BOLD); - } -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/shops/ShopOwner.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/shops/ShopOwner.java.bak deleted file mode 100644 index bdd5493d4..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/shops/ShopOwner.java.bak +++ /dev/null @@ -1,47 +0,0 @@ -package fr.openmc.core.disabled.corporation.shops; - -import fr.openmc.core.disabled.corporation.company.Company; -import lombok.Getter; - -import java.util.UUID; - -@Getter -public class ShopOwner { - - private final Company company; - private final UUID player; - - /** - * ShopOwner for a company or a player - * @param company to set a company as the owner - */ - - public ShopOwner(Company company) { - this.company = company; - this.player = null; - } - - /** - * ShopOwner for a company or a player - * @param owner to set a player as the owner - */ - public ShopOwner(UUID owner) { - this.company = null; - this.player = owner; - } - - /** - * know if it's a company - */ - public boolean isCompany() { - return company != null; - } - - /** - * know if it's a player - */ - public boolean isPlayer() { - return player != null; - } - -} diff --git a/src/main/java/fr/openmc/core/disabled/corporation/shops/Supply.java.bak b/src/main/java/fr/openmc/core/disabled/corporation/shops/Supply.java.bak deleted file mode 100644 index 7091aed94..000000000 --- a/src/main/java/fr/openmc/core/disabled/corporation/shops/Supply.java.bak +++ /dev/null @@ -1,30 +0,0 @@ -package fr.openmc.core.disabled.corporation.shops; - -import lombok.Getter; -import lombok.Setter; - -import java.util.UUID; - -@Getter -public class Supply { - - private final UUID supplier; - private final UUID itemId; - private final UUID supplierUUID; - @Setter - private int amount; - - public Supply(UUID supplier, UUID itemId, int amount) { - this.supplier = supplier; - this.itemId = itemId; - this.amount = amount; - this.supplierUUID = UUID.randomUUID(); - } - - public Supply(UUID supplier, UUID itemId, int amount, UUID supplierUUID) { - this.supplier = supplier; - this.itemId = itemId; - this.amount = amount; - this.supplierUUID = supplierUUID; - } -} diff --git a/src/main/java/fr/openmc/core/features/adminshop/AdminShopManager.java b/src/main/java/fr/openmc/core/features/adminshop/AdminShopManager.java index e0903228a..712affc6b 100644 --- a/src/main/java/fr/openmc/core/features/adminshop/AdminShopManager.java +++ b/src/main/java/fr/openmc/core/features/adminshop/AdminShopManager.java @@ -141,7 +141,7 @@ public static void sellItem(Player player, String itemId, int amount) { } double totalPrice = item.getActualSellPrice() * amount; // Calculate the total price for the items - ItemUtils.removeItemsFromInventory(player, item.getMaterial(), amount); // Remove items from the player's inventory + ItemUtils.removeItemsFromPlayerInventory(player, item.getMaterial(), amount); // Remove items from the player's inventory EconomyManager.addBalance(player.getUniqueId(), totalPrice, "Vente AdminShop"); // Add money to the player's balance Bukkit.getScheduler().runTask(OMCPlugin.getInstance(), () -> { Bukkit.getPluginManager().callEvent(new SellEvent(player, item)); diff --git a/src/main/java/fr/openmc/core/features/city/ProtectionsManager.java b/src/main/java/fr/openmc/core/features/city/ProtectionsManager.java index bb0baf035..a911e0388 100644 --- a/src/main/java/fr/openmc/core/features/city/ProtectionsManager.java +++ b/src/main/java/fr/openmc/core/features/city/ProtectionsManager.java @@ -3,11 +3,13 @@ import fr.openmc.core.OMCPlugin; import fr.openmc.core.features.city.listeners.protections.*; import fr.openmc.core.features.city.sub.war.War; +import fr.openmc.core.features.shops.managers.ShopManager; import fr.openmc.core.utils.text.messages.MessageType; import fr.openmc.core.utils.text.messages.MessagesManager; import fr.openmc.core.utils.text.messages.Prefix; import fr.openmc.core.utils.text.messages.TranslationManager; import org.bukkit.Location; +import org.bukkit.block.Barrel; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; @@ -82,7 +84,7 @@ public static boolean canExplodeNaturally(Location loc) { public static void checkCity(Player player, Cancellable event, City city) { if (!player.getWorld().getName().equals("world")) return; - if (city == null) return; // Pas de ville, pas de protection + if (city == null) return; // Pas de ville, pas de protection if (canBypassPlayer.contains(player.getUniqueId())) return; // Le joueur peut bypass les protections @@ -90,13 +92,19 @@ public static void checkCity(Player player, Cancellable event, City city) { if (!city.isMember(player)) { event.setCancelled(true); - cancelMessage(player); + cancelMessage(player); } } public static void verify(Entity entity, Cancellable event, Location loc) { if (!entity.getWorld().getName().equals("world")) return; + if (ShopManager.getShopAt(loc) != null) { + if (loc.getBlock().getState() instanceof Barrel) return; + event.setCancelled(true); + return; + } + City city = CityManager.getCityFromChunk(loc.getChunk().getX(), loc.getChunk().getZ()); // on regarde le claim ou l'action a été fait if (city == null || city.isInWar()) return; @@ -104,6 +112,7 @@ public static void verify(Entity entity, Cancellable event, Location loc) { if (canInteract(player, loc)) return; event.setCancelled(true); + cancelMessage(player); } else { event.setCancelled(true); diff --git a/src/main/java/fr/openmc/core/features/city/listeners/protections/InteractProtection.java b/src/main/java/fr/openmc/core/features/city/listeners/protections/InteractProtection.java index 2383d5317..8af007822 100644 --- a/src/main/java/fr/openmc/core/features/city/listeners/protections/InteractProtection.java +++ b/src/main/java/fr/openmc/core/features/city/listeners/protections/InteractProtection.java @@ -5,8 +5,10 @@ import fr.openmc.core.features.city.CityPermission; import fr.openmc.core.features.city.ProtectionsManager; import fr.openmc.core.features.city.sub.mascots.utils.MascotUtils; +import fr.openmc.core.features.shops.managers.ShopManager; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.Barrel; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -44,8 +46,6 @@ public void onInteract(PlayerInteractEvent event) { boolean isMinecart = isMinecart(itemType); boolean isTnt = itemType == Material.TNT; - Location loc = clickedBlock.getLocation(); - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { if (inHand != null && inHand.getType().isEdible()) { Material type = clickedBlock.getType(); @@ -53,7 +53,13 @@ public void onInteract(PlayerInteractEvent event) { if (!type.isInteractable()) return; } - City city = CityManager.getCityFromChunk(loc.getChunk().getX(), loc.getChunk().getZ()); + if (ShopManager.getShopAt(location) != null) { + if (clickedBlock.getState() instanceof Barrel) return; + event.setCancelled(true); + return; + } + + City city = CityManager.getCityFromChunk(location.getChunk().getX(), location.getChunk().getZ()); if (city == null) return; if (city.isMember(player)) { @@ -88,6 +94,7 @@ public void onInteractAtEntity(PlayerInteractAtEntityEvent event) { Entity rightClicked = event.getRightClicked(); if (rightClicked instanceof Player) return; + if (!INTERACTION_REFUSED.contains(rightClicked.getType())) return; if (MascotUtils.canBeAMascot(rightClicked)) return; diff --git a/src/main/java/fr/openmc/core/features/city/sub/milestone/requirements/ItemDepositRequirement.java b/src/main/java/fr/openmc/core/features/city/sub/milestone/requirements/ItemDepositRequirement.java index 78613e1b7..044961750 100644 --- a/src/main/java/fr/openmc/core/features/city/sub/milestone/requirements/ItemDepositRequirement.java +++ b/src/main/java/fr/openmc/core/features/city/sub/milestone/requirements/ItemDepositRequirement.java @@ -160,7 +160,7 @@ public void runAction(Menu menu, City city, InventoryClickEvent e) { int toRemove = e.isShiftClick() ? remaining : 1; - int removed = ItemUtils.removeItemsFromInventory(player, itemType, toRemove); + int removed = ItemUtils.removeItemsFromPlayerInventory(player, itemType, toRemove); if (removed > 0) { MessagesManager.sendMessage(player, diff --git a/src/main/java/fr/openmc/core/features/credits/Credits.java b/src/main/java/fr/openmc/core/features/credits/Credits.java index 12396bd39..bcb9829d3 100644 --- a/src/main/java/fr/openmc/core/features/credits/Credits.java +++ b/src/main/java/fr/openmc/core/features/credits/Credits.java @@ -22,6 +22,7 @@ import fr.openmc.core.features.privatemessage.PrivateMessageManager; import fr.openmc.core.features.quests.QuestsManager; import fr.openmc.core.features.settings.PlayerSettingsManager; +import fr.openmc.core.features.shops.managers.ShopManager; import fr.openmc.core.features.tickets.TicketManager; import fr.openmc.core.features.tpa.TPAManager; import fr.openmc.core.registry.items.CustomItem; @@ -60,6 +61,7 @@ public enum Credits { PRIVATEMESSAGE(Material.ZOMBIE_HEAD, "feature.credits.feature.privatemessage", PrivateMessageManager.class), QUEST(OMCRegistry.CUSTOM_ITEMS.HOMES_ICON_CHATEAU, "feature.credits.feature.quest", QuestsManager.class), SETTINGS(Material.REDSTONE_TORCH, "feature.credits.feature.settings", PlayerSettingsManager.class), + SHOPS(OMCRegistry.CUSTOM_ITEMS.CAISSE, "feature.credits.feature.shops", ShopManager.class), TICKETS(Material.BOOK, "feature.credits.feature.tickets", TicketManager.class), TPA(Material.ENDER_PEARL, "feature.credits.feature.tpa", TPAManager.class), RTP(Material.ENDER_PEARL, "feature.credits.feature.rtp", Set.of("miseur")), diff --git a/src/main/java/fr/openmc/core/features/dream/mecanism/altar/AltarManager.java b/src/main/java/fr/openmc/core/features/dream/mecanism/altar/AltarManager.java index 662be36f6..03427adde 100644 --- a/src/main/java/fr/openmc/core/features/dream/mecanism/altar/AltarManager.java +++ b/src/main/java/fr/openmc/core/features/dream/mecanism/altar/AltarManager.java @@ -108,8 +108,8 @@ public static void tryRitual(Player player, Location altarLoc) { return; } - ItemUtils.removeItemsFromInventory(player, soulOrb.getBest(), required); - ItemUtils.removeItemsFromInventory(player, hand, 1); + ItemUtils.removeItemsFromPlayerInventory(player, soulOrb.getBest(), required); + ItemUtils.removeItemsFromPlayerInventory(player, hand, 1); player.getInventory().addItem(recipe.getOutput().getBest()); diff --git a/src/main/java/fr/openmc/core/features/dream/mecanism/tradernpc/GlaciteTradeMenu.java b/src/main/java/fr/openmc/core/features/dream/mecanism/tradernpc/GlaciteTradeMenu.java index bb9330f9b..b8c4c69a1 100644 --- a/src/main/java/fr/openmc/core/features/dream/mecanism/tradernpc/GlaciteTradeMenu.java +++ b/src/main/java/fr/openmc/core/features/dream/mecanism/tradernpc/GlaciteTradeMenu.java @@ -91,7 +91,7 @@ public void onInventoryClick(InventoryClickEvent click) { return; } - ItemUtils.removeItemsFromInventory(player, eweniteItem, 1); + ItemUtils.removeItemsFromPlayerInventory(player, eweniteItem, 1); DreamPlayer dreamPlayer = DreamManager.getDreamPlayer(player); if (dreamPlayer == null) return; @@ -131,8 +131,8 @@ private void handleTrade(Player player, GlaciteTrade trade) { return; } - ItemUtils.removeItemsFromInventory(player, glaciteItem, tradeGlacite); - ItemUtils.removeItemsFromInventory(player, eweniteItem, tradeEwenite); + ItemUtils.removeItemsFromPlayerInventory(player, glaciteItem, tradeGlacite); + ItemUtils.removeItemsFromPlayerInventory(player, eweniteItem, tradeEwenite); player.getInventory().addItem(trade.getResult().getBest()); diff --git a/src/main/java/fr/openmc/core/features/economy/EconomyManager.java b/src/main/java/fr/openmc/core/features/economy/EconomyManager.java index fe79c9041..88ed6260b 100644 --- a/src/main/java/fr/openmc/core/features/economy/EconomyManager.java +++ b/src/main/java/fr/openmc/core/features/economy/EconomyManager.java @@ -16,6 +16,7 @@ import fr.openmc.core.features.economy.models.EconomyPlayer; import fr.openmc.core.hooks.itemsadder.ItemsAdderHook; import lombok.Getter; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.math.BigDecimal; @@ -239,4 +240,9 @@ public static String getEconomyIcon() { return "Ⓐ"; } } + + public static boolean hasEnoughMoney(@NotNull UUID uniqueId, int requiredAmount) { + double balance = EconomyManager.getBalance(uniqueId); + return balance >= requiredAmount; + } } diff --git a/src/main/java/fr/openmc/core/features/economy/models/Bank.java b/src/main/java/fr/openmc/core/features/economy/models/Bank.java index 37b2ce80f..ade3af214 100644 --- a/src/main/java/fr/openmc/core/features/economy/models/Bank.java +++ b/src/main/java/fr/openmc/core/features/economy/models/Bank.java @@ -1,12 +1,11 @@ package fr.openmc.core.features.economy.models; -import java.util.UUID; - import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; - import lombok.Getter; +import java.util.UUID; + @Getter @DatabaseTable(tableName = "banks") public class Bank { diff --git a/src/main/java/fr/openmc/core/features/economy/models/EconomyPlayer.java b/src/main/java/fr/openmc/core/features/economy/models/EconomyPlayer.java index e523b9166..9c92ee4fc 100644 --- a/src/main/java/fr/openmc/core/features/economy/models/EconomyPlayer.java +++ b/src/main/java/fr/openmc/core/features/economy/models/EconomyPlayer.java @@ -1,12 +1,11 @@ package fr.openmc.core.features.economy.models; -import java.util.UUID; - import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; - import lombok.Getter; +import java.util.UUID; + @Getter @DatabaseTable(tableName = "balances") public class EconomyPlayer { diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/menus/HalloweenPumpkinDepositMenu.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/menus/HalloweenPumpkinDepositMenu.java index be9e8b6b7..008f48839 100644 --- a/src/main/java/fr/openmc/core/features/events/contents/halloween/menus/HalloweenPumpkinDepositMenu.java +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/menus/HalloweenPumpkinDepositMenu.java @@ -52,7 +52,7 @@ public String getTexture() { meta.setEnchantmentGlintOverride(true); }).setOnClick(event -> { Player player = (Player) event.getWhoClicked(); - int pumpkinCount = ItemUtils.removeItemsFromInventory(player, Material.PUMPKIN, Integer.MAX_VALUE); + int pumpkinCount = ItemUtils.removeItemsFromPlayerInventory(player, Material.PUMPKIN, Integer.MAX_VALUE); if (pumpkinCount == 0) { MessagesManager.sendMessage( player, diff --git a/src/main/java/fr/openmc/core/features/events/contents/weeklyevents/contents/contest/menu/ContributionMenu.java b/src/main/java/fr/openmc/core/features/events/contents/weeklyevents/contents/contest/menu/ContributionMenu.java index 27e9c915c..99d4bc90a 100644 --- a/src/main/java/fr/openmc/core/features/events/contents/weeklyevents/contents/contest/menu/ContributionMenu.java +++ b/src/main/java/fr/openmc/core/features/events/contents/weeklyevents/contents/contest/menu/ContributionMenu.java @@ -109,7 +109,7 @@ public void onInventoryClick(InventoryClickEvent click) { int shellCount = Arrays.stream(player.getInventory().getContents()).filter(is -> is != null && isSimilar(shellContestItem, is)).mapToInt(ItemStack::getAmount).sum(); if (ItemUtils.hasEnoughItems(player, shellContestItem, shellCount)) { - ItemUtils.removeItemsFromInventory(player, shellContestItem, shellCount); + ItemUtils.removeItemsFromPlayerInventory(player, shellContestItem, shellCount); int newPlayerPoints = shellCount + ContestManager.dataPlayer.get(player.getUniqueId()).getPoints(); int updatedCampPoints = shellCount + ContestManager.data.getInteger("points" + ContestManager.dataPlayer.get(player.getUniqueId()).getCamp()); diff --git a/src/main/java/fr/openmc/core/features/events/contents/weeklyevents/contents/contest/menu/TradeMenu.java b/src/main/java/fr/openmc/core/features/events/contents/weeklyevents/contents/contest/menu/TradeMenu.java index 8472b30dd..e6f94dc99 100644 --- a/src/main/java/fr/openmc/core/features/events/contents/weeklyevents/contents/contest/menu/TradeMenu.java +++ b/src/main/java/fr/openmc/core/features/events/contents/weeklyevents/contents/contest/menu/TradeMenu.java @@ -156,7 +156,7 @@ private void handleSingleTrade(Player player, ItemStack item, int itemsRemoved, sendNotEnoughMessage(player); return; } - ItemUtils.removeItemsFromInventory(player, item, itemsRemoved); + ItemUtils.removeItemsFromPlayerInventory(player, item, itemsRemoved); giveShells(player, shellsEarned); sendSuccessMessage(player, itemsRemoved, shellsEarned, tradeName); } @@ -185,7 +185,7 @@ private void handleBulkTrade(Player player, ItemStack item, int amount, int amou .sum(); int shellsEarned = (totalItems / amount) * amountShell; int itemsRemoved = (shellsEarned / amountShell) * amount; - ItemUtils.removeItemsFromInventory(player, item, itemsRemoved); + ItemUtils.removeItemsFromPlayerInventory(player, item, itemsRemoved); giveShells(player, shellsEarned); sendSuccessMessage(player, itemsRemoved, shellsEarned, tradeName); } diff --git a/src/main/java/fr/openmc/core/features/shops/ShopCommand.java b/src/main/java/fr/openmc/core/features/shops/ShopCommand.java new file mode 100644 index 000000000..d5cc896a8 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/ShopCommand.java @@ -0,0 +1,38 @@ +package fr.openmc.core.features.shops; + +import fr.openmc.core.features.economy.EconomyManager; +import fr.openmc.core.features.shops.managers.PlayerShopManager; +import fr.openmc.core.features.shops.managers.ShopManager; +import fr.openmc.core.utils.text.messages.MessageType; +import fr.openmc.core.utils.text.messages.MessagesManager; +import fr.openmc.core.utils.text.messages.Prefix; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import org.bukkit.entity.Player; +import revxrsal.commands.annotation.Command; +import revxrsal.commands.annotation.CommandPlaceholder; +import revxrsal.commands.annotation.Description; +import revxrsal.commands.annotation.Subcommand; +import revxrsal.commands.bukkit.annotation.CommandPermission; + +@Command("shop") +public class ShopCommand { + + @CommandPlaceholder + @CommandPermission("omc.commands.shop") + @Description("Create a shop") + public void createShop(Player player) { + if (!EconomyManager.hasEnoughMoney(player.getUniqueId(), 500)) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.not_enough_money", Component.text("500 " + EconomyManager.getEconomyIcon())), Prefix.SHOP, MessageType.ERROR, false); + return; + } + PlayerShopManager.startCreatingShop(player); + } + + @Subcommand("bypass") + @CommandPermission("omc.admins.commands.shop.bypass") + public void bypass(Player player) { + if (!ShopManager.shopBypass.contains(player.getUniqueId())) ShopManager.shopBypass.add(player.getUniqueId()); + else ShopManager.shopBypass.remove(player.getUniqueId()); + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/ShopFurniture.java b/src/main/java/fr/openmc/core/features/shops/ShopFurniture.java new file mode 100644 index 000000000..7fc97dbe5 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/ShopFurniture.java @@ -0,0 +1,55 @@ +package fr.openmc.core.features.shops; + +import dev.lone.itemsadder.api.CustomFurniture; +import dev.lone.itemsadder.api.CustomStack; +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.utils.world.Yaw; +import org.bukkit.Material; +import org.bukkit.block.Block; + +public class ShopFurniture { + + /** + * Places a specific type of shop furniture at the given block location using ItemsAdder API, oriented + * according to the player's yaw direction. + * + * @param block The block where the shop furniture should be placed. Must be of type AIR. + * @param playerYaw The yaw direction of the player, used to determine the orientation + * of the furniture. + * @return true if the furniture was successfully placed, false otherwise. + */ + public static boolean placeShopFurniture(Block block, Yaw playerYaw) { + CustomStack customFurniture = CustomFurniture.getInstance(OMCRegistry.CUSTOM_ITEMS.CAISSE.getId()); + if (customFurniture == null || block.getType() != Material.AIR) return false; + + CustomFurniture furniture = CustomFurniture.spawn(OMCRegistry.CUSTOM_ITEMS.CAISSE.getId(), block); + furniture.getEntity().setRotation(playerYaw.getPlayerYaw(), 0); + return true; + } + + /** + * Removes a specific type of shop furniture at the given block location using ItemsAdder API. + * + * @param block The block where the shop furniture is placed. + * @return true if the furniture was successfully removed, false otherwise. + */ + public static boolean removeShopFurniture(Block block) { + CustomStack placed = CustomFurniture.byAlreadySpawned(block); + if (placed == null || !placed.getNamespacedID().equals(OMCRegistry.CUSTOM_ITEMS.CAISSE.getId())) return false; + + CustomFurniture.remove(CustomFurniture.byAlreadySpawned(block).getEntity(), false); + return true; + } + + /** + * Checks if the specified block contains a specific type of shop furniture. + * + * @param block The block to check for shop furniture. Must not be null. + * @return true if the block contains the shop furniture, false otherwise. + */ + public static boolean hasFurniture(Block block) { + CustomStack placed = CustomFurniture.byAlreadySpawned(block); + return placed != null && placed.getNamespacedID().equals(OMCRegistry.CUSTOM_ITEMS.CAISSE.getId()); + } + +} \ No newline at end of file diff --git a/src/main/java/fr/openmc/core/features/shops/ShopListener.java b/src/main/java/fr/openmc/core/features/shops/ShopListener.java new file mode 100644 index 000000000..743653cd9 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/ShopListener.java @@ -0,0 +1,157 @@ +package fr.openmc.core.features.shops; + +import dev.lone.itemsadder.api.CustomFurniture; +import dev.lone.itemsadder.api.Events.FurnitureBreakEvent; +import dev.lone.itemsadder.api.Events.FurnitureInteractEvent; +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.features.shops.managers.ShopManager; +import fr.openmc.core.features.shops.menus.ShopMenu; +import fr.openmc.core.features.shops.menus.ShopSellingMenu; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.utils.text.messages.MessageType; +import fr.openmc.core.utils.text.messages.MessagesManager; +import fr.openmc.core.utils.text.messages.Prefix; +import fr.openmc.core.utils.text.messages.TranslationManager; +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockExplodeEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.Inventory; + +public class ShopListener implements Listener { + + @EventHandler + public void onShopBreak(BlockBreakEvent e) { + if (ShopManager.getShopAt(e.getBlock().getLocation()) != null) e.setCancelled(true); + } + + @EventHandler + public void onShopExplode(BlockExplodeEvent e) { + e.blockList().removeIf(block -> ShopManager.getShopAt(block.getLocation()) != null); + } + + @EventHandler + public void onEntityExplode(EntityExplodeEvent e) { + e.blockList().removeIf(block -> ShopManager.getShopAt(block.getLocation()) != null); + } + + @EventHandler + public void onShopClick(PlayerInteractEvent e) { + Block block = e.getClickedBlock(); + if (block == null) return; + if (!block.getType().equals(Material.OAK_SIGN)) return; + + // Check if the clicked block is a sign with tags + // Instead of getting the entire state of the block + // This is much faster and avoids unnecessary overhead + if (!Tag.SIGNS.isTagged(block.getType())) return; + + if (e.getAction() != Action.RIGHT_CLICK_BLOCK) return; + + Shop shop = ShopManager.getShopAt(block.getLocation()); + if (shop == null) return; + + e.setCancelled(true); + Player player = e.getPlayer(); + if (shop.isMenuOpened()) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.menu.already_opened"), Prefix.SHOP, MessageType.WARNING, false); + return; + } + + if (shop.hasItem()) { + new ShopMenu(player, shop).open(); + shop.setMenuOpened(true); + } else if (shop.isOwner(player)) { + new ShopSellingMenu(player, shop).open(); + shop.setMenuOpened(true); + } else { + MessagesManager.sendMessage(e.getPlayer(), TranslationManager.translation("feature.shop.no_item"), Prefix.SHOP, MessageType.ERROR, true); + } + } + + @EventHandler + public void onInteractWithBlock(PlayerInteractEvent e) { + if (e.getAction() != Action.RIGHT_CLICK_BLOCK) return; + Block block = e.getClickedBlock(); + if (block == null || block.getType() != Material.BARREL) return; + + Shop shop = ShopManager.getShopAt(block.getLocation()); + if (shop == null) return; + + Player player = e.getPlayer(); + if (shop.isOwner(player)) return; + + e.setCancelled(true); + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.is_not_him_shop"), Prefix.SHOP, MessageType.ERROR, true); + } + + @EventHandler + public void onFurnitureBreak(FurnitureBreakEvent e) { + CustomFurniture furniture = e.getFurniture(); + + if (furniture == null || !furniture.getNamespacedID().equals(OMCRegistry.CUSTOM_ITEMS.CAISSE.getId())) return; + + Entity furnitureEntity = furniture.getEntity(); + if (furnitureEntity == null) return; + if (ShopManager.getShopAt(furnitureEntity.getLocation().toBlockLocation()) == null) return; + e.setCancelled(true); + } + + @EventHandler + public void onFurnitureInteract(FurnitureInteractEvent e) { + CustomFurniture furniture = e.getFurniture(); + + if (furniture == null || !furniture.getNamespacedID().equals(OMCRegistry.CUSTOM_ITEMS.CAISSE.getId())) return; + + Player player = e.getPlayer(); + Entity furnitureEntity = furniture.getEntity(); + if (furnitureEntity == null) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.entity_is_null"), Prefix.SHOP, MessageType.ERROR, true); + return; + } + + Shop shop = ShopManager.getShopAt(furnitureEntity.getLocation().toBlockLocation()); + if (shop == null) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.shop_is_null"), Prefix.SHOP, MessageType.ERROR, true); + return; + } + + e.setCancelled(true); + if (shop.isMenuOpened()) { + MessagesManager.sendMessage(e.getPlayer(), TranslationManager.translation("feature.shop.menu.already_opened"), Prefix.SHOP, MessageType.WARNING, false); + return; + } + if (shop.hasItem()) { + new ShopMenu(player, shop).open(); + shop.setMenuOpened(true); + } else if (shop.isOwner(player)) { + new ShopSellingMenu(player, shop).open(); + shop.setMenuOpened(true); + } else { + MessagesManager.sendMessage(e.getPlayer(), TranslationManager.translation("feature.shop.no_item"), Prefix.SHOP, MessageType.ERROR, true); + } + } + + @EventHandler + public void onHopperPickUpItem(InventoryMoveItemEvent e) { + Inventory source = e.getSource(); + if (source.getLocation() == null) return; + if (ShopManager.getShopAt(source.getLocation().toBlockLocation()) == null) return; + e.setCancelled(true); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent e) { + ShopManager.shopBypass.remove(e.getPlayer().getUniqueId()); + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/managers/PlayerShopManager.java b/src/main/java/fr/openmc/core/features/shops/managers/PlayerShopManager.java new file mode 100644 index 000000000..289fb59de --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/managers/PlayerShopManager.java @@ -0,0 +1,165 @@ +package fr.openmc.core.features.shops.managers; + +import fr.openmc.api.input.location.ItemInteraction; +import fr.openmc.core.OMCPlugin; +import fr.openmc.core.bootstrap.integration.OMCLogger; +import fr.openmc.core.features.city.CityManager; +import fr.openmc.core.features.city.ProtectionsManager; +import fr.openmc.core.features.economy.EconomyManager; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.utils.text.messages.MessageType; +import fr.openmc.core.utils.text.messages.MessagesManager; +import fr.openmc.core.utils.text.messages.Prefix; +import fr.openmc.core.utils.text.messages.TranslationManager; +import fr.openmc.core.utils.world.WorldUtils; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Barrel; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class PlayerShopManager { + + /** + * Initiates the shop creation process for the specified player. + * + * @param player The player who is initiating the shop creation process. + */ + public static void startCreatingShop(Player player) { + if (!EconomyManager.withdrawBalance(player.getUniqueId(), 500)) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.not_enough_money", Component.text("500 " + EconomyManager.getEconomyIcon()).color(NamedTextColor.RED)), Prefix.SHOP, MessageType.ERROR, true); + return; + } + + ItemInteraction.runLocationInteraction( + player, + ItemStack.of(Material.BARREL), + "shops:shop_creator", + 300, + TranslationManager.translation("feature.shop.player.creating_begin"), + TranslationManager.translation("feature.shop.player.creating_cancel"), + location -> { + if (location == null) return false; + return createShop(player, location); + }, + () -> { + EconomyManager.addBalance(player.getUniqueId(), 500, "Canceling shop creation"); + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.cancelling_pay", Component.text("500 " + EconomyManager.getEconomyIcon()).color(NamedTextColor.GREEN)), Prefix.SHOP, MessageType.INFO, true); + } + ); + } + + /** + * Creates a shop for the specified player at the given location. + * + * @param player The player who is creating the shop. + * @param location The location where the shop is to be created. + * @return true if the shop creation is successful, false otherwise. + */ + private static boolean createShop(Player player, Location location) { + Shop shop = new Shop(player.getUniqueId(), location.setRotation(0, 0)); + + if (!ProtectionsManager.canBypassPlayer.contains(player.getUniqueId())) { + if (CityManager.isChunkClaimed(location.getChunk()) && !CityManager.getPlayerCity(player.getUniqueId()).equals(CityManager.getCityFromChunk(location.getChunk()))) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.chunk_claimed"), Prefix.SHOP, MessageType.ERROR, true); + return false; + } + } + + Block barrel = shop.getMultiblock().stockBlockLoc().getBlock(); + Block cashBlock = shop.getMultiblock().cashBlockLoc().getBlock(); + + if (barrel.getType() != Material.AIR) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.cant_create_barrel"), Prefix.SHOP, MessageType.ERROR, true); + return false; + } + + if (cashBlock.getType() != Material.AIR) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.cant_create_cash"), Prefix.SHOP, MessageType.ERROR, true); + return false; + } + + if (ShopManager.placeShop(player, shop)) { + barrel.setType(Material.BARREL); + BlockData barrelData = barrel.getBlockData(); + if (barrelData instanceof Directional directional) { + directional.setFacing(WorldUtils.getYaw(player).getOpposite().toBlockFace()); + barrel.setBlockData(barrelData); + } + + Bukkit.getScheduler().runTaskAsynchronously(OMCPlugin.getInstance(), () -> { + if (!ShopDatabaseManager.saveDBShop(shop)) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.cannot_save_location"), Prefix.SHOP, MessageType.ERROR, false); + OMCLogger.error("Error when saving shop location for player {}! Trying to remove shop...", player.getName()); + if (!ShopManager.removeShop(shop)) MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.cannot_delete"), Prefix.SHOP, MessageType.ERROR, false); + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.pay_back", Component.text("500 " + EconomyManager.getEconomyIcon()).color(NamedTextColor.GOLD)), Prefix.SHOP, MessageType.INFO, true); + } + else { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.success_created"), Prefix.SHOP, MessageType.SUCCESS, true); + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.withdraw_money", Component.text("500 " + EconomyManager.getEconomyIcon()).color(NamedTextColor.RED)), Prefix.SHOP, MessageType.SUCCESS, false); + } + }); + return true; + } else { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.multiblock"), Prefix.SHOP, MessageType.ERROR, false); + return false; + } + } + + /** + * Deletes the specified shop for the given player. + * + * @param player The player attempting to delete the shop. + * @param shop The shop to be deleted. If the shop is null or not empty, the deletion + * process will be aborted with a warning message. + */ + public static void deleteShop(Player player, Shop shop) { + if (shop == null) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.not_found"), Prefix.SHOP, MessageType.WARNING, false); + return; + } + + if (shop.getItem() != null && shop.getItem().getAmount() > 0) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.is_not_empty"), Prefix.SHOP, MessageType.WARNING, false); + return; + } + + World world = Bukkit.getWorld("world"); + if (world == null) return; + + if (world.getBlockAt(shop.getMultiblock().stockBlockLoc()).getState() instanceof Barrel barrel) { + if (!barrel.getInventory().isEmpty()) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.barrel_is_not_empty"), Prefix.SHOP, MessageType.WARNING, false); + return; + } + } else { + OMCLogger.error("Barrel block is not an instance of barrel"); + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.barrel"), Prefix.SHOP, MessageType.WARNING, false); + return; + } + + if (!ShopManager.removeShop(shop)) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.cannot_delete"), Prefix.SHOP, MessageType.ERROR, false); + return; + } + + Bukkit.getScheduler().runTaskAsynchronously(OMCPlugin.getInstance(), () -> { + if (!ShopDatabaseManager.deleteDBShop(shop)) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.error.cannot_remove_furniture"), Prefix.SHOP, MessageType.ERROR, false); + OMCLogger.error("Error when " + player.getName() + " trying to delete his shop!"); + } + }); + + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.deleted"), Prefix.SHOP, MessageType.SUCCESS, false); + + EconomyManager.addBalance(player.getUniqueId(), 400); + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.player.pay_back", Component.text("400 " + EconomyManager.getEconomyIcon()).color(NamedTextColor.GREEN)), Prefix.SHOP, MessageType.SUCCESS, true); + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/managers/ShopDatabaseManager.java b/src/main/java/fr/openmc/core/features/shops/managers/ShopDatabaseManager.java new file mode 100644 index 000000000..c6782c187 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/managers/ShopDatabaseManager.java @@ -0,0 +1,168 @@ +package fr.openmc.core.features.shops.managers; + +import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.dao.DaoManager; +import com.j256.ormlite.support.ConnectionSource; +import com.j256.ormlite.table.TableUtils; +import fr.openmc.core.bootstrap.integration.OMCLogger; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.features.shops.models.ShopItem; +import fr.openmc.core.features.shops.models.ShopSale; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.jspecify.annotations.NonNull; + +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class ShopDatabaseManager { + + private static Dao shopDao; + private static Dao shopItemDao; + private static Dao shopSaleDao; + + /** + * Init the Database of the shops + * + * @param connectionSource the connection to the DB + * @throws SQLException if init failed + */ + public static void initDB(ConnectionSource connectionSource) throws SQLException { + TableUtils.createTableIfNotExists(connectionSource, Shop.class); + shopDao = DaoManager.createDao(connectionSource, Shop.class); + + TableUtils.createTableIfNotExists(connectionSource, ShopItem.class); + shopItemDao = DaoManager.createDao(connectionSource, ShopItem.class); + + TableUtils.createTableIfNotExists(connectionSource, ShopSale.class); + shopSaleDao = DaoManager.createDao(connectionSource, ShopSale.class); + } + + /** + * Loads all shops from the database and organizes them by their location. + * + * @return A map where each location is associated with its corresponding shop. + * @throws SQLException if there is an error during the database query. + */ + public static @NonNull Map loadDBShops() throws SQLException { + Map shopsByLocation = new HashMap<>(); + + List shops = shopDao.queryForAll(); + for (Shop shop : shops) { + Location loc = new Location(Bukkit.getWorld("world"), shop.getX(), shop.getY(), shop.getZ()); + if (shop.getMultiblock() == null) { + if (!shop.setMultiblock(new Shop.Multiblock(loc, loc.clone().add(0, 1, 0)))) { + OMCLogger.error("Cannot set multiblock for {}, but shop is registered", shop.getName()); + } + } + shopsByLocation.put(loc, shop); + } + return shopsByLocation; + } + + /** + * Loads all shop items from the database and associates them with their corresponding shops. + * + * @throws SQLException if a database access error occurs during querying or processing. + */ + public static void loadDBShopItems() throws SQLException { + List shopItems = shopItemDao.queryForAll(); + for (ShopItem item : shopItems) { + Shop shop = item.getShop(); + if (shop == null) { + OMCLogger.error("Shop for item with shopUUID " + item.getShopUUID() + " is null, item not assigned"); + continue; + } + shop.setItem(item.deserialize().initMaxAmount()); + } + } + + /** + * Loads all shop sales from the database and associates them with their corresponding shops. + * + * @throws SQLException if a database access error occurs while querying sales. + */ + public static void loadDBShopSales() throws SQLException { + List shopSales = shopSaleDao.queryForAll(); + for (ShopSale sale : shopSales) { + Shop shop = sale.getShop(); + if (shop == null) { + OMCLogger.error("Shop for sale with shopUUID " + sale.getShopUUID() + " is null, sale not assigned"); + continue; + } + sale.registerVariables(); + shop.registerSale(sale); + } + } + + /** + * Saves a shop in DB + * + * @param shop shop to save + * @return true if the shop was saved, false if a database exception occurred + */ + public static boolean saveDBShop(Shop shop) { + try { + shopDao.createOrUpdate(shop); + return true; + } catch (SQLException e) { + OMCLogger.error("Failed to save shop for owner UUID: {}\nCause: {}", shop.getOwnerUUID(), e.getMessage()); + return false; + } + } + + /** + * Saves the given shop item object to the database. + * The ShopItem is serialized before being persisted. + * + * @param item the shop item instance to save in the database + * @return true if the shop item was successfully saved, false if a database + * exception occurred + */ + public static boolean saveDBShopItem(ShopItem item) { + try { + shopItemDao.createOrUpdate(item.serialize()); + return true; + } catch (SQLException e) { + OMCLogger.error("Failed to save shop item for owner UUID: {}\nCause: {}", item.getShop().getOwnerUUID(), e.getMessage()); + return false; + } + } + + /** + * Saves a sale in DB + * + * @param sale the sale to save + * @return true if the sale was saved, false if a database exception occurred + */ + public static boolean saveDBShopSale(ShopSale sale) { + try { + shopSaleDao.createOrUpdate(sale); + return true; + } catch (SQLException e) { + OMCLogger.error("Failed to save shop sale for owner UUID: {}\nCause: {}", sale.getShop().getOwnerUUID(), e.getMessage()); + return false; + } + } + + /** + * Deletes a shop and its associated data (items and sales) from the database. + * + * @param shop the shop instance to be deleted, including its related items and sales + * @return true if the shop and its associated data were successfully deleted, false if a database exception occurred + */ + public static boolean deleteDBShop(Shop shop) { + try { + shopDao.delete(shop); + shopItemDao.delete(shop.getItem()); + shopSaleDao.delete(shop.getSales()); + return true; + } catch (SQLException e) { + OMCLogger.error("Failed to delete shop for owner UUID: {}\nCause: {}", shop.getOwnerUUID(), e.getMessage()); + return false; + } + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/managers/ShopManager.java b/src/main/java/fr/openmc/core/features/shops/managers/ShopManager.java new file mode 100644 index 000000000..999753b31 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/managers/ShopManager.java @@ -0,0 +1,268 @@ +package fr.openmc.core.features.shops.managers; + +import com.j256.ormlite.support.ConnectionSource; +import fr.openmc.core.OMCPlugin; +import fr.openmc.core.bootstrap.features.Feature; +import fr.openmc.core.bootstrap.features.annotations.Credit; +import fr.openmc.core.bootstrap.features.types.DatabaseFeature; +import fr.openmc.core.bootstrap.features.types.HasCommands; +import fr.openmc.core.bootstrap.features.types.HasListeners; +import fr.openmc.core.bootstrap.features.types.LoadAfterItemsAdder; +import fr.openmc.core.bootstrap.integration.OMCLogger; +import fr.openmc.core.features.shops.ShopCommand; +import fr.openmc.core.features.shops.ShopFurniture; +import fr.openmc.core.features.shops.ShopListener; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.features.shops.models.ShopSale; +import fr.openmc.core.hooks.itemsadder.ItemsAdderHook; +import fr.openmc.core.utils.world.WorldUtils; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; + +import java.sql.SQLException; +import java.util.*; + +@Credit(developers = {"gab400", "Nocolm", "Xernas78"}, graphist = {"Gexary"}) +public class ShopManager extends Feature implements LoadAfterItemsAdder, DatabaseFeature, HasListeners, HasCommands { + + @Getter + private static final Map shops = new HashMap<>(); + private static Map shopsByLocation; + public static final Set shopBypass = new HashSet<>(); + + @Override + protected void init() { + loadShops(); + loadShopItems(); + loadShopSales(); + } + + @Override + protected void save() { + saveShops(); + saveShopItems(); + saveShopSales(); + } + + @Override + public void initDB(ConnectionSource connectionSource) throws SQLException { + ShopDatabaseManager.initDB(connectionSource); + } + + @Override + public Set getCommands() { + return Set.of(new ShopCommand()); + } + + @Override + public Set getListeners() { + return Set.of(new ShopListener()); + } + + // LOADING + + /** + * Loads all shops from the database and initializes them into memory. + */ + public static void loadShops() { + if (shopsByLocation != null) shopsByLocation.clear(); + try { + shopsByLocation = ShopDatabaseManager.loadDBShops(); + } catch (SQLException e) { + OMCLogger.error("Cannot load shops from the database:\n" + e.getMessage()); + return; + } + + shopsByLocation.values().forEach(shop -> setUUIDShop(shop.getShopUUID(), shop)); + } + + /** + * Load shops items from DB + */ + public static void loadShopItems() { + try { + ShopDatabaseManager.loadDBShopItems(); + } catch (SQLException e) { + OMCLogger.error("Cannot load shop items from the database:\n" + e.getMessage()); + } + } + + /** + * Load shops sales from DB + */ + public static void loadShopSales() { + try { + ShopDatabaseManager.loadDBShopSales(); + } catch (SQLException e) { + OMCLogger.error("Cannot load shop sales from the database:\n" + e.getMessage()); + } + } + + // SAVING + + /** + * Saves all registered shops to the database. + */ + public static void saveShops() { + for (Shop shop : shops.values()) { + if (ShopDatabaseManager.saveDBShop(shop)) continue; + OMCLogger.error("Failed to save " + shop.getName() + " to database."); + } + } + + /** + * Saves all shop items to the database.finite + */ + public static void saveShopItems() { + for (Shop shop : shops.values()) { + if (!shop.hasItem()) continue; + if (ShopDatabaseManager.saveDBShopItem(shop.getItem())) continue; + OMCLogger.error("Failed to save " + shop.getName() + " item to a database."); + } + } + + /** + * Saves the sales data of all shops to the database. + */ + public static void saveShopSales() { + for (Shop shop : shops.values()) { + if (shop.getSales().isEmpty()) continue; + boolean error = false; + for (ShopSale s : shop.getSales()) { + if (ShopDatabaseManager.saveDBShopSale(s)) continue; + error = true; + } + if (error) OMCLogger.error("Failed to save " + shop.getName() + " sales to a database."); + } + } + + // UTILITY + + /** + * Retrieves a shop located at a given location. + * + * @param location The location to check. + * @return The shop found at that location, or null if none exists. + */ + public static Shop getShopAt(Location location) { + if (location == null) return null; + location.setRotation(0, 0); + Shop shop1 = shopsByLocation.get(location); + Shop shop2 = shopsByLocation.get(location.subtract(0, 1, 0)); + if (shop1 != null) return shop1; + else return shop2; + } + + /** + * Retrieves a shop located at a given location. + * + * @param x The x-coordinate of the location. + * @param y The y-coordinate of the location. + * @param z The z-coordinate of the location. + * @return The shop found at that location, or null if none exists. + */ + public static Shop getShopAt(int x, int y, int z) { + return getShopAt(new Location(Bukkit.getWorld("world"), x, y, z)); + } + + /** + * Places the shop block (sign or ItemsAdder furniture) in the world, + * oriented based on the player's direction. + * + * @param player The player placing the shop. + * @param shop The shop to place. + * @return true if successfully placed, false otherwise. + */ + public static boolean placeShop(Player player, Shop shop) { + Shop.Multiblock multiblock = shop.getMultiblock(); + if (multiblock == null) return false; + + Block cashBlock = multiblock.cashBlockLoc().getBlock(); + + shopsByLocation.put(shop.getLocation(), shop); + shops.put(shop.getShopUUID(), shop); + + if (ItemsAdderHook.isEnable()) { + if (!ShopFurniture.placeShopFurniture(cashBlock, WorldUtils.getYaw(player))) cashBlock.setType(Material.OAK_SIGN); + } else { + cashBlock.setType(Material.OAK_SIGN); + } + + return true; + } + + /** + * Removes a shop from the world and unregisters its multiblock structure. + * Handles both ItemsAdder and fallback vanilla types. + * + * @param shop The shop to remove. + * @return true if successfully removed, false otherwise. + */ + public static boolean removeShop(Shop shop) { + Shop.Multiblock multiblock = shop.getMultiblock(); + if (multiblock == null) { + OMCLogger.error("Multiblock for {} is null!", shop.getName()); + return false; + } + + World world = Bukkit.getWorld("world"); + if (world == null) { + OMCLogger.error("World 'world' not found while removing {} at location: {}", shop.getName(), shop.getLocation()); + return false; + } + + Block cashBlock = world.getBlockAt(multiblock.cashBlockLoc()); + Block stockBlock = world.getBlockAt(multiblock.stockBlockLoc()); + + if (ItemsAdderHook.isEnable()) { + if (ShopFurniture.hasFurniture(cashBlock)) { + if (!ShopFurniture.removeShopFurniture(cashBlock)) { + OMCLogger.warn("Cannot remove furniture for " + shop.getName()); + return false; + } + } else if ((cashBlock.getType() != Material.OAK_SIGN && cashBlock.getType() != Material.BARRIER) || stockBlock.getType() != Material.BARREL) { + OMCLogger.warn("Bad multiblock for " + shop.getName()); + return false; + } + else OMCLogger.warn(shop.getName() + " has no furniture detected."); + } else if ((cashBlock.getType() != Material.OAK_SIGN && cashBlock.getType() != Material.BARRIER) || stockBlock.getType() != Material.BARREL) { + OMCLogger.warn("Bad multiblock for " + shop.getName()); + return false; + } + cashBlock.setType(Material.AIR); // Remove sign or furniture block + stockBlock.setType(Material.AIR); // Remove barrel block + + // Async cleanup of location mappings + Bukkit.getScheduler().runTaskAsynchronously(OMCPlugin.getInstance(), () -> { + shopsByLocation.entrySet().removeIf(entry -> entry.getValue().getShopUUID().equals(shop.getShopUUID())); + shops.remove(shop.getShopUUID()); + }); + return true; + } + + /** + * Retrieves a shop by its unique UUID. + * + * @param shopUUID The unique identifier (UUID) of the shop to retrieve. + * @return The shop associated with the specified UUID, or null if no shop is found. + */ + public static Shop getShopByUUID(UUID shopUUID) { + return shops.get(shopUUID); + } + + /** + * Assign a shop to a player if any shop was already assigned + * + * @param shopUUID the UUID of the player + * @param shop the shop + */ + public static void setUUIDShop(UUID shopUUID, Shop shop) { + shops.put(shopUUID, shop); + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/menus/ShopMenu.java b/src/main/java/fr/openmc/core/features/shops/menus/ShopMenu.java new file mode 100644 index 000000000..2054335c4 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/menus/ShopMenu.java @@ -0,0 +1,242 @@ +package fr.openmc.core.features.shops.menus; + +import fr.openmc.api.input.dialog.DialogInput; +import fr.openmc.api.menulib.Menu; +import fr.openmc.api.menulib.template.ConfirmMenu; +import fr.openmc.api.menulib.utils.InventorySize; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.features.economy.EconomyManager; +import fr.openmc.core.features.shops.managers.PlayerShopManager; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.features.shops.models.ShopItem; +import fr.openmc.core.utils.cache.PlayerNameCache; +import fr.openmc.core.utils.text.InputUtils; +import fr.openmc.core.utils.text.messages.MessageType; +import fr.openmc.core.utils.text.messages.MessagesManager; +import fr.openmc.core.utils.text.messages.Prefix; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ShopMenu extends Menu { + + private int amountToBuy; + private final Shop shop; + private final ShopItem item; + private final boolean isShopOwner; + + private final InventorySize size; + private final String texture; + + public ShopMenu(Player owner, Shop shop) { + this(owner, shop, 1); + } + + public ShopMenu(Player owner, Shop shop, int amountToBuy) { + super(owner); + this.shop = shop; + this.item = shop.getItem(); + this.isShopOwner = shop.isOwner(owner); + this.size = isShopOwner ? InventorySize.LARGER : InventorySize.LARGE; + this.texture = isShopOwner ? "shop_menu" : "sell_shop_menu"; + this.amountToBuy = amountToBuy; + } + + @Override + public @NotNull Component getName() { + return TranslationManager.translation("feature.shop.menu.main.title", PlayerNameCache.name(getOwner().getUniqueId())); + } + + @Override + public String getTexture() { + return "§r§f:offset_-11::" + this.texture + ":"; + } + + @Override + public @NotNull InventorySize getInventorySize() { + return this.size; + } + + @Override + public void onInventoryClick(InventoryClickEvent event) { + } + + @Override + public void onClose(InventoryCloseEvent event) { + if (event.getReason().equals(InventoryCloseEvent.Reason.OPEN_NEW)) return; + this.shop.setMenuOpened(false); + } + + @Override + public @NotNull Map getContent() { + Map map = new HashMap<>(); + + if (this.isShopOwner) { + map.put(0, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.HOMES_ICON_BIN_RED.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.delete.btn.title")); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.delete.btn.lore")); + }).setOnClick(_ -> new ConfirmMenu( + getOwner(), + () -> { + getOwner().closeInventory(); + this.shop.setMenuOpened(false); + PlayerShopManager.deleteShop(getOwner(), shop); + }, + () -> new ShopMenu(getOwner(), shop).open(), + TranslationManager.translationLore("feature.shop.menu.main.delete.confirm.accept"), + TranslationManager.translationLore("feature.shop.menu.main.delete.confirm.refuse") + ).open())); + + map.put(1, new ItemMenuBuilder(this, Material.RED_DYE, itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.remove_item.btn.title")); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.remove_item.btn.lore")); + }).setOnClick(_ -> new ConfirmMenu( + getOwner(), + () -> { + getOwner().closeInventory(); + this.shop.setMenuOpened(false); + if (this.shop.getItem().getAmount() != 0) return; + this.shop.removeItem(); + }, + () -> new ShopMenu(getOwner(), shop).open(), + TranslationManager.translationLore("feature.shop.menu.main.remove_item.confirm.accept"), + TranslationManager.translationLore("feature.shop.menu.main.remove_item.confirm.refuse") + ).open())); + + map.put(3, new ItemMenuBuilder(this, Material.PAPER, itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.sells.title")); + if (this.item == null) itemMeta.lore(List.of(TranslationManager.translation("feature.shop.menu.main.stats.lore.error"))); + else itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.sells.lore.success", Component.text(this.shop.getSales().size()).color(NamedTextColor.DARK_PURPLE))); + }).setOnClick(_ -> { + if (this.item != null) new ShopSalesMenu(getOwner(), this.shop).open(); + })); + + map.put(4, new ItemMenuBuilder(this, Material.GOLD_INGOT, itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.stats.title")); + if (this.item == null) itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.sells.lore.error")); + else itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.stats.lore.success", Component.text(this.shop.getTurnover() + " " + EconomyManager.getEconomyIcon()).color(NamedTextColor.GOLD))); + }).setOnClick(_ -> { + if (this.item != null) new ShopStatsMenu(getOwner(), this.shop).open(); + })); + + map.put(5, new ItemMenuBuilder(this, Material.BARREL, itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.stocks.title")); + if (this.item == null) itemMeta.lore(List.of(TranslationManager.translation("feature.shop.menu.main.stocks.lore.error"))); + else itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.stocks.lore.success", Component.text(this.shop.getItem().getAmount()).color(NamedTextColor.BLUE))); + }).setOnClick(_ -> { + if (this.item != null) new ShopStocksMenu(getOwner(), shop).open(); + })); + + map.put(8, new ItemMenuBuilder(this, Material.GREEN_BANNER, itemMeta -> itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.yours")))); + + map.put(31, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.HOMES_ICON_SHOP, itemMeta -> + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.modify_price.title"))).setOnClick(_ -> + DialogInput.send(getOwner(), + TranslationManager.translation("feature.shop.menu.selling.price_input"), + Integer.MAX_VALUE, + s -> { + if (!InputUtils.isInputMoney(s)) { + MessagesManager.sendMessage(getOwner(), TranslationManager.translation("feature.shop.menu.selling.invalid_enter"), Prefix.SHOP, MessageType.SUCCESS, true); + return; + } + + double pricePerItem = InputUtils.convertToMoneyValue(s); + if (pricePerItem <= 0) return; + + shop.getItem().setPricePerItem(pricePerItem); + new ShopMenu(getOwner(), shop).open(); + MessagesManager.sendMessage(getOwner(), TranslationManager.translation("feature.shop.menu.main.modify_price.message"), Prefix.SHOP, MessageType.SUCCESS, true); + }) + )); + } + + map.put(isShopOwner ? 19 : 10, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.BTN_64.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.remove.title", Component.text(64).color(NamedTextColor.RED))); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.remove.lore", Component.text(64).color(NamedTextColor.YELLOW).decorate(TextDecoration.BOLD))); + }).setOnClick(_ -> removeAmount(64))); + map.put(isShopOwner ? 20 : 11, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.BTN_10.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.remove.title", Component.text(10).color(NamedTextColor.RED))); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.remove.lore", Component.text(10).color(NamedTextColor.YELLOW).decorate(TextDecoration.BOLD))); + }).setOnClick(_ -> removeAmount(10))); + map.put(isShopOwner ? 21 : 12, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.MINUS_BTN.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.remove.title", Component.text(1).color(NamedTextColor.RED))); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.remove.lore", Component.text(1).color(NamedTextColor.YELLOW).decorate(TextDecoration.BOLD))); + }).setOnClick(_ -> removeAmount(1))); + + map.put(isShopOwner ? 23 : 14, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.PLUS_BTN.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.add.title", Component.text(1).color(NamedTextColor.GREEN))); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.add.lore", Component.text(1).color(NamedTextColor.YELLOW).decorate(TextDecoration.BOLD))); + }).setOnClick(_ -> addAmount(1))); + map.put(isShopOwner ? 24 : 15, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.BTN_10.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.add.title", Component.text(10).color(NamedTextColor.GREEN))); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.add.lore", Component.text(10).color(NamedTextColor.YELLOW).decorate(TextDecoration.BOLD))); + }).setOnClick(_ -> addAmount(10))); + map.put(isShopOwner ? 25 : 16, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.BTN_64.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.add.title", Component.text(64).color(NamedTextColor.GREEN))); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.add.lore", Component.text(64).color(NamedTextColor.YELLOW).decorate(TextDecoration.BOLD))); + }).setOnClick(_ -> addAmount(64))); + + map.put(isShopOwner ? 22 : 13, new ItemMenuBuilder(this, this.item.getItemStack().asOne())); + + map.put(isShopOwner ? 30 : 21, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.REFUSE_BTN.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.refuse.title")); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.refuse.lore", Component.text(this.amountToBuy).color(NamedTextColor.GOLD))); + }).setCloseButton()); + map.put(isShopOwner ? 32 : 23, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.ACCEPT_BTN.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.accept.title")); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.accept.lore", + Component.text(this.item.getPrice(this.amountToBuy) + " " + EconomyManager.getEconomyIcon()).color(NamedTextColor.GOLD), + Component.text(this.amountToBuy).color(NamedTextColor.GOLD))); + }).setOnClick(_ -> { + this.shop.buy(getOwner(), this.amountToBuy); + getOwner().closeInventory(); + })); + + return map; + } + + @Override + public List getTakableSlot() { + return List.of(); + } + + /** + * Adds the specified amount to the current amount to buy. + * If the operation is successful, the menu is reopened with the updated amount. + * + * @param amount the amount to add to the current amount to buy. Must be greater than zero + * and less than or equal to the remaining stock of the item. + */ + private void addAmount(int amount) { + if (this.item == null || this.item.getAmount() == 0) return; + if (amount <= 0) return; + if ((amountToBuy + amount) > this.item.getAmount()) amountToBuy = this.item.getAmount(); + else this.amountToBuy += amount; + new ShopMenu(getOwner(), this.shop, this.amountToBuy).open(); + } + + /** + * Reduces the current amount to buy by the specified value while ensuring that the amount + * remains within valid bounds. If the operation is valid, the menu is reopened with the updated value. + * + * @param amount the amount to subtract from the current amount to buy. Must be greater than zero. + */ + private void removeAmount(int amount) { + if (this.item == null) return; + if (amount <= 0) return; + if (amountToBuy <= amount) amountToBuy = 1; + else this.amountToBuy -= amount; + new ShopMenu(getOwner(), this.shop, this.amountToBuy).open(); + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/menus/ShopSalesMenu.java b/src/main/java/fr/openmc/core/features/shops/menus/ShopSalesMenu.java new file mode 100644 index 000000000..66ad4d9a6 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/menus/ShopSalesMenu.java @@ -0,0 +1,121 @@ +package fr.openmc.core.features.shops.menus; + +import fr.openmc.api.menulib.PaginatedMenu; +import fr.openmc.api.menulib.template.ItemMenuTemplate; +import fr.openmc.api.menulib.utils.InventorySize; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.api.menulib.utils.StaticSlots; +import fr.openmc.core.features.economy.EconomyManager; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.features.shops.models.ShopSale; +import fr.openmc.core.utils.cache.PlayerNameCache; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ShopSalesMenu extends PaginatedMenu { + + private final Shop shop; + + public ShopSalesMenu(Player owner, Shop shop) { + super(owner); + this.shop = shop; + } + + @Override + public @NotNull InventorySize getInventorySize() { + return InventorySize.LARGEST; + } + + @Override + public int getSizeOfItems() { + return getItems().size(); + } + + @Override + public @Nullable Material getBorderMaterial() { + return null; + } + + @Override + public @NotNull List getStaticSlots() { + return StaticSlots.getStandardSlots(getInventorySize()); + } + + @Override + public List getItems() { + List items = new ArrayList<>(); + List sales = this.shop.getSales(); + sales.forEach(s -> { + ItemStack item = s.getItem().getItemStack().clone(); + item.editMeta(itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.sales.item.name", PlayerNameCache.name(s.getBuyerUUID()).color(NamedTextColor.LIGHT_PURPLE))); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.sales.item.lore", + Component.text(s.getDate().toLocalDateTime().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM))).color(NamedTextColor.GREEN), + Component.text(s.getAmount()).color(NamedTextColor.GOLD), + Component.text(s.getPrice() + " " + EconomyManager.getEconomyIcon()).color(NamedTextColor.GOLD).decorate(TextDecoration.BOLD))); + }); + items.add(item); + }); + return items; + } + + @Override + public Map getButtons() { + Map map = new HashMap<>(); + map.put(45, ItemMenuTemplate.BTN_CANCEL.apply(this).setBackButton()); + map.put(48, ItemMenuTemplate.BTN_PREVIOUS_PAGE_ORANGE.apply(this)); + map.put(49, new ItemMenuBuilder(this, Material.GOLD_BLOCK, itemMeta -> { + Component lastRemoval = this.shop.getLastWithdrawal() == null ? TranslationManager.translation("global.never") : Component.text(this.shop.getLastWithdrawal().toLocalDateTime().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM))); + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.sales.get_turnover.name")); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.sales.get_turnover.lore", Component.text(this.shop.getTurnover() * 0.8 + " " + EconomyManager.getEconomyIcon()).color(NamedTextColor.GOLD).decorate(TextDecoration.BOLD), lastRemoval.color(NamedTextColor.LIGHT_PURPLE))); + }).setOnClick(_ -> { + this.shop.withdrawTurnover(); + this.shop.setLastWithdrawalToNow(); + update(); + })); + map.put(50, ItemMenuTemplate.BTN_NEXT_PAGE_ORANGE.apply(this)); + return map; + } + + @Override + public @NotNull Component getName() { + return TranslationManager.translation("feature.shop.menu.sales.title"); + } + + @Override + public String getTexture() { + return "§r§f:offset_-11::large_shop_menu:"; + } + + @Override + public void onClose(InventoryCloseEvent event) { + if (event.getReason().equals(InventoryCloseEvent.Reason.OPEN_NEW)) return; + this.shop.setMenuOpened(false); + } + + @Override + public List getTakableSlot() { + return List.of(); + } + + @Override + public void onInventoryClick(InventoryClickEvent inventoryClickEvent) { + + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/menus/ShopSellingMenu.java b/src/main/java/fr/openmc/core/features/shops/menus/ShopSellingMenu.java new file mode 100644 index 000000000..f13522327 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/menus/ShopSellingMenu.java @@ -0,0 +1,159 @@ +package fr.openmc.core.features.shops.menus; + +import fr.openmc.api.input.dialog.DialogInput; +import fr.openmc.api.menulib.PaginatedMenu; +import fr.openmc.api.menulib.template.ConfirmMenu; +import fr.openmc.api.menulib.utils.InventorySize; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.api.menulib.utils.StaticSlots; +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.features.shops.managers.PlayerShopManager; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.features.shops.models.ShopItem; +import fr.openmc.core.utils.text.InputUtils; +import fr.openmc.core.utils.text.messages.MessageType; +import fr.openmc.core.utils.text.messages.MessagesManager; +import fr.openmc.core.utils.text.messages.Prefix; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; +import org.bukkit.block.Barrel; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class ShopSellingMenu extends PaginatedMenu { + + private final Shop shop; + private final Inventory barrelInventory; + + public ShopSellingMenu(Player owner, Shop shop) { + super(owner); + this.shop = shop; + this.barrelInventory = ((Barrel) shop.getMultiblock().stockBlockLoc().getBlock().getState()).getSnapshotInventory(); + } + + @Override + public @NotNull Component getName() { + return TranslationManager.translation("feature.shop.menu.selling.title"); + } + + @Override + public String getTexture() { + return "§r§f:offset_-11::large_shop_menu:"; + } + + @Override + public @NotNull InventorySize getInventorySize() { + return InventorySize.LARGEST; + } + + @Override + public int getSizeOfItems() { + return getItems().size(); + } + + @Override + public void onInventoryClick(InventoryClickEvent e) { + + } + + @Override + public void onClose(InventoryCloseEvent event) { + if (event.getReason().equals(InventoryCloseEvent.Reason.OPEN_NEW)) return; + this.shop.setMenuOpened(false); + } + + @Override + public @Nullable Material getBorderMaterial() { + return null; + } + + @Override + public @NotNull List getStaticSlots() { + return StaticSlots.getStandardSlots(getInventorySize()); + } + + @Override + public @NotNull List getItems() { + List list = new ArrayList<>(); + + List items = getUniqueItemStacks(barrelInventory.getContents()); + for (ItemStack item : items) { + list.add(new ItemMenuBuilder(this, item, itemMeta -> { + if (itemMeta.hasLore()) itemMeta.lore().addAll(TranslationManager.translationLore("feature.shop.menu.selling.item_lore")); + else itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.selling.item_lore")); + }).setOnClick(_ -> DialogInput.send(getOwner(), + TranslationManager.translation("feature.shop.menu.selling.price_input"), + Integer.MAX_VALUE, + s -> { + if (!InputUtils.isInputMoney(s)) { + MessagesManager.sendMessage(getOwner(), TranslationManager.translation("feature.shop.menu.selling.invalid_enter"), Prefix.SHOP, MessageType.SUCCESS, true); + return; + } + + double pricePerItem = InputUtils.convertToMoneyValue(s); + if (pricePerItem <= 0) return; + + shop.setItem(new ShopItem(shop.getShopUUID(), item, pricePerItem)); + new ShopMenu(getOwner(), shop).open(); + MessagesManager.sendMessage(getOwner(), TranslationManager.translation("feature.shop.menu.selling.added_item"), Prefix.SHOP, MessageType.SUCCESS, true); + }))); + } + return list; + } + + @Override + public Map getButtons() { + Map map = new HashMap<>(); + + map.put(8, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.HOMES_ICON_INFORMATION.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.selling.info.title")); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.selling.info.lore")); + })); + + map.put(49, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.HOMES_ICON_BIN_RED.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.main.delete.btn.title")); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.main.delete.btn.lore")); + }).setOnClick(_ -> new ConfirmMenu( + getOwner(), + () -> { + getOwner().closeInventory(); + this.shop.setMenuOpened(false); + PlayerShopManager.deleteShop(getOwner(), shop); + }, + () -> new ShopSellingMenu(getOwner(), shop).open(), + TranslationManager.translationLore("feature.shop.menu.main.delete.confirm.accept"), + TranslationManager.translationLore("feature.shop.menu.main.delete.confirm.refuse") + ).open())); + + return map; + } + + @Override + public List getTakableSlot() { + return List.of(); + } + + /** + * Filters the provided array of {@code ItemStack} objects to return a list of unique item stacks, + * with each stack reduced to a single item version. + * + * @param items an array of {@code ItemStack} objects to process. + * @return a {@code List} of unique {@code ItemStack} objects, each representing a single item stack. + */ + private List getUniqueItemStacks(ItemStack[] items) { + Set itemStacks = new HashSet<>(); + for (ItemStack item : items) { + if (item == null) continue; + itemStacks.add(item.asOne()); + } + return itemStacks.stream().toList(); + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/menus/ShopStatsMenu.java b/src/main/java/fr/openmc/core/features/shops/menus/ShopStatsMenu.java new file mode 100644 index 000000000..377d04272 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/menus/ShopStatsMenu.java @@ -0,0 +1,88 @@ +package fr.openmc.core.features.shops.menus; + +import fr.openmc.api.menulib.Menu; +import fr.openmc.api.menulib.template.ItemMenuTemplate; +import fr.openmc.api.menulib.utils.InventorySize; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.core.features.economy.EconomyManager; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.utils.text.messages.TranslationManager; +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.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class ShopStatsMenu extends Menu { + + private final Shop shop; + private int totalSoldItems = 0; + private final Set totalUniquePlayers = new HashSet<>(); + + protected ShopStatsMenu(Player owner, Shop shop) { + super(owner); + this.shop = shop; + if (shop.getItem() == null) owner.closeInventory(); + if (!shop.getSales().isEmpty()) { + shop.getSales().forEach(s -> { + totalSoldItems += s.getAmount(); + totalUniquePlayers.add(s.getBuyerUUID()); + }); + } + } + + @Override + public @NotNull Component getName() { + return TranslationManager.translation("feature.shop.menu.stats.title"); + } + + @Override + public String getTexture() { + return ""; + } + + @Override + public @NotNull InventorySize getInventorySize() { + return InventorySize.NORMAL; + } + + @Override + public void onInventoryClick(InventoryClickEvent e) { + + } + + @Override + public void onClose(InventoryCloseEvent event) { + if (event.getReason().equals(InventoryCloseEvent.Reason.OPEN_NEW)) return; + this.shop.setMenuOpened(false); + } + + @Override + public @NotNull Map getContent() { + Map map = new HashMap<>(); + + map.put(11, new ItemMenuBuilder(this, Material.PAPER, itemMeta -> + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.stats.sells.title", Component.text(this.shop.getSales().size()).color(NamedTextColor.GREEN))))); + map.put(12, new ItemMenuBuilder(this, Material.GOLD_INGOT, itemMeta -> + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.stats.sales.title", Component.text(this.totalSoldItems).color(NamedTextColor.DARK_GREEN))))); + map.put(13, new ItemMenuBuilder(this, Material.GOLD_BLOCK, itemMeta -> + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.stats.turnover.title", Component.text(this.shop.getTurnover() + " " + EconomyManager.getEconomyIcon()).color(NamedTextColor.GOLD))))); + map.put(14, new ItemMenuBuilder(this, Material.PLAYER_HEAD, itemMeta -> + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.stats.buyers.title", Component.text(this.totalUniquePlayers.size()).color(NamedTextColor.LIGHT_PURPLE))))); + map.put(15, new ItemMenuBuilder(this, Material.BARREL, itemMeta -> + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.stats.stocks.title", Component.text(this.shop.getItem().getAmount()).color(NamedTextColor.AQUA))))); + + map.put(18, ItemMenuTemplate.BTN_CANCEL.apply(this).setBackButton()); + + return map; + } + + @Override + public List getTakableSlot() { + return List.of(); + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/menus/ShopStocksMenu.java b/src/main/java/fr/openmc/core/features/shops/menus/ShopStocksMenu.java new file mode 100644 index 000000000..06e6266f0 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/menus/ShopStocksMenu.java @@ -0,0 +1,141 @@ +package fr.openmc.core.features.shops.menus; + +import fr.openmc.api.menulib.PaginatedMenu; +import fr.openmc.api.menulib.template.ItemMenuTemplate; +import fr.openmc.api.menulib.utils.InventorySize; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.api.menulib.utils.StaticSlots; +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.features.shops.models.Shop; +import fr.openmc.core.features.shops.models.ShopItem; +import fr.openmc.core.utils.bukkit.ContainerUtils; +import fr.openmc.core.utils.bukkit.ItemUtils; +import fr.openmc.core.utils.text.messages.MessageType; +import fr.openmc.core.utils.text.messages.MessagesManager; +import fr.openmc.core.utils.text.messages.Prefix; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Material; +import org.bukkit.block.Barrel; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ShopStocksMenu extends PaginatedMenu { + + private final Shop shop; + private final ShopItem item; + private int barrelStocks; + + public ShopStocksMenu(Player owner, Shop shop) { + super(owner); + this.shop = shop; + reloadBarrelStocks(); + this.item = shop.getItem(); + } + + @Override + public @NotNull InventorySize getInventorySize() { + return InventorySize.LARGEST; + } + + @Override + public int getSizeOfItems() { + return getItems().size(); + } + + @Override + public @Nullable Material getBorderMaterial() { + return null; + } + + @Override + public @NotNull List getStaticSlots() { + return StaticSlots.getStandardSlots(getInventorySize()); + } + + @Override + public List getItems() { + if (item == null || item.getAmount() <= 0) return List.of(); + return ItemUtils.splitAmountIntoStack(item.getItemStack(), item.getAmount()); + } + + @Override + public Map getButtons() { + Map map = new HashMap<>(); + + map.put(45, ItemMenuTemplate.BTN_CANCEL.apply(this).setBackButton()); + map.put(48, new ItemMenuBuilder(this, Material.BARREL, itemMeta -> { + itemMeta.displayName(item.isFull() ? + TranslationManager.translation("feature.shop.menu.stocks.fill.name.full") : + TranslationManager.translation("feature.shop.menu.stocks.fill.name.not_full", Component.text(barrelStocks).color(NamedTextColor.GREEN))); + }).setOnClick(_ -> { + if (barrelStocks == 0) return; + if (item.isFull()) return; + + int amountToAdd = item.getMaxAmount() - item.getAmount(); + if (amountToAdd <= 0) return; + if (amountToAdd > barrelStocks) amountToAdd = barrelStocks; + + ContainerUtils.removeItemsFromContainerInventory((Barrel) this.shop.getMultiblock().stockBlockLoc().getBlock().getState(), item.getItemStack(), amountToAdd); + item.addAmount(amountToAdd); + + MessagesManager.sendMessage(getOwner(), TranslationManager.translation("feature.shop.menu.stocks.fill.success"), Prefix.SHOP, MessageType.SUCCESS, true); + new ShopStocksMenu(getOwner(), shop).open(); + })); + map.put(50, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.COMPANY_BOX.getBest(), itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.shop.menu.stocks.empty.name")); + itemMeta.lore(TranslationManager.translationLore("feature.shop.menu.stocks.empty.lore", Component.text(item.getAmount()).color(NamedTextColor.GRAY))); + }).setOnClick(_ -> { + if (item.getAmount() <= 0) return; + if (!ItemUtils.hasEnoughSpace(getOwner(), item.getItemStack(), item.getAmount())) { + MessagesManager.sendMessage(getOwner(), TranslationManager.translation("feature.shop.menu.stocks.empty.not_enough_space"), Prefix.SHOP, MessageType.ERROR, true); + return; + } + getOwner().give(getItems()); + this.shop.emptyShop(); + MessagesManager.sendMessage(getOwner(), TranslationManager.translation("feature.shop.menu.stocks.empty.success"), Prefix.SHOP, MessageType.SUCCESS, true); + new ShopStocksMenu(getOwner(), shop).open(); + })); + + return map; + } + + @Override + public @NotNull Component getName() { + return TranslationManager.translation("feature.shop.menu.stocks.title"); + } + + @Override + public String getTexture() { + return "§r§f:offset_-11::large_shop_menu:"; + } + + @Override + public void onInventoryClick(InventoryClickEvent inventoryClickEvent) { + + } + + @Override + public void onClose(InventoryCloseEvent event) { + if (event.getReason().equals(InventoryCloseEvent.Reason.OPEN_NEW)) return; + this.shop.setMenuOpened(false); + } + + @Override + public List getTakableSlot() { + return List.of(); + } + + private void reloadBarrelStocks() { + this.barrelStocks = ContainerUtils.getTotalItemsIn((Barrel) this.shop.getMultiblock().stockBlockLoc().getBlock().getState(), this.shop.getItem().getItemStack()); + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/models/Shop.java b/src/main/java/fr/openmc/core/features/shops/models/Shop.java new file mode 100644 index 000000000..ea7079545 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/models/Shop.java @@ -0,0 +1,248 @@ +package fr.openmc.core.features.shops.models; + +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; +import fr.openmc.core.features.economy.EconomyManager; +import fr.openmc.core.features.shops.ShopFurniture; +import fr.openmc.core.features.shops.managers.ShopManager; +import fr.openmc.core.utils.bukkit.ItemUtils; +import fr.openmc.core.utils.cache.CacheOfflinePlayer; +import fr.openmc.core.utils.cache.PlayerNameCache; +import fr.openmc.core.utils.text.messages.MessageType; +import fr.openmc.core.utils.text.messages.MessagesManager; +import fr.openmc.core.utils.text.messages.Prefix; +import fr.openmc.core.utils.text.messages.TranslationManager; +import lombok.Getter; +import lombok.Setter; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Getter +@DatabaseTable(tableName = "shops") +public class Shop { + + @DatabaseField(id = true, columnName = "shop_uuid", canBeNull = false) + private UUID shopUUID; + @DatabaseField(columnName = "owner_uuid", canBeNull = false) + private UUID ownerUUID; + @DatabaseField(canBeNull = false) + private int x; + @DatabaseField(canBeNull = false) + private int y; + @DatabaseField(canBeNull = false) + private int z; + @DatabaseField(canBeNull = false) + @Setter private double turnover = 0; + + private ShopItem item; + private final List sales = new ArrayList<>(); + + private Location location; + private Multiblock multiblock; + + @Setter private boolean menuOpened; + private Timestamp lastWithdrawal; + + Shop() { + // required for ORMLite + } + + public Shop(UUID ownerUUID, int x, int y, int z) { + this(ownerUUID, new Location(Bukkit.getWorld("world"), x, y, z)); + } + + public Shop(UUID ownerUUID, Location location) { + this.shopUUID = UUID.randomUUID(); + this.ownerUUID = ownerUUID; + this.x = location.getBlockX(); + this.y = location.getBlockY(); + this.z = location.getBlockZ(); + this.location = location.toBlockLocation(); + this.multiblock = new Multiblock(this.location, this.location.clone().add(0, 1, 0)); + } + + /** + * Retrieves the owner of the shop as an OfflinePlayer. + * + * @return the OfflinePlayer instance representing the shop's owner, + * retrieved from the cached or default mechanism based on the owner's UUID. + */ + public OfflinePlayer getOwner() { + return CacheOfflinePlayer.getOfflinePlayer(ownerUUID); + } + + /** + * Retrieves the name of the shop by combining the owner's name with a descriptor. + * + * @return the name of the shop in the format "'s Shop" + */ + public String getName() { + return PlayerNameCache.getName(getOwnerUUID()) + "'s Shop"; + } + + /** + * Know if the UUID is the shop owner UUID + * + * @param uuid the UUID to check + */ + public boolean isOwner(UUID uuid) { + return ownerUUID.equals(uuid) || ShopManager.shopBypass.contains(uuid); + } + + /** + * Know if the player is the shop owner + * + * @param player the UUID to check + */ + public boolean isOwner(Player player) { + return isOwner(player.getUniqueId()); + } + + /** + * Records a new sale in the shop by adding a {@code ShopSale} entry. + * + * @param player the player who made the purchase + * @param item the shop item being purchased + */ + public void addSale(Player player, ShopItem item) { + this.sales.add(new ShopSale(this.shopUUID, player.getUniqueId(), item)); + } + + /** + * Registers a new sale in the shop by adding the given {@code ShopSale} entry. + * + * @param sale the {@code ShopSale} instance representing the sale to be recorded + */ + public void registerSale(ShopSale sale) { + this.sales.add(sale); + } + + /** + * Adds the specified amount to the shop's turnover. + * + * @param amount the amount to be added to the turnover + */ + public void addTurnover(double amount) { + this.turnover += amount; + } + + /** + * Withdraws the current turnover of the shop and adds a percentage of the turnover + * to the owner's balance. + */ + public void withdrawTurnover() { + Player player = CacheOfflinePlayer.getOfflinePlayer(getOwnerUUID()).getPlayer(); + if (player == null) return; + if (!isOwner(player)) return; + if (getTurnover() <= 0) return; + double tempTurnover = getTurnover(); + EconomyManager.addBalance(player.getUniqueId(), tempTurnover * 0.8, "turnover"); + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.get_turnover", Component.text(tempTurnover * 0.8 + " " + EconomyManager.getEconomyIcon())), Prefix.SHOP, MessageType.SUCCESS, false); + setTurnover(0); + } + + /** + * Handles the purchase process for a given player, allowing them to buy a specified number + * of items from the shop. + * + * @param player the player attempting to make the purchase + * @param amount the quantity of items the player wants to buy + */ + public void buy(Player player, int amount) { + if (isOwner(player)) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.is_owner"), Prefix.SHOP, MessageType.ERROR, false); + return; + } + if (this.item.getAmount() < amount) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.not_enough_items"), Prefix.SHOP, MessageType.ERROR, false); + return; + } + if (!ItemUtils.hasEnoughSpace(player, item.getItemStack(), amount)) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.not_enough_space"), Prefix.SHOP, MessageType.ERROR, false); + return; + } + double totalPrice = this.item.getPrice(amount); + if (!EconomyManager.withdrawBalance(player.getUniqueId(), totalPrice, getName() + " buying")) { + MessagesManager.sendMessage(player, TranslationManager.translation("feature.shop.not_enough_money"), Prefix.SHOP, MessageType.ERROR, false); + return; + } + player.give(ItemUtils.splitAmountIntoStack(item.clone().getItemStack(), amount)); + addSale(player, this.item.clone().setAmount(amount)); + addTurnover(totalPrice); + this.item.removeAmount(amount); + } + + /** + * Sets the multiblock for the shop, ensuring the required block types and configurations are met. + * + * @param multiblock the {@code Multiblock} instance representing the structure associated with the shop + * @return {@code true} if the multiblock configuration is valid and successfully set, {@code false} otherwise + */ + public boolean setMultiblock(Multiblock multiblock) { + if (multiblock.stockBlockLoc.getBlock().getType() != Material.BARREL + || (multiblock.cashBlockLoc.getBlock().getType() != Material.OAK_SIGN + && !ShopFurniture.hasFurniture(multiblock.cashBlockLoc.getBlock()))) { + return false; + } + this.multiblock = multiblock; + return true; + } + + /** + * Sets the specified {@code ShopItem} as the shop's item if it meets certain conditions. + * + * @param item the {@code ShopItem} to be set in the shop. + */ + public void setItem(ShopItem item) { + if (this.item != null) return; + if (item.getPricePerItem() < 0) return; + if (item.getItemStack() == null) return; + this.item = item; + } + + /** + * Removes the shop's current item if it meets specific conditions. + */ + public void removeItem() { + if (!hasItem()) return; + if (this.item.getAmount() > 0) return; + this.item = null; + } + + /** + * Checks whether the shop currently has an item set. + * + * @return {@code true} if the shop has an item, {@code false} otherwise + */ + public boolean hasItem() { + return this.item != null; + } + + /** + * Empties the shop by setting the amount of the associated shop item to zero. + */ + public void emptyShop() { + if (!hasItem()) return; + this.getItem().setAmount(0); + } + + /** + * Updates the timestamp of the last withdrawal made from the shop. + * The method sets the {@code lastWithdrawal} field to the current date and time. + */ + public void setLastWithdrawalToNow() { + this.lastWithdrawal = Timestamp.valueOf(LocalDateTime.now()); + } + + public record Multiblock(Location stockBlockLoc, Location cashBlockLoc) {} +} diff --git a/src/main/java/fr/openmc/core/features/shops/models/ShopItem.java b/src/main/java/fr/openmc/core/features/shops/models/ShopItem.java new file mode 100644 index 000000000..286a53d7d --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/models/ShopItem.java @@ -0,0 +1,176 @@ +package fr.openmc.core.features.shops.models; + +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; +import fr.openmc.core.features.shops.managers.ShopManager; +import lombok.Getter; +import org.bukkit.inventory.ItemStack; + +import java.util.UUID; + +@Getter +@DatabaseTable(tableName = "shop_items") +public class ShopItem implements Cloneable { + + @DatabaseField(id = true, columnName = "shop_uuid", canBeNull = false) + private UUID shopUUID; + @DatabaseField(canBeNull = false) + private double pricePerItem; + @DatabaseField(canBeNull = false) + private int amount; + @DatabaseField(canBeNull = false, columnName = "item_bytes", dataType = DataType.BYTE_ARRAY) + private byte[] itemBytes; + + private double price; + private ItemStack itemStack; + + private int maxAmount; + + ShopItem() { + // required for ORMLite + } + + public ShopItem(UUID shopUUID, ItemStack itemStack, double pricePerItem) { + this.shopUUID = shopUUID; + this.itemStack = itemStack.clone(); + this.pricePerItem = pricePerItem; + this.amount = 0; + this.price = pricePerItem * amount; + initMaxAmount(); + } + + /** + * Sets the amount of the ShopItem. If the specified amount exceeds + * the maximum allowable value (28 full stacks of the item), the amount + * is capped at the maximum. Also updates the total price based on the + * new amount. + * + * @param amount the desired amount to set for the ShopItem + * @return the updated ShopItem instance + */ + public ShopItem setAmount(int amount) { + if (amount > this.maxAmount) amount = this.maxAmount; + this.amount = amount; + this.price = pricePerItem * amount; + return this; + } + + /** + * Adjusts the amount of the ShopItem by adding the specified value. + * If the resulting amount exceeds the maximum permissible value (28 stacks), + * it is capped at that maximum. Updates the total price based on the new amount. + * + * @param amount the amount to be added to the current amount of the item + */ + public void addAmount(int amount) { + this.amount += amount; + if (this.amount > 28 * itemStack.getMaxStackSize()) this.amount = 28 * itemStack.getMaxStackSize(); + this.price = pricePerItem * this.amount; + } + + /** + * Reduces the amount of this ShopItem by the specified value. If the + * resulting amount is zero or less, the amount is set to zero. Also + * updates the total price based on the new amount. + * + * @param amount the amount to be subtracted from the current amount + */ + public void removeAmount(int amount) { + if (this.amount - amount <= 0) this.amount = 0; + else this.amount -= amount; + this.price = pricePerItem * this.amount; + } + + public ShopItem initMaxAmount() { + this.maxAmount = 28 * itemStack.getMaxStackSize(); + return this; + } + + /** + * Set a new price per item for this shop item + * + * @param pricePerItem the new price per item + */ + public void setPricePerItem(double pricePerItem) { + this.pricePerItem = pricePerItem; + this.price = pricePerItem * amount; + } + + /** + * Get the price of an item based on the amount + * + * @param amount the amount of the item + * @return the total price + */ + public double getPrice(int amount) { + return pricePerItem * amount; + } + + /** + * Retrieves the Shop instance associated with this ShopItem. + * + * @return the Shop object corresponding to the shopUUID of this ShopItem + */ + public Shop getShop() { + return ShopManager.getShopByUUID(this.shopUUID); + } + + /** + * Checks whether the current ShopItem instance has reached its maximum allowable + * stock capacity. + * + * @return true if the current amount of the ShopItem is greater than or equal to + * the maximum capacity (28 stacks); false otherwise. + */ + public boolean isFull() { + return this.amount >= maxAmount; + } + + /** + * Serializes the itemStack of this ShopItem into a byte array + * and stores it in the itemBytes field. Returns the updated + * ShopItem instance. + * + * @return the updated ShopItem instance, with the itemBytes field + * containing the serialized state of the itemStack + */ + public ShopItem serialize() { + this.itemBytes = this.itemStack.serializeAsBytes(); + return this; + } + + /** + * Deserializes the byte array stored in the itemBytes field of this ShopItem + * into an ItemStack object and assigns it to the itemStack field. + * Returns the updated ShopItem instance. + * + * @return the updated ShopItem instance with the deserialized ItemStack. + */ + public ShopItem deserialize() { + this.itemStack = ItemStack.deserializeBytes(this.itemBytes); + return this; + } + + /** + * Creates and returns a copy of this ShopItem object. This method ensures that + * deep copies of mutable fields, such as itemBytes and itemStack, are also created + * to avoid unintended side effects from shared references. + * + * @return a deep clone of this ShopItem instance + * @throws AssertionError if the ShopItem object does not support cloning + */ + @Override + public ShopItem clone() { + try { + ShopItem clone = (ShopItem) super.clone(); + + if (this.itemBytes != null) clone.itemBytes = this.itemBytes.clone(); + if (this.itemStack != null) clone.itemStack = this.itemStack.clone(); + + return clone; + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); + } + } +} diff --git a/src/main/java/fr/openmc/core/features/shops/models/ShopSale.java b/src/main/java/fr/openmc/core/features/shops/models/ShopSale.java new file mode 100644 index 000000000..d802fdda6 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/shops/models/ShopSale.java @@ -0,0 +1,71 @@ +package fr.openmc.core.features.shops.models; + +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; +import fr.openmc.core.features.shops.managers.ShopManager; +import fr.openmc.core.utils.cache.CacheOfflinePlayer; +import lombok.Getter; +import org.bukkit.OfflinePlayer; + +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.UUID; + +@Getter +@DatabaseTable(tableName = "shop_sales") +public class ShopSale { + @DatabaseField(canBeNull = false, id = true, columnName = "sale_uuid") + private UUID saleUUID; + @DatabaseField(canBeNull = false, columnName = "shop_uuid") + private UUID shopUUID; + @DatabaseField(canBeNull = false, columnName = "player_uuid") + private UUID buyerUUID; + @DatabaseField(canBeNull = false) + private Timestamp date; + @DatabaseField(canBeNull = false) + private double price; + @DatabaseField(canBeNull = false) + private int amount; + + private OfflinePlayer buyer; + private ShopItem item; + + ShopSale() { + // required for ORMLite + } + + public ShopSale(UUID shopUUID, UUID buyerUUID, ShopItem item, Timestamp date) { + this.saleUUID = UUID.randomUUID(); + this.shopUUID = shopUUID; + this.buyerUUID = buyerUUID; + this.price = item.getPrice(); + this.amount = item.getAmount(); + this.date = date; + this.item = item; + + registerVariables(); + } + + public ShopSale(UUID shopUUID, UUID buyerUUID, ShopItem item) { + this(shopUUID, buyerUUID, item, Timestamp.valueOf(LocalDateTime.now())); + } + + /** + * Retrieves the associated {@code Shop} object for this sale. + * + * @return the {@code Shop} corresponding to the {@code shopUUID} of this sale + */ + public Shop getShop() { + return ShopManager.getShopByUUID(this.shopUUID); + } + + /** + * Initializes or updates the state of certain member variables in the {@code ShopSale} instance. + * This method ensures that the following variables are properly assigned: + */ + public void registerVariables() { + if (this.buyer == null) this.buyer = CacheOfflinePlayer.getOfflinePlayer(this.buyerUUID); + ShopItem shopItem = getShop().getItem(); + if (this.item == null && shopItem != null) this.item = shopItem.clone().setAmount(this.amount); + } +} diff --git a/src/main/java/fr/openmc/core/listeners/BlockPlaceListener.java b/src/main/java/fr/openmc/core/listeners/BlockPlaceListener.java index 54bca64e2..5feb7a34c 100644 --- a/src/main/java/fr/openmc/core/listeners/BlockPlaceListener.java +++ b/src/main/java/fr/openmc/core/listeners/BlockPlaceListener.java @@ -27,7 +27,7 @@ void onFurniturePlace(FurniturePrePlaceEvent event) { usable.onFurniturePlace(player, event); } else if (item.get() instanceof LootboxBlock lootboxBlock) { event.setCancelled(true); - ItemUtils.removeItemsFromInventory(player, item.get().getBest(), 1); + ItemUtils.removeItemsFromPlayerInventory(player, item.get().getBest(), 1); lootboxBlock.getLootbox().open(player); } } diff --git a/src/main/java/fr/openmc/core/registry/ambient/CustomAmbientRegistry.java b/src/main/java/fr/openmc/core/registry/ambient/CustomAmbientRegistry.java index 01243c4fa..cfa24dc73 100644 --- a/src/main/java/fr/openmc/core/registry/ambient/CustomAmbientRegistry.java +++ b/src/main/java/fr/openmc/core/registry/ambient/CustomAmbientRegistry.java @@ -59,7 +59,7 @@ public void init() { OMCLogger.error("Erreur survenue durant le build du datapack lors du runtime {}", e.getMessage()); } } else { - OMCLogger.infoFormatted("Aucun ambient rajouté, innutile de redémarrer le serveur"); + OMCLogger.infoFormatted("Aucun ambient rajouté, inutile de redémarrer le serveur"); } } diff --git a/src/main/java/fr/openmc/core/registry/items/CustomItem.java b/src/main/java/fr/openmc/core/registry/items/CustomItem.java index a3565f424..8f90e1ace 100644 --- a/src/main/java/fr/openmc/core/registry/items/CustomItem.java +++ b/src/main/java/fr/openmc/core/registry/items/CustomItem.java @@ -6,6 +6,7 @@ import fr.openmc.core.utils.bukkit.ItemUtils; import lombok.Getter; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -30,7 +31,7 @@ public CustomItem(CustomItemMeta meta) { this.id = meta.getId(); } - public abstract ItemStack getVanilla(); + public abstract @NotNull ItemStack getVanilla(); public ItemStack getItemsAdder() { CustomStack stack = CustomStack.getInstance(getId()); diff --git a/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java b/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java index f96d58213..d34b21937 100644 --- a/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java +++ b/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java @@ -19,6 +19,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -62,7 +63,7 @@ public class CustomItemRegistry extends Registry implements public final CustomItem SUIT_CHESTPLATE = register("omc_items:suit_chestplate", Material.IRON_CHESTPLATE); public final CustomItem SUIT_LEGGINGS = register("omc_items:suit_leggings", Material.IRON_LEGGINGS); public final CustomItem SUIT_BOOTS = register("omc_items:suit_boots", Material.IRON_BOOTS); - public final CustomItem COMPANY_BOX = register("omc_company:company_box", Material.CHEST); + public final CustomItem COMPANY_BOX = register("omc_shops:company_box", Material.CHEST); public final CustomItem HOMES_ICON_BIN_RED = register("omc_homes:omc_homes_icon_bin_red", Material.CHEST); public final CustomItem HOMES_ICON_BIN = register("omc_homes:omc_homes_icon_bin", Material.CHEST); public final CustomItem HOMES_ICON_INFORMATION = register("omc_homes:omc_homes_icon_information", Material.CHEST); @@ -73,6 +74,7 @@ public class CustomItemRegistry extends Registry implements public final CustomItem PELUCHE_SEINYY = register("omc_plush:peluche_seinyy", Material.PAPER); public final CustomItem PELUCHE_AWYEN = register("omc_plush:peluche_awyen", Material.PAPER); public final CustomItem URNE = register("omc_blocks:urne", Material.GLASS); + public final CustomItem CAISSE = register("omc_shops:caisse", Material.PAPER); /* Homes icons */ public final CustomItem HOMES_ICON_AXENQ = register("omc_homes:omc_homes_icon_axenq", Material.CHEST); @@ -183,7 +185,7 @@ public CustomItem getOrThrow(ItemStack stack) { public CustomItem register(String name, ItemStack item) { return register(name, new CustomItem(name) { @Override - public ItemStack getVanilla() { + public @NotNull ItemStack getVanilla() { return item; } }); @@ -196,7 +198,7 @@ public CustomItem register(String name, Material item) { public CustomItem register(String name, Material material, String displayName) { return register(new CustomItem(name) { @Override - public ItemStack getVanilla() { + public @NotNull ItemStack getVanilla() { ItemStack item = new ItemStack(material); ItemMeta meta = item.getItemMeta(); meta.displayName(Component.text(displayName).decoration(TextDecoration.ITALIC, false)); diff --git a/src/main/java/fr/openmc/core/utils/bukkit/ContainerUtils.java b/src/main/java/fr/openmc/core/utils/bukkit/ContainerUtils.java new file mode 100644 index 000000000..1e04a4eb3 --- /dev/null +++ b/src/main/java/fr/openmc/core/utils/bukkit/ContainerUtils.java @@ -0,0 +1,41 @@ +package fr.openmc.core.utils.bukkit; + +import org.bukkit.block.Container; +import org.bukkit.inventory.ItemStack; + +/** + * Utility class for managing and manipulating items within containers. + */ +public class ContainerUtils { + + + /** + * Calculates the total number of items in a container that are similar to the given item. + * + * @param container the container to search for the items; if null, the method will return 0 + * @param item the item to look for within the container; must not be null + * @return the total count of items inside the container that are similar to the specified item, or 0 if the container or item is null + */ + public static int getTotalItemsIn(Container container, ItemStack item) { + if (container == null || item == null) return 0; + int total = 0; + for (ItemStack itemStack : container.getSnapshotInventory().getStorageContents()) { + if (itemStack == null) continue; + if (!ItemUtils.isSimilar(item, itemStack)) continue; + total += itemStack.getAmount(); + } + return total; + } + + /** + * Remove the specified number of items from the container's inventory. + * + * @param container the container whose inventory will be modified + * @param item the item to remove; must be similar to the items in the inventory {@link ItemStack} + * @param amountToRemove the number of items to remove + */ + public static int removeItemsFromContainerInventory(Container container, ItemStack item, int amountToRemove) { + if (container == null) return 0; + return InventoryUtils.removeItemsFromInventory(container.getInventory(), item, amountToRemove); + } +} diff --git a/src/main/java/fr/openmc/core/utils/bukkit/InventoryUtils.java b/src/main/java/fr/openmc/core/utils/bukkit/InventoryUtils.java new file mode 100644 index 000000000..5d379cc73 --- /dev/null +++ b/src/main/java/fr/openmc/core/utils/bukkit/InventoryUtils.java @@ -0,0 +1,35 @@ +package fr.openmc.core.utils.bukkit; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public class InventoryUtils { + + public static int removeItemsFromInventory(Inventory inventory, ItemStack item, int amountToRemove) { + if (item == null || amountToRemove <= 0) return 0; + + int removed = 0; + ItemStack[] contents = inventory.getContents(); + + for (int i = 0; i < contents.length && removed < amountToRemove; i++) { + ItemStack stack = contents[i]; + if (stack == null) continue; + + if (ItemUtils.isSimilar(stack, item)) { + int stackAmount = stack.getAmount(); + int toRemove = Math.min(amountToRemove - removed, stackAmount); + + removed += toRemove; + + if (stackAmount <= toRemove) { + inventory.setItem(i, null); + } else { + stack.setAmount(stackAmount - toRemove); + } + } + } + + return removed; + } + +} diff --git a/src/main/java/fr/openmc/core/utils/bukkit/ItemUtils.java b/src/main/java/fr/openmc/core/utils/bukkit/ItemUtils.java index b7fe113b3..962980056 100644 --- a/src/main/java/fr/openmc/core/utils/bukkit/ItemUtils.java +++ b/src/main/java/fr/openmc/core/utils/bukkit/ItemUtils.java @@ -263,8 +263,8 @@ public static boolean hasAvailableSlot(Player player) { * @param material the item to remove, must be similar to the items in the inventory {@link Material} * @param amountToRemove the number of items to remove */ - public static int removeItemsFromInventory(Player player, Material material, int amountToRemove) { - return removeItemsFromInventory(player, ItemStack.of(material), amountToRemove); + public static int removeItemsFromPlayerInventory(Player player, Material material, int amountToRemove) { + return removeItemsFromPlayerInventory(player, ItemStack.of(material), amountToRemove); } /** @@ -274,31 +274,9 @@ public static int removeItemsFromInventory(Player player, Material material, int * @param item the item to remove, must be similar to the items in the inventory {@link ItemStack} * @param amountToRemove the number of items to remove */ - public static int removeItemsFromInventory(Player player, ItemStack item, int amountToRemove) { - if (player == null || item == null || amountToRemove <= 0) return 0; - - int removed = 0; - ItemStack[] contents = player.getInventory().getContents(); - - for (int i = 0; i < contents.length && removed < amountToRemove; i++) { - ItemStack stack = contents[i]; - if (stack == null) continue; - - if (isSimilar(stack, item)) { - int stackAmount = stack.getAmount(); - int toRemove = Math.min(amountToRemove - removed, stackAmount); - - removed += toRemove; - - if (stackAmount <= toRemove) { - player.getInventory().setItem(i, null); - } else { - stack.setAmount(stackAmount - toRemove); - } - } - } - - return removed; + public static int removeItemsFromPlayerInventory(Player player, ItemStack item, int amountToRemove) { + if (player == null) return 0; + return InventoryUtils.removeItemsFromInventory(player.getInventory(), item, amountToRemove); } public static boolean takeAywenite(Player player, int amount) { @@ -318,7 +296,7 @@ public static boolean takeAywenite(Player player, int amount) { return false; } - removeItemsFromInventory(player, aywenite, amount); + removeItemsFromPlayerInventory(player, aywenite, amount); return true; } diff --git a/src/main/java/fr/openmc/core/utils/cache/CachePlayerProfile.java b/src/main/java/fr/openmc/core/utils/cache/CachePlayerProfile.java index 850014b1a..5b27cd3f0 100644 --- a/src/main/java/fr/openmc/core/utils/cache/CachePlayerProfile.java +++ b/src/main/java/fr/openmc/core/utils/cache/CachePlayerProfile.java @@ -11,7 +11,7 @@ public class CachePlayerProfile { private static final Object2ObjectMap playerProfileCache = new Object2ObjectOpenHashMap<>(); /** - * Donne l'PlayerProfile s'il est déjà mis en cache, sinon il exécute la méthode basique + * Donne le PlayerProfile s'il est déjà mis en cache, sinon il exécute la méthode basique */ public static PlayerProfile getPlayerProfile(UUID uuid) { return playerProfileCache.computeIfAbsent(uuid, key -> Bukkit.createProfile(uuid)); diff --git a/src/main/java/fr/openmc/core/utils/world/WorldUtils.java b/src/main/java/fr/openmc/core/utils/world/WorldUtils.java index f7ea7729d..d802ebc8a 100644 --- a/src/main/java/fr/openmc/core/utils/world/WorldUtils.java +++ b/src/main/java/fr/openmc/core/utils/world/WorldUtils.java @@ -34,15 +34,17 @@ public static String getDisplayedWorldName(String worldId) { public static Yaw getYaw(Player p) { float yaw = p.getLocation().getYaw(); - yaw = (yaw % 360 + 360) % 360; // true modulo, as javas modulo is unique for negative values - if (yaw > 135 || yaw < -135) { + if (yaw < 0) yaw += 360; + if (yaw > 135 && yaw <= 225) { return Yaw.NORTH; - } else if (yaw < -45) { + } else if (yaw > 225 && yaw <= 315) { return Yaw.EAST; - } else if (yaw > 45) { + } else if (yaw > 45 && yaw <= 135) { return Yaw.WEST; - } else { + } else if (yaw > 315 || yaw <= 45) { return Yaw.SOUTH; + } else { + return Yaw.NORTH; // should never happen } } diff --git a/src/main/java/fr/openmc/core/utils/world/Yaw.java b/src/main/java/fr/openmc/core/utils/world/Yaw.java index 82b3ba4ed..368875ac4 100644 --- a/src/main/java/fr/openmc/core/utils/world/Yaw.java +++ b/src/main/java/fr/openmc/core/utils/world/Yaw.java @@ -1,13 +1,14 @@ package fr.openmc.core.utils.world; +import lombok.Getter; import org.bukkit.block.BlockFace; public enum Yaw { - NORTH, - EAST, - SOUTH, - WEST; + NORTH(180), + EAST(270), + SOUTH(0), + WEST(90); public Yaw getOpposite() { return switch (this) { @@ -26,5 +27,11 @@ public BlockFace toBlockFace() { case WEST -> BlockFace.WEST; }; } - + + @Getter + final float playerYaw; + + Yaw (float playerYaw) { + this.playerYaw = playerYaw; + } } diff --git a/src/main/resources/contents/omc_company/textures/sell_shop_menu.png b/src/main/resources/contents/omc_company/textures/sell_shop_menu.png deleted file mode 100644 index a8f7d93f4..000000000 Binary files a/src/main/resources/contents/omc_company/textures/sell_shop_menu.png and /dev/null differ diff --git a/src/main/resources/contents/omc_company/textures/shop_menu.png b/src/main/resources/contents/omc_company/textures/shop_menu.png deleted file mode 100644 index 542a1e26e..000000000 Binary files a/src/main/resources/contents/omc_company/textures/shop_menu.png and /dev/null differ diff --git a/src/main/resources/contents/omc_menus/configs/btn.yml b/src/main/resources/contents/omc_menus/configs/btn.yml index de38806ee..fea7dac69 100644 --- a/src/main/resources/contents/omc_menus/configs/btn.yml +++ b/src/main/resources/contents/omc_menus/configs/btn.yml @@ -22,8 +22,15 @@ items: generate: true textures: - 1_btn - 64_btn: + 10_btn: display_name: 10 + resource: + material: PAPER + generate: true + textures: + - 10_btn + 64_btn: + display_name: 64 resource: material: PAPER generate: true @@ -37,7 +44,7 @@ items: textures: - plus_btn minus_btn: - display_name: plus + display_name: moins resource: material: PAPER generate: true diff --git a/src/main/resources/contents/omc_company/textures/10_btn.png b/src/main/resources/contents/omc_menus/textures/10_btn.png similarity index 100% rename from src/main/resources/contents/omc_company/textures/10_btn.png rename to src/main/resources/contents/omc_menus/textures/10_btn.png diff --git a/src/main/resources/contents/omc_company/configs/btn.yml b/src/main/resources/contents/omc_shops/configs/btn.yml similarity index 51% rename from src/main/resources/contents/omc_company/configs/btn.yml rename to src/main/resources/contents/omc_shops/configs/btn.yml index ae8df4c2c..9d51461fd 100644 --- a/src/main/resources/contents/omc_company/configs/btn.yml +++ b/src/main/resources/contents/omc_shops/configs/btn.yml @@ -1,14 +1,6 @@ info: - namespace: omc_company + namespace: omc_shops items: - 10_btn: - display_name: 10 - resource: - material: PAPER - generate: true - textures: - - 10_btn - company_box: display_name: "company box" resource: diff --git a/src/main/resources/contents/omc_company/configs/caisse.yml b/src/main/resources/contents/omc_shops/configs/caisse.yml similarity index 96% rename from src/main/resources/contents/omc_company/configs/caisse.yml rename to src/main/resources/contents/omc_shops/configs/caisse.yml index 35b496505..856a40dea 100644 --- a/src/main/resources/contents/omc_company/configs/caisse.yml +++ b/src/main/resources/contents/omc_shops/configs/caisse.yml @@ -1,5 +1,5 @@ info: - namespace: omc_company + namespace: omc_shops items: caisse: display_name: "§6§lCaisse" diff --git a/src/main/resources/contents/omc_company/configs/menus.yml b/src/main/resources/contents/omc_shops/configs/menus.yml similarity index 97% rename from src/main/resources/contents/omc_company/configs/menus.yml rename to src/main/resources/contents/omc_shops/configs/menus.yml index 37492b831..e5ebdb916 100644 --- a/src/main/resources/contents/omc_company/configs/menus.yml +++ b/src/main/resources/contents/omc_shops/configs/menus.yml @@ -1,5 +1,5 @@ info: - namespace: omc_company + namespace: omc_shops font_images: company_baltop_menu: permission: company.menu diff --git a/src/main/resources/contents/omc_company/models/items/caisse.json b/src/main/resources/contents/omc_shops/models/items/caisse.json similarity index 97% rename from src/main/resources/contents/omc_company/models/items/caisse.json rename to src/main/resources/contents/omc_shops/models/items/caisse.json index 9e07ffba0..e93155f41 100644 --- a/src/main/resources/contents/omc_company/models/items/caisse.json +++ b/src/main/resources/contents/omc_shops/models/items/caisse.json @@ -2,8 +2,8 @@ "credit": "Made with Blockbench", "texture_size": [64, 64], "textures": { - "0": "omc_company:items/texture", - "particle": "omc_company:items/texture" + "0": "omc_shops:items/texture", + "particle": "omc_shops:items/texture" }, "elements": [ { diff --git a/src/main/resources/contents/omc_company/textures/company_baltop_menu.png b/src/main/resources/contents/omc_shops/textures/company_baltop_menu.png similarity index 100% rename from src/main/resources/contents/omc_company/textures/company_baltop_menu.png rename to src/main/resources/contents/omc_shops/textures/company_baltop_menu.png diff --git a/src/main/resources/contents/omc_company/textures/company_box.png b/src/main/resources/contents/omc_shops/textures/company_box.png similarity index 100% rename from src/main/resources/contents/omc_company/textures/company_box.png rename to src/main/resources/contents/omc_shops/textures/company_box.png diff --git a/src/main/resources/contents/omc_company/textures/company_menu.png b/src/main/resources/contents/omc_shops/textures/company_menu.png similarity index 100% rename from src/main/resources/contents/omc_company/textures/company_menu.png rename to src/main/resources/contents/omc_shops/textures/company_menu.png diff --git a/src/main/resources/contents/omc_company/textures/items/texture.png b/src/main/resources/contents/omc_shops/textures/items/texture.png similarity index 100% rename from src/main/resources/contents/omc_company/textures/items/texture.png rename to src/main/resources/contents/omc_shops/textures/items/texture.png diff --git a/src/main/resources/contents/omc_company/textures/large_shop_menu.png b/src/main/resources/contents/omc_shops/textures/large_shop_menu.png similarity index 100% rename from src/main/resources/contents/omc_company/textures/large_shop_menu.png rename to src/main/resources/contents/omc_shops/textures/large_shop_menu.png diff --git a/src/main/resources/contents/omc_company/textures/paginate_company_menu.png b/src/main/resources/contents/omc_shops/textures/paginate_company_menu.png similarity index 100% rename from src/main/resources/contents/omc_company/textures/paginate_company_menu.png rename to src/main/resources/contents/omc_shops/textures/paginate_company_menu.png diff --git a/src/main/resources/contents/omc_shops/textures/sell_shop_menu.png b/src/main/resources/contents/omc_shops/textures/sell_shop_menu.png new file mode 100755 index 000000000..090606ae4 Binary files /dev/null and b/src/main/resources/contents/omc_shops/textures/sell_shop_menu.png differ diff --git a/src/main/resources/contents/omc_shops/textures/shop_menu.png b/src/main/resources/contents/omc_shops/textures/shop_menu.png new file mode 100755 index 000000000..ac1895750 Binary files /dev/null and b/src/main/resources/contents/omc_shops/textures/shop_menu.png differ diff --git a/src/main/resources/translations/default/credits.properties b/src/main/resources/translations/default/credits.properties index 9b6a789f8..73f054574 100644 --- a/src/main/resources/translations/default/credits.properties +++ b/src/main/resources/translations/default/credits.properties @@ -3,7 +3,7 @@ feature.credits.menu.lore.developers=Développeur(s) : %1$s feature.credits.menu.lore.graphists=Graphiste(s) : %1$s feature.credits.menu.lore.builders=Builder(s) : %1$s feature.credits.menu.close=Fermer le menu -feature.credits.feature.adminshop=Adminshop +feature.credits.feature.adminshop=L'Adminshop feature.credits.feature.animations=Les Animations feature.credits.feature.cube=Le Cube feature.credits.feature.city=Les Villes @@ -16,18 +16,19 @@ feature.credits.feature.war=Les Guerres feature.credits.feature.notation=Les Notations feature.credits.feature.rank=Les Grades feature.credits.feature.contest=Les Contests -feature.credits.feature.weekly_events=Les Evenements Hebdomadaires +feature.credits.feature.weekly_events=Les Événements Hebdomadaires feature.credits.feature.holograms=Les Hologrammes -feature.credits.feature.economy=L'Economie -feature.credits.feature.friends=Le systeme d'ami -feature.credits.feature.homes=Le Systeme d'Home +feature.credits.feature.economy=L'Économie +feature.credits.feature.friends=Le Système d'Amis +feature.credits.feature.homes=Le Système de Homes feature.credits.feature.leaderboard=Les Classements feature.credits.feature.mailbox=La Boite aux Lettres feature.credits.feature.mainmenu=Le Menu Principal feature.credits.feature.milestones=Les Milestones feature.credits.feature.privatemessage=Les messages privés feature.credits.feature.quest=Les Quêtes -feature.credits.feature.settings=Les Paramêtres +feature.credits.feature.settings=Les Paramètres +feature.credits.feature.shops=Les Shops feature.credits.feature.tickets=Les Tickets V1 feature.credits.feature.tpa=Le Tpa feature.credits.feature.rtp=Le RTP @@ -35,12 +36,12 @@ feature.credits.feature.versionning=Le Versionning feature.credits.feature.omcregistry=Les Registres OMC feature.credits.feature.customitems=Les Custom Items feature.credits.feature.customlootbox=Les Custom Lootbox -feature.credits.feature.chronometer=Chronomêtre -feature.credits.feature.cooldown=Cooldown -feature.credits.feature.menu_lib=Systeme de Menu -feature.credits.feature.packet_menu_lib=Systeme de Menu en Packet -feature.credits.feature.errorhandler=Le systeme de gestion d'erreur +feature.credits.feature.chronometer=Les Chronomètre +feature.credits.feature.cooldown=Les Cooldowns +feature.credits.feature.menu_lib=Le Système de Menu +feature.credits.feature.packet_menu_lib=Système de Menu en Packet +feature.credits.feature.errorhandler=Le Système de gestion d'erreurs feature.credits.feature.unittest=Les tests unitaires -feature.credits.feature.orm=Systeme de base de données +feature.credits.feature.orm=Système de base de données diff --git a/src/main/resources/translations/default/main.properties b/src/main/resources/translations/default/main.properties index a6835c357..1653ba597 100644 --- a/src/main/resources/translations/default/main.properties +++ b/src/main/resources/translations/default/main.properties @@ -1,9 +1,12 @@ # Language file for the plugin # Native language: French -# Do not use color codes in this file if there is an agument +# Do not use color codes in this file if there is an argument # * KEY DE TEST test=TESTTTT +# ** GLOBAL ** +global.never=Jamais + # ** UTILS ** utils.world.overworld=l'Overworld utils.world.nether=le Nether diff --git a/src/main/resources/translations/default/shop.properties b/src/main/resources/translations/default/shop.properties new file mode 100644 index 000000000..06ede27f1 --- /dev/null +++ b/src/main/resources/translations/default/shop.properties @@ -0,0 +1,113 @@ +# ** SHOPS ** +# * COMMANDS +# - Global Player Messages +feature.shop.player.is_not_him_shop=Ceci n'est pas votre shop. +feature.shop.player.is_not_empty=Votre shop n'est pas vide +feature.shop.player.barrel_is_not_empty=Votre tonneau de shop n'est pas vide + +# - Player Commands +feature.shop.player.not_enough_money=Vous n'avez pas assez d'argent pour créer un shop (%1$s nécessaires). +feature.shop.player.creating_begin=Vous avez recu un tonneau pour poser votre shop. +feature.shop.player.creating_cancel=Création de shop annulée. +feature.shop.player.cancelling_pay=Vous avez été remboursé de %1$s pour l'annulation de la création de votre shop. +feature.shop.player.chunk_claimed=Ce chunk est claim par l'ennemi, impossible de poser un shop ici +feature.shop.player.cant_create_barrel=Impossible de créer un shop ici, l'espace du tonneau doit être libre. +feature.shop.player.cant_create_cash=Impossible de créer un shop ici, l'espace au dessus du tonneau doit être libre. +feature.shop.player.deleted=Votre shop a bien été supprimé ! +feature.shop.player.success_created=Votre shop a été créé avec succès ! Vous pouvez maintenant y ajouter des articles. +feature.shop.player.withdraw_money=%1$s retirés de votre compte personnel. +feature.shop.player.pay_back=%1$s remboursés sur votre compte personnel + +# * ERRORS +feature.shop.error.shop_is_null=Erreur lors de l'ouverture du shop (le shop est nul) : appelez un admin. +feature.shop.error.entity_is_null=Erreur lors de l'ouverture du shop (l'entité est nulle) : appelez un admin. +feature.shop.error.cannot_save_location=Erreur lors de la création du shop (impossible de sauvegarder la position du shop) : tentative de suppression du shop. Appelez un admin +feature.shop.error.cannot_delete=Impossible de supprimer le shop : appelez un admin +feature.shop.error.cannot_remove_furniture=Erreur lors de la suppression du shop (impossible de retirer le meuble) : appelez un admin +feature.shop.error.not_found=Shop introuvable +feature.shop.error.pay_back=La création de shop n'ayant pas été possible, %1$s vous ont été remboursés +feature.shop.error.multiblock=Erreur lors de la création du shop (multiblock est nul) : appelez un admin +feature.shop.error.barrel=Tonneau non détecté, veuillez contacter le staff + +# * SHOP +feature.shop.get_turnover=Vous avez récupéré %1$s de votre shop. +feature.shop.is_owner=Vous ne pouvez pas acheter des items à votre propre shop. +feature.shop.not_enough_items=Le nombre d'items achetés dépasse le nombre d'items disponibles dans le shop +feature.shop.not_enough_space=Vous n'avez pas assez de place dans votre inventaire pour acheter ce nombre d'items +feature.shop.not_enough_money=Vous n'avez pas assez d'argent pour acheter ce nombre d'items +feature.shop.no_item=Ce shop n'a pas d'item + +# * MENUS +feature.shop.menu.already_opened=Ce menu est déjà ouvert. + +# - Main Shop Menu +feature.shop.menu.main.title=Menu du shop de %1$s +feature.shop.menu.main.delete.btn.title=Supprimer le shop +feature.shop.menu.main.delete.btn.lore=Retirer tout l'argent et les items est nécessaire pour supprimer le shop. \ +
ATTENTION, IL SERA IMPOSSIBLE DE REVENIR EN ARRIÈRE ! +feature.shop.menu.main.delete.confirm.accept=Supprimer DÉFINITIVEMENT le shop. +feature.shop.menu.main.delete.confirm.refuse=Revenir dans le menu du shop +feature.shop.menu.main.remove_item.btn.title=Supprimer l'item du shop +feature.shop.menu.main.remove_item.btn.lore=Retirer tous les stocks de l'item est nécessaire pour le supprimer.\ +
ATTENTION, IL SERA IMPOSSIBLE DE REVENIR EN ARRIÈRE +feature.shop.menu.main.remove_item.confirm.accept=Supprimer DÉFINITIVEMENT le l'item. +feature.shop.menu.main.remove_item.confirm.refuse=Revenir dans le menu du shop +feature.shop.menu.main.sells.title=Accéder aux ventes du shop +feature.shop.menu.main.sells.lore.success=%1$s ventes réalisées +feature.shop.menu.main.stats.title=Accéder aux statistiques du shop +feature.shop.menu.main.stats.lore.error=Aucune statistique disponible, car aucun item n'est en vente +feature.shop.menu.main.stats.lore.success=Chiffre d'affaires : %1$s +feature.shop.menu.main.stocks.title=Accéder aux stocks du shop +feature.shop.menu.main.stocks.lore.error=Impossible d'accéder aux stocks, car aucun item n'est en vente. +feature.shop.menu.main.stocks.lore.success=%1$s item(s) en stock +feature.shop.menu.main.modify_price.title=Modifier prix de l'item +feature.shop.menu.main.modify_price.message=Prix modifié +feature.shop.menu.main.remove.title=Retiter %1$s +feature.shop.menu.main.remove.lore=CLIQUEZ ICI POUR RETIRER %1$s +feature.shop.menu.main.add.title=Ajouter %1$s +feature.shop.menu.main.add.lore=CLIQUEZ ICI POUR AJOUTER %1$s +feature.shop.menu.main.refuse.title=Refuser l'achat +feature.shop.menu.main.refuse.lore=Vous refusez d'acheter %1$s item(s) \ +
CLIQUEZ ICI POUR REFUSER L'ACHAT +feature.shop.menu.main.accept.title=Accepter l'achat +feature.shop.menu.main.accept.lore=Cela vous coûtera %1$s pour %2$s item(s) \ +
CLIQUEZ ICI POUR ACCEPTER L'ACHAT +feature.shop.menu.main.yours=Ce shop est le votre. + +# - Selling Menu +feature.shop.menu.selling.title=Menu de vente +feature.shop.menu.selling.item_lore=CLIQUEZ ICI POUR SELECTIONNER CET ITEM À VENDRE +feature.shop.menu.selling.price_input=Entrez le prix auquel vous voulez vendre votre item (les virgules doivent être remplacées par des points) : +feature.shop.menu.selling.invalid_enter=Entrée invalide, pensez à remplacer les virgules par des points +feature.shop.menu.selling.added_item=Item ajouté au shop. Pensez à remplir les stocks dans le menu stocks avant de commencer à vendre. +feature.shop.menu.selling.info.title=Informations sur les shops +feature.shop.menu.selling.info.lore=Placez vos items à vendre dans le tonneau du shop, \ +
puis revenez dans ce menu pour sélectionner l'item à vendre. + +# - Stats Menu +feature.shop.menu.stats.title=Statistiques +feature.shop.menu.stats.sells.title=Total des ventes : %1$s +feature.shop.menu.stats.sales.title=Total d'items vendus : %1$s +feature.shop.menu.stats.turnover.title=Chiffre d'affaires : %1$s +feature.shop.menu.stats.buyers.title=Total d'acheteurs uniques : %1$s +feature.shop.menu.stats.stocks.title=Items restants dans les stocks : %1$s + +# - Sales Menu +feature.shop.menu.sales.title=Ventes du shop +feature.shop.menu.sales.item.name=Achat de %1$s +feature.shop.menu.sales.item.lore=Le %1$s \ +
%2$s item(s) acheté(s) pour %3$s +feature.shop.menu.sales.get_turnover.name=Récupérer les bénéfices +feature.shop.menu.sales.get_turnover.lore=%1$s à récupérer dans le shop (Hors taxes). \ +
La TVA est de 20% \ +
Dernier retrait : %2$s + +# - Stocks Menu +feature.shop.menu.stocks.title=Menu des Stocks +feature.shop.menu.stocks.fill.name.not_full=Remplir depuis le tonneau (%1$s item(s) disponible(s)) +feature.shop.menu.stocks.fill.name.full=Impossible de remplir plus, la limite de 1792 items à été atteinte. +feature.shop.menu.stocks.fill.success=Stocks rechargés. +feature.shop.menu.stocks.empty.name=Vider les stocks +feature.shop.menu.stocks.empty.lore=Cela vous donnera %1$s items +feature.shop.menu.stocks.empty.not_enough_space=Vous n'avez pas assez de place dans votre inventaire pour récupérer tous les items du shop ! +feature.shop.menu.stocks.empty.success=Vous avez bien récupéré les items du shop