Skip to content

Commit

Permalink
Merge branch 'PGMDev:dev' into spread-team-spawns
Browse files Browse the repository at this point in the history
  • Loading branch information
calcastor authored Jul 16, 2022
2 parents 35bce05 + 62f23ae commit 4101176
Show file tree
Hide file tree
Showing 23 changed files with 447 additions and 230 deletions.
5 changes: 1 addition & 4 deletions core/src/main/java/tc/oc/pgm/api/map/MapOrder.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,10 @@ public interface MapOrder {
* Forces a specific map to be played next. The underlying {@link MapOrder} may ignore this, but
* it is recommended not to.
*
* @param map The map to set next
* @param map The map to set next, null to reset
*/
void setNextMap(MapInfo map);

/** Removes any map that was set manually, returning the server to what was previously chosen. */
void resetNextMap();

/**
* Returns the duration used for cycles in {@link CycleMatchModule}.
*
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/tc/oc/pgm/command/MapCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
import tc.oc.pgm.api.map.MapLibrary;
import tc.oc.pgm.api.map.MapTag;
import tc.oc.pgm.api.map.Phase;
import tc.oc.pgm.rotation.MapPool;
import tc.oc.pgm.rotation.MapPoolManager;
import tc.oc.pgm.rotation.pools.MapPool;
import tc.oc.pgm.util.Audience;
import tc.oc.pgm.util.PrettyPaginatedComponentResults;
import tc.oc.pgm.util.named.MapNameStyle;
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/tc/oc/pgm/command/MapOrderCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void setNext(
if (reset) {
if (mapOrder.getNextMap() != null) {
Component mapName = mapOrder.getNextMap().getStyledName(MapNameStyle.COLOR);
mapOrder.resetNextMap();
mapOrder.setNextMap(null);
ChatDispatcher.broadcastAdminChatMessage(
translatable(
"map.setNext.revert",
Expand Down
16 changes: 8 additions & 8 deletions core/src/main/java/tc/oc/pgm/command/MapPoolCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.api.player.MatchPlayer;
import tc.oc.pgm.cycle.CycleCountdown;
import tc.oc.pgm.rotation.MapPoll;
import tc.oc.pgm.rotation.MapPool;
import tc.oc.pgm.rotation.MapPoolManager;
import tc.oc.pgm.rotation.Rotation;
import tc.oc.pgm.rotation.VotingPool;
import tc.oc.pgm.rotation.pools.MapPool;
import tc.oc.pgm.rotation.pools.Rotation;
import tc.oc.pgm.rotation.pools.VotingPool;
import tc.oc.pgm.rotation.vote.MapPoll;
import tc.oc.pgm.util.Audience;
import tc.oc.pgm.util.PrettyPaginatedComponentResults;
import tc.oc.pgm.util.named.MapNameStyle;
Expand All @@ -43,7 +43,7 @@ public final class MapPoolCommand {
private static final DecimalFormat SCORE_FORMAT = new DecimalFormat("00.00%");

@Command(
aliases = {"pool", "rotation", "rot"},
aliases = {"pool"},
desc = "List the maps in the map pool",
usage = "[page] [-p pool] [-s scores] [-c chance of vote]")
public static void pool(
Expand Down Expand Up @@ -96,7 +96,7 @@ public static void pool(
if (chance && votes != null) {
double maxWeight = 0, currWeight;
for (MapInfo map : votes.getMaps()) {
chances.put(map, currWeight = MapPoll.getWeight(votes.getMapScore(map)));
chances.put(map, currWeight = votes.mapPicker.getWeight(null, map, votes.getMapScore(map)));
maxWeight += currWeight;
}
double finalMaxWeight = maxWeight;
Expand Down Expand Up @@ -127,7 +127,7 @@ public Component format(MapInfo map, int index) {
}

@Command(
aliases = {"pools", "rotations", "rots"},
aliases = {"pools"},
desc = "List all the map pools",
flags = "d")
public static void pools(
Expand Down Expand Up @@ -204,7 +204,7 @@ public Component format(MapPool mapPool, int index) {
}

@Command(
aliases = {"setpool", "setrot"},
aliases = {"setpool"},
desc = "Change the map pool",
usage = "[pool name] -r (revert to dynamic) -t (time limit for map pool) -m (match # limit)",
flags = "rtm",
Expand Down
42 changes: 22 additions & 20 deletions core/src/main/java/tc/oc/pgm/command/VotingCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.listeners.ChatDispatcher;
import tc.oc.pgm.rotation.MapPoolManager;
import tc.oc.pgm.rotation.VotingPool;
import tc.oc.pgm.rotation.pools.VotingPool;
import tc.oc.pgm.rotation.vote.MapVotePicker;
import tc.oc.pgm.rotation.vote.VotePoolOptions;
import tc.oc.pgm.util.Audience;
import tc.oc.pgm.util.UsernameFormatUtils;
import tc.oc.pgm.util.named.MapNameStyle;
Expand All @@ -44,7 +46,7 @@ public void addMap(
MapOrder mapOrder,
Match match)
throws CommandException {
VotingPool vote = getVotingPool(sender, mapOrder);
VotePoolOptions vote = getVoteOptions(sender, mapOrder);

Component addMessage =
translatable(
Expand All @@ -53,12 +55,12 @@ public void addMap(
UsernameFormatUtils.formatStaffName(sender, match),
map.getStyledName(MapNameStyle.COLOR));

if (vote.getOptions().isAdded(map)) {
if (vote.isAdded(map)) {
viewer.sendWarning(addMessage);
return;
}

if (vote.getOptions().addVote(map)) {
if (vote.addVote(map)) {
ChatDispatcher.broadcastAdminChatMessage(addMessage, match);
} else {
viewer.sendWarning(translatable("vote.limit", NamedTextColor.RED));
Expand All @@ -77,8 +79,8 @@ public void removeMap(
MapOrder mapOrder,
Match match)
throws CommandException {
VotingPool vote = getVotingPool(sender, mapOrder);
if (vote.getOptions().removeMap(map)) {
VotePoolOptions vote = getVoteOptions(sender, mapOrder);
if (vote.removeMap(map)) {
ChatDispatcher.broadcastAdminChatMessage(
translatable(
"vote.remove",
Expand All @@ -97,10 +99,10 @@ public void removeMap(
perms = Permissions.SETNEXT)
public void mode(Audience viewer, CommandSender sender, MapOrder mapOrder, Match match)
throws CommandException {
VotingPool vote = getVotingPool(sender, mapOrder);
VotePoolOptions vote = getVoteOptions(sender, mapOrder);
Component voteModeName =
translatable(
vote.getOptions().toggleMode() ? "vote.mode.replace" : "vote.mode.create",
vote.toggleMode() ? "vote.mode.replace" : "vote.mode.create",
NamedTextColor.LIGHT_PURPLE);
ChatDispatcher.broadcastAdminChatMessage(
translatable(
Expand All @@ -117,10 +119,10 @@ public void mode(Audience viewer, CommandSender sender, MapOrder mapOrder, Match
perms = Permissions.SETNEXT)
public void clearMaps(Audience viewer, CommandSender sender, Match match, MapOrder mapOrder)
throws CommandException {
VotingPool vote = getVotingPool(sender, mapOrder);
VotePoolOptions vote = getVoteOptions(sender, mapOrder);

List<Component> maps =
vote.getOptions().getCustomVoteMaps().stream()
vote.getCustomVoteMaps().stream()
.map(mi -> mi.getStyledName(MapNameStyle.COLOR))
.collect(Collectors.toList());
Component clearedMsg =
Expand All @@ -130,7 +132,7 @@ public void clearMaps(Audience viewer, CommandSender sender, Match match, MapOrd
UsernameFormatUtils.formatStaffName(sender, match),
TextFormatter.list(maps, NamedTextColor.GRAY));

vote.getOptions().clear();
vote.clear();

if (maps.isEmpty()) {
viewer.sendWarning(translatable("vote.noMapsFound"));
Expand All @@ -144,17 +146,17 @@ public void clearMaps(Audience viewer, CommandSender sender, Match match, MapOrd
desc = "View a list of maps that have been selected for the next vote")
public void listMaps(CommandSender sender, Audience viewer, MapOrder mapOrder)
throws CommandException {
VotingPool vote = getVotingPool(sender, mapOrder);
VotePoolOptions vote = getVoteOptions(sender, mapOrder);

int currentMaps = vote.getOptions().getCustomVoteMaps().size();
int currentMaps = vote.getCustomVoteMaps().size();
TextColor listNumColor =
currentMaps >= VotingPool.MIN_CUSTOM_VOTE_OPTIONS
? currentMaps < VotingPool.MAX_VOTE_OPTIONS
currentMaps >= MapVotePicker.MIN_CUSTOM_VOTE_OPTIONS
? currentMaps < MapVotePicker.MAX_VOTE_OPTIONS
? NamedTextColor.GREEN
: NamedTextColor.YELLOW
: NamedTextColor.RED;

String modeKey = vote.getOptions().isReplace() ? "replace" : "create";
String modeKey = vote.isReplace() ? "replace" : "create";
Component mode =
translatable(String.format("vote.mode.%s", modeKey), NamedTextColor.LIGHT_PURPLE)
.hoverEvent(showText(translatable("vote.mode.hover", NamedTextColor.AQUA)))
Expand All @@ -166,7 +168,7 @@ public void listMaps(CommandSender sender, Audience viewer, MapOrder mapOrder)
.append(text(": ("))
.append(text(currentMaps, listNumColor))
.append(text("/"))
.append(text(VotingPool.MAX_VOTE_OPTIONS, NamedTextColor.RED))
.append(text(MapVotePicker.MAX_VOTE_OPTIONS, NamedTextColor.RED))
.append(text(") "))
.append(text("\u00BB", NamedTextColor.GOLD))
.append(text(" ["))
Expand All @@ -177,7 +179,7 @@ public void listMaps(CommandSender sender, Audience viewer, MapOrder mapOrder)
viewer.sendMessage(listMsg);

int index = 1;
for (MapInfo mi : vote.getOptions().getCustomVoteMaps()) {
for (MapInfo mi : vote.getCustomVoteMaps()) {
Component indexedName =
text()
.append(text(index, NamedTextColor.YELLOW))
Expand All @@ -189,7 +191,7 @@ public void listMaps(CommandSender sender, Audience viewer, MapOrder mapOrder)
}
}

public static VotingPool getVotingPool(CommandSender sender, MapOrder mapOrder)
public static VotePoolOptions getVoteOptions(CommandSender sender, MapOrder mapOrder)
throws CommandException {
if (mapOrder instanceof MapPoolManager) {
MapPoolManager manager = (MapPoolManager) mapOrder;
Expand All @@ -199,7 +201,7 @@ public static VotingPool getVotingPool(CommandSender sender, MapOrder mapOrder)
throw new CommandException(
ChatColor.RED + TextTranslations.translate("vote.modify.disallow", sender));
}
return votePool;
return manager.getVoteOptions();
}
throw new CommandException(
ChatColor.RED + TextTranslations.translate("vote.disabled", sender));
Expand Down
39 changes: 31 additions & 8 deletions core/src/main/java/tc/oc/pgm/controlpoint/ControlPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ protected void tickCapture(Duration duration) {
}

if (lead > 0) {
this.dominateAndFireEvents(leader, calculateDominateTime(lead, duration));
this.dominateAndFireEvents(leader, calculateDominateTime(lead, duration), false);
} else {
this.dominateAndFireEvents(null, duration);
this.dominateAndFireEvents(null, duration, leader != null);
}
}

Expand All @@ -347,12 +347,13 @@ protected void tickCapture(Duration duration) {
* team can be null, which means no team is dominating the point, which can cause the state to
* change in some configurations.
*/
private void dominateAndFireEvents(@Nullable Competitor dominantTeam, Duration dominantTime) {
private void dominateAndFireEvents(
@Nullable Competitor dominantTeam, Duration dominantTime, boolean contested) {
Duration oldCapturingTime = this.capturingTime;
Competitor oldCapturingTeam = this.capturingTeam;
Competitor oldControllingTeam = this.controllingTeam;

this.dominate(dominantTeam, dominantTime);
this.dominate(dominantTeam, dominantTime, contested);

if (oldCapturingTeam != this.capturingTeam || !oldCapturingTime.equals(this.capturingTime)) {
this.match.callEvent(new CapturingTimeChangeEvent(this.match, this));
Expand Down Expand Up @@ -404,7 +405,12 @@ private void dominateAndFireEvents(@Nullable Competitor dominantTeam, Duration d
* <p>If there is no neutral state, then the point is always either being captured by a specific
* team, or not being captured at all.
*/
private void dominate(Competitor dominantTeam, Duration dominantTime) {
private void dominate(Competitor dominantTeam, Duration dominantTime, boolean contested) {
if (dominantTeam != null && contested) {
throw new IllegalArgumentException(
"Control point cannot be contested if there is a dominant team.");
}

if (!this.capturable || !TimeUtils.isLongerThan(dominantTime, Duration.ZERO)) {
return;
}
Expand All @@ -418,6 +424,9 @@ private void dominate(Competitor dominantTeam, Duration dominantTime) {
} else if (dominantTeam != null) {
// non-owner is uncapturing the point
uncapture(dominantTeam, dominantTime);
} else if (contested) {
// the point is contested, so use contested decay
contestedDecay(dominantTime);
} else if (definition.getOwnedDecayRate() > 0) {
// nobody on point so decay to neutral state
ownedDecay(dominantTime);
Expand All @@ -433,6 +442,9 @@ private void dominate(Competitor dominantTeam, Duration dominantTime) {
} else if (dominantTeam != null) {
// non-capturing team is dominate, so regress capturing team's progress
recover(dominantTeam, dominantTime);
} else if (contested) {
// the point is contested, so use contested decay
contestedDecay(dominantTime);
} else {
// No team is dominating so decay
decay(dominantTime);
Expand All @@ -443,7 +455,7 @@ private void dominate(Competitor dominantTeam, Duration dominantTime) {
// Point is not being captured and there is a dominant team that is not the owner, so they
// start capturing
this.capturingTeam = dominantTeam;
this.dominate(dominantTeam, dominantTime);
this.dominate(dominantTeam, dominantTime, contested);
}
}

Expand Down Expand Up @@ -486,7 +498,7 @@ private void uncapture(Competitor dominantTeam, Duration dominantTime) {
dominantTime = addCaptureTime(dominantTime);
if (dominantTime != null) {
this.controllingTeam = null;
this.dominate(dominantTeam, dominantTime);
this.dominate(dominantTeam, dominantTime, false);
}
}

Expand All @@ -502,11 +514,22 @@ private void recover(Competitor dominantTeam, Duration dominantTime) {
this.dominate(
dominantTeam,
Duration.ofMillis(
(long) ((1.0 / definition.getRecoveryRate()) * dominantTime.toMillis())));
(long) ((1.0 / definition.getRecoveryRate()) * dominantTime.toMillis())),
false);
}
}
}

/** Point is being decayed back to its current state (Point is contested) */
private void contestedDecay(Duration dominantTime) {
dominantTime =
subtractCaptureTime(
Duration.ofMillis((long) (definition.getContestedRate() * dominantTime.toMillis())));
if (dominantTime != null) {
this.capturingTeam = null;
}
}

/** Point is being decayed back to its current state (No lead on point) */
private void decay(Duration dominantTime) {
dominantTime =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public class ControlPointDefinition extends GoalDefinition {
// Time it takes for a point to decay while unowned. (Time is accurate when near 100% capture)
private final double decayRate;

// Time it takes for a point to decay while contested. (Time is accurate when near 100% capture)
private final double contestedRate;

// Time it takes for a point to recover to captured state. (Accurate when almost uncaptured)
private final double recoveryRate;

Expand Down Expand Up @@ -101,6 +104,7 @@ public ControlPointDefinition(
double decayRate,
double recoveryRate,
double ownedDecayRate,
double contestedRate,
float timeMultiplier,
@Nullable TeamFactory initialOwner,
CaptureCondition captureCondition,
Expand All @@ -123,6 +127,7 @@ public ControlPointDefinition(
this.decayRate = decayRate;
this.recoveryRate = recoveryRate;
this.ownedDecayRate = ownedDecayRate;
this.contestedRate = contestedRate;
this.timeMultiplier = timeMultiplier;
this.initialOwner = initialOwner;
this.captureCondition = captureCondition;
Expand All @@ -148,6 +153,8 @@ public String toString() {
+ this.getRecoveryRate()
+ " ownedDecayRate="
+ this.getOwnedDecayRate()
+ " contestedRate="
+ this.getContestedRate()
+ " timeMultiplier="
+ this.getTimeMultiplier()
+ " initialOwner="
Expand Down Expand Up @@ -218,6 +225,10 @@ public double getOwnedDecayRate() {
return this.ownedDecayRate;
}

public double getContestedRate() {
return this.contestedRate;
}

public float getTimeMultiplier() {
return this.timeMultiplier;
}
Expand Down
Loading

0 comments on commit 4101176

Please sign in to comment.