Fix respawn after game end with realdeaths

Closes #793

Please note this is not a simple fix and applies it through a large
series of changes that may need to be noted in case of further troubles
in the future.

To accomplish this correctly, if a player is a really dead fighter, his
state and position will not be updated in a number of places. This is
all handled by the respawn hook for really dead fighters, which by the
way I rewrote because yolo. It makes a (potentially incorrect)
assumption that there is no reason a zone should hold a previous player
state when they join, so it is deleted for safety purposes. If not, and
the player leaves the zone, they may lose items. This may fix other
related inventory reset issues.
This commit is contained in:
cmastudios 2014-06-12 20:59:01 -05:00
parent bdc961c7e1
commit df1e5a56df
4 changed files with 53 additions and 29 deletions

View File

@ -464,7 +464,9 @@ public class Team {
}
thePlayer.setFireTicks(0);
thePlayer.setRemainingAir(300);
this.warzone.restorePlayerState(thePlayer);
if (!this.warzone.getReallyDeadFighters().contains(thePlayer.getName())) {
this.warzone.restorePlayerState(thePlayer);
}
this.warzone.getLoadoutSelections().remove(thePlayer);
}

View File

@ -186,6 +186,15 @@ public class Warzone {
return null;
}
public static Warzone getZoneForDeadPlayer(Player player) {
for (Warzone warzone : War.war.getWarzones()) {
if (warzone.getReallyDeadFighters().contains(player.getName())) {
return warzone;
}
}
return null;
}
public boolean ready() {
if (this.volume.hasTwoCorners() && !this.volume.tooSmall() && !this.volume.tooBig()) {
return true;
@ -305,11 +314,13 @@ public class Warzone {
// everyone back to team spawn with full health
for (Team team : this.teams) {
for (Player player : team.getPlayers()) {
if (respawnExempted == null
|| (respawnExempted != null
&& !player.getName().equals(respawnExempted.getName()))) {
this.respawnPlayer(team, player);
if (player.equals(respawnExempted)) {
continue;
}
if (this.getReallyDeadFighters().contains(player.getName())) {
continue;
}
this.respawnPlayer(team, player);
}
team.setRemainingLives(team.getTeamConfig().resolveInt(TeamConfig.LIFEPOOL));
team.initializeTeamSpawns();
@ -370,7 +381,6 @@ public class Warzone {
this.flagThieves.clear();
this.bombThieves.clear();
this.cakeThieves.clear();
this.reallyDeadFighters.clear();
if (this.getScoreboardType() != ScoreboardType.NONE) {
this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
scoreboard.registerNewObjective(this.getScoreboardType().getDisplayName(), "dummy");
@ -959,10 +969,14 @@ public class Warzone {
}
team.addPlayer(player);
team.resetSign();
if (!this.hasPlayerState(player.getName())) {
this.keepPlayerState(player);
War.war.msg(player, "join.inventorystored");
if (this.hasPlayerState(player.getName())) {
War.war.getLogger().log(Level.WARNING, "Player {0} in warzone {1} already has a stored state - they may have lost items",
new Object[] {player.getName(), this.getName()});
this.playerStates.remove(player.getName());
}
this.getReallyDeadFighters().remove(player.getName());
this.keepPlayerState(player);
War.war.msg(player, "join.inventorystored");
this.respawnPlayer(team, player);
this.broadcast("join.broadcast", player.getName(), team.getKind().getFormattedName());
return true;

View File

@ -53,7 +53,9 @@ public class ResetZoneCommand extends AbstractZoneMakerCommand {
Player p = it.next();
it.remove();
team.removePlayer(p);
p.teleport(zone.getEndTeleport(LeaveCause.RESET));
if (!zone.getReallyDeadFighters().contains(p.getName())) {
p.teleport(zone.getEndTeleport(LeaveCause.RESET));
}
}
team.resetPoints();
team.getPlayers().clear();

View File

@ -4,6 +4,8 @@ import java.util.HashMap;
import java.util.List;
import com.tommytony.war.config.WarConfig;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.Location;
@ -43,6 +45,7 @@ import com.tommytony.war.utility.Direction;
import com.tommytony.war.utility.Loadout;
import com.tommytony.war.utility.LoadoutSelection;
import com.tommytony.war.volume.Volume;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
@ -874,27 +877,30 @@ public class WarPlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) {
if (War.war.isLoaded()) {
// Anyone who died in warzones needs to go back there pronto!
for (Warzone zone : War.war.getWarzones()) {
if (zone.getReallyDeadFighters().contains(event.getPlayer().getName())) {
zone.getReallyDeadFighters().remove(event.getPlayer().getName());
for (Team team : zone.getTeams()) {
if (team.getPlayers().contains(event.getPlayer())) {
event.setRespawnLocation(team.getRandomSpawn());
zone.respawnPlayer(team, event.getPlayer());
return;
}
}
if (zone.hasPlayerState(event.getPlayer().getName())) {
// If not member of a team and zone has your state, then game ended while you were dead
War.war.log("Failed to restore game state to dead player.", Level.WARNING);
}
break;
}
Warzone playingZone = Warzone.getZoneByPlayerName(event.getPlayer().getName());
Warzone deadZone = Warzone.getZoneForDeadPlayer(event.getPlayer());
if (playingZone == null && deadZone != null) {
// Game ended while player was dead, so restore state
deadZone.getReallyDeadFighters().remove(event.getPlayer().getName());
if (deadZone.hasPlayerState(event.getPlayer().getName())) {
deadZone.restorePlayerState(event.getPlayer());
}
event.setRespawnLocation(deadZone.getEndTeleport(LeaveCause.DISCONNECT));
return;
} else if (playingZone == null) {
// Player not playing war
return;
} else if (deadZone == null) {
// Player is not a 'really' dead player, nothing to do here
return;
}
Team team = playingZone.getPlayerTeam(event.getPlayer().getName());
Validate.notNull(team, String.format(
"Failed to find a team for player %s in warzone %s on respawn.",
event.getPlayer().getName(), playingZone.getName()));
playingZone.getReallyDeadFighters().remove(event.getPlayer().getName());
event.setRespawnLocation(team.getRandomSpawn());
playingZone.respawnPlayer(team, event.getPlayer());
}
@EventHandler