Clients predict the state of a door when a signal is received (and revert back to the correct state if no verification is received from the server in 1 sec)
This commit is contained in:
@@ -36,6 +36,9 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private float lastReceivedMessage;
|
private float lastReceivedMessage;
|
||||||
|
|
||||||
|
private bool? predictedState;
|
||||||
|
private float resetPredictionTimer;
|
||||||
|
|
||||||
public PhysicsBody Body
|
public PhysicsBody Body
|
||||||
{
|
{
|
||||||
get { return body; }
|
get { return body; }
|
||||||
@@ -286,23 +289,40 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public override void Update(float deltaTime, Camera cam)
|
public override void Update(float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
|
bool isClosing = false;
|
||||||
if (!isStuck)
|
if (!isStuck)
|
||||||
{
|
{
|
||||||
OpenState += deltaTime * ((isOpen) ? 2.0f : -2.0f);
|
if (predictedState == null)
|
||||||
|
{
|
||||||
|
OpenState += deltaTime * ((isOpen) ? 2.0f : -2.0f);
|
||||||
|
isClosing = openState > 0.0f && openState < 1.0f && !isOpen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OpenState += deltaTime * (((bool)predictedState) ? 2.0f : -2.0f);
|
||||||
|
isClosing = openState > 0.0f && openState < 1.0f && !(bool)predictedState;
|
||||||
|
|
||||||
|
resetPredictionTimer -= deltaTime;
|
||||||
|
if (resetPredictionTimer <= 0.0f)
|
||||||
|
{
|
||||||
|
predictedState = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LinkedGap.Open = openState;
|
LinkedGap.Open = openState;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openState > 0.0f && openState < 1.0f && !isOpen)
|
if (isClosing)
|
||||||
{
|
{
|
||||||
PushCharactersAway();
|
PushCharactersAway();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
body.Enabled = openState < 1.0f;
|
body.Enabled = openState < 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//don't use the predicted state here, because it might set
|
||||||
|
//other items to an incorrect state if the prediction is wrong
|
||||||
item.SendSignal(0, (isOpen) ? "1" : "0", "state_out");
|
item.SendSignal(0, (isOpen) ? "1" : "0", "state_out");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,8 +357,6 @@ namespace Barotrauma.Items.Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (isHorizontal)
|
if (isHorizontal)
|
||||||
{
|
{
|
||||||
Vector2 pos = new Vector2(item.Rect.X, item.Rect.Y - item.Rect.Height/2);
|
Vector2 pos = new Vector2(item.Rect.X, item.Rect.Y - item.Rect.Height/2);
|
||||||
@@ -468,7 +486,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0.0f)
|
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0.0f)
|
||||||
{
|
{
|
||||||
if (isStuck || GameMain.Client != null) return;
|
if (isStuck) return;
|
||||||
|
|
||||||
if (connection.Name == "toggle")
|
if (connection.Name == "toggle")
|
||||||
{
|
{
|
||||||
@@ -482,13 +500,26 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public void SetState(bool open, bool isNetworkMessage, bool sendNetworkMessage = false)
|
public void SetState(bool open, bool isNetworkMessage, bool sendNetworkMessage = false)
|
||||||
{
|
{
|
||||||
if (GameMain.Client != null && !isNetworkMessage) return;
|
|
||||||
|
|
||||||
if (isStuck || isOpen == open) return;
|
if (isStuck || isOpen == open) return;
|
||||||
|
|
||||||
PlaySound(ActionType.OnUse, item.WorldPosition);
|
PlaySound(ActionType.OnUse, item.WorldPosition);
|
||||||
|
|
||||||
isOpen = open;
|
if (GameMain.Client != null && !isNetworkMessage)
|
||||||
|
{
|
||||||
|
//clients can "predict" that the door opens/closes when a signal is received
|
||||||
|
|
||||||
|
//the prediction will be reset after 1 second, setting the door to a state
|
||||||
|
//sent by the server, or reverting it back to its old state if no msg from server was received
|
||||||
|
|
||||||
|
predictedState = open;
|
||||||
|
resetPredictionTimer = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isOpen = open;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//opening a partially stuck door makes it less stuck
|
//opening a partially stuck door makes it less stuck
|
||||||
if (isOpen) stuck = MathHelper.Clamp(stuck - 30.0f, 0.0f, 100.0f);
|
if (isOpen) stuck = MathHelper.Clamp(stuck - 30.0f, 0.0f, 100.0f);
|
||||||
@@ -509,7 +540,8 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
SetState(msg.ReadBoolean(), true);
|
SetState(msg.ReadBoolean(), true);
|
||||||
Stuck = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
Stuck = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||||
}
|
|
||||||
|
|
||||||
|
predictedState = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user