Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
EngDlg.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: EngDlg.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Engineering (Power/Maint) Dialog Active Window class
13 */
14 
15 #include "MemDebug.h"
16 #include "EngDlg.h"
17 #include "GameScreen.h"
18 #include "Ship.h"
19 #include "Power.h"
20 #include "Component.h"
21 #include "Sim.h"
22 
23 #include "DataLoader.h"
24 #include "Button.h"
25 #include "ListBox.h"
26 #include "Slider.h"
27 #include "Video.h"
28 #include "Mouse.h"
29 #include "Keyboard.h"
30 #include "Game.h"
31 #include "FormatUtil.h"
32 
33 // +--------------------------------------------------------------------+
34 // DECLARE MAPPING FUNCTIONS:
35 
36 DEF_MAP_CLIENT(EngDlg, OnSource);
37 DEF_MAP_CLIENT(EngDlg, OnClient);
38 DEF_MAP_CLIENT(EngDlg, OnRouteStart);
39 DEF_MAP_CLIENT(EngDlg, OnRouteComplete);
40 DEF_MAP_CLIENT(EngDlg, OnPowerOff);
41 DEF_MAP_CLIENT(EngDlg, OnPowerOn);
42 DEF_MAP_CLIENT(EngDlg, OnOverride);
43 DEF_MAP_CLIENT(EngDlg, OnPowerLevel);
44 DEF_MAP_CLIENT(EngDlg, OnComponent);
45 DEF_MAP_CLIENT(EngDlg, OnAutoRepair);
46 DEF_MAP_CLIENT(EngDlg, OnRepair);
47 DEF_MAP_CLIENT(EngDlg, OnReplace);
48 DEF_MAP_CLIENT(EngDlg, OnQueue);
49 DEF_MAP_CLIENT(EngDlg, OnPriorityIncrease);
50 DEF_MAP_CLIENT(EngDlg, OnPriorityDecrease);
51 DEF_MAP_CLIENT(EngDlg, OnClose);
52 
53 // +--------------------------------------------------------------------+
54 
56 : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr),
57 ship(0), route_source(0), selected_source(0),
58 selected_repair(0), selected_component(0)
59 {
60  Init(def);
61 }
62 
64 {
65 }
66 
67 // +--------------------------------------------------------------------+
68 
69 void
71 {
72  for (int i = 0; i < 4; i++) {
73  sources[i] = (Button*) FindControl(201 + i);
75 
76  source_levels[i] = (Slider*) FindControl(211 + i);
77 
78  clients[i] = (ListBox*) FindControl(301 + i);
79 
80  if (clients[i]) {
82  clients[i]->SetSortColumn(0);
83 
87  }
88  }
89 
92  power_off = (Button*) FindControl(402);
93  power_on = (Button*) FindControl(403);
94  override = (Button*) FindControl(410);
95  power_level = (Slider*) FindControl(404);
96  capacity = (Slider*) FindControl(405);
97 
98  if (close_btn)
100 
101  if (power_off)
103 
104  if (power_on)
106 
107  if (override)
109 
110  if (power_level)
112 
113  components = (ListBox*) FindControl(501);
114 
115  if (components) {
119  }
120 
121  auto_repair = (Button*) FindControl(700);
122  repair = (Button*) FindControl(502);
123  replace = (Button*) FindControl(503);
124  repair_time = FindControl(512);
125  replace_time = FindControl(513);
128 
129  if (auto_repair)
131 
132  if (repair)
134 
135  if (replace)
137 
138  if (repair_time)
139  repair_time->Hide();
140 
141  if (replace_time)
142  replace_time->Hide();
143 
144  if (priority_increase) {
145  char up_arrow[2];
146  up_arrow[0] = Font::ARROW_UP;
147  up_arrow[1] = 0;
148  priority_increase->SetText(up_arrow);
149 
151  }
152 
153  if (priority_decrease) {
154  char dn_arrow[2];
155  dn_arrow[0] = Font::ARROW_DOWN;
156  dn_arrow[1] = 0;
157  priority_decrease->SetText(dn_arrow);
158 
160  }
161 
162  repair_queue = (ListBox*) FindControl(601);
163 
164  if (repair_queue) {
167  }
168 }
169 
170 // +--------------------------------------------------------------------+
171 
172 void
174 {
176 
177  if (ship) {
178  int nsources = ship->Reactors().size();
179 
180  for (int i = 0; i < 4; i++) {
181  if (i >= nsources) {
182  sources[i]->Hide();
183  source_levels[i]->Hide();
184  clients[i]->Hide();
185  }
186  }
187  }
188 }
189 
190 void
192 {
194 }
195 
196 // +--------------------------------------------------------------------+
197 
198 void
200 {
201  if (IsShown() && ship != s) {
202  selected_source = 0;
203  selected_repair = 0;
204  selected_component = 0;
206 
207  ship = s;
208 
210  ExecFrame();
211  }
212 
213  // make sure we clear the ship, even if not shown:
214  else if (!s) {
215  ship = 0;
216  }
217 }
218 
219 void
221 {
222  for (int i = 0; i < 4; i++)
223  clients[i]->ClearSelection();
224 
225  if (components)
227 
228  if (priority_increase)
230 
231  if (priority_decrease)
233 
234  if (ship) {
235  for (int i = 0; i < 4; i++) {
236  if (sources[i])
237  sources[i]->Hide();
238 
239  if (source_levels[i])
240  source_levels[i]->Hide();
241 
242  if (clients[i]) {
243  clients[i]->ClearItems();
244  clients[i]->Hide();
245  }
246  }
247 
248  int reactor_index = 0;
249  ListIter<PowerSource> reactor_iter = ship->Reactors();
250 
251  while (++reactor_iter) {
252  PowerSource* reactor = reactor_iter.value();
253 
254  if (sources[reactor_index] && clients[reactor_index]) {
255  sources[reactor_index]->SetText(Game::GetText(reactor->Abbreviation()));
256  sources[reactor_index]->Show();
257 
258  source_levels[reactor_index]->Show();
259  source_levels[reactor_index]->SetValue((int) reactor->GetPowerLevel());
260 
261  clients[reactor_index]->Show();
262 
263  int index = 0;
264  ListIter<System> client = reactor->Clients();
265  while (++client) {
266  char abrv[64], num[20];
267  FormatNumber(num, client->GetPowerLevel());
268  strcpy_s(abrv, Game::GetText(client->Name()));
269 
270  clients[reactor_index]->AddItemWithData(Game::GetText(abrv), index);
271  clients[reactor_index]->SetItemText(index, 1, num);
272  clients[reactor_index]->SetItemData(index, 1, (DWORD) client->GetPowerLevel());
273 
274  index++;
275  }
276 
277  clients[reactor_index]->SortItems();
278  }
279 
280  reactor->RouteScanned();
281  reactor_index++;
282  }
283  }
284 }
285 
286 // +--------------------------------------------------------------------+
287 
288 void
290 {
291  if (IsShown())
292  UpdateSelection();
293 }
294 
295 void
297 {
298  if (!ship) return;
299 
300  char num[20];
301  int nsources = ship->Reactors().size();
302 
303  // update the route tables:
304  for (int source_index = 0; source_index < nsources; source_index++) {
305  PowerSource* reac = ship->Reactors()[source_index];
306 
307  if (reac->RouteChanged())
309 
310  Color c(62,106,151);
311 
312  if (reac->IsPowerOn()) {
313  switch (reac->Status()) {
314  default:
315  case System::NOMINAL: break;
316  case System::DEGRADED: c = Color::Yellow; break;
317  case System::CRITICAL: c = Color::BrightRed; break;
318  case System::DESTROYED: c = Color::DarkRed; break;
319  }
320  }
321  else {
322  c = Color::Gray;
323  }
324 
325  sources[source_index]->SetBackColor(c);
326  source_levels[source_index]->SetEnabled(reac->IsPowerOn());
327  source_levels[source_index]->SetValue((int) reac->GetPowerLevel());
328 
329  ListBox* client_list = clients[source_index];
330 
331  for (int i = 0; i < client_list->NumItems(); i++) {
332  int index = client_list->GetItemData(i);
333 
334  System* client = reac->Clients()[index];
335  FormatNumber(num, client->GetPowerLevel());
336  client_list->SetItemText(i, 1, num);
337  client_list->SetItemData(i, 1, (DWORD) client->GetPowerLevel());
338 
339  if (client->IsPowerOn()) {
340  Color c;
341 
342  switch (client->Status()) {
343  default:
344  case System::NOMINAL: c = Color::White; break;
345  case System::DEGRADED: c = Color::Yellow; break;
346  case System::CRITICAL: c = Color::BrightRed; break;
347  case System::DESTROYED: c = Color::DarkRed; break;
348  }
349 
350  client_list->SetItemColor(i, c);
351  }
352  else {
353  client_list->SetItemColor(i, Color::Gray);
354  }
355 
356  }
357  }
358 
359  // update the detail info:
360  if (selected_source) {
362  power_off->SetEnabled(true);
363  power_on->SetEnabled(true);
364  override->SetEnabled(true);
365  if (override->GetButtonState() != 2)
369 
370  if (selected_source->Safety() < 100) {
373  }
374  else {
375  power_level->SetMarker(-1, 0);
376  power_level->SetMarker(-1, 1);
377  }
378 
379  capacity->SetEnabled(true);
381 
382  if (selected_source->IsPowerOn()) {
383  if (power_on->GetButtonState() != 2)
385  if (power_off->GetButtonState() != 2)
387  }
388  else {
389  if (power_on->GetButtonState() != 2)
391  if (power_off->GetButtonState() != 2)
393  }
394 
395  if (components) {
396  for (int i = 0; i < components->NumItems(); i++) {
397  int index = components->GetItemData(i);
398 
399  Component* comp = selected_source->GetComponents()[index];
400 
401  Text stat = "OK";
402  Color c;
403 
404  switch (comp->Status()) {
406  case Component::CRITICAL: stat = "FAIL"; c = Color::BrightRed; break;
407  case Component::DEGRADED: stat = "WARN"; c = Color::Yellow; break;
408  case Component::NOMINAL: stat = "OK"; c = Color::White; break;
409  case Component::REPLACE:
410  case Component::REPAIR: stat = "MAINT"; c = Color::Cyan; break;
411  }
412 
413  stat = Game::GetText(Text("EngDlg.") + stat);
414  components->SetItemText(i, 1, stat);
415  components->SetItemData(i, 1, (int) comp->Status());
416 
417  FormatNumber(num, comp->SpareCount());
418  components->SetItemText(i, 2, num);
419  components->SetItemData(i, 2, comp->SpareCount());
420  components->SetItemColor(i, c);
421  }
422  }
423  }
424 
425  else if (selected_clients.size() == 1) {
426  System* sink = selected_clients[0];
427 
429  power_off->SetEnabled(true);
430  power_on->SetEnabled(true);
431  override->SetEnabled(true);
432  if (override->GetButtonState() != 2)
433  override->SetButtonState(sink->GetPowerLevel() > 100 ? 1 : 0);
434  power_level->SetEnabled(sink->IsPowerOn());
435  power_level->SetValue((int) sink->GetPowerLevel());
436 
437  if (sink->Safety() < 100) {
438  power_level->SetMarker((int) sink->Safety(), 0);
439  power_level->SetMarker((int) sink->Safety(), 1);
440  }
441  else {
442  power_level->SetMarker(-1, 0);
443  power_level->SetMarker(-1, 1);
444  }
445 
446  capacity->SetEnabled(true);
447  capacity->SetValue((int) sink->Charge());
448 
449  if (sink->IsPowerOn()) {
450  if (power_on->GetButtonState() != 2)
452  if (power_off->GetButtonState() != 2)
454  }
455  else {
456  if (power_on->GetButtonState() != 2)
458  if (power_off->GetButtonState() != 2)
460  }
461 
462  if (components) {
463  for (int i = 0; i < components->NumItems(); i++) {
464  int index = components->GetItemData(i);
465 
466  Component* comp = sink->GetComponents()[index];
467 
468  Text stat = "OK";
469  Color c;
470 
471  switch (comp->Status()) {
473  case Component::CRITICAL: stat = "FAIL"; c = Color::BrightRed; break;
474  case Component::DEGRADED: stat = "WARN"; c = Color::Yellow; break;
475  case Component::NOMINAL: stat = "OK"; c = Color::White; break;
476  case Component::REPLACE:
477  case Component::REPAIR: stat = "MAINT"; c = Color::Cyan; break;
478  }
479 
480  stat = Game::GetText(Text("EngDlg.") + stat);
481  components->SetItemText(i, 1, stat);
482  components->SetItemData(i, 1, (int) comp->Status());
483 
484  FormatNumber(num, comp->SpareCount());
485  components->SetItemText(i, 2, num);
486  components->SetItemData(i, 2, comp->SpareCount());
487  components->SetItemColor(i, c);
488  }
489  }
490  }
491 
492  else if (selected_clients.size() > 1) {
493  System* sink = selected_clients[0];
494 
495  selected_name->SetText(Game::GetText("[Multiple]"));
496  power_off->SetEnabled(true);
497  power_on->SetEnabled(true);
498  override->SetEnabled(true);
499  if (override->GetButtonState() != 2)
500  override->SetButtonState(sink->GetPowerLevel() > 100 ? 1 : 0);
501  power_level->SetEnabled(true);
502  power_level->SetValue((int) sink->GetPowerLevel());
503 
504  if (sink->Safety() < 100) {
505  power_level->SetMarker((int) sink->Safety(), 0);
506  power_level->SetMarker((int) sink->Safety(), 1);
507  }
508  else {
509  power_level->SetMarker(-1, 0);
510  power_level->SetMarker(-1, 1);
511  }
512 
513  capacity->SetEnabled(true);
514  capacity->SetValue((int) sink->Charge());
515 
516  if (sink->IsPowerOn()) {
517  if (power_on->GetButtonState() != 2)
519  if (power_off->GetButtonState() != 2)
521  }
522  else {
523  if (power_on->GetButtonState() != 2)
525  if (power_off->GetButtonState() != 2)
527  }
528  }
529 
530  else {
531  selected_name->SetText(Game::GetText("No Selection"));
532  power_off->SetEnabled(false);
534  power_on->SetEnabled(false);
536  override->SetEnabled(false);
537  override->SetButtonState(0);
538  power_level->SetEnabled(false);
539  power_level->SetValue(0);
540  power_level->SetMarker(-1, 0);
541  power_level->SetMarker(-1, 1);
542  capacity->SetEnabled(false);
543  capacity->SetValue(0);
544  }
545 
546  // display the repair queue:
547  if (repair_queue) {
548  // if adding to the queue, dump and reload:
549  if (repair_queue->NumItems() < ship->RepairQueue().size()) {
551 
552  int i = 0;
554  while (++iter) {
555  double time_remaining = 0;
556  char etr[20];
557 
558  System* sys = iter.value();
559 
560  ListIter<Component> comp = sys->GetComponents();
561  while (++comp) {
562  Component* c = comp.value();
563  if (c->TimeRemaining() > time_remaining)
564  time_remaining = c->TimeRemaining();
565  }
566 
567  FormatTime(etr, (int) (time_remaining / ship->RepairSpeed()));
569  repair_queue->SetItemText(i, 1, etr);
570  i++;
571  }
572  }
573 
574  // otherwise, update in place:
575  else {
576  while (repair_queue->NumItems() > ship->RepairQueue().size())
578 
579  bool found = false;
580 
581  for (int i = 0; i < repair_queue->NumItems(); i++) {
582  double time_remaining = 0;
583  char etr[20];
584 
585  System* sys = ship->RepairQueue().at(i);
586 
587  ListIter<Component> comp = sys->GetComponents();
588  while (++comp) {
589  Component* c = comp.value();
590  if (c->TimeRemaining() > time_remaining)
591  time_remaining = c->TimeRemaining();
592  }
593 
594  FormatTime(etr, (int) time_remaining);
595  repair_queue->SetItemText(i, sys->Name());
596  repair_queue->SetItemText(i, 1, etr);
597 
598  if (sys == selected_repair) {
599  found = true;
600 
601  if (!Mouse::LButton())
603  }
604  }
605 
606  if (!found)
607  selected_repair = 0;
608  }
609  }
610 
611  if (auto_repair && auto_repair->GetButtonState() != 2)
613 }
614 
615 // +--------------------------------------------------------------------+
616 
617 void
619 {
620  selected_source = 0;
622  selected_component = 0;
623 
624  if (!ship) return;
625 
626  int source_index = -1;
627 
628  for (int i = 0; i < 4; i++)
629  if (event->window == sources[i])
630  source_index = i;
631 
632  // found the source list:
633  if (source_index >= 0) {
634  selected_source = ship->Reactors()[source_index];
635  }
636 
637  for (int i = 0; i < 4; i++) {
638  clients[i]->ClearSelection();
639  }
640 
641  if (components) {
643 
644  if (repair) repair->SetEnabled(false);
645  if (replace) replace->SetEnabled(false);
646  if (repair_time) repair_time->Hide();
648 
650  int index = 0;
652  while (++comp)
654  }
655  }
656 }
657 
658 void
660 {
661  selected_source = 0;
663  selected_component = 0;
664 
665  if (!ship) return;
666 
667  int source_index = -1;
668 
669  for (int i = 0; i < 4; i++) {
670  if (event->window == clients[i])
671  source_index = i;
672  else
673  clients[i]->ClearSelection();
674  }
675 
676  // found the source list:
677  if (source_index >= 0) {
678  // find the power source:
679  PowerSource* src = ship->Reactors()[source_index];
680 
681  // build a list of the clients to be manipulated:
682  List<System>& client_list = src->Clients();
683  for (int i = 0; i < clients[source_index]->NumItems(); i++) {
684  if (clients[source_index]->IsSelected(i)) {
685  int index = clients[source_index]->GetItemData(i);
686  selected_clients.append(client_list[index]);
687  }
688  }
689  }
690 
691  if (components) {
693 
694  if (repair) repair->SetEnabled(false);
695  if (replace) replace->SetEnabled(false);
696  if (repair_time) repair_time->Hide();
698 
699  if (selected_clients.size() == 1) {
700  System* sink = selected_clients[0];
701 
702  if (sink->GetComponents().size()) {
703  int index = 0;
704  ListIter<Component> comp = sink->GetComponents();
705  while (++comp)
707  }
708  }
709  }
710 }
711 
712 // +--------------------------------------------------------------------+
713 
714 void
716 {
717  if (!ship) return;
718 
719  int source_index = -1;
720 
721  for (int i = 0; i < 4; i++)
722  if (event->window == clients[i])
723  source_index = i;
724 
725  // found the source list:
726  if (source_index >= 0) {
727  // remember the power source:
728  route_source = ship->Reactors()[source_index];
729  route_list.clear();
730 
731  // build a list of the clients to be moved:
733  for (int i = 0; i < clients[source_index]->NumItems(); i++) {
734  if (clients[source_index]->IsSelected(i)) {
735  int index = clients[source_index]->GetItemData(i);
736  route_list.append(rsc[index]);
737  }
738  }
739  }
740 }
741 
742 // +--------------------------------------------------------------------+
743 
744 void
746 {
747  if (!ship || !route_source) return;
748 
749  int dest_index = -1;
750 
751  for (int i = 0; i < 4; i++)
752  if (event->window == clients[i])
753  dest_index = i;
754 
755  // found the destination list, copy the clients over:
756  if (dest_index >= 0) {
757  PowerSource* route_dest = ship->Reactors()[dest_index];
758 
759  if (!route_dest)
760  return;
761 
763  while (++iter) {
764  System* client = iter.value();
765 
766  route_source->RemoveClient(client);
767  route_dest->AddClient(client);
768  }
769  }
770 }
771 
772 // +--------------------------------------------------------------------+
773 
774 void
776 {
777  if (selected_source) {
779 
782  override->SetButtonState(0);
783  }
784 
785  else if (selected_clients.size() > 0) {
787  while (++iter)
788  iter->PowerOff();
789 
792  override->SetButtonState(0);
793  }
794 }
795 
796 void
798 {
799  if (selected_source) {
801 
804  override->SetButtonState(0);
805  }
806 
807  else if (selected_clients.size() > 0) {
809  while (++iter)
810  iter->PowerOn();
811 
814  override->SetButtonState(0);
815  }
816 }
817 
818 void
820 {
821  bool over = false;
822 
823  if (override->GetButtonState() > 0)
824  over = true;
825 
826  if (selected_source) {
828  }
829 
830  else if (selected_clients.size() > 0) {
832  while (++iter)
833  iter->SetOverride(over);
834  }
835 
836  if (over) {
839  }
840 }
841 
842 void
844 {
845  int level = power_level->GetValue();
846 
847  if (level < 0)
848  level = 0;
849  else if (level > 100)
850  level = 100;
851 
852  if (selected_source)
854 
855  else if (selected_clients.size() > 0) {
857  while (++iter)
858  iter->SetPowerLevel(level);
859  }
860 
861  if (override)
862  override->SetButtonState(0);
863 }
864 
865 // +--------------------------------------------------------------------+
866 
867 void
869 {
870  selected_component = 0;
871 
872  if (repair) repair->SetEnabled(false);
873  if (replace) replace->SetEnabled(false);
874  if (repair_time) repair_time->Hide();
876 
877  // find index of selected component:
878  int component_index = -1;
879 
880  if (components) {
881  int n = components->GetSelection();
882  if (n >= 0)
883  component_index = components->GetItemData(n);
884  }
885 
886  // now examine the component info:
887  if (component_index >= 0) {
888  repair->SetEnabled(true);
889 
890  if (selected_source) {
892  selected_component = comps[component_index];
893 
894  if (repair_time) {
895  char t[32];
896  int s = (int) (selected_component->RepairTime() /
897  ship->RepairSpeed());
898  FormatTime(t, s);
899  repair_time->SetText(t);
900  repair_time->Show();
901  }
902 
903  if (selected_component->SpareCount() > 0) {
904  if (replace) replace->SetEnabled(true);
905 
906  if (replace_time) {
907  char t[32];
908  int s = (int) (selected_component->ReplaceTime() /
909  ship->RepairSpeed());
910  FormatTime(t, s);
911  replace_time->SetText(t);
912  replace_time->Show();
913  }
914  }
915  }
916  else if (selected_clients.size() > 0) {
917  List<Component>& comps = selected_clients[0]->GetComponents();
918  selected_component = comps[component_index];
919 
920  if (repair_time) {
921  char t[32];
922  int s = (int) (selected_component->RepairTime() /
923  ship->RepairSpeed());
924  FormatTime(t, s);
925  repair_time->SetText(t);
926  repair_time->Show();
927  }
928 
929  if (selected_component->SpareCount() > 0) {
930  if (replace) replace->SetEnabled(true);
931 
932  if (replace_time) {
933  char t[32];
934  int s = (int) (selected_component->ReplaceTime() /
935  ship->RepairSpeed());
936  FormatTime(t, s);
937  replace_time->SetText(t);
938  replace_time->Show();
939  }
940  }
941  }
942  }
943 }
944 
945 // +--------------------------------------------------------------------+
946 
947 void
949 {
950  if (ship)
952 }
953 
954 // +--------------------------------------------------------------------+
955 
956 void
958 {
959  if (selected_component) {
961 
962  if (ship)
964  }
965 }
966 
967 void
969 {
970  if (selected_component) {
972 
973  if (ship)
975  }
976 }
977 
978 void
980 {
981  selected_repair = 0;
982 
985 
986  if (repair_queue) {
987  int n = repair_queue->GetSelection();
988 
989  if (n >= 0)
991  }
992 
993  if (!selected_repair)
994  return;
995 
998 
999  if (components) {
1001 
1002  if (repair) repair->SetEnabled(false);
1003  if (replace) replace->SetEnabled(false);
1004  if (repair_time) repair_time->Hide();
1005  if (replace_time) replace_time->Hide();
1006 
1007  if (selected_repair->GetComponents().size()) {
1008  int index = 0;
1010  while (++comp)
1012  }
1013  }
1014 
1017 }
1018 
1019 void
1021 {
1022  if (ship && repair_queue)
1024 }
1025 
1026 void
1028 {
1029  if (ship && repair_queue)
1031 }
1032 
1033 // +--------------------------------------------------------------------+
1034 
1035 void
1037 {
1038  if (manager)
1039  manager->CloseTopmost();
1040 }
1041 
1042 
1043