Skip to content

Commit

Permalink
Fix mode start command
Browse files Browse the repository at this point in the history
Signed-off-by: Pablete1234 <[email protected]>
  • Loading branch information
Pablete1234 committed Nov 19, 2022
1 parent e0a41a6 commit 78136e9
Show file tree
Hide file tree
Showing 15 changed files with 294 additions and 217 deletions.
158 changes: 63 additions & 95 deletions core/src/main/java/tc/oc/pgm/command/ModeCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.apache.commons.lang.WordUtils;
import org.jetbrains.annotations.NotNull;
import tc.oc.pgm.api.Permissions;
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.countdowns.CountdownContext;
import tc.oc.pgm.modes.Mode;
import tc.oc.pgm.modes.ModeChangeCountdown;
import tc.oc.pgm.modes.ModesPaginatedResult;
import tc.oc.pgm.modes.ObjectiveModesMatchModule;
Expand All @@ -34,43 +36,35 @@ public final class ModeCommand {
public void next(Audience audience, Match match) {
ObjectiveModesMatchModule modes = getModes(match);

if (modes == null) {
throwNoResults();
List<ModeChangeCountdown> countdowns = modes.getActiveCountdowns();

if (countdowns.isEmpty()) throwNoResults();

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));
} 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)));
} else {
List<ModeChangeCountdown> countdowns = modes.getActiveCountdowns();

if (countdowns.isEmpty()) {
throwNoResults();
} else {
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));
} 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)));
} else {
throwNoResults();
}

audience.sendMessage(builder.build());
}
throwNoResults();
}

audience.sendMessage(builder.build());
}

@CommandMethod("list|page [page]")
Expand All @@ -79,7 +73,20 @@ public void list(
Audience audience,
Match match,
@Argument(value = "page", defaultValue = "1") @Range(min = "1") int page) {
showList(page, audience, getModes(match));
ObjectiveModesMatchModule modes = getModes(match);
List<ModeChangeCountdown> 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);

new ModesPaginatedResult(header, resultsPerPage, modes).display(audience, modeList, page);
}

