Fix ghost respawn bug (#17511)

This commit is contained in:
Leon Friedrich
2023-06-21 13:04:07 +12:00
committed by GitHub
parent 1e9d2e388b
commit 1dde5f39ab
11 changed files with 139 additions and 104 deletions

View File

@@ -1,15 +1,12 @@
using System.Globalization;
using System.Linq;
using Content.Server.Ghost;
using Content.Server.Ghost.Components;
using Content.Server.Players;
using Content.Server.Shuttles.Systems;
using Content.Server.Spawners.Components;
using Content.Server.Speech.Components;
using Content.Server.Station.Components;
using Content.Shared.Database;
using Content.Shared.GameTicking;
using Content.Shared.Ghost;
using Content.Shared.Preferences;
using Content.Shared.Roles;
using JetBrains.Annotations;
@@ -131,7 +128,7 @@ namespace Content.Server.GameTicking
if (lateJoin && DisallowLateJoin)
{
MakeObserve(player);
JoinAsObserver(player);
return;
}
@@ -163,7 +160,7 @@ namespace Content.Server.GameTicking
{
if (!LobbyEnabled)
{
MakeObserve(player);
JoinAsObserver(player);
}
_chatManager.DispatchServerMessage(player, Loc.GetString("game-ticker-player-no-jobs-available-when-joining"));
return;
@@ -175,12 +172,12 @@ namespace Content.Server.GameTicking
DebugTools.AssertNotNull(data);
var newMind = _mindSystem.CreateMind(data!.UserId, character.Name);
_mindSystem.SetUserId(newMind, data.UserId);
var newMind = _mind.CreateMind(data!.UserId, character.Name);
_mind.SetUserId(newMind, data.UserId);
var jobPrototype = _prototypeManager.Index<JobPrototype>(jobId);
var job = new Job(newMind, jobPrototype);
_mindSystem.AddRole(newMind, job);
_mind.AddRole(newMind, job);
_playTimeTrackings.PlayerRolesChanged(player);
@@ -189,7 +186,7 @@ namespace Content.Server.GameTicking
DebugTools.AssertNotNull(mobMaybe);
var mob = mobMaybe!.Value;
_mindSystem.TransferTo(newMind, mob);
_mind.TransferTo(newMind, mob);
if (lateJoin)
{
@@ -243,7 +240,7 @@ namespace Content.Server.GameTicking
public void Respawn(IPlayerSession player)
{
_mindSystem.WipeMind(player);
_mind.WipeMind(player);
_adminLogger.Add(LogType.Respawn, LogImpact.Medium, $"Player {player} was respawned.");
if (LobbyEnabled)
@@ -263,32 +260,42 @@ namespace Content.Server.GameTicking
SpawnPlayer(player, station, jobId);
}
public void MakeObserve(IPlayerSession player)
/// <summary>
/// Causes the given player to join the current game as observer ghost. See also <see cref="SpawnObserver"/>
/// </summary>
public void JoinAsObserver(IPlayerSession player)
{
// Can't spawn players with a dummy ticker!
if (DummyTicker)
return;
PlayerJoinGame(player);
SpawnObserver(player);
RaiseNetworkEvent(GetStatusSingle(player, PlayerGameStatus.JoinedGame));
}
/// <summary>
/// Spawns an observer ghost and attaches the given player to it. If the player does not yet have a mind, the
/// player is given a new mind with the observer role. Otherwise, the current mind is transferred to the ghost.
/// </summary>
public void SpawnObserver(IPlayerSession player)
{
if (DummyTicker)
return;
var mind = player.GetMind();
if (mind == null)
{
mind = _mind.CreateMind(player.UserId);
_mind.SetUserId(mind, player.UserId);
_mind.AddRole(mind, new ObserverRole(mind));
}
var name = GetPlayerProfile(player).Name;
var data = player.ContentData();
DebugTools.AssertNotNull(data);
var newMind = _mindSystem.CreateMind(data!.UserId);
_mindSystem.SetUserId(newMind, data.UserId);
_mindSystem.AddRole(newMind, new ObserverRole(newMind));
var mob = SpawnObserverMob();
EntityManager.GetComponent<MetaDataComponent>(mob).EntityName = name;
var ghost = EntityManager.GetComponent<GhostComponent>(mob);
EntitySystem.Get<SharedGhostSystem>().SetCanReturnToBody(ghost, false);
_mindSystem.TransferTo(newMind, mob);
_playerGameStatuses[player.UserId] = PlayerGameStatus.JoinedGame;
RaiseNetworkEvent(GetStatusSingle(player, PlayerGameStatus.JoinedGame));
var ghost = SpawnObserverMob();
MetaData(ghost).EntityName = name;
_ghost.SetCanReturnToBody(ghost, false);
_mind.TransferTo(mind, ghost);
}
#region Mob Spawning Helpers