Option to make limb attacks do damage based on contact with physics bodies instead of distance. Attacks also do damage to all sections of a structure that are within damage range. Closes #108
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Dynamics.Contacts;
|
||||
using FarseerPhysics.Dynamics.Joints;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
@@ -479,12 +480,69 @@ namespace Barotrauma
|
||||
|
||||
body.ApplyTorque(Mass * character.AnimController.Dir * attack.Torque);
|
||||
|
||||
if (dist < attack.DamageRange)
|
||||
bool wasHit = false;
|
||||
|
||||
if (damageTarget != null)
|
||||
{
|
||||
switch (attack.HitDetectionType)
|
||||
{
|
||||
case HitDetection.Distance:
|
||||
wasHit = dist < attack.DamageRange;
|
||||
break;
|
||||
case HitDetection.Contact:
|
||||
List<Body> targetBodies = new List<Body>();
|
||||
if (damageTarget is Character)
|
||||
{
|
||||
Character targetCharacter = (Character)damageTarget;
|
||||
foreach (Limb limb in targetCharacter.AnimController.Limbs)
|
||||
{
|
||||
if (!limb.IsSevered && limb.body?.FarseerBody != null) targetBodies.Add(limb.body.FarseerBody);
|
||||
}
|
||||
}
|
||||
else if (damageTarget is Structure)
|
||||
{
|
||||
Structure targetStructure = (Structure)damageTarget;
|
||||
|
||||
if (character.Submarine == null && targetStructure.Submarine != null)
|
||||
{
|
||||
targetBodies.Add(targetStructure.Submarine.PhysicsBody.FarseerBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
targetBodies.AddRange(targetStructure.Bodies);
|
||||
}
|
||||
}
|
||||
else if (damageTarget is Item)
|
||||
{
|
||||
Item targetItem = damageTarget as Item;
|
||||
if (targetItem.body?.FarseerBody != null) targetBodies.Add(targetItem.body.FarseerBody);
|
||||
}
|
||||
|
||||
if (targetBodies != null)
|
||||
{
|
||||
ContactEdge contactEdge = body.FarseerBody.ContactList;
|
||||
while (contactEdge != null)
|
||||
{
|
||||
if (contactEdge.Contact != null &&
|
||||
contactEdge.Contact.IsTouching &&
|
||||
targetBodies.Any(b => b == contactEdge.Contact.FixtureA?.Body || b == contactEdge.Contact.FixtureB?.Body))
|
||||
{
|
||||
wasHit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
contactEdge = contactEdge.Next;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (wasHit)
|
||||
{
|
||||
if (AttackTimer >= attack.Duration && damageTarget != null)
|
||||
{
|
||||
attack.DoDamage(character, damageTarget, WorldPosition, 1.0f, (SoundTimer <= 0.0f));
|
||||
|
||||
SoundTimer = SoundInterval;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user