Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Change trailer from blocks to particles.
  • Loading branch information
Paldiu committed Mar 28, 2023
1 parent 34269bd commit 922a2bc
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 121 deletions.
@@ -0,0 +1,7 @@
package me.totalfreedom.totalfreedommod.api;

@FunctionalInterface
public interface Interpolator
{
double[] interpolate(double from, double to, int max);
}
@@ -1,28 +1,22 @@
package me.totalfreedom.totalfreedommod.fun;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.SplittableRandom;
import java.util.UUID;

import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.api.ShopItem;
import me.totalfreedom.totalfreedommod.util.Groups;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import me.totalfreedom.totalfreedommod.util.ParticleDisplay;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;

import java.util.HashMap;
import java.util.Map;
import java.util.SplittableRandom;
import java.util.UUID;

public class Trailer extends FreedomService
{
private final SplittableRandom random = new SplittableRandom();
private final Set<UUID> trailPlayers = new HashSet<>(); // player UUID
private final Map<UUID, ParticleDisplay> trailPlayers = new HashMap<>(); // player UUID and relative particle instance.

@Override
public void onStart()
Expand All @@ -46,42 +40,15 @@ public void onPlayerMove(PlayerMoveEvent event)
* - The player doesn't have permission to modify blocks in their current world
*/
if (trailPlayers.isEmpty()
|| !trailPlayers.contains(event.getPlayer().getUniqueId())
|| !plugin.pl.getData(event.getPlayer()).hasItem(ShopItem.RAINBOW_TRAIL)
|| plugin.wr.doRestrict(event.getPlayer())
|| !plugin.wgb.canEditCurrentWorld(event.getPlayer()))
|| !trailPlayers.containsKey(event.getPlayer().getUniqueId())
|| !plugin.pl.getData(event.getPlayer()).hasItem(ShopItem.RAINBOW_TRAIL))
{
return;
}

Block fromBlock = event.getFrom().getBlock();
if (!fromBlock.isEmpty())
{
return;
}

Block toBlock = Objects.requireNonNull(event.getTo()).getBlock();
if (fromBlock.equals(toBlock))
{
return;
}

// TODO: Make this particles instead of blocks!
fromBlock.setType(Groups.WOOL_COLORS.get(random.nextInt(Groups.WOOL_COLORS.size())));
BlockData data = fromBlock.getBlockData();
Material material = Material.getMaterial(String.valueOf(fromBlock.getType()));
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
final Location trail_pos;
trail_pos = new Location(event.getPlayer().getWorld(), fromBlock.getX() + x, fromBlock.getY(), fromBlock.getZ() + z);
if (trailPlayers.contains(event.getPlayer().getUniqueId()) && plugin.cpb.isEnabled())
{
plugin.cpb.getCoreProtectAPI().logPlacement(event.getPlayer().getName(), trail_pos, material, data);
}
}
}
final Player player = event.getPlayer();
final ParticleDisplay particleDisplay = trailPlayers.get(player.getUniqueId());
particleDisplay.spawnNext(player);
}

public void remove(Player player)
Expand All @@ -91,11 +58,13 @@ public void remove(Player player)

public void add(Player player)
{
trailPlayers.add(player.getUniqueId());
if (trailPlayers.containsKey(player.getUniqueId())) return;

trailPlayers.put(player.getUniqueId(), new ParticleDisplay());
}

public boolean contains(Player player)
{
return trailPlayers.contains(player.getUniqueId());
return trailPlayers.containsKey(player.getUniqueId());
}
}
@@ -1,19 +1,22 @@
package me.totalfreedom.totalfreedommod.util;

import java.util.Arrays;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.entity.EntityType;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

public class Groups
{
public static final List<Material> WOOL_COLORS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_WOOL")).toList();
public static final List<Material> SHULKER_BOXES = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("SHULKER_BOX")).toList();
public static final List<EntityType> MOB_TYPES = Arrays.stream(EntityType.values()).filter(EntityType::isAlive).filter(EntityType::isSpawnable).toList();
public static final List<Material> SPAWN_EGGS = Arrays.stream(Material.values()).filter((mat) -> mat.name().endsWith("_SPAWN_EGG")).toList();
public static final List<Material> BANNERS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_BANNER")).toList();
public static final List<Biome> EXPLOSIVE_BED_BIOMES = Arrays.asList(
public static final Set<Material> WOOL_COLORS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_WOOL")).collect(Collectors.toSet());
public static final Set<Material> SHULKER_BOXES = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("SHULKER_BOX")).collect(Collectors.toSet());
public static final Set<EntityType> MOB_TYPES = Arrays.stream(EntityType.values()).filter(EntityType::isAlive).filter(EntityType::isSpawnable).collect(Collectors.toSet());
public static final Set<Material> SPAWN_EGGS = Arrays.stream(Material.values()).filter((mat) -> mat.name().endsWith("_SPAWN_EGG")).collect(Collectors.toSet());
public static final Set<Material> BANNERS = Arrays.stream(Material.values()).filter((m) -> m.name().endsWith("_BANNER")).collect(Collectors.toSet());
public static final Set<Biome> EXPLOSIVE_BED_BIOMES = new HashSet<>(Arrays.asList(
Biome.NETHER_WASTES,
Biome.CRIMSON_FOREST,
Biome.SOUL_SAND_VALLEY,
Expand All @@ -23,5 +26,5 @@ public class Groups
Biome.END_HIGHLANDS,
Biome.END_MIDLANDS,
Biome.THE_END,
Biome.SMALL_END_ISLANDS);
Biome.SMALL_END_ISLANDS));
}
@@ -0,0 +1,58 @@
package me.totalfreedom.totalfreedommod.util;

