From 1ab4bfe177f0f48fa73d7e0b5066a02c19ce4daf Mon Sep 17 00:00:00 2001 From: fullwall Date: Mon, 9 Sep 2024 00:26:52 +0800 Subject: [PATCH] Add open shop action to shops --- .../net/citizensnpcs/trait/ShopTrait.java | 12 ++- .../citizensnpcs/trait/shop/MoneyAction.java | 3 +- .../trait/shop/OpenShopAction.java | 92 +++++++++++++++++++ .../trait/shop/PermissionAction.java | 3 +- .../citizensnpcs/trait/shop/StoredShops.java | 5 +- 5 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 main/src/main/java/net/citizensnpcs/trait/shop/OpenShopAction.java diff --git a/main/src/main/java/net/citizensnpcs/trait/ShopTrait.java b/main/src/main/java/net/citizensnpcs/trait/ShopTrait.java index 9a3a58b16..01421a723 100644 --- a/main/src/main/java/net/citizensnpcs/trait/ShopTrait.java +++ b/main/src/main/java/net/citizensnpcs/trait/ShopTrait.java @@ -68,6 +68,8 @@ import net.citizensnpcs.trait.shop.MoneyAction.MoneyActionGUI; import net.citizensnpcs.trait.shop.NPCShopAction; import net.citizensnpcs.trait.shop.NPCShopAction.GUI; import net.citizensnpcs.trait.shop.NPCShopAction.Transaction; +import net.citizensnpcs.trait.shop.OpenShopAction; +import net.citizensnpcs.trait.shop.OpenShopAction.OpenShopActionGUI; import net.citizensnpcs.trait.shop.PermissionAction; import net.citizensnpcs.trait.shop.PermissionAction.PermissionActionGUI; import net.citizensnpcs.trait.shop.StoredShops; @@ -143,7 +145,14 @@ public class ShopTrait extends Trait { public boolean canEdit(NPC npc, Player sender) { return sender.hasPermission("citizens.admin") || sender.hasPermission("citizens.npc.shop.edit") || sender.hasPermission("citizens.npc.shop.edit." + getName()) - || npc.getOrAddTrait(Owner.class).isOwnedBy(sender); + || (npc != null && npc.getOrAddTrait(Owner.class).isOwnedBy(sender)); + } + + public boolean canView(Player sender) { + if (viewPermission != null && !sender.hasPermission(viewPermission)) + return false; + return Setting.SHOP_GLOBAL_VIEW_PERMISSION.asString().isEmpty() + || sender.hasPermission(Setting.SHOP_GLOBAL_VIEW_PERMISSION.asString()); } public void display(Player sender) { @@ -1042,5 +1051,6 @@ public class ShopTrait extends Trait { NPCShopAction.register(MoneyAction.class, "money", new MoneyActionGUI()); NPCShopAction.register(CommandAction.class, "command", new CommandActionGUI()); NPCShopAction.register(ExperienceAction.class, "experience", new ExperienceActionGUI()); + NPCShopAction.register(OpenShopAction.class, "open_shop", new OpenShopActionGUI()); } } diff --git a/main/src/main/java/net/citizensnpcs/trait/shop/MoneyAction.java b/main/src/main/java/net/citizensnpcs/trait/shop/MoneyAction.java index 37ff26c9c..0d9b448e3 100644 --- a/main/src/main/java/net/citizensnpcs/trait/shop/MoneyAction.java +++ b/main/src/main/java/net/citizensnpcs/trait/shop/MoneyAction.java @@ -125,7 +125,8 @@ public class MoneyAction extends NPCShopAction { public ItemStack createMenuItem(NPCShopAction previous) { if (supported == null) { try { - supported = Bukkit.getServicesManager().getRegistration(Economy.class).getProvider() != null; + supported = Bukkit.getServicesManager().getRegistration(Economy.class) != null + && Bukkit.getServicesManager().getRegistration(Economy.class).getProvider() != null; } catch (Throwable t) { supported = false; Messaging.severe("Error fetching shop economy provider, shop economy integration will not work:"); diff --git a/main/src/main/java/net/citizensnpcs/trait/shop/OpenShopAction.java b/main/src/main/java/net/citizensnpcs/trait/shop/OpenShopAction.java new file mode 100644 index 000000000..75962be7f --- /dev/null +++ b/main/src/main/java/net/citizensnpcs/trait/shop/OpenShopAction.java @@ -0,0 +1,92 @@ +package net.citizensnpcs.trait.shop; + +import java.util.function.Consumer; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import net.citizensnpcs.Citizens; +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.gui.InputMenus; +import net.citizensnpcs.api.gui.InventoryMenuPage; +import net.citizensnpcs.api.persistence.Persist; +import net.citizensnpcs.trait.ShopTrait.NPCShop; +import net.citizensnpcs.util.InventoryMultiplexer; +import net.citizensnpcs.util.Util; + +public class OpenShopAction extends NPCShopAction { + @Persist + public String shopName; + + public OpenShopAction() { + } + + public OpenShopAction(String shopName) { + this.shopName = shopName; + } + + @Override + public String describe() { + NPCShop shop = ((Citizens) CitizensAPI.getPlugin()).getShops().getShop(shopName); + String description = "Open " + shop.getName(); + return description; + } + + @Override + public int getMaxRepeats(Entity entity, InventoryMultiplexer inventory) { + return -1; + } + + @Override + public Transaction grant(Entity entity, InventoryMultiplexer inventory, int repeats) { + return take(entity, inventory, repeats); + } + + @Override + public Transaction take(Entity entity, InventoryMultiplexer inventory, int repeats) { + if (!(entity instanceof Player)) + return Transaction.fail(); + NPCShop shop = ((Citizens) CitizensAPI.getPlugin()).getShops().getShop(shopName); + Player player = (Player) entity; + // TODO: support hierarchical shops? would need to call InventoryMenu#transition somehow + return Transaction.create(() -> shop.canView(player), () -> { + player.closeInventory(); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> shop.display(player)); + }, () -> { + // TODO: closeInventory()? transitionBack()? + }); + } + + public static class OpenShopActionGUI implements GUI { + @Override + public InventoryMenuPage createEditor(NPCShopAction previous, Consumer callback) { + OpenShopAction action = previous == null ? new OpenShopAction() : (OpenShopAction) previous; + return InputMenus.stringSetter(() -> action.shopName, s -> { + if (s == null || s.isEmpty()) { + callback.accept(null); + return; + } + action.shopName = s; + callback.accept(action); + }); + } + + @Override + public ItemStack createMenuItem(NPCShopAction previous) { + String description = null; + if (previous != null) { + OpenShopAction old = (OpenShopAction) previous; + description = old.describe(); + } + return Util.createItem(Material.BOOKSHELF, "Open Shop", description); + } + + @Override + public boolean manages(NPCShopAction action) { + return action instanceof OpenShopAction; + } + } +} \ No newline at end of file diff --git a/main/src/main/java/net/citizensnpcs/trait/shop/PermissionAction.java b/main/src/main/java/net/citizensnpcs/trait/shop/PermissionAction.java index d109f25d5..75badc2d4 100644 --- a/main/src/main/java/net/citizensnpcs/trait/shop/PermissionAction.java +++ b/main/src/main/java/net/citizensnpcs/trait/shop/PermissionAction.java @@ -159,7 +159,8 @@ public class PermissionAction extends NPCShopAction { public ItemStack createMenuItem(NPCShopAction previous) { if (supported == null) { try { - supported = Bukkit.getServicesManager().getRegistration(Permission.class).getProvider() != null; + supported = Bukkit.getServicesManager().getRegistration(Permission.class) != null + && Bukkit.getServicesManager().getRegistration(Permission.class).getProvider() != null; } catch (Throwable t) { supported = false; } diff --git a/main/src/main/java/net/citizensnpcs/trait/shop/StoredShops.java b/main/src/main/java/net/citizensnpcs/trait/shop/StoredShops.java index 655add479..d46a4505f 100644 --- a/main/src/main/java/net/citizensnpcs/trait/shop/StoredShops.java +++ b/main/src/main/java/net/citizensnpcs/trait/shop/StoredShops.java @@ -38,9 +38,8 @@ public class StoredShops { } public NPCShop getShop(String name) { - if (npcShops.containsKey(name)) - return npcShops.get(name); - return getGlobalShop(name); + NPCShop shop = npcShops.get(name); + return shop == null ? getGlobalShop(name) : shop; } public void load() {