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_SPEED = §fSpeed
|
||||||
PARTICLE_PARAM_COLORS = §fColours
|
PARTICLE_PARAM_COLORS = §fColours
|
||||||
PARTICLE_PARAM_BLOCK = §fBlock
|
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_X = §fOffset X
|
||||||
PARTICLE_PARAM_OFFSET_Y = §fOffset Y
|
PARTICLE_PARAM_OFFSET_Y = §fOffset Y
|
||||||
PARTICLE_PARAM_OFFSET_Z = §fOffset Z
|
PARTICLE_PARAM_OFFSET_Z = §fOffset Z
|
||||||
@@ -193,6 +197,7 @@ PARTICLE_TYPE_BLOCK_MARKER = §fBlock marker
|
|||||||
PARTICLE_TYPE_DUST_PILLAR = §fDust pillar
|
PARTICLE_TYPE_DUST_PILLAR = §fDust pillar
|
||||||
PARTICLE_TYPE_FALLING_DUST = §fFalling dust
|
PARTICLE_TYPE_FALLING_DUST = §fFalling dust
|
||||||
PARTICLE_TYPE_ITEM = §fItem breaking
|
PARTICLE_TYPE_ITEM = §fItem breaking
|
||||||
|
PARTICLE_TYPE_TRAIL = §fTrail
|
||||||
PARTICLE_TYPE_FLAME = §fFlame
|
PARTICLE_TYPE_FLAME = §fFlame
|
||||||
PARTICLE_TYPE_SMALL_FLAME = §fSmall flame
|
PARTICLE_TYPE_SMALL_FLAME = §fSmall flame
|
||||||
PARTICLE_TYPE_SOUL_FIRE_FLAME = §fSoul fire 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_SPEED = §fGeschwindigkeit
|
||||||
PARTICLE_PARAM_COLORS = §fFarben
|
PARTICLE_PARAM_COLORS = §fFarben
|
||||||
PARTICLE_PARAM_BLOCK = §fBlock
|
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_X = §fVersatz X
|
||||||
PARTICLE_PARAM_OFFSET_Y = §fVersatz Y
|
PARTICLE_PARAM_OFFSET_Y = §fVersatz Y
|
||||||
PARTICLE_PARAM_OFFSET_Z = §fVersatz Z
|
PARTICLE_PARAM_OFFSET_Z = §fVersatz Z
|
||||||
@@ -193,6 +197,7 @@ PARTICLE_TYPE_BLOCK_MARKER = §fBlockmarkierung
|
|||||||
PARTICLE_TYPE_DUST_PILLAR = §fStaubsäule
|
PARTICLE_TYPE_DUST_PILLAR = §fStaubsäule
|
||||||
PARTICLE_TYPE_FALLING_DUST = §fFallender Staub
|
PARTICLE_TYPE_FALLING_DUST = §fFallender Staub
|
||||||
PARTICLE_TYPE_ITEM = §fGegenstandssplitter
|
PARTICLE_TYPE_ITEM = §fGegenstandssplitter
|
||||||
|
PARTICLE_TYPE_TRAIL = §fSpur
|
||||||
PARTICLE_TYPE_FLAME = §fFlamme
|
PARTICLE_TYPE_FLAME = §fFlamme
|
||||||
PARTICLE_TYPE_SMALL_FLAME = §fKleine Flamme
|
PARTICLE_TYPE_SMALL_FLAME = §fKleine Flamme
|
||||||
PARTICLE_TYPE_SOUL_FIRE_FLAME = §fSeelenfeuerflamme
|
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_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 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 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<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<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);
|
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(
|
public final List<Parameter<?>> ALL = List.of(
|
||||||
PARTICLE, COUNT, SPREAD_X, SPREAD_Y, SPREAD_Z, SPEED, COLORS, BLOCK,
|
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,
|
OFFSET_X, OFFSET_Y, OFFSET_Z, PLACEMENT, INTERVAL, TICK_MODE,
|
||||||
MOVEMENT, GLIDING, GROUND, SNEAK, VISIBILITY
|
MOVEMENT, GLIDING, GROUND, SNEAK, VISIBILITY
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
|
|
||||||
// Left out: ELDER_GUARDIAN, FLASH and the explosion/gust emitters cover other players' screens,
|
// 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
|
@AllArgsConstructor
|
||||||
@Getter
|
@Getter
|
||||||
public enum ParticleType {
|
public enum ParticleType {
|
||||||
@@ -40,6 +40,7 @@ public enum ParticleType {
|
|||||||
DUST_PILLAR(Material.MUD, Particle.DUST_PILLAR, Data.BLOCK, true),
|
DUST_PILLAR(Material.MUD, Particle.DUST_PILLAR, Data.BLOCK, true),
|
||||||
FALLING_DUST(Material.SAND, Particle.FALLING_DUST, Data.BLOCK, true),
|
FALLING_DUST(Material.SAND, Particle.FALLING_DUST, Data.BLOCK, true),
|
||||||
ITEM(Material.ITEM_FRAME, Particle.ITEM, Data.ITEM, 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),
|
FLAME(Material.FLINT_AND_STEEL, Particle.FLAME, Data.NONE, true),
|
||||||
SMALL_FLAME(Material.TORCH, Particle.SMALL_FLAME, Data.NONE, true),
|
SMALL_FLAME(Material.TORCH, Particle.SMALL_FLAME, Data.NONE, true),
|
||||||
@@ -153,6 +154,8 @@ public enum ParticleType {
|
|||||||
BLOCK,
|
BLOCK,
|
||||||
// An item of the entry's block
|
// An item of the entry's block
|
||||||
ITEM,
|
ITEM,
|
||||||
|
// Flies to the entry's trail target in its colour, taking the trail duration
|
||||||
|
TRAIL,
|
||||||
ZERO_INT,
|
ZERO_INT,
|
||||||
ZERO_FLOAT,
|
ZERO_FLOAT,
|
||||||
}
|
}
|
||||||
@@ -171,7 +174,11 @@ public enum ParticleType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean usesColors() {
|
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() {
|
public boolean usesBlock() {
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ import org.bukkit.Color;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Particle;
|
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 {
|
public class DataParticle implements ParticleElement {
|
||||||
|
|
||||||
private final Particle particle;
|
private final Particle particle;
|
||||||
@@ -37,9 +37,9 @@ public class DataParticle implements ParticleElement {
|
|||||||
private final float vz;
|
private final float vz;
|
||||||
private final double speed;
|
private final double speed;
|
||||||
private final int count;
|
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.particle = particle;
|
||||||
this.vx = vx;
|
this.vx = vx;
|
||||||
this.vy = vy;
|
this.vy = vy;
|
||||||
@@ -61,7 +61,7 @@ public class DataParticle implements ParticleElement {
|
|||||||
@Override
|
@Override
|
||||||
public void tick(ParticleTickData particleTickData) {
|
public void tick(ParticleTickData particleTickData) {
|
||||||
Location location = particleTickData.getLocation().add(0.0, 0.2, 0.0);
|
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));
|
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(INTERVAL, Material.CLOCK),
|
||||||
Map.entry(TICK_MODE, Material.REPEATER),
|
Map.entry(TICK_MODE, Material.REPEATER),
|
||||||
Map.entry(PLACEMENT, Material.PLAYER_HEAD),
|
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(MOVEMENT, Material.LEATHER_BOOTS),
|
||||||
Map.entry(GLIDING, Material.ELYTRA),
|
Map.entry(GLIDING, Material.ELYTRA),
|
||||||
Map.entry(GROUND, Material.GRASS_BLOCK),
|
Map.entry(GROUND, Material.GRASS_BLOCK),
|
||||||
@@ -119,6 +123,12 @@ class EntryEditor {
|
|||||||
} else if (type.usesBlock()) {
|
} else if (type.usesBlock()) {
|
||||||
inventory.setItem(ROW_DESIGN * 9 + FIRST_SETTING + 2, parameterItem(context, BLOCK));
|
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));
|
row(inventory, context, ROW_PARTICLE, List.of(COUNT, SPEED, SPREAD_X, SPREAD_Y, SPREAD_Z));
|
||||||
} else {
|
} else {
|
||||||
inventory.setItem(ROW_PARTICLE * 9 + FIRST_SETTING, new SWItem(Material.STRUCTURE_VOID, msg("PARTICLE_FIXED_LOOK", player), clickType -> {
|
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.design.*;
|
||||||
import de.steamwar.lobby.particle.elements.*;
|
import de.steamwar.lobby.particle.elements.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import static de.steamwar.lobby.particle.design.EntryParameters.*;
|
import static de.steamwar.lobby.particle.design.EntryParameters.*;
|
||||||
|
|
||||||
@@ -109,24 +111,32 @@ public class ParticleEntry {
|
|||||||
List<Color> colors = values.get(COLORS);
|
List<Color> colors = values.get(COLORS);
|
||||||
Gradient gradient = colors.isEmpty() ? null : new Gradient(colors.toArray(new Color[0]));
|
Gradient gradient = colors.isEmpty() ? null : new Gradient(colors.toArray(new Color[0]));
|
||||||
Material block = values.get(BLOCK);
|
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
|
// Dust keeps its own element below, so presets look exactly as before
|
||||||
case NONE, DUST -> null;
|
case NONE, DUST -> null;
|
||||||
case COLOR -> tick -> DataParticle.color(gradient, tick);
|
case COLOR -> (tick, location) -> DataParticle.color(gradient, tick);
|
||||||
case COLOR_TRANSITION -> tick -> new Particle.DustTransition(
|
case COLOR_TRANSITION -> (tick, location) -> new Particle.DustTransition(
|
||||||
colors.isEmpty() ? DataParticle.color(null, tick) : bukkitColor(colors.get(0)),
|
colors.isEmpty() ? DataParticle.color(null, tick) : bukkitColor(colors.get(0)),
|
||||||
colors.size() < 2 ? DataParticle.color(null, tick) : bukkitColor(colors.get(1)),
|
colors.size() < 2 ? DataParticle.color(null, tick) : bukkitColor(colors.get(1)),
|
||||||
1);
|
1);
|
||||||
case BLOCK -> {
|
case BLOCK -> {
|
||||||
BlockData blockData = block.createBlockData();
|
BlockData blockData = block.createBlockData();
|
||||||
yield tick -> blockData;
|
yield (tick, location) -> blockData;
|
||||||
}
|
}
|
||||||
case ITEM -> {
|
case ITEM -> {
|
||||||
ItemStack item = new ItemStack(block);
|
ItemStack item = new ItemStack(block);
|
||||||
yield tick -> item;
|
yield (tick, location) -> item;
|
||||||
}
|
}
|
||||||
case ZERO_INT -> tick -> 0;
|
case TRAIL -> {
|
||||||
case ZERO_FLOAT -> tick -> 0f;
|
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()) {
|
if (type.isDust()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user