forked from SteamWar/SteamWar
Unlock tournament wing images and cosy smoke for building
The MiniWarGear league, Underwater MWG, WarGear season 2022 and WarGear clash wing images become Wings shapes, locked behind the placement that earns their reward. Cosy campfire smoke becomes a buildable particle for Hells Bells participants. Choice options can now carry a requirement: locked options show it in the picker, are skipped when cycling and hide entries that use them.
This commit is contained in:
@@ -21,17 +21,25 @@ package de.steamwar.lobby.particle.design;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import de.steamwar.lobby.particle.ParticleRequirement;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Getter
|
||||
public class ChoiceParameter<E> extends Parameter<E> {
|
||||
|
||||
// Internal choices are usable by presets but never offered in the builder or accepted from storage
|
||||
public record Choice<E>(String id, E value, boolean internal) {
|
||||
// Internal choices are usable by presets but never offered in the builder or accepted from storage. Locked choices
|
||||
// are offered with their requirement; the requirement is looked up lazily as it may live in a reward design.
|
||||
public record Choice<E>(String id, E value, boolean internal, Supplier<ParticleRequirement> requirement) {
|
||||
|
||||
public Choice(String id, E value, boolean internal) {
|
||||
this(id, value, internal, () -> ParticleRequirement.NO_REQUIRMENT);
|
||||
}
|
||||
}
|
||||
|
||||
private final List<Choice<E>> choices;
|
||||
@@ -41,14 +49,18 @@ public class ChoiceParameter<E> extends Parameter<E> {
|
||||
this.choices = choices;
|
||||
}
|
||||
|
||||
public static <E extends Enum<E>> ChoiceParameter<E> ofEnum(String key, String nameKey, E defaultValue, Predicate<E> internal) {
|
||||
public static <E extends Enum<E>> ChoiceParameter<E> ofEnum(String key, String nameKey, E defaultValue, Predicate<E> internal, Function<E, ParticleRequirement> requirement) {
|
||||
List<Choice<E>> choices = new ArrayList<>();
|
||||
for (E value : defaultValue.getDeclaringClass().getEnumConstants()) {
|
||||
choices.add(new Choice<>(value.name(), value, internal.test(value)));
|
||||
choices.add(new Choice<>(value.name(), value, internal.test(value), () -> requirement.apply(value)));
|
||||
}
|
||||
return new ChoiceParameter<>(key, nameKey, defaultValue, choices);
|
||||
}
|
||||
|
||||
public static <E extends Enum<E>> ChoiceParameter<E> ofEnum(String key, String nameKey, E defaultValue, Predicate<E> internal) {
|
||||
return ofEnum(key, nameKey, defaultValue, internal, value -> ParticleRequirement.NO_REQUIRMENT);
|
||||
}
|
||||
|
||||
public static <E extends Enum<E>> ChoiceParameter<E> ofEnum(String key, String nameKey, E defaultValue) {
|
||||
return ofEnum(key, nameKey, defaultValue, value -> false);
|
||||
}
|
||||
@@ -57,6 +69,10 @@ public class ChoiceParameter<E> extends Parameter<E> {
|
||||
return choices.stream().filter(choice -> !choice.internal()).map(Choice::value).toList();
|
||||
}
|
||||
|
||||
public ParticleRequirement requirement(E value) {
|
||||
return choiceOf(value).requirement().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement toJson(E value) {
|
||||
return new JsonPrimitive(choiceOf(value).id());
|
||||
|
||||
@@ -74,10 +74,11 @@ public class Designs {
|
||||
new ChoiceParameter.Choice<>("bat", WingShape.drawn(DrawnWings.BAT), false),
|
||||
new ChoiceParameter.Choice<>("butterfly", WingShape.drawn(DrawnWings.BUTTERFLY), false),
|
||||
new ChoiceParameter.Choice<>("fairy", WingShape.drawn(DrawnWings.FAIRY), false),
|
||||
new ChoiceParameter.Choice<>("sw", WingShape.image(WingDesign.SW), true),
|
||||
new ChoiceParameter.Choice<>("wgs", WingShape.image(WingDesign.WGS), true),
|
||||
new ChoiceParameter.Choice<>("sword_crossed", WingShape.image(WingDesign.SWORD_CROSSED), true),
|
||||
new ChoiceParameter.Choice<>("mwgl", WingShape.image(WingDesign.MWGL), true),
|
||||
// Tournament wing images, unlocked by the placement that earns their reward
|
||||
new ChoiceParameter.Choice<>("mwgl", WingShape.image(WingDesign.MWGL), false, () -> RewardDesigns.EVENT_PLACEMENT_MINI_WARGEAR_LIGA.getRequirement()),
|
||||
new ChoiceParameter.Choice<>("sw", WingShape.image(WingDesign.SW), false, () -> RewardDesigns.EVENT_PLACEMENT_UNDERWATER_MWG.getRequirement()),
|
||||
new ChoiceParameter.Choice<>("wgs", WingShape.image(WingDesign.WGS), false, () -> RewardDesigns.EVENT_PLACEMENT_WARGEAR_SEASON_2022.getRequirement()),
|
||||
new ChoiceParameter.Choice<>("sword_crossed", WingShape.image(WingDesign.SWORD_CROSSED), false, () -> RewardDesigns.EVENT_PLACEMENT_WARGEAR_CLASH.getRequirement()),
|
||||
new ChoiceParameter.Choice<>("eclipse", WingShape.image(WingDesign.ECLIPSE), true),
|
||||
new ChoiceParameter.Choice<>("pl", WingShape.image(WingDesign.PL), true),
|
||||
new ChoiceParameter.Choice<>("plompa_easter", WingShape.image(WingDesign.PlompaEasterWings), true),
|
||||
|
||||
@@ -132,7 +132,7 @@ public class EntryParameters {
|
||||
}
|
||||
}
|
||||
|
||||
public final ChoiceParameter<ParticleType> PARTICLE = ChoiceParameter.ofEnum("particle", "PARTICLE_PARAM_PARTICLE", ParticleType.FLAME, type -> !type.isBuildable());
|
||||
public final ChoiceParameter<ParticleType> PARTICLE = ChoiceParameter.ofEnum("particle", "PARTICLE_PARAM_PARTICLE", ParticleType.FLAME, type -> !type.isBuildable(), ParticleType::getRequirement);
|
||||
public final IntParameter COUNT = new IntParameter("count", "PARTICLE_PARAM_COUNT", 5, 1, 20);
|
||||
// Minecraft scatters particles around their point by about this many blocks; beyond half a block a design dissolves
|
||||
public final DoubleParameter SPREAD_X = new DoubleParameter("spreadX", "PARTICLE_PARAM_SPREAD_X", 0, 0, 0.5, 0.01);
|
||||
|
||||
@@ -53,7 +53,7 @@ public enum ParticleType {
|
||||
SMOKE(Material.COBWEB, Particle.SMOKE, Data.NONE, true),
|
||||
LARGE_SMOKE(Material.GRAY_WOOL, Particle.LARGE_SMOKE, Data.NONE, false),
|
||||
WHITE_SMOKE(Material.LIGHT_GRAY_DYE, Particle.WHITE_SMOKE, Data.NONE, true),
|
||||
CAMPFIRE_COSY_SMOKE(Material.CAMPFIRE, Particle.CAMPFIRE_COSY_SMOKE, Data.NONE, false),
|
||||
CAMPFIRE_COSY_SMOKE(Material.CAMPFIRE, Particle.CAMPFIRE_COSY_SMOKE, Data.NONE, true),
|
||||
CAMPFIRE_SIGNAL_SMOKE(Material.HAY_BLOCK, Particle.CAMPFIRE_SIGNAL_SMOKE, Data.NONE, false),
|
||||
ASH(Material.BASALT, Particle.ASH, Data.NONE, true),
|
||||
WHITE_ASH(Material.BONE_MEAL, Particle.WHITE_ASH, Data.NONE, true),
|
||||
@@ -180,10 +180,12 @@ public enum ParticleType {
|
||||
return data == Data.DUST || data == Data.COLOR || data == Data.COLOR_TRANSITION || data == Data.TRAIL;
|
||||
}
|
||||
|
||||
// Leaves drift down slowly and pile up around a player, so only the server team may build with them
|
||||
// Leaves drift down slowly and pile up around a player, so only the server team may build with them. Cosy smoke is
|
||||
// earned by taking part in Hells Bells.
|
||||
public ParticleRequirement getRequirement() {
|
||||
return switch (this) {
|
||||
case CHERRY_LEAVES, PALE_OAK_LEAVES, TINTED_LEAVES -> ParticleRequirement.SERVER_TEAM;
|
||||
case CAMPFIRE_COSY_SMOKE -> RewardDesigns.EVENT_PARTICIPATION_HELLS_BELLS.getRequirement();
|
||||
default -> ParticleRequirement.NO_REQUIRMENT;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ package de.steamwar.lobby.particle.gui;
|
||||
import de.steamwar.inventory.SWInventory;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.lobby.LobbySystem;
|
||||
import de.steamwar.lobby.particle.ParticleRequirement;
|
||||
import de.steamwar.lobby.particle.UnlockContext;
|
||||
import de.steamwar.lobby.particle.design.*;
|
||||
import de.steamwar.lobby.particle.slot.ParticleEntry;
|
||||
@@ -233,16 +232,19 @@ class EntryEditor {
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Left click moves forward, right click backward
|
||||
// Left click moves forward, right click backward, skipping locked options
|
||||
private <E> void cycle(Context context, ChoiceParameter<E> parameter, E current, int direction) {
|
||||
List<E> values = parameter.getBuildableValues();
|
||||
UnlockContext unlock = new UnlockContext(SteamwarUser.get(context.player().getUniqueId()));
|
||||
List<E> values = parameter.getBuildableValues().stream()
|
||||
.filter(value -> value == current || parameter.requirement(value).test(unlock))
|
||||
.toList();
|
||||
apply(context, parameter, values.get(Math.floorMod(values.indexOf(current) + direction, values.size())));
|
||||
context.reopen();
|
||||
}
|
||||
|
||||
private <E> void pick(Context context, ChoiceParameter<E> parameter, E current) {
|
||||
Pickers.choice(context.player(), parameter, current, EntryEditor::choiceIcon,
|
||||
value -> value instanceof ParticleType type ? type.getRequirement() : ParticleRequirement.NO_REQUIRMENT, picked -> {
|
||||
parameter::requirement, picked -> {
|
||||
apply(context, parameter, picked);
|
||||
context.reopen();
|
||||
}, context::reopen);
|
||||
|
||||
@@ -175,12 +175,18 @@ public class ParticleEntry {
|
||||
return new Always(values.get(VISIBILITY).wrap(touch));
|
||||
}
|
||||
|
||||
// Shown only when both the design and, for designs that use it, the particle type are unlocked
|
||||
// Shown only when the design, its chosen options and, for designs that use it, the particle type are unlocked
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean isUnlocked(UnlockContext context) {
|
||||
if (!design.getRequirement().test(context)) {
|
||||
return false;
|
||||
}
|
||||
return !design.usesEntryParticle() || values.get(PARTICLE).getRequirement().test(context);
|
||||
for (Parameter<?> parameter : design.getParameters()) {
|
||||
if (parameter instanceof ChoiceParameter<?> choice && !((ChoiceParameter<Object>) choice).requirement(values.get(choice)).test(context)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !design.usesEntryParticle() || PARTICLE.requirement(values.get(PARTICLE)).test(context);
|
||||
}
|
||||
|
||||
// Particles each point spawns; designs that set their own point count replace the amount with 1
|
||||
|
||||
Reference in New Issue
Block a user