diff --git a/LobbySystem/src/de/steamwar/lobby/particle/ParticleData.java b/LobbySystem/src/de/steamwar/lobby/particle/ParticleData.java
deleted file mode 100644
index b85af8a7..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/ParticleData.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle;
-
-import de.steamwar.inventory.SWItem;
-import de.steamwar.lobby.LobbySystem;
-import de.steamwar.sql.SteamwarUser;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-public class ParticleData {
-
- private final Material material;
- private final String name;
- private final List attributes = new ArrayList<>();
-
- @Getter
- private final ParticleRequirement requirement;
-
- @Getter
- private final ParticleElement particleElement;
-
- public ParticleData(Material material, String name, ParticleElement particleElement) {
- this.material = material;
- this.name = name;
- this.requirement = ParticleRequirement.NO_REQUIRMENT;
- this.particleElement = particleElement;
- particleElement.aggregateAttributes(this);
- }
-
- public ParticleData(Material material, String name, ParticleRequirement requirement, ParticleElement particleElement) {
- this.material = material;
- this.name = name;
- this.requirement = requirement;
- this.particleElement = particleElement;
- particleElement.aggregateAttributes(this);
- }
-
- public ParticleData add(String attribute) {
- attributes.add(attribute);
- return this;
- }
-
- public SWItem toSWItem(Player player, SteamwarUser user, Set eventTeilnahme, String eggHuntConfig) {
- String translatedName;
- try {
- translatedName = LobbySystem.getMessage().parse(name, player);
- } catch (Exception e) {
- translatedName = name;
- }
-
- List lore = new ArrayList<>();
- lore.add("");
- if (!attributes.isEmpty()) {
- lore.add(LobbySystem.getMessage().parse("PARTICLE_ATTRIBUTE", player));
- attributes.forEach(attribute -> lore.add(LobbySystem.getMessage().parse(attribute, player)));
- lore.add("");
- }
-
- String unlockedBy = requirement.getRequirementName(player);
- if (unlockedBy != null) {
- lore.add(LobbySystem.getMessage().parse("PARTICLE_UNLOCKED_BY", player));
- lore.add(unlockedBy);
- lore.add("");
- }
- if (requirement.test(user, eventTeilnahme, eggHuntConfig)) {
- lore.add(LobbySystem.getMessage().parse("PARTICLE_SELECT", player));
- } else {
- lore.add(LobbySystem.getMessage().parse("PARTICLE_LOCKED", player));
- }
- return new SWItem(material, translatedName, lore, false, clickType -> {
- });
- }
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java b/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java
index 8a4bd6ef..4e8bfe2e 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/ParticleElement.java
@@ -59,9 +59,6 @@ public interface ParticleElement {
}
}
- default void aggregateAttributes(ParticleData particleData) {
- }
-
default ParticleTickType tickType() {
return ParticleTickType.MOVE;
}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/ParticleEnum.java b/LobbySystem/src/de/steamwar/lobby/particle/ParticleEnum.java
deleted file mode 100644
index 57830aa3..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/ParticleEnum.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle;
-
-public interface ParticleEnum {
- ParticleData getParticle();
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/ParticleInventory.java b/LobbySystem/src/de/steamwar/lobby/particle/ParticleInventory.java
index 29167c89..0ebe3b41 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/ParticleInventory.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/ParticleInventory.java
@@ -22,124 +22,55 @@ package de.steamwar.lobby.particle;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import de.steamwar.lobby.LobbySystem;
-import de.steamwar.lobby.particle.particles.*;
-import de.steamwar.lobby.particle.particles.custom.CustomEasterParticle;
-import de.steamwar.lobby.particle.particles.custom.CustomPlayerParticle;
-import de.steamwar.lobby.particle.particles.custom.CustomTeamParticle;
-import de.steamwar.lobby.special.easter.EggHunt;
+import de.steamwar.lobby.particle.slot.ParticlePreset;
+import de.steamwar.lobby.particle.slot.Presets;
import de.steamwar.lobby.util.LobbyPlayer;
-import de.steamwar.sql.Event;
import de.steamwar.sql.SteamwarUser;
-import de.steamwar.sql.TeamTeilnahme;
-import de.steamwar.sql.UserConfig;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.stream.Collectors;
+// Lists the presets a player has unlocked; the slot menus replace this
@UtilityClass
public class ParticleInventory {
- private final Class>[] PARTICLES = {
- PlayerParticle.class,
- CustomPlayerParticle.class,
- TeamParticle.class,
- CustomTeamParticle.class,
- RainCloudParticle.class,
- ServerTeamParticle.class,
- EventParticle.class,
- EventParticlePlacement.class,
- EventParticleParticipation.class,
- EasterParticle.class,
- CustomEasterParticle.class,
- };
+ public void openInventory(Player player) {
+ LobbyPlayer lobbyPlayer = LobbyPlayer.getLobbyPlayer(player);
+ UnlockContext context = new UnlockContext(SteamwarUser.get(player.getUniqueId()));
- public String convertToString(ParticleEnum particleEnum) {
- return particleEnum.getClass().getSimpleName() + "@" + ((Enum>) particleEnum).name();
- }
-
- public ParticleEnum convertFromString(String string) {
- String[] split = string.split("@");
- Class> clazz = null;
- for (Class> aClass : PARTICLES) {
- if (aClass.getSimpleName().equals(split[0])) {
- clazz = aClass;
- break;
- }
- }
- if (clazz != null) {
- try {
- return (ParticleEnum) Enum.valueOf((Class extends Enum>) clazz, split[1]);
- } catch (Exception e) {
- return null;
- }
- }
- return null;
- }
-
- public void openInventory(Player player, boolean onlyUnlocked) {
- LobbyPlayer lobbyPlayer = LobbyPlayer.getLobbyPlayer(player.getUniqueId());
-
- SteamwarUser user = SteamwarUser.get(player.getUniqueId());
- Set events = user.getTeam() == 0 ? new HashSet<>() : TeamTeilnahme.getEvents(user.getTeam()).stream().map(Event::getEventID).collect(Collectors.toSet());
- String eggHuntConfig = UserConfig.getConfig(user.getId(), EggHunt.EGG_HUNT_CONFIG_KEY);
-
- AtomicBoolean hasOneLocked = new AtomicBoolean(false);
- List> particleList = new ArrayList<>();
- for (Class> clazz : PARTICLES) {
- addParticles(particleList, (ParticleEnum[]) clazz.getEnumConstants(), player, onlyUnlocked, hasOneLocked, user, events, eggHuntConfig);
- }
- for (int i = 0; i < particleList.size() % 45; i++) {
- particleList.add(new SWListInv.SWListEntry<>(new SWItem(Material.BLACK_STAINED_GLASS_PANE, " "), null));
+ List> presetList = new ArrayList<>();
+ for (ParticlePreset preset : Presets.all()) {
+ if (!preset.getRequirement().test(context)) continue;
+ List lore = new ArrayList<>();
+ lore.add("");
+ lore.add(LobbySystem.getMessage().parse("PARTICLE_SELECT", player));
+ presetList.add(new SWListInv.SWListEntry<>(new SWItem(preset.getIcon(), translate(preset.getNameKey(), player), lore, preset == lobbyPlayer.getActivePreset(), clickType -> {
+ }), preset));
}
- SWListInv particleSWListInv = new SWListInv<>(player, LobbySystem.getMessage().parse("PARTICLE_INVENTORY", player), false, particleList, (clickType, particle) -> {
- if (particle == null) return;
- lobbyPlayer.setParticle(particle);
+ SWListInv inventory = new SWListInv<>(player, LobbySystem.getMessage().parse("PARTICLE_INVENTORY", player), false, presetList, (clickType, preset) -> {
+ if (preset == null) return;
+ lobbyPlayer.selectPreset(preset);
player.closeInventory();
if (ParticleListener.disabled(player)) {
LobbySystem.getMessage().send("PARTICLE_DEACTIVATED", player);
}
});
- particleSWListInv.setItem(48, Material.BARRIER, LobbySystem.getMessage().parse("PARTICLE_DESELECT", player), new ArrayList<>(), false, clickType -> {
- lobbyPlayer.setParticle(null);
+ inventory.setItem(49, Material.BARRIER, LobbySystem.getMessage().parse("PARTICLE_DESELECT", player), new ArrayList<>(), false, clickType -> {
+ lobbyPlayer.deselect();
+ player.closeInventory();
});
- if (!hasOneLocked.get()) {
- particleSWListInv.setItem(50, Material.GRAY_BANNER, LobbySystem.getMessage().parse("PARTICLE_SHOW_HAS_ALL", player), new ArrayList<>(), false, clickType -> {
- });
- } else if (onlyUnlocked) {
- particleSWListInv.setItem(50, Material.LIME_BANNER, LobbySystem.getMessage().parse("PARTICLE_SHOW_ALL", player), new ArrayList<>(), false, clickType -> {
- openInventory(player, false);
- });
- } else {
- particleSWListInv.setItem(50, Material.RED_BANNER, LobbySystem.getMessage().parse("PARTICLE_SHOW_UNLOCKED", player), new ArrayList<>(), false, clickType -> {
- openInventory(player, true);
- });
- }
- particleSWListInv.open();
+ inventory.open();
}
- private void addParticles(List> particleList, ParticleEnum[] particleEnums, Player player, boolean onlyUnlocked, AtomicBoolean hasOneLocked, SteamwarUser user, Set events, String eggHuntConfig) {
- for (ParticleEnum particle : particleEnums) {
- ParticleData particleData = particle.getParticle();
- SWItem swItem = particleData.toSWItem(player, user, events, eggHuntConfig);
- if (particleData.getRequirement().test(user, events, eggHuntConfig)) {
- particleList.add(new SWListInv.SWListEntry<>(swItem, particle));
- } else {
- hasOneLocked.set(true);
- if (!onlyUnlocked) {
- particleList.add(new SWListInv.SWListEntry<>(swItem, null));
- }
- }
- }
- for (int i = 0; i < particleList.size() % 9; i++) {
- particleList.add(new SWListInv.SWListEntry<>(new SWItem(Material.BLACK_STAINED_GLASS_PANE, " "), null));
+ private String translate(String key, Player player) {
+ try {
+ return LobbySystem.getMessage().parse(key, player);
+ } catch (Exception e) {
+ return key;
}
}
}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/ParticleListener.java b/LobbySystem/src/de/steamwar/lobby/particle/ParticleListener.java
index ea758a44..5b19c9e0 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/ParticleListener.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/ParticleListener.java
@@ -76,7 +76,7 @@ public class ParticleListener implements Listener {
if (!PlayerSpawn.PARTICLE.equals(event.getItem())) return;
event.setCancelled(true);
- ParticleInventory.openInventory(player, true);
+ ParticleInventory.openInventory(player);
}
@EventHandler
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/design/Designs.java b/LobbySystem/src/de/steamwar/lobby/particle/design/Designs.java
index 64d5024c..7b6d3590 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/design/Designs.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/design/Designs.java
@@ -35,14 +35,15 @@ import java.util.Map;
@UtilityClass
public class Designs {
- private final Map DESIGNS = new LinkedHashMap<>();
+ // Built on first use, so the design classes never depend on each other's initialisation order
+ private Map registry;
- public final ParticleDesign SIMPLE = register(new ParticleDesign("simple", Material.BLAZE_POWDER, "PARTICLE_DESIGN_SIMPLE") {
+ 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);
@@ -52,7 +53,7 @@ public class Designs {
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 = register(new ParticleDesign("circle", Material.MAGMA_CREAM, "PARTICLE_DESIGN_CIRCLE",
+ 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) {
@@ -62,7 +63,7 @@ public class Designs {
}
return new Circle(particle, values.get(CIRCLE_RADIUS), values.get(CIRCLE_SPEED), values.get(CIRCLE_PHASE));
}
- });
+ };
public final ChoiceParameter WING_IMAGE = new ChoiceParameter<>("image", "PARTICLE_PARAM_WING_IMAGE", WingDesign.SIMPLE, List.of(
new ChoiceParameter.Choice<>("simple", WingDesign.SIMPLE, false),
@@ -82,7 +83,7 @@ public class Designs {
));
public final DoubleParameter WING_SIZE = new DoubleParameter("size", "PARTICLE_PARAM_WING_SIZE", 0.15, 0.05, 0.3, 0.01);
- public final ParticleDesign WING = register(new ParticleDesign("wing", Material.ELYTRA, "PARTICLE_DESIGN_WING", WING_IMAGE, WING_SIZE) {
+ 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));
@@ -92,27 +93,37 @@ public class Designs {
public int points(ParameterValues values) {
return values.get(WING_IMAGE).getVectors().length;
}
- });
+ };
- public final ParticleDesign CLOUD = register(new ParticleDesign("cloud", Material.WHITE_WOOL, "PARTICLE_DESIGN_CLOUD") {
+ 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 ParticleDesign register(ParticleDesign design) {
- if (DESIGNS.put(design.getId(), design) != null) {
+ private Map registry() {
+ if (registry == null) {
+ Map designs = new LinkedHashMap<>();
+ List.of(SIMPLE, CIRCLE, 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 designs, ParticleDesign design) {
+ if (designs.put(design.getId(), design) != null) {
throw new IllegalStateException("Duplicate particle design " + design.getId());
}
- return design;
}
public ParticleDesign byId(String id) {
- return DESIGNS.get(id);
+ return registry().get(id);
}
public List all() {
- return List.copyOf(DESIGNS.values());
+ return List.copyOf(registry().values());
}
}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/design/FixedDesign.java b/LobbySystem/src/de/steamwar/lobby/particle/design/FixedDesign.java
new file mode 100644
index 00000000..48d9e49b
--- /dev/null
+++ b/LobbySystem/src/de/steamwar/lobby/particle/design/FixedDesign.java
@@ -0,0 +1,62 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.lobby.particle.design;
+
+import de.steamwar.lobby.particle.ParticleElement;
+import de.steamwar.lobby.particle.ParticleRequirement;
+import org.bukkit.Material;
+
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+// A design whose look, including its particles, is fixed; only the entry's conditions, timing and offset apply
+public class FixedDesign extends ParticleDesign {
+
+ private final int points;
+ private final Consumer defaults;
+ private final Supplier shape;
+
+ public FixedDesign(String id, Material icon, String nameKey, ParticleRequirement requirement, int points, Consumer defaults, Supplier shape) {
+ super(id, icon, nameKey, DesignVisibility.REWARD, requirement);
+ this.points = points;
+ this.defaults = defaults;
+ this.shape = shape;
+ }
+
+ @Override
+ public ParticleElement build(ParameterValues values, ParticleElement particle) {
+ return shape.get();
+ }
+
+ @Override
+ public int points(ParameterValues values) {
+ return points;
+ }
+
+ @Override
+ public boolean usesEntryParticle() {
+ return false;
+ }
+
+ @Override
+ public void applyDefaults(ParameterValues values) {
+ defaults.accept(values);
+ }
+}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/design/InternalDesigns.java b/LobbySystem/src/de/steamwar/lobby/particle/design/InternalDesigns.java
new file mode 100644
index 00000000..8367cc7c
--- /dev/null
+++ b/LobbySystem/src/de/steamwar/lobby/particle/design/InternalDesigns.java
@@ -0,0 +1,85 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.lobby.particle.design;
+
+import de.steamwar.lobby.particle.ParticleElement;
+import de.steamwar.lobby.particle.ParticleRequirement;
+import de.steamwar.lobby.particle.elements.Circle;
+import de.steamwar.lobby.particle.elements.custom.HearthBeat;
+import de.steamwar.lobby.particle.elements.custom.PulseShimmer;
+import de.steamwar.lobby.particle.elements.custom.YOffset;
+import lombok.experimental.UtilityClass;
+import org.bukkit.Material;
+
+import java.util.List;
+
+// Shapes only presets use; they are never offered in the builder
+@UtilityClass
+public class InternalDesigns {
+
+ public final IntParameter PULSE_SPEED = new IntParameter("pulseSpeed", "PARTICLE_PARAM_PULSE_SPEED", 80, 1, 200);
+ public final IntParameter PULSE_ROTATION = new IntParameter("pulseRotation", "PARTICLE_PARAM_PULSE_ROTATION", 2, 0, 20);
+
+ public final ParticleDesign PULSE_SHIMMER = new ParticleDesign("pulse_shimmer", Material.GRAY_CANDLE, "PARTICLE_DESIGN_PULSE_SHIMMER", DesignVisibility.INTERNAL, ParticleRequirement.NO_REQUIRMENT,
+ PULSE_SPEED, PULSE_ROTATION) {
+ @Override
+ public ParticleElement build(ParameterValues values, ParticleElement particle) {
+ return new PulseShimmer(particle, values.get(PULSE_SPEED), values.get(PULSE_ROTATION));
+ }
+
+ @Override
+ public int points(ParameterValues values) {
+ return 3;
+ }
+ };
+
+ public final DoubleParameter HEART_BEAT_SPEED = new DoubleParameter("heartBeatSpeed", "PARTICLE_PARAM_HEART_BEAT_SPEED", 80, 1, 200, 5);
+
+ public final ParticleDesign HEART_BEAT = new ParticleDesign("heart_beat", Material.APPLE, "PARTICLE_DESIGN_HEART_BEAT", DesignVisibility.INTERNAL, ParticleRequirement.NO_REQUIRMENT,
+ HEART_BEAT_SPEED) {
+ @Override
+ public ParticleElement build(ParameterValues values, ParticleElement particle) {
+ return new HearthBeat(particle, values.get(HEART_BEAT_SPEED));
+ }
+ };
+
+ public final DoubleParameter ORBIT_RADIUS = new DoubleParameter("orbitRadius", "PARTICLE_PARAM_ORBIT_RADIUS", 1.5, 0.2, 3, 0.1);
+ public final DoubleParameter ORBIT_SPEED = new DoubleParameter("orbitSpeed", "PARTICLE_PARAM_ORBIT_SPEED", 1, -20, 20, 0.5);
+ public final DoubleParameter ORBIT_PHASE = new DoubleParameter("orbitPhase", "PARTICLE_PARAM_ORBIT_PHASE", 0, 0, 345, 15);
+
+ // A circle whose centre itself moves on a circle around the player
+ public final ParticleDesign ORBIT = new ParticleDesign("orbit", Material.ENDER_PEARL, "PARTICLE_DESIGN_ORBIT", DesignVisibility.INTERNAL, ParticleRequirement.NO_REQUIRMENT,
+ ORBIT_RADIUS, ORBIT_SPEED, ORBIT_PHASE,
+ Designs.CIRCLE_RADIUS, Designs.CIRCLE_SPEED, Designs.CIRCLE_PHASE, Designs.CIRCLE_RISE, Designs.CIRCLE_RISE_SPEED, Designs.CIRCLE_BOUNCE, Designs.CIRCLE_INVERTED) {
+ @Override
+ public ParticleElement build(ParameterValues values, ParticleElement particle) {
+ double rise = values.get(Designs.CIRCLE_RISE);
+ if (rise > 0) {
+ particle = new YOffset(particle, values.get(Designs.CIRCLE_RISE_SPEED), 0, rise, values.get(Designs.CIRCLE_INVERTED), values.get(Designs.CIRCLE_BOUNCE));
+ }
+ ParticleElement inner = new Circle(particle, values.get(Designs.CIRCLE_RADIUS), values.get(Designs.CIRCLE_SPEED), values.get(Designs.CIRCLE_PHASE));
+ return new Circle(inner, values.get(ORBIT_RADIUS), values.get(ORBIT_SPEED), values.get(ORBIT_PHASE));
+ }
+ };
+
+ public List all() {
+ return List.of(PULSE_SHIMMER, HEART_BEAT, ORBIT);
+ }
+}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/design/ParticleDesign.java b/LobbySystem/src/de/steamwar/lobby/particle/design/ParticleDesign.java
index c463fd91..ce59f23b 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/design/ParticleDesign.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/design/ParticleDesign.java
@@ -56,4 +56,13 @@ public abstract class ParticleDesign {
public int points(ParameterValues values) {
return 1;
}
+
+ // False for designs with a fixed look that ignore the entry's particle type, count, spread, speed and colours
+ public boolean usesEntryParticle() {
+ return true;
+ }
+
+ // Sets the conditions and timing a new entry of this design starts with
+ public void applyDefaults(ParameterValues values) {
+ }
}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/design/RewardDesigns.java b/LobbySystem/src/de/steamwar/lobby/particle/design/RewardDesigns.java
new file mode 100644
index 00000000..6a85b03d
--- /dev/null
+++ b/LobbySystem/src/de/steamwar/lobby/particle/design/RewardDesigns.java
@@ -0,0 +1,166 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.lobby.particle.design;
+
+import de.steamwar.lobby.particle.ParticleElement;
+import de.steamwar.lobby.particle.ParticleRequirement;
+import de.steamwar.lobby.particle.WingDesign;
+import de.steamwar.lobby.particle.elements.*;
+import lombok.experimental.UtilityClass;
+import org.bukkit.Material;
+import org.bukkit.Particle;
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+import static de.steamwar.lobby.particle.design.EntryParameters.*;
+
+// Designs earned in tournaments and the Easter egg hunt
+@UtilityClass
+public class RewardDesigns {
+
+ private final Consumer MOVE = values -> {
+ };
+ private final Consumer ALWAYS = values -> values.set(TICK_MODE, TickMode.ALWAYS);
+ private final Consumer WINGS = values -> values
+ .set(TICK_MODE, TickMode.ALWAYS)
+ .set(INTERVAL, 20)
+ .set(GLIDING, Gliding.NOT_GLIDING);
+
+ public final ParticleDesign EVENT_PLACEMENT_WARGEAR_SEASON = new FixedDesign("event_placement_wargear_season", Material.ENCHANTING_TABLE, "PARTICLE_EVENT_ENCHANTING",
+ ParticleRequirement.eventPlacement(22, 12, 285, 54), 1, MOVE,
+ () -> new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.01), 0, 1.1, 0))));
+ public final ParticleDesign EVENT_PLACEMENT_AIRSHIP = new FixedDesign("event_placement_airship", Material.SNOWBALL, "PARTICLE_EVENT_CLOUD",
+ ParticleRequirement.eventPlacement(26, 205, 9, 54, 120, 292), 1, MOVE,
+ () -> new Circle(new LocationMutator(new SimpleParticle(Particle.CLOUD, 0, 0, 0, 0.01), 0, 2.2, 0)));
+ public final ParticleDesign EVENT_PLACEMENT_HELLS_BELLS = new FixedDesign("event_placement_hells_bells", Material.TNT_MINECART, "PARTICLE_EVENT_SMOKE",
+ ParticleRequirement.eventPlacement(28, 205, 9, 11), 1, MOVE,
+ () -> new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0, 0, 0, 0.01), 0, 2.2, 0))));
+ public final ParticleDesign EVENT_PLACEMENT_UNDERWATER = new FixedDesign("event_placement_underwater", Material.PRISMARINE_SHARD, "PARTICLE_EVENT_WATER",
+ ParticleRequirement.eventPlacement(31, 9, 210, 520), 1, MOVE,
+ () -> new Cloud(new SimpleParticle(Particle.DRIPPING_WATER)));
+ public final ParticleDesign EVENT_PLACEMENT_ADVENT_WAR_SHIP = new FixedDesign("event_placement_advent_war_ship", Material.PRISMARINE_CRYSTALS, "PARTICLE_EVENT_WATER",
+ ParticleRequirement.eventPlacement(32, 9, 205, 210), 2, ALWAYS,
+ () -> new LocationMutator(new Circle(new Group(new SimpleParticle(Particle.DRIPPING_WATER), new SimpleParticle(Particle.UNDERWATER, 0.2F, 0.2F, 0.2F, 0.01))), 0, 1.1, 0));
+ public final ParticleDesign EVENT_PLACEMENT_MINI_WARGEAR_LIGA = wings("event_placement_mini_wargear_liga", Material.IRON_SWORD, "PARTICLE_EVENT_WINGS",
+ ParticleRequirement.eventPlacement(33, 9, 34, 205), Particle.UNDERWATER, 0.15, WingDesign.MWGL);
+ public final ParticleDesign EVENT_PLACEMENT_ABSTURZ = wings("event_placement_absturz", Material.FEATHER, "PARTICLE_EVENT_WINGS",
+ ParticleRequirement.eventPlacement(34, 210, 205, 527, 286), Particle.CRIT, 0.15, WingDesign.SIMPLE);
+ public final ParticleDesign EVENT_PLACEMENT_UNDERWATER_MWG = wings("event_placement_underwater_mwg", Material.CYAN_CARPET, "PARTICLE_EVENT_RAIN_CLOUD",
+ ParticleRequirement.eventPlacement(35, 9, 210), Particle.CRIT, 0.15, WingDesign.SW);
+ public final ParticleDesign EVENT_PLACEMENT_WARGEAR_SEASON_2022 = wings("event_placement_wargear_season_2022", Material.DIAMOND_HELMET, "PARTICLE_EVENT_WGS",
+ ParticleRequirement.eventPlacement(37, 285, 210, 122), Particle.FIREWORK, 0.15, WingDesign.WGS);
+ public final ParticleDesign EVENT_PLACEMENT_WARGEAR_CLASH = wings("event_placement_wargear_clash", Material.GOLDEN_SWORD, "PARTICLE_EVENT_WARGEARCLASH",
+ ParticleRequirement.eventPlacement(38, 210, 158, 167, 286), Particle.CRIT, 0.1, WingDesign.SWORD_CROSSED);
+
+ public final ParticleDesign EVENT_PARTICIPATION_WARGEAR_SEASON = new FixedDesign("event_participation_wargear_season", Material.BOOK, "PARTICLE_EVENT_ENCHANTING",
+ ParticleRequirement.eventParticipation(22), 1, MOVE,
+ () -> new SimpleParticle(Particle.ENCHANT));
+ public final ParticleDesign EVENT_PARTICIPATION_AIRSHIP = new FixedDesign("event_participation_airship", Material.SNOW_BLOCK, "PARTICLE_EVENT_CLOUD",
+ ParticleRequirement.eventParticipation(26), 1, MOVE,
+ () -> new SimpleParticle(Particle.CLOUD));
+ public final ParticleDesign EVENT_PARTICIPATION_HELLS_BELLS = new FixedDesign("event_participation_hells_bells", Material.TNT, "PARTICLE_EVENT_SMOKE",
+ ParticleRequirement.eventParticipation(28), 1, MOVE,
+ () -> new Circle(new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0, 0, 0, 0.01)));
+ public final ParticleDesign EVENT_PARTICIPATION_UNDERWATER = new FixedDesign("event_participation_underwater", Material.PRISMARINE_BRICKS, "PARTICLE_EVENT_WATER",
+ ParticleRequirement.eventParticipation(31), 1, MOVE,
+ () -> new SimpleParticle(Particle.DRIPPING_WATER));
+ public final ParticleDesign EVENT_PARTICIPATION_ADVENT_WAR_SHIP = new FixedDesign("event_participation_advent_war_ship", Material.PRISMARINE_WALL, "PARTICLE_EVENT_WATER",
+ ParticleRequirement.eventParticipation(32), 2, MOVE,
+ () -> new Group(new SimpleParticle(Particle.DRIPPING_WATER), new SimpleParticle(Particle.UNDERWATER, 0.2F, 0.2F, 0.2F, 0.01)));
+ public final ParticleDesign EVENT_PARTICIPATION_MINI_WARGEAR_LIGA = new FixedDesign("event_participation_mini_wargear_liga", Material.PRISMARINE_SLAB, "PARTICLE_EVENT_WATER",
+ ParticleRequirement.eventParticipation(33), 1, MOVE,
+ () -> new Circle(new SimpleParticle(Particle.UNDERWATER, 0, 0, 0, 0)));
+ public final ParticleDesign EVENT_PARTICIPATION_UNDERWATER_MWG = new FixedDesign("event_participation_underwater_mwg", Material.BLUE_CARPET, "PARTICLE_EVENT_RAIN_CLOUD",
+ ParticleRequirement.eventParticipation(35), 3, ALWAYS,
+ () -> new RandomParticle(
+ rainCloud(Particle.RAIN, Particle.DRIPPING_WATER, 5),
+ rainCloud(null, Particle.DRIPPING_LAVA, 5),
+ rainCloud(null, Particle.FALLING_NECTAR, 5),
+ rainCloud(null, Particle.FALLING_HONEY, 5),
+ rainCloud(null, Particle.FALLING_SPORE_BLOSSOM, 5),
+ rainCloud(null, Particle.FALLING_OBSIDIAN_TEAR, 5),
+ rainCloud(null, Particle.NAUTILUS, 5),
+ rainCloud(null, Particle.ENCHANT, 5),
+ rainCloud(null, Particle.ITEM_SLIME, 5),
+ rainCloud(null, Particle.ITEM_SNOWBALL, 5),
+ rainCloud(null, Particle.SNOWFLAKE, 5),
+ rainCloud(null, Particle.TOTEM_OF_UNDYING, 2)
+ ));
+ public final ParticleDesign EVENT_PARTICIPATION_WARGEAR_SEASON_2022 = wings("event_participation_wargear_season_2022", Material.DIAMOND_SWORD, "PARTICLE_EVENT_WINGS",
+ ParticleRequirement.eventParticipation(37), Particle.DRAGON_BREATH, 0.15, WingDesign.COMPLEX);
+
+ public final ParticleDesign EGG_HUNT_EASY = new FixedDesign("egg_hunt_easy", Material.LIME_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_EASY",
+ ParticleRequirement.EGG_HUNT_EASY, 1, ALWAYS,
+ () -> new LocationMutator(new SimpleParticle(Particle.FALLING_SPORE_BLOSSOM, 0.5F, 0.1f, 0.5F, 1, 1), 0, 2.2, 0));
+ public final ParticleDesign EGG_HUNT_MEDIUM = new FixedDesign("egg_hunt_medium", Material.YELLOW_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_MEDIUM",
+ ParticleRequirement.EGG_HUNT_MEDIUM, 1, ALWAYS.andThen(values -> values.set(GROUND, Ground.ON_GROUND).set(SNEAK, Sneak.SNEAKING)),
+ () -> new SimpleParticle(Particle.GLOW_SQUID_INK, 0.4F, 0.9F, 0.4F, 0.01));
+ public final ParticleDesign EGG_HUNT_HARD = new FixedDesign("egg_hunt_hard", Material.RED_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_HARD",
+ ParticleRequirement.EGG_HUNT_HARD, 2, ALWAYS,
+ () -> new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0.01, 1, null), new DustParticle(Particle.DUST, 0, 0, 0, 0.01, 1, null)), 0, 0.5, 0));
+ public final ParticleDesign EGG_HUNT_EXTREME = new FixedDesign("egg_hunt_extreme", Material.PURPLE_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_EXTREME",
+ ParticleRequirement.EGG_HUNT_EXTREME, 1, ALWAYS,
+ () -> new LocationMutator(new SimpleParticle(Particle.FALLING_OBSIDIAN_TEAR, 0.5F, 0.1F, 0.5F, 1, 1), 0, 2.2, 0));
+ public final ParticleDesign EGG_HUNT_ADVANCED = new FixedDesign("egg_hunt_advanced", Material.BLACK_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_ADVANCED",
+ ParticleRequirement.EGG_HUNT_ADVANCED, 2, ALWAYS.andThen(values -> values.set(SNEAK, Sneak.SNEAKING)),
+ () -> new LocationMutator(new Group(
+ new SimpleParticle(Particle.SMOKE, 0.02F, 0, 0.02F, 0.05, 1),
+ new SimpleParticle(Particle.LARGE_SMOKE, 0.02F, 0, 0.02F, 0.05, 1),
+ particleTickData -> {
+ Player player = particleTickData.getPlayer();
+ player.setVelocity(player.getVelocity().add(new Vector(0, 0.1, 0)));
+ }
+ ), 0, -0.2, 0));
+ // Hearts above the head while sneaking on the ground, a heart cloud ring while in the air
+ public final ParticleDesign EGG_HUNT_HALF = new FixedDesign("egg_hunt_half", Material.EGG, "PARTICLE_EGG_HUNT_HALF",
+ ParticleRequirement.EGG_HUNT_FOUND_HALF, 1, ALWAYS,
+ () -> new Group(
+ new Sneaking(new Floor(new LocationMutator(new SimpleParticle(Particle.HEART, 0, 0, 0, 0.01), 0, 1.7, 0))),
+ new NonFloor(new NonFlying(new LocationMutator(new Cloud(new Circle(new SimpleParticle(Particle.HEART, 0, 0, 0, 0.01))), 0, 0.5, 0)))
+ ));
+
+ private ParticleDesign wings(String id, Material icon, String nameKey, ParticleRequirement requirement, Particle particle, double size, WingDesign wingDesign) {
+ return new FixedDesign(id, icon, nameKey, requirement, wingDesign.getVectors().length, WINGS,
+ () -> new Wing(new SimpleParticle(particle, 0, 0, 0, 0, 1), size, wingDesign));
+ }
+
+ // A cloud above the head that drips the given particle; rain is an optional second particle inside the cloud
+ private ParticleElement rainCloud(Particle rain, Particle drip, int dripCount) {
+ ParticleElement cloud = new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01);
+ ParticleElement drops = new LocationMutator(new SimpleParticle(drip, 0.3F, 0.0F, 0.3F, 0.01, dripCount), 0, -0.3, 0);
+ ParticleElement group = rain == null ? new Group(cloud, drops) : new Group(cloud, new SimpleParticle(rain, 0.3F, 0.1F, 0.3F, 0.01), drops);
+ return new LocationMutator(group, 0, 2.4, 0);
+ }
+
+ public List all() {
+ return List.of(
+ EVENT_PLACEMENT_WARGEAR_SEASON, EVENT_PLACEMENT_AIRSHIP, EVENT_PLACEMENT_HELLS_BELLS, EVENT_PLACEMENT_UNDERWATER,
+ EVENT_PLACEMENT_ADVENT_WAR_SHIP, EVENT_PLACEMENT_MINI_WARGEAR_LIGA, EVENT_PLACEMENT_ABSTURZ, EVENT_PLACEMENT_UNDERWATER_MWG,
+ EVENT_PLACEMENT_WARGEAR_SEASON_2022, EVENT_PLACEMENT_WARGEAR_CLASH,
+ EVENT_PARTICIPATION_WARGEAR_SEASON, EVENT_PARTICIPATION_AIRSHIP, EVENT_PARTICIPATION_HELLS_BELLS, EVENT_PARTICIPATION_UNDERWATER,
+ EVENT_PARTICIPATION_ADVENT_WAR_SHIP, EVENT_PARTICIPATION_MINI_WARGEAR_LIGA, EVENT_PARTICIPATION_UNDERWATER_MWG,
+ EVENT_PARTICIPATION_WARGEAR_SEASON_2022,
+ EGG_HUNT_EASY, EGG_HUNT_MEDIUM, EGG_HUNT_HARD, EGG_HUNT_EXTREME, EGG_HUNT_ADVANCED, EGG_HUNT_HALF
+ );
+ }
+}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Always.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Always.java
index 3c036e9d..514d06ff 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Always.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/Always.java
@@ -29,11 +29,6 @@ public class Always extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_TICK";
- }
-
@Override
public ParticleTickType tickType() {
return ParticleTickType.ALWAYS;
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Circle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Circle.java
index 9b9d344c..e95af976 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Circle.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/Circle.java
@@ -47,11 +47,6 @@ public class Circle extends DelegatingParticleElement {
this.phase = Math.toRadians(phaseDegrees);
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_CIRCLE";
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
Location location = particleTickData.getLocation();
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Cloud.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Cloud.java
index d53ef969..598ead74 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Cloud.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/Cloud.java
@@ -31,11 +31,6 @@ public class Cloud extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_CLOUD";
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
if (particleTickData.getWorld().getBlockAt(particleTickData.getPlayer().getLocation().subtract(0, 0.5, 0)).getType() == Material.AIR) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Delayed.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Delayed.java
index b26e8510..32f4ec88 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Delayed.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/Delayed.java
@@ -40,11 +40,6 @@ public class Delayed extends DelegatingParticleElement {
}
}
- @Override
- public String attribute() {
- return null;
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
int currentNumber = data.getOrDefault(particleTickData.getPlayer(), 0) % interval;
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/DelegatingParticleElement.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/DelegatingParticleElement.java
index 58c76500..3eb4181c 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/DelegatingParticleElement.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/DelegatingParticleElement.java
@@ -19,7 +19,6 @@
package de.steamwar.lobby.particle.elements;
-import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickType;
@@ -31,17 +30,6 @@ public abstract class DelegatingParticleElement implements ParticleElement {
this.particleElement = particleElement;
}
- public abstract String attribute();
-
- @Override
- public void aggregateAttributes(ParticleData particleData) {
- String attribute = attribute();
- if (attribute != null) {
- particleData.add(attribute);
- }
- particleElement.aggregateAttributes(particleData);
- }
-
@Override
public ParticleTickType tickType() {
return particleElement.tickType();
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/DoubleCircle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/DoubleCircle.java
index c7c090f1..117fb2a6 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/DoubleCircle.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/DoubleCircle.java
@@ -46,11 +46,6 @@ public class DoubleCircle extends Circle {
this.speed = speed;
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_BI_CIRCLE";
- }
-
@Override
public ParticleTickType tickType() {
if (particleElement.tickType() == second.tickType()) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Floor.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Floor.java
index d7c81e66..df5986df 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Floor.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/Floor.java
@@ -28,11 +28,6 @@ public class Floor extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_FLOOR";
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
if (!particleTickData.getWorld().getBlockAt(particleTickData.getPlayer().getLocation().subtract(0, 0.5, 0)).getType().isAir()) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Flying.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Flying.java
index 6d010c4a..d9e5f525 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Flying.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/Flying.java
@@ -28,11 +28,6 @@ public class Flying extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_FLYING";
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
if (!particleTickData.getPlayer().isGliding()) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Group.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Group.java
index ca027fed..1f119fc2 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Group.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/Group.java
@@ -19,7 +19,6 @@
package de.steamwar.lobby.particle.elements;
-import de.steamwar.lobby.particle.ParticleData;
import de.steamwar.lobby.particle.ParticleElement;
import de.steamwar.lobby.particle.ParticleTickData;
@@ -32,19 +31,6 @@ public class Group extends DelegatingParticleElement {
this.rest = rest;
}
- @Override
- public String attribute() {
- return null;
- }
-
- @Override
- public void aggregateAttributes(ParticleData particleData) {
- particleElement.aggregateAttributes(particleData);
- for (ParticleElement particleElement : rest) {
- particleElement.aggregateAttributes(particleData);
- }
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
particleElement.tick(particleTickData);
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/LocationMutator.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/LocationMutator.java
index f38ef40c..b83ecf0f 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/LocationMutator.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/LocationMutator.java
@@ -38,11 +38,6 @@ public class LocationMutator extends DelegatingParticleElement {
this(particleElement, location -> location.add(vx, vy, vz));
}
- @Override
- public String attribute() {
- return null;
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
ParticleTickData nParticleTickData = particleTickData.withLocation(mutator.apply(particleTickData.getLocation()));
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/NonFloor.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/NonFloor.java
index 79fe9e3f..bc712aa3 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/NonFloor.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/NonFloor.java
@@ -28,11 +28,6 @@ public class NonFloor extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_NON_FLOOR";
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
if (particleTickData.getWorld().getBlockAt(particleTickData.getPlayer().getLocation().subtract(0, 0.5, 0)).getType().isAir()) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/NonFlying.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/NonFlying.java
index 072319d3..e94aed24 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/NonFlying.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/NonFlying.java
@@ -28,11 +28,6 @@ public class NonFlying extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_NON_FLYING";
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
if (particleTickData.getPlayer().isGliding()) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/OnlyOthers.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/OnlyOthers.java
index cb65f0a5..e4483ef7 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/OnlyOthers.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/OnlyOthers.java
@@ -28,11 +28,6 @@ public class OnlyOthers extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return null;
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
particleElement.tick(particleTickData.onlyOthers());
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/OnlySelf.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/OnlySelf.java
index a150b467..b1a80be0 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/OnlySelf.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/OnlySelf.java
@@ -28,11 +28,6 @@ public class OnlySelf extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return null;
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
particleElement.tick(particleTickData.onlySelf());
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/RandomParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/RandomParticle.java
index 94842466..7f1c05d0 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/RandomParticle.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/RandomParticle.java
@@ -20,7 +20,6 @@
package de.steamwar.lobby.particle.elements;
import de.steamwar.lobby.particle.ParticleElement;
-import de.steamwar.lobby.particle.ParticleEnum;
import de.steamwar.lobby.particle.ParticleTickData;
import org.bukkit.entity.Player;
@@ -31,18 +30,18 @@ public class RandomParticle implements ParticleElement {
// Weak keys drop players once they quit, so each player rolls again on their next session
private final Map data = new WeakHashMap<>();
- private final ParticleEnum[] particleEnums;
+ private final ParticleElement[] particleElements;
- public RandomParticle(ParticleEnum... particleEnums) {
- if (particleEnums.length == 0) {
- throw new IllegalArgumentException("ParticleEnums must not be empty");
+ public RandomParticle(ParticleElement... particleElements) {
+ if (particleElements.length == 0) {
+ throw new IllegalArgumentException("ParticleElements must not be empty");
}
- this.particleEnums = particleEnums;
+ this.particleElements = particleElements;
}
@Override
public void tick(ParticleTickData particleTickData) {
- int currentNumber = data.computeIfAbsent(particleTickData.getPlayer(), player -> RANDOM.nextInt(particleEnums.length));
- particleEnums[currentNumber].getParticle().getParticleElement().tick(particleTickData);
+ int currentNumber = data.computeIfAbsent(particleTickData.getPlayer(), player -> RANDOM.nextInt(particleElements.length));
+ particleElements[currentNumber].tick(particleTickData);
}
}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Separator.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Separator.java
deleted file mode 100644
index 8d25da99..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Separator.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.elements;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleElement;
-import de.steamwar.lobby.particle.ParticleTickData;
-
-public class Separator implements ParticleElement {
-
- @Override
- public void aggregateAttributes(ParticleData particleData) {
- particleData.add("PARTICLE_ATTRIBUTE_SEPARATOR");
- }
-
- @Override
- public void tick(ParticleTickData particleTickData) {
- // do nothing
- }
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Sneaking.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Sneaking.java
index 6cf86e40..53c095d2 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Sneaking.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/Sneaking.java
@@ -28,11 +28,6 @@ public class Sneaking extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_SNEAKING";
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
if (!particleTickData.getPlayer().isSneaking()) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java
index f5ba8b66..39425c1e 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/TrippleCircle.java
@@ -48,11 +48,6 @@ public class TrippleCircle extends Circle {
this.speed = speed;
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_TRI_CIRCLE";
- }
-
@Override
public ParticleTickType tickType() {
if (particleElement.tickType() == second.tickType() && particleElement.tickType() == third.tickType()) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/Wing.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/Wing.java
index 147228d3..1c8f1322 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/Wing.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/Wing.java
@@ -36,11 +36,6 @@ public class Wing extends DelegatingParticleElement {
this.wingDesign = wingDesign;
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_WING";
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
for (Vector dVector : wingDesign.getVectors()) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/HearthBeat.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/HearthBeat.java
index 4f076c40..b6ffd443 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/HearthBeat.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/HearthBeat.java
@@ -41,11 +41,6 @@ public class HearthBeat extends DelegatingParticleElement {
this.speed = speed;
}
- @Override
- public String attribute() {
- return null;
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
double time = ((particleTickData.getDeg() * speed) % 360) / 360.0;
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/NonMoving.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/NonMoving.java
index c0f6cf6e..accde42a 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/NonMoving.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/NonMoving.java
@@ -29,11 +29,6 @@ public class NonMoving extends DelegatingParticleElement {
super(particleElement);
}
- @Override
- public String attribute() {
- return "PARTICLE_ATTRIBUTE_NON_MOVING";
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
if (particleTickData.isMoving()) {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/PulseShimmer.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/PulseShimmer.java
index c895a11b..addc92ba 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/PulseShimmer.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/PulseShimmer.java
@@ -47,11 +47,6 @@ public class PulseShimmer extends DelegatingParticleElement {
this.rotationSpeed = rotationSpeed;
}
- @Override
- public String attribute() {
- return null;
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
double time = ((particleTickData.getDeg() * speed) % 360) / 360.0;
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/YOffset.java b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/YOffset.java
index f49e4219..15375522 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/YOffset.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/elements/custom/YOffset.java
@@ -40,11 +40,6 @@ public class YOffset extends DelegatingParticleElement {
this.bounce = bounce;
}
- @Override
- public String attribute() {
- return null;
- }
-
@Override
public void tick(ParticleTickData particleTickData) {
double y;
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/EasterParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/EasterParticle.java
deleted file mode 100644
index 3e3fdabf..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/EasterParticle.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleRequirement;
-import de.steamwar.lobby.particle.elements.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-import org.bukkit.entity.Player;
-import org.bukkit.util.Vector;
-
-@AllArgsConstructor
-public enum EasterParticle implements ParticleEnum {
-
- EGG_HUNT_EASY(new ParticleData(Material.LIME_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_EASY", ParticleRequirement.EGG_HUNT_EASY,
- new Always(new LocationMutator(new SimpleParticle(Particle.FALLING_SPORE_BLOSSOM, 0.5F, 0.1f, 0.5F, 1, 1), 0, 2.2, 0)))
- ),
- EGG_HUNT_MEDIUM(new ParticleData(Material.YELLOW_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_MEDIUM", ParticleRequirement.EGG_HUNT_MEDIUM,
- new Always(new Floor(new Sneaking(new SimpleParticle(Particle.GLOW_SQUID_INK, 0.4F, 0.9F, 0.4F, 0.01)))))
- ),
- EGG_HUNT_HARD(new ParticleData(Material.RED_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_HARD", ParticleRequirement.EGG_HUNT_HARD,
- new Always(new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0.01, 1, null), new DustParticle(Particle.DUST, 0, 0, 0, 0.01, 1, null)), 0, 0.5, 0)))
- ),
- EGG_HUNT_EXTREME(new ParticleData(Material.PURPLE_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_EXTREME", ParticleRequirement.EGG_HUNT_EXTREME,
- new Always(new LocationMutator(new SimpleParticle(Particle.FALLING_OBSIDIAN_TEAR, 0.5F, 0.1F, 0.5F, 1, 1), 0, 2.2, 0)))
- ),
- EGG_HUNT_ADVANCED(new ParticleData(Material.BLACK_CONCRETE_POWDER, "PARTICLE_EGG_HUNT_ADVANCED", ParticleRequirement.EGG_HUNT_ADVANCED,
- new Always(new Sneaking(new LocationMutator(new Group(
- new SimpleParticle(Particle.SMOKE, 0.02F, 0, 0.02F, 0.05, 1),
- new SimpleParticle(Particle.LARGE_SMOKE, 0.02F, 0, 0.02F, 0.05, 1),
- particleTickData -> {
- Player player = particleTickData.getPlayer();
- player.setVelocity(player.getVelocity().add(new Vector(0, 0.1, 0)));
- }
- ), 0, -0.2, 0))))
- ),
- EGG_HUNT_HALF(new ParticleData(Material.EGG, "PARTICLE_EGG_HUNT_HALF", ParticleRequirement.EGG_HUNT_FOUND_HALF,
- new Group(
- new Always(new Sneaking(new Floor(new LocationMutator(new SimpleParticle(Particle.HEART, 0, 0, 0, 0.01), 0, 1.7, 0)))),
- new Separator(),
- new Always(new NonFloor(new NonFlying(new LocationMutator(new Cloud(new Circle(new SimpleParticle(Particle.HEART, 0, 0, 0, 0.01))), 0, 0.5, 0))))
- ))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/EventParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/EventParticle.java
deleted file mode 100644
index 4617bd5e..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/EventParticle.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleRequirement;
-import de.steamwar.lobby.particle.elements.Always;
-import de.steamwar.lobby.particle.elements.Circle;
-import de.steamwar.lobby.particle.elements.LocationMutator;
-import de.steamwar.lobby.particle.elements.SimpleParticle;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-@AllArgsConstructor
-public enum EventParticle implements ParticleEnum {
-
- WATER(new ParticleData(Material.WATER_BUCKET, "PARTICLE_WATER", ParticleRequirement.EVENT_PARTICIPATION,
- new Always(new Circle(new LocationMutator(new SimpleParticle(Particle.DRIPPING_WATER), 0, 1.1, 0))))
- ),
- LAVA(new ParticleData(Material.LAVA_BUCKET, "PARTICLE_FIRE", ParticleRequirement.EVENT_PARTICIPATION,
- new Always(new Circle(new LocationMutator(new SimpleParticle(Particle.DRIPPING_LAVA), 0, 1.1, 0))))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/EventParticleParticipation.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/EventParticleParticipation.java
deleted file mode 100644
index 7d033509..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/EventParticleParticipation.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleRequirement;
-import de.steamwar.lobby.particle.WingDesign;
-import de.steamwar.lobby.particle.elements.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-@AllArgsConstructor
-public enum EventParticleParticipation implements ParticleEnum {
-
- WarGearSeason(new ParticleData(Material.BOOK, "PARTICLE_EVENT_ENCHANTING", ParticleRequirement.eventParticipation(22),
- new SimpleParticle(Particle.ENCHANT))
- ),
- AirshipEvent(new ParticleData(Material.SNOW_BLOCK, "PARTICLE_EVENT_CLOUD", ParticleRequirement.eventParticipation(26),
- new SimpleParticle(Particle.CLOUD))
- ),
- HellsBellsWs(new ParticleData(Material.TNT, "PARTICLE_EVENT_SMOKE", ParticleRequirement.eventParticipation(28),
- new Circle(new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0, 0, 0, 0.01)))
- ),
- Underwater(new ParticleData(Material.PRISMARINE_BRICKS, "PARTICLE_EVENT_WATER", ParticleRequirement.eventParticipation(31),
- new SimpleParticle(Particle.DRIPPING_WATER))
- ),
- AdventWarShip(new ParticleData(Material.PRISMARINE_WALL, "PARTICLE_EVENT_WATER", ParticleRequirement.eventParticipation(32),
- new Group(new SimpleParticle(Particle.DRIPPING_WATER), new SimpleParticle(Particle.UNDERWATER, 0.2F, 0.2F, 0.2F, 0.01)))
- ),
- MiniWarGearLiga(new ParticleData(Material.PRISMARINE_SLAB, "PARTICLE_EVENT_WATER", ParticleRequirement.eventParticipation(33),
- new Circle(new SimpleParticle(Particle.UNDERWATER, 0, 0, 0, 0)))
- ),
- UnderwaterMWG(new ParticleData(Material.BLUE_CARPET, "PARTICLE_EVENT_RAIN_CLOUD", ParticleRequirement.eventParticipation(35),
- new Always(new RandomParticle(RainCloudParticle.values())))
- ),
- WarGearSeason2022(new ParticleData(Material.DIAMOND_SWORD, "PARTICLE_EVENT_WINGS", ParticleRequirement.eventParticipation(37),
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.DRAGON_BREATH, 0, 0, 0, 0, 1), 0.15, WingDesign.COMPLEX)), 20)))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/EventParticlePlacement.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/EventParticlePlacement.java
deleted file mode 100644
index 03cf80d7..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/EventParticlePlacement.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleRequirement;
-import de.steamwar.lobby.particle.WingDesign;
-import de.steamwar.lobby.particle.elements.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-@AllArgsConstructor
-public enum EventParticlePlacement implements ParticleEnum {
-
- WarGearSeason(new ParticleData(Material.ENCHANTING_TABLE, "PARTICLE_EVENT_ENCHANTING", ParticleRequirement.eventPlacement(22, 12, 285, 54),
- new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.01), 0, 1.1, 0)))
- )),
- AirshipEvent(new ParticleData(Material.SNOWBALL, "PARTICLE_EVENT_CLOUD", ParticleRequirement.eventPlacement(26, 205, 9, 54, 120, 292),
- new Circle(new LocationMutator(new SimpleParticle(Particle.CLOUD, 0, 0, 0, 0.01), 0, 2.2, 0))
- )),
- HellsBellsWs(new ParticleData(Material.TNT_MINECART, "PARTICLE_EVENT_SMOKE", ParticleRequirement.eventPlacement(28, 205, 9, 11),
- new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0, 0, 0, 0.01), 0, 2.2, 0)))
- )),
- Underwater(new ParticleData(Material.PRISMARINE_SHARD, "PARTICLE_EVENT_WATER", ParticleRequirement.eventPlacement(31, 9, 210, 520),
- new Cloud(new SimpleParticle(Particle.DRIPPING_WATER)))
- ),
- AdventWarShip(new ParticleData(Material.PRISMARINE_CRYSTALS, "PARTICLE_EVENT_WATER", ParticleRequirement.eventPlacement(32, 9, 205, 210),
- new Always(new LocationMutator(new Circle(new Group(new SimpleParticle(Particle.DRIPPING_WATER), new SimpleParticle(Particle.UNDERWATER, 0.2F, 0.2F, 0.2F, 0.01))), 0, 1.1, 0)))
- ),
- MiniWarGearLiga(new ParticleData(Material.IRON_SWORD, "PARTICLE_EVENT_WINGS", ParticleRequirement.eventPlacement(33, 9, 34, 205),
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.UNDERWATER, 0, 0, 0, 0, 1), 0.15, WingDesign.MWGL)), 20)))
- ),
- Absturz(new ParticleData(Material.FEATHER, "PARTICLE_EVENT_WINGS", ParticleRequirement.eventPlacement(34, 210, 205, 527, 286),
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0, 1), 0.15, WingDesign.SIMPLE)), 20)))
- ),
- UnderwaterMWG(new ParticleData(Material.CYAN_CARPET, "PARTICLE_EVENT_RAIN_CLOUD", ParticleRequirement.eventPlacement(35, 9, 210),
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0, 1), 0.15, WingDesign.SW)), 20)))
- ),
- WarGearSeason2022(new ParticleData(Material.DIAMOND_HELMET, "PARTICLE_EVENT_WGS", ParticleRequirement.eventPlacement(37, 285, 210, 122),
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.FIREWORK, 0, 0, 0, 0, 1), 0.15, WingDesign.WGS)), 20)))
- ),
- WargearClash(new ParticleData(Material.GOLDEN_SWORD, "PARTICLE_EVENT_WARGEARCLASH", ParticleRequirement.eventPlacement(38, 210, 158, 167, 286),
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0, 1), 0.1, WingDesign.SWORD_CROSSED)), 20)))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/PlayerParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/PlayerParticle.java
deleted file mode 100644
index 842bfd79..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/PlayerParticle.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.elements.DustParticle;
-import de.steamwar.lobby.particle.elements.LocationMutator;
-import de.steamwar.lobby.particle.elements.SimpleParticle;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-@AllArgsConstructor
-public enum PlayerParticle implements ParticleEnum {
-
- SNEEZE(new ParticleData(Material.SLIME_BLOCK, "PARTICLE_SNEEZE",
- new SimpleParticle(Particle.SNEEZE, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- SMOKE(new ParticleData(Material.COBWEB, "PARTICLE_SMOKE",
- new SimpleParticle(Particle.SMOKE, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- FIRE(new ParticleData(Material.LAVA_BUCKET, "PARTICLE_FIRE",
- new SimpleParticle(Particle.DRIPPING_LAVA))
- ),
- WATER(new ParticleData(Material.WATER_BUCKET, "PARTICLE_WATER",
- new SimpleParticle(Particle.DRIPPING_WATER))
- ),
- HEARTH(new ParticleData(Material.RED_DYE, "PARTICLE_HEART",
- new LocationMutator(new SimpleParticle(Particle.HEART), 0, 2.2, 0))
- ),
- NOTES(new ParticleData(Material.NOTE_BLOCK, "PARTICLE_NOTES",
- new LocationMutator(new SimpleParticle(Particle.NOTE), 0, 2.2, 0))
- ),
- NAUTILUS(new ParticleData(Material.NAUTILUS_SHELL, "PARTICLE_NAUTILUS",
- new SimpleParticle(Particle.NAUTILUS, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- SNOWBALL(new ParticleData(Material.SNOWBALL, "PARTICLE_SNOWBALL",
- new SimpleParticle(Particle.SNOWFLAKE, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- EFFECT(new ParticleData(Material.GLASS_BOTTLE, "PARTICLE_EFFECT",
- new DustParticle(Particle.DUST, 0, 0.2F, 0, 0.01, 5, null))
- ),
- CAMPFIRE(new ParticleData(Material.CAMPFIRE, "PARTICLE_CAMPFIRE",
- new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0, 0.2F, 0, 0.01))
- ),
- MAGIC(new ParticleData(Material.CAULDRON, "PARTICLE_MAGIC",
- new SimpleParticle(Particle.CRIT, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- ANGRY(new ParticleData(Material.REDSTONE_BLOCK, "PARTICLE_ANGRY",
- new SimpleParticle(Particle.ANGRY_VILLAGER, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- SLIME(new ParticleData(Material.SLIME_BALL, "PARTICLE_SLIME",
- new SimpleParticle(Particle.ITEM_SLIME))
- ),
- MOB(new ParticleData(Material.ZOMBIE_HEAD, "PARTICLE_MOB",
- new SimpleParticle(Particle.SOUL))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/RainCloudParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/RainCloudParticle.java
deleted file mode 100644
index 7df64822..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/RainCloudParticle.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleRequirement;
-import de.steamwar.lobby.particle.elements.Always;
-import de.steamwar.lobby.particle.elements.Group;
-import de.steamwar.lobby.particle.elements.LocationMutator;
-import de.steamwar.lobby.particle.elements.SimpleParticle;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-@AllArgsConstructor
-public enum RainCloudParticle implements ParticleEnum {
-
- Raincloud(new ParticleData(Material.BLUE_CARPET, "PARTICLE_RAINCLOUD_NORMAL", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new SimpleParticle(Particle.RAIN, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.DRIPPING_WATER, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Red_Raincloud(new ParticleData(Material.RED_CARPET, "PARTICLE_RAINCLOUD_RED", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.DRIPPING_LAVA, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Yellow_Raincloud(new ParticleData(Material.YELLOW_CARPET, "PARTICLE_RAINCLOUD_YELLOW", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.FALLING_NECTAR, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Orange_Raincloud(new ParticleData(Material.ORANGE_CARPET, "PARTICLE_RAINCLOUD_ORANGE", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.FALLING_HONEY, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Green_Raincloud(new ParticleData(Material.LIME_CARPET, "PARTICLE_RAINCLOUD_GREEN", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.FALLING_SPORE_BLOSSOM, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Purple_Raincloud(new ParticleData(Material.PURPLE_CARPET, "PARTICLE_RAINCLOUD_PURPLE", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.FALLING_OBSIDIAN_TEAR, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Nautilus_Raincloud(new ParticleData(Material.NAUTILUS_SHELL, "PARTICLE_RAINCLOUD_NAUTILUS", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.NAUTILUS, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Enchantment_Raincloud(new ParticleData(Material.ENCHANTED_BOOK, "PARTICLE_RAINCLOUD_ENCHANTMENT", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.ENCHANT, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Slime_Raincloud(new ParticleData(Material.GREEN_CARPET, "PARTICLE_RAINCLOUD_SLIME", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.ITEM_SLIME, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Hail_Raincloud(new ParticleData(Material.LIGHT_GRAY_CARPET, "PARTICLE_RAINCLOUD_HAIL", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.ITEM_SNOWBALL, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Snow_Raincloud(new ParticleData(Material.WHITE_CARPET, "PARTICLE_RAINCLOUD_SNOW", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.SNOWFLAKE, 0.3F, 0.0F, 0.3F, 0.01), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- Totem_Raincloud(new ParticleData(Material.TOTEM_OF_UNDYING, "PARTICLE_RAINCLOUD_TOTEM", ParticleRequirement.HAS_TEAM,
- new Always(new LocationMutator(new Group(new SimpleParticle(Particle.CLOUD, 0.3F, 0.1F, 0.3F, 0.01), new LocationMutator(new SimpleParticle(Particle.TOTEM_OF_UNDYING, 0.3F, 0.0F, 0.3F, 0.01, 2), 0, -0.3, 0)), 0, 2.4, 0)))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/ServerTeamParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/ServerTeamParticle.java
deleted file mode 100644
index 84b543eb..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/ServerTeamParticle.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleRequirement;
-import de.steamwar.lobby.particle.WingDesign;
-import de.steamwar.lobby.particle.elements.*;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-@AllArgsConstructor
-public enum ServerTeamParticle implements ParticleEnum {
-
- WITCH(new ParticleData(Material.EXPERIENCE_BOTTLE, "PARTICLE_WITCH", ParticleRequirement.SERVER_TEAM,
- new SimpleParticle(Particle.WITCH))
- ),
- ENCHANTING(new ParticleData(Material.ENCHANTING_TABLE, "PARTICLE_ENCHANTING", ParticleRequirement.SERVER_TEAM,
- new SimpleParticle(Particle.ENCHANT))
- ),
- HAPPY(new ParticleData(Material.EMERALD_BLOCK, "PARTICLE_HAPPY", ParticleRequirement.SERVER_TEAM,
- new SimpleParticle(Particle.HEART, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- FLAME(new ParticleData(Material.FLINT_AND_STEEL, "PARTICLE_FLAME", ParticleRequirement.SERVER_TEAM,
- new SimpleParticle(Particle.FLAME, 0, 0.2F, 0, 0.01))
- ),
- END_ROD(new ParticleData(Material.END_ROD, "PARTICLE_END_ROD", ParticleRequirement.SERVER_TEAM,
- new SimpleParticle(Particle.END_ROD, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- CLOUD(new ParticleData(Material.WHITE_WOOL, "PARTICLE_CLOUD", ParticleRequirement.SERVER_TEAM,
- new Cloud(new SimpleParticle(Particle.CLOUD)))
- ),
- TOTEM(new ParticleData(Material.TOTEM_OF_UNDYING, "PARTICLE_TOTEM", ParticleRequirement.SERVER_TEAM,
- new Cloud(new SimpleParticle(Particle.TOTEM_OF_UNDYING, 0.2F, 0.2F, 0.2F, 0.01)))
- ),
- ENCHANTING_CLOUD(new ParticleData(Material.WHITE_DYE, "PARTICLE_ENCHANTING", ParticleRequirement.SERVER_TEAM,
- new Cloud(new SimpleParticle(Particle.ENCHANT)))
- ),
- FLAME_CLOUD(new ParticleData(Material.FIRE_CORAL_BLOCK, "PARTICLE_FLAME", ParticleRequirement.SERVER_TEAM,
- new Cloud(new SimpleParticle(Particle.FLAME)))
- ),
- SNEEZE_CLOUD(new ParticleData(Material.LIME_SHULKER_BOX, "PARTICLE_SNEEZE", ParticleRequirement.SERVER_TEAM,
- new Cloud(new SimpleParticle(Particle.SNEEZE)))
- ),
- SLIME_CLOUD(new ParticleData(Material.GREEN_SHULKER_BOX, "PARTICLE_SLIME", ParticleRequirement.SERVER_TEAM,
- new Cloud(new SimpleParticle(Particle.ITEM_SLIME)))
- ),
- SMOKE_CLOUD(new ParticleData(Material.DEAD_BRAIN_CORAL_BLOCK, "PARTICLE_SMOKE", ParticleRequirement.SERVER_TEAM,
- new Cloud(new SimpleParticle(Particle.CAMPFIRE_COSY_SMOKE, 0.2F, 0.2F, 0.2F, 0.01)))
- ),
- TOWN_CLOUD(new ParticleData(Material.FIREWORK_STAR, "PARTICLE_TOWN", ParticleRequirement.SERVER_TEAM,
- new Cloud(new SimpleParticle(Particle.RAID_OMEN)))
- ),
- FLAME_CIRCLE(new ParticleData(Material.MAGMA_BLOCK, "PARTICLE_FLAME", ParticleRequirement.SERVER_TEAM,
- new Circle(new LocationMutator(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0.01), 0, 1.1, 0)))
- ),
- ENCHANTING_CIRCLE(new ParticleData(Material.WHITE_DYE, "PARTICLE_ENCHANTING_CIRCLE", ParticleRequirement.SERVER_TEAM,
- new Circle(new LocationMutator(new SimpleParticle(Particle.ENCHANT, 0.2F, 0.2F, 0.2F, 0.01), 0, 1.1, 0)))
- ),
- NOTES_CIRCLE(new ParticleData(Material.NOTE_BLOCK, "PARTICLE_NOTES", ParticleRequirement.SERVER_TEAM,
- new Circle(new LocationMutator(new SimpleParticle(Particle.NOTE, 0, 0, 0, 0.01), 0, 2.2, 0)))
- ),
- WATER_FIRE(new ParticleData(Material.GUARDIAN_SPAWN_EGG, "PARTICLE_WATER_FIRE", ParticleRequirement.SERVER_TEAM,
- new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.DRIPPING_WATER, 0, 0, 0, 0.01), new SimpleParticle(Particle.DRIPPING_LAVA, 0, 0, 0, 0.01)), 0, 1.1, 0))
- ),
- WATER_FIRE_ALWAYS(new ParticleData(Material.GUARDIAN_SPAWN_EGG, "PARTICLE_WATER_FIRE", ParticleRequirement.SERVER_TEAM,
- new Always(new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.DRIPPING_WATER, 0, 0, 0, 0.01), new SimpleParticle(Particle.DRIPPING_LAVA, 0, 0, 0, 0.01)), 0, 1.1, 0)))
- ),
- MAGIC_ENCHANTING(new ParticleData(Material.DIAMOND_SWORD, "PARTICLE_MAGIC_ENCHANTING", ParticleRequirement.SERVER_TEAM,
- new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0.01), new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.01)), 0, 1.1, 0))
- ),
- MAGIC_ENCHANTING_ALWAYS(new ParticleData(Material.WOODEN_SWORD, "PARTICLE_MAGIC_ENCHANTING", ParticleRequirement.SERVER_TEAM,
- new Always(new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0.01), new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.01)), 0, 1.1, 0)))
- ),
- MAGIC_CLOUD_CIRCLE(new ParticleData(Material.GLOWSTONE_DUST, "PARTICLE_MAGIC", ParticleRequirement.SERVER_TEAM,
- new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.ENCHANTED_HIT, 0, 0, 0, 0.01), 0, 1.1, 0))))
- ),
- FLAME_CLOUD_CIRCLE(new ParticleData(Material.FIRE_CORAL, "PARTICLE_FLAME", ParticleRequirement.SERVER_TEAM,
- new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0.01), 0, 1.1, 0))))
- ),
- FIREWORK_CLOUD_CIRCLE(new ParticleData(Material.FIREWORK_ROCKET, "PARTICLE_FIREWORK", ParticleRequirement.SERVER_TEAM,
- new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.FIREWORK, 0, 0, 0, 0.01), 0, 1.1, 0))))
- ),
- WATER_CLOUD_CIRCLE(new ParticleData(Material.CYAN_DYE, "PARTICLE_WATER_FIRE", ParticleRequirement.SERVER_TEAM,
- new Cloud(new Circle(new LocationMutator(new SimpleParticle(Particle.RAIN, 0, 0, 0, 0.01), 0, 1.1, 0))))
- ),
- ENCHANTING_DOUBLE_CIRCLE(new ParticleData(Material.BUBBLE_CORAL_BLOCK, "PARTICLE_ENCHANTING", ParticleRequirement.SERVER_TEAM,
- new Always(new LocationMutator(new DoubleCircle(new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.01), new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.01)), 0, 2.2, 0)))
- ),
- EVIL_WINGS(new ParticleData(Material.PURPUR_SLAB, "PARTICLE_WINGS_EVIL", ParticleRequirement.SERVER_TEAM,
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.WITCH, 0, 0, 0, 0, 1), 0.15, WingDesign.SIMPLE)), 20)))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/TeamParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/TeamParticle.java
deleted file mode 100644
index c988316d..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/TeamParticle.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleRequirement;
-import de.steamwar.lobby.particle.elements.Circle;
-import de.steamwar.lobby.particle.elements.LocationMutator;
-import de.steamwar.lobby.particle.elements.NonFloor;
-import de.steamwar.lobby.particle.elements.SimpleParticle;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-@AllArgsConstructor
-public enum TeamParticle implements ParticleEnum {
-
- SQUID(new ParticleData(Material.INK_SAC, "PARTICLE_SQUID", ParticleRequirement.HAS_TEAM,
- new SimpleParticle(Particle.SQUID_INK, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- BUBBLE(new ParticleData(Material.TUBE_CORAL, "PARTICLE_BUBBLE", ParticleRequirement.HAS_TEAM,
- new SimpleParticle(Particle.BUBBLE_POP, 0.2F, 0.2F, 0.2F, 0.01))
- ),
- HONEY(new ParticleData(Material.HONEY_BOTTLE, "PARTICLE_HONEY", ParticleRequirement.HAS_TEAM,
- new SimpleParticle(Particle.DRIPPING_HONEY, 0.2F, 0.2F, 0.2F, 1))
- ),
- NECTAR(new ParticleData(Material.HONEYCOMB, "PARTICLE_NECTAR", ParticleRequirement.HAS_TEAM,
- new SimpleParticle(Particle.FALLING_NECTAR, 0.2F, 0.2F, 0.2F, 1))
- ),
- FIREWORK(new ParticleData(Material.FIRE_CHARGE, "PARTICLE_FIREWORK", ParticleRequirement.HAS_TEAM,
- new LocationMutator(new NonFloor(new SimpleParticle(Particle.FIREWORK, 0.1F, 0.1F, 0.1F, 0.2, 2)), 0, -0.2, 0))
- ),
- DRAGON_BREATH(new ParticleData(Material.DRAGON_BREATH, "PARTICLE_DRAGON_BREATH", ParticleRequirement.HAS_TEAM,
- new SimpleParticle(Particle.DRAGON_BREATH, 1F, 0.2F, 1F, 0.01))
- ),
- DAMAGE(new ParticleData(Material.SPIDER_EYE, "PARTICLE_DAMAGE", ParticleRequirement.HAS_TEAM,
- new SimpleParticle(Particle.DAMAGE_INDICATOR, 0.2F, 0, 0.2F, 0.01))
- ),
- DOLPHIN(new ParticleData(Material.BLUE_DYE, "PARTICLE_DOLPHIN", ParticleRequirement.HAS_TEAM,
- new SimpleParticle(Particle.DOLPHIN, 0.2F, 0, 0.2F, 0.01))
- ),
- HEART(new ParticleData(Material.RED_CONCRETE, "PARTICLE_HEART", ParticleRequirement.HAS_TEAM,
- new Circle(new LocationMutator(new SimpleParticle(Particle.HEART), 0, 2.2, 0)))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java
deleted file mode 100644
index 496eb49f..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomEasterParticle.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles.custom;
-
-import de.steamwar.lobby.particle.*;
-import de.steamwar.lobby.particle.elements.*;
-import de.steamwar.lobby.particle.elements.custom.HearthBeat;
-import de.steamwar.lobby.particle.elements.custom.NonMoving;
-import de.steamwar.lobby.particle.elements.custom.PulseShimmer;
-import de.steamwar.lobby.particle.elements.custom.YOffset;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-import java.awt.*;
-
-@AllArgsConstructor
-public enum CustomEasterParticle implements ParticleEnum {
-
- PLAYER_1063(new ParticleData(Material.ENDER_PEARL, "PARTICLE_PLAYER_1063", ParticleRequirement.easterEventSpecificPlayer(1063),
- new Always(
- new DoubleCircle(
- new DoubleCircle(
- new YOffset(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0.01, 1), 20, 0, 2, true, true),
- new YOffset(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0.01, 1), 20, 0, 2, false, true), 0.5, 4),
- new DoubleCircle(
- new YOffset(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0.01, 1), 20, 0, 2, false, true),
- new YOffset(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0.01, 1), 20, 0, 2, true, true), 0.5, 4), 1.5, 1)
- ))
- ),
- PLAYER_10916(new ParticleData(Material.TORCHFLOWER, "PARTICLE_PLAYER_10916_AURA", ParticleRequirement.easterEventSpecificPlayer(10916),
- new Always(new NonMoving(new Group(
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 10), location -> location.add(0, 0.2, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.5, 10), location -> location.add(0, 0.3, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 10), location -> location.add(0, 0.4, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.55, 10), location -> location.add(0, 0.5, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 10), location -> location.add(0, 0.6, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.65, 10), location -> location.add(0, 0.7, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 0.8, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 0.9, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.7, 10), location -> location.add(0, 1.0, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.1, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.2, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.75, 10), location -> location.add(0, 1.3, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.4, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.5, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.8, 10), location -> location.add(0, 1.6, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.7, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.8, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.85, 10), location -> location.add(0, 1.9, 0)),
- new LocationMutator(new DoubleCircle(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.RED)), 0.9, 10), location -> location.add(0, 2.0, 0))
- ))))
- ),
- PLAYER_10697(new ParticleData(Material.GUNPOWDER, "PARTICLE_PLAYER_10697_AURA", ParticleRequirement.easterEventSpecificPlayer(10697),
- new Always(new Sneaking(new Group(
- new OnlySelf(new Delayed(new SimpleParticle(Particle.EXPLOSION, 0, 0, 0, 0.01, 1), 20)),
- new OnlyOthers(new Delayed(new SimpleParticle(Particle.EXPLOSION, 0, 0, 0, 0.01, 1), 2))
- ))))
- ),
- PLAYER_64(new ParticleData(Material.PUFFERFISH_BUCKET, "PARTICLE_PLAYER_64", ParticleRequirement.easterEventSpecificPlayer(64),
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.END_ROD, 0, 0, 0, 0, 1), 0.15, WingDesign.PlompaEasterWings)), 80)))
- ),
- TEAM_210_1(new ParticleData(Material.RED_CANDLE, "PARTICLE_TEAM_PULSE_AURA", ParticleRequirement.easterEventSpecificTeam(210),
- new Always(new NonMoving(new PulseShimmer(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0, 1), 80, 2))))
- ),
- TEAM_210_2(new ParticleData(Material.APPLE, "PARTICLE_TEAM_PULSE_HEART_BEAT", ParticleRequirement.easterEventSpecificTeam(210),
- new Always(new NonFlying(new HearthBeat(new SimpleParticle(Particle.FLAME, 0, 0, 0, 0, 1), 80))))
- ),
- PLAYER_153(new ParticleData(Material.OAK_SIGN, "PARTICLE_PLAYER_153", ParticleRequirement.easterEventSpecificPlayer(153),
- new Always(new Delayed(new NonFlying(new Group(
- new Wing(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.DARK_GRAY)), 0.15, WingDesign.ELY_E),
- new Wing(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.GREEN)), 0.15, WingDesign.ELY_L),
- new Wing(new DustParticle(Particle.DUST, 0, 0, 0, 0, 1, new Gradient(Color.GRAY)), 0.15, WingDesign.ELY_Y)
- )), 10)))
- ),
- // TODO: Implement zSalos! -> Team
- // TODO: Implement GroupXyz!
- // TODO: Implement minecrafter_133 1817!
- // TODO: Implement TheReaper22122!
- // TODO: Implement Bosslar!
- // TODO: Implement ATOM65!
- PLAYER_3266(new ParticleData(Material.BREAD, "PARTICLE_PLAYER_3266", ParticleRequirement.easterEventSpecificPlayer(3266),
- new Group(
- new Always(new Sneaking(new LocationMutator(new None(), location -> location))),
- new Always(new NonFlying(new LocationMutator(new TrippleCircle(
- new DustParticle(Particle.DUST, new Gradient(Color.CYAN, Color.BLUE, Color.MAGENTA.darker(), Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN)),
- new DustParticle(Particle.DUST, new Gradient(Color.CYAN, Color.BLUE, Color.MAGENTA.darker(), Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN)),
- new DustParticle(Particle.DUST, new Gradient(Color.CYAN, Color.BLUE, Color.MAGENTA.darker(), Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN)),
- 0.7,
- 0.5), location -> location.add(0, 0.6, 0)
- ))))
- )
- ),
- // TODO: Implement Gehfxhler!
- // TODO: Implement SchwarzerFuerst
- // TODO: Implement byVallu
- TEAM_158_1(new ParticleData(Material.ENCHANTED_BOOK, "PARTICLE_TEAM_158_1", ParticleRequirement.easterEventSpecificTeam(158),
- new Always(new NonFlying(new Delayed(new Wing(new SimpleParticle(Particle.CRIT, 0, 0, 0, 0, 1), 0.2, WingDesign.EV), 15))))
- ),
- TEAM_158_2(new ParticleData(Material.ENDER_EYE, "PARTICLE_TEAM_158_2", ParticleRequirement.easterEventSpecificTeam(158),
- new Always(new NonFlying(new YOffset(new DoubleCircle(new DustParticle(Particle.CRIT, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.RED)), new DustParticle(Particle.DUST, 0.01f, 0.01f, 0.01f, 0.1, 1, new Gradient(Color.BLUE)), 0.7, 1), 40, 0, 2, false, false))))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomPlayerParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomPlayerParticle.java
deleted file mode 100644
index b0884018..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomPlayerParticle.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles.custom;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleRequirement;
-import de.steamwar.lobby.particle.elements.*;
-import de.steamwar.lobby.particle.elements.custom.NonMoving;
-import de.steamwar.lobby.particle.elements.custom.YOffset;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-@AllArgsConstructor
-public enum CustomPlayerParticle implements ParticleEnum {
-
- Haylim_(new ParticleData(Material.WHITE_CANDLE, "PARTICLE_PLAYER_HAYLIM_AURA", ParticleRequirement.specificPlayer(9426),
- new Always(new NonMoving(new NonFlying(new Group(
- new DoubleCircle(new YOffset(new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.01, 5), 40, 0, 2, false, false), new YOffset(new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.0, 5), 40, 0, 2, true, false)),
- new DoubleCircle(new YOffset(new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.01, 5), 40, 0, 2, true, false), new YOffset(new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0.0, 5), 40, 0, 2, false, false))
- )))))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomTeamParticle.java b/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomTeamParticle.java
deleted file mode 100644
index 9da1f443..00000000
--- a/LobbySystem/src/de/steamwar/lobby/particle/particles/custom/CustomTeamParticle.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This file is a part of the SteamWar software.
- *
- * Copyright (C) 2025 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 .
- */
-
-package de.steamwar.lobby.particle.particles.custom;
-
-import de.steamwar.lobby.particle.ParticleData;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleRequirement;
-import de.steamwar.lobby.particle.WingDesign;
-import de.steamwar.lobby.particle.elements.*;
-import de.steamwar.lobby.particle.elements.custom.NonMoving;
-import de.steamwar.lobby.particle.elements.custom.PulseShimmer;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.bukkit.Material;
-import org.bukkit.Particle;
-
-@AllArgsConstructor
-public enum CustomTeamParticle implements ParticleEnum {
-
- Eclipse(new ParticleData(Material.ENDER_CHEST, "PARTICLE_EVENT_ENCHANTING", ParticleRequirement.specificTeam(34),
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.END_ROD, 0, 0, 0, 0, 1), 0.15, WingDesign.ECLIPSE)), 80)))
- ),
- Pulse_1(new ParticleData(Material.GRAY_CANDLE, "PARTICLE_TEAM_PULSE_AURA_2", ParticleRequirement.specificTeam(210),
- new Always(new NonMoving(new PulseShimmer(new SimpleParticle(Particle.END_ROD, 0, 0, 0, 0, 1), 80, 2))))
- ),
- Pulse_2(new ParticleData(Material.WHITE_CANDLE, "PARTICLE_TEAM_PULSE_AURA_3", ParticleRequirement.specificTeam(210),
- new Always(new NonMoving(new PulseShimmer(new SimpleParticle(Particle.ENCHANT, 0, 0, 0, 0, 5), 80, 2))))
- ),
- Pulse_Logo(new ParticleData(Material.ENDER_CHEST, "PARTICLE_TEAM_PULSE_LOGO", ParticleRequirement.specificTeam(210),
- new Always(new Delayed(new NonFlying(new Wing(new SimpleParticle(Particle.END_ROD, 0, 0, 0, 0, 1), 0.15, WingDesign.PL)), 80)))
- ),
- ;
- public static ParticleEnum[] particles = values();
-
- @Getter
- private ParticleData particle;
-}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/slot/ParticleEntry.java b/LobbySystem/src/de/steamwar/lobby/particle/slot/ParticleEntry.java
index 9178951c..de006312 100644
--- a/LobbySystem/src/de/steamwar/lobby/particle/slot/ParticleEntry.java
+++ b/LobbySystem/src/de/steamwar/lobby/particle/slot/ParticleEntry.java
@@ -44,8 +44,15 @@ public class ParticleEntry {
this.values = values;
}
+ // A new entry with the design's default conditions and timing
public ParticleEntry(ParticleDesign design) {
this(design, new ParameterValues());
+ design.applyDefaults(values);
+ }
+
+ public ParticleEntry with(Parameter parameter, T value) {
+ values.set(parameter, value);
+ return this;
}
public List> getParameters() {
@@ -59,30 +66,13 @@ public class ParticleEntry {
}
public ParticleElement build() {
- ParticleType type = values.get(PARTICLE);
- float spreadX = values.get(SPREAD_X).floatValue();
- float spreadY = values.get(SPREAD_Y).floatValue();
- float spreadZ = values.get(SPREAD_Z).floatValue();
- double speed = values.get(SPEED);
- int count = values.get(COUNT);
-
ParticleElement element;
- if (type.isDust()) {
- List colors = values.get(COLORS);
- Gradient gradient = colors.isEmpty() ? null : new Gradient(colors.toArray(new Color[0]));
- element = new DustParticle(type.getParticle(), spreadX, spreadY, spreadZ, speed, count, gradient);
+ if (design.usesEntryParticle()) {
+ element = design.build(values, withOffset(particle()));
} else {
- element = new SimpleParticle(type.getParticle(), spreadX, spreadY, spreadZ, speed, count);
+ element = withOffset(design.build(values, null));
}
- double offsetX = values.get(OFFSET_X);
- double offsetY = values.get(OFFSET_Y);
- double offsetZ = values.get(OFFSET_Z);
- if (offsetX != 0 || offsetY != 0 || offsetZ != 0) {
- element = new LocationMutator(element, offsetX, offsetY, offsetZ);
- }
-
- element = design.build(values, element);
element = values.get(MOVEMENT).wrap(element);
element = values.get(GLIDING).wrap(element);
element = values.get(GROUND).wrap(element);
@@ -99,9 +89,36 @@ public class ParticleEntry {
return element;
}
- // Particles spawned per tick, used for the slot budget
+ private ParticleElement particle() {
+ ParticleType type = values.get(PARTICLE);
+ float spreadX = values.get(SPREAD_X).floatValue();
+ float spreadY = values.get(SPREAD_Y).floatValue();
+ float spreadZ = values.get(SPREAD_Z).floatValue();
+ double speed = values.get(SPEED);
+ int count = values.get(COUNT);
+
+ if (type.isDust()) {
+ List colors = values.get(COLORS);
+ Gradient gradient = colors.isEmpty() ? null : new Gradient(colors.toArray(new Color[0]));
+ return new DustParticle(type.getParticle(), spreadX, spreadY, spreadZ, speed, count, gradient);
+ }
+ return new SimpleParticle(type.getParticle(), spreadX, spreadY, spreadZ, speed, count);
+ }
+
+ private ParticleElement withOffset(ParticleElement element) {
+ double offsetX = values.get(OFFSET_X);
+ double offsetY = values.get(OFFSET_Y);
+ double offsetZ = values.get(OFFSET_Z);
+ if (offsetX == 0 && offsetY == 0 && offsetZ == 0) {
+ return element;
+ }
+ return new LocationMutator(element, offsetX, offsetY, offsetZ);
+ }
+
+ // Particle positions spawned per tick, used for the slot budget
public double cost() {
- return (double) design.points(values) * values.get(COUNT) / values.get(INTERVAL);
+ double perTick = design.usesEntryParticle() ? (double) design.points(values) * values.get(COUNT) : design.points(values);
+ return perTick / values.get(INTERVAL);
}
public JsonObject toJson() {
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/slot/ParticlePreset.java b/LobbySystem/src/de/steamwar/lobby/particle/slot/ParticlePreset.java
new file mode 100644
index 00000000..98b2177a
--- /dev/null
+++ b/LobbySystem/src/de/steamwar/lobby/particle/slot/ParticlePreset.java
@@ -0,0 +1,49 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.lobby.particle.slot;
+
+import de.steamwar.lobby.particle.ParticleRequirement;
+import lombok.Getter;
+import org.bukkit.Material;
+
+import java.util.List;
+
+// A read-only particle for a specific team or user, selectable without using a slot
+@Getter
+public class ParticlePreset implements ParticleSet {
+
+ private final String id;
+ private final Material icon;
+ private final String nameKey;
+ private final ParticleRequirement requirement;
+ private final List entries;
+
+ public ParticlePreset(String id, Material icon, String nameKey, ParticleRequirement requirement, List entries) {
+ this.id = id;
+ this.icon = icon;
+ this.nameKey = nameKey;
+ this.requirement = requirement;
+ this.entries = List.copyOf(entries);
+ }
+
+ public ParticlePreset(String id, Material icon, String nameKey, ParticleRequirement requirement, ParticleEntry... entries) {
+ this(id, icon, nameKey, requirement, List.of(entries));
+ }
+}
diff --git a/LobbySystem/src/de/steamwar/lobby/particle/slot/Presets.java b/LobbySystem/src/de/steamwar/lobby/particle/slot/Presets.java
new file mode 100644
index 00000000..3a025539
--- /dev/null
+++ b/LobbySystem/src/de/steamwar/lobby/particle/slot/Presets.java
@@ -0,0 +1,218 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.lobby.particle.slot;
+
+import de.steamwar.lobby.particle.ParticleRequirement;
+import de.steamwar.lobby.particle.WingDesign;
+import de.steamwar.lobby.particle.design.Designs;
+import de.steamwar.lobby.particle.design.InternalDesigns;
+import de.steamwar.lobby.particle.design.ParticleDesign;
+import de.steamwar.lobby.particle.design.ParticleType;
+import lombok.experimental.UtilityClass;
+import org.bukkit.Material;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import static de.steamwar.lobby.particle.design.EntryParameters.*;
+
+// Particles made for specific teams and users
+@UtilityClass
+public class Presets {
+
+ private final Map PRESETS = new LinkedHashMap<>();
+
+ public final ParticlePreset TEAM_34_ECLIPSE = register(new ParticlePreset("team_34_eclipse", Material.ENDER_CHEST, "PARTICLE_EVENT_ENCHANTING", ParticleRequirement.specificTeam(34),
+ wing(ParticleType.END_ROD, 0.15, WingDesign.ECLIPSE, 80)));
+ public final ParticlePreset TEAM_210_PULSE_1 = register(new ParticlePreset("team_210_pulse_1", Material.GRAY_CANDLE, "PARTICLE_TEAM_PULSE_AURA_2", ParticleRequirement.specificTeam(210),
+ pulse(ParticleType.END_ROD, 1)));
+ public final ParticlePreset TEAM_210_PULSE_2 = register(new ParticlePreset("team_210_pulse_2", Material.WHITE_CANDLE, "PARTICLE_TEAM_PULSE_AURA_3", ParticleRequirement.specificTeam(210),
+ pulse(ParticleType.ENCHANT, 5)));
+ public final ParticlePreset TEAM_210_PULSE_LOGO = register(new ParticlePreset("team_210_pulse_logo", Material.ENDER_CHEST, "PARTICLE_TEAM_PULSE_LOGO", ParticleRequirement.specificTeam(210),
+ wing(ParticleType.END_ROD, 0.15, WingDesign.PL, 80)));
+
+ public final ParticlePreset PLAYER_9426_AURA = register(new ParticlePreset("player_9426_aura", Material.WHITE_CANDLE, "PARTICLE_PLAYER_HAYLIM_AURA", ParticleRequirement.specificPlayer(9426),
+ haylimRing(0, 0.01, false),
+ haylimRing(180, 0, true),
+ haylimRing(0, 0.01, true),
+ haylimRing(180, 0, false)));
+
+ public final ParticlePreset EASTER_PLAYER_1063 = register(new ParticlePreset("easter_player_1063", Material.ENDER_PEARL, "PARTICLE_PLAYER_1063", ParticleRequirement.easterEventSpecificPlayer(1063),
+ orbit(0, 0, true),
+ orbit(0, 180, false),
+ orbit(180, 0, false),
+ orbit(180, 180, true)));
+ public final ParticlePreset EASTER_PLAYER_10916 = register(new ParticlePreset("easter_player_10916", Material.TORCHFLOWER, "PARTICLE_PLAYER_10916_AURA", ParticleRequirement.easterEventSpecificPlayer(10916),
+ redRingTower()));
+ public final ParticlePreset EASTER_PLAYER_10697 = register(new ParticlePreset("easter_player_10697", Material.GUNPOWDER, "PARTICLE_PLAYER_10697_AURA", ParticleRequirement.easterEventSpecificPlayer(10697),
+ explosion(Visibility.ONLY_SELF, 20),
+ explosion(Visibility.ONLY_OTHERS, 2)));
+ public final ParticlePreset EASTER_PLAYER_64 = register(new ParticlePreset("easter_player_64", Material.PUFFERFISH_BUCKET, "PARTICLE_PLAYER_64", ParticleRequirement.easterEventSpecificPlayer(64),
+ wing(ParticleType.END_ROD, 0.15, WingDesign.PlompaEasterWings, 80)));
+ public final ParticlePreset EASTER_TEAM_210_AURA = register(new ParticlePreset("easter_team_210_aura", Material.RED_CANDLE, "PARTICLE_TEAM_PULSE_AURA", ParticleRequirement.easterEventSpecificTeam(210),
+ pulse(ParticleType.FLAME, 1)));
+ public final ParticlePreset EASTER_TEAM_210_HEART_BEAT = register(new ParticlePreset("easter_team_210_heart_beat", Material.APPLE, "PARTICLE_TEAM_PULSE_HEART_BEAT", ParticleRequirement.easterEventSpecificTeam(210),
+ particle(InternalDesigns.HEART_BEAT, ParticleType.FLAME, 0, 0, 1)
+ .with(InternalDesigns.HEART_BEAT_SPEED, 80.0)
+ .with(TICK_MODE, TickMode.ALWAYS)
+ .with(GLIDING, Gliding.NOT_GLIDING)));
+ public final ParticlePreset EASTER_PLAYER_153 = register(new ParticlePreset("easter_player_153", Material.OAK_SIGN, "PARTICLE_PLAYER_153", ParticleRequirement.easterEventSpecificPlayer(153),
+ dustWing(Color.DARK_GRAY, WingDesign.ELY_E),
+ dustWing(Color.GREEN, WingDesign.ELY_L),
+ dustWing(Color.GRAY, WingDesign.ELY_Y)));
+ public final ParticlePreset EASTER_PLAYER_3266 = register(new ParticlePreset("easter_player_3266", Material.BREAD, "PARTICLE_PLAYER_3266", ParticleRequirement.easterEventSpecificPlayer(3266),
+ rainbowRing(0),
+ rainbowRing(120),
+ rainbowRing(240)));
+ public final ParticlePreset EASTER_TEAM_158_WINGS = register(new ParticlePreset("easter_team_158_wings", Material.ENCHANTED_BOOK, "PARTICLE_TEAM_158_1", ParticleRequirement.easterEventSpecificTeam(158),
+ wing(ParticleType.CRIT, 0.2, WingDesign.EV, 15)));
+ // The red half used to pass dust options to CRIT, which CRIT does not take; it is a plain CRIT now
+ public final ParticlePreset EASTER_TEAM_158_RINGS = register(new ParticlePreset("easter_team_158_rings", Material.ENDER_EYE, "PARTICLE_TEAM_158_2", ParticleRequirement.easterEventSpecificTeam(158),
+ team158Ring(particle(Designs.CIRCLE, ParticleType.CRIT, 0.01, 0.1, 1), 0),
+ team158Ring(particle(Designs.CIRCLE, ParticleType.DUST, 0.01, 0.1, 1).with(COLORS, List.of(Color.BLUE)), 180)));
+
+ private ParticlePreset register(ParticlePreset preset) {
+ if (PRESETS.put(preset.getId(), preset) != null) {
+ throw new IllegalStateException("Duplicate particle preset " + preset.getId());
+ }
+ return preset;
+ }
+
+ public ParticlePreset byId(String id) {
+ return PRESETS.get(id);
+ }
+
+ public List all() {
+ return List.copyOf(PRESETS.values());
+ }
+
+ private ParticleEntry particle(ParticleDesign design, ParticleType type, double spread, double speed, int count) {
+ return new ParticleEntry(design)
+ .with(PARTICLE, type)
+ .with(SPREAD_X, spread)
+ .with(SPREAD_Y, spread)
+ .with(SPREAD_Z, spread)
+ .with(SPEED, speed)
+ .with(COUNT, count);
+ }
+
+ private ParticleEntry wing(ParticleType type, double size, WingDesign image, int interval) {
+ return particle(Designs.WING, type, 0, 0, 1)
+ .with(Designs.WING_IMAGE, image)
+ .with(Designs.WING_SIZE, size)
+ .with(TICK_MODE, TickMode.ALWAYS)
+ .with(INTERVAL, interval)
+ .with(GLIDING, Gliding.NOT_GLIDING);
+ }
+
+ private ParticleEntry dustWing(Color color, WingDesign image) {
+ return wing(ParticleType.DUST, 0.15, image, 10)
+ .with(COLORS, List.of(color));
+ }
+
+ private ParticleEntry pulse(ParticleType type, int count) {
+ return particle(InternalDesigns.PULSE_SHIMMER, type, 0, 0, count)
+ .with(InternalDesigns.PULSE_SPEED, 80)
+ .with(InternalDesigns.PULSE_ROTATION, 2)
+ .with(TICK_MODE, TickMode.ALWAYS)
+ .with(MOVEMENT, Movement.STANDING_STILL);
+ }
+
+ private ParticleEntry haylimRing(double phase, double speed, boolean inverted) {
+ return particle(Designs.CIRCLE, ParticleType.ENCHANT, 0, speed, 5)
+ .with(Designs.CIRCLE_PHASE, phase)
+ .with(Designs.CIRCLE_RISE, 2.0)
+ .with(Designs.CIRCLE_RISE_SPEED, 40.0)
+ .with(Designs.CIRCLE_BOUNCE, false)
+ .with(Designs.CIRCLE_INVERTED, inverted)
+ .with(TICK_MODE, TickMode.ALWAYS)
+ .with(MOVEMENT, Movement.STANDING_STILL)
+ .with(GLIDING, Gliding.NOT_GLIDING);
+ }
+
+ private ParticleEntry orbit(double orbitPhase, double phase, boolean inverted) {
+ return particle(InternalDesigns.ORBIT, ParticleType.CRIT, 0, 0.01, 1)
+ .with(InternalDesigns.ORBIT_RADIUS, 1.5)
+ .with(InternalDesigns.ORBIT_SPEED, 1.0)
+ .with(InternalDesigns.ORBIT_PHASE, orbitPhase)
+ .with(Designs.CIRCLE_RADIUS, 0.5)
+ .with(Designs.CIRCLE_SPEED, 4.0)
+ .with(Designs.CIRCLE_PHASE, phase)
+ .with(Designs.CIRCLE_RISE, 2.0)
+ .with(Designs.CIRCLE_RISE_SPEED, 20.0)
+ .with(Designs.CIRCLE_BOUNCE, true)
+ .with(Designs.CIRCLE_INVERTED, inverted)
+ .with(TICK_MODE, TickMode.ALWAYS);
+ }
+
+ // Two opposite red rings on each of 19 heights, widening towards the top
+ private List redRingTower() {
+ double[] radii = {0.5, 0.5, 0.55, 0.55, 0.65, 0.65, 0.7, 0.7, 0.7, 0.75, 0.75, 0.75, 0.8, 0.8, 0.8, 0.85, 0.85, 0.85, 0.9};
+ List entries = new ArrayList<>();
+ for (int i = 0; i < radii.length; i++) {
+ for (double phase : new double[]{0, 180}) {
+ entries.add(particle(Designs.CIRCLE, ParticleType.DUST, 0, 0, 1)
+ .with(COLORS, List.of(Color.RED))
+ .with(Designs.CIRCLE_RADIUS, radii[i])
+ .with(Designs.CIRCLE_SPEED, 10.0)
+ .with(Designs.CIRCLE_PHASE, phase)
+ .with(OFFSET_Y, 0.2 + i * 0.1)
+ .with(TICK_MODE, TickMode.ALWAYS)
+ .with(MOVEMENT, Movement.STANDING_STILL));
+ }
+ }
+ return entries;
+ }
+
+ private ParticleEntry explosion(Visibility visibility, int interval) {
+ return particle(Designs.SIMPLE, ParticleType.EXPLOSION, 0, 0.01, 1)
+ .with(TICK_MODE, TickMode.ALWAYS)
+ .with(SNEAK, Sneak.SNEAKING)
+ .with(VISIBILITY, visibility)
+ .with(INTERVAL, interval);
+ }
+
+ private ParticleEntry rainbowRing(double phase) {
+ return particle(Designs.CIRCLE, ParticleType.DUST, 0.01, 0.01, 5)
+ .with(COLORS, List.of(Color.CYAN, Color.BLUE, Color.MAGENTA.darker(), Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN))
+ .with(Designs.CIRCLE_RADIUS, 0.7)
+ .with(Designs.CIRCLE_SPEED, 0.5)
+ .with(Designs.CIRCLE_PHASE, phase)
+ .with(OFFSET_Y, 0.6)
+ .with(TICK_MODE, TickMode.ALWAYS)
+ .with(GLIDING, Gliding.NOT_GLIDING);
+ }
+
+ private ParticleEntry team158Ring(ParticleEntry entry, double phase) {
+ return entry
+ .with(Designs.CIRCLE_RADIUS, 0.7)
+ .with(Designs.CIRCLE_SPEED, 1.0)
+ .with(Designs.CIRCLE_PHASE, phase)
+ .with(Designs.CIRCLE_RISE, 2.0)
+ .with(Designs.CIRCLE_RISE_SPEED, 40.0)
+ .with(Designs.CIRCLE_BOUNCE, false)
+ .with(Designs.CIRCLE_INVERTED, false)
+ .with(TICK_MODE, TickMode.ALWAYS)
+ .with(GLIDING, Gliding.NOT_GLIDING);
+ }
+}
diff --git a/LobbySystem/src/de/steamwar/lobby/util/LobbyPlayer.java b/LobbySystem/src/de/steamwar/lobby/util/LobbyPlayer.java
index 8bc49ef7..8eec2d30 100644
--- a/LobbySystem/src/de/steamwar/lobby/util/LobbyPlayer.java
+++ b/LobbySystem/src/de/steamwar/lobby/util/LobbyPlayer.java
@@ -20,11 +20,11 @@
package de.steamwar.lobby.util;
import de.steamwar.lobby.particle.CompiledSet;
-import de.steamwar.lobby.particle.ParticleEnum;
-import de.steamwar.lobby.particle.ParticleInventory;
import de.steamwar.lobby.particle.UnlockContext;
+import de.steamwar.lobby.particle.slot.ParticlePreset;
import de.steamwar.lobby.particle.slot.ParticleSlot;
import de.steamwar.lobby.particle.slot.ParticleSlots;
+import de.steamwar.lobby.particle.slot.Presets;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserConfig;
import org.bukkit.entity.Player;
@@ -37,14 +37,16 @@ public class LobbyPlayer {
private static final String ACTIVE_KEY = "lobby-particle-active";
private static final String ACTIVE_SLOT_PREFIX = "slot:";
+ private static final String ACTIVE_PRESET_PREFIX = "preset:";
private static Map cache = new HashMap<>();
private final UUID uuid;
- private ParticleEnum particle;
private final ParticleSlot[] slots = new ParticleSlot[ParticleSlots.COUNT];
private final boolean[] loadedSlots = new boolean[ParticleSlots.COUNT];
+ // At most one of activeSlot and activePreset is set
private int activeSlot = -1;
+ private ParticlePreset activePreset;
private CompiledSet compiledSet;
private int userId;
@@ -54,11 +56,6 @@ public class LobbyPlayer {
this.uuid = uuid;
userId = SteamwarUser.get(uuid).getId();
cache.put(uuid, this);
- particle = null;
- String saved = UserConfig.getConfig(userId, "lobby-particle");
- if (saved != null) {
- particle = ParticleInventory.convertFromString(saved);
- }
String active = UserConfig.getConfig(userId, ACTIVE_KEY);
if (active != null && active.startsWith(ACTIVE_SLOT_PREFIX)) {
try {
@@ -67,8 +64,10 @@ public class LobbyPlayer {
activeSlot = index;
}
} catch (NumberFormatException e) {
- // Ignore unreadable selection, the player simply has no slot selected
+ // Ignore unreadable selection, the player simply has no particle selected
}
+ } else if (active != null && active.startsWith(ACTIVE_PRESET_PREFIX)) {
+ activePreset = Presets.byId(active.substring(ACTIVE_PRESET_PREFIX.length()));
}
recompile();
}
@@ -81,22 +80,6 @@ public class LobbyPlayer {
this.fly = fly;
}
- public ParticleEnum getParticle() {
- return particle;
- }
-
- public void setParticle(ParticleEnum particle) {
- if (particle == null) {
- UserConfig.removePlayerConfig(userId, "lobby-particle");
- } else {
- String saved = ParticleInventory.convertToString(particle);
- UserConfig.updatePlayerConfig(userId, "lobby-particle", saved);
- }
- setActiveSlot(-1);
- this.particle = particle;
- recompile();
- }
-
public ParticleSlot getSlot(int index) {
if (!loadedSlots[index]) {
slots[index] = ParticleSlots.load(userId, index);
@@ -119,44 +102,65 @@ public class LobbyPlayer {
return activeSlot;
}
+ public ParticlePreset getActivePreset() {
+ return activePreset;
+ }
+
// Returns false when the slot is empty or locked for this player
public boolean selectSlot(int index) {
if (getSlot(index) == null || !ParticleSlots.requirement(index).test(unlockContext())) {
return false;
}
- if (particle != null) {
- UserConfig.removePlayerConfig(userId, "lobby-particle");
- particle = null;
- }
- setActiveSlot(index);
+ activeSlot = index;
+ activePreset = null;
+ saveSelection();
recompile();
return true;
}
+ // Returns false when the preset is locked for this player
+ public boolean selectPreset(ParticlePreset preset) {
+ if (!preset.getRequirement().test(unlockContext())) {
+ return false;
+ }
+ activeSlot = -1;
+ activePreset = preset;
+ saveSelection();
+ recompile();
+ return true;
+ }
+
+ public void deselect() {
+ activeSlot = -1;
+ activePreset = null;
+ saveSelection();
+ recompile();
+ }
+
public CompiledSet getCompiledSet() {
return compiledSet;
}
- // A locked active slot shows nothing but stays selected, so it comes back once the rank does
+ // A locked selection shows nothing but stays selected, so it comes back once the rank does
public void recompile() {
+ UnlockContext context = unlockContext();
if (activeSlot >= 0) {
ParticleSlot slot = getSlot(activeSlot);
- UnlockContext context = unlockContext();
compiledSet = slot != null && ParticleSlots.requirement(activeSlot).test(context) ? CompiledSet.of(slot, context) : null;
+ } else if (activePreset != null) {
+ compiledSet = activePreset.getRequirement().test(context) ? CompiledSet.of(activePreset, context) : null;
} else {
- compiledSet = particle == null ? null : CompiledSet.of(particle.getParticle().getParticleElement());
+ compiledSet = null;
}
}
- private void setActiveSlot(int index) {
- if (index == activeSlot) {
- return;
- }
- activeSlot = index;
- if (index < 0) {
- UserConfig.removePlayerConfig(userId, ACTIVE_KEY);
+ private void saveSelection() {
+ if (activeSlot >= 0) {
+ UserConfig.updatePlayerConfig(userId, ACTIVE_KEY, ACTIVE_SLOT_PREFIX + (activeSlot + 1));
+ } else if (activePreset != null) {
+ UserConfig.updatePlayerConfig(userId, ACTIVE_KEY, ACTIVE_PRESET_PREFIX + activePreset.getId());
} else {
- UserConfig.updatePlayerConfig(userId, ACTIVE_KEY, ACTIVE_SLOT_PREFIX + (index + 1));
+ UserConfig.removePlayerConfig(userId, ACTIVE_KEY);
}
}