Rise
The Vieneo Province
gui.cpp
Go to the documentation of this file.
1 #include "gui.h"
2 
10 #include "Dialogs\WaypointDialog.h"
11 
12 #include "GameClass.h"
13 #include "Networking.h"
14 
15 #include <clocale> // For setlocale
16 #include <fcntl.h> // For _O_RDWR, _O_BINARY, _O_RDONLY, O_TEXT
17 #include <io.h> // For _open, _read, _close, _lseek, eof, _write
18 #include <sys/stat.h> // For _S_IWRITE, _S_IREAD
19 #include <KnownFolders.h>
20 #include <ctime>
21 
22 #include "../SteamWorks/sdk/public/steam/steam_api.h"
23 #include "MathUtilities.h"
24 #include "ActiveHelp.h"
25 
26 
27 void HMI::SexChangeOperation(char newsex)
28 {
29  for (short t = 1; t < humantextureC; t++)
30  {
31  if (game->graphics->m_pddsAvatar[t])
32  {
33  SAFE_RELEASE(game->graphics->m_pddsAvatar[t]);
34  char msg[99];
35  sprintf_s(msg, sizeof(msg), "m_pddsAvatar[%i]", t);
36  game->UpdateTrackedResource(msg, 3);
37  }
38  }
39 
40  if (newsex == 1)
41  {
42  if (tempobject.VB)
43  {
44  SAFE_RELEASE(tempobject.VB);
45  game->UpdateTrackedResource("tempobject.VB", 3);
46  }
47  tempobject = polyobj.LoadDAW("Meshes\\male1.DAW");
48  game->AddTrackedResource("tempobject.VB"); // managed
49 
50 
51  polyobj.LoadDIX("Meshes\\male1.DIX");
52 
53 
54  for (short t = 1; t < humantextureC; t++)
55  {
56  WCHAR hullfile[199];
57  hullfile[0] = 0;
58  D3DFORMAT format = D3DFMT_A8L8;
59  switch (t)
60  {
61  case 1: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\BODY1.dds");
62  break;
63  //case 2: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\VECTOR.dds");
64  // break;
65  //case 3: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\EXO.dds");
66  // break;
67  //case 4: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\VICTOR.dds");
68  // break;
69  //case 5: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\SOCK.dds");
70  // break;
71  //case 6: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\FOCUS.dds");
72  // break;
73  case 7: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\ears1.dds");
74  break;
75  case 8: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\straight1.dds");
76  break;
77  case 9: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\HEAD1.dds");
78  break;
79  case 10: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\noses1.dds");
80  break;
81  case 11: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\HEAD2.dds");
82  break;
83  case 12: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\HEAD3.dds");
84  break;
85  case 13: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\flattop1.dds");
86  break;
87  case 14: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\HAMMONDS1.dds");
88  format = D3DFMT_DXT3;
89  break;
90  default:
91  continue;
92  }
93  char msg[99];
94  sprintf_s(msg, sizeof(msg), "m_pddsAvatar[%i]", t);
95  game->LoadTexture(&game->graphics->m_pddsAvatar[t], msg, hullfile, format);
96  }
97 
98  g_HUD.GetSlider(IDC_HEAD)->SetRange(151, 153);
99  g_HUD.GetSlider(IDC_NOSE)->SetRange(101, 104);
100  g_HUD.GetSlider(IDC_HAIRSTYLE)->SetRange(175, 179);
101  g_HUD.GetSlider(IDC_FRAMETYPE)->SetRange(451, 451);
102  g_HUD.GetSlider(IDC_JAWLINE)->SetRange(676, 680);
103  g_HUD.GetSlider(IDC_EARS)->SetRange(226, 228);
104  //g_HUD.GetSlider(IDC_FEATURE)->SetRange(125, 127);
105  if (!player[ourplayerC].facialhair)
106  g_HUD.GetSlider(IDC_FEATURE)->SetVisible(true);
107  g_HUD.GetStatic(IDC_FEATURETEXT)->SetText(strings[L_IMMIGRATION_FEATUREBEARD].c_str());
109 
111  maxWeight = 155.0f; // kg
112  minWeight = 53.0f; // kg
113 
115  maxHeight = 192.0f; // cm
116  minHeight = 156.0f; // cm
117  }
118  else if (newsex == 2)
119  {
120  if (tempobject.VB)
121  {
122  SAFE_RELEASE(tempobject.VB);
123  game->UpdateTrackedResource("tempobject.VB", 3);
124  }
125  tempobject = polyobj.LoadDAW("Meshes\\female1.DAW");
126  game->AddTrackedResource("tempobject.VB"); // managed
127 
128 
129  polyobj.LoadDIX("Meshes\\female1.DIX");
130 
131 
132  for (short t = 1; t < humantextureC; t++)
133  {
134  WCHAR hullfile[199];
135  hullfile[0] = 0;
136  D3DFORMAT format = D3DFMT_A8L8;
137  switch (t)
138  {
139  case 1: wcscpy_s(hullfile, 199, L"textures\\People\\Female\\BODY1.dds");
140  break;
141  case 2: wcscpy_s(hullfile, 199, L"textures\\People\\Female\\ears1.dds");
142  break;
143  case 3: wcscpy_s(hullfile, 199, L"textures\\People\\Female\\HEAD2.dds");
144  break;
145  case 4: wcscpy_s(hullfile, 199, L"textures\\People\\Female\\HEAD1.dds");
146  break;
147  case 5: wcscpy_s(hullfile, 199, L"textures\\People\\Female\\noses1.dds");
148  break;
149  case 6: wcscpy_s(hullfile, 199, L"textures\\People\\Female\\head3.dds");
150  break;
151  case 7: wcscpy_s(hullfile, 199, L"textures\\People\\Female\\HAIR3-Chantal.dds");
152  break;
153  case 8: wcscpy_s(hullfile, 199, L"textures\\People\\Female\\HAIR1-MARYMOORE.dds");
154  break;
155  case 9: wcscpy_s(hullfile, 199, L"textures\\People\\Female\\HAIR2-Suzette.dds");
156  break;
157  case 10: wcscpy_s(hullfile, 199, L"textures\\People\\Male\\HAMMONDS1.dds");
158  format = D3DFMT_DXT3;
159  break;
160  default:
161  continue;
162  }
163  char msg[99];
164  sprintf_s(msg, sizeof(msg), "m_pddsAvatar[%i]", t);
165  game->LoadTexture(&game->graphics->m_pddsAvatar[t], msg, hullfile, format);
166  }
167 
168  g_HUD.GetSlider(IDC_HEAD)->SetRange(151, 153);
169  g_HUD.GetSlider(IDC_NOSE)->SetRange(101, 103);
170  g_HUD.GetSlider(IDC_HAIRSTYLE)->SetRange(175, 180);
171  g_HUD.GetSlider(IDC_FRAMETYPE)->SetRange(451, 451);
172  g_HUD.GetSlider(IDC_JAWLINE)->SetRange(676, 678);
173  g_HUD.GetSlider(IDC_EARS)->SetRange(226, 227);
174  g_HUD.GetSlider(IDC_FEATURE)->SetVisible(false); // unsupported
175  g_HUD.GetStatic(IDC_FEATURETEXT)->SetText(strings[L_IMMIGRATION_FEATUREUNUSED].c_str());
177 
179  maxWeight = 138.0f; // kg
180  minWeight = 44.0f; // kg
181 
183  maxHeight = 177.0f; // cm
184  minHeight = 144.0f; // cm
185  }
186 
187  WCHAR str[4];
188  swprintf_s(str, 4, L"%.3s", g_HUD.GetEditBox(IDC_WEIGHT)->GetText());
189  if (!str[0]) // blank
190  {
191  weight = 1.0f;
193  //float random = powf(RandomFloat(), 4.0f); // so 0-1 weighted at 0
194  //if (rand() % 2 == 0) random = -random;
195  //swprintf_s(str, 4, L"%.0f", weight + random);
196  //g_HUD.GetEditBox(IDC_WEIGHT)->SetText(str);
197  //g_HUD.GetEditBox(IDC_WEIGHT)->SetEnabled(true);
198  }
199 
200  swprintf_s(str, 4, L"%.3s", g_HUD.GetEditBox(IDC_HEIGHT)->GetText());
201  if (!str[0]) // blank
202  {
203  height = 1.0f;
205  //float random = powf(RandomFloat(), 4.0f); // so 0-1 weighted at 0
206  //if (rand() % 2 == 0) random = -random;
207  //swprintf_s(str, 4, L"%.0f", height + random);
208  //g_HUD.GetEditBox(IDC_HEIGHT)->SetText(str);
209  }
210 }
211 
212 void HMI::OnFrameMove(float fElapsedTime)
213 {
214  logger->AddToCallStack("HMI::OnFrameMove");
215 
216  if (isSteam)
217  SteamAPI_RunCallbacks();
218  game->discord->FrameMove();
219 
220  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
221  // ReSharper disable once CppIncompleteSwitchStatement
222  switch (game->displaystage) // NOLINT
223  {
224 #pragma region STATUS_CREATE
226  {
227  static char oldSex = -1;
228  char newSex = 0;
229  if (g_HUD.GetRadioButton(IDC_MALE)->GetChecked())
230  newSex = 1;
231  else if (g_HUD.GetRadioButton(IDC_FEMALE)->GetChecked())
232  newSex = 2;
233  if (newSex != oldSex)
234  {
235  if (newSex)
236  {
237  SexChangeOperation(newSex);
238  }
239  else
240  {
241  SAFE_RELEASE(pBuffer);
242  game->UpdateTrackedResource("pBuffer", 3);
243  if (tempobject.VB)
244  {
245  SAFE_RELEASE(tempobject.VB);
246  game->UpdateTrackedResource("tempobject.VB", 3);
247  }
248  }
249  oldSex = newSex;
250  }
251 
252  if (!g_HUD.GetEditBox(IDC_WEIGHT)->m_bHasFocus && minWeight)
253  {
254  WCHAR str[4];
255  swprintf_s(str, 4, L"%.3s", g_HUD.GetEditBox(IDC_WEIGHT)->GetText());
256  if (str[0]) // not blank
257  {
258  const int val = _wtoi(str);
259  int newval = min((int)maxWeight, val);
260  newval = max((int)minWeight, newval);
261  swprintf_s(str, 4, L"%i", newval);
262  g_HUD.GetEditBox(IDC_WEIGHT)->SetText(str);
263  weight = static_cast<float>(newval) / ((maxWeight - minWeight) * 0.5f + minWeight);
264  }
265  }
266 
267  if (!g_HUD.GetEditBox(IDC_HEIGHT)->m_bHasFocus && minHeight)
268  {
269  WCHAR str[4];
270  swprintf_s(str, 4, L"%.3s", g_HUD.GetEditBox(IDC_HEIGHT)->GetText());
271  if (str[0]) // not blank
272  {
273  const int val = _wtoi(str);
274  int newval = min((int)maxHeight, val);
275  newval = max((int)minHeight, newval);
276  swprintf_s(str, 4, L"%i", newval);
277  g_HUD.GetEditBox(IDC_HEIGHT)->SetText(str);
278  // so the model we give them is 156 to 192 ... means model is 174
279  height = static_cast<float>(newval) / ((maxHeight - minHeight) * 0.5f + minHeight);
280  }
281  }
282 
283  if (!g_HUD.GetEditBox(IDC_AGE)->m_bHasFocus)
284  {
285  WCHAR str[4];
286  swprintf_s(str, 4, L"%.3s", g_HUD.GetEditBox(IDC_AGE)->GetText());
287  if (str[0]) // not blank
288  {
289  const int val = _wtoi(str);
290  int newval = min((int)80, val);
291  newval = max((int)18, newval);
292  swprintf_s(str, 4, L"%i", newval);
293  g_HUD.GetEditBox(IDC_AGE)->SetText(str);
294  age = (static_cast<float>(newval) - 18.0f) / 62.0f;
295  }
296  }
297 
298 #pragma region Set Access
299  // snapshot
300  if ((g_HUD.GetRadioButton(IDC_MALE)->GetChecked() || g_HUD.GetRadioButton(IDC_FEMALE)->GetChecked()) &&
301  _wtoi(g_HUD.GetEditBox(IDC_AGE)->GetText()) >= 18 && _wtoi(g_HUD.GetEditBox(IDC_AGE)->GetText()) <= 80 &&
302  _wtoi(g_HUD.GetEditBox(IDC_HEIGHT)->GetText()) >= minHeight && _wtoi(g_HUD.GetEditBox(IDC_HEIGHT)->GetText()) <= maxHeight &&
303  _wtoi(g_HUD.GetEditBox(IDC_WEIGHT)->GetText()) >= minWeight && _wtoi(g_HUD.GetEditBox(IDC_WEIGHT)->GetText()) <= maxWeight &&
304  (g_HUD.GetRadioButton(IDC_NORMAL)->GetChecked() || g_HUD.GetRadioButton(IDC_IMPLANTS)->GetChecked() || g_HUD.GetRadioButton(IDC_FRAMES)->GetChecked()) &&
305  !pBuffer)
306  g_HUD.GetButton(IDC_SNAPSHOT)->SetEnabled(true);
307  else
308  g_HUD.GetButton(IDC_SNAPSHOT)->SetEnabled(false);
309 
310  // void snapshot
311  if (pBuffer && g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
312  g_HUD.GetButton(IDC_VOID)->SetEnabled(true);
313  else
314  g_HUD.GetButton(IDC_VOID)->SetEnabled(false);
315 
316  // Sex
317  if (pBuffer ||
318  !g_HUD.GetButton(IDC_SUGGEST)->GetEnabled() ||
319  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
320  {
321  g_HUD.GetRadioButton(IDC_MALE)->SetEnabled(false);
322  g_HUD.GetRadioButton(IDC_FEMALE)->SetEnabled(false);
323  }
324  else
325  {
326  if (player[ourplayerC].sex)
327  {
328  g_HUD.GetRadioButton(IDC_MALE)->SetEnabled(false);
329  g_HUD.GetRadioButton(IDC_FEMALE)->SetEnabled(false);
330 
331  g_HUD.GetRadioButton(IDC_MALE)->SetChecked(player[ourplayerC].sex == 1);
332  g_HUD.GetRadioButton(IDC_FEMALE)->SetChecked(player[ourplayerC].sex == 2);
333  }
334  else
335  {
336  g_HUD.GetRadioButton(IDC_MALE)->SetEnabled(true);
337  g_HUD.GetRadioButton(IDC_FEMALE)->SetEnabled(true);
338  }
339  }
340 
341  // Character Name and Suggest
342  if (!g_HUD.GetButton(IDC_SUGGEST)->GetEnabled() ||
343  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled() || charnameValid == 1) // charnameValid==1 means we are checking, please wait
344  {
345  g_HUD.GetEditBox(IDC_CHARNAME)->SetEnabled(false);
346  //g_HUD.GetButton(IDC_SUGGEST)->SetEnabled(false);
347  }
348  else
349  {
350  if (player[ourplayerC].characterName[0])
351  {
352  g_HUD.GetEditBox(IDC_CHARNAME)->SetEnabled(false);
353  g_HUD.GetButton(IDC_SUGGEST)->SetEnabled(false);
354  WCHAR str[99];
355  swprintf_s(str, 99, L"%S", player[ourplayerC].characterName);
356  g_HUD.GetEditBox(IDC_CHARNAME)->SetText(str);
357  g_HUD.GetEditBox(IDC_SIGNATUREHINT)->SetText(str);
358  }
359  else
360  {
361  g_HUD.GetEditBox(IDC_CHARNAME)->SetEnabled(true);
362  g_HUD.GetButton(IDC_SUGGEST)->SetEnabled(true);
363  }
364  }
365 
366  // Handle
367  if (!g_HUD.GetButton(IDC_CONFIRM)->GetEnabled() || handleValid == 1) // handleValid==1 means it is checking
368  {
369  g_HUD.GetEditBox(IDC_HANDLE)->SetEnabled(false);
370  }
371  else
372  {
373  if (player[ourplayerC].callsign[0])
374  {
375  g_HUD.GetEditBox(IDC_HANDLE)->SetEnabled(false);
376  WCHAR str[99];
377  swprintf_s(str, 99, L"%S", player[ourplayerC].callsign);
378  g_HUD.GetEditBox(IDC_HANDLE)->SetText(str);
379  }
380  else
381  {
382  g_HUD.GetEditBox(IDC_HANDLE)->SetEnabled(true);
383  }
384  }
385 
386  // passwords
387  if (g_HUD.GetButton(IDC_CONFIRM)->GetEnabled() && !player[ourplayerC].serial)
388  {
389  g_HUD.GetEditBox(IDC_PASSWORD)->SetEnabled(true);
390  g_HUD.GetEditBox(IDC_PWVERIFY)->SetEnabled(true);
391  }
392  else
393  {
394  g_HUD.GetEditBox(IDC_PASSWORD)->SetEnabled(false);
395  g_HUD.GetEditBox(IDC_PWVERIFY)->SetEnabled(false);
396  }
397 
398  // Don't let them change referral, need to bring over the wire to populate this
399  if (!g_HUD.GetButton(IDC_CONFIRM)->GetEnabled() || referralValid == 1)
400  {
401  g_HUD.GetEditBox(IDC_REFERRAL)->SetEnabled(false);
402  }
403  else
404  {
405  if (player[ourplayerC].referrer[0])
406  {
407  g_HUD.GetEditBox(IDC_REFERRAL)->SetEnabled(false);
408  WCHAR str[99];
409  swprintf_s(str, 99, L"%S", player[ourplayerC].referrer);
410  g_HUD.GetEditBox(IDC_REFERRAL)->SetText(str);
411  }
412  else
413  g_HUD.GetEditBox(IDC_REFERRAL)->SetEnabled(true);
414  }
415 
416  // Emphasis
417  //g_HUD.GetComboBox(IDC_EMPHASIS)->SetEnabled(false);
418 
419  // age
420  if (pBuffer || !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
421  {
422  g_HUD.GetEditBox(IDC_AGE)->SetEnabled(false);
423  }
424  else
425  {
426  if (player[ourplayerC].age)
427  {
428  g_HUD.GetEditBox(IDC_AGE)->SetEnabled(false);
429  WCHAR str[99];
430  swprintf_s(str, 99, L"%i", player[ourplayerC].age);
431  g_HUD.GetEditBox(IDC_AGE)->SetText(str);
432  age = (static_cast<float>(player[ourplayerC].age) - 18.0f) / 62.0f;
433  }
434  else
435  {
436  g_HUD.GetEditBox(IDC_AGE)->SetEnabled(true);
437  }
438  }
439 
440  // height
441  if (pBuffer || !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
442  {
443  g_HUD.GetEditBox(IDC_HEIGHT)->SetEnabled(false);
444  }
445  else
446  {
447  if (player[ourplayerC].heightCm)
448  {
449  g_HUD.GetEditBox(IDC_HEIGHT)->SetEnabled(false);
450  WCHAR str[99];
451  swprintf_s(str, 99, L"%i", player[ourplayerC].heightCm);
452  g_HUD.GetEditBox(IDC_HEIGHT)->SetText(str);
453  }
454  else
455  {
456  g_HUD.GetEditBox(IDC_HEIGHT)->SetEnabled(true);
457  }
458  }
459 
460  // weight
461  if (pBuffer ||
462  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
463  {
464  g_HUD.GetEditBox(IDC_WEIGHT)->SetEnabled(false);
465  }
466  else
467  {
468  if (player[ourplayerC].weight)
469  {
470  g_HUD.GetEditBox(IDC_WEIGHT)->SetEnabled(false);
471  WCHAR str[99];
472  swprintf_s(str, 99, L"%i", player[ourplayerC].weight);
473  g_HUD.GetEditBox(IDC_WEIGHT)->SetText(str);
474  }
475  else
476  {
477  g_HUD.GetEditBox(IDC_WEIGHT)->SetEnabled(true);
478  }
479  }
480 
481  // email
482  if (player[ourplayerC].email[0])
483  {
484  g_HUD.GetEditBox(IDC_EMAILADDRESS)->SetEnabled(false);
485  WCHAR str[99];
486  swprintf_s(str, 99, L"%S", player[ourplayerC].email);
487  g_HUD.GetEditBox(IDC_EMAILADDRESS)->SetText(str);
488  }
489  else
490  g_HUD.GetEditBox(IDC_EMAILADDRESS)->SetEnabled(true);
491 
492  // hair color
493  if (pBuffer ||
494  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
495  {
496  g_HUD.GetComboBox(IDC_HAIRCOLOR)->SetEnabled(false);
497  }
498  else
499  {
501  {
502  g_HUD.GetComboBox(IDC_HAIRCOLOR)->SetEnabled(false);
503  g_HUD.GetComboBox(IDC_HAIRCOLOR)->SetSelectedByIndex(player[ourplayerC].haircolor - 1);
504  haircolor = GetHairColorAtIndex(g_HUD.GetComboBox(IDC_HAIRCOLOR)->GetSelectedIndex() + 1);
505  }
506  else
507  {
508  g_HUD.GetComboBox(IDC_HAIRCOLOR)->SetEnabled(true);
509  }
510  }
511 
512  // eye color
513  if (pBuffer ||
514  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
515  {
516  g_HUD.GetComboBox(IDC_EYECOLOR)->SetEnabled(false);
517  }
518  else
519  {
521  {
522  g_HUD.GetComboBox(IDC_EYECOLOR)->SetEnabled(false);
523  g_HUD.GetComboBox(IDC_EYECOLOR)->SetSelectedByIndex(player[ourplayerC].eyecolor - 1);
524  eyecolor = GetEyeColorAtIndex(g_HUD.GetComboBox(IDC_EYECOLOR)->GetSelectedIndex() + 1);
525  }
526  else
527  {
528  g_HUD.GetComboBox(IDC_EYECOLOR)->SetEnabled(true);
529  }
530  }
531 
532  // skin color
533  if (pBuffer ||
534  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
535  {
536  g_HUD.GetSlider(IDC_SKINCOLOR)->SetEnabled(false);
537  }
538  else
539  {
540  if (player[ourplayerC].skincolor)
541  {
542  g_HUD.GetSlider(IDC_SKINCOLOR)->SetEnabled(false);
543  g_HUD.GetSlider(IDC_SKINCOLOR)->SetValue(player[ourplayerC].skincolor);
544  }
545  else
546  {
547  g_HUD.GetSlider(IDC_SKINCOLOR)->SetEnabled(true);
548  }
549  }
550 
551  // skin tone
552  if (pBuffer ||
553  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
554  {
555  g_HUD.GetSlider(IDC_SKINTONE)->SetEnabled(false);
556  }
557  else
558  {
560  {
561  g_HUD.GetSlider(IDC_SKINTONE)->SetEnabled(false);
562  g_HUD.GetSlider(IDC_SKINTONE)->SetValue(player[ourplayerC].skintone);
563  }
564  else
565  {
566  g_HUD.GetSlider(IDC_SKINTONE)->SetEnabled(true);
567  }
568  }
569 
570  // stubble/freckle
571  if (pBuffer ||
572  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
573  {
574  g_HUD.GetSlider(IDC_STUBBLEFRECKLE)->SetEnabled(false);
575  }
576  else
577  {
578  if (player[ourplayerC].stubbleFreckle != -1)
579  {
580  g_HUD.GetSlider(IDC_STUBBLEFRECKLE)->SetEnabled(false);
582  }
583  else
584  {
585  g_HUD.GetSlider(IDC_STUBBLEFRECKLE)->SetEnabled(true);
586  }
587  }
588 
589  // vision
590  if (pBuffer || !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
591  {
592  g_HUD.GetRadioButton(IDC_NORMAL)->SetEnabled(false);
593  g_HUD.GetRadioButton(IDC_IMPLANTS)->SetEnabled(false);
594  g_HUD.GetRadioButton(IDC_FRAMES)->SetEnabled(false);
595  }
596  else
597  {
598  if (player[ourplayerC].vision > 0 && player[ourplayerC].vision < 4)
599  {
600  g_HUD.GetRadioButton(IDC_NORMAL)->SetEnabled(false);
601  g_HUD.GetRadioButton(IDC_IMPLANTS)->SetEnabled(false);
602  g_HUD.GetRadioButton(IDC_FRAMES)->SetEnabled(false);
603 
604  if (player[ourplayerC].vision == 1) // normal
605  {
606  g_HUD.GetRadioButton(IDC_NORMAL)->SetChecked(true);
607  g_HUD.GetSlider(IDC_FRAMETYPE)->SetVisible(false);
608 
609  }
610  else if (player[ourplayerC].vision == 2) // implants
611  {
612  g_HUD.GetRadioButton(IDC_IMPLANTS)->SetChecked(true);
613  g_HUD.GetSlider(IDC_FRAMETYPE)->SetVisible(false);
614  }
615  else if (player[ourplayerC].vision == 3) // frames
616  {
617  g_HUD.GetRadioButton(IDC_FRAMES)->SetChecked(true);
618  g_HUD.GetSlider(IDC_FRAMETYPE)->SetVisible(true);
619  }
620  }
621  else
622  {
623  g_HUD.GetRadioButton(IDC_NORMAL)->SetEnabled(true);
624  g_HUD.GetRadioButton(IDC_IMPLANTS)->SetEnabled(true);
625  g_HUD.GetRadioButton(IDC_FRAMES)->SetEnabled(true);
626  }
627  }
628 
629  // frames slider
630  if (pBuffer ||
631  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled() ||
632  !g_HUD.GetRadioButton(IDC_FRAMES)->GetChecked())
633  {
634  g_HUD.GetSlider(IDC_FRAMETYPE)->SetEnabled(false);
635  }
636  else
637  {
638  if (player[ourplayerC].framegroup)
639  {
640  g_HUD.GetSlider(IDC_FRAMETYPE)->SetEnabled(false);
641  g_HUD.GetSlider(IDC_FRAMETYPE)->SetValue(player[ourplayerC].framegroup);
642  }
643  else
644  {
645  g_HUD.GetSlider(IDC_FRAMETYPE)->SetEnabled(true);
646  }
647  }
648 
649  // head
650  if (pBuffer ||
651  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
652  {
653  g_HUD.GetSlider(IDC_HEAD)->SetEnabled(false);
654  }
655  else
656  {
657  if (player[ourplayerC].headgroup)
658  {
659  g_HUD.GetSlider(IDC_HEAD)->SetEnabled(false);
660  g_HUD.GetSlider(IDC_HEAD)->SetValue(player[ourplayerC].headgroup);
661  }
662  else
663  {
664  g_HUD.GetSlider(IDC_HEAD)->SetEnabled(true);
665  }
666  }
667 
668  // nose
669  if (pBuffer ||
670  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
671  {
672  g_HUD.GetSlider(IDC_NOSE)->SetEnabled(false);
673  }
674  else
675  {
676  if (player[ourplayerC].nosegroup)
677  {
678  g_HUD.GetSlider(IDC_NOSE)->SetEnabled(false);
679  g_HUD.GetSlider(IDC_NOSE)->SetValue(player[ourplayerC].nosegroup);
680  }
681  else
682  {
683  g_HUD.GetSlider(IDC_NOSE)->SetEnabled(true);
684  }
685  }
686 
687  // hairstyle
688  if (pBuffer ||
689  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
690  {
691  g_HUD.GetSlider(IDC_HAIRSTYLE)->SetEnabled(false);
692  }
693  else
694  {
695  if (player[ourplayerC].hairgroup)
696  {
697  g_HUD.GetSlider(IDC_HAIRSTYLE)->SetEnabled(false);
698  g_HUD.GetSlider(IDC_HAIRSTYLE)->SetValue(player[ourplayerC].hairgroup);
699  }
700  else
701  {
702  g_HUD.GetSlider(IDC_HAIRSTYLE)->SetEnabled(true);
703  }
704  }
705 
706  // jawline
707  if (pBuffer ||
708  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
709  {
710  g_HUD.GetSlider(IDC_JAWLINE)->SetEnabled(false);
711  }
712  else
713  {
714  if (player[ourplayerC].jawline)
715  {
716  g_HUD.GetSlider(IDC_JAWLINE)->SetEnabled(false);
717  g_HUD.GetSlider(IDC_JAWLINE)->SetValue(player[ourplayerC].jawline);
718  }
719  else
720  {
721  g_HUD.GetSlider(IDC_JAWLINE)->SetEnabled(true);
722  }
723  }
724 
725  // ears
726  if (pBuffer ||
727  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
728  {
729  g_HUD.GetSlider(IDC_EARS)->SetEnabled(false);
730  }
731  else
732  {
733  if (player[ourplayerC].eargroup)
734  {
735  g_HUD.GetSlider(IDC_EARS)->SetEnabled(false);
736  g_HUD.GetSlider(IDC_EARS)->SetValue(player[ourplayerC].eargroup);
737  }
738  else
739  {
740  g_HUD.GetSlider(IDC_EARS)->SetEnabled(true);
741  }
742  }
743 
744  // feature
745  if (pBuffer ||
746  !g_HUD.GetButton(IDC_CONFIRM)->GetEnabled())
747  {
748  g_HUD.GetSlider(IDC_FEATURE)->SetEnabled(false);
749  }
750  else
751  {
752  if (player[ourplayerC].facialhair)
753  {
754  g_HUD.GetSlider(IDC_FEATURE)->SetEnabled(false);
755  g_HUD.GetSlider(IDC_FEATURE)->SetValue(player[ourplayerC].facialhair);
756  }
757  else
758  {
759  g_HUD.GetSlider(IDC_FEATURE)->SetEnabled(true);
760  }
761  }
762 #pragma endregion
763 
764 #pragma region Validators
765  static int oldfocus = -1;
766  int newfocus = -1;
767  if (g_HUD.GetEditBox(IDC_HANDLE)->m_bHasFocus)
768  newfocus = IDC_HANDLE;
769  else if (g_HUD.GetEditBox(IDC_REFERRAL)->m_bHasFocus)
770  newfocus = IDC_REFERRAL;
771  else if (g_HUD.GetEditBox(IDC_CHARNAME)->m_bHasFocus)
772  newfocus = IDC_CHARNAME;
773  else if (g_HUD.GetEditBox(IDC_EMAILADDRESS)->m_bHasFocus)
774  newfocus = IDC_EMAILADDRESS;
775  if (oldfocus != newfocus)
776  {
777  if (oldfocus == IDC_HANDLE)
778  {
779  // fire validator
780  SPacketBig datapacket = SPacketBig();
781  datapacket.type = 24;
782  sprintf_s(datapacket.msg, sizeof(datapacket.msg), "%S", g_HUD.GetEditBox(IDC_HANDLE)->GetText());
783  datapacket.array = 0;
784  if (datapacket.msg[0])
785  {
786  networking->SendToServer(&datapacket, sizeof(SPacketBig), true);
787  txbuffer += sizeof(SPacketBig);
788  handleValid = 1; // checking
789  }
790  }
791  else if (oldfocus == IDC_REFERRAL)
792  {
793  // fire validator2
794  SPacketBig datapacket = SPacketBig();
795  datapacket.type = 24;
796  sprintf_s(datapacket.msg, sizeof(datapacket.msg), "%S", g_HUD.GetEditBox(IDC_REFERRAL)->GetText());
797  datapacket.array = 1;
798  if (datapacket.msg[0])
799  {
800  networking->SendToServer(&datapacket, sizeof(SPacketBig), true);
801  txbuffer += sizeof(SPacketBig);
802  referralValid = 1; // checking
803  }
804  else
805  referralValid = 2; // blank is ok
806  }
807  else if (oldfocus == IDC_CHARNAME)
808  {
809  // fire validator
810  SPacketBig datapacket = SPacketBig();
811  datapacket.type = 24;
812  sprintf_s(datapacket.msg, sizeof(datapacket.msg), "%S", g_HUD.GetEditBox(IDC_CHARNAME)->GetText());
813  datapacket.array = 2;
814  if (datapacket.msg[0])
815  {
816  networking->SendToServer(&datapacket, sizeof(SPacketBig), true);
817  txbuffer += sizeof(SPacketBig);
818  charnameValid = 1; // checking
819  }
820  }
821  else if (oldfocus == IDC_EMAILADDRESS)
822  {
823  // fire validator
824  SPacketBig datapacket = SPacketBig();
825  datapacket.type = 24;
826  sprintf_s(datapacket.msg, sizeof(datapacket.msg), "%S", g_HUD.GetEditBox(IDC_EMAILADDRESS)->GetText());
827  datapacket.array = 3;
828  if (datapacket.msg[0])
829  {
830  networking->SendToServer(&datapacket, sizeof(SPacketBig), true);
831  txbuffer += sizeof(SPacketBig);
832  emailValid = 1; // checking
833  }
834  }
835  oldfocus = newfocus;
836  }
837 #pragma endregion
838  }
839  break;
840 #pragma endregion
841 #pragma region STATUS_LOADING
843  {
844  // Initialize dialogs (HMI::OnFrameMove only calls once?)
845  logger->Log("Special OnFrameMove(STATUS_LOADING) called!");
846  //No longer needed because we are only doing full-screen otherwise we have to call
847  // something to lose and reset the device
848  // SetWindowLong(DXUTGetHWND(), GWL_STYLE, WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_OVERLAPPED);
849  }
850  break;
851 #pragma endregion
852 #pragma region STATUS_GAME
854 
855  static POINT oldptCursor = ptCursor;
856 
857  //if (DXUTGetHWND() == GetForegroundWindow())//GetFocus())
858  {
859  GetCursorPos(&ptCursor);
860  if (DXUTIsWindowed()) ScreenToClient(DXUTGetHWND(), &ptCursor);
861  ptCursor.x = static_cast<LONG>(ptCursor.x / game->displayscale);
862  ptCursor.y = static_cast<LONG>(ptCursor.y / game->displayscale);
863 
864  if (abs(ptCursor.x - oldptCursor.x) > 2 ||
865  abs(ptCursor.y - oldptCursor.y) > 2)
866  g_fMouseLastMoveTime = 0.0f;
867  oldptCursor = ptCursor;
868  }
869 
870  g_fMouseLastMoveTime += fElapsedTime;
871  if (g_bLeftDown)
872  {
873  g_fLeftDownTime += fElapsedTime * 2.0f;
874  if (g_fLeftDownTime > 20.0f)
875  g_fLeftDownTime = 20.0f;
876  g_fDownCounterTime += g_fLeftDownTime * fElapsedTime;
877  }
878  else
879  g_fDownCounterTime = 0.0f;
880 
881  if (g_bDragging ||
882  (g_bLeftDown && ((abs(ptClick.x - ptCursor.x) > 2 || abs(ptClick.y - ptCursor.y) > 2) && cursoroverwindow > -1))) // moved so we are dragging
883  g_bDragging = true;
884  else
885  g_bDragging = false;
886 
887  // these are things like animations and etc that don't matter first layer hit
888  g_fTabFlashTime += fElapsedTime;
889  if (g_fTabFlashTime > 0.5f)
890  {
891  g_fTabFlashTime = 0.0f;
892  g_bTabLit = !g_bTabLit;
893  }
894 
895  helpboxlang = -1;
896 
897 
898  DialogBase::UpdateAllActiveDialogs(fElapsedTime); // calls "Update" not "FrameMove" or "UpdateMenu"
899  informationDialog->FrameMove(fElapsedTime);
900  // 0000702: Sort not continuously updating
902 
903 
904  // slide up slide away 0 to 32 pixels bottom menu chits
906  (ptCursor.y >= static_cast<long>(game->displayHeight / game->displayscale - (32.0f - m_fSlide)) &&
907  ptCursor.x >= 0 && ptCursor.x < static_cast<long>(game->displayWidth / game->displayscale)))
908  {
909  // slide in (starts at 27 to 0) so 16*20 320 to 1*20 20 per second
910  m_fSlide -= powf(m_fSlide / 27.0f + 1.0f, 4.0f) * fElapsedTime * 20.0f;
911  if (m_fSlide < 0.0f)
912  m_fSlide = 0.0f;
913  }
914  else
915  { // want it to be 3
916  m_fSlide += powf((27.0f - m_fSlide) / 27.0f + 1.0f, 4.0f) * fElapsedTime * 20.0f;
917  if (g_fMouseLastMoveTime > 5.0f)
918  {
919  if (m_fSlide > 32.0f)
920  m_fSlide = 32.0f;
921  }
922  else
923  {
924  if (m_fSlide > 27.0f)
925  m_fSlide = 27.0f;
926  }
927  }
928 
929  cursoroverwindow = -1;
930 
931  for (short t = 0; t < (D_ENUMERATION + 1); t++) // bottom bar
932  {
933  // bottom bar
934  if (ptCursor.x >= icon[t].iconlocation.x && ptCursor.x < (icon[t].iconlocation.x + 32) &&
935  ptCursor.y >= (game->displayHeight / game->displayscale - 32 + m_fSlide) && ptCursor.y <= static_cast<long>(game->displayHeight / game->displayscale))
936  {
937  if (!icon[t].mouseover)
938  {
939  icon[t].mouseover = true;
940  if (icon[t].dialog < 0 || DialogBase::dialogs[icon[t].dialog]->enabled)
942  }
943  cursoroverwindow = -2;
944  }
945  else
946  icon[t].mouseover = false;
947  if (icon[t].mouseover && g_bLeftClick && !g_bDragging)
948  {
950  }
951  }
952 
953  // actual windows (dialogs)
954  // my theory here is that we go through all the items (iconlocation, windowlocation) in order of their
955  // depth and see if there is a mouse over, mouse click, mouse drag, etc...
956 
957  //Check if the mouse is in one of the dialogs and handle it
959 
960  //MARTY's MARKER !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
961 
962  // catchall
964  if (!g_bDragging && !g_bLeftDown)
965  {
966  dragt = -1;
967  dragline = -1;
968  }
969 
970  // DialogBase::SortDialogs();
971 
972  if (grippy)
973  {
974  SetCursor(LoadCursor(nullptr, IDC_SIZENWSE));
975  currentCursor = IDC_SIZENWSE;
976  }
977 
978  if (g_fMouseLastMoveTime > 5.0f)
979  {
980  if (cursorVisible)
981  {
982  ShowCursor(false);
983  cursorVisible = false;
984  }
985  }
986  else if (!cursorVisible)
987  {
988  ShowCursor(true);
989  cursorVisible = true;
990  }
991 
992 
993  break;
994 #pragma endregion
995  }
996 
997  logger->AddToCallStack("HMI::OnFrameMove DONE");
998 }
999 
1001 {
1002  char msg[99];
1003  sprintf_s(msg, sizeof(msg), "HMI::OnResetDevice() @ displaystage=%i", game->displaystage);
1004  logger->Log(msg);
1005  logger->AddToCallStack(msg);
1006 
1007  logger->AddToCallStack("HMI::OnResetDevice() g_pTextSprite");
1008  if (g_pTextSprite)
1009  {
1010  g_pTextSprite->OnResetDevice();
1011  game->UpdateTrackedResource("g_pTextSprite", 2);
1012  }
1013 
1014  logger->Log("HMI::OnResetDevice() g_DialogResourceManager");
1015  logger->AddToCallStack("HMI::OnResetDevice() g_DialogResourceManager");
1016  g_DialogResourceManager.OnD3D9ResetDevice();
1017  game->UpdateTrackedResource("g_DialogResourceManager", 2);
1018 
1019  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
1021  {
1022  logger->Log("HMI::OnResetDevice() g_pFont");
1023  logger->AddToCallStack("HMI::OnResetDevice() g_pFont");
1024  if (g_pFont)
1025  {
1026  g_pFont->OnResetDevice();
1027  game->UpdateTrackedResource("g_pFont", 2);
1028  }
1029  logger->Log("HMI::OnResetDevice() g_pChatFont");
1030  logger->AddToCallStack("HMI::OnResetDevice() g_pChatFont");
1031  if (g_pChatFont)
1032  {
1033  g_pChatFont->OnResetDevice();
1034  game->UpdateTrackedResource("g_pChatFont", 2);
1035  }
1036 
1037  logger->Log("HMI::OnResetDevice() OnDeviceReset");
1038  logger->AddToCallStack("HMI::OnResetDevice() OnDeviceReset");
1040  }
1041 
1042  logger->Log("HMI::OnResetDevice() done!");
1043  logger->AddToCallStack("HMI::OnResetDevice() done!");
1044 }
1045 
1046 bool HMI::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1047 {
1048  logger->AddToCallStack("HMI::MsgProc");
1049 
1050  // Always allow dialog resource manager calls to handle global messages
1051  // so GUI state is updated correctly
1052 
1053  // If you look at this function it just returns false!
1054 // bool pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
1055  // if( pbNoFurtherProcessing )
1056  // return true;
1057 
1058  for (short t = 0; t < D_ENUMERATION; t++)
1059  {
1060  if (DialogBase::dialogs[t] && DialogBase::dialogs[t]->active && DialogBase::dialogs[t]->usesHUD)
1061  {
1062  if (cursoroverwindow == t || cursoroverwindow == -1 || t == D_COMMUNICATIONS || t == D_INTERMEDIA) // always process communications because of global chat
1063  {
1064  if (DialogBase::dialogs[t]->HUD.MsgProc(hWnd, uMsg, wParam, lParam))
1065  return true;
1066  }
1067  }
1068  }
1069 
1070  logger->AddToCallStack("HMI::MsgProc (Past Dialog Iteration)");
1071 
1072  if (uMsg == WM_CHAR)
1073  {
1074  if (LOWORD(wParam) == VK_RETURN && !g_bShift && game->displaystage == GameState::STATUS_GAME)
1075  {
1076  if (DialogBase::OnEnter())
1077  return true;
1078  }
1079  }
1080 
1081  logger->AddToCallStack("HMI::MsgProc (Past WM_CHAR Handler)");
1082 
1083  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
1084  switch (uMsg)
1085  {
1086  case WM_LBUTTONDBLCLK:
1087  g_bLeftDouble = true;
1088  break;
1089  case WM_LBUTTONDOWN:
1090  g_bLeftDown = true;
1091  g_bLeftClick = true;
1092  ptClick = ptCursor;
1093  g_fLeftDownTime = 5.0f;
1094  g_fDownCounterTime = 0.0f;
1095  break;
1096  case WM_LBUTTONUP:
1097  if (g_bDragging)
1098  g_bDropped = true;
1099  g_bLeftDown = false;
1100  g_bDragging = false;
1101  break;
1102  case WM_MOUSEWHEEL:
1103  if (cursoroverwindow > -1)
1104  {
1105  DialogBase::dialogs[cursoroverwindow]->linetop -= GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
1108  else if (cursoroverwindow == D_COMMUNICATIONS)
1110  else if (cursoroverwindow == DD_COMMUNICATIONS)
1112  //else if (cursoroverwindow == D_MESSAGECENTER)
1113  // DialogBase::dialogs[cursoroverwindow]->UpdateMenu(-1);
1114  else if (cursoroverwindow == D_PEOPLEMANAGER)
1116  if (DialogBase::dialogs[cursoroverwindow]->allowscroll)
1119  }
1120  break;
1121  }
1122 
1123  logger->AddToCallStack("HMI::MsgProc (Past uMsg Switch)");
1124 
1125  return false;
1126 }
1127 
1129 {
1130  if (player[ourplayerC].sex == 1)
1131  {
1132  game->sound->LoadCockpitSound(SOUND_PEOPLEGRUNT1, "Sounds\\People\\pain1.wav", false, &game->config.soundConfigLegacy);
1133  game->sound->LoadCockpitSound(SOUND_PEOPLEGRUNT2, "Sounds\\People\\pain2.wav", false, &game->config.soundConfigLegacy);
1134  game->sound->LoadCockpitSound(SOUND_PEOPLEGRUNT3, "Sounds\\People\\pain3.wav", false, &game->config.soundConfigLegacy);
1135  }
1136  else
1137  {
1138  game->sound->LoadCockpitSound(SOUND_PEOPLEGRUNT1, "Sounds\\People\\femalepain1.wav", false, &game->config.soundConfigLegacy);
1139  game->sound->LoadCockpitSound(SOUND_PEOPLEGRUNT2, "Sounds\\People\\femalepain2.wav", false, &game->config.soundConfigLegacy);
1140  game->sound->LoadCockpitSound(SOUND_PEOPLEGRUNT3, "Sounds\\People\\femalepain3.wav", false, &game->config.soundConfigLegacy);
1141  }
1142 }
1143 
1144 HRESULT HMI::OnCreateDevice(IDirect3DDevice9* pd3dDevice)
1145 {
1146  HRESULT hr;
1147 
1148  V_RETURN(D3DXCreateSprite(pd3dDevice, &g_pTextSprite));
1149  game->AddTrackedResource("g_pTextSprite", D3DPOOL_FORCE_DWORD);
1150 
1151  V_RETURN(g_DialogResourceManager.OnD3D9CreateDevice(pd3dDevice));
1152  game->AddTrackedResource("g_DialogResourceManager", D3DPOOL_FORCE_DWORD);
1153 
1154  // Initialize the fonts
1155  V_RETURN(D3DXCreateFontW(pd3dDevice, 12, 6, FW_LIGHT, 1, false, DEFAULT_CHARSET,
1156  OUT_TT_ONLY_PRECIS, ANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE,
1157  L"DejaVu Sans Mono", &g_pFont));
1158  game->AddTrackedResource("g_pFont", D3DPOOL_FORCE_DWORD);
1159 
1160  V_RETURN(D3DXCreateFontW(pd3dDevice, 16, 6, FW_LIGHT, 1, false, DEFAULT_CHARSET,
1161  OUT_TT_ONLY_PRECIS, ANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE,
1162  L"DejaVu Sans Mono", &g_pChatFont));
1163  game->AddTrackedResource("g_pChatFont", D3DPOOL_FORCE_DWORD);
1164 
1166  {
1167  logger->Log("OnCreateDevice called with displaystage between LOGIN and LOADING", Logger::Level::Debug);
1168  for (int i = 0; i < 20; i++)
1170  }
1172  {
1173  logger->Log("OnCreateDevice called with displaystage GAME", Logger::Level::Debug);
1175  }
1176 
1177  return S_OK;
1178 }
1179 
1181 {
1182  if (playerships[0].reference == REF_BUILDING && player[ourplayerC].bldg == 1)
1183  {
1185  {
1188  else
1189  {
1192  }
1193 
1196  else
1198  }
1199  }
1200 }
1201 
1202 void HMI::Toast(const WCHAR* message, ActiveHelp activeHelp)
1203 {
1204  HRESULT hr;
1205 
1206  currentToast.clear();
1207  size_t startOfLine = 0;
1208  size_t lastGoodSpaceIndex = 0;
1209  for (size_t i = 0; i < wcslen(message) - startOfLine; i++)
1210  {
1211  size_t i1 = wcslen(message) - startOfLine - 1;
1212  // taking substring from startOfLine for X characters
1213  WCHAR tempStr[510];
1214  wcscpy_s(tempStr, 510, &message[startOfLine]);
1215  // truncate
1216  tempStr[i + 1] = 0;
1217  // render and calculate
1218  RECT rect = RECT();
1219  try
1220  {
1221  V(game->GUI->g_pFont->DrawTextW(game->GUI->g_pTextSprite, tempStr, -1, &rect, DT_CALCRECT, 0xFFFFFFFF));
1222  }
1223  catch (...)
1224  {
1225  // apparently we get an exception trying to calculate "\n "?
1226  }
1227  // evaluate
1228  if (rect.right < 147 && i != i1)
1229  {
1230  if (tempStr[i] == L' ' || tempStr[i] == L'!' || tempStr[i] == L'。' || tempStr[i] == L',')
1231  lastGoodSpaceIndex = i;
1232  }
1233  else
1234  {
1235  // back up to lastGoodSpaceIndex and push
1236  if (lastGoodSpaceIndex != 0 && i != i1)
1237  {
1238  if (tempStr[lastGoodSpaceIndex] == L' ')
1239  tempStr[lastGoodSpaceIndex] = 0;
1240  else
1241  tempStr[lastGoodSpaceIndex + 1] = 0;
1242  }
1243  currentToast.emplace_back(tempStr);
1244  if (i == i1)
1245  break;
1246  if (lastGoodSpaceIndex != 0)
1247  startOfLine += lastGoodSpaceIndex + 1;
1248  else
1249  startOfLine += wcslen(tempStr) + 1;
1250  i = 0;
1251  lastGoodSpaceIndex = 0;
1252  }
1253  }
1254 
1255  // so if it is 1 then it should be at line 2 ... 2 is at 1.5 ... 3 is at 1 ... 4 is at 0.5 ... 5 is at 0
1256  toastY = (5 - currentToast.size()) * 6;
1257  toastTime = 10.0f;
1258  toastId = activeHelp;
1259  switch (toastId)
1260  {
1267  toastIcon = 13; // information
1268  break;
1271  {
1272  Command command;
1273  command.name = "AuralCargoBay";
1274  game->bus->commandStream.emplace_back(command);
1275  toastIcon = 13; // information
1276  }
1277  break;
1278  case ActiveHelp::Scanning:
1281  toastIcon = 12; // scanner
1282  break;
1298  toastIcon = 11; // construction
1299  break;
1300  case ActiveHelp::NewsFlash:
1302  toastIcon = 9; // news flash
1303  break;
1307  toastIcon = 7; // repair
1308  break;
1312  sound->Play(SOUND_NEWMSG); // @todo new sound
1313  toastIcon = 6; // car
1314  break;
1318  sound->Play(SOUND_NEWMSG); // @todo new sound
1319  toastIcon = 5; // container
1320  break;
1323  case ActiveHelp::FuelTransferSent: // @todo could be fuel icon
1324  case ActiveHelp::FuelTransferReceived: // @todo could be fuel icon
1325  case ActiveHelp::FuelTransferGave: // @todo could be fuel icon
1326  case ActiveHelp::JettisonFuel: // @todo could be fuel icon
1373  case ActiveHelp::LoadedFuel: // @todo could be fuel icon
1374  case ActiveHelp::UnloadedFuel: // @todo could be fuel icon
1375  case ActiveHelp::LoadedCargo: // @todo could be commodity icon
1376  case ActiveHelp::UnloadedCargo: // @todo could be commodity icon
1377  case ActiveHelp::AchievementLevelUp: // @todo could be achievement icon
1378  case ActiveHelp::AchievementUnlocked: // @todo could be achievement icon
1380  toastIcon = 4; // success
1381  break;
1382  case ActiveHelp::TaxiFare:
1383  sound->Play(SOUND_TAXI);
1384  toastIcon = 3; // passenger
1385  break;
1391  toastIcon = 3; // passenger
1392  break;
1398  toastIcon = 2; // contract
1399  break;
1407  toastIcon = 1; // cha-ching
1408  break;
1409  default:
1411  toastIcon = 0; // caution
1412  break;
1413  }
1414 }
1415 
1416 void HMI::AddLanguageOptions(UIControlIds controlId, CDXUTDialog* HUD) const
1417 {
1418  HUD->GetComboBox(controlId)->AddItem(L"English", nullptr);
1419  // skip east asian if not supported
1420  if (eastasian)
1421  {
1422  HUD->GetComboBox(controlId)->AddItem(L"汉语", nullptr);
1423  }
1424  HUD->GetComboBox(controlId)->AddItem(L"Nederlands", nullptr);
1425  HUD->GetComboBox(controlId)->AddItem(L"Français", nullptr);
1426  HUD->GetComboBox(controlId)->AddItem(L"Deutsch", nullptr);
1427  HUD->GetComboBox(controlId)->AddItem(L"Ελληνικά", nullptr);
1428  HUD->GetComboBox(controlId)->AddItem(L"Italiano", nullptr);
1429  // skip east asian if not supported
1430  if (eastasian)
1431  {
1432  HUD->GetComboBox(controlId)->AddItem(L"日本語", nullptr);
1433  HUD->GetComboBox(controlId)->AddItem(L"한국어", nullptr);
1434  }
1435  HUD->GetComboBox(controlId)->AddItem(L"Portuguese", nullptr);
1436  HUD->GetComboBox(controlId)->AddItem(L"Русско", nullptr);
1437  HUD->GetComboBox(controlId)->AddItem(L"Español", nullptr);
1438  unsigned char templang = game->config.language;
1439  if (!eastasian)
1440  {
1441  if (templang >= 1)
1442  templang--;
1443  if (templang >= 7)
1444  templang -= 2;
1445  }
1446  HUD->GetComboBox(controlId)->SetSelectedByIndex(templang);
1447 }
1448 
1449 void HMI::SetLocale() const
1450 {
1451  switch (game->config.language)
1452  {
1453  case 1:
1454  setlocale(LC_ALL, "Chinese"); break;
1455  case 2:
1456  setlocale(LC_ALL, "Dutch"); break;
1457  case 3:
1458  setlocale(LC_ALL, "French"); break;
1459  case 4:
1460  setlocale(LC_ALL, "German"); break;
1461  case 5:
1462  setlocale(LC_ALL, "Greek"); break;
1463  case 6:
1464  setlocale(LC_ALL, "Italian"); break;
1465  case 7:
1466  setlocale(LC_ALL, "Japanese"); break;
1467  case 8:
1468  setlocale(LC_ALL, "Korean"); break;
1469  case 9:
1470  setlocale(LC_ALL, "Portuguese"); break;
1471  case 10:
1472  setlocale(LC_ALL, "Russian"); break;
1473  case 11:
1474  setlocale(LC_ALL, "Spanish"); break;
1475  default:
1476  setlocale(LC_ALL, "English"); break;
1477  }
1478 }
1479 
1481 {
1482  char msg[199];
1483  sprintf_s(msg, sizeof(msg), "LoadLanguage() language %i (east asian support %i)", game->config.language, eastasian ? 1 : 0);
1484  logger->Log(msg);
1485  logger->AddToCallStack(msg);
1486 
1487  FILE* file;
1488  FONT_WIDTH = 6;
1489 
1491  {
1493 
1494  char steamLanguage[99];
1495  strcpy_s(steamLanguage, 99, SteamApps()->GetCurrentGameLanguage());
1496  // ReSharper disable once StringLiteralTypo
1497  if (_strcmpi(steamLanguage, "schinese") == 0) game->config.language = 1;
1498  else if (_strcmpi(steamLanguage, "tchinese") == 0) game->config.language = 1;
1499  else if (_strcmpi(steamLanguage, "dutch") == 0) game->config.language = 2;
1500  else if (_strcmpi(steamLanguage, "french") == 0) game->config.language = 3;
1501  else if (_strcmpi(steamLanguage, "german") == 0) game->config.language = 4;
1502  else if (_strcmpi(steamLanguage, "greek") == 0) game->config.language = 5;
1503  else if (_strcmpi(steamLanguage, "italian") == 0) game->config.language = 6;
1504  else if (_strcmpi(steamLanguage, "japanese") == 0) game->config.language = 7;
1505  // ReSharper disable once StringLiteralTypo
1506  else if (_strcmpi(steamLanguage, "koreana") == 0) game->config.language = 8;
1507  else if (_strcmpi(steamLanguage, "portuguese") == 0) game->config.language = 9;
1508  else if (_strcmpi(steamLanguage, "brazilian") == 0) game->config.language = 9;
1509  else if (_strcmpi(steamLanguage, "russian") == 0) game->config.language = 10;
1510  else if (_strcmpi(steamLanguage, "spanish") == 0) game->config.language = 11;
1511  else
1512  game->config.language = 0; // english
1513 
1514  sprintf_s(msg, sizeof(msg), "LoadLanguage() language %i (Steam override '%s')", game->config.language, steamLanguage);
1515  logger->Log(msg, Logger::Level::Debug);
1516  }
1517 
1518  SetLocale();
1519 
1520  switch (game->config.language)
1521  {
1522  case 0: fopen_s(&file, "Languages\\english.txt", "rt, ccs=UTF-8");
1523  break;
1524  case 1: fopen_s(&file, "Languages\\chinese.txt", "rt, ccs=UNICODE"); FONT_WIDTH = 14;
1525  break;
1526  case 2: fopen_s(&file, "Languages\\dutch.txt", "rt, ccs=UTF-8");
1527  break;
1528  case 3: fopen_s(&file, "Languages\\french.txt", "rt, ccs=UTF-8");
1529  break;
1530  case 4: fopen_s(&file, "Languages\\german.txt", "rt, ccs=UTF-8");
1531  break;
1532  case 5: fopen_s(&file, "Languages\\greek.txt", "rt, ccs=UTF-8");
1533  break;
1534  case 6: fopen_s(&file, "Languages\\italian.txt", "rt, ccs=UTF-8");
1535  break;
1536  case 7: fopen_s(&file, "Languages\\japanese.txt", "rt, ccs=UNICODE"); FONT_WIDTH = 14;
1537  break;
1538  case 8: fopen_s(&file, "Languages\\korean.txt", "rt, ccs=UNICODE"); FONT_WIDTH = 12;
1539  break;
1540  case 9: fopen_s(&file, "Languages\\portuguese.txt", "rt, ccs=UTF-8");
1541  break;
1542  case 10: fopen_s(&file, "Languages\\russian.txt", "rt, ccs=UTF-8");
1543  break;
1544  case 11: fopen_s(&file, "Languages\\spanish.txt", "rt, ccs=UTF-8");
1545  break;
1546  default:
1547  file = nullptr; break;
1548  }
1549  if (!file)
1550  {
1551  sprintf_s(msg, sizeof(msg), "Could not open language file %i!", game->config.language);
1552  logger->Log(msg, Logger::Level::Fatal);
1553  }
1554 
1555  WCHAR str[512];
1556  fwscanf_s(file, L"%[^\n]\n", str, 512); // attribution
1557  for (short t = 0; t < L_ENUMERATION; t++)
1558  {
1559  if (feof(file))
1560  {
1561  strings[t] = L"EOF";
1562  sprintf_s(msg, sizeof(msg), "Reached EOF prematurely on language file %i (%i)!", game->config.language, t);
1563  logger->Log(msg, Logger::Level::Fatal);
1564  }
1565  else
1566  {
1567  fwscanf_s(file, L"%[^\n]\n", str, 512);
1568  if (!str[0])
1569  {
1570  sprintf_s(msg, sizeof(msg), "Reached EOL prematurely on language file %i (%i)!", game->config.language, t);
1571  logger->Log(msg, Logger::Level::Fatal);
1572  }
1573 
1574  const auto wcslen1 = static_cast<short>(wcslen(str));
1575  for (short q = 1; q < wcslen1; q++)
1576  {
1577  if (str[q] == '/' && (q + 1) < wcslen1 && str[q + 1] == '/') // truncate
1578  {
1579  if (q > 0 && str[q - 1] == ' ')
1580  str[q - 1] = 0;
1581  else
1582  str[q] = 0;
1583  }
1584  else if (str[q] == '\\' && (q + 1) < wcslen1 && str[q + 1] == 'n') // LF
1585  {
1586  str[q] = '\r';
1587  str[q + 1] = '\n';
1588  }
1589  else if (str[q] == '\\' && (q + 1) < wcslen1 && str[q + 1] == 't') // tab
1590  {
1591  str[q] = '\t';
1592  str[q + 1] = '\r';
1593  }
1594  }
1595  if (t >= L_TAB_UNNAMED && t < L_BUTTON_RESTOREDEFAULTS)
1596  str[MAX_TAB_CHARS - 1] = 0; // truncate for tabs in case the file is off
1597  strings[t] = str;
1598  }
1599  }
1600 
1601  fclose(file);
1602 
1603  if (strings[L_TAB_GLOBAL].length() >= (MAX_TAB_CHARS - 5))
1604  {
1605  sprintf_s(msg, sizeof(msg), "Error in language file %i at L_TAB_GLOBAL", game->config.language);
1606  logger->Log(msg, Logger::Level::Error);
1607  }
1608  if (strings[L_TAB_UNNAMED].length() >= (MAX_TAB_CHARS - 5))
1609  {
1610  sprintf_s(msg, sizeof(msg), "Error in language file %i at L_TAB_UNNAMED", game->config.language);
1611  logger->Log(msg, Logger::Level::Error);
1612  }
1613 
1614  for (short t = 0; t < D_ENUMERATION; t++)
1615  {
1616  if (DialogBase::dialogs[t])
1617  {
1618  DialogBase::dialogs[t]->ActiveTab(); // for content, width changes because of language change
1619  DialogBase::CheckWidth(t); // for fields, width changes because of language change
1621  }
1622  }
1623  if (informationDialog)
1625 
1626  logger->Log("LoadLanguage() successful!");
1627  logger->AddToCallStack("LoadLanguage() DONE");
1628 }
1629 
1630 void HMI::ShowHelpBubble(const WCHAR* msg) const
1631 {
1632  // 56 letters
1633  RECT rect;
1634  const long bubblewidth = FONT_WIDTH * static_cast<long>(wcslen(msg)) + 1;
1635  if (ptCursor.x >= static_cast<long>(designedWidthC / 2)) // right half
1636  rect.left = ptCursor.x - bubblewidth;
1637  else
1638  rect.left = ptCursor.x + 1;
1639  if (ptCursor.y > static_cast<long>(designedHeightC / 2))
1640  rect.top = ptCursor.y - 12; // bottom half
1641  else
1642  {
1643  rect.top = ptCursor.y + 4; // top half
1644  if (ptCursor.x <= static_cast<long>(designedWidthC / 2)) // left half
1645  rect.left += 12;
1646  else
1647  rect.left -= 2;
1648  }
1649  rect.top -= 2;
1650  rect.right = rect.left + bubblewidth;
1651  rect.bottom = rect.top + 12;
1652  rect.top += 2;
1653 
1654  D3DXVECTOR3 tempvec;
1655  tempvec.x = static_cast<float>(rect.left) - 1;
1656  tempvec.y = static_cast<float>(rect.top) - 4;
1657  tempvec.z = 0.0f;
1658  RECT rect2;
1659  rect2.left = 62;
1660  rect2.right = rect2.left + bubblewidth + 3;
1661  rect2.top = 0; rect2.bottom = 16;
1662  g_pTextSprite->Draw(m_pddsGUILateral, &rect2, nullptr, &tempvec, 0xFFFFFFFF);
1663  tempvec.x = static_cast<float>(rect.right);
1664  tempvec.y = static_cast<float>(rect.top) - 4;
1665  tempvec.z = 0.0f;
1666  rect2.left = 59; rect2.right = 61;
1667  rect2.top = 0; rect2.bottom = 16;
1668  g_pTextSprite->Draw(m_pddsGUILateral, &rect2, nullptr, &tempvec, 0xFFFFFFFF);
1669 
1670 
1671  rect.top = rect.top - 2; // doxygen did NOT like this when it was a -=2;
1672  g_pFont->DrawTextW(g_pTextSprite, msg, -1, &rect, DT_LEFT | DT_NOCLIP, 0xFF000000);
1673 }
1674 
1676 {
1677  logger->Log("InitApp() entry...");
1678 
1679  ptClick.x = ptClick.y = -1;
1680 
1681  for (short t = 0; t < (D_ENUMERATION + 1); t++)
1682  {
1683  icon[t].iconlocation = centerC;// .x = (designedWidthC - (D_ENUMERATION + 1) * 32) / 2 + t * 32;
1684  //icon[t].iconlocation.y = designedHeightC - 32.0f;
1685  //icon[t].iconlocation.z = 0.0f; // this doesn't change for these
1686 
1687  icon[t].iconsource.top = 32;
1688  icon[t].iconsource.bottom = 64;
1689  if (t < (D_ENUMERATION - 1))
1690  icon[t].iconsource.left = 32 * DialogBase::dialogs[t]->icon;
1691  else
1692  icon[t].iconsource.left = 32 * (t + 8);
1693  icon[t].iconsource.right = icon[t].iconsource.left + 32;
1694  icon[t].dialog = t;
1695  }
1696 
1697  icon[(D_ENUMERATION + 1) - 2].dialog = -1;
1698  icon[(D_ENUMERATION + 1) - 1].dialog = -2;
1699 }
1700 
1702 {
1703  int menudat = -1;
1704  _sopen_s(&menudat, "Save\\gui.cfg", _O_BINARY | _O_RDONLY, _SH_DENYNO, _S_IWRITE);
1705  if (menudat == -1)
1706  {
1707  // create
1708  logger->Log(R"(File not yet created: "Save\gui.cfg")");
1709  for (short t = 0; t < D_ENUMERATION; t++)
1710  {
1712  // this might fix sumta's issue
1714  // I think this is where we weren't getting the stuff at the top of the config dialog
1715  DialogBase::dialogs[t]->ActiveTab(); // for content, width changes because of language change
1716  DialogBase::CheckWidth(t); // for fields, width changes because of language change
1717  DialogBase::CheckHeight(t); // for fields, width changes because of language change
1719  }
1720  return;
1721  }
1722 
1723  // load from gui.cfg
1724  logger->Log(R"(Loading file: "Save\gui.cfg")");
1725 
1726  int version, unused;
1727  _read(menudat, &version, 4);
1729  _read(menudat, &unused, 4);
1730 
1731  for (long t = 0; t < D_ENUMERATION; t++)
1732  {
1733  _lseek(menudat, (t + 1L) * 512L, SEEK_SET);
1734  _read(menudat, &DialogBase::dialogs[t]->windowlocation, 12); // 0
1735  if (DialogBase::dialogs[t]->allowresize)
1736  {
1737  _read(menudat, &DialogBase::dialogs[t]->width, 2); // 12
1738  _read(menudat, &DialogBase::dialogs[t]->height, 2); // 14
1739  }
1740  else
1741  {
1742  _lseek(menudat, 4, SEEK_CUR);
1743  }
1744  short tabs, activetab;
1745  _read(menudat, &tabs, 2); // 16
1746  _read(menudat, &activetab, 2); // 18
1747  _read(menudat, &DialogBase::dialogs[t]->sortfield, 2); // 20
1748  _read(menudat, &DialogBase::dialogs[t]->sortdirection, 2); // 22
1749  if (version >= 2 && t != D_INFORMATION)
1750  _read(menudat, &DialogBase::dialogs[t]->active, 1); // 24
1751  else
1752  _lseek(menudat, 1, SEEK_CUR);
1753  // 25-255 unused
1754  _lseek(menudat, (t + 1L) * 512L + 256L, SEEK_SET);
1755  _read(menudat, DialogBase::dialogs[t]->tabstr, MAX_TAB * MAX_TAB_CHARS * 2); // 256-448
1756  // 448-511 unused
1757 
1759  DialogBase::dialogs[t]->ActiveTab(); // for content, width changes because of language change
1760  DialogBase::CheckWidth(static_cast<short>(t)); // for fields, width changes because of language change
1761  DialogBase::CheckHeight(static_cast<short>(t)); // for fields, width changes because of language change
1763  }
1764 
1765  _close(menudat);
1766 }
1767 
1769 {
1770  int menudat = -1;
1771  _sopen_s(&menudat, "Save\\gui.cfg", _O_BINARY | _O_CREAT | _O_WRONLY, _SH_DENYNO, _S_IWRITE);
1772  if (menudat == -1)
1773  logger->Log(R"(SaveConfiguration() could not open or create file: "Save\gui.cfg")", Logger::Level::Warn);
1774  else
1775  logger->Log(R"(Saving file: "Save\gui.cfg")");
1776 
1777  int version = 2, unused = 0;
1778  _write(menudat, &version, 4); //0
1779  _write(menudat, &unused, 4); //4
1780 
1781  for (long t = 0; t < D_ENUMERATION; t++)
1782  {
1783  _lseek(menudat, (t + 1L) * 512L, SEEK_SET);
1784  _write(menudat, &DialogBase::dialogs[t]->windowlocation, 12); // 0
1785  _write(menudat, &DialogBase::dialogs[t]->width, 2); // 12
1786  _write(menudat, &DialogBase::dialogs[t]->height, 2); // 14
1787  _write(menudat, &DialogBase::dialogs[t]->tabs, 2); // 16
1788  _write(menudat, &DialogBase::dialogs[t]->activetab, 2); // 18
1789  _write(menudat, &DialogBase::dialogs[t]->sortfield, 2); // 20
1790  _write(menudat, &DialogBase::dialogs[t]->sortdirection, 2); // 22
1791  _write(menudat, &DialogBase::dialogs[t]->active, 1); // 24
1792  // 25-255 unused
1793  _lseek(menudat, (t + 1L) * 512L + 256L, SEEK_SET);
1794  _write(menudat, DialogBase::dialogs[t]->tabstr, MAX_TAB * MAX_TAB_CHARS * 2); // 256-448
1795  // 448-511 unused
1796  }
1797 
1798  _close(menudat);
1799 }
1800 
1801 void HMI::GetVersionText(WCHAR* str, int size) const
1802 {
1803  if (isSteam)
1804  swprintf_s(str, size, L"%i.%i.%i.%i (%s)", major, minor, build, revision, strings[L_SPLASH_STEAM].c_str());
1805  else if (isLocal)
1806  swprintf_s(str, size, L"%i.%i.%i.%i (%s)", major, minor, build, revision, strings[L_SPLASH_LOCAL].c_str());
1807  else
1808  swprintf_s(str, size, L"%i.%i.%i.%i (%s)", major, minor, build, revision, strings[L_SPLASH_DIRECT].c_str());
1809 }
1810 
1812 {
1813  for (short s = 0; s < D_ENUMERATION; s++)
1814  {
1819  }
1820 
1822 }
1823 
1825 {
1826  static bool callsignFocus = false;
1827  if (callsignFocus && !g_HUD.GetControl(IDC_CALLSIGN)->m_bHasFocus) // lost focus
1828  {
1829  callsignFocus = false;
1830  g_HUD.GetControl(IDC_CALLSIGN)->GetElement(0)->dwTextFormat = DT_RIGHT | DT_VCENTER;
1831  if (!game->config.defaultuser[0])
1832  g_HUD.GetEditBox(IDC_CALLSIGN)->SetText(strings[L_LOGIN_CALLSIGN].c_str(), false);
1833  }
1834  else if (!callsignFocus && g_HUD.GetControl(IDC_CALLSIGN)->m_bHasFocus) // gained focus
1835  {
1836  callsignFocus = true;
1837  if (!game->config.defaultuser[0])
1838  g_HUD.GetEditBox(IDC_CALLSIGN)->ClearText();
1839  g_HUD.GetControl(IDC_CALLSIGN)->GetElement(0)->dwTextFormat = DT_LEFT | DT_VCENTER;
1840  }
1841  if (callsignFocus)
1842  {
1843  sprintf_s(game->config.defaultuser, 13, "%.12S", g_HUD.GetEditBox(IDC_CALLSIGN)->GetText());
1844  WCHAR tempuser[13];
1845  swprintf_s(tempuser, 13, L"%S", game->config.defaultuser);
1846  g_HUD.GetEditBox(IDC_CALLSIGN)->SetText(tempuser);
1847  }
1848 }
1849 
1851 {
1852  static bool passwordfocus = false;
1853  if (passwordfocus && !g_HUD.GetControl(IDC_PASSWORD)->m_bHasFocus)
1854  {
1855  passwordfocus = false;
1856  if (!game->config.defaultpass[0])
1857  g_HUD.GetEditBox(IDC_PASSWORD)->SetText(strings[L_LOGIN_PASSWORD].c_str(), false);
1858  }
1859  else if (!passwordfocus && g_HUD.GetControl(IDC_PASSWORD)->m_bHasFocus)
1860  {
1861  passwordfocus = true;
1862  if (!game->config.defaultpass[0])
1863  g_HUD.GetEditBox(IDC_PASSWORD)->ClearText();
1864  }
1865  if (passwordfocus)
1866  sprintf_s(game->config.defaultpass, 16, "%.15S", g_HUD.GetEditBox(IDC_PASSWORD)->GetText());
1867 }
1868 
1870 {
1871  if (!game->config.defaultuser[0] || !game->config.defaultpass[0])
1872  {
1873  g_HUD.GetButton(IDC_LOGIN)->SetEnabled(false);
1874  g_HUD.GetButton(IDC_CREATE)->SetEnabled(true);
1875  }
1876  else
1877  {
1878  g_HUD.GetButton(IDC_LOGIN)->SetEnabled(true);
1879  g_HUD.GetButton(IDC_CREATE)->SetEnabled(false);
1880  }
1881 }
1882 
1883 void HMI::DisplaySnow(IDirect3DDevice9* pd3dDevice, float fade, float fElapsed)
1884 {
1885  fTime += fElapsed;
1886 
1887  if (tm_time.tm_mon != 11) // not december
1888  return;
1889 
1890  pd3dDevice->SetFVF(D3DFVF_INSTRUMENT);
1891  pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
1892  pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
1893  pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
1894 
1895  //pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
1896  pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
1897 
1898  LPDIRECT3DVERTEXBUFFER9 m_avSnow = nullptr;
1899 
1900  // ReSharper disable once CppEntityAssignedButNoRead
1901  HRESULT hr;
1902  V(pd3dDevice->CreateVertexBuffer(4 * sizeof(D3DINSTRUMENT), D3DUSAGE_WRITEONLY, D3DFVF_INSTRUMENT, D3DPOOL_DEFAULT, &m_avSnow, NULL));
1903 
1904  D3DINSTRUMENT* vtxs;
1905  // Lock the vertex buffer
1906  V(m_avSnow->Lock(0, 0, reinterpret_cast<void**>(&vtxs), D3DLOCK_DISCARD));
1907 
1908  (*vtxs).x = 700.0f * game->displayscale; (*vtxs).y = 0.0f; (*vtxs).z = 1.0f; (*vtxs).w = 2.0f;
1909  (*vtxs).tu = 1; (*vtxs).tv = 0;
1910  vtxs++;
1911  (*vtxs).x = 0.0f; (*vtxs).y = 0.0f; (*vtxs).z = 1.0f; (*vtxs).w = 2.0f;
1912  (*vtxs).tu = 0; (*vtxs).tv = 0;
1913  vtxs++;
1914  (*vtxs).x = 700.0f * game->displayscale; (*vtxs).y = 500.0f * game->displayscale; (*vtxs).z = 1.0f; (*vtxs).w = 2.0f;
1915  (*vtxs).tu = 1; (*vtxs).tv = 1;
1916  vtxs++;
1917  (*vtxs).x = 0.0f; (*vtxs).y = 500.0f * game->displayscale; (*vtxs).z = 1.0f; (*vtxs).w = 2.0f;
1918  (*vtxs).tu = 0; (*vtxs).tv = 1;
1919 
1920  V(m_avSnow->Unlock());
1921 
1922  V(pd3dDevice->SetStreamSource(0, m_avSnow, 0, sizeof D3DINSTRUMENT));
1923 
1924  D3DXVECTOR4 ambient;
1925  ambient.x = fTime;
1926  ambient.y = fade;
1927  ambient.z = 0.0f; // unused
1928  ambient.w = 0.0f; // unused
1929  V(game->graphics->g_pEffect->SetVector("ambient", &ambient));
1930 
1931  V(game->graphics->g_pEffect->Begin(nullptr, 0));
1932  V(game->graphics->g_pEffect->BeginPass(12)); // snow
1933 
1934  V(pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2));
1935 
1936  V(game->graphics->g_pEffect->EndPass());
1937  V(game->graphics->g_pEffect->End());
1938 
1939  V(pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false));
1940  V(pd3dDevice->SetFVF(D3DFVF_VERTEX));
1941  V(pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW));
1942 
1943  SAFE_RELEASE(m_avSnow);
1944 }
1945 
1946 void HMI::OnRender(float fElapsedTime, IDirect3DDevice9* pd3dDevice)
1947 {
1948  HRESULT hr;
1949 
1950  char msg[99];
1951  sprintf_s(msg, sizeof(msg), "HMI::OnRender @ displaystage=%i", game->displaystage);
1952  logger->AddToCallStack(msg);
1953 
1954  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
1955  // ReSharper disable once CppIncompleteSwitchStatement
1956  switch (game->displaystage) // NOLINT
1957  {
1958 #pragma region STATUS_SPLASH
1960  {
1961  D3DXMATRIX matScale;
1962  D3DXMatrixScaling(&matScale, game->displayscale, game->displayscale, 1.0f); // both use Y due to locked 7x5 aspect
1963  V(g_pTextSprite->SetTransform(&matScale));
1964  V(g_pTextSprite->Begin(0));
1965  if (m_pddsGUIRanks)
1966  {
1967  V(g_pTextSprite->Draw(m_pddsGUIRanks, nullptr, nullptr, nullptr,
1968  D3DCOLOR_ARGB(static_cast<short>(255.0f * fade * (1.0f - max(lightningabove[1].intensity * lightningabove[1].
1969  distance, lightningabove[3].intensity * lightningabove[3].distance))), 255, 255, 255)));
1970  }
1972  {
1973  V(g_pTextSprite->Draw(game->graphics->m_pddsLightningAndBackground[1], nullptr, nullptr, nullptr,
1974  D3DCOLOR_ARGB(static_cast<short>(255.0f * fade * max(lightningabove[1].intensity * lightningabove[1].distance,
1975  lightningabove[3].intensity * lightningabove[3].distance)), 255, 255, 255)));
1976  }
1978  {
1979  V(g_pTextSprite->Draw(m_pddsGUIScrollButton, nullptr, nullptr, nullptr,
1980  D3DCOLOR_ARGB(static_cast<short>(255.0f * fade * (1.0f - lightningabove[3].intensity * lightningabove[3
1981  ].distance)), 255, 255, 255)));
1982  }
1984  {
1985  V(g_pTextSprite->Draw(game->graphics->m_pddsLightningAndBackground[0], nullptr, nullptr, nullptr, D3DCOLOR_ARGB(static_cast<short>(255.0f * fade * lightningabove[3].intensity * lightningabove[3].distance), 255, 255, 255)));
1986  }
1987 
1988  D3DXVECTOR3 bill = D3DXVECTOR3(123.0f, 73.0f, 0.0f);
1989  if (m_pddsGUIScroll)
1990  {
1991  V(g_pTextSprite->Draw(m_pddsGUIScroll, nullptr, nullptr, &bill, D3DCOLOR_ARGB(static_cast<short>(255.0f * fade), 255, 255, 255)));
1992  }
1993 
1994 
1995 
1996  if (fade == 1.0f)
1997  {
1998  if (m_pddsGUIParts)
1999  {
2000  bill = D3DXVECTOR3(234.0f, 207.0f, 0.0f);
2001  V(g_pTextSprite->Draw(m_pddsGUIParts, nullptr, nullptr, &bill, 0xFFFFFFFF));
2002  }
2003 
2004  RECT rect;
2005  rect.left = 245; rect.top = 219; rect.right = rect.bottom = -1;
2007  {
2008  g_pFont->DrawTextW(g_pTextSprite, strings[L_SPLASH_CONNECTING].c_str(), -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2009  rect.top += 12;
2010  if (networking->retryconnect)
2011  {
2012  WCHAR tempstr[99];
2013  swprintf_s(tempstr, 99, L"%s (%i)...", strings[L_SPLASH_RETRYING].c_str(), networking->retryconnect);
2014  g_pFont->DrawTextW(g_pTextSprite, tempstr, -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2015  rect.top += 12;
2016  }
2017  }
2019  {
2020  g_pFont->DrawTextW(g_pTextSprite, strings[L_SPLASH_CONNECTED].c_str(), -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2021  rect.top += 12;
2022  }
2023 
2024  static char prepatchdate = game->config.patchdate[0];
2026  {
2027  if (prepatchdate)
2028  g_pFont->DrawTextW(g_pTextSprite, strings[L_SPLASH_CHECKINGFORUPDATES].c_str(), -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2029  else
2030  g_pFont->DrawTextW(g_pTextSprite, strings[L_SPLASH_VALIDATINGINSTALL].c_str(), -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2031  rect.top += 12;
2032 
2033  if (networking->patchbytes)
2034  {
2035  WCHAR tempstr[99];
2036  const float f_temp = static_cast<float>(networking->rcvdbytes) / static_cast<float>(networking->patchbytes) * 100.0f;
2037  if (f_temp >= 100.0f)
2038  {
2039  if (prepatchdate)
2040  swprintf_s(tempstr, 99, strings[L_SPLASH_PATCHING].c_str());
2041  else
2042  swprintf_s(tempstr, 99, strings[L_SPLASH_INSTALLING].c_str());
2043  }
2044  else
2045  {
2046  swprintf_s(tempstr, 99, L"%s (%.0f%%)", strings[L_SPLASH_DOWNLOADING].c_str(), f_temp);
2047  }
2048  g_pFont->DrawTextW(g_pTextSprite, tempstr, -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2049  rect.top += 12;
2050  }
2051  }
2052 
2054  {
2055  if (isSteam)
2056  g_pFont->DrawTextW(g_pTextSprite, strings[L_SPLASH_STEAMUPDATES].c_str(), -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2057  else if (prepatchdate)
2058  g_pFont->DrawTextW(g_pTextSprite, strings[L_SPLASH_UPTODATE].c_str(), -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2059  else
2060  g_pFont->DrawTextW(g_pTextSprite, strings[L_SPLASH_VALIDATED].c_str(), -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2061  rect.top += 12;
2062  }
2063 
2065  {
2066  if (isSteam)
2067  {
2068  // steam version info
2069  SPacketBig outpacket = SPacketBig();
2070  outpacket.type = 30;
2071  sprintf_s(outpacket.msg, sizeof(outpacket.msg), "%s,%i,%i,%i,%i,%llu", game->config.patchdate, major, minor, build, revision, SteamUser()->GetSteamID().ConvertToUint64());
2072  networking->SendToServer(&outpacket, sizeof(SPacketBig), true);
2073 
2075  }
2076  else
2077  {
2078  // request patch
2079  SPacketBig outpacket = SPacketBig();
2080  outpacket.type = 29;
2081  sprintf_s(outpacket.msg, sizeof(outpacket.msg), "%s,%i,%i,%i,%i", game->config.patchdate, major, minor, build, revision);
2082  networking->SendToServer(&outpacket, sizeof(SPacketBig), true);
2083 
2085 
2086  if (game->config.patchdate[0])
2087  {
2088  sprintf_s(msg, sizeof(msg), "Patchdate was %s...", game->config.patchdate);
2089  logger->Log(msg);
2090  }
2091  else
2092  {
2093  logger->Log("Validating installation...");
2094  }
2095  }
2096  }
2097  }
2098 
2099  RECT rect;
2100  rect.left = 10; rect.top = 480; rect.right = rect.bottom = 0;
2101  WCHAR str[99];
2102  GetVersionText(str, 99);
2103  g_pChatFont->DrawTextW(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFFFFFFFF);
2104 
2105 
2106  V(g_pTextSprite->End());
2107 
2108  DisplaySnow(pd3dDevice, 1.0f, fElapsedTime);
2109  }
2110  break;
2111 #pragma endregion
2112 #pragma region STATUS_LOGIN
2114  {
2115  const float adjfade = max(fade - 0.4f, 0.0f) * 1.6666666666666666666666666666667f;
2116  D3DXMATRIX matScale;
2117  D3DXMatrixScaling(&matScale, game->displayscale, game->displayscale, 1.0f); // both use Y due to locked 7x5 aspect
2118  V(g_pTextSprite->SetTransform(&matScale));
2119  V(g_pTextSprite->Begin(D3DXSPRITE_ALPHABLEND));
2120 
2121  if (m_pddsGUIRanks)
2122  {
2123  V(g_pTextSprite->Draw(m_pddsGUIRanks, nullptr, nullptr, nullptr, D3DCOLOR_ARGB(static_cast<short>(255.0f * (1.0f - adjfade)), 255, 255, 255)));
2124  }
2125 
2126  D3DXVECTOR3 bill;
2127 
2128  // city
2130  {
2131  bill = D3DXVECTOR3(0.0f, 500.0f * adjfade * adjfade, 0.0f);
2132  V(g_pTextSprite->Draw(m_pddsGUIScrollButton, nullptr, nullptr, &bill, D3DCOLOR_ARGB(static_cast<short>(255.0f * (1.0f - adjfade)), 255, 255, 255)));
2133  }
2134 
2135  RECT rect;
2136 
2138  {
2139  cloudmotion += fElapsedTime * 6.0f;
2140  if (cloudmotion > 2048.0f)
2141  cloudmotion -= 2048.0f;
2142  rect.left = static_cast<long>(cloudmotion); rect.top = 512 - 500 / 2; rect.right = 700 + static_cast<long>(cloudmotion); rect.bottom = 512 + 500 / 2;
2143  pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
2144  V(g_pTextSprite->Draw(game->graphics->m_pddsCloudBaseMapAndNetwork, &rect, nullptr, nullptr, D3DCOLOR_ARGB(static_cast<short>(255.0f * adjfade), 100, 100, 100)));
2145  V(g_pTextSprite->Flush());
2146  pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2147  }
2148 
2149  for (short s = 0; s < ACLlightningguiC; s++)
2150  {
2152  {
2153  D3DXVECTOR3 tempvec = D3DXVECTOR3(lightningabove[s].panelx -= fElapsedTime * 6.0f, lightningabove[s].panely, 0.0f);
2154  D3DXMATRIX matTemp, matTemp2;
2155  D3DXMatrixScaling(&matTemp, 0.5f, 0.5f, 1.0f);
2156  D3DXMatrixRotationZ(&matTemp2, lightningabove[s].rotate);
2157  matTemp = matTemp * matTemp2;
2158  V(g_pTextSprite->SetTransform(&matTemp));
2159  V(g_pTextSprite->Draw(game->graphics->m_pddsLightningAndBackground[lightningabove[s].texture], nullptr, nullptr, &tempvec, D3DCOLOR_ARGB(static_cast<short>(255.0f * adjfade * lightningabove[s].intensity), 255, 255, 255)));
2160  V(g_pTextSprite->SetTransform(&matScale));
2161  }
2162  }
2163 
2164  // Logo
2165  if (m_pddsGUIScroll)
2166  {
2167  bill = D3DXVECTOR3(123.0f, 73.0f, 0.0f);
2168  V(g_pTextSprite->Draw(m_pddsGUIScroll, nullptr, nullptr, &bill, 0xFFFFFFFF));
2169  }
2170  else
2171  {
2172  logger->Log("m_pddsGUIScroll (Logo.png) was null trying to render the STATUS_LOGIN page (it is loaded on STATUS_SPLASH)", Logger::Level::Debug);
2173  }
2174 
2175  if (fade == 1.0f)
2176  {
2177  // MOTD glass
2178  if (m_pddsGUIParts)
2179  {
2180  bill = D3DXVECTOR3(9.0f, 405.0f, 0.0f);
2181  V(g_pTextSprite->Draw(m_pddsGUIParts, nullptr, nullptr, &bill, 0xFFFFFFFF));
2182 
2183  // MOTD text
2184  for (size_t i = 0; i < motd.size(); i++)
2185  {
2186  rect.left = 19; rect.top = 417 + 12 * i; rect.right = rect.bottom = 0;
2187  g_pFont->DrawTextW(g_pTextSprite, motd.at(i).c_str(), -1, &rect, DT_LEFT | DT_NOCLIP, 0xFFFFFFFF);
2188  }
2189  }
2190 
2191  // Callsign and Password Boxes (Login.png)
2192  if (m_pddsGUIInterlace)
2193  {
2194  bill = D3DXVECTOR3(94.0f, 221.0f, 0.0f);
2195  V(g_pTextSprite->Draw(m_pddsGUIInterlace, nullptr, nullptr, &bill, D3DCOLOR_ARGB(255, 255, 255, 255)));
2196  }
2197 
2198  if (makehud)
2199  {
2200  makehud = false;
2201  g_HUD.Init(&g_DialogResourceManager, true, L"Textures\\dxutcontrols.png");
2202  g_HUD.SetCallback(OnGUIEvent, this);
2203  g_HUD.EnableKeyboardInput(true);
2204  g_HUD.SetFont(0, L"DejaVu Sans Mono", static_cast<LONG>(12.0f * game->displayscale), FW_NORMAL);
2205  g_HUD.SetFont(1, L"EuroseWide Heavy", static_cast<LONG>(20.0f * game->displayscale), FW_NORMAL);
2206  if (game->config.defaultuser[0])
2207  {
2208  WCHAR str[99];
2209  swprintf_s(str, 99, L"%S", game->config.defaultuser);
2210  g_HUD.AddEditBox(IDC_CALLSIGN, str, static_cast<int>(248.0f * game->displayscale), static_cast<int>(230.0f * game->displayscale), static_cast<int>(96.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
2211  }
2212  else
2213  g_HUD.AddEditBox(IDC_CALLSIGN, strings[L_LOGIN_CALLSIGN].c_str(), static_cast<int>(248.0f * game->displayscale), static_cast<int>(230.0f * game->displayscale), static_cast<int>(96.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
2214  g_HUD.GetEditBox(IDC_CALLSIGN)->SetTextColor(0xFFA3A8AF);
2215  g_HUD.GetControl(IDC_CALLSIGN)->GetElement(0)->dwTextFormat = DT_RIGHT | DT_VCENTER;
2216  if (game->config.defaultpass[0])
2217  {
2218  WCHAR wstr[99];
2219  swprintf_s(wstr, 99, L"%S", game->config.defaultpass);
2220  g_HUD.AddEditBox(IDC_PASSWORD, wstr, static_cast<int>(356.0f * game->displayscale), static_cast<int>(230.0f * game->displayscale), static_cast<int>(96.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), false, true);
2221  }
2222  else
2223  g_HUD.AddEditBox(IDC_PASSWORD, strings[L_LOGIN_PASSWORD].c_str(), static_cast<int>(356.0f * game->displayscale), static_cast<int>(230.0f * game->displayscale), static_cast<int>(96.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), false, true);
2224  g_HUD.GetControl(IDC_PASSWORD)->GetElement(0)->dwTextFormat = DT_VCENTER;
2225  g_HUD.GetEditBox(IDC_PASSWORD)->SetTextColor(0xFFA3A8AF);
2226 
2227  g_HUD.AddButton(IDC_LOGIN, strings[L_LOGIN_AWAKEN].c_str(), static_cast<int>(275.0f * game->displayscale), static_cast<int>(291.0f * game->displayscale), static_cast<int>(152.0f * game->displayscale), static_cast<int>(37.0f * game->displayscale));
2228  g_HUD.GetControl(IDC_LOGIN)->GetElement(0)->iFont = 1;
2229  g_HUD.GetControl(IDC_LOGIN)->GetElement(1)->iFont = 1;
2230  g_HUD.AddButton(IDC_CREATE, strings[L_LOGIN_CREATE].c_str(), static_cast<int>(535.0f * game->displayscale), static_cast<int>(409.0f * game->displayscale), static_cast<int>(152.0f * game->displayscale), static_cast<int>(37.0f * game->displayscale));
2231  g_HUD.GetControl(IDC_CREATE)->GetElement(0)->iFont = 1;
2232  g_HUD.GetControl(IDC_CREATE)->GetElement(1)->iFont = 1;
2233  if (game->config.defaultuser[0])
2234  g_HUD.GetControl(IDC_CREATE)->SetEnabled(false);
2235  g_HUD.AddButton(IDC_EULA, strings[L_LOGIN_EULA].c_str(), static_cast<int>(535.0f * game->displayscale), static_cast<int>(451.0f * game->displayscale), static_cast<int>(152.0f * game->displayscale), static_cast<int>(37.0f * game->displayscale));
2236  g_HUD.GetControl(IDC_EULA)->GetElement(0)->iFont = 1;
2237  g_HUD.GetControl(IDC_EULA)->GetElement(1)->iFont = 1;
2238  }
2239 
2240  static bool oldmouseover = false;
2241  if ((g_HUD.GetButton(IDC_LOGIN)->m_bMouseOver || g_HUD.GetButton(IDC_EULA)->m_bMouseOver || g_HUD.GetButton(IDC_CREATE)->m_bMouseOver) && !oldmouseover)
2243  oldmouseover = g_HUD.GetButton(IDC_LOGIN)->m_bMouseOver || g_HUD.GetButton(IDC_EULA)->m_bMouseOver || g_HUD.GetButton(IDC_CREATE)->m_bMouseOver;
2244 
2248 
2249  if (g_HUD.GetEditBox(IDC_CALLSIGN)->GetEnabled())
2250  {
2251  g_HUD.GetButton(IDC_LOGIN)->SetVisible(true);
2252  if (loginstr[0])
2253  {
2254  rect.left = 275; rect.top = 291 + 37; rect.right = 275 + 152; rect.bottom = 291 + 37 + 20;
2255  g_pFont->DrawText(g_pTextSprite, loginstr, -1, &rect, DT_CENTER, 0xFFFF0000);
2256  }
2257  }
2258  else if (sound->musicleft != 0.0f)
2259  {
2260  // draw text and bargraph
2261  const float width = 100.0f;
2262  float percent = min(sound->musicdone / sound->musicleft, 1.0f);
2263  if (percent < 0 || _isnan(percent) || isinf(percent))
2264  {
2265  sprintf_s(msg, sizeof msg, "Found it... musicdone percent was %f", percent);
2266  logger->Log(msg, Logger::Level::Debug);
2267  percent = 0.0f;
2268  }
2269 
2270  rect.left = 62; rect.top = 32; rect.right = 62 + static_cast<long>(width * percent); rect.bottom = 40;
2271  bill = D3DXVECTOR3(300.0f, 315.0f, 0.0f);
2272  V(g_pTextSprite->Draw(m_pddsGUILateral, &rect, nullptr, &bill, 0xFFFFFFFF));
2273  rect.left = 62; rect.top = 40; rect.right = 62 + static_cast<long>(width * (1.0f - percent)); rect.bottom = 48;
2274  bill = D3DXVECTOR3(300.0f + static_cast<long>(width * percent), 315.0f, 0.0f);
2275  V(g_pTextSprite->Draw(m_pddsGUILateral, &rect, nullptr, &bill, 0xFFFFFFFF));
2276  rect.left = 299; rect.top = 300; rect.right = 300 + static_cast<long>(width); rect.bottom = 325;
2277  g_pFont->DrawTextW(g_pTextSprite, strings[L_LOGIN_AUTHENTICATING].c_str(), -1, &rect, DT_CENTER, 0xFFFFFFFF);
2278  sound->musicdone += fElapsedTime;
2279  }
2280  }
2281 
2282  V(g_pTextSprite->End());
2283 
2284  if (fade == 1.0f)
2285  g_HUD.OnRender(fElapsedTime);
2286 
2287  DisplaySnow(pd3dDevice, 1.0f - fade, fElapsedTime);
2288  }
2289  break;
2290 #pragma endregion
2291 #pragma region STATUS_LOADING
2293  {
2295  {
2296  logger->Log("None of the STATUS_LOADING textures are available!", Logger::Debug);
2297  break;
2298  }
2299 
2300  //436,338 is center, start with 46x32 (-23 -16) and works to 512,365
2301  const float tempvar = 18.9565f - 18.1537f * sqrtf(eyemotion);
2302 
2303  D3DXVECTOR3 bill = D3DXVECTOR3(436.0f, 311.5f, 0.0f);
2304 
2305  logger->AddToCallStack("Drawing m_pddsGUIActions");
2306 
2307  // going from .04 to .68 or .64 over time OR 25 to 0.68 over time
2308  D3DXMATRIX matTemp, matTemp2;
2309  D3DXMatrixScaling(&matTemp, tempvar, tempvar, 1.0f);
2310  D3DXMatrixTranslation(&matTemp2, 350.0f * game->displayscale, 250.0f * game->displayscale, 0.0f);
2311  matTemp = matTemp * matTemp2;
2312  V(g_pTextSprite->SetTransform(&matTemp));
2313 
2314  V(g_pTextSprite->Begin(D3DXSPRITE_ALPHABLEND));
2315 
2316  if (m_pddsGUIActions)
2317  {
2318  V(g_pTextSprite->Draw(m_pddsGUIActions, nullptr, &bill, nullptr, D3DCOLOR_ARGB(static_cast<short>(255.0f * fade * (0.5f - furtherdelay) / 0.5f), 255, 255, 255)));
2319  }
2320 
2321  logger->AddToCallStack("Drawing m_pddsCloudBaseMapAndNetwork");
2322 
2323  D3DXMATRIX matScale;
2324  D3DXMatrixScaling(&matScale, game->displayscale, game->displayscale, 1.0f); // both use Y due to locked 7x5 aspect
2325  V(g_pTextSprite->SetTransform(&matScale));
2326  cloudmotion += fElapsedTime * 6.0f;
2327  RECT rect;
2328  rect.left = static_cast<long>(cloudmotion); rect.top = 512 - 500 / 2; rect.right = 700 + static_cast<long>(cloudmotion); rect.bottom = 512 + 500 / 2;
2330  {
2331  V(g_pTextSprite->Draw(game->graphics->m_pddsCloudBaseMapAndNetwork, &rect, nullptr, nullptr, D3DCOLOR_ARGB(static_cast<short>(255.0f * (1.0f - fade)), 100, 100, 100)));
2332  }
2333 
2334  // g_pTextSprite is not null because we just called it above
2335  // bill gets initialized to real numbers, further delay could be NAN?
2336  if (_isnan(furtherdelay) || isinf(furtherdelay)) // can't imagine this is it since we use it above
2337  {
2338  logger->Log("furtherdelay is NAN or INF!? WTH", Logger::Level::Debug);
2339  V(g_pTextSprite->End());
2340  break;
2341  }
2342  if (furtherdelay > 0.5f || furtherdelay < 0.0f) // can't imagine this is it since we use it above
2343  {
2344  logger->Log("furtherdelay is OOB!? WTH", Logger::Level::Debug);
2345  V(g_pTextSprite->End());
2346  break;
2347  }
2348 
2349  if (m_pddsGUIScroll)
2350  {
2351  logger->AddToCallStack("Drawing m_pddsGUIScroll");
2352 
2353  bill = D3DXVECTOR3(123.0f, 73.0f, 0.0f);
2354  if (fade == 1.0f) // fade out logo when fading to white at end of loading
2355  {
2356  V(g_pTextSprite->Draw(m_pddsGUIScroll, nullptr, nullptr, &bill, D3DCOLOR_ARGB(static_cast<short>(255.0f * (0.5f - furtherdelay) / 0.5f), 255, 255, 255)));
2357  }
2358  else
2359  {
2360  V(g_pTextSprite->Draw(m_pddsGUIScroll, nullptr, nullptr, &bill, 0xFFFFFFFF));
2361  }
2362  }
2363 
2364  logger->AddToCallStack("g_pTextSprite->End()");
2365 
2366  try
2367  {
2368  V(g_pTextSprite->End());
2369  }
2370  catch (...)
2371  {
2372  logger->Log("Untyped exception caught calling g_pTextSprite->End() ... calling g_pTextSprite->OnResetDevice()", Logger::Level::Debug);
2373  sprintf_s(msg, sizeof msg, "g_pTextSprite %p", g_pTextSprite);
2374  logger->Log(msg, Logger::Level::Debug);
2375  sprintf_s(msg, sizeof msg, "m_pddsGUIActions %p", m_pddsGUIActions);
2376  logger->Log(msg, Logger::Level::Debug);
2377  sprintf_s(msg, sizeof msg, "m_pddsCloudBaseMapAndNetwork %p", game->graphics->m_pddsCloudBaseMapAndNetwork);
2378  logger->Log(msg, Logger::Level::Debug);
2379  sprintf_s(msg, sizeof msg, "m_pddsGUIScroll %p", m_pddsGUIScroll);
2380  logger->Log(msg, Logger::Level::Debug);
2381  g_pTextSprite->OnResetDevice();
2382  }
2383  }
2384  break;
2385 #pragma endregion
2386 #pragma region STATUS_GAME
2388  if (!dead || playerships[0].simulator)
2389  {
2390  D3DXMATRIX matScale;
2391  D3DXMatrixScaling(&matScale, game->displayscale, game->displayscale, 1.0f);
2392  V(g_pTextSprite->SetTransform(&matScale));
2393 
2394  V(pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP));
2395 
2396  V(g_pTextSprite->Begin(0));
2397 
2398 
2399  // Bottom Bar
2400  RECT source;
2401  source.top = 96;
2402  source.right = 0;
2403  source.left = -static_cast<long>(game->displayWidth / game->displayscale);
2404  source.bottom = 128;
2405  D3DXVECTOR3 tempvec;
2406 
2407  tempvec.x = 0.0f; tempvec.y = game->displayHeight / game->displayscale - 32.0f + m_fSlide; tempvec.z = 0.0f;
2408  V(g_pTextSprite->Draw(m_pddsGUILateral, &source, nullptr, &tempvec, 0xFFFFFFFF));
2409 
2410  // Bottom icons
2411  for (short t = 0; t < (D_ENUMERATION + 1); t++)
2412  {
2413  DWORD tempcolor;
2414  if (icon[t].mouseover && (icon[t].dialog < 0 || DialogBase::dialogs[icon[t].dialog]->enabled))
2415  tempcolor = 0xFFFFFFFF; // bright
2416  else
2417  tempcolor = 0xFFA0A0A0; // dim
2418 
2419  icon[t].iconlocation.x = (game->displayWidth / game->displayscale - (D_ENUMERATION + 1) * 32) / 2 + t * 32;
2420  icon[t].iconlocation.y = game->displayHeight / game->displayscale - 32.0f;
2421  tempvec = icon[t].iconlocation;
2422  tempvec.y += m_fSlide;
2423  RECT rect = icon[t].iconsource;
2424  if (icon[t].dialog > -1 && !DialogBase::dialogs[icon[t].dialog]->enabled)
2425  {
2426  rect.top -= 32; rect.bottom -= 32;
2427  V(g_pTextSprite->Draw(m_pddsGUIParts, &rect, nullptr, &tempvec, 0xFFFFFFFF));
2428  }
2429  else if (icon[t].dialog < 0 || !DialogBase::dialogs[icon[t].dialog]->active)
2430  {
2431  V(g_pTextSprite->Draw(m_pddsGUIParts, &rect, nullptr, &tempvec, tempcolor));
2432  }
2433  else
2434  {
2435  rect.top += 32; rect.bottom += 32;
2436  V(g_pTextSprite->Draw(m_pddsGUIParts, &rect, nullptr, &tempvec, tempcolor));
2437  }
2438 
2439  // Help
2440  if (icon[t].mouseover)
2441  {
2442  if (icon[t].dialog > -1)
2444  else
2445  {
2446  if (icon[t].dialog == -1) // minimize all
2447  {
2448  if (!minimized)
2450  else
2452  }
2453  else if (icon[t].dialog == -2) // exit
2455  }
2456  }
2457  }
2458 
2459  // Draw Dialogs
2460  DialogBase::DrawAllActiveDialogs(fElapsedTime);
2461 
2462  // Help Bubble
2463  if (helpboxlang != -1 && g_fMouseLastMoveTime > 0.5f)
2465 
2466  if (toastTime > 0)
2467  {
2468  toastTime -= fElapsedTime;
2469 
2470  D3DXMatrixScaling(&matScale, game->displayWidth / designedWidthC, game->displayHeight / designedHeightC, 1.0f);
2471  V(g_pTextSprite->SetTransform(&matScale));
2472 
2473  tempvec.x = designedWidthC - 240.0f;
2474  tempvec.y = designedHeightC - 98.0f;
2475  tempvec.z = 0.0f;
2476  V(g_pTextSprite->Draw(m_pddsToast, nullptr, nullptr, &tempvec, 0xFFFFFFFF));
2477 
2478  // Icon at 483 x 424
2479  tempvec.x = designedWidthC - 240.0f + 23.0f;
2480  tempvec.y = designedHeightC - 98.0f + 23.0f;
2481  tempvec.z = 0.0f;
2482  RECT rect;
2483  rect.top = 0; rect.bottom = 32;
2484  rect.left = toastIcon * 32;
2485  rect.right = rect.left + 32;
2486  V(g_pTextSprite->Draw(m_pddsToastIcons, &rect, nullptr, &tempvec, 0xFFFFFFFF));
2487 
2488  // Text at 530 x 404 to 677 x 476
2489  for (size_t i = 0; i < currentToast.size(); i++)
2490  {
2491  rect.left = static_cast<LONG>(designedWidthC) - 171;
2492  rect.top = static_cast<LONG>(designedHeightC) - 90 + toastY + i * 12;
2493  rect.right = rect.bottom = 0;
2494  g_pFont->DrawTextW(g_pTextSprite, currentToast.at(i).c_str(), -1, &rect, DT_LEFT | DT_NOCLIP, 0xFFa6aab1);
2495  }
2496 
2497  if (IsAdmin)
2498  {
2499  // Text at 530 x 404 to 677 x 476
2500  rect.left = static_cast<LONG>(designedWidthC) - 171;
2501  rect.top = static_cast<LONG>(designedHeightC) - 18;
2502  rect.right = rect.bottom = 0;
2503  WCHAR verbiage[99];
2504  swprintf_s(verbiage, 99, L"Toast ID: %i", -toastId);
2505  g_pFont->DrawText(g_pTextSprite, verbiage, -1, &rect, DT_LEFT | DT_NOCLIP, 0xFFa6aab1);
2506  }
2507  }
2508 
2509  // Keyboard Mappings 1815x530 -> 1680x491
2510  if (game->showKeymapOverlay)
2511  {
2512  D3DXMatrixScaling(&matScale, game->displayWidth / 1815.0f, game->displayWidth / 1815.0f, 1.0f);
2513  V(g_pTextSprite->SetTransform(&matScale));
2514 
2515  tempvec.x = 0.0f; tempvec.y = (game->displayHeight - 530.0f * game->displayWidth / 1815.0f) / (game->displayWidth / 1815.0f) * 0.5f; tempvec.z = 0.0f;
2516  RECT src;
2517  src.top = src.left = 0;
2518  src.right = 1815;
2519  src.bottom = 530;
2520  V(g_pTextSprite->Draw(game->viewscreen->m_pddsKeycard, &src, nullptr, &tempvec, 0xAAFFFFFF));
2521  }
2522 
2523  V(g_pTextSprite->End());
2524  }
2525  break;
2526 #pragma endregion
2527  }
2528 
2529  logger->AddToCallStack("HMI::OnRender DONE");
2530 }
2531 
2533 {
2534  logger->Log("CreateDialogs()...");
2535 
2536  for (short t = 0; t < D_ENUMERATION; t++)
2537  DialogBase::draworder[t] = t;
2538 
2539  // Can't do these in the constructor because InitializeDialog is a static reference
2540  // This whole thing was architected poorly
2541 
2542  //DialogBase::dialogs[D_LOCALEINVENTORY] = new VehicleInventoryDialog(D_LOCALEINVENTORY);
2543  //DialogBase::InitializeDialog(D_LOCALEINVENTORY);
2544 
2545  //DialogBase::dialogs[D_PERSONALINVENTORY] = new PersonalInventoryDialog(D_PERSONALINVENTORY);
2546  //DialogBase::InitializeDialog(D_PERSONALINVENTORY);
2547 
2550 
2551  //DialogBase::dialogs[D_VEHICLEMANAGER] = new VehicleManagerDialog(D_VEHICLEMANAGER);
2552  //DialogBase::InitializeDialog(D_VEHICLEMANAGER);
2553 
2554  //DialogBase::dialogs[D_PODSMANAGER] = new PODSManagerDialog(D_PODSMANAGER);
2555  //DialogBase::InitializeDialog(D_PODSMANAGER);
2556 
2557  //DialogBase::dialogs[D_COLONYMANAGER] = new ColonyManagerDialog(D_COLONYMANAGER);
2558  //DialogBase::InitializeDialog(D_COLONYMANAGER);
2559 
2562 
2565 
2568 
2571 
2572  //DialogBase::dialogs[D_MAP] = new MapDialog(D_MAP);
2573  //DialogBase::InitializeDialog(D_MAP);
2574 
2575  //DialogBase::dialogs[D_MESSAGECENTER] = new MessageCenterDialog(D_MESSAGECENTER);
2576  //DialogBase::InitializeDialog(D_MESSAGECENTER);
2577 
2581 
2584 
2585  //DialogBase::dialogs[DD_PEOPLEMANAGER] = new DockedPeopleManagerDialog(DD_PEOPLEMANAGER);
2586  //DialogBase::InitializeDialog(DD_PEOPLEMANAGER);
2587 
2590 
2591  //DialogBase::dialogs[DD_MESSAGECENTER] = new DockedMessageCenterDialog(DD_MESSAGECENTER);
2592  //DialogBase::InitializeDialog(DD_MESSAGECENTER);
2593 
2594  //DialogBase::dialogs[D_CONFIRMATION] = new ConfirmationDialog(D_CONFIRMATION);
2595  //DialogBase::InitializeDialog(D_CONFIRMATION);
2596 }
2597 
2599 {
2600  g->logger->Log("In HMI constructor...");
2601 
2602  game = g;
2603  networking = n;
2604  sound = s;
2605  logger = g->logger;
2606 
2607  time_t now = time(nullptr);
2608  _localtime64_s(&tm_time, &now);
2609 
2610  maxWeight = maxHeight = 0.0f;
2611  eastasian = false;
2612  helpboxlang = -1;
2613  g_bRightDown = false;
2614  g_bRightClick = false;
2615  g_bGVfilter = true;
2616  major = minor = build = revision = 0;
2617 
2618  g_fMouseLastMoveTime = 0.0f;
2619  m_fSlide = 0.0f;
2620  g_fLeftDownTime = 0.0f;
2621  g_fDownCounterTime = 0.0f;
2622  g_fTabFlashTime = 0.0f;
2623  g_bTabLit = false;
2624  cursoroverwindow = -1;
2625  g_bDragging = false;
2626  g_bLeftClick = false;
2627  g_bLeftDown = false;
2628  g_bLeftDouble = false;
2629  FONT_WIDTH = 6;
2630  //sortwindows=false;
2631  g_bDropped = false;
2632  flood = 0.0f;
2633  pBuffer = nullptr;
2634  haircolor = D3DXCOLOR(0UL);
2635  eyecolor = D3DXCOLOR(0UL);
2636  referralValid = 2;
2637  handleValid = 2;
2638  charnameValid = 2;
2639  emailValid = 2;
2640  rxlight = false;
2641  txlight = false;
2642  showerrors = 0;
2643  haserrors = false;
2644  age = 0.0f;
2645  stubbleFreckle = 0.0f;
2646  height = 0.0f;
2647  weight = 0.0f;
2648  rxbuffer = 0;
2649  txbuffer = 0;
2650  fade = 0.0f;
2651  furtherdelay = 0.0f;
2652  eyemotion = 0.0f;
2653  g_pTextSprite = nullptr;
2654  cloudmotion = 0.0f;
2655  makehud = true;
2656 
2657 
2658  for (short t = 0; t < MAX_ONLINEPLAYERS; t++)
2659  {
2660  ZeroMemory(&player[t], sizeof SPlayerData);
2661  player[t].stubbleFreckle = -1;
2662  }
2663 
2664  for (short t = 0; t < MAX_TAB; t++)
2665  {
2666  ZeroMemory(&chatchannel[t], sizeof CHATCHANNEL);
2667  }
2668 
2669  for (short t = 0; t < ACLlightningguiC; t++)
2670  {
2671  ZeroMemory(&lightningabove[t], sizeof LIGHTNINGABOVEGUI);
2672  }
2673 
2674  ZeroMemory(&tempobject, sizeof s_polygon_object);
2675  polyobj = PolyObj(game);
2676 
2677  dragt = -1;
2678  dragline = -1;
2679 
2680  for (short t = 0; t < L_ENUMERATION; t++)
2681  {
2682  WCHAR temp[16];
2683  swprintf_s(temp, 16, L"[VERBIAGE_%i]", t);
2684  strings[t] = temp;
2685  }
2686 
2687  DialogBase::Initialize(this);
2688 
2689  // check working directory ... if it is STEAM then we go straight to CONNECT_PATCHED
2690  PWSTR str;
2691  const HRESULT hr = SHGetKnownFolderPath(FOLDERID_ProgramData, KF_FLAG_DEFAULT, nullptr, &str);
2692  if (hr != S_OK)
2693  logger->Log("Could not SHGetKnownFolderPath for FOLDERID_ProgramData!", Logger::Fatal);
2694 
2695  char programDataPath[MAX_PATH];
2696  sprintf_s(programDataPath, MAX_PATH, "%S", str);
2697  const std::string programDataFolder = programDataPath;
2698  char currentWorkingPath[MAX_PATH];
2699  if (!_getcwd(currentWorkingPath, MAX_PATH))
2700  logger->Log("Could not _getcwd!", Logger::Fatal);
2701 
2702  std::string currentWorkingFolder = currentWorkingPath;
2703  isLocal = currentWorkingFolder.find("\\Rise Base\\CustomUI") == 2;
2704  isSteam = currentWorkingFolder.find(programDataFolder) != 0 && !isLocal;
2705 
2706  if (isSteam)
2707  {
2708  if (SteamAPI_RestartAppIfNecessary(795990))
2709  {
2710  logger->Log("Working directory is a Steam Library folder but was not launched from Steam... restarting...", Logger::Fatal);
2711  }
2712 
2713  if (!SteamAPI_Init())
2714  {
2715  Sleep(1000);
2716  if (!SteamAPI_Init())
2717  {
2718  logger->Log("The Steam Edition of Rise: The Vieneo Province must be launched from the Steam Client!", Logger::Fatal);
2719  }
2720  }
2721  }
2722 
2724 }
2725 
2727 {
2728  for (short t = 0; t < D_ENUMERATION; t++)
2729  SAFE_DELETE(DialogBase::dialogs[t]);
2730 
2731  if (isSteam)
2732  SteamAPI_Shutdown();
2733 
2734  int count1 = 0, count2 = 0;
2735  for (int t = 0; t < 16384; t++)
2736  {
2737  if (buffer1[t]) count1++;
2738  if (buffer2[t]) count2++;
2739  }
2740  if (count1 || count2)
2741  {
2742  char msg[99];
2743  sprintf_s(msg, sizeof msg, "My suspicion was correct: %i %i", count1, count2);
2744  logger->Log(msg, Logger::Level::Error);
2745  }
2746 
2748 }
2749 
2750 void HMI::GarbleChat(wchar_t* str) const
2751 {
2752  if (!playerships[0].simulator && game->viewscreen->ptrPropulsion->tat_mod_qz_x > 140000.0f)
2753  {
2754  const float effect = (game->viewscreen->ptrPropulsion->tat_mod_qz_x - 140000.0f) / 1400000.0f;
2755  if (effect > 0.0f)
2756  {
2757  float len = static_cast<float>(wcslen(str));
2758  const int charsToAffect = static_cast<int>(len * effect);
2759  for (int i = 0; i < charsToAffect; i++)
2760  {
2761  const int index = static_cast<int>(RandomFloat() * len);
2762  str[index] = 1 + static_cast<int>(RandomFloat() * 254.0f);
2763  }
2764  }
2765  }
2766 }
2767 
2768 //--------------------------------------------------------------------------------------
2769 // Handles the GUI events
2770 //--------------------------------------------------------------------------------------
2771 void CALLBACK HMI::OnGUIEvent(UINT nEvent, int nControlID, CDXUTControl*, void* pUserContext)
2772 {
2773  HMI* gui = static_cast<HMI*>(pUserContext);
2774 
2775  char msg[99];
2776  sprintf_s(msg, sizeof(msg), "HMI::OnGUIEvent(%i) @ displaystage=%i", nControlID, gui->game->displaystage);
2777  gui->logger->Log(msg);
2778 
2779  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2780  // ReSharper disable once CppIncompleteSwitchStatement
2781  switch (gui->game->displaystage) // NOLINT
2782  {
2784  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2785  switch (nControlID)
2786  {
2787  case IDC_LOGIN:
2788  {
2789  if (!gui->g_HUD.GetButton(IDC_LOGIN)->GetEnabled())
2790  break;
2791 
2792  gui->sound->Play(SOUND_MOUSECLICK);
2793 
2794  if (gui->sound->g_pSoundIntro)
2795  {
2796  // capture seconds remaining until song transition
2797  const QWORD tempmusicleft = BASS_ChannelGetPosition(gui->sound->g_pSoundIntro, BASS_POS_BYTE);
2798  if (tempmusicleft == -1) // NOLINT
2799  {
2800  sprintf_s(msg, sizeof(msg), "BASS_ChannelGetPosition: %i", BASS_ErrorGetCode());
2801  gui->logger->Log(msg, Logger::Level::Error);
2802  }
2803  else
2804  gui->sound->musicleft = 48.074f - static_cast<float>(BASS_ChannelBytes2Seconds(gui->sound->g_pSoundIntro, tempmusicleft));
2805  gui->sound->musicdone = 0.0f;
2806  }
2807 
2808  gui->g_HUD.GetButton(IDC_LOGIN)->SetVisible(false);
2809  gui->g_HUD.GetEditBox(IDC_CALLSIGN)->SetEnabled(false);
2810  gui->g_HUD.GetEditBox(IDC_PASSWORD)->SetEnabled(false);
2811 
2812  // This is where we do our new packet
2813  SPacketHuge outpacket;
2814  outpacket.type = 0;
2815  strcpy_s(outpacket.login.handle, sizeof(outpacket.login.handle), gui->game->config.defaultuser);
2816  strcpy_s(outpacket.login.password, sizeof(outpacket.login.password), gui->game->config.defaultpass);
2817  outpacket.login.unused1 = 0;
2818  outpacket.login.unused2 = 0;
2819  outpacket.login.unused3 = 0;
2820  outpacket.login.unused4 = 0;
2821  gui->networking->SendToServer(&outpacket, sizeof(SPacketHuge), true);
2822 
2823  sprintf_s(msg, sizeof(msg), "Login packet transmitted: %s", gui->game->config.defaultuser);
2824  gui->logger->Log(msg);
2825  }
2826  break;
2827  case IDC_CALLSIGN:
2828  {
2829  gui->loginstr[0] = 0; // clear error text
2830  gui->ProcessCallsignBox();
2831  gui->UpdateLoginCreateButtons();
2832  }
2833  break;
2834  case IDC_PASSWORD:
2835  {
2836  gui->loginstr[0] = 0; // clear error text
2837  gui->ProcessPasswordBox();
2838  gui->UpdateLoginCreateButtons();
2839  }
2840  break;
2841  case IDC_CREATE:
2842  {
2843  gui->game->config.defaultpass[0] = 0;
2844  gui->sound->Play(SOUND_MOUSECLICK);
2845  gui->showerrors = 0; // no error boxes to start
2846  gui->createRoute = true;
2847  gui->DisplayImmigration(false);
2848  gui->game->sound->loopintro = true;
2849  }
2850  break;
2851  case IDC_EULA:
2852  gui->sound->Play(SOUND_MOUSECLICK);
2853  system("start eula.txt");
2854  gui->g_HUD.GetButton(IDC_EULA)->OnMouseLeave();
2855  break;
2856  }
2857 
2858  break;
2860  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2861  switch (nControlID)
2862  {
2863  case IDC_LANGUAGE:
2864  if (nEvent == EVENT_COMBOBOX_SELECTION_CHANGED)
2865  {
2866  const unsigned char oldlang = gui->game->config.language;
2867  gui->game->config.language = static_cast<unsigned char>(gui->g_HUD.GetComboBox(IDC_LANGUAGE)->GetSelectedIndex());
2868 
2869  if (!gui->eastasian)
2870  {
2871  if (gui->game->config.language >= 1)
2872  gui->game->config.language++;
2873  if (gui->game->config.language >= 7)
2874  gui->game->config.language += 2;
2875  }
2876 
2877  if (oldlang != gui->game->config.language)
2878  {
2879  gui->LoadLanguage(); // do this first so if it fails it doesn't save it
2880  gui->game->config.Save();
2881  gui->networking->RequestVerbiage(0); // just changing language... same as ActiveHelp::MessageOfTheDay
2882  gui->DisplayImmigration(true);
2883  }
2884  }
2885  break;
2886  case IDC_PASSWORD:
2887  case IDC_PWVERIFY:
2888  {
2889  WCHAR str[16];
2890  swprintf_s(str, 16, L"%.15s", gui->g_HUD.GetEditBox(nControlID)->GetText());
2891  gui->g_HUD.GetEditBox(nControlID)->SetText(str);
2892  }
2893  break;
2894 
2895  case IDC_SNAPSHOT:
2896  gui->sound->Play(SOUND_SNAPSHOT);
2897  // save picture to memory buffer
2898  D3DXCreateBuffer(65536, &gui->pBuffer);
2899  gui->game->AddTrackedResource("pBuffer"); // managed
2900  LPDIRECT3DSURFACE9 pSurface;
2901  DXUTGetD3D9Device()->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
2902  RECT rect;
2903  rect.left = static_cast<LONG>(49.0f * gui->game->displayscale);
2904  rect.top = static_cast<LONG>(271.0f * gui->game->displayscale);
2905  rect.right = static_cast<LONG>(177.0f * gui->game->displayscale);
2906  rect.bottom = static_cast<LONG>(399.0f * gui->game->displayscale);
2907  D3DXSaveSurfaceToFileInMemory(&gui->pBuffer, D3DXIFF_JPG, pSurface, nullptr, &rect);
2908  SAFE_RELEASE(pSurface);
2909  break;
2910  case IDC_VOID:
2911  // Free memory buffer for new picture
2912  SAFE_RELEASE(gui->pBuffer);
2913  gui->game->UpdateTrackedResource("pBuffer", 3);
2914  break;
2915  case IDC_FRAMES:
2916  gui->g_HUD.GetControl(IDC_FRAMETYPE)->SetVisible(true);
2917  gui->g_HUD.GetSlider(IDC_FRAMETYPE)->SetValue(451);
2918  break;
2919  case IDC_NORMAL:
2920  case IDC_IMPLANTS:
2921  gui->g_HUD.GetControl(IDC_FRAMETYPE)->SetVisible(false);
2922  gui->g_HUD.GetSlider(IDC_FRAMETYPE)->SetValue(450);
2923  break;
2924  /*case IDC_EMPHASIS:
2925  break;*/
2926  case IDC_HAIRCOLOR:
2927  gui->haircolor = gui->GetHairColorAtIndex(gui->g_HUD.GetComboBox(IDC_HAIRCOLOR)->GetSelectedIndex() + 1);
2928  break;
2929  case IDC_EYECOLOR:
2930  gui->eyecolor = gui->GetEyeColorAtIndex(gui->g_HUD.GetComboBox(IDC_EYECOLOR)->GetSelectedIndex() + 1);
2931  break;
2932  case IDC_CHARNAME:
2933  {
2934  WCHAR str[20];
2935  swprintf_s(str, 20, L"%.19s", gui->g_HUD.GetEditBox(IDC_CHARNAME)->GetText());
2936  if (str[0]) // not blank
2937  {
2938  _wcsupr_s(str, 20);
2939  gui->g_HUD.GetEditBox(IDC_CHARNAME)->SetText(str);
2940  }
2941  gui->g_HUD.GetEditBox(IDC_SIGNATUREHINT)->SetText(str);
2942  }
2943  break;
2944  case IDC_SIGNATURE:
2945  {
2946  WCHAR str[20];
2947  swprintf_s(str, 20, L"%.19s", gui->g_HUD.GetEditBox(IDC_SIGNATURE)->GetText());
2948  if (str[0]) // not blank
2949  {
2950  _wcsupr_s(str, 20);
2951  gui->g_HUD.GetEditBox(IDC_SIGNATURE)->SetText(str);
2952  }
2953  }
2954  break;
2955  case IDC_HANDLE:
2956  {
2957  WCHAR str[13];
2958  swprintf_s(str, 13, L"%.12s", gui->g_HUD.GetEditBox(IDC_HANDLE)->GetText());
2959  if (str[0]) // not blank
2960  {
2961  _wcslwr_s(str, 13);
2962  gui->g_HUD.GetEditBox(IDC_HANDLE)->SetText(str);
2963  }
2964  }
2965  break;
2966  case IDC_EMAILADDRESS:
2967  {
2968  WCHAR str[32];
2969  swprintf_s(str, 32, L"%.31s", gui->g_HUD.GetEditBox(IDC_EMAILADDRESS)->GetText());
2970  if (str[0]) // not blank
2971  gui->g_HUD.GetEditBox(IDC_EMAILADDRESS)->SetText(str);
2972  }
2973  break;
2974  case IDC_REFERRAL:
2975  {
2976  WCHAR str[13];
2977  swprintf_s(str, 13, L"%.12s", gui->g_HUD.GetEditBox(IDC_REFERRAL)->GetText());
2978  if (str[0]) // not blank
2979  {
2980  _wcslwr_s(str, 13);
2981  gui->g_HUD.GetEditBox(IDC_REFERRAL)->SetText(str);
2982  }
2983  gui->referralValid = 2;
2984  }
2985  break;
2986  case IDC_AGE:
2987  {
2988  WCHAR str[3];
2989  swprintf_s(str, 3, L"%.2s", gui->g_HUD.GetEditBox(IDC_AGE)->GetText());
2990  if (str[0] && str[1]) // not blank
2991  {
2992  int val = _wtoi(str);
2993  val = min(80, val);
2994  val = max(18, val);
2995  gui->age = (static_cast<float>(val) - 18.0f) / 62.0f;
2996  gui->g_HUD.GetEditBox(IDC_AGE)->SetText(str);
2997  }
2998  }
2999  break;
3000  case IDC_HEIGHT:
3001  case IDC_WEIGHT:
3002  {
3003  WCHAR str[4];
3004  swprintf_s(str, 4, L"%.3s", gui->g_HUD.GetEditBox(nControlID)->GetText());
3005  gui->g_HUD.GetEditBox(nControlID)->SetText(str);
3006  }
3007  break;
3008  case IDC_STUBBLEFRECKLE:
3009  {
3010  const int val = gui->g_HUD.GetSlider(IDC_STUBBLEFRECKLE)->GetValue();
3011  gui->stubbleFreckle = static_cast<float>(val) * 0.01f;
3012  }
3013  break;
3014  case IDC_BACK:
3015  {
3016  // we don't allow them to go back if it is a re-visit to the form (already a player)
3017  if (wcscmp(gui->g_HUD.GetButton(IDC_BACK)->GetText(), gui->strings[L_IMMIGRATION_QUIT].c_str()) == 0)
3018  {
3019  PostQuitMessage(0);
3020  break;
3021  }
3022 
3023  gui->sound->Play(SOUND_MOUSECLICK);
3024 
3025  gui->game->loadstage = 0;
3027  gui->logger->Log("Reversed to STATUS_LOGIN");
3028  gui->game->discord->UpdatePresence("Login Screen", "Waiting for credentials...", "login");
3029 
3030  SAFE_RELEASE(gui->game->graphics->m_pddsCloudBaseMapAndNetwork);
3031  gui->game->UpdateTrackedResource("m_pddsCloudBaseMapAndNetwork", 3);
3032  SAFE_RELEASE(gui->game->graphics->m_pddsLightningAndBackground[2]);
3033  gui->game->UpdateTrackedResource("m_pddsLightningAndBackground[2]", 3);
3034  SAFE_RELEASE(gui->m_pddsGUILateral);
3035  gui->game->UpdateTrackedResource("m_pddsGUILateral", 3);
3036  SAFE_RELEASE(gui->m_pddsGUIInterlace);
3037  gui->game->UpdateTrackedResource("m_pddsGUIInterlace", 3);
3038 
3039  // this fixes the window size after we leave immigration
3040  if (!GetWindowRect(DXUTGetHWND(), &rect))
3041  {
3042  sprintf_s(msg, 99, "Error in GetWindowRect: %d", GetLastError());
3043  gui->logger->Log(msg, Logger::Fatal);
3044  return;
3045  }
3046 
3047  // both use Y due to locked 7x5 aspect
3048  if (!MoveWindow(DXUTGetHWND(), rect.left, static_cast<int>(rect.top + (705.0f - 500.0f) * 0.5f * gui->game->displayscale), static_cast<int>(700.0f * gui->game->displayscale), static_cast<int>(500.0f * gui->game->displayscale), true))
3049  {
3050  sprintf_s(msg, 99, "Error in MoveWindow: %d", GetLastError());
3051  gui->logger->Log(msg, Logger::Fatal);
3052  return;
3053  }
3054  DXUTReset3DEnvironment();
3055 
3056  gui->g_HUD.RemoveAllControls();
3057  gui->makehud = true;
3058  gui->fade = 1.0f;
3059  gui->game->loadstage = 0;
3060  gui->handleValid = 2;
3061  gui->referralValid = 2;
3062  gui->charnameValid = 2;
3063  gui->emailValid = 2;
3064  }
3065  break;
3066  case IDC_SUGGEST:
3067  {
3068  gui->sound->Play(SOUND_MOUSECLICK);
3069  SClientPacket outpacket; // NOLINT
3070  outpacket.type = 9;
3071  if (gui->g_HUD.GetRadioButton(IDC_MALE)->GetChecked())
3072  outpacket.f_x = 1.0f;
3073  else if (gui->g_HUD.GetRadioButton(IDC_FEMALE)->GetChecked())
3074  outpacket.f_x = 2.0f;
3075  else
3076  outpacket.f_x = 0.0f;
3077  outpacket.f_y = (gui->handleValid == 2) ? 0.0f : 1.0f;
3078  outpacket.f_z = 0.0f; // NULL
3079  outpacket.f_w = 0.0f; // NULL
3080  gui->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
3081  gui->txbuffer += sizeof(SClientPacket);
3082 
3083  gui->g_HUD.GetButton(IDC_SUGGEST)->SetEnabled(false);
3084  }
3085  break;
3086  case IDC_CONFIRM:
3087  {
3088  gui->showerrors = 1; // switch to red highlights
3089  gui->DrawErrorBoxes(); // recalculate if there are still errors
3090 
3091  if (gui->haserrors)
3092  break;
3093 
3094  unsigned char sex;
3095  if (gui->g_HUD.GetRadioButton(IDC_MALE)->GetChecked())
3096  sex = 1;
3097  else if (gui->g_HUD.GetRadioButton(IDC_FEMALE)->GetChecked())
3098  sex = 2;
3099  else
3100  break;
3101 
3102  gui->game->config.g_bAutoLogin = true; // default
3103 
3104  //short context = gui->g_HUD.GetComboBox(IDC_EMPHASIS)->GetSelectedIndex() - 1;
3105 
3106  SPacketHuge outpacket;
3107  outpacket.type = 2; // subscribe to server
3108  sprintf_s(outpacket.subscribe.handle, sizeof(outpacket.subscribe.handle), "%.12S", gui->g_HUD.GetEditBox(IDC_HANDLE)->GetText());
3109  strcpy_s(gui->game->config.defaultuser, sizeof(gui->game->config.defaultuser), outpacket.subscribe.handle);
3110  sprintf_s(outpacket.subscribe.password, sizeof(outpacket.subscribe.password), "%.15S", gui->g_HUD.GetEditBox(IDC_PASSWORD)->GetText());
3111  strcpy_s(gui->game->config.defaultpass, sizeof(gui->game->config.defaultpass), outpacket.subscribe.password);
3112  sprintf_s(outpacket.subscribe.referrer, sizeof(outpacket.subscribe.referrer), "%.12S", gui->g_HUD.GetEditBox(IDC_REFERRAL)->GetText());
3113  sprintf_s(outpacket.subscribe.characterName, sizeof(outpacket.subscribe.characterName), "%.29S", gui->g_HUD.GetEditBox(IDC_CHARNAME)->GetText());
3114  sprintf_s(outpacket.subscribe.email, sizeof(outpacket.subscribe.email), "%.31S", gui->g_HUD.GetEditBox(IDC_EMAILADDRESS)->GetText());
3115 
3116  outpacket.subscribe.age = static_cast<unsigned char>(_wtoi(gui->g_HUD.GetEditBox(IDC_AGE)->GetText()));
3117  outpacket.subscribe.context = 0; // unsupported
3118  outpacket.subscribe.eargroup = static_cast<short>(gui->g_HUD.GetSlider(IDC_EARS)->GetValue());
3119  outpacket.subscribe.eyecolor = static_cast<unsigned char>(gui->g_HUD.GetComboBox(IDC_EYECOLOR)->GetSelectedIndex()) + 1;
3120  outpacket.subscribe.facialhair = static_cast<short>(gui->g_HUD.GetSlider(IDC_FEATURE)->GetValue());
3121  outpacket.subscribe.framegroup = static_cast<short>(gui->g_HUD.GetSlider(IDC_FRAMETYPE)->GetValue());
3122  outpacket.subscribe.haircolor = static_cast<unsigned char>(gui->g_HUD.GetComboBox(IDC_HAIRCOLOR)->GetSelectedIndex()) + 1;
3123  outpacket.subscribe.hairgroup = static_cast<short>(gui->g_HUD.GetSlider(IDC_HAIRSTYLE)->GetValue());
3124  outpacket.subscribe.headgroup = static_cast<short>(gui->g_HUD.GetSlider(IDC_HEAD)->GetValue());
3125  outpacket.subscribe.heightCm = static_cast<unsigned char>(_wtoi(gui->g_HUD.GetEditBox(IDC_HEIGHT)->GetText()));
3126  outpacket.subscribe.jawline = static_cast<short>(gui->g_HUD.GetSlider(IDC_JAWLINE)->GetValue());
3127  outpacket.subscribe.nosegroup = static_cast<short>(gui->g_HUD.GetSlider(IDC_NOSE)->GetValue());
3128  outpacket.subscribe.sex = sex;
3129  outpacket.subscribe.skincolor = static_cast<unsigned char>(gui->g_HUD.GetSlider(IDC_SKINCOLOR)->GetValue());
3130  outpacket.subscribe.skintone = static_cast<unsigned char>(gui->g_HUD.GetSlider(IDC_SKINTONE)->GetValue());
3131  outpacket.subscribe.stubbleFreckle = static_cast<unsigned char>(gui->g_HUD.GetSlider(IDC_STUBBLEFRECKLE)->GetValue());
3132  if (gui->g_HUD.GetRadioButton(IDC_NORMAL)->GetChecked())
3133  outpacket.subscribe.vision = 1;
3134  else if (gui->g_HUD.GetRadioButton(IDC_IMPLANTS)->GetChecked())
3135  outpacket.subscribe.vision = 2;
3136  else
3137  outpacket.subscribe.vision = 3;
3138  outpacket.subscribe.weight = static_cast<unsigned char>(_wtoi(gui->g_HUD.GetEditBox(IDC_WEIGHT)->GetText()));
3139 
3140 
3141  // Final sanity checks
3142  if (!outpacket.subscribe.handle[0])
3143  {
3144  gui->logger->Log("User got here trying to submit a form with a blank handle!?", Logger::Level::Error);
3145  break;
3146  }
3147  if (!outpacket.subscribe.email[0])
3148  {
3149  gui->logger->Log("User got here trying to submit a form with a blank email!?", Logger::Level::Error);
3150  break;
3151  }
3152 
3153 
3154  gui->g_HUD.GetButton(IDC_CONFIRM)->SetEnabled(false);
3155  gui->g_HUD.GetButton(IDC_BACK)->SetEnabled(false);
3156  gui->g_HUD.GetButton(IDC_SUGGEST)->SetEnabled(false);
3157 
3158 
3159  if (gui->player[gui->ourplayerC].serial) // has one
3160  outpacket.subscribe.addrequest = false; // update
3161  else
3162  {
3163  outpacket.subscribe.addrequest = true; // new player
3164  gui->game->config.Save(); // by default autoLogin is ON so we need to save
3165  }
3166 
3167  gui->networking->SendToServer(&outpacket, sizeof(SPacketHuge), true);
3168  gui->txbuffer += sizeof(SPacketHuge);
3169 
3170  // these are things that need to be copied from the immigration form that affect experience later!
3171  strcpy_s(gui->player[gui->ourplayerC].characterName, 30, outpacket.subscribe.characterName);
3172  strcpy_s(gui->player[gui->ourplayerC].email, 32, outpacket.subscribe.email);
3173  gui->player[gui->ourplayerC].heightCm = outpacket.subscribe.heightCm;
3174  ourcockpit.chaireye.z = static_cast<float>(gui->player[gui->ourplayerC].heightCm - 12) * 0.00001f;
3175  }
3176  break;
3177  }
3178  break;
3180  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
3181  switch (nControlID)
3182  {
3183  case IDC_REJOINBTN:
3184  {
3185  gui->g_HUD.GetButton(IDC_REJOINBTN)->SetEnabled(false);
3186 
3187  playerships[0].geardown = true;
3188  ourcockpit.gearextent = 1.0f; // gear down on ground
3190 
3191  gui->game->bus->flapSettingTE = 0;
3192  playerships[0].flapdown = ourcockpit.flapExtent = 0.0f; // flaps up on ground
3194 
3195  playerships[0].baydoor = false;
3196  playerships[0].baydoorextent = 0.0f; // door closed by default
3198 
3199  ourcockpit.hitpoints = 255;
3200  gui->game->RepairVehicle();
3201 
3202  // Flip for them too
3203  if (fabsf(gui->game->bus->RollAttitudeRadians) > 1.5708f && playerships[0].reference == REF_ONGROUND)
3204  {
3205  D3DXQUATERNION quaternionTemp;
3206  D3DXQuaternionRotationYawPitchRoll(&quaternionTemp, 0.0f, 0.0f, D3DX_PI);
3207  D3DXQuaternionMultiply(&playerships[0].orientation, &playerships[0].orientation, &quaternionTemp);
3208  }
3209 
3211 
3212  dead = 0; // false;
3213 
3214  gui->game->viewscreen->counteri = gui->game->viewscreen->counterj = gui->game->viewscreen->counterk = 0.0f;
3215  }
3216  break;
3217  }
3218  break;
3219  }
3220 }
3221 
3222 void HMI::LoadTextures(GameState displaystage, short loadstage)
3223 {
3224  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
3225  switch (displaystage)
3226  {
3228  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
3229  switch (loadstage)
3230  {
3231  case 1:
3232  game->LoadTexture(&m_pddsGUIRanks, "m_pddsGUIRanks", L"Textures\\Splash.png", D3DFMT_R8G8B8); // dark sky background, should be renamed to Sky.png
3233  break;
3234  case 2:
3235  game->LoadTexture(&m_pddsGUIScroll, "m_pddsGUIScroll", L"Textures\\Logo.png"); // Does NOT get released in STATUS_LOGIN
3236  break;
3237  case 3:
3238  game->LoadTexture(&m_pddsGUIScrollButton, "m_pddsGUIScrollButton", L"Textures\\City.png");
3239  break;
3240  case 4:
3241  game->LoadTexture(&game->graphics->m_pddsLightningAndBackground[0], "m_pddsLightningAndBackground[0]", L"Textures\\City-lit.png", D3DFMT_R8G8B8);
3242  break;
3243  case 5:
3244  game->LoadTexture(&game->graphics->m_pddsLightningAndBackground[1], "m_pddsLightningAndBackground[1]", L"Textures\\Sky-lit.png", D3DFMT_R8G8B8);
3245  break;
3246  case 6:
3247  game->LoadTexture(&m_pddsGUIParts, "m_pddsGUIParts", L"Textures\\Glass.png"); // Needed for the login patching window
3248  break;
3249  }
3250  break;
3252  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
3253  switch (loadstage)
3254  {
3255  case 1:
3256  game->LoadTexture(&game->graphics->m_pddsCloudBaseMapAndNetwork, "m_pddsCloudBaseMapAndNetwork", L"Textures\\Clouds\\cloudbase.png", D3DFMT_L8);
3257  break;
3258  case 2:
3259  SAFE_RELEASE(game->graphics->m_pddsLightningAndBackground[0]);
3260  game->UpdateTrackedResource("m_pddsLightningAndBackground[0]", 3);
3261  game->LoadTexture(&game->graphics->m_pddsLightningAndBackground[0], "m_pddsLightningAndBackground[0]", L"Textures\\Clouds\\lightningtoground.dds", D3DFMT_DXT3);
3262  break;
3263  case 3:
3264  SAFE_RELEASE(game->graphics->m_pddsLightningAndBackground[1]);
3265  game->UpdateTrackedResource("m_pddsLightningAndBackground[1]", 3);
3266  game->LoadTexture(&game->graphics->m_pddsLightningAndBackground[1], "m_pddsLightningAndBackground[1]", L"Textures\\Clouds\\lightningtosky.dds", D3DFMT_DXT3);
3267  break;
3268  case 4:
3269  game->LoadTexture(&game->graphics->m_pddsLightningAndBackground[2], "m_pddsLightningAndBackground[2]", L"Textures\\Clouds\\lightningincloud.dds", D3DFMT_DXT3);
3270  break;
3271  case 5:
3272  game->LoadTexture(&m_pddsGUIInterlace, "m_pddsGUIInterlace", L"Textures\\Login.png");
3273  break;
3274  case 6:
3275  game->LoadTexture(&m_pddsGUILateral, "m_pddsGUILateral", L"Textures\\GUI\\guilateral.png"); // needed for the login progress bar
3276  break;
3277  }
3278  break;
3280  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
3281  switch (loadstage)
3282  {
3283  case 1:
3284  SAFE_RELEASE(m_pddsGUIInterlace);
3285  game->UpdateTrackedResource("m_pddsGUIInterlace", 3);
3286  game->LoadTexture(&m_pddsGUIInterlace, "m_pddsGUIInterlace", L"Textures\\Immigration.png", D3DFMT_R8G8B8);
3287  break;
3288  case 2:
3289  SAFE_RELEASE(game->graphics->m_pddsCloudBaseMapAndNetwork);
3290  game->UpdateTrackedResource("m_pddsCloudBaseMapAndNetwork", 3);
3291  game->LoadTexture(&game->graphics->m_pddsCloudBaseMapAndNetwork, "m_pddsCloudBaseMapAndNetwork", L"Textures\\Network.png");
3292  break;
3293  }
3294  break;
3296  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
3297  switch (loadstage)
3298  {
3299  case 1:
3300  game->LoadTexture(&m_pddsGUIActions, "m_pddsGUIActions", L"Textures\\eyezoomtest.png", D3DFMT_R8G8B8);
3301  break;
3302  }
3303  break;
3305  {
3306  logger->Log("Loading GUI Textures (Managed)");
3307  game->LoadTexture(&m_pddsGUIScroll, "m_pddsGUIScroll", L"Textures\\GUI\\scrollbar.png");
3308  game->LoadTexture(&m_pddsGUIScrollButton, "m_pddsGUIScrollButton", L"Textures\\GUI\\scrollbutton.png");
3309  game->LoadTexture(&m_pddsGUIInterlace, "m_pddsGUIInterlace", L"Textures\\GUI\\interlace.png");
3310  game->LoadTexture(&m_pddsGUIInterlace2, "m_pddsGUIInterlace2", L"Textures\\GUI\\smokescreen.png");
3311  game->LoadTexture(&m_pddsGUIActions, "m_pddsGUIActions", L"Textures\\GUI\\actions.png");
3312  game->LoadTexture(&m_pddsGUIRanks, "m_pddsGUIRanks", L"Textures\\GUI\\ranks.png");
3313  game->LoadTexture(&m_pddsGUIParts, "m_pddsGUIParts", L"Textures\\GUI\\gui.png");
3314  game->LoadTexture(&m_pddsToast, "m_pddsToast", L"Textures\\GUI\\toast.png", D3DFMT_R8G8B8);
3315  game->LoadTexture(&m_pddsToastIcons, "m_pddsToastIcons", L"Textures\\GUI\\icons.png");
3316  game->LoadTexture(&m_pddsEasydockAd, "m_pddsEasydockAd", L"Textures\\GUI\\EasydockAd.png", D3DFMT_R8G8B8);
3317  if (!m_pddsGUILateral)
3318  game->LoadTexture(&m_pddsGUILateral, "m_pddsGUILateral", L"Textures\\GUI\\guilateral.png"); // for OnDestroyDevice
3319  }
3320  break;
3321  }
3322 }
3323 
3325 {
3326  logger->Log("HMI::OnDestroyDevice");
3327  logger->AddToCallStack("HMI::OnDestroyDevice");
3328 
3329  g_DialogResourceManager.OnD3D9DestroyDevice();
3330  game->UpdateTrackedResource("g_DialogResourceManager", 3);
3331 
3332  if (tempobject.VB)
3333  {
3334  SAFE_RELEASE(tempobject.VB);
3335  game->UpdateTrackedResource("tempobject.VB", 3);
3336  }
3337 
3338  SAFE_RELEASE(g_pTextSprite);
3339  game->UpdateTrackedResource("g_pTextSprite", 3);
3340  SAFE_RELEASE(g_pFont);
3341  game->UpdateTrackedResource("g_pFont", 3);
3342  SAFE_RELEASE(g_pChatFont);
3343  game->UpdateTrackedResource("g_pChatFont", 3);
3344 
3345  SAFE_RELEASE(m_pddsGUIParts);
3346  game->UpdateTrackedResource("m_pddsGUIParts", 3);
3347  SAFE_RELEASE(m_pddsGUILateral);
3348  game->UpdateTrackedResource("m_pddsGUILateral", 3);
3349 
3350  SAFE_RELEASE(m_pddsGUIScroll);
3351  game->UpdateTrackedResource("m_pddsGUIScroll",3);
3352 
3353  SAFE_RELEASE(m_pddsGUIScrollButton);
3354  game->UpdateTrackedResource("m_pddsGUIScrollButton", 3);
3355  SAFE_RELEASE(m_pddsGUIInterlace);
3356  game->UpdateTrackedResource("m_pddsGUIInterlace", 3);
3357  SAFE_RELEASE(m_pddsGUIInterlace2);
3358  game->UpdateTrackedResource("m_pddsGUIInterlace2", 3);
3359  SAFE_RELEASE(m_pddsGUIRanks);
3360  game->UpdateTrackedResource("m_pddsGUIRanks", 3);
3361  SAFE_RELEASE(m_pddsGUIActions);
3362  game->UpdateTrackedResource("m_pddsGUIActions", 3);
3363  SAFE_RELEASE(m_pddsToast);
3364  game->UpdateTrackedResource("m_pddsToast", 3);
3365  SAFE_RELEASE(m_pddsToastIcons);
3366  game->UpdateTrackedResource("m_pddsToastIcons", 3);
3367  SAFE_RELEASE(m_pddsEasydockAd);
3368  game->UpdateTrackedResource("m_pddsEasydockAd", 3);
3369 
3370  logger->AddToCallStack("HMI::OnDestroyDevice DONE");
3371 }
3372 
3373 void HMI::PlayerOffline(unsigned char arrayindex)
3374 {
3375  if (player[arrayindex].online)
3376  {
3377  WCHAR str[199];
3378  swprintf_s(str, 199, L"Player logged off %S", player[arrayindex].extraText);
3379  chatchannel[0].chatline.emplace_back(str);
3380  chatchannel[0].chatlineplayer.emplace_back(player[arrayindex].callsign);
3381  chatchannel[0].RemovePlayer(arrayindex);
3382 
3383  player[arrayindex].online = false;
3384  player[arrayindex].callsign[0] = 0;
3385 
3387  {
3388  for (int t = 1; t < DialogBase::dialogs[D_COMMUNICATIONS]->tabs; t++)
3389  PlayerLeftChannel(t, arrayindex);
3391  if (!chatchannel[0].dnd)
3392  {
3393  if (DialogBase::dialogs[D_COMMUNICATIONS]->activetab != 0)
3396  }
3398  }
3399  }
3400  else
3401  {
3402  logger->Log("Could be this is the problem with blank callsignY2Y2?", Logger::Level::Debug);
3403  }
3404 }
3405 
3407 {
3408  g_HUD.GetButton(IDC_LOGIN)->SetEnabled(true);
3409  g_HUD.GetEditBox(IDC_CALLSIGN)->SetEnabled(true);
3410  g_HUD.GetEditBox(IDC_PASSWORD)->SetEnabled(true);
3411 }
3412 
3413 void HMI::PlayerJoinedChannel(short tab, unsigned char playerindex)
3414 {
3415  chatchannel[tab].AddPlayer(playerindex);
3416  chatchannel[tab].chatline.emplace_back(L"Player joined channel");
3417  chatchannel[tab].chatlineplayer.emplace_back(player[playerindex].callsign);
3418 
3420  {
3423  if (!chatchannel[tab].dnd)
3424  {
3425  if (DialogBase::dialogs[D_COMMUNICATIONS]->activetab != tab)
3428  }
3429  }
3430 }
3431 
3432 void HMI::PlayerLeftChannel(short tab, unsigned char playerindex)
3433 {
3434  chatchannel[tab].chatline.emplace_back(L"Player left channel");
3435  chatchannel[tab].chatlineplayer.emplace_back(player[playerindex].callsign);
3436  chatchannel[tab].RemovePlayer(playerindex);
3437 
3439  {
3442  if (!chatchannel[tab].dnd)
3443  {
3444  if (DialogBase::dialogs[D_COMMUNICATIONS]->activetab != tab)
3447  }
3448  }
3449 }
3450 
3451 void HMI::ChangeChannelOwner(short tab, unsigned char playerindex)
3452 {
3453  char msg[99];
3454  sprintf_s(msg, sizeof(msg), "Got new owner %i for tab %i channel %i", playerindex, tab, chatchannel[tab].channel);
3455  logger->Log(msg);
3456 
3457  chatchannel[tab].owner = playerindex;
3458 
3461 }
3462 
3463 void HMI::AddSupportChatMessage(const WCHAR* wmsg)
3464 {
3465  chatchannel[0].chatline.emplace_back(wmsg);
3466  chatchannel[0].chatlineplayer.emplace_back("support");
3467 
3469  {
3471  if (!chatchannel[0].dnd)
3472  {
3473  if (DialogBase::dialogs[D_COMMUNICATIONS]->activetab == 0)
3474  sound->Play(SOUND_CHAT);
3475  else
3477  }
3478  }
3479 }
3480 
3481 void HMI::AddDiscordChatMessage(const WCHAR* msg)
3482 {
3483  WCHAR wmsg[STORE_CHAT_SIZE];
3484  for (size_t i = 0; i < wcslen(msg); i++)
3485  {
3486  if (msg[i] == L']') // find first separator
3487  {
3488  wcscpy_s(wmsg, STORE_CHAT_SIZE, &msg[i + 1]);
3489  chatchannel[0].chatline.emplace_back(wmsg);
3490 
3491  char callsign[13];
3492  sprintf_s(callsign, 13, "%.*S", i, msg);
3493  chatchannel[0].chatlineplayer.emplace_back(callsign);
3494  break;
3495  }
3496  }
3497 
3499  {
3501  if (!chatchannel[0].dnd)
3502  {
3503  if (DialogBase::dialogs[D_COMMUNICATIONS]->activetab == 0)
3504  sound->Play(SOUND_CHAT);
3505  else
3507  }
3508  }
3509 }
3510 
3511 void HMI::AddChatMessage(WCHAR* msg, unsigned char playerindex, unsigned char channel)
3512 {
3513  for (short t = 0; t < MAX_TAB; t++)
3514  {
3515  if (chatchannel[t].channel == channel) // channel
3516  {
3517  bool allow = true;
3518  if (playerindex < MAX_ONLINEPLAYERS) // reserved 254 from server, 255 from support
3519  {
3520  for (short s = 0; s < MAX_ONLINEPLAYERS; s++)
3521  {
3522  if (chatchannel[t].seqplayer[s] == playerindex) // from
3523  {
3524  if (chatchannel[t].dndplayer[s])
3525  {
3526  allow = false;
3527  logger->Log("AddChatMessage was disallowed due to DND");
3528  }
3529  s = MAX_ONLINEPLAYERS;
3530  }
3531  }
3532  }
3533  if (allow)
3534  {
3535  if (msg[0] != 0) // not a token, this is the 4th position in the array
3536  {
3537  GarbleChat(msg);
3538 
3539  chatchannel[t].chatline.emplace_back(msg);
3540 
3541  logger->Log("AddChatMessage was non-tokenized");
3542  }
3543  else
3544  {
3545  Swaypoint waypoint;
3546  memcpy_s(&waypoint, sizeof(Swaypoint), &msg[2], sizeof(Swaypoint));
3547  WCHAR tokenchatline[STORE_CHAT_SIZE];
3548  tokenchatline[0] = msg[0]; // tokenized
3549  tokenchatline[1] = msg[1]; // token type
3550  memcpy_s(&tokenchatline[2], STORE_CHAT_SIZE, &waypoint, sizeof(Swaypoint));
3551 
3552  chatchannel[t].chatline.emplace_back(tokenchatline);
3553  logger->Log("AddChatMessage was tokenized");
3554  }
3555  if (playerindex == 254)
3556  chatchannel[t].chatlineplayer.emplace_back("SERVER");
3557  else if (playerindex == 255)
3558  chatchannel[t].chatlineplayer.emplace_back("SUPPORT");
3559  else
3560  chatchannel[t].chatlineplayer.emplace_back(player[playerindex].callsign);
3561 
3562  char str[99];
3563  sprintf_s(str, 99, "AddChatMessage was from %s (Channel %i Line %i)", chatchannel[t].chatlineplayer.at(chatchannel[t].chatlineplayer.size() - 1).c_str(), t, chatchannel[t].chatline.size());
3564  logger->Log(str);
3565  char charmsg[999];
3566  sprintf_s(charmsg, 999, "%S", msg);
3567  logger->Log(charmsg);
3568 
3570  {
3572  if (!chatchannel[t].dnd)
3573  {
3574  if (DialogBase::dialogs[D_COMMUNICATIONS]->activetab == t)
3575  sound->Play(SOUND_CHAT);
3576  else
3578  }
3579  }
3580  }
3581  t = MAX_TAB; // stop loop
3582  }
3583  }
3584 }
3585 
3586 void HMI::AddPlayer(char* msg, unsigned char playerindex)
3587 {
3588  int sex, serial, rank, context, joined;
3589  const int count = sscanf_s(msg, "%d,%[^,],%d,%d,%d,%d,%[^\n,],%[^\n]",
3590  &sex,
3591  player[playerindex].callsign, sizeof(player[playerindex].callsign),
3592  &context,
3593  &rank,
3594  &serial,
3595  &joined,
3596  player[playerindex].characterName, sizeof(player[playerindex].characterName),
3597  player[playerindex].extraText, sizeof player[playerindex].extraText);
3598  if (count == 7)
3599  player[playerindex].extraText[0] = 0;
3600 
3601  player[playerindex].sex = static_cast<char>(sex);
3602  player[playerindex].context = static_cast<char>(context);
3603  player[playerindex].rank = static_cast<char>(rank);
3604  // this is 0 until initialized
3605  player[playerindex].serial = static_cast<unsigned short>(serial);
3606  player[playerindex].createdate = static_cast<time_t>(joined);
3607 
3608  WCHAR str[199];
3609  if (!player[playerindex].online)
3610  {
3611  chatchannel[0].AddPlayer(playerindex);
3612  swprintf_s(str, 199, L"Player logged on %S", player[playerindex].extraText);
3613  chatchannel[0].chatline.emplace_back(str);
3614  chatchannel[0].chatlineplayer.emplace_back(player[playerindex].callsign);
3615 
3617  {
3619  if (!chatchannel[0].dnd)
3620  {
3625  }
3626  }
3627 
3628  player[playerindex].online = true;
3629  }
3630  else
3631  {
3632  logger->Log("Could be this is the problem with blank callsign?", Logger::Level::Debug);
3633  }
3634 
3637 }
3638 
3639 void HMI::SetPlayerAlignment(char* msg, unsigned char playerindex)
3640 {
3641  int i_temp1, i_temp2, i_temp3, i_temp4, i_temp5, i_temp6;
3642  sscanf_s(msg, "%[^,],%d,%d,%d,%d,%d,%d",
3643  player[playerindex].allianceName, sizeof player[playerindex].allianceName, &i_temp1, &i_temp2, &i_temp3, &i_temp4, &i_temp5, &i_temp6);
3644  player[playerindex].allianceHeadId = static_cast<unsigned short>(i_temp1);
3645  if (!player[playerindex].allianceHeadId)
3646  player[playerindex].allianceName[0] = 0;
3647  player[playerindex].alignment = static_cast<char>(i_temp3);
3648 
3649  int t = people.ResidesLocally(player[playerindex].serial);
3650  if (t)
3651  {
3652  SPlayerData playerData = people.LoadPerson(t);
3653 
3654  strcpy_s(playerData.allianceName, sizeof playerData.allianceName, player[playerindex].allianceName);
3655  playerData.allianceHeadId = player[playerindex].allianceHeadId;
3656 
3657  if (playerData.alignment != player[playerindex].alignment)
3658  {
3659  playerData.alignment = player[playerindex].alignment;
3660  for (t = 0; t < MAX_SCAN; t++)
3661  {
3662  // crap we can only do this with vehicles that we know about
3663  if (playerships[t].active && _strcmpi(playerships[t].owner, playerData.callsign) == 0)
3664  {
3665  const Sscan scan = game->bus->Scanner.Get(playerships[t].vehicleId);
3666  if (scan.initialized)
3667  playerships[t].align = player[playerindex].alignment;
3668  else
3669  playerships[t].align = 1;
3670  }
3671  }
3674  }
3675 
3676  people.SavePerson(t, playerData);
3677 
3680  }
3681 }
3682 
3683 void HMI::ChangeChannelName(unsigned char channelId, char* title)
3684 {
3685  char msg[99];
3686  sprintf_s(msg, sizeof(msg), "Got new title for channel %i: %s", channelId, title);
3687  logger->Log(msg);
3688  for (short t = 1; t < MAX_TAB; t++)
3689  {
3690  if (chatchannel[t].channel == channelId)
3691  {
3692  sprintf_s(msg, sizeof(msg), "Found tab %i for channel %i title change!", t, channelId);
3693  logger->Log(msg);
3694  swprintf_s(chatchannel[t].title, MAX_TAB_CHARS - 5, L"%S", title);
3696  {
3698  }
3699  }
3700  }
3701 }
3702 
3703 void HMI::ChannelInvite(char* title, unsigned char whoinvited, unsigned char channel, unsigned char players) const
3704 {
3705  char msg[99];
3706  sprintf_s(msg, sizeof(msg), "Got new invite for channel %i player %i: %s", channel, whoinvited, title);
3707  logger->Log(msg);
3708 
3710  {
3711  dynamic_cast<CommunicationsDialog*>(DialogBase::dialogs[D_COMMUNICATIONS])->ChannelInvite(title, whoinvited, channel, players);
3712  }
3713 }
3714 
3715 void HMI::ChangePlayerProperties(SSubscribeData* prop)
3716 {
3717  strcpy_s(player[ourplayerC].characterName, 30, prop->characterName);
3718  strcpy_s(player[ourplayerC].email, 32, prop->email);
3719  player[ourplayerC].heightCm = prop->heightCm;
3720 
3721  player[ourplayerC].eargroup = prop->eargroup;
3722  player[ourplayerC].eyecolor = prop->eyecolor;
3723  player[ourplayerC].facialhair = prop->facialhair;
3724  player[ourplayerC].framegroup = prop->framegroup;
3725  player[ourplayerC].haircolor = prop->haircolor;
3726  player[ourplayerC].hairgroup = prop->hairgroup;
3727  player[ourplayerC].headgroup = prop->headgroup;
3728  player[ourplayerC].jawline = prop->jawline;
3729  player[ourplayerC].nosegroup = prop->nosegroup;
3730  player[ourplayerC].skincolor = prop->skincolor;
3731  player[ourplayerC].skintone = prop->skintone;
3732  player[ourplayerC].vision = prop->vision;
3733  player[ourplayerC].age = prop->age;
3734  player[ourplayerC].hasAvatar = prop->hasAvatar;
3735  player[ourplayerC].sex = prop->sex;
3736  player[ourplayerC].weight = prop->weight;
3737  player[ourplayerC].stubbleFreckle = prop->stubbleFreckle;
3738  player[ourplayerC].revisitImmigration = prop->revisitImmigration;
3739 
3740  strcpy_s(player[ourplayerC].referrer, 13, prop->referrer); // optional
3741 
3742  showerrors = 2; // yellow to start
3743  createRoute = false;
3744  DisplayImmigration(false);
3745 }
3746 
3747 void HMI::DisplayImmigration(bool refresh)
3748 {
3749  logger->Log("DisplayImmigration()...");
3750 
3751  const SPlayerData d = player[ourplayerC];
3752 
3753  if (!refresh)
3754  {
3755  if (d.characterName[0] && d.email[0] && // d.context &&
3756  d.eargroup && d.eyecolor && d.facialhair && d.framegroup &&
3757  d.haircolor && d.hairgroup && d.headgroup && d.heightCm &&
3758  d.jawline && d.nosegroup && d.skincolor && d.skintone &&
3759  d.vision && d.age && d.hasAvatar && d.sex && d.weight && d.stubbleFreckle != -1 && !d.revisitImmigration)
3760  {
3761  networking->connectstatus = CONNECT_LOGGEDIN; //Its really dirty to do it in here, should move it later
3762  sound->loopintro = false;
3763  if (game->config.g_bAutoLogin)
3764  game->config.Save(); // every subsequent login we will save if autoLogin is ON
3765  logger->Log("Leaving DisplayImmigration(): complete profile");
3766  return;
3767  }
3768 
3769  game->loadstage = 0;
3771  logger->Log("Advancing displaystage: STATUS_CREATE");
3772  if (createRoute)
3773  game->discord->UpdatePresence("Immigration Form", "Creating character...", "immigration");
3774  else
3775  game->discord->UpdatePresence("Immigration Form", "Updating character...", "immigration");
3776  if (!game->screenShotStatus)
3777  game->screenShotStatus = 1; // requesting it once, make sure we get a render
3778  }
3779 
3780  g_HUD.RemoveAllControls();
3781  g_HUD.Init(&g_DialogResourceManager, true, L"Textures\\dxutcontrols-immigration.png");
3782  g_HUD.SetCallback(OnGUIEvent, this);
3783  g_HUD.SetScale(1.0f);
3784  g_HUD.EnableKeyboardInput(true);
3785  g_HUD.SetFont(0, L"Lucida Handwriting", static_cast<int>(21.0f * game->displayscale), FW_NORMAL);
3786  g_HUD.SetFont(1, L"DejaVu Sans Mono", static_cast<int>(10.0f * game->displayscale), FW_LIGHT);
3787  g_HUD.SetFont(2, L"DejaVu Sans Mono", static_cast<int>(13.0f * game->displayscale), FW_EXTRALIGHT);
3788 
3789  g_HUD.AddStatic(IDC_REPUBLICTEXT, strings[L_IMMIGRATION_REPUBLIC].c_str(), static_cast<int>(102.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), static_cast<int>(561.0f * game->displayscale), static_cast<int>(90.0f * game->displayscale), false, nullptr, false);
3790  g_HUD.GetStatic(IDC_REPUBLICTEXT)->GetElement(0)->SetFont(1, 0xFF09518d, DT_LEFT);
3791  g_HUD.AddStatic(IDC_SYSTEMTEXT, strings[L_IMMIGRATION_SYSTEM].c_str(), static_cast<int>(102.0f * game->displayscale), static_cast<int>(53.0f * game->displayscale), static_cast<int>(561.0f * game->displayscale), static_cast<int>(90.0f * game->displayscale), false, nullptr, false);
3792  g_HUD.GetStatic(IDC_SYSTEMTEXT)->GetElement(0)->SetFont(1, 0xFF5585ab, DT_LEFT);
3793  g_HUD.AddStatic(IDC_PROVINCETEXT, strings[L_IMMIGRATION_PROVINCE].c_str(), static_cast<int>(102.0f * game->displayscale), static_cast<int>(63.0f * game->displayscale), static_cast<int>(561.0f * game->displayscale), static_cast<int>(90.0f * game->displayscale), false, nullptr, false);
3794  g_HUD.GetStatic(IDC_PROVINCETEXT)->GetElement(0)->SetFont(1, 0xFF5585ab, DT_LEFT);
3795 
3796  g_HUD.AddStatic(IDC_DISCLAIMERTEXT, strings[L_IMMIGRATION_DISCLAIMER].c_str(), static_cast<int>(500.0f * game->displayscale), static_cast<int>(37.0f * game->displayscale), static_cast<int>(171.0f * game->displayscale), static_cast<int>(42.0f * game->displayscale), false, nullptr, false);
3797  g_HUD.GetStatic(IDC_DISCLAIMERTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_RIGHT | DT_WORDBREAK);
3798  g_HUD.AddStatic(IDC_DEPARTMENTTEXT, strings[L_IMMIGRATION_DEPARTMENT].c_str(), static_cast<int>(37.0f * game->displayscale), static_cast<int>(102.0f * game->displayscale), static_cast<int>(263.0f * game->displayscale), static_cast<int>(90.0f * game->displayscale), false, nullptr, false);
3799  g_HUD.GetStatic(IDC_DEPARTMENTTEXT)->GetElement(0)->SetFont(1, 0xFF000000, DT_LEFT);
3800  g_HUD.AddStatic(IDC_DIVISIONTEXT, strings[L_IMMIGRATION_DIVISION].c_str(), static_cast<int>(37.0f * game->displayscale), static_cast<int>(113.0f * game->displayscale), static_cast<int>(263.0f * game->displayscale), static_cast<int>(90.0f * game->displayscale), false, nullptr, false);
3801  g_HUD.GetStatic(IDC_DIVISIONTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3802 
3803  g_HUD.AddStatic(IDC_FORMTEXT, strings[L_IMMIGRATION_FORM].c_str(), static_cast<int>(364.0f * game->displayscale), static_cast<int>(89.0f * game->displayscale), static_cast<int>(307.0f * game->displayscale), static_cast<int>(35.0f * game->displayscale), false, nullptr, false);
3804  g_HUD.GetStatic(IDC_FORMTEXT)->GetElement(0)->SetFont(2, 0xFF5f5f5d, DT_RIGHT | DT_WORDBREAK | DT_BOTTOM);
3805 
3806  g_HUD.AddStatic(IDC_LANGUAGELABEL, strings[L_CONFIG_LANGUAGE].c_str(), static_cast<int>(35.0f * game->displayscale), static_cast<int>(146.0f * game->displayscale), static_cast<int>(156.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3807  g_HUD.GetStatic(IDC_LANGUAGELABEL)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3808  g_HUD.AddComboBox(IDC_LANGUAGE, static_cast<int>(36.0f * game->displayscale), static_cast<int>(156.0f * game->displayscale), static_cast<int>(146.0f * game->displayscale), static_cast<int>(19.0f * game->displayscale));
3809  g_HUD.GetComboBox(IDC_LANGUAGE)->SetScrollBarWidth(0);
3810  g_HUD.GetComboBox(IDC_LANGUAGE)->SetTextColor(0xFF000000, 0xFF000000);
3811  g_HUD.GetComboBox(IDC_LANGUAGE)->GetElement(0)->dwTextFormat = DT_LEFT;
3812  g_HUD.GetComboBox(IDC_LANGUAGE)->GetElement(0)->FontColor.Init(0xFF000000, 0xFF000000);
3813  g_HUD.GetComboBox(IDC_LANGUAGE)->GetElement(2)->iFont = 2;
3814  g_HUD.GetComboBox(IDC_LANGUAGE)->GetElement(3)->iFont = 2;
3816  g_HUD.GetComboBox(IDC_LANGUAGE)->SetDropHeight(static_cast<UINT>(g_HUD.GetComboBox(IDC_LANGUAGE)->GetNumItems() * 14.0f * game->displayscale));
3817 
3818  g_HUD.AddStatic(IDC_SEX, strings[L_IMMIGRATION_GENDER].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(146.0f * game->displayscale), static_cast<int>(98.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3819  g_HUD.GetStatic(IDC_SEX)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3820 
3821  g_HUD.AddStatic(IDC_MALETEXT, strings[L_IMMIGRATION_MALE].c_str(), static_cast<int>(210.0f * game->displayscale), static_cast<int>(161.0f * game->displayscale), static_cast<int>(38.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3822  g_HUD.GetStatic(IDC_MALETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3823  g_HUD.AddRadioButton(IDC_MALE, IDC_SEX, L"", static_cast<int>(192.0f * game->displayscale), static_cast<int>(155.0f * game->displayscale), static_cast<int>(38.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false);
3824 
3825  g_HUD.AddStatic(IDC_FEMALETEXT, strings[L_IMMIGRATION_FEMALE].c_str(), static_cast<int>(257.0f * game->displayscale), static_cast<int>(161.0f * game->displayscale), static_cast<int>(38.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3826  g_HUD.GetStatic(IDC_FEMALETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3827  g_HUD.AddRadioButton(IDC_FEMALE, IDC_SEX, L"", static_cast<int>(239.0f * game->displayscale), static_cast<int>(155.0f * game->displayscale), static_cast<int>(55.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false);
3828 
3829  g_HUD.AddStatic(IDC_CHARNAMETEXT, strings[L_IMMIGRATION_NAME].c_str(), static_cast<int>(301.0f * game->displayscale), static_cast<int>(145.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3830  g_HUD.GetStatic(IDC_CHARNAMETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3831  g_HUD.AddEditBox(IDC_CHARNAME, L"", static_cast<int>(293.0f * game->displayscale), static_cast<int>(145.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
3832 
3833  g_HUD.AddButton(IDC_SUGGEST, strings[L_IMMIGRATION_SUGGEST].c_str(), static_cast<int>(620.0f * game->displayscale), static_cast<int>(143.0f * game->displayscale), static_cast<int>(42.0f * game->displayscale), static_cast<int>(16.0f * game->displayscale));
3834  g_HUD.GetButton(IDC_SUGGEST)->SetTextColor(0xFF5F5F5F);
3835  g_HUD.GetControl(IDC_SUGGEST)->GetElement(0)->iFont = 1;
3836  g_HUD.GetControl(IDC_SUGGEST)->GetElement(1)->iFont = 1;
3837 
3838  g_HUD.AddStatic(IDC_HANDLETEXT, strings[L_IMMIGRATION_CALLSIGN].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(178.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3839  g_HUD.GetStatic(IDC_HANDLETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3840  g_HUD.AddEditBox(IDC_HANDLE, L"", static_cast<int>(188.0f * game->displayscale), static_cast<int>(178.0f * game->displayscale), static_cast<int>(152.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
3841 
3842  WCHAR str[99];
3843  swprintf_s(str, 99, L"%S", game->config.defaultpass);
3844  g_HUD.AddStatic(IDC_PASSWORDTEXT, strings[L_IMMIGRATION_PASSWORD].c_str(), static_cast<int>(352.0f * game->displayscale), static_cast<int>(178.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3845  g_HUD.GetStatic(IDC_PASSWORDTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3846  g_HUD.AddEditBox(IDC_PASSWORD, str, static_cast<int>(345.0f * game->displayscale), static_cast<int>(178.0f * game->displayscale), static_cast<int>(156.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), false, true);
3847  g_HUD.GetControl(IDC_PASSWORD)->GetElement(0)->iFont = 2;
3848  g_HUD.AddStatic(IDC_PWVERIFYTEXT, strings[L_IMMIGRATION_CONFIRM].c_str(), static_cast<int>(512.0f * game->displayscale), static_cast<int>(178.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3849  g_HUD.GetStatic(IDC_PWVERIFYTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3850  g_HUD.AddEditBox(IDC_PWVERIFY, str, static_cast<int>(505.0f * game->displayscale), static_cast<int>(178.0f * game->displayscale), static_cast<int>(159.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), false, true);
3851  g_HUD.GetControl(IDC_PWVERIFY)->GetElement(0)->iFont = 2;
3852 
3853  g_HUD.AddStatic(IDC_EMAILTEXT, strings[L_IMMIGRATION_EMAIL].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(210.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3854  g_HUD.GetStatic(IDC_EMAILTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3855  g_HUD.AddEditBox(IDC_EMAILADDRESS, L"", static_cast<int>(187.0f * game->displayscale), static_cast<int>(211.0f * game->displayscale), static_cast<int>(360.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
3856 
3857  g_HUD.AddStatic(IDC_AGETEXT, strings[L_IMMIGRATION_AGE].c_str(), static_cast<int>(545.0f * game->displayscale), static_cast<int>(210.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3858  g_HUD.GetStatic(IDC_AGETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3859  g_HUD.AddEditBox(IDC_AGE, L"", static_cast<int>(538.0f * game->displayscale), static_cast<int>(209.0f * game->displayscale), static_cast<int>(63.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
3860 
3861  g_HUD.AddStatic(IDC_WEIGHTTEXT, strings[L_IMMIGRATION_WEIGHT].c_str(), static_cast<int>(609.0f * game->displayscale), static_cast<int>(210.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3862  g_HUD.GetStatic(IDC_WEIGHTTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3863  g_HUD.AddEditBox(IDC_WEIGHT, L"", static_cast<int>(599.0f * game->displayscale), static_cast<int>(209.0f * game->displayscale), static_cast<int>(92.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
3864 
3865  g_HUD.AddStatic(IDC_HEIGHTTEXT, strings[L_IMMIGRATION_HEIGHT].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(242.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3866  g_HUD.GetStatic(IDC_HEIGHTTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3867  g_HUD.AddEditBox(IDC_HEIGHT, L"", static_cast<int>(186.0f * game->displayscale), static_cast<int>(241.0f * game->displayscale), static_cast<int>(64.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
3868 
3869  g_HUD.AddStatic(IDC_HAIRCOLORTEXT, strings[L_IMMIGRATION_HAIRCOLOR].c_str(), static_cast<int>(260.0f * game->displayscale), static_cast<int>(242.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3870  g_HUD.GetStatic(IDC_HAIRCOLORTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3871  g_HUD.AddComboBox(IDC_HAIRCOLOR, static_cast<int>(261.0f * game->displayscale), static_cast<int>(252.0f * game->displayscale), static_cast<int>(203.0f * game->displayscale), static_cast<int>(19.0f * game->displayscale));
3872  g_HUD.GetComboBox(IDC_HAIRCOLOR)->SetScrollBarWidth(0);
3873  g_HUD.GetComboBox(IDC_HAIRCOLOR)->SetDropHeight(static_cast<UINT>(24.0f * 14.0f * game->displayscale));
3874  g_HUD.GetComboBox(IDC_HAIRCOLOR)->SetTextColor(0xFF000000, 0xFF000000);
3875  g_HUD.GetComboBox(IDC_HAIRCOLOR)->GetElement(0)->dwTextFormat = DT_LEFT;
3876  g_HUD.GetComboBox(IDC_HAIRCOLOR)->GetElement(0)->FontColor.Init(0xFF000000, 0xFF000000);
3877  g_HUD.GetComboBox(IDC_HAIRCOLOR)->GetElement(2)->iFont = 2;
3878  g_HUD.GetComboBox(IDC_HAIRCOLOR)->GetElement(3)->iFont = 2;
3879  for (int i = 0; i < 24; i++)
3880  g_HUD.GetComboBox(IDC_HAIRCOLOR)->AddItem(strings[L_IMMIGRATION_HAIRCOLOR1 + i].c_str(), nullptr);
3881 
3882  /*g_HUD.AddComboBox(IDC_EMPHASIS, static_cast<int>(353.0f * game->displayscaley), static_cast<int>(424.0f * game->displayscaley), static_cast<int>(202.0f * game->displayscaley), static_cast<int>(39.0f * game->displayscaley));
3883  g_HUD.GetComboBox(IDC_EMPHASIS)->SetDropHeight(static_cast<int>(24.0f * game->displayscaley));
3884  g_HUD.GetComboBox(IDC_EMPHASIS)->SetTextColor(0xFF000000, 0xFF000000);
3885  g_HUD.GetComboBox(IDC_EMPHASIS)->GetElement(0)->dwTextFormat = DT_LEFT | DT_BOTTOM;
3886  g_HUD.GetComboBox(IDC_EMPHASIS)->GetElement(2)->iFont = 1;
3887  g_HUD.GetComboBox(IDC_EMPHASIS)->GetElement(3)->iFont = 1;
3888  g_HUD.GetComboBox(IDC_EMPHASIS)->AddItem(L"", nullptr);
3889  g_HUD.GetComboBox(IDC_EMPHASIS)->AddItem(L"Military", nullptr);
3890  g_HUD.GetComboBox(IDC_EMPHASIS)->AddItem(L"Civilian", nullptr);
3891  g_HUD.GetComboBox(IDC_EMPHASIS)->AddItem(L"Business", nullptr);
3892  g_HUD.GetComboBox(IDC_EMPHASIS)->SetSelectedByIndex(1);*/
3893 
3894  g_HUD.AddStatic(IDC_EYECOLORTEXT, strings[L_IMMIGRATION_EYECOLOR].c_str(), static_cast<int>(467.0f * game->displayscale), static_cast<int>(242.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3895  g_HUD.GetStatic(IDC_EYECOLORTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3896  g_HUD.AddComboBox(IDC_EYECOLOR, static_cast<int>(467.0f * game->displayscale), static_cast<int>(252.0f * game->displayscale), static_cast<int>(204.0f * game->displayscale), static_cast<int>(19.0f * game->displayscale));
3897  g_HUD.GetComboBox(IDC_EYECOLOR)->SetScrollBarWidth(0);
3898  g_HUD.GetComboBox(IDC_EYECOLOR)->SetDropHeight(static_cast<UINT>(6.0f * 14.0f * game->displayscale));
3899  g_HUD.GetComboBox(IDC_EYECOLOR)->SetTextColor(0xFF000000, 0xFF000000);
3900  g_HUD.GetComboBox(IDC_EYECOLOR)->GetElement(0)->dwTextFormat = DT_LEFT;
3901  g_HUD.GetComboBox(IDC_EYECOLOR)->GetElement(0)->FontColor.Init(0xFF000000, 0xFF000000);
3902  g_HUD.GetComboBox(IDC_EYECOLOR)->GetElement(2)->iFont = 2;
3903  g_HUD.GetComboBox(IDC_EYECOLOR)->GetElement(3)->iFont = 2;
3904  for (int i = 0; i < 6; i++)
3905  g_HUD.GetComboBox(IDC_EYECOLOR)->AddItem(strings[L_IMMIGRATION_EYECOLOR1 + i].c_str(), nullptr);
3906 
3907  g_HUD.AddStatic(IDC_SKINCOLORTEXT, strings[L_IMMIGRATION_SKINCOLOR].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(274.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3908  g_HUD.GetStatic(IDC_SKINCOLORTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3909  g_HUD.AddSlider(IDC_SKINCOLOR, static_cast<int>(256.0f * game->displayscale), static_cast<int>(271.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 1, 255, rand() % 255 + 1);
3910 
3911  g_HUD.AddStatic(IDC_SKINTONETEXT, strings[L_IMMIGRATION_SKINTONE].c_str(), static_cast<int>(435.0f * game->displayscale), static_cast<int>(274.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3912  g_HUD.GetStatic(IDC_SKINTONETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3913  g_HUD.AddSlider(IDC_SKINTONE, static_cast<int>(493.0f * game->displayscale), static_cast<int>(271.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 1, 255, rand() % 255 + 1);
3914 
3915  g_HUD.AddStatic(IDC_VISION, strings[L_IMMIGRATION_VISION].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(306.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3916  g_HUD.GetStatic(IDC_VISION)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3917  const int randomVision = rand() % 3 + 1;
3918  g_HUD.AddStatic(IDC_VISION1TEXT, strings[L_IMMIGRATION_VISION1].c_str(), static_cast<int>(210.0f * game->displayscale), static_cast<int>(322.0f * game->displayscale), static_cast<int>(38.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3919  g_HUD.GetStatic(IDC_VISION1TEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3920  g_HUD.AddRadioButton(IDC_NORMAL, IDC_VISION, L"", static_cast<int>(192.0f * game->displayscale), static_cast<int>(316.0f * game->displayscale), static_cast<int>(45.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), randomVision == 1);
3921  g_HUD.AddStatic(IDC_VISION2TEXT, strings[L_IMMIGRATION_VISION2].c_str(), static_cast<int>(267.0f * game->displayscale), static_cast<int>(322.0f * game->displayscale), static_cast<int>(38.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3922  g_HUD.GetStatic(IDC_VISION2TEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3923  g_HUD.AddRadioButton(IDC_IMPLANTS, IDC_VISION, L"", static_cast<int>(249.0f * game->displayscale), static_cast<int>(316.0f * game->displayscale), static_cast<int>(55.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), randomVision == 2);
3924  g_HUD.AddStatic(IDC_VISION3TEXT, strings[L_IMMIGRATION_VISION3].c_str(), static_cast<int>(332.0f * game->displayscale), static_cast<int>(322.0f * game->displayscale), static_cast<int>(38.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3925  g_HUD.GetStatic(IDC_VISION3TEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3926  g_HUD.AddRadioButton(IDC_FRAMES, IDC_VISION, L"", static_cast<int>(314.0f * game->displayscale), static_cast<int>(316.0f * game->displayscale), static_cast<int>(55.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), randomVision == 3);
3927 
3928  g_HUD.AddStatic(IDC_FRAMESTEXT, strings[L_IMMIGRATION_FRAMES].c_str(), static_cast<int>(435.0f * game->displayscale), static_cast<int>(306.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3929  g_HUD.GetStatic(IDC_FRAMESTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3930  g_HUD.AddSlider(IDC_FRAMETYPE, static_cast<int>(493.0f * game->displayscale), static_cast<int>(303.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 451, 453, 451);
3931  g_HUD.GetControl(IDC_FRAMETYPE)->SetVisible(randomVision == 3);
3932 
3933  g_HUD.AddStatic(IDC_HEADTEXT, strings[L_IMMIGRATION_HEAD].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(338.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3934  g_HUD.GetStatic(IDC_HEADTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3935  g_HUD.AddSlider(IDC_HEAD, static_cast<int>(256.0f * game->displayscale), static_cast<int>(335.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 151, 153, rand() % 5 + 150);
3936 
3937  g_HUD.AddStatic(IDC_JAWTEXT, strings[L_IMMIGRATION_JAW].c_str(), static_cast<int>(435.0f * game->displayscale), static_cast<int>(338.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3938  g_HUD.GetStatic(IDC_JAWTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3939  g_HUD.AddSlider(IDC_JAWLINE, static_cast<int>(493.0f * game->displayscale), static_cast<int>(335.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 676, 680, rand() % 5 + 676);
3940 
3941  g_HUD.AddStatic(IDC_NOSETEXT, strings[L_IMMIGRATION_NOSE].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(370.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3942  g_HUD.GetStatic(IDC_NOSETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3943  g_HUD.AddSlider(IDC_NOSE, static_cast<int>(256.0f * game->displayscale), static_cast<int>(367.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 101, 104, rand() % 4 + 101);
3944 
3945  g_HUD.AddStatic(IDC_EARSTEXT, strings[L_IMMIGRATION_EARS].c_str(), static_cast<int>(435.0f * game->displayscale), static_cast<int>(370.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3946  g_HUD.GetStatic(IDC_EARSTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3947  g_HUD.AddSlider(IDC_EARS, static_cast<int>(493.0f * game->displayscale), static_cast<int>(367.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 226, 228, rand() % 5 + 226);
3948 
3949  g_HUD.AddStatic(IDC_HAIRSTYLETEXT, strings[L_IMMIGRATION_HAIRSTYLE].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(402.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3950  g_HUD.GetStatic(IDC_HAIRSTYLETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3951  g_HUD.AddSlider(IDC_HAIRSTYLE, static_cast<int>(256.0f * game->displayscale), static_cast<int>(399.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 175, 179, rand() % 5 + 175);
3952 
3953  // Female is UNUSED, Freckles ... Men is Beard, Stubble
3954  g_HUD.AddStatic(IDC_FEATURETEXT, L"", static_cast<int>(435.0f * game->displayscale), static_cast<int>(402.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3955  g_HUD.GetStatic(IDC_FEATURETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3956  g_HUD.AddSlider(IDC_FEATURE, static_cast<int>(493.0f * game->displayscale), static_cast<int>(399.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 125, 127, rand() % 3 + 125);
3957 
3958  g_HUD.AddStatic(IDC_STUBBLEFRECKLETEXT, L"", static_cast<int>(435.0f * game->displayscale), static_cast<int>(434.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3959  g_HUD.GetStatic(IDC_STUBBLEFRECKLETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3960  const int randomStubble = rand() % 101;
3961  stubbleFreckle = static_cast<float>(randomStubble) * 0.01f;
3962  g_HUD.AddSlider(IDC_STUBBLEFRECKLE, static_cast<int>(493.0f * game->displayscale), static_cast<int>(431.0f * game->displayscale), static_cast<int>(163.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), 0, 100, randomStubble);
3963 
3964  g_HUD.AddStatic(IDC_REFERRALTEXT, strings[L_IMMIGRATION_REFERRAL].c_str(), static_cast<int>(196.0f * game->displayscale), static_cast<int>(434.0f * game->displayscale), static_cast<int>(321.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale), NULL, nullptr, false);
3965  g_HUD.GetStatic(IDC_REFERRALTEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3966  g_HUD.AddEditBox(IDC_REFERRAL, L"", static_cast<int>(187.0f * game->displayscale), static_cast<int>(435.0f * game->displayscale), static_cast<int>(152.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
3967 
3968  g_HUD.AddButton(IDC_SNAPSHOT, strings[L_IMMIGRATION_SNAPSHOT].c_str(), static_cast<int>(50.0f * game->displayscale), static_cast<int>(399.0f * game->displayscale), static_cast<int>(70.0f * game->displayscale), static_cast<int>(16.0f * game->displayscale));
3969  g_HUD.GetButton(IDC_SNAPSHOT)->SetTextColor(0xFF5F5F5F);
3970  g_HUD.GetControl(IDC_SNAPSHOT)->GetElement(0)->iFont = 1;
3971  g_HUD.GetControl(IDC_SNAPSHOT)->GetElement(1)->iFont = 1;
3972 
3973  g_HUD.AddButton(IDC_VOID, strings[L_IMMIGRATION_VOID].c_str(), static_cast<int>(131.0f * game->displayscale), static_cast<int>(399.0f * game->displayscale), static_cast<int>(42.0f * game->displayscale), static_cast<int>(16.0f * game->displayscale));
3974  g_HUD.GetButton(IDC_VOID)->SetTextColor(0xFF5F5F5F);
3975  g_HUD.GetControl(IDC_VOID)->GetElement(0)->iFont = 1;
3976  g_HUD.GetControl(IDC_VOID)->GetElement(1)->iFont = 1;
3977  g_HUD.GetButton(IDC_VOID)->SetEnabled(false);
3978 
3979  g_HUD.AddStatic(IDC_STATEMENTLABEL, strings[L_IMMIGRATION_STATEMENTTEXT].c_str(), static_cast<int>(35.0f * game->displayscale), static_cast<int>(530.0f * game->displayscale), static_cast<int>(156.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3980  g_HUD.GetStatic(IDC_STATEMENTLABEL)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3981  g_HUD.AddStatic(IDC_STATEMENTTEXT, strings[L_IMMIGRATION_STATEMENTTEXT].c_str(), static_cast<int>(72.0f * game->displayscale), static_cast<int>(550.0f * game->displayscale), static_cast<int>(561.0f * game->displayscale), static_cast<int>(90.0f * game->displayscale), false, nullptr, false);
3982  g_HUD.GetStatic(IDC_STATEMENTTEXT)->GetElement(0)->SetFont(2, 0xFF000000, DT_LEFT | DT_WORDBREAK);
3983 
3984  g_HUD.AddStatic(IDC_PROOF, strings[L_IMMIGRATION_PROOF].c_str(), static_cast<int>(35.0f * game->displayscale), static_cast<int>(658.0f * game->displayscale), static_cast<int>(156.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3985  g_HUD.GetStatic(IDC_PROOF)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3986 
3987  g_HUD.AddEditBox(IDC_SIGNATUREHINT, L"", static_cast<int>(25.0f * game->displayscale), static_cast<int>(657.0f * game->displayscale), static_cast<int>(575.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
3988  g_HUD.GetEditBox(IDC_SIGNATUREHINT)->SetTextColor(0xFFC2C2BA);
3989  g_HUD.GetEditBox(IDC_SIGNATUREHINT)->SetEnabled(false);
3990 
3991  g_HUD.AddStatic(IDC_SIGNHERE, strings[L_IMMIGRATION_SIGNHERE].c_str(), static_cast<int>(368.0f * game->displayscale), static_cast<int>(665.0f * game->displayscale), static_cast<int>(89.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3992  g_HUD.GetStatic(IDC_SIGNHERE)->GetElement(0)->SetFont(2, 0xFF000000, DT_RIGHT);
3993 
3994  g_HUD.AddEditBox(IDC_SIGNATURE, L"", static_cast<int>(25.0f * game->displayscale), static_cast<int>(657.0f * game->displayscale), static_cast<int>(575.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
3995 
3996  g_HUD.AddStatic(IDC_DATETEXT, strings[L_IMMIGRATION_DATE].c_str(), static_cast<int>(477.0f * game->displayscale), static_cast<int>(658.0f * game->displayscale), static_cast<int>(156.0f * game->displayscale), static_cast<int>(20.0f * game->displayscale), false, nullptr, false);
3997  g_HUD.GetStatic(IDC_DATETEXT)->GetElement(0)->SetFont(1, 0xFF5f5f5d, DT_LEFT);
3998  time_t ltime;
3999  time(&ltime);
4000  tm tm_time{};
4001  _localtime64_s(&tm_time, &ltime);
4002  swprintf_s(str, 99, L"%02i/%02i/%04i", tm_time.tm_mon + 1, tm_time.tm_mday, tm_time.tm_year + 1900 + 225);
4003  g_HUD.AddEditBox(IDC_DATE, str, static_cast<int>(466.0f * game->displayscale), static_cast<int>(657.0f * game->displayscale), static_cast<int>(130.0f * game->displayscale), static_cast<int>(39.0f * game->displayscale));
4004  g_HUD.GetEditBox(IDC_DATE)->SetEnabled(false);
4005 
4006  g_HUD.AddButton(IDC_CONFIRM, strings[L_IMMIGRATION_SUBMIT].c_str(), static_cast<int>(618.0f * game->displayscale), static_cast<int>(655.0f * game->displayscale), static_cast<int>(42.0f * game->displayscale), static_cast<int>(16.0f * game->displayscale));
4007  g_HUD.GetButton(IDC_CONFIRM)->SetTextColor(0xFF5F5F5F);
4008  g_HUD.GetControl(IDC_CONFIRM)->GetElement(0)->iFont = 1;
4009  g_HUD.GetControl(IDC_CONFIRM)->GetElement(1)->iFont = 1;
4010 
4011  if (createRoute)
4012  g_HUD.AddButton(IDC_BACK, strings[L_IMMIGRATION_CANCEL].c_str(), static_cast<int>(620.0f * game->displayscale), static_cast<int>(7.0f * game->displayscale), static_cast<int>(42.0f * game->displayscale), static_cast<int>(16.0f * game->displayscale));
4013  else
4014  g_HUD.AddButton(IDC_BACK, strings[L_IMMIGRATION_QUIT].c_str(), static_cast<int>(620.0f * game->displayscale), static_cast<int>(7.0f * game->displayscale), static_cast<int>(42.0f * game->displayscale), static_cast<int>(16.0f * game->displayscale));
4015  g_HUD.GetButton(IDC_BACK)->SetTextColor(0xFF5F5F5F);
4016  g_HUD.GetControl(IDC_BACK)->GetElement(0)->iFont = 1;
4017  g_HUD.GetControl(IDC_BACK)->GetElement(1)->iFont = 1;
4018 
4019  if (!refresh)
4020  {
4021  // set up the window for immigration
4022  RECT rect;
4023  if (!GetWindowRect(DXUTGetHWND(), &rect))
4024  {
4025  char msg[99];
4026  sprintf_s(msg, 99, "Error in GetWindowRect: %d", GetLastError());
4027  logger->Log(msg, Logger::Fatal);
4028  return;
4029  }
4030 
4031  // was 700 x 705? go to 1050x1050?
4032  const int width = static_cast<int>(700.0f * game->displayscale);
4033  const int y = static_cast<int>(rect.top - (705.0f - 500.0f) * 0.5f * game->displayscale);
4034  const int height = static_cast<int>(705.0f * game->displayscale);
4035  if (!MoveWindow(DXUTGetHWND(), rect.left, y, width, height, true))
4036  {
4037  char msg[99];
4038  sprintf_s(msg, 99, "Error in MoveWindow: %d", GetLastError());
4039  logger->Log(msg, Logger::Fatal);
4040  return;
4041  }
4042  DXUTReset3DEnvironment();
4043  }
4044 
4045  if (!d.haircolor)
4047  if (!d.eyecolor)
4048  GetEyeColorAtIndex(0);
4049 
4050  logger->Log("DisplayImmigration() exit!");
4051 }
4052 
4053 void HMI::DrawRXTXLights(LPDIRECT3DTEXTURE9* tex) const
4054 {
4055  logger->AddToCallStack("HMI::DrawRXTXLights");
4056 
4057  if (rxlight)
4058  {
4059  D3DXVECTOR3 tempvec = D3DXVECTOR3(2, 2, 0);
4060  g_pTextSprite->Draw(*tex, nullptr, nullptr, &tempvec, 0xFFFFFFFF);
4061  }
4062  if (txlight)
4063  {
4064  D3DXVECTOR3 tempvec = D3DXVECTOR3(20, 2, 0);
4065  g_pTextSprite->Draw(*tex, nullptr, nullptr, &tempvec, 0xFFFFFFFF);
4066  }
4067 
4068  logger->AddToCallStack("HMI::DrawRXTXLights DONE");
4069 }
4070 
4072 {
4073  logger->AddToCallStack("HMI::DrawErrorBoxes");
4074 
4075  RECT rect;
4076  // highlight boxes red (if showerrors==true and are bad) or gray if they are !enabled
4077  D3DXVECTOR3 tempvec;
4078  haserrors = false;
4079 
4080  // sex
4081  DWORD tempcolor = 0;
4082  if (!g_HUD.GetRadioButton(IDC_FEMALE)->GetChecked() && !g_HUD.GetRadioButton(IDC_MALE)->GetChecked())
4083  {
4084  if (showerrors == 1)
4085  tempcolor = 0xFFFF9A9C;
4086  else if (showerrors == 2)
4087  tempcolor = 0xFFFDFB43;
4088  haserrors = true;
4089  }
4090  if (tempcolor)
4091  {
4092  rect.left = 194; rect.top = 144; rect.right = 298; rect.bottom = 175;
4093  tempvec = D3DXVECTOR3(194, 144, 0);
4094  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4095  }
4096 
4097  // charname
4098  tempcolor = 0;
4099  char playername[30];
4100  sprintf_s(playername, 30, "%.29S", g_HUD.GetEditBox(IDC_CHARNAME)->GetText());
4101  if (!playername[0] || charnameValid != 2)
4102  {
4103  if (charnameValid == 1) // checking
4104  tempcolor = 0xFF9B9A9C;
4105  else if (showerrors || charnameValid == 0)
4106  {
4107  if (showerrors == 1 || charnameValid == 0)
4108  tempcolor = 0xFFFF9A9C;
4109  else if (showerrors == 2)
4110  tempcolor = 0xFFFDFB43;
4111  }
4112  haserrors = true;
4113  }
4114  if (tempcolor)
4115  {
4116  rect.left = 299; rect.top = 144; rect.right = 672; rect.bottom = 175;
4117  tempvec = D3DXVECTOR3(299, 144, 0);
4118  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4119  }
4120 
4121  // email
4122  tempcolor = 0;
4123  char email[32];
4124  sprintf_s(email, 32, "%.31S", g_HUD.GetEditBox(IDC_EMAILADDRESS)->GetText());
4125  if (!email[0] || emailValid != 2)
4126  {
4127  if (emailValid == 1) // checking
4128  tempcolor = 0xFF9B9A9C;
4129  else if (showerrors || emailValid == 0)
4130  {
4131  if (showerrors == 1 || emailValid == 0)
4132  tempcolor = 0xFFFF9A9C;
4133  else if (showerrors == 2)
4134  tempcolor = 0xFFFDFB43;
4135  }
4136  haserrors = true;
4137  }
4138  if (tempcolor)
4139  {
4140  rect.left = 194; rect.top = 208; rect.right = 542; rect.bottom = 239;
4141  tempvec = D3DXVECTOR3(194, 208, 0);
4142  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4143  }
4144 
4145  // callsign
4146  tempcolor = 0;
4147  char callsign[16];
4148  sprintf_s(callsign, 16, "%.15S", g_HUD.GetEditBox(IDC_HANDLE)->GetText());
4149  if (strlen(callsign) < 2 || handleValid != 2)
4150  {
4151  if (handleValid == 1) // checking
4152  tempcolor = 0xFF9B9A9C;
4153  else if (showerrors || handleValid == 0)
4154  {
4155  if (showerrors == 1 || handleValid == 0)
4156  tempcolor = 0xFFFF9A9C;
4157  else if (showerrors == 2)
4158  tempcolor = 0xFFFDFB43;
4159  }
4160  haserrors = true;
4161  }
4162  if (tempcolor)
4163  {
4164  rect.left = 194; rect.top = 176; rect.right = 349; rect.bottom = 207;
4165  tempvec = D3DXVECTOR3(194, 176, 0);
4166  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4167  }
4168 
4169  // password
4170  tempcolor = 0;
4171  char password[16];
4172  sprintf_s(password, 16, "%.15S", g_HUD.GetEditBox(IDC_PASSWORD)->GetText());
4173  if (!password[0])
4174  {
4175  if (showerrors == 1)
4176  tempcolor = 0xFFFF9A9C;
4177  else if (showerrors == 2)
4178  tempcolor = 0xFFFDFB43;
4179  haserrors = true;
4180  }
4181  if (tempcolor)
4182  {
4183  rect.left = 350; rect.top = 176; rect.right = 509; rect.bottom = 207;
4184  tempvec = D3DXVECTOR3(350, 176, 0);
4185  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4186  }
4187 
4188  // confirmpassword
4189  tempcolor = 0;
4190  char confirm[16];
4191  sprintf_s(confirm, 16, "%.15S", g_HUD.GetEditBox(IDC_PWVERIFY)->GetText());
4192  if (_strcmpi(password, confirm) != 0 || !confirm[0])
4193  {
4194  if (showerrors)
4195  tempcolor = 0xFFFF9A9C;
4196  haserrors = true;
4197  }
4198  if (tempcolor)
4199  {
4200  rect.left = 510; rect.top = 176; rect.right = 672; rect.bottom = 207;
4201  tempvec = D3DXVECTOR3(510, 176, 0);
4202  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4203  }
4204 
4205  // picture
4206  tempcolor = 0;
4207  if (!pBuffer)
4208  {
4209  if (showerrors == 1)
4210  tempcolor = 0xFFFF9A9C;
4211  else if (showerrors == 2)
4212  tempcolor = 0xFFFDFB43;
4213  haserrors = true;
4214  }
4215  if (tempcolor)
4216  {
4217  rect.left = 33; rect.top = 255; rect.right = 193; rect.bottom = 415;
4218  tempvec = D3DXVECTOR3(33, 255, 0);
4219  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4220  }
4221 
4222  // referred by
4223  char referredby[13];
4224  sprintf_s(referredby, 13, "%.12S", g_HUD.GetEditBox(IDC_REFERRAL)->GetText());
4225  // have to do this client-side since server doesn't have both pieces
4226  if (referredby[0]) // referral has value
4227  {
4228  if (referredby[0] && _strcmpi(callsign, referredby) == 0) // can't be the same
4229  referralValid = 0;
4230  }
4231  else
4232  referralValid = 2;
4233 
4234  tempcolor = 0;
4235  if (referralValid != 2) // checking or invalid
4236  {
4237  if (referralValid == 1) // checking
4238  tempcolor = 0xFF9B9A9C;
4239  else if (showerrors || referralValid == 0)
4240  {
4241  if (showerrors == 1 || referralValid == 0)
4242  tempcolor = 0xFFFF9A9C;
4243  else if (showerrors == 2)
4244  tempcolor = 0xFFFDFB43;
4245  }
4246  haserrors = true;
4247  }
4248  if (tempcolor)
4249  {
4250  rect.left = 194; rect.top = 433; rect.right = 349; rect.bottom = 464;
4251  tempvec = D3DXVECTOR3(194, 433, 0);
4252  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4253  }
4254 
4256  //rect.left=350; rect.top=208; rect.right=509; rect.bottom=239;
4257  //tempvec = D3DXVECTOR3(350, 208, 0);
4258  //g_pTextSprite->Draw(GUI.m_pddsGUIInterlace, &rect, NULL, &tempvec, 0xFFFF8080);
4259 
4260  // age
4261  tempcolor = 0;
4262  WCHAR wcdefault[4];
4263  swprintf_s(wcdefault, 4, L"%.2s", g_HUD.GetEditBox(IDC_AGE)->GetText());
4264  if (_wtoi(wcdefault) < 18 || _wtoi(wcdefault) > 80)
4265  {
4266  if (showerrors == 1)
4267  tempcolor = 0xFFFF9A9C;
4268  else if (showerrors == 2)
4269  tempcolor = 0xFFFDFB43;
4270  haserrors = true;
4271  }
4272  if (tempcolor)
4273  {
4274  rect.left = 543; rect.top = 208; rect.right = 606; rect.bottom = 239;
4275  tempvec = D3DXVECTOR3(543, 208, 0);
4276  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4277  }
4278 
4279  // weight
4280  tempcolor = 0;
4281  swprintf_s(wcdefault, 4, L"%.3s", g_HUD.GetEditBox(IDC_WEIGHT)->GetText());
4282  if (!minWeight || _wtoi(wcdefault) < minWeight || _wtoi(wcdefault) > maxWeight)
4283  {
4284  if (showerrors == 1)
4285  tempcolor = 0xFFFF9A9C;
4286  else if (showerrors == 2)
4287  tempcolor = 0xFFFDFB43;
4288  haserrors = true;
4289  }
4290  if (tempcolor)
4291  {
4292  rect.left = 607; rect.top = 208; rect.right = 672; rect.bottom = 239;
4293  tempvec = D3DXVECTOR3(607, 208, 0);
4294  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4295  }
4296 
4297  // height
4298  tempcolor = 0;
4299  swprintf_s(wcdefault, 4, L"%.3s", g_HUD.GetEditBox(IDC_HEIGHT)->GetText());
4300  if (!minHeight || _wtoi(wcdefault) < minHeight || _wtoi(wcdefault) > maxHeight)
4301  {
4302  if (showerrors == 1)
4303  tempcolor = 0xFFFF9A9C;
4304  else if (showerrors == 2)
4305  tempcolor = 0xFFFDFB43;
4306  haserrors = true;
4307  }
4308  if (tempcolor)
4309  {
4310  rect.left = 194; rect.top = 240; rect.right = 257; rect.bottom = 271;
4311  tempvec = D3DXVECTOR3(194, 240, 0);
4312  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4313  }
4314 
4315  // vision
4316  tempcolor = 0;
4317  if (!g_HUD.GetRadioButton(IDC_NORMAL)->GetChecked() &&
4318  !g_HUD.GetRadioButton(IDC_IMPLANTS)->GetChecked() &&
4319  !g_HUD.GetRadioButton(IDC_FRAMES)->GetChecked())
4320  {
4321  if (showerrors == 1)
4322  tempcolor = 0xFFFF9A9C;
4323  else if (showerrors == 2)
4324  tempcolor = 0xFFFDFB43;
4325  haserrors = true;
4326  }
4327  if (tempcolor)
4328  {
4329  rect.left = 194; rect.top = 176 + 128; rect.right = 349 + 83; rect.bottom = 207 + 128;
4330  tempvec = D3DXVECTOR3(194, 176 + 128, 0);
4331  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4332  }
4333 
4334  // signature
4335  WCHAR wcdefault3[99], wcdefault4[99];
4336  tempcolor = 0;
4337  g_HUD.GetEditBox(IDC_SIGNATURE)->GetTextCopy(wcdefault3, 99);
4338  g_HUD.GetEditBox(IDC_CHARNAME)->GetTextCopy(wcdefault4, 99);
4339  if (wcscmp(wcdefault3, wcdefault4) != 0 || !wcdefault3[0] || !wcdefault4[0])
4340  {
4341  if (showerrors == 1)
4342  tempcolor = 0xFFFF9A9C;
4343  else if (showerrors == 2)
4344  tempcolor = 0xFFFDFB43;
4345  haserrors = true;
4346  }
4347  if (tempcolor)
4348  {
4349  rect.left = 33; rect.top = 656; rect.right = 672; rect.bottom = 689;
4350  tempvec = D3DXVECTOR3(33, 656, 0);
4351  g_pTextSprite->Draw(m_pddsGUIInterlace, &rect, nullptr, &tempvec, tempcolor);
4352  }
4353 
4354  // hair color
4355  const int hairindex = g_HUD.GetComboBox(IDC_HAIRCOLOR)->GetSelectedIndex() + 1;
4356  haircolor = GetHairColorAtIndex(hairindex);
4357 
4358  // eye color
4359  const int eyeindex = g_HUD.GetComboBox(IDC_EYECOLOR)->GetSelectedIndex() + 1;
4360  eyecolor = GetEyeColorAtIndex(eyeindex);
4361 
4362  const int hemoglobin = g_HUD.GetSlider(IDC_SKINCOLOR)->GetValue();
4363  const int melanin = g_HUD.GetSlider(IDC_SKINTONE)->GetValue();
4364 
4365  int skinColorFile;
4366  _sopen_s(&skinColorFile, "Textures\\People\\skincolors.bmp", _O_RDONLY | O_BINARY, _SH_DENYWR, _S_IWRITE);
4367  if (skinColorFile == -1)
4368  logger->Log("Could not find file: Textures\\People\\skincolors.bmp", Logger::Level::Fatal);
4369  unsigned char uch_tempR, uch_tempG, uch_tempB;
4370  unsigned long bpr = 256L * 3L;
4371  unsigned long k = 54L + melanin * 3L + (256L - hemoglobin - 1L) * bpr;
4372  _lseek(skinColorFile, k, SEEK_SET);
4373  _read(skinColorFile, &uch_tempB, 1);
4374  _read(skinColorFile, &uch_tempG, 1);
4375  _read(skinColorFile, &uch_tempR, 1);
4376  _close(skinColorFile);
4377  skintone = D3DCOLOR_ARGB(255, uch_tempR, uch_tempG, uch_tempB);
4378 
4379  WCHAR str[99];
4380  swprintf_s(str, 99, L"%.2f", hemoglobin / 255.0f * 0.32f);
4381  rect.left = 211; rect.top = 285;
4382  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4383  swprintf_s(str, 99, L"%03i", g_HUD.GetSlider(IDC_HEAD)->GetValue());
4384  rect.left = 211; rect.top = 349;
4385  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4386  swprintf_s(str, 99, L"%03i", g_HUD.GetSlider(IDC_NOSE)->GetValue());
4387  rect.left = 211; rect.top = 381;
4388  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4389  swprintf_s(str, 99, L"%03i", g_HUD.GetSlider(IDC_HAIRSTYLE)->GetValue());
4390  rect.left = 211; rect.top = 413;
4391  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4392 
4393  swprintf_s(str, 99, L"%.2f", melanin / 255.0f * 0.5f);
4394  rect.left = 449; rect.top = 285;
4395  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4396  if (g_HUD.GetSlider(IDC_FRAMETYPE)->m_bVisible)
4397  swprintf_s(str, 99, L"%03i", g_HUD.GetSlider(IDC_FRAMETYPE)->GetValue());
4398  else
4399  swprintf_s(str, 99, L"%03i", 450);
4400  rect.left = 449; rect.top = 317;
4401  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4402  swprintf_s(str, 99, L"%03i", g_HUD.GetSlider(IDC_JAWLINE)->GetValue());
4403  rect.left = 449; rect.top = 349;
4404  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4405  swprintf_s(str, 99, L"%03i", g_HUD.GetSlider(IDC_EARS)->GetValue());
4406  rect.left = 449; rect.top = 381;
4407  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4408  swprintf_s(str, 99, L"%03i", g_HUD.GetSlider(IDC_FEATURE)->GetValue());
4409  rect.left = 449; rect.top = 413;
4410  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4411  swprintf_s(str, 99, L"%03i", g_HUD.GetSlider(IDC_STUBBLEFRECKLE)->GetValue());
4412  rect.left = 449; rect.top = 445;
4413  g_pFont->DrawText(g_pTextSprite, str, -1, &rect, DT_NOCLIP, 0xFF000000);
4414 
4415  logger->AddToCallStack("HMI::DrawErrorBoxes DONE");
4416 }
4417 
4418 D3DXCOLOR HMI::GetHairColorAtIndex(int index)
4419 {
4420  D3DXCOLOR tempcolor;
4421  if (!index) // pick random
4422  {
4423  index = rand() % 24 + 1;
4424  g_HUD.GetComboBox(IDC_HAIRCOLOR)->SetSelectedByIndex(index - 1);
4425  }
4426  switch (index)
4427  {
4428  case 1: tempcolor = 0xFF090806; break; // Midnight Black
4429  case 2: tempcolor = 0xFF2C222B; break; // Off Black
4430  case 3: tempcolor = 0xFF3B3024; break; // Darkest Brown
4431  case 4: tempcolor = 0xFF4E433F; break; // Med. Dark Brown
4432  case 5: tempcolor = 0xFF504444; break; // Chestnut Brown
4433  case 6: tempcolor = 0xFF6A4E42; break; // Lt. Chestnut Brown
4434  case 7: tempcolor = 0xFF554838; break; // Dark Golden Brown
4435  case 8: tempcolor = 0xFFA7856A; break; // Lt. Golden Brown
4436  case 9: tempcolor = 0xFFB89778; break; // Dark Honey Blonde
4437  case 10: tempcolor = 0xFFDCD0BA; break; // Bleached Blonde
4438  case 11: tempcolor = 0xFFDEBC99; break; // Light Ash Blonde
4439  case 12: tempcolor = 0xFF977961; break; // Light Ash Brown
4440  case 13: tempcolor = 0xFFE6CEA8; break; // Lightest Blonde
4441  case 14: tempcolor = 0xFFE5C8A8; break; // Pale Golden Blonde
4442  case 15: tempcolor = 0xFFA56B46; break; // Strawberry Blonde
4443  case 16: tempcolor = 0xFF91553D; break; // Light Auburn
4444  case 17: tempcolor = 0xFF533D32; break; // Dark Auburn
4445  case 18: tempcolor = 0xFF71635A; break; // Darkest Gray
4446  case 19: tempcolor = 0xFFB7A69E; break; // Medium Gray
4447  case 20: tempcolor = 0xFFD6C4C2; break; // Lightest Gray
4448  case 21: tempcolor = 0xFFFFF5E1; break; // White Blonde
4449  case 22: tempcolor = 0xFFCABFB1; break; // Platinum Blonde
4450  case 23: tempcolor = 0xFF8D4A43; break; // Russet Red
4451  case 24: tempcolor = 0xFFB55239; break; // Terra Cotta
4452  default: tempcolor = D3DXCOLOR(0, 0, 0, 0); break;
4453  }
4454  return tempcolor;
4455 }
4456 
4457 D3DXCOLOR HMI::GetEyeColorAtIndex(int index)
4458 {
4459  D3DXCOLOR tempcolor;
4460  if (!index) // pick random
4461  {
4462  index = rand() % 6 + 1;
4463  g_HUD.GetComboBox(IDC_EYECOLOR)->SetSelectedByIndex(index - 1);
4464  }
4465  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
4466  switch (index)
4467  {
4468  case 1: tempcolor = 0xFFB98A32; break; // Brown
4469  case 2: tempcolor = 0xFF9E6C37; break; // Hazel
4470  case 3: tempcolor = 0xFFD0B42C; break; // Amber
4471  case 4: tempcolor = 0xFF5C932D; break; // Green
4472  case 5: tempcolor = 0xFF4C5596; break; // Blue
4473  case 6: tempcolor = 0xFF908293; break; // Gray
4474  }
4475  return tempcolor;
4476 }
4477 
4478 void HMI::FadeIn(float f, float fElapsedTime)
4479 {
4480  if (fade == 0.0f)
4481  fade = f / 6.0f;
4482  else
4483  {
4484  fade += fElapsedTime / 6.0f; // fade in over six seconds (with music)
4485  if (fade > 1.0f)
4486  fade = 1.0f;
4487  }
4488 }
4489 
4490 void HMI::LightningCalculations(float fElapsedTime)
4491 {
4492  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
4493  // ReSharper disable once CppIncompleteSwitchStatement
4494  switch (game->displaystage) // NOLINT
4495  {
4497  for (short s = 0; s < ACLlightningguiC; s++)
4498  {
4499  if (lightningabove[s].inuse)
4500  {
4501  lightningabove[s].timeleft -= fElapsedTime;
4502  if (lightningabove[s].trend)
4503  {
4504  lightningabove[s].intensity += RandomFloat() * fElapsedTime * 50.0f;
4505  if (lightningabove[s].intensity > 1.0f)
4506  {
4507  lightningabove[s].intensity = 1.0f;
4508  if (rand() > 16384)
4509  lightningabove[s].trend = false;
4510  }
4511  }
4512  else
4513  {
4514  lightningabove[s].intensity -= RandomFloat() * fElapsedTime * 50.0f;
4515  if (lightningabove[s].intensity < 0.0f)
4516  {
4517  lightningabove[s].intensity = 0.0f;
4518  if (rand() > 16384)
4519  lightningabove[s].trend = true;
4520  if (lightningabove[s].timeleft < 0.0f && lightningabove[s].trend)
4521  lightningabove[s].inuse = false;
4522  }
4523  }
4524  }
4525  else if ((rand() % 500) == 0) // !lightningabove[s].inuse
4526  {
4527  lightningabove[s].timeleft = RandomFloat() * 2.0f;
4528  lightningabove[s].trend = true;
4530 
4531  lightningabove[s].inuse = true;
4532  lightningabove[s].intensity = RandomFloat(); // 1.0f is violent
4533 
4534  if (s == 2) // not all of them trigger sounds
4535  sound->PlayEx(SOUND_THUNDER + rand() % 15, false, lightningabove[s].intensity);
4536  }
4537  }
4538  break;
4540  for (short s = 0; s < ACLlightningguiC; s++)
4541  {
4542  if (lightningabove[s].inuse)
4543  {
4544  lightningabove[s].timeleft -= fElapsedTime;
4545  if (lightningabove[s].trend)
4546  {
4547  lightningabove[s].intensity += RandomFloat() * fElapsedTime * 50.0f;
4548  if (lightningabove[s].intensity > 1.0f)
4549  {
4550  lightningabove[s].intensity = 1.0f;
4551  if (rand() > 16384)
4552  lightningabove[s].trend = false;
4553  }
4554  }
4555  else
4556  {
4557  lightningabove[s].intensity -= RandomFloat() * fElapsedTime * 50.0f;
4558  if (lightningabove[s].intensity < 0.0f)
4559  {
4560  lightningabove[s].intensity = 0.0f;
4561  if (rand() > 16384)
4562  lightningabove[s].trend = true;
4563  if (lightningabove[s].timeleft < 0.0f && lightningabove[s].trend)
4564  lightningabove[s].inuse = false;
4565  }
4566  }
4567  }
4568  else if (rand() % 5 == 0)
4569  {
4570  lightningabove[s].timeleft = RandomFloat() * 2.0f;
4571  lightningabove[s].trend = true;
4572  // they are 512x512, the canvas is 700x500 plus 512 either side 1724x1524 or -512,-512 to 1212,1012
4573  lightningabove[s].panelx = static_cast<float>(rand() % 1724);
4574  lightningabove[s].panely = static_cast<float>(rand() % 1524);
4575  lightningabove[s].rotate = RandomFloat() * D3DX_TAU;
4576  lightningabove[s].panelx = floorf(lightningabove[s].panelx / 5.0f) * 5.0f / 0.5f - 512.0f; // 0 344 689 1034 1379 1724
4577  lightningabove[s].panely = floorf(lightningabove[s].panely / 4.42f) * 4.42f / 0.5f - 512.0f;
4578  lightningabove[s].texture = static_cast<short>(rand()) % 3;
4579 
4580  lightningabove[s].inuse = true;
4581  lightningabove[s].intensity = RandomFloat(); // 1.0f is violent
4582  }
4583  }
4584  break;
4585  }
4586 }
float baydoorextent
Definition: globals.h:572
short FONT_WIDTH
Definition: gui.h:713
void LoadDIX(const char *prmFilename)
Definition: polyobj.cpp:91
Definition: polyobj.h:7
LPDIRECT3DTEXTURE9 m_pddsGUIInterlace
Definition: gui.h:733
float musicdone
Definition: Sound.h:334
D3DXVECTOR3 chaireye
Definition: globals.h:618
float tat_mod_qz_x
Definition: propulsion.h:82
short texture
Definition: gui.h:689
long ResidesLocally(unsigned short serial) const
Definition: people.h:166
Scockpit ourcockpit
Definition: globals.cpp:176
#define humantextureC
Definition: Graphics.h:11
Definition: gui.h:399
float panely
Definition: gui.h:688
float toastTime
Definition: gui.h:700
Sicons icon[(D_ENUMERATION+1)]
Definition: gui.h:751
#define designedHeightC
Definition: GameClass.h:23
char referralValid
Definition: gui.h:773
static void InitializeDialog(short t)
Definition: DialogBase.cpp:82
WCHAR loginstr[99]
Definition: gui.h:747
HMI(GameClass *g, Networking *n, Sound *s)
Definition: gui.cpp:2598
ID3DXEffect * g_pEffect
Definition: Graphics.h:30
void OnResetDevice()
Definition: gui.cpp:1000
int screenShotStatus
Definition: GameClass.h:105
bool g_bCheckSteamLanguage
Definition: config.h:13
SPlayerData LoadPerson(long temprecord) const
Definition: people.h:54
UINT flapSettingTE
Definition: Bus.h:56
LPDIRECT3DTEXTURE9 m_pddsKeycard
Definition: Viewscreen.h:168
Definition: gui.h:479
void AddSupportChatMessage(const WCHAR *wmsg)
Definition: gui.cpp:3463
virtual void UpdateMenu(short tab)
void InitApp()
Definition: gui.cpp:1675
float timeleft
Definition: gui.h:685
Networking * networking
Definition: gui.h:855
short helpboxlang
Definition: gui.h:713
Definition: Sound.h:276
char buffer2[16384]
Definition: gui.h:737
D3DXCOLOR GetHairColorAtIndex(int index)
Definition: gui.cpp:4418
void ProcessCallsignBox()
Definition: gui.cpp:1824
void LoadCockpitSound(int soundEnum, const char *path, bool force, SoundConfig *device=nullptr)
Definition: Sound.cpp:983
Config config
Definition: GameClass.h:102
Logger * logger
Definition: gui.h:858
LPDIRECT3DTEXTURE9 m_pddsGUIRanks
Definition: gui.h:740
unsigned char language
Definition: config.h:12
std::vector< Command > commandStream
Definition: Bus.h:342
Definition: gui.h:439
int revision
Definition: gui.h:788
void ProcessPasswordBox()
Definition: gui.cpp:1850
float stubbleFreckle
Definition: gui.h:755
void GetVersionText(WCHAR *, int size) const
Definition: gui.cpp:1801
GameState displaystage
Definition: GameClass.h:121
unsigned long rcvdbytes
Definition: Networking.h:93
std::vector< std::wstring > motd
Definition: gui.h:746
Definition: gui.h:415
void SendToServer(void *pData, DWORD dwSize, bool bGuaranteed, PacketOrdering order=ORDERING_NONE) const
Definition: Networking.cpp:59
float counterj
Definition: Viewscreen.h:315
#define designedWidthC
Definition: GameClass.h:22
LPDIRECT3DTEXTURE9 m_pddsLightningAndBackground[3]
Definition: Graphics.h:32
std::vector< std::wstring > chatline
Definition: chat.h:47
bool MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: gui.cpp:1046
GameClass * game
Definition: gui.h:857
LPDIRECT3DTEXTURE9 m_pddsGUIActions
Definition: gui.h:739
ID3DXFont * g_pFont
Definition: gui.h:727
void ReleaseComponents()
Definition: polyobj.cpp:197
D3DXVECTOR3 windowlocation
Definition: DialogBase.h:59
void ChannelInvite(char *title, unsigned char whoinvited, unsigned char channel, unsigned char players) const
Definition: gui.cpp:3703
scanDb Scanner
Definition: Bus.h:379
LPDIRECT3DTEXTURE9 m_pddsGUIInterlace2
Definition: gui.h:734
InformationDialog * informationDialog
Definition: gui.h:789
void SexChangeOperation(char newsex)
Definition: gui.cpp:27
void ShowHelpBubble(const WCHAR *msg) const
Definition: gui.cpp:1630
void PlayerOffline(unsigned char arrayindex)
Definition: gui.cpp:3373
float counteri
Definition: Viewscreen.h:315
~HMI()
Definition: gui.cpp:2726
HSTREAM g_pSoundIntro
Definition: Sound.h:329
void DisplaySnow(IDirect3DDevice9 *pd3dDevice, float fade, float fElapsed)
Definition: gui.cpp:1883
void SetLocale() const
Definition: gui.cpp:1449
void DrawErrorBoxes()
Definition: gui.cpp:4071
s_network_objects playerships[MAX_SCAN]
Definition: globals.cpp:174
static void Initialize(HMI *gui)
Definition: DialogBase.cpp:114
SoundConfig soundConfigLegacy
Definition: config.h:45
float displayHeight
Definition: GameClass.h:129
float RollAttitudeRadians
Definition: Bus.h:37
#define ACLlightningguiC
Definition: gui.h:693
LPDIRECT3DTEXTURE9 m_pddsToast
Definition: gui.h:741
LPWSTR currentCursor
Definition: gui.h:779
LPDIRECT3DTEXTURE9 m_pddsToastIcons
Definition: gui.h:742
bool mouseover
Definition: gui.h:392
D3DXCOLOR GetEyeColorAtIndex(int index)
Definition: gui.cpp:4457
std::vector< std::wstring > currentToast
Definition: gui.h:699
float age
Definition: gui.h:755
int major
Definition: gui.h:785
short tabs
Definition: DialogBase.h:62
float height
Definition: gui.h:755
char defaultpass[16]
Definition: config.h:16
LPDIRECT3DVERTEXBUFFER9 VB
Definition: globals.h:366
float g_fTabFlashTime
Definition: gui.h:712
LIGHTNINGABOVEGUI lightningabove[ACLlightningguiC]
Definition: gui.h:762
float cloudmotion
Definition: gui.h:760
void SendEvent(EventType eventType, float extent=0.0f) const
Definition: Networking.cpp:111
float displayWidth
Definition: GameClass.h:129
void ResetLoginFields()
Definition: gui.cpp:3406
short dragt
Definition: gui.h:716
static bool OnEnter()
D3DXCOLOR eyecolor
Definition: gui.h:754
Definition: gui.h:452
unsigned char owner
Definition: chat.h:57
short defaultwidth
Definition: DialogBase.h:51
void Save()
Definition: config.cpp:363
Logger * logger
Definition: GameClass.h:113
bool rxlight
Definition: gui.h:770
POINT ptClick
Definition: gui.h:724
short toastIcon
Definition: gui.h:701
float fade
Definition: gui.h:758
float fTime
Definition: gui.h:698
CDXUTDialogResourceManager g_DialogResourceManager
Definition: gui.h:752
bool showKeymapOverlay
Definition: GameClass.h:131
DiscordRPC * discord
Definition: GameClass.h:115
std::vector< std::string > chatlineplayer
Definition: chat.h:48
LPDIRECTINPUTDEVICE8 g_pJoystick
Definition: InputConfig.h:22
POINT ptCursor
Definition: gui.h:724
void DrawRXTXLights(LPDIRECT3DTEXTURE9 *tex) const
Definition: gui.cpp:4053
std::string name
Definition: Command.h:11
Definition: gui.h:472
Definition: gui.h:462
void AddChatMessage(WCHAR *msg, unsigned char playerindex, unsigned char channel)
Definition: gui.cpp:3511
short text
Definition: DialogBase.h:69
void PlayerLeftChannel(short tab, unsigned char playerindex)
Definition: gui.cpp:3432
float intensity
Definition: gui.h:686
float g_fMouseLastMoveTime
Definition: gui.h:712
bool g_bDragging
Definition: gui.h:714
static void CheckDialogMouse()
Definition: DialogBase.cpp:293
static DialogBase * dialogs[D_ENUMERATION]
Definition: DialogBase.h:39
CDXUTDialog g_HUD
Definition: gui.h:710
LPDIRECT3DTEXTURE9 m_pddsGUIParts
Definition: gui.h:731
void OnDestroyDevice()
Definition: gui.cpp:3324
void AddPlayer(unsigned char tempplayer)
Definition: chat.h:17
propulsion * ptrPropulsion
Definition: Viewscreen.h:285
short dialog
Definition: gui.h:393
void DisplayImmigration(bool refresh)
Definition: gui.cpp:3747
float maxWeight
Definition: gui.h:755
char defaultuser[13]
Definition: config.h:15
float g_fDownCounterTime
Definition: gui.h:712
float flapExtent
Definition: globals.h:655
bool loopintro
Definition: Sound.h:332
bool g_bDropped
Definition: gui.h:715
static void OnDeviceReset()
bool IsAdmin
Definition: gui.h:777
void GetProgramVersion(int &major, int &minor, int &build, int &revision) const
Definition: GameClass.cpp:2644
D3DXCOLOR haircolor
Definition: gui.h:754
bool txlight
Definition: gui.h:770
Viewscreen * viewscreen
Definition: GameClass.h:111
Definition: gui.h:477
unsigned char ourplayerC
Definition: gui.h:766
Networking * networking
Definition: GameClass.h:107
bool PopUpHelp(short helpId, bool allowDismiss=true, bool isLearnMore=false)
#define D3DFVF_INSTRUMENT
Definition: globals.h:110
static short CheckHeight(short t)
bool g_bLeftClick
Definition: gui.h:714
Definition: gui.h:413
float m_fSlide
Definition: gui.h:712
static void CALLBACK OnGUIEvent(UINT nEvent, int nControlID, CDXUTControl *pControl, void *pUserContext)
Definition: gui.cpp:2771
SPlayerData player[MAX_ONLINEPLAYERS]
Definition: gui.h:765
UIControlIds
Definition: gui.h:396
char showerrors
Definition: gui.h:771
short defaultheight
Definition: DialogBase.h:51
LPDIRECT3DTEXTURE9 m_pddsCloudBaseMapAndNetwork
Definition: Graphics.h:31
Definition: gui.h:402
bool isLocal
Definition: gui.h:784
void RepairVehicle() const
Definition: GameClass.cpp:168
LPDIRECT3DTEXTURE9 m_pddsGUILateral
Definition: gui.h:732
void LoadPeopleSounds() const
Definition: gui.cpp:1128
short width
Definition: DialogBase.h:60
void FadeIn(float f, float fElapsedTime)
Definition: gui.cpp:4478
bool grippy
Definition: gui.h:781
void LoadLanguage()
Definition: gui.cpp:1480
void LoadConfiguration() const
Definition: gui.cpp:1701
bool g_bRightDown
Definition: gui.h:720
void CreateDialogs()
Definition: gui.cpp:2532
LPDIRECT3DTEXTURE9 m_pddsEasydockAd
Definition: gui.h:743
long dragline
Definition: gui.h:717
bool inuse
Definition: gui.h:684
bool isSteam
Definition: gui.h:783
static void IconClick(short icon_id)
Definition: DialogBase.cpp:192
short txbuffer
Definition: gui.h:772
static short CheckWidth(short dialogid)
int linetop
Definition: DialogBase.h:73
D3DXVECTOR3 iconlocation
Definition: gui.h:391
float maxHeight
Definition: gui.h:755
void AddPlayer(char *msg, unsigned char playerindex)
Definition: gui.cpp:3586
char charnameValid
Definition: gui.h:773
void LoadTexture(LPDIRECT3DTEXTURE9 *resource, const std::string &pointerName, const WCHAR *file, D3DFORMAT format=D3DFMT_A8R8G8B8)
Definition: GameClass.cpp:2020
Definition: Command.h:5
RECT iconsource
Definition: gui.h:390
char handleValid
Definition: gui.h:773
void Toast(const WCHAR *message, ActiveHelp activeHelp)
Definition: gui.cpp:1202
void LightningCalculations(float fElapsedTime)
Definition: gui.cpp:4490
Graphics * graphics
Definition: GameClass.h:109
bool trend
Definition: gui.h:687
void TriggerWelcomeApt2() const
Definition: gui.cpp:1180
const D3DXVECTOR3 centerC
float eyemotion
Definition: gui.h:756
PolyObj polyobj
Definition: gui.h:775
float furtherdelay
Definition: gui.h:757
static void RestoreDefaults()
Definition: gui.cpp:1811
bool g_bLeftDouble
Definition: gui.h:715
Sound * sound
Definition: GameClass.h:108
void FrameMove(float fElapsedTime)
int toastY
Definition: gui.h:702
void OnRender(float fElapsedTime, IDirect3DDevice9 *pd3dDevice)
Definition: gui.cpp:1946
Sound * sound
Definition: gui.h:856
void AddLanguageOptions(UIControlIds controlId, CDXUTDialog *HUD) const
Definition: gui.cpp:1416
bool g_bRightClick
Definition: gui.h:720
char emailValid
Definition: gui.h:773
unsigned long patchbytes
Definition: Networking.h:92
CHATCHANNEL chatchannel[MAX_TAB]
Definition: gui.h:768
s_polygon_object tempobject
Definition: gui.h:774
void Log(const char *msg, Level level=Info, int errorCode=0)
Definition: Logger.cpp:11
short tabflash[MAX_TAB]
Definition: DialogBase.h:88
void PlayerJoinedChannel(short tab, unsigned char playerindex)
Definition: gui.cpp:3413
bool g_bTabLit
Definition: gui.h:715
bool g_bGVfilter
Definition: gui.h:721
unsigned char hitpoints
Definition: globals.h:663
short icon
Definition: DialogBase.h:53
float gearextent
Definition: globals.h:621
D3DXCOLOR skintone
Definition: gui.h:754
float distance
Definition: gui.h:690
short rxbuffer
Definition: gui.h:772
bool eastasian
Definition: gui.h:715
Definition: gui.h:696
PEOPLE people
Definition: gui.h:769
virtual void ClearEdit()
int minor
Definition: gui.h:786
void ChangeChannelName(unsigned char channelId, char *title)
Definition: gui.cpp:3683
float counterk
Definition: Viewscreen.h:315
HRESULT OnCreateDevice(IDirect3DDevice9 *pd3dDevice)
Definition: gui.cpp:1144
bool haserrors
Definition: gui.h:770
char buffer1[16384]
Definition: gui.h:735
static void FrameMove()
Definition: DiscordRPC.cpp:320
float Play(int soundEnum)
Definition: Sound.cpp:577
ActiveHelp
Definition: ActiveHelp.h:3
void UpdatePresence(const char *prmDetails, const char *prmState, const char *prmLargeImageKey)
Definition: DiscordRPC.cpp:44
ID3DXSprite * g_pTextSprite
Definition: gui.h:726
static void UpdateScrollBar(short t)
short height
Definition: DialogBase.h:60
LPD3DXBUFFER pBuffer
Definition: gui.h:761
float minHeight
Definition: gui.h:755
void AddDiscordChatMessage(const WCHAR *msg)
Definition: gui.cpp:3481
LPDIRECT3DTEXTURE9 m_pddsGUIScrollButton
Definition: gui.h:738
void OnFrameMove(float fElapsedTime)
Definition: gui.cpp:212
#define STORE_CHAT_SIZE
Definition: chat.h:7
void SetPlayerAlignment(char *msg, unsigned char playerindex)
Definition: gui.cpp:3639
void SavePerson(long temprecord, SPlayerData tempperson) const
Definition: people.h:94
short loadstage
Definition: GameClass.h:122
bool g_bAutoLogin
Definition: config.h:20
void UpdateLoginCreateButtons()
Definition: gui.cpp:1869
ID3DXFont * g_pChatFont
Definition: gui.h:728
HMI * GUI
Definition: GameClass.h:110
float panelx
Definition: gui.h:688
tm tm_time
Definition: gui.h:708
Definition: gui.h:429
bool g_bLeftDown
Definition: gui.h:714
Definition: scanDb.h:46
float rotate
Definition: gui.h:688
void LoadTextures(GameState displaystage, short loadstage)
Definition: gui.cpp:3222
InputConfig inputConfigWalkVertical
Definition: config.h:41
char dead
Definition: globals.cpp:49
void AddTrackedResource(const char *name, _D3DPOOL pool=D3DPOOL_MANAGED)
Definition: GameClass.cpp:2702
float minWeight
Definition: gui.h:755
Sscan Get(USHORT vehicleId) const
Definition: scanDb.cpp:87
int build
Definition: gui.h:787
float displayscale
Definition: GameClass.h:128
static void UpdateAllActiveDialogs(float fElapsedTime)
Definition: DialogBase.cpp:121
void ChangePlayerProperties(SSubscribeData *prop)
Definition: gui.cpp:3715
#define D3DFVF_VERTEX
Definition: globals.h:101
D3DXVECTOR3 windowdefaultlocation
Definition: DialogBase.h:52
LPDIRECT3DTEXTURE9 m_pddsGUIScroll
Definition: gui.h:736
std::wstring strings[L_ENUMERATION]
Definition: gui.h:749
void PlayEx(int soundEnum, bool loop, float volume=1.0f, float frequencyMod=1.0f, float pan=0.0f, bool restart=true)
Definition: Sound.cpp:606
s_polygon_object LoadDAW(const char *filename) const
Definition: polyobj.cpp:21
void RemovePlayer(short tempplayer)
Definition: chat.h:24
static short draworder[D_ENUMERATION]
Definition: DialogBase.h:105
void ChangeChannelOwner(short tab, unsigned char playerindex)
Definition: gui.cpp:3451
bool g_bShift
Definition: globals.cpp:126
void UpdateTrackedResource(const char *name, int status)
Definition: GameClass.cpp:2725
void AddToCallStack(const char *msg)
Definition: Logger.cpp:86
Bus * bus
Definition: GameClass.h:112
float flood
Definition: gui.h:767
virtual void ActiveTab()
float g_fLeftDownTime
Definition: gui.h:712
float musicleft
Definition: Sound.h:334
static void DrawAllActiveDialogs(float fElapsedTime)
Definition: DialogBase.cpp:742
void SaveConfiguration() const
Definition: gui.cpp:1768
void RequestVerbiage(int helpId) const
Definition: Networking.cpp:168
LPDIRECT3DTEXTURE9 m_pddsAvatar[humantextureC]
Definition: Graphics.h:33
bool initialized
Definition: scanDb.h:48
float RandomFloat()
Definition: MathUtilities.h:98
short retryconnect
Definition: Networking.h:94
bool makehud
Definition: gui.h:759
short cursoroverwindow
Definition: gui.h:713
float weight
Definition: gui.h:755
InputConfig inputConfigLookLateral
Definition: config.h:37
Definition: gui.h:450
ActiveHelp toastId
Definition: gui.h:703
bool IsActive(ActiveHelp helpId) const
bool cursorVisible
Definition: gui.h:780
GameState
Definition: GameState.h:3
D3DXVECTOR3 windowseeklocation
Definition: DialogBase.h:68
char patchdate[24]
Definition: config.h:17
bool minimized
Definition: gui.h:782
bool createRoute
Definition: gui.h:704
char connectstatus
Definition: Networking.h:91
void GarbleChat(wchar_t *str) const
Definition: gui.cpp:2750