diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdFWarp.java b/src/main/java/com/massivecraft/factions/cmd/CmdFWarp.java index d1fc1cc2..6067124a 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdFWarp.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdFWarp.java @@ -6,6 +6,7 @@ import com.massivecraft.factions.P; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.util.LazyLocation; import com.massivecraft.factions.util.WarmUpUtil; +import com.massivecraft.factions.util.WarpGUI; import com.massivecraft.factions.zcore.fperms.Access; import com.massivecraft.factions.zcore.fperms.PermissableAction; import com.massivecraft.factions.zcore.util.TL; @@ -44,12 +45,10 @@ public class CmdFWarp extends FCommand { } if (args.size() == 0) { - FancyMessage msg = new FancyMessage(TL.COMMAND_FWARP_WARPS.toString()).color(ChatColor.GOLD); - Map warps = myFaction.getWarps(); - for (String s : warps.keySet()) { - msg.then(s + " ").tooltip(TL.COMMAND_FWARP_CLICKTOWARP.toString()).command("/" + Conf.baseCommandAliases.get(0) + " warp " + s).color(ChatColor.WHITE); - } - sendFancyMessage(msg); + WarpGUI warpGUI = new WarpGUI(fme); + warpGUI.build(); + + me.openInventory(warpGUI.getInventory()); } else if (args.size() > 2) { fme.msg(TL.COMMAND_FWARP_COMMANDFORMAT); } else { diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java index 455950de..43537af2 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -12,7 +12,7 @@ import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.util.VisualizeUtil; import com.massivecraft.factions.zcore.fperms.Access; import com.massivecraft.factions.zcore.fperms.PermissableAction; -import com.massivecraft.factions.zcore.fperms.gui.PermissionGUI; +import com.massivecraft.factions.util.FactionGUI; import com.massivecraft.factions.zcore.persist.MemoryFPlayer; import com.massivecraft.factions.zcore.util.TL; import com.massivecraft.factions.zcore.util.TextUtil; @@ -609,15 +609,15 @@ public class FactionsPlayerListener implements Listener { if (event.getClickedInventory() == null) { return; } - if (event.getClickedInventory().getHolder() instanceof PermissionGUI) { + if (event.getClickedInventory().getHolder() instanceof FactionGUI) { event.setCancelled(true); - ((PermissionGUI) event.getClickedInventory().getHolder()).onClick(event.getRawSlot(), event.getClick()); + ((FactionGUI) event.getClickedInventory().getHolder()).onClick(event.getRawSlot(), event.getClick()); } } @EventHandler(priority = EventPriority.HIGH) public void onPlayerMoveGUI(InventoryDragEvent event) { - if (event.getInventory().getHolder() instanceof PermissionGUI) { + if (event.getInventory().getHolder() instanceof FactionGUI) { event.setCancelled(true); } } diff --git a/src/main/java/com/massivecraft/factions/util/FactionGUI.java b/src/main/java/com/massivecraft/factions/util/FactionGUI.java new file mode 100644 index 00000000..077a3f08 --- /dev/null +++ b/src/main/java/com/massivecraft/factions/util/FactionGUI.java @@ -0,0 +1,11 @@ +package com.massivecraft.factions.util; + +import org.bukkit.event.inventory.ClickType; + +public interface FactionGUI { + + public void onClick(int slot, ClickType action); + + public void build(); + +} diff --git a/src/main/java/com/massivecraft/factions/util/WarpGUI.java b/src/main/java/com/massivecraft/factions/util/WarpGUI.java new file mode 100644 index 00000000..08c9a352 --- /dev/null +++ b/src/main/java/com/massivecraft/factions/util/WarpGUI.java @@ -0,0 +1,252 @@ +package com.massivecraft.factions.util; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; +import com.massivecraft.factions.integration.Econ; +import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.*; +import java.util.logging.Level; + +public class WarpGUI implements InventoryHolder, FactionGUI { + + private Inventory warpGUI; + private FPlayer fme; + + int guiSize; + + private HashMap warpSlots = new HashMap<>(); + private int maxWarps; + + private List dummySlots = new ArrayList<>(); + + private final ConfigurationSection section; + + public WarpGUI(FPlayer fme) { + this.fme = fme; + this.section = P.p.getConfig().getConfigurationSection("fwarp-gui"); + } + + @Override + public void build() { + if (section == null) { + P.p.log(Level.WARNING, "Attempted to build f warp GUI but config section not present."); + P.p.log(Level.WARNING, "Copy your config, allow the section to generate, then copy it back to your old config."); + return; + } + + // Build basic Inventory info + guiSize = section.getInt("rows", 3); + if (guiSize > 6) { + guiSize = 6; + P.p.log(Level.INFO, "Warp GUI size out of bounds, defaulting to 6"); + } + + guiSize *= 9; + String guiName = ChatColor.translateAlternateColorCodes('&', section.getString("name", "FactionPermissions")); + warpGUI = Bukkit.createInventory(this, guiSize, guiName); + + maxWarps = P.p.getConfig().getInt("max-warps", 5); + + Set factionWarps = fme.getFaction().getWarps().keySet(); + List warpOpenSlots = section.getIntegerList("warp-slots"); + + buildDummyItems(); + + if (maxWarps != warpOpenSlots.size()) { + P.p.log(Level.SEVERE, "Invalid warp slots for GUI, Please use same value as max warps"); + return; + } + + int warpSlotIndex = 0; + for (String warp : factionWarps) { + warpSlots.put(warpOpenSlots.get(warpSlotIndex), warp); + warpSlotIndex++; + } + + buildItems(); + } + + @Override + public Inventory getInventory() { + return warpGUI; + } + + private void buildItems() { + for (Map.Entry entry : warpSlots.entrySet()) { + warpGUI.setItem(entry.getKey(), buildItem(entry.getValue())); + } + } + + @Override + public void onClick(int slot, ClickType action) { + if (warpSlots.containsKey(slot)) { + fme.getPlayer().closeInventory(); + + // All clear lets TP them or ask for password + String warp = warpSlots.get(slot); + if (!fme.getFaction().hasWarpPassword(warp)) { + if (transact(fme)) { + doWarmup(warp); + } + } else { + fme.msg(TL.COMMAND_FWARP_PASSWORD_REQUIRED); + } + } + } + + private void doWarmup(final String warp) { + WarmUpUtil.process(fme, WarmUpUtil.Warmup.WARP, TL.WARMUPS_NOTIFY_TELEPORT, warp, new Runnable() { + @Override + public void run() { + Player player = Bukkit.getPlayer(fme.getPlayer().getUniqueId()); + if (player != null) { + player.teleport(fme.getFaction().getWarp(warp).getLocation()); + fme.msg(TL.COMMAND_FWARP_WARPED, warp); + } + } + }, P.p.getConfig().getLong("warmups.f-warp", 0)); + } + + private boolean transact(FPlayer player) { + if (!P.p.getConfig().getBoolean("warp-cost.enabled", false) || player.isAdminBypassing()) { + return true; + } + + double cost = P.p.getConfig().getDouble("warp-cost.warp", 5); + + if (!Econ.shouldBeUsed() || this.fme == null || cost == 0.0 || fme.isAdminBypassing()) { + return true; + } + + if (Conf.bankEnabled && Conf.bankFactionPaysCosts && fme.hasFaction()) { + return Econ.modifyMoney(fme.getFaction(), -cost, TL.COMMAND_FWARP_TOWARP.toString(), TL.COMMAND_FWARP_FORWARPING.toString()); + } else { + return Econ.modifyMoney(fme, -cost, TL.COMMAND_FWARP_TOWARP.toString(), TL.COMMAND_FWARP_FORWARPING.toString()); + } + } + + private ItemStack buildItem(String warp) { + ConfigurationSection warpItemSection = section.getConfigurationSection("warp-item"); + if (warpItemSection == null) { + P.p.log(Level.WARNING, "Attempted to build f warp GUI but config section not present."); + P.p.log(Level.WARNING, "Copy your config, allow the section to generate, then copy it back to your old config."); + return new ItemStack(Material.AIR); + } + + String displayName = replacePlaceholers(warpItemSection.getString("name"), warp, fme.getFaction()); + List lore = new ArrayList<>(); + + if (warpItemSection.getString("material") == null) { + return null; + } + Material material = Material.matchMaterial(warpItemSection.getString("material")); + if (material == null) { + material = Material.STONE; + } + + ItemStack item = new ItemStack(material); + ItemMeta itemMeta = item.getItemMeta(); + + for (String loreLine : warpItemSection.getStringList("lore")) { + lore.add(replacePlaceholers(loreLine, warp, fme.getFaction())); + } + + itemMeta.setDisplayName(displayName); + itemMeta.setLore(lore); + item.setItemMeta(itemMeta); + + return item; + } + + private String replacePlaceholers(String string, String warp, Faction faction) { + string = ChatColor.translateAlternateColorCodes('&', string); + string = string.replace("{warp}", warp); + string = string.replace("{warp-protected}", faction.hasWarpPassword(warp) ? "Enabled" : "Disabled"); + string = string.replace("{warp-cost}", !P.p.getConfig().getBoolean("warp-cost.enabled", false) ? "Disabled" : Integer.toString(P.p.getConfig().getInt("warp-cost.warp", 5))); + return string; + } + + private void buildDummyItems() { + for (String key : section.getConfigurationSection("dummy-slots").getKeys(false)) { + int dummyId; + try { + dummyId = Integer.parseInt(key); + } catch (NumberFormatException exception) { + P.p.log(Level.WARNING, "Invalid dummy item id: " + key.toUpperCase()); + continue; + } + + ItemStack dummyItem = buildDummyItem(dummyId); + if (dummyItem == null) { + continue; + } + + List dummyIdSlots = section.getIntegerList("dummy-slots." + key); + for (Integer slot : dummyIdSlots) { + if (slot + 1 > guiSize || slot < 0) { + P.p.log(Level.WARNING, "Invalid slot: " + slot + " for dummy item: " + key); + continue; + } + dummySlots.add(slot); + warpGUI.setItem(slot, dummyItem); + } + } + } + + private ItemStack buildDummyItem(int id) { + final ConfigurationSection dummySection = section.getConfigurationSection("dummy-items." + id); + + if (dummySection == null) { + P.p.log(Level.WARNING, "Attempted to build f warp GUI but config section not present."); + P.p.log(Level.WARNING, "Copy your config, allow the section to generate, then copy it back to your old config."); + return new ItemStack(Material.AIR); + } + + Material material = Material.matchMaterial(dummySection.getString("material", "")); + if (material == null) { + P.p.log(Level.WARNING, "Invalid material for dummy item: " + id); + return null; + } + + ItemStack itemStack = new ItemStack(material); + + DyeColor color; + try { + color = DyeColor.valueOf(dummySection.getString("color", "")); + } catch (Exception exception) { + color = null; + } + if (color != null) { + itemStack.setDurability(color.getWoolData()); + } + + ItemMeta itemMeta = itemStack.getItemMeta(); + + itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', dummySection.getString("name", " "))); + + List lore = new ArrayList<>(); + for (String loreLine : dummySection.getStringList("lore")) { + lore.add(ChatColor.translateAlternateColorCodes('&', loreLine)); + } + itemMeta.setLore(lore); + + itemStack.setItemMeta(itemMeta); + + return itemStack; + } + +} diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionGUI.java b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionGUI.java index efd8f8b1..9aa50e80 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionGUI.java +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionGUI.java @@ -2,6 +2,7 @@ package com.massivecraft.factions.zcore.fperms.gui; import com.massivecraft.factions.FPlayer; import com.massivecraft.factions.P; +import com.massivecraft.factions.util.FactionGUI; import com.massivecraft.factions.zcore.fperms.Access; import com.massivecraft.factions.zcore.fperms.Permissable; import com.massivecraft.factions.zcore.fperms.PermissableAction; @@ -20,7 +21,7 @@ import org.bukkit.inventory.meta.ItemMeta; import java.util.*; import java.util.logging.Level; -public class PermissableActionGUI implements InventoryHolder, PermissionGUI { +public class PermissableActionGUI implements InventoryHolder, FactionGUI { private Inventory actionGUI; private FPlayer fme; @@ -272,4 +273,22 @@ public class PermissableActionGUI implements InventoryHolder, PermissionGUI { return itemStack; } + public enum SpecialItem { + BACK, + RELATION; + + static boolean isSpecial(String string) { + return fromString(string) != null; + } + + static SpecialItem fromString(String string) { + for (SpecialItem specialItem : SpecialItem.values()) { + if (string.equalsIgnoreCase(specialItem.name())) { + return specialItem; + } + } + return null; + } + } + } diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationGUI.java b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationGUI.java index 94b7dadc..9f33937c 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationGUI.java +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationGUI.java @@ -4,6 +4,7 @@ import com.massivecraft.factions.FPlayer; import com.massivecraft.factions.P; import com.massivecraft.factions.struct.Relation; import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.util.FactionGUI; import com.massivecraft.factions.zcore.fperms.Permissable; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -22,7 +23,7 @@ import java.util.List; import java.util.Map; import java.util.logging.Level; -public class PermissableRelationGUI implements InventoryHolder, PermissionGUI { +public class PermissableRelationGUI implements InventoryHolder, FactionGUI { private Inventory relationGUI; private FPlayer fme; diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissionGUI.java b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissionGUI.java deleted file mode 100644 index e01e3fb4..00000000 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissionGUI.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.massivecraft.factions.zcore.fperms.gui; - -import org.bukkit.event.inventory.ClickType; - -public interface PermissionGUI { - - public void onClick(int slot, ClickType action); - - public void build(); - - public enum SpecialItem { - BACK, - RELATION; - - static boolean isSpecial(String string) { - return fromString(string) != null; - } - - static SpecialItem fromString(String string) { - for (SpecialItem specialItem : SpecialItem.values()) { - if (string.equalsIgnoreCase(specialItem.name())) { - return specialItem; - } - } - return null; - } - } - -} diff --git a/src/main/java/com/massivecraft/factions/zcore/util/TL.java b/src/main/java/com/massivecraft/factions/zcore/util/TL.java index e536d86c..9b128e1b 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TL.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TL.java @@ -196,6 +196,7 @@ public enum TL { COMMAND_FWARP_WARPS("Warps: "), COMMAND_FWARP_DESCRIPTION("Teleport to a faction warp"), COMMAND_FWARP_INVALID_PASSWORD("&4Invalid password!"), + COMMAND_FWARP_PASSWORD_REQUIRED("&cThis faction warp requires a password, use command instead"), COMMAND_HELP_404("This page does not exist"), COMMAND_HELP_NEXTCREATE("Learn how to create a faction on the next page."), diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index db179482..948317d0 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -518,6 +518,63 @@ fperm-gui: name: ' ' lore: - +############################################################ +# +------------------------------------------------------+ # +# | Faction Warp GUI | # +# +------------------------------------------------------+ # +############################################################ + +fwarp-gui: + name: "Faction Warps" + rows: 3 + warp-slots: + - 11 + - 12 + - 13 + - 14 + - 15 + dummy-slots: + '0': + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 16 + - 17 + - 18 + - 19 + - 20 + - 21 + - 22 + - 23 + - 24 + - 25 + - 26 + warp-item: + material: STONE + name: "&8[&5&l{warp}&8]" + # {warp-protected} Warp protection by password, Enabled & Disabled + # {warp-cost} Warp cost + lore: + - "&8Password: &l{warp-protected}" + - "&8Cost: &l{warp-cost}" + # Dummy Items + dummy-items: + # Dummy Item id, used to set the slots above + '0': + material: STAINED_GLASS_PANE + # Color will only work on colorable materials + color: BLACK + name: ' ' + lore: + - ############################################################ # +------------------------------------------------------+ #