Allow controllables to define a rollback to neutral rate

This commit is contained in:
Electroid 2017-12-30 14:56:46 -07:00
parent aca0c3845a
commit 6b381897d7
5 changed files with 58 additions and 24 deletions

View File

@ -97,6 +97,26 @@ public abstract class ControllableGoal<T extends ControllableGoalDefinition> ext
}
}
/**
* Get an approximate region of where the capture/control region of the goal is.
*/
public abstract Region region();
/**
* Should the controllable goal track the given player at the given location.
*/
protected abstract boolean tracking(MatchPlayer player, Location location);
/**
* Display progress of the controllable goal in the physical world.
*/
protected abstract void displayProgress(Competitor controlling, Competitor capturing, double progress);
/**
* Reset progress of the controllable goal in the physical world to a new owning team.
*/
protected abstract void displaySet(Competitor owner);
/**
* The team that owns (is receiving points from) this goal,
* or null if the goal is unowned.
@ -300,7 +320,7 @@ public abstract class ControllableGoal<T extends ControllableGoalDefinition> ext
match.callEvent(new GoalCompleteEvent(this, owner != null, c -> c.equals(oldOwner), c -> c.equals(owner)));
match.module(ScoreMatchModule.class).ifPresent(scores -> {
if(oldOwner != null) {
scores.incrementScore(owner, definition.pointsOwned() * -1);
scores.incrementScore(oldOwner, definition.pointsOwned() * -1);
}
if(owner != null) {
scores.incrementScore(owner, definition.pointsOwned());
@ -362,6 +382,14 @@ public abstract class ControllableGoal<T extends ControllableGoalDefinition> ext
// Point is not being captured and there is a dominant team that is not the owner, so they start capturing
capturer = dominator;
dominate(dominator, duration);
} else if(owner != null && definition.neutralRate() > 0) {
// Point has an owner and there are no players nearby, so it rolls back to neutral,
// even if the goal explicitly states it has no neutral state
if(players.stream().noneMatch(player -> canCapture(player.getCompetitor()))) {
rollback(duration);
} else {
recover(duration, dominator);
}
}
}
@ -418,6 +446,18 @@ public abstract class ControllableGoal<T extends ControllableGoalDefinition> ext
}
}
/**
* The goal has no player controlling it and will revert to a neutral state.
*/
private void rollback(Duration duration) {
duration = TimeUtils.multiply(duration, 1.0 / definition.neutralRate());
duration = addCaptureTime(duration);
if(duration != null) {
// If uncapture is complete, recurse with the dominant team's remaining time
owner = null;
}
}
/**
* Increase the base amount of capture time by a certain amount.
*/
@ -446,11 +486,6 @@ public abstract class ControllableGoal<T extends ControllableGoalDefinition> ext
}
}
/**
* Get an approximate region of where the capture/control region of the goal is.
*/
public abstract Region region();
/**
* Reset and show progress of the controllable goal in the physical world for the first time.
*/
@ -459,16 +494,6 @@ public abstract class ControllableGoal<T extends ControllableGoalDefinition> ext
displayProgress(owner, capturer, getCompletion());
}
/**
* Display progress of the controllable goal in the physical world.
*/
protected abstract void displayProgress(Competitor controlling, Competitor capturing, double progress);
/**
* Reset progress of the controllable goal in the physical world to a new owning team.
*/
protected abstract void displaySet(Competitor owner);
/**
* Update the tracked players that are on the controllable goal
*/
@ -482,11 +507,6 @@ public abstract class ControllableGoal<T extends ControllableGoalDefinition> ext
}
}
/**
* Should the controllable goal track the given player at the given location.
*/
protected abstract boolean tracking(MatchPlayer player, Location location);
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerMove(CoarsePlayerMoveEvent event) {
updatePlayers(event.getPlayer(), event.getTo());

View File

@ -40,6 +40,11 @@ public interface ControllableGoalDefinition extends GoalDefinition, GamemodeFeat
*/
double recoveryRate();
/**
* Relative rate at which progress will transition to neutral even if a neutral state if false.
*/
double neutralRate();
/**
* The team that initially controls the goal before the match starts.
*/

View File

@ -19,6 +19,7 @@ public abstract class ControllableGoalDefinitionImpl extends GoalDefinitionImpl
private final double multiplierTime;
private final double recoveryRate;
private final double decayRate;
private final double neutralRate;
private final Optional<TeamFactory> initialOwner;
private final CaptureCondition captureCondition;
private final boolean neutralState;
@ -37,6 +38,7 @@ public abstract class ControllableGoalDefinitionImpl extends GoalDefinitionImpl
double multiplierTime,
double recoveryRate,
double decayRate,
double neutralRate,
Optional<TeamFactory> initialOwner,
CaptureCondition captureCondition,
boolean neutralState,
@ -52,6 +54,7 @@ public abstract class ControllableGoalDefinitionImpl extends GoalDefinitionImpl
this.multiplierTime = multiplierTime;
this.recoveryRate = recoveryRate;
this.decayRate = decayRate;
this.neutralRate = neutralRate;
this.initialOwner = initialOwner;
this.captureCondition = captureCondition;
this.neutralState = neutralState;
@ -102,6 +105,11 @@ public abstract class ControllableGoalDefinitionImpl extends GoalDefinitionImpl
return recoveryRate;
}
@Override
public double neutralRate() {
return neutralRate;
}
@Override
public Optional<TeamFactory> initialOwner() {
return initialOwner;

View File

@ -39,12 +39,12 @@ class ControlPointDefinitionImpl extends ControllableGoalDefinitionImpl implemen
private final Region controllerDisplayRegion;
private final Filter visualMaterials;
public ControlPointDefinitionImpl(String name, @Nullable Boolean required, boolean visible, Filter captureFilter, Filter defendFilter, Duration captureTime, double multiplierTime, double recoveryRate, double decayRate, Optional<TeamFactory> initialOwner, CaptureCondition captureCondition, boolean neutralState, boolean permanent, float pointsOwned, float pointsPerSecond, float pointsGrowth, boolean showProgress,
public ControlPointDefinitionImpl(String name, @Nullable Boolean required, boolean visible, Filter captureFilter, Filter defendFilter, Duration captureTime, double multiplierTime, double recoveryRate, double decayRate, double neutralRate, Optional<TeamFactory> initialOwner, CaptureCondition captureCondition, boolean neutralState, boolean permanent, float pointsOwned, float pointsPerSecond, float pointsGrowth, boolean showProgress,
Region captureRegion,
Region progressDisplayRegion,
Region controllerDisplayRegion,
Filter visualMaterials) {
super(name, required, visible, captureFilter, defendFilter, captureTime, multiplierTime, recoveryRate, decayRate, initialOwner, captureCondition, neutralState, permanent, pointsOwned, pointsPerSecond, pointsGrowth, showProgress);
super(name, required, visible, captureFilter, defendFilter, captureTime, multiplierTime, recoveryRate, decayRate, neutralRate, initialOwner, captureCondition, neutralState, permanent, pointsOwned, pointsPerSecond, pointsGrowth, showProgress);
this.captureRegion = captureRegion;
this.progressDisplayRegion = progressDisplayRegion;
this.controllerDisplayRegion = controllerDisplayRegion;

View File

@ -81,6 +81,7 @@ public final class ControlPointParser implements FeatureDefinitionParser<Control
decayRate = incremental ? 0D : Double.POSITIVE_INFINITY;
}
boolean neutralState = XMLUtils.parseBoolean(elControlPoint.getAttribute("neutral-state"), koth);
double neutralRate = XMLUtils.parseNumber(Node.fromAttr(elControlPoint, "rollback"), Double.class, Range.atLeast(0D), 0.0);
boolean permanent = XMLUtils.parseBoolean(elControlPoint.getAttribute("permanent"), false);
float pointsOwned = XMLUtils.parseNumber(elControlPoint.getAttribute("owner-points"), Float.class, 0f);
float pointsPerSecond = XMLUtils.parseNumber(elControlPoint.getAttribute("points"), Float.class, 1f);
@ -95,7 +96,7 @@ public final class ControlPointParser implements FeatureDefinitionParser<Control
ControlPointDefinition.CaptureCondition.EXCLUSIVE);
return new ControlPointDefinitionImpl(
name, required, visible, captureFilter, playerFilter,
timeToCapture, timeMultiplier, recoveryRate, decayRate,
timeToCapture, timeMultiplier, recoveryRate, decayRate, neutralRate,
Optional.ofNullable(initialOwner), captureCondition, neutralState, permanent,
pointsOwned, pointsPerSecond, pointsGrowth, showProgress,
captureRegion, progressDisplayRegion, ownerDisplayRegion, visualMaterials