Moved collider position correction logic to the physicsbody class (so that it can be used for sub & item syncing), character position msg length is written in bytes instead of bits, misc cleanup/refactoring
This commit is contained in:
@@ -321,16 +321,6 @@ namespace Barotrauma
|
||||
l.body.SetTransform(l.SimPosition,
|
||||
-l.body.Rotation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
|
||||
{
|
||||
timePassed = MathHelper.Clamp(timePassed, 0.0f, 1.0f);
|
||||
|
||||
Vector2 currPosition = prevPosition + targetMovement * timePassed;
|
||||
|
||||
return currPosition;
|
||||
}
|
||||
|
||||
private void Mirror()
|
||||
|
||||
@@ -1083,17 +1083,6 @@ namespace Barotrauma
|
||||
hand.body.SmoothRotate((ang2 + handAngle * Dir), 100.0f * force);
|
||||
}
|
||||
|
||||
public override Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
|
||||
{
|
||||
timePassed = MathHelper.Clamp(timePassed, 0.0f, 1.0f);
|
||||
|
||||
Vector2 targetMovement = character.GetTargetMovement();
|
||||
|
||||
Vector2 currPosition = prevPosition + targetMovement * timePassed / 500.0f;
|
||||
|
||||
return currPosition;
|
||||
}
|
||||
|
||||
public override void Flip()
|
||||
{
|
||||
base.Flip();
|
||||
|
||||
@@ -941,18 +941,6 @@ namespace Barotrauma
|
||||
{
|
||||
case Physics.CollisionStairs:
|
||||
if (inWater && TargetMovement.Y < 0.5f) return -1;
|
||||
//Structure structure = fixture.Body.UserData as Structure;
|
||||
//if (stairs == null && structure != null)
|
||||
//{
|
||||
// if (LowestLimb.SimPosition.Y < structure.SimPosition.Y)
|
||||
// {
|
||||
// return -1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// stairs = structure;
|
||||
// }
|
||||
//}
|
||||
break;
|
||||
case Physics.CollisionPlatform:
|
||||
Structure platform = fixture.Body.UserData as Structure;
|
||||
@@ -1040,7 +1028,7 @@ namespace Barotrauma
|
||||
|
||||
protected void CheckDistFromCollider()
|
||||
{
|
||||
float allowedDist = Math.Max(Math.Max(collider.radius, collider.width), collider.height);
|
||||
float allowedDist = Math.Max(Math.Max(collider.radius, collider.width), collider.height) * 2.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)
|
||||
@@ -1055,19 +1043,20 @@ namespace Barotrauma
|
||||
}
|
||||
else if (collisionsDisabled)
|
||||
{
|
||||
//set the position of the ragdoll to make sure limbs don't get stuck inside walls when re-enabling collisions
|
||||
SetPosition(MainLimb.SimPosition, true);
|
||||
|
||||
UpdateCollisionCategories();
|
||||
collisionsDisabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
float t = 0.0f;
|
||||
|
||||
|
||||
private void UpdateNetPlayerPosition(float deltaTime)
|
||||
{
|
||||
if (character.MemPos.Count < 2) return;
|
||||
|
||||
if (character == GameMain.NetworkMember.Character)
|
||||
{
|
||||
if (character.MemPos.Count < 2) return;
|
||||
|
||||
PosInfo serverPos = character.MemPos.Last();
|
||||
|
||||
int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID);
|
||||
@@ -1086,46 +1075,10 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
PosInfo prev = character.MemPos[0];
|
||||
PosInfo next = character.MemPos[1];
|
||||
|
||||
Vector2 currPos = collider.SimPosition;
|
||||
|
||||
//interpolate the position of the collider from the first position in the buffer towards the second
|
||||
if (prev.Timestamp < next.Timestamp)
|
||||
{
|
||||
//if there are more than 2 positions in the buffer,
|
||||
//increase the interpolation speed to catch up with the server
|
||||
float speedMultiplier = 1.0f + (float)Math.Pow((character.MemPos.Count - 2) / 2.0f, 2.0f);
|
||||
|
||||
t += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp);
|
||||
currPos = Vector2.Lerp(prev.Position, next.Position, t);
|
||||
|
||||
//override the targetMovement to make the character play the walking/running animation
|
||||
overrideTargetMovement = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
currPos = next.Position;
|
||||
t = 1.0f;
|
||||
}
|
||||
|
||||
collider.SetTransform(currPos, collider.Rotation);
|
||||
|
||||
if (t >= 1.0f)
|
||||
{
|
||||
t = 0.0f;
|
||||
character.MemPos.RemoveAt(0);
|
||||
}
|
||||
collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed)
|
||||
{
|
||||
return prevPosition;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Vector2 GetFlowForce()
|
||||
{
|
||||
Vector2 limbPos = ConvertUnits.ToDisplayUnits(Limbs[0].SimPosition);
|
||||
|
||||
@@ -798,14 +798,23 @@ namespace Barotrauma
|
||||
if (length > 0.0f) targetMovement = targetMovement / length;
|
||||
}
|
||||
|
||||
if (AnimController is HumanoidAnimController &&
|
||||
!((HumanoidAnimController)AnimController).Crouching &&
|
||||
Math.Sign(targetMovement.X) != -Math.Sign(AnimController.Dir) &&
|
||||
IsKeyDown(InputType.Run))
|
||||
if (IsKeyDown(InputType.Run))
|
||||
{
|
||||
targetMovement *= 3.0f;
|
||||
//can't run if
|
||||
// - not a humanoid
|
||||
// - dragging someone
|
||||
// - crouching
|
||||
// - moving backwards
|
||||
if (AnimController is HumanoidAnimController &&
|
||||
selectedCharacter == null &&
|
||||
!((HumanoidAnimController)AnimController).Crouching &&
|
||||
Math.Sign(targetMovement.X) != -Math.Sign(AnimController.Dir))
|
||||
{
|
||||
targetMovement *= 3.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
targetMovement *= SpeedMultiplier;
|
||||
SpeedMultiplier = 1.0f;
|
||||
|
||||
@@ -1845,41 +1854,39 @@ namespace Barotrauma
|
||||
{
|
||||
msg.Write(ID);
|
||||
|
||||
//todo: only write this if sending for the client who's controlling the character?
|
||||
msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count));
|
||||
if (this == c.Character)
|
||||
{
|
||||
//length of the message
|
||||
msg.Write((byte)(4+4+4+4));
|
||||
msg.Write(true);
|
||||
msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count));
|
||||
}
|
||||
else
|
||||
{
|
||||
//length of the message
|
||||
msg.Write((byte)(4+4+4));
|
||||
msg.Write(false);
|
||||
}
|
||||
|
||||
msg.Write(AnimController.Dir > 0.0f);
|
||||
|
||||
msg.Write(SimPosition.X);
|
||||
msg.Write(SimPosition.Y);
|
||||
}
|
||||
|
||||
public static void ClientReadStatic(NetIncomingMessage msg, float sendingTime)
|
||||
{
|
||||
UInt16 id = msg.ReadUInt16();
|
||||
var character = Entity.FindEntityByID(id) as Character;
|
||||
|
||||
if (character == null)
|
||||
{
|
||||
//skip through the rest of the message
|
||||
//todo: a better way to skip through the message?
|
||||
msg.Position += 32 + 1 + 32 + 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
character.ClientRead(msg, sendingTime);
|
||||
}
|
||||
msg.WritePadBits();
|
||||
}
|
||||
|
||||
public virtual void ClientRead(NetIncomingMessage msg, float sendingTime)
|
||||
{
|
||||
UInt32 networkUpdateID = msg.ReadUInt32();
|
||||
UInt32 networkUpdateID = 0;
|
||||
if (msg.ReadBoolean())
|
||||
{
|
||||
networkUpdateID = msg.ReadUInt32();
|
||||
}
|
||||
|
||||
//float sendingTime = msg.ReadSingle();
|
||||
bool facingRight = msg.ReadBoolean();
|
||||
Vector2 pos = new Vector2(msg.ReadFloat(), msg.ReadFloat());
|
||||
|
||||
|
||||
|
||||
var posInfo =
|
||||
GameMain.NetworkMember.Character == this ?
|
||||
new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID) :
|
||||
|
||||
@@ -707,7 +707,20 @@ namespace Barotrauma.Networking
|
||||
lastSentChatMsgID = inc.ReadUInt32();
|
||||
break;
|
||||
case ServerNetObject.CHARACTER_POSITION:
|
||||
Character.ClientReadStatic(inc, sendingTime);
|
||||
UInt16 id = inc.ReadUInt16();
|
||||
byte msgLength = inc.ReadByte();
|
||||
|
||||
var character = Entity.FindEntityByID(id) as Character;
|
||||
if (character == null)
|
||||
{
|
||||
//skip through the rest of the message
|
||||
inc.Position += msgLength * 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
character.ClientRead(inc, sendingTime);
|
||||
}
|
||||
|
||||
inc.ReadPadBits();
|
||||
break;
|
||||
case ServerNetObject.CHAT_MESSAGE:
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace Barotrauma
|
||||
|
||||
Vector2 offsetFromTargetPos;
|
||||
|
||||
private float netInterpolationState;
|
||||
|
||||
public Shape BodyShape
|
||||
{
|
||||
get { return bodyShape; }
|
||||
@@ -461,6 +463,45 @@ namespace Barotrauma
|
||||
new Vector2(bodyShapeTexture.Width / 2, bodyShapeTexture.Height / 2),
|
||||
1.0f, SpriteEffects.None, 0.0f);
|
||||
}
|
||||
|
||||
public void CorrectPosition(List<PosInfo> positionBuffer, float deltaTime, out Vector2 newVelocity)
|
||||
{
|
||||
newVelocity = Vector2.Zero;
|
||||
if (positionBuffer.Count < 2) return;
|
||||
|
||||
PosInfo prev = positionBuffer[0];
|
||||
PosInfo next = positionBuffer[1];
|
||||
|
||||
Vector2 currPos = SimPosition;
|
||||
|
||||
//interpolate the position of the collider from the first position in the buffer towards the second
|
||||
if (prev.Timestamp < next.Timestamp)
|
||||
{
|
||||
//if there are more than 2 positions in the buffer,
|
||||
//increase the interpolation speed to catch up with the server
|
||||
float speedMultiplier = 1.0f + (float)Math.Pow((positionBuffer.Count - 2) / 2.0f, 2.0f);
|
||||
|
||||
netInterpolationState += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp);
|
||||
currPos = Vector2.Lerp(prev.Position, next.Position, netInterpolationState);
|
||||
|
||||
//override the targetMovement to make the character play the walking/running animation
|
||||
newVelocity = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
currPos = next.Position;
|
||||
netInterpolationState = 1.0f;
|
||||
}
|
||||
|
||||
SetTransform(currPos, Rotation);
|
||||
|
||||
if (netInterpolationState >= 1.0f)
|
||||
{
|
||||
netInterpolationState = 0.0f;
|
||||
positionBuffer.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user