Quiet no-op particle setting clicks and show entry particle counts

Clicking a step past the minimum or maximum, or setting an unchanged
value, now does nothing instead of showing the budget message, and
changes that lower a slot's particles are allowed even over budget.
Entries show their particles per tick in the slot editor list, and the
entry editor's paper shows the edited entry's share.
This commit is contained in:
2026-10-26 10:23:24 +01:00
parent 38a33b7298
commit 4c6b5e654a
6 changed files with 27 additions and 6 deletions
@@ -116,6 +116,8 @@ PARTICLE_ENTRY_EDITOR = §0{0}
PARTICLE_ENTRY_DESIGN = §7Design§8: {0}
PARTICLE_ENTRY_PARTICLE = §7Particle§8: {0}
PARTICLE_ENTRY_LOCKED = §cDesign locked, not shown
PARTICLE_ENTRY_COST = §7Particles per tick§8: §e{0}
PARTICLE_ENTRY_COST_SHARE = §7This entry§8: §e{0}
PARTICLE_ENTRY_EDIT = §eClick to edit
PARTICLE_ENTRY_DELETE = §cDelete entry
@@ -116,6 +116,8 @@ PARTICLE_ENTRY_EDITOR = §0{0}
PARTICLE_ENTRY_DESIGN = §7Design§8: {0}
PARTICLE_ENTRY_PARTICLE = §7Partikel§8: {0}
PARTICLE_ENTRY_LOCKED = §cDesign gesperrt, wird nicht angezeigt
PARTICLE_ENTRY_COST = §7Partikel pro Tick§8: §e{0}
PARTICLE_ENTRY_COST_SHARE = §7Dieser Eintrag§8: §e{0}
PARTICLE_ENTRY_EDIT = §eZum Bearbeiten klicken
PARTICLE_ENTRY_DELETE = §cEintrag löschen
@@ -37,6 +37,7 @@ import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static de.steamwar.lobby.particle.design.EntryParameters.*;
import static de.steamwar.lobby.particle.gui.ParticleGuiText.*;
@@ -139,7 +140,7 @@ class EntryEditor {
row(inventory, context, ROW_CONDITIONS, List.of(MOVEMENT, GLIDING, GROUND, SNEAK, VISIBILITY));
inventory.setItem(BACK, new SWItem(Material.ARROW, msg("PARTICLE_BACK", player), clickType -> SlotEditor.open(player, index)));
inventory.setItem(COST, SlotEditor.costItem(player, user, slot));
inventory.setItem(COST, SlotEditor.costItem(player, user, slot, entry));
inventory.setItem(DELETE, new SWItem(Material.LAVA_BUCKET, msg("PARTICLE_ENTRY_DELETE", player), List.of(msg("PARTICLE_SHIFT_TO_DELETE", player)), false, clickType -> {
if (!clickType.isShiftClick()) return;
slot.getEntries().remove(entryIndex);
@@ -251,8 +252,12 @@ class EntryEditor {
// Saves the change, or reverts it and tells the player when the slot would go over its budget
private <T> boolean apply(Context context, Parameter<T> parameter, T value) {
T previous = context.entry().getValues().get(parameter);
if (Objects.equals(previous, parameter.validate(value))) {
return true;
}
double previousCost = context.slot().cost();
context.entry().getValues().set(parameter, value);
if (!SlotEditor.fits(context.user(), context.slot())) {
if (!SlotEditor.allows(context.user(), context.slot(), previousCost)) {
context.entry().getValues().set(parameter, previous);
LobbySystem.getMessage().send("PARTICLE_SLOT_OVER_BUDGET", context.player());
return false;
@@ -272,8 +277,9 @@ class EntryEditor {
design.applyDefaults(next.getValues());
}
List<ParticleEntry> entries = context.slot().getEntries();
double previousCost = context.slot().cost();
entries.set(context.entryIndex(), next);
if (!SlotEditor.fits(context.user(), context.slot())) {
if (!SlotEditor.allows(context.user(), context.slot(), previousCost)) {
entries.set(context.entryIndex(), previous);
LobbySystem.getMessage().send("PARTICLE_SLOT_OVER_BUDGET", context.player());
} else {
@@ -126,6 +126,7 @@ class ParticleGuiText {
addCondition(lore, GROUND, values.get(GROUND), Ground.ANY, player);
addCondition(lore, SNEAK, values.get(SNEAK), Sneak.ANY, player);
addCondition(lore, VISIBILITY, values.get(VISIBILITY), Visibility.EVERYONE, player);
lore.add(msg("PARTICLE_ENTRY_COST", player, number(entry.cost())));
if (!entry.getDesign().getRequirement().test(context)) {
lore.add(msg("PARTICLE_ENTRY_LOCKED", player));
}
@@ -96,8 +96,9 @@ public class SlotEditor {
return;
}
Pickers.design(player, null, design -> {
double previousCost = slot.cost();
entries.add(new ParticleEntry(design));
if (!fits(user, slot)) {
if (!allows(user, slot, previousCost)) {
entries.remove(entries.size() - 1);
LobbySystem.getMessage().send("PARTICLE_SLOT_OVER_BUDGET", player);
open(player, index);
@@ -142,8 +143,15 @@ public class SlotEditor {
});
}
boolean fits(SteamwarUser user, ParticleSlot slot) {
return slot.cost() <= ParticleSlots.maxCost(user);
// The slot's particles per tick, with the share of the entry being edited
SWItem costItem(Player player, SteamwarUser user, ParticleSlot slot, ParticleEntry entry) {
return costItem(player, user, slot).setLore(msg("PARTICLE_ENTRY_COST_SHARE", player, number(entry.cost())));
}
// A change is fine within the budget, and also when it does not add particles to a slot already over it
boolean allows(SteamwarUser user, ParticleSlot slot, double previousCost) {
double cost = slot.cost();
return cost <= ParticleSlots.maxCost(user) || cost <= previousCost;
}
void save(Player player, int index, ParticleSlot slot) {
@@ -91,6 +91,8 @@ class ValueEditors {
double next = Math.max(min, Math.min(max, unclamped));
String limit = next == max && unclamped >= max ? "PARTICLE_NUMBER_AT_MAX" : next == min && unclamped <= min ? "PARTICLE_NUMBER_AT_MIN" : "PARTICLE_NUMBER_RESULT";
return new SWItem(material, label, List.of(msg(limit, player, number(next))), false, clickType -> {
// Stepping past the minimum or maximum changes nothing, so it does nothing
if (next == value) return;
apply.test(next);
reopen.run();
});