forked from SteamWar/SteamWar
A new Drawn wings design draws angel, bat, butterfly, fairy and phoenix wings from lines and curves instead of images. The points per wing can be set from 6 to 60, so sparse wings stay cheap enough to show often.
162 lines
7.8 KiB
Java
162 lines
7.8 KiB
Java
/*
|
|
* This file is a part of the SteamWar software.
|
|
*
|
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package de.steamwar.lobby.particle.design;
|
|
|
|
import de.steamwar.lobby.particle.ParticleElement;
|
|
import de.steamwar.lobby.particle.DrawnWings;
|
|
import de.steamwar.lobby.particle.WingDesign;
|
|
import de.steamwar.lobby.particle.elements.Circle;
|
|
import de.steamwar.lobby.particle.elements.Cloud;
|
|
import de.steamwar.lobby.particle.elements.Wing;
|
|
import de.steamwar.lobby.particle.elements.custom.YOffset;
|
|
import lombok.experimental.UtilityClass;
|
|
import org.bukkit.Material;
|
|
|
|
import java.util.LinkedHashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
@UtilityClass
|
|
public class Designs {
|
|
|
|
// Built on first use, so the design classes never depend on each other's initialisation order
|
|
private Map<String, ParticleDesign> registry;
|
|
|
|
public final ParticleDesign SIMPLE = new ParticleDesign("simple", Material.BLAZE_POWDER, "PARTICLE_DESIGN_SIMPLE") {
|
|
@Override
|
|
public ParticleElement build(ParameterValues values, ParticleElement particle) {
|
|
return particle;
|
|
}
|
|
};
|
|
|
|
public final DoubleParameter CIRCLE_RADIUS = new DoubleParameter("radius", "PARTICLE_PARAM_RADIUS", 1, 0.2, 3, 0.1);
|
|
public final DoubleParameter CIRCLE_SPEED = new DoubleParameter("circleSpeed", "PARTICLE_PARAM_CIRCLE_SPEED", 1, -20, 20, 0.5);
|
|
public final DoubleParameter CIRCLE_PHASE = new DoubleParameter("phase", "PARTICLE_PARAM_PHASE", 0, 0, 345, 15);
|
|
public final DoubleParameter CIRCLE_RISE = new DoubleParameter("rise", "PARTICLE_PARAM_RISE", 0, 0, 3, 0.1);
|
|
public final DoubleParameter CIRCLE_RISE_SPEED = new DoubleParameter("riseSpeed", "PARTICLE_PARAM_RISE_SPEED", 20, 0, 100, 5);
|
|
public final BooleanParameter CIRCLE_BOUNCE = new BooleanParameter("bounce", "PARTICLE_PARAM_BOUNCE", true);
|
|
public final BooleanParameter CIRCLE_INVERTED = new BooleanParameter("inverted", "PARTICLE_PARAM_INVERTED", false);
|
|
|
|
public final ParticleDesign CIRCLE = new ParticleDesign("circle", Material.MAGMA_CREAM, "PARTICLE_DESIGN_CIRCLE",
|
|
CIRCLE_RADIUS, CIRCLE_SPEED, CIRCLE_PHASE, CIRCLE_RISE, CIRCLE_RISE_SPEED, CIRCLE_BOUNCE, CIRCLE_INVERTED) {
|
|
@Override
|
|
public ParticleElement build(ParameterValues values, ParticleElement particle) {
|
|
double rise = values.get(CIRCLE_RISE);
|
|
if (rise > 0) {
|
|
particle = new YOffset(particle, values.get(CIRCLE_RISE_SPEED), 0, rise, values.get(CIRCLE_INVERTED), values.get(CIRCLE_BOUNCE));
|
|
}
|
|
return new Circle(particle, values.get(CIRCLE_RADIUS), values.get(CIRCLE_SPEED), values.get(CIRCLE_PHASE));
|
|
}
|
|
};
|
|
|
|
public final ChoiceParameter<WingDesign> WING_IMAGE = new ChoiceParameter<>("image", "PARTICLE_PARAM_WING_IMAGE", WingDesign.SIMPLE, List.of(
|
|
new ChoiceParameter.Choice<>("simple", WingDesign.SIMPLE, false),
|
|
new ChoiceParameter.Choice<>("complex", WingDesign.COMPLEX, false),
|
|
new ChoiceParameter.Choice<>("sword", WingDesign.SWORD, false),
|
|
new ChoiceParameter.Choice<>("sw", WingDesign.SW, true),
|
|
new ChoiceParameter.Choice<>("wgs", WingDesign.WGS, true),
|
|
new ChoiceParameter.Choice<>("sword_crossed", WingDesign.SWORD_CROSSED, true),
|
|
new ChoiceParameter.Choice<>("mwgl", WingDesign.MWGL, true),
|
|
new ChoiceParameter.Choice<>("eclipse", WingDesign.ECLIPSE, true),
|
|
new ChoiceParameter.Choice<>("pl", WingDesign.PL, true),
|
|
new ChoiceParameter.Choice<>("plompa_easter", WingDesign.PlompaEasterWings, true),
|
|
new ChoiceParameter.Choice<>("ely_e", WingDesign.ELY_E, true),
|
|
new ChoiceParameter.Choice<>("ely_l", WingDesign.ELY_L, true),
|
|
new ChoiceParameter.Choice<>("ely_y", WingDesign.ELY_Y, true),
|
|
new ChoiceParameter.Choice<>("ev", WingDesign.EV, true)
|
|
));
|
|
public final DoubleParameter WING_SIZE = new DoubleParameter("size", "PARTICLE_PARAM_WING_SIZE", 0.15, 0.05, 0.3, 0.01);
|
|
|
|
public final ParticleDesign WING = new ParticleDesign("wing", Material.ELYTRA, "PARTICLE_DESIGN_WING", WING_IMAGE, WING_SIZE) {
|
|
@Override
|
|
public ParticleElement build(ParameterValues values, ParticleElement particle) {
|
|
return new Wing(particle, values.get(WING_SIZE), values.get(WING_IMAGE));
|
|
}
|
|
|
|
@Override
|
|
public int points(ParameterValues values) {
|
|
return values.get(WING_IMAGE).getVectors().length;
|
|
}
|
|
|
|
// Wings spawn a particle on every pixel of the image, so they start sparse, and sit on the back even while gliding
|
|
@Override
|
|
public void applyDefaults(ParameterValues values) {
|
|
values.set(EntryParameters.COUNT, 1)
|
|
.set(EntryParameters.SPEED, 0.0)
|
|
.set(EntryParameters.TICK_MODE, EntryParameters.TickMode.ALWAYS)
|
|
.set(EntryParameters.INTERVAL, 20)
|
|
.set(EntryParameters.PLACEMENT, EntryParameters.Placement.BODY);
|
|
}
|
|
};
|
|
|
|
public final ChoiceParameter<DrawnWings> DRAWN_SHAPE = ChoiceParameter.ofEnum("shape", "PARTICLE_PARAM_DRAWN_SHAPE", DrawnWings.ANGEL);
|
|
public final IntParameter WING_DETAIL = new IntParameter("detail", "PARTICLE_PARAM_WING_DETAIL", 20, 6, 60);
|
|
|
|
// Wings drawn from lines, with a chosen number of points per wing; sparse ones stay cheap enough to show often
|
|
public final ParticleDesign DRAWN_WING = new ParticleDesign("drawn_wing", Material.FEATHER, "PARTICLE_DESIGN_DRAWN_WING", DRAWN_SHAPE, WING_DETAIL, WING_SIZE) {
|
|
@Override
|
|
public ParticleElement build(ParameterValues values, ParticleElement particle) {
|
|
return new Wing(particle, values.get(WING_SIZE), values.get(DRAWN_SHAPE).withDetail(values.get(WING_DETAIL)));
|
|
}
|
|
|
|
@Override
|
|
public int points(ParameterValues values) {
|
|
return 2 * values.get(WING_DETAIL);
|
|
}
|
|
|
|
@Override
|
|
public void applyDefaults(ParameterValues values) {
|
|
WING.applyDefaults(values);
|
|
}
|
|
};
|
|
|
|
public final ParticleDesign CLOUD = new ParticleDesign("cloud", Material.WHITE_WOOL, "PARTICLE_DESIGN_CLOUD") {
|
|
@Override
|
|
public ParticleElement build(ParameterValues values, ParticleElement particle) {
|
|
return new Cloud(particle);
|
|
}
|
|
};
|
|
|
|
private Map<String, ParticleDesign> registry() {
|
|
if (registry == null) {
|
|
Map<String, ParticleDesign> designs = new LinkedHashMap<>();
|
|
List.of(SIMPLE, CIRCLE, WING, DRAWN_WING, CLOUD).forEach(design -> register(designs, design));
|
|
RewardDesigns.all().forEach(design -> register(designs, design));
|
|
InternalDesigns.all().forEach(design -> register(designs, design));
|
|
registry = designs;
|
|
}
|
|
return registry;
|
|
}
|
|
|
|
private void register(Map<String, ParticleDesign> designs, ParticleDesign design) {
|
|
if (designs.put(design.getId(), design) != null) {
|
|
throw new IllegalStateException("Duplicate particle design " + design.getId());
|
|
}
|
|
}
|
|
|
|
public ParticleDesign byId(String id) {
|
|
return registry().get(id);
|
|
}
|
|
|
|
public List<ParticleDesign> all() {
|
|
return List.copyOf(registry().values());
|
|
}
|
|
}
|