diff --git a/Barotrauma/Content/Characters/Crawler/crawler.xml b/Barotrauma/Content/Characters/Crawler/crawler.xml
index abe5f087b..aaf2c1588 100644
--- a/Barotrauma/Content/Characters/Crawler/crawler.xml
+++ b/Barotrauma/Content/Characters/Crawler/crawler.xml
@@ -44,7 +44,9 @@
-
+
diff --git a/Barotrauma/Content/Characters/Human/humanhusk.xml b/Barotrauma/Content/Characters/Human/humanhusk.xml
index 9b8b82df6..01cdef7c9 100644
--- a/Barotrauma/Content/Characters/Human/humanhusk.xml
+++ b/Barotrauma/Content/Characters/Human/humanhusk.xml
@@ -84,7 +84,8 @@
-
+
diff --git a/Barotrauma/Content/Characters/Husk/husk.xml b/Barotrauma/Content/Characters/Husk/husk.xml
index 3bd593b42..4ddbfeaa4 100644
--- a/Barotrauma/Content/Characters/Husk/husk.xml
+++ b/Barotrauma/Content/Characters/Husk/husk.xml
@@ -32,11 +32,11 @@
-
-
+
diff --git a/Barotrauma/Content/Characters/Mantis/mantis.xml b/Barotrauma/Content/Characters/Mantis/mantis.xml
index 80d9781c5..45ab41fab 100644
--- a/Barotrauma/Content/Characters/Mantis/mantis.xml
+++ b/Barotrauma/Content/Characters/Mantis/mantis.xml
@@ -61,7 +61,8 @@
-
+
diff --git a/Barotrauma/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/Source/Characters/AI/EnemyAIController.cs
index c7b68ff88..047ddf9e1 100644
--- a/Barotrauma/Source/Characters/AI/EnemyAIController.cs
+++ b/Barotrauma/Source/Characters/AI/EnemyAIController.cs
@@ -221,6 +221,21 @@ namespace Barotrauma
if (selectedAiTarget.Entity != null && Character.Submarine == null && selectedAiTarget.Entity.Submarine != null) attackSimPosition += ConvertUnits.ToSimUnits(selectedAiTarget.Entity.Submarine.Position);
}
+ else if (selectedAiTarget.Entity is Character)
+ {
+ //target the closest limb if the target is a character
+ float closestDist = Vector2.DistanceSquared(selectedAiTarget.SimPosition, SimPosition);
+ foreach (Limb limb in ((Character)selectedAiTarget.Entity).AnimController.Limbs)
+ {
+ if (limb == null) continue;
+ float dist = Vector2.DistanceSquared(limb.SimPosition, SimPosition);
+ if (dist < closestDist)
+ {
+ closestDist = dist;
+ attackSimPosition = limb.SimPosition;
+ }
+ }
+ }
if (Math.Abs(Character.AnimController.movement.X) > 0.1f && !Character.AnimController.InWater)
{
diff --git a/Barotrauma/Source/Characters/Attack.cs b/Barotrauma/Source/Characters/Attack.cs
index 87c79291f..7f6ac1454 100644
--- a/Barotrauma/Source/Characters/Attack.cs
+++ b/Barotrauma/Source/Characters/Attack.cs
@@ -51,6 +51,10 @@ namespace Barotrauma
public readonly float SeverLimbsProbability;
+ //the indices of the limbs Force is applied on
+ //(if none, force is applied only to the limb the attack is attached to)
+ public readonly List ApplyForceOnLimbs;
+
private Sound sound;
private ParticleEmitterPrefab particleEmitterPrefab;
@@ -92,7 +96,7 @@ namespace Barotrauma
SeverLimbsProbability = ToolBox.GetAttributeFloat(element, "severlimbsprobability", 0.0f);
- Force = ToolBox.GetAttributeFloat(element,"force", 0.0f);
+ Force = ToolBox.GetAttributeFloat(element, "force", 0.0f);
TargetForce = ToolBox.GetAttributeFloat(element, "targetforce", 0.0f);
Torque = ToolBox.GetAttributeFloat(element, "torque", 0.0f);
@@ -107,6 +111,20 @@ namespace Barotrauma
priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f);
+ string limbIndicesStr = ToolBox.GetAttributeString(element, "applyforceonlimbs", "");
+ if (!string.IsNullOrWhiteSpace(limbIndicesStr))
+ {
+ ApplyForceOnLimbs = new List();
+ foreach (string limbIndexStr in limbIndicesStr.Split(','))
+ {
+ int limbIndex;
+ if (int.TryParse(limbIndexStr, out limbIndex))
+ {
+ ApplyForceOnLimbs.Add(limbIndex);
+ }
+ }
+ }
+
statusEffects = new List();
foreach (XElement subElement in element.Elements())
{
diff --git a/Barotrauma/Source/Characters/Limb.cs b/Barotrauma/Source/Characters/Limb.cs
index be5dcae0d..2fb3c553e 100644
--- a/Barotrauma/Source/Characters/Limb.cs
+++ b/Barotrauma/Source/Characters/Limb.cs
@@ -449,17 +449,32 @@ namespace Barotrauma
{
attack.DoDamage(character, damageTarget, WorldPosition, 1.0f, (soundTimer <= 0.0f));
- soundTimer = Limb.SoundInterval;
+ soundTimer = SoundInterval;
}
}
Vector2 diff = attackPosition - SimPosition;
- if (diff.LengthSquared() > 0.00001f)
+ if (diff.LengthSquared() < 0.00001f) return;
+
+ if (attack.ApplyForceOnLimbs != null)
{
- Vector2 pos = pullJoint == null ? body.SimPosition : pullJoint.WorldAnchorA;
- body.ApplyLinearImpulse(Mass * attack.Force *
- Vector2.Normalize(attackPosition - SimPosition), pos);
+ foreach (int limbIndex in attack.ApplyForceOnLimbs)
+ {
+ if (limbIndex < 0 || limbIndex >= character.AnimController.Limbs.Length) continue;
+
+ Limb limb = character.AnimController.Limbs[limbIndex];
+ Vector2 forcePos = limb.pullJoint == null ? limb.body.SimPosition : limb.pullJoint.WorldAnchorA;
+ limb.body.ApplyLinearImpulse(
+ limb.Mass * attack.Force * Vector2.Normalize(attackPosition - SimPosition), forcePos);
+ }
}
+ else
+ {
+ Vector2 forcePos = pullJoint == null ? body.SimPosition : pullJoint.WorldAnchorA;
+ body.ApplyLinearImpulse(Mass * attack.Force *
+ Vector2.Normalize(attackPosition - SimPosition), forcePos);
+ }
+
}
public void Draw(SpriteBatch spriteBatch)