This commit is contained in:
Evil Factory
2022-02-24 14:30:39 -03:00
364 changed files with 10838 additions and 3966 deletions
@@ -269,6 +269,11 @@ namespace Barotrauma
}
}
public float GetHeightFromFloor() => GetColliderBottom().Y - FloorY;
// We need some margin, because if a hatch has closed, it's possible that the height from floor is slightly negative.
public bool IsAboveFloor => GetHeightFromFloor() > -0.1f;
public void UpdateUseItem(bool allowMovement, Vector2 handWorldPos)
{
useItemTimer = 0.5f;
@@ -332,7 +337,7 @@ namespace Barotrauma
aimingMelee = aimMelee;
if (character.Stun > 0.0f || character.IsIncapacitated)
{
aim = false;
aim = false;
}
//calculate the handle positions
@@ -346,7 +346,12 @@ namespace Barotrauma
Vector2 limbDiff = attackSimPosition - mouthPos;
float extent = Math.Max(mouthLimb.body.GetMaxExtent(), 1);
if (limbDiff.LengthSquared() < extent * extent)
bool tooFar = character.InWater ? limbDiff.LengthSquared() > extent * extent : limbDiff.X > extent;
if (tooFar)
{
character.SelectedCharacter = null;
}
else
{
//pull the target character to the position of the mouth
//(+ make the force fluctuate to waggle the character a bit)
@@ -382,55 +387,55 @@ namespace Barotrauma
mouthLimb.body.ApplyLinearImpulse(Vector2.UnitY * force * 2, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
mouthLimb.body.ApplyTorque(-force * 50);
}
var jaw = GetLimb(LimbType.Jaw);
if (jaw != null)
{
jaw.body.ApplyTorque(-(float)Math.Sin(eatTimer * 150) * jaw.Mass * 25);
}
character.ApplyStatusEffects(ActionType.OnEating, deltaTime);
float particleFrequency = MathHelper.Clamp(eatSpeed / 2, 0.02f, 0.5f);
if (Rand.Value() < particleFrequency / 6)
if (Character.CanEat && target.IsDead)
{
target.AnimController.MainLimb.AddDamage(target.SimPosition, dmg, 0, 0, false);
}
if (Rand.Value() < particleFrequency)
{
target.AnimController.MainLimb.AddDamage(target.SimPosition, 0, dmg, 0, false);
}
if (eatTimer % 1.0f < 0.5f && (eatTimer - deltaTime * eatSpeed) % 1.0f > 0.5f)
{
static bool CanBeSevered(LimbJoint j) => !j.IsSevered && j.CanBeSevered && j.LimbA != null && !j.LimbA.IsSevered && j.LimbB != null && !j.LimbB.IsSevered;
//keep severing joints until there is only one limb left
var nonSeveredJoints = target.AnimController.LimbJoints.Where(CanBeSevered);
if (nonSeveredJoints.None())
var jaw = GetLimb(LimbType.Jaw);
if (jaw != null)
{
//small monsters don't eat the contents of the character's inventory
if (Mass < target.AnimController.Mass)
{
target.Inventory?.AllItemsMod.ForEach(it => it?.Drop(dropper: null));
}
//only one limb left, the character is now full eaten
Entity.Spawner?.AddToRemoveQueue(target);
if (Character.AIController is EnemyAIController enemyAi)
{
enemyAi.PetBehavior?.OnEat("dead", 1.0f);
}
character.SelectedCharacter = null;
jaw.body.ApplyTorque(-(float)Math.Sin(eatTimer * 150) * jaw.Mass * 25);
}
else //sever a random joint
character.ApplyStatusEffects(ActionType.OnEating, deltaTime);
float particleFrequency = MathHelper.Clamp(eatSpeed / 2, 0.02f, 0.5f);
if (Rand.Value() < particleFrequency / 6)
{
target.AnimController.SeverLimbJoint(nonSeveredJoints.GetRandom());
target.AnimController.MainLimb.AddDamage(target.SimPosition, dmg, 0, 0, false);
}
}
}
else
{
character.SelectedCharacter = null;
if (Rand.Value() < particleFrequency)
{
target.AnimController.MainLimb.AddDamage(target.SimPosition, 0, dmg, 0, false);
}
if (eatTimer % 1.0f < 0.5f && (eatTimer - deltaTime * eatSpeed) % 1.0f > 0.5f)
{
static bool CanBeSevered(LimbJoint j) => !j.IsSevered && j.CanBeSevered && j.LimbA != null && !j.LimbA.IsSevered && j.LimbB != null && !j.LimbB.IsSevered;
//keep severing joints until there is only one limb left
var nonSeveredJoints = target.AnimController.LimbJoints.Where(CanBeSevered);
if (nonSeveredJoints.None())
{
//small monsters don't eat the contents of the character's inventory
if (Mass < target.AnimController.Mass)
{
target.Inventory?.AllItemsMod.ForEach(it => it?.Drop(dropper: null));
}
//only one limb left, the character is now full eaten
Entity.Spawner?.AddToRemoveQueue(target);
if (Character.AIController is EnemyAIController enemyAi)
{
enemyAi.PetBehavior?.OnEat(target);
}
character.SelectedCharacter = null;
}
else //sever a random joint
{
target.AnimController.SeverLimbJoint(nonSeveredJoints.GetRandom());
}
}
}
}
}
@@ -533,6 +533,8 @@ namespace Barotrauma
bool onSlope = Math.Abs(movement.X) > 0.01f && Math.Abs(floorNormal.X) > 0.1f && Math.Sign(floorNormal.X) != Math.Sign(movement.X);
bool movingHorizontally = !MathUtils.NearlyEqual(TargetMovement.X, 0.0f);
if (Stairs != null || onSlope)
{
torso.PullJointWorldAnchorB = new Vector2(
@@ -562,10 +564,8 @@ namespace Barotrauma
if (!torso.Disabled)
{
if (TorsoPosition.HasValue)
{
y += TorsoPosition.Value;
}
if (TorsoPosition.HasValue) { y += TorsoPosition.Value; }
if (Crouching && !movingHorizontally) { y -= HumanCrouchParams.MoveDownAmountWhenStationary; }
torso.PullJointWorldAnchorB =
MathUtils.SmoothStep(torso.SimPosition,
new Vector2(footMid + movement.X * TorsoLeanAmount, y), getUpForce);
@@ -574,10 +574,8 @@ namespace Barotrauma
if (!head.Disabled)
{
y = colliderPos.Y + stepLift * CurrentGroundedParams.StepLiftHeadMultiplier;
if (HeadPosition.HasValue)
{
y += HeadPosition.Value;
}
if (HeadPosition.HasValue) { y += HeadPosition.Value; }
if (Crouching && !movingHorizontally) { y -= HumanCrouchParams.MoveDownAmountWhenStationary; }
head.PullJointWorldAnchorB =
MathUtils.SmoothStep(head.SimPosition,
new Vector2(footMid + movement.X * HeadLeanAmount, y), getUpForce * 1.2f);
@@ -593,12 +591,15 @@ namespace Barotrauma
{
float torsoAngle = TorsoAngle.Value;
float herpesStrength = character.CharacterHealth.GetAfflictionStrength("spaceherpes");
if (Crouching && !movingHorizontally) { torsoAngle -= HumanCrouchParams.ExtraTorsoAngleWhenStationary; }
torsoAngle -= herpesStrength / 150.0f;
torso.body.SmoothRotate(torsoAngle * Dir, CurrentGroundedParams.TorsoTorque);
}
if (HeadAngle.HasValue)
{
head.body.SmoothRotate(HeadAngle.Value * Dir, CurrentGroundedParams.HeadTorque);
float headAngle = HeadAngle.Value;
if (Crouching && !movingHorizontally) { headAngle -= HumanCrouchParams.ExtraHeadAngleWhenStationary; }
head.body.SmoothRotate(headAngle * Dir, CurrentGroundedParams.HeadTorque);
}
if (!onGround)
@@ -616,8 +617,7 @@ namespace Barotrauma
Vector2 waistPos = waist != null ? waist.SimPosition : torso.SimPosition;
//moving horizontally
if (TargetMovement.X != 0.0f)
if (movingHorizontally)
{
//progress the walking animation
WalkPos -= MathHelper.ToRadians(CurrentAnimationParams.CycleSpeed) * walkCycleMultiplier * movement.X;
@@ -808,7 +808,8 @@ namespace Barotrauma
if (head == null) { return; }
if (torso == null) { return; }
if (currentHull != null)
//check both hulls: the hull whose coordinate space the ragdoll is in, and the hull whose bounds the character's origin actually is inside
if (currentHull != null && character.CurrentHull != null)
{
float surfacePos = currentHull.Surface;
float surfaceThreshold = ConvertUnits.ToDisplayUnits(Collider.SimPosition.Y + 1.0f);
@@ -816,7 +817,7 @@ namespace Barotrauma
//and use its water surface instead of the current hull's
if (currentHull.Rect.Y - currentHull.Surface < 5.0f)
{
GetSurfacePos(CurrentHull, ref surfacePos);
GetSurfacePos(currentHull, ref surfacePos);
void GetSurfacePos(Hull hull, ref float prevSurfacePos)
{
if (prevSurfacePos > surfaceThreshold) { return; }
@@ -834,7 +835,7 @@ namespace Barotrauma
foreach (var linkedTo in gap.linkedTo)
{
if (linkedTo is Hull otherHull && otherHull != hull)
if (linkedTo is Hull otherHull && otherHull != hull && otherHull != currentHull)
{
prevSurfacePos = Math.Max(surfacePos, otherHull.Surface);
GetSurfacePos(otherHull, ref prevSurfacePos);
@@ -888,7 +889,6 @@ namespace Barotrauma
{
Vector2 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition);
Vector2 diff = (mousePos - torso.SimPosition) * Dir;
TargetMovement = new Vector2(0.0f, -0.1f);
float newRotation = MathUtils.VectorToAngle(diff);
Collider.SmoothRotate(newRotation, CurrentSwimParams.SteerTorque * character.SpeedMultiplier);
}
@@ -305,7 +305,27 @@ namespace Barotrauma
public abstract float? TorsoPosition { get; }
public abstract float? TorsoAngle { get; }
public float ImpactTolerance => RagdollParams.ImpactTolerance;
float? impactTolerance;
public float ImpactTolerance
{
get
{
if (impactTolerance == null)
{
impactTolerance = RagdollParams.ImpactTolerance;
if (character.Params.VariantFile != null)
{
float? tolerance = character.Params.VariantFile.Root.GetChildElement("ragdoll")?.GetAttributeFloat("impacttolerance", impactTolerance.Value);
if (tolerance.HasValue)
{
impactTolerance = tolerance;
}
}
}
return impactTolerance.Value;
}
}
public bool Draggable => RagdollParams.Draggable;
public bool CanEnterSubmarine => RagdollParams.CanEnterSubmarine;
@@ -764,8 +784,8 @@ namespace Barotrauma
if (limbDiff.LengthSquared() < 0.0001f) { limbDiff = Rand.Vector(1.0f); }
limbDiff = Vector2.Normalize(limbDiff);
float mass = limbJoint.BodyA.Mass + limbJoint.BodyB.Mass;
limbJoint.LimbA.body.ApplyLinearImpulse(limbDiff * mass, (limbJoint.LimbA.SimPosition + limbJoint.LimbB.SimPosition) / 2.0f);
limbJoint.LimbB.body.ApplyLinearImpulse(-limbDiff * mass, (limbJoint.LimbA.SimPosition + limbJoint.LimbB.SimPosition) / 2.0f);
limbJoint.LimbA.body.ApplyLinearImpulse(limbDiff * Math.Min(mass, limbJoint.BodyA.Mass * 500), (limbJoint.LimbA.SimPosition + limbJoint.LimbB.SimPosition) / 2.0f);
limbJoint.LimbB.body.ApplyLinearImpulse(-limbDiff * Math.Min(mass, limbJoint.BodyB.Mass * 500), (limbJoint.LimbA.SimPosition + limbJoint.LimbB.SimPosition) / 2.0f);
connectedLimbs.Clear();
checkedJoints.Clear();
@@ -1180,13 +1200,13 @@ namespace Barotrauma
{
headInWater = false;
inWater = false;
RefreshFloorY(ignoreStairs: Stairs == null);
if (currentHull.WaterVolume > currentHull.Volume * 0.95f)
{
inWater = true;
}
else
{
RefreshFloorY(ignoreStairs: Stairs == null);
float waterSurface = ConvertUnits.ToSimUnits(currentHull.Surface);
if (targetMovement.Y < 0.0f)
{
@@ -1841,7 +1861,7 @@ namespace Barotrauma
float sin = (float)Math.Sin(mouthLimb.Rotation);
Vector2 bodySize = mouthLimb.body.GetSize();
Vector2 offset = new Vector2(mouthLimb.MouthPos.X * bodySize.X / 2, mouthLimb.MouthPos.Y * bodySize.Y / 2);
return mouthLimb.SimPosition + new Vector2(offset.X * cos - offset.Y * sin, offset.X * sin + offset.Y * cos) * mouthLimb.Scale * RagdollParams.LimbScale;
return mouthLimb.SimPosition + new Vector2(offset.X * cos - offset.Y * sin, offset.X * sin + offset.Y * cos);
}
public Vector2 GetColliderBottom()