diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..acd63e1 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,106 @@ +== UPDATING WILL DELETE YOUR CONFIG.YML == +* Create a backup of your config.yml if you wish to import all your old settings! +=== v4.2 === +* Rainbow particles are back! /pp data rainbow (for colorable particles) +* Added new style 'arrows' +* Renamed style 'spiral' to 'beam' +* Added new style 'spiral' +* Spawning particles is now more efficient +* You can now view the spawned particles from 2x as far away +* Checking disabled worlds is now taken from cache +=== v4.1 === +Added support for the 1.11 particles 'totem' and 'spit' +Added new style 'cube' - it should be self explanatory +Added full plugin message configuration +Fixed odd coloring of some messages +Fixed missing message entry in config, nobody probably noticed +Maintains support for 1.11, 1.10, 1.9, 1.8, and 1.7 - that's a lot! +=== v4 === +Changes some permissions, make sure to update those +Changed some commands, make sure you check up on those +Added four new particles, fallingdust, blockcrack, iconcrack, blockdust +Added new command /pp data - Allows you to modify effect data +Colorable particles can now be colored! +Particles no longer show up in spectator mode +Added Styles API, a way for developers to add more styles to the plugin +v4.1 will come out relatively soon with any found bugs fixes and the remainder of the features +=== v3.9 === +Added 1.10+ support (Still support with 1.7, 1.8, and 1.9) +Fixed a bug preventing the message-no-styles from not displaying +Removed leading comma from /pp styles +Reorganized command executors in code +Reorganized how customized messages work in code +Did not add the new particle 'fallingdust' (Will be in PlayerParticles v4 update) +Changed GitHub Repository name from 'PlayerParticles-3' to 'PlayerParticles' (https://github.com/Esophose/PlayerParticles) +This version was not tested on any other version than 1.10. If you have problems on >1.10 versions post a comment. +=== v3.8 === +Added new style 'orb' (Same as 'quadhelix' except it doesn't go up and down) +Fixed a bug with the 'move' style relating to permissions +Added some stuff to the plugin.yml, will affect nothing +Cleaned up some code +=== v3.7 === +Added new update checking system (Can be disabled by setting check-updates to false in config.yml) +Update system will notify OPs when they join the server, and will be shown in the console when the plugin loads +Added new style "quadhelix" - Try it out! +Removed /pp reload (This never worked properly, restart or reload your server instead) +Changed default config value for disabled-worlds +Changed colors for the default prefix +Fixed some possible console errors +=== v3.6 === +Added new 1.9 particles +Added tab completion +Removed useless reset command that caused a NPE +Got version numbers back on track +=== v3.0.5 === +Fixed issue where particles would be displayed in ALL worlds +Added new style "spin" - Displays in a spinning fashion above head +Added new style "move" - Displays only when player is moving +This update won't reset your config.yml +=== v3.0.3 === +Fixed major issue where plugin wouldn't work unless connected to a database +Fixed particles not working until you choose a style (Uses 'None' by default) +=== v3.0.2 === +Probably fixed masses of errors printed by disconnecting from database issue +=== v3.0.1 === +Fixed NullPointerException when players logged in while database is disabled +Fixed incorrect colors for no permission messages +Fixed issue with particles not showing up when logging in sometimes +=== v3 === +Added new Styles! Try them with /pp style [style] +Added command '/pp styles' which lists all styles available to you +Added command '/pp help' which displays all commands available +Added mySQL database support for those of you into that sort of thing +Removed failed attempt at negative permissions, nothing changed here +Fixed some bugs +Added more hugs +=== v2.7 === +Fixed issues with reddust and rainbow permissions +Added support for disabling particles in specific worlds (Found in config) +Added command '/pp worlds' to see what worlds are disabled in-game +Added command '/pp version' to see the current installed plugin version +=== v2.6 === +Added complete message configuration! +Added reload command /pp reload +Footstep particles now display at your feet +=== v2.5 === +Added support for Minecraft 1.8 +Added backwards compatibility for Minecraft 1.6 and 1.7 +Added new particles (Only visible when using Minecraft 1.8) +Removed some particles that did nothing +Edited the config a little bit, it will be reset upon updating the plugin +Fixed a few bugs +Added extra hugs +=== v2.3 Fix === +Fixed permission playerparticles.* not correctly rendering particles around player +=== v2.2 === +Support for 40 particles a second by setting "ticks-per-particle" to a value of 0.5 +=== v2.1 Fix === +Should now be compatible with Java 7 servers +=== v2.0 === +Rewrote entire plugin from scratch +Now more efficient +37 total particles types! +New customization +Particle effect data now stored in effectData.yml +config.yml added that allows for customization of message prefix, and particle count +Removed permission playerparticles.clearall and command /pp clearall (To clear all particles of everyone delete effectData.yml and /reload) \ No newline at end of file diff --git a/src/com/esophose/playerparticles/PPlayer.java b/src/com/esophose/playerparticles/PPlayer.java index 184a22d..046e6a6 100644 --- a/src/com/esophose/playerparticles/PPlayer.java +++ b/src/com/esophose/playerparticles/PPlayer.java @@ -206,8 +206,17 @@ public class PPlayer { public ParticleColor getParticleSpawnColor() { if (particleEffect.hasProperty(ParticleProperty.COLORABLE)) { if (particleEffect == ParticleEffect.NOTE) { + if (particleNoteColorData.getValueX() * 24 == 99) { + return ParticleCreator.getRainbowNoteParticleColor(); + } return particleNoteColorData; - } else return particleColorData; + } else { + if (particleColorData.getRed() == 999 && particleColorData.getGreen() == 999 && particleColorData.getBlue() == 999) { + return ParticleCreator.getRainbowParticleColor(); + } else { + return particleColorData; + } + } } return null; } diff --git a/src/com/esophose/playerparticles/ParticleCommandExecutor.java b/src/com/esophose/playerparticles/ParticleCommandExecutor.java index bc204fb..66ae107 100644 --- a/src/com/esophose/playerparticles/ParticleCommandExecutor.java +++ b/src/com/esophose/playerparticles/ParticleCommandExecutor.java @@ -8,6 +8,9 @@ package com.esophose.playerparticles; +import java.util.Arrays; + +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.command.Command; @@ -49,33 +52,36 @@ public class ParticleCommandExecutor implements CommandExecutor { MessageManager.sendMessage(p, MessageType.INVALID_ARGUMENTS); return true; } else { + String[] cmdArgs = new String[0]; + if (args.length >= 2) cmdArgs = Arrays.copyOfRange(args, 1, args.length); + switch (args[0].toLowerCase()) { case "help": - onHelp(p, args); + onHelp(p); break; case "worlds": - onWorlds(p, args); + onWorlds(p); break; case "version": - onVersion(p, args); + onVersion(p); break; case "effect": - onEffect(p, args); + onEffect(p, cmdArgs); break; case "effects": - onEffects(p, args); + onEffects(p); break; case "style": - onStyle(p, args); + onStyle(p, cmdArgs); break; case "styles": - onStyles(p, args); + onStyles(p); break; case "data": - onData(p, args); + onData(p, cmdArgs); break; case "reset": - onReset(p, args); + onReset(p, cmdArgs); break; default: MessageManager.sendMessage(p, MessageType.INVALID_ARGUMENTS); @@ -84,13 +90,24 @@ public class ParticleCommandExecutor implements CommandExecutor { } } + /** + * Gets an online player by their username if they exist + * + * @param playerName The player's username to lookup + * @return The player, if they exist + */ + private Player getOnlinePlayerByName(String playerName) { + for (Player p : Bukkit.getOnlinePlayers()) + if (p.getName().toLowerCase().contains(playerName.toLowerCase())) return p; + return null; + } + /** * Called when a player uses /pp help * * @param p The player who used the command - * @param args The arguments for the command */ - private void onHelp(Player p, String[] args) { + private void onHelp(Player p) { MessageManager.sendMessage(p, MessageType.AVAILABLE_COMMANDS); MessageManager.sendMessage(p, MessageType.COMMAND_USAGE); } @@ -99,20 +116,19 @@ public class ParticleCommandExecutor implements CommandExecutor { * Called when a player uses /pp worlds * * @param p The player who used the command - * @param args The arguments for the command */ - private void onWorlds(Player p, String[] args) { + private void onWorlds(Player p) { if (ConfigManager.getInstance().getDisabledWorlds() == null || ConfigManager.getInstance().getDisabledWorlds().isEmpty()) { MessageManager.sendMessage(p, MessageType.DISABLED_WORLDS_NONE); return; } - + String worlds = ""; for (String s : ConfigManager.getInstance().getDisabledWorlds()) { worlds += s + ", "; } if (worlds.length() > 2) worlds = worlds.substring(0, worlds.length() - 2); - + MessageManager.sendCustomMessage(p, MessageType.DISABLED_WORLDS.getMessage() + " " + worlds); } @@ -120,9 +136,8 @@ public class ParticleCommandExecutor implements CommandExecutor { * Called when a player uses /pp version * * @param p The player who used the command - * @param args The arguments for the command */ - private void onVersion(Player p, String[] args) { + private void onVersion(Player p) { MessageManager.sendCustomMessage(p, ChatColor.GOLD + "Running PlayerParticles v" + PlayerParticles.getPlugin().getDescription().getVersion()); MessageManager.sendCustomMessage(p, ChatColor.GOLD + "Plugin created by: Esophose"); } @@ -135,7 +150,7 @@ public class ParticleCommandExecutor implements CommandExecutor { */ private void onData(Player p, String[] args) { ParticleEffect effect = ConfigManager.getInstance().getPPlayer(p.getUniqueId()).getParticleEffect(); - if ((!effect.hasProperty(ParticleProperty.REQUIRES_DATA) && !effect.hasProperty(ParticleProperty.COLORABLE)) || args.length == 1) { + if ((!effect.hasProperty(ParticleProperty.REQUIRES_DATA) && !effect.hasProperty(ParticleProperty.COLORABLE)) || args.length == 0) { if (effect.hasProperty(ParticleProperty.COLORABLE)) { if (effect == ParticleEffect.NOTE) { MessageManager.sendMessage(p, MessageType.DATA_USAGE, "note"); @@ -159,50 +174,54 @@ public class ParticleCommandExecutor implements CommandExecutor { } if (effect.hasProperty(ParticleProperty.COLORABLE)) { if (effect == ParticleEffect.NOTE) { - if (args.length >= 2) { - int note = -1; - try { - note = Integer.parseInt(args[1]); - } catch (Exception e) { - MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "note"); - MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.NOTE_DATA_USAGE.getMessage()); - return; - } - - if (note < 0 || note > 23) { - MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "note"); - MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.NOTE_DATA_USAGE.getMessage()); - return; - } - - ConfigManager.getInstance().savePPlayer(p.getUniqueId(), new NoteColor(note)); + if (args[0].equalsIgnoreCase("rainbow")) { + ConfigManager.getInstance().savePPlayer(p.getUniqueId(), new NoteColor(99)); MessageManager.sendMessage(p, MessageType.DATA_APPLIED, "note"); - } else { + return; + } + + int note = -1; + try { + note = Integer.parseInt(args[0]); + } catch (Exception e) { MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "note"); MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.NOTE_DATA_USAGE.getMessage()); + return; } + + if (note < 0 || note > 23) { + MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "note"); + MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.NOTE_DATA_USAGE.getMessage()); + return; + } + + ConfigManager.getInstance().savePPlayer(p.getUniqueId(), new NoteColor(note)); + MessageManager.sendMessage(p, MessageType.DATA_APPLIED, "note"); } else { - if (args.length >= 4) { + if (args[0].equalsIgnoreCase("rainbow")) { + ConfigManager.getInstance().savePPlayer(p.getUniqueId(), new OrdinaryColor(999, 999, 999)); + MessageManager.sendMessage(p, MessageType.DATA_APPLIED, "color"); + } else if (args.length >= 3) { int r = -1; int g = -1; int b = -1; try { - r = Integer.parseInt(args[1]); - g = Integer.parseInt(args[2]); - b = Integer.parseInt(args[3]); + r = Integer.parseInt(args[0]); + g = Integer.parseInt(args[1]); + b = Integer.parseInt(args[2]); } catch (Exception e) { MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "color"); MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.COLOR_DATA_USAGE.getMessage()); return; } - + if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "color"); MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.COLOR_DATA_USAGE.getMessage()); return; } - + ConfigManager.getInstance().savePPlayer(p.getUniqueId(), new OrdinaryColor(r, g, b)); MessageManager.sendMessage(p, MessageType.DATA_APPLIED, "color"); } else { @@ -216,8 +235,8 @@ public class ParticleCommandExecutor implements CommandExecutor { int data = -1; try { - material = ParticlesUtil.closestMatch(args[1]); - if (material == null) material = Material.matchMaterial(args[1]); + material = ParticlesUtil.closestMatch(args[0]); + if (material == null) material = Material.matchMaterial(args[0]); if (material == null) throw new Exception(); } catch (Exception e) { MessageManager.sendMessage(p, MessageType.DATA_MATERIAL_UNKNOWN, "item"); @@ -226,7 +245,7 @@ public class ParticleCommandExecutor implements CommandExecutor { } try { - data = Integer.parseInt(args[2]); + data = Integer.parseInt(args[1]); } catch (Exception e) { MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "item"); MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.ITEM_DATA_USAGE.getMessage()); @@ -238,13 +257,13 @@ public class ParticleCommandExecutor implements CommandExecutor { MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.ITEM_DATA_USAGE.getMessage()); return; } - + if (data < 0 || data > 15) { MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "item"); MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.ITEM_DATA_USAGE.getMessage()); return; } - + ConfigManager.getInstance().savePPlayer(p.getUniqueId(), new ItemData(material, (byte) data)); MessageManager.sendMessage(p, MessageType.DATA_APPLIED, "item"); } else { @@ -252,8 +271,8 @@ public class ParticleCommandExecutor implements CommandExecutor { int data = -1; try { - material = ParticlesUtil.closestMatch(args[1]); - if (material == null) material = Material.matchMaterial(args[1]); + material = ParticlesUtil.closestMatch(args[0]); + if (material == null) material = Material.matchMaterial(args[0]); if (material == null) throw new Exception(); } catch (Exception e) { MessageManager.sendMessage(p, MessageType.DATA_MATERIAL_UNKNOWN, "block"); @@ -262,7 +281,7 @@ public class ParticleCommandExecutor implements CommandExecutor { } try { - data = Integer.parseInt(args[2]); + data = Integer.parseInt(args[1]); } catch (Exception e) { MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "block"); MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.BLOCK_DATA_USAGE.getMessage()); @@ -274,13 +293,13 @@ public class ParticleCommandExecutor implements CommandExecutor { MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.BLOCK_DATA_USAGE.getMessage()); return; } - + if (data < 0 || data > 15) { MessageManager.sendMessage(p, MessageType.DATA_INVALID_ARGUMENTS, "block"); MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.BLOCK_DATA_USAGE.getMessage()); return; } - + ConfigManager.getInstance().savePPlayer(p.getUniqueId(), new BlockData(material, (byte) data)); MessageManager.sendMessage(p, MessageType.DATA_APPLIED, "block"); } @@ -291,11 +310,28 @@ public class ParticleCommandExecutor implements CommandExecutor { * Called when a player uses /pp reset * * @param p The player who used the command - * @param args The arguments for the command + * @param altPlayer The alternate player to reset */ - private void onReset(Player p, String[] args) { - ConfigManager.getInstance().resetPPlayer(p.getUniqueId()); - MessageManager.sendMessage(p, MessageType.RESET); + private void onReset(Player p, String[] args) { // TODO: Apply this to effects, styles, and data(?) + if (args.length >= 1) { + String altPlayerName = args[0]; + if (!PermissionManager.canExecuteForOthers(p)) { + MessageManager.sendMessage(p, MessageType.FAILED_EXECUTE_NO_PERMISSION, altPlayerName); + } else { + Player altPlayer = getOnlinePlayerByName(altPlayerName); + if (altPlayer == null) { + MessageManager.sendMessage(p, MessageType.FAILED_EXECUTE_NOT_FOUND); + } else { + ConfigManager.getInstance().resetPPlayer(altPlayer.getUniqueId()); + MessageManager.sendMessage(altPlayer, MessageType.RESET); + + MessageManager.sendMessage(p, MessageType.EXECUTED_FOR_PLAYER, altPlayer.getName()); + } + } + } else { + ConfigManager.getInstance().resetPPlayer(p.getUniqueId()); + MessageManager.sendMessage(p, MessageType.RESET); + } } /** @@ -303,13 +339,14 @@ public class ParticleCommandExecutor implements CommandExecutor { * * @param p The player who used the command * @param args The arguments for the command + * @param altPlayer The alternate player to give the effect */ private void onEffect(Player p, String[] args) { - if (args.length == 1) { + if (args.length == 0) { MessageManager.sendMessage(p, MessageType.INVALID_TYPE); return; } - String argument = args[1].replace("_", ""); + String argument = args[0].replace("_", ""); if (ParticleCreator.particleFromString(argument) != null) { ParticleEffect effect = ParticleCreator.particleFromString(argument); if (!PermissionManager.hasEffectPermission(p, effect)) { @@ -331,9 +368,8 @@ public class ParticleCommandExecutor implements CommandExecutor { * Called when a player uses /pp effects * * @param p The player who used the command - * @param args The arguments for the command */ - private void onEffects(Player p, String[] args) { + private void onEffects(Player p) { String toSend = MessageType.USE.getMessage() + " "; for (ParticleEffect effect : ParticleEffect.getSupportedEffects()) { if (PermissionManager.hasEffectPermission(p, effect)) { @@ -357,13 +393,14 @@ public class ParticleCommandExecutor implements CommandExecutor { * * @param p The player who used the command * @param args The arguments for the command + * @param altPlayer The alternate player to give the style */ private void onStyle(Player p, String[] args) { - if (args.length == 1) { + if (args.length == 0) { MessageManager.sendMessage(p, MessageType.INVALID_TYPE_STYLE); return; } - String argument = args[1].replace("_", ""); + String argument = args[0].replace("_", ""); if (ParticleStyleManager.styleFromString(argument) != null) { ParticleStyle style = ParticleStyleManager.styleFromString(argument); if (!PermissionManager.hasStylePermission(p, style)) { @@ -385,9 +422,8 @@ public class ParticleCommandExecutor implements CommandExecutor { * Called when a player uses /pp styles * * @param p The player who used the command - * @param args The arguments for the command */ - private void onStyles(Player p, String[] args) { + private void onStyles(Player p) { String toSend = MessageType.USE.getMessage() + " "; for (ParticleStyle style : ParticleStyleManager.getStyles()) { if (PermissionManager.hasStylePermission(p, style)) { diff --git a/src/com/esophose/playerparticles/ParticleCreator.java b/src/com/esophose/playerparticles/ParticleCreator.java index 9219aca..d572f9b 100644 --- a/src/com/esophose/playerparticles/ParticleCreator.java +++ b/src/com/esophose/playerparticles/ParticleCreator.java @@ -8,6 +8,7 @@ package com.esophose.playerparticles; +import java.awt.Color; import java.util.ArrayList; import org.bukkit.Bukkit; @@ -21,6 +22,8 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scheduler.BukkitRunnable; import com.esophose.playerparticles.library.ParticleEffect; +import com.esophose.playerparticles.library.ParticleEffect.NoteColor; +import com.esophose.playerparticles.library.ParticleEffect.OrdinaryColor; import com.esophose.playerparticles.library.ParticleEffect.ParticleProperty; import com.esophose.playerparticles.manager.ConfigManager; import com.esophose.playerparticles.manager.PermissionManager; @@ -28,11 +31,23 @@ import com.esophose.playerparticles.styles.api.PParticle; import com.esophose.playerparticles.styles.api.ParticleStyleManager; public class ParticleCreator extends BukkitRunnable implements Listener { + + /** + * How far away particles will spawn from players + */ + public static final int PARTICLE_RANGE = 512; /** * The list containing all the player effect info */ public static ArrayList particlePlayers = new ArrayList(); + + /** + * Rainbow particle effect hue and note color used for rainbow colorable effects + * These should be moved to a more appropriate place later + */ + private static int hue = 0; + private static int note = 0; /** * Adds the player to the array when they join @@ -65,6 +80,11 @@ public class ParticleCreator extends BukkitRunnable implements Listener { } } + /** + * Overrides an existing PPlayer with the same UUID + * + * @param pplayer The PPlayer to override + */ public static void updateIfContains(PPlayer pplayer) { for (PPlayer pp : particlePlayers) { if (pp.getUniqueId() == pplayer.getUniqueId()) { @@ -94,16 +114,25 @@ public class ParticleCreator extends BukkitRunnable implements Listener { */ public void run() { ParticleStyleManager.updateTimers(); - - for (Player player : Bukkit.getOnlinePlayers()) { + + hue++; + hue %= 360; + + if (hue % 10 == 0) { // Only increment note by 2 notes per second + note++; + note %= 24; + } + + for (PPlayer pplayer : particlePlayers) { + Player player = Bukkit.getPlayer(pplayer.getUniqueId()); + + if (!PermissionManager.hasEffectPermission(player, pplayer.getParticleEffect())) continue; if (ConfigManager.getInstance().isWorldDisabled(player.getWorld().getName())) continue; if (player.getGameMode() == GameMode.SPECTATOR) continue; - PPlayer pplayer = ConfigManager.getInstance().getPPlayer(player.getUniqueId()); - if (PermissionManager.hasEffectPermission(player, pplayer.getParticleEffect())) { - Location loc = player.getLocation(); - loc.setY(loc.getY() + 1); - displayParticles(pplayer, loc); - } + + Location loc = player.getLocation(); + loc.setY(loc.getY() + 1); + displayParticles(pplayer, loc); } } @@ -119,18 +148,18 @@ public class ParticleCreator extends BukkitRunnable implements Listener { if (effect == ParticleEffect.NONE) return; for (PParticle particle : pplayer.getParticleStyle().getParticles(pplayer, location)) { if (effect.hasProperty(ParticleProperty.REQUIRES_DATA)) { - effect.display(pplayer.getParticleSpawnData(), particle.getXOff(), particle.getYOff(), particle.getZOff(), particle.getSpeed(), 1, particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), 256); + effect.display(pplayer.getParticleSpawnData(), particle.getXOff(), particle.getYOff(), particle.getZOff(), particle.getSpeed(), 1, particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), PARTICLE_RANGE); } else if (effect.hasProperty(ParticleProperty.COLORABLE)) { - effect.display(pplayer.getParticleSpawnColor(), particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), 256); + effect.display(pplayer.getParticleSpawnColor(), particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), PARTICLE_RANGE); } else { - effect.display(particle.getXOff(), particle.getYOff(), particle.getZOff(), particle.getSpeed(), 1, particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), 256); + effect.display(particle.getXOff(), particle.getYOff(), particle.getZOff(), particle.getSpeed(), 1, particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), PARTICLE_RANGE); } } } } /** - * An alternative method typically used for custom handled styles + * An alternative method used for custom handled styles * * @param pplayer The PPlayer to use for getting particle settings * @param location The location to display at @@ -140,13 +169,22 @@ public class ParticleCreator extends BukkitRunnable implements Listener { if (effect == ParticleEffect.NONE) return; for (PParticle particle : particles) { if (effect.hasProperty(ParticleProperty.REQUIRES_DATA)) { - effect.display(pplayer.getParticleSpawnData(), particle.getXOff(), particle.getYOff(), particle.getZOff(), particle.getSpeed(), 1, particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), 256); + effect.display(pplayer.getParticleSpawnData(), particle.getXOff(), particle.getYOff(), particle.getZOff(), particle.getSpeed(), 1, particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), PARTICLE_RANGE); } else if (effect.hasProperty(ParticleProperty.COLORABLE)) { - effect.display(pplayer.getParticleSpawnColor(), particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), 256); + effect.display(pplayer.getParticleSpawnColor(), particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), PARTICLE_RANGE); } else { - effect.display(particle.getXOff(), particle.getYOff(), particle.getZOff(), particle.getSpeed(), 1, particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), 256); + effect.display(particle.getXOff(), particle.getYOff(), particle.getZOff(), particle.getSpeed(), 1, particle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), PARTICLE_RANGE); } } } + + public static OrdinaryColor getRainbowParticleColor() { + Color rgb = Color.getHSBColor(hue / 360F, 1.0F, 1.0F); + return new OrdinaryColor(rgb.getRed(), rgb.getGreen(), rgb.getBlue()); + } + + public static NoteColor getRainbowNoteParticleColor() { + return new NoteColor(note); + } } diff --git a/src/com/esophose/playerparticles/PlayerParticles.java b/src/com/esophose/playerparticles/PlayerParticles.java index a5297b3..bbc409b 100644 --- a/src/com/esophose/playerparticles/PlayerParticles.java +++ b/src/com/esophose/playerparticles/PlayerParticles.java @@ -4,13 +4,26 @@ * you must not claim it as your own. This plugin may * be modified and installed on a server, but may not * be distributed to any person by any means. - * - * TODO: Make sure copyright notice is on all files - * TODO: Make sure all the comments are properly formatted still - * TODO: Add option to config to show particles in spectator mode or not - Disabled by default - * TODO: Add message configuration for data usage */ +/* + v4.2 Changelog + + + Added new style 'arrows' + * Renamed style 'spiral' to 'beam' + + Added new style 'spiral' + * Spawning particles is now more efficient + * Checking disabled worlds is now taken from cache + + Rainbow colorable particles - /pp data rainbow for any colorable particle + + TODO: + + Add player variable in commands + + Add new style 'tornado' + + Add new style 'atom' + + Fixed particle spawn locations + + GUI for styles and effects +*/ + package com.esophose.playerparticles; import java.io.File; diff --git a/src/com/esophose/playerparticles/library/ParticleEffect.java b/src/com/esophose/playerparticles/library/ParticleEffect.java index 655666d..8684334 100644 --- a/src/com/esophose/playerparticles/library/ParticleEffect.java +++ b/src/com/esophose/playerparticles/library/ParticleEffect.java @@ -11,7 +11,6 @@ import java.util.Map; import java.util.Map.Entry; import org.bukkit.Bukkit; -import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -922,36 +921,33 @@ public enum ParticleEffect { * or higher than 255 */ public OrdinaryColor(int red, int green, int blue) throws IllegalArgumentException { - if (red < 0) { - throw new IllegalArgumentException("The red value is lower than 0"); + if (red == 999 && green == 999 && blue == 999) { + this.red = red; + this.green = green; + this.blue = blue; + } else { + if (red < 0) { + throw new IllegalArgumentException("The red value is lower than 0"); + } + if (red > 255) { + throw new IllegalArgumentException("The red value is higher than 255"); + } + this.red = red; + if (green < 0) { + throw new IllegalArgumentException("The green value is lower than 0"); + } + if (green > 255) { + throw new IllegalArgumentException("The green value is higher than 255"); + } + this.green = green; + if (blue < 0) { + throw new IllegalArgumentException("The blue value is lower than 0"); + } + if (blue > 255) { + throw new IllegalArgumentException("The blue value is higher than 255"); + } + this.blue = blue; } - if (red > 255) { - throw new IllegalArgumentException("The red value is higher than 255"); - } - this.red = red; - if (green < 0) { - throw new IllegalArgumentException("The green value is lower than 0"); - } - if (green > 255) { - throw new IllegalArgumentException("The green value is higher than 255"); - } - this.green = green; - if (blue < 0) { - throw new IllegalArgumentException("The blue value is lower than 0"); - } - if (blue > 255) { - throw new IllegalArgumentException("The blue value is higher than 255"); - } - this.blue = blue; - } - - /** - * Construct a new ordinary color - * - * @param color Bukkit color - */ - public OrdinaryColor(Color color) { - this(color.getRed(), color.getGreen(), color.getBlue()); } /** @@ -988,6 +984,7 @@ public enum ParticleEffect { */ @Override public float getValueX() { + if (red == 999) return 0F; return (float) red / 255F; } @@ -998,6 +995,7 @@ public enum ParticleEffect { */ @Override public float getValueY() { + if (green == 999) return 0F; return (float) green / 255F; } @@ -1008,6 +1006,7 @@ public enum ParticleEffect { */ @Override public float getValueZ() { + if (blue == 999) return 0F; return (float) blue / 255F; } } @@ -1032,13 +1031,17 @@ public enum ParticleEffect { * higher than 24 */ public NoteColor(int note) throws IllegalArgumentException { - if (note < 0) { - throw new IllegalArgumentException("The note value is lower than 0"); + if (note == 99) { + this.note = note; + } else { + if (note < 0) { + throw new IllegalArgumentException("The note value is lower than 0"); + } + if (note > 24) { + throw new IllegalArgumentException("The note value is higher than 24"); + } + this.note = note; } - if (note > 24) { - throw new IllegalArgumentException("The note value is higher than 24"); - } - this.note = note; } /** diff --git a/src/com/esophose/playerparticles/manager/ConfigManager.java b/src/com/esophose/playerparticles/manager/ConfigManager.java index a7a3e34..b0b4700 100644 --- a/src/com/esophose/playerparticles/manager/ConfigManager.java +++ b/src/com/esophose/playerparticles/manager/ConfigManager.java @@ -15,7 +15,6 @@ import java.sql.SQLException; import java.util.List; import java.util.UUID; -import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; @@ -46,6 +45,11 @@ public class ConfigManager { * The configuration used to edit the .yaml file */ private FileConfiguration config; + + /** + * The disabled worlds cached for quick access + */ + private List disabledWorlds = null; /** * @return The instance of the config for effects @@ -119,7 +123,7 @@ public class ConfigManager { ParticleStyle particleStyle = ParticleStyleManager.styleFromString(styleSection.getString("name")); ItemData particleItemData = new ItemData(Material.matchMaterial(itemDataSection.getString("material")), (byte) itemDataSection.getInt("data")); BlockData particleBlockData = new BlockData(Material.matchMaterial(blockDataSection.getString("material")), (byte) blockDataSection.getInt("data")); - OrdinaryColor particleColorData = new OrdinaryColor(Color.fromRGB(colorDataSection.getInt("r"), colorDataSection.getInt("g"), colorDataSection.getInt("b"))); + OrdinaryColor particleColorData = new OrdinaryColor(colorDataSection.getInt("r"), colorDataSection.getInt("g"), colorDataSection.getInt("b")); NoteColor particleNoteColorData = new NoteColor(noteColorDataSection.getInt("note")); return new PPlayer(playerUUID, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData); @@ -142,7 +146,7 @@ public class ConfigManager { ParticleStyle particleStyle = ParticleStyleManager.styleFromString(res.getString("u.style")); ItemData particleItemData = new ItemData(Material.matchMaterial(res.getString("i.material")), res.getByte("i.data")); BlockData particleBlockData = new BlockData(Material.matchMaterial(res.getString("b.material")), res.getByte("b.data")); - OrdinaryColor particleColorData = new OrdinaryColor(Color.fromRGB(res.getInt("c.r"), res.getInt("c.g"), res.getInt("c.b"))); + OrdinaryColor particleColorData = new OrdinaryColor(res.getInt("c.r"), res.getInt("c.g"), res.getInt("c.b")); NoteColor particleNoteColorData = new NoteColor(res.getByte("n.note")); return new PPlayer(playerUUID, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData); @@ -400,9 +404,10 @@ public class ConfigManager { * @return All world names that are disabled */ public List getDisabledWorlds() { - if (PlayerParticles.getPlugin().getConfig().get("disabled-worlds") != null) { - return PlayerParticles.getPlugin().getConfig().getStringList("disabled-worlds"); - } else return null; + if (disabledWorlds == null) { + disabledWorlds = PlayerParticles.getPlugin().getConfig().getStringList("disabled-worlds"); + } + return disabledWorlds; } } diff --git a/src/com/esophose/playerparticles/manager/MessageManager.java b/src/com/esophose/playerparticles/manager/MessageManager.java index cb49ae4..4fb8718 100644 --- a/src/com/esophose/playerparticles/manager/MessageManager.java +++ b/src/com/esophose/playerparticles/manager/MessageManager.java @@ -60,7 +60,10 @@ public class MessageManager { AVAILABLE_COMMANDS("message-available-commands"), DISABLED_WORLDS_NONE("message-disabled-worlds-none"), DISABLED_WORLDS("message-disabled-worlds"), - COMMAND_USAGE("message-command-usage"); + COMMAND_USAGE("message-command-usage"), + EXECUTED_FOR_PLAYER("message-executed-for-player"), + FAILED_EXECUTE_NOT_FOUND("message-failed-execute-not-found"), + FAILED_EXECUTE_NO_PERMISSION("message-failed-execute-no-permission"); public String configLocation; diff --git a/src/com/esophose/playerparticles/manager/PermissionManager.java b/src/com/esophose/playerparticles/manager/PermissionManager.java index 49d87da..47f7511 100644 --- a/src/com/esophose/playerparticles/manager/PermissionManager.java +++ b/src/com/esophose/playerparticles/manager/PermissionManager.java @@ -78,4 +78,8 @@ public class PermissionManager { return list; } + public static boolean canExecuteForOthers(Player player) { + return player.hasPermission("playerparticles.other"); + } + } diff --git a/src/com/esophose/playerparticles/styles/DefaultStyles.java b/src/com/esophose/playerparticles/styles/DefaultStyles.java index 04b5aa9..eed048f 100644 --- a/src/com/esophose/playerparticles/styles/DefaultStyles.java +++ b/src/com/esophose/playerparticles/styles/DefaultStyles.java @@ -13,7 +13,7 @@ public class DefaultStyles { * All the styles that are available by default from this plugin */ public static ParticleStyle NONE = new ParticleStyleNone(); - public static ParticleStyle SPIRAL = new ParticleStyleSpiral(); + public static ParticleStyle BEAM = new ParticleStyleBeam(); public static ParticleStyle HALO = new ParticleStyleHalo(); public static ParticleStyle POINT = new ParticleStylePoint(); public static ParticleStyle MOVE = new ParticleStyleMove(); @@ -22,13 +22,15 @@ public class DefaultStyles { public static ParticleStyle ORBIT = new ParticleStyleOrbit(); public static ParticleStyle FEET = new ParticleStyleFeet(); public static ParticleStyle CUBE = new ParticleStyleCube(); + public static ParticleStyle ARROWS = new ParticleStyleArrows(); + public static ParticleStyle SPIRAL = new ParticleStyleSpiral(); /** * Registers all the default styles to the ParticleStyleManager */ public static void registerStyles() { ParticleStyleManager.registerStyle(NONE); - ParticleStyleManager.registerStyle(SPIRAL); + ParticleStyleManager.registerStyle(BEAM); ParticleStyleManager.registerStyle(HALO); ParticleStyleManager.registerStyle(POINT); ParticleStyleManager.registerCustomHandledStyle(MOVE); @@ -37,8 +39,11 @@ public class DefaultStyles { ParticleStyleManager.registerStyle(ORBIT); ParticleStyleManager.registerStyle(FEET); ParticleStyleManager.registerStyle(CUBE); - + ParticleStyleManager.registerStyle(ARROWS); + ParticleStyleManager.registerStyle(SPIRAL); + Bukkit.getPluginManager().registerEvents((Listener) MOVE, PlayerParticles.getPlugin()); + Bukkit.getPluginManager().registerEvents((Listener) ARROWS, PlayerParticles.getPlugin()); } } diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleArrows.java b/src/com/esophose/playerparticles/styles/ParticleStyleArrows.java new file mode 100644 index 0000000..5d9c21b --- /dev/null +++ b/src/com/esophose/playerparticles/styles/ParticleStyleArrows.java @@ -0,0 +1,61 @@ +package com.esophose.playerparticles.styles; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityShootBowEvent; + +import com.esophose.playerparticles.PPlayer; +import com.esophose.playerparticles.styles.api.PParticle; +import com.esophose.playerparticles.styles.api.ParticleStyle; + +public class ParticleStyleArrows implements ParticleStyle, Listener { + + private List arrows = new ArrayList(); + + public PParticle[] getParticles(PPlayer pplayer, Location location) { + List particles = new ArrayList(); + + for (Arrow arrow : arrows) { + if (((Player) arrow.getShooter()).getUniqueId() == pplayer.getUniqueId()) { + particles.add(new PParticle(arrow.getLocation(), 0.05F, 0.05F, 0.05F, 0.0F)); + } + } + + return particles.toArray(new PParticle[particles.size()]); + } + + /** + * Removes all arrows that are considered dead + */ + public void updateTimers() { + for (int i = arrows.size() - 1; i >= 0; i--) { + if (arrows.get(i).isDead()) + arrows.remove(i); + } + } + + public String getName() { + return "arrows"; + } + + /** + * The event used to get all arrows fired by players + * Adds all arrows fired from players to the array + * + * @param e + */ + @EventHandler + public void onArrowFired(EntityShootBowEvent e) { + if (e.getEntityType() == EntityType.PLAYER && e.getProjectile().getType() == EntityType.ARROW) { + arrows.add((Arrow) e.getProjectile()); + } + } + +} diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleBeam.java b/src/com/esophose/playerparticles/styles/ParticleStyleBeam.java new file mode 100644 index 0000000..7694b19 --- /dev/null +++ b/src/com/esophose/playerparticles/styles/ParticleStyleBeam.java @@ -0,0 +1,39 @@ +package com.esophose.playerparticles.styles; + +import org.bukkit.Location; + +import com.esophose.playerparticles.PPlayer; +import com.esophose.playerparticles.styles.api.PParticle; +import com.esophose.playerparticles.styles.api.ParticleStyle; + +public class ParticleStyleBeam implements ParticleStyle { + + private float step = 0; + + public PParticle[] getParticles(PPlayer pplayer, Location location) { + int points = 16; + double radius = 1; + double slice = 2 * Math.PI / points; + PParticle[] particles = new PParticle[points]; + for (int i = 0; i < points; i++) { + double angle = slice * i; + double newX = location.getX() + radius * Math.cos(angle); + double newY = location.getY() + (step / 10) - 1; + double newZ = location.getZ() + radius * Math.sin(angle); + particles[i] = new PParticle(new Location(location.getWorld(), newX, newY, newZ)); + } + return particles; + } + + public void updateTimers() { + step++; + if (step > 30) { + step = 0; + } + } + + public String getName() { + return "beam"; + } + +} diff --git a/src/com/esophose/playerparticles/styles/ParticleStyleSpiral.java b/src/com/esophose/playerparticles/styles/ParticleStyleSpiral.java index 70fcb5b..8e6df7d 100644 --- a/src/com/esophose/playerparticles/styles/ParticleStyleSpiral.java +++ b/src/com/esophose/playerparticles/styles/ParticleStyleSpiral.java @@ -1,5 +1,8 @@ package com.esophose.playerparticles.styles; +import java.util.ArrayList; +import java.util.List; + import org.bukkit.Location; import com.esophose.playerparticles.PPlayer; @@ -8,28 +11,21 @@ import com.esophose.playerparticles.styles.api.ParticleStyle; public class ParticleStyleSpiral implements ParticleStyle { - private float step = 0; + private float stepX = 0; public PParticle[] getParticles(PPlayer pplayer, Location location) { - int points = 16; - double radius = 1; - double slice = 2 * Math.PI / points; - PParticle[] particles = new PParticle[points]; - for (int i = 0; i < points; i++) { - double angle = slice * i; - double newX = location.getX() + radius * Math.cos(angle); - double newY = location.getY() + (step / 10) - 1; - double newZ = location.getZ() + radius * Math.sin(angle); - particles[i] = new PParticle(new Location(location.getWorld(), newX, newY, newZ)); + List particles = new ArrayList(); + for (int stepY = -60; stepY < 60; stepY += 10) { + double dx = -(Math.cos(((stepX + stepY) / 90) * Math.PI * 2)) * 0.8; + double dy = stepY / 45D; + double dz = -(Math.sin(((stepX + stepY) / 90) * Math.PI * 2)) * 0.8; + particles.add(new PParticle(new Location(location.getWorld(), location.getX() + dx, location.getY() + dy, location.getZ() + dz))); } - return particles; + return particles.toArray(new PParticle[particles.size()]); } public void updateTimers() { - step++; - if (step > 30) { - step = 0; - } + stepX++; } public String getName() { diff --git a/src/config.yml b/src/config.yml index bbc978b..e7fa0e2 100644 --- a/src/config.yml +++ b/src/config.yml @@ -13,10 +13,10 @@ # Changing this value will reset your config on the next server reload/restart. # I don't recommend changing it -version: 4.1 +version: 4.2 # How many ticks to wait before spawning more particles -# Increasing this value may cause less lag, but will decrease prettiness +# Increasing this value may cause less lag (if there was any), but will decrease prettiness # The lowest possible value is 1 # Going over 5 will likely look terrible # Default: 1 @@ -27,12 +27,20 @@ ticks-per-particle: 1 check-updates: true # The worlds which this plugin is disabled in -# Remove the [] before you enter worlds names +# Remove the [] before you enter world names # Default: [] disabled-worlds: [] # - your_world_name_here # - add_more_under_these - + +# ================================================================ # +# MESSAGE CONFIGURATION # +# Important Notes: # +# * You can use the & symbol to color the messages # +# * {TYPE} Will be replaced with whatever that message requires # +# * You can not use the apostrophe character! ( ' ) # +# ================================================================ # + # If you're using other plugins to execute commands you may wish to turn off messages # Default: true messages-enabled: true @@ -42,19 +50,10 @@ messages-enabled: true use-message-prefix: true # The prefix to use for all PlayerParticle messages -# Use & to set color / format # This is useless if use-message-prefix is set to false # Default: '&7[&3PlayerParticles&7]' message-prefix: '&7[&3PlayerParticles&7]' -# ================================================================ # -# MESSAGE CONFIGURATION # -# Important Notes: # -# * You can use the & symbol to color the messages # -# * {TYPE} Will be replaced with whatever that message requires # -# * You can not use the apostrophe character! ( ' ) # -# ================================================================ # - # ------------- # # Particles # # ------------- # @@ -149,7 +148,7 @@ message-note-data-usage: '&b/pp data <0-23>' # Color Data Usage # You should not change the text here, only the coloring # Default: '&b/pp data <0-255> <0-255> <0-255>' -message-color-data-usage: '&b/pp data <0-255> <0-255> <0-255>' +message-color-data-usage: '&b/pp data [<0-255> <0-255> <0-255>] [rainbow]' # Item Data Usage # You should not change the text here, only the coloring @@ -201,6 +200,18 @@ message-disabled-worlds-none: '&eParticles are not disabled in any worlds!' # Default: '&eCommand Usage: /pp ' message-command-usage: '&eCommand Usage: &b/pp ' +# Executed For Player +# Default: '&aCommand executed for &b{TYPE}' +message-executed-for-player: '&aCommand executed for &b{TYPE}' + +# Failed Execute Not Found +# Default: '&cFailed to execute for &b{TYPE}&c! Player not found!' +message-failed-execute-not-found: '&cFailed to execute for &b{TYPE}&c! Player not found!' + +# Failed Execute No Permission +# Default: '&cFailed to execute for &b{TYPE}&c! You do not have permission!' +message-failed-execute-no-permission: '&cFailed to execute for &b{TYPE}&c! You do not have permission!' + # ================================================================ # # DATABASE CONFIGURATION # # Information: # diff --git a/src/plugin.yml b/src/plugin.yml index fd399c9..18778a1 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -1,7 +1,7 @@ name: PlayerParticles main: com.esophose.playerparticles.PlayerParticles -version: 4.1 -description: Make particles around players. +version: 4.2 +description: Make particles around players in fancy ways. author: Esophose website: http://dev.bukkit.org/bukkit-plugins/playerparticles/ commands: