package dev.loki.util; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.util.Vector; import java.util.List; public final class ParticleUtil { private ParticleUtil() {} public static void spawn(Particle p, Location loc, int count) { World w = loc.getWorld(); if (w == null) return; w.spawnParticle(p, loc, count); } public static void spawn(Particle p, Location loc, int count, double sx, double sy, double sz, double speed) { World w = loc.getWorld(); if (w == null) return; w.spawnParticle(p, loc, count, sx, sy, sz, speed); } public static void spawnDust(Location loc, Color c, float size) { World w = loc.getWorld(); if (w == null) return; w.spawnParticle(Particle.DUST, loc, 1, new Particle.DustOptions(c, size)); } public static void spawnDust(Location loc, Color c, float size, int count) { World w = loc.getWorld(); if (w == null) return; w.spawnParticle(Particle.DUST, loc, count, 0.1, 0.1, 0.1, 0, new Particle.DustOptions(c, size)); } public static void drawLine(Particle p, Location a, Location b, int points) { if (!a.getWorld().equals(b.getWorld())) return; Vector dir = b.toVector().subtract(a.toVector()); double dist = dir.length(); dir.normalize(); double step = dist / points; Location cur = a.clone(); for (int i = 0; i <= points; i++) { spawn(p, cur, 1); cur.add(dir.clone().multiply(step)); } } public static void drawCircle(Particle p, Location c, double r, int points) { World w = c.getWorld(); if (w == null) return; for (int i = 0; i < points; i++) { double a = 2 * Math.PI * i / points; spawn(p, new Location(w, c.getX() + r * Math.cos(a), c.getY(), c.getZ() + r * Math.sin(a)), 1); } } public static void drawCircle(Particle p, Location c, double r, int points, Color col, float size) { World w = c.getWorld(); if (w == null) return; for (int i = 0; i < points; i++) { double a = 2 * Math.PI * i / points; spawnDust(new Location(w, c.getX() + r * Math.cos(a), c.getY(), c.getZ() + r * Math.sin(a)), col, size); } } public static void burst(Particle p, Location c, int count, double speed) { World w = c.getWorld(); if (w == null) return; w.spawnParticle(p, c, count, 0.5, 0.5, 0.5, speed); } public static void burstToPlayers(Particle p, List players, Location c, int count, double speed) { for (Player pl : players) pl.spawnParticle(p, c, count, 0.5, 0.5, 0.5, speed); } public static void trail(Particle p, Location start, Vector dir, int len, double spacing) { Location cur = start.clone(); Vector step = dir.clone().normalize().multiply(spacing); for (int i = 0; i < len; i++) { spawn(p, cur, 1); cur.add(step); } } public static void shockwave(Particle p, Location c, double maxR, int rings, double speed) { for (int i = 1; i <= rings; i++) drawCircle(p, c, (maxR / rings) * i, (int) (16 * (maxR / rings) * i)); } public static void damage(Location loc) { World w = loc.getWorld(); if (w == null) return; w.spawnParticle(Particle.DAMAGE_INDICATOR, loc, 10, 0.3, 0.3, 0.3, 0); } public static void blood(Location loc) { World w = loc.getWorld(); if (w == null) return; w.spawnParticle(Particle.BLOCK, loc, 20, 0.2, 0.2, 0.2, 0, org.bukkit.Material.REDSTONE_BLOCK.createBlockData()); } public static void sparks(Location loc) { World w = loc.getWorld(); if (w == null) return; w.spawnParticle(Particle.ELECTRIC_SPARK, loc, 5, 0.1, 0.1, 0.1, 0.1); } public static void heal(Location loc) { spawnDust(loc, Color.LIME, 1.0f, 10); } public static void teleportEffect(Location loc) { World w = loc.getWorld(); if (w == null) return; w.spawnParticle(Particle.PORTAL, loc, 100, 0.5, 1.0, 0.5, 1.0); w.spawnParticle(Particle.REVERSE_PORTAL, loc, 50, 0.3, 0.5, 0.3, 0.5); } }