This commit is contained in:
EvilFactory
2023-06-15 12:13:50 -03:00
210 changed files with 4491 additions and 2580 deletions
@@ -29,10 +29,10 @@ namespace Barotrauma.Items.Components
private readonly Item item;
public readonly bool IsOutput;
public readonly List<StatusEffect> Effects;
public readonly List<ushort> LoadedWireIds;
public readonly List<(ushort wireId, int? connectionIndex)> LoadedWires;
//The grid the connection is a part of
public GridInfo Grid;
@@ -40,6 +40,9 @@ namespace Barotrauma.Items.Components
//Priority in which power output will be handled - load is unaffected
public PowerPriority Priority = PowerPriority.Default;
public Signal LastSentSignal { get; private set; }
public Signal LastReceivedSignal {get; private set;}
public bool IsPower
{
get;
@@ -151,16 +154,20 @@ namespace Barotrauma.Items.Components
IsPower = Name == "power_in" || Name == "power" || Name == "power_out";
LoadedWireIds = new List<ushort>();
LoadedWires = new List<(ushort wireId, int? connectionIndex)>();
foreach (var subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "link":
int id = subElement.GetAttributeInt("w", 0);
int? i = null;
if (subElement.GetAttribute("i") != null)
{
i = subElement.GetAttributeInt("i", 0);
}
if (id < 0) { id = 0; }
if (LoadedWireIds.Count < MaxWires) { LoadedWireIds.Add(idRemap.GetOffsetId(id)); }
if (LoadedWires.Count < MaxWires) { LoadedWires.Add((idRemap.GetOffsetId(id), i)); }
break;
case "statuseffect":
Effects ??= new List<StatusEffect>();
@@ -288,6 +295,7 @@ namespace Barotrauma.Items.Components
public void SendSignal(Signal signal)
{
LastSentSignal = signal;
enumeratingWires = true;
foreach (var wire in wires)
{
@@ -298,6 +306,10 @@ namespace Barotrauma.Items.Components
signal.source?.LastSentSignalRecipients.Add(recipient);
Connection connection = recipient;
connection.LastReceivedSignal = signal;
#if CLIENT
wire.RegisterSignal(signal, source: this);
#endif
object[] obj = new object[] { signal, connection };
GameMain.LuaCs.Hook.Call("signalReceived", obj);
@@ -355,22 +367,29 @@ namespace Barotrauma.Items.Components
public void InitializeFromLoaded()
{
if (LoadedWireIds.Count == 0) { return; }
if (LoadedWires.Count == 0) { return; }
for (int i = 0; i < LoadedWireIds.Count; i++)
foreach ((ushort wireId, int? connectionIndex) in LoadedWires)
{
if (!(Entity.FindEntityByID(LoadedWireIds[i]) is Item wireItem)) { continue; }
if (Entity.FindEntityByID(wireId) is not Item wireItem) { continue; }
var wire = wireItem.GetComponent<Wire>();
if (wire != null && TryAddLink(wire))
{
if (wire.Item.body != null) wire.Item.body.Enabled = false;
wire.Connect(this, false, false);
if (wire.Item.body != null) { wire.Item.body.Enabled = false; }
if (connectionIndex.HasValue)
{
wire.Connect(this, connectionIndex.Value, addNode: false, sendNetworkEvent: false);
}
else
{
wire.TryConnect(this, addNode: false, sendNetworkEvent: false);
}
wire.FixNodeEnds();
recipientsDirty = true;
}
}
LoadedWireIds.Clear();
LoadedWires.Clear();
}
@@ -381,7 +400,8 @@ namespace Barotrauma.Items.Components
foreach (var wire in wires.OrderBy(w => w.Item.ID))
{
newElement.Add(new XElement("link",
new XAttribute("w", wire.Item.ID.ToString())));
new XAttribute("w", wire.Item.ID.ToString()),
new XAttribute("i", wire.Connections[0] == this ? 0 : 1)));
}
parentElement.Add(newElement);
@@ -295,8 +295,8 @@ namespace Barotrauma.Items.Components
for (int i = 0; i < loadedConnections.Count && i < Connections.Count; i++)
{
Connections[i].LoadedWireIds.Clear();
Connections[i].LoadedWireIds.AddRange(loadedConnections[i].LoadedWireIds);
Connections[i].LoadedWires.Clear();
Connections[i].LoadedWires.AddRange(loadedConnections[i].LoadedWires);
}
disconnectedWireIds = element.GetAttributeUshortArray("disconnectedwires", Array.Empty<ushort>()).ToList();
@@ -82,8 +82,10 @@ namespace Barotrauma.Items.Components
signalOut.SendDuration -= 1;
item.SendSignal(new Signal(signalOut.Signal.value, sender: signalOut.Signal.sender, strength: signalOut.Signal.strength), "signal_out");
if (signalOut.SendDuration <= 0)
{
signalQueue.Dequeue();
{
//check the queue isn't empty again, because sending the signal may empty it
//if this component is set to reset when it receives a signal and the signal is routed back to this component
signalQueue.TryDequeue(out _);
}
else
{
@@ -173,6 +173,8 @@ namespace Barotrauma.Items.Components
set
{
lightColor = value;
//reset previously received signal to force updating the color if we receive a set_color signal after the color has been modified manually
prevColorSignal = string.Empty;
#if CLIENT
if (Light != null)
{
@@ -249,6 +251,11 @@ namespace Barotrauma.Items.Components
base.OnItemLoaded();
SetLightSourceState(IsActive, lightBrightness);
turret = item.GetComponent<Turret>();
if (item.body != null)
{
item.body.FarseerBody.OnEnabled += CheckIfNeedsUpdate;
item.body.FarseerBody.OnDisabled += CheckIfNeedsUpdate;
}
#if CLIENT
Drawable = AlphaBlend && Light.LightSprite != null;
if (Screen.Selected.IsEditor)
@@ -277,15 +284,24 @@ namespace Barotrauma.Items.Components
return;
}
if (item.body == null && powerConsumption <= 0.0f && Parent == null && turret == null &&
if ((item.body == null || !item.body.Enabled) &&
powerConsumption <= 0.0f && Parent == null && turret == null &&
(statusEffectLists == null || !statusEffectLists.ContainsKey(ActionType.OnActive)) &&
(IsActiveConditionals == null || IsActiveConditionals.Count == 0))
{
lightBrightness = 1.0f;
SetLightSourceState(true, lightBrightness);
if (item.body != null && !item.body.Enabled)
{
lightBrightness = 0.0f;
SetLightSourceState(false, 0.0f);
}
else
{
lightBrightness = 1.0f;
SetLightSourceState(true, lightBrightness);
}
isOn = true;
SetLightSourceTransformProjSpecific();
base.IsActive = false;
isOn = true;
#if CLIENT
Light.ParentSub = item.Submarine;
#endif
@@ -222,10 +222,10 @@ namespace Barotrauma.Items.Components
{
Vector2 e1 = edge.Point1 + cell.Translation;
Vector2 e2 = edge.Point2 + cell.Translation;
if (MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Y), new Vector2(detectRect.Right, detectRect.Y)) ||
MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Bottom), new Vector2(detectRect.Right, detectRect.Bottom)) ||
MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Y), new Vector2(detectRect.X, detectRect.Bottom)) ||
MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.Right, detectRect.Y), new Vector2(detectRect.Right, detectRect.Bottom)))
if (MathUtils.LineSegmentsIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Y), new Vector2(detectRect.Right, detectRect.Y)) ||
MathUtils.LineSegmentsIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Bottom), new Vector2(detectRect.Right, detectRect.Bottom)) ||
MathUtils.LineSegmentsIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Y), new Vector2(detectRect.X, detectRect.Bottom)) ||
MathUtils.LineSegmentsIntersect(e1, e2, new Vector2(detectRect.Right, detectRect.Y), new Vector2(detectRect.Right, detectRect.Bottom)))
{
MotionDetected = true;
return;
@@ -8,6 +8,9 @@ namespace Barotrauma.Items.Components
public Item source;
public float power;
public float strength;
public readonly double CreationTime;
public double TimeSinceCreated => Timing.TotalTimeUnpaused - CreationTime;
public Signal(string value, int stepsTaken = 0, Character sender = null,
Item source = null, float power = 0.0f, float strength = 1.0f)
@@ -18,6 +21,7 @@ namespace Barotrauma.Items.Components
this.source = source;
this.power = power;
this.strength = strength;
CreationTime = Timing.TotalTimeUnpaused;
}
internal Signal WithStepsTaken(int stepsTaken)
@@ -64,9 +64,7 @@ namespace Barotrauma.Items.Components
set;
}
private bool linkToChat = false;
[ConditionallyEditable(ConditionallyEditable.ConditionType.AllowLinkingWifiToChat)]
[ConditionallyEditable(ConditionallyEditable.ConditionType.AllowLinkingWifiToChat, onlyInEditors: false)]
[Serialize(false, IsPropertySaveable.No, description: "If enabled, any signals received from another chat-linked wifi component are displayed " +
"as chat messages in the chatbox of the player holding the item.", alwaysUseInstanceValues: true)]
public bool LinkToChat
@@ -19,7 +19,7 @@ namespace Barotrauma.Items.Components
private Vector2 end;
private readonly float angle;
private readonly float length;
public readonly float Length;
public Vector2 Start
{
@@ -36,7 +36,7 @@ namespace Barotrauma.Items.Components
this.end = end;
angle = MathUtils.VectorToAngle(end - start);
length = Vector2.Distance(start, end);
Length = Vector2.Distance(start, end);
}
}
@@ -52,7 +52,7 @@ namespace Barotrauma.Items.Components
private List<Vector2> nodes;
private readonly List<WireSection> sections;
private Connection[] connections;
private readonly Connection[] connections;
private bool canPlaceNode;
private Vector2 newNodePos;
@@ -81,6 +81,8 @@ namespace Barotrauma.Items.Components
get { return connections; }
}
public float Length { get; private set; }
[Serialize(5000.0f, IsPropertySaveable.No, description: "The maximum distance the wire can extend (in pixels).")]
public float MaxLength
{
@@ -162,14 +164,50 @@ namespace Barotrauma.Items.Components
SetConnectedDirty();
}
public bool Connect(Connection newConnection, bool addNode = true, bool sendNetworkEvent = false)
/// <summary>
/// Tries to add the given connection to this wire. Note that this only affects the wire -
/// adding the wire to the connection is done in <see cref="Connection.ConnectWire(Wire)"/>
/// </summary>
public bool TryConnect(Connection newConnection, bool addNode = true, bool sendNetworkEvent = false)
{
if (connections[0] == null)
{
return Connect(newConnection, 0, addNode, sendNetworkEvent);
}
else if (connections[1] == null)
{
return Connect(newConnection, 1, addNode, sendNetworkEvent);
}
return false;
}
/// <summary>
/// Tries to add the given connection to this wire. Note that this only affects the wire -
/// adding the wire to the connection is done in <see cref="Connection.ConnectWire(Wire)"/>
/// </summary>
/// <param name="connectionIndex">Which end of the wire to add the connection to? 0 or 1.
/// Normally doesn't make a difference, but matters if we're copying/loading a wire,
/// in which case the 1st node should be located at the same item as the 1st connection.</param>
/// <returns></returns>
public bool Connect(Connection newConnection, int connectionIndex, bool addNode = true, bool sendNetworkEvent = false)
{
for (int i = 0; i < 2; i++)
{
if (connections[i] == newConnection) { return false; }
}
if (!connections.Any(c => c == null)) { return false; }
if (connectionIndex < 0 || connectionIndex > 1)
{
DebugConsole.ThrowError($"Error while connecting a wire to {newConnection.Item}: {connectionIndex} is not a valid index.");
return false;
}
if (connections[connectionIndex] != null)
{
DebugConsole.ThrowError($"Error while connecting a wire to {newConnection.Item}: a wire is already connected to the index {connectionIndex}.");
return false;
}
for (int i = 0; i < 2; i++)
{
@@ -183,70 +221,12 @@ namespace Barotrauma.Items.Components
newConnection.ConnectionPanel.DisconnectedWires.Remove(this);
for (int i = 0; i < 2; i++)
connections[connectionIndex] = newConnection;
FixNodeEnds();
if (addNode)
{
if (connections[i] != null) { continue; }
connections[i] = newConnection;
FixNodeEnds();
if (!addNode) { break; }
Submarine refSub = newConnection.Item.Submarine;
if (refSub == null)
{
Structure attachTarget = Structure.GetAttachTarget(newConnection.Item.WorldPosition);
if (attachTarget == null && !(newConnection.Item.GetComponent<Holdable>()?.Attached ?? false))
{
connections[i] = null;
continue;
}
refSub = attachTarget?.Submarine;
}
Vector2 nodePos = refSub == null ?
newConnection.Item.Position :
newConnection.Item.Position - refSub.HiddenSubPosition;
if (nodes.Count > 0 && nodes[0] == nodePos) { break; }
if (nodes.Count > 1 && nodes[nodes.Count - 1] == nodePos) { break; }
//make sure we place the node at the correct end of the wire (the end that's closest to the new node pos)
int newNodeIndex = 0;
if (nodes.Count > 1)
{
if (connections[0] != null && connections[0] != newConnection)
{
if (Vector2.DistanceSquared(nodes[0], connections[0].Item.Position - (refSub?.HiddenSubPosition ?? Vector2.Zero)) <
Vector2.DistanceSquared(nodes[nodes.Count - 1], connections[0].Item.Position - (refSub?.HiddenSubPosition ?? Vector2.Zero)))
{
newNodeIndex = nodes.Count;
}
}
else if (connections[1] != null && connections[1] != newConnection)
{
if (Vector2.DistanceSquared(nodes[0], connections[1].Item.Position - (refSub?.HiddenSubPosition ?? Vector2.Zero)) <
Vector2.DistanceSquared(nodes[nodes.Count - 1], connections[1].Item.Position - (refSub?.HiddenSubPosition ?? Vector2.Zero)))
{
newNodeIndex = nodes.Count;
}
}
else if (Vector2.DistanceSquared(nodes[nodes.Count - 1], nodePos) < Vector2.DistanceSquared(nodes[0], nodePos))
{
newNodeIndex = nodes.Count;
}
}
if (newNodeIndex == 0 && nodes.Count > 1)
{
nodes.Insert(0, nodePos);
}
else
{
nodes.Add(nodePos);
}
break;
AddNode(newConnection, connectionIndex);
}
SetConnectedDirty();
@@ -258,7 +238,7 @@ namespace Barotrauma.Items.Components
if (ic == this) { continue; }
ic.Drop(null);
}
if (item.Container != null) { item.Container.RemoveContained(this.item); }
item.Container?.RemoveContained(item);
if (item.body != null) { item.body.Enabled = false; }
IsActive = false;
@@ -286,6 +266,63 @@ namespace Barotrauma.Items.Components
return true;
}
private void AddNode(Connection newConnection, int selectedIndex)
{
Submarine refSub = newConnection.Item.Submarine;
if (refSub == null)
{
Structure attachTarget = Structure.GetAttachTarget(newConnection.Item.WorldPosition);
if (attachTarget == null && !(newConnection.Item.GetComponent<Holdable>()?.Attached ?? false))
{
connections[selectedIndex] = null;
return;
}
refSub = attachTarget?.Submarine;
}
Vector2 nodePos = refSub == null ?
newConnection.Item.Position :
newConnection.Item.Position - refSub.HiddenSubPosition;
if (nodes.Count > 0 && nodes[0] == nodePos) { return; }
if (nodes.Count > 1 && nodes[nodes.Count - 1] == nodePos) { return; }
//make sure we place the node at the correct end of the wire (the end that's closest to the new node pos)
int newNodeIndex = 0;
if (nodes.Count > 1)
{
if (connections[0] != null && connections[0] != newConnection)
{
if (Vector2.DistanceSquared(nodes[0], connections[0].Item.Position - (refSub?.HiddenSubPosition ?? Vector2.Zero)) <
Vector2.DistanceSquared(nodes[nodes.Count - 1], connections[0].Item.Position - (refSub?.HiddenSubPosition ?? Vector2.Zero)))
{
newNodeIndex = nodes.Count;
}
}
else if (connections[1] != null && connections[1] != newConnection)
{
if (Vector2.DistanceSquared(nodes[0], connections[1].Item.Position - (refSub?.HiddenSubPosition ?? Vector2.Zero)) <
Vector2.DistanceSquared(nodes[nodes.Count - 1], connections[1].Item.Position - (refSub?.HiddenSubPosition ?? Vector2.Zero)))
{
newNodeIndex = nodes.Count;
}
}
else if (Vector2.DistanceSquared(nodes[nodes.Count - 1], nodePos) < Vector2.DistanceSquared(nodes[0], nodePos))
{
newNodeIndex = nodes.Count;
}
}
if (newNodeIndex == 0 && nodes.Count > 1)
{
nodes.Insert(0, nodePos);
}
else
{
nodes.Add(nodePos);
}
}
public override void Equip(Character character)
{
if (shouldClearConnections) { ClearConnections(character); }
@@ -298,7 +335,7 @@ namespace Barotrauma.Items.Components
IsActive = false;
}
public override void Drop(Character dropper)
public override void Drop(Character dropper, bool setTransform = true)
{
if (shouldClearConnections) { ClearConnections(dropper); }
IsActive = false;
@@ -528,6 +565,7 @@ namespace Barotrauma.Items.Components
sections.Add(new WireSection(nodes[i], nodes[i + 1]));
}
Drawable = IsActive || sections.Count > 0;
Length = sections.Count > 0 ? sections.Sum(s => s.Length) : 0;
CalculateExtents();
}