diff --git a/src/com/esophose/playerparticles/PlayerParticles.java b/src/com/esophose/playerparticles/PlayerParticles.java index cb13811..4e92f0a 100644 --- a/src/com/esophose/playerparticles/PlayerParticles.java +++ b/src/com/esophose/playerparticles/PlayerParticles.java @@ -116,6 +116,8 @@ public class PlayerParticles extends JavaPlugin { /** * Reloads the settings of the plugin + * + * @param updatePluginSettings True if the settings should be updated to the latest version of the plugin */ public void reload(boolean updatePluginSettings) { this.reloadConfig(); diff --git a/src/com/esophose/playerparticles/command/CommandModule.java b/src/com/esophose/playerparticles/command/CommandModule.java index e74cb9f..a4165a6 100644 --- a/src/com/esophose/playerparticles/command/CommandModule.java +++ b/src/com/esophose/playerparticles/command/CommandModule.java @@ -82,18 +82,5 @@ public interface CommandModule { LangManager.sendCustomMessage(pplayer, new MessageFormat(ChatColor.YELLOW + "/pp {0} {1} - {2}").format(args)); } } - - /** - * Displays a command's sub-command usage to the player - * - * @param pplayer The PPlayer to display the command usage to - * @param command The command to display usage for - * @param subCommandName The name of the command's sub-command to display usage for - * @param subCommandArgs The sub-command's arguments - */ - public static void printSubcommandUsage(PPlayer pplayer, CommandModule command, String subCommandName, String subCommandArgs) { - Object[] args = new Object[] { command.getName(), subCommandName, subCommandArgs }; - LangManager.sendCustomMessage(pplayer, new MessageFormat(ChatColor.YELLOW + "/pp {0} {1} {2}").format(args)); - } } diff --git a/src/com/esophose/playerparticles/command/GroupCommandModule.java b/src/com/esophose/playerparticles/command/GroupCommandModule.java index 739b8b0..b1008da 100644 --- a/src/com/esophose/playerparticles/command/GroupCommandModule.java +++ b/src/com/esophose/playerparticles/command/GroupCommandModule.java @@ -2,6 +2,7 @@ package com.esophose.playerparticles.command; import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.List; import org.bukkit.entity.Player; @@ -215,8 +216,11 @@ public class GroupCommandModule implements CommandModule { } } + List particles = group.getParticles(); + particles.sort(Comparator.comparingInt(ParticlePair::getId)); + LangManager.sendMessage(pplayer, Lang.GROUP_INFO_HEADER, groupName); - for (ParticlePair particle : group.getParticles()) + for (ParticlePair particle : particles) LangManager.sendMessage(pplayer, Lang.LIST_OUTPUT, particle.getId(), particle.getEffect().getName(), particle.getStyle().getName(), particle.getDataString()); } @@ -227,6 +231,7 @@ public class GroupCommandModule implements CommandModule { */ private void onList(PPlayer pplayer) { List groups = pplayer.getParticleGroups(); + groups.sort(Comparator.comparing(ParticleGroup::getName)); String groupsList = ""; for (ParticleGroup group : groups) diff --git a/src/com/esophose/playerparticles/command/ListCommandModule.java b/src/com/esophose/playerparticles/command/ListCommandModule.java index b02b8b3..93b1a73 100644 --- a/src/com/esophose/playerparticles/command/ListCommandModule.java +++ b/src/com/esophose/playerparticles/command/ListCommandModule.java @@ -1,6 +1,7 @@ package com.esophose.playerparticles.command; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import com.esophose.playerparticles.manager.LangManager; @@ -12,6 +13,7 @@ public class ListCommandModule implements CommandModule { public void onCommandExecute(PPlayer pplayer, String[] args) { List particles = pplayer.getActiveParticles(); + particles.sort(Comparator.comparingInt(ParticlePair::getId)); if (particles.isEmpty()) { LangManager.sendMessage(pplayer, Lang.LIST_NONE); diff --git a/src/com/esophose/playerparticles/command/ParticleCommandHandler.java b/src/com/esophose/playerparticles/command/ParticleCommandHandler.java index 5047e14..5282da5 100644 --- a/src/com/esophose/playerparticles/command/ParticleCommandHandler.java +++ b/src/com/esophose/playerparticles/command/ParticleCommandHandler.java @@ -90,7 +90,11 @@ public class ParticleCommandHandler implements CommandExecutor, TabCompleter { * @return true */ public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - if (!(sender instanceof Player)) return true; + if (!(sender instanceof Player)) { + sender.sendMessage("Error: PlayerParticles only supports players executing commands."); + return true; + } + Player p = (Player) sender; DataManager.getPPlayer(p.getUniqueId(), (pplayer) -> { diff --git a/src/com/esophose/playerparticles/command/VersionCommandModule.java b/src/com/esophose/playerparticles/command/VersionCommandModule.java index d082645..6b75be2 100644 --- a/src/com/esophose/playerparticles/command/VersionCommandModule.java +++ b/src/com/esophose/playerparticles/command/VersionCommandModule.java @@ -13,8 +13,8 @@ import com.esophose.playerparticles.particles.PPlayer; public class VersionCommandModule implements CommandModule { public void onCommandExecute(PPlayer pplayer, String[] args) { - LangManager.sendCustomMessage(pplayer, ChatColor.GOLD + "Running PlayerParticles v" + PlayerParticles.getPlugin().getDescription().getVersion()); - LangManager.sendCustomMessage(pplayer, ChatColor.GOLD + "Plugin created by: Esophose"); + LangManager.sendCustomMessage(pplayer, ChatColor.YELLOW + "Running PlayerParticles " + ChatColor.AQUA + "v" + PlayerParticles.getPlugin().getDescription().getVersion()); + LangManager.sendCustomMessage(pplayer, ChatColor.YELLOW + "Plugin created by: " + ChatColor.AQUA + "Esophose"); } public List onTabComplete(PPlayer pplayer, String[] args) { diff --git a/src/com/esophose/playerparticles/gui/GuiActionButton.java b/src/com/esophose/playerparticles/gui/GuiActionButton.java index 96bbfe1..9bf1707 100644 --- a/src/com/esophose/playerparticles/gui/GuiActionButton.java +++ b/src/com/esophose/playerparticles/gui/GuiActionButton.java @@ -3,7 +3,6 @@ package com.esophose.playerparticles.gui; import java.util.Arrays; import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -14,24 +13,22 @@ public class GuiActionButton { private Material[] icons; private String[] names; private String[] lore; - private boolean glowing; private GuiActionButtonClickCallback onClick; private int iconIndex; - public GuiActionButton(int slot, Material[] icons, String[] names, String[] lore, boolean glowing, GuiActionButtonClickCallback onClick) { + public GuiActionButton(int slot, Material[] icons, String[] names, String[] lore, GuiActionButtonClickCallback onClick) { this.slot = slot; this.icons = icons; this.names = names; this.lore = lore; - this.glowing = glowing; this.onClick = onClick; if (icons.length != names.length) throw new IllegalArgumentException("icons and names must have the same length!"); } - public GuiActionButton(int slot, Material icon, String name, String[] lore, boolean glowing, GuiActionButtonClickCallback onClick) { - this(slot, new Material[] { icon }, new String[] { name }, lore, glowing, onClick); + public GuiActionButton(int slot, Material icon, String name, String[] lore, GuiActionButtonClickCallback onClick) { + this(slot, new Material[] { icon }, new String[] { name }, lore, onClick); } /** @@ -54,10 +51,7 @@ public class GuiActionButton { itemMeta.setDisplayName(this.names[this.iconIndex]); itemMeta.setLore(Arrays.asList(this.lore)); - itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_ENCHANTS); - - if (this.glowing) - itemMeta.addEnchant(Enchantment.ARROW_INFINITE, 1, false); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS); itemStack.setItemMeta(itemMeta); @@ -69,9 +63,9 @@ public class GuiActionButton { * * @param isShiftClick If the player was holding shift when they clicked */ - public void handleClick(boolean isShiftClick) { + public void handleClick(GuiActionButton button, boolean isShiftClick) { if (this.onClick != null) - this.onClick.execute(isShiftClick); + this.onClick.execute(this, isShiftClick); } /** @@ -93,8 +87,9 @@ public class GuiActionButton { /** * Allows button click callbacks as parameters */ + @FunctionalInterface public static interface GuiActionButtonClickCallback { - public void execute(boolean isShiftClick); + public void execute(GuiActionButton button, boolean isShiftClick); } } diff --git a/src/com/esophose/playerparticles/gui/GuiHandler.java b/src/com/esophose/playerparticles/gui/GuiHandler.java index ec4f445..5d3450f 100644 --- a/src/com/esophose/playerparticles/gui/GuiHandler.java +++ b/src/com/esophose/playerparticles/gui/GuiHandler.java @@ -9,6 +9,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; import com.esophose.playerparticles.PlayerParticles; import com.esophose.playerparticles.manager.DataManager; @@ -22,12 +23,15 @@ import com.esophose.playerparticles.particles.PPlayer; public class GuiHandler extends BukkitRunnable implements Listener { private static List guiInventories = new ArrayList(); + private static BukkitTask guiTask = null; /** * Initializes all the static values for this class */ public static void setup() { - new GuiHandler().runTaskTimer(PlayerParticles.getPlugin(), 0, 10); + if (guiTask != null) + guiTask.cancel(); + guiTask = new GuiHandler().runTaskTimer(PlayerParticles.getPlugin(), 0, 10); } /** @@ -115,12 +119,13 @@ public class GuiHandler extends BukkitRunnable implements Listener { /** * Changes the player's inventory to another one + * + * @param nextInventory The GuiInventory to transition to */ protected static void transition(GuiInventory nextInventory) { removeGuiInventory(nextInventory.getPPlayer()); guiInventories.add(nextInventory); nextInventory.getPPlayer().getPlayer().openInventory(nextInventory.getInventory()); - System.out.println("Transitioned inventories"); } /** diff --git a/src/com/esophose/playerparticles/gui/GuiInventory.java b/src/com/esophose/playerparticles/gui/GuiInventory.java index 0eeebe1..cebc9ca 100644 --- a/src/com/esophose/playerparticles/gui/GuiInventory.java +++ b/src/com/esophose/playerparticles/gui/GuiInventory.java @@ -127,6 +127,8 @@ public abstract class GuiInventory { /** * Handles clicks of GuiActionButtons + * + * @param event The InventoryClickEvent triggered when the player clicks a GuiActionButton */ public void onClick(InventoryClickEvent event) { int slot = event.getSlot(); @@ -134,7 +136,7 @@ public abstract class GuiInventory { for (GuiActionButton button : this.actionButtons) { if (button.getSlot() == slot) { - button.handleClick(isShiftClick); + button.handleClick(button, isShiftClick); break; } } diff --git a/src/com/esophose/playerparticles/gui/GuiInventoryDefault.java b/src/com/esophose/playerparticles/gui/GuiInventoryDefault.java index 7bdc431..40ea0b3 100644 --- a/src/com/esophose/playerparticles/gui/GuiInventoryDefault.java +++ b/src/com/esophose/playerparticles/gui/GuiInventoryDefault.java @@ -3,12 +3,14 @@ package com.esophose.playerparticles.gui; import java.util.Arrays; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.SkullType; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.SkullMeta; +import com.esophose.playerparticles.manager.LangManager; +import com.esophose.playerparticles.manager.LangManager.Lang; +import com.esophose.playerparticles.manager.SettingManager.GUIIcon; import com.esophose.playerparticles.particles.PPlayer; import com.esophose.playerparticles.util.ParticleUtils; @@ -16,7 +18,7 @@ import com.esophose.playerparticles.util.ParticleUtils; public class GuiInventoryDefault extends GuiInventory { public GuiInventoryDefault(PPlayer pplayer) { - super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, "PlayerParticles")); + super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_PLAYERPARTICLES))); this.fillBorder(BorderColor.WHITE); @@ -28,13 +30,13 @@ public class GuiInventoryDefault extends GuiInventory { } else { headIcon = new ItemStack(ParticleUtils.closestMatch("SKULL_ITEM"), 1, (short) SkullType.PLAYER.ordinal()); } - + SkullMeta currentIconMeta = (SkullMeta) headIcon.getItemMeta(); - currentIconMeta.setDisplayName(ChatColor.GREEN + pplayer.getPlayer().getName()); + currentIconMeta.setDisplayName(LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + pplayer.getPlayer().getName()); String[] currentIconLore = new String[] { - ChatColor.YELLOW + "Active Particles: " + ChatColor.AQUA + pplayer.getActiveParticles().size(), - ChatColor.YELLOW + "Saved Groups: " + ChatColor.AQUA + pplayer.getParticleGroups().size(), - ChatColor.YELLOW + "Fixed Effects: " + ChatColor.AQUA + pplayer.getFixedEffectIds().size() + LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_ACTIVE_PARTICLES, pplayer.getActiveParticles().size()), + LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVED_GROUPS, pplayer.getParticleGroups().size()), + LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_FIXED_EFFECTS, pplayer.getFixedEffectIds().size()) }; currentIconMeta.setLore(Arrays.asList(currentIconLore)); currentIconMeta.setOwner(pplayer.getPlayer().getName()); @@ -43,20 +45,32 @@ public class GuiInventoryDefault extends GuiInventory { this.inventory.setItem(13, headIcon); // Manage Your Particles button - GuiActionButton manageYourParticlesButton = new GuiActionButton(38, Material.BLAZE_POWDER, ChatColor.GREEN + "Manage Your Particles", new String[] { ChatColor.YELLOW + "Create, edit, and delete your particles" }, false, (isShiftClick) -> { + GuiActionButton manageYourParticlesButton = new GuiActionButton(38, + GUIIcon.PARTICLES.get(), + LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_MANAGE_YOUR_PARTICLES), + new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_MANAGE_YOUR_PARTICLES_DESCRIPTION) }, + (button, isShiftClick) -> { GuiHandler.transition(new GuiInventoryManageParticles(pplayer)); }); this.actionButtons.add(manageYourParticlesButton); // Manage Your Groups button - GuiActionButton manageYourGroupsButton = new GuiActionButton(40, Material.CHEST, ChatColor.GREEN + "Manage Your Groups", new String[] { ChatColor.YELLOW + "Create, delete, and load particle groups" }, false, (isShiftClick) -> { - // transition to GuiInventoryManageGroups + GuiActionButton manageYourGroupsButton = new GuiActionButton(40, + GUIIcon.GROUPS.get(), + LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_MANAGE_YOUR_GROUPS), + new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_MANAGE_YOUR_GROUPS_DESCRIPTION) }, + (button, isShiftClick) -> { + GuiHandler.transition(new GuiInventoryManageGroups(pplayer)); }); this.actionButtons.add(manageYourGroupsButton); // Load Preset Groups - GuiActionButton loadPresetGroups = new GuiActionButton(42, Material.ENDER_CHEST, ChatColor.GREEN + "Load Preset Groups", new String[] { ChatColor.YELLOW + "Load pre-existing particle groups" }, false, (isShiftClick) -> { - // transition to GuiInventoryPresetGroups + GuiActionButton loadPresetGroups = new GuiActionButton(42, + GUIIcon.PRESET_GROUPS.get(), + LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_LOAD_A_PRESET_GROUP), + new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_LOAD_A_PRESET_GROUP_DESCRIPTION) }, + (button, isShiftClick) -> { + GuiHandler.transition(new GuiInventoryLoadPresetGroups(pplayer)); }); this.actionButtons.add(loadPresetGroups); diff --git a/src/com/esophose/playerparticles/gui/GuiInventoryLoadPresetGroups.java b/src/com/esophose/playerparticles/gui/GuiInventoryLoadPresetGroups.java new file mode 100644 index 0000000..6feed9d --- /dev/null +++ b/src/com/esophose/playerparticles/gui/GuiInventoryLoadPresetGroups.java @@ -0,0 +1,72 @@ +package com.esophose.playerparticles.gui; + +import java.util.Comparator; +import java.util.List; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.Material; + +import com.esophose.playerparticles.manager.DataManager; +import com.esophose.playerparticles.manager.LangManager; +import com.esophose.playerparticles.manager.LangManager.Lang; +import com.esophose.playerparticles.manager.SettingManager.GUIIcon; +import com.esophose.playerparticles.particles.PPlayer; +import com.esophose.playerparticles.particles.ParticleGroup; +import com.esophose.playerparticles.particles.ParticlePair; + +public class GuiInventoryLoadPresetGroups extends GuiInventory { + + public GuiInventoryLoadPresetGroups(PPlayer pplayer) { + super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_LOAD_A_PRESET_GROUP))); + + this.fillBorder(BorderColor.GREEN); + + int index = 10; + int nextWrap = 17; + int maxIndex = 43; + List> groups = ParticleGroup.getPresetGroupsForGUIForPlayer(pplayer.getPlayer()); + for (Entry groupEntry : groups) { + ParticleGroup group = groupEntry.getKey(); + Material iconMaterial = groupEntry.getValue(); + List particles = group.getParticles(); + particles.sort(Comparator.comparingInt(ParticlePair::getId)); + + String[] lore = new String[particles.size() + 1]; + lore[0] = LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_CLICK_TO_LOAD, particles.size()); + int i = 1; + for (ParticlePair particle : particles) { + lore[i] = LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), particle.getEffect().getName(), particle.getStyle().getName(), particle.getDataString()); + i++; + } + + // Load Group Buttons + GuiActionButton groupButton = new GuiActionButton(index, iconMaterial, LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + group.getName(), lore, (button, isShiftClick) -> { + ParticleGroup activeGroup = pplayer.getActiveParticleGroup(); + activeGroup.getParticles().clear(); + for (ParticlePair particle : particles) + activeGroup.getParticles().add(particle.clone()); + DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup); + + pplayer.getPlayer().closeInventory(); + }); + this.actionButtons.add(groupButton); + + index++; + if (index == nextWrap) { // Loop around border + nextWrap += 9; + index += 2; + } + if (index > maxIndex) break; // Overflowed the available space + } + + // Back Button + GuiActionButton backButton = new GuiActionButton(INVENTORY_SIZE - 1, GUIIcon.BACK.get(), LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON), new String[] {}, (button, isShiftClick) -> { + GuiHandler.transition(new GuiInventoryDefault(pplayer)); + }); + this.actionButtons.add(backButton); + + this.populate(); + } + +} diff --git a/src/com/esophose/playerparticles/gui/GuiInventoryManageGroups.java b/src/com/esophose/playerparticles/gui/GuiInventoryManageGroups.java new file mode 100644 index 0000000..eddd7d6 --- /dev/null +++ b/src/com/esophose/playerparticles/gui/GuiInventoryManageGroups.java @@ -0,0 +1,91 @@ +package com.esophose.playerparticles.gui; + +import java.util.Comparator; +import java.util.List; + +import org.bukkit.Bukkit; + +import com.esophose.playerparticles.manager.DataManager; +import com.esophose.playerparticles.manager.LangManager; +import com.esophose.playerparticles.manager.LangManager.Lang; +import com.esophose.playerparticles.manager.SettingManager.GUIIcon; +import com.esophose.playerparticles.particles.PPlayer; +import com.esophose.playerparticles.particles.ParticleGroup; +import com.esophose.playerparticles.particles.ParticlePair; + +public class GuiInventoryManageGroups extends GuiInventory { + + public GuiInventoryManageGroups(PPlayer pplayer) { + super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_MANAGE_YOUR_GROUPS))); + + this.fillBorder(BorderColor.BROWN); + + int index = 10; + int nextWrap = 17; + int maxIndex = 35; + List groups = pplayer.getParticleGroups(); + groups.sort(Comparator.comparing(ParticleGroup::getName)); + + for (ParticleGroup group : groups) { + if (group.getName().equals(ParticleGroup.DEFAULT_NAME)) continue; + + List particles = group.getParticles(); + particles.sort(Comparator.comparingInt(ParticlePair::getId)); + + String[] lore = new String[particles.size() + 2]; + lore[0] = LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_CLICK_TO_LOAD, particles.size()); + int i = 1; + for (ParticlePair particle : particles) { + lore[i] = LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), particle.getEffect().getName(), particle.getStyle().getName(), particle.getDataString()); + i++; + } + lore[i] = LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SHIFT_CLICK_TO_DELETE); + + // Load Group Buttons + GuiActionButton groupButton = new GuiActionButton(index, GUIIcon.GROUPS.get(), LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + group.getName(), lore, (button, isShiftClick) -> { + if (isShiftClick) { + DataManager.removeParticleGroup(pplayer.getUniqueId(), group); + + this.actionButtons.remove(button); + this.inventory.setItem(button.getSlot(), null); + } else { + ParticleGroup activeGroup = pplayer.getActiveParticleGroup(); + activeGroup.getParticles().clear(); + for (ParticlePair particle : particles) + activeGroup.getParticles().add(particle.clone()); + DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup); + + pplayer.getPlayer().closeInventory(); + } + }); + this.actionButtons.add(groupButton); + + index++; + if (index == nextWrap) { // Loop around border + nextWrap += 9; + index += 2; + } + if (index > maxIndex) break; // Overflowed the available space + } + + // Save Group Button + GuiActionButton saveGroupButton = new GuiActionButton(40, + GUIIcon.CREATE.get(), + LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_SAVE_GROUP), + new String[] { + LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION), + LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION_2), + }, + (button, isShiftClick) -> {}); // Does nothing on click + this.actionButtons.add(saveGroupButton); + + // Back Button + GuiActionButton backButton = new GuiActionButton(INVENTORY_SIZE - 1, GUIIcon.BACK.get(), LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON), new String[] {}, (button, isShiftClick) -> { + GuiHandler.transition(new GuiInventoryDefault(pplayer)); + }); + this.actionButtons.add(backButton); + + this.populate(); + } + +} diff --git a/src/com/esophose/playerparticles/gui/GuiInventoryManageParticles.java b/src/com/esophose/playerparticles/gui/GuiInventoryManageParticles.java index 03bb688..aeaecf8 100644 --- a/src/com/esophose/playerparticles/gui/GuiInventoryManageParticles.java +++ b/src/com/esophose/playerparticles/gui/GuiInventoryManageParticles.java @@ -3,19 +3,21 @@ package com.esophose.playerparticles.gui; import org.bukkit.Bukkit; import org.bukkit.Material; +import com.esophose.playerparticles.manager.LangManager; +import com.esophose.playerparticles.manager.LangManager.Lang; import com.esophose.playerparticles.particles.PPlayer; public class GuiInventoryManageParticles extends GuiInventory { public GuiInventoryManageParticles(PPlayer pplayer) { - super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE)); + super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_MANAGE_YOUR_PARTICLES))); this.fillBorder(BorderColor.ORANGE); - GuiActionButton button = new GuiActionButton(0, new Material[] { Material.BLAZE_POWDER, Material.BLAZE_ROD }, new String[] { "Test 2!", "Look at that!" } , new String[] { "To be continued..." }, true, (isShiftClick) -> { + GuiActionButton testButton = new GuiActionButton(0, new Material[] { Material.BLAZE_POWDER, Material.BLAZE_ROD }, new String[] { "Test 2!", "Look at that!" } , new String[] { "To be continued..." }, (button, isShiftClick) -> { GuiHandler.transition(new GuiInventoryDefault(pplayer)); }); - this.actionButtons.add(button); + this.actionButtons.add(testButton); this.populate(); } diff --git a/src/com/esophose/playerparticles/manager/DataManager.java b/src/com/esophose/playerparticles/manager/DataManager.java index 6600d10..d8d7dd7 100644 --- a/src/com/esophose/playerparticles/manager/DataManager.java +++ b/src/com/esophose/playerparticles/manager/DataManager.java @@ -420,6 +420,7 @@ public class DataManager { /** * Provides an easy way to run a section of code either synchronously or asynchronously using a callback */ + @FunctionalInterface private static interface SyncInterface { public void execute(); } @@ -427,6 +428,7 @@ public class DataManager { /** * Allows callbacks to be passed between configuration methods and executed for returning objects after database queries */ + @FunctionalInterface public static interface ConfigurationCallback { public void execute(T obj); } diff --git a/src/com/esophose/playerparticles/manager/LangManager.java b/src/com/esophose/playerparticles/manager/LangManager.java index 0e7d6f1..eda4b0e 100644 --- a/src/com/esophose/playerparticles/manager/LangManager.java +++ b/src/com/esophose/playerparticles/manager/LangManager.java @@ -177,16 +177,36 @@ public class LangManager { // GUI GUI_DISABLED, GUI_BY_DEFAULT, + GUI_COLOR_ICON_NAME, + GUI_COLOR_INFO, + GUI_COLOR_SUBTEXT, + GUI_COLOR_UNAVAILABLE, GUI_BACK_BUTTON, - GUI_ICON_NAME_COLOR, - GUI_ICON_CURRENT_ACTIVE, - GUI_ICON_SETS_TO, - GUI_ICON_SET_YOUR, - GUI_NO_ACCESS_TO, - GUI_NO_DATA; // @formatter:on + GUI_CLICK_TO_LOAD, + GUI_SHIFT_CLICK_TO_DELETE, + GUI_PARTICLE_INFO, + GUI_PLAYERPARTICLES, + GUI_ACTIVE_PARTICLES, + GUI_SAVED_GROUPS, + GUI_FIXED_EFFECTS, + GUI_MANAGE_YOUR_PARTICLES, + GUI_MANAGE_YOUR_PARTICLES_DESCRIPTION, + GUI_MANAGE_YOUR_GROUPS, + GUI_MANAGE_YOUR_GROUPS_DESCRIPTION, + GUI_LOAD_A_PRESET_GROUP, + GUI_LOAD_A_PRESET_GROUP_DESCRIPTION, + GUI_SAVE_GROUP, + GUI_SAVE_GROUP_DESCRIPTION, + GUI_SAVE_GROUP_DESCRIPTION_2; + // @formatter:on private String message; + /** + * Gets the name of the message in the config + * + * @return The location in the config that this message is located + */ private String getConfigName() { return this.name().toLowerCase().replaceAll("_", "-"); } @@ -230,6 +250,8 @@ public class LangManager { * Used to set up the LangManager * This should only get called once by the PlayerParticles class, however * calling it multiple times wont affect anything negatively + * + * @param resetLangFile If the default.lang file should be updated to the latest version */ public static void reload(boolean resetLangFile) { YamlConfiguration lang = configureLangFile(resetLangFile); @@ -242,6 +264,7 @@ public class LangManager { * If it doesn't exist, default to default.lang * If default.lang doesn't exist, copy the file from this .jar to the target directory * + * @param resetLangFile If the default.lang file should be updated to the latest version * @return The YamlConfiguration of the target .lang file */ private static YamlConfiguration configureLangFile(boolean resetLangFile) { diff --git a/src/com/esophose/playerparticles/manager/SettingManager.java b/src/com/esophose/playerparticles/manager/SettingManager.java index e4be44a..0d82a61 100644 --- a/src/com/esophose/playerparticles/manager/SettingManager.java +++ b/src/com/esophose/playerparticles/manager/SettingManager.java @@ -1,20 +1,33 @@ package com.esophose.playerparticles.manager; +import java.util.HashMap; import java.util.List; +import java.util.Map; + +import org.bukkit.Material; import com.esophose.playerparticles.PlayerParticles; +import com.esophose.playerparticles.particles.ParticleEffect; +import com.esophose.playerparticles.util.ParticleUtils; public class SettingManager { + /** + * The types of settings that can be loaded + */ private enum PSettingType { BOOLEAN, INTEGER, LONG, DOUBLE, STRING, - STRING_LIST + STRING_LIST, + MATERIAL } + /** + * An enum containing all settings in the config.yml for the plugin + */ public enum PSetting { VERSION(PSettingType.DOUBLE), TICKS_PER_PARTICLE(PSettingType.LONG), @@ -87,6 +100,15 @@ public class SettingManager { case STRING_LIST: this.value = PlayerParticles.getPlugin().getConfig().getStringList(configPath); break; + case MATERIAL: + String materialName = PlayerParticles.getPlugin().getConfig().getString(configPath); + Material material = ParticleUtils.closestMatch(materialName); + if (material == null) { + material = Material.BARRIER; + PlayerParticles.getPlugin().getLogger().severe("Invalid block/item name for '" + this.name().toLowerCase().replace('_', '-') + "' in config.yml: '" + materialName + "'"); + } + this.value = material; + break; } } return this.value; @@ -146,6 +168,92 @@ public class SettingManager { public List getStringList() { return (List) this.getValue(); } + + /** + * Gets the setting's value as a Material + * + * @return The setting's value as a Material + */ + public Material getMaterial() { + return (Material) this.getValue(); + } + } + + public enum GUIIcon { + PARTICLES, + GROUPS, + PRESET_GROUPS, + BACK, + CREATE, + EDIT_EFFECT, + EDIT_STYLE, + EDIT_DATA, + RANDOMIZE, + + EFFECT, + STYLE; + + private Map materials; + + private GUIIcon() { + this.materials = new HashMap(); + } + + /** + * Gets the Material for this icon from the 'gui-icon.misc' section in the config.yml + * Tries to get from cache first, otherwise loads it + * + * @return The Material for this Icon + */ + public Material get() { + return this.getInternal("gui-icon.misc." + this.name().toLowerCase()); + } + + /** + * Gets the Material for a subsection of this icon in the config.yml + * Tries to get from cache first, otherwise loads it + * + * @param subsection The name of the icon in the section + * @return The Material for this Icon + */ + public Material get(String subsection) { + return this.getInternal("gui-icon." + this.name().toLowerCase() + "." + subsection); + } + + /** + * Gets the Material for this icon + * Tries to get from cache first, otherwise loads it + * + * @return The path in the config.yml to lookup + */ + private Material getInternal(String configPath) { + Material material = this.materials.get(configPath); + if (material != null) + return material; + + List materials = PlayerParticles.getPlugin().getConfig().getStringList(configPath); + + try { + if (materials.size() == 1) { + material = ParticleUtils.closestMatch(materials.get(0)); + } else { + if (ParticleEffect.VERSION_13) { + material = ParticleUtils.closestMatch(materials.get(0)); + } else { + material = ParticleUtils.closestMatch(materials.get(1)); + } + } + } catch (Exception e) { + PlayerParticles.getPlugin().getLogger().severe("Missing GUI icon for '" + this.name().toLowerCase() + "'"); + } + + if (material == null) + material = Material.BARRIER; + + this.materials.put(configPath, material); + + return material; + } } private SettingManager() { diff --git a/src/com/esophose/playerparticles/particles/ParticleEffect.java b/src/com/esophose/playerparticles/particles/ParticleEffect.java index 7ece5c7..63a691b 100644 --- a/src/com/esophose/playerparticles/particles/ParticleEffect.java +++ b/src/com/esophose/playerparticles/particles/ParticleEffect.java @@ -77,8 +77,8 @@ public enum ParticleEffect { UNDERWATER("SUSPENDED_DEPTH", "SUSPENDED_DEPTH"), WITCH("SPELL_WITCH", "SPELL_WTICH"); + public static boolean VERSION_13; // This is a particle unique to Minecraft 1.13, this is a reliable way of telling what server version is running private static final Map NAME_MAP = new HashMap(); - private static boolean VERSION_13; // This is a particle unique to Minecraft 1.13, this is a reliable way of telling what server version is running private static Constructor DustOptions_CONSTRUCTOR; private static Method createBlockData_METHOD; private final Particle internalEnum; @@ -307,6 +307,7 @@ public enum ParticleEffect { * Gets a List of Players within the particle display range * * @param center The center of the radius to check around + * @param isFixedEffect If the particle is spawned from a fixed effect * @return A List of Players within the particle display range */ private List getPlayersInRange(Location center, boolean isFixedEffect) { diff --git a/src/com/esophose/playerparticles/particles/ParticleGroup.java b/src/com/esophose/playerparticles/particles/ParticleGroup.java index ebac619..ec88509 100644 --- a/src/com/esophose/playerparticles/particles/ParticleGroup.java +++ b/src/com/esophose/playerparticles/particles/ParticleGroup.java @@ -5,9 +5,10 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map.Entry; import java.util.Set; @@ -84,8 +85,6 @@ public class ParticleGroup { /** * Loads the preset groups from the groups.yml file - * - * @param pluginDataFolder */ public static void reload() { presetGroups = new HashMap(); @@ -213,7 +212,8 @@ public class ParticleGroup { } if (iconMaterial == null) { - + PlayerParticles.getPlugin().getLogger().severe("Missing icon for group '" + groupName + "'! Defaulting to ENDER_CHEST"); + iconMaterial = Material.ENDER_CHEST; } presetGroups.put(new ParticleGroup(groupName, particles), iconMaterial); @@ -223,11 +223,21 @@ public class ParticleGroup { } } - public static Set> getPresetGroupsForGUIForPlayer(Player player) { - Set> groups = new HashSet>(); - for (Entry entry : presetGroups.entrySet()) - if (entry.getKey().canPlayerUse(player)) - groups.add(entry); + /** + * Gets all the preset ParticleGroups ordered for display in the GUI + * + * @param player The player + * @return a List of preset ParticleGroups the player can use + */ + public static List> getPresetGroupsForGUIForPlayer(Player player) { + List> groups = new ArrayList>(); + List orderedGroups = new ArrayList(); + orderedGroups.addAll(presetGroups.keySet()); + orderedGroups.sort(Comparator.comparing(ParticleGroup::getName)); + + for (ParticleGroup group : orderedGroups) + if (group.canPlayerUse(player)) + groups.add(new AbstractMap.SimpleEntry(group, presetGroups.get(group))); return groups; } diff --git a/src/config.yml b/src/config.yml index 0a7ede1..ae91b85 100644 --- a/src/config.yml +++ b/src/config.yml @@ -31,7 +31,7 @@ messages-enabled: true # Default: true use-message-prefix: true -# The prefix to use for all PlayerParticle messages +# The prefix to use for all PlayerParticles messages # This is useless if use-message-prefix is set to false # Default: '&7[&3PlayerParticles&7]' message-prefix: '&7[&3PlayerParticles&7]' @@ -49,12 +49,12 @@ disabled-worlds: [] # - add_more_under_these # The maximum number of particles a player can apply at once -# The GUI will only display up to 14, don't set this any higher than that +# The GUI will only display up to 21, don't set this any higher than that # Default: 3 max-particles: 3 # The maximum number of groups a player can have saved -# The GUI will only display up to 14, don't set this any higher than that +# The GUI will only display up to 21, don't set this any higher than that # Default: 10 max-groups: 10 @@ -133,165 +133,213 @@ database-user-password: '' # * You MUST use the Spigot-given name for it to work. You can see # # all the Spigot-given names at the link below: # # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html # +# * If two icons are listed, the second one is used for below MC 1.13 # # =================================================================== # -gui-icon: - main-menu: - EFFECT: BLAZE_POWDER - STYLE: NETHER_STAR - DATA: BOOK - effect: # 1.13 and up - AMBIENT_ENTITY_EFFECT: BEACON - ANGRY_VILLAGER: IRON_DOOR - BARRIER: BARRIER - BLOCK: STONE - BUBBLE: BUBBLE_CORAL - BUBBLE_COLUMN_UP: MAGMA_BLOCK - BUBBLE_POP: BUBBLE_CORAL_FAN - CLOUD: WHITE_WOOL - CRIT: IRON_SWORD - CURRENT_DOWN: SOUL_SAND - DAMAGE_INDICATOR: BOW - DOLPHIN: DOLPHIN_SPAWN_EGG - DRAGON_BREATH: DRAGON_BREATH - DRIPPING_LAVA: LAVA_BUCKET - DRIPPING_WATER: WATER_BUCKET - DUST: REDSTONE - ENCHANT: ENCHANTING_TABLE - ENCHANTED_HIT: DIAMOND_SWORD - END_ROD: END_ROD - ENTITY_EFFECT: GLOWSTONE_DUST - EXPLOSION: FIRE_CHARGE - EXPLOSION_EMITTER: TNT - FALLING_DUST: SAND - FIREWORK: FIREWORK_ROCKET - FISHING: FISHING_ROD - FLAME: BLAZE_POWDER - HAPPY_VILLAGER: DARK_OAK_DOOR - HEART: POPPY - INSTANT_EFFECT: SPLASH_POTION - ITEM: ITEM_FRAME - ITEM_SLIME: SLIME_BALL - ITEM_SNOWBALL: SNOWBALL - LARGE_SMOKE: COBWEB - LAVA: MAGMA_CREAM - MYCELIUM: MYCELIUM - NAUTILUS: HEART_OF_THE_SEA - NOTE: NOTE_BLOCK - POOF: FIREWORK_STAR - PORTAL: OBSIDIAN - RAIN: PUFFERFISH_BUCKET - SMOKE: TORCH - SPELL: POTION - SPIT: LLAMA_SPAWN_EGG - SPLASH: SALMON - SQUID_INK: INK_SAC - SWEEP_ATTACK: GOLDEN_SWORD - TOTEM_OF_UNDYING: TOTEM - UNDERWATER: TURTLE_HELMET - WITCH: CAULDRON - effect-legacy: # 1.9 to 1.12 - AMBIENT_ENTITY_EFFECT: BEACON - ANGRY_VILLAGER: IRON_DOOR - BARRIER: BARRIER - BLOCK: STONE - BUBBLE: GLASS - CLOUD: WOOL - CRIT: IRON_SWORD - DAMAGE_INDICATOR: BOW - DRAGON_BREATH: DRAGONS_BREATH - DRIPPING_LAVA: LAVA_BUCKET - DRIPPING_WATER: WATER_BUCKET - DUST: REDSTONE - ENCHANT: ENCHANTMENT_TABLE - ENCHANTED_HIT: DIAMOND_SWORD - END_ROD: END_ROD - ENTITY_EFFECT: GLOWSTONE_DUST - EXPLOSION: FIREBALL - EXPLOSION_EMITTER: TNT - FALLING_DUST: SAND - FIREWORK: FIREWORK - FISHING: FISHING_ROD - FLAME: BLAZE_POWDER - FOOTSTEP: GRASS - HAPPY_VILLAGER: WOOD_DOOR - HEART: RED_ROSE - INSTANT_EFFECT: POTION - ITEM: ITEM_FRAME - ITEM_SLIME: SLIME_BALL - ITEM_SNOWBALL: SNOWBALL - LARGE_SMOKE: WEB - LAVA: MAGMA_CREAM - MYCELIUM: MYCEL - NOTE: NOTE_BLOCK - POOF: FIREWORK_CHARGE - PORTAL: OBSIDIAN - RAIN: LAPIS_BLOCK - SMOKE: TORCH - SPELL: GLASS_BOTTLE - SPIT: PUMPKIN_SEEDS - SPLASH: FISH - SWEEP_ATTACK: GOLD_SWORD - TOTEM_OF_UNDYING: TOTEM - UNDERWATER: BOAT - WITCH: CAULDRON - style: # 1.13 and up - ARROWS: BOW - BATMAN: COAL - BEAM: POWERED_RAIL - BLOCKBREAK: IRON_PICKAXE - BLOCKEDIT: DISPENSER - BLOCKPLACE: OAK_PLANKS - CHAINS: TRIPWIRE_HOOK - COMPANION: NAME_TAG - CUBE: STONE - FEET: GRASS - HALO: END_PORTAL_FRAME - HURT: CACTUS - INVOCATION: ENDER_EYE - MOVE: PISTON - NONE: GLASS_PANE - ORBIT: ENCHANTING_TABLE - OVERHEAD: GLOWSTONE - POINT: STONE_BUTTON - QUADHELIX: NAUTILUS_SHELL - NORMAL: DIRT - RINGS: STRING - SPHERE: HEART_OF_THE_SEA - SPIN: BEACON - SPIRAL: HOPPER - SWORDS: IRON_SWORD - THICK: COBWEB - VORTEX: GLOWSTONE_DUST - WINGS: ELYTRA - style-legacy: # 1.9 to 1.12 - ARROWS: BOW - BATMAN: COAL - BEAM: POWERED_RAIL - BLOCKBREAK: IRON_PICKAXE - BLOCKEDIT: DISPENSER - BLOCKPLACE: WOOD - CHAINS: TRIPWIRE_HOOK - COMPANION: NAME_TAG - CUBE: STONE - FEET: GRASS - HALO: ENDER_PORTAL_FRAME - HURT: CACTUS - INVOCATION: EYE_OF_ENDER - MOVE: PISTON_BASE - NORMAL: DIRT - ORBIT: ENCHANTMENT_TABLE - OVERHEAD: GLOWSTONE - POINT: STONE_BUTTON - QUADHELIX: ACTIVATOR_RAIL - RINGS: STRING - SPHERE: SNOW_BALL - SPIN: BEACON - SPIRAL: HOPPER - SWORDS: IRON_SWORD - THICK: VINE - VORTEX: GLOWSTONE_DUST - WINGS: ELYTRA +gui-icon: + misc: + particles: + - BLAZE_POWDER + groups: + - CHEST + preset_groups: + - ENDER_CHEST + back: + - ARROW + create: + - WRITABLE_BOOK + - BOOK_AND_QUILL + edit_effect: + - FIREWORK_ROCKET + - FIREWORK + edit_style: + - NETHER_STAR + edit_data: + - BOOK + randomize: + - HOPPER + effect: + ambient_entity_effect: + - BEACON + angry_villager: + - IRON_DOOR + barrier: + - BARRIER + block: + - STONE + bubble: + - BUBBLE_CORAL + - GLASS + bubble_column_up: + - MAGMA_BLOCK + bubble_pop: + - BUBBLE_CORAL_FAN + cloud: + - WHITE_WOOL + - WOOL + crit: + - IRON_SWORD + current_down: + - SOUL_SAND + damage_indicator: + - BOW + dolphin: + - DOLPHIN_SPAWN_EGG + dragon_breath: + - DRAGON_BREATH + - DRAGONS_BREATH + dripping_lava: + - LAVA_BUCKET + dripping_water: + - WATER_BUCKET + dust: + - REDSTONE + enchant: + - ENCHANTING_TABLE + - ENCHANTMENT_TABLE + enchanted_hit: + - DIAMOND_SWORD + end_rod: + - END_ROD + entity_effect: + - GLOWSTONE_DUST + explosion: + - FIRE_CHARGE + - FIREBALL + explosion_emitter: + - TNT + falling_dust: + - SAND + firework: + - FIREWORK_ROCKET + - FIREWORK + fishing: + - FISHING_ROD + flame: + - BLAZE_POWDER + footstep: + - GRASS + happy_villager: + - DARK_OAK_DOOR + - WOOD_DOOR + heart: + - POPPY + - RED_ROSE + instant_effect: + - SPLASH_POTION + - POTION + item: + - ITEM_FRAME + item_slime: + - SLIME_BALL + item_snowball: + - SNOWBALL + large_smoke: + - COBWEB + - WEB + lava: + - MAGMA_CREAM + mycelium: + - MYCELIUM + - MYCEL + nautilus: + - HEART_OF_THE_SEA + note: + - NOTE_BLOCK + poof: + - FIREWORK_STAR + - FIREWORK_CHARGE + portal: + - OBSIDIAN + rain: + - PUFFERFISH_BUCKET + - LAPIS_BLOCK + smoke: + - TORCH + spell: + - POTION + - GLASS_BOTTLE + spit: + - LLAMA_SPAWN_EGG + - PUMPKIN_SEEDS + splash: + - SALMON + - FISH + squid_ink: + - INK_SAC + sweep_attack: + - GOLDEN_SWORD + - GOLD_SWORD + totem_of_undying: + - TOTEM + underwater: + - TURTLE_HELMET + witch: + - CAULDRON + style: + arrows: + - BOW + batman: + - BAT_SPAWN_EGG + - COAL + beam: + - POWERED_RAIL + blockbreak: + - IRON_PICKAXE + blockedit: + - DISPENSER + blockplace: + - OAK_PLANKS + - WOOD + chains: + - TRIPWIRE_HOOK + companion: + - NAME_TAG + cube: + - STONE + feet: + - GRASS + halo: + - END_PORTAL_FRAME + - ENDER_PORTAL_FRAME + hurt: + - CACTUS + invocation: + - ENDER_EYE + - EYE_OF_ENDER + move: + - PISTON + - PISTON_BASE + normal: + - DIRT + orbit: + - ENCHANTING_TABLE + - ENCHANTMENT_TABLE + overhead: + - GLOWSTONE + point: + - STONE_BUTTON + quadhelix: + - NAUTILUS_SHELL + - ACTIVATOR_RAIL + rings: + - STRING + sphere: + - HEART_OF_THE_SEA + - SNOWBALL + spin: + - BEACON + spiral: + - HOPPER + swords: + - IRON_SWORD + thick: + - COBWEB + - WEB + vortex: + - GLOWSTONE_DUST + wings: + - ELYTRA # That's everything! You reached the end of the configuration. # Enjoy the plugin! diff --git a/src/lang/default.lang b/src/lang/default.lang index 5dab866..1e42bb4 100644 --- a/src/lang/default.lang +++ b/src/lang/default.lang @@ -163,10 +163,24 @@ fixed-invalid-command: '&cInvalid sub-command for &b/pp fixed&c!' # GUI gui-disabled: '&cThe server administrator has disabled the GUI!' gui-by-default: '&eWe opened the GUI for you because you did not specify a command. View other commands with &b/pp help&e or use &b/pp gui&e to avoid this message.' -gui-back-button: '&eGo Back' -gui-icon-name-color: '&a' -gui-icon-current-active: '&d- Your current {0} -' -gui-icon-sets-to: '&eSets your {0} to &b' -gui-icon-set-your: '&eSelect your {0}' -gui-no-access-to: '&cYou have no access to any {0}!' -gui-no-data: '&cYour effect does not use any data!' +gui-color-icon-name: '&a' +gui-color-info: '&e' +gui-color-subtext: '&b' +gui-color-unavailable: '&c' +gui-back-button: 'Go Back' +gui-click-to-load: 'Click to load the following {0} particle(s):' +gui-shift-click-to-delete: 'Shift click to delete' +gui-particle-info: ' - ID: &b{0} &eEffect: &b{1} &eStyle: &b{2} &eData: &b{3}' +gui-playerparticles: 'PlayerParticles' +gui-active-particles: 'Active Particles: &b{0}' +gui-saved-groups: 'Saved Groups: &b{0}' +gui-fixed-effects: 'Fixed Effects: &b{0}' +gui-manage-your-particles: 'Manage Your Particles' +gui-manage-your-particles-description: 'Create, edit, and delete your particles' +gui-manage-your-groups: 'Manage Your Groups' +gui-manage-your-groups-description: 'Create, delete, and load your particle groups' +gui-load-a-preset-group: 'Load A Preset Group' +gui-load-a-preset-group-description: 'Load a premade particle group' +gui-save-group: 'Save New Group' +gui-save-group-description: 'You can save a new group using the following command:' +gui-save-group-description-2: '/pp group save '