forked from SteamWar/SteamWar
Add the trail particle with duration and target
Trail particles fly from where they spawn to a target offset over the chosen number of ticks, in the entry's colour. The target follows the body like other offsets when the entry is placed relative to it.
This commit is contained in:
@@ -138,6 +138,10 @@ PARTICLE_PARAM_SPREAD_Z = §fSpread Z
|
||||
PARTICLE_PARAM_SPEED = §fSpeed
|
||||
PARTICLE_PARAM_COLORS = §fColours
|
||||
PARTICLE_PARAM_BLOCK = §fBlock
|
||||
PARTICLE_PARAM_TRAIL_DURATION = §fTrail duration (ticks)
|
||||
PARTICLE_PARAM_TRAIL_TARGET_X = §fTrail target X
|
||||
PARTICLE_PARAM_TRAIL_TARGET_Y = §fTrail target Y
|
||||
PARTICLE_PARAM_TRAIL_TARGET_Z = §fTrail target Z
|
||||
PARTICLE_PARAM_OFFSET_X = §fOffset X
|
||||
PARTICLE_PARAM_OFFSET_Y = §fOffset Y
|
||||
PARTICLE_PARAM_OFFSET_Z = §fOffset Z
|
||||
@@ -193,6 +197,7 @@ PARTICLE_TYPE_BLOCK_MARKER = §fBlock marker
|
||||
PARTICLE_TYPE_DUST_PILLAR = §fDust pillar
|
||||
PARTICLE_TYPE_FALLING_DUST = §fFalling dust
|
||||
PARTICLE_TYPE_ITEM = §fItem breaking
|
||||
PARTICLE_TYPE_TRAIL = §fTrail
|
||||
PARTICLE_TYPE_FLAME = §fFlame
|
||||
PARTICLE_TYPE_SMALL_FLAME = §fSmall flame
|
||||
PARTICLE_TYPE_SOUL_FIRE_FLAME = §fSoul fire flame
|
||||
|
||||
@@ -138,6 +138,10 @@ PARTICLE_PARAM_SPREAD_Z = §fStreuung Z
|
||||
PARTICLE_PARAM_SPEED = §fGeschwindigkeit
|
||||
PARTICLE_PARAM_COLORS = §fFarben
|
||||
PARTICLE_PARAM_BLOCK = §fBlock
|
||||
PARTICLE_PARAM_TRAIL_DURATION = §fSpurdauer (Ticks)
|
||||
PARTICLE_PARAM_TRAIL_TARGET_X = §fSpurziel X
|
||||
PARTICLE_PARAM_TRAIL_TARGET_Y = §fSpurziel Y
|
||||
PARTICLE_PARAM_TRAIL_TARGET_Z = §fSpurziel Z
|
||||
PARTICLE_PARAM_OFFSET_X = §fVersatz X
|
||||
PARTICLE_PARAM_OFFSET_Y = §fVersatz Y
|
||||
PARTICLE_PARAM_OFFSET_Z = §fVersatz Z
|
||||
@@ -193,6 +197,7 @@ PARTICLE_TYPE_BLOCK_MARKER = §fBlockmarkierung
|
||||
PARTICLE_TYPE_DUST_PILLAR = §fStaubsäule
|
||||
PARTICLE_TYPE_FALLING_DUST = §fFallender Staub
|
||||
PARTICLE_TYPE_ITEM = §fGegenstandssplitter
|
||||
PARTICLE_TYPE_TRAIL = §fSpur
|
||||
PARTICLE_TYPE_FLAME = §fFlamme
|
||||
PARTICLE_TYPE_SMALL_FLAME = §fKleine Flamme
|
||||
PARTICLE_TYPE_SOUL_FIRE_FLAME = §fSeelenfeuerflamme
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Relative zur rotation den spielers und co
|
||||
@@ -189,6 +189,11 @@ public class EntryParameters {
|
||||
public final DoubleParameter OFFSET_Y = new DoubleParameter("offsetY", "PARTICLE_PARAM_OFFSET_Y", 0, -3, 3, 0.1);
|
||||
public final DoubleParameter OFFSET_Z = new DoubleParameter("offsetZ", "PARTICLE_PARAM_OFFSET_Z", 0, -3, 3, 0.1);
|
||||
public final IntParameter INTERVAL = new IntParameter("interval", "PARTICLE_PARAM_INTERVAL", 1, 1, 100);
|
||||
public final IntParameter TRAIL_DURATION = new IntParameter("trailDuration", "PARTICLE_PARAM_TRAIL_DURATION", 20, 1, 200);
|
||||
// Where a trail particle flies to, relative to where it spawns
|
||||
public final DoubleParameter TRAIL_TARGET_X = new DoubleParameter("trailTargetX", "PARTICLE_PARAM_TRAIL_TARGET_X", 0, -5, 5, 0.1);
|
||||
public final DoubleParameter TRAIL_TARGET_Y = new DoubleParameter("trailTargetY", "PARTICLE_PARAM_TRAIL_TARGET_Y", 1, -5, 5, 0.1);
|
||||
public final DoubleParameter TRAIL_TARGET_Z = new DoubleParameter("trailTargetZ", "PARTICLE_PARAM_TRAIL_TARGET_Z", 0, -5, 5, 0.1);
|
||||
public final ChoiceParameter<Placement> PLACEMENT = ChoiceParameter.ofEnum("placement", "PARTICLE_PARAM_PLACEMENT", Placement.WORLD);
|
||||
public final ChoiceParameter<TickMode> TICK_MODE = ChoiceParameter.ofEnum("tickMode", "PARTICLE_PARAM_TICK_MODE", TickMode.MOVE);
|
||||
public final ChoiceParameter<Movement> MOVEMENT = ChoiceParameter.ofEnum("movement", "PARTICLE_PARAM_MOVEMENT", Movement.ANY);
|
||||
@@ -199,6 +204,7 @@ public class EntryParameters {
|
||||
|
||||
public final List<Parameter<?>> ALL = List.of(
|
||||
PARTICLE, COUNT, SPREAD_X, SPREAD_Y, SPREAD_Z, SPEED, COLORS, BLOCK,
|
||||
TRAIL_DURATION, TRAIL_TARGET_X, TRAIL_TARGET_Y, TRAIL_TARGET_Z,
|
||||
OFFSET_X, OFFSET_Y, OFFSET_Z, PLACEMENT, INTERVAL, TICK_MODE,
|
||||
MOVEMENT, GLIDING, GROUND, SNEAK, VISIBILITY
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
|
||||
// Left out: ELDER_GUARDIAN, FLASH and the explosion/gust emitters cover other players' screens,
|
||||
// BUBBLE, BUBBLE_COLUMN_UP and CURRENT_DOWN only show under water, VIBRATION and TRAIL need a target
|
||||
// BUBBLE, BUBBLE_COLUMN_UP and CURRENT_DOWN only show under water, VIBRATION needs a block or entity to fly to
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum ParticleType {
|
||||
@@ -40,6 +40,7 @@ public enum ParticleType {
|
||||
DUST_PILLAR(Material.MUD, Particle.DUST_PILLAR, Data.BLOCK, true),
|
||||
FALLING_DUST(Material.SAND, Particle.FALLING_DUST, Data.BLOCK, true),
|
||||
ITEM(Material.ITEM_FRAME, Particle.ITEM, Data.ITEM, true),
|
||||
TRAIL(Material.LEAD, Particle.TRAIL, Data.TRAIL, true),
|
||||
|
||||
FLAME(Material.FLINT_AND_STEEL, Particle.FLAME, Data.NONE, true),
|
||||
SMALL_FLAME(Material.TORCH, Particle.SMALL_FLAME, Data.NONE, true),
|
||||
@@ -153,6 +154,8 @@ public enum ParticleType {
|
||||
BLOCK,
|
||||
// An item of the entry's block
|
||||
ITEM,
|
||||
// Flies to the entry's trail target in its colour, taking the trail duration
|
||||
TRAIL,
|
||||
ZERO_INT,
|
||||
ZERO_FLOAT,
|
||||
}
|
||||
@@ -171,7 +174,11 @@ public enum ParticleType {
|
||||
}
|
||||
|
||||
public boolean usesColors() {
|
||||
return data == Data.DUST || data == Data.COLOR || data == Data.COLOR_TRANSITION;
|
||||
return data == Data.DUST || data == Data.COLOR || data == Data.COLOR_TRANSITION || data == Data.TRAIL;
|
||||
}
|
||||
|
||||
public boolean isTrail() {
|
||||
return data == Data.TRAIL;
|
||||
}
|
||||
|
||||
public boolean usesBlock() {
|
||||
|
||||
@@ -26,9 +26,9 @@ import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
// A particle that needs extra data, computed per tick so colours can follow a gradient
|
||||
// A particle that needs extra data, computed per tick from the tick and spawn location so colours can follow a gradient
|
||||
public class DataParticle implements ParticleElement {
|
||||
|
||||
private final Particle particle;
|
||||
@@ -37,9 +37,9 @@ public class DataParticle implements ParticleElement {
|
||||
private final float vz;
|
||||
private final double speed;
|
||||
private final int count;
|
||||
private final Function<ParticleTickData, Object> data;
|
||||
private final BiFunction<ParticleTickData, Location, Object> data;
|
||||
|
||||
public DataParticle(Particle particle, float vx, float vy, float vz, double speed, int count, Function<ParticleTickData, Object> data) {
|
||||
public DataParticle(Particle particle, float vx, float vy, float vz, double speed, int count, BiFunction<ParticleTickData, Location, Object> data) {
|
||||
this.particle = particle;
|
||||
this.vx = vx;
|
||||
this.vy = vy;
|
||||
@@ -61,7 +61,7 @@ public class DataParticle implements ParticleElement {
|
||||
@Override
|
||||
public void tick(ParticleTickData particleTickData) {
|
||||
Location location = particleTickData.getLocation().add(0.0, 0.2, 0.0);
|
||||
Object value = data.apply(particleTickData);
|
||||
Object value = data.apply(particleTickData, location);
|
||||
display(particleTickData, player -> player.spawnParticle(particle, location, count, vx, vy, vz, speed, value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,10 @@ class EntryEditor {
|
||||
Map.entry(INTERVAL, Material.CLOCK),
|
||||
Map.entry(TICK_MODE, Material.REPEATER),
|
||||
Map.entry(PLACEMENT, Material.PLAYER_HEAD),
|
||||
Map.entry(TRAIL_DURATION, Material.CLOCK),
|
||||
Map.entry(TRAIL_TARGET_X, Material.LEAD),
|
||||
Map.entry(TRAIL_TARGET_Y, Material.LEAD),
|
||||
Map.entry(TRAIL_TARGET_Z, Material.LEAD),
|
||||
Map.entry(MOVEMENT, Material.LEATHER_BOOTS),
|
||||
Map.entry(GLIDING, Material.ELYTRA),
|
||||
Map.entry(GROUND, Material.GRASS_BLOCK),
|
||||
@@ -119,6 +123,12 @@ class EntryEditor {
|
||||
} else if (type.usesBlock()) {
|
||||
inventory.setItem(ROW_DESIGN * 9 + FIRST_SETTING + 2, parameterItem(context, BLOCK));
|
||||
}
|
||||
if (type.isTrail()) {
|
||||
List<Parameter<?>> trail = List.of(TRAIL_DURATION, TRAIL_TARGET_X, TRAIL_TARGET_Y, TRAIL_TARGET_Z);
|
||||
for (int i = 0; i < trail.size(); i++) {
|
||||
inventory.setItem(ROW_DESIGN * 9 + FIRST_SETTING + 3 + i, parameterItem(context, trail.get(i)));
|
||||
}
|
||||
}
|
||||
row(inventory, context, ROW_PARTICLE, List.of(COUNT, SPEED, SPREAD_X, SPREAD_Y, SPREAD_Z));
|
||||
} else {
|
||||
inventory.setItem(ROW_PARTICLE * 9 + FIRST_SETTING, new SWItem(Material.STRUCTURE_VOID, msg("PARTICLE_FIXED_LOOK", player), clickType -> {
|
||||
|
||||
@@ -27,15 +27,17 @@ import de.steamwar.lobby.particle.ParticleTickData;
|
||||
import de.steamwar.lobby.particle.design.*;
|
||||
import de.steamwar.lobby.particle.elements.*;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static de.steamwar.lobby.particle.design.EntryParameters.*;
|
||||
|
||||
@@ -109,24 +111,32 @@ public class ParticleEntry {
|
||||
List<Color> colors = values.get(COLORS);
|
||||
Gradient gradient = colors.isEmpty() ? null : new Gradient(colors.toArray(new Color[0]));
|
||||
Material block = values.get(BLOCK);
|
||||
Function<ParticleTickData, Object> data = switch (type.getData()) {
|
||||
BiFunction<ParticleTickData, Location, Object> data = switch (type.getData()) {
|
||||
// Dust keeps its own element below, so presets look exactly as before
|
||||
case NONE, DUST -> null;
|
||||
case COLOR -> tick -> DataParticle.color(gradient, tick);
|
||||
case COLOR_TRANSITION -> tick -> new Particle.DustTransition(
|
||||
case COLOR -> (tick, location) -> DataParticle.color(gradient, tick);
|
||||
case COLOR_TRANSITION -> (tick, location) -> new Particle.DustTransition(
|
||||
colors.isEmpty() ? DataParticle.color(null, tick) : bukkitColor(colors.get(0)),
|
||||
colors.size() < 2 ? DataParticle.color(null, tick) : bukkitColor(colors.get(1)),
|
||||
1);
|
||||
case BLOCK -> {
|
||||
BlockData blockData = block.createBlockData();
|
||||
yield tick -> blockData;
|
||||
yield (tick, location) -> blockData;
|
||||
}
|
||||
case ITEM -> {
|
||||
ItemStack item = new ItemStack(block);
|
||||
yield tick -> item;
|
||||
yield (tick, location) -> item;
|
||||
}
|
||||
case ZERO_INT -> tick -> 0;
|
||||
case ZERO_FLOAT -> tick -> 0f;
|
||||
case TRAIL -> {
|
||||
int duration = values.get(TRAIL_DURATION);
|
||||
Vector target = new Vector(values.get(TRAIL_TARGET_X), values.get(TRAIL_TARGET_Y), values.get(TRAIL_TARGET_Z));
|
||||
// The target follows the body like offsets do when the entry is placed relative to it
|
||||
yield (tick, location) -> new Particle.Trail(
|
||||
location.clone().add(tick.getFrame() == null ? target : tick.getFrame().local(target.getX(), target.getY(), target.getZ())),
|
||||
DataParticle.color(gradient, tick), duration);
|
||||
}
|
||||
case ZERO_INT -> (tick, location) -> 0;
|
||||
case ZERO_FLOAT -> (tick, location) -> 0f;
|
||||
};
|
||||
|
||||
if (type.isDust()) {
|
||||
|
||||
Reference in New Issue
Block a user