From c38f8940d52acfad949d897344fae0e8553a838f Mon Sep 17 00:00:00 2001 From: Pablo Herrera Date: Sun, 3 Nov 2024 23:33:51 +0100 Subject: [PATCH] Implement custom objective modes (#1422) Signed-off-by: Pablo Herrera --- .../java/tc/oc/pgm/command/ModeCommand.java | 52 ++++++++--------- core/src/main/java/tc/oc/pgm/core/Core.java | 8 ++- .../java/tc/oc/pgm/core/CoreMatchModule.java | 2 +- .../tc/oc/pgm/destroyable/Destroyable.java | 8 ++- .../destroyable/DestroyableMatchModule.java | 2 +- .../java/tc/oc/pgm/goals/ModeChangeGoal.java | 6 +- core/src/main/java/tc/oc/pgm/modes/Mode.java | 56 ++++++++---------- .../main/java/tc/oc/pgm/modes/ModeUtils.java | 11 ++-- .../pgm/modes/ObjectiveModeChangeEvent.java | 41 ++++++------- .../pgm/modes/ObjectiveModesMatchModule.java | 11 +++- .../tc/oc/pgm/modes/ObjectiveModesModule.java | 57 ++++++++----------- .../tc/oc/pgm/util/xml/XMLFluentParser.java | 12 +++- .../pgm/util/xml/parsers/StringBuilder.java | 29 ++++++++++ 13 files changed, 162 insertions(+), 133 deletions(-) create mode 100644 core/src/main/java/tc/oc/pgm/util/xml/parsers/StringBuilder.java diff --git a/core/src/main/java/tc/oc/pgm/command/ModeCommand.java b/core/src/main/java/tc/oc/pgm/command/ModeCommand.java index 4623b77cd2..c947272ce6 100644 --- a/core/src/main/java/tc/oc/pgm/command/ModeCommand.java +++ b/core/src/main/java/tc/oc/pgm/command/ModeCommand.java @@ -38,26 +38,22 @@ public void next(Audience audience, ObjectiveModesMatchModule modes) { if (countdowns.isEmpty()) throwNoResults(); - TextComponent.Builder builder = - text().append(translatable("command.nextMode", NamedTextColor.DARK_PURPLE).append(space())); + TextComponent.Builder builder = text() + .append(translatable("command.nextMode", NamedTextColor.DARK_PURPLE).append(space())); ModeChangeCountdown next = countdowns.get(0); Duration timeLeft = modes.getCountdown().getTimeLeft(next); if (timeLeft == null) { - builder.append(text(next.getMode().getPreformattedMaterialName(), NamedTextColor.GOLD)); + builder.append(text(next.getMode().getLegacyName(), NamedTextColor.GOLD)); } else if (timeLeft.getSeconds() >= 0) { - builder.append( - text( - WordUtils.capitalize(next.getMode().getPreformattedMaterialName()), - NamedTextColor.GOLD) - .append(space()) - .append(text("(", NamedTextColor.AQUA)) - .append( - new ModesPaginatedResult(modes) - .formatSingleCountdown(next) - .color(NamedTextColor.AQUA)) - .append(text(")", NamedTextColor.AQUA))); + builder.append(text(WordUtils.capitalize(next.getMode().getLegacyName()), NamedTextColor.GOLD) + .append(space()) + .append(text("(", NamedTextColor.AQUA)) + .append(new ModesPaginatedResult(modes) + .formatSingleCountdown(next) + .color(NamedTextColor.AQUA)) + .append(text(")", NamedTextColor.AQUA))); } else { throwNoResults(); } @@ -83,14 +79,13 @@ public void list( List modeList = modes.getSortedCountdowns(true); int resultsPerPage = 8; int pages = (modeList.size() + resultsPerPage - 1) / resultsPerPage; - Component header = - TextFormatter.paginate( - translatable("command.monumentModes"), - page, - pages, - NamedTextColor.DARK_AQUA, - NamedTextColor.AQUA, - true); + Component header = TextFormatter.paginate( + translatable("command.monumentModes"), + page, + pages, + NamedTextColor.DARK_AQUA, + NamedTextColor.AQUA, + true); new ModesPaginatedResult(header, resultsPerPage, modes).display(audience, modeList, page); } @@ -122,7 +117,8 @@ public void push( TextComponent.Builder builder = text().append(translatable("command.modesPushed", NamedTextColor.GOLD).append(space())); if (duration.isNegative()) { - builder.append(translatable("command.modesPushedBack", NamedTextColor.GOLD).append(space())); + builder.append( + translatable("command.modesPushedBack", NamedTextColor.GOLD).append(space())); } else { builder.append( translatable("command.modesPushedForwards", NamedTextColor.GOLD).append(space())); @@ -152,12 +148,10 @@ public void start( context.cancel(countdown); context.start(countdown, time); - TextComponent.Builder builder = - text() - .append( - translatable("command.selectedModePushed", mode.getComponentName()) - .color(NamedTextColor.GOLD) - .append(space())); + TextComponent.Builder builder = text() + .append(translatable("command.selectedModePushed", mode.getComponentName()) + .color(NamedTextColor.GOLD) + .append(space())); builder.append(clock(Math.abs(time.getSeconds())).color(NamedTextColor.AQUA)); audience.sendMessage(builder); } diff --git a/core/src/main/java/tc/oc/pgm/core/Core.java b/core/src/main/java/tc/oc/pgm/core/Core.java index 1774c1d70e..2af5c62204 100644 --- a/core/src/main/java/tc/oc/pgm/core/Core.java +++ b/core/src/main/java/tc/oc/pgm/core/Core.java @@ -7,7 +7,6 @@ import static net.kyori.adventure.text.format.Style.style; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import java.util.Collections; import java.util.Set; import net.kyori.adventure.text.Component; @@ -132,8 +131,10 @@ public Iterable getProximityLocations(ParticipantState player) { return proximityLocations; } - public ImmutableSet getModes() { - return this.definition.getModes(); + @Override + public boolean isAffectedBy(Mode mode) { + return mode.getMaterialData() != null + && (this.definition.getModes() == null || this.definition.getModes().contains(mode)); } public boolean isCoreMaterial(MaterialData material) { @@ -241,6 +242,7 @@ public boolean isObjectiveMaterial(Block block) { return material.matches(block.getState()); } + @Override public String getModeChangeMessage(Material material) { return ModeUtils.formatMaterial(material) + " CORE MODE"; } diff --git a/core/src/main/java/tc/oc/pgm/core/CoreMatchModule.java b/core/src/main/java/tc/oc/pgm/core/CoreMatchModule.java index 06e6ca6ed8..9f43d6dbd8 100644 --- a/core/src/main/java/tc/oc/pgm/core/CoreMatchModule.java +++ b/core/src/main/java/tc/oc/pgm/core/CoreMatchModule.java @@ -161,7 +161,7 @@ public void lavaProtection(final BlockTransformEvent event) { @EventHandler(priority = EventPriority.HIGHEST) public void onObjectiveModeSwitch(final ObjectiveModeChangeEvent event) { for (Core core : this.cores) { - if (core.getModes() == null || core.getModes().contains(event.getMode())) { + if (core.isAffectedBy(event.getMode())) { core.replaceBlocks(event.getMode().getMaterialData()); // if at least one of the cores are visible, the mode change message will be sent if (core.hasShowOption(ShowOption.SHOW_MESSAGES)) { 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 a4050b94c3..356ba9ea44 100644 --- a/core/src/main/java/tc/oc/pgm/destroyable/Destroyable.java +++ b/core/src/main/java/tc/oc/pgm/destroyable/Destroyable.java @@ -8,7 +8,6 @@ import static tc.oc.pgm.util.nms.NMSHacks.NMS_HACKS; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import java.time.Duration; import java.time.Instant; @@ -171,8 +170,10 @@ public Iterable getProximityLocations(ParticipantState player) { return proximityLocations; } - public ImmutableSet getModes() { - return this.definition.getModes(); + @Override + public boolean isAffectedBy(Mode mode) { + return mode.getMaterialData() != null + && (this.definition.getModes() == null || this.definition.getModes().contains(mode)); } /** Calculate maximum/current health */ @@ -611,6 +612,7 @@ public boolean isObjectiveMaterial(Block block) { return this.hasMaterial(MaterialData.block(block)); } + @Override public String getModeChangeMessage(Material material) { return ModeUtils.formatMaterial(material) + " OBJECTIVE MODE"; } diff --git a/core/src/main/java/tc/oc/pgm/destroyable/DestroyableMatchModule.java b/core/src/main/java/tc/oc/pgm/destroyable/DestroyableMatchModule.java index 6177c76a85..502581540f 100644 --- a/core/src/main/java/tc/oc/pgm/destroyable/DestroyableMatchModule.java +++ b/core/src/main/java/tc/oc/pgm/destroyable/DestroyableMatchModule.java @@ -128,7 +128,7 @@ public void processBlockDamage(BlockDamageEvent event) { @EventHandler(priority = EventPriority.HIGHEST) public void onObjectiveModeSwitch(final ObjectiveModeChangeEvent event) { for (Destroyable destroyable : this.destroyables) { - if (destroyable.getModes() == null || destroyable.getModes().contains(event.getMode())) { + if (destroyable.isAffectedBy(event.getMode())) { double oldCompletion = destroyable.getCompletion(); destroyable.replaceBlocks(event.getMode().getMaterialData()); // if at least one of the destroyables are visible, the mode change message will be sent diff --git a/core/src/main/java/tc/oc/pgm/goals/ModeChangeGoal.java b/core/src/main/java/tc/oc/pgm/goals/ModeChangeGoal.java index 6f50712584..7870c629f1 100644 --- a/core/src/main/java/tc/oc/pgm/goals/ModeChangeGoal.java +++ b/core/src/main/java/tc/oc/pgm/goals/ModeChangeGoal.java @@ -1,15 +1,17 @@ package tc.oc.pgm.goals; -import com.google.common.collect.ImmutableSet; +import org.bukkit.Material; import org.bukkit.block.Block; import tc.oc.pgm.modes.Mode; import tc.oc.pgm.util.material.BlockMaterialData; public interface ModeChangeGoal extends Goal { + boolean isAffectedBy(Mode mode); + void replaceBlocks(BlockMaterialData newMaterial); boolean isObjectiveMaterial(Block block); - ImmutableSet getModes(); + String getModeChangeMessage(Material material); } diff --git a/core/src/main/java/tc/oc/pgm/modes/Mode.java b/core/src/main/java/tc/oc/pgm/modes/Mode.java index c9ae02962b..7d135ce2e1 100644 --- a/core/src/main/java/tc/oc/pgm/modes/Mode.java +++ b/core/src/main/java/tc/oc/pgm/modes/Mode.java @@ -3,53 +3,51 @@ import static net.kyori.adventure.text.Component.text; import java.time.Duration; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.Objects; +import java.util.function.Supplier; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.jetbrains.annotations.Nullable; +import tc.oc.pgm.action.Action; import tc.oc.pgm.api.feature.FeatureInfo; import tc.oc.pgm.api.filter.Filter; +import tc.oc.pgm.api.match.Match; import tc.oc.pgm.features.SelfIdentifyingFeatureDefinition; import tc.oc.pgm.util.material.BlockMaterialData; @FeatureInfo(name = "mode") public class Mode extends SelfIdentifyingFeatureDefinition { - private final BlockMaterialData material; - private final Duration after; - private final @Nullable Filter filter; private final @Nullable String name; private final String legacyName; private final Component componentName; - private final Duration showBefore; - public Mode(final BlockMaterialData material, final Duration after, Duration showBefore) { - this(null, material, after, null, null, showBefore); - } + private final Duration after; + private final Duration showBefore; + private final @Nullable Filter filter; + private final @Nullable BlockMaterialData material; + private final @Nullable Action action; public Mode( - final @Nullable String id, - final BlockMaterialData material, + final String id, + final @Nullable String name, final Duration after, + final Duration showBefore, final @Nullable Filter filter, - final @Nullable String name, - Duration showBefore) { + final @Nullable BlockMaterialData material, + final @Nullable Action action) { super(id); - this.material = material; - this.after = after; - this.filter = filter; this.name = name; - this.legacyName = name != null ? name : getPreformattedMaterialName(); + this.legacyName = getName(() -> ModeUtils.formatMaterial(material)); this.componentName = text(legacyName, NamedTextColor.RED); + this.after = after; this.showBefore = showBefore; + this.filter = filter; + this.material = material; + this.action = action; } - @Override - protected String getDefaultId() { - return makeDefaultId() + "--" + makeId(legacyName); - } - - public BlockMaterialData getMaterialData() { - return this.material; + public String getName(Supplier ifNull) { + return Objects.requireNonNullElseGet(this.name, ifNull); } public String getLegacyName() { @@ -60,10 +58,6 @@ public Component getComponentName() { return componentName; } - public String getPreformattedMaterialName() { - return ModeUtils.formatMaterial(this.material); - } - public Duration getAfter() { return this.after; } @@ -76,11 +70,11 @@ public Duration getShowBefore() { return this.filter; } - public @Nullable String getName() { - return this.name; + public @Nullable BlockMaterialData getMaterialData() { + return this.material; } - public static String makeDefaultId(@Nullable String name, AtomicInteger serial) { - return "--" + makeTypeName(Mode.class) + "-" + makeId(name); + public @Nullable Action getAction() { + return this.action; } } diff --git a/core/src/main/java/tc/oc/pgm/modes/ModeUtils.java b/core/src/main/java/tc/oc/pgm/modes/ModeUtils.java index 1157dab14b..29a36c73ab 100644 --- a/core/src/main/java/tc/oc/pgm/modes/ModeUtils.java +++ b/core/src/main/java/tc/oc/pgm/modes/ModeUtils.java @@ -5,15 +5,14 @@ public class ModeUtils { public static String formatMaterial(Material m) { - switch (m) { - case GOLD_BLOCK: - return "GOLD"; - default: - return m.name().replaceAll("_", " "); - } + return switch (m) { + case GOLD_BLOCK -> "GOLD"; + default -> m.name().replaceAll("_", " "); + }; } public static String formatMaterial(MaterialData m) { + if (m == null) return "Unknown mode"; return formatMaterial(m.getItemType()); } } diff --git a/core/src/main/java/tc/oc/pgm/modes/ObjectiveModeChangeEvent.java b/core/src/main/java/tc/oc/pgm/modes/ObjectiveModeChangeEvent.java index 0fa074b6bd..a578fcbaaf 100644 --- a/core/src/main/java/tc/oc/pgm/modes/ObjectiveModeChangeEvent.java +++ b/core/src/main/java/tc/oc/pgm/modes/ObjectiveModeChangeEvent.java @@ -2,7 +2,6 @@ import static tc.oc.pgm.util.Assert.assertNotNull; -import java.util.Collection; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; import tc.oc.pgm.api.match.Match; @@ -10,6 +9,7 @@ import tc.oc.pgm.core.Core; import tc.oc.pgm.destroyable.Destroyable; import tc.oc.pgm.goals.GoalMatchModule; +import tc.oc.pgm.goals.ModeChangeGoal; public class ObjectiveModeChangeEvent extends MatchEvent { @@ -22,27 +22,30 @@ public ObjectiveModeChangeEvent(Match match, final Mode mode) { super(match); this.mode = mode; this.visible = false; + this.name = this.mode.getName(() -> { + ModeChangeGoal objective = getMainObjective(); + return objective == null || mode.getMaterialData() == null + ? mode.getLegacyName() + : objective.getModeChangeMessage(mode.getMaterialData().getItemType()); + }); + } - if (this.mode.getName() != null) { - this.name = this.mode.getName(); - } else { - GoalMatchModule wins = getMatch().needModule(GoalMatchModule.class); - Collection cores = wins.getGoals(Core.class).values(); - Collection destroyables = wins.getGoals(Destroyable.class).values(); + private ModeChangeGoal getMainObjective() { + GoalMatchModule wins = getMatch().needModule(GoalMatchModule.class); + Destroyable lastDestroyable = null; + int affectedDestroyables = 0; + for (Destroyable destroyable : wins.getGoals(Destroyable.class).values()) { + if (!destroyable.isAffectedBy(mode)) continue; + affectedDestroyables++; + lastDestroyable = destroyable; + } - if (cores.size() > destroyables.size() && cores.size() > 0) { - this.name = - cores.iterator().next().getModeChangeMessage(this.mode.getMaterialData().getItemType()); - } else if (destroyables.size() >= cores.size() && destroyables.size() > 0) { - this.name = - destroyables - .iterator() - .next() - .getModeChangeMessage(this.mode.getMaterialData().getItemType()); - } else { - this.name = "Unknown Mode"; - } + int affectedCores = 0; + for (Core core : wins.getGoals(Core.class).values()) { + if (!core.isAffectedBy(mode)) continue; + if (++affectedCores > affectedDestroyables) return core; } + return lastDestroyable; } public boolean isVisible() { diff --git a/core/src/main/java/tc/oc/pgm/modes/ObjectiveModesMatchModule.java b/core/src/main/java/tc/oc/pgm/modes/ObjectiveModesMatchModule.java index 5f2769deba..0a786c6b6b 100644 --- a/core/src/main/java/tc/oc/pgm/modes/ObjectiveModesMatchModule.java +++ b/core/src/main/java/tc/oc/pgm/modes/ObjectiveModesMatchModule.java @@ -117,7 +117,16 @@ public ModeChangeCountdown getCountdown(Mode mode) { .orElse(null); } - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + @EventHandler(priority = EventPriority.HIGHEST) + public void onObjectiveModeAction(ObjectiveModeChangeEvent event) { + var action = event.getMode().getAction(); + if (action != null) { + action.trigger(event.getMatch()); + event.setVisible(true); + } + } + + @EventHandler(priority = EventPriority.MONITOR) public void onObjectiveModeChange(ObjectiveModeChangeEvent event) { if (event.isVisible()) { Component broadcast = text() diff --git a/core/src/main/java/tc/oc/pgm/modes/ObjectiveModesModule.java b/core/src/main/java/tc/oc/pgm/modes/ObjectiveModesModule.java index cbd0b6d572..7f1992cba7 100644 --- a/core/src/main/java/tc/oc/pgm/modes/ObjectiveModesModule.java +++ b/core/src/main/java/tc/oc/pgm/modes/ObjectiveModesModule.java @@ -6,11 +6,9 @@ import java.time.Duration; import java.util.Collection; import java.util.logging.Logger; -import org.bukkit.ChatColor; import org.jdom2.Document; import org.jdom2.Element; import org.jetbrains.annotations.Nullable; -import tc.oc.pgm.api.filter.Filter; import tc.oc.pgm.api.map.MapModule; import tc.oc.pgm.api.map.factory.MapFactory; import tc.oc.pgm.api.map.factory.MapModuleFactory; @@ -18,10 +16,8 @@ import tc.oc.pgm.api.match.MatchModule; import tc.oc.pgm.features.FeatureDefinitionContext; import tc.oc.pgm.filters.FilterMatchModule; -import tc.oc.pgm.filters.parse.DynamicFilterValidation; import tc.oc.pgm.goals.GoalMatchModule; import tc.oc.pgm.util.material.BlockMaterialData; -import tc.oc.pgm.util.text.TextParser; import tc.oc.pgm.util.xml.InvalidXMLException; import tc.oc.pgm.util.xml.Node; import tc.oc.pgm.util.xml.XMLUtils; @@ -59,51 +55,44 @@ public ObjectiveModesModule parse(MapFactory factory, Logger logger, Document do return null; } + var parser = factory.getParser(); + ImmutableList.Builder parsedModes = ImmutableList.builder(); if (doc.getRootElement().getChild("modes") == null) { return null; } - for (Element modeEl : XMLUtils.flattenElements(doc.getRootElement(), "modes", "mode")) { - String id = modeEl.getAttributeValue("id"); - if (modeEl.getAttributeValue("after") == null) { - throw new InvalidXMLException("No period has been specified", modeEl); - } - - BlockMaterialData material = - XMLUtils.parseBlockMaterialData(Node.fromRequiredAttr(modeEl, "material")); - Duration after = TextParser.parseDuration(modeEl.getAttributeValue("after")); - Filter filter = - factory.getFilters().parseProperty(modeEl, "filter", DynamicFilterValidation.MATCH); - String name = modeEl.getAttributeValue("name"); - if (name != null) { - name = ChatColor.translateAlternateColorCodes('`', name); - } - - String showBeforeRaw = modeEl.getAttributeValue("show-before"); - Duration showBefore = - showBeforeRaw != null ? TextParser.parseDuration(showBeforeRaw) : DEFAULT_SHOW_BEFORE; - - // Legacy - boolean legacyShowBossBar = XMLUtils.parseBoolean(modeEl.getAttribute("boss-bar"), true); - if (!legacyShowBossBar) showBefore = Duration.ZERO; + for (Element el : XMLUtils.flattenElements(doc.getRootElement(), "modes", "mode")) { + var name = parser.string(el, "name").colored().orNull(); + var after = parser.duration(el, "after").required(); + var showBefore = parser.duration(el, "show-before").optional(DEFAULT_SHOW_BEFORE); + if (!parser.parseBool(el, "boss-bar").orTrue()) showBefore = Duration.ZERO; + var filter = parser.filter(el, "filter").dynamic(Match.class).orNull(); + + var material = XMLUtils.parseBlockMaterialData(Node.fromAttr(el, "material")); + var action = parser.action(Match.class, el, "action").orNull(); + + if (material == null && (name == null || action == null)) + throw new InvalidXMLException("Expected either 'material', or 'name' & 'action'", el); // Autogenerate a unique id, required for /mode start - if (id == null) { - String legacyName = name != null ? name : ModeUtils.formatMaterial(material); - id = makeUniqueId(legacyName, factory.getFeatures()); - } + String id = parser + .string(el, "id") + .optional(() -> makeUniqueId(name, material, factory.getFeatures())); - Mode mode = new Mode(id, material, after, filter, name, showBefore); + Mode mode = new Mode(id, name, after, showBefore, filter, material, action); parsedModes.add(mode); - factory.getFeatures().addFeature(modeEl, mode); + factory.getFeatures().addFeature(el, mode); } return new ObjectiveModesModule(parsedModes.build()); } - private String makeUniqueId(String name, FeatureDefinitionContext features) { + private String makeUniqueId( + String name, BlockMaterialData material, FeatureDefinitionContext features) { + if (name == null) name = ModeUtils.formatMaterial(material); + String baseId = "mode-" + Mode.makeId(name); if (!features.contains(baseId)) return baseId; diff --git a/core/src/main/java/tc/oc/pgm/util/xml/XMLFluentParser.java b/core/src/main/java/tc/oc/pgm/util/xml/XMLFluentParser.java index e0bb0f6dec..9c741a1213 100644 --- a/core/src/main/java/tc/oc/pgm/util/xml/XMLFluentParser.java +++ b/core/src/main/java/tc/oc/pgm/util/xml/XMLFluentParser.java @@ -1,5 +1,6 @@ package tc.oc.pgm.util.xml; +import java.time.Duration; import org.bukkit.util.BlockVector; import org.bukkit.util.Vector; import org.jdom2.Element; @@ -24,6 +25,7 @@ import tc.oc.pgm.util.xml.parsers.PrimitiveBuilder; import tc.oc.pgm.util.xml.parsers.ReferenceBuilder; import tc.oc.pgm.util.xml.parsers.RegionBuilder; +import tc.oc.pgm.util.xml.parsers.StringBuilder; import tc.oc.pgm.util.xml.parsers.VariableBuilder; import tc.oc.pgm.variables.VariablesModule; @@ -66,11 +68,15 @@ protected T parse(String text) throws TextException { }; } - public PrimitiveBuilder.Generic string(Element el, String... prop) { + public StringBuilder string(Element el, String... prop) { + return new StringBuilder(el, prop); + } + + public PrimitiveBuilder.Generic duration(Element el, String... prop) { return new PrimitiveBuilder.Generic<>(el, prop) { @Override - protected String parse(String text) throws TextException { - return text; + protected Duration parse(String text) throws TextException { + return TextParser.parseDuration(text); } }; } diff --git a/core/src/main/java/tc/oc/pgm/util/xml/parsers/StringBuilder.java b/core/src/main/java/tc/oc/pgm/util/xml/parsers/StringBuilder.java new file mode 100644 index 0000000000..1827f2b3ec --- /dev/null +++ b/core/src/main/java/tc/oc/pgm/util/xml/parsers/StringBuilder.java @@ -0,0 +1,29 @@ +package tc.oc.pgm.util.xml.parsers; + +import org.bukkit.ChatColor; +import org.jdom2.Element; +import tc.oc.pgm.util.text.TextException; + +public class StringBuilder extends PrimitiveBuilder { + private boolean colored; + + public StringBuilder(Element el, String... props) { + super(el, props); + } + + public StringBuilder colored() { + this.colored = true; + return this; + } + + @Override + protected String parse(String text) throws TextException { + if (colored) text = ChatColor.translateAlternateColorCodes('`', text); + return text; + } + + @Override + protected StringBuilder getThis() { + return this; + } +}