From a9798e4c0625440f0eaa8bd0d51b949bdcf75eb7 Mon Sep 17 00:00:00 2001 From: arcadeboss Date: Wed, 9 Oct 2024 14:54:18 -0500 Subject: [PATCH] Add near sparks option to destroyables (#1405) Signed-off-by: arcadeboss Signed-off-by: Pablo Herrera Co-authored-by: Pablo Herrera --- .../tc/oc/pgm/destroyable/Destroyable.java | 15 ++++---- .../pgm/destroyable/DestroyableFactory.java | 34 ++++++++++++++++--- .../oc/pgm/destroyable/DestroyableModule.java | 4 ++- .../java/tc/oc/pgm/util/text/TextParser.java | 24 +++++++++---- 4 files changed, 59 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/tc/oc/pgm/destroyable/Destroyable.java b/core/src/main/java/tc/oc/pgm/destroyable/Destroyable.java index 0ba2092310..a4050b94c3 100644 --- a/core/src/main/java/tc/oc/pgm/destroyable/Destroyable.java +++ b/core/src/main/java/tc/oc/pgm/destroyable/Destroyable.java @@ -330,7 +330,7 @@ public DestroyableHealthChange handleBlockChange( if (deltaHealth < 0) { touch(player); - if (this.definition.hasSparks()) { + if (this.definition.isSparksActive()) { Location blockLocation = BlockVectors.center(oldState); Instant now = Instant.now(); @@ -356,12 +356,13 @@ public DestroyableHealthChange handleBlockChange( NMS_HACKS.skipFireworksLaunch(firework); } - // Players more than 64m away will not see or hear the fireworks, so just play the sound - // for them - for (MatchPlayer listener : this.getOwner().getMatch().getPlayers()) { - if (listener.getBukkit().getLocation().distance(blockLocation) > 64) { - listener.playSound(Sounds.OBJECTIVE_FIREWORKS_FAR); - listener.playSound(Sounds.OBJECTIVE_FIREWORKS_TWINKLE); + if (this.definition.isSparksAll()) { + // Players more than 64m away will not see or hear the fireworks, so play sound for them + for (MatchPlayer listener : this.getOwner().getMatch().getPlayers()) { + if (listener.getBukkit().getLocation().distance(blockLocation) > 64) { + listener.playSound(Sounds.OBJECTIVE_FIREWORKS_FAR); + listener.playSound(Sounds.OBJECTIVE_FIREWORKS_TWINKLE); + } } } } diff --git a/core/src/main/java/tc/oc/pgm/destroyable/DestroyableFactory.java b/core/src/main/java/tc/oc/pgm/destroyable/DestroyableFactory.java index eaed8dfd13..39ab2ffe07 100644 --- a/core/src/main/java/tc/oc/pgm/destroyable/DestroyableFactory.java +++ b/core/src/main/java/tc/oc/pgm/destroyable/DestroyableFactory.java @@ -1,6 +1,9 @@ package tc.oc.pgm.destroyable; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterators; +import java.util.Iterator; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import tc.oc.pgm.api.feature.FeatureInfo; import tc.oc.pgm.api.region.Region; @@ -9,6 +12,7 @@ import tc.oc.pgm.goals.ShowOptions; import tc.oc.pgm.modes.Mode; import tc.oc.pgm.teams.TeamFactory; +import tc.oc.pgm.util.Aliased; import tc.oc.pgm.util.material.MaterialMatcher; @FeatureInfo(name = "destroyable") @@ -18,7 +22,7 @@ public class DestroyableFactory extends ProximityGoalDefinition { protected final double destructionRequired; protected final ImmutableSet modeList; protected final boolean showProgress; - protected final boolean sparks; + protected final SparksType sparks; protected final boolean repairable; public DestroyableFactory( @@ -33,7 +37,7 @@ public DestroyableFactory( double destructionRequired, @Nullable ImmutableSet modeList, boolean showProgress, - boolean sparks, + SparksType sparks, boolean repairable) { super(id, name, required, showOptions, owner, proximityMetric); this.region = region; @@ -65,11 +69,33 @@ public boolean getShowProgress() { return this.showProgress; } - public boolean hasSparks() { - return this.sparks; + public boolean isSparksActive() { + return this.sparks != SparksType.NONE; + } + + public boolean isSparksAll() { + return this.sparks == SparksType.ALL; } public boolean isRepairable() { return this.repairable; } + + public enum SparksType implements Aliased { + NONE("false", "no", "off"), + NEAR("near"), + ALL("true", "yes", "on"); + + private final String[] names; + + SparksType(String... names) { + this.names = names; + } + + @NotNull + @Override + public Iterator iterator() { + return Iterators.forArray(names); + } + } } diff --git a/core/src/main/java/tc/oc/pgm/destroyable/DestroyableModule.java b/core/src/main/java/tc/oc/pgm/destroyable/DestroyableModule.java index 307dcdfdda..6ae487021d 100644 --- a/core/src/main/java/tc/oc/pgm/destroyable/DestroyableModule.java +++ b/core/src/main/java/tc/oc/pgm/destroyable/DestroyableModule.java @@ -18,6 +18,7 @@ import tc.oc.pgm.api.match.MatchModule; import tc.oc.pgm.api.region.Region; import tc.oc.pgm.blockdrops.BlockDropsModule; +import tc.oc.pgm.destroyable.DestroyableFactory.SparksType; import tc.oc.pgm.goals.GoalMatchModule; import tc.oc.pgm.goals.ProximityMetric; import tc.oc.pgm.goals.ShowOptions; @@ -127,7 +128,8 @@ public DestroyableModule parse(MapFactory context, Logger logger, Document doc) boolean showProgress = XMLUtils.parseBoolean(destroyableEl.getAttribute("show-progress"), false); - boolean sparks = XMLUtils.parseBoolean(destroyableEl.getAttribute("sparks"), false); + SparksType sparks = XMLUtils.parseEnum( + Node.fromAttr(destroyableEl, "sparks"), SparksType.class, SparksType.NONE); boolean repairable = XMLUtils.parseBoolean(destroyableEl.getAttribute("repairable"), true); ShowOptions options = ShowOptions.parse(context.getFilters(), destroyableEl); Boolean required = XMLUtils.parseBoolean(destroyableEl.getAttribute("required"), null); diff --git a/util/src/main/java/tc/oc/pgm/util/text/TextParser.java b/util/src/main/java/tc/oc/pgm/util/text/TextParser.java index d9b15d32cc..2c3a1f1de9 100644 --- a/util/src/main/java/tc/oc/pgm/util/text/TextParser.java +++ b/util/src/main/java/tc/oc/pgm/util/text/TextParser.java @@ -29,6 +29,7 @@ import org.bukkit.Chunk; import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; +import tc.oc.pgm.util.Aliased; import tc.oc.pgm.util.StringUtils; import tc.oc.pgm.util.TimeUtils; import tc.oc.pgm.util.Version; @@ -343,7 +344,7 @@ public static > E parseEnum( String name = text.replace(' ', '_'); E value = StringUtils.bestFuzzyMatch(name, type); - if (value == null || (!fuzzyMatch && !name.equalsIgnoreCase(value.name()))) { + if (value == null || (!fuzzyMatch && !isExactMatch(name, value))) { throw invalidFormat(text, type, value != null ? value.name().toLowerCase() : null, null); } @@ -354,6 +355,17 @@ public static > E parseEnum( return value; } + private static > boolean isExactMatch(String text, E value) { + if (value instanceof Aliased aliased) { + for (String aliases : aliased) { + if (text.equalsIgnoreCase(aliases)) return true; + } + return false; + } else { + return text.equalsIgnoreCase(value.name()); + } + } + /** * Parses text into an enum. * @@ -434,11 +446,11 @@ public static Component parseComponent(String text) throws TextException { * *

Accepts full qualified json strings as components. * - *

This method is mainly for backwards compatability for {@link - * XMLUtils#parseFormattedText(Node, Component)}. Previously using {@link #parseComponent(String)} - * with the result from {@code parseFormattedText} would bug out when sent to older clients, since - * the LegacyComponentSerializer expects "&" but {@link BukkitUtils#colorize(String)}(Used in the - * XMLUtils method) results in using "§". + *

This method is mainly for backwards compatability for + * {@link XMLUtils#parseFormattedText(Node, Component)}. Previously using + * {@link #parseComponent(String)} with the result from {@code parseFormattedText} would bug out + * when sent to older clients, since the LegacyComponentSerializer expects "&" but + * {@link BukkitUtils#colorize(String)}(Used in the XMLUtils method) results in using "§". * * @param text The text. * @return a Component.