Server LuaCsForBarotrauma
WaterDetector.cs
1 using Microsoft.Xna.Framework;
2 using System;
3 using System.Xml.Linq;
4 
6 {
8  {
9  //how often the detector can switch from state to another
10  const float StateSwitchInterval = 1.0f;
11 
12  private int prevSentWaterPercentageValue;
13  private string waterPercentageSignal;
14 
15  private bool isInWater;
16  private float stateSwitchDelay;
17 
18  private int maxOutputLength;
19  [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.")]
20  public int MaxOutputLength
21  {
22  get { return maxOutputLength; }
23  set
24  {
25  maxOutputLength = Math.Max(value, 0);
26  }
27  }
28 
29  private string output;
30  [InGameEditable, Serialize("1", IsPropertySaveable.Yes, description: "The signal the item sends out when it's underwater.", alwaysUseInstanceValues: true)]
31  public string Output
32  {
33  get { return output; }
34  set
35  {
36  if (value == null) { return; }
37  output = value;
38  if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
39  {
40  output = output.Substring(0, MaxOutputLength);
41  }
42  }
43  }
44 
45  private string falseOutput;
46  [InGameEditable, Serialize("0", IsPropertySaveable.Yes, description: "The signal the item sends out when it's not underwater.", alwaysUseInstanceValues: true)]
47  public string FalseOutput
48  {
49  get { return falseOutput; }
50  set
51  {
52  if (value == null) { return; }
53  falseOutput = value;
54  if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
55  {
56  falseOutput = falseOutput.Substring(0, MaxOutputLength);
57  }
58  }
59  }
60 
61  public bool WaterDetected => isInWater;
63 
65  : base(item, element)
66  {
67  IsActive = true;
68  }
69 
70  public static int GetWaterPercentage(Hull hull)
71  {
72  //treat less than one pixel of water as "no water"
73  return hull.WaterVolume / hull.Rect.Width > 1.0f ?
74  MathHelper.Clamp((int)Math.Ceiling(hull.WaterPercentage), 0, 100) :
75  0;
76  }
77 
78  public override void Update(float deltaTime, Camera cam)
79  {
80  if (stateSwitchDelay > 0.0f)
81  {
82  stateSwitchDelay -= deltaTime;
83  }
84  else
85  {
86  bool prevState = isInWater;
87 
88  isInWater = false;
89  if (item.InWater)
90  {
91  //item in water -> we definitely want to send the True output
92  isInWater = true;
93  }
94  else if (item.CurrentHull != null && GetWaterPercentage(item.CurrentHull) > 0)
95  {
96  //(center of the) item in not water -> check if the water surface is below the bottom of the item's rect
97  if (item.CurrentHull.Surface > item.Rect.Y - item.Rect.Height)
98  {
99  isInWater = true;
100  }
101  }
102 
103  if (prevState != isInWater)
104  {
105  stateSwitchDelay = StateSwitchInterval;
106  }
107  }
108 
109  string signalOut = isInWater ? Output : FalseOutput;
110  if (!string.IsNullOrEmpty(signalOut))
111  {
112  item.SendSignal(signalOut, "signal_out");
113  }
114 
115  if (item.CurrentHull != null)
116  {
117  int waterPercentage = GetWaterPercentage(item.CurrentHull);
118  if (prevSentWaterPercentageValue != waterPercentage || waterPercentageSignal == null)
119  {
120  prevSentWaterPercentageValue = waterPercentage;
121  waterPercentageSignal = prevSentWaterPercentageValue.ToString();
122  }
123  item.SendSignal(waterPercentageSignal, "water_%");
124  }
125  string highPressureOut = (item.CurrentHull == null || item.CurrentHull.LethalPressure > 5.0f) ? "1" : "0";
126  item.SendSignal(highPressureOut, "high_pressure");
127  }
128  }
129 }
Submarine Submarine
Definition: Entity.cs:53
void SendSignal(string signal, string connectionName)
The base class for components holding the different functionalities of the item
WaterDetector(Item item, ContentXElement element)
override void Update(float deltaTime, Camera cam)
virtual Rectangle Rect
Definition: MapEntity.cs:99