diff --git a/README.md b/README.md index 91e3552..8e7ba58 100644 --- a/README.md +++ b/README.md @@ -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.\.horizontalVelocity | Decimal number | The horizontal (sideways) velocity applied to launchpads of type \ if not overridden for the block. | | launchpad.materialVelocities.\.verticalVelocity | Decimal number | The vertical (sideways) velocity applied to launchpads of type \ 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. | \ No newline at end of file diff --git a/src/main/java/net/knarcraft/launchpad/config/LaunchpadConfiguration.java b/src/main/java/net/knarcraft/launchpad/config/LaunchpadConfiguration.java index feacf40..12884b4 100644 --- a/src/main/java/net/knarcraft/launchpad/config/LaunchpadConfiguration.java +++ b/src/main/java/net/knarcraft/launchpad/config/LaunchpadConfiguration.java @@ -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 launchpadMaterials = new HashSet<>(); private @NotNull Set materialWhitelist = new HashSet<>(); @@ -135,6 +141,28 @@ public class LaunchpadConfiguration { return loadedMaterials; } + /** + * Adds a trail behind the player with the given id + * + * @param playerId

The id of the player to add the trail to

+ */ + public void addTrail(UUID playerId) { + if (trailSpawner != null) { + trailSpawner.startTrail(playerId); + } + } + + /** + * Removes the trail behind the player with the given id + * + * @param playerId

The id of the player to remove the trail for

+ */ + 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 materialConfigs; @@ -168,8 +205,22 @@ public class LaunchpadConfiguration { materialConfigs = new HashMap<>(); } - particleTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Launchpad.getInstance(), - new ParticleSpawner(particleConfig, materialConfigs), 20, particleConfig.getSpawnDelay()); + 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)); } } diff --git a/src/main/java/net/knarcraft/launchpad/config/LaunchpadParticleConfig.java b/src/main/java/net/knarcraft/launchpad/config/LaunchpadParticleConfig.java index da97e07..4ac4442 100644 --- a/src/main/java/net/knarcraft/launchpad/config/LaunchpadParticleConfig.java +++ b/src/main/java/net/knarcraft/launchpad/config/LaunchpadParticleConfig.java @@ -25,7 +25,7 @@ public class LaunchpadParticleConfig { * * @param particlesSection

The configuration section containing the particle's settings

*/ - public LaunchpadParticleConfig(ConfigurationSection particlesSection) { + public LaunchpadParticleConfig(@NotNull ConfigurationSection particlesSection) { @NotNull Particle particleType; try { particleType = Particle.valueOf(particlesSection.getString("type")); diff --git a/src/main/java/net/knarcraft/launchpad/listener/LaunchpadUseListener.java b/src/main/java/net/knarcraft/launchpad/listener/LaunchpadUseListener.java index 3a884e6..bd0fe4f 100644 --- a/src/main/java/net/knarcraft/launchpad/listener/LaunchpadUseListener.java +++ b/src/main/java/net/knarcraft/launchpad/listener/LaunchpadUseListener.java @@ -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()); } /** diff --git a/src/main/java/net/knarcraft/launchpad/task/ParticleTrailSpawner.java b/src/main/java/net/knarcraft/launchpad/task/ParticleTrailSpawner.java new file mode 100644 index 0000000..d04d23d --- /dev/null +++ b/src/main/java/net/knarcraft/launchpad/task/ParticleTrailSpawner.java @@ -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 playersWithTrails = new HashSet<>(); + private final Particle particle; + + /** + * Instantiates a new particle trail spawner + * + * @param particle

The type of particle used for the trail

+ */ + public ParticleTrailSpawner(@NotNull Particle particle) { + this.particle = particle; + } + + @Override + public void run() { + Set 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

The id of the player to remove the trail for

+ */ + public void removeTrail(UUID playerId) { + this.playersWithTrails.remove(playerId); + } + + /** + * Adds a trail behind the player with the given id + * + * @param playerId

The id of the player to add the trail to

+ */ + public void startTrail(UUID playerId) { + this.playersWithTrails.add(playerId); + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ea65dde..aeb626b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -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,31 +21,40 @@ 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 mode used for spawning particles. Valid values are: SINGLE, SQUARE, PYRAMID, SPHERE, CUBE and CIRCLE - mode: SQUARE - # The type of particle to spawn. See https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html - type: DRIP_LAVA - # 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 - offsetX: 0 - # The offset, or spread of the particles in the Y direction, relative to the launchpad - offsetY: 0 - # The offset, or spread of the particles in the Z direction, relative to the launchpad - offsetZ: 0 - # The height above the launchpad the particle should spawn. 1 = one block above, 0.5 = half a block above - heightOffset: 0.5 - # 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 - # 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 + # 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: SINGLE + # The type of particle to spawn. See https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html + 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 + offsetX: 0 + # The offset, or spread of the particles in the Y direction, relative to the launchpad + offsetY: 0 + # The offset, or spread of the particles in the Z direction, relative to the launchpad + offsetZ: 0 + # The height above the launchpad the particle should spawn. 1 = one block above, 0.5 = half a block above + heightOffset: 0.5 + # 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.1 + # Extra data for the particle. Valid values depend on the particle type. + extra: 0 # 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: [ ] \ No newline at end of file