v0.13.0.11

This commit is contained in:
Joonas Rikkonen
2021-04-22 17:33:08 +03:00
parent 0697d7fc64
commit 8bb31f2893
391 changed files with 17271 additions and 5949 deletions
@@ -4,7 +4,7 @@ using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
class AndComponent : ItemComponent
{
{
protected string output, falseOutput;
//an array to keep track of how long ago a non-zero signal was received on both inputs
@@ -27,14 +27,41 @@ namespace Barotrauma.Items.Components
public string Output
{
get { return output; }
set { output = value; }
set
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
}
}
[InGameEditable, Serialize("", true, description: "The signal sent when the condition is met (if empty, no signal is sent).", alwaysUseInstanceValues: true)]
public string FalseOutput
{
get { return falseOutput; }
set { falseOutput = value; }
set
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}
}
}
private int maxOutputLength;
[Editable, Serialize(200, false, description: "The maximum length of the output strings. Warning: Large values can lead to large memory usage or networking issues.")]
public int MaxOutputLength
{
get { return maxOutputLength; }
set
{
maxOutputLength = Math.Max(value, 0);
}
}
public AndComponent(Item item, XElement element)
@@ -56,23 +83,23 @@ namespace Barotrauma.Items.Components
string signalOut = sendOutput ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) return;
item.SendSignal(0, signalOut, "signal_out", null);
item.SendSignal(signalOut, "signal_out");
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "signal_in1":
if (signal == "0") return;
if (signal.value == "0") return;
timeSinceReceived[0] = 0.0f;
break;
case "signal_in2":
if (signal == "0") return;
if (signal.value == "0") return;
timeSinceReceived[1] = 0.0f;
break;
case "set_output":
output = signal;
output = signal.value;
break;
}
}
@@ -67,23 +67,23 @@ namespace Barotrauma.Items.Components
float output = Calculate(receivedSignal[0], receivedSignal[1]);
if (MathUtils.IsValid(output))
{
item.SendSignal(0, MathHelper.Clamp(output, ClampMin, ClampMax).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
item.SendSignal(MathHelper.Clamp(output, ClampMin, ClampMax).ToString("G", CultureInfo.InvariantCulture), "signal_out");
}
}
protected abstract float Calculate(float signal1, float signal2);
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "signal_in1":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
timeSinceReceived[0] = 0.0f;
IsActive = true;
break;
case "signal_in2":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
timeSinceReceived[1] = 0.0f;
IsActive = true;
break;
@@ -1,6 +1,7 @@
using System;
using System.Globalization;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
namespace Barotrauma.Items.Components
{
@@ -10,6 +11,9 @@ namespace Barotrauma.Items.Components
private string output = "0,0,0,0";
[InGameEditable, Serialize(false, true, description: "When enabled makes the component translate the signal from HSV into RGB where red is the hue between 0 and 360, green is the saturation between 0 and 1 and blue is the value between 0 and 1.", alwaysUseInstanceValues: true)]
public bool UseHSV { get; set; }
public ColorComponent(Item item, XElement element)
: base(item, element)
{
@@ -19,35 +23,48 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
item.SendSignal(0, output, "signal_out", null);
item.SendSignal(output, "signal_out");
}
private void UpdateOutput()
{
output = receivedSignal[0].ToString("G", CultureInfo.InvariantCulture);
output += "," + receivedSignal[1].ToString("G", CultureInfo.InvariantCulture);
output += "," + receivedSignal[2].ToString("G", CultureInfo.InvariantCulture);
output += "," + receivedSignal[3].ToString("G", CultureInfo.InvariantCulture);
float signalR = receivedSignal[0],
signalG = receivedSignal[1],
signalB = receivedSignal[2],
signalA = receivedSignal[3];
if (UseHSV)
{
Color hsvColor = ToolBox.HSVToRGB(signalR, signalG, signalB);
signalR = hsvColor.R / (float) byte.MaxValue;
signalG = hsvColor.G / (float) byte.MaxValue;
signalB = hsvColor.B / (float) byte.MaxValue;
}
output = signalR.ToString("G", CultureInfo.InvariantCulture);
output += "," + signalG.ToString("G", CultureInfo.InvariantCulture);
output += "," + signalB.ToString("G", CultureInfo.InvariantCulture);
output += "," + signalA.ToString("G", CultureInfo.InvariantCulture);
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "signal_r":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
UpdateOutput();
break;
case "signal_g":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
UpdateOutput();
break;
case "signal_b":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[2]);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[2]);
UpdateOutput();
break;
case "signal_a":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[3]);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[3]);
UpdateOutput();
break;
}
@@ -1,5 +1,4 @@
using Microsoft.Xna.Framework;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
@@ -11,7 +10,10 @@ namespace Barotrauma.Items.Components
//how many wires can be linked to connectors by default
private const int DefaultMaxWires = 5;
//how many wires can be linked to this connection
//how many wires a player can link to this connection
public readonly int MaxPlayerConnectableWires = 5;
//how many wires can be linked to this connection in total
public readonly int MaxWires = 5;
public readonly string Name;
@@ -81,6 +83,9 @@ namespace Barotrauma.Items.Components
item = connectionPanel.Item;
MaxWires = element.GetAttributeInt("maxwires", DefaultMaxWires);
MaxWires = Math.Max(element.Elements().Count(e => e.Name.ToString().Equals("link", StringComparison.OrdinalIgnoreCase)), MaxWires);
MaxPlayerConnectableWires = element.GetAttributeInt("maxplayerconnectablewires", MaxWires);
wires = new Wire[MaxWires];
IsOutput = element.Name.ToString() == "output";
@@ -149,19 +154,15 @@ namespace Barotrauma.Items.Components
int index = -1;
for (int i = 0; i < MaxWires; i++)
{
if (wireId[i] < 1) index = i;
if (wireId[i] < 1) { index = i; }
}
if (index == -1) break;
if (index == -1) { break; }
int id = subElement.GetAttributeInt("w", 0);
if (id < 0)
{
id = 0;
}
if (id < 0) { id = 0; }
wireId[index] = idRemap.GetOffsetId(id);
break;
case "statuseffect":
Effects.Add(StatusEffect.Load(subElement, item.Name + ", connection " + Name));
break;
@@ -251,8 +252,8 @@ namespace Barotrauma.Items.Components
}
}
}
public void SendSignal(int stepsTaken, string signal, Item source, Character sender, float power, float signalStrength = 1.0f)
public void SendSignal(Signal signal)
{
for (int i = 0; i < MaxWires; i++)
{
@@ -260,22 +261,27 @@ namespace Barotrauma.Items.Components
Connection recipient = wires[i].OtherConnection(this);
if (recipient == null) { continue; }
if (recipient.item == this.item || recipient.item == source) { continue; }
if (recipient.item == this.item || signal.source?.LastSentSignalRecipients.LastOrDefault() == recipient) { continue; }
source?.LastSentSignalRecipients.Add(recipient.item);
signal.source?.LastSentSignalRecipients.Add(recipient);
Connection connection = recipient;
foreach (ItemComponent ic in recipient.item.Components)
{
ic.ReceiveSignal(stepsTaken, signal, recipient, source, sender, power, signalStrength);
ic.ReceiveSignal(signal, connection);
}
foreach (StatusEffect effect in recipient.Effects)
if (signal.value != "0")
{
recipient.Item.ApplyStatusEffect(effect, ActionType.OnUse, (float)Timing.Step);
foreach (StatusEffect effect in recipient.Effects)
{
recipient.Item.ApplyStatusEffect(effect, ActionType.OnUse, (float)Timing.Step);
}
}
}
}
public void SendPowerProbeSignal(Item source, float power)
{
for (int i = 0; i < MaxWires; i++)
@@ -65,10 +65,10 @@ namespace Barotrauma.Items.Components
}
base.IsActive = true;
InitProjSpecific(element);
InitProjSpecific();
}
partial void InitProjSpecific(XElement element);
partial void InitProjSpecific();
private bool linksInitialized;
public override void OnMapLoaded()
@@ -352,7 +352,7 @@ namespace Barotrauma.Items.Components
#endif
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1)
public override void ReceiveSignal(Signal signal, Connection connection)
{
//do nothing
}
@@ -16,13 +16,18 @@ namespace Barotrauma.Items.Components
[Serialize("", false, translationTextTag: "Label.", description: "The text displayed on this button/tickbox."), Editable]
public string Label { get; set; }
[Serialize("1", false, description: "The signal sent out when this button is pressed or this tickbox checked."), Editable]
public string Signal { get; set; }
public string PropertyName { get; }
public bool TargetOnlyParentProperty { get; }
public int NumberInputMin { get; }
public int NumberInputMax { get; }
public int MaxTextLength { get; }
public const int DefaultNumberInputMin = 0, DefaultNumberInputMax = 99;
public bool IsIntegerInput { get; }
public bool HasPropertyName { get; }
@@ -46,7 +51,7 @@ namespace Barotrauma.Items.Components
TargetOnlyParentProperty = element.GetAttributeBool("targetonlyparentproperty", false);
NumberInputMin = element.GetAttributeInt("min", DefaultNumberInputMin);
NumberInputMax = element.GetAttributeInt("max", DefaultNumberInputMax);
MaxTextLength = element.GetAttributeInt("maxtextlength", int.MaxValue);
HasPropertyName = !string.IsNullOrEmpty(PropertyName);
IsIntegerInput = HasPropertyName && element.Name.ToString().ToLowerInvariant() == "integerinput";
@@ -244,7 +249,7 @@ namespace Barotrauma.Items.Components
if (btnElement == null) return;
if (btnElement.Connection != null)
{
item.SendSignal(0, btnElement.Signal, btnElement.Connection, sender: null, source: item);
item.SendSignal(new Signal(btnElement.Signal, 0, null, item), btnElement.Connection);
}
foreach (StatusEffect effect in btnElement.StatusEffects)
{
@@ -303,7 +308,7 @@ namespace Barotrauma.Items.Components
//TODO: allow changing output when a tickbox is not selected
if (!string.IsNullOrEmpty(ciElement.Signal) && ciElement.Connection != null)
{
item.SendSignal(0, ciElement.State ? ciElement.Signal : "0", ciElement.Connection, sender: null, source: item);
item.SendSignal(new Signal(ciElement.State ? ciElement.Signal : "0", source: item), ciElement.Connection);
}
foreach (StatusEffect effect in ciElement.StatusEffects)
@@ -7,17 +7,15 @@ namespace Barotrauma.Items.Components
{
class DelayedSignal
{
public readonly string Signal;
public readonly float SignalStrength;
public readonly Signal Signal;
//in number of frames
public int SendTimer;
//in number of frames
public int SendDuration;
public DelayedSignal(string signal, float signalStrength, int sendTimer)
public DelayedSignal(Signal signal, int sendTimer)
{
Signal = signal;
SignalStrength = signalStrength;
SendTimer = sendTimer;
}
}
@@ -75,34 +73,34 @@ namespace Barotrauma.Items.Components
{
var signalOut = signalQueue.Peek();
signalOut.SendDuration -= 1;
item.SendSignal(0, signalOut.Signal, "signal_out", null, signalStrength: signalOut.SignalStrength);
item.SendSignal(new Signal(signalOut.Signal.value, strength: signalOut.Signal.strength), "signal_out");
if (signalOut.SendDuration <= 0) { signalQueue.Dequeue(); } else { break; }
}
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "signal_in":
if (signalQueue.Count >= signalQueueSize) { return; }
if (ResetWhenSignalReceived) { prevQueuedSignal = null; signalQueue.Clear(); }
if (ResetWhenDifferentSignalReceived && signalQueue.Count > 0 && signalQueue.Peek().Signal != signal)
if (ResetWhenDifferentSignalReceived && signalQueue.Count > 0 && signalQueue.Peek().Signal.value != signal.value)
{
prevQueuedSignal = null;
signalQueue.Clear();
}
if (prevQueuedSignal != null &&
prevQueuedSignal.Signal == signal &&
MathUtils.NearlyEqual(prevQueuedSignal.SignalStrength, signalStrength) &&
prevQueuedSignal.Signal.value == signal.value &&
MathUtils.NearlyEqual(prevQueuedSignal.Signal.strength, signal.strength) &&
((prevQueuedSignal.SendTimer + prevQueuedSignal.SendDuration == delayTicks) || (prevQueuedSignal.SendTimer <= 0 && prevQueuedSignal.SendDuration > 0)))
{
prevQueuedSignal.SendDuration += 1;
return;
}
prevQueuedSignal = new DelayedSignal(signal, signalStrength, delayTicks)
prevQueuedSignal = new DelayedSignal(signal, delayTicks)
{
SendDuration = 1
};
@@ -15,18 +15,45 @@ namespace Barotrauma.Items.Components
//the output is sent if both inputs have received a signal within the timeframe
protected float timeFrame;
[InGameEditable, Serialize("1", true, description: "The signal this item outputs when the condition is met.", alwaysUseInstanceValues: true)]
[InGameEditable, Serialize("1", true, description: "The signal sent when the condition is met.", alwaysUseInstanceValues: true)]
public string Output
{
get { return output; }
set { output = value; }
set
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
}
}
[InGameEditable, Serialize("", true, description: "The signal this item outputs when the condition is not met.", alwaysUseInstanceValues: true)]
[InGameEditable, Serialize("", true, description: "The signal sent when the condition is met (if empty, no signal is sent).", alwaysUseInstanceValues: true)]
public string FalseOutput
{
get { return falseOutput; }
set { falseOutput = value; }
set
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}
}
}
private int maxOutputLength;
[Editable, Serialize(200, false, description: "The maximum length of the output strings. Warning: Large values can lead to large memory usage or networking issues.")]
public int MaxOutputLength
{
get { return maxOutputLength; }
set
{
maxOutputLength = Math.Max(value, 0);
}
}
[InGameEditable(DecimalCount = 2), Serialize(0.0f, true, description: "The maximum amount of time between the received signals. If set to 0, the signals must be received at the same time.", alwaysUseInstanceValues: true)]
@@ -61,20 +88,20 @@ namespace Barotrauma.Items.Components
string signalOut = receivedSignal[0] == receivedSignal[1] ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) return;
item.SendSignal(0, signalOut, "signal_out", null);
item.SendSignal(signalOut, "signal_out");
}
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "signal_in1":
receivedSignal[0] = signal;
receivedSignal[0] = signal.value;
timeSinceReceived[0] = 0.0f;
break;
case "signal_in2":
receivedSignal[1] = signal;
receivedSignal[1] = signal.value;
timeSinceReceived[1] = 0.0f;
break;
}
@@ -25,17 +25,18 @@ namespace Barotrauma.Items.Components
IsActive = true;
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "set_exponent":
case "exponent":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out exponent);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out exponent);
break;
case "signal_in":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out float value);
item.SendSignal(0, MathUtils.Pow(value, Exponent).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float value);
signal.value = MathUtils.Pow(value, Exponent).ToString("G", CultureInfo.InvariantCulture);
item.SendSignal(signal, "signal_out");
break;
}
}
@@ -28,20 +28,20 @@ namespace Barotrauma.Items.Components
IsActive = true;
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1)
public override void ReceiveSignal(Signal signal, Connection connection)
{
if (connection.Name != "signal_in") return;
if (!float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out float value)) return;
if (connection.Name != "signal_in") { return; }
if (!float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float value)) { return; }
switch (Function)
{
case FunctionType.Round:
item.SendSignal(0, Math.Round(value).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = MathF.Round(value);
break;
case FunctionType.Ceil:
item.SendSignal(0, Math.Ceiling(value).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = MathF.Ceiling(value);
break;
case FunctionType.Floor:
item.SendSignal(0, Math.Floor(value).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = MathF.Floor(value);
break;
case FunctionType.Factorial:
int intVal = (int)Math.Min(value, 20);
@@ -50,20 +50,24 @@ namespace Barotrauma.Items.Components
{
factorial *= (ulong)i;
}
item.SendSignal(0, factorial.ToString(), "signal_out", null);
value = factorial;
break;
case FunctionType.AbsoluteValue:
item.SendSignal(0, Math.Abs(value).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = MathF.Abs(value);
break;
case FunctionType.SquareRoot:
if (value > 0)
if (value < 0)
{
item.SendSignal(0, Math.Sqrt(value).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
return;
}
value = MathF.Sqrt(value);
break;
default:
throw new NotImplementedException($"Function {Function} has not been implemented.");
}
signal.value = value.ToString("G", CultureInfo.InvariantCulture);
item.SendSignal(signal, "signal_out");
}
}
}
@@ -27,13 +27,13 @@ namespace Barotrauma.Items.Components
string signalOut = val1 > val2 ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) return;
item.SendSignal(0, signalOut, "signal_out", null);
item.SendSignal(signalOut, "signal_out");
}
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
base.ReceiveSignal(stepsTaken, signal, connection, source, sender, power, signalStrength);
base.ReceiveSignal(signal, connection);
float.TryParse(receivedSignal[0], NumberStyles.Float, CultureInfo.InvariantCulture, out val1);
float.TryParse(receivedSignal[1], NumberStyles.Float, CultureInfo.InvariantCulture, out val2);
}
@@ -308,12 +308,12 @@ namespace Barotrauma.Items.Components
partial void OnStateChanged();
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "toggle":
if (signal != "0")
if (signal.value != "0")
{
if (!IgnoreContinuousToggle || lastToggleSignalTime < Timing.TotalTime - 0.1)
{
@@ -323,10 +323,10 @@ namespace Barotrauma.Items.Components
}
break;
case "set_state":
IsOn = signal != "0";
IsOn = signal.value != "0";
break;
case "set_color":
LightColor = XMLExtensions.ParseColor(signal, false);
LightColor = XMLExtensions.ParseColor(signal.value, false);
break;
}
}
@@ -1,13 +1,11 @@
using Barotrauma.Networking;
using System;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
partial class MemoryComponent : ItemComponent, IServerSerializable
{
const int MaxValueLength = ChatMessage.MaxLength;
private string value;
[InGameEditable, Serialize("", true, description: "The currently stored signal the item outputs.", alwaysUseInstanceValues: true)]
@@ -17,10 +15,25 @@ namespace Barotrauma.Items.Components
set
{
if (value == null) { return; }
this.value = value.Length <= MaxValueLength ? value : value.Substring(0, MaxValueLength);
this.value = value;
if (this.value.Length > MaxValueLength && (item.Submarine == null || !item.Submarine.Loading))
{
this.value = this.value.Substring(0, MaxValueLength);
}
}
}
private int maxValueLength;
[Editable, Serialize(200, false, description: "The maximum length of the stored value. Warning: Large values can lead to large memory usage or networking issues.")]
public int MaxValueLength
{
get { return maxValueLength; }
set
{
maxValueLength = Math.Max(value, 0);
}
}
protected bool writeable = true;
public MemoryComponent(Item item, XElement element)
@@ -31,26 +44,29 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
item.SendSignal(0, Value, "signal_out", null);
item.SendSignal(Value, "signal_out");
}
partial void OnStateChanged();
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "signal_in":
if (writeable)
{
if (Value == signal) { return; }
Value = signal;
OnStateChanged();
string prevValue = Value;
Value = signal.value;
if (Value != prevValue)
{
OnStateChanged();
}
}
break;
case "signal_store":
case "lock_state":
writeable = signal == "1";
writeable = signal.value == "1";
break;
}
}
@@ -21,18 +21,19 @@ namespace Barotrauma.Items.Components
IsActive = true;
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "set_modulus":
case "modulus":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out float newModulus);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float newModulus);
Modulus = newModulus;
break;
case "signal_in":
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out float value);
item.SendSignal(0, (value % modulus).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float value);
signal.value = (value % modulus).ToString("G", CultureInfo.InvariantCulture);
item.SendSignal(signal, "signal_out");
break;
}
@@ -74,11 +74,48 @@ namespace Barotrauma.Items.Components
}
}
private string output;
[InGameEditable, Serialize("1", true, description: "The signal the item outputs when it has detected movement.", alwaysUseInstanceValues: true)]
public string Output { get; set; }
public string Output
{
get { return output; }
set
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
}
}
private string falseOutput;
[InGameEditable, Serialize("", true, description: "The signal the item outputs when it has not detected movement.", alwaysUseInstanceValues: true)]
public string FalseOutput { get; set; }
public string FalseOutput
{
get { return falseOutput; }
set
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}
}
}
private int maxOutputLength;
[Editable, Serialize(200, false, description: "The maximum length of the output strings. Warning: Large values can lead to large memory usage or networking issues.")]
public int MaxOutputLength
{
get { return maxOutputLength; }
set
{
maxOutputLength = Math.Max(value, 0);
}
}
[Editable(DecimalCount = 3), Serialize(0.01f, true, description: "How fast the objects within the detector's range have to be moving (in m/s).", alwaysUseInstanceValues: true)]
public float MinimumVelocity
@@ -113,7 +150,7 @@ namespace Barotrauma.Items.Components
{
string signalOut = MotionDetected ? Output : FalseOutput;
if (!string.IsNullOrEmpty(signalOut)) item.SendSignal(1, signalOut, "state_out", null);
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(new Signal(signalOut, 1), "state_out"); }
updateTimer -= deltaTime;
if (updateTimer > 0.0f) return;
@@ -138,6 +175,10 @@ namespace Barotrauma.Items.Components
{
if (IgnoreDead && c.IsDead) { continue; }
//ignore characters that have spawned a second or less ago
//makes it possible to detect when a spawned character moves without triggering the detector immediately as the ragdoll spawns and drops to the ground
if (c.SpawnTime > Timing.TotalTime - 1.0) { continue; }
switch (Target)
{
case TargetType.Human:
@@ -24,15 +24,18 @@ namespace Barotrauma.Items.Components
base.Update(deltaTime, cam);
if (!signalReceived)
{
item.SendSignal(0, "1", "signal_out", null, 0.0f);
item.SendSignal("1", "signal_out");
}
signalReceived = false;
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
if (connection.Name != "signal_in") { return; }
item.SendSignal(stepsTaken, signal == "0" || signal == string.Empty ? "1" : "0", "signal_out", sender, 0.0f, source, signalStrength);
signal.value = signal.value == "0" || string.IsNullOrEmpty(signal.value) ? "1" : "0";
signal.power = 0.0f;
item.SendSignal(signal, "signal_out");
signalReceived = true;
}
}
@@ -22,7 +22,7 @@ namespace Barotrauma.Items.Components
string signalOut = sendOutput ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) return;
item.SendSignal(0, signalOut, "signal_out", null);
item.SendSignal(signalOut, "signal_out");
}
}
}
@@ -59,29 +59,29 @@ namespace Barotrauma.Items.Components
float pulseInterval = 1.0f / frequency;
while (phase >= pulseInterval)
{
item.SendSignal(0, "1", "signal_out", null);
item.SendSignal("1", "signal_out");
phase -= pulseInterval;
}
break;
case WaveType.Square:
phase = (phase + deltaTime * frequency) % 1.0f;
item.SendSignal(0, phase < 0.5f ? "0" : "1", "signal_out", null);
item.SendSignal(phase < 0.5f ? "0" : "1", "signal_out");
break;
case WaveType.Sine:
phase = (phase + deltaTime * frequency) % 1.0f;
item.SendSignal(0, Math.Sin(phase * MathHelper.TwoPi).ToString(CultureInfo.InvariantCulture), "signal_out", null);
item.SendSignal(Math.Sin(phase * MathHelper.TwoPi).ToString(CultureInfo.InvariantCulture), "signal_out");
break;
}
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "set_frequency":
case "frequency_in":
float newFrequency;
if (float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out newFrequency))
if (float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out newFrequency))
{
Frequency = newFrequency;
}
@@ -90,7 +90,7 @@ namespace Barotrauma.Items.Components
case "set_outputtype":
case "set_wavetype":
WaveType newOutputType;
if (Enum.TryParse(signal, out newOutputType))
if (Enum.TryParse(signal.value, out newOutputType))
{
OutputType = newOutputType;
}
@@ -14,7 +14,7 @@ namespace Barotrauma.Items.Components
{
if (item.CurrentHull == null) return;
item.SendSignal(0, ((int)item.CurrentHull.OxygenPercentage).ToString(), "signal_out", null);
item.SendSignal(((int)item.CurrentHull.OxygenPercentage).ToString(), "signal_out");
}
}
@@ -1,4 +1,5 @@
using System.Text.RegularExpressions;
using System;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
@@ -17,8 +18,22 @@ namespace Barotrauma.Items.Components
private bool nonContinuousOutputSent;
private string output;
[InGameEditable, Serialize("1", true, description: "The signal this item outputs when the received signal matches the regular expression.", alwaysUseInstanceValues: true)]
public string Output { get; set; }
public string Output
{
get { return output; }
set
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
}
}
[InGameEditable, Serialize(false, true, description: "Should the component output a value of a capture group instead of a constant signal.", alwaysUseInstanceValues: true)]
public bool UseCaptureGroup { get; set; }
@@ -46,12 +61,23 @@ namespace Barotrauma.Items.Components
catch
{
item.SendSignal(0, "ERROR", "signal_out", null);
item.SendSignal("ERROR", "signal_out");
return;
}
}
}
private int maxOutputLength;
[Editable, Serialize(200, false, description: "The maximum length of the output string. Warning: Large values can lead to large memory usage or networking issues.")]
public int MaxOutputLength
{
get { return maxOutputLength; }
set
{
maxOutputLength = Math.Max(value, 0);
}
}
public RegExFindComponent(Item item, XElement element)
: base(item, element)
{
@@ -74,7 +100,7 @@ namespace Barotrauma.Items.Components
}
catch
{
item.SendSignal(0, "ERROR", "signal_out", null);
item.SendSignal("ERROR", "signal_out");
previousResult = false;
return;
}
@@ -106,25 +132,25 @@ namespace Barotrauma.Items.Components
if (ContinuousOutput)
{
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(0, signalOut, "signal_out", null); }
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(signalOut, "signal_out"); }
}
else if (!nonContinuousOutputSent)
{
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(0, signalOut, "signal_out", null); }
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(signalOut, "signal_out"); }
nonContinuousOutputSent = true;
}
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "signal_in":
receivedSignal = signal;
receivedSignal = signal.value;
nonContinuousOutputSent = false;
break;
case "set_output":
Output = signal;
Output = signal.value;
break;
}
}
@@ -86,7 +86,7 @@ namespace Barotrauma.Items.Components
{
RefreshConnections();
item.SendSignal(0, IsOn ? "1" : "0", "state_out", null);
item.SendSignal(IsOn ? "1" : "0", "state_out");
if (!CanTransfer) { Voltage = 0.0f; return; }
@@ -169,23 +169,23 @@ namespace Barotrauma.Items.Components
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
if (item.Condition <= 0.0f || connection.IsPower) { return; }
if (connectionPairs.TryGetValue(connection.Name, out string outConnection))
{
if (!IsOn) { return; }
item.SendSignal(stepsTaken, signal, outConnection, sender, power, source, signalStrength);
item.SendSignal(signal, outConnection);
}
else if (connection.Name == "toggle")
{
if (signal == "0") { return; }
if (signal.value == "0") { return; }
SetState(!IsOn, false);
}
else if (connection.Name == "set_state")
{
SetState(signal != "0", false);
SetState(signal.value != "0", false);
}
}
@@ -0,0 +1,23 @@
namespace Barotrauma.Items.Components
{
public struct Signal
{
internal string value;
internal int stepsTaken;
internal Character sender;
internal Item source;
internal float power;
internal float strength;
internal Signal(string value, int stepsTaken = 0, Character sender = null,
Item source = null, float power = 0.0f, float strength = 1.0f)
{
this.value = value;
this.stepsTaken = stepsTaken;
this.sender = sender;
this.source = source;
this.power = power;
this.strength = strength;
}
}
}
@@ -1,38 +1,76 @@
using System.Xml.Linq;
using System;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
class SignalCheckComponent : ItemComponent
{
private string output;
[InGameEditable, Serialize("1", true, description: "The signal this item outputs when the received signal matches the target signal.", alwaysUseInstanceValues: true)]
public string Output { get; set; }
public string Output
{
get { return output; }
set
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
}
}
private string falseOutput;
[InGameEditable, Serialize("0", true, description: "The signal this item outputs when the received signal does not match the target signal.", alwaysUseInstanceValues: true)]
public string FalseOutput { get; set; }
public string FalseOutput
{
get { return falseOutput; }
set
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}
}
}
[InGameEditable, Serialize("", true, description: "The value to compare the received signals against.", alwaysUseInstanceValues: true)]
public string TargetSignal { get; set; }
private int maxOutputLength;
[Editable, Serialize(200, false, description: "The maximum length of the output strings. Warning: Large values can lead to large memory usage or networking issues.")]
public int MaxOutputLength
{
get { return maxOutputLength; }
set
{
maxOutputLength = Math.Max(value, 0);
}
}
public SignalCheckComponent(Item item, XElement element)
: base(item, element)
{
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "signal_in":
string signalOut = (signal == TargetSignal) ? Output : FalseOutput;
if (string.IsNullOrWhiteSpace(signalOut)) return;
item.SendSignal(stepsTaken, signalOut, "signal_out", sender, signalStrength);
string signalOut = (signal.value == TargetSignal) ? Output : FalseOutput;
if (string.IsNullOrEmpty(signalOut)) { return; }
signal.value = signalOut;
item.SendSignal(signal, "signal_out");
break;
case "set_output":
Output = signal;
Output = signal.value;
break;
case "set_targetsignal":
TargetSignal = signal;
TargetSignal = signal.value;
break;
}
}
@@ -1,4 +1,5 @@
using System.Xml.Linq;
using System;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
@@ -9,11 +10,48 @@ namespace Barotrauma.Items.Components
private bool fireInRange;
[InGameEditable, Serialize("1", true, description: "The signal the item outputs when it has detected movement.", alwaysUseInstanceValues: true)]
public string Output { get; set; }
private string output;
[InGameEditable, Serialize("1", true, description: "The signal the item outputs when it has detected a fire.", alwaysUseInstanceValues: true)]
public string Output
{
get { return output; }
set
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
}
}
[InGameEditable, Serialize("0", true, description: "The signal the item outputs when it has not detected movement.", alwaysUseInstanceValues: true)]
public string FalseOutput { get; set; }
private string falseOutput;
[InGameEditable, Serialize("0", true, description: "The signal the item outputs when it has not detected a fire.", alwaysUseInstanceValues: true)]
public string FalseOutput
{
get { return falseOutput; }
set
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}
}
}
private int maxOutputLength;
[Editable, Serialize(200, false, description: "The maximum length of the output strings. Warning: Large values can lead to large memory usage or networking issues.")]
public int MaxOutputLength
{
get { return maxOutputLength; }
set
{
maxOutputLength = Math.Max(value, 0);
}
}
public SmokeDetector(Item item, XElement element)
: base(item, element)
@@ -45,7 +83,8 @@ namespace Barotrauma.Items.Components
fireInRange = IsFireInRange();
fireCheckTimer = FireCheckInterval;
}
item.SendSignal(0, fireInRange ? Output : FalseOutput, "signal_out", null);
string signalOut = fireInRange ? Output : FalseOutput;
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(signalOut, "signal_out"); }
}
}
}
@@ -37,32 +37,35 @@ namespace Barotrauma.Items.Components
sealed public override void Update(float deltaTime, Camera cam)
{
bool deactivate = true;
bool earlyReturn = false;
for (int i = 0; i < timeSinceReceived.Length; i++)
{
if (timeSinceReceived[i] > timeFrame)
{
IsActive = false;
return;
}
deactivate &= timeSinceReceived[i] > timeFrame;
earlyReturn |= timeSinceReceived[i] > timeFrame;
timeSinceReceived[i] += deltaTime;
}
// only stop Update() if both signals timed-out. if IsActive == false, then the component stops updating.
IsActive = !deactivate;
// early return if either of the signal timed-out
if (earlyReturn) { return; }
string output = Calculate(receivedSignal[0], receivedSignal[1]);
item.SendSignal(0, output, "signal_out", null);
item.SendSignal(output, "signal_out");
}
protected abstract string Calculate(string signal1, string signal2);
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
switch (connection.Name)
{
case "signal_in1":
receivedSignal[0] = signal;
receivedSignal[0] = signal.value;
timeSinceReceived[0] = 0.0f;
IsActive = true;
break;
case "signal_in2":
receivedSignal[1] = signal;
receivedSignal[1] = signal.value;
timeSinceReceived[1] = 0.0f;
IsActive = true;
break;
@@ -1,5 +1,6 @@
using Barotrauma.Networking;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
@@ -31,6 +32,19 @@ namespace Barotrauma.Items.Components
}
}
/// <summary>
/// Can be used to display messages on the terminal via status effects
/// </summary>
public string ShowMessage
{
get { return messageHistory.Count == 0 ? string.Empty : messageHistory.Last(); }
set
{
if (string.IsNullOrEmpty(value)) { return; }
ShowOnDisplay(value);
}
}
private string OutputValue { get; set; }
public Terminal(Item item, XElement element)
@@ -42,29 +56,34 @@ namespace Barotrauma.Items.Components
partial void InitProjSpecific(XElement element);
partial void ShowOnDisplay(string input);
partial void ShowOnDisplay(string input, bool addToHistory = true);
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1)
public override void ReceiveSignal(Signal signal, Connection connection)
{
if (connection.Name != "signal_in") { return; }
if (signal.Length > MaxMessageLength)
if (signal.value.Length > MaxMessageLength)
{
signal = signal.Substring(0, MaxMessageLength);
signal.value = signal.value.Substring(0, MaxMessageLength);
}
string inputSignal = signal.Replace("\\n", "\n");
string inputSignal = signal.value.Replace("\\n", "\n");
ShowOnDisplay(inputSignal);
}
public override void OnItemLoaded()
{
bool isSubEditor = false;
#if CLIENT
isSubEditor = Screen.Selected != GameMain.SubEditorScreen || GameMain.GameSession?.GameMode is TestGameMode;
#endif
base.OnItemLoaded();
if (!string.IsNullOrEmpty(DisplayedWelcomeMessage))
{
ShowOnDisplay(DisplayedWelcomeMessage);
ShowOnDisplay(DisplayedWelcomeMessage, addToHistory: !isSubEditor);
DisplayedWelcomeMessage = "";
//remove welcome message if a game session is running so it doesn't reappear on successive rounds
if (GameMain.GameSession != null)
if (GameMain.GameSession != null && !isSubEditor)
{
welcomeMessage = null;
}
@@ -56,71 +56,74 @@ namespace Barotrauma.Items.Components
{
float angle = (float)Math.Atan2(receivedSignal[1], receivedSignal[0]);
if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
item.SendSignal(0, angle.ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
item.SendSignal(angle.ToString("G", CultureInfo.InvariantCulture), "signal_out");
}
}
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1)
public override void ReceiveSignal(Signal signal, Connection connection)
{
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out float value);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float value);
switch (Function)
{
case FunctionType.Sin:
if (!UseRadians) { value = MathHelper.ToRadians(value); }
item.SendSignal(0, ((float)Math.Sin(value)).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = MathF.Sin(value);
break;
case FunctionType.Cos:
if (!UseRadians) { value = MathHelper.ToRadians(value); }
item.SendSignal(0, ((float)Math.Cos(value)).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = MathF.Cos(value);
break;
case FunctionType.Tan:
if (!UseRadians) { value = MathHelper.ToRadians(value); }
//tan is undefined if the value is (π / 2) + πk, where k is any integer
if (!MathUtils.NearlyEqual(value % MathHelper.Pi, MathHelper.PiOver2))
{
item.SendSignal(0, ((float)Math.Tan(value)).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = MathF.Tan(value);
}
break;
case FunctionType.Asin:
//asin is only defined in the range [-1,1]
if (value >= -1.0f && value <= 1.0f)
{
float angle = (float)Math.Asin(value);
float angle = MathF.Asin(value);
if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
item.SendSignal(0, angle.ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = angle;
}
break;
case FunctionType.Acos:
//acos is only defined in the range [-1,1]
if (value >= -1.0f && value <= 1.0f)
{
float angle = (float)Math.Acos(value);
float angle = MathF.Acos(value);
if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
item.SendSignal(0, angle.ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = angle;
}
break;
case FunctionType.Atan:
if (connection.Name == "signal_in_x")
{
timeSinceReceived[0] = 0.0f;
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
}
else if (connection.Name == "signal_in_y")
{
timeSinceReceived[1] = 0.0f;
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
}
else
{
float angle = (float)Math.Atan(value);
float angle = MathF.Atan(value);
if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
item.SendSignal(0, angle.ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
value = angle;
}
break;
default:
throw new NotImplementedException($"Function {Function} has not been implemented.");
}
signal.value = value.ToString("G", CultureInfo.InvariantCulture);
item.SendSignal(signal, "signal_out");
}
}
}
@@ -12,11 +12,48 @@ namespace Barotrauma.Items.Components
private bool isInWater;
private float stateSwitchDelay;
private string output;
[InGameEditable, Serialize("1", true, description: "The signal the item sends out when it's underwater.", alwaysUseInstanceValues: true)]
public string Output { get; set; }
public string Output
{
get { return output; }
set
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
}
}
private string falseOutput;
[InGameEditable, Serialize("0", true, description: "The signal the item sends out when it's not underwater.", alwaysUseInstanceValues: true)]
public string FalseOutput { get; set; }
public string FalseOutput
{
get { return falseOutput; }
set
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}
}
}
private int maxOutputLength;
[Editable, Serialize(200, false, description: "The maximum length of the output strings. Warning: Large values can lead to large memory usage or networking issues.")]
public int MaxOutputLength
{
get { return maxOutputLength; }
set
{
maxOutputLength = Math.Max(value, 0);
}
}
public WaterDetector(Item item, XElement element)
: base(item, element)
@@ -59,13 +96,13 @@ namespace Barotrauma.Items.Components
string signalOut = isInWater ? Output : FalseOutput;
if (!string.IsNullOrEmpty(signalOut))
{
item.SendSignal(0, signalOut, "signal_out", null);
item.SendSignal(signalOut, "signal_out");
}
if (item.CurrentHull != null)
{
int waterPercentage = MathHelper.Clamp((int)Math.Round(item.CurrentHull.WaterPercentage), 0, 100);
item.SendSignal(0, waterPercentage.ToString(), "water_%", null);
item.SendSignal(waterPercentage.ToString(), "water_%");
}
}
}
@@ -152,9 +152,9 @@ namespace Barotrauma.Items.Components
channelMemory[index] = MathHelper.Clamp(value, 0, 10000);
}
public void TransmitSignal(int stepsTaken, string signal, Item source, Character sender, bool sentFromChat, float signalStrength = 1.0f)
public void TransmitSignal(Signal signal, bool sentFromChat)
{
var senderComponent = source?.GetComponent<WifiComponent>();
var senderComponent = signal.source?.GetComponent<WifiComponent>();
if (senderComponent != null && !CanReceive(senderComponent)) { return; }
bool chatMsgSent = false;
@@ -165,22 +165,24 @@ namespace Barotrauma.Items.Components
if (sentFromChat && !wifiComp.LinkToChat) { continue; }
//signal strength diminishes by distance
float sentSignalStrength = signalStrength *
float sentSignalStrength = signal.strength *
MathHelper.Clamp(1.0f - (Vector2.Distance(item.WorldPosition, wifiComp.item.WorldPosition) / wifiComp.range), 0.0f, 1.0f);
wifiComp.item.SendSignal(stepsTaken, signal, "signal_out", sender, 0, source, sentSignalStrength);
Signal s = new Signal(signal.value, signal.stepsTaken, sender: signal.sender, source: signal.source,
power: 0.0f, strength: sentSignalStrength);
wifiComp.item.SendSignal(s, "signal_out");
if (source != null)
if (signal.source != null)
{
foreach (Item receiverItem in wifiComp.item.LastSentSignalRecipients)
foreach (Connection receiver in wifiComp.item.LastSentSignalRecipients)
{
if (!source.LastSentSignalRecipients.Contains(receiverItem))
if (!signal.source.LastSentSignalRecipients.Contains(receiver))
{
source.LastSentSignalRecipients.Add(receiverItem);
signal.source.LastSentSignalRecipients.Add(receiver);
}
}
}
if (DiscardDuplicateChatMessages && signal == prevSignal) { continue; }
if (DiscardDuplicateChatMessages && signal.value == prevSignal) { continue; }
//create a chat message
if (LinkToChat && wifiComp.LinkToChat && chatMsgCooldown <= 0.0f && !sentFromChat)
@@ -188,7 +190,7 @@ namespace Barotrauma.Items.Components
if (wifiComp.item.ParentInventory != null &&
wifiComp.item.ParentInventory.Owner != null)
{
string chatMsg = signal;
string chatMsg = signal.value;
if (senderComponent != null)
{
chatMsg = ChatMessage.ApplyDistanceEffect(chatMsg, 1.0f - sentSignalStrength);
@@ -201,7 +203,7 @@ namespace Barotrauma.Items.Components
{
if (GameMain.Client == null)
{
GameMain.GameSession?.CrewManager?.AddSinglePlayerChatMessage(source?.Name ?? "", signal, ChatMessageType.Radio, sender: null);
GameMain.GameSession?.CrewManager?.AddSinglePlayerChatMessage(signal.source?.Name ?? "", signal.value, ChatMessageType.Radio, sender: null);
}
}
#elif SERVER
@@ -211,7 +213,7 @@ namespace Barotrauma.Items.Components
if (recipientClient != null)
{
GameMain.Server.SendDirectChatMessage(
ChatMessage.Create(source?.Name ?? "", chatMsg, ChatMessageType.Radio, null), recipientClient);
ChatMessage.Create(signal.source?.Name ?? "", chatMsg, ChatMessageType.Radio, null), recipientClient);
}
}
#endif
@@ -225,26 +227,26 @@ namespace Barotrauma.Items.Components
IsActive = true;
}
prevSignal = signal;
prevSignal = signal.value;
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
public override void ReceiveSignal(Signal signal, Connection connection)
{
if (connection == null) { return; }
switch (connection.Name)
{
case "signal_in":
TransmitSignal(stepsTaken, signal, source, sender, false, signalStrength);
TransmitSignal(signal, false);
break;
case "set_channel":
if (int.TryParse(signal, out int newChannel))
if (int.TryParse(signal.value, out int newChannel))
{
Channel = newChannel;
}
break;
case "set_range":
if (float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out float newRange))
if (float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float newRange))
{
Range = newRange;
}
@@ -37,11 +37,6 @@ namespace Barotrauma.Items.Components
angle = MathUtils.VectorToAngle(end - start);
length = Vector2.Distance(start, end);
if (length > 5000.0f)
{
int akjsdnfkjsadf = 1;
}
}
}
@@ -100,6 +95,20 @@ namespace Barotrauma.Items.Components
set;
}
[Editable, Serialize(false, true, "If enabled, this wire will be ignored by the \"Lock all default wires\" setting.", alwaysUseInstanceValues: true)]
public bool NoAutoLock
{
get;
set;
}
[Editable, Serialize(false, true, "If enabled, this wire will use the sprite depth instead of a constant depth.")]
public bool UseSpriteDepth
{
get;
set;
}
public Wire(Item item, XElement element)
: base(item, element)
{
@@ -309,6 +318,8 @@ namespace Barotrauma.Items.Components
if (Screen.Selected != GameMain.SubEditorScreen)
{
if (user != null) { NoAutoLock = true; }
//cannot run wires from sub to another
if (item.Submarine != sub && sub != null && item.Submarine != null)
{
@@ -22,7 +22,7 @@ namespace Barotrauma.Items.Components
string signalOut = sendOutput == 1 ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) return;
item.SendSignal(0, signalOut, "signal_out", null);
item.SendSignal(signalOut, "signal_out");
}
}
}