Expand API (#80)

* PLAYER particles

When creating a custom particle effect its very limiting not having access to the player object, this PR adds a method that calls with the player object, allowing you to get player UUID for hash-map or checking nearby blocks etc.

* Remove metadata check

Bad for performance and not necessary (If a target is vanished player.canSee(target) will return false)

ParticleSpawner.canSee() 11.29% 577.34ms
CraftPlayer.getMetadata() 7.71% 394.13ms

* Add size param to PParticle

More customization

* Let actual vibration be used

Lets custom effects make cool skulk animations.

* Use eye location for spawning

Particles adjust when you sneak/crawl (player.getEyeLocation() exists in 1.8 also iirc)

* Remove unnecessary .clone

entity.getLocation returns a clone of their location.

* The changes esophose requested

* Changes

* Remove player from imports

* Where did this even come from

* and this
This commit is contained in:
basedAF 2021-07-14 20:16:51 +01:00 committed by GitHub
parent 45152fcfcb
commit 97cf24053c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 93 additions and 28 deletions

View file

@ -193,7 +193,7 @@ public class ParticleManager extends Manager implements Listener, Runnable {
// Don't spawn particles if the world doesn't allow it
if (player != null && ParticleUtils.isPlayerVisible(player) && permissionManager.isWorldEnabled(player.getWorld().getName()))
for (ParticlePair particles : pplayer.getActiveParticles())
this.displayParticles(pplayer, particles, player.getLocation().clone().add(0, 1, 0));
this.displayParticles(pplayer, particles, player.getEyeLocation().add(0, -0.6, 0));
// Loop for FixedParticleEffects
// Don't spawn particles if the world doesn't allow it
@ -260,11 +260,24 @@ public class ParticleManager extends Manager implements Listener, Runnable {
}
}
for (PParticle pparticle : particle.getStyle().getParticles(particle, location))
for (PParticle pparticle : getParticlesWithPlayer(particle, location, pplayer.getPlayer()))
ParticleEffect.display(particle, pparticle, particle.getStyle().hasLongRangeVisibility(), pplayer.getPlayer());
}
}
/**
* Gets all particles with the player object, if no particles are returned it defaults to non-player method
*
* @param particle The ParticlePair that contains the particle's data
* @param location The central location of the particles
* @param player The player that the particles are spawning on - null for fixed effects
* @return A List of PParticles to spawn
*/
private List<PParticle> getParticlesWithPlayer(ParticlePair particle, Location location, Player player){
List<PParticle> particles = particle.getStyle().getParticles(particle, location, player);
return particles != null ? particles : particle.getStyle().getParticles(particle, location);
}
/**
* An alternative method used for event styles
*

View file

@ -12,6 +12,7 @@ public class PParticle {
private double xOff, yOff, zOff;
private boolean directional;
private Object overrideData;
private float size;
/**
* The constructor with all the fancy parameters and override data for customization
@ -33,6 +34,26 @@ public class PParticle {
this.directional = directional;
this.overrideData = overrideData;
}
/**
* The constructor with all the fancy parameters and override data 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
* @param size Size of the redstone particle
*/
public PParticle(Location location, double xOff, double yOff, double zOff, double speed, boolean directional, float size) {
this.location = location;
this.xOff = xOff;
this.yOff = yOff;
this.zOff = zOff;
this.speed = speed;
this.directional = directional;
this.size = size;
}
/**
* The constructor with all the fancy parameters for customization
@ -121,6 +142,15 @@ public class PParticle {
return this.xOff;
}
/**
* Gets the size of the particle
*
* @return The size
*/
public float getSize() {
return this.size;
}
/**
* Gets the offset on the y-axis for the particle
*

View file

@ -375,7 +375,7 @@ public enum ParticleEffect {
} else {
data = particle.getSpawnColorTransition();
}
effect.display(data, pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), 1, pparticle.getLocation(false), isLongRange, owner);
effect.display(data, pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), 1, pparticle.getLocation(false), isLongRange, owner, pparticle.getSize());
} else if (effect.hasProperty(ParticleProperty.VIBRATION)) {
Vibration data;
if (pparticle.getOverrideData() instanceof Vibration) {
@ -416,7 +416,7 @@ public enum ParticleEffect {
* @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
*/
public void display(ParticleColor color, Location center, boolean isLongRange, Player owner) {
particleSpawner.display(this, color, center, isLongRange, owner);
particleSpawner.display(this, color, center, isLongRange, owner, 1.0F);
}
/**
@ -454,8 +454,8 @@ public enum ParticleEffect {
* @param owner The player that owns the particles
* @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
*/
public void display(ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner) {
particleSpawner.display(this, colorTransition, offsetX, offsetY, offsetZ, amount, center, isLongRange, owner);
public void display(ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner, float size) {
particleSpawner.display(this, colorTransition, offsetX, offsetY, offsetZ, amount, center, isLongRange, owner, size);
}
/**

View file

@ -2,8 +2,13 @@ package dev.esophose.playerparticles.particles.data;
public class Vibration {
private org.bukkit.Vibration vibration;
private final int duration;
public Vibration(org.bukkit.Vibration vibration) {
this.vibration = vibration;
this.duration = vibration.getArrivalTime();
}
public Vibration(int duration) {
this.duration = duration;
}
@ -12,4 +17,7 @@ public class Vibration {
return this.duration;
}
public org.bukkit.Vibration getVibration() {
return this.vibration;
}
}

View file

@ -41,9 +41,10 @@ public abstract class ParticleSpawner {
* @param center Center location of the effect
* @param isLongRange If the particle can be viewed from long range
* @param owner The player that owns the particles
* @param size The size of the particle
* @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
*/
public abstract void display(ParticleEffect particleEffect, ParticleColor color, Location center, boolean isLongRange, Player owner);
public abstract void display(ParticleEffect particleEffect, ParticleColor color, Location center, boolean isLongRange, Player owner, float size);
/**
* Displays a particle effect which requires additional data and is only
@ -80,7 +81,7 @@ public abstract class ParticleSpawner {
* @param owner The player that owns the particles
* @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
*/
public abstract void display(ParticleEffect particleEffect, ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner);
public abstract void display(ParticleEffect particleEffect, ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner, float size);
/**
* Displays a particle effect which requires additional data and is only
@ -136,9 +137,9 @@ public abstract class ParticleSpawner {
if (player == null || target == null)
return true;
for (MetadataValue meta : target.getMetadata("vanished"))
/*for (MetadataValue meta : target.getMetadata("vanished"))
if (meta.asBoolean())
return false;
return false;*/
return player.canSee(target);
}

