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

@@ -20,7 +20,7 @@ namespace Content.Client.GameObjects.Components.CloningPod
base.Open(); base.Open();
_window = new CloningPodWindow(new Dictionary<int, string>()); _window = new CloningPodWindow(new Dictionary<int, string?>());
_window.OnClose += Close; _window.OnClose += Close;
_window.CloneButton.OnPressed += _ => _window.CloneButton.OnPressed += _ =>
{ {

View File

@@ -11,7 +11,7 @@ namespace Content.Client.GameObjects.Components.CloningPod
{ {
public sealed class CloningPodWindow : SS14Window public sealed class CloningPodWindow : SS14Window
{ {
private Dictionary<int, string> _scanManager; private Dictionary<int, string?> _scanManager;
private readonly VBoxContainer _scanList; private readonly VBoxContainer _scanList;
public readonly Button CloneButton; public readonly Button CloneButton;
@@ -21,11 +21,11 @@ namespace Content.Client.GameObjects.Components.CloningPod
private readonly ProgressBar _cloningProgressBar; private readonly ProgressBar _cloningProgressBar;
private readonly Label _mindState; private readonly Label _mindState;
private CloningPodBoundUserInterfaceState _lastUpdate = null!; private CloningPodBoundUserInterfaceState? _lastUpdate;
public int? SelectedScan; public int? SelectedScan;
public CloningPodWindow(Dictionary<int, string> scanManager) public CloningPodWindow(Dictionary<int, string?> scanManager)
{ {
SetSize = MinSize = (250, 300); SetSize = MinSize = (250, 300);
_scanManager = scanManager; _scanManager = scanManager;
@@ -120,7 +120,7 @@ namespace Content.Client.GameObjects.Components.CloningPod
{ {
var button = new CloningScanButton var button = new CloningScanButton
{ {
Scan = scan.Value, Scan = scan.Value ?? string.Empty,
Id = scan.Key Id = scan.Key
}; };
button.ActualButton.OnToggled += OnItemButtonToggled; button.ActualButton.OnToggled += OnItemButtonToggled;

View File

@@ -20,7 +20,7 @@ namespace Content.Client.GameObjects.Components.Interactable
[ViewVariables(VVAccess.ReadWrite)] private bool _uiUpdateNeeded; [ViewVariables(VVAccess.ReadWrite)] private bool _uiUpdateNeeded;
[ViewVariables] public bool StatusShowBehavior => _statusShowBehavior; [ViewVariables] public bool StatusShowBehavior => _statusShowBehavior;
[ViewVariables] public ToolQuality Behavior => _behavior; [ViewVariables] public ToolQuality? Behavior => _behavior;
public override string Name => "MultiTool"; public override string Name => "MultiTool";
public override uint? NetID => ContentNetIDs.MULTITOOLS; public override uint? NetID => ContentNetIDs.MULTITOOLS;
@@ -63,11 +63,7 @@ namespace Content.Client.GameObjects.Components.Interactable
_parent._uiUpdateNeeded = false; _parent._uiUpdateNeeded = false;
if(!_parent.StatusShowBehavior) _label.SetMarkup(_parent.StatusShowBehavior ? _parent.Behavior.ToString() ?? string.Empty : string.Empty);
_label.SetMarkup(string.Empty);
else
_label.SetMarkup(_parent.Behavior.ToString());
} }
} }
} }

View File

@@ -41,7 +41,7 @@ namespace Content.Client.GameObjects.Components.Mobs
private void UpdateLooks() private void UpdateLooks()
{ {
if (Appearance is null || if (Appearance is null! ||
!Owner.TryGetComponent(out SpriteComponent? sprite)) !Owner.TryGetComponent(out SpriteComponent? sprite))
{ {
return; return;

View File

@@ -74,20 +74,23 @@ namespace Content.Client.UserInterface
{ {
var playerInfoText = new RichTextLabel(); var playerInfoText = new RichTextLabel();
if (playerInfo.Observer) if (playerInfo.PlayerICName != null)
{ {
playerInfoText.SetMarkup( if (playerInfo.Observer)
Loc.GetString("[color=gray]{0}[/color] was [color=lightblue]{1}[/color], an observer.", {
playerInfo.PlayerOOCName, playerInfo.PlayerICName)); playerInfoText.SetMarkup(
} Loc.GetString("[color=gray]{0}[/color] was [color=lightblue]{1}[/color], an observer.",
else playerInfo.PlayerOOCName, playerInfo.PlayerICName));
{ }
//TODO: On Hover display a popup detailing more play info. else
//For example: their antag goals and if they completed them sucessfully. {
var icNameColor = playerInfo.Antag ? "red" : "white"; //TODO: On Hover display a popup detailing more play info.
playerInfoText.SetMarkup( //For example: their antag goals and if they completed them sucessfully.
Loc.GetString("[color=gray]{0}[/color] was [color={1}]{2}[/color] playing role of [color=orange]{3}[/color].", var icNameColor = playerInfo.Antag ? "red" : "white";
playerInfo.PlayerOOCName, icNameColor, playerInfo.PlayerICName, Loc.GetString(playerInfo.Role))); playerInfoText.SetMarkup(
Loc.GetString("[color=gray]{0}[/color] was [color={1}]{2}[/color] playing role of [color=orange]{3}[/color].",
playerInfo.PlayerOOCName, icNameColor, playerInfo.PlayerICName, Loc.GetString(playerInfo.Role)));
}
} }
innerScrollContainer.AddChild(playerInfoText); innerScrollContainer.AddChild(playerInfoText);
} }

View File

@@ -1,10 +1,12 @@
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.Interfaces.GameTicking; using Content.Server.Interfaces.GameTicking;
using Content.Shared.Roles;
using Content.Shared.Preferences;
using Content.Server.Mobs; using Content.Server.Mobs;
using Content.Shared.Preferences;
using Content.Shared.Roles;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Map; using Robust.Shared.Map;
@@ -60,7 +62,7 @@ namespace Content.IntegrationTests
{ {
} }
public void MakeJoinGame(IPlayerSession player, string jobId) public void MakeJoinGame(IPlayerSession player, string? jobId)
{ {
} }
@@ -76,7 +78,7 @@ namespace Content.IntegrationTests
public EntityCoordinates GetJobSpawnPoint(string jobId) => EntityCoordinates.Invalid; public EntityCoordinates GetJobSpawnPoint(string jobId) => EntityCoordinates.Invalid;
public EntityCoordinates GetObserverSpawnPoint() => EntityCoordinates.Invalid; public EntityCoordinates GetObserverSpawnPoint() => EntityCoordinates.Invalid;
public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear, HumanoidCharacterProfile profile) public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear, HumanoidCharacterProfile? profile)
{ {
} }
@@ -85,7 +87,12 @@ namespace Content.IntegrationTests
return new(); return new();
} }
public bool HasGameRule(Type type) public bool HasGameRule(string? type)
{
return false;
}
public bool HasGameRule(Type? type)
{ {
return false; return false;
} }
@@ -96,7 +103,7 @@ namespace Content.IntegrationTests
public IEnumerable<GameRule> ActiveGameRules { get; } = Array.Empty<GameRule>(); public IEnumerable<GameRule> ActiveGameRules { get; } = Array.Empty<GameRule>();
public bool TryGetPreset(string name, out Type type) public bool TryGetPreset(string name, [NotNullWhen(true)] out Type? type)
{ {
type = default; type = default;
return false; return false;

View File

@@ -29,7 +29,7 @@ namespace Content.Server.AI.Operators.Combat.Melee
return true; return true;
} }
if (!_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) if (!_owner.TryGetComponent(out CombatModeComponent? combatModeComponent))
{ {
return false; return false;
} }
@@ -47,7 +47,7 @@ namespace Content.Server.AI.Operators.Combat.Melee
if (!base.Shutdown(outcome)) if (!base.Shutdown(outcome))
return false; return false;
if (_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) if (_owner.TryGetComponent(out CombatModeComponent? combatModeComponent))
{ {
combatModeComponent.IsInCombatMode = false; combatModeComponent.IsInCombatMode = false;
} }
@@ -62,16 +62,16 @@ namespace Content.Server.AI.Operators.Combat.Melee
return Outcome.Success; return Outcome.Success;
} }
if (!_owner.TryGetComponent(out HandsComponent hands) || hands.GetActiveHand == null) if (!_owner.TryGetComponent(out HandsComponent? hands) || hands.GetActiveHand == null)
{ {
return Outcome.Failed; return Outcome.Failed;
} }
var meleeWeapon = hands.GetActiveHand.Owner; var meleeWeapon = hands.GetActiveHand.Owner;
meleeWeapon.TryGetComponent(out MeleeWeaponComponent meleeWeaponComponent); meleeWeapon.TryGetComponent(out MeleeWeaponComponent? meleeWeaponComponent);
if ((_target.Transform.Coordinates.Position - _owner.Transform.Coordinates.Position).Length > if ((_target.Transform.Coordinates.Position - _owner.Transform.Coordinates.Position).Length >
meleeWeaponComponent.Range) meleeWeaponComponent?.Range)
{ {
return Outcome.Failed; return Outcome.Failed;
} }

View File

@@ -13,7 +13,7 @@ namespace Content.Server.AI.Operators.Combat.Melee
private readonly IEntity _owner; private readonly IEntity _owner;
private readonly IEntity _target; private readonly IEntity _target;
private UnarmedCombatComponent _unarmedCombat; private UnarmedCombatComponent? _unarmedCombat;
public UnarmedCombatOperator(IEntity owner, IEntity target, float burstTime = 1.0f) public UnarmedCombatOperator(IEntity owner, IEntity target, float burstTime = 1.0f)
{ {
@@ -29,7 +29,7 @@ namespace Content.Server.AI.Operators.Combat.Melee
return true; return true;
} }
if (!_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) if (!_owner.TryGetComponent(out CombatModeComponent? combatModeComponent))
{ {
return false; return false;
} }
@@ -39,7 +39,7 @@ namespace Content.Server.AI.Operators.Combat.Melee
combatModeComponent.IsInCombatMode = true; combatModeComponent.IsInCombatMode = true;
} }
if (_owner.TryGetComponent(out UnarmedCombatComponent unarmedCombatComponent)) if (_owner.TryGetComponent(out UnarmedCombatComponent? unarmedCombatComponent))
{ {
_unarmedCombat = unarmedCombatComponent; _unarmedCombat = unarmedCombatComponent;
} }
@@ -56,7 +56,7 @@ namespace Content.Server.AI.Operators.Combat.Melee
if (!base.Shutdown(outcome)) if (!base.Shutdown(outcome))
return false; return false;
if (_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) if (_owner.TryGetComponent(out CombatModeComponent? combatModeComponent))
{ {
combatModeComponent.IsInCombatMode = false; combatModeComponent.IsInCombatMode = false;
} }
@@ -71,7 +71,7 @@ namespace Content.Server.AI.Operators.Combat.Melee
return Outcome.Success; return Outcome.Success;
} }
if (_unarmedCombat.Deleted) if (_unarmedCombat?.Deleted ?? true)
{ {
return Outcome.Failed; return Outcome.Failed;
} }

