diff --git a/Content.Server/AI/Operators/AiOperator.cs b/Content.Server/AI/Operators/AiOperator.cs index 94c809eabd..4714998040 100644 --- a/Content.Server/AI/Operators/AiOperator.cs +++ b/Content.Server/AI/Operators/AiOperator.cs @@ -5,38 +5,36 @@ namespace Content.Server.AI.Operators { public abstract class AiOperator { - public bool HasStartup => _hasStartup; - private bool _hasStartup = false; - private bool _hasShutdown = false; + public bool HasStartup { get; private set; } + + public bool HasShutdown { get; private set; } /// /// Called once when the AiLogicProcessor starts this action /// - public virtual bool TryStartup() + /// true if it hasn't started up previously + public virtual bool Startup() { // If we've already startup then no point continuing // This signals to the override that it's already startup // Should probably throw but it made some code elsewhere marginally easier - if (_hasStartup) - { + if (HasStartup) return false; - } - - _hasStartup = true; + + HasStartup = true; return true; } /// /// Called once when the AiLogicProcessor is done with this action if the outcome is successful or fails. /// - public virtual void Shutdown(Outcome outcome) + public virtual bool Shutdown(Outcome outcome) { - if (_hasShutdown) - { - throw new InvalidOperationException("AiOperator has already shutdown"); - } + if (HasShutdown) + return false; - _hasShutdown = true; + HasShutdown = true; + return true; } /// @@ -53,4 +51,4 @@ namespace Content.Server.AI.Operators Continuing, Failed, } -} \ No newline at end of file +} diff --git a/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs b/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs index 69db28af24..90a174ea34 100644 --- a/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs +++ b/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs @@ -22,9 +22,9 @@ namespace Content.Server.AI.Operators.Combat.Melee _burstTime = burstTime; } - public override bool TryStartup() + public override bool Startup() { - if (!base.TryStartup()) + if (!base.Startup()) { return true; } @@ -42,13 +42,17 @@ namespace Content.Server.AI.Operators.Combat.Melee return true; } - public override void Shutdown(Outcome outcome) + public override bool Shutdown(Outcome outcome) { - base.Shutdown(outcome); + if (!base.Shutdown(outcome)) + return false; + if (_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) { combatModeComponent.IsInCombatMode = false; } + + return true; } public override Outcome Execute(float frameTime) diff --git a/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs b/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs index 3d00db189d..a614b34c21 100644 --- a/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs +++ b/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs @@ -22,9 +22,9 @@ namespace Content.Server.AI.Operators.Combat.Melee _burstTime = burstTime; } - public override bool TryStartup() + public override bool Startup() { - if (!base.TryStartup()) + if (!base.Startup()) { return true; } @@ -51,13 +51,17 @@ namespace Content.Server.AI.Operators.Combat.Melee return true; } - public override void Shutdown(Outcome outcome) + public override bool Shutdown(Outcome outcome) { - base.Shutdown(outcome); + if (!base.Shutdown(outcome)) + return false; + if (_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) { combatModeComponent.IsInCombatMode = false; } + + return true; } public override Outcome Execute(float frameTime) diff --git a/Content.Server/AI/Operators/Inventory/CloseStorageOperator.cs b/Content.Server/AI/Operators/Inventory/CloseStorageOperator.cs index fd4567ffba..0b3208588d 100644 --- a/Content.Server/AI/Operators/Inventory/CloseStorageOperator.cs +++ b/Content.Server/AI/Operators/Inventory/CloseStorageOperator.cs @@ -21,9 +21,9 @@ namespace Content.Server.AI.Operators.Inventory _owner = owner; } - public override bool TryStartup() + public override bool Startup() { - if (!base.TryStartup()) + if (!base.Startup()) { return true; } @@ -40,12 +40,15 @@ namespace Content.Server.AI.Operators.Inventory return _target != null; } - public override void Shutdown(Outcome outcome) + public override bool Shutdown(Outcome outcome) { - base.Shutdown(outcome); + if (!base.Shutdown(outcome)) + return false; + var blackboard = UtilityAiHelpers.GetBlackboard(_owner); blackboard?.GetState().SetValue(null); + return true; } public override Outcome Execute(float frameTime) diff --git a/Content.Server/AI/Operators/Movement/MoveToEntityOperator.cs b/Content.Server/AI/Operators/Movement/MoveToEntityOperator.cs index 0b84e525fa..0327b8b9da 100644 --- a/Content.Server/AI/Operators/Movement/MoveToEntityOperator.cs +++ b/Content.Server/AI/Operators/Movement/MoveToEntityOperator.cs @@ -32,9 +32,9 @@ namespace Content.Server.AI.Operators.Movement _requiresInRangeUnobstructed = requiresInRangeUnobstructed; } - public override bool TryStartup() + public override bool Startup() { - if (!base.TryStartup()) + if (!base.Startup()) { return true; } @@ -45,11 +45,14 @@ namespace Content.Server.AI.Operators.Movement return true; } - public override void Shutdown(Outcome outcome) + public override bool Shutdown(Outcome outcome) { - base.Shutdown(outcome); + if (!base.Shutdown(outcome)) + return false; + var steering = EntitySystem.Get(); steering.Unregister(_owner); + return true; } public override Outcome Execute(float frameTime) diff --git a/Content.Server/AI/Operators/Movement/MoveToGridOperator.cs b/Content.Server/AI/Operators/Movement/MoveToGridOperator.cs index c86923d3ec..19f8ef465a 100644 --- a/Content.Server/AI/Operators/Movement/MoveToGridOperator.cs +++ b/Content.Server/AI/Operators/Movement/MoveToGridOperator.cs @@ -21,9 +21,9 @@ namespace Content.Server.AI.Operators.Movement DesiredRange = desiredRange; } - public override bool TryStartup() + public override bool Startup() { - if (!base.TryStartup()) + if (!base.Startup()) { return true; } @@ -34,11 +34,14 @@ namespace Content.Server.AI.Operators.Movement return true; } - public override void Shutdown(Outcome outcome) + public override bool Shutdown(Outcome outcome) { - base.Shutdown(outcome); + if (!base.Shutdown(outcome)) + return false; + var steering = EntitySystem.Get(); steering.Unregister(_owner); + return true; } public override Outcome Execute(float frameTime) diff --git a/Content.Server/AI/Operators/Sequences/SequenceOperator.cs b/Content.Server/AI/Operators/Sequences/SequenceOperator.cs index 0b103ffdb3..5446a9f5cc 100644 --- a/Content.Server/AI/Operators/Sequences/SequenceOperator.cs +++ b/Content.Server/AI/Operators/Sequences/SequenceOperator.cs @@ -17,9 +17,9 @@ namespace Content.Server.AI.Operators.Sequences { return Outcome.Success; } - + var op = Sequence.Peek(); - op.TryStartup(); + op.Startup(); var outcome = op.Execute(frameTime); switch (outcome) @@ -35,10 +35,10 @@ namespace Content.Server.AI.Operators.Sequences op.Shutdown(outcome); Sequence.Clear(); return Outcome.Failed; - + default: throw new ArgumentOutOfRangeException(); } } } -} \ No newline at end of file +} diff --git a/Content.Server/AI/Utility/Actions/UtilityAction.cs b/Content.Server/AI/Utility/Actions/UtilityAction.cs index b79fa0955a..3fbf978cfc 100644 --- a/Content.Server/AI/Utility/Actions/UtilityAction.cs +++ b/Content.Server/AI/Utility/Actions/UtilityAction.cs @@ -62,7 +62,7 @@ namespace Content.Server.AI.Utility.Actions { Owner = owner; } - + public virtual void Shutdown() {} /// @@ -78,7 +78,7 @@ namespace Content.Server.AI.Utility.Actions return Outcome.Success; } - op.TryStartup(); + op.Startup(); var outcome = op.Execute(frameTime); switch (outcome) @@ -116,7 +116,7 @@ namespace Content.Server.AI.Utility.Actions // Overall structure is based on Building a better centaur // Ideally we should early-out each action as cheaply as possible if it's not valid, thus // the finalScore can only go down over time. - + var finalScore = 1.0f; var minThreshold = min / Bonus; context.GetState().SetValue(considerations.Count); diff --git a/Content.Server/AI/Utility/AiLogic/UtilityAI.cs b/Content.Server/AI/Utility/AiLogic/UtilityAI.cs index 305e8ebfca..df0284deed 100644 --- a/Content.Server/AI/Utility/AiLogic/UtilityAI.cs +++ b/Content.Server/AI/Utility/AiLogic/UtilityAI.cs @@ -137,6 +137,8 @@ namespace Content.Server.AI.Utility.AiLogic { var currentOp = CurrentAction?.ActionOperators.Peek(); currentOp?.Shutdown(Outcome.Failed); + CurrentAction?.Shutdown(); + CurrentAction = null; } public void MobStateChanged(MobStateChangedMessage message) diff --git a/Content.Server/GameObjects/EntitySystems/AI/AiSystem.cs b/Content.Server/GameObjects/EntitySystems/AI/AiSystem.cs index 5a7e6bb994..36b56d93f3 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/AiSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/AiSystem.cs @@ -110,17 +110,18 @@ namespace Content.Server.GameObjects.EntitySystems.AI foreach (var processor in _awakeAi) { - if (count >= maxUpdates) - { - break; - } - - if (processor.SelfEntity.Deleted) + if (processor.SelfEntity.Deleted || + !processor.SelfEntity.HasComponent()) { toRemove.Add(processor); continue; } + if (count >= maxUpdates) + { + break; + } + processor.Update(frameTime); count++; }