mirror of
https://github.com/SunNetservers/Launchpad.git
synced 2024-12-05 01:43:15 +01:00
Uses particle spawning code from KnarLib
This commit is contained in:
parent
13f3de32fa
commit
31af3639b5
2
pom.xml
2
pom.xml
@ -97,7 +97,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.knarcraft</groupId>
|
<groupId>net.knarcraft</groupId>
|
||||||
<artifactId>knarlib</artifactId>
|
<artifactId>knarlib</artifactId>
|
||||||
<version>1.1-SNAPSHOT</version>
|
<version>1.2</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
package net.knarcraft.launchpad.config;
|
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;
|
||||||
import net.knarcraft.launchpad.launchpad.LaunchpadBlockHandler;
|
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 net.knarcraft.launchpad.util.MaterialHelper;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -33,6 +37,7 @@ public class LaunchpadConfiguration {
|
|||||||
private boolean trailsEnabled;
|
private boolean trailsEnabled;
|
||||||
private int particleTaskId = -1;
|
private int particleTaskId = -1;
|
||||||
private int particleTrailTaskId = -1;
|
private int particleTrailTaskId = -1;
|
||||||
|
private UUID particleStoredCalculationsId;
|
||||||
private ParticleTrailSpawner trailSpawner = null;
|
private ParticleTrailSpawner trailSpawner = null;
|
||||||
private @NotNull Set<Material> launchpadMaterials = new HashSet<>();
|
private @NotNull Set<Material> launchpadMaterials = new HashSet<>();
|
||||||
private @NotNull Set<Material> materialWhitelist = new HashSet<>();
|
private @NotNull Set<Material> materialWhitelist = new HashSet<>();
|
||||||
@ -184,6 +189,7 @@ public class LaunchpadConfiguration {
|
|||||||
// Cancel previous particle spawning task if previously enabled
|
// Cancel previous particle spawning task if previously enabled
|
||||||
if (previousEnabled) {
|
if (previousEnabled) {
|
||||||
Bukkit.getScheduler().cancelTask(particleTaskId);
|
Bukkit.getScheduler().cancelTask(particleTaskId);
|
||||||
|
ParticleHelper.clearStoredCalculations(particleStoredCalculationsId);
|
||||||
}
|
}
|
||||||
if (previousTrailsEnabled) {
|
if (previousTrailsEnabled) {
|
||||||
Bukkit.getScheduler().cancelTask(particleTrailTaskId);
|
Bukkit.getScheduler().cancelTask(particleTrailTaskId);
|
||||||
@ -234,13 +240,13 @@ public class LaunchpadConfiguration {
|
|||||||
*/
|
*/
|
||||||
private void loadLaunchpadParticleConfig(ConfigurationSection particlesSection) {
|
private void loadLaunchpadParticleConfig(ConfigurationSection particlesSection) {
|
||||||
ConfigurationSection particleSection = particlesSection.getConfigurationSection("particle");
|
ConfigurationSection particleSection = particlesSection.getConfigurationSection("particle");
|
||||||
LaunchpadParticleConfig particleConfig = null;
|
ParticleConfig particleConfig = null;
|
||||||
if (particleSection != null) {
|
if (particleSection != null) {
|
||||||
particleConfig = new LaunchpadParticleConfig(particleSection);
|
particleConfig = new ParticleConfig(particleSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load any per-material configuration options
|
// Load any per-material configuration options
|
||||||
Map<Material, LaunchpadParticleConfig> materialConfigs;
|
Map<Material, ParticleConfig> materialConfigs;
|
||||||
ConfigurationSection perMaterialSection = particlesSection.getConfigurationSection("materialParticles");
|
ConfigurationSection perMaterialSection = particlesSection.getConfigurationSection("materialParticles");
|
||||||
if (perMaterialSection != null) {
|
if (perMaterialSection != null) {
|
||||||
materialConfigs = loadMaterialParticleConfigs(perMaterialSection);
|
materialConfigs = loadMaterialParticleConfigs(perMaterialSection);
|
||||||
@ -249,27 +255,35 @@ public class LaunchpadConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (particleConfig != null) {
|
if (particleConfig != null) {
|
||||||
particleTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Launchpad.getInstance(),
|
ParticleSpawner particleSpawner = new ParticleSpawner(particleConfig, materialConfigs, this::getLaunchpadBlocks);
|
||||||
new ParticleSpawner(particleConfig, materialConfigs), 20, particleConfig.getSpawnDelay());
|
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
|
* Loads all per-material particle configuration options
|
||||||
*
|
*
|
||||||
* @param perMaterialSection <p>The configuration section containing per-material particle options</p>
|
* @param perMaterialSection <p>The configuration section containing per-material particle options</p>
|
||||||
* @return <p>The loaded per-material particle configuration 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) {
|
@NotNull ConfigurationSection perMaterialSection) {
|
||||||
Map<Material, LaunchpadParticleConfig> materialConfigs = new HashMap<>();
|
Map<Material, ParticleConfig> materialConfigs = new HashMap<>();
|
||||||
for (String key : perMaterialSection.getKeys(false)) {
|
for (String key : perMaterialSection.getKeys(false)) {
|
||||||
Set<Material> materials = MaterialHelper.loadMaterialString(key);
|
Set<Material> materials = MaterialHelper.loadMaterialString(key);
|
||||||
ConfigurationSection materialSection = perMaterialSection.getConfigurationSection(key);
|
ConfigurationSection materialSection = perMaterialSection.getConfigurationSection(key);
|
||||||
if (materialSection == null) {
|
if (materialSection == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LaunchpadParticleConfig materialParticleConfig = new LaunchpadParticleConfig(materialSection);
|
ParticleConfig materialParticleConfig = new ParticleConfig(materialSection);
|
||||||
for (Material material : materials) {
|
for (Material material : materials) {
|
||||||
materialConfigs.put(material, materialParticleConfig);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user