Adds particle trails to launched players

Adds configurable particle trails that appear when a player is launched, and disappear when the player lands.
Changes some configuration paths to clarify the structure.
This commit is contained in:
Kristian Knarvik 2023-07-05 12:41:26 +02:00
parent 322cb804a7
commit 19477a31ae
6 changed files with 175 additions and 38 deletions

View File

@ -40,15 +40,18 @@ If you alter several launchpad values in succession, they'll all be applied to t
| launchpad.horizontalVelocity | Decimal number | The horizontal (sideways) velocity applied to launchpads if not specified otherwise. |
| launchpad.materialVelocities.\<MATERIAL>.horizontalVelocity | Decimal number | The horizontal (sideways) velocity applied to launchpads of type \<MATERIAL> if not overridden for the block. |
| launchpad.materialVelocities.\<MATERIAL>.verticalVelocity | Decimal number | The vertical (sideways) velocity applied to launchpads of type \<MATERIAL> if not overridden for the block. |
| launchpad.particles.trailsEnabled | True / False | Whether to enable particle trails behind players |
| launchpad.particles.trailSpawnDelay | Positive integer | The amount of ticks (1 second = 20 ticks) between each time the particle(s) of a trail should be spawned. |
| launchpad.particles.trailType | [Particle](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html) | The type of trail to spawn behind launched players. |
| launchpad.particles.enabled | True / False | Whether to display some kind of particle effect above manually added launchpads. |
| launchpad.particles.mode | SINGLE / SQUARE / PYRAMID / SPHERE / CIRCLE / CUBE | The mode used for drawing particles. SINGLE directly spawns the particle(s) in one spot above the launchpad. The other ones spawn particles a bunch of times in a pattern. |
| launchpad.particles.type | [Particle](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html) | The type of particle to spawn above launchpads. |
| launchpad.particles.amount | Positive integer | The amount of particles to spawn. Use 1 if mode is anything except SINGLE, unless you know what you are doing! |
| launchpad.particles.offsetX | Decimal number | The offset, or spread of the particles in the X direction, relative to the launchpad |
| launchpad.particles.offsetY | Decimal number | The offset, or spread of the particles in the Y direction, relative to the launchpad |
| launchpad.particles.offsetZ | Decimal number | The offset, or spread of the particles in the Z direction, relative to the launchpad |
| launchpad.particles.heightOffset | Decimal number | The amount of blocks above the launchpad the particle should spawn. 0.5 = half a block. 1 = one block. |
| launchpad.particles.particleDensity | Decimal number | A definition for the number of particles used to draw shapes. The number of particles is basically `distance / particleDensity`, so lower numbers create a more dense shape. |
| launchpad.particles.extra | Decimal number | Extra data for the specific particle. Check the Spigot documentation for details. |
| launchpad.particles.spawnDelay | Positive integer | The amount of ticks (1 second = 20 ticks) between each time the particle(s) should be spawned again. Depending on the particle, higher values will make the particle(s) completely disappear and reappear. |
| launchpad.particles.particle.mode | SINGLE / SQUARE / PYRAMID / SPHERE / CIRCLE / CUBE | The mode used for drawing particles. SINGLE directly spawns the particle(s) in one spot above the launchpad. The other ones spawn particles a bunch of times in a pattern. |
| launchpad.particles.particle.type | [Particle](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html) | The type of particle to spawn above launchpads. |
| launchpad.particles.particle.amount | Positive integer | The amount of particles to spawn. Use 1 if mode is anything except SINGLE, unless you know what you are doing! |
| launchpad.particles.particle.offsetX | Decimal number | The offset, or spread of the particles in the X direction, relative to the launchpad |
| launchpad.particles.particle.offsetY | Decimal number | The offset, or spread of the particles in the Y direction, relative to the launchpad |
| launchpad.particles.particle.offsetZ | Decimal number | The offset, or spread of the particles in the Z direction, relative to the launchpad |
| launchpad.particles.particle.heightOffset | Decimal number | The amount of blocks above the launchpad the particle should spawn. 0.5 = half a block. 1 = one block. |
| launchpad.particles.particle.particleDensity | Decimal number | A definition for the number of particles used to draw shapes. The number of particles is basically `distance / particleDensity`, so lower numbers create a more dense shape. |
| launchpad.particles.particle.extra | Decimal number | Extra data for the specific particle. Check the Spigot documentation for details. |
| launchpad.particles.materialParticles | Configuration section | This section allows specifying different particle configurations for a material or a material tag. So you'd set materialParticles.LIGHT_WEIGHTED_PRESSURE_PLATE.type to set the particle type for LIGHT_WEIGHTED_PRESSURE_PLATE. |

