Client LuaCsForBarotrauma
VotingInterface.cs
1 using System;
2 using System.Globalization;
4 using Microsoft.Xna.Framework;
5 
6 namespace Barotrauma
7 {
9  {
10  public bool VoteRunning = false;
11 
12  private GUIFrame frame;
13  private GUITextBlock votingTextBlock, votedTextBlock, voteCounter;
14  private GUIProgressBar votingTimer;
15  private GUIButton yesVoteButton, noVoteButton;
16  private Action onVoteEnd;
17 
18  private int yesVotes, noVotes, maxVotes;
19  private Func<int> getYesVotes, getNoVotes, getMaxVotes;
20  private bool votePassed;
21 
22  private RichString votingOnText;
23  private float votingTime = 100f;
24  private float timer;
25  private VoteType currentVoteType;
26  private static Color SubmarineColor => GUIStyle.Orange;
27  private Point createdForResolution;
28 
29  //timer ran out but server still hasn't notified of the result of the vote
30  public bool TimedOut => VoteRunning && timer - votingTime > 10.0f;
31 
32  public static VotingInterface CreateSubmarineVotingInterface(Client starter, SubmarineInfo info, VoteType type, bool transferItems, float votingTime)
33  {
34  if (starter == null || info == null) { return null; }
35 
36  var subVoting = new VotingInterface()
37  {
38  votingTime = votingTime,
39  getYesVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountYes(type) ?? 0,
40  getNoVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountNo(type) ?? 0,
41  getMaxVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountMax(type) ?? 0,
42  };
43  subVoting.onVoteEnd = () => subVoting.SendSubmarineVoteEndMessage(info, type);
44  subVoting.SetSubmarineVotingText(starter, info, transferItems, type);
45  subVoting.Initialize(starter, type);
46  return subVoting;
47  }
48 
49  public static VotingInterface CreateMoneyTransferVotingInterface(Client starter, Client from, Client to, int amount, float votingTime)
50  {
51  if (starter == null) { return null; }
52  if (from == null && to == null) { return null; }
53 
54  var transferVoting = new VotingInterface()
55  {
56  votingTime = votingTime,
57  getYesVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountYes(VoteType.TransferMoney) ?? 0,
58  getNoVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountNo(VoteType.TransferMoney) ?? 0,
59  getMaxVotes = () => GameMain.NetworkMember?.Voting?.GetVoteCountMax(VoteType.TransferMoney) ?? 0,
60  };
61  transferVoting.onVoteEnd = () => transferVoting.SendMoneyTransferVoteEndMessage(from, to, amount);
62  transferVoting.SetMoneyTransferVotingText(starter, from, to, amount);
63  transferVoting.Initialize(starter, VoteType.TransferMoney);
64  return transferVoting;
65  }
66 
67 
68  private void Initialize(Client starter, VoteType type)
69  {
70  currentVoteType = type;
71  CreateVotingGUI();
72  if (starter.SessionId == GameMain.Client.SessionId) { SetGUIToVotedState(2); }
73  VoteRunning = true;
74  }
75 
76  private void CreateVotingGUI()
77  {
78  createdForResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
79 
80  frame?.Parent.RemoveChild(frame);
81  frame = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.VotingArea, GameMain.Client.InGameHUD.RectTransform), style: "");
82 
83  int padding = HUDLayoutSettings.Padding * 2;
84  int spacing = HUDLayoutSettings.Padding;
85  int yOffset = padding;
86  int paddedWidth = frame.Rect.Width - padding * 2;
87 
88  votingTextBlock = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), votingOnText, wrap: true);
89  votingTextBlock.RectTransform.NonScaledSize = votingTextBlock.RectTransform.MinSize = votingTextBlock.RectTransform.MaxSize = new Point(votingTextBlock.Rect.Width, votingTextBlock.Rect.Height);
90  votingTextBlock.RectTransform.IsFixedSize = true;
91  votingTextBlock.RectTransform.AbsoluteOffset = new Point(padding, yOffset);
92 
93  yOffset += votingTextBlock.Rect.Height + spacing;
94 
95  voteCounter = new GUITextBlock(new RectTransform(new Point(paddedWidth, 0), frame.RectTransform), "(0/0)", GUIStyle.Green, textAlignment: Alignment.Center);
96  voteCounter.RectTransform.NonScaledSize = voteCounter.RectTransform.MinSize = voteCounter.RectTransform.MaxSize = new Point(voteCounter.Rect.Width, voteCounter.Rect.Height);
97  voteCounter.RectTransform.IsFixedSize = true;
98  voteCounter.RectTransform.AbsoluteOffset = new Point(padding, yOffset);
99 
100  yOffset += voteCounter.Rect.Height + spacing;
101 
102  votingTimer = new GUIProgressBar(new RectTransform(new Point(paddedWidth, Math.Max(spacing, 8)), frame.RectTransform) { AbsoluteOffset = new Point(padding, yOffset) }, HUDLayoutSettings.Padding);
103  votingTimer.RectTransform.IsFixedSize = true;
104  yOffset += votingTimer.Rect.Height + spacing;
105 
106  int buttonWidth = (int)(paddedWidth * 0.3f);
107  yesVoteButton = new GUIButton(new RectTransform(new Point(buttonWidth, 0), frame.RectTransform) { AbsoluteOffset = new Point((int)(frame.Rect.Width / 2f - buttonWidth - spacing), yOffset) }, TextManager.Get("yes"))
108  {
109  OnClicked = (applyButton, obj) =>
110  {
111  SetGUIToVotedState(2);
112  GameMain.Client.Vote(currentVoteType, 2);
113  return true;
114  }
115  };
116 
117  noVoteButton = new GUIButton(new RectTransform(new Point(buttonWidth, 0), frame.RectTransform) { AbsoluteOffset = new Point(yesVoteButton.RectTransform.AbsoluteOffset.X + yesVoteButton.Rect.Width + padding, yOffset) }, TextManager.Get("no"))
118  {
119  OnClicked = (applyButton, obj) =>
120  {
121  SetGUIToVotedState(1);
122  GameMain.Client.Vote(currentVoteType, 1);
123  return true;
124  }
125  };
126 
127  votedTextBlock = new GUITextBlock(new RectTransform(new Point(paddedWidth, yesVoteButton.Rect.Height), frame.RectTransform), string.Empty, textAlignment: Alignment.Center);
128  votedTextBlock.RectTransform.IsFixedSize = true;
129  votedTextBlock.RectTransform.AbsoluteOffset = new Point(padding, yOffset);
130  votedTextBlock.Visible = false;
131 
132  yOffset += yesVoteButton.Rect.Height;
133 
134  frame.RectTransform.NonScaledSize = new Point(frame.Rect.Width, yOffset + padding);
135  }
136 
137  private void SetGUIToVotedState(int vote)
138  {
139  yesVoteButton.Visible = noVoteButton.Visible = false;
140  votedTextBlock.Text = TextManager.Get(vote == 2 ? "yesvoted" : "novoted");
141  votedTextBlock.Visible = true;
142  }
143 
144  public void Update(float deltaTime)
145  {
146  if (!VoteRunning) { return; }
147  if (GameMain.GraphicsWidth != createdForResolution.X || GameMain.GraphicsHeight != createdForResolution.Y) { CreateVotingGUI(); }
148  yesVotes = getYesVotes();
149  noVotes = getNoVotes();
150  maxVotes = getMaxVotes();
151  voteCounter.Text = $"({yesVotes + noVotes}/{maxVotes})";
152  timer += deltaTime;
153  votingTimer.BarSize = timer / votingTime;
154  }
155 
156  public void EndVote(bool passed, int yesVoteFinal, int noVoteFinal)
157  {
158  VoteRunning = false;
159  votePassed = passed;
160  yesVotes = yesVoteFinal;
161  noVotes = noVoteFinal;
162  onVoteEnd?.Invoke();
163  }
164 
165  #region Submarine Voting
166 
167  private void SetSubmarineVotingText(Client starter, SubmarineInfo info, bool transferItems, VoteType type)
168  {
169  int price = info.GetPrice();
170  string name = starter.Name;
171  JobPrefab prefab = starter?.Character?.Info?.Job?.Prefab;
172  Color nameColor = prefab != null ? prefab.UIColor : Color.White;
173  string characterRichString = $"‖color:{nameColor.R},{nameColor.G},{nameColor.B}‖{name}‖color:end‖";
174  string submarineRichString = $"‖color:{SubmarineColor.R},{SubmarineColor.G},{SubmarineColor.B}‖{info.DisplayName}‖color:end‖";
175  string tag = string.Empty;
176  LocalizedString text = string.Empty;
177  switch (type)
178  {
179  case VoteType.PurchaseAndSwitchSub:
180  tag = transferItems ? "submarinepurchaseandswitchwithitemsvote" : "submarinepurchaseandswitchvote";
181  text = TextManager.GetWithVariables(tag,
182  ("[playername]", characterRichString),
183  ("[submarinename]", submarineRichString),
184  ("[amount]", price.ToString()),
185  ("[currencyname]", TextManager.Get("credit").ToLower()));
186  break;
187  case VoteType.PurchaseSub:
188  text = TextManager.GetWithVariables("submarinepurchasevote",
189  ("[playername]", characterRichString),
190  ("[submarinename]", submarineRichString),
191  ("[amount]", price.ToString()),
192  ("[currencyname]", TextManager.Get("credit").ToLower()));
193  break;
194  case VoteType.SwitchSub:
195  tag = transferItems ? "submarineswitchwithitemsnofeevote" : "submarineswitchnofeevote";
196  text = TextManager.GetWithVariables(tag,
197  ("[playername]", characterRichString),
198  ("[submarinename]", submarineRichString));
199  break;
200  }
201  votingOnText = RichString.Rich(text);
202  }
203 
204  private void SendSubmarineVoteEndMessage(SubmarineInfo info, VoteType type)
205  {
206  GameMain.NetworkMember.AddChatMessage(GetSubmarineVoteResultMessage(info, type, yesVotes, noVotes, votePassed).Value, ChatMessageType.Server);
207  }
208 
209  private LocalizedString GetSubmarineVoteResultMessage(SubmarineInfo info, VoteType type, int yesVoteCount, int noVoteCount, bool votePassed)
210  {
211  int price = info.GetPrice();
212  LocalizedString result = string.Empty;
213 
214  switch (type)
215  {
216  case VoteType.PurchaseAndSwitchSub:
217  result = TextManager.GetWithVariables(votePassed ? "submarinepurchaseandswitchvotepassed" : "submarinepurchaseandswitchvotefailed",
218  ("[submarinename]", info.DisplayName),
219  ("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", price)),
220  ("[currencyname]", TextManager.Get("credit").ToLower()),
221  ("[yesvotecount]", yesVoteCount.ToString()),
222  ("[novotecount]" , noVoteCount.ToString()));
223  break;
224  case VoteType.PurchaseSub:
225  result = TextManager.GetWithVariables(votePassed ? "submarinepurchasevotepassed" : "submarinepurchasevotefailed",
226  ("[submarinename]", info.DisplayName),
227  ("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", price)),
228  ("[currencyname]", TextManager.Get("credit").ToLower()),
229  ("[yesvotecount]", yesVoteCount.ToString()),
230  ("[novotecount]", noVoteCount.ToString()));
231  break;
232  case VoteType.SwitchSub:
233  result = TextManager.GetWithVariables(votePassed ? "submarineswitchnofeevotepassed" : "submarineswitchnofeevotefailed",
234  ("[submarinename]", info.DisplayName),
235  ("[yesvotecount]", yesVoteCount.ToString()),
236  ("[novotecount]", noVoteCount.ToString()));
237  break;
238  default:
239  break;
240  }
241  return result;
242  }
243  #endregion
244 
245 
246  private void SetMoneyTransferVotingText(Client starter, Client from, Client to, int amount)
247  {
248  string name = starter.Name;
249  JobPrefab prefab = starter?.Character?.Info?.Job?.Prefab;
250  Color nameColor = prefab != null ? prefab.UIColor : Color.White;
251  string characterRichString = $"‖color:{nameColor.R},{nameColor.G},{nameColor.B}‖{name}‖color:end‖";
252 
253  LocalizedString text = string.Empty;
254  if (from == null && to != null)
255  {
256  text = TextManager.GetWithVariables("crewwallet.requestbanktoselfvote",
257  ("[requester]", characterRichString),
258  ("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", amount)));
259  }
260  else if (from != null && to == null)
261  {
262  text = TextManager.GetWithVariables("crewwallet.requestselftobankvote",
263  ("[requester]", characterRichString),
264  ("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", amount)));
265  }
266  else
267  {
268  //not supported atm: clients can only requests transfers between their own wallet and the bank
269  LocalizedString bankName = TextManager.Get("crewwallet.bank");
270  text = TextManager.GetWithVariables("crewwallet.requesttransfervote",
271  ("[requester]", characterRichString),
272  ("[player1]", from?.Character == null ? bankName : from.Character.Name),
273  ("[player2]", to?.Character == null ? bankName : to.Character.Name),
274  ("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", amount)));
275  }
276 
277  votingOnText = RichString.Rich(text);
278  }
279  private void SendMoneyTransferVoteEndMessage(Client from, Client to, int amount)
280  {
281  GameMain.NetworkMember.AddChatMessage(GetMoneyTransferVoteResultMessage(from, to, amount, yesVotes, noVotes, votePassed).Value, ChatMessageType.Server);
282  }
283 
284  public static LocalizedString GetMoneyTransferVoteResultMessage(Client from, Client to, int transferAmount, int yesVoteCount, int noVoteCount, bool votePassed)
285  {
286  LocalizedString result = string.Empty;
287  if (from == null && to != null)
288  {
289  result = TextManager.GetWithVariables(votePassed ? "crewwallet.banktoplayer.votepassed" : "crewwallet.banktoplayer.votefailed",
290  ("[playername]", to.Name),
291  ("[amount]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", transferAmount)),
292  ("[yesvotecount]", yesVoteCount.ToString()),
293  ("[novotecount]", noVoteCount.ToString()));
294  }
295  return result;
296  }
297  public void Remove()
298  {
299  if (frame != null)
300  {
301  frame.Parent.RemoveChild(frame);
302  frame = null;
303  }
304  }
305  }
306 }
virtual void RemoveChild(GUIComponent child)
Definition: GUIComponent.cs:87
virtual Rectangle Rect
RectTransform RectTransform
static int GraphicsWidth
Definition: GameMain.cs:162
static int GraphicsHeight
Definition: GameMain.cs:168
static NetworkMember NetworkMember
Definition: GameMain.cs:190
static GameClient Client
Definition: GameMain.cs:188
JobPrefab Prefab
Definition: Job.cs:18
readonly byte SessionId
An ID for this client for the current session. THIS IS NOT A PERSISTENT VALUE. DO NOT STORE THIS LONG...
Point AbsoluteOffset
Absolute in pixels but relative to the anchor point. Calculated away from the anchor point,...
Point?? MinSize
Min size in pixels. Does not affect scaling.
Point NonScaledSize
Size before scale multiplications.
Point?? MaxSize
Max size in pixels. Does not affect scaling.
bool IsFixedSize
If false, the element will resize if the parent is resized (with the children). If true,...
static RichString Rich(LocalizedString str, Func< string, string >? postProcess=null)
Definition: RichString.cs:67
int GetPrice(Location location=null, ImmutableHashSet< Character > characterList=null)
void Update(float deltaTime)
void EndVote(bool passed, int yesVoteFinal, int noVoteFinal)
static VotingInterface CreateMoneyTransferVotingInterface(Client starter, Client from, Client to, int amount, float votingTime)
static LocalizedString GetMoneyTransferVoteResultMessage(Client from, Client to, int transferAmount, int yesVoteCount, int noVoteCount, bool votePassed)
static VotingInterface CreateSubmarineVotingInterface(Client starter, SubmarineInfo info, VoteType type, bool transferItems, float votingTime)