Client LuaCsForBarotrauma
TrigonometricFunctionComponent.cs
1 using Microsoft.Xna.Framework;
2 using System;
3 using System.Globalization;
4 using System.Xml.Linq;
5 
7 {
9  {
10  public enum FunctionType
11  {
12  Sin,
13  Cos,
14  Tan,
15  Asin,
16  Acos,
17  Atan,
18  }
19 
20  private readonly float[] receivedSignal = new float[2];
21  private readonly float[] timeSinceReceived = new float[2];
22 
24 
25  [Serialize(FunctionType.Sin, IsPropertySaveable.No, description: "Which kind of function to run the input through.", alwaysUseInstanceValues: true)]
27  {
28  get; set;
29  }
30 
31 
32  [InGameEditable, Serialize(false, IsPropertySaveable.Yes, description: "If set to true, the trigonometric function uses radians instead of degrees.", alwaysUseInstanceValues: true)]
33  public bool UseRadians
34  {
35  get; set;
36  }
37 
38 
40  : base(item, element)
41  {
42  IsActive = true;
43  }
44 
45  public override void Update(float deltaTime, Camera cam)
46  {
47  if (Function == FunctionType.Atan)
48  {
49  for (int i = 0; i < 2; i++)
50  {
51  timeSinceReceived[i] += deltaTime;
52  if (timeSinceReceived[i] > 0.1f)
53  {
54  receivedSignal[i] = float.NaN;
55  }
56  }
57  if (!float.IsNaN(receivedSignal[0]) && !float.IsNaN(receivedSignal[1]))
58  {
59  float angle = (float)Math.Atan2(receivedSignal[1], receivedSignal[0]);
60  if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
61  item.SendSignal(new Signal(angle.ToString("G", CultureInfo.InvariantCulture), sender: signalSender), "signal_out");
62  }
63  }
64  }
65 
66  public override void ReceiveSignal(Signal signal, Connection connection)
67  {
68  float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float value);
69  bool sendOutputImmediately = true;
70  signalSender = signal.sender;
71  switch (Function)
72  {
73  case FunctionType.Sin:
74  if (!UseRadians) { value = MathHelper.ToRadians(value); }
75  value = MathF.Sin(value);
76  break;
77  case FunctionType.Cos:
78  if (!UseRadians) { value = MathHelper.ToRadians(value); }
79  value = MathF.Cos(value);
80  break;
81  case FunctionType.Tan:
82  if (!UseRadians) { value = MathHelper.ToRadians(value); }
83  //tan is undefined if the value is (π / 2) + πk, where k is any integer
84  if (!MathUtils.NearlyEqual(value % MathHelper.Pi, MathHelper.PiOver2))
85  {
86  value = MathF.Tan(value);
87  }
88  break;
89  case FunctionType.Asin:
90  //asin is only defined in the range [-1,1]
91  if (value >= -1.0f && value <= 1.0f)
92  {
93  float angle = MathF.Asin(value);
94  if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
95  value = angle;
96  }
97  break;
98  case FunctionType.Acos:
99  //acos is only defined in the range [-1,1]
100  if (value >= -1.0f && value <= 1.0f)
101  {
102  float angle = MathF.Acos(value);
103  if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
104  value = angle;
105  }
106  break;
107  case FunctionType.Atan:
108  if (connection.Name == "signal_in_x")
109  {
110  timeSinceReceived[0] = 0.0f;
111  float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
112  sendOutputImmediately = false;
113  }
114  else if (connection.Name == "signal_in_y")
115  {
116  timeSinceReceived[1] = 0.0f;
117  float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
118  sendOutputImmediately = false;
119  }
120  else
121  {
122  float angle = MathF.Atan(value);
123  if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
124  value = angle;
125  }
126  break;
127  default:
128  throw new NotImplementedException($"Function {Function} has not been implemented.");
129  }
130  if (sendOutputImmediately)
131  {
132  signal.value = value.ToString("G", CultureInfo.InvariantCulture);
133  item.SendSignal(signal, "signal_out");
134  }
135  }
136  }
137 }
void SendSignal(string signal, string connectionName)
The base class for components holding the different functionalities of the item
override void ReceiveSignal(Signal signal, Connection connection)