From 1f92e31166a88ec9fafa8674ed124f5faba36fc8 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Thu, 19 Oct 2017 00:01:34 +0300 Subject: [PATCH] HumanAIController calculates the "dangerousness" of an enemy based on the largest amount of damage received from it (assuming it's larger than the attack values of the enemy's limbs). Meaning that an enemy that inflicted lots of damage to the character using items is considered dangerous even if it has no attacks assigned to it's limbs. --- .../Source/Characters/AI/EnemyAIController.cs | 2 +- .../Source/Characters/AI/HumanAIController.cs | 5 +++++ .../Characters/AI/Objectives/AIObjectiveCombat.cs | 15 ++++++--------- .../AI/Objectives/AIObjectiveManager.cs | 9 +++++++++ .../Source/Characters/AICharacter.cs | 2 +- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs index a5360c96e..5ee04843b 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs @@ -461,7 +461,7 @@ namespace Barotrauma if (attacker == null || attacker.AiTarget == null) return; AITargetMemory targetMemory = FindTargetMemory(attacker.AiTarget); - targetMemory.Priority += amount; + targetMemory.Priority += amount / Math.Max(Character.Health, 1.0f); } private void UpdateLimbAttack(float deltaTime, Limb limb, Vector2 attackPosition) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs index 5df6dd5cd..172f969a3 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs @@ -145,6 +145,11 @@ namespace Barotrauma if (enemy == null || enemy == Character) return; objectiveManager.AddObjective(new AIObjectiveCombat(Character, enemy)); + + //the objective in the manager is not necessarily the same as the one we just instantiated, + //because the objective isn't added if there's already an identical objective in the manager + var combatObjective = objectiveManager.GetObjective(); + combatObjective.MaxEnemyDamage = Math.Max(amount, combatObjective.MaxEnemyDamage); } public void SetOrder(Order order, string option) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs index b4f1a61f0..cbe66e791 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs @@ -9,6 +9,10 @@ namespace Barotrauma { const float CoolDown = 10.0f; + //the largest amount of damage the enemy has inflicted on this character + //(may be higher than enemyStrength if the enemy is e.g. a human using items) + public float MaxEnemyDamage; + private Character enemy; private AIObjectiveFindSafety escapeObjective; @@ -17,7 +21,7 @@ namespace Barotrauma private readonly float enemyStrength; - public AIObjectiveCombat (Character character, Character enemy) + public AIObjectiveCombat(Character character, Character enemy) : base(character, "") { this.enemy = enemy; @@ -88,13 +92,6 @@ namespace Barotrauma } escapeObjective.TryComplete(deltaTime); - - //if (Vector2.Distance(character.SimPosition, enemy.SimPosition) < 3.0f) - //{ - // character.AIController.SteeringManager.SteeringManual(deltaTime, - // new Vector2(Math.Sign(character.SimPosition.X - enemy.SimPosition.X), 0.0f)); - // coolDownTimer = CoolDown; - //} } public override bool IsCompleted() @@ -107,7 +104,7 @@ namespace Barotrauma //clamp the strength to the health of this character //(it doesn't make a difference whether the enemy does 200 or 600 damage, it's one hit kill anyway) - float enemyDanger = Math.Min(enemyStrength, character.Health) + enemy.Health / 10.0f; + float enemyDanger = Math.Min(Math.Max(enemyStrength, MaxEnemyDamage), character.Health) + enemy.Health / 10.0f; EnemyAIController enemyAI = enemy.AIController as EnemyAIController; if (enemyAI != null) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs index 1a6b91b45..8482e3867 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs @@ -36,6 +36,15 @@ namespace Barotrauma objectives.Add(objective); } + public T GetObjective() where T : AIObjective + { + foreach (AIObjective objective in objectives) + { + if (objective is T) return (T)objective; + } + return null; + } + public float GetCurrentPriority(Character character) { if (currentObjective != null) return OrderPriority; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AICharacter.cs b/Barotrauma/BarotraumaShared/Source/Characters/AICharacter.cs index 5bcc5aeb3..697b4032c 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AICharacter.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AICharacter.cs @@ -61,7 +61,7 @@ namespace Barotrauma { AttackResult result = base.AddDamage(attacker, worldPosition, attack, deltaTime, playSound); - aiController.OnAttacked(attacker, (result.Damage + result.Bleeding) / Math.Max(Health, 1.0f)); + aiController.OnAttacked(attacker, result.Damage + result.Bleeding); return result; }