Unstable 0.16.0.0

This commit is contained in:
Markus Isberg
2022-01-14 01:28:24 +09:00
parent d9baeaa2e1
commit 7d6421a548
237 changed files with 6430 additions and 2205 deletions
@@ -12,6 +12,8 @@ namespace Barotrauma.Items.Components
//the output is sent if both inputs have received a signal within the timeframe
protected float timeFrame;
protected readonly Character[] signalSender = new Character[2];
[InGameEditable(DecimalCount = 2), Serialize(0.0f, true, description: "The item sends the output if both inputs have received a non-zero signal within the timeframe. If set to 0, the inputs must receive a signal at the same time.", alwaysUseInstanceValues: true)]
public float TimeFrame
@@ -80,14 +82,14 @@ namespace Barotrauma.Items.Components
bool sendOutput = true;
for (int i = 0; i < timeSinceReceived.Length; i++)
{
if (timeSinceReceived[i] > timeFrame) sendOutput = false;
if (timeSinceReceived[i] > timeFrame) { sendOutput = false; }
timeSinceReceived[i] += deltaTime;
}
string signalOut = sendOutput ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) return;
if (string.IsNullOrEmpty(signalOut)) { return; }
item.SendSignal(signalOut, "signal_out");
item.SendSignal(new Signal(signalOut, sender: signalSender[0] ?? signalSender[1]), "signal_out");
}
public override void ReceiveSignal(Signal signal, Connection connection)
@@ -95,12 +97,14 @@ namespace Barotrauma.Items.Components
switch (connection.Name)
{
case "signal_in1":
if (signal.value == "0") return;
if (signal.value == "0") { return; }
timeSinceReceived[0] = 0.0f;
signalSender[0] = signal.sender;
break;
case "signal_in2":
if (signal.value == "0") return;
if (signal.value == "0") { return; }
timeSinceReceived[1] = 0.0f;
signalSender[1] = signal.sender;
break;
case "set_output":
output = signal.value;
@@ -19,7 +19,7 @@ namespace Barotrauma.Items.Components
private HashSet<ItemPrefab> ActivatingItemPrefabs { get; set; } = new HashSet<ItemPrefab>();
private bool AllowUsingButtons => ActivatingItemPrefabs.None() || Container.Inventory.AllItems.Any(i => i != null && ActivatingItemPrefabs.Any(p => p == i.Prefab));
private bool AllowUsingButtons => ActivatingItemPrefabs.None() || (Container != null && Container.Inventory.AllItems.Any(i => i != null && ActivatingItemPrefabs.Any(p => p == i.Prefab)));
public ButtonTerminal(Item item, XElement element) : base(item, element)
{
@@ -101,12 +101,12 @@ namespace Barotrauma.Items.Components
partial void OnItemLoadedProjSpecific();
private bool SendSignal(int signalIndex, bool isServerMessage = false)
private bool SendSignal(int signalIndex, Character sender, bool isServerMessage = false)
{
if (!isServerMessage && !AllowUsingButtons) { return false; }
string signal = Signals[signalIndex];
string connectionName = $"signal_out{signalIndex + 1}";
item.SendSignal(signal, connectionName);
item.SendSignal(new Signal(signal, sender: sender), connectionName);
return true;
}
@@ -17,6 +17,12 @@ namespace Barotrauma.Items.Components
}
}
[Editable, Serialize("", false)]
public string Separator
{
get;
set;
}
public ConcatComponent(Item item, XElement element)
: base(item, element)
@@ -25,7 +31,15 @@ namespace Barotrauma.Items.Components
protected override string Calculate(string signal1, string signal2)
{
string output = signal1 + signal2;
string output;
if (string.IsNullOrEmpty(Separator))
{
output = signal1 + signal2;
}
else
{
output = signal1 + Separator + signal2;
}
return output.Length <= maxOutputLength ? output : output.Substring(0, MaxOutputLength);
}
}
@@ -25,7 +25,7 @@ namespace Barotrauma.Items.Components
get { return wires; }
}
private Item item;
private readonly Item item;
public readonly bool IsOutput;
@@ -142,7 +142,6 @@ namespace Barotrauma.Items.Components
IsPower = Name == "power_in" || Name == "power" || Name == "power_out";
Effects = new List<StatusEffect>();
wireId = new ushort[MaxWires];
@@ -164,6 +163,7 @@ namespace Barotrauma.Items.Components
break;
case "statuseffect":
Effects ??= new List<StatusEffect>();
Effects.Add(StatusEffect.Load(subElement, item.Name + ", connection " + Name));
break;
}
@@ -272,7 +272,7 @@ namespace Barotrauma.Items.Components
ic.ReceiveSignal(signal, connection);
}
if (signal.value != "0")
if (recipient.Effects != null && signal.value != "0" && !string.IsNullOrEmpty(signal.value))
{
foreach (StatusEffect effect in recipient.Effects)
{
@@ -24,7 +24,19 @@ namespace Barotrauma.Items.Components
/// </summary>
public bool AlwaysAllowRewiring
{
get { return item.Submarine?.Info.Type == SubmarineType.BeaconStation; }
get
{
if (item.Submarine == null) { return true; }
switch (item.Submarine.Info.Type)
{
case SubmarineType.Wreck:
case SubmarineType.BeaconStation:
case SubmarineType.EnemySubmarine:
case SubmarineType.Ruin:
return true;
}
return false;
}
}
[Editable, Serialize(false, true, description: "Locked connection panels cannot be rewired in-game.", alwaysUseInstanceValues: true)]
@@ -301,7 +301,6 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
UpdateProjSpecific();
foreach (CustomInterfaceElement ciElement in customInterfaceElementList)
{
if (!ciElement.ContinuousSignal) { continue; }
@@ -318,8 +317,6 @@ namespace Barotrauma.Items.Components
}
}
partial void UpdateProjSpecific();
public override XElement Save(XElement parentElement)
{
labels = customInterfaceElementList.Select(ci => ci.Label).ToArray();
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
namespace Barotrauma.Items.Components
@@ -24,7 +25,7 @@ namespace Barotrauma.Items.Components
private int signalQueueSize;
private int delayTicks;
private readonly Queue<DelayedSignal> signalQueue;
private readonly Queue<DelayedSignal> signalQueue = new Queue<DelayedSignal>();
private DelayedSignal prevQueuedSignal;
@@ -39,6 +40,7 @@ namespace Barotrauma.Items.Components
delay = value;
delayTicks = (int)(delay / Timing.Step);
signalQueueSize = Math.Max(delayTicks, 1) * 2;
signalQueue.Clear();
}
}
@@ -59,7 +61,6 @@ namespace Barotrauma.Items.Components
public DelayComponent(Item item, XElement element)
: base (item, element)
{
signalQueue = new Queue<DelayedSignal>();
IsActive = true;
}
@@ -74,7 +75,7 @@ namespace Barotrauma.Items.Components
{
var signalOut = signalQueue.Peek();
signalOut.SendDuration -= 1;
item.SendSignal(new Signal(signalOut.Signal.value, strength: signalOut.Signal.strength), "signal_out");
item.SendSignal(new Signal(signalOut.Signal.value, sender: signalOut.Signal.sender, strength: signalOut.Signal.strength), "signal_out");
if (signalOut.SendDuration <= 0)
{
signalQueue.Dequeue();
@@ -115,7 +116,7 @@ namespace Barotrauma.Items.Components
signalQueue.Enqueue(prevQueuedSignal);
break;
case "set_delay":
if (float.TryParse(signal.value, out float newDelay))
if (float.TryParse(signal.value, NumberStyles.Any, CultureInfo.InvariantCulture, out float newDelay))
{
newDelay = MathHelper.Clamp(newDelay, 0, 60);
if (signalQueue.Count > 0 && newDelay != Delay)
@@ -12,6 +12,8 @@ namespace Barotrauma.Items.Components
protected string[] receivedSignal;
private readonly Character[] signalSender = new Character[2];
//the output is sent if both inputs have received a signal within the timeframe
protected float timeFrame;
@@ -90,9 +92,8 @@ namespace Barotrauma.Items.Components
if (sendOutput)
{
string signalOut = receivedSignal[0] == receivedSignal[1] ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) return;
item.SendSignal(signalOut, "signal_out");
if (string.IsNullOrEmpty(signalOut)) { return; }
item.SendSignal(new Signal(signalOut, sender: signalSender[0] ?? signalSender[1]), "signal_out");
}
}
@@ -103,10 +104,15 @@ namespace Barotrauma.Items.Components
case "signal_in1":
receivedSignal[0] = signal.value;
timeSinceReceived[0] = 0.0f;
signalSender[0] = signal.sender;
break;
case "signal_in2":
receivedSignal[1] = signal.value;
timeSinceReceived[1] = 0.0f;
signalSender[1] = signal.sender;
break;
case "set_output":
output = signal.value;
break;
}
}
@@ -32,10 +32,22 @@ namespace Barotrauma.Items.Components
}
public override void ReceiveSignal(Signal signal, Connection connection)
{
base.ReceiveSignal(signal, connection);
float.TryParse(receivedSignal[0], NumberStyles.Float, CultureInfo.InvariantCulture, out val1);
float.TryParse(receivedSignal[1], NumberStyles.Float, CultureInfo.InvariantCulture, out val2);
{
//base.ReceiveSignal(signal, connection);
switch (connection.Name)
{
case "signal_in1":
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out val1);
timeSinceReceived[0] = 0.0f;
break;
case "signal_in2":
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out val2);
timeSinceReceived[1] = 0.0f;
break;
case "set_output":
output = signal.value;
break;
}
}
}
}
@@ -50,7 +50,7 @@ namespace Barotrauma.Items.Components
set
{
rotation = value;
SetLightSourceTransform();
SetLightSourceTransformProjSpecific();
}
}
@@ -256,7 +256,7 @@ namespace Barotrauma.Items.Components
return;
}
SetLightSourceTransform();
SetLightSourceTransformProjSpecific();
PhysicsBody body = ParentBody ?? item.body;
if (body != null && !body.Enabled)
@@ -338,7 +338,11 @@ namespace Barotrauma.Items.Components
partial void SetLightSourceState(bool enabled, float brightness);
partial void SetLightSourceTransform();
public void SetLightSourceTransform()
{
SetLightSourceTransformProjSpecific();
}
partial void SetLightSourceTransformProjSpecific();
}
}
@@ -74,6 +74,17 @@ namespace Barotrauma.Items.Components
}
}
public Vector2 TransformedDetectOffset
{
get
{
Vector2 transformedDetectOffset = detectOffset;
if (item.FlippedX) { transformedDetectOffset.X = -transformedDetectOffset.X; }
if (item.FlippedY) { transformedDetectOffset.Y = -transformedDetectOffset.Y; }
return transformedDetectOffset;
}
}
[Editable(MinValueFloat = 0.1f, MaxValueFloat = 100.0f, DecimalCount = 2), Serialize(0.1f, true, description: "How often the sensor checks if there's something moving near it. Higher values are better for performance.", alwaysUseInstanceValues: true)]
public float UpdateInterval
{
@@ -184,15 +195,15 @@ namespace Barotrauma.Items.Components
}
}
Vector2 detectPos = item.WorldPosition + detectOffset;
Vector2 detectPos = item.WorldPosition + TransformedDetectOffset;
Rectangle detectRect = new Rectangle((int)(detectPos.X - rangeX), (int)(detectPos.Y - rangeY), (int)(rangeX * 2), (int)(rangeY * 2));
float broadRangeX = Math.Max(rangeX * 2, 500);
float broadRangeY = Math.Max(rangeY * 2, 500);
if (item.CurrentHull == null && item.Submarine != null && Level.Loaded != null &&
if (item.CurrentHull == null && item.Submarine != null &&
(Target == TargetType.Wall || Target == TargetType.Any))
{
if (Math.Abs(item.Submarine.Velocity.X) > MinimumVelocity || Math.Abs(item.Submarine.Velocity.Y) > MinimumVelocity)
if (Level.Loaded != null && (Math.Abs(item.Submarine.Velocity.X) > MinimumVelocity || Math.Abs(item.Submarine.Velocity.Y) > MinimumVelocity))
{
var cells = Level.Loaded.GetCells(item.WorldPosition, 1);
foreach (var cell in cells)
@@ -268,7 +279,7 @@ namespace Barotrauma.Items.Components
foreach (Limb limb in c.AnimController.Limbs)
{
if (limb.IsSevered) { continue; }
if (limb.LinearVelocity.LengthSquared() <= MinimumVelocity * MinimumVelocity) { continue; }
if (limb.LinearVelocity.LengthSquared() < MinimumVelocity * MinimumVelocity) { continue; }
if (MathUtils.CircleIntersectsRectangle(limb.WorldPosition, ConvertUnits.ToDisplayUnits(limb.body.GetMaxExtent()), detectRect))
{
MotionDetected = true;
@@ -276,23 +287,12 @@ namespace Barotrauma.Items.Components
}
}
}
}
}
}
public override void FlipX(bool relativeToSub)
{
detectOffset.X = -detectOffset.X;
}
public override void FlipY(bool relativeToSub)
{
detectOffset.Y = -detectOffset.Y;
}
public override XElement Save(XElement parentElement)
{
Vector2 prevDetectOffset = detectOffset;
//undo flipping before saving
if (item.FlippedX) { detectOffset.X = -detectOffset.X; }
if (item.FlippedY) { detectOffset.Y = -detectOffset.Y; }
XElement element = base.Save(parentElement);
detectOffset = prevDetectOffset;
return element;
@@ -15,14 +15,14 @@ namespace Barotrauma.Items.Components
bool sendOutput = false;
for (int i = 0; i < timeSinceReceived.Length; i++)
{
if (timeSinceReceived[i] <= timeFrame) sendOutput = true;
if (timeSinceReceived[i] <= timeFrame) { sendOutput = true; }
timeSinceReceived[i] += deltaTime;
}
string signalOut = sendOutput ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) return;
if (string.IsNullOrEmpty(signalOut)) { return; }
item.SendSignal(signalOut, "signal_out");
item.SendSignal(new Signal(signalOut, sender: signalSender[0] ?? signalSender[1]), "signal_out");
}
}
}
@@ -4,6 +4,9 @@ namespace Barotrauma.Items.Components
{
class OxygenDetector : ItemComponent
{
private int prevSentOxygenValue;
private string oxygenSignal;
public OxygenDetector(Item item, XElement element)
: base (item, element)
{
@@ -12,9 +15,15 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
if (item.CurrentHull == null) return;
if (item.CurrentHull == null) { return; }
item.SendSignal(((int)item.CurrentHull.OxygenPercentage).ToString(), "signal_out");
if (prevSentOxygenValue != (int)item.CurrentHull.OxygenPercentage || oxygenSignal == null)
{
prevSentOxygenValue = (int)item.CurrentHull.OxygenPercentage;
oxygenSignal = prevSentOxygenValue.ToString();
}
item.SendSignal(oxygenSignal, "signal_out");
}
}
@@ -9,6 +9,9 @@ namespace Barotrauma.Items.Components
//how often the detector can switch from state to another
const float StateSwitchInterval = 1.0f;
private int prevSentWaterPercentageValue;
private string waterPercentageSignal;
private bool isInWater;
private float stateSwitchDelay;
@@ -106,7 +109,12 @@ namespace Barotrauma.Items.Components
{
waterPercentage = MathHelper.Clamp((int)Math.Ceiling(item.CurrentHull.WaterPercentage), 0, 100);
}
item.SendSignal(waterPercentage.ToString(), "water_%");
if (prevSentWaterPercentageValue != waterPercentage || waterPercentageSignal == null)
{
prevSentWaterPercentageValue = waterPercentage;
waterPercentageSignal = prevSentWaterPercentageValue.ToString();
}
item.SendSignal(waterPercentageSignal, "water_%");
}
string highPressureOut = (item.CurrentHull == null || item.CurrentHull.LethalPressure > 5.0f) ? "1" : "0";
item.SendSignal(highPressureOut, "high_pressure");
@@ -24,6 +24,7 @@ namespace Barotrauma.Items.Components
private readonly int[] channelMemory = new int[ChannelMemorySize];
private Connection signalInConnection;
private Connection signalOutConnection;
[Serialize(CharacterTeamType.None, true, description: "WiFi components can only communicate with components that have the same Team ID.", alwaysUseInstanceValues: true)]
@@ -98,6 +99,7 @@ namespace Barotrauma.Items.Components
if (item.Connections != null)
{
signalOutConnection = item.Connections.Find(c => c.Name == "signal_out");
signalInConnection = item.Connections.Find(c => c.Name == "signal_in");
}
if (channelMemory.All(m => m == 0))
{
@@ -207,6 +209,18 @@ namespace Barotrauma.Items.Components
if (wifiComp.signalOutConnection != null)
{
if (signal.source != null && wifiComp.signalInConnection != null)
{
if (signal.source.LastSentSignalRecipients.Contains(wifiComp.signalInConnection))
{
//signal already passed through this wifi component -> stop here to prevent an infinite loop
continue;
}
else
{
signal.source.LastSentSignalRecipients.Add(wifiComp.signalInConnection);
}
}
wifiComp.item.SendSignal(s, wifiComp.signalOutConnection);
}
@@ -503,13 +503,6 @@ namespace Barotrauma.Items.Components
return true;
}
public override void Move(Vector2 amount)
{
#if CLIENT
if (item.IsSelected) MoveNodes(amount);
#endif
}
public List<Vector2> GetNodes()
{
return new List<Vector2>(nodes);
@@ -15,14 +15,14 @@ namespace Barotrauma.Items.Components
int sendOutput = 0;
for (int i = 0; i < timeSinceReceived.Length; i++)
{
if (timeSinceReceived[i] <= timeFrame) sendOutput += 1;
if (timeSinceReceived[i] <= timeFrame) { sendOutput += 1; }
timeSinceReceived[i] += deltaTime;
}
string signalOut = sendOutput == 1 ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) return;
if (string.IsNullOrEmpty(signalOut)) { return; }
item.SendSignal(signalOut, "signal_out");
item.SendSignal(new Signal(signalOut, sender: signalSender[0] ?? signalSender[1]), "signal_out");
}
}
}