Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TacRefDlg.cpp
Go to the documentation of this file.
1 /* Project Starshatter 5.0
2  Destroyer Studios LLC
3  Copyright © 1997-2007. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: TacRefDlg.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Tactical Reference Dialog Active Window class
13 */
14 
15 #include "MemDebug.h"
16 #include "TacRefDlg.h"
17 #include "MenuScreen.h"
18 #include "Campaign.h"
19 #include "Mission.h"
20 #include "Ship.h"
21 #include "ShipDesign.h"
22 #include "WeaponDesign.h"
23 #include "WeaponGroup.h"
24 
25 #include "Game.h"
26 #include "EventDispatch.h"
27 #include "Mouse.h"
28 #include "Button.h"
29 #include "ListBox.h"
30 #include "Slider.h"
31 #include "ParseUtil.h"
32 #include "FormatUtil.h"
33 #include "Light.h"
34 #include "Solid.h"
35 
36 // +--------------------------------------------------------------------+
37 // DECLARE MAPPING FUNCTIONS:
38 DEF_MAP_CLIENT(TacRefDlg, OnClose);
39 DEF_MAP_CLIENT(TacRefDlg, OnSelect);
40 DEF_MAP_CLIENT(TacRefDlg, OnMode);
41 DEF_MAP_CLIENT(TacRefDlg, OnCamRButtonDown);
42 DEF_MAP_CLIENT(TacRefDlg, OnCamRButtonUp);
43 DEF_MAP_CLIENT(TacRefDlg, OnCamMove);
44 DEF_MAP_CLIENT(TacRefDlg, OnCamZoom);
45 
46 // +--------------------------------------------------------------------+
47 
49 : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr),
50 beauty(0), camview(0), imgview(0),
51 txt_caption(0), txt_stats(0), txt_description(0),
52 lst_designs(0), btn_close(0), btn_ships(0), btn_weaps(0),
53 mode(MODE_NONE), radius(100), mouse_x(0), mouse_y(0),
54 cam_zoom(2.5), cam_az(-PI/6), cam_el(PI/7), captured(false),
55 ship_index(0), weap_index(0)
56 {
57  Init(def);
58 }
59 
61 {
62  if (beauty) {
65  }
66 
67  delete camview;
68  delete imgview;
69 }
70 
71 // +--------------------------------------------------------------------+
72 
73 void
75 {
77  btn_ships = (Button*) FindControl(101);
78  btn_weaps = (Button*) FindControl(102);
80  txt_caption = FindControl(301);
81  beauty = FindControl(401);
84 
85  if (btn_close) {
87  }
88 
89  if (btn_ships) {
92  }
93 
94  if (btn_weaps) {
97  }
98 
99  if (lst_designs) {
101  }
102 
103  if (beauty) {
108 
109  scene.SetAmbient(Color(60,60,60));
110 
111  Point light_pos(3e6, 5e6, 4e6);
112 
113  Light* main_light = new Light(1.0f); //1.25f);
114  main_light->MoveTo(light_pos);
115  main_light->SetType(Light::LIGHT_DIRECTIONAL);
116  main_light->SetColor(Color::White);
117  main_light->SetShadow(true);
118 
119  scene.AddLight(main_light);
120 
121  Light* back_light = new Light(0.5f);
122  back_light->MoveTo(light_pos * -1);
123  back_light->SetType(Light::LIGHT_DIRECTIONAL);
124  back_light->SetColor(Color::White);
125  back_light->SetShadow(false);
126 
127  scene.AddLight(back_light);
128 
129  camview = new(__FILE__,__LINE__) CameraView(beauty, &cam, &scene);
132 
134 
135  imgview = new(__FILE__,__LINE__) ImgView(beauty, 0);
137  }
138 }
139 
140 // +--------------------------------------------------------------------+
141 
142 void
144 {
145  update_scene = !shown;
146 
148 
149  if (update_scene) {
151  OnMode(&event);
152  }
153 }
154 
155 struct WepGroup {
156  Text name;
157  int count;
158 
159  WepGroup() : count(0) { }
160 };
161 WepGroup* FindWepGroup(WepGroup* weapons, const char* name);
162 
163 
164 void
166 {
167  if (beauty && camview) {
168  scene.Graphics().clear();
169 
170  if (design) {
171  radius = design->radius;
172 
173  UpdateCamera();
174 
175  int level = design->lod_levels-1;
176  int n = design->models[level].size();
177 
178  for (int i = 0; i < n; i++) {
179  Model* model = design->models[level].at(i);
180 
181  Solid* s = new(__FILE__,__LINE__) Solid;
182  s->UseModel(model);
183  s->CreateShadows(1);
184  s->MoveTo(*design->offsets[level].at(i));
185 
186  scene.Graphics().append(s);
187  }
188  }
189  }
190 
191  if (txt_caption) {
192  txt_caption->SetText("");
193 
194  if (design) {
195  char txt[256];
196  sprintf_s(txt, "%s %s", design->abrv, design->DisplayName());
197  txt_caption->SetText(txt);
198  }
199  }
200 
201  if (txt_stats) {
202  txt_stats->SetText("");
203 
204  if (design) {
205  Text desc;
206  char txt[256];
207 
208  sprintf_s(txt, "%s\t\t\t%s\n", Game::GetText("tacref.type").data(), Ship::ClassName(design->type));
209  desc += txt;
210 
211  sprintf_s(txt, "%s\t\t\t%s\n", Game::GetText("tacref.class").data(), design->DisplayName());
212  desc += txt;
213  desc += Game::GetText("tacref.length");
214  desc += "\t\t";
215 
216  if (design->type < Ship::STATION)
217  FormatNumber(txt, design->radius/2);
218  else
219  FormatNumber(txt, design->radius*2);
220 
221  strcat_s(txt, " m\n");
222  desc += txt;
223  desc += Game::GetText("tacref.mass");
224  desc += "\t\t\t";
225 
226  FormatNumber(txt, design->mass);
227  strcat_s(txt, " T\n");
228  desc += txt;
229  desc += Game::GetText("tacref.hull");
230  desc += "\t\t\t";
231 
232  FormatNumber(txt, design->integrity);
233  strcat_s(txt, "\n");
234  desc += txt;
235 
236  if (design->weapons.size()) {
237  desc += Game::GetText("tacref.weapons");
238 
239  WepGroup groups[8];
240  for (int w = 0; w < design->weapons.size(); w++) {
241  Weapon* gun = design->weapons[w];
242  WepGroup* group = FindWepGroup(groups, gun->Group());
243 
244  if (group)
245  group->count++;
246  }
247 
248  for (int g = 0; g < 8; g++) {
249  WepGroup* group = &groups[g];
250  if (group && group->count) {
251  sprintf_s(txt, "\t\t%s (%d)\n\t\t", group->name.data(), group->count);
252  desc += txt;
253 
254  for (int w = 0; w < design->weapons.size(); w++) {
255  Weapon* gun = design->weapons[w];
256 
257  if (group->name == gun->Group()) {
258  sprintf_s(txt, "\t\t\t%s\n\t\t", (const char*) gun->Design()->name);
259  desc += txt;
260  }
261  }
262  }
263  }
264 
265  desc += "\n";
266  }
267 
268  txt_stats->SetText(desc);
269  }
270  }
271 
272  if (txt_description) {
273  if (design && design->description.length()) {
275  }
276  else {
277  txt_description->SetText(Game::GetText("tacref.mass"));
278  }
279  }
280 }
281 
282 // +--------------------------------------------------------------------+
283 
284 void
286 {
287  if (beauty && imgview) {
288  imgview->SetPicture(0);
289 
290  if (design)
291  imgview->SetPicture(design->beauty_img);
292  }
293 
294  if (txt_caption) {
295  txt_caption->SetText("");
296 
297  if (design)
298  txt_caption->SetText(design->name);
299  }
300 
301  if (txt_stats) {
302  txt_stats->SetText("");
303 
304  if (design) {
305  Text desc;
306  char txt[256];
307 
308  desc = Game::GetText("tacref.name");
309  desc += "\t";
310  desc += design->name;
311  desc += "\n";
312  desc += Game::GetText("tacref.type");
313  desc += "\t\t";
314 
315  if (design->damage < 1)
316  desc += Game::GetText("tacref.wep.other");
317  else if (design->beam)
318  desc += Game::GetText("tacref.wep.beam");
319  else if (design->primary)
320  desc += Game::GetText("tacref.wep.bolt");
321  else if (design->drone)
322  desc += Game::GetText("tacref.wep.drone");
323  else if (design->guided)
324  desc += Game::GetText("tacref.wep.guided");
325  else
326  desc += Game::GetText("tacref.wep.missile");
327 
328  if (design->turret_model && design->damage >= 1) {
329  desc += " ";
330  desc += Game::GetText("tacref.wep.turret");
331  desc += "\n";
332  }
333  else {
334  desc += "\n";
335  }
336 
337  desc += Game::GetText("tacref.targets");
338  desc += "\t";
339 
340  if ((design->target_type & Ship::DROPSHIPS) != 0) {
341  if ((design->target_type & Ship::STARSHIPS) != 0) {
342  if ((design->target_type & Ship::GROUND_UNITS) != 0) {
343  desc += Game::GetText("tacref.targets.fsg");
344  }
345  else {
346  desc += Game::GetText("tacref.targets.fs");
347  }
348  }
349  else {
350  if ((design->target_type & Ship::GROUND_UNITS) != 0) {
351  desc += Game::GetText("tacref.targets.fg");
352  }
353  else {
354  desc += Game::GetText("tacref.targets.f");
355  }
356  }
357  }
358 
359  else if ((design->target_type & Ship::STARSHIPS) != 0) {
360  if ((design->target_type & Ship::GROUND_UNITS) != 0) {
361  desc += Game::GetText("tacref.targets.sg");
362  }
363  else {
364  desc += Game::GetText("tacref.targets.s");
365  }
366  }
367 
368  else if ((design->target_type & Ship::GROUND_UNITS) != 0) {
369  desc += Game::GetText("tacref.targets.g");
370  }
371 
372  desc += "\n";
373  desc += Game::GetText("tacref.speed");
374  desc += "\t";
375 
376  FormatNumber(txt, design->speed);
377  desc += txt;
378  desc += "m/s\n";
379  desc += Game::GetText("tacref.range");
380  desc += "\t";
381 
382  FormatNumber(txt, design->max_range);
383  desc += txt;
384  desc += "m\n";
385  desc += Game::GetText("tacref.damage");
386  desc += "\t";
387 
388  if (design->damage > 0) {
389  FormatNumber(txt, design->damage * design->charge);
390  desc += txt;
391  if (design->beam)
392  desc += "/s";
393  }
394  else {
395  desc += Game::GetText("tacref.none");
396  }
397 
398  desc += "\n";
399 
400  if (!design->primary && design->damage > 0) {
401  desc += Game::GetText("tacref.kill-radius");
402  desc += "\t";
403  FormatNumber(txt, design->lethal_radius);
404  desc += txt;
405  desc += " m\n";
406  }
407 
408  txt_stats->SetText(desc);
409  }
410  }
411 
412  if (txt_description) {
413  if (design && design->description.length()) {
415  }
416  else {
417  txt_description->SetText(Game::GetText("tacref.no-info"));
418  }
419  }
420 }
421 
422 // +--------------------------------------------------------------------+
423 
424 void
426 {
427 }
428 
429 // +--------------------------------------------------------------------+
430 
431 bool
433 {
435  if (dispatch && beauty)
436  return dispatch->CaptureMouse(beauty) ? true : false;
437 
438  return 0;
439 }
440 
441 bool
443 {
445  if (dispatch && beauty)
446  return dispatch->ReleaseMouse(beauty) ? true : false;
447 
448  return 0;
449 }
450 
451 // +--------------------------------------------------------------------+
452 
453 void
455 {
456  cam_az += a;
457 
458  if (cam_az > PI)
459  cam_az = -2*PI + cam_az;
460 
461  else if (cam_az < -PI)
462  cam_az = 2*PI + cam_az;
463 }
464 
465 void
467 {
468  cam_el += e;
469 
470  const double limit = (0.43 * PI);
471 
472  if (cam_el > limit)
473  cam_el = limit;
474  else if (cam_el < -limit)
475  cam_el = -limit;
476 }
477 
478 void
480 {
481  cam_zoom *= delta;
482 
483  if (cam_zoom < 1.2)
484  cam_zoom = 1.2;
485 
486  else if (cam_zoom > 10)
487  cam_zoom = 10;
488 }
489 
490 void
492 {
493  double x = cam_zoom * radius * sin(cam_az) * cos(cam_el);
494  double y = cam_zoom * radius * cos(cam_az) * cos(cam_el);
495  double z = cam_zoom * radius * sin(cam_el);
496 
497  cam.LookAt(Point(0,0,0), Point(x,z,y), Point(0,1,0));
498 }
499 
500 // +--------------------------------------------------------------------+
501 
502 void
504 {
505  if (lst_designs) {
506  int seln = lst_designs->GetSelection();
507  DWORD dsn = lst_designs->GetItemData(seln);
508 
509  if (mode == MODE_SHIPS) {
510  ship_index = seln;
511 
512  if (dsn) {
513  SelectShip((ShipDesign*) dsn);
514  }
515  }
516 
517  else if (mode == MODE_WEAPONS) {
518  weap_index = seln;
519 
520  if (dsn) {
521  SelectWeapon((WeaponDesign*) dsn);
522  }
523  }
524  }
525 }
526 
527 // +--------------------------------------------------------------------+
528 
529 void
531 {
533  mouse_x = event->x;
534  mouse_y = event->y;
535 }
536 
537 void
539 {
540  if (captured)
542 
543  captured = false;
544  mouse_x = 0;
545  mouse_y = 0;
546 }
547 
548 void
550 {
551  if (captured) {
552  int mouse_dx = event->x - mouse_x;
553  int mouse_dy = event->y - mouse_y;
554 
555  UpdateAzimuth( mouse_dx * 0.3 * DEGREES);
556  UpdateElevation( mouse_dy * 0.3 * DEGREES);
557  UpdateCamera();
558 
559  mouse_x = event->x;
560  mouse_y = event->y;
561  }
562 }
563 
564 void
566 {
567  int w = Mouse::Wheel();
568 
569  if (w < 0) {
570  while (w < 0) {
571  UpdateZoom(1.25);
572  w += 120;
573  }
574  }
575  else {
576  while (w > 0) {
577  UpdateZoom(0.75f);
578  w -= 120;
579  }
580  }
581 
582  UpdateCamera();
583 }
584 
585 // +--------------------------------------------------------------------+
586 
587 void
589 {
590  if (event->window == btn_ships && mode != MODE_SHIPS) {
591  mode = MODE_SHIPS;
592 
593  if (lst_designs) {
595 
596  List<Text> designs;
597 
598  for (int n = 0; n < 16; n++) {
599  int type = 1 << n;
600  ShipDesign::GetDesignList(type, designs);
601 
602  ListIter<Text> iter = designs;
603  while (++iter) {
604  Text* val = iter.value();
605 
606  const ShipDesign* dsn = ShipDesign::Get(*val);
607 
608  if (dsn) {
609  char txt[256];
610  sprintf_s(txt, "%s %s", dsn->abrv, dsn->DisplayName());
611 
612  lst_designs->AddItemWithData(txt, (DWORD) dsn);
613  }
614  else {
615  lst_designs->AddItemWithData(*val, 0);
616  }
617  }
618  }
619 
621  }
622 
623  if (beauty) {
626  }
627 
628  DWORD dsn = lst_designs->GetItemData(ship_index);
629 
630  if (dsn) {
631  SelectShip((ShipDesign*) dsn);
632  }
633  }
634 
635  else if (event->window == btn_weaps && mode != MODE_WEAPONS) {
636  mode = MODE_WEAPONS;
637 
638  const WeaponDesign* design = 0;
639 
640  if (lst_designs) {
642  List<Text> designs;
643 
645 
646  ListIter<Text> iter = designs;
647  while (++iter) {
648  Text* val = iter.value();
649 
650  if (val->contains("Zolon") || val->contains("Inverted"))
651  continue;
652 
653  const WeaponDesign* dsn = WeaponDesign::Find(*val);
654 
655  if (dsn && !dsn->secret) {
656  lst_designs->AddItemWithData(*val, (DWORD) dsn);
657 
658  if (!design)
659  design = dsn;
660  }
661  }
662 
664  }
665 
666  if (beauty) {
669  }
670 
671  DWORD dsn = lst_designs->GetItemData(weap_index);
672 
673  if (dsn) {
674  SelectWeapon((WeaponDesign*) dsn);
675  }
676  }
677 
680 }
681 
682 // +--------------------------------------------------------------------+
683 
684 void
686 {
687  manager->ShowMenuDlg();
688 }
689