Skip to content
19 changes: 13 additions & 6 deletions core/src/main/java/tc/oc/pgm/command/MapPoolCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ public Component format(MapPool mapPool, int index) {
@Command(
aliases = {"setpool", "setrot"},
desc = "Change the map pool",
usage = "[pool name] -r (revert to dynamic) -t (time limit for map pool)",
flags = "r",
usage = "[pool name] -r (revert to dynamic) -t (time limit for map pool) -m (match # limit)",
flags = "rtm",
perms = Permissions.SETNEXT)
public void setPool(
Audience sender,
Expand All @@ -209,7 +209,8 @@ public void setPool(
MapOrder mapOrder,
@Nullable String poolName,
@Switch('r') boolean reset,
@Switch('t') Duration timeLimit)
@Switch('t') Duration timeLimit,
@Switch('m') Integer matchLimit)
throws CommandException {
if (!match.getCountdown().getAll(CycleCountdown.class).isEmpty()) {
sender.sendMessage(TranslatableComponent.of("admin.setPool.activeCycle", TextColor.RED));
Expand All @@ -232,7 +233,9 @@ public void setPool(
TextComponent.of(newPool.getName(), TextColor.LIGHT_PURPLE)));
return;
}
mapPoolManager.updateActiveMapPool(newPool, match, true, source, timeLimit);

mapPoolManager.updateActiveMapPool(
newPool, match, true, source, timeLimit, matchLimit != null ? matchLimit : 0);
}
}

Expand Down Expand Up @@ -275,7 +278,11 @@ public static void skip(

@Command(aliases = "votenext", desc = "Vote for the next map", usage = "map")
public static void voteNext(
MatchPlayer player, CommandSender sender, MapOrder mapOrder, @Text MapInfo map)
MatchPlayer player,
CommandSender sender,
MapOrder mapOrder,
@Switch('o') boolean forceOpen,
@Text MapInfo map)
throws CommandException {
MapPool pool = getMapPoolManager(sender, mapOrder).getActiveMapPool();
MapPoll poll = pool instanceof VotingPool ? ((VotingPool) pool).getCurrentPoll() : null;
Expand All @@ -291,7 +298,7 @@ public static void voteNext(
voteResult ? TextColor.GREEN : TextColor.RED,
map.getStyledName(MapNameStyle.COLOR));
player.sendMessage(voteAction);
poll.sendBook(player);
poll.sendBook(player, forceOpen);
}

public static MapPoolManager getMapPoolManager(CommandSender sender, MapOrder mapOrder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public void mute(
warn(sender, target, match, reason);

if (punish(PunishmentType.MUTE, targetMatchPlayer, sender, reason, true)) {
chat.addMuted(targetMatchPlayer);
chat.addMuted(targetMatchPlayer, reason);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ private void freeze(MatchPlayer freezee, Component senderName, boolean silent) {
"moderation.freeze.broadcast.frozen",
TextColor.GRAY,
senderName,
freezee.getName(NameStyle.FANCY)),
freezee.getName(NameStyle.CONCISE)),
match);
}

Expand All @@ -370,7 +370,7 @@ private void thaw(MatchPlayer freezee, Component senderName, boolean silent) {
"moderation.freeze.broadcast.thaw",
TextColor.GRAY,
senderName,
freezee.getName(NameStyle.FANCY)),
freezee.getName(NameStyle.CONCISE)),
match);
}