View File

@ -3,9 +3,11 @@ package net.knarcraft.launchpad.config;
import net.knarcraft.launchpad.Launchpad;
import net.knarcraft.launchpad.launchpad.LaunchpadBlockHandler;
import net.knarcraft.launchpad.task.ParticleSpawner;
import net.knarcraft.launchpad.task.ParticleTrailSpawner;
import net.knarcraft.launchpad.util.MaterialHelper;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
@ -15,6 +17,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
/**
@ -26,7 +29,10 @@ public class LaunchpadConfiguration {
private double horizontalVelocity;
private double verticalVelocity;
private boolean particlesEnabled;
private boolean trailsEnabled;
private int particleTaskId = -1;
private int particleTrailTaskId = -1;
private ParticleTrailSpawner trailSpawner = null;
private @NotNull Set<Material> launchpadMaterials = new HashSet<>();
private @NotNull Set<Material> materialWhitelist = new HashSet<>();
@ -135,6 +141,28 @@ public class LaunchpadConfiguration {
return loadedMaterials;
}
/**
* Adds a trail behind the player with the given id
*
* @param playerId <p>The id of the player to add the trail to</p>
*/
public void addTrail(UUID playerId) {
if (trailSpawner != null) {
trailSpawner.startTrail(playerId);
}
}
/**
* Removes the trail behind the player with the given id
*
* @param playerId <p>The id of the player to remove the trail for</p>
*/
public void removeTrail(UUID playerId) {
if (trailSpawner != null) {
trailSpawner.removeTrail(playerId);
}
}
/**
* Loads configuration values related to launchpad particles
*
@ -148,16 +176,25 @@ public class LaunchpadConfiguration {
return;
}
boolean previousEnabled = this.particlesEnabled;
boolean previousTrailsEnabled = this.trailsEnabled;
this.particlesEnabled = particlesSection.getBoolean("enabled", false);
this.trailsEnabled = particlesSection.getBoolean("trailsEnabled", false);
// Cancel previous particle spawning task if previously enabled
if (previousEnabled) {
Bukkit.getScheduler().cancelTask(particleTaskId);
}
if (previousTrailsEnabled) {
Bukkit.getScheduler().cancelTask(particleTrailTaskId);
}
// Start particle spawning if enabled
if (this.particlesEnabled) {
LaunchpadParticleConfig particleConfig = new LaunchpadParticleConfig(particlesSection);
ConfigurationSection particleSection = particlesSection.getConfigurationSection("particle");
LaunchpadParticleConfig particleConfig = null;
if (particleSection != null) {
particleConfig = new LaunchpadParticleConfig(particleSection);
}
// Load any per-material configuration options
Map<Material, LaunchpadParticleConfig> materialConfigs;
@ -168,11 +205,25 @@ public class LaunchpadConfiguration {
materialConfigs = new HashMap<>();
}
if (particleConfig != null) {
particleTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Launchpad.getInstance(),
new ParticleSpawner(particleConfig, materialConfigs), 20, particleConfig.getSpawnDelay());
}
}
if (this.trailsEnabled) {
Particle trailType;
try {
trailType = Particle.valueOf(particlesSection.getString("trailType"));
} catch (IllegalArgumentException | NullPointerException exception) {
trailType = Particle.EGG_CRACK;
}
trailSpawner = new ParticleTrailSpawner(trailType);
particleTrailTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Launchpad.getInstance(),
trailSpawner, 20, particlesSection.getInt("trailSpawnDelay", 1));
}
}
/**
* Loads all per-material particle configuration options
*

View File

@ -25,7 +25,7 @@ public class LaunchpadParticleConfig {
*
* @param particlesSection <p>The configuration section containing the particle's settings</p>
*/
public LaunchpadParticleConfig(ConfigurationSection particlesSection) {
public LaunchpadParticleConfig(@NotNull ConfigurationSection particlesSection) {
@NotNull Particle particleType;
try {
particleType = Particle.valueOf(particlesSection.getString("type"));

View File

@ -60,6 +60,13 @@ public class LaunchpadUseListener implements Listener {
}
}
Player player = event.getPlayer();
// Remove the player's trail
if (player.getVelocity().getY() <= 0) {
Launchpad.getInstance().getConfiguration().removeTrail(player.getUniqueId());
}
// Pressure plates are detected in onPressurePlateUse instead
Material type = block.getType();
if (Tag.PRESSURE_PLATES.isTagged(type)) {
@ -72,8 +79,6 @@ public class LaunchpadUseListener implements Listener {
return;
}
Player player = event.getPlayer();
// Launch the player
if (launchpad != null) {
launch(player, launchpad);
@ -126,6 +131,7 @@ public class LaunchpadUseListener implements Listener {
direction = direction.normalize().multiply(horizontalVelocity);
direction = direction.add(new Vector(0, verticalVelocity, 0));
player.setVelocity(direction);
Launchpad.getInstance().getConfiguration().addTrail(player.getUniqueId());
}
/**

View File

@ -0,0 +1,70 @@
package net.knarcraft.launchpad.task;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* A task for spawning trails behind players
*/
public class ParticleTrailSpawner implements Runnable {
private final Set<UUID> playersWithTrails = new HashSet<>();
private final Particle particle;
/**
* Instantiates a new particle trail spawner
*
* @param particle <p>The type of particle used for the trail</p>
*/
public ParticleTrailSpawner(@NotNull Particle particle) {
this.particle = particle;
}
@Override
public void run() {
Set<UUID> offlinePlayers = new HashSet<>();
for (UUID playerId : playersWithTrails) {
Player player = Bukkit.getPlayer(playerId);
if (player == null) {
offlinePlayers.add(playerId);
continue;
}
Location playerLocation = player.getLocation();
World playerWorld = playerLocation.getWorld();
if (playerWorld == null) {
continue;
}
playerWorld.spawnParticle(this.particle, playerLocation, 1);
}
playersWithTrails.removeAll(offlinePlayers);
}
/**
* Removes the trail behind the player with the given id
*
* @param playerId <p>The id of the player to remove the trail for</p>
*/
public void removeTrail(UUID playerId) {
this.playersWithTrails.remove(playerId);
}
/**
* Adds a trail behind the player with the given id
*
* @param playerId <p>The id of the player to add the trail to</p>
*/
public void startTrail(UUID playerId) {
this.playersWithTrails.add(playerId);
}
}

View File

@ -1,9 +1,7 @@
launchpad:
# A list of all materials automatically enabled as a launch-pad. Use +PRESSURE_PLATES for all pressure plates, or
# +WOODEN_PRESSURE_PLATES for all wooden pressure plates.
materials:
- LIGHT_WEIGHTED_PRESSURE_PLATE # This is the gold pressure plate
- HEAVY_WEIGHTED_PRESSURE_PLATE # This is the iron pressure plate
materials: [ ]
# A whitelist for the materials that can be manually set as a launchpad. If non-empty, only the materials listed can
# be clicked after executing "/launchpad add" or a different launchpad-editing command. As with materials, this
# supports tags like +PRESSURE_PLATES
@ -23,12 +21,24 @@ launchpad:
horizontalVelocity: 1
# Settings for particles displayed above launchpads
particles:
# Whether to enable particle trails behind players
trailsEnabled: false
# The amount of ticks (1 second = 20 ticks) between each time the particle(s) of a trail should be spawned.
trailSpawnDelay: 5
# The type of trail to spawn behind launched players.
# See https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html
trailType: EGG_CRACK
# Whether to enable particles above launchpads
enabled: false
# The amount of ticks (1 second = 20 ticks) between each time the particle(s) should be spawned again. Depending on
# the particle, higher values will make the particle(s) completely disappear and reappear.
spawnDelay: 20
# Options for the particle(s) spawned for each launchpad
particle:
# The mode used for spawning particles. Valid values are: SINGLE, SQUARE, PYRAMID, SPHERE, CUBE and CIRCLE
mode: SQUARE
mode: SINGLE
# The type of particle to spawn. See https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html
type: DRIP_LAVA
type: ASH
# The number of particles to spawn every second
amount: 1
# The offset, or spread of the particles in the X direction, relative to the launchpad
@ -42,12 +52,9 @@ launchpad:
# The density of particles when using square or circle modes. For example, square with density = 1 will have 1
# particle for each corner, density = 0.1 will have 10 particles on each side and density = 0.01 will have 100
# particles on each side.
particleDensity: 0.5
particleDensity: 0.1
# Extra data for the particle. Valid values depend on the particle type.
extra: 0
# The amount of ticks (1 second = 20 ticks) between each time the particle(s) should be spawned again. Depending on
# the particle, higher values will make the particle(s) completely disappear and reappear.
spawnDelay: 20
# Particle configurations per material. So you'd set materialParticles.LIGHT_WEIGHTED_PRESSURE_PLATE.type to set the
# particle type for LIGHT_WEIGHTED_PRESSURE_PLATE.
materialParticles: [ ]