Client LuaCsForBarotrauma
BooleanOperatorComponent.cs
1 using System;
2 using System.Xml.Linq;
3 
5 {
7  {
8  protected string output, falseOutput;
9 
10  //an array to keep track of how long ago a non-zero signal was received on both inputs
11  protected float[] timeSinceReceived;
12 
13  //the output is sent if both inputs have received a signal within the timeframe
14  protected float timeFrame;
15 
16  protected readonly Character[] signalSender = new Character[2];
17 
18  [InGameEditable(DecimalCount = 2), Serialize(0.0f, IsPropertySaveable.Yes, 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)]
19  public float TimeFrame
20  {
21  get { return timeFrame; }
22  set
23  {
24  if (value > timeFrame)
25  {
26  timeSinceReceived[0] = timeSinceReceived[1] = Math.Max(value * 2.0f, 0.1f);
27  }
28  timeFrame = Math.Max(0.0f, value);
29  }
30  }
31 
32  private int maxOutputLength;
33  [Editable, Serialize(200, IsPropertySaveable.No, description: "The maximum length of the output strings. Warning: Large values can lead to large memory usage or networking issues.")]
34  public int MaxOutputLength
35  {
36  get { return maxOutputLength; }
37  set
38  {
39  maxOutputLength = Math.Max(value, 0);
40  }
41  }
42 
43  [InGameEditable, Serialize("1", IsPropertySaveable.Yes, description: "The signal sent when the condition is met.", alwaysUseInstanceValues: true)]
44  public string Output
45  {
46  get { return output; }
47  set
48  {
49  if (value == null) { return; }
50  output = value;
51  //reactivate (we may not have been previously sending a signal, but might now)
52  IsActive = true;
53  if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
54  {
55  output = output.Substring(0, MaxOutputLength);
56  }
57  }
58  }
59 
60  [InGameEditable, Serialize("0", IsPropertySaveable.Yes, description: "The signal sent when the condition is met (if empty, no signal is sent).", alwaysUseInstanceValues: true)]
61  public string FalseOutput
62  {
63  get { return falseOutput; }
64  set
65  {
66  if (value == null) { return; }
67  falseOutput = value;
68  //reactivate (we may not have been previously sending a signal, but might now)
69  IsActive = true;
70  if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
71  {
72  falseOutput = falseOutput.Substring(0, MaxOutputLength);
73  }
74  }
75  }
76 
78  : base(item, element)
79  {
80  timeSinceReceived = new float[] { Math.Max(timeFrame * 2.0f, 0.1f), Math.Max(timeFrame * 2.0f, 0.1f) };
81  IsActive = true;
82  }
83 
84  protected abstract bool GetOutput(int numTrueInputs);
85 
86  public sealed override void Update(float deltaTime, Camera cam)
87  {
88  int receivedInputs = 0;
89  bool allInputsTimedOut = true;
90  for (int i = 0; i < timeSinceReceived.Length; i++)
91  {
92  if (timeSinceReceived[i] <= timeFrame)
93  {
94  allInputsTimedOut = false;
95  receivedInputs += 1;
96  }
97  timeSinceReceived[i] += deltaTime;
98  }
99 
100  bool state = GetOutput(receivedInputs);
101  string signalOut = state ? output : falseOutput;
102  if (string.IsNullOrEmpty(signalOut))
103  {
104  //deactivate the component if state is false and there's no false output (will be woken up by non-zero signals in ReceiveSignal)
105  if (!state && allInputsTimedOut) { IsActive = false; }
106  return;
107  }
108 
109  item.SendSignal(new Signal(signalOut, sender: signalSender[0] ?? signalSender[1]), "signal_out");
110  }
111 
112  public override void ReceiveSignal(Signal signal, Connection connection)
113  {
114  switch (connection.Name)
115  {
116  case "signal_in1":
117  if (signal.value == "0") { return; }
118  timeSinceReceived[0] = 0.0f;
119  signalSender[0] = signal.sender;
120  IsActive = true;
121  break;
122  case "signal_in2":
123  if (signal.value == "0") { return; }
124  timeSinceReceived[1] = 0.0f;
125  signalSender[1] = signal.sender;
126  IsActive = true;
127  break;
128  case "set_output":
129  output = signal.value;
130  break;
131  }
132  }
133  }
134 }
Submarine Submarine
Definition: Entity.cs:53
void SendSignal(string signal, string connectionName)
sealed override void Update(float deltaTime, Camera cam)
BooleanOperatorComponent(Item item, ContentXElement element)
override void ReceiveSignal(Signal signal, Connection connection)
abstract bool GetOutput(int numTrueInputs)
The base class for components holding the different functionalities of the item