Expand Down
9 changes: 8 additions & 1 deletion core/src/main/java/tc/oc/pgm/events/MapPoolAdjustEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,23 @@ public class MapPoolAdjustEvent extends Event {
private final boolean forced;
private final @Nullable CommandSender sender;
private final @Nullable Duration timeLimit;
private final int matchLimit;

public MapPoolAdjustEvent(
MapPool oldMapPool,
MapPool newMapPool,
Match match,
boolean forced,
@Nullable CommandSender sender,
@Nullable Duration timeLimit) {
@Nullable Duration timeLimit,
int matchLimit) {
this.oldPool = oldMapPool;
this.newPool = newMapPool;
this.match = match;
this.forced = forced;
this.sender = sender;
this.timeLimit = timeLimit;
this.matchLimit = matchLimit;
}

public MapPool getOldPool() {
Expand All @@ -58,6 +61,10 @@ public Duration getTimeLimit() {
return timeLimit;
}

public int getMatchLimit() {
return matchLimit;
}

private static final HandlerList handlers = new HandlerList();

@Override
Expand Down
23 changes: 15 additions & 8 deletions core/src/main/java/tc/oc/pgm/flag/Flag.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public class Flag extends TouchableGoal<FlagDefinition> implements Listener {
private final Set<Team> completers;
private BaseState state;
private boolean transitioning;
private @Nullable Post predeterminedPost;

protected Flag(Match match, FlagDefinition definition, ImmutableSet<Net> nets)
throws ModuleLoadException {
Expand Down Expand Up @@ -234,29 +235,35 @@ public boolean canDropAt(Location location) {
}
}

private int sequentialPostCounter = 0;
private Post returnPost;
private int sequentialPostCounter = 1;

public Post getReturnPost(Post post) {
if (post.isSpecifiedPost()) {
return post;
}
if (definition.isSequential()) {
Post returnPost = definition.getPosts().get(sequentialPostCounter++);
if (sequentialPostCounter == definition.getPosts().size()) {
sequentialPostCounter = 0;
}
if (predeterminedPost != null) {
Post returnPost = predeterminedPost;
predeterminedPost = null;
return returnPost;
}
if (definition.isSequential()) {
sequentialPostCounter %= definition.getPosts().size();
return definition.getPosts().get(sequentialPostCounter++);
}
Random random = match.getRandom();
return definition.getPosts().get(random.nextInt(definition.getPosts().size()));
}

public Location getReturnPoint(Post post) {
returnPost = getReturnPost(post);
Post returnPost = getReturnPost(post);
return returnPost.getReturnPoint(this, this.bannerYawProvider).clone();
}

public String predeterminePost(Post post) {
predeterminedPost = getReturnPost(post);
return predeterminedPost.getPostName();
}

public AngleProvider getBannerYawProvider() {
return bannerYawProvider;
}
Expand Down
15 changes: 14 additions & 1 deletion core/src/main/java/tc/oc/pgm/flag/FlagDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ private static String makeName(@Nullable String name, @Nullable DyeColor color)
private final boolean dropOnWater; // Flag can freeze water to drop on it
private final boolean showBeam;
private final boolean sequential;
private boolean
showRespawnOnPickup; // When a flag is picked up, if true, it will display where it will
// respawn. Will be set to false if a net defines a different respawn post.

public FlagDefinition(
@Nullable String id,
Expand All @@ -69,7 +72,8 @@ public FlagDefinition(
boolean showBeam,
ProximityMetric flagProximityMetric,
ProximityMetric netProximityMetric,
boolean sequential) {
boolean sequential,
boolean showRespawnOnPickup) {

// We can't use the owner field in OwnedGoal because our owner
// is a reference that can't be resolved until after parsing.
Expand Down Expand Up @@ -98,6 +102,7 @@ public FlagDefinition(
this.dropOnWater = dropOnWater;
this.showBeam = showBeam;
this.sequential = sequential;
this.showRespawnOnPickup = showRespawnOnPickup;
}

public @Nullable DyeColor getColor() {
Expand Down Expand Up @@ -181,6 +186,14 @@ public boolean isSequential() {
return sequential;
}

public boolean willShowRespawnOnPickup() {
return showRespawnOnPickup;
}

public void setShowRespawnOnPickup(boolean value) {
this.showRespawnOnPickup = value;
}

@SuppressWarnings("unchecked")
@Override
public Flag getGoal(Match match) {
Expand Down
13 changes: 12 additions & 1 deletion core/src/main/java/tc/oc/pgm/flag/FlagParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ public Net parseNet(Element el, @Nullable FlagDefinition parentFlag) throws Inva
capturableFlags = ImmutableSet.copyOf(this.flags);
}

if (capturableFlags.size() != 0 && returnPost != null) {
for (FlagDefinition flagDef : flags) {
if (capturableFlags.contains(flagDef)) {
flagDef.setShowRespawnOnPickup(false);
}
}
}

ImmutableSet<FlagDefinition> returnableFlags;
Node returnableNode = Node.fromAttr(el, "rescue", "return");
if (returnableNode != null) {
Expand Down Expand Up @@ -211,6 +219,8 @@ public FlagDefinition parseFlag(Element el) throws InvalidXMLException {
boolean multiCarrier = XMLUtils.parseBoolean(el.getAttribute("shared"), false);
boolean sequential = XMLUtils.parseBoolean(el.getAttribute("sequential"), false);
Component carryMessage = XMLUtils.parseFormattedText(el, "carry-message");
boolean showRespawnOnPickup =
XMLUtils.parseBoolean(el.getAttribute("show-respawn-on-pickup"), true);
boolean dropOnWater = XMLUtils.parseBoolean(el.getAttribute("drop-on-water"), true);
boolean showBeam = XMLUtils.parseBoolean(el.getAttribute("beam"), true);
ProximityMetric flagProximityMetric =
Expand Down Expand Up @@ -260,7 +270,8 @@ public FlagDefinition parseFlag(Element el) throws InvalidXMLException {
showBeam,
flagProximityMetric,
netProximityMetric,
sequential);
sequential,
showRespawnOnPickup);
flags.add(flag);
factory.getFeatures().addFeature(el, flag);

Expand Down
12 changes: 12 additions & 0 deletions core/src/main/java/tc/oc/pgm/flag/state/Carried.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ public Carried(Flag flag, Post post, MatchPlayer carrier, Location dropLocation)
this.carrier = carrier;
this.dropLocations.add(
dropLocation); // Need an initial dropLocation in case the carrier never generates ones
if (this.flag.getDefinition().willShowRespawnOnPickup()) {
String postName = this.flag.predeterminePost(this.post);
if (postName != null) { // The post needs a name in order to display the message.
this.flag
.getMatch()
.sendMessage(
TranslatableComponent.of(
"flag.willRespawn.next",
this.flag.getComponentName(),
TextComponent.of(postName, TextColor.AQUA)));
}
}
}

@Override
Expand Down
20 changes: 12 additions & 8 deletions core/src/main/java/tc/oc/pgm/listeners/ChatDispatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import app.ashcon.intake.parametric.annotation.Text;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Sets;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
Expand Down Expand Up @@ -57,7 +58,7 @@ public static ChatDispatcher get() {
private final VanishManager vanish;
private final OnlinePlayerMapAdapter<UUID> lastMessagedBy;

private final Set<UUID> muted;
private final Map<UUID, String> muted;

public static final TextComponent ADMIN_CHAT_PREFIX =
TextComponent.builder()
Expand Down Expand Up @@ -85,24 +86,24 @@ public ChatDispatcher() {
this.manager = PGM.get().getMatchManager();
this.vanish = PGM.get().getVanishManager();
this.lastMessagedBy = new OnlinePlayerMapAdapter<>(PGM.get());
this.muted = Sets.newHashSet();
this.muted = Maps.newHashMap();
PGM.get().getServer().getPluginManager().registerEvents(this, PGM.get());
}

public void addMuted(MatchPlayer player) {
this.muted.add(player.getId());
public void addMuted(MatchPlayer player, String reason) {
this.muted.put(player.getId(), reason);
}

public void removeMuted(MatchPlayer player) {
this.muted.remove(player.getId());
}

public boolean isMuted(MatchPlayer player) {
return player != null ? muted.contains(player.getId()) : false;
return player != null ? muted.containsKey(player.getId()) : false;
}

public Set<UUID> getMutedUUIDs() {
return muted;
return muted.keySet();
}

@Command(
Expand Down Expand Up @@ -399,7 +400,10 @@ private MatchPlayer getApproximatePlayer(Match match, String query, CommandSende
}

private void sendMutedMessage(MatchPlayer player) {
Component warning = TranslatableComponent.of("moderation.mute.message");
Component warning =
TranslatableComponent.of(
"moderation.mute.message",
TextComponent.of(muted.getOrDefault(player.getId(), ""), TextColor.AQUA));
player.sendWarning(warning);
}

Expand Down
27 changes: 26 additions & 1 deletion core/src/main/java/tc/oc/pgm/listeners/PGMListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,37 @@ public void announceDynamicMapPoolChange(MapPoolAdjustEvent event) {
Component poolName = TextComponent.of(event.getNewPool().getName(), TextColor.LIGHT_PURPLE);
Component staffName =
UsernameFormatUtils.formatStaffName(event.getSender(), event.getMatch());
Component matchLimit =
TextComponent.builder()
.append(Integer.toString(event.getMatchLimit()), TextColor.GREEN)
.append(" ")
.append(
TranslatableComponent.of(
"match.name" + (event.getMatchLimit() != 1 ? ".plural" : ""), TextColor.GRAY))
.build();

// No limit
Component forced = TranslatableComponent.of("pool.change.force", poolName, staffName);
if (event.getTimeLimit() != null) {
Component time =
PeriodFormats.briefNaturalApproximate(event.getTimeLimit()).color(TextColor.GREEN);
forced = TranslatableComponent.of("pool.change.forceTimed", poolName, time, staffName);

// If time & match limit are present, display both
if (event.getMatchLimit() != 0) {
Component timeAndLimit =
TranslatableComponent.of("misc.or", TextColor.GRAY, time, matchLimit);
forced =
TranslatableComponent.of("pool.change.forceTimed", poolName, timeAndLimit, staffName);
} else {
// Just time limit
forced = TranslatableComponent.of("pool.change.forceTimed", poolName, time, staffName);
}
} else if (event.getMatchLimit() != 0) {
// Just match limit
forced =
TranslatableComponent.of("pool.change.forceTimed", poolName, matchLimit, staffName);
}

ChatDispatcher.broadcastAdminChatMessage(forced.color(TextColor.GRAY), event.getMatch());
}

Expand Down
12 changes: 6 additions & 6 deletions core/src/main/java/tc/oc/pgm/modules/MapmakerMatchModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ public MapmakerMatchModule(Match match) {
@EventHandler(ignoreCancelled = true)
public void onPlayerAddEvent(final MatchPlayerAddEvent event) {
MatchPlayer player = event.getPlayer();
player
.getBukkit()
.addAttachment(
PGM.get(),
Permissions.MAPMAKER,
authors.stream().anyMatch(c -> c.isPlayer(player.getId())));
if (authors.stream().anyMatch(c -> c.isPlayer(player.getId()))) {
player.getBukkit().addAttachment(PGM.get(), Permissions.MAPMAKER, true);
} else {
player.getBukkit().removeAttachments(Permissions.MAPMAKER);
}

PGM.get().getPrefixRegistry().removePlayer(player.getId()); // Refresh prefixes for the player
}
}
Loading