From 024094cfba478f7f7fa90c442f4d21ee56d04a44 Mon Sep 17 00:00:00 2001 From: Regalis Date: Wed, 24 May 2017 17:39:02 +0300 Subject: [PATCH] Enemies can attack each other --- .../Content/Characters/Carrier/carrier.xml | 3 +- .../Characters/Charybdis/charybdis.xml | 2 +- .../Content/Characters/Endworm/endworm.xml | 2 +- .../Content/Characters/Mantis/mantis.xml | 13 ++-- .../Tigerthresher/tigerthresher.xml | 9 ++- .../Source/Characters/AI/EnemyAIController.cs | 67 +++++++++++++++---- Subsurface/Source/Utils/ToolBox.cs | 29 ++++++++ 7 files changed, 104 insertions(+), 21 deletions(-) diff --git a/Subsurface/Content/Characters/Carrier/carrier.xml b/Subsurface/Content/Characters/Carrier/carrier.xml index 4ff3312d2..1791cf3c9 100644 --- a/Subsurface/Content/Characters/Carrier/carrier.xml +++ b/Subsurface/Content/Characters/Carrier/carrier.xml @@ -53,7 +53,8 @@ \ No newline at end of file diff --git a/Subsurface/Content/Characters/Charybdis/charybdis.xml b/Subsurface/Content/Characters/Charybdis/charybdis.xml index 9029f90f7..e11750e1f 100644 --- a/Subsurface/Content/Characters/Charybdis/charybdis.xml +++ b/Subsurface/Content/Characters/Charybdis/charybdis.xml @@ -37,5 +37,5 @@ - + \ No newline at end of file diff --git a/Subsurface/Content/Characters/Endworm/endworm.xml b/Subsurface/Content/Characters/Endworm/endworm.xml index 1ed66da24..824642ecd 100644 --- a/Subsurface/Content/Characters/Endworm/endworm.xml +++ b/Subsurface/Content/Characters/Endworm/endworm.xml @@ -75,6 +75,6 @@ - + diff --git a/Subsurface/Content/Characters/Mantis/mantis.xml b/Subsurface/Content/Characters/Mantis/mantis.xml index 298d4c9e6..0dee0b607 100644 --- a/Subsurface/Content/Characters/Mantis/mantis.xml +++ b/Subsurface/Content/Characters/Mantis/mantis.xml @@ -85,11 +85,16 @@ - - + diff --git a/Subsurface/Content/Characters/Tigerthresher/tigerthresher.xml b/Subsurface/Content/Characters/Tigerthresher/tigerthresher.xml index 1c9f3935c..b6727bb62 100644 --- a/Subsurface/Content/Characters/Tigerthresher/tigerthresher.xml +++ b/Subsurface/Content/Characters/Tigerthresher/tigerthresher.xml @@ -72,5 +72,12 @@ - + \ No newline at end of file diff --git a/Subsurface/Source/Characters/AI/EnemyAIController.cs b/Subsurface/Source/Characters/AI/EnemyAIController.cs index bc2238579..349a6236b 100644 --- a/Subsurface/Source/Characters/AI/EnemyAIController.cs +++ b/Subsurface/Source/Characters/AI/EnemyAIController.cs @@ -25,6 +25,8 @@ namespace Barotrauma //negative values = escapes targets of this type private float attackRooms, attackHumans, attackWeaker, attackStronger; + private float combatStrength; + private SteeringManager outsideSteering, insideSteering; private float updateTargetsTimer; @@ -73,10 +75,12 @@ namespace Barotrauma XElement aiElement = doc.Root.Element("ai"); if (aiElement == null) return; - attackRooms = ToolBox.GetAttributeFloat(aiElement, "attackrooms", 0.0f) / 100.0f; - attackHumans = ToolBox.GetAttributeFloat(aiElement, "attackhumans", 0.0f) / 100.0f; - attackWeaker = ToolBox.GetAttributeFloat(aiElement, "attackweaker", 0.0f) / 100.0f; - attackStronger = ToolBox.GetAttributeFloat(aiElement, "attackstronger", 0.0f) / 100.0f; + attackRooms = ToolBox.GetAttributeFloat(aiElement, 0.0f, "attackrooms", "attackpriorityrooms") / 100.0f; + attackHumans = ToolBox.GetAttributeFloat(aiElement, 0.0f, "attackhumans", "attackpriorityhumans") / 100.0f; + attackWeaker = ToolBox.GetAttributeFloat(aiElement, 0.0f, "attackweaker", "attackpriorityweaker") / 100.0f; + attackStronger = ToolBox.GetAttributeFloat(aiElement, 0.0f, "attackstronger", "attackprioritystronger") / 100.0f; + + combatStrength = ToolBox.GetAttributeFloat(aiElement, "combatstrength", 1.0f); attackCoolDown = ToolBox.GetAttributeFloat(aiElement, "attackcooldown", 5.0f); @@ -157,6 +161,11 @@ namespace Barotrauma case AiState.Attack: UpdateAttack(deltaTime); break; + case AiState.Escape: + UpdateEscape(deltaTime); + break; + default: + throw new NotImplementedException(); } steeringManager.Update(); @@ -260,6 +269,13 @@ namespace Barotrauma } } + private void UpdateEscape(float deltaTime) + { + SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(SimPosition - selectedAiTarget.SimPosition)); + SteeringManager.SteeringWander(1.0f); + SteeringManager.SteeringAvoid(deltaTime, 2f); + } + private void UpdateCoolDown(Vector2 attackPosition, float deltaTime) { coolDownTimer -= deltaTime; @@ -397,9 +413,30 @@ namespace Barotrauma if (targetCharacter!=null) { - if (attackHumans == 0.0f || targetCharacter.SpeciesName != "human") continue; - - valueModifier = attackHumans; + if (targetCharacter.SpeciesName == "human") + { + if (attackHumans == 0.0f) continue; + valueModifier = attackHumans; + } + else + { + EnemyAIController enemy = targetCharacter.AIController as EnemyAIController; + if (enemy != null) + { + if (enemy.combatStrength > combatStrength) + { + valueModifier = attackStronger; + } + else if (enemy.combatStrength < combatStrength) + { + valueModifier = attackWeaker; + } + else + { + continue; + } + } + } } else if (target.Entity!=null && attackRooms != 0.0f) { @@ -409,11 +446,13 @@ namespace Barotrauma valueModifier = attackRooms; } + if (valueModifier == 0.0f) continue; + dist = Vector2.Distance(character.WorldPosition, target.WorldPosition); //if the target has been within range earlier, the character will notice it more easily //(i.e. remember where the target was) - if (targetMemories.ContainsKey(target)) dist *= 0.1f; + if (targetMemories.ContainsKey(target)) dist *= 0.5f; //ignore target if it's too far to see or hear if (dist > target.SightRange * sight && dist > target.SoundRange * hearing) continue; @@ -434,19 +473,21 @@ namespace Barotrauma Body closestBody = Submarine.CheckVisibility(rayStart, rayEnd); Structure closestStructure = (closestBody == null) ? null : closestBody.UserData as Structure; + /* float targetStrength = 0.0f; if (targetDamageable != null) { - valueModifier = valueModifier / targetDamageable.Health; + targetStrength = targetDamageable.Health; } else if (closestStructure!=null) { - valueModifier = valueModifier / ((IDamageable)closestStructure).Health; + targetStrength = ((IDamageable)closestStructure).Health; } else { - valueModifier = valueModifier / 1000.0f; - } - + targetStrength = 1000.0f; + }*/ +; + if (selectedAiTarget == null || Math.Abs(valueModifier) > Math.Abs(targetValue)) { selectedAiTarget = target; diff --git a/Subsurface/Source/Utils/ToolBox.cs b/Subsurface/Source/Utils/ToolBox.cs index bbf2aa6c5..c75c35cc2 100644 --- a/Subsurface/Source/Utils/ToolBox.cs +++ b/Subsurface/Source/Utils/ToolBox.cs @@ -162,6 +162,35 @@ namespace Barotrauma return value; } + public static float GetAttributeFloat(XElement element, float defaultValue, params string[] matchingAttributeName) + { + if (element == null) return defaultValue; + + foreach (string name in matchingAttributeName) + { + if (element.Attribute(name) == null) continue; + + float val = defaultValue; + + try + { + if (!float.TryParse(element.Attribute(name).Value, NumberStyles.Float, CultureInfo.InvariantCulture, out val)) + { + continue; + } + } + catch (Exception e) + { + DebugConsole.ThrowError("Error in "+element+"!", e); + continue; + } + + return val; + } + + return defaultValue; + } + public static float GetAttributeFloat(XElement element, string name, float defaultValue) { if (element == null || element.Attribute(name) == null) return defaultValue;