Fixes to unconscious character pos syncing:
- main limb is anchored to collider - server ignores inputs from unconscious characters and doesn't freeze them - using timestamp-based interpolation on the client's own character instead of IDs
This commit is contained in:
@@ -59,7 +59,7 @@ namespace Barotrauma
|
||||
ColliderIndex = Crouching ? 1 : 0;
|
||||
if (!Crouching && ColliderIndex == 1) Crouching = true;
|
||||
|
||||
if (character.IsDead || character.IsUnconscious || stunTimer > 0.0f)
|
||||
if (!character.AllowMovement)
|
||||
{
|
||||
levitatingCollider = false;
|
||||
Collider.FarseerBody.FixedRotation = false;
|
||||
@@ -921,13 +921,15 @@ namespace Barotrauma
|
||||
|
||||
target.AnimController.IgnorePlatforms = IgnorePlatforms;
|
||||
|
||||
if (target.Stun > 0.0f || target.IsUnconscious || target.IsDead)
|
||||
if (!target.AllowMovement)
|
||||
{
|
||||
target.AnimController.TargetMovement = TargetMovement;
|
||||
}
|
||||
else if (target is AICharacter)
|
||||
{
|
||||
target.AnimController.TargetMovement = Vector2.Lerp(target.AnimController.TargetMovement, (character.SimPosition + Vector2.UnitX * Dir) - target.SimPosition, 0.5f);
|
||||
target.AnimController.TargetMovement = Vector2.Lerp(
|
||||
target.AnimController.TargetMovement,
|
||||
(character.SimPosition + Vector2.UnitX * Dir) - target.SimPosition, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1170,12 +1170,20 @@ namespace Barotrauma
|
||||
|
||||
protected void CheckDistFromCollider()
|
||||
{
|
||||
float allowedDist = Math.Max(Math.Max(Collider.radius, Collider.width), Collider.height) * 2.0f;
|
||||
float allowedDist = Math.Max(Math.Max(Collider.radius, Collider.width), Collider.height) * 2.0f;
|
||||
float resetDist = allowedDist * 10.0f;
|
||||
|
||||
//if the ragdoll is too far from the collider, disable collisions until it's close enough
|
||||
//(in case the ragdoll has gotten stuck somewhere)
|
||||
if (Vector2.DistanceSquared(Collider.SimPosition, MainLimb.SimPosition) > allowedDist*allowedDist)
|
||||
float distSqrd = Vector2.DistanceSquared(Collider.SimPosition, MainLimb.SimPosition);
|
||||
|
||||
if (distSqrd > resetDist * resetDist)
|
||||
{
|
||||
//ragdoll way too far, reset position
|
||||
SetPosition(Collider.SimPosition, true);
|
||||
}
|
||||
if (distSqrd > allowedDist * allowedDist)
|
||||
{
|
||||
//ragdoll too far from the collider, disable collisions until it's close enough
|
||||
//(in case the ragdoll has gotten stuck somewhere)
|
||||
foreach (Limb limb in Limbs)
|
||||
{
|
||||
limb.body.CollidesWith = Physics.CollisionNone;
|
||||
@@ -1197,20 +1205,31 @@ namespace Barotrauma
|
||||
{
|
||||
if (GameMain.NetworkMember == null) return;
|
||||
|
||||
if (character != GameMain.NetworkMember.Character ||
|
||||
character.IsUnconscious || character.Stun > 0.0f)
|
||||
if (character != GameMain.NetworkMember.Character || !character.AllowMovement)
|
||||
{
|
||||
//use simple interpolation for other players' characters and unconscious characters
|
||||
//use simple interpolation for other players' characters and characters that can't move
|
||||
if (character.MemPos.Count > 0)
|
||||
{
|
||||
Collider.LinearVelocity = Vector2.Zero;
|
||||
Collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement);
|
||||
}
|
||||
|
||||
//unconscious/dead characters can't correct their position using AnimController movement
|
||||
// -> we need to correct it manually
|
||||
if (character.AllowMovement)
|
||||
{
|
||||
Collider.LinearVelocity = overrideTargetMovement;
|
||||
MainLimb.pullJoint.WorldAnchorB = Collider.SimPosition;
|
||||
MainLimb.pullJoint.Enabled = true;
|
||||
}
|
||||
}
|
||||
character.MemLocalPos.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (character.MemPos.Count < 1) return;
|
||||
|
||||
overrideTargetMovement = Vector2.Zero;
|
||||
|
||||
PosInfo serverPos = character.MemPos.Last();
|
||||
|
||||
int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID);
|
||||
|
||||
Reference in New Issue
Block a user