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)