@CommandMethod("push <time>")
Expand All @@ -88,13 +95,7 @@ public void list(
public void push(Audience audience, Match match, @Argument("time") Duration duration) {
ObjectiveModesMatchModule modes = getModes(match);

if (!match.isRunning()) {
throwMatchNotStarted();
}

if (modes == null) {
throwNoResults();
}
if (!match.isRunning()) throwMatchNotStarted();

CountdownContext countdowns = modes.getCountdown();
List<ModeChangeCountdown> sortedCountdowns = modes.getSortedCountdowns(false);
Expand Down Expand Up @@ -125,72 +126,39 @@ public void push(Audience audience, Match match, @Argument("time") Duration dura
audience.sendMessage(builder);
}

@CommandMethod("start")
@CommandMethod("start <mode> [time]")
@CommandDescription("Starts an objective mode")
@CommandPermission(Permissions.GAMEPLAY)
public void start(Audience audience, Match match, int modeNumber, Duration duration) {
ObjectiveModesMatchModule modes = getModes(match);
public void start(
Audience audience,
Match match,
@Argument("mode") Mode mode,
@Argument(value = "time", defaultValue = "0s") Duration time) {
if (!match.isRunning()) throwMatchNotStarted();

if (!match.isRunning()) {
throwMatchNotStarted();
}
if (modes == null) {
throwNoResults();
}
modeNumber--;
CountdownContext countdowns = modes.getCountdown();
List<ModeChangeCountdown> sortedCountdowns = modes.getSortedCountdowns(true);
ModeChangeCountdown selectedMode;
ObjectiveModesMatchModule modes = getModes(match);
if (time.isNegative()) throwInvalidNumber(time.toString());

if (sortedCountdowns.toArray().length < modeNumber) {
throwInvalidNumber(Integer.toString(modeNumber));
}
if (duration.isNegative()) {
throwInvalidNumber(duration.toString());
}
selectedMode = sortedCountdowns.get(modeNumber);
countdowns.cancel(selectedMode);
countdowns.start(selectedMode, duration);
CountdownContext context = modes.getCountdown();
ModeChangeCountdown countdown = modes.getCountdown(mode);

String modeName;
if (selectedMode.getMode().getName() != null) {
modeName = selectedMode.getMode().getName();
} else {
modeName = selectedMode.getMode().getPreformattedMaterialName();
}
context.cancel(countdown);
context.start(countdown, time);

TextComponent.Builder builder =
text()
.append(
translatable("command.selectedModePushed", text(modeName))
translatable("command.selectedModePushed", mode.getComponentName())
.color(NamedTextColor.GOLD)
.append(space()));
builder.append(clock(Math.abs(duration.getSeconds())).color(NamedTextColor.AQUA));
builder.append(clock(Math.abs(time.getSeconds())).color(NamedTextColor.AQUA));
audience.sendMessage(builder);
}

private static void showList(int page, Audience audience, ObjectiveModesMatchModule modes) {
if (modes == null) {
throwNoResults();
} else {
List<ModeChangeCountdown> 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);

new ModesPaginatedResult(header, resultsPerPage, modes).display(audience, modeList, page);
}
}

private static ObjectiveModesMatchModule getModes(Match match) {
return match.getModule(ObjectiveModesMatchModule.class);
private static @NotNull ObjectiveModesMatchModule getModes(Match match) {
return match
.moduleOptional(ObjectiveModesMatchModule.class)
.orElseThrow(() -> exception("command.moduleNotFound", text("modes")));
}

private static void throwNoResults() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package tc.oc.pgm.command.parsers;

import static cloud.commandframework.arguments.parser.ArgumentParseResult.failure;
import static net.kyori.adventure.text.Component.text;
import static tc.oc.pgm.util.text.TextException.exception;
import static tc.oc.pgm.util.text.TextException.invalidFormat;
import static tc.oc.pgm.util.text.TextException.playerOnly;

import cloud.commandframework.arguments.parser.ArgumentParseResult;
import cloud.commandframework.arguments.parser.ParserParameters;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.paper.PaperCommandManager;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.command.CommandSender;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull;
import tc.oc.pgm.api.PGM;
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.api.match.MatchModule;
import tc.oc.pgm.command.util.CommandKeys;
import tc.oc.pgm.util.LiquidMetal;
import tc.oc.pgm.util.StringUtils;
import tc.oc.pgm.util.text.TextException;

/**
* Generic parser for match-time objects, eg: teams, classes, modes, etc. Automatically handles
* getting the module, and failing if module isn't enabled.
*
* @param <T> The object-type to parse
* @param <M> The match module that provides it
*/
public abstract class MatchObjectParser<T, M extends MatchModule>
extends StringLikeParser<CommandSender, T> {

private final Class<T> objType;
private final Class<M> moduleType;
private final String moduleName;

public MatchObjectParser(
PaperCommandManager<CommandSender> manager,
ParserParameters options,
Class<T> objType,
Class<M> moduleType,
String moduleName) {
super(manager, options);
this.objType = objType;
this.moduleType = moduleType;
this.moduleName = moduleName;
}

@Override
public ArgumentParseResult<T> parse(
@NotNull CommandContext<CommandSender> context, @NotNull String text) {
Match match = PGM.get().getMatchManager().getMatch(context.getSender());
if (match == null) return failure(playerOnly());

M module = match.getModule(moduleType);
if (module == null) return failure(moduleNotFound());

T obj = StringUtils.bestFuzzyMatch(text, objects(module), this::getName);
if (obj == null) return failure(invalidFormat(text, objType));

return ArgumentParseResult.success(obj);
}

@Override
public @NonNull List<@NonNull String> suggestions(
@NonNull CommandContext<CommandSender> context, @NonNull String input) {
Match match = PGM.get().getMatchManager().getMatch(context.getSender());
if (match == null) return Collections.emptyList();

List<String> inputQueue = context.get(CommandKeys.INPUT_QUEUE);
String text = StringUtils.getText(inputQueue);
String mustKeep = StringUtils.getMustKeepText(inputQueue);

return match.moduleOptional(moduleType).map(this::objects).orElse(Collections.emptySet())
.stream()
.map(this::getName)
.filter(name -> LiquidMetal.match(name, text))
.map(name -> StringUtils.getSuggestion(name, mustKeep))
.collect(Collectors.toList());
}

protected abstract Collection<T> objects(M module);

protected abstract String getName(T obj);

protected TextException moduleNotFound() {
return exception("command.moduleNotFound", text(moduleName));
}
}
25 changes: 25 additions & 0 deletions core/src/main/java/tc/oc/pgm/command/parsers/ModeParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package tc.oc.pgm.command.parsers;

import cloud.commandframework.arguments.parser.ParserParameters;
import cloud.commandframework.paper.PaperCommandManager;
import java.util.Collection;
import org.bukkit.command.CommandSender;
import tc.oc.pgm.modes.Mode;
import tc.oc.pgm.modes.ObjectiveModesMatchModule;

public class ModeParser extends MatchObjectParser<Mode, ObjectiveModesMatchModule> {

public ModeParser(PaperCommandManager<CommandSender> manager, ParserParameters options) {
super(manager, options, Mode.class, ObjectiveModesMatchModule.class, "modes");
}

@Override
protected Collection<Mode> objects(ObjectiveModesMatchModule module) {
return module.getModes();
}

@Override
protected String getName(Mode mode) {
return mode.getId();
}
}
14 changes: 8 additions & 6 deletions core/src/main/java/tc/oc/pgm/command/parsers/PartyParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.paper.PaperCommandManager;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.bukkit.command.CommandSender;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull;
Expand All @@ -19,10 +17,14 @@
import tc.oc.pgm.api.party.Party;
import tc.oc.pgm.util.LiquidMetal;

/** Parses parties, ie: teams, plus the obs keyword for the observer party */
public final class PartyParser extends StringLikeParser<CommandSender, Party> {

private final TeamParser teamParser;

public PartyParser(PaperCommandManager<CommandSender> manager, ParserParameters options) {
super(manager, options);
this.teamParser = new TeamParser(manager, options);
}

@Override
Expand All @@ -33,14 +35,14 @@ public ArgumentParseResult<Party> parse(

if (text.equalsIgnoreCase("obs")) return success(match.getDefaultParty());

return TeamParser.getTeam(match, text).mapParsedValue(team -> team);
return teamParser.parse(context, text).mapParsedValue(team -> team);
}

@Override
public @NonNull List<@NonNull String> suggestions(
@NonNull CommandContext<CommandSender> context, @NonNull String input) {
return Stream.concat(Stream.of("obs"), TeamParser.getTeams(context.getSender()))
.filter(str -> LiquidMetal.match(str, input))
.collect(Collectors.toList());
List<String> teams = teamParser.suggestions(context, input);
if (LiquidMetal.match("obs", input)) teams.add("obs");
return teams;
}
}
Loading

0 comments on commit 78136e9

Please sign in to comment.