From 9a36df0f524a4dba9309184ca7b82695c949995b Mon Sep 17 00:00:00 2001 From: Regalis Date: Tue, 11 Apr 2017 20:36:52 +0300 Subject: [PATCH] ItemComponent syncing fixes: - Relay and lightcomponent states are synced (otherwise clients won't be notified if the state is, for example, toggled by a signal from a button). - Clients don't play door sounds if a signal attempts to set the state to the same value as the predicted state, but DO play if a correction from the server changes the state from the predicted one. - Clients are notified if a reactor receives a shutdown signal. - Powercontainer updates are sent if the charge changes by 1%, not by 1 unit. --- Subsurface/Source/Items/Components/Door.cs | 7 ++-- .../Items/Components/Machines/Reactor.cs | 6 +++- .../Items/Components/Power/PowerContainer.cs | 2 +- .../Items/Components/Signal/LightComponent.cs | 17 +++++++++- .../Items/Components/Signal/RelayComponent.cs | 33 ++++++++++++++----- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/Subsurface/Source/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs index d47418319..30fc0135a 100644 --- a/Subsurface/Source/Items/Components/Door.cs +++ b/Subsurface/Source/Items/Components/Door.cs @@ -500,10 +500,8 @@ namespace Barotrauma.Items.Components public void SetState(bool open, bool isNetworkMessage, bool sendNetworkMessage = false) { - if (isStuck || isOpen == open) return; - if (GameMain.Client != null && !isNetworkMessage) { //clients can "predict" that the door opens/closes when a signal is received @@ -511,14 +509,15 @@ namespace Barotrauma.Items.Components //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 - PlaySound(ActionType.OnUse, item.WorldPosition); + if (open != predictedState) PlaySound(ActionType.OnUse, item.WorldPosition); predictedState = open; resetPredictionTimer = CorrectionDelay; + } else { - if (!isNetworkMessage) PlaySound(ActionType.OnUse, item.WorldPosition); + if (!isNetworkMessage || open != predictedState) PlaySound(ActionType.OnUse, item.WorldPosition); isOpen = open; } diff --git a/Subsurface/Source/Items/Components/Machines/Reactor.cs b/Subsurface/Source/Items/Components/Machines/Reactor.cs index d01c9de65..201336b66 100644 --- a/Subsurface/Source/Items/Components/Machines/Reactor.cs +++ b/Subsurface/Source/Items/Components/Machines/Reactor.cs @@ -545,7 +545,11 @@ namespace Barotrauma.Items.Components switch (connection.Name) { case "shutdown": - shutDownTemp = 0.0f; + if (shutDownTemp > 0.0f) + { + unsentChanges = true; + shutDownTemp = 0.0f; + } break; } } diff --git a/Subsurface/Source/Items/Components/Power/PowerContainer.cs b/Subsurface/Source/Items/Components/Power/PowerContainer.cs index 3334b2c7c..859f161e7 100644 --- a/Subsurface/Source/Items/Components/Power/PowerContainer.cs +++ b/Subsurface/Source/Items/Components/Power/PowerContainer.cs @@ -56,7 +56,7 @@ namespace Barotrauma.Items.Components if (!MathUtils.IsValid(value)) return; charge = MathHelper.Clamp(value, 0.0f, capacity); - if (Math.Abs(charge - lastSentCharge) > 1.0f) + if (Math.Abs(charge - lastSentCharge) / capacity > 1.0f) { if (GameMain.Server != null) item.CreateServerEvent(this); lastSentCharge = charge; diff --git a/Subsurface/Source/Items/Components/Signal/LightComponent.cs b/Subsurface/Source/Items/Components/Signal/LightComponent.cs index bb51c0353..7bfa10d7e 100644 --- a/Subsurface/Source/Items/Components/Signal/LightComponent.cs +++ b/Subsurface/Source/Items/Components/Signal/LightComponent.cs @@ -2,10 +2,12 @@ using Barotrauma.Lights; using System; using System.Xml.Linq; +using Barotrauma.Networking; +using Lidgren.Network; namespace Barotrauma.Items.Components { - class LightComponent : Powered, IDrawableComponent + class LightComponent : Powered, IServerSerializable, IDrawableComponent { private Color lightColor; @@ -47,7 +49,10 @@ namespace Barotrauma.Items.Components get { return IsActive; } set { + if (IsActive == value) return; + IsActive = value; + if (GameMain.Server != null) item.CreateServerEvent(this); } } @@ -205,5 +210,15 @@ namespace Barotrauma.Items.Components break; } } + + public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null) + { + msg.Write(IsOn); + } + + public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) + { + IsOn = msg.ReadBoolean(); + } } } diff --git a/Subsurface/Source/Items/Components/Signal/RelayComponent.cs b/Subsurface/Source/Items/Components/Signal/RelayComponent.cs index 649441f76..a019d980f 100644 --- a/Subsurface/Source/Items/Components/Signal/RelayComponent.cs +++ b/Subsurface/Source/Items/Components/Signal/RelayComponent.cs @@ -1,14 +1,14 @@ -using System; +using Barotrauma.Networking; +using Lidgren.Network; +using System; using System.Xml.Linq; namespace Barotrauma.Items.Components { - class RelayComponent : PowerTransfer + class RelayComponent : PowerTransfer, IServerSerializable { private float maxPower; - - private float lastReceivedMessage; - + [Editable, HasDefaultValue(1000.0f, true)] public float MaxPower { @@ -75,19 +75,34 @@ namespace Barotrauma.Items.Components } else if (connection.Name == "toggle") { - SetState(!IsOn); + SetState(!IsOn, false); } else if (connection.Name == "set_state") { - SetState(signal != "0"); + SetState(signal != "0", false); } } - public void SetState(bool on) + public void SetState(bool on, bool isNetworkMessage) { - //if (GameMain.Client != null && !isNetworkMessage) return; + if (GameMain.Client != null && !isNetworkMessage) return; + + if (on != IsOn && GameMain.Server != null) + { + item.CreateServerEvent(this); + } IsOn = on; } + + public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null) + { + msg.Write(isOn); + } + + public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) + { + SetState(msg.ReadBoolean(), true); + } } }