mirror of
https://github.com/taoneill/war.git
synced 2025-01-05 07:17:34 +01:00
Fix #412, auto team balance for autoassign warzones
This commit is contained in:
parent
eb7b600aef
commit
22cbba62b3
@ -1,37 +1,34 @@
|
||||
package com.tommytony.war;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.tommytony.war.config.*;
|
||||
import com.tommytony.war.event.WarBattleWinEvent;
|
||||
import com.tommytony.war.event.WarPlayerLeaveEvent;
|
||||
import com.tommytony.war.event.WarPlayerThiefEvent;
|
||||
import com.tommytony.war.event.WarScoreCapEvent;
|
||||
import com.tommytony.war.job.InitZoneJob;
|
||||
import com.tommytony.war.job.LoadoutResetJob;
|
||||
import com.tommytony.war.job.LogKillsDeathsJob;
|
||||
import com.tommytony.war.job.LogKillsDeathsJob.KillsDeathsRecord;
|
||||
import com.tommytony.war.job.ZoneTimeJob;
|
||||
import com.tommytony.war.mapper.LoadoutYmlMapper;
|
||||
import com.tommytony.war.mapper.VolumeMapper;
|
||||
import com.tommytony.war.mapper.ZoneVolumeMapper;
|
||||
import com.tommytony.war.spout.SpoutDisplayer;
|
||||
import com.tommytony.war.structure.*;
|
||||
import com.tommytony.war.utility.*;
|
||||
import com.tommytony.war.volume.Volume;
|
||||
import com.tommytony.war.volume.ZoneVolume;
|
||||
import net.milkbowl.vault.economy.EconomyResponse;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
@ -50,33 +47,13 @@ import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.getspout.spoutapi.SpoutManager;
|
||||
import org.getspout.spoutapi.player.SpoutPlayer;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.tommytony.war.config.InventoryBag;
|
||||
import com.tommytony.war.config.ScoreboardType;
|
||||
import com.tommytony.war.config.TeamConfig;
|
||||
import com.tommytony.war.config.TeamConfigBag;
|
||||
import com.tommytony.war.config.TeamKind;
|
||||
import com.tommytony.war.config.WarzoneConfig;
|
||||
import com.tommytony.war.config.WarzoneConfigBag;
|
||||
import com.tommytony.war.event.WarBattleWinEvent;
|
||||
import com.tommytony.war.event.WarPlayerLeaveEvent;
|
||||
import com.tommytony.war.event.WarPlayerThiefEvent;
|
||||
import com.tommytony.war.event.WarScoreCapEvent;
|
||||
import com.tommytony.war.job.InitZoneJob;
|
||||
import com.tommytony.war.job.LoadoutResetJob;
|
||||
import com.tommytony.war.job.LogKillsDeathsJob;
|
||||
import com.tommytony.war.job.LogKillsDeathsJob.KillsDeathsRecord;
|
||||
import com.tommytony.war.mapper.LoadoutYmlMapper;
|
||||
import com.tommytony.war.mapper.VolumeMapper;
|
||||
import com.tommytony.war.mapper.ZoneVolumeMapper;
|
||||
import com.tommytony.war.spout.SpoutDisplayer;
|
||||
import com.tommytony.war.utility.Direction;
|
||||
import com.tommytony.war.utility.Loadout;
|
||||
import com.tommytony.war.utility.LoadoutSelection;
|
||||
import com.tommytony.war.utility.PlayerState;
|
||||
import com.tommytony.war.utility.PotionEffectHelper;
|
||||
import com.tommytony.war.volume.Volume;
|
||||
import com.tommytony.war.volume.ZoneVolume;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -86,28 +63,29 @@ import com.tommytony.war.volume.ZoneVolume;
|
||||
public class Warzone {
|
||||
|
||||
|
||||
public enum LeaveCause {
|
||||
COMMAND, DISCONNECT, SCORECAP, RESET;
|
||||
public boolean useRallyPoint() {
|
||||
return this == SCORECAP ? true : false;
|
||||
static final Comparator<Team> LEAST_PLAYER_COUNT_ORDER = new Comparator<Team>() {
|
||||
@Override
|
||||
public int compare(Team arg0, Team arg1) {
|
||||
return arg0.getPlayers().size() - arg1.getPlayers().size();
|
||||
}
|
||||
}
|
||||
|
||||
private String name;
|
||||
private ZoneVolume volume;
|
||||
private World world;
|
||||
};
|
||||
private final List<Team> teams = new ArrayList<Team>();
|
||||
private final List<Monument> monuments = new ArrayList<Monument>();
|
||||
private final List<CapturePoint> capturePoints = new ArrayList<CapturePoint>();
|
||||
private final List<Bomb> bombs = new ArrayList<Bomb>();
|
||||
private final List<Cake> cakes = new ArrayList<Cake>();
|
||||
private final List<String> authors = new ArrayList<String>();
|
||||
private final int minSafeDistanceFromWall = 6;
|
||||
private final List<Player> respawn = new ArrayList<Player>();
|
||||
private final List<String> reallyDeadFighters = new ArrayList<String>();
|
||||
private final WarzoneConfigBag warzoneConfig;
|
||||
private final TeamConfigBag teamDefaultConfig;
|
||||
private String name;
|
||||
private ZoneVolume volume;
|
||||
private World world;
|
||||
private Location teleport;
|
||||
private ZoneLobby lobby;
|
||||
private Location rallyPoint;
|
||||
|
||||
private final List<String> authors = new ArrayList<String>();
|
||||
|
||||
private final int minSafeDistanceFromWall = 6;
|
||||
private List<ZoneWallGuard> zoneWallGuards = new ArrayList<ZoneWallGuard>();
|
||||
private HashMap<String, PlayerState> playerStates = new HashMap<String, PlayerState>();
|
||||
private HashMap<UUID, Team> flagThieves = new HashMap<UUID, Team>();
|
||||
@ -116,15 +94,9 @@ public class Warzone {
|
||||
private HashMap<String, LoadoutSelection> loadoutSelections = new HashMap<String, LoadoutSelection>();
|
||||
private HashMap<String, PlayerState> deadMenInventories = new HashMap<String, PlayerState>();
|
||||
private HashMap<String, Integer> killCount = new HashMap<String, Integer>();
|
||||
private final List<Player> respawn = new ArrayList<Player>();
|
||||
private final List<String> reallyDeadFighters = new ArrayList<String>();
|
||||
private HashMap<Player, PermissionAttachment> attachments = new HashMap<Player, PermissionAttachment>();
|
||||
private HashMap<Player, Team> delayedJoinPlayers = new HashMap<Player, Team>();
|
||||
|
||||
private List<LogKillsDeathsJob.KillsDeathsRecord> killsDeathsTracker = new ArrayList<KillsDeathsRecord>();
|
||||
|
||||
private final WarzoneConfigBag warzoneConfig;
|
||||
private final TeamConfigBag teamDefaultConfig;
|
||||
private InventoryBag defaultInventories = new InventoryBag();
|
||||
|
||||
private Scoreboard scoreboard;
|
||||
@ -139,6 +111,9 @@ public class Warzone {
|
||||
//private final Object gameEndLock = new Object();
|
||||
|
||||
private boolean pvpReady = true;
|
||||
private Random killSeed = new Random();
|
||||
// prevent tryCallDelayedPlayers from being recursively called by Warzone#assign
|
||||
private boolean activeDelayedCall = false;
|
||||
|
||||
public Warzone(World world, String name) {
|
||||
this.world = world;
|
||||
@ -204,10 +179,7 @@ public class Warzone {
|
||||
}
|
||||
|
||||
public boolean ready() {
|
||||
if (this.volume.hasTwoCorners() && !this.volume.tooSmall() && !this.volume.tooBig()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return this.volume.hasTwoCorners() && !this.volume.tooSmall() && !this.volume.tooBig();
|
||||
}
|
||||
|
||||
public List<Team> getTeams() {
|
||||
@ -244,19 +216,24 @@ public class Warzone {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String newName) {
|
||||
this.name = newName;
|
||||
this.volume.setName(newName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
public void setTeleport(Location location) {
|
||||
this.teleport = location;
|
||||
}
|
||||
|
||||
public Location getTeleport() {
|
||||
return this.teleport;
|
||||
}
|
||||
|
||||
public void setTeleport(Location location) {
|
||||
this.teleport = location;
|
||||
}
|
||||
|
||||
public int saveState(boolean clearArtifacts) {
|
||||
if (this.ready()) {
|
||||
if (clearArtifacts) {
|
||||
@ -1025,20 +1002,13 @@ public class Warzone {
|
||||
playerGuards.clear();
|
||||
}
|
||||
|
||||
public void setLobby(ZoneLobby lobby) {
|
||||
this.lobby = lobby;
|
||||
}
|
||||
|
||||
public ZoneLobby getLobby() {
|
||||
return this.lobby;
|
||||
}
|
||||
|
||||
static final Comparator<Team> LEAST_PLAYER_COUNT_ORDER = new Comparator<Team>() {
|
||||
@Override
|
||||
public int compare(Team arg0, Team arg1) {
|
||||
return arg0.getPlayers().size() - arg1.getPlayers().size();
|
||||
public void setLobby(ZoneLobby lobby) {
|
||||
this.lobby = lobby;
|
||||
}
|
||||
};
|
||||
|
||||
public Team autoAssign(Player player) {
|
||||
Collections.sort(teams, LEAST_PLAYER_COUNT_ORDER);
|
||||
@ -1101,8 +1071,6 @@ public class Warzone {
|
||||
}
|
||||
}
|
||||
|
||||
private Random killSeed = new Random();
|
||||
|
||||
/**
|
||||
* Send death messages and process other records before passing off the
|
||||
* death to the {@link #handleDeath(Player)} method.
|
||||
@ -1311,12 +1279,51 @@ public class Warzone {
|
||||
War.war.getLogger().log(Level.INFO, "Last player left warzone {0}. Warzone blocks resetting automatically...", new Object[] {this.getName()});
|
||||
}
|
||||
}
|
||||
this.autoTeamBalance();
|
||||
|
||||
WarPlayerLeaveEvent event1 = new WarPlayerLeaveEvent(player.getName());
|
||||
War.war.getServer().getPluginManager().callEvent(event1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves players from team to team if the player size delta is greater than or equal to 2.
|
||||
* Only works for autoassign zones.
|
||||
*/
|
||||
private void autoTeamBalance() {
|
||||
if (!this.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOASSIGN)) {
|
||||
return;
|
||||
}
|
||||
boolean rerun = false;
|
||||
for (Team team1 : this.teams) {
|
||||
for (Team team2 : this.teams) {
|
||||
if (team1 == team2) {
|
||||
continue;
|
||||
}
|
||||
int t1p = team1.getPlayers().size();
|
||||
int t2p = team2.getPlayers().size();
|
||||
if (t1p - t2p >= 2) {
|
||||
Player eject = team1.getPlayers().get(killSeed.nextInt(t1p));
|
||||
team1.removePlayer(eject);
|
||||
team1.resetSign();
|
||||
this.assign(eject, team2);
|
||||
rerun = true;
|
||||
break;
|
||||
} else if (t2p - t1p >= 2) {
|
||||
Player eject = team2.getPlayers().get(killSeed.nextInt(t2p));
|
||||
team2.removePlayer(eject);
|
||||
team2.resetSign();
|
||||
this.assign(eject, team1);
|
||||
rerun = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rerun) {
|
||||
this.autoTeamBalance();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnemyTeamFlagBlock(Team playerTeam, Block block) {
|
||||
for (Team team : this.teams) {
|
||||
if (!team.getName().equals(playerTeam.getName()) && team.isTeamFlagBlock(block)) {
|
||||
@ -1414,12 +1421,12 @@ public class Warzone {
|
||||
return this.bombThieves.get(thief.getUniqueId());
|
||||
}
|
||||
|
||||
// Cake
|
||||
|
||||
public void removeBombThief(Player thief) {
|
||||
this.bombThieves.remove(thief.getUniqueId());
|
||||
}
|
||||
|
||||
// Cake
|
||||
|
||||
public void addCakeThief(Cake cake, Player cakeThief) {
|
||||
this.cakeThieves.put(cakeThief.getUniqueId(), cake);
|
||||
WarPlayerThiefEvent event1 = new WarPlayerThiefEvent(cakeThief, WarPlayerThiefEvent.StolenObject.CAKE);
|
||||
@ -1526,10 +1533,7 @@ public class Warzone {
|
||||
}
|
||||
|
||||
public boolean isDeadMan(String playerName) {
|
||||
if (this.deadMenInventories.containsKey(playerName)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return this.deadMenInventories.containsKey(playerName);
|
||||
}
|
||||
|
||||
public void restoreDeadmanInventory(Player player) {
|
||||
@ -1539,14 +1543,14 @@ public class Warzone {
|
||||
}
|
||||
}
|
||||
|
||||
public void setRallyPoint(Location location) {
|
||||
this.rallyPoint = location;
|
||||
}
|
||||
|
||||
public Location getRallyPoint() {
|
||||
return this.rallyPoint;
|
||||
}
|
||||
|
||||
public void setRallyPoint(Location location) {
|
||||
this.rallyPoint = location;
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
War.war.log("Unloading zone " + this.getName() + "...", Level.INFO);
|
||||
for (Team team : this.getTeams()) {
|
||||
@ -1572,10 +1576,7 @@ public class Warzone {
|
||||
teamsWithEnough++;
|
||||
}
|
||||
}
|
||||
if (teamsWithEnough >= this.getWarzoneConfig().getInt(WarzoneConfig.MINTEAMS)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return teamsWithEnough >= this.getWarzoneConfig().getInt(WarzoneConfig.MINTEAMS);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1616,8 +1617,6 @@ public class Warzone {
|
||||
tryCallDelayedPlayers();
|
||||
}
|
||||
|
||||
// prevent tryCallDelayedPlayers from being recursively called by Warzone#assign
|
||||
private boolean activeDelayedCall = false;
|
||||
private void tryCallDelayedPlayers() {
|
||||
if (activeDelayedCall || (!isEnoughPlayers() && !testEnoughPlayers(null, true))) {
|
||||
return;
|
||||
@ -1693,7 +1692,7 @@ public class Warzone {
|
||||
int i = 0;
|
||||
Iterator<String> it = sortedNames.iterator();
|
||||
while (it.hasNext()) {
|
||||
String name = (String) it.next();
|
||||
String name = it.next();
|
||||
if (i == currentIndex) {
|
||||
if (playerTeam.getTeamConfig().resolveBoolean(TeamConfig.PLAYERLOADOUTASDEFAULT) && name.equals("default")) {
|
||||
// Use player's own inventory as loadout
|
||||
@ -1789,11 +1788,6 @@ public class Warzone {
|
||||
// return gameEndLock;
|
||||
// }
|
||||
|
||||
public void setName(String newName) {
|
||||
this.name = newName;
|
||||
this.volume.setName(newName);
|
||||
}
|
||||
|
||||
public HubLobbyMaterials getLobbyMaterials() {
|
||||
return this.lobbyMaterials;
|
||||
}
|
||||
@ -1824,14 +1818,14 @@ public class Warzone {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setWarzoneMaterials(WarzoneMaterials warzoneMaterials) {
|
||||
this.warzoneMaterials = warzoneMaterials;
|
||||
}
|
||||
|
||||
public WarzoneMaterials getWarzoneMaterials() {
|
||||
return warzoneMaterials;
|
||||
}
|
||||
|
||||
public void setWarzoneMaterials(WarzoneMaterials warzoneMaterials) {
|
||||
this.warzoneMaterials = warzoneMaterials;
|
||||
}
|
||||
|
||||
public Scoreboard getScoreboard() {
|
||||
return scoreboard;
|
||||
}
|
||||
@ -1839,6 +1833,7 @@ public class Warzone {
|
||||
public ScoreboardType getScoreboardType() {
|
||||
return this.getWarzoneConfig().getScoreboardType(WarzoneConfig.SCOREBOARD);
|
||||
}
|
||||
|
||||
public boolean hasKillCount(String player) {
|
||||
return killCount.containsKey(player);
|
||||
}
|
||||
@ -1934,7 +1929,6 @@ public class Warzone {
|
||||
return zoneCap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the amount of players in all teams in this warzone. Same as
|
||||
* {@link #getPlayerCount()}, except only checks teams that the specified
|
||||
@ -2117,11 +2111,19 @@ public class Warzone {
|
||||
return this.isFlagThief(suspect) || this.isBombThief(suspect) || this.isCakeThief(suspect);
|
||||
}
|
||||
|
||||
public boolean getPvpReady() {
|
||||
return this.pvpReady;
|
||||
}
|
||||
|
||||
public void setPvpReady(boolean ready) {
|
||||
this.pvpReady = ready;
|
||||
}
|
||||
|
||||
public boolean getPvpReady() {
|
||||
return this.pvpReady;
|
||||
public enum LeaveCause {
|
||||
COMMAND, DISCONNECT, SCORECAP, RESET;
|
||||
|
||||
public boolean useRallyPoint() {
|
||||
return this == SCORECAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user