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;