Add dynamic rotations (#2)
* Start work on multidynamic rotations
* Finish up dynamic rotations ♻️
* Fix typo
* Some changes to Dynamic Rotations
* Add dynamic player count requirements to config.yml
* Fix messages and change participating players count logic
This commit is contained in:
parent
b883ef5799
commit
7e5325daaf
|
@ -65,6 +65,9 @@ map.gamemode.long.mixed = Mixed
|
|||
map.gamemode.long.skywars = Skywars
|
||||
map.gamemode.long.survival = Survival Games
|
||||
|
||||
rotation.change.broadcast.title = Changing Rotation...
|
||||
rotation.change.broadcast.info = The server is automatically changing rotations to best accommodate the current player count.
|
||||
|
||||
command.match.matchInfo.title = Match
|
||||
command.match.matchInfo.title.tip = View this match on the web
|
||||
command.match.matchInfo.time = Time
|
||||
|
|
|
@ -40,6 +40,7 @@ import tc.oc.pgm.match.MatchManager;
|
|||
import tc.oc.pgm.match.MatchPlayer;
|
||||
import tc.oc.pgm.polls.PollListener;
|
||||
import tc.oc.pgm.polls.PollManager;
|
||||
import tc.oc.pgm.rotation.DynamicRotationChangeListener;
|
||||
import tc.oc.pgm.start.StartCommands;
|
||||
import tc.oc.pgm.tablist.MatchTabManager;
|
||||
import tc.oc.pgm.timelimit.TimeLimitCommands;
|
||||
|
@ -199,6 +200,7 @@ public final class PGM extends JavaPlugin {
|
|||
this.registerEvents(new CraftingProtect());
|
||||
this.registerEvents(new ObjectivesFireworkListener());
|
||||
this.registerEvents(new ItemTransferListener());
|
||||
this.registerEvents(new DynamicRotationChangeListener());
|
||||
}
|
||||
|
||||
public void registerEvents(Listener listener) {
|
||||
|
|
|
@ -130,4 +130,11 @@ public class MapModuleContext extends ModuleContext<MapModule, MapScoped> {
|
|||
public Range<Integer> playerLimits() {
|
||||
return playerLimits.get();
|
||||
}
|
||||
|
||||
public Integer playerLimitAverage() {
|
||||
Range<Integer> lims = playerLimits();
|
||||
int sum = lims.lowerEndpoint() + lims.upperEndpoint();
|
||||
|
||||
return ((Double) Math.floor(sum/2)).intValue();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package tc.oc.pgm.rotation;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.chat.TranslatableComponent;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import tc.oc.commons.core.chat.Component;
|
||||
import tc.oc.pgm.Config;
|
||||
import tc.oc.pgm.PGM;
|
||||
import tc.oc.pgm.cycle.CycleMatchModule;
|
||||
import tc.oc.pgm.events.MatchEndEvent;
|
||||
|
||||
public class DynamicRotationChangeListener implements Listener {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(RotationCategory.MEDIUM.toString().toLowerCase());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onMatchEnd(MatchEndEvent event) {
|
||||
RotationManager rotationManager = PGM.getMatchManager().getRotationManager();
|
||||
|
||||
// Ignore if there is only one rotation available
|
||||
if (rotationManager.getRotations().size() == 1) return;
|
||||
|
||||
// Number of players we can assume is active
|
||||
int participatingPlayers = event.getMatch().getServer().getOnlinePlayers().size();
|
||||
|
||||
RotationCategory appr = getAppropriateRotationCategory(participatingPlayers, rotationManager);
|
||||
if (appr != null && rotationManager.getRotation(appr.toString().toLowerCase()) != rotationManager.getRotation()) {
|
||||
rotationManager.setRotation(rotationManager.getRotation(appr.toString().toLowerCase()));
|
||||
CycleMatchModule cmm = event.getMatch().needMatchModule(CycleMatchModule.class);
|
||||
cmm.startCountdown(cmm.getConfig().countdown());
|
||||
|
||||
event.getMatch().sendMessage(new TextComponent(ChatColor.RED + "" + ChatColor.STRIKETHROUGH + "---------------------------------------------------"));
|
||||
event.getMatch().sendMessage(new Component(new TranslatableComponent("rotation.change.broadcast.title"), ChatColor.GOLD));
|
||||
event.getMatch().sendMessage(new Component(new TranslatableComponent("rotation.change.broadcast.info"), ChatColor.YELLOW));
|
||||
event.getMatch().sendMessage(new TextComponent(ChatColor.RED + "" + ChatColor.STRIKETHROUGH + "---------------------------------------------------"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns appropriate rotation looking at how many players (participating) are online.
|
||||
*
|
||||
* @param players Current participant player count.
|
||||
* @param rotationManager The {@link RotationManager}
|
||||
* @return any of {@link RotationCategory}
|
||||
*/
|
||||
private RotationCategory getAppropriateRotationCategory(int players, RotationManager rotationManager) {
|
||||
Configuration config = Config.getConfiguration();
|
||||
int medium = config.getInt("rotation.providers.file.medium.count");
|
||||
int mega = config.getInt("rotation.providers.file.mega.count");
|
||||
|
||||
if (players > medium && players <= mega && rotationManager.getRotation("medium") != null) return RotationCategory.MEDIUM;
|
||||
if (players > mega && rotationManager.getRotation("mega") != null) return RotationCategory.MEGA;
|
||||
|
||||
return RotationCategory.MINI;
|
||||
}
|
||||
}
|
|
@ -34,9 +34,10 @@ public class FileRotationProviderFactory {
|
|||
if(!rotationFile.isAbsolute()) rotationFile = dataPath.resolve(rotationFile);
|
||||
|
||||
int priority = provider.getInt("priority", 0);
|
||||
int count = provider.getInt("count", 0);
|
||||
|
||||
if(Files.isRegularFile(rotationFile)) {
|
||||
providers.add(new RotationProviderInfo(new FileRotationProvider(mapLibrary, name, rotationFile, dataPath), name, priority));
|
||||
providers.add(new RotationProviderInfo(new FileRotationProvider(mapLibrary, name, rotationFile, dataPath), name, priority, count));
|
||||
} else if(minecraftService.getLocalServer().startup_visibility() == ServerDoc.Visibility.PUBLIC) {
|
||||
// This is not a perfect way to decide whether or not to throw an error, but it's the best we can do right now
|
||||
mapLibrary.getLogger().severe("Missing rotation file: " + rotationFile);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package tc.oc.pgm.rotation;
|
||||
|
||||
public enum RotationCategory {
|
||||
MINI, MEDIUM, MEGA
|
||||
}
|
|
@ -116,12 +116,12 @@ public class RotationManager {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void addProvider(@Nonnull RotationProvider provider, @Nonnull String name, int priority) {
|
||||
public void addProvider(@Nonnull RotationProvider provider, @Nonnull String name, int priority, int count) {
|
||||
Preconditions.checkNotNull(provider, "rotation provider");
|
||||
Preconditions.checkNotNull(name, "name");
|
||||
Preconditions.checkArgument(this.getProviderByName(name) == null, "provider is already registered to name");
|
||||
|
||||
RotationProviderInfo state = new RotationProviderInfo(provider, name, priority);
|
||||
RotationProviderInfo state = new RotationProviderInfo(provider, name, priority, count);
|
||||
this.providers.add(state);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,15 +8,17 @@ public class RotationProviderInfo implements Comparable<RotationProviderInfo> {
|
|||
public final @Nonnull
|
||||
RotationProvider provider;
|
||||
public final int priority;
|
||||
public final int count;
|
||||
public final @Nonnull String name;
|
||||
|
||||
public RotationProviderInfo(@Nonnull RotationProvider provider, @Nonnull String name, int priority) {
|
||||
public RotationProviderInfo(@Nonnull RotationProvider provider, @Nonnull String name, int priority, int count) {
|
||||
Preconditions.checkNotNull(provider, "rotation provider");
|
||||
Preconditions.checkNotNull(name, "name");
|
||||
|
||||
this.provider = provider;
|
||||
this.name = name;
|
||||
this.priority = priority;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package tc.oc.pgm.rotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -39,6 +40,20 @@ public final class RotationState {
|
|||
return this.maps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the approximate number of players supposed to be playing the rotation maps.
|
||||
* @return Integer with average size of teams over all maps
|
||||
*/
|
||||
public @Nonnull Integer getAverageNeededPlayers() {
|
||||
List<Integer> players = new ArrayList<>();
|
||||
int total = 0;
|
||||
|
||||
getMaps().stream().forEach(m -> players.add(m.getContext().playerLimitAverage()));
|
||||
for (int pl : players) { total += pl; }
|
||||
|
||||
return ((Double) Math.floor(total / players.size())).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next map in the rotation as specified by the next id.
|
||||
* @return Next map in rotation
|
||||
|
|
Loading…
Reference in New Issue