Enable nullability in Content.Server (#3685)

This commit is contained in:
DrSmugleaf
2021-03-16 15:50:20 +01:00
committed by GitHub
parent 90fec0ed24
commit a5ade526b7
306 changed files with 1616 additions and 1441 deletions

View File

@@ -1,16 +1,16 @@
#nullable enable annotations
using System.Collections.Generic;
using Content.Shared.Preferences;
using Content.Server.GameObjects.Components.Observer;
using Content.Server.Interfaces.GameTicking;
using Content.Server.Mobs;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.Components.Mobs.State;
using Content.Shared.Preferences;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Network;
using Robust.Shared.IoC;
using Robust.Shared.Network;
namespace Content.Server.GameTicking
{
@@ -75,7 +75,7 @@ namespace Content.Server.GameTicking
var entityManager = IoCManager.Resolve<IEntityManager>();
var ghost = entityManager.SpawnEntity("MobObserver", position);
ghost.Name = mind.CharacterName;
ghost.Name = mind.CharacterName ?? string.Empty;
var ghostComponent = ghost.GetComponent<GhostComponent>();
ghostComponent.CanReturnToBody = canReturn;

View File

@@ -21,6 +21,7 @@ using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;
namespace Content.Server.GameTicking.GamePresets
{
@@ -106,19 +107,22 @@ namespace Content.Server.GameTicking.GamePresets
list.Remove(traitor);
Logger.InfoS("preset", "Selected a preferred traitor.");
}
var mind = traitor.Data.ContentData().Mind;
var mind = traitor.Data.ContentData()?.Mind;
var antagPrototype = _prototypeManager.Index<AntagPrototype>(TraitorID);
var traitorRole = new SuspicionTraitorRole(mind, antagPrototype);
mind.AddRole(traitorRole);
DebugTools.AssertNotNull(mind?.OwnedEntity);
var traitorRole = new SuspicionTraitorRole(mind!, antagPrototype);
mind!.AddRole(traitorRole);
traitors.Add(traitorRole);
// creadth: we need to create uplink for the antag.
// PDA should be in place already, so we just need to
// initiate uplink account.
var uplinkAccount =
new UplinkAccount(mind.OwnedEntity.Uid,
new UplinkAccount(mind.OwnedEntity!.Uid,
TraitorStartingBalance);
var inventory = mind.OwnedEntity.GetComponent<InventoryComponent>();
if (!inventory.TryGetSlotItem(EquipmentSlotDefines.Slots.IDCARD, out ItemComponent pdaItem))
if (!inventory.TryGetSlotItem(EquipmentSlotDefines.Slots.IDCARD, out ItemComponent? pdaItem))
{
continue;
}
@@ -137,9 +141,12 @@ namespace Content.Server.GameTicking.GamePresets
foreach (var player in list)
{
var mind = player.Data.ContentData().Mind;
var mind = player.Data.ContentData()?.Mind;
var antagPrototype = _prototypeManager.Index<AntagPrototype>(InnocentID);
mind.AddRole(new SuspicionInnocentRole(mind, antagPrototype));
DebugTools.AssertNotNull(mind);
mind!.AddRole(new SuspicionInnocentRole(mind, antagPrototype));
}
foreach (var traitor in traitors)

View File

@@ -22,6 +22,7 @@ using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;
namespace Content.Server.GameTicking.GamePresets
{
@@ -107,7 +108,6 @@ namespace Content.Server.GameTicking.GamePresets
Logger.InfoS("preset", "Selected a preferred traitor.");
}
var mind = traitor.Data.ContentData()?.Mind;
var traitorRole = new TraitorRole(mind);
if (mind == null)
{
Logger.ErrorS("preset", "Failed getting mind for picked traitor.");
@@ -117,9 +117,11 @@ namespace Content.Server.GameTicking.GamePresets
// creadth: we need to create uplink for the antag.
// PDA should be in place already, so we just need to
// initiate uplink account.
var uplinkAccount = new UplinkAccount(mind.OwnedEntity.Uid, StartingBalance);
DebugTools.AssertNotNull(mind.OwnedEntity);
var uplinkAccount = new UplinkAccount(mind.OwnedEntity!.Uid, StartingBalance);
var inventory = mind.OwnedEntity.GetComponent<InventoryComponent>();
if (!inventory.TryGetSlotItem(EquipmentSlotDefines.Slots.IDCARD, out ItemComponent pdaItem))
if (!inventory.TryGetSlotItem(EquipmentSlotDefines.Slots.IDCARD, out ItemComponent? pdaItem))
{
Logger.ErrorS("preset", "Failed getting pda for picked traitor.");
continue;
@@ -134,6 +136,8 @@ namespace Content.Server.GameTicking.GamePresets
continue;
}
var traitorRole = new TraitorRole(mind);
mind.AddRole(traitorRole);
_traitors.Add(traitorRole);
pdaComponent.InitUplinkAccount(uplinkAccount);
@@ -185,7 +189,10 @@ namespace Content.Server.GameTicking.GamePresets
foreach (var traitor in _traitors)
{
result += "\n"+Loc.GetString("traitor-user-was-a-traitor", ("user", traitor.Mind.Session.Name));
if (traitor.Mind.TryGetSession(out var session))
{
result += "\n" + Loc.GetString("traitor-user-was-a-traitor", ("user", session.Name));
}
var objectives = traitor.Mind.AllObjectives.ToArray();
if (objectives.Length == 0)

View File

@@ -1,30 +1,30 @@
using System;
using System.Collections.Generic;
using Content.Server.GameTicking.GameRules;
using Content.Server.Interfaces.GameTicking;
using Content.Server.Interfaces.Chat;
using Content.Server.Atmos;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.PDA;
using Content.Server.GameObjects.Components.Markers;
using Content.Server.GameObjects.Components.PDA;
using Content.Server.GameObjects.Components.TraitorDeathMatch;
using Content.Server.GameTicking.GameRules;
using Content.Server.Interfaces.Chat;
using Content.Server.Interfaces.GameTicking;
using Content.Server.Mobs;
using Content.Server.Mobs.Roles.Traitor;
using Content.Server.Players;
using Content.Server.Atmos;
using Content.Shared;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.Components.Inventory;
using Content.Shared.GameObjects.Components.PDA;
using Content.Shared.GameObjects.Components.Mobs.State;
using Content.Shared;
using Content.Shared.GameObjects.Components.PDA;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Map;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.GameObjects;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Random;
namespace Content.Server.GameTicking.GamePresets
@@ -43,7 +43,7 @@ namespace Content.Server.GameTicking.GamePresets
public string BeltPrototypeName => "ClothingBeltJanitorFilled";
public string BackpackPrototypeName => "ClothingBackpackFilled";
private RuleMaxTimeRestart _restarter;
private RuleMaxTimeRestart _restarter = default!;
private bool _safeToEndRound = false;
private Dictionary<UplinkAccount, string> _allOriginalNames = new();
@@ -60,53 +60,57 @@ namespace Content.Server.GameTicking.GamePresets
public override void OnSpawnPlayerCompleted(IPlayerSession session, IEntity mob, bool lateJoin)
{
int startingBalance = _cfg.GetCVar(CCVars.TraitorDeathMatchStartingBalance);
var startingBalance = _cfg.GetCVar(CCVars.TraitorDeathMatchStartingBalance);
// Yup, they're a traitor
var mind = session.Data.ContentData()?.Mind;
var traitorRole = new TraitorRole(mind);
if (mind == null)
{
Logger.ErrorS("preset", "Failed getting mind for TDM player.");
return;
}
var traitorRole = new TraitorRole(mind);
mind.AddRole(traitorRole);
// Delete anything that may contain "dangerous" role-specific items.
// (This includes the PDA, as everybody gets the captain PDA in this mode for true-all-access reasons.)
var inventory = mind.OwnedEntity.GetComponent<InventoryComponent>();
var victimSlots = new[] {EquipmentSlotDefines.Slots.IDCARD, EquipmentSlotDefines.Slots.BELT, EquipmentSlotDefines.Slots.BACKPACK};
foreach (var slot in victimSlots)
if (inventory.TryGetSlotItem(slot, out ItemComponent vItem))
vItem.Owner.Delete();
if (mind.OwnedEntity != null && mind.OwnedEntity.TryGetComponent(out InventoryComponent? inventory))
{
var victimSlots = new[] {EquipmentSlotDefines.Slots.IDCARD, EquipmentSlotDefines.Slots.BELT, EquipmentSlotDefines.Slots.BACKPACK};
foreach (var slot in victimSlots)
{
if (inventory.TryGetSlotItem(slot, out ItemComponent? vItem))
vItem.Owner.Delete();
}
// Replace their items:
// Replace their items:
// pda
var newPDA = _entityManager.SpawnEntity(PDAPrototypeName, mind.OwnedEntity.Transform.Coordinates);
inventory.Equip(EquipmentSlotDefines.Slots.IDCARD, newPDA.GetComponent<ItemComponent>());
// pda
var newPDA = _entityManager.SpawnEntity(PDAPrototypeName, mind.OwnedEntity.Transform.Coordinates);
inventory.Equip(EquipmentSlotDefines.Slots.IDCARD, newPDA.GetComponent<ItemComponent>());
// belt
var newTmp = _entityManager.SpawnEntity(BeltPrototypeName, mind.OwnedEntity.Transform.Coordinates);
inventory.Equip(EquipmentSlotDefines.Slots.BELT, newTmp.GetComponent<ItemComponent>());
// belt
var newTmp = _entityManager.SpawnEntity(BeltPrototypeName, mind.OwnedEntity.Transform.Coordinates);
inventory.Equip(EquipmentSlotDefines.Slots.BELT, newTmp.GetComponent<ItemComponent>());
// backpack
newTmp = _entityManager.SpawnEntity(BackpackPrototypeName, mind.OwnedEntity.Transform.Coordinates);
inventory.Equip(EquipmentSlotDefines.Slots.BACKPACK, newTmp.GetComponent<ItemComponent>());
// backpack
newTmp = _entityManager.SpawnEntity(BackpackPrototypeName, mind.OwnedEntity.Transform.Coordinates);
inventory.Equip(EquipmentSlotDefines.Slots.BACKPACK, newTmp.GetComponent<ItemComponent>());
// Like normal traitors, they need access to a traitor account.
var uplinkAccount = new UplinkAccount(mind.OwnedEntity.Uid, startingBalance);
var pdaComponent = newPDA.GetComponent<PDAComponent>();
pdaComponent.InitUplinkAccount(uplinkAccount);
_allOriginalNames[uplinkAccount] = mind.OwnedEntity.Name;
// Like normal traitors, they need access to a traitor account.
var uplinkAccount = new UplinkAccount(mind.OwnedEntity.Uid, startingBalance);
var pdaComponent = newPDA.GetComponent<PDAComponent>();
pdaComponent.InitUplinkAccount(uplinkAccount);
_allOriginalNames[uplinkAccount] = mind.OwnedEntity.Name;
// The PDA needs to be marked with the correct owner.
pdaComponent.SetPDAOwner(mind.OwnedEntity.Name);
newPDA.AddComponent<TraitorDeathMatchReliableOwnerTagComponent>().UserId = mind.UserId;
// The PDA needs to be marked with the correct owner.
pdaComponent.SetPDAOwner(mind.OwnedEntity.Name);
newPDA.AddComponent<TraitorDeathMatchReliableOwnerTagComponent>().UserId = mind.UserId;
}
// Finally, it would be preferrable if they spawned as far away from other players as reasonably possible.
if (FindAnyIsolatedSpawnLocation(mind, out var bestTarget))
if (mind.OwnedEntity != null && FindAnyIsolatedSpawnLocation(mind, out var bestTarget))
{
mind.OwnedEntity.Transform.Coordinates = bestTarget;
}
@@ -136,7 +140,7 @@ namespace Content.Server.GameTicking.GamePresets
var avoidMeEntity = avoidMeMind.OwnedEntity;
if (avoidMeEntity == null)
continue;
if (avoidMeEntity.TryGetComponent(out IMobStateComponent mobState))
if (avoidMeEntity.TryGetComponent(out IMobStateComponent? mobState))
{
// Does have mob state component; if critical or dead, they don't really matter for spawn checks
if (mobState.IsCritical() || mobState.IsDead())
@@ -181,12 +185,12 @@ namespace Content.Server.GameTicking.GamePresets
public override bool OnGhostAttempt(Mind mind, bool canReturnGlobal)
{
var entity = mind.OwnedEntity;
if ((entity != null) && (entity.TryGetComponent(out IMobStateComponent mobState)))
if ((entity != null) && (entity.TryGetComponent(out IMobStateComponent? mobState)))
{
if (mobState.IsCritical())
{
// TODO: This is copy/pasted from ghost code. Really, IDamagableComponent needs a method to reliably kill the target.
if (entity.TryGetComponent(out IDamageableComponent damageable))
if (entity.TryGetComponent(out IDamageableComponent? damageable))
{
//todo: what if they dont breathe lol
damageable.ChangeDamage(DamageType.Asphyxiation, 100, true);

View File

@@ -29,7 +29,7 @@ namespace Content.Server.GameTicking.GameRules
[Dependency] private readonly IGameTicker _gameTicker = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
private CancellationTokenSource _checkTimerCancel;
private CancellationTokenSource? _checkTimerCancel;
public override void Added()
{
@@ -59,12 +59,12 @@ namespace Content.Server.GameTicking.GameRules
if (!_cfg.GetCVar(CCVars.GameLobbyEnableWin))
return;
IPlayerSession winner = null;
IPlayerSession? winner = null;
foreach (var playerSession in _playerManager.GetAllPlayers())
{
var playerEntity = playerSession.AttachedEntity;
if (playerEntity == null
|| !playerEntity.TryGetComponent(out IMobStateComponent state))
|| !playerEntity.TryGetComponent(out IMobStateComponent? state))
{
continue;
}
@@ -94,7 +94,7 @@ namespace Content.Server.GameTicking.GameRules
Timer.Spawn(TimeSpan.FromSeconds(restartDelay), () => _gameTicker.RestartRound());
}
private void PlayerManagerOnPlayerStatusChanged(object sender, SessionStatusEventArgs e)
private void PlayerManagerOnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
{
if (e.NewStatus == SessionStatus.Disconnected)
{

View File

@@ -86,7 +86,7 @@ namespace Content.Server.GameTicking.GameRules
foreach (var playerSession in _playerManager.GetAllPlayers())
{
if (playerSession.AttachedEntity == null
|| !playerSession.AttachedEntity.TryGetComponent(out IMobStateComponent mobState)
|| !playerSession.AttachedEntity.TryGetComponent(out IMobStateComponent? mobState)
|| !playerSession.AttachedEntity.HasComponent<SuspicionRoleComponent>())
{
continue;

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared.Preferences;
using Content.Shared.Roles;
@@ -45,7 +46,7 @@ namespace Content.Server.GameTicking
.Where(j =>
{
var (jobId, priority) = j;
if (!_prototypeManager.TryIndex(jobId, out JobPrototype job))
if (!_prototypeManager.TryIndex(jobId, out JobPrototype? job))
{
// Job doesn't exist, probably old data?
return false;
@@ -145,7 +146,7 @@ namespace Content.Server.GameTicking
{
var available = GetAvailablePositions();
bool TryPick(JobPriority priority, out string jobId)
bool TryPick(JobPriority priority, [NotNullWhen(true)] out string? jobId)
{
var filtered = profile.JobPriorities
.Where(p => p.Value == priority)

View File

@@ -15,8 +15,6 @@ using Content.Server.GameObjects.Components.Mobs.Speech;
using Content.Server.GameObjects.Components.Observer;
using Content.Server.GameObjects.Components.PDA;
using Content.Server.GameTicking.GamePresets;
using Content.Server.Holiday;
using Content.Server.Holiday.Interfaces;
using Content.Server.Interfaces;
using Content.Server.Interfaces.Chat;
using Content.Server.Interfaces.GameTicking;
@@ -80,7 +78,7 @@ namespace Content.Server.GameTicking
[ViewVariables] private bool _initialized;
[ViewVariables] private Type _presetType;
[ViewVariables] private Type? _presetType;
[ViewVariables] private TimeSpan _pauseTime;
[ViewVariables] private bool _roundStartCountdownHasNotStartedYetDueToNoPlayers;
@@ -93,7 +91,7 @@ namespace Content.Server.GameTicking
[ViewVariables] private bool LobbyEnabled => _configurationManager.GetCVar(CCVars.GameLobbyEnabled);
[ViewVariables] private bool _updateOnRoundEnd;
private CancellationTokenSource _updateShutdownCts;
private CancellationTokenSource? _updateShutdownCts;
[ViewVariables] public bool Paused { get; private set; }
@@ -118,24 +116,24 @@ namespace Content.Server.GameTicking
}
[ViewVariables]
public GamePreset Preset
public GamePreset? Preset
{
get => _preset == null ? MakeGamePreset(null) : _preset;
get => _preset ?? MakeGamePreset(new Dictionary<NetUserId, HumanoidCharacterProfile>());
set => _preset = value;
}
public ImmutableDictionary<string, Type> Presets { get; private set; }
public ImmutableDictionary<string, Type> Presets { get; private set; } = default!;
private GamePreset _preset;
private GamePreset? _preset;
public event Action<GameRunLevelChangedEventArgs> OnRunLevelChanged;
public event Action<GameRuleAddedEventArgs> OnRuleAdded;
public event Action<GameRunLevelChangedEventArgs>? OnRunLevelChanged;
public event Action<GameRuleAddedEventArgs>? OnRuleAdded;
private TimeSpan LobbyDuration =>
TimeSpan.FromSeconds(_configurationManager.GetCVar(CCVars.GameLobbyDuration));
private SoundCollectionPrototype _lobbyCollection = default!;
[ViewVariables] public string LobbySong { get; private set; }
[ViewVariables] public string LobbySong { get; private set; } = default!;
public override void Initialize()
{
@@ -356,7 +354,7 @@ namespace Content.Server.GameTicking
private void UpdateLateJoinStatus()
{
var msg = new MsgTickerLateJoinStatus(null) {Disallowed = DisallowLateJoin};
var msg = new MsgTickerLateJoinStatus(null!) {Disallowed = DisallowLateJoin};
_netManager.ServerSendToAll(msg);
}
@@ -382,8 +380,8 @@ namespace Content.Server.GameTicking
//Tell every client the round has ended.
var roundEndMessage = _netManager.CreateNetMessage<MsgRoundEndMessage>();
roundEndMessage.GamemodeTitle = Preset.ModeTitle;
roundEndMessage.RoundEndText = roundEndText + $"\n{Preset.GetRoundEndDescription()}";
roundEndMessage.GamemodeTitle = Preset?.ModeTitle ?? string.Empty;
roundEndMessage.RoundEndText = roundEndText + $"\n{Preset?.GetRoundEndDescription() ?? string.Empty}";
//Get the timespan of the round.
roundEndMessage.RoundDuration = IoCManager.Resolve<IGameTiming>().RealTime.Subtract(_roundStartTimeSpan);
@@ -392,7 +390,8 @@ namespace Content.Server.GameTicking
var listOfPlayerInfo = new List<RoundEndPlayerInfo>();
foreach (var ply in PlayerManager.GetAllPlayers().OrderBy(p => p.Name))
{
var mind = ply.ContentData().Mind;
var mind = ply.ContentData()?.Mind;
if (mind != null)
{
_playersInLobby.TryGetValue(ply, out var status);
@@ -400,7 +399,7 @@ namespace Content.Server.GameTicking
var playerEndRoundInfo = new RoundEndPlayerInfo()
{
PlayerOOCName = ply.Name,
PlayerICName = mind.CurrentEntity.Name,
PlayerICName = mind.CurrentEntity?.Name,
Role = antag
? mind.AllRoles.First(role => role.Antagonist).Name
: mind.AllRoles.FirstOrDefault()?.Name ?? Loc.GetString("Unknown"),
@@ -417,8 +416,10 @@ namespace Content.Server.GameTicking
public void Respawn(IPlayerSession targetPlayer)
{
targetPlayer.AttachedEntity.TryGetComponent<GhostComponent>(out var ghost);
var ghost = targetPlayer.AttachedEntity?.GetComponentOrNull<GhostComponent>();
targetPlayer.ContentData()?.WipeMind();
if (ghost?.Deleted == false)
ghost.Owner.Delete();
@@ -437,7 +438,7 @@ namespace Content.Server.GameTicking
_netManager.ServerSendToAll(GetStatusSingle(player, PlayerStatus.Observer));
}
public void MakeJoinGame(IPlayerSession player, string jobId = null)
public void MakeJoinGame(IPlayerSession player, string? jobId = null)
{
if (!_playersInLobby.ContainsKey(player)) return;
@@ -473,7 +474,7 @@ namespace Content.Server.GameTicking
public bool OnGhostAttempt(Mind mind, bool canReturnGlobal)
{
return Preset.OnGhostAttempt(mind, canReturnGlobal);
return Preset?.OnGhostAttempt(mind, canReturnGlobal) ?? false;
}
public T AddGameRule<T>() where T : GameRule, new()
@@ -488,14 +489,30 @@ namespace Content.Server.GameTicking
return instance;
}
public bool HasGameRule(Type t)
public bool HasGameRule(string? name)
{
if (t == null || !typeof(GameRule).IsAssignableFrom(t))
if (name == null)
return false;
foreach (var rule in _gameRules)
{
if (rule.GetType().IsAssignableFrom(t))
if (rule.GetType().Name == name)
{
return true;
}
}
return false;
}
public bool HasGameRule(Type? type)
{
if (type == null || !typeof(GameRule).IsAssignableFrom(type))
return false;
foreach (var rule in _gameRules)
{
if (rule.GetType().IsAssignableFrom(type))
return true;
}
@@ -513,7 +530,7 @@ namespace Content.Server.GameTicking
public IEnumerable<GameRule> ActiveGameRules => _gameRules;
public bool TryGetPreset(string name, [NotNullWhen(true)] out Type type)
public bool TryGetPreset(string name, [NotNullWhen(true)] out Type? type)
{
name = name.ToLowerInvariant();
return Presets.TryGetValue(name, out type);
@@ -597,12 +614,16 @@ namespace Content.Server.GameTicking
return Paused;
}
private IEntity _spawnPlayerMob(Job job, HumanoidCharacterProfile profile, bool lateJoin = true)
private IEntity _spawnPlayerMob(Job job, HumanoidCharacterProfile? profile, bool lateJoin = true)
{
var coordinates = lateJoin ? GetLateJoinSpawnPoint() : GetJobSpawnPoint(job.Prototype.ID);
var entity = _entityManager.SpawnEntity(PlayerPrototypeName, coordinates);
var startingGear = _prototypeManager.Index<StartingGearPrototype>(job.StartingGear);
EquipStartingGear(entity, startingGear, profile);
if (job.StartingGear != null)
{
var startingGear = _prototypeManager.Index<StartingGearPrototype>(job.StartingGear);
EquipStartingGear(entity, startingGear, profile);
}
if (profile != null)
{
@@ -613,9 +634,9 @@ namespace Content.Server.GameTicking
return entity;
}
public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear, HumanoidCharacterProfile profile)
public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear, HumanoidCharacterProfile? profile)
{
if (entity.TryGetComponent(out InventoryComponent inventory))
if (entity.TryGetComponent(out InventoryComponent? inventory))
{
foreach (var slot in AllSlots)
{
@@ -628,7 +649,7 @@ namespace Content.Server.GameTicking
}
}
if (entity.TryGetComponent(out HandsComponent handsComponent))
if (entity.TryGetComponent(out HandsComponent? handsComponent))
{
var inhand = startingGear.Inhand;
foreach (var (hand, prototype) in inhand)
@@ -669,7 +690,7 @@ namespace Content.Server.GameTicking
foreach (var entity in _entityManager.GetEntities(new TypeEntityQuery(typeof(SpawnPointComponent))))
{
var point = entity.GetComponent<SpawnPointComponent>();
if (point.SpawnType == SpawnPointType.Job && point.Job.ID == jobId)
if (point.SpawnType == SpawnPointType.Job && point.Job?.ID == jobId)
possiblePoints.Add(entity.Transform.Coordinates);
}
@@ -754,7 +775,13 @@ namespace Content.Server.GameTicking
{
DefaultMap = _mapManager.CreateMap();
var startTime = _gameTiming.RealTime;
var grid = _mapLoader.LoadBlueprint(DefaultMap, GetMap());
var map = GetMap();
var grid = _mapLoader.LoadBlueprint(DefaultMap, map);
if (grid == null)
{
throw new InvalidOperationException($"No grid found for map {map}");
}
DefaultGridId = grid.Index;
_spawnPoint = grid.ToCoordinates();
@@ -763,7 +790,7 @@ namespace Content.Server.GameTicking
Logger.InfoS("ticker", $"Loaded map in {timeSpan.TotalMilliseconds:N2}ms.");
}
protected override void PlayerStatusChanged(object sender, SessionStatusEventArgs args)
protected override void PlayerStatusChanged(object? sender, SessionStatusEventArgs args)
{
base.PlayerStatusChanged(sender, args);
@@ -794,7 +821,10 @@ namespace Content.Server.GameTicking
_prefsManager.OnClientConnected(session);
var data = session.ContentData();
if (data.Mind == null)
DebugTools.AssertNotNull(data);
if (data!.Mind == null)
{
if (LobbyEnabled)
{
@@ -871,7 +901,7 @@ namespace Content.Server.GameTicking
}, _updateShutdownCts.Token);
}
private void SpawnPlayer(IPlayerSession session, string jobId = null, bool lateJoin = true)
private void SpawnPlayer(IPlayerSession session, string? jobId = null, bool lateJoin = true)
{
var character = GetPlayerProfile(session);
@@ -881,7 +911,7 @@ namespace Content.Server.GameTicking
private void SpawnPlayer(IPlayerSession session,
HumanoidCharacterProfile character,
string jobId = null,
string? jobId = null,
bool lateJoin = true)
{
if (lateJoin && DisallowLateJoin)
@@ -893,17 +923,17 @@ namespace Content.Server.GameTicking
_playerJoinGame(session);
var data = session.ContentData();
data.WipeMind();
DebugTools.AssertNotNull(data);
data!.WipeMind();
data.Mind = new Mind(session.UserId)
{
CharacterName = character.Name
};
if (jobId == null)
{
// Pick best job best on prefs.
jobId = PickBestAvailableJob(character);
}
// Pick best job best on prefs.
jobId ??= PickBestAvailableJob(character);
var jobPrototype = _prototypeManager.Index<JobPrototype>(jobId);
var job = new Job(data.Mind, jobPrototype);
@@ -931,14 +961,14 @@ namespace Content.Server.GameTicking
EquipIdCard(mob, character.Name, jobPrototype);
jobPrototype.Special?.AfterEquip(mob);
Preset.OnSpawnPlayerCompleted(session, mob, lateJoin);
Preset?.OnSpawnPlayerCompleted(session, mob, lateJoin);
}
private void EquipIdCard(IEntity mob, string characterName, JobPrototype jobPrototype)
{
var inventory = mob.GetComponent<InventoryComponent>();
if (!inventory.TryGetSlotItem(Slots.IDCARD, out ItemComponent pdaItem))
if (!inventory.TryGetSlotItem(Slots.IDCARD, out ItemComponent? pdaItem))
{
return;
}
@@ -946,7 +976,7 @@ namespace Content.Server.GameTicking
var pda = pdaItem.Owner;
var pdaComponent = pda.GetComponent<PDAComponent>();
if (pdaComponent.IdSlotEmpty)
if (pdaComponent.ContainedID == null)
{
return;
}
@@ -973,7 +1003,10 @@ namespace Content.Server.GameTicking
var name = GetPlayerProfile(session).Name;
var data = session.ContentData();
data.WipeMind();
DebugTools.AssertNotNull(data);
data!.WipeMind();
data.Mind = new Mind(session.UserId);
var mob = _spawnObserverMob();
@@ -1069,6 +1102,11 @@ namespace Content.Server.GameTicking
private string GetInfoText()
{
if (Preset == null)
{
return string.Empty;
}
var gmTitle = Preset.ModeTitle;
var desc = Preset.Description;
return Loc.GetString(@"Hi and welcome to [color=white]Space Station 14![/color]