Some refactoring: made PosInfo a class and moved character-specific fields to a "CharacterStateInfo" subclass

This commit is contained in:
Regalis
2017-03-21 19:36:28 +02:00
parent d42d017aab
commit 823ad12058
5 changed files with 119 additions and 111 deletions
@@ -595,15 +595,15 @@ namespace Barotrauma
} }
} }
if (character.MemPos.Count > 1) if (character.MemState.Count > 1)
{ {
Vector2 prevPos = ConvertUnits.ToDisplayUnits(character.MemPos[0].Position); Vector2 prevPos = ConvertUnits.ToDisplayUnits(character.MemState[0].Position);
if (currentHull != null) prevPos += currentHull.Submarine.DrawPosition; if (currentHull != null) prevPos += currentHull.Submarine.DrawPosition;
prevPos.Y = -prevPos.Y; prevPos.Y = -prevPos.Y;
for (int i = 1; i < character.MemPos.Count; i++ ) for (int i = 1; i < character.MemState.Count; i++ )
{ {
Vector2 currPos = ConvertUnits.ToDisplayUnits(character.MemPos[i].Position); Vector2 currPos = ConvertUnits.ToDisplayUnits(character.MemState[i].Position);
if (currentHull != null) currPos += currentHull.Submarine.DrawPosition; if (currentHull != null) currPos += currentHull.Submarine.DrawPosition;
currPos.Y = -currPos.Y; currPos.Y = -currPos.Y;
@@ -1232,19 +1232,19 @@ namespace Barotrauma
{ {
if (GameMain.NetworkMember == null) return; if (GameMain.NetworkMember == null) return;
for (int i = 0; i < character.MemPos.Count; i++ ) for (int i = 0; i < character.MemState.Count; i++ )
{ {
if (character.Submarine == null) if (character.Submarine == null)
{ {
//transform in-sub coordinates to outside coordinates //transform in-sub coordinates to outside coordinates
if (character.MemPos[i].Position.Y > ConvertUnits.ToSimUnits(Level.Loaded.Size.Y)) if (character.MemState[i].Position.Y > ConvertUnits.ToSimUnits(Level.Loaded.Size.Y))
character.MemPos[i] = PosInfo.TransformInToOutside(character.MemPos[i]); character.MemState[i].TransformInToOutside();
} }
else if (currentHull != null) else if (currentHull != null)
{ {
//transform outside coordinates to in-sub coordinates //transform outside coordinates to in-sub coordinates
if (character.MemPos[i].Position.Y < ConvertUnits.ToSimUnits(Level.Loaded.Size.Y)) if (character.MemState[i].Position.Y < ConvertUnits.ToSimUnits(Level.Loaded.Size.Y))
character.MemPos[i] = PosInfo.TransformOutToInside(character.MemPos[i], currentHull.Submarine); character.MemState[i].TransformOutToInside(currentHull.Submarine);
} }
} }
@@ -1253,20 +1253,20 @@ namespace Barotrauma
if (character != GameMain.NetworkMember.Character || !character.AllowInput) if (character != GameMain.NetworkMember.Character || !character.AllowInput)
{ {
//use simple interpolation for other players' characters and characters that can't move //use simple interpolation for other players' characters and characters that can't move
if (character.MemPos.Count > 0) if (character.MemState.Count > 0)
{ {
if (character.MemPos[0].Interact == null) if (character.MemState[0].Interact == null)
{ {
character.DeselectCharacter(); character.DeselectCharacter();
character.SelectedConstruction = null; character.SelectedConstruction = null;
} }
else if (character.MemPos[0].Interact is Character) else if (character.MemState[0].Interact is Character)
{ {
character.SelectCharacter((Character)character.MemPos[0].Interact); character.SelectCharacter((Character)character.MemState[0].Interact);
} }
else if (character.MemPos[0].Interact is Item) else if (character.MemState[0].Interact is Item)
{ {
var newSelectedConstruction = (Item)character.MemPos[0].Interact; var newSelectedConstruction = (Item)character.MemState[0].Interact;
if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction) if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction)
{ {
newSelectedConstruction.Pick(character, true, true); newSelectedConstruction.Pick(character, true, true);
@@ -1274,7 +1274,7 @@ namespace Barotrauma
} }
Collider.LinearVelocity = Vector2.Zero; Collider.LinearVelocity = Vector2.Zero;
Collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement); Collider.CorrectPosition(character.MemState, deltaTime, out overrideTargetMovement);
//unconscious/dead characters can't correct their position using AnimController movement //unconscious/dead characters can't correct their position using AnimController movement
// -> we need to correct it manually // -> we need to correct it manually
@@ -1285,46 +1285,46 @@ namespace Barotrauma
MainLimb.pullJoint.Enabled = true; MainLimb.pullJoint.Enabled = true;
} }
} }
character.MemLocalPos.Clear(); character.MemLocalState.Clear();
} }
else else
{ {
for (int i = 0; i < character.MemLocalPos.Count; i++) for (int i = 0; i < character.MemLocalState.Count; i++)
{ {
if (character.Submarine == null) if (character.Submarine == null)
{ {
//transform in-sub coordinates to outside coordinates //transform in-sub coordinates to outside coordinates
if (character.MemLocalPos[i].Position.Y > ConvertUnits.ToSimUnits(Level.Loaded.Size.Y)) if (character.MemLocalState[i].Position.Y > ConvertUnits.ToSimUnits(Level.Loaded.Size.Y))
character.MemLocalPos[i] = PosInfo.TransformInToOutside(character.MemLocalPos[i]); character.MemLocalState[i].TransformInToOutside();
} }
else if (currentHull != null) else if (currentHull != null)
{ {
//transform outside coordinates to in-sub coordinates //transform outside coordinates to in-sub coordinates
if (character.MemLocalPos[i].Position.Y < ConvertUnits.ToSimUnits(Level.Loaded.Size.Y)) if (character.MemLocalState[i].Position.Y < ConvertUnits.ToSimUnits(Level.Loaded.Size.Y))
character.MemLocalPos[i] = PosInfo.TransformOutToInside(character.MemLocalPos[i], currentHull.Submarine); character.MemLocalState[i].TransformOutToInside(currentHull.Submarine);
} }
} }
if (character.MemPos.Count < 1) return; if (character.MemState.Count < 1) return;
overrideTargetMovement = Vector2.Zero; overrideTargetMovement = Vector2.Zero;
PosInfo serverPos = character.MemPos.Last(); CharacterStateInfo serverPos = character.MemState.Last();
if (!character.isSynced) if (!character.isSynced)
{ {
SetPosition(serverPos.Position, false); SetPosition(serverPos.Position, false);
Collider.LinearVelocity = Vector2.Zero; Collider.LinearVelocity = Vector2.Zero;
character.MemLocalPos.Clear(); character.MemLocalState.Clear();
character.LastNetworkUpdateID = serverPos.ID; character.LastNetworkUpdateID = serverPos.ID;
character.isSynced = true; character.isSynced = true;
return; return;
} }
int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID); int localPosIndex = character.MemLocalState.FindIndex(m => m.ID == serverPos.ID);
if (localPosIndex > -1) if (localPosIndex > -1)
{ {
PosInfo localPos = character.MemLocalPos[localPosIndex]; CharacterStateInfo localPos = character.MemLocalState[localPosIndex];
//the entity we're interacting with doesn't match the server's //the entity we're interacting with doesn't match the server's
if (localPos.Interact != serverPos.Interact) if (localPos.Interact != serverPos.Interact)
@@ -1349,22 +1349,21 @@ namespace Barotrauma
} }
Vector2 positionError = serverPos.Position - localPos.Position; Vector2 positionError = serverPos.Position - localPos.Position;
for (int i = localPosIndex; i < character.MemLocalPos.Count; i++) for (int i = localPosIndex; i < character.MemLocalState.Count; i++)
{ {
character.MemLocalPos[i] = character.MemLocalState[i] =
new PosInfo( new CharacterStateInfo(
character.MemLocalPos[i].Position + positionError, character.MemLocalState[i].Position + positionError,
character.MemLocalPos[i].Direction, character.MemLocalState[i].ID,
character.MemLocalPos[i].ID, character.MemLocalState[i].Direction,
0.0f, character.MemLocalState[i].Interact);
character.MemLocalPos[i].Interact);
} }
Collider.SetTransform(Collider.SimPosition + positionError, Collider.Rotation); Collider.SetTransform(Collider.SimPosition + positionError, Collider.Rotation);
} }
if (character.MemLocalPos.Count > 120) character.MemLocalPos.RemoveRange(0, character.MemLocalPos.Count - 120); if (character.MemLocalState.Count > 120) character.MemLocalState.RemoveRange(0, character.MemLocalState.Count - 120);
character.MemPos.Clear(); character.MemState.Clear();
} }
} }
+6 -17
View File
@@ -198,17 +198,6 @@ namespace Barotrauma
get { return Submarine == null ? cursorPosition : cursorPosition + Submarine.Position; } get { return Submarine == null ? cursorPosition : cursorPosition + Submarine.Position; }
} }
public List<PosInfo> MemPos
{
get { return memPos; }
}
public List<PosInfo> MemLocalPos
{
get { return memLocalPos; }
}
public Character ClosestCharacter public Character ClosestCharacter
{ {
get { return closestCharacter; } get { return closestCharacter; }
@@ -843,9 +832,9 @@ namespace Barotrauma
} }
else if (GameMain.Client != null && Character.controlled != this) else if (GameMain.Client != null && Character.controlled != this)
{ {
if (memPos.Count > 0) if (memState.Count > 0)
{ {
AnimController.TargetDir = memPos[0].Direction; AnimController.TargetDir = memState[0].Direction;
} }
} }
@@ -1547,7 +1536,7 @@ namespace Barotrauma
if (aiTarget != null) aiTarget.Draw(spriteBatch); if (aiTarget != null) aiTarget.Draw(spriteBatch);
} }
if (memPos != null && memPos.Count > 0 && controlled == this) /*if (memPos != null && memPos.Count > 0 && controlled == this)
{ {
PosInfo serverPos = memPos.Last(); PosInfo serverPos = memPos.Last();
Vector2 remoteVec = ConvertUnits.ToDisplayUnits(serverPos.Position); Vector2 remoteVec = ConvertUnits.ToDisplayUnits(serverPos.Position);
@@ -1559,8 +1548,8 @@ namespace Barotrauma
PosInfo localPos = memLocalPos.Find(m => m.ID == serverPos.ID); PosInfo localPos = memLocalPos.Find(m => m.ID == serverPos.ID);
int mpind = memLocalPos.FindIndex(lp => lp.ID == localPos.ID); int mpind = memLocalPos.FindIndex(lp => lp.ID == localPos.ID);
PosInfo? localPos1 = mpind > 0 ? memLocalPos[mpind - 1] : (PosInfo?)null; PosInfo localPos1 = mpind > 0 ? memLocalPos[mpind - 1] : null;
PosInfo? localPos2 = mpind < memLocalPos.Count-1 ? memLocalPos[mpind + 1] : (PosInfo?)null; PosInfo localPos2 = mpind < memLocalPos.Count-1 ? memLocalPos[mpind + 1] : null;
Vector2 localVec = ConvertUnits.ToDisplayUnits(localPos.Position); Vector2 localVec = ConvertUnits.ToDisplayUnits(localPos.Position);
Vector2 localVec1 = localPos1 != null ? ConvertUnits.ToDisplayUnits(((PosInfo)localPos1).Position) : Vector2.Zero; Vector2 localVec1 = localPos1 != null ? ConvertUnits.ToDisplayUnits(((PosInfo)localPos1).Position) : Vector2.Zero;
@@ -1578,7 +1567,7 @@ namespace Barotrauma
//GUI.DrawLine(spriteBatch, remoteVec, localVec, Color.Yellow, 0, 10); //GUI.DrawLine(spriteBatch, remoteVec, localVec, Color.Yellow, 0, 10);
if (localPos1 != null) GUI.DrawLine(spriteBatch, remoteVec, localVec1, Color.Lime, 0, 2); if (localPos1 != null) GUI.DrawLine(spriteBatch, remoteVec, localVec1, Color.Lime, 0, 2);
if (localPos2 != null) GUI.DrawLine(spriteBatch, remoteVec + Vector2.One, localVec2 + Vector2.One, Color.Red, 0, 2); if (localPos2 != null) GUI.DrawLine(spriteBatch, remoteVec + Vector2.One, localVec2 + Vector2.One, Color.Red, 0, 2);
} }*/
Vector2 mouseDrawPos = CursorWorldPosition; Vector2 mouseDrawPos = CursorWorldPosition;
mouseDrawPos.Y = -mouseDrawPos.Y; mouseDrawPos.Y = -mouseDrawPos.Y;
@@ -4,11 +4,33 @@ using Microsoft.Xna.Framework;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Barotrauma namespace Barotrauma
{ {
class CharacterStateInfo : PosInfo
{
public readonly Direction Direction;
public readonly Entity Interact; //the entity being interacted with
public CharacterStateInfo(Vector2 pos, float time, Direction dir, Entity interact)
: this(pos, 0, time, dir, interact)
{
}
public CharacterStateInfo(Vector2 pos, UInt16 ID, Direction dir, Entity interact)
: this(pos, ID, 0.0f, dir, interact)
{
}
protected CharacterStateInfo(Vector2 pos, UInt16 ID, float time, Direction dir, Entity interact)
: base(pos, ID, time)
{
Direction = dir;
Interact = interact;
}
}
partial class Character partial class Character
{ {
[Flags] [Flags]
@@ -50,13 +72,23 @@ namespace Barotrauma
private List<NetInputMem> memInput = new List<NetInputMem>(); private List<NetInputMem> memInput = new List<NetInputMem>();
private List<PosInfo> memPos = new List<PosInfo>(); private List<CharacterStateInfo> memState = new List<CharacterStateInfo>();
private List<PosInfo> memLocalPos = new List<PosInfo>(); private List<CharacterStateInfo> memLocalState = new List<CharacterStateInfo>();
private bool networkUpdateSent; private bool networkUpdateSent;
public bool isSynced = false; public bool isSynced = false;
public List<CharacterStateInfo> MemState
{
get { return memState; }
}
public List<CharacterStateInfo> MemLocalState
{
get { return memLocalState; }
}
private void UpdateNetInput() private void UpdateNetInput()
{ {
if (this != Character.Controlled) if (this != Character.Controlled)
@@ -67,7 +99,7 @@ namespace Barotrauma
if (lastRecvPositionUpdateTime < NetTime.Now - 1.0f) if (lastRecvPositionUpdateTime < NetTime.Now - 1.0f)
{ {
AnimController.Frozen = true; AnimController.Frozen = true;
memPos.Clear(); memState.Clear();
//hide after 2 seconds //hide after 2 seconds
if (lastRecvPositionUpdateTime < NetTime.Now - 2.0f) if (lastRecvPositionUpdateTime < NetTime.Now - 2.0f)
{ {
@@ -127,13 +159,13 @@ namespace Barotrauma
} }
else if (GameMain.Client != null) else if (GameMain.Client != null)
{ {
var posInfo = new PosInfo( var posInfo = new CharacterStateInfo(
SimPosition, SimPosition,
LastNetworkUpdateID,
AnimController.TargetDir, AnimController.TargetDir,
LastNetworkUpdateID, 0.0f,
selectedCharacter == null ? (Entity)selectedConstruction : (Entity)selectedCharacter); selectedCharacter == null ? (Entity)selectedConstruction : (Entity)selectedCharacter);
memLocalPos.Add(posInfo); memLocalState.Add(posInfo);
InputNetFlags newInput = InputNetFlags.None; InputNetFlags newInput = InputNetFlags.None;
if (IsKeyDown(InputType.Left)) newInput |= InputNetFlags.Left; if (IsKeyDown(InputType.Left)) newInput |= InputNetFlags.Left;
@@ -449,21 +481,25 @@ namespace Barotrauma
msg.ReadFloat(), msg.ReadFloat(),
msg.ReadFloat()); msg.ReadFloat());
var posInfo = new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID, sendingTime, selectedEntity);
int index = 0; int index = 0;
if (GameMain.NetworkMember.Character == this && AllowInput) if (GameMain.NetworkMember.Character == this && AllowInput)
{ {
while (index < memPos.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memPos[index].ID)) var posInfo = new CharacterStateInfo(pos, networkUpdateID, facingRight ? Direction.Right : Direction.Left, selectedEntity);
while (index < memState.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memState[index].ID))
index++; index++;
memState.Insert(index, posInfo);
} }
else else
{ {
while (index < memPos.Count && posInfo.Timestamp > memPos[index].Timestamp) var posInfo = new CharacterStateInfo(pos, sendingTime, facingRight ? Direction.Right : Direction.Left, selectedEntity);
while (index < memState.Count && posInfo.Timestamp > memState[index].Timestamp)
index++; index++;
memState.Insert(index, posInfo);
} }
memPos.Insert(index, posInfo);
break; break;
case ServerNetObject.ENTITY_EVENT: case ServerNetObject.ENTITY_EVENT:
bool isInventoryUpdate = msg.ReadBoolean(); bool isInventoryUpdate = msg.ReadBoolean();
@@ -673,8 +709,8 @@ namespace Barotrauma
GameMain.LightManager.LosEnabled = true; GameMain.LightManager.LosEnabled = true;
character.memInput.Clear(); character.memInput.Clear();
character.memPos.Clear(); character.memState.Clear();
character.memLocalPos.Clear(); character.memLocalState.Clear();
} }
else else
{ {
+1 -1
View File
@@ -1339,7 +1339,7 @@ namespace Barotrauma
return; return;
} }
subBody.MemPos.Insert(index, new PosInfo(newTargetPosition, Direction.Right, sendingTime)); subBody.MemPos.Insert(index, new PosInfo(newTargetPosition, sendingTime));
} }
} }
+21 -37
View File
@@ -2,71 +2,55 @@
using FarseerPhysics; using FarseerPhysics;
using FarseerPhysics.Dynamics; using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories; using FarseerPhysics.Factories;
using Lidgren.Network;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Networking;
using System.Collections.Generic; using System.Collections.Generic;
using System; using System;
namespace Barotrauma namespace Barotrauma
{ {
struct PosInfo class PosInfo
{ {
public readonly Vector2 Position; public Vector2 Position
public readonly Direction Direction; {
get;
private set;
}
public readonly float Timestamp; public readonly float Timestamp;
public readonly UInt16 ID; public readonly UInt16 ID;
public readonly Entity Interact; //the entity being interacted with public PosInfo(Vector2 pos, float time)
: this(pos, 0, time)
public PosInfo(Vector2 pos, Direction dir, float time)
: this(pos, dir, 0, time)
{ {
} }
public PosInfo(Vector2 pos, Direction dir, UInt16 ID) public PosInfo(Vector2 pos, UInt16 ID)
: this(pos, dir, ID, 0.0f) : this(pos, ID, 0.0f)
{ {
} }
public PosInfo(Vector2 pos, Direction dir, UInt16 ID, float time) protected PosInfo(Vector2 pos, UInt16 ID, float time)
: this(pos, dir, ID, time, null)
{
}
public PosInfo(Vector2 pos, Direction dir, UInt16 ID, float time, Entity interact)
{ {
Position = pos; Position = pos;
Direction = dir;
this.ID = ID; this.ID = ID;
Interact = interact;
Timestamp = time; Timestamp = time;
} }
public static PosInfo TransformOutToInside(PosInfo posInfo, Submarine submarine) public void TransformOutToInside(Submarine submarine)
{ {
//transform outside coordinates to in-sub coordinates //transform outside coordinates to in-sub coordinates
return new PosInfo( Position -= ConvertUnits.ToSimUnits(submarine.Position);
posInfo.Position - ConvertUnits.ToSimUnits(submarine.Position),
posInfo.Direction,
posInfo.ID,
posInfo.Timestamp);
} }
public static PosInfo TransformInToOutside(PosInfo posInfo) public void TransformInToOutside()
{ {
var sub = Submarine.FindContaining(ConvertUnits.ToDisplayUnits(posInfo.Position)); var sub = Submarine.FindContaining(ConvertUnits.ToDisplayUnits(Position));
if (sub == null) return posInfo; if (sub != null)
{
return new PosInfo( Position += ConvertUnits.ToSimUnits(sub.Position);
posInfo.Position + ConvertUnits.ToSimUnits(sub.Position), }
posInfo.Direction,
posInfo.ID,
posInfo.Timestamp);
} }
} }
@@ -549,7 +533,7 @@ namespace Barotrauma
1.0f, SpriteEffects.None, 0.0f); 1.0f, SpriteEffects.None, 0.0f);
} }
public void CorrectPosition(List<PosInfo> positionBuffer, float deltaTime, out Vector2 newVelocity) public void CorrectPosition<T>(List<T> positionBuffer, float deltaTime, out Vector2 newVelocity) where T : PosInfo
{ {
Vector2 newPosition = SimPosition; Vector2 newPosition = SimPosition;
CorrectPosition(positionBuffer, deltaTime, out newVelocity, out newPosition); CorrectPosition(positionBuffer, deltaTime, out newVelocity, out newPosition);
@@ -558,7 +542,7 @@ namespace Barotrauma
} }
public void CorrectPosition(List<PosInfo> positionBuffer, float deltaTime, out Vector2 newVelocity, out Vector2 newPosition) public void CorrectPosition<T>(List<T> positionBuffer, float deltaTime, out Vector2 newVelocity, out Vector2 newPosition) where T : PosInfo
{ {
newVelocity = Vector2.Zero; newVelocity = Vector2.Zero;
newPosition = SimPosition; newPosition = SimPosition;