Merge branch 'master' of https://github.com/Regalis11/Barotrauma.git
This commit is contained in:
@@ -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
|
||||
|
||||
+49
-44
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-15
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user