Reactors, sonars, nav terminals, pumps and batteries use similar delayed correction logic as doors and inventories.
I.e. the clients delay correcting the state of the item until the local player stops manipulating the state (atm the delay is 1 sec). Prevents pumping speeds, steering directions and whatnot from switching to an old state and back - now the corrections should not be visible to the players unless the client predicts the state wrong.
This commit is contained in:
@@ -514,7 +514,7 @@ namespace Barotrauma.Items.Components
|
||||
PlaySound(ActionType.OnUse, item.WorldPosition);
|
||||
|
||||
predictedState = open;
|
||||
resetPredictionTimer = 1.0f;
|
||||
resetPredictionTimer = CorrectionDelay;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -523,7 +523,6 @@ namespace Barotrauma.Items.Components
|
||||
isOpen = open;
|
||||
}
|
||||
|
||||
|
||||
//opening a partially stuck door makes it less stuck
|
||||
if (isOpen) stuck = MathHelper.Clamp(stuck - 30.0f, 0.0f, 100.0f);
|
||||
|
||||
|
||||
@@ -59,9 +59,7 @@ namespace Barotrauma.Items.Components
|
||||
public bool WasUsed;
|
||||
|
||||
public readonly Dictionary<ActionType, List<StatusEffect>> statusEffectLists;
|
||||
|
||||
protected bool updated;
|
||||
|
||||
|
||||
public List<RelatedItem> requiredItems;
|
||||
|
||||
public List<Skill> requiredSkills;
|
||||
@@ -72,6 +70,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public ItemComponent Parent;
|
||||
|
||||
protected const float CorrectionDelay = 1.0f;
|
||||
protected CoroutineHandle delayedCorrectionCoroutine;
|
||||
protected float correctionTimer;
|
||||
|
||||
private string msg;
|
||||
|
||||
[HasDefaultValue(0.0f, false)]
|
||||
@@ -86,15 +88,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
get { return properties; }
|
||||
}
|
||||
//has the component already been updated this frame
|
||||
public bool Updated
|
||||
{
|
||||
get { return updated; }
|
||||
set { updated = value; }
|
||||
}
|
||||
|
||||
public bool NetworkUpdateSent;
|
||||
|
||||
|
||||
public virtual bool IsActive
|
||||
{
|
||||
get { return isActive; }
|
||||
@@ -535,6 +529,12 @@ namespace Barotrauma.Items.Components
|
||||
Sounds.SoundManager.Stop(loopingSoundIndex);
|
||||
}
|
||||
|
||||
if (delayedCorrectionCoroutine != null)
|
||||
{
|
||||
CoroutineManager.StopCoroutines(delayedCorrectionCoroutine);
|
||||
delayedCorrectionCoroutine = null;
|
||||
}
|
||||
|
||||
RemoveComponentSpecific();
|
||||
}
|
||||
|
||||
@@ -680,6 +680,30 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
//Starts a coroutine that will read the correct state of the component from the NetBuffer when correctionTimer reaches zero.
|
||||
protected void StartDelayedCorrection(ServerNetObject type, NetBuffer buffer, float sendingTime)
|
||||
{
|
||||
if (delayedCorrectionCoroutine != null) CoroutineManager.StopCoroutines(delayedCorrectionCoroutine);
|
||||
|
||||
delayedCorrectionCoroutine = CoroutineManager.StartCoroutine(DoDelayedCorrection(type, buffer, sendingTime));
|
||||
}
|
||||
|
||||
private IEnumerable<object> DoDelayedCorrection(ServerNetObject type, NetBuffer buffer, float sendingTime)
|
||||
{
|
||||
while (correctionTimer > 0.0f)
|
||||
{
|
||||
correctionTimer -= CoroutineManager.DeltaTime;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
((IServerSerializable)this).ClientRead(type, buffer, sendingTime);
|
||||
|
||||
correctionTimer = 0.0f;
|
||||
delayedCorrectionCoroutine = null;
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
public virtual XElement Save(XElement parentElement)
|
||||
{
|
||||
XElement componentElement = new XElement(name);
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
correctionTimer = CorrectionDelay;
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
|
||||
@@ -97,6 +98,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
correctionTimer = CorrectionDelay;
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
|
||||
@@ -114,6 +116,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
correctionTimer = CorrectionDelay;
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
|
||||
@@ -234,7 +237,7 @@ namespace Barotrauma.Items.Components
|
||||
msg.Write(IsActive);
|
||||
}
|
||||
|
||||
public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c)
|
||||
public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Client c)
|
||||
{
|
||||
float flowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
|
||||
bool isActive = msg.ReadBoolean();
|
||||
@@ -243,9 +246,12 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
FlowPercentage = flowPercentage;
|
||||
IsActive = isActive;
|
||||
|
||||
//notify all clients of the changed state
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
|
||||
public void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null)
|
||||
public void ServerWrite(Lidgren.Network.NetBuffer msg, Client c, object[] extraData = null)
|
||||
{
|
||||
//flowpercentage can only be adjusted at 10% intervals -> no need for more accuracy than this
|
||||
msg.WriteRangedInteger(-10, 10, (int)(flowPercentage / 10.0f));
|
||||
@@ -254,6 +260,12 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer msg, float sendingTime)
|
||||
{
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(5 + 1), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
FlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
|
||||
IsActive = msg.ReadBoolean();
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ namespace Barotrauma.Items.Components
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
correctionTimer = CorrectionDelay;
|
||||
}
|
||||
IsActive = box.Selected;
|
||||
|
||||
@@ -450,6 +451,12 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer msg, float sendingTime)
|
||||
{
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(1), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
IsActive = msg.ReadBoolean();
|
||||
isActiveTickBox.Selected = IsActive;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
class Reactor : Powered, IDrawableComponent, IServerSerializable, IClientSerializable
|
||||
{
|
||||
const float NetworkUpdateInterval = 3.0f;
|
||||
const float NetworkUpdateInterval = 0.5f;
|
||||
|
||||
//the rate at which the reactor is being run un
|
||||
//higher rates generate more power (and heat)
|
||||
@@ -553,16 +553,18 @@ namespace Barotrauma.Items.Components
|
||||
public void ClientWrite(NetBuffer msg, object[] extraData = null)
|
||||
{
|
||||
msg.Write(autoTemp);
|
||||
msg.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 8);
|
||||
msg.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 15);
|
||||
|
||||
msg.WriteRangedSingle(coolingRate, 0.0f, 100.0f, 8);
|
||||
msg.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8);
|
||||
|
||||
correctionTimer = CorrectionDelay;
|
||||
}
|
||||
|
||||
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c)
|
||||
{
|
||||
bool autoTemp = msg.ReadBoolean();
|
||||
float shutDownTemp = msg.ReadRangedSingle(0.0f, 10000.0f, 8);
|
||||
float shutDownTemp = msg.ReadRangedSingle(0.0f, 10000.0f, 15);
|
||||
float coolingRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
float fissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
|
||||
@@ -583,7 +585,7 @@ namespace Barotrauma.Items.Components
|
||||
msg.WriteRangedSingle(temperature, 0.0f, 10000.0f, 16);
|
||||
|
||||
msg.Write(autoTemp);
|
||||
msg.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 8);
|
||||
msg.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 15);
|
||||
|
||||
msg.WriteRangedSingle(coolingRate, 0.0f, 100.0f, 8);
|
||||
msg.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8);
|
||||
@@ -591,10 +593,16 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(16 + 1 + 15 + 8 + 8), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
Temperature = msg.ReadRangedSingle(0.0f, 10000.0f, 16);
|
||||
|
||||
AutoTemp = msg.ReadBoolean();
|
||||
ShutDownTemp = msg.ReadRangedSingle(0.0f, 10000.0f, 8);
|
||||
ShutDownTemp = msg.ReadRangedSingle(0.0f, 10000.0f, 15);
|
||||
|
||||
CoolingRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
FissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
|
||||
@@ -146,6 +146,7 @@ namespace Barotrauma.Items.Components
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
correctionTimer = CorrectionDelay;
|
||||
}
|
||||
else if (GameMain.Server != null)
|
||||
{
|
||||
@@ -597,6 +598,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer msg, float sendingTime)
|
||||
{
|
||||
long msgStartPos = msg.Position;
|
||||
|
||||
bool autoPilot = msg.ReadBoolean();
|
||||
Vector2 newTargetVelocity = targetVelocity;
|
||||
bool maintainPos = false;
|
||||
@@ -622,6 +625,14 @@ namespace Barotrauma.Items.Components
|
||||
newTargetVelocity = new Vector2(msg.ReadFloat(), msg.ReadFloat());
|
||||
}
|
||||
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
int msgLength = (int)(msg.Position - msgStartPos);
|
||||
msg.Position = msgStartPos;
|
||||
StartDelayedCorrection(type, msg.ExtractBits(msgLength), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPilot = autoPilot;
|
||||
|
||||
if (!AutoPilot)
|
||||
|
||||
@@ -100,9 +100,14 @@ namespace Barotrauma.Items.Components
|
||||
RechargeSpeed = rechargeSpeed - maxRechargeSpeed * 0.1f;
|
||||
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
correctionTimer = CorrectionDelay;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
@@ -113,9 +118,14 @@ namespace Barotrauma.Items.Components
|
||||
RechargeSpeed = rechargeSpeed + maxRechargeSpeed * 0.1f;
|
||||
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
correctionTimer = CorrectionDelay;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
@@ -269,7 +279,6 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ClientWrite(NetBuffer msg, object[] extraData)
|
||||
{
|
||||
DebugConsole.NewMessage("writing recharge speed " + (rechargeSpeed / MaxRechargeSpeed * 10), Color.White);
|
||||
msg.WriteRangedInteger(0, 10, (int)(rechargeSpeed / MaxRechargeSpeed * 10));
|
||||
}
|
||||
|
||||
@@ -277,8 +286,6 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
float newRechargeSpeed = msg.ReadRangedInteger(0,10) / 10.0f * maxRechargeSpeed;
|
||||
|
||||
DebugConsole.NewMessage("received recharge speed " + newRechargeSpeed, Color.White);
|
||||
|
||||
if (item.CanClientAccess(c))
|
||||
{
|
||||
RechargeSpeed = newRechargeSpeed;
|
||||
@@ -297,6 +304,12 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(4 + 8), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
RechargeSpeed = msg.ReadRangedInteger(0, 10) / 10.0f * maxRechargeSpeed;
|
||||
Charge = msg.ReadRangedSingle(0.0f, 1.0f, 8) * capacity;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
@@ -593,5 +594,19 @@ namespace Barotrauma
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a number of bits from the buffer and inserts them to a new NetBuffer instance
|
||||
/// </summary>
|
||||
public static NetBuffer ExtractBits(this NetBuffer originalBuffer, int numberOfBits)
|
||||
{
|
||||
var buffer = new NetBuffer();
|
||||
byte[] data = new byte[(int)Math.Ceiling(numberOfBits / (double)8)];
|
||||
|
||||
originalBuffer.ReadBits(data, 0, numberOfBits);
|
||||
buffer.Write(data);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user