View file

@ -34,7 +34,7 @@ public class ReflectiveParticleSpawner extends ParticleSpawner {
}
@Override
public void display(ParticleEffect particleEffect, ParticleColor color, Location center, boolean isLongRange, Player owner) {
public void display(ParticleEffect particleEffect, ParticleColor color, Location center, boolean isLongRange, Player owner, float size) {
if (!particleEffect.hasProperty(ParticleProperty.COLORABLE))
throw new ParticleColorException("This particle effect is not colorable");
@ -58,7 +58,7 @@ public class ReflectiveParticleSpawner extends ParticleSpawner {
}
@Override
public void display(ParticleEffect particleEffect, ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner) {
public void display(ParticleEffect particleEffect, ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner,float size) {
throw new IllegalStateException("This method is unavailable for legacy versions");
}

View file

@ -28,13 +28,13 @@ public class SpigotParticleSpawner extends ParticleSpawner {
}
@Override
public void display(ParticleEffect particleEffect, ParticleColor color, Location center, boolean isLongRange, Player owner) {
public void display(ParticleEffect particleEffect, ParticleColor color, Location center, boolean isLongRange, Player owner, float size) {
if (!particleEffect.hasProperty(ParticleProperty.COLORABLE))
throw new ParticleColorException("This particle effect is not colorable");
if (particleEffect == ParticleEffect.DUST && NMSUtil.getVersionNumber() >= 13) { // DUST uses a special data object for spawning in 1.13+
OrdinaryColor dustColor = (OrdinaryColor) color;
DustOptions dustOptions = new DustOptions(dustColor.toSpigot(), Setting.DUST_SIZE.getFloat());
DustOptions dustOptions = new DustOptions(dustColor.toSpigot(), size > 0 ? size : Setting.DUST_SIZE.getFloat());
for (Player player : getPlayersInRange(center, isLongRange, owner))
player.spawnParticle(particleEffect.getSpigotEnum(), center.getX(), center.getY(), center.getZ(), 1, 0, 0, 0, 0, dustOptions);
} else {
@ -65,14 +65,14 @@ public class SpigotParticleSpawner extends ParticleSpawner {
}
@Override
public void display(ParticleEffect particleEffect, ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner) {
public void display(ParticleEffect particleEffect, ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner, float size) {
if (NMSUtil.getVersionNumber() < 17)
return;
if (!particleEffect.hasProperty(ParticleProperty.COLORABLE_TRANSITION))
throw new ParticleDataException("This particle effect does not require additional data");
org.bukkit.Particle.DustTransition dustTransition = new org.bukkit.Particle.DustTransition(colorTransition.getStartColor().toSpigot(), colorTransition.getEndColor().toSpigot(), Setting.DUST_SIZE.getFloat());
org.bukkit.Particle.DustTransition dustTransition = new org.bukkit.Particle.DustTransition(colorTransition.getStartColor().toSpigot(), colorTransition.getEndColor().toSpigot(), size > 0 ? size : Setting.DUST_SIZE.getFloat());
for (Player player : getPlayersInRange(center, isLongRange, owner))
player.spawnParticle(particleEffect.getSpigotEnum(), center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, dustTransition);
}

View file

@ -8,6 +8,7 @@ import dev.esophose.playerparticles.util.ParticleUtils;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
public interface ParticleStyle {
@ -20,6 +21,18 @@ public interface ParticleStyle {
*/
List<PParticle> getParticles(ParticlePair particle, Location location);
/**
* Gets all the particles to display based on the style's logic
*
* @param particle The ParticlePair that contains the particle's data
* @param location The central location of the particles
* @param player The player that the particles are spawning on - null for fixed effects
* @return A List of PParticles to spawn
*/
default List<PParticle> getParticles(ParticlePair particle, Location location, Player player) {
return null;
}
/**
* Used to update timers for animations, called once per particle tick
*/

View file

@ -73,7 +73,7 @@ public class ParticleStyleBlockBreak extends DefaultParticleStyle implements Lis
return;
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.BLOCKBREAK)) {
Location loc = event.getBlock().getLocation().clone();
Location loc = event.getBlock().getLocation();
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.BLOCKBREAK.getParticles(particle, loc), false);
}
}

View file

@ -73,7 +73,7 @@ public class ParticleStyleBlockPlace extends DefaultParticleStyle implements Lis
return;
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.BLOCKPLACE)) {
Location loc = event.getBlock().getLocation().clone();
Location loc = event.getBlock().getLocation();
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.BLOCKPLACE.getParticles(particle, loc), false);
}
}

View file

@ -44,7 +44,7 @@ public class ParticleStyleCelebration extends DefaultParticleStyle {
public List<PParticle> getParticles(ParticlePair particle, Location location) {
return new ArrayList<>();
}
/**
* Spawns fireworks every spawnTime number of ticks
* This style uses two different effects, one is always 'firework'

View file

@ -80,7 +80,7 @@ public class ParticleStyleDeath extends DefaultParticleStyle implements Listener
if (pplayer == null)
return;
Location location = event.getEntity().getLocation().clone().add(0, 1, 0);
Location location = event.getEntity().getLocation().add(0, 1, 0);
new BukkitRunnable() {
private int totalDuration = 0;

View file

@ -54,7 +54,7 @@ public class ParticleStyleHurt extends DefaultParticleStyle implements Listener
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(player.getUniqueId());
if (pplayer != null) {
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.HURT)) {
Location loc = player.getLocation().clone().add(0, 1, 0);
Location loc = player.getLocation().add(0, 1, 0);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.HURT.getParticles(particle, loc), false);
}
}

View file

@ -71,7 +71,7 @@ public class ParticleStyleMove extends DefaultParticleStyle implements Listener
return;
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.MOVE)) {
Location loc = player.getLocation().clone();
Location loc = player.getLocation();
loc.setY(loc.getY() + 0.05);
this.particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.MOVE.getParticles(particle, loc), false);
}

View file

@ -89,7 +89,7 @@ public class ParticleStyleSwords extends DefaultParticleStyle implements Listene
}
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.SWORDS)) {
Location loc = entity.getLocation().clone().add(0, 1, 0);
Location loc = entity.getLocation().add(0, 1, 0);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.SWORDS.getParticles(particle, loc), false);
}
}

View file

@ -85,14 +85,14 @@ public class ParticleStyleTeleport extends DefaultParticleStyle implements Liste
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.TELEPORT)) {
if (this.before) {
Location loc1 = player.getLocation().clone();
Location loc1 = player.getLocation();
loc1.setY(loc1.getY() + 1);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.TELEPORT.getParticles(particle, loc1), false);
}
if (this.after) {
Bukkit.getScheduler().runTaskLater(PlayerParticles.getInstance(), () -> {
Location loc2 = player.getLocation().clone();
Location loc2 = player.getLocation();
loc2.setY(loc2.getY() + 1);
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.TELEPORT.getParticles(particle, loc2), false);
}, 1);

View file

@ -71,7 +71,7 @@ public class ParticleStyleTrail extends DefaultParticleStyle implements Listener
return;
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.TRAIL)) {
Location loc = player.getLocation().clone();
Location loc = player.getLocation();
loc.setY(loc.getY() + 1);
this.particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.TRAIL.getParticles(particle, loc), false);
}

View file

@ -17,7 +17,7 @@ public class VibrationUtil {
if (!particleEffect.hasProperty(ParticleEffect.ParticleProperty.VIBRATION))
throw new ParticleSpawner.ParticleDataException("This particle effect does not require additional data");
org.bukkit.Vibration data = new org.bukkit.Vibration(center, new org.bukkit.Vibration.Destination.BlockDestination(center), vibration.getDuration());
org.bukkit.Vibration data = vibration.getVibration() != null ? vibration.getVibration() : new org.bukkit.Vibration(center, new org.bukkit.Vibration.Destination.BlockDestination(center), vibration.getDuration());
for (Player player : SpigotParticleSpawner.getPlayersInRange(center, isLongRange, owner))
player.spawnParticle(particleEffect.getSpigotEnum(), center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, data);
}

View file

@ -28,7 +28,7 @@ public class ParsableLocation extends Parsable<Location> {
if (targetBlock.getLocation().distanceSquared(player.getLocation()) > maxDistanceSqrd)
return null; // Looking at a block too far away
return targetBlock.getLocation().clone().add(0.5, 0.5, 0.5); // Center of block
return targetBlock.getLocation().add(0.5, 0.5, 0.5); // Center of block
}
String input2 = inputs.remove(0);