(d9829ac) v0.9.4.0

This commit is contained in:
Regalis
2019-10-24 18:05:42 +02:00
parent 9aa12bcac2
commit b39922a074
319 changed files with 12516 additions and 6815 deletions
@@ -9,6 +9,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Networking;
using LimbParams = Barotrauma.RagdollParams.LimbParams;
using JointParams = Barotrauma.RagdollParams.JointParams;
namespace Barotrauma
{
@@ -21,14 +23,14 @@ namespace Barotrauma
partial class LimbJoint : RevoluteJoint
{
public bool IsSevered;
public bool CanBeSevered => jointParams.CanBeSevered;
public readonly JointParams jointParams;
public bool CanBeSevered => Params.CanBeSevered;
public readonly JointParams Params;
public readonly Ragdoll ragdoll;
public readonly Limb LimbA, LimbB;
public LimbJoint(Limb limbA, Limb limbB, JointParams jointParams, Ragdoll ragdoll) : this(limbA, limbB, Vector2.One, Vector2.One)
{
this.jointParams = jointParams;
Params = jointParams;
this.ragdoll = ragdoll;
LoadParams();
}
@@ -43,63 +45,37 @@ namespace Barotrauma
LimbB = limbB;
}
public void SaveParams()
{
// Saving to the params is handled only in the params level.
return;
jointParams.Stiffness = MaxMotorTorque;
if (ragdoll.IsFlipped)
{
jointParams.Limb1Anchor = ConvertUnits.ToDisplayUnits(new Vector2(-LocalAnchorA.X, LocalAnchorA.Y) / jointParams.Ragdoll.JointScale);
jointParams.Limb2Anchor = ConvertUnits.ToDisplayUnits(new Vector2(-LocalAnchorB.X, LocalAnchorB.Y) / jointParams.Ragdoll.JointScale);
jointParams.UpperLimit = MathHelper.ToDegrees(-LowerLimit);
jointParams.LowerLimit = MathHelper.ToDegrees(-UpperLimit);
}
else
{
jointParams.Limb1Anchor = ConvertUnits.ToDisplayUnits(LocalAnchorA / jointParams.Ragdoll.JointScale);
jointParams.Limb2Anchor = ConvertUnits.ToDisplayUnits(LocalAnchorB / jointParams.Ragdoll.JointScale);
jointParams.UpperLimit = MathHelper.ToDegrees(UpperLimit);
jointParams.LowerLimit = MathHelper.ToDegrees(LowerLimit);
}
}
public void LoadParams()
{
MaxMotorTorque = jointParams.Stiffness;
LimitEnabled = jointParams.LimitEnabled;
if (float.IsNaN(jointParams.LowerLimit))
MaxMotorTorque = Params.Stiffness;
LimitEnabled = Params.LimitEnabled;
if (float.IsNaN(Params.LowerLimit))
{
jointParams.LowerLimit = 0;
Params.LowerLimit = 0;
}
if (float.IsNaN(jointParams.UpperLimit))
if (float.IsNaN(Params.UpperLimit))
{
jointParams.UpperLimit = 0;
Params.UpperLimit = 0;
}
if (ragdoll.IsFlipped)
{
LocalAnchorA = ConvertUnits.ToSimUnits(new Vector2(-jointParams.Limb1Anchor.X, jointParams.Limb1Anchor.Y) * jointParams.Ragdoll.JointScale);
LocalAnchorB = ConvertUnits.ToSimUnits(new Vector2(-jointParams.Limb2Anchor.X, jointParams.Limb2Anchor.Y) * jointParams.Ragdoll.JointScale);
UpperLimit = MathHelper.ToRadians(-jointParams.LowerLimit);
LowerLimit = MathHelper.ToRadians(-jointParams.UpperLimit);
LocalAnchorA = ConvertUnits.ToSimUnits(new Vector2(-Params.Limb1Anchor.X, Params.Limb1Anchor.Y) * Params.Ragdoll.JointScale);
LocalAnchorB = ConvertUnits.ToSimUnits(new Vector2(-Params.Limb2Anchor.X, Params.Limb2Anchor.Y) * Params.Ragdoll.JointScale);
UpperLimit = MathHelper.ToRadians(-Params.LowerLimit);
LowerLimit = MathHelper.ToRadians(-Params.UpperLimit);
}
else
{
LocalAnchorA = ConvertUnits.ToSimUnits(jointParams.Limb1Anchor * jointParams.Ragdoll.JointScale);
LocalAnchorB = ConvertUnits.ToSimUnits(jointParams.Limb2Anchor * jointParams.Ragdoll.JointScale);
UpperLimit = MathHelper.ToRadians(jointParams.UpperLimit);
LowerLimit = MathHelper.ToRadians(jointParams.LowerLimit);
LocalAnchorA = ConvertUnits.ToSimUnits(Params.Limb1Anchor * Params.Ragdoll.JointScale);
LocalAnchorB = ConvertUnits.ToSimUnits(Params.Limb2Anchor * Params.Ragdoll.JointScale);
UpperLimit = MathHelper.ToRadians(Params.UpperLimit);
LowerLimit = MathHelper.ToRadians(Params.LowerLimit);
}
}
}
partial class Limb : ISerializableEntity, ISpatialEntity
{
// Note: not used
private const float LimbDensity = 15;
private const float LimbAngularDamping = 7;
//how long it takes for severed limbs to fade out
private const float SeveredFadeOutTime = 10.0f;
@@ -108,12 +84,12 @@ namespace Barotrauma
/// Note that during the limb initialization, character.AnimController returns null, whereas this field is already assigned.
/// </summary>
public readonly Ragdoll ragdoll;
public readonly LimbParams limbParams;
public readonly LimbParams Params;
//the physics body of the limb
public PhysicsBody body;
public Vector2 StepOffset => ConvertUnits.ToSimUnits(limbParams.StepOffset) * ragdoll.RagdollParams.JointScale;
public Vector2 StepOffset => ConvertUnits.ToSimUnits(Params.StepOffset) * ragdoll.RagdollParams.JointScale;
public bool inWater;
@@ -125,19 +101,34 @@ namespace Barotrauma
private bool isSevered;
private float severedFadeOutTimer;
public Vector2? MouthPos;
private Vector2? mouthPos;
public Vector2 MouthPos
{
get
{
if (!mouthPos.HasValue)
{
mouthPos = Params.MouthPos;
}
return mouthPos.Value;
}
set
{
mouthPos = value;
}
}
public readonly Attack attack;
private List<DamageModifier> damageModifiers;
private Direction dir;
public int HealthIndex => limbParams.HealthIndex;
public float Scale => limbParams.Ragdoll.LimbScale;
public float AttackPriority => limbParams.AttackPriority;
public bool DoesFlip => limbParams.Flip;
public float SteerForce => limbParams.SteerForce;
public int HealthIndex => Params.HealthIndex;
public float Scale => Params.Ragdoll.LimbScale;
public float AttackPriority => Params.AttackPriority;
public bool DoesFlip => Params.Flip;
public float SteerForce => Params.SteerForce;
public Vector2 DebugTargetPos;
public Vector2 DebugRefPos;
@@ -198,7 +189,7 @@ namespace Barotrauma
set { dir = (value == -1.0f) ? Direction.Left : Direction.Right; }
}
public int RefJointIndex => limbParams.RefJoint;
public int RefJointIndex => Params.RefJoint;
private List<WearableSprite> wearingItems;
public List<WearableSprite> WearingItems
@@ -291,7 +282,7 @@ namespace Barotrauma
get { return pullJoint.LocalAnchorA; }
}
public string Name => limbParams.Name;
public string Name => Params.Name;
public Dictionary<string, SerializableProperty> SerializableProperties
{
@@ -303,7 +294,7 @@ namespace Barotrauma
{
this.ragdoll = ragdoll;
this.character = character;
this.limbParams = limbParams;
this.Params = limbParams;
wearingItems = new List<WearableSprite>();
dir = Direction.Right;
body = new PhysicsBody(limbParams);
@@ -324,19 +315,16 @@ namespace Barotrauma
pullJoint = new FixedMouseJoint(body.FarseerBody, ConvertUnits.ToSimUnits(limbParams.PullPos * Scale))
{
Enabled = false,
MaxForce = ((type == LimbType.LeftHand || type == LimbType.RightHand) ? 400.0f : 150.0f) * body.Mass
//MaxForce = ((type == LimbType.LeftHand || type == LimbType.RightHand) ? 400.0f : 150.0f) * body.Mass
// 150 or even 400 is too low if the joint is used for moving the character position from the mainlimb towards the collider position
MaxForce = 1000 * Mass
};
GameMain.World.AddJoint(pullJoint);
var element = limbParams.Element;
if (element.Attribute("mouthpos") != null)
{
MouthPos = ConvertUnits.ToSimUnits(element.GetAttributeVector2("mouthpos", Vector2.Zero));
}
body.BodyType = BodyType.Dynamic;
body.FarseerBody.AngularDamping = LimbAngularDamping;
damageModifiers = new List<DamageModifier>();
@@ -403,19 +391,19 @@ namespace Barotrauma
return AddDamage(simPosition, afflictions, playSound);
}
public AttackResult AddDamage(Vector2 simPosition, List<Affliction> afflictions, bool playSound)
public AttackResult AddDamage(Vector2 simPosition, IEnumerable<Affliction> afflictions, bool playSound)
{
List<DamageModifier> appliedDamageModifiers = new List<DamageModifier>();
//create a copy of the original affliction list to prevent modifying the afflictions of an Attack/StatusEffect etc
afflictions = new List<Affliction>(afflictions.Where(a => Rand.Range(0.0f, 1.0f) <= a.ApplyProbability));
for (int i = 0; i < afflictions.Count; i++)
var afflictionsCopy = afflictions.Where(a => Rand.Range(0.0f, 1.0f) <= a.Probability).ToList();
for (int i = 0; i < afflictionsCopy.Count; i++)
{
foreach (DamageModifier damageModifier in damageModifiers)
{
if (!damageModifier.MatchesAffliction(afflictions[i])) continue;
if (SectorHit(damageModifier.ArmorSector, simPosition))
if (!damageModifier.MatchesAffliction(afflictionsCopy[i])) continue;
if (SectorHit(damageModifier.ArmorSectorInRadians, simPosition))
{
afflictions[i] = afflictions[i].CreateMultiplied(damageModifier.DamageMultiplier);
afflictionsCopy[i] = afflictionsCopy[i].CreateMultiplied(damageModifier.DamageMultiplier);
appliedDamageModifiers.Add(damageModifier);
}
}
@@ -424,19 +412,19 @@ namespace Barotrauma
{
foreach (DamageModifier damageModifier in wearable.WearableComponent.DamageModifiers)
{
if (!damageModifier.MatchesAffliction(afflictions[i])) continue;
if (SectorHit(damageModifier.ArmorSector, simPosition))
if (!damageModifier.MatchesAffliction(afflictionsCopy[i])) continue;
if (SectorHit(damageModifier.ArmorSectorInRadians, simPosition))
{
afflictions[i] = afflictions[i].CreateMultiplied(damageModifier.DamageMultiplier);
afflictionsCopy[i] = afflictionsCopy[i].CreateMultiplied(damageModifier.DamageMultiplier);
appliedDamageModifiers.Add(damageModifier);
}
}
}
}
AddDamageProjSpecific(simPosition, afflictions, playSound, appliedDamageModifiers);
AddDamageProjSpecific(simPosition, afflictionsCopy, playSound, appliedDamageModifiers);
return new AttackResult(afflictions, this, appliedDamageModifiers);
return new AttackResult(afflictionsCopy, this, appliedDamageModifiers);
}
partial void AddDamageProjSpecific(Vector2 simPosition, List<Affliction> afflictions, bool playSound, List<DamageModifier> appliedDamageModifiers);
@@ -456,7 +444,7 @@ namespace Barotrauma
protected float GetArmorSectorRotationOffset(Vector2 armorSector)
{
float midAngle = MathUtils.GetMidAngle(armorSector.X, armorSector.Y);
float spritesheetOrientation = MathHelper.ToRadians(limbParams.Ragdoll.SpritesheetOrientation);
float spritesheetOrientation = Params.GetSpriteOrientation();
return midAngle + spritesheetOrientation;
}
@@ -495,10 +483,13 @@ namespace Barotrauma
partial void UpdateProjSpecific(float deltaTime);
private readonly List<Body> contactBodies = new List<Body>();
private List<Body> ignoredBodies;
/// <summary>
/// Returns true if the attack successfully hit something. If the distance is not given, it will be calculated.
/// </summary>
public bool UpdateAttack(float deltaTime, Vector2 attackSimPos, IDamageable damageTarget, out AttackResult attackResult, float distance = -1)
public bool UpdateAttack(float deltaTime, Vector2 attackSimPos, IDamageable damageTarget, out AttackResult attackResult, float distance = -1, Limb targetLimb = null)
{
attackResult = default(AttackResult);
float dist = distance > -1 ? distance : ConvertUnits.ToDisplayUnits(Vector2.Distance(SimPosition, attackSimPos));
@@ -514,8 +505,11 @@ namespace Barotrauma
case HitDetection.Distance:
if (dist < attack.DamageRange)
{
List<Body> ignoredBodies = character.AnimController.Limbs.Select(l => l.body.FarseerBody).ToList();
ignoredBodies.Add(character.AnimController.Collider.FarseerBody);
if (ignoredBodies == null)
{
ignoredBodies = character.AnimController.Limbs.Select(l => l.body.FarseerBody).ToList();
ignoredBodies.Add(character.AnimController.Collider.FarseerBody);
}
structureBody = Submarine.PickBody(
SimPosition, attackSimPos,
@@ -541,46 +535,42 @@ namespace Barotrauma
}
break;
case HitDetection.Contact:
var targetBodies = new List<Body>();
contactBodies.Clear();
if (damageTarget is Character targetCharacter)
{
foreach (Limb limb in targetCharacter.AnimController.Limbs)
{
if (!limb.IsSevered && limb.body?.FarseerBody != null) targetBodies.Add(limb.body.FarseerBody);
if (!limb.IsSevered && limb.body?.FarseerBody != null) contactBodies.Add(limb.body.FarseerBody);
}
}
else if (damageTarget is Structure targetStructure)
{
if (character.Submarine == null && targetStructure.Submarine != null)
{
targetBodies.Add(targetStructure.Submarine.PhysicsBody.FarseerBody);
contactBodies.Add(targetStructure.Submarine.PhysicsBody.FarseerBody);
}
else
{
targetBodies.AddRange(targetStructure.Bodies);
contactBodies.AddRange(targetStructure.Bodies);
}
}
else if (damageTarget is Item)
{
Item targetItem = damageTarget as Item;
if (targetItem.body?.FarseerBody != null) targetBodies.Add(targetItem.body.FarseerBody);
if (targetItem.body?.FarseerBody != null) contactBodies.Add(targetItem.body.FarseerBody);
}
if (targetBodies != null)
ContactEdge contactEdge = body.FarseerBody.ContactList;
while (contactEdge != null)
{
ContactEdge contactEdge = body.FarseerBody.ContactList;
while (contactEdge != null)
if (contactEdge.Contact != null &&
contactEdge.Contact.IsTouching &&
contactBodies.Any(b => b == contactEdge.Contact.FixtureA?.Body || b == contactEdge.Contact.FixtureB?.Body))
{
if (contactEdge.Contact != null &&
contactEdge.Contact.IsTouching &&
targetBodies.Any(b => b == contactEdge.Contact.FixtureA?.Body || b == contactEdge.Contact.FixtureB?.Body))
{
structureBody = targetBodies.LastOrDefault();
wasHit = true;
break;
}
contactEdge = contactEdge.Next;
structureBody = contactBodies.LastOrDefault();
wasHit = true;
break;
}
contactEdge = contactEdge.Next;
}
break;
}
@@ -601,11 +591,18 @@ namespace Barotrauma
LastAttackSoundTime = SoundInterval;
}
#endif
attackResult = attack.DoDamage(character, damageTarget, WorldPosition, 1.0f, playSound);
if (damageTarget is Character targetCharacter && targetLimb != null)
{
attackResult = attack.DoDamageToLimb(character, targetLimb, WorldPosition, 1.0f, playSound);
}
else
{
attackResult = attack.DoDamage(character, damageTarget, WorldPosition, 1.0f, playSound);
}
if (structureBody != null && attack.StickChance > Rand.Range(0.0f, 1.0f, Rand.RandSync.Server))
{
// TODO: use the hit pos?
var localFront = body.GetLocalFront(MathHelper.ToRadians(ragdoll.RagdollParams.SpritesheetOrientation));
var localFront = body.GetLocalFront(Params.GetSpriteOrientation());
var from = body.FarseerBody.GetWorldPoint(localFront);
var to = from;
var drawPos = body.DrawPosition;
@@ -665,7 +662,7 @@ namespace Barotrauma
{
PhysicsBody mainLimbBody = ragdoll.MainLimb.body;
Body colliderBody = ragdoll.Collider.FarseerBody;
Vector2 mainLimbLocalFront = mainLimbBody.GetLocalFront(MathHelper.ToRadians(ragdoll.RagdollParams.SpritesheetOrientation));
Vector2 mainLimbLocalFront = mainLimbBody.GetLocalFront(ragdoll.MainLimb.Params.GetSpriteOrientation());
if (Dir < 0)
{
mainLimbLocalFront.X = -mainLimbLocalFront.X;
@@ -715,8 +712,7 @@ namespace Barotrauma
public void LoadParams()
{
attack?.Deserialize();
pullJoint.LocalAnchorA = ConvertUnits.ToSimUnits(limbParams.PullPos * Scale);
pullJoint.LocalAnchorA = ConvertUnits.ToSimUnits(Params.PullPos * Scale);
LoadParamsProjSpecific();
}