View File

@@ -14,7 +14,7 @@ namespace Content.Server.AI.Operators.Inventory
public sealed class CloseLastStorageOperator : AiOperator public sealed class CloseLastStorageOperator : AiOperator
{ {
private readonly IEntity _owner; private readonly IEntity _owner;
private IEntity _target; private IEntity? _target;
public CloseLastStorageOperator(IEntity owner) public CloseLastStorageOperator(IEntity owner)
{ {
@@ -53,12 +53,12 @@ namespace Content.Server.AI.Operators.Inventory
public override Outcome Execute(float frameTime) public override Outcome Execute(float frameTime)
{ {
if (!_owner.InRangeUnobstructed(_target, popup: true)) if (_target == null || !_owner.InRangeUnobstructed(_target, popup: true))
{ {
return Outcome.Failed; return Outcome.Failed;
} }
if (!_target.TryGetComponent(out EntityStorageComponent storageComponent) || if (!_target.TryGetComponent(out EntityStorageComponent? storageComponent) ||
storageComponent.IsWeldedShut) storageComponent.IsWeldedShut)
{ {
return Outcome.Failed; return Outcome.Failed;

View File

@@ -20,7 +20,7 @@ namespace Content.Server.AI.Operators.Inventory
/// <returns></returns> /// <returns></returns>
public override Outcome Execute(float frameTime) public override Outcome Execute(float frameTime)
{ {
if (!_owner.TryGetComponent(out HandsComponent handsComponent) || if (!_owner.TryGetComponent(out HandsComponent? handsComponent) ||
!handsComponent.TryHand(_entity, out _)) !handsComponent.TryHand(_entity, out _))
{ {
return Outcome.Failed; return Outcome.Failed;

View File

@@ -14,7 +14,7 @@ namespace Content.Server.AI.Operators.Inventory
public override Outcome Execute(float frameTime) public override Outcome Execute(float frameTime)
{ {
if (!_owner.TryGetComponent(out HandsComponent handsComponent)) if (!_owner.TryGetComponent(out HandsComponent? handsComponent))
{ {
return Outcome.Failed; return Outcome.Failed;
} }

View File

@@ -15,7 +15,7 @@ namespace Content.Server.AI.Operators.Inventory
public override Outcome Execute(float frameTime) public override Outcome Execute(float frameTime)
{ {
if (!_owner.TryGetComponent(out HandsComponent handsComponent)) if (!_owner.TryGetComponent(out HandsComponent? handsComponent))
{ {
return Outcome.Failed; return Outcome.Failed;
} }

View File

@@ -33,7 +33,7 @@ namespace Content.Server.AI.Operators.Inventory
return Outcome.Failed; return Outcome.Failed;
} }
if (_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) if (_owner.TryGetComponent(out CombatModeComponent? combatModeComponent))
{ {
combatModeComponent.IsInCombatMode = false; combatModeComponent.IsInCombatMode = false;
} }

View File

@@ -9,7 +9,7 @@ namespace Content.Server.AI.Operators.Movement
{ {
// TODO: This and steering need to support InRangeUnobstructed now // TODO: This and steering need to support InRangeUnobstructed now
private readonly IEntity _owner; private readonly IEntity _owner;
private EntityTargetSteeringRequest _request; private EntityTargetSteeringRequest? _request;
private readonly IEntity _target; private readonly IEntity _target;
// For now we'll just get as close as we can because we're not doing LOS checks to be able to pick up at the max interaction range // For now we'll just get as close as we can because we're not doing LOS checks to be able to pick up at the max interaction range
public float ArrivalDistance { get; } public float ArrivalDistance { get; }
@@ -56,7 +56,7 @@ namespace Content.Server.AI.Operators.Movement
public override Outcome Execute(float frameTime) public override Outcome Execute(float frameTime)
{ {
switch (_request.Status) switch (_request?.Status)
{ {
case SteeringStatus.Pending: case SteeringStatus.Pending:
DebugTools.Assert(EntitySystem.Get<AiSteeringSystem>().IsRegistered(_owner)); DebugTools.Assert(EntitySystem.Get<AiSteeringSystem>().IsRegistered(_owner));

View File

@@ -9,7 +9,7 @@ namespace Content.Server.AI.Operators.Movement
public sealed class MoveToGridOperator : AiOperator public sealed class MoveToGridOperator : AiOperator
{ {
private readonly IEntity _owner; private readonly IEntity _owner;
private GridTargetSteeringRequest _request; private GridTargetSteeringRequest? _request;
private readonly EntityCoordinates _target; private readonly EntityCoordinates _target;
public float DesiredRange { get; set; } public float DesiredRange { get; set; }
@@ -45,7 +45,7 @@ namespace Content.Server.AI.Operators.Movement
public override Outcome Execute(float frameTime) public override Outcome Execute(float frameTime)
{ {
switch (_request.Status) switch (_request?.Status)
{ {
case SteeringStatus.Pending: case SteeringStatus.Pending:
DebugTools.Assert(EntitySystem.Get<AiSteeringSystem>().IsRegistered(_owner)); DebugTools.Assert(EntitySystem.Get<AiSteeringSystem>().IsRegistered(_owner));

View File

@@ -9,7 +9,7 @@ namespace Content.Server.AI.Operators.Sequences
/// </summary> /// </summary>
public abstract class SequenceOperator : AiOperator public abstract class SequenceOperator : AiOperator
{ {
public Queue<AiOperator> Sequence { get; protected set; } public Queue<AiOperator> Sequence { get; protected set; } = new();
public override Outcome Execute(float frameTime) public override Outcome Execute(float frameTime)
{ {

View File

@@ -13,7 +13,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Gloves
{ {
public sealed class EquipGloves : UtilityAction public sealed class EquipGloves : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -14,7 +14,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Gloves
{ {
public sealed class PickUpGloves : UtilityAction public sealed class PickUpGloves : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -13,7 +13,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Head
{ {
public sealed class EquipHead : UtilityAction public sealed class EquipHead : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -14,7 +14,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Head
{ {
public sealed class PickUpHead : UtilityAction public sealed class PickUpHead : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -13,7 +13,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.OuterClothing
{ {
public sealed class EquipOuterClothing : UtilityAction public sealed class EquipOuterClothing : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -14,7 +14,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.OuterClothing
{ {
public sealed class PickUpOuterClothing : UtilityAction public sealed class PickUpOuterClothing : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -13,7 +13,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Shoes
{ {
public sealed class EquipShoes : UtilityAction public sealed class EquipShoes : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -14,7 +14,7 @@ namespace Content.Server.AI.Utility.Actions.Clothing.Shoes
{ {
public sealed class PickUpShoes : UtilityAction public sealed class PickUpShoes : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -15,7 +15,7 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
{ {
public sealed class EquipMelee : UtilityAction public sealed class EquipMelee : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -21,13 +21,13 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
{ {
public sealed class MeleeWeaponAttackEntity : UtilityAction public sealed class MeleeWeaponAttackEntity : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {
MoveToEntityOperator moveOperator; MoveToEntityOperator moveOperator;
var equipped = context.GetState<EquippedEntityState>().GetValue(); var equipped = context.GetState<EquippedEntityState>().GetValue();
if (equipped != null && equipped.TryGetComponent(out MeleeWeaponComponent meleeWeaponComponent)) if (equipped != null && equipped.TryGetComponent(out MeleeWeaponComponent? meleeWeaponComponent))
{ {
moveOperator = new MoveToEntityOperator(Owner, Target, meleeWeaponComponent.Range - 0.01f); moveOperator = new MoveToEntityOperator(Owner, Target, meleeWeaponComponent.Range - 0.01f);
} }

View File

@@ -15,7 +15,7 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
{ {
public sealed class PickUpMeleeWeapon : UtilityAction public sealed class PickUpMeleeWeapon : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -19,12 +19,12 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
{ {
public sealed class UnarmedAttackEntity : UtilityAction public sealed class UnarmedAttackEntity : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {
MoveToEntityOperator moveOperator; MoveToEntityOperator moveOperator;
if (Owner.TryGetComponent(out UnarmedCombatComponent unarmedCombatComponent)) if (Owner.TryGetComponent(out UnarmedCombatComponent? unarmedCombatComponent))
{ {
moveOperator = new MoveToEntityOperator(Owner, Target, unarmedCombatComponent.Range - 0.01f); moveOperator = new MoveToEntityOperator(Owner, Target, unarmedCombatComponent.Range - 0.01f);
} }

View File

@@ -10,7 +10,6 @@ using Content.Server.AI.Utility.Considerations.State;
using Content.Server.AI.WorldState; using Content.Server.AI.WorldState;
using Content.Server.AI.WorldState.States; using Content.Server.AI.WorldState.States;
using Content.Server.AI.WorldState.States.Inventory; using Content.Server.AI.WorldState.States.Inventory;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
namespace Content.Server.AI.Utility.Actions.Idle namespace Content.Server.AI.Utility.Actions.Idle
@@ -26,6 +25,16 @@ namespace Content.Server.AI.Utility.Actions.Idle
{ {
var lastStorage = context.GetState<LastOpenedStorageState>().GetValue(); var lastStorage = context.GetState<LastOpenedStorageState>().GetValue();
if (lastStorage == null)
{
ActionOperators = new Queue<AiOperator>(new AiOperator[]
{
new CloseLastStorageOperator(Owner),
});
return;
}
ActionOperators = new Queue<AiOperator>(new AiOperator[] ActionOperators = new Queue<AiOperator>(new AiOperator[]
{ {
new MoveToEntityOperator(Owner, lastStorage), new MoveToEntityOperator(Owner, lastStorage),

View File

@@ -14,7 +14,7 @@ namespace Content.Server.AI.Utility.Actions.Nutrition.Drink
{ {
public sealed class PickUpDrink : UtilityAction public sealed class PickUpDrink : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -15,7 +15,7 @@ namespace Content.Server.AI.Utility.Actions.Nutrition.Drink
{ {
public sealed class UseDrinkInInventory : UtilityAction public sealed class UseDrinkInInventory : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -14,7 +14,7 @@ namespace Content.Server.AI.Utility.Actions.Nutrition.Food
{ {
public sealed class PickUpFood : UtilityAction public sealed class PickUpFood : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -15,7 +15,7 @@ namespace Content.Server.AI.Utility.Actions.Nutrition.Food
{ {
public sealed class UseFoodInInventory : UtilityAction public sealed class UseFoodInInventory : UtilityAction
{ {
public IEntity Target { get; set; } public IEntity Target { get; set; } = default!;
public override void SetupOperators(Blackboard context) public override void SetupOperators(Blackboard context)
{ {

View File

@@ -59,7 +59,11 @@ namespace Content.Server.AI.Utility.Actions
protected virtual void UpdateBlackboard(Blackboard context) {} protected virtual void UpdateBlackboard(Blackboard context) {}
// Needs to be able to be instantiated without args via typefactory. // Needs to be able to be instantiated without args via typefactory.
public UtilityAction() {} public UtilityAction()
{
Owner = default!;
ActionOperators = default!;
}
public virtual void Shutdown() {} public virtual void Shutdown() {}

View File

@@ -28,9 +28,9 @@ namespace Content.Server.AI.Utility.AiLogic
// TODO: Look at having ParallelOperators (probably no more than that as then you'd have a full-blown BT) // TODO: Look at having ParallelOperators (probably no more than that as then you'd have a full-blown BT)
// Also RepeatOperators (e.g. if we're following an entity keep repeating MoveToEntity) // Also RepeatOperators (e.g. if we're following an entity keep repeating MoveToEntity)
private AiActionSystem _planner; private AiActionSystem _planner = default!;
public Blackboard Blackboard => _blackboard; public Blackboard Blackboard => _blackboard;
private Blackboard _blackboard; private Blackboard _blackboard = default!;
/// <summary> /// <summary>
/// The sum of all BehaviorSets gives us what actions the AI can take /// The sum of all BehaviorSets gives us what actions the AI can take
@@ -43,7 +43,7 @@ namespace Content.Server.AI.Utility.AiLogic
/// <summary> /// <summary>
/// The currently running action; most importantly are the operators. /// The currently running action; most importantly are the operators.
/// </summary> /// </summary>
public UtilityAction CurrentAction { get; private set; } public UtilityAction? CurrentAction { get; private set; }
/// <summary> /// <summary>
/// How frequently we can re-plan. If an AI's in combat you could decrease the cooldown, /// How frequently we can re-plan. If an AI's in combat you could decrease the cooldown,
@@ -55,9 +55,9 @@ namespace Content.Server.AI.Utility.AiLogic
/// <summary> /// <summary>
/// If we've requested a plan then wait patiently for the action /// If we've requested a plan then wait patiently for the action
/// </summary> /// </summary>
private AiActionRequestJob _actionRequest; private AiActionRequestJob? _actionRequest;
private CancellationTokenSource _actionCancellation; private CancellationTokenSource? _actionCancellation;
/// <summary> /// <summary>
/// If we can't do anything then stop thinking; should probably use ActionBlocker instead /// If we can't do anything then stop thinking; should probably use ActionBlocker instead
@@ -126,6 +126,11 @@ namespace Content.Server.AI.Utility.AiLogic
private void ReceivedAction() private void ReceivedAction()
{ {
if (_actionRequest == null)
{
return;
}
switch (_actionRequest.Exception) switch (_actionRequest.Exception)
{ {
case null: case null:

View File

@@ -9,7 +9,8 @@ namespace Content.Server.AI.Utility.Considerations.ActionBlocker
protected override float GetScore(Blackboard context) protected override float GetScore(Blackboard context)
{ {
var self = context.GetState<SelfState>().GetValue(); var self = context.GetState<SelfState>().GetValue();
if (!ActionBlockerSystem.CanMove(self))
if (self == null || !ActionBlockerSystem.CanMove(self))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -23,7 +23,7 @@ namespace Content.Server.AI.Utility.Considerations.Clothing
foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue()) foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue())
{ {
if (!entity.TryGetComponent(out ClothingComponent clothingComponent)) if (!entity.TryGetComponent(out ClothingComponent? clothingComponent))
{ {
continue; continue;
} }

View File

@@ -8,7 +8,7 @@ namespace Content.Server.AI.Utility.Considerations.Combat.Melee
{ {
protected override float GetScore(Blackboard context) protected override float GetScore(Blackboard context)
{ {
return context.GetState<SelfState>().GetValue().HasComponent<UnarmedCombatComponent>() ? 1.0f : 0.0f; return context.GetState<SelfState>().GetValue()?.HasComponent<UnarmedCombatComponent>() ?? false ? 1.0f : 0.0f;
} }
} }
} }

View File

@@ -10,7 +10,7 @@ namespace Content.Server.AI.Utility.Considerations.Combat.Melee
{ {
var target = context.GetState<WeaponEntityState>().GetValue(); var target = context.GetState<WeaponEntityState>().GetValue();
if (target == null || !target.TryGetComponent(out MeleeWeaponComponent meleeWeaponComponent)) if (target == null || !target.TryGetComponent(out MeleeWeaponComponent? meleeWeaponComponent))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -10,7 +10,7 @@ namespace Content.Server.AI.Utility.Considerations.Combat.Melee
{ {
var target = context.GetState<WeaponEntityState>().GetValue(); var target = context.GetState<WeaponEntityState>().GetValue();
if (target == null || !target.TryGetComponent(out MeleeWeaponComponent meleeWeaponComponent)) if (target == null || !target.TryGetComponent(out MeleeWeaponComponent? meleeWeaponComponent))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -10,7 +10,7 @@ namespace Content.Server.AI.Utility.Considerations.Combat
{ {
var target = context.GetState<TargetEntityState>().GetValue(); var target = context.GetState<TargetEntityState>().GetValue();
if (target == null || target.Deleted || !target.TryGetComponent(out IDamageableComponent damageableComponent)) if (target == null || target.Deleted || !target.TryGetComponent(out IDamageableComponent? damageableComponent))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -10,7 +10,7 @@ namespace Content.Server.AI.Utility.Considerations.Combat
{ {
var target = context.GetState<TargetEntityState>().GetValue(); var target = context.GetState<TargetEntityState>().GetValue();
if (target == null || !target.TryGetComponent(out IMobStateComponent mobState)) if (target == null || !target.TryGetComponent(out IMobStateComponent? mobState))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -10,7 +10,7 @@ namespace Content.Server.AI.Utility.Considerations.Combat
{ {
var target = context.GetState<TargetEntityState>().GetValue(); var target = context.GetState<TargetEntityState>().GetValue();
if (target == null || !target.TryGetComponent(out IMobStateComponent mobState)) if (target == null || !target.TryGetComponent(out IMobStateComponent? mobState))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -24,7 +24,7 @@ namespace Content.Server.AI.Utility.Considerations.Containers
if (target.TryGetContainer(out var container)) if (target.TryGetContainer(out var container))
{ {
if (container.Owner.TryGetComponent(out EntityStorageComponent storageComponent)) if (container.Owner.TryGetComponent(out EntityStorageComponent? storageComponent))
{ {
if (storageComponent.IsWeldedShut && !storageComponent.Open) if (storageComponent.IsWeldedShut && !storageComponent.Open)
{ {
@@ -41,6 +41,11 @@ namespace Content.Server.AI.Utility.Considerations.Containers
var owner = context.GetState<SelfState>().GetValue(); var owner = context.GetState<SelfState>().GetValue();
if (owner == null)
{
return 0;
}
return EntitySystem.Get<AiReachableSystem>().CanAccess(owner, target, SharedInteractionSystem.InteractionRange) ? 1.0f : 0.0f; return EntitySystem.Get<AiReachableSystem>().CanAccess(owner, target, SharedInteractionSystem.InteractionRange) ? 1.0f : 0.0f;
} }
} }

View File

@@ -10,7 +10,7 @@ namespace Content.Server.AI.Utility.Considerations.Hands
{ {
var owner = context.GetState<SelfState>().GetValue(); var owner = context.GetState<SelfState>().GetValue();
if (!owner.TryGetComponent(out HandsComponent handsComponent)) if (owner == null || !owner.TryGetComponent(out HandsComponent? handsComponent))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -9,7 +9,7 @@ namespace Content.Server.AI.Utility.Considerations.Movement
{ {
var self = context.GetState<SelfState>().GetValue(); var self = context.GetState<SelfState>().GetValue();
var target = context.GetState<TargetEntityState>().GetValue(); var target = context.GetState<TargetEntityState>().GetValue();
if (target == null || target.Deleted || target.Transform.GridID != self.Transform.GridID) if (target == null || target.Deleted || target.Transform.GridID != self?.Transform.GridID)
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -10,7 +10,7 @@ namespace Content.Server.AI.Utility.Considerations.Nutrition.Drink
{ {
var target = context.GetState<TargetEntityState>().GetValue(); var target = context.GetState<TargetEntityState>().GetValue();
if (target.Deleted || !target.TryGetComponent(out SolutionContainerComponent drink)) if (target == null || target.Deleted || !target.TryGetComponent(out SolutionContainerComponent? drink))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -11,7 +11,7 @@ namespace Content.Server.AI.Utility.Considerations.Nutrition.Drink
{ {
var owner = context.GetState<SelfState>().GetValue(); var owner = context.GetState<SelfState>().GetValue();
if (!owner.TryGetComponent(out ThirstComponent thirst)) if (owner == null || !owner.TryGetComponent(out ThirstComponent? thirst))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -10,7 +10,7 @@ namespace Content.Server.AI.Utility.Considerations.Nutrition.Food
{ {
var target = context.GetState<TargetEntityState>().GetValue(); var target = context.GetState<TargetEntityState>().GetValue();
if (target.Deleted || !target.TryGetComponent(out SolutionContainerComponent food)) if (target == null || target.Deleted || !target.TryGetComponent(out SolutionContainerComponent? food))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -12,7 +12,7 @@ namespace Content.Server.AI.Utility.Considerations.Nutrition.Food
{ {
var owner = context.GetState<SelfState>().GetValue(); var owner = context.GetState<SelfState>().GetValue();
if (!owner.TryGetComponent(out HungerComponent hunger)) if (owner == null || !owner.TryGetComponent(out HungerComponent? hunger))
{ {
return 0.0f; return 0.0f;
} }

View File

@@ -21,6 +21,12 @@ namespace Content.Server.AI.Utility.Considerations.State
protected override float GetScore(Blackboard context) protected override float GetScore(Blackboard context)
{ {
var stateData = context.GetState<StoredStateIsNullState>().GetValue(); var stateData = context.GetState<StoredStateIsNullState>().GetValue();
if (stateData == null)
{
return 0;
}
context.GetStoredState(stateData, out StoredStateData<IEntity> state); context.GetStoredState(stateData, out StoredStateData<IEntity> state);
return state.GetValue() == null ? 1.0f : 0.0f; return state.GetValue() == null ? 1.0f : 0.0f;
} }

View File

@@ -37,7 +37,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Gloves
foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue()) foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue())
{ {
if (entity.TryGetComponent(out ClothingComponent clothing) && if (entity.TryGetComponent(out ClothingComponent? clothing) &&
(clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.GLOVES) != 0) (clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.GLOVES) != 0)
{ {
yield return new EquipGloves {Owner = owner, Target = entity, Bonus = Bonus}; yield return new EquipGloves {Owner = owner, Target = entity, Bonus = Bonus};

View File

@@ -35,7 +35,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Gloves
foreach (var entity in context.GetState<NearbyClothingState>().GetValue()) foreach (var entity in context.GetState<NearbyClothingState>().GetValue())
{ {
if (entity.TryGetComponent(out ClothingComponent clothing) && if (entity.TryGetComponent(out ClothingComponent? clothing) &&
(clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.GLOVES) != 0) (clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.GLOVES) != 0)
{ {
yield return new PickUpGloves {Owner = owner, Target = entity, Bonus = Bonus}; yield return new PickUpGloves {Owner = owner, Target = entity, Bonus = Bonus};

View File

@@ -36,7 +36,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Head
foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue()) foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue())
{ {
if (entity.TryGetComponent(out ClothingComponent clothing) && if (entity.TryGetComponent(out ClothingComponent? clothing) &&
(clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.HEAD) != 0) (clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.HEAD) != 0)
{ {
yield return new EquipHead {Owner = owner, Target = entity, Bonus = Bonus}; yield return new EquipHead {Owner = owner, Target = entity, Bonus = Bonus};

View File

@@ -35,10 +35,10 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Head
foreach (var entity in context.GetState<NearbyClothingState>().GetValue()) foreach (var entity in context.GetState<NearbyClothingState>().GetValue())
{ {
if (entity.TryGetComponent(out ClothingComponent clothing) && if (entity.TryGetComponent(out ClothingComponent? clothing) &&
(clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.HEAD) != 0) (clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.HEAD) != 0)
{ {
yield return new PickUpHead() {Owner = owner, Target = entity, Bonus = Bonus}; yield return new PickUpHead {Owner = owner, Target = entity, Bonus = Bonus};
} }
} }
} }

View File

@@ -37,10 +37,10 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.OuterClothing
foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue()) foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue())
{ {
if (entity.TryGetComponent(out ClothingComponent clothing) && if (entity.TryGetComponent(out ClothingComponent? clothing) &&
(clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.OUTERCLOTHING) != 0) (clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.OUTERCLOTHING) != 0)
{ {
yield return new EquipOuterClothing() {Owner = owner, Target = entity, Bonus = Bonus}; yield return new EquipOuterClothing {Owner = owner, Target = entity, Bonus = Bonus};
} }
} }
} }

View File

@@ -36,10 +36,10 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.OuterClothing
foreach (var entity in context.GetState<NearbyClothingState>().GetValue()) foreach (var entity in context.GetState<NearbyClothingState>().GetValue())
{ {
if (entity.TryGetComponent(out ClothingComponent clothing) && if (entity.TryGetComponent(out ClothingComponent? clothing) &&
(clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.OUTERCLOTHING) != 0) (clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.OUTERCLOTHING) != 0)
{ {
yield return new PickUpOuterClothing() {Owner = owner, Target = entity, Bonus = Bonus}; yield return new PickUpOuterClothing {Owner = owner, Target = entity, Bonus = Bonus};
} }
} }
} }

View File

@@ -37,10 +37,10 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Shoes
foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue()) foreach (var entity in context.GetState<EnumerableInventoryState>().GetValue())
{ {
if (entity.TryGetComponent(out ClothingComponent clothing) && if (entity.TryGetComponent(out ClothingComponent? clothing) &&
(clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.SHOES) != 0) (clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.SHOES) != 0)
{ {
yield return new EquipShoes() {Owner = owner, Target = entity, Bonus = Bonus}; yield return new EquipShoes {Owner = owner, Target = entity, Bonus = Bonus};
} }
} }
} }

View File

@@ -36,7 +36,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Clothing.Shoes
foreach (var entity in context.GetState<NearbyClothingState>().GetValue()) foreach (var entity in context.GetState<NearbyClothingState>().GetValue())
{ {
if (entity.TryGetComponent(out ClothingComponent clothing) && if (entity.TryGetComponent(out ClothingComponent? clothing) &&
(clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.SHOES) != 0) (clothing.SlotFlags & EquipmentSlotDefines.SlotFlags.SHOES) != 0)
{ {
yield return new PickUpShoes {Owner = owner, Target = entity, Bonus = Bonus}; yield return new PickUpShoes {Owner = owner, Target = entity, Bonus = Bonus};

View File

@@ -38,7 +38,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
continue; continue;
} }
yield return new EquipMelee() {Owner = owner, Target = entity, Bonus = Bonus}; yield return new EquipMelee {Owner = owner, Target = entity, Bonus = Bonus};
} }
} }
} }

View File

@@ -31,7 +31,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
public override IEnumerable<UtilityAction> GetActions(Blackboard context) public override IEnumerable<UtilityAction> GetActions(Blackboard context)
{ {
var owner = context.GetState<SelfState>().GetValue(); var owner = context.GetState<SelfState>().GetValue();
if (!owner.TryGetComponent(out AiControllerComponent controller)) if (!owner.TryGetComponent(out AiControllerComponent? controller))
{ {
throw new InvalidOperationException(); throw new InvalidOperationException();
} }
@@ -39,7 +39,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
foreach (var target in EntitySystem.Get<AiFactionTagSystem>() foreach (var target in EntitySystem.Get<AiFactionTagSystem>()
.GetNearbyHostiles(owner, controller.VisionRadius)) .GetNearbyHostiles(owner, controller.VisionRadius))
{ {
yield return new MeleeWeaponAttackEntity() {Owner = owner, Target = target, Bonus = Bonus}; yield return new MeleeWeaponAttackEntity {Owner = owner, Target = target, Bonus = Bonus};
} }
} }
} }

View File

@@ -31,7 +31,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee
public override IEnumerable<UtilityAction> GetActions(Blackboard context) public override IEnumerable<UtilityAction> GetActions(Blackboard context)
{ {
var owner = context.GetState<SelfState>().GetValue(); var owner = context.GetState<SelfState>().GetValue();
if (!owner.TryGetComponent(out AiControllerComponent controller)) if (!owner.TryGetComponent(out AiControllerComponent? controller))
{ {
throw new InvalidOperationException(); throw new InvalidOperationException();
} }

View File

@@ -12,7 +12,7 @@ namespace Content.Server.AI.Utility.ExpandableActions
/// </summary> /// </summary>
public abstract class ExpandableUtilityAction : IAiUtility public abstract class ExpandableUtilityAction : IAiUtility
{ {
public IEntity Owner { get; set; } public IEntity Owner { get; set; } = default!;
public abstract float Bonus { get; } public abstract float Bonus { get; }

View File

@@ -7,9 +7,9 @@ namespace Content.Server.AI.Utility
{ {
public static class UtilityAiHelpers public static class UtilityAiHelpers
{ {
public static Blackboard GetBlackboard(IEntity entity) public static Blackboard? GetBlackboard(IEntity entity)
{ {
if (!entity.TryGetComponent(out AiControllerComponent aiControllerComponent)) if (!entity.TryGetComponent(out AiControllerComponent? aiControllerComponent))
{ {
return null; return null;
} }

View File

@@ -24,7 +24,7 @@ namespace Content.Server.AI.Utils
return false; return false;
} }
if (owner.TryGetComponent(out AiControllerComponent controller)) if (owner.TryGetComponent(out AiControllerComponent? controller))
{ {
var targetRange = (target.Transform.Coordinates.Position - owner.Transform.Coordinates.Position).Length; var targetRange = (target.Transform.Coordinates.Position - owner.Transform.Coordinates.Position).Length;
if (targetRange > controller.VisionRadius) if (targetRange > controller.VisionRadius)

View File

@@ -32,14 +32,14 @@ namespace Content.Server.AI.WorldState
public abstract class StateData<T> : IAiState public abstract class StateData<T> : IAiState
{ {
public abstract string Name { get; } public abstract string Name { get; }
protected IEntity Owner { get; private set; } protected IEntity Owner { get; private set; } = default!;
public void Setup(IEntity owner) public void Setup(IEntity owner)
{ {
Owner = owner; Owner = owner;
} }
public abstract T GetValue(); public abstract T? GetValue();
} }
/// <summary> /// <summary>
@@ -51,21 +51,21 @@ namespace Content.Server.AI.WorldState
{ {
// Probably not the best class name but couldn't think of anything better // Probably not the best class name but couldn't think of anything better
public abstract string Name { get; } public abstract string Name { get; }
private IEntity Owner { get; set; } private IEntity? Owner { get; set; }
private T _value; private T? _value;
public void Setup(IEntity owner) public void Setup(IEntity owner)
{ {
Owner = owner; Owner = owner;
} }
public virtual void SetValue(T value) public virtual void SetValue(T? value)
{ {
_value = value; _value = value;
} }
public T GetValue() public T? GetValue()
{ {
return _value; return _value;
} }
@@ -79,8 +79,8 @@ namespace Content.Server.AI.WorldState
public abstract class PlanningStateData<T> : IAiState, IPlanningState public abstract class PlanningStateData<T> : IAiState, IPlanningState
{ {
public abstract string Name { get; } public abstract string Name { get; }
protected IEntity Owner { get; private set; } protected IEntity? Owner { get; private set; }
protected T Value; protected T? Value;
public void Setup(IEntity owner) public void Setup(IEntity owner)
{ {
@@ -89,12 +89,12 @@ namespace Content.Server.AI.WorldState
public abstract void Reset(); public abstract void Reset();
public T GetValue() public T? GetValue()
{ {
return Value; return Value;
} }
public virtual void SetValue(T value) public virtual void SetValue(T? value)
{ {
Value = value; Value = value;
} }
@@ -108,9 +108,9 @@ namespace Content.Server.AI.WorldState
public abstract class CachedStateData<T> : IAiState, ICachedState public abstract class CachedStateData<T> : IAiState, ICachedState
{ {
public abstract string Name { get; } public abstract string Name { get; }
protected IEntity Owner { get; private set; } protected IEntity Owner { get; private set; } = default!;
private bool _cached; private bool _cached;
protected T Value; protected T Value = default!;
private TimeSpan _lastCache = TimeSpan.Zero; private TimeSpan _lastCache = TimeSpan.Zero;
/// <summary> /// <summary>
/// How long something stays in the cache before new values are retrieved /// How long something stays in the cache before new values are retrieved

View File

@@ -15,7 +15,7 @@ namespace Content.Server.AI.WorldState.States.Clothing
{ {
var result = new Dictionary<EquipmentSlotDefines.Slots, IEntity>(); var result = new Dictionary<EquipmentSlotDefines.Slots, IEntity>();
if (!Owner.TryGetComponent(out InventoryComponent inventoryComponent)) if (!Owner.TryGetComponent(out InventoryComponent? inventoryComponent))
{ {
return result; return result;
} }

View File

@@ -18,7 +18,7 @@ namespace Content.Server.AI.WorldState.States.Clothing
{ {
var result = new List<IEntity>(); var result = new List<IEntity>();
if (!Owner.TryGetComponent(out AiControllerComponent controller)) if (!Owner.TryGetComponent(out AiControllerComponent? controller))
{ {
return result; return result;
} }

View File

@@ -16,7 +16,7 @@ namespace Content.Server.AI.WorldState.States.Combat.Nearby
{ {
var result = new List<IEntity>(); var result = new List<IEntity>();
if (!Owner.TryGetComponent(out AiControllerComponent controller)) if (!Owner.TryGetComponent(out AiControllerComponent? controller))
{ {
return result; return result;
} }

View File

@@ -9,7 +9,7 @@ namespace Content.Server.AI.WorldState.States.Hands
public override string Name => "AnyFreeHand"; public override string Name => "AnyFreeHand";
public override bool GetValue() public override bool GetValue()
{ {
if (!Owner.TryGetComponent(out HandsComponent handsComponent)) if (!Owner.TryGetComponent(out HandsComponent? handsComponent))
{ {
return false; return false;
} }

View File

@@ -13,7 +13,7 @@ namespace Content.Server.AI.WorldState.States.Hands
{ {
var result = new List<string>(); var result = new List<string>();
if (!Owner.TryGetComponent(out HandsComponent handsComponent)) if (!Owner.TryGetComponent(out HandsComponent? handsComponent))
{ {
return result; return result;
} }

View File

@@ -12,7 +12,7 @@ namespace Content.Server.AI.WorldState.States.Hands
public override List<IEntity> GetValue() public override List<IEntity> GetValue()
{ {
var result = new List<IEntity>(); var result = new List<IEntity>();
if (!Owner.TryGetComponent(out HandsComponent handsComponent)) if (!Owner.TryGetComponent(out HandsComponent? handsComponent))
{ {
return result; return result;
} }

View File

@@ -12,9 +12,9 @@ namespace Content.Server.AI.WorldState.States.Inventory
{ {
public override string Name => "EquippedEntity"; public override string Name => "EquippedEntity";
public override IEntity GetValue() public override IEntity? GetValue()
{ {
if (!Owner.TryGetComponent(out HandsComponent handsComponent)) if (!Owner.TryGetComponent(out HandsComponent? handsComponent))
{ {
return null; return null;
} }

View File

@@ -12,7 +12,7 @@ namespace Content.Server.AI.WorldState.States.Inventory
public override IEnumerable<IEntity> GetValue() public override IEnumerable<IEntity> GetValue()
{ {
if (Owner.TryGetComponent(out HandsComponent handsComponent)) if (Owner.TryGetComponent(out HandsComponent? handsComponent))
{ {
foreach (var item in handsComponent.GetAllHeldItems()) foreach (var item in handsComponent.GetAllHeldItems())
{ {

View File

@@ -14,7 +14,7 @@ namespace Content.Server.AI.WorldState.States.Inventory
// Fine for now I guess // Fine for now I guess
public override string Name => "LastOpenedStorage"; public override string Name => "LastOpenedStorage";
public override void SetValue(IEntity value) public override void SetValue(IEntity? value)
{ {
base.SetValue(value); base.SetValue(value);
if (value != null && !value.HasComponent<EntityStorageComponent>()) if (value != null && !value.HasComponent<EntityStorageComponent>())

View File

@@ -16,7 +16,7 @@ namespace Content.Server.AI.WorldState.States.Mobs
{ {
var result = new List<IEntity>(); var result = new List<IEntity>();
if (!Owner.TryGetComponent(out AiControllerComponent controller)) if (!Owner.TryGetComponent(out AiControllerComponent? controller))
{ {
return result; return result;
} }

View File

@@ -17,7 +17,7 @@ namespace Content.Server.AI.WorldState.States.Mobs
{ {
var result = new List<IEntity>(); var result = new List<IEntity>();
if (!Owner.TryGetComponent(out AiControllerComponent controller)) if (!Owner.TryGetComponent(out AiControllerComponent? controller))
{ {
return result; return result;
} }
@@ -27,6 +27,11 @@ namespace Content.Server.AI.WorldState.States.Mobs
foreach (var player in nearbyPlayers) foreach (var player in nearbyPlayers)
{ {
if (player.AttachedEntity == null)
{
continue;
}
if (player.AttachedEntity != Owner && player.AttachedEntity.HasComponent<IDamageableComponent>()) if (player.AttachedEntity != Owner && player.AttachedEntity.HasComponent<IDamageableComponent>())
{ {
result.Add(player.AttachedEntity); result.Add(player.AttachedEntity);

View File

@@ -12,7 +12,7 @@ namespace Content.Server.AI.WorldState.States.Nutrition
public override bool GetValue() public override bool GetValue()
{ {
if (!Owner.TryGetComponent(out HungerComponent hungerComponent)) if (!Owner.TryGetComponent(out HungerComponent? hungerComponent))
{ {
return false; return false;
} }

View File

@@ -18,7 +18,7 @@ namespace Content.Server.AI.WorldState.States.Nutrition
{ {
var result = new List<IEntity>(); var result = new List<IEntity>();
if (!Owner.TryGetComponent(out AiControllerComponent controller)) if (!Owner.TryGetComponent(out AiControllerComponent? controller))
{ {
return result; return result;
} }

View File

@@ -18,7 +18,7 @@ namespace Content.Server.AI.WorldState.States.Nutrition
{ {
var result = new List<IEntity>(); var result = new List<IEntity>();
if (!Owner.TryGetComponent(out AiControllerComponent controller)) if (!Owner.TryGetComponent(out AiControllerComponent? controller))
{ {
return result; return result;
} }

View File

@@ -12,7 +12,7 @@ namespace Content.Server.AI.WorldState.States.Nutrition
public override bool GetValue() public override bool GetValue()
{ {
if (!Owner.TryGetComponent(out ThirstComponent thirstComponent)) if (!Owner.TryGetComponent(out ThirstComponent? thirstComponent))
{ {
return false; return false;
} }

View File

@@ -21,14 +21,14 @@ namespace Content.Server.Actions
args.Performer.PopupMessageEveryone(Message); args.Performer.PopupMessageEveryone(Message);
if (Cooldown > 0) if (Cooldown > 0)
{ {
args.ItemActions.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(Cooldown)); args.ItemActions?.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(Cooldown));
} }
} }
public void DoInstantAction(InstantActionEventArgs args) public void DoInstantAction(InstantActionEventArgs args)
{ {
args.Performer.PopupMessageEveryone(Message); args.Performer.PopupMessageEveryone(Message);
args.PerformerActions.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(Cooldown)); args.PerformerActions?.Cooldown(args.ActionType, Cooldowns.SecondsFromNow(Cooldown));
} }
} }
} }

View File

@@ -46,7 +46,7 @@ namespace Content.Server.Administration.Commands
if (canReturn) if (canReturn)
{ {
ghost.Name = mind.CharacterName; ghost.Name = mind.CharacterName ?? string.Empty;
mind.Visit(ghost); mind.Visit(ghost);
} }
else else

View File

@@ -7,6 +7,7 @@ using Robust.Shared.Console;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Localization; using Robust.Shared.Localization;
using Robust.Shared.Utility;
namespace Content.Server.Administration.Commands namespace Content.Server.Administration.Commands
{ {
@@ -33,7 +34,6 @@ namespace Content.Server.Administration.Commands
} }
var mind = player.ContentData().Mind;
var entityManager = IoCManager.Resolve<IEntityManager>(); var entityManager = IoCManager.Resolve<IEntityManager>();
if (!int.TryParse(args[0], out var targetId)) if (!int.TryParse(args[0], out var targetId))
@@ -51,20 +51,25 @@ namespace Content.Server.Administration.Commands
} }
var target = entityManager.GetEntity(eUid); var target = entityManager.GetEntity(eUid);
if (!target.TryGetComponent(out MindComponent mindComponent)) if (!target.TryGetComponent(out MindComponent? mindComponent))
{ {
shell.WriteLine(Loc.GetString("Target entity is not a mob!")); shell.WriteLine(Loc.GetString("Target entity is not a mob!"));
return; return;
} }
var oldEntity = mind.CurrentEntity; var mind = player.ContentData()?.Mind;
DebugTools.AssertNotNull(mind);
var oldEntity = mind!.CurrentEntity;
mindComponent.Mind?.TransferTo(null); mindComponent.Mind?.TransferTo(null);
mind.TransferTo(target); mind.TransferTo(target);
if(oldEntity.HasComponent<GhostComponent>()) DebugTools.AssertNotNull(oldEntity);
oldEntity.Delete();
if (oldEntity!.HasComponent<GhostComponent>())
oldEntity.Delete();
} }
} }
} }

View File

@@ -115,7 +115,7 @@ namespace Content.Server.Administration.Commands
if (found.GetGridId(entityManager) != GridId.Invalid) if (found.GetGridId(entityManager) != GridId.Invalid)
{ {
player.AttachedEntity.Transform.Coordinates = found; player.AttachedEntity.Transform.Coordinates = found;
if (player.AttachedEntity.TryGetComponent(out IPhysBody physics)) if (player.AttachedEntity.TryGetComponent(out IPhysBody? physics))
{ {
physics.LinearVelocity = Vector2.Zero; physics.LinearVelocity = Vector2.Zero;
} }

View File

@@ -14,7 +14,7 @@ namespace Content.Server.Alert.Click
{ {
public void AlertClicked(ClickAlertEventArgs args) public void AlertClicked(ClickAlertEventArgs args)
{ {
if (args.Player.TryGetComponent(out FlammableComponent flammable)) if (args.Player.TryGetComponent(out FlammableComponent? flammable))
{ {
flammable.Resist(); flammable.Resist();
} }

View File

@@ -14,7 +14,7 @@ namespace Content.Server.Alert.Click
{ {
public void AlertClicked(ClickAlertEventArgs args) public void AlertClicked(ClickAlertEventArgs args)
{ {
if (args.Player.TryGetComponent(out ShuttleControllerComponent controller)) if (args.Player.TryGetComponent(out ShuttleControllerComponent? controller))
{ {
controller.RemoveController(); controller.RemoveController();
} }

View File

@@ -14,7 +14,7 @@ namespace Content.Server.Alert.Click
{ {
public void AlertClicked(ClickAlertEventArgs args) public void AlertClicked(ClickAlertEventArgs args)
{ {
if (args.Player.TryGetComponent(out BuckleComponent buckle)) if (args.Player.TryGetComponent(out BuckleComponent? buckle))
{ {
buckle.TryUnbuckle(args.Player); buckle.TryUnbuckle(args.Player);
} }

View File

@@ -15,7 +15,7 @@ namespace Content.Server.Atmos
private readonly HashSet<TileAtmosphere> _tiles = new(); private readonly HashSet<TileAtmosphere> _tiles = new();
[ViewVariables] [ViewVariables]
private GridAtmosphereComponent _gridAtmosphereComponent; private GridAtmosphereComponent _gridAtmosphereComponent = default!;
[ViewVariables] [ViewVariables]
public int DismantleCooldown { get; set; } public int DismantleCooldown { get; set; }
@@ -139,7 +139,7 @@ namespace Content.Server.Atmos
Dismantle(false); Dismantle(false);
_gridAtmosphereComponent = null; _gridAtmosphereComponent = null!;
} }
} }
} }

View File

@@ -1,3 +1,4 @@
#nullable disable warnings
#nullable enable annotations #nullable enable annotations
using System; using System;
using System.Buffers; using System.Buffers;

View File

@@ -21,7 +21,7 @@ namespace Content.Server.Cargo
} }
} }
public event Action OnBalanceChange; public event Action? OnBalanceChange;
public CargoBankAccount(int id, string name, int balance) public CargoBankAccount(int id, string name, int balance)
{ {

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Content.Shared.Prototypes.Cargo; using Content.Shared.Prototypes.Cargo;
using Robust.Shared.Localization; using Robust.Shared.Localization;
@@ -38,15 +39,9 @@ namespace Content.Server.Cargo
return _orders.Values.ToList(); return _orders.Values.ToList();
} }
public bool TryGetOrder(int id, out CargoOrderData order) public bool TryGetOrder(int id, [NotNullWhen(true)] out CargoOrderData? order)
{ {
if (_orders.TryGetValue(id, out var _order)) return _orders.TryGetValue(id, out order);
{
order = _order;
return true;
}
order = null;
return false;
} }
public List<CargoOrderData> SpliceApproved() public List<CargoOrderData> SpliceApproved()

View File

@@ -60,7 +60,7 @@ namespace Content.Server.Chat
private const string MaxLengthExceededMessage = "Your message exceeded {0} character limit"; private const string MaxLengthExceededMessage = "Your message exceeded {0} character limit";
//TODO: make prio based? //TODO: make prio based?
private List<TransformChat> _chatTransformHandlers; private readonly List<TransformChat> _chatTransformHandlers = new();
private bool _oocEnabled = true; private bool _oocEnabled = true;
private bool _adminOocEnabled = true; private bool _adminOocEnabled = true;
@@ -74,8 +74,6 @@ namespace Content.Server.Chat
msg.MaxMessageLength = MaxMessageLength; msg.MaxMessageLength = MaxMessageLength;
_netManager.ServerSendToAll(msg); _netManager.ServerSendToAll(msg);
_chatTransformHandlers = new List<TransformChat>();
_configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true); _configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
_configurationManager.OnValueChanged(CCVars.AdminOocEnabled, OnAdminOocEnabledChanged, true); _configurationManager.OnValueChanged(CCVars.AdminOocEnabled, OnAdminOocEnabledChanged, true);
} }
@@ -128,7 +126,7 @@ namespace Content.Server.Chat
} }
// Check if message exceeds the character limit if the sender is a player // Check if message exceeds the character limit if the sender is a player
if (source.TryGetComponent(out IActorComponent actor) && if (source.TryGetComponent(out IActorComponent? actor) &&
message.Length > MaxMessageLength) message.Length > MaxMessageLength)
{ {
var feedback = Loc.GetString(MaxLengthExceededMessage, MaxMessageLength); var feedback = Loc.GetString(MaxLengthExceededMessage, MaxMessageLength);
@@ -158,9 +156,9 @@ namespace Content.Server.Chat
message = message[0].ToString().ToUpper() + message = message[0].ToString().ToUpper() +
message.Remove(0, 1); message.Remove(0, 1);
if (source.TryGetComponent(out InventoryComponent inventory) && if (source.TryGetComponent(out InventoryComponent? inventory) &&
inventory.TryGetSlotItem(EquipmentSlotDefines.Slots.EARS, out ItemComponent item) && inventory.TryGetSlotItem(EquipmentSlotDefines.Slots.EARS, out ItemComponent? item) &&
item.Owner.TryGetComponent(out HeadsetComponent headset)) item.Owner.TryGetComponent(out HeadsetComponent? headset))
{ {
headset.RadioRequested = true; headset.RadioRequested = true;
} }
@@ -197,13 +195,13 @@ namespace Content.Server.Chat
} }
// Check if entity is a player // Check if entity is a player
if (!source.TryGetComponent(out IActorComponent actor)) if (!source.TryGetComponent(out IActorComponent? actor))
{ {
return; return;
} }
// Check if message exceeds the character limit // Check if message exceeds the character limit
if (actor.playerSession != null && action.Length > MaxMessageLength) if (action.Length > MaxMessageLength)
{ {
DispatchServerMessage(actor.playerSession, Loc.GetString(MaxLengthExceededMessage, MaxMessageLength)); DispatchServerMessage(actor.playerSession, Loc.GetString(MaxLengthExceededMessage, MaxMessageLength));
return; return;
@@ -282,7 +280,7 @@ namespace Content.Server.Chat
var msg = _netManager.CreateNetMessage<MsgChatMessage>(); var msg = _netManager.CreateNetMessage<MsgChatMessage>();
msg.Channel = ChatChannel.Dead; msg.Channel = ChatChannel.Dead;
msg.Message = message; msg.Message = message;
msg.MessageWrap = $"{Loc.GetString("DEAD")}: {player.AttachedEntity.Name}: {{0}}"; msg.MessageWrap = $"{Loc.GetString("DEAD")}: {player.AttachedEntity?.Name}: {{0}}";
msg.SenderEntity = player.AttachedEntityUid.GetValueOrDefault(); msg.SenderEntity = player.AttachedEntityUid.GetValueOrDefault();
_netManager.ServerSendToMany(msg, clients.ToList()); _netManager.ServerSendToMany(msg, clients.ToList());
} }

View File

@@ -25,7 +25,7 @@ namespace Content.Server.Chemistry.Metabolism
ReagentUnit IMetabolizable.Metabolize(IEntity solutionEntity, string reagentId, float tickTime) ReagentUnit IMetabolizable.Metabolize(IEntity solutionEntity, string reagentId, float tickTime)
{ {
var metabolismAmount = MetabolismRate * tickTime; var metabolismAmount = MetabolismRate * tickTime;
if (solutionEntity.TryGetComponent(out ThirstComponent thirst)) if (solutionEntity.TryGetComponent(out ThirstComponent? thirst))
thirst.UpdateThirst(metabolismAmount.Float() * HydrationFactor); thirst.UpdateThirst(metabolismAmount.Float() * HydrationFactor);
//Return amount of reagent to be removed, remove reagent regardless of ThirstComponent presence //Return amount of reagent to be removed, remove reagent regardless of ThirstComponent presence

View File

@@ -27,7 +27,7 @@ namespace Content.Server.Chemistry.Metabolism
ReagentUnit IMetabolizable.Metabolize(IEntity solutionEntity, string reagentId, float tickTime) ReagentUnit IMetabolizable.Metabolize(IEntity solutionEntity, string reagentId, float tickTime)
{ {
var metabolismAmount = MetabolismRate * tickTime; var metabolismAmount = MetabolismRate * tickTime;
if (solutionEntity.TryGetComponent(out HungerComponent hunger)) if (solutionEntity.TryGetComponent(out HungerComponent? hunger))
hunger.UpdateFood(metabolismAmount.Float() * NutritionFactor); hunger.UpdateFood(metabolismAmount.Float() * NutritionFactor);
//Return amount of reagent to be removed, remove reagent regardless of HungerComponent presence //Return amount of reagent to be removed, remove reagent regardless of HungerComponent presence

View File

@@ -26,12 +26,12 @@ namespace Content.Server.Chemistry.ReactionEffects
/// </summary> /// </summary>
[DataField("maxScale")] private float _maxScale = 1; [DataField("maxScale")] private float _maxScale = 1;
public void React(IEntity solutionEntity, double intensity) public void React(IEntity? solutionEntity, double intensity)
{ {
var floatIntensity = (float)intensity; var floatIntensity = (float) intensity;
if (solutionEntity == null) if (solutionEntity == null)
return; return;
if(!solutionEntity.TryGetComponent(out SolutionContainerComponent solution)) if (!solutionEntity.HasComponent<SolutionContainerComponent>())
return; return;
//Handle scaling //Handle scaling

View File

@@ -17,7 +17,7 @@ namespace Content.Server.Chemistry.TileReactions
var amount = ReagentUnit.Zero; var amount = ReagentUnit.Zero;
foreach (var entity in entities) foreach (var entity in entities)
{ {
if (entity.TryGetComponent(out CleanableComponent cleanable)) if (entity.TryGetComponent(out CleanableComponent? cleanable))
{ {
var next = amount + cleanable.CleanAmount; var next = amount + cleanable.CleanAmount;
// Nothing left? // Nothing left?

View File

@@ -19,7 +19,7 @@ namespace Content.Server.Chemistry.TileReactions
{ {
if (reactVolume <= ReagentUnit.Zero || tile.Tile.IsEmpty) return ReagentUnit.Zero; if (reactVolume <= ReagentUnit.Zero || tile.Tile.IsEmpty) return ReagentUnit.Zero;
var tileAtmos = tile.GridIndices.GetTileAtmosphere(tile.GridIndex); var tileAtmos = tile.GridIndices.GetTileAtmosphere(tile.GridIndex);
if (tileAtmos == null || !tileAtmos.Hotspot.Valid) return ReagentUnit.Zero; if (tileAtmos == null || !tileAtmos.Hotspot.Valid || tileAtmos.Air == null) return ReagentUnit.Zero;
tileAtmos.Air.Temperature = tileAtmos.Air.Temperature =
MathF.Max(MathF.Min(tileAtmos.Air.Temperature - (_coolingTemperature * 1000f), MathF.Max(MathF.Min(tileAtmos.Air.Temperature - (_coolingTemperature * 1000f),
tileAtmos.Air.Temperature / _coolingTemperature), tileAtmos.Air.Temperature / _coolingTemperature),

View File

@@ -18,7 +18,7 @@ namespace Content.Server.Chemistry.TileReactions
{ {
if (reactVolume <= ReagentUnit.Zero || tile.Tile.IsEmpty) return ReagentUnit.Zero; if (reactVolume <= ReagentUnit.Zero || tile.Tile.IsEmpty) return ReagentUnit.Zero;
var tileAtmos = tile.GridIndices.GetTileAtmosphere(tile.GridIndex); var tileAtmos = tile.GridIndices.GetTileAtmosphere(tile.GridIndex);
if (tileAtmos == null || !tileAtmos.Hotspot.Valid) return ReagentUnit.Zero; if (tileAtmos?.Air == null || !tileAtmos.Hotspot.Valid) return ReagentUnit.Zero;
tileAtmos.Air.Temperature *= MathF.Max(_temperatureMultiplier * reactVolume.Float(), 1f); tileAtmos.Air.Temperature *= MathF.Max(_temperatureMultiplier * reactVolume.Float(), 1f);
tileAtmos.Air.React(tileAtmos); tileAtmos.Air.React(tileAtmos);
return reactVolume; return reactVolume;

View File

@@ -17,7 +17,14 @@ namespace Content.Server.Commands.Chat
public void Execute(IConsoleShell shell, string argStr, string[] args) public void Execute(IConsoleShell shell, string argStr, string[] args)
{ {
var player = shell.Player as IPlayerSession; var player = (IPlayerSession?) shell.Player;
if (player == null)
{
shell.WriteError("You can't run this command locally.");
return;
}
if (args.Length < 1) if (args.Length < 1)
return; return;

Some files were not shown because too many files have changed in this diff Show More