import me.totalfreedom.totalfreedommod.api.Interpolator;
import org.bukkit.Color;

import java.util.LinkedHashSet;

public class Interpolation
{
public LinkedHashSet<Color> rainbow(int length)
{
LinkedHashSet<Color> base = new LinkedHashSet<>();
LinkedHashSet<Color> redToOrange = hsvGradient(length, Color.RED, Color.ORANGE, this::linear);
LinkedHashSet<Color> orangeToYellow = hsvGradient(length, Color.ORANGE, Color.YELLOW, this::linear);
LinkedHashSet<Color> yellowToGreen = hsvGradient(length, Color.YELLOW, Color.GREEN, this::linear);
LinkedHashSet<Color> greenToBlue = hsvGradient(length, Color.GREEN, Color.BLUE, this::linear);
LinkedHashSet<Color> blueToPurple = hsvGradient(length, Color.BLUE, Color.PURPLE, this::linear);
LinkedHashSet<Color> purpleToRed = hsvGradient(length, Color.PURPLE, Color.RED, this::linear);
base.addAll(redToOrange);
base.addAll(orangeToYellow);
base.addAll(yellowToGreen);
base.addAll(greenToBlue);
base.addAll(blueToPurple);
base.addAll(purpleToRed);
return base;
}

private double[] linear(double from, double to, int max)
{
final double[] res = new double[max];
for (int i = 0; i < max; i++)
{
res[i] = from + i * ((to - from) / (max - 1));
}
return res;
}

private LinkedHashSet<Color> hsvGradient(int length, Color from, Color to, Interpolator interpolator)
{
// returns a float-array where hsv[0] = hue, hsv[1] = saturation, hsv[2] = value/brightness
final float[] hsvFrom = java.awt.Color.RGBtoHSB(from.getRed(), from.getGreen(), from.getBlue(), null);
final float[] hsvTo = java.awt.Color.RGBtoHSB(to.getRed(), to.getGreen(), to.getBlue(), null);

final double[] h = interpolator.interpolate(hsvFrom[0], hsvTo[0], length);
final double[] s = interpolator.interpolate(hsvFrom[1], hsvTo[1], length);
final double[] v = interpolator.interpolate(hsvFrom[2], hsvTo[2], length);

final LinkedHashSet<Color> gradient = new LinkedHashSet<>();

for (int i = 0; i < length; i++)
{
final int rgb = java.awt.Color.HSBtoRGB((float) h[i], (float) s[i], (float) v[i]);
final Color color = Color.fromRGB(rgb);
gradient.add(color);
}
return gradient;
}
}
@@ -0,0 +1,57 @@
package me.totalfreedom.totalfreedommod.util;

import com.destroystokyo.paper.ParticleBuilder;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;

import java.util.Iterator;

public class ParticleDisplay
{
private final Interpolation interpolation;
private Iterator<Color> colorIterator;

public ParticleDisplay()
{
this.interpolation = new Interpolation();
this.colorIterator = interpolation.rainbow(43).iterator();
}

public void spawnNext(Player player)
{
Location location = getBehind(player);
Color color = getIterator().next();
Particle.DustOptions options = new Particle.DustOptions(color, 3);
ParticleBuilder builder = new ParticleBuilder(Particle.REDSTONE);
builder.data(options)
.receivers(30, 15, true)
.offset(0.5, 0.5, 0.5)
.location(location)
.spawn();
}

private Location getBehind(Player player)
{
@NotNull Vector inverse = player.getLocation()
.clone()
.getDirection()
.normalize()
.multiply(-1);

return player.getLocation().add(inverse);
}

private Iterator<Color> getIterator()
{
if (!this.colorIterator.hasNext())
{
this.colorIterator = interpolation.rainbow(43).iterator();
}

return this.colorIterator;
}
}

0 comments on commit 922a2bc

Please sign in to comment.