mirror of https://github.com/taoneill/war.git
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:
parent
bdc961c7e1
commit
df1e5a56df
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue