From c35325c5a7cdb16fde2d1d827859d4c1367356fd Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 12 Feb 2024 23:06:44 +0100 Subject: [PATCH] Improves particles Allows specifying separate particle trails for each player. Removes random particles as a class option. Adds a particle config builder for easier particle specification. --- .../particle/ParticleConfigBuilder.java | 148 ++++++++++++++++++ .../particle/ParticleTrailSpawner.java | 43 ++--- 2 files changed, 173 insertions(+), 18 deletions(-) create mode 100644 src/main/java/net/knarcraft/knarlib/particle/ParticleConfigBuilder.java diff --git a/src/main/java/net/knarcraft/knarlib/particle/ParticleConfigBuilder.java b/src/main/java/net/knarcraft/knarlib/particle/ParticleConfigBuilder.java new file mode 100644 index 0000000..29e1ce7 --- /dev/null +++ b/src/main/java/net/knarcraft/knarlib/particle/ParticleConfigBuilder.java @@ -0,0 +1,148 @@ +package net.knarcraft.knarlib.particle; + +import org.bukkit.Particle; +import org.jetbrains.annotations.NotNull; + +/** + * A builder for creating particle configurations + * + *

The default behavior will spawn a single particle with no offset or extra data, and density 1.

+ */ +@SuppressWarnings("unused") +public class ParticleConfigBuilder { + + private final Particle particleType; + private ParticleMode particleMode = ParticleMode.SINGLE; + private int particleAmount = 1; + private double particleDensity = 1; + private double heightOffset = 0; + private double offsetX = 0; + private double offsetY = 0; + private double offsetZ = 0; + private double extra = 0; + + /** + * Instantiates a new particle config builder + * + * @param particleType

The type of particle to spawn

+ */ + public ParticleConfigBuilder(@NotNull Particle particleType) { + this.particleType = particleType; + } + + /** + * Sets the mode to use when spawning the particles + * + * @param particleMode

The mode to use

+ * @return

This particle configuration builder

+ */ + public @NotNull ParticleConfigBuilder setMode(@NotNull ParticleMode particleMode) { + this.particleMode = particleMode; + return this; + } + + /** + * Sets the amount of particles to spawn + * + * @param particleAmount

The number/amount of particles to spawn

+ * @return

This particle configuration builder

+ */ + public @NotNull ParticleConfigBuilder setAmount(int particleAmount) { + this.particleAmount = particleAmount; + return this; + } + + /** + * Sets the density of the particles to spawn + * + * @param particleDensity

The new density

+ * @return

This particle configuration builder

+ */ + public @NotNull ParticleConfigBuilder setDensity(double particleDensity) { + this.particleDensity = particleDensity; + return this; + } + + /** + * Sets the x,y,z offsets of the spawned particles + * + *

These values control the spread of the spawned particles

+ * + * @param offsetX

The offset in the x-direction

+ * @param offsetY

The offset in the y-direction

+ * @param offsetZ

The offset in the z-direction

+ * @return

This particle configuration builder

+ */ + public @NotNull ParticleConfigBuilder setOffsets(double offsetX, double offsetY, double offsetZ) { + this.offsetX = offsetX; + this.offsetY = offsetY; + this.offsetZ = offsetZ; + return this; + } + + /** + * Sets the x offset of the spawned particles + * + * @param offsetX

The offset in the x-direction

+ * @return

This particle configuration builder

+ */ + public @NotNull ParticleConfigBuilder setXOffset(double offsetX) { + this.offsetX = offsetX; + return this; + } + + /** + * Sets the y offset of the spawned particles + * + * @param offsetY

The offset in the y-direction

+ * @return

This particle configuration builder

+ */ + public @NotNull ParticleConfigBuilder setYOffset(double offsetY) { + this.offsetY = offsetY; + return this; + } + + /** + * Sets the z offset of the spawned particles + * + * @param offsetZ

The offset in the z-direction

+ * @return

This particle configuration builder

+ */ + public @NotNull ParticleConfigBuilder setZOffset(double offsetZ) { + this.offsetZ = offsetZ; + return this; + } + + /** + * Sets the extra data for the spawned particles + * + * @param extra

The extra data to set

+ * @return

This particle configuration builder

+ */ + public @NotNull ParticleConfigBuilder setExtra(double extra) { + this.extra = extra; + return this; + } + + /** + * Sets the height offset for the spawned particles + * + * @param heightOffset

The height offset to use

+ * @return

This particle configuration builder

+ */ + public @NotNull ParticleConfigBuilder setHeightOffset(double heightOffset) { + this.heightOffset = heightOffset; + return this; + } + + /** + * Builds the particle configuration + * + * @return

The built particle configuration

+ */ + public @NotNull ParticleConfig build() { + return new ParticleConfig(particleMode, particleType, particleAmount, particleDensity, heightOffset, offsetX, + offsetY, offsetZ, extra); + } + +} diff --git a/src/main/java/net/knarcraft/knarlib/particle/ParticleTrailSpawner.java b/src/main/java/net/knarcraft/knarlib/particle/ParticleTrailSpawner.java index 19c2275..daec96b 100644 --- a/src/main/java/net/knarcraft/knarlib/particle/ParticleTrailSpawner.java +++ b/src/main/java/net/knarcraft/knarlib/particle/ParticleTrailSpawner.java @@ -7,6 +7,7 @@ import org.bukkit.Particle; import org.bukkit.World; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.HashSet; @@ -26,20 +27,16 @@ public final class ParticleTrailSpawner implements Runnable { private final Map playerParticles = new HashMap<>(); private final Random random = new Random(); private final Particle particle; - private final boolean randomTrailType; private final List randomTrailTypes; /** * Instantiates a new particle trail spawner * * @param particle

The type of particle used for the trail

- * @param randomTrailType

Whether to use a random trail type each time a player is launched

* @param randomTrailTypes

The types of particles to use for random trails

*/ - public ParticleTrailSpawner(@NotNull Particle particle, boolean randomTrailType, - @NotNull List randomTrailTypes) { + public ParticleTrailSpawner(@NotNull Particle particle, @NotNull List randomTrailTypes) { this.particle = particle; - this.randomTrailType = randomTrailType; this.randomTrailTypes = randomTrailTypes; } @@ -54,6 +51,7 @@ public final class ParticleTrailSpawner implements Runnable { continue; } + // Get the world and location to spawn the particle at Location playerLocation = player.getLocation(); World playerWorld = playerLocation.getWorld(); if (playerWorld == null) { @@ -61,19 +59,13 @@ public final class ParticleTrailSpawner implements Runnable { } // Decide on which type of particle to spawn - Particle spawnParticle; - if (randomTrailType) { - spawnParticle = playerParticles.get(playerId); - if (spawnParticle == null) { - spawnParticle = this.particle; - } - } else { + Particle spawnParticle = playerParticles.get(playerId); + if (spawnParticle == null) { spawnParticle = this.particle; } // Spawn a trail particle - ParticleConfig particleConfig = new ParticleConfig(ParticleMode.SINGLE, spawnParticle, - 1, 1, 0, 0, 0, 0, 0); + ParticleConfig particleConfig = new ParticleConfigBuilder(spawnParticle).build(); ParticleHelper.spawnParticle(playerWorld, playerLocation, particleConfig, 0); } playersWithTrails.removeAll(offlinePlayers); @@ -91,21 +83,36 @@ public final class ParticleTrailSpawner implements Runnable { } /** - * Adds a trail behind the player with the given id + * Adds a random trail behind the player with the given id * * @param playerId

The id of the player to add the trail to

*/ - public void startTrail(@NotNull UUID playerId) { + public void startRandomTrail(@NotNull UUID playerId) { this.playerParticles.put(playerId, randomParticle()); this.playersWithTrails.add(playerId); } /** - * Gets a random particle in the whitelist + * Adds a trail behind the player with the given id * - * @return

A random particle

+ * @param playerId

The id of the player to add the trail to

+ * @param particle

The particle to spawn, or null for the particle specified in the constructor

+ */ + public void startTrail(@NotNull UUID playerId, @Nullable Particle particle) { + this.playerParticles.put(playerId, particle); + this.playersWithTrails.add(playerId); + } + + /** + * Gets a random particle from random the specified trail types + * + * @return

A random particle, or EGG_CRACK if no random trail types have been specified

*/ private @NotNull Particle randomParticle() { + if (this.randomTrailTypes.isEmpty()) { + return Particle.EGG_CRACK; + } + Particle spawnParticle = null; while (spawnParticle == null || spawnParticle.getDataType() != Void.class) { spawnParticle = randomTrailTypes.get(random.nextInt(randomTrailTypes.size()));