/pp reload, 5 new styles, create fixed effects where you're looking, directional particles in styles now possible

Need to rework the locations that styles' particles spawn at. Need to always spawn them relative to 0, 0, 0 and adjust for the player/coordinates they are targeted to spawn at accordingly. This will fix '/pp fixed create looking'  not creating the fixed effects properly centered around blocks.
This commit is contained in:
Esophose 2018-10-28 04:18:34 -06:00
parent 57e4678f8b
commit cb7e1ef91c
24 changed files with 641 additions and 110 deletions

View file

@ -199,7 +199,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.13.1-R0.1-SNAPSHOT</version>
<version>1.13.2-R0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View file

@ -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;
@ -62,6 +63,11 @@ public class PlayerParticles extends JavaPlugin {
*/
private static DatabaseConnector databaseConnector = null;
/**
* The task that spawns the particles
*/
private static BukkitTask particleTask = null;
/**
* Registers all the styles available by default
* Saves the default config if it doesn't exist
@ -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();
}
/**
@ -127,6 +128,34 @@ public class PlayerParticles extends JavaPlugin {
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,24 +230,14 @@ 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'";
}
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.");
// 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.");
}
}
} catch (SQLException ex) {
@ -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);
}

View file

@ -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,12 +95,36 @@ 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;
if (args[0].equalsIgnoreCase("looking")) {
Block targetBlock = p.getTargetBlock((Set<Material>)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();
@ -124,6 +150,7 @@ public class FixedCommandModule implements CommandModule {
LangManager.sendMessage(p, Lang.FIXED_CREATE_INVALID_COORDS);
return;
}
}
double distanceFromEffect = p.getLocation().distance(new Location(p.getWorld(), xPos, yPos, zPos));
int maxCreationDistance = DataManager.getMaxFixedEffectCreationDistance();
@ -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);

View file

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

View file

@ -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<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
}
public String getName() {
return "reload";
}
public Lang getDescription() {
return Lang.COMMAND_DESCRIPTION_RELOAD;
}
public String getArguments() {
return "";
}
public boolean requiresEffects() {
return false;
}
}

View file

@ -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;
@ -453,6 +452,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
*

View file

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

View file

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

View file

@ -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 {
@ -187,6 +189,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
*

View file

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

View file

@ -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<PParticle> getParticles(ParticlePair particle, Location location) {
List<PParticle> particles = new ArrayList<PParticle>();
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;
}
}

View file

@ -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<PParticle> getParticles(ParticlePair particle, Location location) {
List<PParticle> particles = new ArrayList<PParticle>();
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;
}
}

View file

@ -52,7 +52,7 @@ public class ParticleStyleCube implements ParticleStyle {
public List<PParticle> getParticles(ParticlePair particle, Location location) {
List<PParticle> pparticles = new ArrayList<PParticle>();
if (!skipNextStep) { // TODO: relative position lookup tables
if (!skipNextStep) {
double xRotation = 0, yRotation = 0, zRotation = 0;
xRotation = step * angularVelocityX;
yRotation = step * angularVelocityY;

View file

@ -13,7 +13,7 @@ public class ParticleStyleFeet implements ParticleStyle {
public List<PParticle> getParticles(ParticlePair particle, Location location) {
List<PParticle> particles = new ArrayList<PParticle>();
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;
}

View file

@ -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<PParticle> getParticles(ParticlePair particle, Location location) {
List<PParticle> particles = new ArrayList<PParticle>();
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;
}
}

View file

@ -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<PParticle> getParticles(ParticlePair particle, Location location) {
List<PParticle> particles = new ArrayList<PParticle>();
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;
}
}

View file

@ -12,7 +12,7 @@ import com.esophose.playerparticles.styles.api.ParticleStyle;
public class ParticleStylePoint implements ParticleStyle {
public List<PParticle> 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() {

View file

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

View file

@ -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<PParticle> getParticles(ParticlePair particle, Location location) {
List<PParticle> particles = new ArrayList<PParticle>();
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;
}
}

View file

@ -10,6 +10,26 @@ 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);
}
/**
@ -71,6 +87,15 @@ public class PParticle {
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
*

View file

@ -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);
}
@ -58,6 +71,16 @@ public class ParticleStyleManager {
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
*

View file

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

28
src/groups.yml Normal file
View file

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

View file

@ -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 <x> <y> <z> <effect> <style> [data] - Creates a new fixed effect'
command-description-fixed-create: '&e/pp fixed create <<x> <y> <z>|<looking>> <effect> <style> [data] - Creates a new fixed effect'
command-description-fixed-remove: '&e/pp fixed remove <ID> - Removes a fixed effect by its ID'
command-description-fixed-list: '&e/pp fixed list - Lists all IDs of your fixed effects'
command-description-fixed-info: '&e/pp fixed info <ID> - Gets info on one of your fixed effects'
@ -75,6 +76,10 @@ group-list-none: '&eYou do not have any particle groups saved!'
group-list-output: '&eYou have the following groups saved: &b{0}'
group-list-presets: '&eThe following preset groups are available: &b{0}'
# Reload Command
reload-success: '&aThe plugin has been reloaded!'
reload-no-permission: '&cYou do not have permission to reload the plugin settings!'
# Remove Command
remove-no-args: '&cYou did not specify an ID to remove! &b/pp remove <ID>'
remove-success: '&aYour particle with the ID &b{0} &ahas been removed!'
@ -124,6 +129,7 @@ reset-success: '&aRemoved &b{0} &aactive particle(s)!'
fixed-create-missing-args: '&cUnable to create fixed effect, you are missing &b{0} &crequired arguments!'
fixed-create-invalid-coords: '&cUnable to create fixed effect, one or more coordinates you entered is invalid!'
fixed-create-out-of-range: '&cUnable to create fixed effect, you must be within &b{0} &cblocks of your desired location!'
fixed-create-looking-too-far: '&cUnable to create fixed effect, you are standing too far away from the block you are looking at!'
fixed-create-effect-invalid: '&cUnable to create fixed effect, an effect with the name &b{0} &cdoes not exist!'
fixed-create-effect-no-permission: '&cUnable to create fixed effect, you do not have permission to use the effect &b{0}&c!'
fixed-create-style-invalid: '&cUnable to create fixed effect, a style with the name &b{0} &cdoes not exist!'