mirror of
				https://github.com/SunNetservers/Launchpad.git
				synced 2025-10-30 17:23:46 +01:00 
			
		
		
		
	Uses particle spawning code from KnarLib
This commit is contained in:
		
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -97,7 +97,7 @@ | ||||
|         <dependency> | ||||
|             <groupId>net.knarcraft</groupId> | ||||
|             <artifactId>knarlib</artifactId> | ||||
|             <version>1.1-SNAPSHOT</version> | ||||
|             <version>1.2</version> | ||||
|             <scope>compile</scope> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
|   | ||||
| @@ -1,18 +1,22 @@ | ||||
| package net.knarcraft.launchpad.config; | ||||
|  | ||||
| import net.knarcraft.knarlib.particle.ParticleConfig; | ||||
| import net.knarcraft.knarlib.particle.ParticleSpawner; | ||||
| import net.knarcraft.knarlib.particle.ParticleTrailSpawner; | ||||
| import net.knarcraft.knarlib.util.ParticleHelper; | ||||
| 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.block.Block; | ||||
| import org.bukkit.configuration.ConfigurationSection; | ||||
| import org.bukkit.configuration.file.FileConfiguration; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| @@ -33,6 +37,7 @@ public class LaunchpadConfiguration { | ||||
|     private boolean trailsEnabled; | ||||
|     private int particleTaskId = -1; | ||||
|     private int particleTrailTaskId = -1; | ||||
|     private UUID particleStoredCalculationsId; | ||||
|     private ParticleTrailSpawner trailSpawner = null; | ||||
|     private @NotNull Set<Material> launchpadMaterials = new HashSet<>(); | ||||
|     private @NotNull Set<Material> materialWhitelist = new HashSet<>(); | ||||
| @@ -184,6 +189,7 @@ public class LaunchpadConfiguration { | ||||
|         // Cancel previous particle spawning task if previously enabled | ||||
|         if (previousEnabled) { | ||||
|             Bukkit.getScheduler().cancelTask(particleTaskId); | ||||
|             ParticleHelper.clearStoredCalculations(particleStoredCalculationsId); | ||||
|         } | ||||
|         if (previousTrailsEnabled) { | ||||
|             Bukkit.getScheduler().cancelTask(particleTrailTaskId); | ||||
| @@ -234,13 +240,13 @@ public class LaunchpadConfiguration { | ||||
|      */ | ||||
|     private void loadLaunchpadParticleConfig(ConfigurationSection particlesSection) { | ||||
|         ConfigurationSection particleSection = particlesSection.getConfigurationSection("particle"); | ||||
|         LaunchpadParticleConfig particleConfig = null; | ||||
|         ParticleConfig particleConfig = null; | ||||
|         if (particleSection != null) { | ||||
|             particleConfig = new LaunchpadParticleConfig(particleSection); | ||||
|             particleConfig = new ParticleConfig(particleSection); | ||||
|         } | ||||
|  | ||||
|         // Load any per-material configuration options | ||||
|         Map<Material, LaunchpadParticleConfig> materialConfigs; | ||||
|         Map<Material, ParticleConfig> materialConfigs; | ||||
|         ConfigurationSection perMaterialSection = particlesSection.getConfigurationSection("materialParticles"); | ||||
|         if (perMaterialSection != null) { | ||||
|             materialConfigs = loadMaterialParticleConfigs(perMaterialSection); | ||||
| @@ -249,27 +255,35 @@ public class LaunchpadConfiguration { | ||||
|         } | ||||
|  | ||||
|         if (particleConfig != null) { | ||||
|             particleTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Launchpad.getInstance(), | ||||
|                     new ParticleSpawner(particleConfig, materialConfigs), 20, particleConfig.getSpawnDelay()); | ||||
|             ParticleSpawner particleSpawner = new ParticleSpawner(particleConfig, materialConfigs, this::getLaunchpadBlocks); | ||||
|             particleTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Launchpad.getInstance(), particleSpawner, | ||||
|                     20, particlesSection.getInt("spawnDelay", 20)); | ||||
|             particleStoredCalculationsId = particleSpawner.getStoredCalculationId(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private Collection<Block> getLaunchpadBlocks() { | ||||
|         Set<Block> blocks = new HashSet<>(); | ||||
|         LaunchpadBlockHandler.getAll().forEach((item) -> blocks.add(item.getBlock())); | ||||
|         return blocks; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Loads all per-material particle configuration options | ||||
|      * | ||||
|      * @param perMaterialSection <p>The configuration section containing per-material particle options</p> | ||||
|      * @return <p>The loaded per-material particle configuration options</p> | ||||
|      */ | ||||
|     private @NotNull Map<Material, LaunchpadParticleConfig> loadMaterialParticleConfigs( | ||||
|     private @NotNull Map<Material, ParticleConfig> loadMaterialParticleConfigs( | ||||
|             @NotNull ConfigurationSection perMaterialSection) { | ||||
|         Map<Material, LaunchpadParticleConfig> materialConfigs = new HashMap<>(); | ||||
|         Map<Material, ParticleConfig> materialConfigs = new HashMap<>(); | ||||
|         for (String key : perMaterialSection.getKeys(false)) { | ||||
|             Set<Material> materials = MaterialHelper.loadMaterialString(key); | ||||
|             ConfigurationSection materialSection = perMaterialSection.getConfigurationSection(key); | ||||
|             if (materialSection == null) { | ||||
|                 continue; | ||||
|             } | ||||
|             LaunchpadParticleConfig materialParticleConfig = new LaunchpadParticleConfig(materialSection); | ||||
|             ParticleConfig materialParticleConfig = new ParticleConfig(materialSection); | ||||
|             for (Material material : materials) { | ||||
|                 materialConfigs.put(material, materialParticleConfig); | ||||
|             } | ||||
|   | ||||
| @@ -1,151 +0,0 @@ | ||||
| package net.knarcraft.launchpad.config; | ||||
|  | ||||
| import org.bukkit.Particle; | ||||
| import org.bukkit.configuration.ConfigurationSection; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
|  | ||||
| /** | ||||
|  * A configuration describing a launchpad | ||||
|  */ | ||||
| public class LaunchpadParticleConfig { | ||||
|  | ||||
|     private final ParticleMode particleMode; | ||||
|     private final Particle particleType; | ||||
|     private final int particleAmount; | ||||
|     private final double particleDensity; | ||||
|     private final double heightOffset; | ||||
|     private final int spawnDelay; | ||||
|     private final double offsetX; | ||||
|     private final double offsetY; | ||||
|     private final double offsetZ; | ||||
|     private final double extra; | ||||
|  | ||||
|     /** | ||||
|      * Instantiates a new particle config | ||||
|      * | ||||
|      * @param particlesSection <p>The configuration section containing the particle's settings</p> | ||||
|      */ | ||||
|     public LaunchpadParticleConfig(@NotNull ConfigurationSection particlesSection) { | ||||
|         @NotNull Particle particleType; | ||||
|         try { | ||||
|             particleType = Particle.valueOf(particlesSection.getString("type")); | ||||
|         } catch (IllegalArgumentException | NullPointerException exception) { | ||||
|             particleType = Particle.ASH; | ||||
|         } | ||||
|         this.particleType = particleType; | ||||
|         this.particleAmount = particlesSection.getInt("amount", 30); | ||||
|         this.offsetX = particlesSection.getDouble("offsetX", 0.5); | ||||
|         this.offsetY = particlesSection.getDouble("offsetY", 1); | ||||
|         this.offsetZ = particlesSection.getDouble("offsetZ", 0.5); | ||||
|         this.heightOffset = particlesSection.getDouble("heightOffset", 0.5); | ||||
|         this.extra = particlesSection.getDouble("extra", 0); | ||||
|         this.spawnDelay = particlesSection.getInt("spawnDelay", 20); | ||||
|         ParticleMode particleMode; | ||||
|         try { | ||||
|             particleMode = ParticleMode.valueOf(particlesSection.getString("mode")); | ||||
|         } catch (IllegalArgumentException | NullPointerException exception) { | ||||
|             particleMode = ParticleMode.SINGLE; | ||||
|         } | ||||
|         this.particleMode = particleMode; | ||||
|  | ||||
|         // Make sure particle density is between 1 (inclusive) and 0 (exclusive) | ||||
|         double particleDensity = particlesSection.getDouble("particleDensity", 0.1); | ||||
|         if (particleDensity <= 0) { | ||||
|             particleDensity = 0.1; | ||||
|         } else if (particleDensity > 360) { | ||||
|             particleDensity = 360; | ||||
|         } | ||||
|         this.particleDensity = particleDensity; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The mode to use when drawing/spawning the particle(s) | ||||
|      * | ||||
|      * @return <p>The particle mode</p> | ||||
|      */ | ||||
|     public ParticleMode getParticleMode() { | ||||
|         return particleMode; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The type of particle to spawn | ||||
|      * | ||||
|      * @return <p>The particle type</p> | ||||
|      */ | ||||
|     public Particle getParticleType() { | ||||
|         return particleType; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The amount of particles to spawn | ||||
|      * | ||||
|      * @return <p>The amount of particles</p> | ||||
|      */ | ||||
|     public int getParticleAmount() { | ||||
|         return particleAmount; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The density of particles to use in shapes closer to 0 causes larger density | ||||
|      * | ||||
|      * @return <p>The particle density</p> | ||||
|      */ | ||||
|     public double getParticleDensity() { | ||||
|         return particleDensity; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The number of blocks above the launchpad the particle(s) should spawn | ||||
|      * | ||||
|      * @return <p>The y-offset</p> | ||||
|      */ | ||||
|     public double getHeightOffset() { | ||||
|         return heightOffset; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the delay in ticks to wait before spawning the particle(s) again | ||||
|      * | ||||
|      * @return <p>The spawn delay</p> | ||||
|      */ | ||||
|     public int getSpawnDelay() { | ||||
|         return spawnDelay; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The offset/spread of particles in the x-direction | ||||
|      * | ||||
|      * @return <p>The x-offset</p> | ||||
|      */ | ||||
|     public double getOffsetX() { | ||||
|         return offsetX; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The offset/spread of particles in the y-direction | ||||
|      * | ||||
|      * @return <p>The y-offset</p> | ||||
|      */ | ||||
|     public double getOffsetY() { | ||||
|         return offsetY; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The offset/spread of particles in the z-direction | ||||
|      * | ||||
|      * @return <p>The z-offset</p> | ||||
|      */ | ||||
|     public double getOffsetZ() { | ||||
|         return offsetZ; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The extra value to set for the particle. Exactly what it does depends on the particle. | ||||
|      * | ||||
|      * @return <p>The particle's extra value</p> | ||||
|      */ | ||||
|     public double getExtra() { | ||||
|         return extra; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,38 +0,0 @@ | ||||
| package net.knarcraft.launchpad.config; | ||||
|  | ||||
| /** | ||||
|  * The mode used for spawning particles | ||||
|  */ | ||||
| public enum ParticleMode { | ||||
|  | ||||
|     /** | ||||
|      * Spawns the set amount of particles on a single point in the world | ||||
|      */ | ||||
|     SINGLE, | ||||
|  | ||||
|     /** | ||||
|      * Spawns the set amount of particles in a square around the block | ||||
|      */ | ||||
|     SQUARE, | ||||
|  | ||||
|     /** | ||||
|      * Spawns the set amount of particles in a circle around the block | ||||
|      */ | ||||
|     CIRCLE, | ||||
|  | ||||
|     /** | ||||
|      * Spawns the set amount of particles in a pyramid centered on the block | ||||
|      */ | ||||
|     PYRAMID, | ||||
|  | ||||
|     /** | ||||
|      * Spawns the set amount of particles in a sphere centered on the block | ||||
|      */ | ||||
|     SPHERE, | ||||
|  | ||||
|     /** | ||||
|      * Spawns the set amount of particles in a cube centered on the block | ||||
|      */ | ||||
|     CUBE, | ||||
|  | ||||
| } | ||||
| @@ -1,247 +0,0 @@ | ||||
| package net.knarcraft.launchpad.task; | ||||
|  | ||||
| import net.knarcraft.launchpad.config.LaunchpadParticleConfig; | ||||
| import net.knarcraft.launchpad.launchpad.LaunchpadBlock; | ||||
| import net.knarcraft.launchpad.launchpad.LaunchpadBlockHandler; | ||||
| import org.bukkit.Location; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.World; | ||||
| import org.bukkit.util.BoundingBox; | ||||
| import org.bukkit.util.Vector; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
|  | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * A runnable tasks that spawns particles at every launchpad | ||||
|  */ | ||||
| public class ParticleSpawner implements Runnable { | ||||
|  | ||||
|     private Vector[] pyramidVectors; | ||||
|     private double[][] circleCoordinates; | ||||
|     private double[][] sphereCoordinates; | ||||
|  | ||||
|     private final LaunchpadParticleConfig particleConfig; | ||||
|     private final Map<Material, LaunchpadParticleConfig> materialConfigs; | ||||
|     private LaunchpadBlock processingLaunchpad = null; | ||||
|  | ||||
|     /** | ||||
|      * Instantiates a new particle spawner | ||||
|      * | ||||
|      * @param particleConfig <p>The configuration for the particle to spawn</p> | ||||
|      */ | ||||
|     public ParticleSpawner(LaunchpadParticleConfig particleConfig, Map<Material, | ||||
|             LaunchpadParticleConfig> materialConfigs) { | ||||
|         this.particleConfig = particleConfig; | ||||
|         this.materialConfigs = materialConfigs; | ||||
|  | ||||
|         this.pyramidVectors = null; | ||||
|         this.circleCoordinates = null; | ||||
|         this.sphereCoordinates = null; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void run() { | ||||
|         for (LaunchpadBlock launchpad : LaunchpadBlockHandler.getAll()) { | ||||
|             // Ignore launchpads in unloaded chunks | ||||
|             if (!launchpad.getBlock().getChunk().isLoaded()) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             Location location = launchpad.getBlock().getLocation().clone(); | ||||
|             World world = location.getWorld(); | ||||
|             if (world == null) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // Store the currently processed launchpad for height calculation | ||||
|             processingLaunchpad = launchpad; | ||||
|  | ||||
|             switch (getParticleConfig().getParticleMode()) { | ||||
|                 case SINGLE -> spawnParticle(world, location.clone().add( | ||||
|                         0.5, getParticleConfig().getHeightOffset(), 0.5)); | ||||
|                 case SQUARE -> drawSquare(world, location); | ||||
|                 case CIRCLE -> drawCircle(world, location); | ||||
|                 case PYRAMID -> drawPyramid(world, location); | ||||
|                 case SPHERE -> drawSphere(world, location); | ||||
|                 case CUBE -> drawCube(world, location); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the particle config to use for the current launchpad's material | ||||
|      * | ||||
|      * @return <p>The particle config to use</p> | ||||
|      */ | ||||
|     private LaunchpadParticleConfig getParticleConfig() { | ||||
|         LaunchpadParticleConfig materialConfig = this.materialConfigs.get(processingLaunchpad.getBlock().getType()); | ||||
|         if (materialConfig != null) { | ||||
|             return materialConfig; | ||||
|         } | ||||
|         return this.particleConfig; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Spawns a cube of particles at the given location | ||||
|      * | ||||
|      * @param world    <p>The world to spawn the particles in</p> | ||||
|      * @param location <p>The location of the block to spawn the particles at</p> | ||||
|      */ | ||||
|     private void drawCube(@NotNull World world, @NotNull Location location) { | ||||
|         // Draw the top and bottom of the cube | ||||
|         drawSquare(world, location); | ||||
|         drawSquare(world, location.clone().add(0, 1, 0)); | ||||
|  | ||||
|         for (float y = 0; y <= 1; y += getParticleConfig().getParticleDensity()) { | ||||
|             double height = getParticleConfig().getHeightOffset() + y; | ||||
|             spawnParticle(world, location.clone().add(0, height, 0)); | ||||
|             spawnParticle(world, location.clone().add(0, height, 1)); | ||||
|             spawnParticle(world, location.clone().add(1, height, 0)); | ||||
|             spawnParticle(world, location.clone().add(1, height, 1)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Spawns a sphere of particles at the given location | ||||
|      * | ||||
|      * @param world    <p>The world to spawn the particles in</p> | ||||
|      * @param location <p>The location of the block to spawn the particles at</p> | ||||
|      */ | ||||
|     private void drawSphere(@NotNull World world, @NotNull Location location) { | ||||
|         // For spheres, densities below 0.1 has weird bugs such as blinking in and out of existence, and floating point | ||||
|         // errors when calculating the length of circleCoordinates | ||||
|         double density = Math.max(1, getParticleConfig().getParticleDensity()); | ||||
|         // Store calculations for improved efficiency | ||||
|         if (sphereCoordinates == null) { | ||||
|             int length = (int) Math.ceil((180 / density)); | ||||
|             sphereCoordinates = new double[length * 3][]; | ||||
|             int i = 0; | ||||
|             for (float x = 0; x < 180; x += density) { | ||||
|                 if (i >= sphereCoordinates.length) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 sphereCoordinates[i++] = new double[]{(0.5 * Math.sin(x)) + 0.5, | ||||
|                         getParticleConfig().getHeightOffset() + 0.5, (0.5 * Math.cos(x)) + 0.5}; | ||||
|                 sphereCoordinates[i++] = new double[]{(0.5 * Math.sin(x)) + 0.5, | ||||
|                         getParticleConfig().getHeightOffset() + 0.5 + (0.5 * Math.cos(x)), 0.5}; | ||||
|                 sphereCoordinates[i++] = new double[]{0.5, | ||||
|                         getParticleConfig().getHeightOffset() + 0.5 + (0.5 * Math.sin(x)), (0.5 * Math.cos(x)) + 0.5}; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Spawn particles on the stored locations, relative to the launchpad | ||||
|         for (double[] sphereCoordinate : sphereCoordinates) { | ||||
|             spawnParticle(world, location.clone().add(sphereCoordinate[0], sphereCoordinate[1], sphereCoordinate[2])); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Spawns a pyramid of particles at the given location | ||||
|      * | ||||
|      * @param world    <p>The world to spawn the particles in</p> | ||||
|      * @param location <p>The location of the block to spawn the particles at</p> | ||||
|      */ | ||||
|     private void drawPyramid(@NotNull World world, @NotNull Location location) { | ||||
|         // Draw the bottom of the pyramid | ||||
|         drawSquare(world, location); | ||||
|  | ||||
|         // Store calculations for improved efficiency | ||||
|         if (pyramidVectors == null) { | ||||
|             // The 0.5 offsets are required for the angle of the pyramid's 4 lines to be correct | ||||
|             double coordinateMin = -0.5 * getParticleConfig().getHeightOffset(); | ||||
|             double coordinateMax = 1 + (0.5 * getParticleConfig().getHeightOffset()); | ||||
|  | ||||
|             pyramidVectors = new Vector[5]; | ||||
|             // The vector from the origin to the top of the pyramid | ||||
|             pyramidVectors[0] = new Vector(0.5, 1 + getParticleConfig().getHeightOffset(), 0.5); | ||||
|             // The vectors from the top of the pyramid towards each corner | ||||
|             pyramidVectors[1] = new Vector(coordinateMin, 0, coordinateMin).subtract(pyramidVectors[0]).normalize(); | ||||
|             pyramidVectors[2] = new Vector(coordinateMax, 0, coordinateMin).subtract(pyramidVectors[0]).normalize(); | ||||
|             pyramidVectors[3] = new Vector(coordinateMin, 0, coordinateMax).subtract(pyramidVectors[0]).normalize(); | ||||
|             pyramidVectors[4] = new Vector(coordinateMax, 0, coordinateMax).subtract(pyramidVectors[0]).normalize(); | ||||
|         } | ||||
|  | ||||
|         Location topLocation = location.clone().add(pyramidVectors[0]); | ||||
|         for (double x = 0; x <= 1.2; x += getParticleConfig().getParticleDensity()) { | ||||
|             spawnParticle(world, topLocation.clone().add(pyramidVectors[1].clone().multiply(x))); | ||||
|             spawnParticle(world, topLocation.clone().add(pyramidVectors[2].clone().multiply(x))); | ||||
|             spawnParticle(world, topLocation.clone().add(pyramidVectors[3].clone().multiply(x))); | ||||
|             spawnParticle(world, topLocation.clone().add(pyramidVectors[4].clone().multiply(x))); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Spawns a circle of particles at the given location | ||||
|      * | ||||
|      * @param world    <p>The world to spawn the particles in</p> | ||||
|      * @param location <p>The location of the block to spawn the particles at</p> | ||||
|      */ | ||||
|     private void drawCircle(@NotNull World world, @NotNull Location location) { | ||||
|         // For circles, densities below 0.1 has weird bugs such as blinking in and out of existence, and floating point | ||||
|         // errors when calculating the length of circleCoordinates | ||||
|         double density = Math.max(1, getParticleConfig().getParticleDensity()); | ||||
|         // Store calculations for improved efficiency | ||||
|         if (circleCoordinates == null) { | ||||
|             circleCoordinates = new double[(int) Math.ceil((180 / density))][]; | ||||
|             int i = 0; | ||||
|             for (float x = 0; x < 180; x += density) { | ||||
|                 if (i >= circleCoordinates.length) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 circleCoordinates[i++] = new double[]{(0.5 * Math.sin(x)) + 0.5, (0.5 * Math.cos(x)) + 0.5}; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Spawn particles on the stored locations, relative to the launchpad | ||||
|         for (double[] circleCoordinate : circleCoordinates) { | ||||
|             spawnParticle(world, location.clone().add(circleCoordinate[0], getParticleConfig().getHeightOffset(), | ||||
|                     circleCoordinate[1])); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Spawns a square of particles at the given location | ||||
|      * | ||||
|      * @param world    <p>The world to spawn the particles in</p> | ||||
|      * @param location <p>The location of the block to spawn the particles at</p> | ||||
|      */ | ||||
|     private void drawSquare(@NotNull World world, @NotNull Location location) { | ||||
|         for (float x = 0; x <= 1; x += getParticleConfig().getParticleDensity()) { | ||||
|             spawnParticle(world, location.clone().add(x, getParticleConfig().getHeightOffset(), 0)); | ||||
|             spawnParticle(world, location.clone().add(x, getParticleConfig().getHeightOffset(), 1)); | ||||
|             spawnParticle(world, location.clone().add(0, getParticleConfig().getHeightOffset(), x)); | ||||
|             spawnParticle(world, location.clone().add(1, getParticleConfig().getHeightOffset(), x)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Spawns the specified particle at the given location | ||||
|      * | ||||
|      * @param world    <p>The world to spawn the particle in</p> | ||||
|      * @param location <p>The location to spawn the particle at</p> | ||||
|      */ | ||||
|     private void spawnParticle(@NotNull World world, @NotNull Location location) { | ||||
|         world.spawnParticle(getParticleConfig().getParticleType(), | ||||
|                 location.add(0, getBlockHeight(processingLaunchpad), 0), getParticleConfig().getParticleAmount(), | ||||
|                 getParticleConfig().getOffsetX(), getParticleConfig().getOffsetY(), getParticleConfig().getOffsetZ(), | ||||
|                 getParticleConfig().getExtra()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the height of the launchpad block at the given location | ||||
|      * | ||||
|      * @param launchpad <p>The launchpad to check</p> | ||||
|      * @return <p>The height of the block</p> | ||||
|      */ | ||||
|     private double getBlockHeight(LaunchpadBlock launchpad) { | ||||
|         double maxY = 0; | ||||
|         for (BoundingBox boundingBox : launchpad.getBlock().getCollisionShape().getBoundingBoxes()) { | ||||
|             if (boundingBox.getMaxY() > maxY) { | ||||
|                 maxY = boundingBox.getMaxY(); | ||||
|             } | ||||
|         } | ||||
|         return maxY; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,108 +0,0 @@ | ||||
| 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.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Random; | ||||
| 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 Map<UUID, Particle> playerParticles = new HashMap<>(); | ||||
|     private final Random random = new Random(); | ||||
|     private final Particle particle; | ||||
|     private final boolean randomTrailType; | ||||
|     private final List<Particle> randomTrailTypes; | ||||
|  | ||||
|     /** | ||||
|      * Instantiates a new particle trail spawner | ||||
|      * | ||||
|      * @param particle         <p>The type of particle used for the trail</p> | ||||
|      * @param randomTrailType  <p>Whether to use a random trail type each time a player is launched</p> | ||||
|      * @param randomTrailTypes <p>The types of particles to use for random trails</p> | ||||
|      */ | ||||
|     public ParticleTrailSpawner(@NotNull Particle particle, boolean randomTrailType, | ||||
|                                 @NotNull List<Particle> randomTrailTypes) { | ||||
|         this.particle = particle; | ||||
|         this.randomTrailType = randomTrailType; | ||||
|         this.randomTrailTypes = randomTrailTypes; | ||||
|     } | ||||
|  | ||||
|     @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; | ||||
|             } | ||||
|  | ||||
|             Particle spawnParticle; | ||||
|             if (randomTrailType) { | ||||
|                 spawnParticle = playerParticles.get(playerId); | ||||
|                 if (spawnParticle == null) { | ||||
|                     spawnParticle = this.particle; | ||||
|                 } | ||||
|             } else { | ||||
|                 spawnParticle = this.particle; | ||||
|             } | ||||
|             playerWorld.spawnParticle(spawnParticle, playerLocation, 0, 0, 0, 0, 0); | ||||
|         } | ||||
|         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); | ||||
|         this.playerParticles.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.playerParticles.put(playerId, randomParticle()); | ||||
|         this.playersWithTrails.add(playerId); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets a random particle | ||||
|      * | ||||
|      * @return <p>A random particle</p> | ||||
|      */ | ||||
|     private Particle randomParticle() { | ||||
|         Particle spawnParticle = null; | ||||
|         while (spawnParticle == null || spawnParticle.getDataType() != Void.class) { | ||||
|             spawnParticle = randomTrailTypes.get(random.nextInt(randomTrailTypes.size())); | ||||
|         } | ||||
|         return spawnParticle; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,29 +0,0 @@ | ||||
| package net.knarcraft.launchpad.util; | ||||
|  | ||||
| import net.md_5.bungee.api.ChatColor; | ||||
|  | ||||
| import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | ||||
|  | ||||
| /** | ||||
|  * A helper class for converting colors | ||||
|  */ | ||||
| public class ColorHelper { | ||||
|  | ||||
|     /** | ||||
|      * Translates all found color codes to formatting in a string | ||||
|      * | ||||
|      * @param message <p>The string to search for color codes</p> | ||||
|      * @return <p>The message with color codes translated</p> | ||||
|      */ | ||||
|     public static String translateAllColorCodes(String message) { | ||||
|         message = ChatColor.translateAlternateColorCodes('&', message); | ||||
|         Pattern pattern = Pattern.compile("&?(#[a-fA-F0-9]{6})"); | ||||
|         Matcher matcher = pattern.matcher(message); | ||||
|         while (matcher.find()) { | ||||
|             message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group(1))); | ||||
|         } | ||||
|         return message; | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	