38f1ddb...178a853: v0.8.9.1, removed content folder
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
@@ -14,7 +15,7 @@ namespace Barotrauma.Items.Components
|
||||
//the output is sent if both inputs have received a signal within the timeframe
|
||||
protected float timeFrame;
|
||||
|
||||
[InGameEditable, Serialize(0.0f, true)]
|
||||
[InGameEditable(DecimalCount = 2), Serialize(0.0f, true)]
|
||||
public float TimeFrame
|
||||
{
|
||||
get { return timeFrame; }
|
||||
@@ -46,16 +47,16 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
switch (connection.Name)
|
||||
{
|
||||
case "signal_in1":
|
||||
float.TryParse(signal, out receivedSignal[0]);
|
||||
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
|
||||
timeSinceReceived[0] = 0.0f;
|
||||
break;
|
||||
case "signal_in2":
|
||||
float.TryParse(signal, out receivedSignal[1]);
|
||||
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
|
||||
timeSinceReceived[1] = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Barotrauma.Items.Components
|
||||
//the output is sent if both inputs have received a signal within the timeframe
|
||||
protected float timeFrame;
|
||||
|
||||
[InGameEditable, Serialize(0.0f, true)]
|
||||
[InGameEditable(DecimalCount = 2), Serialize(0.0f, true)]
|
||||
public float TimeFrame
|
||||
{
|
||||
get { return timeFrame; }
|
||||
@@ -59,7 +59,7 @@ namespace Barotrauma.Items.Components
|
||||
item.SendSignal(0, signalOut, "signal_out", null);
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
switch (connection.Name)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
@@ -12,14 +13,16 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public readonly string Name;
|
||||
|
||||
public Wire[] Wires;
|
||||
private Wire[] wires;
|
||||
public IEnumerable<Wire> Wires
|
||||
{
|
||||
get { return wires; }
|
||||
}
|
||||
|
||||
private Item item;
|
||||
|
||||
public readonly bool IsOutput;
|
||||
|
||||
private static Wire draggingConnected;
|
||||
|
||||
|
||||
public readonly List<StatusEffect> effects;
|
||||
|
||||
public readonly ushort[] wireId;
|
||||
@@ -30,45 +33,45 @@ namespace Barotrauma.Items.Components
|
||||
private set;
|
||||
}
|
||||
|
||||
private bool recipientsDirty = true;
|
||||
private List<Connection> recipients = new List<Connection>();
|
||||
public List<Connection> Recipients
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Connection> recipients = new List<Connection>();
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (Wires[i] == null) continue;
|
||||
Connection recipient = Wires[i].OtherConnection(this);
|
||||
if (recipient != null) recipients.Add(recipient);
|
||||
}
|
||||
if (recipientsDirty) RefreshRecipients();
|
||||
return recipients;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Item Item
|
||||
{
|
||||
get { return item; }
|
||||
}
|
||||
|
||||
public Connection(XElement element, Item item)
|
||||
public ConnectionPanel ConnectionPanel
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Connection(XElement element, ConnectionPanel connectionPanel)
|
||||
{
|
||||
|
||||
#if CLIENT
|
||||
if (connector == null)
|
||||
{
|
||||
panelTexture = Sprite.LoadTexture("Content/Items/connectionpanel.png");
|
||||
|
||||
connector = new Sprite(panelTexture, new Rectangle(470, 102, 19, 43), Vector2.Zero, 0.0f);
|
||||
connector.Origin = new Vector2(9.5f, 10.0f);
|
||||
|
||||
wireVertical = new Sprite(panelTexture, new Rectangle(408, 1, 11, 102), Vector2.Zero, 0.0f);
|
||||
}
|
||||
connector = GUI.Style.GetComponentStyle("ConnectionPanelConnector").Sprites[GUIComponent.ComponentState.None][0].Sprite;
|
||||
wireVertical = GUI.Style.GetComponentStyle("ConnectionPanelWire").Sprites[GUIComponent.ComponentState.None][0].Sprite;
|
||||
connectionSprite = GUI.Style.GetComponentStyle("ConnectionPanelConnection").Sprites[GUIComponent.ComponentState.None][0].Sprite;
|
||||
connectionSpriteHighlight = GUI.Style.GetComponentStyle("ConnectionPanelConnection").Sprites[GUIComponent.ComponentState.Hover][0].Sprite;
|
||||
screwSprites = GUI.Style.GetComponentStyle("ConnectionPanelScrew").Sprites[GUIComponent.ComponentState.None].Select(s => s.Sprite).ToList();
|
||||
}
|
||||
#endif
|
||||
ConnectionPanel = connectionPanel;
|
||||
item = connectionPanel.Item;
|
||||
|
||||
this.item = item;
|
||||
|
||||
//recipient = new Connection[MaxLinked];
|
||||
Wires = new Wire[MaxLinked];
|
||||
wires = new Wire[MaxLinked];
|
||||
|
||||
IsOutput = (element.Name.ToString() == "output");
|
||||
Name = element.GetAttributeString("name", (IsOutput) ? "output" : "input");
|
||||
@@ -98,37 +101,48 @@ namespace Barotrauma.Items.Components
|
||||
break;
|
||||
|
||||
case "statuseffect":
|
||||
effects.Add(StatusEffect.Load(subElement));
|
||||
effects.Add(StatusEffect.Load(subElement, item.Name + ", connection " + Name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshRecipients()
|
||||
{
|
||||
recipients.Clear();
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (wires[i] == null) continue;
|
||||
Connection recipient = wires[i].OtherConnection(this);
|
||||
if (recipient != null) recipients.Add(recipient);
|
||||
}
|
||||
recipientsDirty = false;
|
||||
}
|
||||
|
||||
public int FindEmptyIndex()
|
||||
{
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (Wires[i] == null) return i;
|
||||
if (wires[i] == null) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//public int FindLinkIndex(Item item)
|
||||
//{
|
||||
// for (int i = 0; i < MaxLinked; i++)
|
||||
// {
|
||||
// if (item == null && recipient[i] == null) return i;
|
||||
// if (recipient[i]!=null && recipient[i].item == item) return i;
|
||||
// }
|
||||
// return -1;
|
||||
//}
|
||||
public int FindWireIndex(Wire wire)
|
||||
{
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (wires[i] == wire) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int FindWireIndex(Item wireItem)
|
||||
{
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (Wires[i] == null && wireItem == null) return i;
|
||||
if (Wires[i] != null && Wires[i].Item == wireItem) return i;
|
||||
if (wires[i] == null && wireItem == null) return i;
|
||||
if (wires[i] != null && wires[i].Item == wireItem) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -137,26 +151,27 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (Wires[i] == null)
|
||||
if (wires[i] == null)
|
||||
{
|
||||
Wires[i] = wire;
|
||||
SetWire(i, wire);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddLink(int index, Wire wire)
|
||||
public void SetWire(int index, Wire wire)
|
||||
{
|
||||
Wires[index] = wire;
|
||||
wires[index] = wire;
|
||||
recipientsDirty = true;
|
||||
}
|
||||
|
||||
public void SendSignal(int stepsTaken, string signal, Item source, Character sender, float power)
|
||||
public void SendSignal(int stepsTaken, string signal, Item source, Character sender, float power, float signalStrength = 1.0f)
|
||||
{
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (Wires[i] == null) continue;
|
||||
if (wires[i] == null) continue;
|
||||
|
||||
Connection recipient = Wires[i].OtherConnection(this);
|
||||
Connection recipient = wires[i].OtherConnection(this);
|
||||
if (recipient == null) continue;
|
||||
if (recipient.item == this.item || recipient.item == source) continue;
|
||||
|
||||
@@ -167,12 +182,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (ItemComponent ic in recipient.item.components)
|
||||
{
|
||||
ic.ReceiveSignal(stepsTaken, signal, recipient, item, sender, power);
|
||||
ic.ReceiveSignal(stepsTaken, signal, recipient, source, sender, power, signalStrength);
|
||||
}
|
||||
|
||||
bool broken = recipient.Item.Condition <= 0.0f;
|
||||
foreach (StatusEffect effect in recipient.effects)
|
||||
{
|
||||
recipient.item.ApplyStatusEffect(effect, ActionType.OnUse, 1.0f);
|
||||
if (broken && effect.type != ActionType.OnBroken) continue;
|
||||
recipient.Item.ApplyStatusEffect(effect, ActionType.OnUse, 1.0f, null, null, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,10 +198,11 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (Wires[i] == null) continue;
|
||||
if (wires[i] == null) continue;
|
||||
|
||||
Wires[i].RemoveConnection(this);
|
||||
Wires[i] = null;
|
||||
wires[i].RemoveConnection(this);
|
||||
wires[i] = null;
|
||||
recipientsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,15 +214,16 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (wireId[i] == 0) continue;
|
||||
|
||||
Item wireItem = MapEntity.FindEntityByID(wireId[i]) as Item;
|
||||
Item wireItem = Entity.FindEntityByID(wireId[i]) as Item;
|
||||
|
||||
if (wireItem == null) continue;
|
||||
Wires[i] = wireItem.GetComponent<Wire>();
|
||||
wires[i] = wireItem.GetComponent<Wire>();
|
||||
recipientsDirty = true;
|
||||
|
||||
if (Wires[i] != null)
|
||||
if (wires[i] != null)
|
||||
{
|
||||
if (Wires[i].Item.body != null) Wires[i].Item.body.Enabled = false;
|
||||
Wires[i].Connect(this, false, false);
|
||||
if (wires[i].Item.body != null) wires[i].Item.body.Enabled = false;
|
||||
wires[i].Connect(this, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -214,7 +233,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
XElement newElement = new XElement(IsOutput ? "output" : "input", new XAttribute("name", Name));
|
||||
|
||||
Array.Sort(Wires, delegate (Wire wire1, Wire wire2)
|
||||
Array.Sort(wires, delegate (Wire wire1, Wire wire2)
|
||||
{
|
||||
if (wire1 == null) return 1;
|
||||
if (wire2 == null) return -1;
|
||||
@@ -223,10 +242,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (Wires[i] == null) continue;
|
||||
if (wires[i] == null) continue;
|
||||
|
||||
newElement.Add(new XElement("link",
|
||||
new XAttribute("w", Wires[i].Item.ID.ToString())));
|
||||
new XAttribute("w", wires[i].Item.ID.ToString())));
|
||||
}
|
||||
|
||||
parentElement.Add(newElement);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Barotrauma.Networking;
|
||||
using FarseerPhysics;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -10,8 +11,6 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class ConnectionPanel : ItemComponent, IServerSerializable, IClientSerializable
|
||||
{
|
||||
public static Wire HighlightedWire;
|
||||
|
||||
public List<Connection> Connections;
|
||||
|
||||
private Character user;
|
||||
@@ -23,6 +22,13 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
//connection panels can't be deactivated
|
||||
public override bool IsActive
|
||||
{
|
||||
get { return true; }
|
||||
set { /*do nothing*/ }
|
||||
}
|
||||
|
||||
public ConnectionPanel(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
@@ -33,17 +39,20 @@ namespace Barotrauma.Items.Components
|
||||
switch (subElement.Name.ToString())
|
||||
{
|
||||
case "input":
|
||||
Connections.Add(new Connection(subElement, item));
|
||||
Connections.Add(new Connection(subElement, this));
|
||||
break;
|
||||
case "output":
|
||||
Connections.Add(new Connection(subElement, item));
|
||||
Connections.Add(new Connection(subElement, this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IsActive = true;
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element);
|
||||
|
||||
public override void OnMapLoaded()
|
||||
{
|
||||
foreach (Connection c in Connections)
|
||||
@@ -52,9 +61,57 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnItemLoaded()
|
||||
{
|
||||
if (item.body != null)
|
||||
{
|
||||
var holdable = item.GetComponent<Holdable>();
|
||||
if (holdable == null || !holdable.Attachable)
|
||||
{
|
||||
DebugConsole.ThrowError("Item \"" + item.Name + "\" has a ConnectionPanel component," +
|
||||
" but cannot be wired because it has an active physics body that cannot be attached to a wall." +
|
||||
" Remove the physics body or add a Holdable component with the Attachable attribute set to true.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveConnectedWires(Vector2 amount)
|
||||
{
|
||||
Vector2 wireNodeOffset = item.Submarine == null ? Vector2.Zero : item.Submarine.HiddenSubPosition + amount;
|
||||
foreach (Connection c in Connections)
|
||||
{
|
||||
foreach (Wire wire in c.Wires)
|
||||
{
|
||||
if (wire == null) continue;
|
||||
#if CLIENT
|
||||
if (wire.Item.IsSelected) continue;
|
||||
#endif
|
||||
var wireNodes = wire.GetNodes();
|
||||
if (wireNodes.Count == 0) continue;
|
||||
|
||||
if (Submarine.RectContains(item.Rect, wireNodes[0] + wireNodeOffset))
|
||||
{
|
||||
wire.MoveNode(0, amount);
|
||||
}
|
||||
else if (Submarine.RectContains(item.Rect, wireNodes[wireNodes.Count - 1] + wireNodeOffset))
|
||||
{
|
||||
wire.MoveNode(wireNodes.Count - 1, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
if (user != null && user.SelectedConstruction != item) user = null;
|
||||
if (user == null || user.SelectedConstruction != item)
|
||||
{
|
||||
user = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.Enabled || !HasRequiredItems(user, addMessage: false)) { return; }
|
||||
|
||||
user.AnimController.UpdateUseItem(true, item.WorldPosition + new Vector2(0.0f, 100.0f) * (((float)Timing.TotalTime / 10.0f) % 0.1f));
|
||||
}
|
||||
|
||||
public override bool Select(Character picker)
|
||||
@@ -70,10 +127,10 @@ namespace Barotrauma.Items.Components
|
||||
IsActive = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override bool Use(float deltaTime, Character character = null)
|
||||
{
|
||||
if (character == null || character!=user) return false;
|
||||
if (character == null || character != user) return false;
|
||||
|
||||
var powered = item.GetComponent<Powered>();
|
||||
if (powered != null)
|
||||
@@ -82,7 +139,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
float degreeOfSuccess = DegreeOfSuccess(character);
|
||||
if (Rand.Range(0.0f, 50.0f) < degreeOfSuccess) return false;
|
||||
if (Rand.Range(0.0f, 0.5f) < degreeOfSuccess) return false;
|
||||
|
||||
character.SetStun(5.0f);
|
||||
|
||||
@@ -94,7 +151,7 @@ namespace Barotrauma.Items.Components
|
||||
public override void Load(XElement element)
|
||||
{
|
||||
base.Load(element);
|
||||
|
||||
|
||||
List<Connection> loadedConnections = new List<Connection>();
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
@@ -102,15 +159,15 @@ namespace Barotrauma.Items.Components
|
||||
switch (subElement.Name.ToString())
|
||||
{
|
||||
case "input":
|
||||
loadedConnections.Add(new Connection(subElement, item));
|
||||
loadedConnections.Add(new Connection(subElement, this));
|
||||
break;
|
||||
case "output":
|
||||
loadedConnections.Add(new Connection(subElement, item));
|
||||
loadedConnections.Add(new Connection(subElement, this));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i<loadedConnections.Count && i<Connections.Count; i++)
|
||||
|
||||
for (int i = 0; i < loadedConnections.Count && i < Connections.Count; i++)
|
||||
{
|
||||
loadedConnections[i].wireId.CopyTo(Connections[i].wireId, 0);
|
||||
}
|
||||
@@ -157,9 +214,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (Connection connection in Connections)
|
||||
{
|
||||
for (int i = 0; i < Connection.MaxLinked; i++)
|
||||
foreach (Wire wire in connection.Wires)
|
||||
{
|
||||
msg.Write(connection.Wires[i]?.Item == null ? (ushort)0 : connection.Wires[i].Item.ID);
|
||||
msg.Write(wire?.Item == null ? (ushort)0 : wire.Item.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,8 +228,7 @@ namespace Barotrauma.Items.Components
|
||||
//read wire IDs for each connection
|
||||
for (int i = 0; i < Connections.Count; i++)
|
||||
{
|
||||
wires[i] = new List<Wire>();
|
||||
|
||||
wires[i] = new List<Wire>();
|
||||
for (int j = 0; j < Connection.MaxLinked; j++)
|
||||
{
|
||||
ushort wireId = msg.ReadUInt16();
|
||||
@@ -212,9 +268,10 @@ namespace Barotrauma.Items.Components
|
||||
//go through existing wire links
|
||||
for (int i = 0; i < Connections.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < Connection.MaxLinked; j++)
|
||||
int j = -1;
|
||||
foreach (Wire existingWire in Connections[i].Wires)
|
||||
{
|
||||
Wire existingWire = Connections[i].Wires[j];
|
||||
j++;
|
||||
if (existingWire == null) continue;
|
||||
|
||||
//existing wire not in the list of new wires -> disconnect it
|
||||
@@ -263,9 +320,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
Connections[i].Wires[j] = null;
|
||||
}
|
||||
|
||||
Connections[i].SetWire(j, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,6 +358,6 @@ namespace Barotrauma.Items.Components
|
||||
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
{
|
||||
ClientWrite(msg, extraData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
using Barotrauma.Networking;
|
||||
using Lidgren.Network;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class CustomInterface : ItemComponent, IClientSerializable, IServerSerializable
|
||||
{
|
||||
class CustomInterfaceElement
|
||||
{
|
||||
public bool ContinuousSignal;
|
||||
public bool State;
|
||||
public string Label, Connection, Signal;
|
||||
|
||||
public CustomInterfaceElement(XElement element)
|
||||
{
|
||||
Label = element.GetAttributeString("text", "");
|
||||
Connection = element.GetAttributeString("connection", "");
|
||||
Signal = element.GetAttributeString("signal", "1");
|
||||
}
|
||||
}
|
||||
|
||||
private string[] labels;
|
||||
[Serialize("", true), Editable()]
|
||||
public string Labels
|
||||
{
|
||||
get { return string.Join(",", labels); }
|
||||
set
|
||||
{
|
||||
if (value == null) { return; }
|
||||
string[] splitValues = value == "" ? new string[0] : value.Split(',');
|
||||
if (customInterfaceElementList.Count > 0)
|
||||
{
|
||||
UpdateLabels(splitValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
private string[] signals;
|
||||
[Serialize("", true), Editable()]
|
||||
public string Signals
|
||||
{
|
||||
//use semicolon as a separator because comma may be needed in the signals (for color or vector values for example)
|
||||
//kind of hacky, we should probably add support for (string) arrays to SerializableEntityEditor so this wouldn't be needed
|
||||
get { return signals == null ? "" : string.Join(";", signals); }
|
||||
set
|
||||
{
|
||||
if (value == null) { return; }
|
||||
string[] splitValues = value == "" ? new string[0] : value.Split(';');
|
||||
if (customInterfaceElementList.Count > 0)
|
||||
{
|
||||
signals = new string[customInterfaceElementList.Count];
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
signals[i] = i < splitValues.Length ? splitValues[i] : customInterfaceElementList[i].Signal;
|
||||
customInterfaceElementList[i].Signal = signals[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<CustomInterfaceElement> customInterfaceElementList = new List<CustomInterfaceElement>();
|
||||
|
||||
public CustomInterface(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "button":
|
||||
var button = new CustomInterfaceElement(subElement)
|
||||
{
|
||||
ContinuousSignal = false
|
||||
};
|
||||
if (string.IsNullOrEmpty(button.Label))
|
||||
{
|
||||
button.Label = "Signal out " + customInterfaceElementList.Count(e => !e.ContinuousSignal);
|
||||
}
|
||||
customInterfaceElementList.Add(button);
|
||||
break;
|
||||
case "tickbox":
|
||||
var tickBox = new CustomInterfaceElement(subElement)
|
||||
{
|
||||
ContinuousSignal = true
|
||||
};
|
||||
if (string.IsNullOrEmpty(tickBox.Label))
|
||||
{
|
||||
tickBox.Label = "Signal out " + customInterfaceElementList.Count(e => !e.ContinuousSignal);
|
||||
}
|
||||
customInterfaceElementList.Add(tickBox);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
IsActive = true;
|
||||
InitProjSpecific(element);
|
||||
Labels = element.GetAttributeString("labels", "");
|
||||
Signals = element.GetAttributeString("signals", "");
|
||||
}
|
||||
|
||||
private void UpdateLabels(string[] newLabels)
|
||||
{
|
||||
labels = new string[customInterfaceElementList.Count];
|
||||
for (int i = 0; i < labels.Length; i++)
|
||||
{
|
||||
labels[i] = i < newLabels.Length ? newLabels[i] : customInterfaceElementList[i].Label;
|
||||
customInterfaceElementList[i].Label = labels[i];
|
||||
}
|
||||
UpdateLabelsProjSpecific();
|
||||
}
|
||||
|
||||
partial void UpdateLabelsProjSpecific();
|
||||
|
||||
partial void InitProjSpecific(XElement element);
|
||||
|
||||
private void ButtonClicked(CustomInterfaceElement btnElement)
|
||||
{
|
||||
if (btnElement == null) return;
|
||||
item.SendSignal(0, btnElement.Signal, btnElement.Connection, sender: null, source: item);
|
||||
}
|
||||
|
||||
private void TickBoxToggled(CustomInterfaceElement tickBoxElement, bool state)
|
||||
{
|
||||
if (tickBoxElement == null) return;
|
||||
tickBoxElement.State = state;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
foreach (CustomInterfaceElement ciElement in customInterfaceElementList)
|
||||
{
|
||||
if (!ciElement.ContinuousSignal) { continue; }
|
||||
//TODO: allow changing output when a tickbox is not selected
|
||||
item.SendSignal(0, ciElement.State ? ciElement.Signal : "0", ciElement.Connection, sender: null, source: item);
|
||||
}
|
||||
}
|
||||
|
||||
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c)
|
||||
{
|
||||
bool[] elementStates = new bool[customInterfaceElementList.Count];
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
elementStates[i] = msg.ReadBoolean();
|
||||
}
|
||||
|
||||
CustomInterfaceElement clickedButton = null;
|
||||
if (item.CanClientAccess(c))
|
||||
{
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
if (customInterfaceElementList[i].ContinuousSignal)
|
||||
{
|
||||
TickBoxToggled(customInterfaceElementList[i], elementStates[i]);
|
||||
}
|
||||
else if (elementStates[i])
|
||||
{
|
||||
clickedButton = customInterfaceElementList[i];
|
||||
ButtonClicked(customInterfaceElementList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//notify all clients of the new state
|
||||
GameMain.Server.CreateEntityEvent(item, new object[]
|
||||
{
|
||||
NetEntityEvent.Type.ComponentState,
|
||||
item.components.IndexOf(this),
|
||||
clickedButton
|
||||
});
|
||||
|
||||
item.CreateServerEvent(this);
|
||||
}
|
||||
|
||||
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
{
|
||||
//extradata contains an array of buttons clicked by a client (or nothing if nothing was clicked)
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
if (customInterfaceElementList[i].ContinuousSignal)
|
||||
{
|
||||
msg.Write(customInterfaceElementList[i].State);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Write(extraData != null && extraData.Any(d => d as CustomInterfaceElement == customInterfaceElementList[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,29 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class DelayComponent : ItemComponent
|
||||
{
|
||||
class DelayedSignal
|
||||
{
|
||||
public readonly string Signal;
|
||||
public readonly float SignalStrength;
|
||||
public float SendTimer;
|
||||
|
||||
public DelayedSignal(string signal, float signalStrength, float sendTimer)
|
||||
{
|
||||
Signal = signal;
|
||||
SignalStrength = signalStrength;
|
||||
SendTimer = sendTimer;
|
||||
}
|
||||
}
|
||||
|
||||
const int SignalQueueSize = 500;
|
||||
|
||||
private Queue<Pair<string, float>> signalQueue;
|
||||
private Queue<DelayedSignal> signalQueue;
|
||||
|
||||
[InGameEditable(MinValueFloat = 0.0f, MaxValueFloat = 60.0f), Serialize(1.0f, true)]
|
||||
[InGameEditable(MinValueFloat = 0.0f, MaxValueFloat = 60.0f, DecimalCount = 2), Serialize(1.0f, true)]
|
||||
public float Delay
|
||||
{
|
||||
get;
|
||||
@@ -26,10 +37,17 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[InGameEditable(ToolTip = "Should the component discard previously received signals when the incoming signal changes."), Serialize(false, true)]
|
||||
public bool ResetWhenDifferentSignalReceived
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public DelayComponent(Item item, XElement element)
|
||||
: base (item, element)
|
||||
{
|
||||
signalQueue = new Queue<Pair<string, float>>();
|
||||
signalQueue = new Queue<DelayedSignal>();
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
@@ -37,24 +55,28 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (var val in signalQueue)
|
||||
{
|
||||
val.Second -= deltaTime;
|
||||
val.SendTimer -= deltaTime;
|
||||
}
|
||||
|
||||
while (signalQueue.Count > 0 && signalQueue.Peek().Second <= 0.0f)
|
||||
while (signalQueue.Count > 0 && signalQueue.Peek().SendTimer <= 0.0f)
|
||||
{
|
||||
var signalOut = signalQueue.Dequeue();
|
||||
item.SendSignal(0, signalOut.First, "signal_out", null);
|
||||
item.SendSignal(0, signalOut.Signal, "signal_out", null, signalStrength: signalOut.SignalStrength);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f)
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
switch (connection.Name)
|
||||
{
|
||||
case "signal_in":
|
||||
if (signalQueue.Count >= SignalQueueSize) return;
|
||||
if (ResetWhenSignalReceived) signalQueue.Clear();
|
||||
signalQueue.Enqueue(Pair<string, float>.Create(signal, Delay));
|
||||
if (ResetWhenDifferentSignalReceived && signalQueue.Count > 0 && signalQueue.Peek().Signal != signal)
|
||||
{
|
||||
signalQueue.Clear();
|
||||
}
|
||||
signalQueue.Enqueue(new DelayedSignal(signal, signalStrength, Delay));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,24 +13,24 @@ namespace Barotrauma.Items.Components
|
||||
partial class LightComponent : Powered, IServerSerializable, IDrawableComponent
|
||||
{
|
||||
private Color lightColor;
|
||||
|
||||
private float range;
|
||||
|
||||
private float lightBrightness;
|
||||
|
||||
private float blinkFrequency;
|
||||
private float range;
|
||||
private float flicker;
|
||||
|
||||
private bool castShadows;
|
||||
private bool drawBehindSubs;
|
||||
|
||||
private float blinkTimer;
|
||||
|
||||
public PhysicsBody ParentBody;
|
||||
|
||||
[Editable(0.0f, 2048.0f), Serialize(100.0f, true)]
|
||||
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 2048.0f), Serialize(100.0f, true)]
|
||||
public float Range
|
||||
{
|
||||
get { return range; }
|
||||
set
|
||||
{
|
||||
range = MathHelper.Clamp(value, 0.0f, 2048.0f);
|
||||
range = MathHelper.Clamp(value, 0.0f, 4096.0f);
|
||||
#if CLIENT
|
||||
if (light != null) light.Range = range;
|
||||
#endif
|
||||
@@ -53,6 +53,20 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Editable(ToolTip = "Lights drawn behind submarines don't cast any shadows and are much faster to draw than shadow-casting lights. "+
|
||||
"It's recommended to enable this on decorative lights outside the submarine's hull."), Serialize(false, true)]
|
||||
public bool DrawBehindSubs
|
||||
{
|
||||
get { return drawBehindSubs; }
|
||||
set
|
||||
{
|
||||
drawBehindSubs = value;
|
||||
#if CLIENT
|
||||
if (light != null) light.IsBackground = drawBehindSubs;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, true)]
|
||||
public bool IsOn
|
||||
{
|
||||
@@ -76,6 +90,16 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Editable, Serialize(0.0f, true)]
|
||||
public float BlinkFrequency
|
||||
{
|
||||
get { return blinkFrequency; }
|
||||
set
|
||||
{
|
||||
blinkFrequency = MathHelper.Clamp(value, 0.0f, 60.0f);
|
||||
}
|
||||
}
|
||||
|
||||
[InGameEditable, Serialize("1.0,1.0,1.0,1.0", true)]
|
||||
public Color LightColor
|
||||
{
|
||||
@@ -84,7 +108,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
lightColor = value;
|
||||
#if CLIENT
|
||||
if (light != null) light.Color = lightColor;
|
||||
if (light != null) light.Color = IsActive ? lightColor : Color.Transparent;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -118,10 +142,13 @@ namespace Barotrauma.Items.Components
|
||||
: base (item, element)
|
||||
{
|
||||
#if CLIENT
|
||||
light = new LightSource(element);
|
||||
light.ParentSub = item.CurrentHull == null ? null : item.CurrentHull.Submarine;
|
||||
light.Position = item.Position;
|
||||
light.CastShadows = castShadows;
|
||||
light = new LightSource(element)
|
||||
{
|
||||
ParentSub = item.CurrentHull?.Submarine,
|
||||
Position = item.Position,
|
||||
CastShadows = castShadows,
|
||||
IsBackground = drawBehindSubs
|
||||
};
|
||||
#endif
|
||||
|
||||
IsActive = IsOn;
|
||||
@@ -130,6 +157,7 @@ namespace Barotrauma.Items.Components
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
UpdateOnActiveEffects(deltaTime);
|
||||
if (AITarget != null) AITarget.Enabled = voltage > minVoltage || powerConsumption <= 0.0f;
|
||||
|
||||
#if CLIENT
|
||||
light.ParentSub = item.Submarine;
|
||||
@@ -176,7 +204,11 @@ namespace Barotrauma.Items.Components
|
||||
if (Rand.Range(0.0f, 1.0f) < 0.05f && voltage < Rand.Range(0.0f, minVoltage))
|
||||
{
|
||||
#if CLIENT
|
||||
if (voltage > 0.1f) sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 400.0f, item.WorldPosition);
|
||||
if (voltage > 0.1f && sparkSounds.Count > 0)
|
||||
{
|
||||
var sparkSound = sparkSounds[Rand.Int(sparkSounds.Count)];
|
||||
SoundPlayer.PlaySound(sparkSound.Sound, sparkSound.Volume, sparkSound.Range, item.WorldPosition, item.CurrentHull);
|
||||
}
|
||||
#endif
|
||||
lightBrightness = 0.0f;
|
||||
}
|
||||
@@ -185,11 +217,26 @@ namespace Barotrauma.Items.Components
|
||||
lightBrightness = MathHelper.Lerp(lightBrightness, Math.Min(voltage, 1.0f), 0.1f);
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
light.Color = lightColor * lightBrightness * (1.0f-Rand.Range(0.0f,Flicker));
|
||||
light.Range = range * (float)Math.Sqrt(lightBrightness);
|
||||
#endif
|
||||
if (blinkFrequency > 0.0f)
|
||||
{
|
||||
blinkTimer = (blinkTimer + deltaTime * blinkFrequency) % 1.0f;
|
||||
}
|
||||
|
||||
if (blinkTimer > 0.5f)
|
||||
{
|
||||
#if CLIENT
|
||||
light.Color = Color.Transparent;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CLIENT
|
||||
light.Color = lightColor * lightBrightness * (1.0f - Rand.Range(0.0f, Flicker));
|
||||
light.Range = range;
|
||||
#endif
|
||||
item.SightRange = Math.Max(range * (float)Math.Sqrt(lightBrightness), item.SightRange);
|
||||
}
|
||||
|
||||
voltage = 0.0f;
|
||||
}
|
||||
|
||||
@@ -210,9 +257,9 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
base.ReceiveSignal(stepsTaken, signal, connection, source, sender, power);
|
||||
base.ReceiveSignal(stepsTaken, signal, connection, source, sender, power, signalStrength);
|
||||
|
||||
switch (connection.Name)
|
||||
{
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class MotionSensor : ItemComponent
|
||||
partial class MotionSensor : ItemComponent
|
||||
{
|
||||
private const float UpdateInterval = 0.1f;
|
||||
|
||||
@@ -13,17 +14,54 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool motionDetected;
|
||||
|
||||
private float range;
|
||||
private float rangeX, rangeY;
|
||||
|
||||
private Vector2 detectOffset;
|
||||
|
||||
private float updateTimer;
|
||||
|
||||
[InGameEditable, Serialize(0.0f, true)]
|
||||
public float Range
|
||||
[Serialize(false, false)]
|
||||
public bool MotionDetected
|
||||
{
|
||||
get { return range; }
|
||||
get { return motionDetected; }
|
||||
set { motionDetected = value; }
|
||||
}
|
||||
|
||||
[Serialize(false, true), Editable]
|
||||
public bool OnlyHumans
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[InGameEditable, Serialize(0.0f, true)]
|
||||
public float RangeX
|
||||
{
|
||||
get { return rangeX; }
|
||||
set
|
||||
{
|
||||
range = MathHelper.Clamp(value, 0.0f, 500.0f);
|
||||
rangeX = MathHelper.Clamp(value, 0.0f, 1000.0f);
|
||||
}
|
||||
}
|
||||
[InGameEditable, Serialize(0.0f, true)]
|
||||
public float RangeY
|
||||
{
|
||||
get { return rangeY; }
|
||||
set
|
||||
{
|
||||
rangeY = MathHelper.Clamp(value, 0.0f, 1000.0f);
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize("0,0", true), Editable(ToolTip = "The position to detect the movement at relative to the item. For example, 0,100 would detect movement 100 units above the item.")]
|
||||
public Vector2 DetectOffset
|
||||
{
|
||||
get { return detectOffset; }
|
||||
set
|
||||
{
|
||||
detectOffset = value;
|
||||
detectOffset.X = MathHelper.Clamp(value.X, -rangeX, rangeX);
|
||||
detectOffset.Y = MathHelper.Clamp(value.Y, -rangeY, rangeY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,10 +79,17 @@ namespace Barotrauma.Items.Components
|
||||
set { falseOutput = value; }
|
||||
}
|
||||
|
||||
|
||||
public MotionSensor(Item item, XElement element)
|
||||
: base (item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
|
||||
//backwards compatibility
|
||||
if (element.Attribute("range") != null)
|
||||
{
|
||||
rangeX = rangeY = element.GetAttributeFloat("range", 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
@@ -67,16 +112,31 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 detectPos = item.WorldPosition + detectOffset;
|
||||
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);
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (Math.Abs(c.WorldPosition.X - item.WorldPosition.X) < range &&
|
||||
Math.Abs(c.WorldPosition.Y - item.WorldPosition.Y) < range)
|
||||
{
|
||||
if (!c.AnimController.Limbs.Any(l => l.body.FarseerBody.Awake)) continue;
|
||||
if (OnlyHumans && c.ConfigPath != Character.HumanConfigFile) { continue; }
|
||||
|
||||
motionDetected = true;
|
||||
break;
|
||||
}
|
||||
//do a rough check based on the position of the character's collider first
|
||||
//before the more accurate limb-based check
|
||||
if (Math.Abs(c.WorldPosition.X - detectPos.X) > broadRangeX || Math.Abs(c.WorldPosition.Y - detectPos.Y) > broadRangeY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
if (limb.LinearVelocity.LengthSquared() <= 0.001f) continue;
|
||||
if (MathUtils.CircleIntersectsRectangle(limb.WorldPosition, ConvertUnits.ToDisplayUnits(limb.body.GetMaxExtent()), detectRect))
|
||||
{
|
||||
motionDetected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ namespace Barotrauma.Items.Components
|
||||
: base (item, element)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
if (connection.Name != "signal_in") return;
|
||||
|
||||
item.SendSignal(stepsTaken, signal=="0" ? "1" : "0", "signal_out", sender);
|
||||
|
||||
item.SendSignal(stepsTaken, signal == "0" ? "1" : "0", "signal_out", sender, 0.0f, source, signalStrength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[InGameEditable, Serialize(1.0f, true)]
|
||||
[InGameEditable(DecimalCount = 2), Serialize(1.0f, true)]
|
||||
public float Frequency
|
||||
{
|
||||
get { return frequency; }
|
||||
@@ -71,14 +71,14 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f)
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
switch (connection.Name)
|
||||
{
|
||||
case "set_frequency":
|
||||
case "frequency_in":
|
||||
float newFrequency;
|
||||
if (float.TryParse(signal, out newFrequency))
|
||||
if (float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out newFrequency))
|
||||
{
|
||||
Frequency = newFrequency;
|
||||
}
|
||||
|
||||
@@ -75,18 +75,19 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
string signalOut = previousResult ? Output : FalseOutput;
|
||||
if (ContinuousOutput)
|
||||
{
|
||||
item.SendSignal(0, previousResult ? Output : FalseOutput, "signal_out", null);
|
||||
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(0, signalOut, "signal_out", null); }
|
||||
}
|
||||
else if (!nonContinuousOutputSent)
|
||||
{
|
||||
item.SendSignal(0, previousResult ? Output : FalseOutput, "signal_out", null);
|
||||
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(0, signalOut, "signal_out", null); }
|
||||
nonContinuousOutputSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f)
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
switch (connection.Name)
|
||||
{
|
||||
|
||||
@@ -53,13 +53,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (Math.Min(-currPowerConsumption, PowerLoad) > maxPower) item.Condition = 0.0f;
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
|
||||
{
|
||||
if (connection.IsPower) return;
|
||||
|
||||
if (item.Condition <= 0.0f) return;
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
if (connection.IsPower || item.Condition <= 0.0f) return;
|
||||
|
||||
if (connection.Name.Contains("_in"))
|
||||
{
|
||||
if (!IsOn) return;
|
||||
@@ -68,10 +66,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
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);
|
||||
item.SendSignal(stepsTaken, signal, outConnection, sender, power, source, signalStrength);
|
||||
}
|
||||
else if (connection.Name == "toggle")
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
switch (connection.Name)
|
||||
{
|
||||
@@ -41,7 +41,7 @@ namespace Barotrauma.Items.Components
|
||||
string signalOut = (signal == targetSignal) ? output : falseOutput;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(signalOut)) return;
|
||||
item.SendSignal(stepsTaken, signalOut, "signal_out", sender);
|
||||
item.SendSignal(stepsTaken, signalOut, "signal_out", sender, signalStrength);
|
||||
|
||||
break;
|
||||
case "set_output":
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class SmokeDetector : ItemComponent
|
||||
{
|
||||
[Serialize(50.0f, false)]
|
||||
public float FireSizeThreshold
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public SmokeDetector(Item item, XElement element)
|
||||
: base (item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
item.SendSignal(0, item.CurrentHull != null && item.CurrentHull.FireSources.Any(fs => fs.Size.X > FireSizeThreshold) ? "1" : "0", "signal_out", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,15 +4,50 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
class WaterDetector : ItemComponent
|
||||
{
|
||||
private string output, falseOutput;
|
||||
|
||||
[InGameEditable, Serialize("1", true)]
|
||||
public string Output
|
||||
{
|
||||
get { return output; }
|
||||
set { output = value; }
|
||||
}
|
||||
|
||||
[InGameEditable, Serialize("0", true)]
|
||||
public string FalseOutput
|
||||
{
|
||||
get { return falseOutput; }
|
||||
set { falseOutput = value; }
|
||||
}
|
||||
|
||||
public WaterDetector(Item item, XElement element)
|
||||
: base (item, element)
|
||||
: base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
item.SendSignal(0, item.InWater ? "1" : "0", "signal_out", null);
|
||||
string signalOut = falseOutput;
|
||||
if (item.InWater)
|
||||
{
|
||||
//item in water -> we definitely want to send the True output
|
||||
signalOut = Output;
|
||||
}
|
||||
else if (item.CurrentHull != null)
|
||||
{
|
||||
//item in not water -> check if there's water anywhere within the rect of the item
|
||||
if (item.CurrentHull.Surface > item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height + 1 &&
|
||||
item.CurrentHull.Surface > item.Rect.Y - item.Rect.Height)
|
||||
{
|
||||
signalOut = output;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(signalOut))
|
||||
{
|
||||
item.SendSignal(0, signalOut, "signal_out", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,17 @@ using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class WifiComponent : ItemComponent
|
||||
partial class WifiComponent : ItemComponent
|
||||
{
|
||||
private static List<WifiComponent> list = new List<WifiComponent>();
|
||||
|
||||
private float range;
|
||||
|
||||
private int channel;
|
||||
|
||||
private float chatMsgCooldown;
|
||||
|
||||
private string prevSignal;
|
||||
|
||||
public byte TeamID;
|
||||
|
||||
@@ -33,18 +37,36 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Editable(ToolTip = "If enabled, any signals received by the item are displayed as chat messages in the chatbox of the player holding the item."), Serialize(false, false)]
|
||||
[Editable(ToolTip =
|
||||
"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."), Serialize(false, false)]
|
||||
public bool LinkToChat
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable(ToolTip = "How many seconds have to pass between signals for a message to be displayed in the chatbox. "+
|
||||
"Setting this to a very low value is not recommended, because it may cause an excessive amount of chat messages to be created "+
|
||||
"if there are chat-linked wifi components that transmit a continuous signal."), Serialize(1.0f, true)]
|
||||
public float MinChatMessageInterval
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable(ToolTip = "If set to true, the component will only create chat messages when the received signal changes."), Serialize(false, true)]
|
||||
public bool DiscardDuplicateChatMessages
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public WifiComponent(Item item, XElement element)
|
||||
: base (item, element)
|
||||
{
|
||||
|
||||
list.Add(this);
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
public bool CanTransmit()
|
||||
@@ -59,57 +81,86 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public bool CanReceive(WifiComponent sender)
|
||||
{
|
||||
if (!HasRequiredContainedItems(false)) return false;
|
||||
|
||||
if (sender == null || sender.channel != channel || sender.TeamID != TeamID) return false;
|
||||
if (Vector2.DistanceSquared(item.WorldPosition, sender.item.WorldPosition) > sender.range * sender.range) return false;
|
||||
|
||||
return Vector2.Distance(item.WorldPosition, sender.item.WorldPosition) <= sender.Range;
|
||||
return HasRequiredContainedItems(false);
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power=0.0f)
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
var senderComponent = source.GetComponent<WifiComponent>();
|
||||
chatMsgCooldown -= deltaTime;
|
||||
}
|
||||
|
||||
public void TransmitSignal(int stepsTaken, string signal, Item source, Character sender, bool sendToChat, float signalStrength = 1.0f)
|
||||
{
|
||||
var senderComponent = source?.GetComponent<WifiComponent>();
|
||||
if (senderComponent != null && !CanReceive(senderComponent)) return;
|
||||
|
||||
if (LinkToChat)
|
||||
bool chatMsgSent = false;
|
||||
|
||||
var receivers = GetReceiversInRange();
|
||||
foreach (WifiComponent wifiComp in receivers)
|
||||
{
|
||||
if (item.ParentInventory != null &&
|
||||
item.ParentInventory.Owner != null &&
|
||||
item.ParentInventory.Owner == Character.Controlled &&
|
||||
GameMain.NetworkMember != null)
|
||||
//signal strength diminishes by distance
|
||||
float sentSignalStrength = signalStrength *
|
||||
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);
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
if (senderComponent != null)
|
||||
foreach (Item receiverItem in wifiComp.item.LastSentSignalRecipients)
|
||||
{
|
||||
signal = ChatMessage.ApplyDistanceEffect(item, sender, signal, senderComponent.range);
|
||||
}
|
||||
|
||||
GameMain.NetworkMember.AddChatMessage(signal, ChatMessageType.Radio);
|
||||
}
|
||||
}
|
||||
|
||||
if (connection == null) return;
|
||||
|
||||
switch (connection.Name)
|
||||
{
|
||||
case "signal_in":
|
||||
var receivers = GetReceiversInRange();
|
||||
|
||||
foreach (WifiComponent wifiComp in receivers)
|
||||
{
|
||||
wifiComp.item.SendSignal(stepsTaken, signal, "signal_out", sender);
|
||||
if (source != null)
|
||||
if (!source.LastSentSignalRecipients.Contains(receiverItem))
|
||||
{
|
||||
foreach (Item receiverItem in wifiComp.item.LastSentSignalRecipients)
|
||||
{
|
||||
if (!source.LastSentSignalRecipients.Contains(receiverItem))
|
||||
{
|
||||
source.LastSentSignalRecipients.Add(receiverItem);
|
||||
}
|
||||
}
|
||||
source.LastSentSignalRecipients.Add(receiverItem);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (DiscardDuplicateChatMessages && signal == prevSignal) continue;
|
||||
|
||||
if (LinkToChat && wifiComp.LinkToChat && chatMsgCooldown <= 0.0f && sendToChat)
|
||||
{
|
||||
if (wifiComp.item.ParentInventory != null &&
|
||||
wifiComp.item.ParentInventory.Owner != null &&
|
||||
GameMain.NetworkMember != null)
|
||||
{
|
||||
string chatMsg = signal;
|
||||
if (senderComponent != null)
|
||||
{
|
||||
chatMsg = ChatMessage.ApplyDistanceEffect(chatMsg, 1.0f - sentSignalStrength);
|
||||
}
|
||||
if (chatMsg.Length > ChatMessage.MaxLength) chatMsg = chatMsg.Substring(0, ChatMessage.MaxLength);
|
||||
if (string.IsNullOrEmpty(chatMsg)) continue;
|
||||
|
||||
if (wifiComp.item.ParentInventory.Owner == Character.Controlled)
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
GameMain.NetworkMember.AddChatMessage(signal, ChatMessageType.Radio, source == null ? "" : source.Name);
|
||||
}
|
||||
else if (GameMain.Server != null)
|
||||
{
|
||||
Client recipientClient = GameMain.Server.ConnectedClients.Find(c => c.Character == wifiComp.item.ParentInventory.Owner);
|
||||
if (recipientClient != null)
|
||||
{
|
||||
GameMain.Server.SendDirectChatMessage(
|
||||
ChatMessage.Create(source == null ? "" : source.Name, chatMsg, ChatMessageType.Radio, null), recipientClient);
|
||||
}
|
||||
}
|
||||
chatMsgSent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chatMsgSent) chatMsgCooldown = MinChatMessageInterval;
|
||||
|
||||
prevSignal = signal;
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
if (connection == null || connection.Name != "signal_in") return;
|
||||
TransmitSignal(stepsTaken, signal, source, sender, true, signalStrength);
|
||||
}
|
||||
|
||||
protected override void RemoveComponentSpecific()
|
||||
|
||||
@@ -40,8 +40,18 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool canPlaceNode;
|
||||
private Vector2 newNodePos;
|
||||
|
||||
public bool Hidden, Locked;
|
||||
|
||||
public bool Hidden;
|
||||
|
||||
private bool locked;
|
||||
public bool Locked
|
||||
{
|
||||
get
|
||||
{
|
||||
return locked || connections.Any(c => c != null && c.ConnectionPanel.Locked);
|
||||
}
|
||||
set { locked = value; }
|
||||
}
|
||||
|
||||
public Connection[] Connections
|
||||
{
|
||||
@@ -95,13 +105,14 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (connections[i] == null || connections[i].Item != item) continue;
|
||||
|
||||
for (int n = 0; n < connections[i].Wires.Length; n++)
|
||||
foreach (Wire wire in connections[i].Wires)
|
||||
{
|
||||
if (connections[i].Wires[n] != this) continue;
|
||||
|
||||
if (wire != this) continue;
|
||||
SetConnectedDirty();
|
||||
connections[i].Wires[n] = null;
|
||||
|
||||
connections[i].SetWire(connections[i].FindWireIndex(wire), null);
|
||||
}
|
||||
|
||||
connections[i] = null;
|
||||
}
|
||||
}
|
||||
@@ -142,18 +153,29 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (!addNode) break;
|
||||
|
||||
if (newConnection.Item.Submarine == null) continue;
|
||||
Submarine refSub = newConnection.Item.Submarine;
|
||||
if (refSub == null)
|
||||
{
|
||||
Structure attachTarget = Structure.GetAttachTarget(newConnection.Item.WorldPosition);
|
||||
if (attachTarget == null) continue;
|
||||
refSub = attachTarget.Submarine;
|
||||
}
|
||||
|
||||
if (nodes.Count > 0 && nodes[0] == newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition) break;
|
||||
if (nodes.Count > 1 && nodes[nodes.Count - 1] == newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition) break;
|
||||
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;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
nodes.Insert(0, newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition);
|
||||
nodes.Insert(0, nodePos);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodes.Add(newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition);
|
||||
nodes.Add(nodePos);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -226,7 +248,7 @@ namespace Barotrauma.Items.Components
|
||||
if (Screen.Selected != GameMain.SubEditorScreen)
|
||||
{
|
||||
//cannot run wires from sub to another
|
||||
if (sub == null || (item.Submarine != sub && sub != null && item.Submarine != null))
|
||||
if (item.Submarine != sub && sub != null && item.Submarine != null)
|
||||
{
|
||||
ClearConnections();
|
||||
return;
|
||||
@@ -234,12 +256,18 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (item.CurrentHull == null)
|
||||
{
|
||||
newNodePos = item.WorldPosition - sub.Position - sub.HiddenSubPosition;
|
||||
canPlaceNode = false;
|
||||
Structure attachTarget = Structure.GetAttachTarget(item.WorldPosition);
|
||||
canPlaceNode = attachTarget != null;
|
||||
|
||||
sub = attachTarget?.Submarine;
|
||||
newNodePos = sub == null ?
|
||||
item.WorldPosition :
|
||||
item.WorldPosition - sub.Position - sub.HiddenSubPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
newNodePos = RoundNode(item.Position, item.CurrentHull) - sub.HiddenSubPosition;
|
||||
newNodePos = RoundNode(item.Position, item.CurrentHull);
|
||||
if (sub != null) { newNodePos -= sub.HiddenSubPosition; }
|
||||
canPlaceNode = true;
|
||||
}
|
||||
|
||||
@@ -250,7 +278,7 @@ namespace Barotrauma.Items.Components
|
||||
if (user == null) return;
|
||||
|
||||
Vector2 prevNodePos = nodes[nodes.Count - 1];
|
||||
prevNodePos += sub.HiddenSubPosition;
|
||||
if (sub != null) { prevNodePos += sub.HiddenSubPosition; }
|
||||
|
||||
float currLength = 0.0f;
|
||||
for (int i = 0; i < nodes.Count - 1; i++)
|
||||
@@ -263,8 +291,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
Vector2 diff = nodes[nodes.Count - 1] - newNodePos;
|
||||
Vector2 pullBackDir = diff == Vector2.Zero ? Vector2.Zero : Vector2.Normalize(diff);
|
||||
|
||||
user.AnimController.Collider.ApplyForce(pullBackDir * user.Mass * 50.0f);
|
||||
user.AnimController.UpdateUseItem(true, user.SimPosition + pullBackDir * 2.0f);
|
||||
user.AnimController.UpdateUseItem(true, user.WorldPosition + pullBackDir * 200.0f);
|
||||
if (currLength > MaxLength * 1.5f && GameMain.Client == null)
|
||||
{
|
||||
ClearConnections();
|
||||
@@ -344,6 +373,13 @@ namespace Barotrauma.Items.Components
|
||||
UpdateSections();
|
||||
}
|
||||
|
||||
public void MoveNode(int index, Vector2 amount)
|
||||
{
|
||||
if (index < 0 || index >= nodes.Count) return;
|
||||
nodes[index] += amount;
|
||||
UpdateSections();
|
||||
}
|
||||
|
||||
public void MoveNodes(Vector2 amount)
|
||||
{
|
||||
for (int i = 0; i < nodes.Count; i++)
|
||||
@@ -397,7 +433,7 @@ namespace Barotrauma.Items.Components
|
||||
int wireIndex = connections[i].FindWireIndex(item);
|
||||
|
||||
if (wireIndex == -1) continue;
|
||||
connections[i].AddLink(wireIndex, null);
|
||||
connections[i].SetWire(wireIndex, null);
|
||||
|
||||
connections[i] = null;
|
||||
}
|
||||
@@ -512,7 +548,7 @@ namespace Barotrauma.Items.Components
|
||||
return closestIndex;
|
||||
}
|
||||
|
||||
public override void FlipX()
|
||||
public override void FlipX(bool relativeToSub)
|
||||
{
|
||||
for (int i = 0; i < nodes.Count; i++)
|
||||
{
|
||||
@@ -521,6 +557,15 @@ namespace Barotrauma.Items.Components
|
||||
UpdateSections();
|
||||
}
|
||||
|
||||
public override void FlipY(bool relativeToSub)
|
||||
{
|
||||
for (int i = 0; i < nodes.Count; i++)
|
||||
{
|
||||
nodes[i] = new Vector2(nodes[i].X, -nodes[i].Y);
|
||||
}
|
||||
UpdateSections();
|
||||
}
|
||||
|
||||
public override void Load(XElement componentElement)
|
||||
{
|
||||
base.Load(componentElement);
|
||||
@@ -533,17 +578,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
float x = 0.0f, y = 0.0f;
|
||||
|
||||
try
|
||||
{
|
||||
x = float.Parse(nodeCoords[i * 2], CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch { x = 0.0f; }
|
||||
float.TryParse(nodeCoords[i * 2], NumberStyles.Float, CultureInfo.InvariantCulture, out x);
|
||||
|
||||
try
|
||||
{
|
||||
y = float.Parse(nodeCoords[i * 2 + 1], CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch { y = 0.0f; }
|
||||
float.TryParse(nodeCoords[i * 2 + 1], NumberStyles.Float, CultureInfo.InvariantCulture, out y);
|
||||
|
||||
nodes.Add(new Vector2(x, y));
|
||||
}
|
||||
@@ -571,7 +608,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
protected override void ShallowRemoveComponentSpecific()
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
/*for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (connections[i] == null) continue;
|
||||
int wireIndex = connections[i].FindWireIndex(item);
|
||||
@@ -580,7 +617,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
connections[i].AddLink(wireIndex, null);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
protected override void RemoveComponentSpecific()
|
||||
|
||||
Reference in New Issue
Block a user