Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/RelayComponent.cs
T
Joonas Rikkonen bb987676ca Improved PowerTransfer logic. The PowerTransfer components cache all the connections that are connected to the item (directly or via another item) and only recalculate them when changes are done to the wiring. Signals received by the PowerTransfer component are relayed directly to the recipients instead of stepping through all the wires and junction boxes in between.
Fixes stack overflow exceptions caused by signals looping between junction boxes and improves performance because the layout of the power grid doesn't have to be calculated every frame and the wire connections don't have to be rechecked when sending a signal. Closes #222
2018-01-01 14:59:40 +02:00

109 lines
2.9 KiB
C#

using Barotrauma.Networking;
using Lidgren.Network;
using System;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
class RelayComponent : PowerTransfer, IServerSerializable
{
private float maxPower;
private bool isOn;
[Editable, Serialize(1000.0f, true)]
public float MaxPower
{
get { return maxPower; }
set
{
maxPower = Math.Max(0.0f, value);
}
}
[Editable, Serialize(false, true)]
public bool IsOn
{
get
{
return isOn;
}
set
{
isOn = value;
CanTransfer = value;
if (!isOn)
{
currPowerConsumption = 0.0f;
}
}
}
public RelayComponent(Item item, XElement element)
: base (item, element)
{
IsActive = true;
}
public override void Update(float deltaTime, Camera cam)
{
base.Update(deltaTime, cam);
item.SendSignal(0, IsOn ? "1" : "0", "state_out", null);
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
{
if (connection.IsPower && connection.Name.Contains("_out")) return;
if (item.Condition <= 0.0f) return;
if (power > maxPower) item.Condition = 0.0f;
if (connection.Name.Contains("_in"))
{
if (!IsOn) return;
string outConnection = connection.Name.Contains("power_in") ? "power_out" : "signal_out";
int connectionNumber = -1;
int.TryParse(connection.Name.Substring(connection.Name.Length - 1, 1), out connectionNumber);
if (connectionNumber > 0) outConnection += connectionNumber;
item.SendSignal(stepsTaken, signal, outConnection, sender, power);
}
else if (connection.Name == "toggle")
{
SetState(!IsOn, false);
}
else if (connection.Name == "set_state")
{
SetState(signal != "0", false);
}
}
public void SetState(bool on, bool isNetworkMessage)
{
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);
}
}
}