Client LuaCsForBarotrauma
BarotraumaClient/ClientSource/Items/Components/Machines/Pump.cs
3 using Microsoft.Xna.Framework;
4 using System;
5 using System.Collections.Generic;
6 
8 {
9  partial class Pump : Powered, IServerSerializable, IClientSerializable
10  {
11  public GUIButton PowerButton { get; private set; }
12 
13  private GUIScrollBar pumpSpeedSlider;
14  private GUITickBox powerLight;
15  private GUITickBox autoControlIndicator;
16 
17  private readonly List<(Vector2 position, ParticleEmitter emitter)> pumpOutEmitters = new List<(Vector2 position, ParticleEmitter emitter)>();
18  private readonly List<(Vector2 position, ParticleEmitter emitter)> pumpInEmitters = new List<(Vector2 position, ParticleEmitter emitter)>();
19 
20  partial void InitProjSpecific(ContentXElement element)
21  {
22  foreach (var subElement in element.Elements())
23  {
24  switch (subElement.Name.ToString().ToLowerInvariant())
25  {
26  case "pumpoutemitter":
27  pumpOutEmitters.Add((subElement.GetAttributeVector2("position", Vector2.Zero), new ParticleEmitter(subElement)));
28  break;
29  case "pumpinemitter":
30  pumpInEmitters.Add((subElement.GetAttributeVector2("position", Vector2.Zero), new ParticleEmitter(subElement)));
31  break;
32  }
33  }
34 
35  if (GuiFrame == null) { return; }
36 
37  GUIFrame paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.85f, 0.65f), GuiFrame.RectTransform, Anchor.Center)
38  {
39  RelativeOffset = new Vector2(0, 0.04f)
40  }, style: null);
41 
42  // Power button
43  float powerButtonSize = 1f;
44  var powerArea = new GUIFrame(new RectTransform(new Vector2(0.3f, 1) * powerButtonSize, paddedFrame.RectTransform, Anchor.CenterLeft), style: null);
45  var paddedPowerArea = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.8f), powerArea.RectTransform, Anchor.Center), style: "PowerButtonFrame");
46  var powerLightArea = new GUIFrame(new RectTransform(new Vector2(0.87f, 0.2f), powerArea.RectTransform, Anchor.TopRight), style: null);
47  powerLight = new GUITickBox(new RectTransform(Vector2.One, powerLightArea.RectTransform, Anchor.Center),
48  TextManager.Get("PowerLabel"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightPower")
49  {
50  CanBeFocused = false
51  };
52  powerLight.TextBlock.AutoScaleHorizontal = true;
53  powerLight.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal);
54  PowerButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.75f), paddedPowerArea.RectTransform, Anchor.TopCenter)
55  {
56  RelativeOffset = new Vector2(0, 0.1f)
57  }, style: "PowerButton")
58  {
59  UserData = UIHighlightAction.ElementId.PowerButton,
60  OnClicked = (button, data) =>
61  {
62  TargetLevel = null;
63  IsActive = !IsActive;
64  if (GameMain.Client != null)
65  {
67  item.CreateClientEvent(this);
68  }
69  powerLight.Selected = IsActive;
70  return true;
71  }
72  };
73 
74  var rightArea = new GUIFrame(new RectTransform(new Vector2(0.65f, 1), paddedFrame.RectTransform, Anchor.CenterRight), style: null);
75 
76  autoControlIndicator = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.25f), rightArea.RectTransform, Anchor.TopLeft),
77  TextManager.Get("PumpAutoControl", "ReactorAutoControl"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightYellow")
78  {
79  Selected = false,
80  Enabled = false,
81  ToolTip = TextManager.Get("AutoControlTip")
82  };
83  autoControlIndicator.TextBlock.AutoScaleHorizontal = true;
84  autoControlIndicator.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal);
85 
86  var sliderArea = new GUIFrame(new RectTransform(new Vector2(1, 0.65f), rightArea.RectTransform, Anchor.BottomLeft), style: null);
87  var pumpSpeedText = new GUITextBlock(new RectTransform(new Vector2(1, 0.3f), sliderArea.RectTransform, Anchor.TopLeft), "",
88  textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.CenterLeft, wrap: false, font: GUIStyle.SubHeadingFont)
89  {
90  AutoScaleHorizontal = true
91  };
92  LocalizedString pumpSpeedStr = TextManager.Get("PumpSpeed");
93  pumpSpeedText.TextGetter = () => { return TextManager.AddPunctuation(':', pumpSpeedStr, (int)Math.Round(flowPercentage) + " %"); };
94  pumpSpeedSlider = new GUIScrollBar(new RectTransform(new Vector2(1, 0.35f), sliderArea.RectTransform, Anchor.Center), barSize: 0.1f, style: "DeviceSlider")
95  {
96  Step = 0.05f,
97  OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
98  {
99  if (pumpSpeedLockTimer <= 0.0f)
100  {
101  TargetLevel = null;
102  }
103  float newValue = barScroll * 200.0f - 100.0f;
104  if (Math.Abs(newValue - FlowPercentage) < 0.1f) { return false; }
105 
106  FlowPercentage = newValue;
107 
108  if (GameMain.Client != null)
109  {
111  item.CreateClientEvent(this);
112  }
113  return true;
114  }
115  };
116  pumpSpeedSlider.Frame.UserData = UIHighlightAction.ElementId.PumpSpeedSlider;
117  var textsArea = new GUIFrame(new RectTransform(new Vector2(1, 0.25f), sliderArea.RectTransform, Anchor.BottomCenter), style: null);
118  var outLabel = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), textsArea.RectTransform, Anchor.CenterLeft), TextManager.Get("PumpOut"),
119  textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.CenterLeft, wrap: false, font: GUIStyle.SubHeadingFont);
120  var inLabel = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), textsArea.RectTransform, Anchor.CenterRight), TextManager.Get("PumpIn"),
121  textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.CenterRight, wrap: false, font: GUIStyle.SubHeadingFont);
122  GUITextBlock.AutoScaleAndNormalize(outLabel, inLabel);
123  }
124 
125  public override void OnItemLoaded()
126  {
127  base.OnItemLoaded();
128  if (pumpSpeedSlider != null)
129  {
130  pumpSpeedSlider.BarScroll = (flowPercentage + 100.0f) / 200.0f;
131  }
132  }
133 
134  partial void UpdateProjSpecific(float deltaTime)
135  {
136  if (FlowPercentage < 0.0f)
137  {
138  foreach (var (position, emitter) in pumpOutEmitters)
139  {
140  if (item.CurrentHull != null && item.CurrentHull.Surface < item.Rect.Location.Y + position.Y) { continue; }
141 
142  //only emit "pump out" particles when underwater
143  Vector2 relativeParticlePos = (item.WorldRect.Location.ToVector2() + position * item.Scale) - item.WorldPosition;
144  relativeParticlePos = MathUtils.RotatePoint(relativeParticlePos, item.FlippedX ? item.RotationRad : -item.RotationRad);
145  float angle = -item.RotationRad;
146  if (item.FlippedX)
147  {
148  relativeParticlePos.X = -relativeParticlePos.X;
149  angle += MathHelper.Pi;
150  }
151  if (item.FlippedY)
152  {
153  relativeParticlePos.Y = -relativeParticlePos.Y;
154  }
155 
156  emitter.Emit(deltaTime, item.WorldPosition + relativeParticlePos, item.CurrentHull, angle,
157  velocityMultiplier: MathHelper.Lerp(0.5f, 1.0f, -FlowPercentage / 100.0f));
158  }
159  }
160  else if (FlowPercentage > 0.0f)
161  {
162  foreach (var (position, emitter) in pumpInEmitters)
163  {
164  Vector2 relativeParticlePos = (item.WorldRect.Location.ToVector2() + position * item.Scale) - item.WorldPosition;
165  relativeParticlePos = MathUtils.RotatePoint(relativeParticlePos, item.FlippedX ? item.RotationRad : -item.RotationRad);
166  float angle = -item.RotationRad;
167  if (item.FlippedX)
168  {
169  relativeParticlePos.X = -relativeParticlePos.X;
170  angle += MathHelper.Pi;
171  }
172  if (item.FlippedY)
173  {
174  relativeParticlePos.Y = -relativeParticlePos.Y;
175  }
176  emitter.Emit(deltaTime, item.WorldPosition + relativeParticlePos, item.CurrentHull, angle,
177  velocityMultiplier: MathHelper.Lerp(0.5f, 1.0f, FlowPercentage / 100.0f));
178  }
179  }
180  }
181 
182  private float flickerTimer;
183  private readonly float flickerFrequency = 1;
184  public override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
185  {
186  autoControlIndicator.Selected = IsAutoControlled;
187  PowerButton.Enabled = isActiveLockTimer <= 0.0f;
188  if (HasPower)
189  {
190  flickerTimer = 0;
191  powerLight.Selected = IsActive;
192  }
193  else if (IsActive)
194  {
195  flickerTimer += deltaTime;
196  if (flickerTimer > flickerFrequency)
197  {
198  flickerTimer = 0;
199  powerLight.Selected = !powerLight.Selected;
200  }
201  }
202  else
203  {
204  flickerTimer = 0;
205  powerLight.Selected = false;
206  }
207  pumpSpeedSlider.Enabled = pumpSpeedLockTimer <= 0.0f && IsActive;
209  {
210  float pumpSpeedScroll = (FlowPercentage + 100.0f) / 200.0f;
211  if (Math.Abs(pumpSpeedScroll - pumpSpeedSlider.BarScroll) > 0.01f)
212  {
213  pumpSpeedSlider.BarScroll = pumpSpeedScroll;
214  }
215  }
216  }
217 
218  public void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData = null)
219  {
220  //flowpercentage can only be adjusted at 10% intervals -> no need for more accuracy than this
221  msg.WriteRangedInteger((int)(flowPercentage / 10.0f), -10, 10);
222  msg.WriteBoolean(IsActive);
223  }
224 
225  public void ClientEventRead(IReadMessage msg, float sendingTime)
226  {
227  int msgStartPos = msg.BitPosition;
228 
229  float flowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
230  bool isActive = msg.ReadBoolean();
231  bool hijacked = msg.ReadBoolean();
232  float? targetLevel;
233  if (msg.ReadBoolean())
234  {
235  targetLevel = msg.ReadSingle();
236  }
237  else
238  {
239  targetLevel = null;
240  }
241 
242  if (correctionTimer > 0.0f)
243  {
244  int msgLength = msg.BitPosition - msgStartPos;
245  msg.BitPosition = msgStartPos;
246  StartDelayedCorrection(msg.ExtractBits(msgLength), sendingTime);
247  return;
248  }
249 
250  FlowPercentage = flowPercentage;
251  IsActive = isActive;
252  Hijacked = hijacked;
253  TargetLevel = targetLevel;
254  }
255  }
256 }
IEnumerable< ContentXElement > Elements()
override bool Enabled
Definition: GUIButton.cs:27
RectTransform RectTransform
override bool Enabled
Definition: GUIScrollBar.cs:76
void OverrideTextColor(Color color)
Overrides the color for all the states.
bool AutoScaleHorizontal
When enabled, the text is automatically scaled down to fit the textblock horizontally.
GUITextBlock TextBlock
Definition: GUITickBox.cs:93
override bool Selected
Definition: GUITickBox.cs:18
void StartDelayedCorrection(IReadMessage buffer, float sendingTime, bool waitForMidRoundSync=false)
void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData=null)
override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
override void OnItemLoaded()
Called when all the components of the item have been loaded. Use to initialize connections between co...
Highlights an UI element of some kind. Generally used in tutorials.
Interface for entities that the clients can send events to the server
int ReadRangedInteger(int min, int max)
Interface for entities that the server can send events to the clients
void WriteRangedInteger(int val, int min, int max)