diff --git a/pom.xml b/pom.xml index 620fc28..fef8e09 100644 --- a/pom.xml +++ b/pom.xml @@ -199,7 +199,7 @@ org.spigotmc spigot-api - 1.13.1-R0.1-SNAPSHOT + 1.13.2-R0.1-SNAPSHOT - \ No newline at end of file + diff --git a/src/com/esophose/playerparticles/PlayerParticles.java b/src/com/esophose/playerparticles/PlayerParticles.java index c2c057b..1fea150 100644 --- a/src/com/esophose/playerparticles/PlayerParticles.java +++ b/src/com/esophose/playerparticles/PlayerParticles.java @@ -1,7 +1,6 @@ /* * TODO: v5.3 * + Add new style 'tornado' - * + Add new style 'companion' * * Setting in config.yml for max number of particle groups, default 10 * * Permission to allow players to overrule the max particle groups allowed in the config playerparticles.groups.unlimited * * Setting in config.yml to disable non-event styles while the player is moving @@ -35,12 +34,14 @@ import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; import com.esophose.playerparticles.command.ParticleCommandHandler; import com.esophose.playerparticles.database.DatabaseConnector; import com.esophose.playerparticles.database.MySqlDatabaseConnector; import com.esophose.playerparticles.database.SqliteDatabaseConnector; import com.esophose.playerparticles.gui.PlayerParticlesGui; +import com.esophose.playerparticles.manager.DataManager; import com.esophose.playerparticles.manager.LangManager; import com.esophose.playerparticles.manager.ParticleManager; import com.esophose.playerparticles.styles.DefaultStyles; @@ -61,6 +62,11 @@ public class PlayerParticles extends JavaPlugin { * The database connection manager */ private static DatabaseConnector databaseConnector = null; + + /** + * The task that spawns the particles + */ + private static BukkitTask particleTask = null; /** * Registers all the styles available by default @@ -94,13 +100,6 @@ public class PlayerParticles extends JavaPlugin { getLogger().warning("The config.yml has been updated to v" + getDescription().getVersion() + "!"); } - DefaultStyles.registerStyles(); - LangManager.setup(); - - configureDatabase(getConfig().getBoolean("database-enable")); - ParticleManager.refreshData(); - startParticleTask(); - if (shouldCheckUpdates()) { new BukkitRunnable() { public void run() { @@ -116,6 +115,8 @@ public class PlayerParticles extends JavaPlugin { } }.runTaskAsynchronously(this); } + + this.reload(); } /** @@ -126,6 +127,34 @@ public class PlayerParticles extends JavaPlugin { databaseConnector.closeConnection(); PlayerParticlesGui.forceCloseAllOpenGUIs(); } + + /** + * Reloads the settings of the plugin + */ + public void reload() { + this.reloadConfig(); + + // If not null, plugin is already loaded + if (particleTask != null) { + particleTask.cancel(); + particleTask = null; + databaseConnector.closeConnection(); + databaseConnector = null; + PlayerParticlesGui.forceCloseAllOpenGUIs(); + } else { + DefaultStyles.registerStyles(); // Only ever load styles once + } + + configureDatabase(getConfig().getBoolean("database-enable")); + + DataManager.reload(); + LangManager.reload(); + + PlayerParticlesGui.setup(); + + ParticleManager.refreshData(); + startParticleTask(); + } /** * Gets the instance of the plugin running on the server @@ -201,26 +230,16 @@ public class PlayerParticles extends JavaPlugin { } } - // Check if pp_group exists, if it doesn't, we need to create all the tables - try (Statement statement = connection.createStatement()) { - String pp_groupQuery; - if (useMySql) { - pp_groupQuery = "SHOW TABLES LIKE 'pp_group'"; - } else { - pp_groupQuery = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'pp_group'"; + // Try to create the tables just in case they don't exist + try (Statement createStatement = connection.createStatement()) { + createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_group (uuid VARCHAR(36), owner_uuid VARCHAR(36), name VARCHAR(100), PRIMARY KEY(uuid))"); + createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_fixed (owner_uuid VARCHAR(36), id SMALLINT, particle_uuid VARCHAR(36), world VARCHAR(100), xPos DOUBLE, yPos DOUBLE, zPos DOUBLE, PRIMARY KEY(owner_uuid, id), FOREIGN KEY(particle_uuid) REFERENCES pp_particle(uuid))"); + createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_particle (uuid VARCHAR(36), group_uuid VARCHAR(36), id SMALLINT, effect VARCHAR(100), style VARCHAR(100), item_material VARCHAR(100), block_material VARCHAR(100), note SMALLINT, r SMALLINT, g SMALLINT, b SMALLINT, PRIMARY KEY(uuid))"); + int[] results = createStatement.executeBatch(); + if (results[0] + results[1] + results[2] > 0) { + getLogger().warning("Updated " + (useMySql ? "MySQL" : "SQLite") + " database schema."); } - ResultSet result = statement.executeQuery(pp_groupQuery); - if (!result.next()) { - statement.close(); - - Statement createStatement = connection.createStatement(); - createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_group (uuid VARCHAR(36), owner_uuid VARCHAR(36), name VARCHAR(100))"); - createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_fixed (owner_uuid VARCHAR(36), id SMALLINT, particle_uuid VARCHAR(36), world VARCHAR(100), xPos DOUBLE, yPos DOUBLE, zPos DOUBLE)"); - createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_particle (uuid VARCHAR(36), group_uuid VARCHAR(36), id SMALLINT, effect VARCHAR(100), style VARCHAR(100), item_material VARCHAR(100), block_material VARCHAR(100), note SMALLINT, r SMALLINT, g SMALLINT, b SMALLINT)"); - createStatement.executeBatch(); - getLogger().warning("Created new " + (useMySql ? "MySQL" : "SQLite") + " database schema."); - } - } + } } catch (SQLException ex) { ex.printStackTrace(); if (useMySql) { @@ -241,10 +260,8 @@ public class PlayerParticles extends JavaPlugin { final Plugin playerParticles = this; new BukkitRunnable() { public void run() { - PlayerParticlesGui.setup(); - long ticks = getConfig().getLong("ticks-per-particle"); - new ParticleManager().runTaskTimer(playerParticles, 0, ticks); + particleTask = new ParticleManager().runTaskTimer(playerParticles, 0, ticks); } }.runTaskLater(playerParticles, 1); } diff --git a/src/com/esophose/playerparticles/command/FixedCommandModule.java b/src/com/esophose/playerparticles/command/FixedCommandModule.java index a5506e3..68ea126 100644 --- a/src/com/esophose/playerparticles/command/FixedCommandModule.java +++ b/src/com/esophose/playerparticles/command/FixedCommandModule.java @@ -5,10 +5,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.util.StringUtil; @@ -93,36 +95,61 @@ public class FixedCommandModule implements CommandModule { return; } - if (args.length < 5) { + if (args.length < 5 && !(args.length > 0 && args[0].equalsIgnoreCase("looking") && args.length >= 3)) { LangManager.sendMessage(p, Lang.FIXED_CREATE_MISSING_ARGS, 5 - args.length); return; } double xPos = -1, yPos = -1, zPos = -1; - try { - if (args[0].startsWith("~")) { - if (args[0].equals("~")) xPos = p.getLocation().getX(); - else xPos = p.getLocation().getX() + Double.parseDouble(args[0].substring(1)); - } else { - xPos = Double.parseDouble(args[0]); + + if (args[0].equalsIgnoreCase("looking")) { + Block targetBlock = p.getTargetBlock((Set)null, 8); + int maxDistanceSqrd = 6 * 6; + if (targetBlock.getLocation().distanceSquared(p.getLocation()) > maxDistanceSqrd) { + LangManager.sendMessage(p, Lang.FIXED_CREATE_OUT_OF_RANGE); + return; } + + Location blockLocation = targetBlock.getLocation().clone().add(0.5, 0.5, 0.5); // Center of block + + xPos = blockLocation.getX(); + yPos = blockLocation.getY(); + zPos = blockLocation.getZ(); + + // Pad the args with the coordinates so we don't have to adjust all the indices + String[] paddedArgs = new String[args.length + 2]; + paddedArgs[0] = String.valueOf(xPos); + paddedArgs[1] = String.valueOf(yPos); + paddedArgs[2] = String.valueOf(zPos); + for (int i = 1; i < args.length; i++) + paddedArgs[i + 2] = args[i]; + args = paddedArgs; + } else { + try { + if (args[0].startsWith("~")) { + if (args[0].equals("~")) xPos = p.getLocation().getX(); + else xPos = p.getLocation().getX() + Double.parseDouble(args[0].substring(1)); + } else { + xPos = Double.parseDouble(args[0]); + } - if (args[1].startsWith("~")) { - if (args[1].equals("~")) yPos = p.getLocation().getY() + 1; - else yPos = p.getLocation().getY() + 1 + Double.parseDouble(args[1].substring(1)); - } else { - yPos = Double.parseDouble(args[1]); - } + if (args[1].startsWith("~")) { + if (args[1].equals("~")) yPos = p.getLocation().getY() + 1; + else yPos = p.getLocation().getY() + 1 + Double.parseDouble(args[1].substring(1)); + } else { + yPos = Double.parseDouble(args[1]); + } - if (args[2].startsWith("~")) { - if (args[2].equals("~")) zPos = p.getLocation().getZ(); - else zPos = p.getLocation().getZ() + Double.parseDouble(args[2].substring(1)); - } else { - zPos = Double.parseDouble(args[2]); + if (args[2].startsWith("~")) { + if (args[2].equals("~")) zPos = p.getLocation().getZ(); + else zPos = p.getLocation().getZ() + Double.parseDouble(args[2].substring(1)); + } else { + zPos = Double.parseDouble(args[2]); + } + } catch (Exception e) { + LangManager.sendMessage(p, Lang.FIXED_CREATE_INVALID_COORDS); + return; } - } catch (Exception e) { - LangManager.sendMessage(p, Lang.FIXED_CREATE_INVALID_COORDS); - return; } double distanceFromEffect = p.getLocation().distance(new Location(p.getWorld(), xPos, yPos, zPos)); @@ -403,9 +430,21 @@ public class FixedCommandModule implements CommandModule { } if (args.length == 2) { possibleValues.add("~ ~ ~"); + possibleValues.add("looking"); } StringUtil.copyPartialMatches(args[args.length - 1], possibleValues, matches); - } else if (args.length == 5) { + } + + // Pad arguments if the first coordinate is "looking" + if (args.length > 1 && args[1].equalsIgnoreCase("looking")) { + String[] paddedArgs = new String[args.length + 2]; + paddedArgs[0] = paddedArgs[1] = paddedArgs[2] = paddedArgs[3] = ""; + for (int i = 2; i < args.length; i++) + paddedArgs[i + 2] = args[i]; + args = paddedArgs; + } + + if (args.length == 5) { StringUtil.copyPartialMatches(args[4], PermissionManager.getEffectsUserHasPermissionFor(p), matches); } else if (args.length == 6) { StringUtil.copyPartialMatches(args[5], PermissionManager.getStylesUserHasPermissionFor(p), matches); diff --git a/src/com/esophose/playerparticles/command/ParticleCommandHandler.java b/src/com/esophose/playerparticles/command/ParticleCommandHandler.java index 37c26c0..5047e14 100644 --- a/src/com/esophose/playerparticles/command/ParticleCommandHandler.java +++ b/src/com/esophose/playerparticles/command/ParticleCommandHandler.java @@ -36,6 +36,7 @@ public class ParticleCommandHandler implements CommandExecutor, TabCompleter { commands.add(new GUICommandModule()); commands.add(new HelpCommandModule()); commands.add(new ListCommandModule()); + commands.add(new ReloadCommandModule()); commands.add(new RemoveCommandModule()); commands.add(new ResetCommandModule()); commands.add(new StyleCommandModule()); diff --git a/src/com/esophose/playerparticles/command/ReloadCommandModule.java b/src/com/esophose/playerparticles/command/ReloadCommandModule.java new file mode 100644 index 0000000..ce69c50 --- /dev/null +++ b/src/com/esophose/playerparticles/command/ReloadCommandModule.java @@ -0,0 +1,42 @@ +package com.esophose.playerparticles.command; + +import java.util.ArrayList; +import java.util.List; + +import com.esophose.playerparticles.PlayerParticles; +import com.esophose.playerparticles.manager.LangManager; +import com.esophose.playerparticles.manager.LangManager.Lang; +import com.esophose.playerparticles.particles.PPlayer; + +public class ReloadCommandModule implements CommandModule { + + public void onCommandExecute(PPlayer pplayer, String[] args) { + if (pplayer.getPlayer().hasPermission("playerparticles.reload")) { + ((PlayerParticles)PlayerParticles.getPlugin()).reload(); + LangManager.sendMessage(pplayer, Lang.RELOAD_SUCCESS); + } else { + LangManager.sendMessage(pplayer, Lang.RELOAD_NO_PERMISSION); + } + } + + public List onTabComplete(PPlayer pplayer, String[] args) { + return new ArrayList(); + } + + public String getName() { + return "reload"; + } + + public Lang getDescription() { + return Lang.COMMAND_DESCRIPTION_RELOAD; + } + + public String getArguments() { + return ""; + } + + public boolean requiresEffects() { + return false; + } + +} diff --git a/src/com/esophose/playerparticles/manager/DataManager.java b/src/com/esophose/playerparticles/manager/DataManager.java index 4709abf..bca9b3d 100644 --- a/src/com/esophose/playerparticles/manager/DataManager.java +++ b/src/com/esophose/playerparticles/manager/DataManager.java @@ -6,7 +6,6 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.scheduler.BukkitRunnable; @@ -452,6 +451,15 @@ public class DataManager { } return disabledWorlds; } + + /** + * Resets all config-related settings + */ + public static void reload() { + maxFixedEffects = -1; + maxFixedEffectCreationDistance = -1; + disabledWorlds = null; + } /** * Asynchronizes the callback with it's own thread diff --git a/src/com/esophose/playerparticles/manager/LangManager.java b/src/com/esophose/playerparticles/manager/LangManager.java index ca4e5b8..dfe2e0e 100644 --- a/src/com/esophose/playerparticles/manager/LangManager.java +++ b/src/com/esophose/playerparticles/manager/LangManager.java @@ -39,6 +39,7 @@ public class LangManager { COMMAND_DESCRIPTION_HELP, COMMAND_DESCRIPTION_INFO, COMMAND_DESCRIPTION_LIST, + COMMAND_DESCRIPTION_RELOAD, COMMAND_DESCRIPTION_REMOVE, COMMAND_DESCRIPTION_RESET, COMMAND_DESCRIPTION_STYLE, @@ -89,6 +90,10 @@ public class LangManager { GROUP_LIST_OUTPUT, GROUP_LIST_PRESETS, + // Reload Command + RELOAD_SUCCESS, + RELOAD_NO_PERMISSION, + // Remove Command REMOVE_NO_ARGS, REMOVE_SUCCESS, @@ -138,6 +143,7 @@ public class LangManager { FIXED_CREATE_MISSING_ARGS, FIXED_CREATE_INVALID_COORDS, FIXED_CREATE_OUT_OF_RANGE, + FIXED_CREATE_LOOKING_TOO_FAR, FIXED_CREATE_EFFECT_INVALID, FIXED_CREATE_EFFECT_NO_PERMISSION, FIXED_CREATE_STYLE_INVALID, @@ -224,7 +230,7 @@ public class LangManager { * This should only get called once by the PlayerParticles class, however * calling it multiple times wont affect anything negatively */ - public static void setup() { + public static void reload() { FileConfiguration config = PlayerParticles.getPlugin().getConfig(); messagesEnabled = config.getBoolean("messages-enabled"); prefixEnabled = config.getBoolean("use-message-prefix"); diff --git a/src/com/esophose/playerparticles/manager/ParticleManager.java b/src/com/esophose/playerparticles/manager/ParticleManager.java index ef257cc..4afbdba 100644 --- a/src/com/esophose/playerparticles/manager/ParticleManager.java +++ b/src/com/esophose/playerparticles/manager/ParticleManager.java @@ -20,7 +20,6 @@ import com.esophose.playerparticles.particles.PPlayer; import com.esophose.playerparticles.particles.ParticleEffect; import com.esophose.playerparticles.particles.ParticleEffect.NoteColor; import com.esophose.playerparticles.particles.ParticleEffect.OrdinaryColor; -import com.esophose.playerparticles.particles.ParticleEffect.ParticleProperty; import com.esophose.playerparticles.particles.ParticlePair; import com.esophose.playerparticles.styles.api.PParticle; import com.esophose.playerparticles.styles.api.ParticleStyleManager; @@ -103,16 +102,15 @@ public class ParticleManager extends BukkitRunnable implements Listener { // Don't show their particles if they are in spectator mode // Don't spawn particles if the world doesn't allow it - if (player != null && player.getGameMode() != GameMode.SPECTATOR && !DataManager.isWorldDisabled(player.getWorld().getName())) { - for (ParticlePair particles : pplayer.getActiveParticles()) { + if (player != null && player.getGameMode() != GameMode.SPECTATOR && !DataManager.isWorldDisabled(player.getWorld().getName())) + for (ParticlePair particles : pplayer.getActiveParticles()) displayParticles(particles, player.getLocation().clone().add(0, 1, 0)); - } - } // Loop for FixedParticleEffects // Don't spawn particles if the world doesn't allow it for (FixedParticleEffect effect : pplayer.getFixedParticles()) - if (!DataManager.isWorldDisabled(effect.getLocation().getWorld().getName())) displayFixedParticleEffect(effect); + if (!DataManager.isWorldDisabled(effect.getLocation().getWorld().getName())) + displayFixedParticleEffect(effect); } } @@ -123,18 +121,9 @@ public class ParticleManager extends BukkitRunnable implements Listener { * @param location The location to display at */ private void displayParticles(ParticlePair particle, Location location) { - if (!ParticleStyleManager.isCustomHandled(particle.getStyle())) { - ParticleEffect effect = particle.getEffect(); - for (PParticle pparticle : particle.getStyle().getParticles(particle, location)) { - if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { - effect.display(particle.getSpawnMaterial(), pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); - } else if (effect.hasProperty(ParticleProperty.COLORABLE)) { - effect.display(particle.getSpawnColor(), pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); - } else { - effect.display(pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); - } - } - } + if (!ParticleStyleManager.isCustomHandled(particle.getStyle())) + for (PParticle pparticle : particle.getStyle().getParticles(particle, location)) + ParticleEffect.display(particle, pparticle); } /** @@ -144,16 +133,8 @@ public class ParticleManager extends BukkitRunnable implements Listener { * @param particles The particles to display */ public static void displayParticles(ParticlePair particle, List particles) { - ParticleEffect effect = particle.getEffect(); - for (PParticle pparticle : particles) { - if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { - effect.display(particle.getSpawnMaterial(), pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); - } else if (effect.hasProperty(ParticleProperty.COLORABLE)) { - effect.display(particle.getSpawnColor(), pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); - } else { - effect.display(pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); - } - } + for (PParticle pparticle : particles) + ParticleEffect.display(particle, pparticle); } /** @@ -163,16 +144,8 @@ public class ParticleManager extends BukkitRunnable implements Listener { */ private void displayFixedParticleEffect(FixedParticleEffect fixedEffect) { ParticlePair particle = fixedEffect.getParticlePair(); - ParticleEffect effect = particle.getEffect(); - for (PParticle pparticle : particle.getStyle().getParticles(particle, fixedEffect.getLocation())) { - if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { - effect.display(particle.getSpawnMaterial(), pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); - } else if (effect.hasProperty(ParticleProperty.COLORABLE)) { - effect.display(particle.getSpawnColor(), pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); - } else { - effect.display(pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); - } - } + for (PParticle pparticle : particle.getStyle().getParticles(particle, fixedEffect.getLocation())) + ParticleEffect.display(particle, pparticle); } public static OrdinaryColor getRainbowParticleColor() { diff --git a/src/com/esophose/playerparticles/particles/ParticleEffect.java b/src/com/esophose/playerparticles/particles/ParticleEffect.java index 9bd21c4..1055a34 100644 --- a/src/com/esophose/playerparticles/particles/ParticleEffect.java +++ b/src/com/esophose/playerparticles/particles/ParticleEffect.java @@ -18,6 +18,8 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.material.MaterialData; +import com.esophose.playerparticles.styles.api.PParticle; + @SuppressWarnings("deprecation") public enum ParticleEffect { @@ -186,6 +188,25 @@ public enum ParticleEffect { } return null; } + + /** + * Invokes the correct spawn method for the particle information given + * + * @param particle The ParticlePair, given the effect/style/data + * @param pparticle The particle spawn information + */ + public static void display(ParticlePair particle, PParticle pparticle) { + ParticleEffect effect = particle.getEffect(); + int count = pparticle.isDirectional() ? 0 : 1; + + if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { + effect.display(particle.getSpawnMaterial(), pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); + } else if (effect.hasProperty(ParticleProperty.COLORABLE)) { + effect.display(particle.getSpawnColor(), pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); + } else { + effect.display(pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), count, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE))); + } + } /** * Displays a particle effect diff --git a/src/com/esophose/playerparticles/styles/DefaultStyles.java b/src/com/esophose/playerparticles/styles/DefaultStyles.java index aa1f3f6..3cc6d60 100644 --- a/src/com/esophose/playerparticles/styles/DefaultStyles.java +++ b/src/com/esophose/playerparticles/styles/DefaultStyles.java @@ -20,13 +20,17 @@ public class DefaultStyles { public static final ParticleStyle BLOCKBREAK = new ParticleStyleBlockBreak(); public static final ParticleStyle BLOCKEDIT = new ParticleStyleBlockEdit(); public static final ParticleStyle BLOCKPLACE = new ParticleStyleBlockPlace(); + public static final ParticleStyle CHAINS = new ParticleStyleChains(); + public static final ParticleStyle COMPANION = new ParticleStyleCompanion(); public static final ParticleStyle CUBE = new ParticleStyleCube(); public static final ParticleStyle FEET = new ParticleStyleFeet(); public static final ParticleStyle HALO = new ParticleStyleHalo(); public static final ParticleStyle HURT = new ParticleStyleHurt(); + public static final ParticleStyle INVOCATION = new ParticleStyleInvocation(); public static final ParticleStyle MOVE = new ParticleStyleMove(); public static final ParticleStyle NORMAL = new ParticleStyleNormal(); public static final ParticleStyle ORBIT = new ParticleStyleOrbit(); + public static final ParticleStyle OVERHEAD = new ParticleStyleOverhead(); public static final ParticleStyle POINT = new ParticleStylePoint(); public static final ParticleStyle QUADHELIX = new ParticleStyleQuadhelix(); public static final ParticleStyle RINGS = new ParticleStyleRings(); @@ -35,6 +39,7 @@ public class DefaultStyles { public static final ParticleStyle SPIRAL = new ParticleStyleSpiral(); public static final ParticleStyle SWORDS = new ParticleStyleSwords(); public static final ParticleStyle THICK = new ParticleStyleThick(); + public static final ParticleStyle VORTEX = new ParticleStyleVortex(); public static final ParticleStyle WINGS = new ParticleStyleWings(); /** @@ -48,13 +53,17 @@ public class DefaultStyles { ParticleStyleManager.registerCustomHandledStyle(BLOCKBREAK); ParticleStyleManager.registerCustomHandledStyle(BLOCKEDIT); ParticleStyleManager.registerCustomHandledStyle(BLOCKPLACE); + ParticleStyleManager.registerStyle(CHAINS); + ParticleStyleManager.registerStyle(COMPANION); ParticleStyleManager.registerStyle(CUBE); ParticleStyleManager.registerStyle(FEET); ParticleStyleManager.registerStyle(HALO); ParticleStyleManager.registerCustomHandledStyle(HURT); + ParticleStyleManager.registerStyle(INVOCATION); ParticleStyleManager.registerCustomHandledStyle(MOVE); ParticleStyleManager.registerStyle(NORMAL); ParticleStyleManager.registerStyle(ORBIT); + ParticleStyleManager.registerStyle(OVERHEAD); ParticleStyleManager.registerStyle(POINT); ParticleStyleManager.registerStyle(QUADHELIX); ParticleStyleManager.registerStyle(RINGS); @@ -63,8 +72,10 @@ public class DefaultStyles { ParticleStyleManager.registerStyle(SPIRAL); ParticleStyleManager.registerCustomHandledStyle(SWORDS); ParticleStyleManager.registerStyle(THICK); + ParticleStyleManager.registerStyle(VORTEX); ParticleStyleManager.registerStyle(WINGS); + // Register their events PluginManager manager = Bukkit.getPluginManager(); Plugin playerParticles = PlayerParticles.getPlugin(); manager.registerEvents((Listener) ARROWS, playerParticles); diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleChains.java b/src/com/esophose/playerparticles/styles/ParticleStyleChains.java new file mode 100644 index 0000000..45181e0 --- /dev/null +++ b/src/com/esophose/playerparticles/styles/ParticleStyleChains.java @@ -0,0 +1,39 @@ +package com.esophose.playerparticles.styles; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; + +import com.esophose.playerparticles.particles.ParticlePair; +import com.esophose.playerparticles.styles.api.PParticle; +import com.esophose.playerparticles.styles.api.ParticleStyle; + +public class ParticleStyleChains implements ParticleStyle { + + public List getParticles(ParticlePair particle, Location location) { + List particles = new ArrayList(); + + for (double n = -0.2; n < 0.6; n += 0.1) { + particles.add(new PParticle(location.clone().add(1 - n, n - 1.1, 1 - n))); + particles.add(new PParticle(location.clone().add(1 - n, n - 1.1, -1 + n))); + particles.add(new PParticle(location.clone().add(-1 + n, n - 1.1, 1 - n))); + particles.add(new PParticle(location.clone().add(-1 + n, n - 1.1, -1 + n))); + } + + return particles; + } + + public void updateTimers() { + + } + + public String getName() { + return "chains"; + } + + public boolean canBeFixed() { + return true; + } + +} diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleCompanion.java b/src/com/esophose/playerparticles/styles/ParticleStyleCompanion.java new file mode 100644 index 0000000..92116af --- /dev/null +++ b/src/com/esophose/playerparticles/styles/ParticleStyleCompanion.java @@ -0,0 +1,77 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Slikey + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.esophose.playerparticles.styles; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.util.Vector; + +import com.esophose.playerparticles.particles.ParticlePair; +import com.esophose.playerparticles.styles.api.PParticle; +import com.esophose.playerparticles.styles.api.ParticleStyle; + +public class ParticleStyleCompanion implements ParticleStyle { + + private int numParticles = 150; + private int particlesPerIteration = 5; + private double size = 1.25; + private double xFactor = 1.0, yFactor = 1.5, zFactor = 1.0; + private double xOffset = 0.0, yOffset = -0.75, zOffset = 0.0; + private int step = 0; + + public List getParticles(ParticlePair particle, Location location) { + List particles = new ArrayList(); + + Vector vector = new Vector(); + + double t = (Math.PI / numParticles) * step; + double r = Math.sin(t) * size; + double s = 2 * Math.PI * t; + + vector.setX(xFactor * r * Math.cos(s) + xOffset); + vector.setZ(zFactor * r * Math.sin(s) + zOffset); + vector.setY(yFactor * size * Math.cos(t) + yOffset); + + for (int i = 0; i < particlesPerIteration; i++) { + particles.add(new PParticle(location.clone().subtract(vector))); + } + + return particles; + } + + public void updateTimers() { + step++; + } + + public String getName() { + return "companion"; + } + + public boolean canBeFixed() { + return true; + } + +} diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleCube.java b/src/com/esophose/playerparticles/styles/ParticleStyleCube.java index f6f5eea..27fda78 100644 --- a/src/com/esophose/playerparticles/styles/ParticleStyleCube.java +++ b/src/com/esophose/playerparticles/styles/ParticleStyleCube.java @@ -52,7 +52,7 @@ public class ParticleStyleCube implements ParticleStyle { public List getParticles(ParticlePair particle, Location location) { List pparticles = new ArrayList(); - if (!skipNextStep) { // TODO: relative position lookup tables + if (!skipNextStep) { double xRotation = 0, yRotation = 0, zRotation = 0; xRotation = step * angularVelocityX; yRotation = step * angularVelocityY; diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleFeet.java b/src/com/esophose/playerparticles/styles/ParticleStyleFeet.java index 936e42e..ac30ed5 100644 --- a/src/com/esophose/playerparticles/styles/ParticleStyleFeet.java +++ b/src/com/esophose/playerparticles/styles/ParticleStyleFeet.java @@ -13,7 +13,7 @@ public class ParticleStyleFeet implements ParticleStyle { public List getParticles(ParticlePair particle, Location location) { List particles = new ArrayList(); - particles.add(new PParticle(location.subtract(0, 0.95, 0), 0.4F, 0.0F, 0.4F, 0.0F)); + particles.add(new PParticle(location.clone().subtract(0, 0.95, 0), 0.4F, 0.0F, 0.4F, 0.0F)); return particles; } diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleInvocation.java b/src/com/esophose/playerparticles/styles/ParticleStyleInvocation.java new file mode 100644 index 0000000..9d83e71 --- /dev/null +++ b/src/com/esophose/playerparticles/styles/ParticleStyleInvocation.java @@ -0,0 +1,102 @@ +package com.esophose.playerparticles.styles; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; + +import com.esophose.playerparticles.particles.ParticleEffect; +import com.esophose.playerparticles.particles.ParticlePair; +import com.esophose.playerparticles.styles.api.PParticle; +import com.esophose.playerparticles.styles.api.ParticleStyle; + +public class ParticleStyleInvocation implements ParticleStyle { + + private int points = 5; + private double radius = 3.5; + private double step = 0; + private int circleStep = 0; + private int numSteps = 120; + + public List getParticles(ParticlePair particle, Location location) { + List particles = new ArrayList(); + double speed = getSpeedByEffect(particle.getEffect()); + + // Circle around everything, spawn less often + if (circleStep % 5 == 0) { + for (int i = 0; i < numSteps; i++) { + double dx = Math.cos(Math.PI * 2 * ((double)i / numSteps)) * radius; + double dy = -0.9; + double dz = Math.sin(Math.PI * 2 * ((double)i / numSteps)) * radius; + particles.add(new PParticle(location.clone().add(dx, dy, dz))); + } + } + + // Orbit going clockwise + for (int i = 0; i < points; i++) { + double dx = Math.cos(step + (Math.PI * 2 * ((double)i / points))) * radius; + double dy = -0.9; + double dz = Math.sin(step + (Math.PI * 2 * ((double)i / points))) * radius; + double angle = Math.atan2(dz, dx); + double xAng = -Math.cos(angle); + double zAng = -Math.sin(angle); + particles.add(new PParticle(location.clone().add(dx, dy, dz), xAng, 0, zAng, speed, true)); + } + + // Orbit going counter-clockwise + for (int i = 0; i > -points; i--) { + double dx = Math.cos(-step + (Math.PI * 2 * ((double)i / points))) * radius; + double dy = -0.9; + double dz = Math.sin(-step + (Math.PI * 2 * ((double)i / points))) * radius; + double angle = Math.atan2(dz, dx); + double xAng = -Math.cos(angle); + double zAng = -Math.sin(angle); + particles.add(new PParticle(location.clone().add(dx, dy, dz), xAng, 0, zAng, speed, true)); + } + + return particles; + } + + private double getSpeedByEffect(ParticleEffect effect) { + switch (effect) { + case CRIT: + case DAMAGE_INDICATOR: + case ENCHANTED_HIT: + return 2; + case DRAGON_BREATH: + return 0.01; + case ENCHANT: + case NAUTILUS: + case PORTAL: + return radius * 2; + case END_ROD: + case SMOKE: + case SQUID_INK: + return 0.3; + case FIREWORK: + case SPIT: + case SPLASH: + return 0.5; + case POOF: + return 0.4; + case TOTEM_OF_UNDYING: + return 1.25; + default: + return 0.2; // Flame + } + } + + public void updateTimers() { + step = (step + Math.PI * 2 / numSteps) % numSteps; + circleStep = (circleStep + 1) % numSteps; + } + + public String getName() { + return "invocation"; + } + + public boolean canBeFixed() { + return true; + } + +} diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleOverhead.java b/src/com/esophose/playerparticles/styles/ParticleStyleOverhead.java new file mode 100644 index 0000000..4fd41f3 --- /dev/null +++ b/src/com/esophose/playerparticles/styles/ParticleStyleOverhead.java @@ -0,0 +1,33 @@ +package com.esophose.playerparticles.styles; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; + +import com.esophose.playerparticles.particles.ParticlePair; +import com.esophose.playerparticles.styles.api.PParticle; +import com.esophose.playerparticles.styles.api.ParticleStyle; + +public class ParticleStyleOverhead implements ParticleStyle { + + public List getParticles(ParticlePair particle, Location location) { + List particles = new ArrayList(); + particles.add(new PParticle(location.clone().add(0, 1.75, 0), 0.4F, 0.1F, 0.4F, 0.0F)); + particles.add(new PParticle(location.clone().add(0, 1.75, 0), 0.4F, 0.1F, 0.4F, 0.0F)); + return particles; + } + + public void updateTimers() { + + } + + public String getName() { + return "overhead"; + } + + public boolean canBeFixed() { + return true; + } + +} diff --git a/src/com/esophose/playerparticles/styles/ParticleStylePoint.java b/src/com/esophose/playerparticles/styles/ParticleStylePoint.java index 3043048..e275a7e 100644 --- a/src/com/esophose/playerparticles/styles/ParticleStylePoint.java +++ b/src/com/esophose/playerparticles/styles/ParticleStylePoint.java @@ -12,7 +12,7 @@ import com.esophose.playerparticles.styles.api.ParticleStyle; public class ParticleStylePoint implements ParticleStyle { public List getParticles(ParticlePair particle, Location location) { - return Collections.singletonList(new PParticle(location.add(0.0, 1.5, 0.0))); + return Collections.singletonList(new PParticle(location.clone().add(0.0, 1.5, 0.0))); } public void updateTimers() { diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleSphere.java b/src/com/esophose/playerparticles/styles/ParticleStyleSphere.java index a4c39dc..b58e4a7 100644 --- a/src/com/esophose/playerparticles/styles/ParticleStyleSphere.java +++ b/src/com/esophose/playerparticles/styles/ParticleStyleSphere.java @@ -21,10 +21,10 @@ public class ParticleStyleSphere implements ParticleStyle { double v = Math.random(); double theta = 2 * Math.PI * u; double phi = Math.acos(2 * v - 1); - double x = location.getX() + (radius * Math.sin(phi) * Math.cos(theta)); - double y = location.getY() + (radius * Math.sin(phi) * Math.sin(theta)); - double z = location.getZ() + (radius * Math.cos(phi)); - particles.add(new PParticle(new Location(location.getWorld(), x, y, z))); + double dx = radius * Math.sin(phi) * Math.cos(theta); + double dy = radius * Math.sin(phi) * Math.sin(theta); + double dz = radius * Math.cos(phi); + particles.add(new PParticle(location.clone().add(dx, dy, dz))); } return particles; diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleVortex.java b/src/com/esophose/playerparticles/styles/ParticleStyleVortex.java new file mode 100644 index 0000000..61b3b19 --- /dev/null +++ b/src/com/esophose/playerparticles/styles/ParticleStyleVortex.java @@ -0,0 +1,70 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2014 Slikey + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.esophose.playerparticles.styles; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.util.Vector; + +import com.esophose.playerparticles.particles.ParticlePair; +import com.esophose.playerparticles.styles.api.PParticle; +import com.esophose.playerparticles.styles.api.ParticleStyle; + +public class ParticleStyleVortex implements ParticleStyle { + + private double grow = .05f; + private double radials = Math.PI / 16; + private int helices = 4; + private int step = 0; + private int maxStep = 70; + + public List getParticles(ParticlePair particle, Location location) { + List particles = new ArrayList(); + + double radius = 2 * (1 - (double)step / maxStep); + for (int i = 0; i < helices; i++) { + double angle = step * radials + (2 * Math.PI * i / helices); + Vector v = new Vector(Math.cos(angle) * radius, step * grow - 1, Math.sin(angle) * radius); + + particles.add(new PParticle(location.clone().add(v))); + } + + return particles; + } + + public void updateTimers() { + step = (step + 1) % maxStep; + } + + public String getName() { + return "vortex"; + } + + public boolean canBeFixed() { + return true; + } + +} diff --git a/src/com/esophose/playerparticles/styles/api/PParticle.java b/src/com/esophose/playerparticles/styles/api/PParticle.java index efcbb37..9404de0 100644 --- a/src/com/esophose/playerparticles/styles/api/PParticle.java +++ b/src/com/esophose/playerparticles/styles/api/PParticle.java @@ -10,7 +10,27 @@ public class PParticle { private Location location; private double speed; private double xOff, yOff, zOff; + private boolean directional; + /** + * The constructor with all the fancy parameters for customization + * + * @param location The location to display the particle at + * @param xOff The offset for the x-axis + * @param yOff The offset for the y-axis + * @param zOff The offset for the z-axis + * @param speed The speed the particle will move at + * @param directional If the particle should use the x, y, and z offsets as directions instead + */ + public PParticle(Location location, double xOff, double yOff, double zOff, double speed, boolean directional) { + this.location = location; + this.xOff = xOff; + this.yOff = yOff; + this.zOff = zOff; + this.speed = speed; + this.directional = directional; + } + /** * The constructor with all the fancy parameters for customization * @@ -21,11 +41,7 @@ public class PParticle { * @param speed The speed the particle will move at */ public PParticle(Location location, double xOff, double yOff, double zOff, double speed) { - this.location = location; - this.xOff = xOff; - this.yOff = yOff; - this.zOff = zOff; - this.speed = speed; + this(location, xOff, yOff, zOff, speed, false); } /** @@ -35,7 +51,7 @@ public class PParticle { * @param location The location to display the particles at */ public PParticle(Location location) { - this(location, 0.0F, 0.0F, 0.0F, 0.0F); + this(location, 0.0F, 0.0F, 0.0F, 0.0F, false); } /** @@ -70,6 +86,15 @@ public class PParticle { public double getSpeed() { return this.speed; } + + /** + * Gets if the particle is directional + * + * @return If the particle is directional + */ + public boolean isDirectional() { + return this.directional; + } /** * Gets the offset on the x-axis for the particle diff --git a/src/com/esophose/playerparticles/styles/api/ParticleStyleManager.java b/src/com/esophose/playerparticles/styles/api/ParticleStyleManager.java index 52b7cbe..6bbb91a 100644 --- a/src/com/esophose/playerparticles/styles/api/ParticleStyleManager.java +++ b/src/com/esophose/playerparticles/styles/api/ParticleStyleManager.java @@ -19,13 +19,26 @@ public class ParticleStyleManager { * @param style The style to add */ public static void registerStyle(ParticleStyle style) { + if (style == null) { + PlayerParticles.getPlugin().getLogger().severe("Tried to register a null style"); + return; + } + + if (style.getName() == null || style.getName().trim().equals("")) { + PlayerParticles.getPlugin().getLogger().severe("Tried to register a style with a null or empty name: '" + style.getName() + "'"); + return; + } + for (ParticleStyle testAgainst : styles) { if (testAgainst.getName().equalsIgnoreCase(style.getName())) { - PlayerParticles.getPlugin().getLogger().severe("Tried to register two styles with the same name spelling: " + style.getName()); + PlayerParticles.getPlugin().getLogger().severe("Tried to register two styles with the same name spelling: '" + style.getName() + "'"); + return; } else if (testAgainst.equals(style)) { - PlayerParticles.getPlugin().getLogger().severe("Tried to register the same style twice: " + style.getName()); + PlayerParticles.getPlugin().getLogger().severe("Tried to register the same style twice: '" + style.getName() + "'"); + return; } } + styles.add(style); } @@ -57,6 +70,16 @@ public class ParticleStyleManager { public static List getStyles() { return styles; } + + /** + * Removes all styles from the registry + * + * It is not recommended to call this + */ + public static void reset() { + styles.clear(); + customHandledStyles.clear(); + } /** * Updates all the timers for the particle styles to make the animations diff --git a/src/config.yml b/src/config.yml index 3552d92..006c1de 100644 --- a/src/config.yml +++ b/src/config.yml @@ -224,13 +224,17 @@ gui-icon: 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 @@ -240,6 +244,7 @@ gui-icon: SPIRAL: HOPPER SWORDS: IRON_SWORD THICK: COBWEB + VORTEX: GLOWSTONE_DUST WINGS: ELYTRA style-legacy: # 1.9 to 1.12 ARROWS: BOW @@ -248,13 +253,17 @@ gui-icon: 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 @@ -263,6 +272,7 @@ gui-icon: SPIRAL: HOPPER SWORDS: IRON_SWORD THICK: VINE + VORTEX: GLOWSTONE_DUST WINGS: ELYTRA # That's everything! You reached the end of the configuration. diff --git a/src/groups.yml b/src/groups.yml new file mode 100644 index 0000000..e636724 --- /dev/null +++ b/src/groups.yml @@ -0,0 +1,28 @@ +# ==================================================== # +# PRESET GROUPS # +# Information: # +# * The groups listed within this file will be # +# available to all players who have access to the # +# effect and style! # +# * Feel free to create your own, they will be # +# available for users to select within the GUI! # +# ==================================================== # + +raincloud: + 1: + effect: 'cloud' + style: 'overhead' + data: '' + 2: + effect: 'rain' + style: 'overhead' + data: '' +rainbows: + 1: + effect: 'dust' + style: 'orbit' + data: 'rainbow' + 2: + effect: 'entity_effect' + style: 'feet' + data: 'rainbow' diff --git a/src/lang/default.lang b/src/lang/default.lang index 4ce2714..842e22c 100644 --- a/src/lang/default.lang +++ b/src/lang/default.lang @@ -25,6 +25,7 @@ command-description-gui: 'Display the GUI for easy editing of particles' command-description-help: 'Displays the help menu... You have arrived' command-description-info: 'Gets the description of one of your active particles' command-description-list: 'Lists the IDs of your active particles' +command-description-reload: 'Reloads the config.yml and lang file' command-description-remove: 'Removes one of your active particles' command-description-reset: 'Removes all your active particles' command-description-style: '&cThis command has been removed, use &b/pp help &cto find new commands' @@ -33,7 +34,7 @@ command-description-version: 'Display the current version of the plugin and the command-description-worlds: 'Find out what worlds particles are disabled in' # Sub-Command Usage -command-description-fixed-create: '&e/pp fixed create