Group GUI sections finished, sort command list outputs, GUI configuration added

This commit is contained in:
Esophose 2018-11-04 04:03:54 -07:00
parent f7eb08e48d
commit 98a570a236
20 changed files with 619 additions and 232 deletions

View file

@ -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();

View file

@ -83,17 +83,4 @@ public interface CommandModule {
}
}
/**
* 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));
}
}

View file

@ -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<ParticlePair> 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<ParticleGroup> groups = pplayer.getParticleGroups();
groups.sort(Comparator.comparing(ParticleGroup::getName));
String groupsList = "";
for (ParticleGroup group : groups)

View file

@ -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<ParticlePair> particles = pplayer.getActiveParticles();
particles.sort(Comparator.comparingInt(ParticlePair::getId));
if (particles.isEmpty()) {
LangManager.sendMessage(pplayer, Lang.LIST_NONE);

View file

@ -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) -> {

View file

@ -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<String> onTabComplete(PPlayer pplayer, String[] args) {

View file

@ -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);
}
}

View file

@ -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<GuiInventory> guiInventories = new ArrayList<GuiInventory>();
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");
}
/**

View file

@ -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;
}
}

View file

@ -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);
@ -30,11 +32,11 @@ public class GuiInventoryDefault extends GuiInventory {
}
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);

View file

@ -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<Entry<ParticleGroup, Material>> groups = ParticleGroup.getPresetGroupsForGUIForPlayer(pplayer.getPlayer());
for (Entry<ParticleGroup, Material> groupEntry : groups) {
ParticleGroup group = groupEntry.getKey();
Material iconMaterial = groupEntry.getValue();
List<ParticlePair> 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();
}
}

View file

@ -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<ParticleGroup> groups = pplayer.getParticleGroups();
groups.sort(Comparator.comparing(ParticleGroup::getName));
for (ParticleGroup group : groups) {
if (group.getName().equals(ParticleGroup.DEFAULT_NAME)) continue;
List<ParticlePair> 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();
}
}

View file

@ -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();
}

View file

@ -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<T> {
public void execute(T obj);
}

View file

@ -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) {

View file

@ -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<String> getStringList() {
return (List<String>) 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<String, Material> materials;
private GUIIcon() {
this.materials = new HashMap<String, Material>();
}
/**
* 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<String> 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() {

View file

@ -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<String, ParticleEffect> NAME_MAP = new HashMap<String, ParticleEffect>();
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<Player> getPlayersInRange(Location center, boolean isFixedEffect) {

View file

@ -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<ParticleGroup, Material>();
@ -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<Entry<ParticleGroup, Material>> getPresetGroupsForGUIForPlayer(Player player) {
Set<Entry<ParticleGroup, Material>> groups = new HashSet<Entry<ParticleGroup, Material>>();
for (Entry<ParticleGroup, Material> 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<Entry<ParticleGroup, Material>> getPresetGroupsForGUIForPlayer(Player player) {
List<Entry<ParticleGroup, Material>> groups = new ArrayList<Entry<ParticleGroup, Material>>();
List<ParticleGroup> orderedGroups = new ArrayList<ParticleGroup>();
orderedGroups.addAll(presetGroups.keySet());
orderedGroups.sort(Comparator.comparing(ParticleGroup::getName));
for (ParticleGroup group : orderedGroups)
if (group.canPlayerUse(player))
groups.add(new AbstractMap.SimpleEntry<ParticleGroup, Material>(group, presetGroups.get(group)));
return groups;
}

View file

@ -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
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!

View file

@ -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 <groupName>'