Add support for multiple spawn points. Closes gh-628.

/setteam <color> now will add an additional spawn point if the team already
exists.

When a player joins a team in a warzone, they will be sent to any one of
their teams spawn points, picked at random.

This change required major modifications to the underlying teams subsystem
in order to support multiple spawn points for the team.
This commit is contained in:
cmastudios 2013-08-08 23:27:09 -05:00
parent 200ae92e0f
commit 5a571e7329
11 changed files with 182 additions and 110 deletions

View File

@ -26,6 +26,10 @@ import com.tommytony.war.utility.Direction;
import com.tommytony.war.utility.SignHelper; import com.tommytony.war.utility.SignHelper;
import com.tommytony.war.volume.BlockInfo; import com.tommytony.war.volume.BlockInfo;
import com.tommytony.war.volume.Volume; import com.tommytony.war.volume.Volume;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import org.kitteh.tag.TagAPI; import org.kitteh.tag.TagAPI;
/** /**
@ -35,12 +39,12 @@ import org.kitteh.tag.TagAPI;
*/ */
public class Team { public class Team {
private List<Player> players = new ArrayList<Player>(); private List<Player> players = new ArrayList<Player>();
private Location teamSpawn = null; private List<Location> teamSpawns;
private Location teamFlag = null; private Location teamFlag = null;
private String name; private String name;
private int remainingLives; private int remainingLives;
private int points = 0; private int points = 0;
private Volume spawnVolume; private Map<Location, Volume> spawnVolumes;
private Volume flagVolume; private Volume flagVolume;
private final Warzone warzone; private final Warzone warzone;
private TeamKind kind; private TeamKind kind;
@ -48,13 +52,16 @@ public class Team {
private TeamConfigBag teamConfig; private TeamConfigBag teamConfig;
private InventoryBag inventories; private InventoryBag inventories;
public Team(String name, TeamKind kind, Location teamSpawn, Warzone warzone) { public Team(String name, TeamKind kind, List<Location> teamSpawn, Warzone warzone) {
this.warzone = warzone; this.warzone = warzone;
this.teamConfig = new TeamConfigBag(warzone); this.teamConfig = new TeamConfigBag(warzone);
this.inventories = new InventoryBag(warzone); // important constructors for cascading configs this.inventories = new InventoryBag(warzone); // important constructors for cascading configs
this.setName(name); this.setName(name);
this.teamSpawn = teamSpawn; this.teamSpawns = new ArrayList(teamSpawn);
this.setSpawnVolume(new Volume(name, warzone.getWorld())); this.spawnVolumes = new HashMap();
for (Location spawn : teamSpawn) {
this.setSpawnVolume(spawn, new Volume(name + teamSpawns.indexOf(spawn), warzone.getWorld()));
}
this.kind = kind; this.kind = kind;
this.setFlagVolume(null); // no flag at the start this.setFlagVolume(null); // no flag at the start
} }
@ -73,50 +80,39 @@ public class Team {
return this.kind; return this.kind;
} }
private void setSpawnVolume() { private void createSpawnVolume(Location teamSpawn) {
if (this.spawnVolume.isSaved()) { Volume spawnVolume = this.spawnVolumes.get(teamSpawn);
this.spawnVolume.resetBlocks(); if (spawnVolume.isSaved()) {
spawnVolume.resetBlocks();
} }
int x = this.teamSpawn.getBlockX(); int x = teamSpawn.getBlockX();
int y = this.teamSpawn.getBlockY(); int y = teamSpawn.getBlockY();
int z = this.teamSpawn.getBlockZ(); int z = teamSpawn.getBlockZ();
TeamSpawnStyle style = this.getTeamConfig().resolveSpawnStyle(); TeamSpawnStyle style = this.getTeamConfig().resolveSpawnStyle();
if (style.equals(TeamSpawnStyle.INVISIBLE)) { if (style.equals(TeamSpawnStyle.INVISIBLE)) {
this.spawnVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x, y - 1, z)); spawnVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x, y - 1, z));
this.spawnVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x, y + 3, z)); spawnVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x, y + 3, z));
} else if (style.equals(TeamSpawnStyle.SMALL)) { } else if (style.equals(TeamSpawnStyle.SMALL)) {
this.spawnVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x - 1, y - 1, z - 1)); spawnVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x - 1, y - 1, z - 1));
this.spawnVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x + 1, y + 3, z + 1)); spawnVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x + 1, y + 3, z + 1));
} else { } else {
// flat or big // flat or big
this.spawnVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x - 2, y - 1, z - 2)); spawnVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x - 2, y - 1, z - 2));
this.spawnVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x + 2, y + 3, z + 2)); spawnVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x + 2, y + 3, z + 2));
} }
} }
@SuppressWarnings("unused") public void initializeTeamSpawns() {
public void initializeTeamSpawn() { for (Location teamSpawn : this.spawnVolumes.keySet()) {
// make air (old two-high above floor) initializeTeamSpawn(teamSpawn);
Volume airGap = new Volume("airgap", this.warzone.getWorld()); }
airGap.setCornerOne(new BlockInfo( }
this.spawnVolume.getCornerOne().getX(), public void initializeTeamSpawn(Location teamSpawn) {
this.spawnVolume.getCornerOne().getY() + 1,
this.spawnVolume.getCornerOne().getZ(),
0,
(byte)0));
airGap.setCornerTwo(new BlockInfo(
this.spawnVolume.getCornerTwo().getX(),
this.spawnVolume.getCornerOne().getY() + 2,
this.spawnVolume.getCornerTwo().getZ(),
0,
(byte)0));
airGap.setToMaterial(Material.AIR);
// Set the spawn // Set the spawn
int x = this.teamSpawn.getBlockX(); int x = teamSpawn.getBlockX();
int y = this.teamSpawn.getBlockY(); int y = teamSpawn.getBlockY();
int z = this.teamSpawn.getBlockZ(); int z = teamSpawn.getBlockZ();
Material light = Material.getMaterial(this.warzone.getWarzoneMaterials().getLightId()); Material light = Material.getMaterial(this.warzone.getWarzoneMaterials().getLightId());
byte lightData = this.warzone.getWarzoneMaterials().getLightData(); byte lightData = this.warzone.getWarzoneMaterials().getLightData();
@ -139,10 +135,10 @@ public class Team {
// Orientation // Orientation
int yaw = 0; int yaw = 0;
if (this.teamSpawn.getYaw() >= 0) { if (teamSpawn.getYaw() >= 0) {
yaw = (int) (this.teamSpawn.getYaw() % 360); yaw = (int) (teamSpawn.getYaw() % 360);
} else { } else {
yaw = (int) (360 + (this.teamSpawn.getYaw() % 360)); yaw = (int) (360 + (teamSpawn.getYaw() % 360));
} }
Block signBlock = null; Block signBlock = null;
int signData = 0; int signData = 0;
@ -344,18 +340,25 @@ public class Team {
block.setData(kind.getData()); block.setData(kind.getData());
} }
public void setTeamSpawn(Location teamSpawn) { public void addTeamSpawn(Location teamSpawn) {
this.teamSpawn = teamSpawn; if (!this.teamSpawns.contains(teamSpawn)) {
this.teamSpawns.add(teamSpawn);
}
// this resets the block to old state // this resets the block to old state
this.setSpawnVolume(); this.setSpawnVolume(teamSpawn, new Volume(name + teamSpawns.indexOf(teamSpawn), warzone.getWorld()));
this.getSpawnVolume().saveBlocks(); this.createSpawnVolume(teamSpawn);
this.spawnVolumes.get(teamSpawn).saveBlocks();
this.initializeTeamSpawn(); this.initializeTeamSpawn(teamSpawn);
} }
public Location getTeamSpawn() { public List<Location> getTeamSpawns() {
return this.teamSpawn; return this.teamSpawns;
}
Random teamSpawnRandomizer = new Random();
public Location getRandomSpawn() {
return this.teamSpawns.get(teamSpawnRandomizer.nextInt(this.teamSpawns.size()));
} }
public void addPlayer(Player player) { public void addPlayer(Player player) {
@ -473,22 +476,24 @@ public class Team {
return this.points; return this.points;
} }
public Volume getSpawnVolume() { public Map<Location, Volume> getSpawnVolumes() {
return this.spawnVolume; return this.spawnVolumes;
} }
public void resetSign() { public void resetSign() {
this.getSpawnVolume().resetBlocks(); for (Entry<Location, Volume> spawnEntry : this.getSpawnVolumes().entrySet()) {
this.initializeTeamSpawn(); // reset everything instead of just sign spawnEntry.getValue().resetBlocks();
this.initializeTeamSpawn(spawnEntry.getKey()); // reset everything instead of just sign
}
if (this.warzone.getLobby() != null) { if (this.warzone.getLobby() != null) {
this.warzone.getLobby().resetTeamGateSign(this); this.warzone.getLobby().resetTeamGateSign(this);
} }
} }
public void setSpawnVolume(Volume volume) { public void setSpawnVolume(Location spawnLocation, Volume volume) {
this.spawnVolume = volume; this.spawnVolumes.put(spawnLocation, volume);
} }
public void resetPoints() { public void resetPoints() {
@ -673,4 +678,19 @@ public class Team {
public TeamConfigBag getTeamConfig() { public TeamConfigBag getTeamConfig() {
return this.teamConfig; return this.teamConfig;
} }
/**
* Check if any team spawns contain a certain location.
*
* @param loc Location to check if contained by a spawn.
* @return true if loc is part of a spawn volume, false otherwise.
*/
public boolean isSpawnLocation(Location loc) {
for (Volume spawnVolume : this.spawnVolumes.values()) {
if (spawnVolume.contains(loc)) {
return true;
}
}
return false;
}
} }

View File

@ -55,6 +55,7 @@ import com.tommytony.war.utility.Loadout;
import com.tommytony.war.utility.PlayerState; import com.tommytony.war.utility.PlayerState;
import com.tommytony.war.utility.SizeCounter; import com.tommytony.war.utility.SizeCounter;
import com.tommytony.war.utility.WarLogFormatter; import com.tommytony.war.utility.WarLogFormatter;
import com.tommytony.war.volume.Volume;
/** /**
* Main class of War * Main class of War
@ -639,8 +640,10 @@ public class War extends JavaPlugin {
bomb.addBombBlocks(); bomb.addBombBlocks();
} }
for (Team team : warzone.getTeams()) { for (Team team : warzone.getTeams()) {
team.getSpawnVolume().resetBlocks(); for (Volume spawnVolume : team.getSpawnVolumes().values()) {
team.initializeTeamSpawn(); spawnVolume.resetBlocks();
}
team.initializeTeamSpawns();
if (team.getTeamFlag() != null) { if (team.getTeamFlag() != null) {
team.getFlagVolume().resetBlocks(); team.getFlagVolume().resetBlocks();
team.initializeTeamFlag(); team.initializeTeamFlag();

View File

@ -225,7 +225,9 @@ public class Warzone {
this.zoneWallGuards.clear(); this.zoneWallGuards.clear();
for (Team team : this.teams) { for (Team team : this.teams) {
team.getSpawnVolume().resetBlocks(); for (Volume teamVolume : team.getSpawnVolumes().values()) {
teamVolume.resetBlocks();
}
if (team.getTeamFlag() != null) { if (team.getTeamFlag() != null) {
team.getFlagVolume().resetBlocks(); team.getFlagVolume().resetBlocks();
} }
@ -270,7 +272,7 @@ public class Warzone {
} }
} }
team.setRemainingLives(team.getTeamConfig().resolveInt(TeamConfig.LIFEPOOL)); team.setRemainingLives(team.getTeamConfig().resolveInt(TeamConfig.LIFEPOOL));
team.initializeTeamSpawn(); team.initializeTeamSpawns();
if (team.getTeamFlag() != null) { if (team.getTeamFlag() != null) {
team.setTeamFlag(team.getTeamFlag()); team.setTeamFlag(team.getTeamFlag());
} }
@ -353,13 +355,13 @@ public class Warzone {
public void respawnPlayer(Team team, Player player) { public void respawnPlayer(Team team, Player player) {
this.handleRespawn(team, player); this.handleRespawn(team, player);
// Teleport the player back to spawn // Teleport the player back to spawn
player.teleport(team.getTeamSpawn()); player.teleport(team.getRandomSpawn());
} }
public void respawnPlayer(PlayerMoveEvent event, Team team, Player player) { public void respawnPlayer(PlayerMoveEvent event, Team team, Player player) {
this.handleRespawn(team, player); this.handleRespawn(team, player);
// Teleport the player back to spawn // Teleport the player back to spawn
event.setTo(team.getTeamSpawn()); event.setTo(team.getRandomSpawn());
} }
public boolean isRespawning(Player p) { public boolean isRespawning(Player p) {
@ -647,9 +649,12 @@ public class Warzone {
} }
} }
for (Team t : this.teams) { for (Team t : this.teams) {
if (t.getSpawnVolume().contains(block)) { for (Volume tVolume : t.getSpawnVolumes().values()) {
return true; if (tVolume.contains(block)) {
} else if (t.getFlagVolume() != null && t.getFlagVolume().contains(block)) { return true;
}
}
if (t.getFlagVolume() != null && t.getFlagVolume().contains(block)) {
return true; return true;
} }
} }
@ -1483,12 +1488,14 @@ public class Warzone {
public boolean isOpponentSpawnPeripheryBlock(Team team, Block block) { public boolean isOpponentSpawnPeripheryBlock(Team team, Block block) {
for (Team maybeOpponent : this.getTeams()) { for (Team maybeOpponent : this.getTeams()) {
if (maybeOpponent != team) { if (maybeOpponent != team) {
Volume periphery = new Volume("periphery", this.getWorld()); for (Volume teamSpawnVolume : maybeOpponent.getSpawnVolumes().values()) {
periphery.setCornerOne(new BlockInfo(maybeOpponent.getSpawnVolume().getMinX()-1 , maybeOpponent.getSpawnVolume().getMinY()-1, maybeOpponent.getSpawnVolume().getMinZ()-1, 0, (byte)0)); Volume periphery = new Volume("periphery", this.getWorld());
periphery.setCornerTwo(new BlockInfo(maybeOpponent.getSpawnVolume().getMaxX()+1, maybeOpponent.getSpawnVolume().getMaxY()+1, maybeOpponent.getSpawnVolume().getMaxZ()+1, 0, (byte)0)); periphery.setCornerOne(new BlockInfo(teamSpawnVolume.getMinX()-1 , teamSpawnVolume.getMinY()-1, teamSpawnVolume.getMinZ()-1, 0, (byte)0));
periphery.setCornerTwo(new BlockInfo(teamSpawnVolume.getMaxX()+1, teamSpawnVolume.getMaxY()+1, teamSpawnVolume.getMaxZ()+1, 0, (byte)0));
if (periphery.contains(block)) { if (periphery.contains(block)) {
return true; return true;
}
} }
} }
} }

View File

@ -12,6 +12,7 @@ import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamKind; import com.tommytony.war.config.TeamKind;
import com.tommytony.war.mapper.WarzoneYmlMapper; import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby; import com.tommytony.war.structure.ZoneLobby;
import com.tommytony.war.volume.Volume;
/** /**
* Deletes a team. * Deletes a team.
@ -59,7 +60,9 @@ public class DeleteTeamCommand extends AbstractZoneMakerCommand {
if (team.getFlagVolume() != null) { if (team.getFlagVolume() != null) {
team.getFlagVolume().resetBlocks(); team.getFlagVolume().resetBlocks();
} }
team.getSpawnVolume().resetBlocks(); for (Volume spawnVolume : team.getSpawnVolumes().values()) {
spawnVolume.resetBlocks();
}
zone.getTeams().remove(team); zone.getTeams().remove(team);
if (zone.getLobby() != null) { if (zone.getLobby() != null) {
zone.getLobby().setLocation(zone.getTeleport()); zone.getLobby().setLocation(zone.getTeleport());

View File

@ -12,6 +12,8 @@ import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamConfig; import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.TeamKind; import com.tommytony.war.config.TeamKind;
import com.tommytony.war.mapper.WarzoneYmlMapper; import com.tommytony.war.mapper.WarzoneYmlMapper;
import java.util.Collections;
import org.bukkit.Location;
/** /**
* Places a soawn * Places a soawn
@ -50,20 +52,20 @@ public class SetTeamCommand extends AbstractZoneMakerCommand {
} else { } else {
Team existingTeam = zone.getTeamByKind(teamKind); Team existingTeam = zone.getTeamByKind(teamKind);
if (existingTeam != null) { if (existingTeam != null) {
// relocate // add additional spawn
existingTeam.setTeamSpawn(player.getLocation()); existingTeam.addTeamSpawn(player.getLocation());
this.msg("Team " + existingTeam.getName() + " spawn relocated."); this.msg("Additional spawn added for team " + existingTeam.getName() + ". Use /deleteteam " + existingTeam.getName() + " to remove all spawns.");
War.war.log(this.getSender().getName() + " moved team " + existingTeam.getName() + " in warzone " + zone.getName(), Level.INFO); War.war.log(this.getSender().getName() + " moved team " + existingTeam.getName() + " in warzone " + zone.getName(), Level.INFO);
} else { } else {
// new team (use default TeamKind name for now) // new team (use default TeamKind name for now)
Team newTeam = new Team(teamKind.toString(), teamKind, player.getLocation(), zone); Team newTeam = new Team(teamKind.toString(), teamKind, Collections.<Location>emptyList(), zone);
newTeam.setRemainingLives(newTeam.getTeamConfig().resolveInt(TeamConfig.LIFEPOOL)); newTeam.setRemainingLives(newTeam.getTeamConfig().resolveInt(TeamConfig.LIFEPOOL));
zone.getTeams().add(newTeam); zone.getTeams().add(newTeam);
if (zone.getLobby() != null) { if (zone.getLobby() != null) {
zone.getLobby().setLocation(zone.getTeleport()); zone.getLobby().setLocation(zone.getTeleport());
zone.getLobby().initialize(); zone.getLobby().initialize();
} }
newTeam.setTeamSpawn(player.getLocation()); newTeam.addTeamSpawn(player.getLocation());
this.msg("Team " + newTeam.getName() + " created with spawn here."); this.msg("Team " + newTeam.getName() + " created with spawn here.");
War.war.log(this.getSender().getName() + " created team " + newTeam.getName() + " in warzone " + zone.getName(), Level.INFO); War.war.log(this.getSender().getName() + " created team " + newTeam.getName() + " in warzone " + zone.getName(), Level.INFO);
} }

View File

@ -277,7 +277,7 @@ public class WarBlockListener implements Listener {
// changes in parts of important areas // changes in parts of important areas
if (warzone != null && warzone.isImportantBlock(block) && (!isZoneMaker || (isZoneMaker && team != null))) { if (warzone != null && warzone.isImportantBlock(block) && (!isZoneMaker || (isZoneMaker && team != null))) {
// breakage of spawn // breakage of spawn
if (team != null && team.getSpawnVolume().contains(block)) { if (team != null && team.isSpawnLocation(block.getLocation())) {
ItemStack teamKindBlock = new ItemStack(team.getKind().getMaterial(), team.getKind().getData()); ItemStack teamKindBlock = new ItemStack(team.getKind().getMaterial(), team.getKind().getData());
// let team members loot one block the spawn for monument captures // let team members loot one block the spawn for monument captures
if (player.getInventory().contains(teamKindBlock)) { if (player.getInventory().contains(teamKindBlock)) {

View File

@ -431,7 +431,7 @@ public class WarEntityListener implements Listener {
if (zone != null && team != null) { if (zone != null && team != null) {
LoadoutSelection playerLoadoutState = zone.getLoadoutSelections().get(player.getName()); LoadoutSelection playerLoadoutState = zone.getLoadoutSelections().get(player.getName());
if (team.getSpawnVolume().contains(player.getLocation()) if (team.isSpawnLocation(player.getLocation())
&& playerLoadoutState != null && playerLoadoutState.isStillInSpawn()) { && playerLoadoutState != null && playerLoadoutState.isStillInSpawn()) {
// don't let a player still in spawn get damaged // don't let a player still in spawn get damaged
event.setCancelled(true); event.setCancelled(true);
@ -475,6 +475,7 @@ public class WarEntityListener implements Listener {
} }
@EventHandler @EventHandler
// TODO Remove due to deletion of cantreenterspawnjob
public void onEntityCombust(final EntityDamageEvent event) { public void onEntityCombust(final EntityDamageEvent event) {
if (!War.war.isLoaded()) { if (!War.war.isLoaded()) {
return; return;
@ -483,7 +484,7 @@ public class WarEntityListener implements Listener {
if (entity instanceof Player) { if (entity instanceof Player) {
Player player = (Player) entity; Player player = (Player) entity;
Team team = Team.getTeamByPlayerName(player.getName()); Team team = Team.getTeamByPlayerName(player.getName());
if (team != null && team.getSpawnVolume().contains(player.getLocation())) { if (team != null && team.isSpawnLocation(player.getLocation())) {
// smother out the fire that didn't burn out when you respawned // smother out the fire that didn't burn out when you respawned
// Stop fire // Stop fire
player.setFireTicks(0); player.setFireTicks(0);

View File

@ -42,6 +42,7 @@ import com.tommytony.war.structure.ZoneLobby;
import com.tommytony.war.utility.Direction; import com.tommytony.war.utility.Direction;
import com.tommytony.war.utility.Loadout; import com.tommytony.war.utility.Loadout;
import com.tommytony.war.utility.LoadoutSelection; import com.tommytony.war.utility.LoadoutSelection;
import com.tommytony.war.volume.Volume;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
@ -393,7 +394,7 @@ public class WarPlayerListener implements Listener {
if (isLeaving) { // already in a team and in warzone, leaving if (isLeaving) { // already in a team and in warzone, leaving
// same as leave // same as leave
if (playerTeam != null) { if (playerTeam != null) {
boolean atSpawnAlready = playerTeam.getTeamSpawn().getBlockX() == player.getLocation().getBlockX() && playerTeam.getTeamSpawn().getBlockY() == player.getLocation().getBlockY() && playerTeam.getTeamSpawn().getBlockZ() == player.getLocation().getBlockZ(); boolean atSpawnAlready = playerTeam.isSpawnLocation(playerLoc);
if (!atSpawnAlready) { if (!atSpawnAlready) {
playerWarzone.handlePlayerLeave(player, playerWarzone.getTeleport(), event, true); playerWarzone.handlePlayerLeave(player, playerWarzone.getTeleport(), event, true);
return; return;
@ -435,7 +436,7 @@ public class WarPlayerListener implements Listener {
upDownMove -= moveDistance; upDownMove -= moveDistance;
} else if (nearestWalls.contains(BlockFace.DOWN)) { } else if (nearestWalls.contains(BlockFace.DOWN)) {
// fell off the map, back to spawn // fell off the map, back to spawn
event.setTo(playerTeam.getTeamSpawn()); event.setTo(playerTeam.getRandomSpawn());
return; return;
} }
@ -502,13 +503,13 @@ public class WarPlayerListener implements Listener {
LoadoutSelection loadoutSelectionState = playerWarzone.getLoadoutSelections().get(player.getName()); LoadoutSelection loadoutSelectionState = playerWarzone.getLoadoutSelections().get(player.getName());
FlagReturn flagReturn = playerTeam.getTeamConfig().resolveFlagReturn(); FlagReturn flagReturn = playerTeam.getTeamConfig().resolveFlagReturn();
if (!playerTeam.getSpawnVolume().contains(playerLoc)) { if (!playerTeam.isSpawnLocation(playerLoc)) {
if (!playerWarzone.isEnoughPlayers() && loadoutSelectionState != null && loadoutSelectionState.isStillInSpawn()) { if (!playerWarzone.isEnoughPlayers() && loadoutSelectionState != null && loadoutSelectionState.isStillInSpawn()) {
// Be sure to keep only players that just respawned locked inside the spawn for minplayer/minteams restrictions - otherwise // Be sure to keep only players that just respawned locked inside the spawn for minplayer/minteams restrictions - otherwise
// this will conflict with the can't-renter-spawn bump just a few lines below // this will conflict with the can't-renter-spawn bump just a few lines below
War.war.badMsg(player, "Can't leave spawn until there's a minimum of " + playerWarzone.getWarzoneConfig().getInt(WarzoneConfig.MINPLAYERS) War.war.badMsg(player, "Can't leave spawn until there's a minimum of " + playerWarzone.getWarzoneConfig().getInt(WarzoneConfig.MINPLAYERS)
+" player(s) on at least " + playerWarzone.getWarzoneConfig().getInt(WarzoneConfig.MINTEAMS) + " team(s)."); +" player(s) on at least " + playerWarzone.getWarzoneConfig().getInt(WarzoneConfig.MINTEAMS) + " team(s).");
event.setTo(playerTeam.getTeamSpawn()); event.setTo(playerTeam.getRandomSpawn());
return; return;
} }
if (playerWarzone.isRespawning(player)) { if (playerWarzone.isRespawning(player)) {
@ -518,7 +519,7 @@ public class WarPlayerListener implements Listener {
isS = ""; isS = "";
} }
War.war.badMsg(player, "Can't leave spawn for " + rt + " second" + isS + " after spawning!"); War.war.badMsg(player, "Can't leave spawn for " + rt + " second" + isS + " after spawning!");
event.setTo(playerTeam.getTeamSpawn()); event.setTo(playerTeam.getRandomSpawn());
return; return;
} }
} else if (loadoutSelectionState != null && !loadoutSelectionState.isStillInSpawn() } else if (loadoutSelectionState != null && !loadoutSelectionState.isStillInSpawn()
@ -567,7 +568,7 @@ public class WarPlayerListener implements Listener {
// Make sure game ends can't occur simultaneously. // Make sure game ends can't occur simultaneously.
// See Warzone.handleDeath() for details. // See Warzone.handleDeath() for details.
boolean inSpawn = playerTeam.getSpawnVolume().contains(player.getLocation()); boolean inSpawn = playerTeam.isSpawnLocation(player.getLocation());
boolean inFlag = (playerTeam.getFlagVolume() != null && playerTeam.getFlagVolume().contains(player.getLocation())); boolean inFlag = (playerTeam.getFlagVolume() != null && playerTeam.getFlagVolume().contains(player.getLocation()));
if (playerTeam.getTeamConfig().resolveFlagReturn().equals(FlagReturn.BOTH)) { if (playerTeam.getTeamConfig().resolveFlagReturn().equals(FlagReturn.BOTH)) {
@ -662,7 +663,7 @@ public class WarPlayerListener implements Listener {
Team victim = null; Team victim = null;
for (Team team : playerWarzone.getTeams()) { for (Team team : playerWarzone.getTeams()) {
if (team != playerTeam if (team != playerTeam
&& team.getSpawnVolume().contains(player.getLocation()) && team.isSpawnLocation(player.getLocation())
&& team.getPlayers().size() > 0) { && team.getPlayers().size() > 0) {
inEnemySpawn = true; inEnemySpawn = true;
victim = team; victim = team;
@ -718,8 +719,10 @@ public class WarPlayerListener implements Listener {
// just added a point // just added a point
// restore bombed team's spawn // restore bombed team's spawn
victim.getSpawnVolume().resetBlocks(); for (Volume spawnVolume : victim.getSpawnVolumes().values()) {
victim.initializeTeamSpawn(); spawnVolume.resetBlocks();
}
victim.initializeTeamSpawns();
// bring back tnt // bring back tnt
bomb.getVolume().resetBlocks(); bomb.getVolume().resetBlocks();
@ -746,7 +749,7 @@ public class WarPlayerListener implements Listener {
// Make sure game ends can't occur simultaneously. // Make sure game ends can't occur simultaneously.
// Not thread safe. See Warzone.handleDeath() for details. // Not thread safe. See Warzone.handleDeath() for details.
boolean inSpawn = playerTeam.getSpawnVolume().contains(player.getLocation()); boolean inSpawn = playerTeam.isSpawnLocation(player.getLocation());
if (inSpawn && playerTeam.getPlayers().contains(player)) { if (inSpawn && playerTeam.getPlayers().contains(player)) {
// Made sure player is still part of team, game may have ended while waiting. // Made sure player is still part of team, game may have ended while waiting.
@ -819,7 +822,7 @@ public class WarPlayerListener implements Listener {
} }
// Class selection lock // Class selection lock
if (!playerTeam.getSpawnVolume().contains(player.getLocation()) && if (!playerTeam.isSpawnLocation(player.getLocation()) &&
playerWarzone.getLoadoutSelections().keySet().contains(player.getName()) playerWarzone.getLoadoutSelections().keySet().contains(player.getName())
&& playerWarzone.getLoadoutSelections().get(player.getName()).isStillInSpawn()) { && playerWarzone.getLoadoutSelections().get(player.getName()).isStillInSpawn()) {
playerWarzone.getLoadoutSelections().get(player.getName()).setStillInSpawn(false); playerWarzone.getLoadoutSelections().get(player.getName()).setStillInSpawn(false);
@ -839,7 +842,7 @@ public class WarPlayerListener implements Listener {
if (War.war.isLoaded() && event.isSneaking()) { if (War.war.isLoaded() && event.isSneaking()) {
Warzone playerWarzone = Warzone.getZoneByLocation(event.getPlayer()); Warzone playerWarzone = Warzone.getZoneByLocation(event.getPlayer());
Team playerTeam = Team.getTeamByPlayerName(event.getPlayer().getName()); Team playerTeam = Team.getTeamByPlayerName(event.getPlayer().getName());
if (playerWarzone != null && playerTeam != null && playerTeam.getInventories().resolveLoadouts().keySet().size() > 1 && playerTeam.getSpawnVolume().contains(event.getPlayer().getLocation())) { if (playerWarzone != null && playerTeam != null && playerTeam.getInventories().resolveLoadouts().keySet().size() > 1 && playerTeam.isSpawnLocation(event.getPlayer().getLocation())) {
if (playerWarzone.getLoadoutSelections().keySet().contains(event.getPlayer().getName()) if (playerWarzone.getLoadoutSelections().keySet().contains(event.getPlayer().getName())
&& playerWarzone.getLoadoutSelections().get(event.getPlayer().getName()).isStillInSpawn()) { && playerWarzone.getLoadoutSelections().get(event.getPlayer().getName()).isStillInSpawn()) {
LoadoutSelection selection = playerWarzone.getLoadoutSelections().get(event.getPlayer().getName()); LoadoutSelection selection = playerWarzone.getLoadoutSelections().get(event.getPlayer().getName());
@ -875,7 +878,7 @@ public class WarPlayerListener implements Listener {
zone.getReallyDeadFighters().remove(event.getPlayer().getName()); zone.getReallyDeadFighters().remove(event.getPlayer().getName());
for (Team team : zone.getTeams()) { for (Team team : zone.getTeams()) {
if (team.getPlayers().contains(event.getPlayer())) { if (team.getPlayers().contains(event.getPlayer())) {
event.setRespawnLocation(team.getTeamSpawn()); event.setRespawnLocation(team.getRandomSpawn());
zone.respawnPlayer(team, event.getPlayer()); zone.respawnPlayer(team, event.getPlayer());
break; break;
} }

View File

@ -24,6 +24,7 @@ import com.tommytony.war.structure.ZoneLobby;
import com.tommytony.war.utility.Direction; import com.tommytony.war.utility.Direction;
import com.tommytony.war.volume.Volume; import com.tommytony.war.volume.Volume;
import com.tommytony.war.volume.ZoneVolume; import com.tommytony.war.volume.ZoneVolume;
import java.util.Arrays;
/** /**
* *
@ -301,7 +302,7 @@ public class WarzoneTxtMapper {
int yaw = Integer.parseInt(teamStrSplit[4]); int yaw = Integer.parseInt(teamStrSplit[4]);
teamLocation.setYaw(yaw); teamLocation.setYaw(yaw);
} }
Team team = new Team(teamStrSplit[0], TeamKind.teamKindFromString(teamStrSplit[0]), teamLocation, warzone); Team team = new Team(teamStrSplit[0], TeamKind.teamKindFromString(teamStrSplit[0]), Arrays.asList(teamLocation), warzone);
team.setRemainingLives(warzone.getTeamDefaultConfig().resolveInt(TeamConfig.LIFEPOOL)); team.setRemainingLives(warzone.getTeamDefaultConfig().resolveInt(TeamConfig.LIFEPOOL));
warzone.getTeams().add(team); warzone.getTeams().add(team);
} }
@ -348,7 +349,9 @@ public class WarzoneTxtMapper {
// team spawn blocks // team spawn blocks
for (Team team : warzone.getTeams()) { for (Team team : warzone.getTeams()) {
team.setSpawnVolume(VolumeMapper.loadVolume(team.getName(), warzone.getName(), world)); for (Location spawnLocation : team.getTeamSpawns()) {
team.setSpawnVolume(spawnLocation, VolumeMapper.loadVolume(team.getName(), warzone.getName(), world));
}
if (team.getTeamFlag() != null) { if (team.getTeamFlag() != null) {
team.setFlagVolume(VolumeMapper.loadVolume(team.getName() + "flag", warzone.getName(), world)); team.setFlagVolume(VolumeMapper.loadVolume(team.getName() + "flag", warzone.getName(), world));
} }

View File

@ -30,6 +30,7 @@ import com.tommytony.war.utility.Direction;
import com.tommytony.war.utility.Loadout; import com.tommytony.war.utility.Loadout;
import com.tommytony.war.volume.Volume; import com.tommytony.war.volume.Volume;
import com.tommytony.war.volume.ZoneVolume; import com.tommytony.war.volume.ZoneVolume;
import java.util.Map;
public class WarzoneYmlMapper { public class WarzoneYmlMapper {
@ -196,13 +197,34 @@ public class WarzoneYmlMapper {
// try lowercase instead - supports custom team names // try lowercase instead - supports custom team names
teamInfoPrefix = "team." + teamName.toLowerCase() + ".info."; teamInfoPrefix = "team." + teamName.toLowerCase() + ".info.";
} }
int teamX = warzoneRootSection.getInt(teamInfoPrefix + "spawn.x"); List<Location> teamSpawns = new ArrayList();
int teamY = warzoneRootSection.getInt(teamInfoPrefix + "spawn.y"); if (warzoneRootSection.contains(teamInfoPrefix + "spawn")) {
int teamZ = warzoneRootSection.getInt(teamInfoPrefix + "spawn.z"); int teamX = warzoneRootSection.getInt(teamInfoPrefix + "spawn.x");
int teamYaw = warzoneRootSection.getInt(teamInfoPrefix + "spawn.yaw"); int teamY = warzoneRootSection.getInt(teamInfoPrefix + "spawn.y");
Location teamLocation = new Location(world, teamX, teamY, teamZ, teamYaw, 0); int teamZ = warzoneRootSection.getInt(teamInfoPrefix + "spawn.z");
int teamYaw = warzoneRootSection.getInt(teamInfoPrefix + "spawn.yaw");
Location teamLocation = new Location(world, teamX, teamY, teamZ, teamYaw, 0);
teamSpawns.add(teamLocation);
File original = new File(War.war.getDataFolder().getPath() + "/dat/warzone-" + name + "/volume-" + teamName + ".dat");
File modified = new File(War.war.getDataFolder().getPath() + "/dat/warzone-" + name + "/volume-" + teamName + teamSpawns.indexOf(teamLocation) + ".dat");
try {
original.renameTo(modified);
} catch (Exception e) {
// Will be logged later
}
}
if (warzoneRootSection.contains(teamInfoPrefix + "spawns")) {
for (Map<?, ?> map : warzoneRootSection.getMapList(teamInfoPrefix + "spawns")) {
int teamX = (Integer) map.get("x");
int teamY = (Integer) map.get("y");
int teamZ = (Integer) map.get("z");
int teamYaw = (Integer) map.get("yaw");
Location teamLocation = new Location(world, teamX, teamY, teamZ, teamYaw, 0);
teamSpawns.add(teamLocation);
}
}
Team team = new Team(teamName, TeamKind.teamKindFromString(teamName), teamLocation, warzone); Team team = new Team(teamName, TeamKind.teamKindFromString(teamName), teamSpawns, warzone);
warzone.getTeams().add(team); warzone.getTeams().add(team);
if (warzoneRootSection.contains(teamInfoPrefix + "flag")) { if (warzoneRootSection.contains(teamInfoPrefix + "flag")) {
@ -278,7 +300,9 @@ public class WarzoneYmlMapper {
// team spawn blocks // team spawn blocks
for (Team team : warzone.getTeams()) { for (Team team : warzone.getTeams()) {
team.setSpawnVolume(VolumeMapper.loadVolume(team.getName(), warzone.getName(), world)); for (Location teamSpawn : team.getTeamSpawns()) {
team.setSpawnVolume(teamSpawn, VolumeMapper.loadVolume(team.getName() + team.getTeamSpawns().indexOf(teamSpawn), warzone.getName(), world));
}
if (team.getTeamFlag() != null) { if (team.getTeamFlag() != null) {
team.setFlagVolume(VolumeMapper.loadVolume(team.getName() + "flag", warzone.getName(), world)); team.setFlagVolume(VolumeMapper.loadVolume(team.getName() + "flag", warzone.getName(), world));
} }
@ -570,12 +594,16 @@ public class WarzoneYmlMapper {
ConfigurationSection teamInfoSection = teamsSection.createSection(team.getName() + ".info"); ConfigurationSection teamInfoSection = teamsSection.createSection(team.getName() + ".info");
ConfigurationSection spawnSection = teamInfoSection.createSection("spawn"); List<Map<String, Object>> spawnSerilization = new ArrayList();
Location spawn = team.getTeamSpawn(); for (Location spawn : team.getTeamSpawns()) {
spawnSection.set("x", spawn.getBlockX()); Map<String, Object> map = new HashMap();
spawnSection.set("y", spawn.getBlockY()); map.put("x", spawn.getBlockX());
spawnSection.set("z", spawn.getBlockZ()); map.put("y", spawn.getBlockY());
spawnSection.set("yaw", toIntYaw(spawn.getYaw())); map.put("z", spawn.getBlockZ());
map.put("yaw", toIntYaw(spawn.getYaw()));
spawnSerilization.add(map);
}
teamInfoSection.set("spawns", spawnSerilization);
if (team.getTeamFlag() != null) { if (team.getTeamFlag() != null) {
ConfigurationSection flagSection = teamInfoSection.createSection("flag"); ConfigurationSection flagSection = teamInfoSection.createSection("flag");
@ -604,7 +632,9 @@ public class WarzoneYmlMapper {
// team spawn & flag blocks // team spawn & flag blocks
for (Team team : teams) { for (Team team : teams) {
VolumeMapper.save(team.getSpawnVolume(), warzone.getName()); for (Volume volume : team.getSpawnVolumes().values()) {
VolumeMapper.save(volume, warzone.getName());
}
if (team.getFlagVolume() != null) { if (team.getFlagVolume() != null) {
VolumeMapper.save(team.getFlagVolume(), warzone.getName()); VolumeMapper.save(team.getFlagVolume(), warzone.getName());
} }

View File

@ -229,8 +229,8 @@ public class ZoneVolume extends Volume {
public boolean zoneStructuresAreOutside() { public boolean zoneStructuresAreOutside() {
// check team spawns & flags // check team spawns & flags
for (Team team : this.zone.getTeams()) { for (Team team : this.zone.getTeams()) {
if (team.getTeamSpawn() != null) { for (Volume spawnVolume : team.getSpawnVolumes().values()) {
if (!this.isInside(team.getSpawnVolume().getCornerOne()) || !this.isInside(team.getSpawnVolume().getCornerTwo())) { if (!this.isInside(spawnVolume.getCornerOne()) || !this.isInside(spawnVolume.getCornerTwo())) {
return true; return true;
} }
} }