ProjectAres/PGM/src/main/java/tc/oc/pgm/timelimit/TimeLimit.java

106 lines
3.1 KiB
Java

package tc.oc.pgm.timelimit;
import javax.annotation.Nullable;
import java.time.Duration;
import tc.oc.commons.core.util.Comparables;
import tc.oc.pgm.match.Match;
import tc.oc.pgm.victory.AbstractVictoryCondition;
import tc.oc.pgm.victory.DefaultResult;
import tc.oc.pgm.victory.MatchResult;
import tc.oc.pgm.victory.VictoryCondition;
import tc.oc.pgm.victory.VictoryMatchModule;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
/**
* A time limit configuration in the context of a specific match.
*
* It can be created from a {@link TimeLimitDefinition}, or from a manually entered command.
* In either case, it has the same immutable parameters as a definition.
*
* This class is responsible for creating and starting {@link TimeLimitCountdown}s.
* It tracks the current countdown, if any, and whether it has completed.
* It uses this state to implement {@link VictoryCondition}.
*
* A single {@link TimeLimit} can potentially be reused, if its countdown is cancelled.
*
* @see TimeLimitDefinition
* @see TimeLimitCountdown
*/
public class TimeLimit extends AbstractVictoryCondition {
public static final Duration MAX_DURATION = Duration.ofDays(99999);
private final Match match;
private final Duration duration;
private final boolean show;
private final DefaultResult defaultResult = new DefaultResult();
private @Nullable TimeLimitCountdown countdown;
private boolean finished;
public TimeLimit(Match match, Duration duration, MatchResult result, boolean show) {
super(Priority.TIME_LIMIT, result);
checkArgument(Comparables.lessOrEqual(duration, MAX_DURATION));
this.match = checkNotNull(match);
this.duration = checkNotNull(duration);
this.show = show;
}
public TimeLimit(Match match, TimeLimitDefinition definition) {
this(match, definition.duration(), definition.result(), definition.show());
}
public Duration getDuration() {
return duration;
}
public boolean getShow() {
return show;
}
public void start() {
checkState(!finished);
checkState(countdown == null);
countdown = new TimeLimitCountdown(match, this);
match.countdowns().start(countdown, duration);
}
void onCancel(boolean manual) {
if(!finished) {
countdown = null;
if(manual) {
match.needMatchModule(TimeLimitMatchModule.class).setTimeLimit(null);
}
}
}
void onEnd() {
finished = true;
match.needMatchModule(VictoryMatchModule.class).invalidateAndCheckEnd();
}
public @Nullable Duration remaining() {
return countdown == null ? null : countdown.remaining();
}
@Override
public boolean isCompleted() {
return finished;
}
@Override
public MatchResult result() {
return finished ? super.result() : defaultResult;
}
@Override
public String toString() {
return getClass().getSimpleName() + "{" + duration + " result=" + result() + "}";
}
}