From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_map_view_8cpp_source.html | 3595 +++++++++++++++++++++++++++ 1 file changed, 3595 insertions(+) create mode 100644 Doc/doxygen/html/_map_view_8cpp_source.html (limited to 'Doc/doxygen/html/_map_view_8cpp_source.html') diff --git a/Doc/doxygen/html/_map_view_8cpp_source.html b/Doc/doxygen/html/_map_view_8cpp_source.html new file mode 100644 index 0000000..d04b1bf --- /dev/null +++ b/Doc/doxygen/html/_map_view_8cpp_source.html @@ -0,0 +1,3595 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/MapView.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
MapView.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: MapView.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Star Map class
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "MapView.h"
+
17 
+
18 #include "Galaxy.h"
+
19 #include "StarSystem.h"
+
20 #include "Ship.h"
+
21 #include "ShipDesign.h"
+
22 #include "Instruction.h"
+
23 #include "Element.h"
+
24 #include "NavAI.h"
+
25 #include "Weapon.h"
+
26 #include "Sim.h"
+
27 #include "Mission.h"
+
28 #include "Campaign.h"
+
29 #include "Combatant.h"
+
30 #include "CombatGroup.h"
+
31 #include "CombatUnit.h"
+
32 #include "Contact.h"
+
33 #include "MenuView.h"
+
34 
+
35 #include "NetLobby.h"
+
36 #include "NetUtil.h"
+
37 
+
38 #include "Game.h"
+
39 #include "DataLoader.h"
+
40 #include "EventDispatch.h"
+
41 #include "Video.h"
+
42 #include "Button.h"
+
43 #include "Bitmap.h"
+
44 #include "Font.h"
+
45 #include "FontMgr.h"
+
46 #include "Mouse.h"
+
47 #include "FormatUtil.h"
+
48 #include "Menu.h"
+
49 
+
50 // +--------------------------------------------------------------------+
+
51 
+
52 // Supported Selection Modes:
+
53 
+
54 const int SELECT_NONE = -1;
+
55 const int SELECT_SYSTEM = 0;
+
56 const int SELECT_PLANET = 1;
+
57 const int SELECT_REGION = 2;
+
58 const int SELECT_STATION = 3;
+
59 const int SELECT_STARSHIP = 4;
+
60 const int SELECT_FIGHTER = 5;
+
61 const int SELECT_NAVPT = 6;
+
62 
+
63 const int VIEW_GALAXY = 0;
+
64 const int VIEW_SYSTEM = 1;
+
65 const int VIEW_REGION = 2;
+
66 
+
67 // +--------------------------------------------------------------------+
+
68 
+ +
70 : View(win)
+
71 , system(0), zoom(1.1), offset_x(0), offset_y(0), ship(0), campaign(0)
+
72 , captured(false), dragging(false), adding_navpt(false)
+
73 , moving_navpt(false), moving_elem(false)
+
74 , view_mode(VIEW_SYSTEM), seln_mode(SELECT_REGION), ship_filter(0xffffffff)
+
75 , current_star(0), current_planet(0), current_region(0)
+
76 , current_ship(0), current_elem(0), current_navpt(0), mission(0)
+
77 , scrolling(0), scroll_x(0), scroll_y(0), click_x(0), click_y(0)
+
78 , active_menu(0), map_menu(0), map_system_menu(0), map_sector_menu(0)
+
79 , ship_menu(0), editor(false)
+
80 , nav_menu(0), action_menu(0), objective_menu(0), formation_menu(0), speed_menu(0)
+
81 , hold_menu(0), farcast_menu(0), menu_view(0)
+
82 {
+
83  for (int i = 0; i < 3; i++) {
+
84  view_zoom[i] = zoom;
+ + +
87  }
+
88 
+
89  menu_view = new(__FILE__,__LINE__) MenuView(window);
+
90 
+
91  title_font = FontMgr::Find("Limerick12");
+
92  font = FontMgr::Find("Verdana");
+
93 
+ +
95 
+
96  if (active_window)
+
97  active_window->AddView(this);
+
98 }
+
99 
+
100 // +--------------------------------------------------------------------+
+
101 
+ +
103 {
+
104  ClearMenu();
+ +
106 
+
107  delete menu_view;
+
108 }
+
109 
+
110 // +--------------------------------------------------------------------+
+
111 
+
112 void
+ +
114 {
+
115  if (menu_view)
+ +
117 }
+
118 
+
119 // +--------------------------------------------------------------------+
+
120 
+
121 void
+ +
123 {
+
124  system_list.clear();
+
125  system_list.append(g);
+
126 
+
127  if (system_list.size() > 0) {
+ +
129  }
+
130 }
+
131 
+
132 void
+ +
134 {
+
135  if (system != s) {
+
136  system = s;
+
137 
+
138  // forget invalid selection:
+
139  current_star = 0;
+
140  current_planet = 0;
+
141  current_region = 0;
+
142  current_ship = 0;
+
143  current_elem = 0;
+
144  current_navpt = 0;
+
145 
+
146  // flush old object pointers:
+
147  stars.clear();
+
148  planets.clear();
+
149  regions.clear();
+
150 
+
151  // insert objects from star system:
+
152  if (system) {
+ +
154  while (++star) {
+
155  switch (star->Type()) {
+
156  case Orbital::STAR: stars.append(star.value());
+
157  break;
+
158  case Orbital::PLANET:
+
159  case Orbital::MOON: planets.append(star.value());
+
160  break;
+
161  }
+
162  }
+
163 
+
164  ListIter<OrbitalBody> planet = star->Satellites();
+
165  while (++planet) {
+
166  planets.append(planet.value());
+
167 
+
168  ListIter<OrbitalBody> moon = planet->Satellites();
+
169  while (++moon) {
+
170  planets.append(moon.value());
+
171  }
+
172  }
+
173 
+ +
175  while (++rgn)
+
176  regions.append(rgn.value());
+
177 
+
178  // sort region list by distance from the star:
+
179  regions.sort();
+
180  }
+
181 
+
182  BuildMenu();
+
183  }
+
184 }
+
185 
+
186 // +--------------------------------------------------------------------+
+
187 
+
188 void
+ +
190 {
+
191  if (ship != s) {
+
192  ship = s;
+
193 
+
194  // forget invalid selection:
+
195  current_star = 0;
+
196  current_planet = 0;
+
197  current_region = 0;
+
198  current_ship = 0;
+
199  current_elem = 0;
+
200  current_navpt = 0;
+
201 
+
202  if (ship && system_list.size() > 0) {
+
203  SimRegion* rgn = ship->GetRegion();
+
204 
+
205  if (rgn && rgn->System()) {
+
206  system = 0;
+
207  SetSystem(rgn->System());
+
208  }
+
209  }
+
210 
+
211  BuildMenu();
+
212  }
+
213 }
+
214 
+
215 // +--------------------------------------------------------------------+
+
216 
+
217 void
+ +
219 {
+
220  if (mission != m) {
+
221  mission = m;
+
222 
+
223  // forget invalid selection:
+
224  current_star = 0;
+
225  current_planet = 0;
+
226  current_region = 0;
+
227  current_ship = 0;
+
228  current_elem = 0;
+
229  current_navpt = 0;
+
230 
+
231  if (mission && system_list.size() > 0) {
+
232  system = 0;
+ +
234  }
+
235 
+
236  BuildMenu();
+
237  }
+
238 }
+
239 
+
240 // +--------------------------------------------------------------------+
+
241 
+
242 void
+ +
244 {
+
245  if (campaign != c) {
+
246  campaign = c;
+
247 
+
248  // forget invalid selection:
+
249  current_star = 0;
+
250  current_planet = 0;
+
251  current_region = 0;
+
252  current_ship = 0;
+
253  current_elem = 0;
+
254  current_navpt = 0;
+
255 
+
256  if (campaign)
+ +
258  }
+
259 }
+
260 
+
261 // +--------------------------------------------------------------------+
+
262 
+ +
264  MAP_SYSTEM = 1000,
+
265  MAP_SECTOR = 2000,
+
266  MAP_SHIP = 3000,
+
267  MAP_NAV = 4000,
+
268  MAP_ADDNAV = 4001,
+
269  MAP_DELETE = 4002,
+
270  MAP_CLEAR = 4003,
+
271  MAP_ACTION = 5000,
+ +
273  MAP_SPEED = 7000,
+
274  MAP_HOLD = 8000,
+
275  MAP_FARCAST = 8500,
+ +
277 };
+
278 
+
279 void
+ +
281 {
+
282  ClearMenu();
+
283 
+
284  map_system_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.STARSYSTEM"));
+
285 
+
286  if (system_list.size() > 0) {
+
287  int i = 0;
+ +
289  while (++iter) {
+
290  StarSystem* s = iter.value();
+ +
292  i++;
+
293  }
+
294  }
+
295 
+
296  else if (system) {
+ +
298  }
+
299 
+
300  map_sector_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.SECTOR"));
+
301  for (int i = 0; i < regions.size(); i++) {
+
302  Orbital* rgn = regions[i];
+
303  map_sector_menu->AddItem(rgn->Name(), MAP_SECTOR + i);
+
304  }
+
305 
+
306  map_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.MAP"));
+
307  map_menu->AddMenu("System", map_system_menu);
+
308  map_menu->AddMenu("Sector", map_sector_menu);
+
309 
+
310  if (ship || mission) {
+
311  ship_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.SHIP"));
+
312  ship_menu->AddMenu(Game::GetText("MapView.item.Starsystem"), map_system_menu);
+
313  ship_menu->AddMenu(Game::GetText("MapView.item.Sector"), map_sector_menu);
+
314 
+
315  ship_menu->AddItem("", 0);
+
316  ship_menu->AddItem(Game::GetText("MapView.item.Add-Nav"), MAP_ADDNAV);
+
317  ship_menu->AddItem(Game::GetText("MapView.item.Clear-All"), MAP_CLEAR);
+
318 
+
319  action_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.ACTION"));
+
320  for (int i = 0; i < Instruction::NUM_ACTIONS; i++) {
+ +
322  }
+
323 
+
324  formation_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.FORMATION"));
+
325  for (int i = 0; i < Instruction::NUM_FORMATIONS; i++) {
+ +
327  }
+
328 
+
329  speed_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.SPEED"));
+
330  speed_menu->AddItem("250", MAP_SPEED + 0);
+
331  speed_menu->AddItem("500", MAP_SPEED + 1);
+
332  speed_menu->AddItem("750", MAP_SPEED + 2);
+
333  speed_menu->AddItem("1000", MAP_SPEED + 3);
+
334 
+
335  hold_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.HOLD"));
+
336  hold_menu->AddItem(Game::GetText("MapView.item.None"), MAP_HOLD + 0);
+
337  hold_menu->AddItem(Game::GetText("MapView.item.1-Minute"), MAP_HOLD + 1);
+
338  hold_menu->AddItem(Game::GetText("MapView.item.5-Minutes"), MAP_HOLD + 2);
+
339  hold_menu->AddItem(Game::GetText("MapView.item.10-Minutes"), MAP_HOLD + 3);
+
340  hold_menu->AddItem(Game::GetText("MapView.item.15-Minutes"), MAP_HOLD + 4);
+
341 
+
342  farcast_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.FARCAST"));
+
343  farcast_menu->AddItem(Game::GetText("MapView.item.Use-Quantum"), MAP_FARCAST + 0);
+
344  farcast_menu->AddItem(Game::GetText("MapView.item.Use-Farcast"), MAP_FARCAST + 1);
+
345 
+
346  objective_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.OBJECTIVE"));
+
347 
+
348  nav_menu = new(__FILE__,__LINE__) Menu(Game::GetText("MapView.menu.NAVPT"));
+
349  nav_menu->AddMenu(Game::GetText("MapView.item.Action"), action_menu);
+
350  nav_menu->AddMenu(Game::GetText("MapView.item.Objective"), objective_menu);
+
351  nav_menu->AddMenu(Game::GetText("MapView.item.Formation"), formation_menu);
+
352  nav_menu->AddMenu(Game::GetText("MapView.item.Speed"), speed_menu);
+
353  nav_menu->AddMenu(Game::GetText("MapView.item.Hold"), hold_menu);
+
354  nav_menu->AddMenu(Game::GetText("MapView.item.Farcast"), farcast_menu);
+
355  nav_menu->AddItem("", 0);
+
356  nav_menu->AddItem(Game::GetText("MapView.item.Add-Nav"), MAP_ADDNAV);
+
357  nav_menu->AddItem(Game::GetText("MapView.item.Del-Nav"), MAP_DELETE);
+
358  }
+
359 
+
360  else if (campaign) {
+
361  ship_menu = 0;
+
362  speed_menu = 0;
+
363  hold_menu = 0;
+
364  farcast_menu = 0;
+
365  objective_menu = 0;
+
366  formation_menu = 0;
+
367  nav_menu = 0;
+
368  }
+
369 
+ +
371 }
+
372 
+
373 // +--------------------------------------------------------------------+
+
374 
+
375 void
+ +
377 {
+
378  delete map_menu;
+
379  delete map_system_menu;
+
380  delete map_sector_menu;
+
381  delete ship_menu;
+
382  delete nav_menu;
+
383  delete action_menu;
+
384  delete objective_menu;
+
385  delete formation_menu;
+
386  delete speed_menu;
+
387  delete hold_menu;
+
388  delete farcast_menu;
+
389 
+
390  map_menu = 0;
+
391  map_system_menu = 0;
+
392  map_sector_menu = 0;
+
393  ship_menu = 0;
+
394  nav_menu = 0;
+
395  action_menu = 0;
+
396  objective_menu = 0;
+
397  formation_menu = 0;
+
398  speed_menu = 0;
+
399  hold_menu = 0;
+
400  farcast_menu = 0;
+
401 }
+
402 
+
403 // +--------------------------------------------------------------------+
+
404 
+
405 void
+ +
407 {
+
408  bool send_nav_data = false;
+
409  bool can_command = true;
+
410 
+
411  if (ship && current_ship && ship != current_ship) {
+
412  if (ship->GetElement() && current_ship->GetElement()) {
+ +
414  can_command = false;
+
415  }
+
416  }
+
417  }
+
418 
+
419  else if (current_elem && NetLobby::GetInstance()) {
+
420  can_command = false;
+
421  }
+
422 
+
423  if (action >= MAP_OBJECTIVE) {
+
424  int index = action - MAP_OBJECTIVE;
+
425 
+
426  if (current_navpt && can_command) {
+ +
428  send_nav_data = true;
+
429  }
+
430  }
+
431 
+
432  else if (action >= MAP_FARCAST) {
+
433  if (current_navpt && can_command) {
+ +
435  send_nav_data = true;
+
436  }
+
437  }
+
438 
+
439  else if (action >= MAP_HOLD) {
+
440  int hold_time = 0;
+
441  switch (action) {
+
442  default:
+
443  case MAP_HOLD + 0: hold_time = 0; break;
+
444  case MAP_HOLD + 1: hold_time = 60; break;
+
445  case MAP_HOLD + 2: hold_time = 300; break;
+
446  case MAP_HOLD + 3: hold_time = 600; break;
+
447  case MAP_HOLD + 4: hold_time = 900; break;
+
448  }
+
449 
+
450  if (current_navpt && can_command) {
+
451  current_navpt->SetHoldTime(hold_time);
+
452  send_nav_data = true;
+
453  }
+
454  }
+
455 
+
456  else if (action >= MAP_SPEED) {
+
457  if (current_navpt && can_command) {
+
458  current_navpt->SetSpeed((action - MAP_SPEED + 1) * 250);
+
459  send_nav_data = true;
+
460  }
+
461  }
+
462 
+
463  else if (action >= MAP_FORMATION) {
+
464  if (current_navpt && can_command) {
+ +
466  send_nav_data = true;
+
467  }
+
468  }
+
469 
+
470  else if (action >= MAP_ACTION) {
+
471  if (current_navpt && can_command) {
+ + +
474  send_nav_data = true;
+
475  }
+
476  }
+
477 
+
478  else if (action == MAP_ADDNAV) {
+
479  Text rgn_name = regions[current_region]->Name();
+
480  Instruction* prior = current_navpt;
+
481  Instruction* n = 0;
+
482 
+
483  if (current_ship && can_command) {
+
484  Sim* sim = Sim::GetSim();
+
485  SimRegion* rgn = sim->FindRegion(rgn_name);
+
486  Point init_pt;
+
487 
+
488  if (rgn) {
+
489  if (rgn->IsAirSpace())
+
490  init_pt.z = 10e3;
+
491 
+
492  n = new(__FILE__,__LINE__) Instruction(rgn, init_pt);
+
493  }
+
494  else {
+
495  n = new(__FILE__,__LINE__) Instruction(rgn_name, init_pt);
+
496  }
+
497 
+
498  n->SetSpeed(500);
+
499 
+
500  if (prior) {
+
501  n->SetAction(prior->Action());
+
502  n->SetFormation(prior->Formation());
+
503  n->SetSpeed(prior->Speed());
+
504  n->SetTarget(prior->GetTarget());
+
505  }
+
506 
+
507  current_ship->AddNavPoint(n, prior);
+
508  }
+
509 
+
510  else if (current_elem && can_command) {
+
511  Point init_pt;
+
512 
+
513  if (regions[current_region]->Type() == Orbital::TERRAIN)
+
514  init_pt.z = 10e3;
+
515 
+
516  n = new(__FILE__,__LINE__) Instruction(rgn_name, init_pt);
+
517  n->SetSpeed(500);
+
518 
+
519  if (prior) {
+
520  n->SetAction(prior->Action());
+
521  n->SetFormation(prior->Formation());
+
522  n->SetSpeed(prior->Speed());
+
523  n->SetTarget(prior->GetTarget());
+
524  }
+
525 
+
526  current_elem->AddNavPoint(n, prior);
+
527  }
+
528 
+
529  if (can_command) {
+
530  current_navpt = n;
+ +
532  adding_navpt = true;
+
533  captured = SetCapture();
+
534  }
+
535  }
+
536 
+
537  else if (action == MAP_DELETE) {
+
538  if (current_navpt && can_command) {
+
539  if (current_ship)
+ +
541  else if (current_elem && can_command)
+ +
543 
+
544  SelectNavpt(0);
+
545  }
+
546  }
+
547 
+
548  else if (action == MAP_CLEAR) {
+
549  if (current_ship && can_command)
+ +
551  else if (current_elem && can_command)
+ +
553 
+
554  SelectNavpt(0);
+
555  }
+
556 
+
557  else if (action >= MAP_NAV) {
+
558  }
+
559 
+
560  else if (action >= MAP_SHIP) {
+
561  }
+
562 
+
563  else if (action >= MAP_SECTOR) {
+
564  int index = action - MAP_SECTOR;
+
565 
+
566  if (index < regions.size())
+
567  current_region = index;
+
568 
+
569  if (view_mode == VIEW_SYSTEM) {
+ +
571  SetupScroll(s);
+
572  }
+
573  }
+
574 
+
575  else if (system_list.size() > 0 && action >= MAP_SYSTEM) {
+
576  int index = action - MAP_SYSTEM;
+
577 
+
578  if (index < system_list.size())
+
579  SetSystem(system_list[index]);
+
580  }
+
581 
+
582  else {
+
583  }
+
584 
+
585  Sim* sim = Sim::GetSim();
+
586  if (send_nav_data && sim) {
+
587  Ship* s = current_ship;
+
588 
+
589  if (s && s->GetElement()) {
+
590  Element* elem = s->GetElement();
+
591  int index = elem->GetNavIndex(current_navpt);
+
592 
+
593  if (index >= 0)
+
594  NetUtil::SendNavData(false, elem, index-1, current_navpt);
+
595  }
+
596  }
+
597 }
+
598 
+
599 // +--------------------------------------------------------------------+
+
600 
+
601 bool
+ +
603 {
+ +
605  if (dispatch)
+
606  return dispatch->CaptureMouse(this) ? true : false;
+
607 
+
608  return 0;
+
609 }
+
610 
+
611 // +--------------------------------------------------------------------+
+
612 
+
613 bool
+ +
615 {
+ +
617  if (dispatch)
+
618  return dispatch->ReleaseMouse(this) ? true : false;
+
619 
+
620  return 0;
+
621 }
+
622 
+
623 // +--------------------------------------------------------------------+
+
624 
+
625 void
+ +
627 {
+
628  if (mode >= 0 && mode < 3) {
+
629  // save state:
+ + + +
633 
+
634  // switch mode:
+
635  view_mode = mode;
+
636 
+
637  // restore state:
+
638 
+
639  if (view_mode == VIEW_GALAXY) {
+
640  zoom = 1;
+
641  offset_x = 0;
+
642  offset_y = 0;
+
643  }
+
644  else {
+ + + +
648  }
+
649 
+
650  scrolling = 0;
+
651  scroll_x = 0;
+
652  scroll_y = 0;
+
653  }
+
654 }
+
655 
+
656 // +--------------------------------------------------------------------+
+
657 
+
658 bool
+ +
660 {
+
661  if (obj == current_ship) {
+
662  current_ship = 0;
+ +
664  }
+
665 
+
666  return SimObserver::Update(obj);
+
667 }
+
668 
+
669 // +--------------------------------------------------------------------+
+
670 
+
671 void
+ +
673 {
+
674  if (selship != current_ship) {
+
675  current_ship = selship;
+
676 
+
677  if (current_ship) {
+
678  if (current_ship->Life() == 0 || current_ship->IsDying() || current_ship->IsDead()) {
+
679  current_ship = 0;
+
680  }
+
681  else {
+ +
683  }
+
684  }
+
685  }
+
686 
+
687  SelectNavpt(0);
+
688 }
+
689 
+
690 // +--------------------------------------------------------------------+
+
691 
+
692 void
+ +
694 {
+
695  if (elem != current_elem) {
+
696  current_elem = elem;
+
697 
+
698  if (current_elem) {
+
699  if (current_elem->IsStarship()) {
+
700  ship_menu->GetItem(3)->SetEnabled(true);
+
701  }
+
702 
+
703  else if (current_elem->IsDropship()) {
+
704  ship_menu->GetItem(3)->SetEnabled(true);
+
705  }
+
706 
+
707  else {
+
708  ship_menu->GetItem(3)->SetEnabled(false);
+
709  }
+
710  }
+
711  }
+
712 
+
713  SelectNavpt(0);
+
714 }
+
715 
+
716 // +--------------------------------------------------------------------+
+
717 
+
718 void
+ +
720 {
+
721  current_navpt = navpt;
+
722 
+
723  if (current_navpt) {
+ +
725 
+
726  List<Text> ships;
+ +
728 
+
729  switch (current_navpt->Action()) {
+
730  case Instruction::VECTOR:
+
731  case Instruction::LAUNCH:
+
732  case Instruction::PATROL:
+
733  case Instruction::SWEEP:
+
734  case Instruction::RECON:
+
735  objective_menu->AddItem(Game::GetText("MapView.item.not-available"), 0);
+
736  objective_menu->GetItem(0)->SetEnabled(false);
+
737  break;
+
738 
+
739  case Instruction::DOCK:
+
740  FindShips(true, true, true, false, ships);
+
741  break;
+
742 
+
743  case Instruction::DEFEND:
+
744  FindShips(true, true, true, false, ships);
+
745  break;
+
746 
+
747  case Instruction::ESCORT:
+
748  FindShips(true, false, true, true, ships);
+
749  break;
+
750 
+ +
752  FindShips(false, false, false, true, ships);
+
753  break;
+
754 
+ +
756  FindShips(false, false, true, false, ships);
+
757  break;
+
758 
+
759  case Instruction::STRIKE:
+
760  FindShips(false, true, false, false, ships);
+
761  break;
+
762  }
+
763 
+
764  for (int i = 0; i < ships.size(); i++)
+
765  objective_menu->AddItem(ships[i]->data(), MAP_OBJECTIVE + i);
+
766 
+
767  ships.destroy();
+
768  }
+
769  else {
+ +
771  objective_menu->AddItem(Game::GetText("MapView.item.not-available"), 0);
+
772  objective_menu->GetItem(0)->SetEnabled(false);
+
773  }
+
774 }
+
775 
+
776 // +--------------------------------------------------------------------+
+
777 
+
778 void
+
779 MapView::FindShips(bool friendly, bool station, bool starship, bool dropship,
+
780 List<Text>& result)
+
781 {
+
782  if (mission) {
+
783  for (int i = 0; i < mission->GetElements().size(); i++) {
+
784  MissionElement* elem = mission->GetElements().at(i);
+
785 
+
786  if (elem->IsSquadron()) continue;
+
787  if (!station && elem->IsStatic()) continue;
+
788  if (!starship && elem->IsStarship()) continue;
+
789  if (!dropship && elem->IsDropship()) continue;
+
790 
+
791  if (!editor && friendly && elem->GetIFF() > 0 && elem->GetIFF() != mission->Team())
+
792  continue;
+
793 
+
794  if (!editor && !friendly && (elem->GetIFF() == 0 || elem->GetIFF() == mission->Team()))
+
795  continue;
+
796 
+
797  result.append(new(__FILE__,__LINE__) Text(elem->Name()));
+
798  }
+
799  }
+
800 
+
801  else if (ship) {
+
802  Sim* sim = Sim::GetSim();
+
803 
+
804  if (sim) {
+
805  for (int r = 0; r < sim->GetRegions().size(); r++) {
+
806  SimRegion* rgn = sim->GetRegions().at(r);
+
807 
+
808  for (int i = 0; i < rgn->Ships().size(); i++) {
+
809  Ship* s = rgn->Ships().at(i);
+
810 
+
811  if (!station && s->IsStatic()) continue;
+
812  if (!starship && s->IsStarship()) continue;
+
813  if (!dropship && s->IsDropship()) continue;
+
814 
+
815  if (friendly && s->GetIFF() > 0 && s->GetIFF() != ship->GetIFF())
+
816  continue;
+
817 
+
818  if (!friendly && (s->GetIFF() == 0 || s->GetIFF() == ship->GetIFF()))
+
819  continue;
+
820 
+
821  result.append(new(__FILE__,__LINE__) Text(s->Name()));
+
822  }
+
823  }
+
824  }
+
825  }
+
826 }
+
827 
+
828 // +--------------------------------------------------------------------+
+
829 
+
830 void
+ +
832 {
+
833  if (mode <= SELECT_NONE) {
+ +
835  return;
+
836  }
+
837 
+
838  if (mode != seln_mode && mode <= SELECT_FIGHTER) {
+
839  seln_mode = mode;
+
840 
+
841  // when changing mode,
+
842  // select the item closest to the current center:
+
843  if (system && view_mode == VIEW_SYSTEM)
+
844  SelectAt(rect.x + rect.w/2,
+
845  rect.y + rect.h/2);
+
846  }
+
847 }
+
848 
+
849 void
+ +
851 {
+
852  if (scrolling) return;
+
853  Orbital* s = 0;
+
854 
+
855  switch (seln_mode) {
+
856  case SELECT_SYSTEM:
+
857  if (index < system_list.size())
+
858  SetSystem(system_list[index]);
+
859  s = stars[current_star];
+
860  break;
+
861 
+
862  default:
+
863  case SELECT_PLANET:
+
864  if (index < planets.size())
+
865  current_planet = index;
+
866  s = planets[current_planet];
+
867  break;
+
868 
+
869  case SELECT_REGION:
+
870  if (index < regions.size())
+
871  current_region = index;
+
872  s = regions[current_region];
+
873  break;
+
874 
+
875  case SELECT_STATION:
+
876  {
+
877  if (mission) {
+
878  MissionElement* selected_elem = 0;
+
879 
+ +
881  while (++elem) {
+
882  if (elem->IsStatic()) {
+
883  if (elem->Identity() == index) {
+
884  selected_elem = elem.value();
+
885  break;
+
886  }
+
887  }
+
888  }
+
889 
+
890  SelectElem(selected_elem);
+
891 
+
892  if (selected_elem && regions.size()) {
+ +
894  while (++rgn) {
+
895  if (!_stricmp(selected_elem->Region(), rgn->Name())) {
+
896  Orbital* elem_region = rgn.value();
+
897  current_region = regions.index(elem_region);
+
898  }
+
899  }
+
900  }
+
901  }
+
902 
+
903  else {
+
904  Ship* selship = 0;
+
905 
+
906  if (ship) {
+
907  SimRegion* simrgn = ship->GetRegion();
+
908  if (simrgn) {
+
909  ListIter<Ship> s = simrgn->Ships();
+
910  while (++s) {
+
911  if (s->IsStatic()) {
+
912  if (s->Identity() == index) {
+
913  selship = s.value();
+
914  break;
+
915  }
+
916  }
+
917  }
+
918  }
+
919  }
+
920 
+
921  SelectShip(selship);
+
922 
+
923  if (selship) {
+
924  s = selship->GetRegion()->GetOrbitalRegion();
+ +
926  }
+
927  }
+
928  }
+
929  break;
+
930 
+
931  case SELECT_STARSHIP:
+
932  {
+
933  if (mission) {
+
934  MissionElement* selected_elem = 0;
+
935 
+ +
937  while (++elem) {
+
938  if (elem->IsStarship()) {
+
939  if (elem->Identity() == index) {
+
940  selected_elem = elem.value();
+
941  break;
+
942  }
+
943  }
+
944  }
+
945 
+
946  SelectElem(selected_elem);
+
947 
+
948  if (selected_elem && regions.size()) {
+ +
950  while (++rgn) {
+
951  if (!_stricmp(selected_elem->Region(), rgn->Name())) {
+
952  Orbital* elem_region = rgn.value();
+
953  current_region = regions.index(elem_region);
+
954  }
+
955  }
+
956  }
+
957  }
+
958 
+
959  else {
+
960  Ship* selship = 0;
+
961 
+
962  if (ship) {
+
963  SimRegion* simrgn = ship->GetRegion();
+
964  if (simrgn) {
+
965  ListIter<Ship> s = simrgn->Ships();
+
966  while (++s) {
+
967  if (s->IsStarship()) {
+
968  if (s->Identity() == index) {
+
969  selship = s.value();
+
970  break;
+
971  }
+
972  }
+
973  }
+
974  }
+
975  }
+
976 
+
977  SelectShip(selship);
+
978 
+
979  if (selship) {
+
980  s = selship->GetRegion()->GetOrbitalRegion();
+ +
982  }
+
983  }
+
984  }
+
985  break;
+
986 
+
987  case SELECT_FIGHTER:
+
988  {
+
989  if (mission) {
+
990  MissionElement* selected_elem = 0;
+
991 
+ +
993  while (++elem) {
+
994  if (elem->IsDropship() && !elem->IsSquadron()) {
+
995  if (elem->Identity() == index) {
+
996  selected_elem = elem.value();
+
997  break;
+
998  }
+
999  }
+
1000  }
+
1001 
+
1002  SelectElem(selected_elem);
+
1003 
+
1004  if (selected_elem && regions.size()) {
+
1005  ListIter<Orbital> rgn = regions;
+
1006  while (++rgn) {
+
1007  if (!_stricmp(selected_elem->Region(), rgn->Name())) {
+
1008  Orbital* elem_region = rgn.value();
+
1009  current_region = regions.index(elem_region);
+
1010  }
+
1011  }
+
1012  }
+
1013  }
+
1014 
+
1015  else {
+
1016  Ship* selship = 0;
+
1017 
+
1018  if (ship) {
+
1019  SimRegion* simrgn = ship->GetRegion();
+
1020  if (simrgn) {
+
1021  ListIter<Ship> s = simrgn->Ships();
+
1022  while (++s) {
+
1023  if (s->IsDropship()) {
+
1024  if (s->Identity() == index) {
+
1025  selship = s.value();
+
1026  break;
+
1027  }
+
1028  }
+
1029  }
+
1030  }
+
1031  }
+
1032 
+
1033  SelectShip(selship);
+
1034 
+
1035  if (selship) {
+
1036  s = selship->GetRegion()->GetOrbitalRegion();
+ +
1038  }
+
1039  }
+
1040  }
+
1041  break;
+
1042  }
+
1043 
+
1044  SetupScroll(s);
+
1045 }
+
1046 
+
1047 void
+ +
1049 {
+
1050  if (scrolling) return;
+
1051  Orbital* s = 0;
+
1052  Ship* selship = 0;
+
1053 
+
1054 
+
1055  switch (seln_mode) {
+
1056  case SELECT_SYSTEM:
+
1057  case SELECT_PLANET:
+
1058  case SELECT_REGION:
+
1059  default:
+
1060  break;
+
1061 
+
1062  case SELECT_STATION:
+
1063  case SELECT_STARSHIP:
+
1064  case SELECT_FIGHTER:
+
1065  {
+
1066  if (ship) {
+
1067  SimRegion* simrgn = ship->GetRegion();
+
1068 
+
1069  if (simrgn && simrgn->NumShips()) {
+
1070  selship = simrgn->Ships().find(ship);
+
1071  }
+
1072  }
+
1073 
+
1074  SelectShip(selship);
+
1075  }
+
1076  break;
+
1077  }
+
1078 
+
1079  if (selship)
+
1080  SetupScroll(s);
+
1081 }
+
1082 
+
1083 void
+ +
1085 {
+
1086  if (scrolling) return;
+
1087  Orbital* s = 0;
+
1088 
+
1089  switch (seln_mode) {
+
1090  case SELECT_SYSTEM:
+
1091  case SELECT_PLANET:
+
1092  case SELECT_REGION:
+
1093  default:
+
1094  break;
+
1095 
+
1096  case SELECT_STATION:
+
1097  case SELECT_STARSHIP:
+
1098  case SELECT_FIGHTER:
+
1099  {
+
1100  SelectElem(elem);
+
1101  }
+
1102  break;
+
1103  }
+
1104 
+
1105  if (current_elem)
+
1106  SetupScroll(s);
+
1107 }
+
1108 
+
1109 void
+ +
1111 {
+
1112  switch (view_mode) {
+
1113  case VIEW_GALAXY:
+
1114  zoom = 1;
+
1115  offset_x = 0;
+
1116  offset_y = 0;
+
1117  scrolling = 0;
+
1118  break;
+
1119 
+
1120  case VIEW_SYSTEM:
+
1121  if (s == 0) {
+
1122  offset_x = 0;
+
1123  offset_y = 0;
+
1124  scrolling = 0;
+
1125  }
+
1126  else {
+
1127  scroll_x = (offset_x + s->Location().x) / 5.0;
+
1128  scroll_y = (offset_y + s->Location().y) / 5.0;
+
1129  scrolling = 5;
+
1130  }
+
1131  break;
+
1132 
+
1133  case VIEW_REGION:
+
1134  if (current_navpt) {
+
1135  // don't move the map
+
1136  scrolling = 0;
+
1137  }
+
1138  else if (current_ship) {
+
1139  Point sloc = current_ship->Location().OtherHand();
+
1140 
+
1141  if (!IsVisible(sloc)) {
+
1142  scroll_x = (offset_x + sloc.x) / 5.0;
+
1143  scroll_y = (offset_y + sloc.y) / 5.0;
+
1144  scrolling = 5;
+
1145  }
+
1146  else {
+
1147  scroll_x = 0;
+
1148  scroll_y = 0;
+
1149  scrolling = 0;
+
1150  }
+
1151  }
+
1152  else if (current_elem) {
+
1153  Point sloc = current_elem->Location();
+
1154 
+
1155  if (!IsVisible(sloc)) {
+
1156  scroll_x = (offset_x + sloc.x) / 5.0;
+
1157  scroll_y = (offset_y + sloc.y) / 5.0;
+
1158  scrolling = 5;
+
1159  }
+
1160  else {
+
1161  scroll_x = 0;
+
1162  scroll_y = 0;
+
1163  scrolling = 0;
+
1164  }
+
1165  }
+
1166  else {
+
1167  offset_x = 0;
+
1168  offset_y = 0;
+
1169  scrolling = 0;
+
1170  }
+
1171  break;
+
1172  }
+
1173 }
+
1174 
+
1175 bool
+ +
1177 {
+
1178  if (view_mode == VIEW_REGION) {
+
1179  double scale = c/r;
+
1180  double ox = offset_x * scale;
+
1181  double oy = offset_y * scale;
+
1182  double sx = loc.x * scale;
+
1183  double sy = loc.y * scale;
+
1184  double cx = rect.w/2;
+
1185  double cy = rect.h/2;
+
1186 
+
1187  int test_x = (int) (cx + sx + ox);
+
1188  int test_y = (int) (cy + sy + oy);
+
1189 
+
1190  bool visible = test_x >= 0 && test_x < rect.w &&
+
1191  test_y >= 0 && test_y < rect.h;
+
1192 
+
1193  return visible;
+
1194  }
+
1195 
+
1196  return false;
+
1197 }
+
1198 
+
1199 // +--------------------------------------------------------------------+
+
1200 
+
1201 void
+ +
1203 {
+
1204  if (scrolling || rgn == 0) return;
+
1205 
+
1206  int index = regions.index(rgn);
+
1207 
+
1208  if (index < 0 || index == current_region || index >= regions.size())
+
1209  return;
+
1210 
+
1211  current_region = index;
+ +
1213 
+
1214  if (!s)
+
1215  return;
+
1216 
+
1217  switch (view_mode) {
+
1218  case VIEW_GALAXY:
+
1219  case VIEW_SYSTEM:
+
1220  scroll_x = (offset_x + s->Location().x) / 5.0;
+
1221  scroll_y = (offset_y + s->Location().y) / 5.0;
+
1222  scrolling = 5;
+
1223  break;
+
1224 
+
1225  case VIEW_REGION:
+
1226  offset_x = 0;
+
1227  offset_y = 0;
+
1228  scrolling = 0;
+
1229  break;
+
1230  }
+
1231 }
+
1232 
+
1233 // +--------------------------------------------------------------------+
+
1234 
+
1235 void
+
1236 MapView::SetRegionByName(const char* rgn_name)
+
1237 {
+
1238  OrbitalRegion* rgn = 0;
+
1239 
+
1240  for (int i = 0; i < regions.size(); i++) {
+
1241  Orbital* r = regions[i];
+
1242  if (!strcmp(rgn_name, r->Name())) {
+
1243  rgn = (OrbitalRegion*) r;
+
1244  break;
+
1245  }
+
1246  }
+
1247 
+
1248  SetRegion(rgn);
+
1249 }
+
1250 
+
1251 // +--------------------------------------------------------------------+
+
1252 
+
1253 void
+
1254 MapView::SelectAt(int x, int y)
+
1255 {
+
1256  if (scrolling) return;
+
1257  if (c == 0) return;
+
1258  if (seln_mode < 0) return;
+
1259 
+
1260  Orbital* s = 0;
+
1261 
+
1262  double scale = r/c;
+
1263  double cx = rect.w/2;
+
1264  double cy = rect.h/2;
+
1265  double test_x = (x - rect.x - cx) * scale - offset_x;
+
1266  double test_y = (y - rect.y - cy) * scale - offset_y;
+
1267  double dist = 1.0e20;
+
1268  int closest = 0;
+
1269 
+
1270  if (view_mode == VIEW_GALAXY) {
+
1271  c = (cx>cy) ? cx : cy;
+
1272  r = 10;
+
1273 
+
1274  Galaxy* g = Galaxy::GetInstance();
+
1275  if (g)
+
1276  r = g->Radius();
+
1277 
+
1278  StarSystem* closest_system = 0;
+
1279 
+
1280  // draw the list of systems, and their connections:
+ +
1282  while (++iter) {
+
1283  StarSystem* s = iter.value();
+
1284 
+
1285  double dx = (s->Location().x - test_x);
+
1286  double dy = (s->Location().y - test_y);
+
1287  double d = sqrt(dx*dx + dy*dy);
+
1288 
+
1289  if (d < dist) {
+
1290  dist = d;
+
1291  closest_system = s;
+
1292  }
+
1293  }
+
1294 
+
1295  if (closest_system)
+
1296  SetSystem(closest_system);
+
1297  }
+
1298 
+
1299  else if (view_mode == VIEW_SYSTEM) {
+
1300  switch (seln_mode) {
+
1301  case SELECT_SYSTEM: {
+
1302  if (stars.isEmpty()) return;
+
1303  int index = 0;
+
1304  ListIter<Orbital> star = stars;
+
1305  while (++star) {
+
1306  double dx = (star->Location().x - test_x);
+
1307  double dy = (star->Location().y - test_y);
+
1308  double d = sqrt(dx*dx + dy*dy);
+
1309 
+
1310  if (d < dist) {
+
1311  dist = d;
+
1312  closest = index;
+
1313  }
+
1314 
+
1315  index++;
+
1316  }
+
1317 
+
1318  current_star = closest;
+
1319  }
+
1320  s = stars[current_star];
+
1321  break;
+
1322 
+
1323  case SELECT_PLANET: {
+
1324  if (planets.isEmpty()) return;
+
1325  int index = 0;
+
1326  ListIter<Orbital> planet = planets;
+
1327  while (++planet) {
+
1328  double dx = (planet->Location().x - test_x);
+
1329  double dy = (planet->Location().y - test_y);
+
1330  double d = sqrt(dx*dx + dy*dy);
+
1331 
+
1332  if (d < dist) {
+
1333  dist = d;
+
1334  closest = index;
+
1335  }
+
1336 
+
1337  index++;
+
1338  }
+
1339 
+
1340  current_planet = closest;
+
1341  }
+
1342  s = planets[current_planet];
+
1343  break;
+
1344 
+
1345  default:
+
1346  case SELECT_REGION: {
+
1347  if (regions.isEmpty()) return;
+
1348  int index = 0;
+
1349  ListIter<Orbital> region = regions;
+
1350  while (++region) {
+
1351  double dx = (region->Location().x - test_x);
+
1352  double dy = (region->Location().y - test_y);
+
1353  double d = sqrt(dx*dx + dy*dy);
+
1354 
+
1355  if (d < dist) {
+
1356  dist = d;
+
1357  closest = index;
+
1358  }
+
1359 
+
1360  index++;
+
1361  }
+
1362 
+
1363  current_region = closest;
+
1364  }
+
1365  s = regions[current_region];
+
1366  break;
+
1367  }
+
1368  }
+
1369 
+
1370  else if (view_mode == VIEW_REGION) {
+
1371  dist = 5.0e3;
+
1372 
+
1373  if (mission) {
+
1374  Orbital* rgn = regions[current_region];
+
1375  MissionElement* sel_elem = 0;
+
1376  Instruction* sel_nav = 0;
+
1377 
+
1378  if (!rgn) return;
+
1379 
+
1380  // check nav points:
+ +
1382  while (++elem) {
+
1383  MissionElement* e = elem.value();
+
1384 
+
1385  if (!e->IsSquadron() && (editor || e->GetIFF() == mission->Team())) {
+
1386  ListIter<Instruction> navpt = e->NavList();
+
1387  while (++navpt) {
+
1388  Instruction* n = navpt.value();
+
1389 
+
1390  if (!_stricmp(n->RegionName(), rgn->Name())) {
+
1391  Point nloc = n->Location();
+
1392  double dx = nloc.x - test_x;
+
1393  double dy = nloc.y - test_y;
+
1394  double d = sqrt(dx*dx + dy*dy);
+
1395 
+
1396  if (d < dist) {
+
1397  dist = d;
+
1398  sel_nav = n;
+
1399  sel_elem = e;
+
1400  }
+
1401  }
+
1402  }
+
1403  }
+
1404  }
+
1405 
+
1406  if (sel_nav) {
+
1407  SelectElem(sel_elem);
+
1408  SelectNavpt(sel_nav);
+
1409  }
+
1410 
+
1411  // check elements:
+
1412  else {
+
1413  elem.reset();
+
1414  while (++elem) {
+
1415  MissionElement* e = elem.value();
+
1416 
+
1417  if (e->Region() == rgn->Name() && !e->IsSquadron()) {
+
1418  Point sloc = e->Location();
+
1419  double dx = sloc.x - test_x;
+
1420  double dy = sloc.y - test_y;
+
1421  double d = sqrt(dx*dx + dy*dy);
+
1422 
+
1423  if (d < dist) {
+
1424  dist = d;
+
1425  sel_elem = e;
+
1426  }
+
1427  }
+
1428  }
+
1429 
+
1430  SelectElem(sel_elem);
+
1431 
+
1432  if (sel_elem)
+
1433  s = rgn;
+
1434  }
+
1435  }
+
1436  else if (ship) {
+
1437  Sim* sim = Sim::GetSim();
+
1438  Orbital* rgn = regions[current_region];
+
1439  SimRegion* simrgn = 0;
+
1440  Ship* sel_ship = 0;
+
1441  Instruction* sel_nav = 0;
+
1442 
+
1443  if (sim && rgn)
+
1444  simrgn = sim->FindRegion(rgn->Name());
+
1445 
+
1446  // check nav points:
+
1447  if (simrgn) {
+
1448  for (int r = 0; r < sim->GetRegions().size(); r++) {
+
1449  SimRegion* simrgn = sim->GetRegions().at(r);
+
1450 
+
1451  for (int i = 0; i < simrgn->Ships().size(); i++) {
+
1452  Ship* s = simrgn->Ships().at(i);
+
1453 
+
1454  if (s->GetIFF() == ship->GetIFF() && s->GetElementIndex() == 1) {
+
1455  ListIter<Instruction> navpt = s->GetFlightPlan();
+
1456  while (++navpt) {
+
1457  Instruction* n = navpt.value();
+
1458 
+
1459  if (!_stricmp(n->RegionName(), rgn->Name())) {
+
1460  Point nloc = n->Location();
+
1461  double dx = nloc.x - test_x;
+
1462  double dy = nloc.y - test_y;
+
1463  double d = sqrt(dx*dx + dy*dy);
+
1464 
+
1465  if (d < dist) {
+
1466  dist = d;
+
1467  sel_nav = n;
+
1468  sel_ship = s;
+
1469  }
+
1470  }
+
1471  }
+
1472  }
+
1473  }
+
1474  }
+
1475  }
+
1476 
+
1477  if (sel_nav) {
+
1478  SelectShip(sel_ship);
+
1479  SelectNavpt(sel_nav);
+
1480  }
+
1481 
+
1482  // check ships:
+
1483  else if (simrgn->NumShips()) {
+
1484  ListIter<Ship> ship = simrgn->Ships();
+
1485  while (++ship) {
+
1486  Ship* s = ship.value();
+
1487 
+
1488  if (!IsClutter(*s)) {
+
1489  Point sloc = s->Location().OtherHand();
+
1490  double dx = sloc.x - test_x;
+
1491  double dy = sloc.y - test_y;
+
1492  double d = sqrt(dx*dx + dy*dy);
+
1493 
+
1494  if (d < dist) {
+
1495  dist = d;
+
1496  sel_ship = s;
+
1497  }
+
1498  }
+
1499  }
+
1500 
+
1501  SelectShip(sel_ship);
+
1502  }
+
1503  else {
+
1504  SelectShip(0);
+
1505  SelectNavpt(0);
+
1506  }
+
1507  }
+
1508  }
+
1509 
+
1510  if (s)
+
1511  SetupScroll(s);
+
1512 }
+
1513 
+
1514 // +--------------------------------------------------------------------+
+
1515 
+
1516 Orbital*
+ +
1518 {
+
1519  Orbital* s = 0;
+
1520 
+
1521  switch (seln_mode) {
+
1522  case SELECT_SYSTEM:
+
1523  if (current_star < stars.size())
+
1524  s = stars[current_star];
+
1525  break;
+
1526 
+
1527  default:
+
1528  case SELECT_PLANET:
+
1529  if (current_planet < planets.size())
+
1530  s = planets[current_planet];
+
1531  break;
+
1532 
+
1533  case SELECT_REGION:
+
1534  if (current_region < regions.size())
+
1535  s = regions[current_region];
+
1536  break;
+
1537 
+
1538  case SELECT_STATION:
+
1539  case SELECT_STARSHIP:
+
1540  case SELECT_FIGHTER:
+
1541  break;
+
1542  }
+
1543 
+
1544  return s;
+
1545 }
+
1546 
+
1547 Ship*
+ +
1549 {
+
1550  return current_ship;
+
1551 }
+
1552 
+ + +
1555 {
+
1556  return current_elem;
+
1557 }
+
1558 
+
1559 // +--------------------------------------------------------------------+
+
1560 
+
1561 int
+ +
1563 {
+
1564  int s = 0;
+
1565 
+
1566  switch (seln_mode) {
+
1567  case SELECT_SYSTEM: s = current_star; break;
+
1568  default:
+
1569  case SELECT_PLANET: s = current_planet; break;
+
1570  case SELECT_REGION: s = current_region; break;
+
1571 
+
1572  case SELECT_STATION:
+
1573  case SELECT_STARSHIP:
+
1574  case SELECT_FIGHTER:
+
1575  {
+
1576  s = -1;
+
1577  Sim* sim = Sim::GetSim();
+
1578  Orbital* rgn = regions[current_region];
+
1579  SimRegion* simrgn = 0;
+
1580 
+
1581  if (sim && rgn)
+
1582  simrgn = sim->FindRegion(rgn->Name());
+
1583 
+
1584  if (simrgn) {
+
1585  if (current_ship && simrgn->NumShips()) {
+
1586  s = simrgn->Ships().index(current_ship);
+
1587  }
+
1588  }
+
1589  }
+
1590  break;
+
1591  }
+
1592 
+
1593  return s;
+
1594 }
+
1595 
+
1596 void
+
1597 MapView::DrawTabbedText(Font* font, const char* text)
+
1598 {
+
1599  if (font && text && *text) {
+
1600  Rect label_rect;
+
1601 
+
1602  label_rect.w = rect.w;
+
1603  label_rect.h = rect.h;
+
1604 
+
1605  label_rect.Inset(8,8,8,8);
+
1606 
+
1607  DWORD text_flags = DT_WORDBREAK | DT_LEFT;
+
1608 
+
1609  active_window->SetFont(font);
+
1610  active_window->DrawText(text, 0, label_rect, text_flags);
+
1611  }
+
1612 }
+
1613 
+
1614 // +--------------------------------------------------------------------+
+
1615 
+
1616 void
+ +
1618 {
+
1619  rect = window->GetRect();
+
1620 
+
1621  if (!system) {
+
1622  DrawGrid();
+
1623  DrawTabbedText(title_font, Game::GetText("MapView.item.no-system"));
+
1624  return;
+
1625  }
+
1626 
+
1627  if (font)
+ +
1629 
+
1630  if (scrolling) {
+
1631  offset_x -= scroll_x;
+
1632  offset_y -= scroll_y;
+
1633  scrolling--;
+
1634  }
+
1635 
+
1636  rect.w -= 2;
+
1637  rect.h -= 2;
+
1638 
+
1639  switch (view_mode) {
+
1640  case VIEW_GALAXY: DrawGalaxy(); break;
+
1641  case VIEW_SYSTEM: DrawSystem(); break;
+
1642  case VIEW_REGION: DrawRegion(); break;
+
1643  default: DrawGrid(); break;
+
1644  }
+
1645 
+
1646  rect.w += 2;
+
1647  rect.h += 2;
+
1648 
+
1649  if (menu_view) {
+
1650  if (current_navpt) {
+ +
1652  }
+
1653  else if (current_ship) {
+
1654  if (current_ship->GetIFF() == ship->GetIFF())
+ +
1656  else
+ +
1658  }
+
1659  else if (current_elem) {
+
1660  if (editor || current_elem->GetIFF() == mission->Team())
+ +
1662  else
+ +
1664  }
+
1665  else {
+ +
1667  }
+
1668 
+ + + + +
1673 
+
1674  if (menu_view->GetAction()) {
+ +
1676  }
+
1677 
+
1678  menu_view->Refresh();
+
1679  }
+
1680 
+
1681  DrawTitle();
+
1682 }
+
1683 
+
1684 // +--------------------------------------------------------------------+
+
1685 
+
1686 void
+ +
1688 {
+ + +
1691 }
+
1692 
+
1693 // +--------------------------------------------------------------------+
+
1694 
+
1695 void
+ +
1697 {
+
1698  title = Game::GetText("MapView.title.Galaxy");
+
1699  DrawGrid();
+
1700 
+
1701  double cx = rect.w/2;
+
1702  double cy = rect.h/2;
+
1703 
+
1704  c = (cx>cy) ? cx : cy;
+
1705  r = 10; // * zoom;
+
1706 
+
1707  Galaxy* g = Galaxy::GetInstance();
+
1708  if (g)
+
1709  r = g->Radius(); // * zoom;
+
1710 
+
1711  double scale = c/r;
+
1712  double ox = 0;
+
1713  double oy = 0;
+
1714 
+
1715  // compute offset:
+ +
1717  while (++iter) {
+
1718  StarSystem* s = iter.value();
+
1719 
+
1720  if (system == s) {
+
1721  if (fabs(s->Location().x) > 10 || fabs(s->Location().y) > 10) {
+
1722  int sx = (int) s->Location().x;
+
1723  int sy = (int) s->Location().y;
+
1724 
+
1725  sx -= sx % 10;
+
1726  sy -= sy % 10;
+
1727 
+
1728  ox = sx * -scale;
+
1729  oy = sy * -scale;
+
1730  }
+
1731  }
+
1732  }
+
1733 
+
1734  // draw the list of systems, and their connections:
+
1735  iter.reset();
+
1736  while (++iter) {
+
1737  StarSystem* s = iter.value();
+
1738 
+
1739  int sx = (int) (cx + ox + s->Location().x * scale);
+
1740  int sy = (int) (cy + oy + s->Location().y * scale);
+
1741 
+
1742  if (sx < 4 || sx > rect.w-4 || sy < 4 || sy > rect.h-4)
+
1743  continue;
+
1744 
+
1745  window->DrawEllipse(sx-7, sy-7, sx+7, sy+7, Ship::IFFColor(s->Affiliation()));
+
1746 
+
1747  if (s == system) {
+ + +
1750  }
+
1751 
+ +
1753  while (++iter2) {
+
1754  StarSystem* s2 = iter2.value();
+
1755 
+
1756  if (s != s2 && s->HasLinkTo(s2)) {
+
1757  int ax = sx;
+
1758  int ay = sy;
+
1759 
+
1760  int bx = (int) (cx + ox + s2->Location().x * scale);
+
1761  int by = (int) (cy + oy + s2->Location().y * scale);
+
1762 
+
1763  if (ax == bx) {
+
1764  if (ay < by) {
+
1765  ay += 8; by -= 8;
+
1766  }
+
1767  else {
+
1768  ay -= 8; by += 8;
+
1769  }
+
1770  }
+
1771 
+
1772  else if (ay == by) {
+
1773  if (ax < bx) {
+
1774  ax += 8; bx -= 8;
+
1775  }
+
1776  else {
+
1777  ax -= 8; bx += 8;
+
1778  }
+
1779  }
+
1780 
+
1781  else {
+
1782  Point d = Point(bx, by, 0) - Point(ax, ay, 0);
+
1783  d.Normalize();
+
1784 
+
1785  ax += (int) (8 * d.x);
+
1786  ay += (int) (8 * d.y);
+
1787 
+
1788  bx -= (int) (8 * d.x);
+
1789  by -= (int) (8 * d.y);
+
1790  }
+
1791 
+
1792  window->DrawLine(ax, ay, bx, by, Color(120,120,120), Video::BLEND_ADDITIVE);
+
1793  }
+
1794  }
+
1795  }
+
1796 
+
1797  // finally draw all the stars in the galaxy:
+
1798  if (g) {
+
1799  ListIter<Star> iter = g->Stars();
+
1800  while (++iter) {
+
1801  Star* s = iter.value();
+
1802 
+
1803  int sx = (int) (cx + ox + s->Location().x * scale);
+
1804  int sy = (int) (cy + oy + s->Location().y * scale);
+
1805  int sr = s->GetSize();
+
1806 
+
1807  if (sx < 4 || sx > rect.w-4 || sy < 4 || sy > rect.h-4)
+
1808  continue;
+
1809 
+
1810  window->FillEllipse(sx-sr, sy-sr, sx+sr, sy+sr, s->GetColor());
+
1811 
+
1812  if (!strncmp(s->Name(), "GSC", 3))
+
1813  font->SetColor(Color(100,100,100));
+
1814  else
+ +
1816 
+
1817  Rect name_rect(sx-60, sy+8, 120, 20);
+ +
1819  active_window->DrawText(s->Name(), 0, name_rect, DT_SINGLELINE | DT_CENTER);
+
1820  }
+
1821  }
+
1822 
+ +
1824 }
+
1825 
+
1826 // +--------------------------------------------------------------------+
+
1827 
+
1828 void
+ +
1830 {
+
1831  Text caption = Game::GetText("MapView.title.Starsystem");
+
1832  caption += " ";
+
1833  caption += system->Name();
+
1834 
+
1835  if (current_ship) {
+
1836  caption += "\n";
+
1837  caption += Game::GetText("MapView.title.Ship");
+
1838  caption += " ";
+
1839  caption += current_ship->Name();
+
1840  }
+
1841  else if (current_elem) {
+
1842  caption += "\n";
+
1843  caption += Game::GetText("MapView.title.Ship");
+
1844  caption += " ";
+
1845  caption += current_elem->Name();
+
1846  }
+
1847 
+
1848  title = caption;
+
1849 
+ +
1851  while (++star) {
+
1852  int p_orb = 1;
+
1853 
+
1854  ListIter<OrbitalBody> planet = star->Satellites();
+
1855  while (++planet) {
+
1856  DrawOrbital(*planet, p_orb++);
+
1857 
+
1858  int m_orb = 1;
+
1859 
+
1860  ListIter<OrbitalBody> moon = planet->Satellites();
+
1861  while (++moon) {
+
1862  DrawOrbital(*moon, m_orb++);
+
1863 
+
1864  ListIter<OrbitalRegion> region = moon->Regions();
+
1865  while (++region) {
+
1866  DrawOrbital(*region, 1);
+
1867  }
+
1868  }
+
1869 
+
1870  ListIter<OrbitalRegion> region = planet->Regions();
+
1871  while (++region) {
+
1872  DrawOrbital(*region, 1);
+
1873  }
+
1874  }
+
1875 
+
1876  ListIter<OrbitalRegion> region = star->Regions();
+
1877  while (++region) {
+
1878  DrawOrbital(*region, 1);
+
1879  }
+
1880 
+
1881  DrawOrbital(*star, 0);
+
1882  }
+
1883 
+
1884  char r_txt[32];
+
1885  FormatNumber(r_txt, system->Radius() * zoom);
+
1886  char resolution[64];
+
1887  sprintf_s(resolution, "%s: %s", Game::GetText("MapView.info.Resolution").data(), r_txt);
+
1888 
+ +
1890  active_window->DrawText(resolution, -1, Rect(4, 4, rect.w-8, 24), DT_SINGLELINE|DT_RIGHT);
+
1891 }
+
1892 
+
1893 // +--------------------------------------------------------------------+
+
1894 
+
1895 void
+ +
1897 {
+ +
1899 
+
1900  Text caption = Game::GetText("MapView.title.Sector");
+
1901  caption += " ";
+
1902  caption += rgn->Name();
+
1903 
+
1904  if (current_ship) {
+
1905  caption += "\n";
+
1906  caption += Game::GetText("MapView.title.Ship");
+
1907  caption += " ";
+
1908  caption += current_ship->Name();
+
1909  }
+
1910  else if (current_elem) {
+
1911  caption += "\n";
+
1912  caption += Game::GetText("MapView.title.Ship");
+
1913  caption += " ";
+
1914  caption += current_elem->Name();
+
1915  }
+
1916 
+
1917  title = caption;
+
1918 
+
1919  double cx = rect.w/2;
+
1920  double cy = rect.h/2;
+
1921 
+
1922  int size = (int) rgn->Radius();
+
1923  int step = (int) rgn->GridSpace();
+
1924 
+
1925  c = (cx<cy) ? cx : cy;
+
1926  r = rgn->Radius() * zoom;
+
1927  double scale = c/r;
+
1928 
+
1929  double ox = offset_x * scale;
+
1930  double oy = offset_y * scale;
+
1931 
+
1932  int left = (int) (-size * scale + ox + cx);
+
1933  int right = (int) ( size * scale + ox + cx);
+
1934  int top = (int) (-size * scale + oy + cy);
+
1935  int bottom = (int) ( size * scale + oy + cy);
+
1936 
+
1937  Color major(48,48,48);
+
1938  Color minor(24,24,24);
+
1939 
+
1940  int x,y;
+
1941  int tick = 0;
+
1942 
+
1943  for (x = 0; x <= size; x += step) {
+
1944  int lx = (int) (x * scale + ox + cx);
+
1945  if (!tick)
+
1946  window->DrawLine(lx, top, lx, bottom, major, Video::BLEND_ADDITIVE);
+
1947  else
+
1948  window->DrawLine(lx, top, lx, bottom, minor, Video::BLEND_ADDITIVE);
+
1949 
+
1950  lx = (int) (-x * scale + ox + cx);
+
1951  if (!tick)
+
1952  window->DrawLine(lx, top, lx, bottom, major, Video::BLEND_ADDITIVE);
+
1953  else
+
1954  window->DrawLine(lx, top, lx, bottom, minor, Video::BLEND_ADDITIVE);
+
1955 
+
1956  if (++tick > 3) tick = 0;
+
1957  }
+
1958 
+
1959  tick = 0;
+
1960 
+
1961  for (y = 0; y <= size; y += step) {
+
1962  int ly = (int) (y * scale + oy + cy);
+
1963  if (!tick)
+
1964  window->DrawLine(left, ly, right, ly, major, Video::BLEND_ADDITIVE);
+
1965  else
+
1966  window->DrawLine(left, ly, right, ly, minor, Video::BLEND_ADDITIVE);
+
1967 
+
1968  ly = (int) (-y * scale + oy + cy);
+
1969  if (!tick)
+
1970  window->DrawLine(left, ly, right, ly, major, Video::BLEND_ADDITIVE);
+
1971  else
+
1972  window->DrawLine(left, ly, right, ly, minor, Video::BLEND_ADDITIVE);
+
1973 
+
1974  if (++tick > 3) tick = 0;
+
1975  }
+
1976 
+
1977  int rep = 3;
+
1978  if (r > 70e3) rep = 2;
+
1979  if (r > 250e3) rep = 1;
+
1980 
+
1981  if (campaign && rgn) {
+
1982  // draw the combatants in this region:
+ +
1984  while (++iter) {
+
1985  Combatant* combatant = iter.value();
+
1986  DrawCombatGroup(combatant->GetForce(), rep);
+
1987  }
+
1988  }
+
1989 
+
1990  else if (mission && rgn) {
+
1991  // draw the elements in this region:
+ +
1993  while (++elem)
+
1994  if (!elem->IsSquadron())
+
1995  DrawElem(*elem, (elem.value() == current_elem), rep);
+
1996  }
+
1997 
+
1998  else if (ship) {
+
1999  // draw the ships in this region:
+
2000  Sim* sim = Sim::GetSim();
+
2001  SimRegion* simrgn = 0;
+
2002 
+
2003  if (sim && rgn)
+
2004  simrgn = sim->FindRegion(rgn->Name());
+
2005 
+
2006  // this algorithm uses the allied track list for the region,
+
2007  // even if this ship is in a different region. a previous
+
2008  // version used the ship's own contact list, which only shows
+
2009  // ships in the player's region. this way is less "realistic"
+
2010  // but more fun for managing large battles.
+
2011 
+
2012  if (simrgn) {
+
2013  ListIter<Contact> c = simrgn->TrackList(ship->GetIFF());
+
2014  while (++c) {
+
2015  Contact* contact = c.value();
+
2016  Ship* s = contact->GetShip();
+
2017 
+
2018  if (s && (s->Class() & ship_filter) && !IsClutter(*s) && s != ship)
+
2019  DrawShip(*s, (s == current_ship), rep);
+
2020  }
+
2021 
+
2022  ListIter<Ship> s_iter = simrgn->Ships();
+
2023  while (++s_iter) {
+
2024  Ship* s = s_iter.value();
+
2025 
+
2026  if (s && (s->IsStatic()) && !IsClutter(*s) &&
+
2027  (s->GetIFF() == ship->GetIFF() || s->GetIFF() == 0))
+
2028  DrawShip(*s, (s == current_ship), rep);
+
2029  }
+
2030 
+
2031  // draw nav routes for allied ships not in the region:
+
2032  ListIter<SimRegion> r_iter = sim->GetRegions();
+
2033  while (++r_iter) {
+
2034  SimRegion* r = r_iter.value();
+
2035 
+
2036  if (r != simrgn) {
+
2037  ListIter<Ship> s_iter = r->Ships();
+
2038  while (++s_iter) {
+
2039  Ship* s = s_iter.value();
+
2040 
+
2041  if (s && !s->IsStatic() && !IsClutter(*s) &&
+
2042  (s->GetIFF() == ship->GetIFF() || s->GetIFF() == 0)) {
+
2043  DrawNavRoute(simrgn->GetOrbitalRegion(),
+
2044  s->GetFlightPlan(),
+
2045  s->MarkerColor(),
+
2046  s, 0);
+
2047  }
+
2048  }
+
2049  }
+
2050  }
+
2051  }
+
2052 
+
2053  // draw our own ship:
+
2054  DrawShip(*ship, (ship == current_ship), rep);
+
2055  }
+
2056 
+
2057  char r_txt[32];
+
2058  FormatNumber(r_txt, r*2);
+
2059  char resolution[64];
+
2060  sprintf_s(resolution, "%s: %s", Game::GetText("MapView.info.Resolution").data(), r_txt);
+
2061 
+ +
2063  active_window->DrawText(resolution, -1, Rect(4, 4, rect.w-8, 24), DT_SINGLELINE|DT_RIGHT);
+
2064 }
+
2065 
+
2066 // +--------------------------------------------------------------------+
+
2067 
+
2068 void
+ +
2070 {
+
2071  int grid_step = rect.w/8;
+
2072  int cx = rect.w/2;
+
2073  int cy = rect.h/2;
+
2074 
+
2075  Color c(32,32,32);
+
2076 
+
2077  window->DrawLine(0, cy, rect.w, cy, c, Video::BLEND_ADDITIVE);
+
2078  window->DrawLine(cx, 0, cx, rect.h, c, Video::BLEND_ADDITIVE);
+
2079 
+
2080  for (int i = 1; i < 4; i++) {
+
2081  window->DrawLine(0, cy + (i*grid_step), rect.w, cy + (i*grid_step), c, Video::BLEND_ADDITIVE);
+
2082  window->DrawLine(0, cy - (i*grid_step), rect.w, cy - (i*grid_step), c, Video::BLEND_ADDITIVE);
+
2083  window->DrawLine(cx + (i*grid_step), 0, cx + (i*grid_step), rect.h, c, Video::BLEND_ADDITIVE);
+
2084  window->DrawLine(cx - (i*grid_step), 0, cx - (i*grid_step), rect.h, c, Video::BLEND_ADDITIVE);
+
2085  }
+
2086 }
+
2087 
+
2088 // +--------------------------------------------------------------------+
+
2089 
+
2090 void
+ +
2092 {
+
2093  int type = body.Type();
+
2094 
+
2095  if (type == Orbital::NOTHING)
+
2096  return;
+
2097 
+
2098  int x1, y1, x2, y2;
+
2099  Rect label_rect;
+
2100  int label_w = 64;
+
2101  int label_h = 18;
+
2102 
+
2103  double cx = rect.w/2;
+
2104  double cy = rect.h/2;
+
2105 
+
2106  c = (cx<cy) ? cx : cy;
+
2107  r = system->Radius() * zoom;
+
2108 
+
2109  if ((r > 300e9) && (type > Orbital::PLANET))
+
2110  return;
+
2111 
+
2112  double xscale = cx / r;
+
2113  double yscale = cy / r * 0.75;
+
2114 
+
2115  double ox = offset_x * xscale;
+
2116  double oy = offset_y * yscale;
+
2117 
+
2118  double bo_x = body.Orbit() * xscale;
+
2119  double bo_y = body.Orbit() * yscale;
+
2120  double br = body.Radius() * yscale;
+
2121  double bx = body.Location().x * xscale;
+
2122  double by = body.Location().y * yscale;
+
2123 
+
2124  double px = 0;
+
2125  double py = 0;
+
2126 
+
2127  if (body.Primary()) {
+
2128  double min_pr = GetMinRadius(body.Primary()->Type());
+
2129 
+
2130  if (index) {
+
2131  if (min_pr < 4)
+
2132  min_pr = 4;
+
2133 
+
2134  min_pr *= (index+1);
+
2135  }
+
2136 
+
2137  double min_x = min_pr * xscale / yscale;
+
2138  double min_y = min_pr;
+
2139 
+
2140  if (bo_x < min_x)
+
2141  bo_x = min_x;
+
2142 
+
2143  if (bo_y < min_y)
+
2144  bo_y = min_y;
+
2145 
+
2146  px = body.Primary()->Location().x * xscale;
+
2147  py = body.Primary()->Location().y * yscale;
+
2148  }
+
2149 
+
2150  if (type == Orbital::TERRAIN)
+
2151  bo_x = bo_y;
+
2152 
+
2153  int ipx = (int) (cx + px + ox);
+
2154  int ipy = (int) (cy + py + oy);
+
2155  int ibo_x = (int) bo_x;
+
2156  int ibo_y = (int) bo_y;
+
2157 
+
2158  x1 = ipx - ibo_x;
+
2159  y1 = ipy - ibo_y;
+
2160  x2 = ipx + ibo_x;
+
2161  y2 = ipy + ibo_y;
+
2162 
+
2163  if (type != Orbital::TERRAIN) {
+
2164  double a = x2-x1;
+
2165  double b = rect.w*32;
+
2166 
+
2167  if (a < b)
+
2168  window->DrawEllipse(x1, y1, x2, y2, Color(64,64,64), Video::BLEND_ADDITIVE);
+
2169  }
+
2170 
+
2171  // show body's location on possibly magnified orbit
+
2172  bx = px + bo_x * cos(body.Phase());
+
2173  by = py + bo_y * sin(body.Phase());
+
2174 
+
2175  double min_br = GetMinRadius(type);
+
2176  if (br < min_br) br = min_br;
+
2177 
+
2178  Color color;
+
2179 
+
2180  switch (type) {
+
2181  case Orbital::STAR: color = Color(248, 248, 128); break;
+
2182  case Orbital::PLANET: color = Color( 64, 64, 192); break;
+
2183  case Orbital::MOON: color = Color( 32, 192, 96); break;
+
2184  case Orbital::REGION: color = Color(255, 255, 255); break;
+
2185  case Orbital::TERRAIN: color = Color( 16, 128, 48); break;
+
2186  }
+
2187 
+
2188  int icx = (int) (cx + bx + ox);
+
2189  int icy = (int) (cy + by + oy);
+
2190  int ibr = (int) br;
+
2191 
+
2192  x1 = icx - ibr;
+
2193  y1 = icy - ibr;
+
2194  x2 = icx + ibr;
+
2195  y2 = icy + ibr;
+
2196 
+
2197  if (type < Orbital::REGION) {
+
2198  if (body.GetMapIcon().Width() > 64) {
+
2199  Bitmap* map_icon = (Bitmap*) &body.GetMapIcon();
+
2200 
+
2201  if (type == Orbital::STAR)
+
2202  window->DrawBitmap(x1,y1,x2,y2, map_icon, Video::BLEND_ADDITIVE);
+
2203  else
+
2204  window->DrawBitmap(x1,y1,x2,y2, map_icon, Video::BLEND_ALPHA);
+
2205  }
+
2206  else {
+
2207  window->FillEllipse(x1, y1, x2, y2, color);
+
2208  }
+
2209  }
+
2210  else {
+
2211  window->DrawRect(x1, y1, x2, y2, color);
+
2212 
+
2213  if (campaign) {
+ +
2215  while (++iter) {
+
2216  Combatant* combatant = iter.value();
+
2217 
+
2218  if (ibr >= 4 || combatant->GetIFF() == 1)
+
2219  DrawCombatantSystem(combatant, &body, icx, icy, ibr);
+
2220  }
+
2221  }
+
2222  }
+
2223 
+
2224  if (type == Orbital::STAR || bo_y > label_h) {
+
2225  label_rect.x = x1 - label_w + (int) br;
+
2226  label_rect.y = y1 - label_h;
+
2227  label_rect.w = label_w * 2;
+
2228  label_rect.h = label_h;
+
2229 
+ +
2231  active_window->DrawText(body.Name(), -1, label_rect, DT_SINGLELINE|DT_CENTER);
+
2232  }
+
2233 }
+
2234 
+
2235 // +--------------------------------------------------------------------+
+
2236 
+
2237 double
+ +
2239 {
+
2240  switch (type) {
+
2241  case Orbital::STAR: return 8;
+
2242  case Orbital::PLANET: return 4;
+
2243  case Orbital::MOON: return 2;
+
2244  case Orbital::REGION: return 2;
+
2245  }
+
2246 
+
2247  return 0;
+
2248 }
+
2249 
+
2250 // +--------------------------------------------------------------------+
+
2251 
+
2252 static void
+
2253 ColorizeBitmap(Bitmap& img, Color color)
+
2254 {
+
2255  int w = img.Width();
+
2256  int h = img.Height();
+
2257 
+
2258  for (int y = 0; y < h; y++) {
+
2259  for (int x = 0; x < w; x++) {
+
2260  Color c = img.GetColor(x, y);
+
2261 
+
2262  if (c != Color::Black && c != Color::White) {
+
2263  img.SetColor(x,y,color.ShadeColor(c.Blue()/2));
+
2264  }
+
2265  }
+
2266  }
+
2267 
+
2268  img.AutoMask();
+
2269 }
+
2270 
+
2271 static POINT shipshape1[] = { {6,0}, {-6,4}, {-6,-4} };
+
2272 static POINT shipshape2[] = { {8,0}, { 4,4}, {-8,4}, {-8,-4}, {4,-4} };
+
2273 static POINT shipshape3[] = { {8,8}, {-8,8}, {-8,-8}, {8,-8} };
+
2274 
+
2275 void
+
2276 MapView::DrawShip(Ship& s, bool current, int rep)
+
2277 {
+ +
2279  if (!rgn) return;
+
2280 
+
2281  int x1, y1, x2, y2;
+
2282  POINT shiploc;
+
2283  Point sloc = s.Location().OtherHand();
+
2284 
+
2285  double cx = rect.w/2;
+
2286  double cy = rect.h/2;
+
2287 
+
2288  c = (cx<cy) ? cx : cy;
+
2289  r = rgn->Radius() * zoom;
+
2290 
+
2291  double scale = c/r;
+
2292 
+
2293  double ox = offset_x * scale;
+
2294  double oy = offset_y * scale;
+
2295 
+
2296  double rlx = 0;
+
2297  double rly = 0;
+
2298 
+
2299  int sprite_width = 10;
+
2300 
+
2301  window->SetFont(font);
+
2302 
+
2303  // draw ship icon:
+
2304  if (rep && view_mode == VIEW_REGION && rgn == s.GetRegion()->GetOrbitalRegion()) {
+
2305  double sx = (sloc.x + rlx) * scale;
+
2306  double sy = (sloc.y + rly) * scale;
+
2307 
+
2308  shiploc.x = (int) (cx + sx + ox);
+
2309  shiploc.y = (int) (cy + sy + oy);
+
2310 
+
2311  bool ship_visible = shiploc.x >= 0 && shiploc.x < rect.w &&
+
2312  shiploc.y >= 0 && shiploc.y < rect.h;
+
2313 
+
2314  if (ship_visible) {
+
2315  if (rep < 3) {
+
2316  window->FillRect(shiploc.x-2, shiploc.y-2, shiploc.x+2, shiploc.y+2, s.MarkerColor());
+
2317  sprite_width = 2;
+
2318 
+
2319  if (&s == ship || !IsCrowded(s))
+
2320  window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, s.Name());
+
2321  }
+
2322  else {
+
2323  Point heading = s.Heading().OtherHand();
+
2324  heading.z = 0;
+
2325  heading.Normalize();
+
2326 
+
2327  double theta = 0;
+
2328 
+
2329  if (heading.y > 0)
+
2330  theta = acos(heading.x);
+
2331  else
+
2332  theta = -acos(heading.x);
+
2333 
+
2334  const double THETA_SLICE = 4 / PI;
+
2335  const double THETA_OFFSET = PI + THETA_SLICE/2;
+
2336 
+
2337  int sprite_index = (int) ((theta + THETA_OFFSET) * THETA_SLICE);
+
2338  int nsprites = s.Design()->map_sprites.size();
+
2339 
+
2340  if (nsprites) {
+
2341  if (sprite_index < 0 || sprite_index >= nsprites)
+
2342  sprite_index = sprite_index % nsprites;
+
2343 
+
2344  Bitmap* map_sprite = s.Design()->map_sprites[sprite_index];
+
2345 
+
2346  Bitmap bmp;
+
2347  bmp.CopyBitmap(*map_sprite);
+
2348  ColorizeBitmap(bmp, s.MarkerColor());
+
2349  sprite_width = bmp.Width()/2;
+
2350  int h = bmp.Height()/2;
+
2351 
+
2352  window->DrawBitmap(shiploc.x-sprite_width,
+
2353  shiploc.y-h,
+
2354  shiploc.x+sprite_width,
+
2355  shiploc.y+h,
+
2356  &bmp,
+ +
2358  }
+
2359 
+
2360  else {
+
2361  theta -= PI/2;
+
2362 
+
2363  if (s.IsStatic()) {
+
2364  window->FillRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, s.MarkerColor());
+
2365  window->DrawRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, Color::White);
+
2366  }
+
2367  else if (s.IsStarship()) {
+
2368  window->FillRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, s.MarkerColor());
+
2369  window->DrawRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, Color::White);
+
2370  }
+
2371  else {
+
2372  window->FillRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, s.MarkerColor());
+
2373  window->DrawRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, Color::White);
+
2374  }
+
2375  }
+
2376 
+
2377  window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, s.Name());
+
2378  }
+
2379  }
+
2380  }
+
2381 
+
2382  // draw nav route:
+
2383  // draw current ship marker:
+
2384  if (current && Text(s.GetRegion()->Name()) == regions[current_region]->Name()) {
+
2385  x1 = (int) (shiploc.x - sprite_width - 1);
+
2386  x2 = (int) (shiploc.x + sprite_width + 1);
+
2387  y1 = (int) (shiploc.y - sprite_width - 1);
+
2388  y2 = (int) (shiploc.y + sprite_width + 1);
+
2389 
+
2390  window->DrawRect(x1, y1, x2, y2, Color::White);
+
2391  }
+
2392 
+
2393  // only see routes for your own team:
+
2394  if (s.GetIFF() == 0 || ship && s.GetIFF() == ship->GetIFF()) {
+
2395  DrawNavRoute(rgn, s.GetFlightPlan(), s.MarkerColor(), &s, 0);
+
2396  }
+
2397 }
+
2398 
+
2399 void
+
2400 MapView::DrawElem(MissionElement& s, bool current, int rep)
+
2401 {
+
2402  if (!mission) return;
+
2403 
+
2404  bool visible = editor ||
+
2405  s.GetIFF() == 0 ||
+
2406  s.GetIFF() == mission->Team() ||
+
2407  s.IntelLevel() > Intel::KNOWN;
+
2408 
+
2409  if (!visible) return;
+
2410 
+ +
2412 
+
2413  if (!rgn) return;
+
2414 
+
2415  int x1, y1, x2, y2;
+
2416  POINT shiploc;
+
2417 
+
2418  double cx = rect.w/2;
+
2419  double cy = rect.h/2;
+
2420 
+
2421  c = (cx<cy) ? cx : cy;
+
2422  r = rgn->Radius() * zoom;
+
2423 
+
2424  double scale = c/r;
+
2425 
+
2426  double ox = offset_x * scale;
+
2427  double oy = offset_y * scale;
+
2428 
+
2429  double rlx = 0;
+
2430  double rly = 0;
+
2431 
+
2432  int sprite_width = 10;
+
2433 
+
2434  window->SetFont(font);
+
2435 
+
2436  // draw ship icon:
+
2437  if (!_stricmp(s.Region(), rgn->Name())) {
+
2438  double sx = (s.Location().x + rlx) * scale;
+
2439  double sy = (s.Location().y + rly) * scale;
+
2440 
+
2441  shiploc.x = (int) (cx + sx + ox);
+
2442  shiploc.y = (int) (cy + sy + oy);
+
2443 
+
2444  bool ship_visible = shiploc.x >= 0 && shiploc.x < rect.w &&
+
2445  shiploc.y >= 0 && shiploc.y < rect.h;
+
2446 
+
2447  if (ship_visible) {
+
2448  if (rep < 3) {
+
2449  window->FillRect(shiploc.x-2, shiploc.y-2, shiploc.x+2, shiploc.y+2, s.MarkerColor());
+
2450  sprite_width = 2;
+
2451 
+
2452  if (!IsCrowded(s))
+
2453  window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, s.Name());
+
2454  }
+
2455  else {
+
2456  double theta = s.Heading();
+
2457 
+
2458  const double THETA_SLICE = 4 / PI;
+
2459  const double THETA_OFFSET = PI / 2;
+
2460 
+
2461  int sprite_index = (int) ((theta + THETA_OFFSET) * THETA_SLICE);
+
2462  int nsprites = 0;
+
2463 
+
2464  if (s.GetDesign())
+
2465  nsprites = s.GetDesign()->map_sprites.size();
+
2466 
+
2467  if (nsprites > 0) {
+
2468  if (sprite_index < 0 || sprite_index >= nsprites)
+
2469  sprite_index = sprite_index % nsprites;
+
2470 
+
2471  Bitmap* map_sprite = s.GetDesign()->map_sprites[sprite_index];
+
2472 
+
2473  Bitmap bmp;
+
2474  bmp.CopyBitmap(*map_sprite);
+
2475  ColorizeBitmap(bmp, s.MarkerColor());
+
2476  sprite_width = bmp.Width()/2;
+
2477  int h = bmp.Height()/2;
+
2478 
+
2479  window->DrawBitmap(shiploc.x-sprite_width,
+
2480  shiploc.y-h,
+
2481  shiploc.x+sprite_width,
+
2482  shiploc.y+h,
+
2483  &bmp,
+ +
2485  }
+
2486 
+
2487  else {
+
2488  theta -= PI/2;
+
2489 
+
2490  if (s.IsStatic()) {
+
2491  window->FillRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, s.MarkerColor());
+
2492  window->DrawRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, Color::White);
+
2493  }
+
2494  else if (s.IsStarship()) {
+
2495  window->FillRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, s.MarkerColor());
+
2496  window->DrawRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, Color::White);
+
2497  }
+
2498  else {
+
2499  window->FillRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, s.MarkerColor());
+
2500  window->DrawRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, Color::White);
+
2501  }
+
2502  }
+
2503 
+
2504  char label[64];
+
2505 
+
2506  if (s.Count() > 1)
+
2507  sprintf_s(label, "%s x %d", (const char*) s.Name(), s.Count());
+
2508  else
+
2509  strcpy_s(label, (const char*) s.Name());
+
2510 
+
2511  window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, label);
+
2512  }
+
2513  }
+
2514  }
+
2515 
+
2516  // draw nav route:
+
2517  // draw current ship marker:
+
2518  if (current && s.Region() == regions[current_region]->Name()) {
+
2519  x1 = (int) (shiploc.x - sprite_width - 1);
+
2520  x2 = (int) (shiploc.x + sprite_width + 1);
+
2521  y1 = (int) (shiploc.y - sprite_width - 1);
+
2522  y2 = (int) (shiploc.y + sprite_width + 1);
+
2523 
+
2524  window->DrawRect(x1, y1, x2, y2, Color::White);
+
2525  }
+
2526 
+
2527  // only see routes for your own team:
+
2528  if (editor || s.GetIFF() == 0 || mission && s.GetIFF() == mission->Team()) {
+
2529  DrawNavRoute(rgn, s.NavList(), s.MarkerColor(), 0, &s);
+
2530  }
+
2531 }
+
2532 
+
2533 void
+ +
2535 List<Instruction>& s_route,
+
2536 Color s_marker,
+
2537 Ship* ship,
+
2538 MissionElement* elem)
+
2539 {
+
2540  int x1, y1, x2, y2;
+
2541  double cx = rect.w/2;
+
2542  double cy = rect.h/2;
+
2543 
+
2544  c = (cx<cy) ? cx : cy;
+
2545  r = system->Radius() * zoom;
+
2546 
+
2547  if (view_mode == VIEW_REGION) {
+
2548  if (!rgn) return;
+
2549  r = rgn->Radius() * zoom;
+
2550  }
+
2551 
+
2552  double scale = c/r;
+
2553  double ox = offset_x * scale;
+
2554  double oy = offset_y * scale;
+
2555 
+
2556  Point old_loc;
+
2557  double old_x = 0;
+
2558  double old_y = 0;
+
2559  bool old_in = false;
+
2560 
+
2561  Point first_loc;
+
2562  int first_x = 0;
+
2563  int first_y = 0;
+
2564  bool first_in = false;
+
2565 
+
2566  bool draw_route = true;
+
2567  bool draw_bold = false;
+
2568 
+
2569  if (ship && ship->GetElementIndex() > 1)
+
2570  draw_route = false;
+
2571 
+
2572  if (ship && ship == current_ship) {
+
2573  s_marker = s_marker * 1.5;
+
2574  draw_bold = true;
+
2575  }
+
2576 
+
2577  else if (elem && elem == current_elem) {
+
2578  s_marker = s_marker * 1.5;
+
2579  draw_bold = true;
+
2580  }
+
2581 
+
2582  for (int i = 0; i < s_route.size(); i++) {
+
2583  Instruction* navpt = s_route[i];
+
2584 
+
2585  if (!_stricmp(navpt->RegionName(), rgn->Name())) {
+
2586  double nav_x = navpt->Location().x * scale;
+
2587  double nav_y = navpt->Location().y * scale;
+
2588 
+
2589  int isx = (int) (cx + nav_x + ox);
+
2590  int isy = (int) (cy + nav_y + oy);
+
2591 
+
2592  if (old_in && draw_route) {
+
2593  int iox = (int) (cx + old_x + ox);
+
2594  int ioy = (int) (cy + old_y + oy);
+
2595  window->DrawLine(iox, ioy, isx, isy, s_marker);
+
2596 
+
2597  int x1 = (iox-isx);
+
2598  int y1 = (ioy-isy);
+
2599 
+
2600  if (draw_bold) {
+
2601  if (x1 > y1) {
+
2602  window->DrawLine(iox, ioy+1, isx, isy+1, s_marker);
+
2603  }
+
2604  else {
+
2605  window->DrawLine(iox+1, ioy, isx+1, isy, s_marker);
+
2606  }
+
2607  }
+
2608 
+
2609  if ((x1*x1 + y1*y1) > 2000) {
+
2610  double dist = Point(navpt->Location() - old_loc).length();
+
2611 
+
2612  int imx = (int) (cx + (old_x+nav_x)/2 + ox);
+
2613  int imy = (int) (cy + (old_y+nav_y)/2 + oy);
+
2614 
+
2615  char dist_txt[32];
+
2616  FormatNumber(dist_txt, dist);
+ +
2618  window->SetFont(font);
+
2619  window->Print(imx-20, imy-6, dist_txt);
+ +
2621  }
+
2622  }
+
2623 
+
2624  x1 = isx - 3;
+
2625  y1 = isy - 3;
+
2626  x2 = isx + 3;
+
2627  y2 = isy + 3;
+
2628 
+
2629  Color c = Color::White;
+
2630  if (navpt->Status() > Instruction::ACTIVE) {
+
2631  c = Color::Gray;
+
2632  }
+
2633  else if (!first_in) {
+
2634  first_in = true;
+
2635  first_loc = navpt->Location();
+
2636  first_x = isx;
+
2637  first_y = isy;
+
2638  }
+
2639 
+
2640  if (draw_route) {
+
2641  window->DrawLine(x1, y1, x2, y2, c);
+
2642  window->DrawLine(x1, y2, x2, y1, c);
+
2643 
+
2644  if (navpt == current_navpt)
+
2645  window->DrawRect(x1-2, y1-2, x2+2, y2+2, c);
+
2646 
+
2647  char buf[256];
+
2648  sprintf_s(buf, "%d", i+1);
+
2649  window->SetFont(font);
+
2650  window->Print(x2+3, y1, buf);
+
2651 
+
2652  if (navpt == current_navpt) {
+
2653  if (navpt->TargetName() && strlen(navpt->TargetName())) {
+
2654  sprintf_s(buf, "%s %s", Game::GetText(Text("MapView.item.") + Instruction::ActionName(navpt->Action())).data(), navpt->TargetName());
+
2655  window->Print(x2+3, y1+10, buf);
+
2656  }
+
2657  else {
+
2658  sprintf_s(buf, "%s", Game::GetText(Text("MapView.item.") + Instruction::ActionName(navpt->Action())).data());
+
2659  window->Print(x2+3, y1+10, buf);
+
2660  }
+
2661 
+
2662  sprintf_s(buf, "%s", Game::GetText(Text("MapView.item.") + Instruction::FormationName(navpt->Formation())).data());
+
2663  window->Print(x2+3, y1+20, buf);
+
2664 
+
2665  sprintf_s(buf, "%d", navpt->Speed());
+
2666  window->Print(x2+3, y1+30, buf);
+
2667 
+
2668  if (navpt->HoldTime()) {
+
2669  char hold_time[32];
+
2670  FormatTime(hold_time, navpt->HoldTime());
+
2671 
+
2672  sprintf_s(buf, "%s %s", Game::GetText("MapView.item.Hold").data(), hold_time);
+
2673  window->Print(x2+3, y1+40, buf);
+
2674  }
+
2675  }
+
2676  }
+
2677 
+
2678  old_loc = navpt->Location();
+
2679  old_x = nav_x;
+
2680  old_y = nav_y;
+
2681  old_in = true;
+
2682  }
+
2683 
+
2684  else {
+
2685  old_loc = navpt->Location();
+
2686  old_x = 0;
+
2687  old_y = 0;
+
2688  old_in = false;
+
2689  }
+
2690  }
+
2691 
+
2692  // if the ship and the first active navpoint are both in the region,
+
2693  // draw a line from the ship to the first active navpoint:
+
2694 
+
2695  if (first_in) {
+
2696  old_in = false;
+
2697 
+
2698  if (ship && ship->GetRegion()) {
+
2699  old_in = (ship->GetRegion()->GetOrbitalRegion() == rgn);
+
2700 
+
2701  if (old_in) {
+
2702  old_loc = ship->Location().OtherHand();
+
2703  old_x = old_loc.x * scale;
+
2704  old_y = old_loc.y * scale;
+
2705  }
+
2706  }
+
2707 
+
2708  else if (elem) {
+
2709  old_in = (elem->Region() == rgn->Name()) ? true : false;
+
2710 
+
2711  if (old_in) {
+
2712  old_loc = elem->Location();
+
2713  old_x = old_loc.x * scale;
+
2714  old_y = old_loc.y * scale;
+
2715  }
+
2716  }
+
2717 
+
2718  if (old_in) {
+
2719  int iox = (int) (cx + old_x + ox);
+
2720  int ioy = (int) (cy + old_y + oy);
+
2721  window->DrawLine(iox, ioy, first_x, first_y, s_marker);
+
2722 
+
2723  int x1 = (iox-first_x);
+
2724  int y1 = (ioy-first_y);
+
2725 
+
2726  if (draw_bold) {
+
2727  if (x1 > y1) {
+
2728  window->DrawLine(iox, ioy+1, first_x, first_y+1, s_marker);
+
2729  }
+
2730  else {
+
2731  window->DrawLine(iox+1, ioy, first_x+1, first_y, s_marker);
+
2732  }
+
2733  }
+
2734 
+
2735  if ((x1*x1 + y1*y1) > 2000) {
+
2736  double dist = Point(first_loc - old_loc).length();
+
2737  double nav_x = first_loc.x * scale;
+
2738  double nav_y = first_loc.y * scale;
+
2739 
+
2740  int imx = (int) (cx + (old_x+nav_x)/2 + ox);
+
2741  int imy = (int) (cy + (old_y+nav_y)/2 + oy);
+
2742 
+
2743  char dist_txt[32];
+
2744  FormatNumber(dist_txt, dist);
+ +
2746  window->SetFont(font);
+
2747  window->Print(imx-20, imy-6, dist_txt);
+ +
2749  }
+
2750  }
+
2751  }
+
2752 }
+
2753 
+
2754 // +--------------------------------------------------------------------+
+
2755 
+
2756 void
+
2757 MapView::DrawCombatantSystem(Combatant* c, Orbital* rgn, int x, int y, int r)
+
2758 {
+
2759  int team = c->GetIFF();
+
2760  int x1 = 0;
+
2761  int x2 = 0;
+
2762  int y1 = y - r;
+
2763  int a = 0;
+
2764 
+
2765  switch (team) {
+
2766  case 0: x1 = x - 64;
+
2767  x2 = x + 64;
+
2768  y1 = y + r + 4;
+
2769  a = DT_CENTER;
+
2770  break;
+
2771 
+
2772  case 1: x1 = x - 200;
+
2773  x2 = x - r - 4;
+
2774  a = DT_RIGHT;
+
2775  break;
+
2776 
+
2777  default: x1 = x + r + 4;
+
2778  x2 = x + 200;
+
2779  a = DT_LEFT;
+
2780  break;
+
2781  }
+
2782 
+
2783  DrawCombatGroupSystem(c->GetForce(), rgn, x1, x2, y1, a);
+
2784 }
+
2785 
+
2786 // +--------------------------------------------------------------------+
+
2787 
+
2788 void
+
2789 MapView::DrawCombatGroupSystem(CombatGroup* group, Orbital* rgn, int x1, int x2, int& y, int a)
+
2790 {
+
2791  if (!group || group->IsReserve() || group->CalcValue() < 1)
+
2792  return;
+
2793 
+
2794  char txt[80];
+
2795 
+
2796  if (group->GetRegion() == rgn->Name()) {
+
2797  switch (group->Type()) {
+ + + +
2801  sprintf_s(txt, "%s '%s'", group->GetShortDescription(), group->Name().data());
+ +
2803  active_window->DrawText(txt, 0, Rect(x1, y, x2-x1, 12), a);
+
2804  y += 10;
+
2805  break;
+
2806 
+ +
2808  case CombatGroup::STATION:
+
2809  case CombatGroup::STARBASE:
+
2810 
+ +
2812  case CombatGroup::BATTERY:
+
2813  case CombatGroup::MISSILE:
+
2814 
+ +
2816  active_window->DrawText(group->GetShortDescription(), 0, Rect(x1, y, x2-x1, 12), a);
+
2817  y += 10;
+
2818  break;
+
2819 
+
2820  default:
+
2821  break;
+
2822  }
+
2823  }
+
2824 
+
2825  ListIter<CombatGroup> iter = group->GetComponents();
+
2826  while (++iter) {
+
2827  CombatGroup* g = iter.value();
+
2828  DrawCombatGroupSystem(g, rgn, x1, x2, y, a);
+
2829  }
+
2830 }
+
2831 
+
2832 // +--------------------------------------------------------------------+
+
2833 
+
2834 void
+ +
2836 {
+
2837  // does group even exist yet?
+
2838  if (!group || group->IsReserve() || group->CalcValue() < 1)
+
2839  return;
+
2840 
+
2841  // is group a squadron? don't draw squadrons on map:
+
2842  if (group->Type() >= CombatGroup::WING && group->Type() < CombatGroup::FLEET)
+
2843  return;
+
2844 
+
2845  // has group been discovered yet?
+
2846  CombatGroup* player_group = campaign->GetPlayerGroup();
+
2847  if (group->GetIFF() && player_group && player_group->GetIFF() != group->GetIFF())
+
2848  if (group->IntelLevel() <= Intel::KNOWN)
+
2849  return;
+
2850 
+
2851  // has group been destroyed already?
+
2852  if (group->CalcValue() < 1)
+
2853  return;
+
2854 
+ +
2856  if (!rgn) return;
+
2857 
+
2858  POINT shiploc;
+
2859 
+
2860  double cx = rect.w/2;
+
2861  double cy = rect.h/2;
+
2862 
+
2863  c = (cx<cy) ? cx : cy;
+
2864  r = rgn->Radius() * zoom;
+
2865 
+
2866  double scale = c/r;
+
2867 
+
2868  double ox = offset_x * scale;
+
2869  double oy = offset_y * scale;
+
2870 
+
2871  double rlx = 0;
+
2872  double rly = 0;
+
2873 
+
2874  int sprite_width = 10;
+
2875 
+
2876  if (group->GetUnits().size() > 0) {
+
2877  CombatUnit* unit = 0;
+
2878 
+
2879  for (int i = 0; i < group->GetUnits().size(); i++) {
+
2880  unit = group->GetUnits().at(i);
+
2881 
+
2882  if (unit->Count() - unit->DeadCount() > 0)
+
2883  break;
+
2884  }
+
2885 
+
2886  // draw unit icon:
+
2887  if (unit->GetRegion() == rgn->Name() && unit->Type() > Ship::LCA && unit->Count() > 0) {
+
2888  double sx = (unit->Location().x + rlx) * scale;
+
2889  double sy = (unit->Location().y + rly) * scale;
+
2890 
+
2891  shiploc.x = (int) (cx + sx + ox);
+
2892  shiploc.y = (int) (cy + sy + oy);
+
2893 
+
2894  bool ship_visible = shiploc.x >= 0 && shiploc.x < rect.w &&
+
2895  shiploc.y >= 0 && shiploc.y < rect.h;
+
2896 
+
2897  if (ship_visible) {
+
2898  if (rep < 3) {
+
2899  window->FillRect(shiploc.x-2, shiploc.y-2, shiploc.x+2, shiploc.y+2, unit->MarkerColor());
+
2900  sprite_width = 2;
+
2901 
+
2902  char buf[256];
+
2903  sprintf_s(buf, "%s", unit->Name().data());
+
2904  window->SetFont(font);
+
2905  window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, buf);
+
2906  }
+
2907  else {
+
2908  int sprite_index = 2;
+
2909  int nsprites = 0;
+
2910 
+
2911  if (unit->GetDesign())
+
2912  nsprites = unit->GetDesign()->map_sprites.size();
+
2913 
+
2914  if (nsprites) {
+
2915  if (sprite_index < 0 || sprite_index >= nsprites)
+
2916  sprite_index = sprite_index % nsprites;
+
2917 
+
2918  Bitmap* map_sprite = unit->GetDesign()->map_sprites[sprite_index];
+
2919 
+
2920  Bitmap bmp;
+
2921  bmp.CopyBitmap(*map_sprite);
+
2922  ColorizeBitmap(bmp, unit->MarkerColor());
+
2923  sprite_width = bmp.Width()/2;
+
2924  int h = bmp.Height()/2;
+
2925 
+
2926  window->DrawBitmap(shiploc.x-sprite_width,
+
2927  shiploc.y-h,
+
2928  shiploc.x+sprite_width,
+
2929  shiploc.y+h,
+
2930  &bmp,
+ +
2932  }
+
2933 
+
2934  else {
+
2935  if (unit->IsStatic()) {
+
2936  window->FillRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, unit->MarkerColor());
+
2937  window->DrawRect(shiploc.x-6, shiploc.y-6, shiploc.x+6, shiploc.y+6, Color::White);
+
2938  }
+
2939  else if (unit->IsStarship()) {
+
2940  window->FillRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, unit->MarkerColor());
+
2941  window->DrawRect(shiploc.x-4, shiploc.y-4, shiploc.x+4, shiploc.y+4, Color::White);
+
2942  }
+
2943  else {
+
2944  window->FillRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, unit->MarkerColor());
+
2945  window->DrawRect(shiploc.x-3, shiploc.y-3, shiploc.x+3, shiploc.y+3, Color::White);
+
2946  }
+
2947  }
+
2948 
+
2949  char label[128];
+
2950  strcpy_s(label, unit->GetDescription());
+
2951  window->SetFont(font);
+
2952  window->Print(shiploc.x-sprite_width, shiploc.y+sprite_width+2, label);
+
2953  }
+
2954  }
+
2955  }
+
2956  }
+
2957 
+
2958  // recurse
+
2959  ListIter<CombatGroup> iter = group->GetComponents();
+
2960  while (++iter) {
+
2961  CombatGroup* g = iter.value();
+
2962  DrawCombatGroup(g, rep);
+
2963  }
+
2964 }
+
2965 
+
2966 // +--------------------------------------------------------------------+
+
2967 
+
2968 bool
+ +
2970 {
+
2971  // get leader:
+
2972  Ship* lead = test.GetLeader();
+
2973 
+
2974  if (lead == &test) // this is the leader:
+
2975  return false;
+
2976 
+
2977  // too close?
+
2978  if (lead) {
+
2979  POINT testloc, leadloc;
+
2980 
+
2981  GetShipLoc(test, testloc);
+
2982  GetShipLoc(*lead, leadloc);
+
2983 
+
2984  double dx = testloc.x - leadloc.x;
+
2985  double dy = testloc.y - leadloc.y;
+
2986  double d = dx*dx + dy*dy;
+
2987 
+
2988  if (d <= 64)
+
2989  return true;
+
2990  }
+
2991 
+
2992  return false;
+
2993 }
+
2994 
+
2995 // +--------------------------------------------------------------------+
+
2996 
+
2997 bool
+ +
2999 {
+
3000  POINT testloc, refloc;
+
3001  Sim* sim = Sim::GetSim();
+
3002  Orbital* rgn = regions[current_region];
+
3003  SimRegion* simrgn = sim->FindRegion(rgn->Name());
+
3004 
+
3005  if (simrgn) {
+
3006  GetShipLoc(test, testloc);
+
3007 
+
3008  ListIter<Ship> s = simrgn->Ships();
+
3009  while (++s) {
+
3010  Ship* ref = s.value();
+
3011 
+
3012  // too close?
+
3013  if (ref && ref != &test) {
+
3014  GetShipLoc(*ref, refloc);
+
3015 
+
3016  double dx = testloc.x - refloc.x;
+
3017  double dy = testloc.y - refloc.y;
+
3018  double d = dx*dx + dy*dy;
+
3019 
+
3020  if (d <= 64)
+
3021  return true;
+
3022  }
+
3023  }
+
3024  }
+
3025 
+
3026  return false;
+
3027 }
+
3028 
+
3029 void
+
3030 MapView::GetShipLoc(Ship& s, POINT& shiploc)
+
3031 {
+
3032  double cx = rect.w/2;
+
3033  double cy = rect.h/2;
+
3034 
+
3035  c = (cx<cy) ? cx : cy;
+
3036  r = system->Radius() * zoom;
+
3037 
+ +
3039 
+
3040  if (view_mode == VIEW_REGION) {
+
3041  if (!rgn) return;
+
3042  r = rgn->Radius() * zoom;
+
3043  }
+
3044 
+
3045  double scale = c/r;
+
3046 
+
3047  double ox = offset_x * scale;
+
3048  double oy = offset_y * scale;
+
3049 
+
3050  double rlx = 0;
+
3051  double rly = 0;
+
3052 
+
3053  if (view_mode == VIEW_SYSTEM) {
+
3054  rgn = system->ActiveRegion();
+
3055 
+
3056  if (rgn) {
+
3057  rlx = rgn->Location().x;
+
3058  rly = rgn->Location().y;
+
3059  }
+
3060  }
+
3061 
+
3062  if (view_mode == VIEW_SYSTEM ||
+
3063  (view_mode == VIEW_REGION && rgn == s.GetRegion()->GetOrbitalRegion())) {
+
3064  double sx = (s.Location().x + rlx) * scale;
+
3065  double sy = (s.Location().y + rly) * scale;
+
3066 
+
3067  shiploc.x = (int) (cx + sx + ox);
+
3068  shiploc.y = (int) (cy + sy + oy);
+
3069  }
+
3070  else {
+
3071  shiploc.x = -1;
+
3072  shiploc.y = -1;
+
3073  }
+
3074 }
+
3075 
+
3076 // +--------------------------------------------------------------------+
+
3077 
+
3078 bool
+ +
3080 {
+
3081  POINT testloc, refloc;
+
3082  Sim* sim = Sim::GetSim();
+
3083  Orbital* rgn = regions[current_region];
+
3084 
+
3085  if (mission) {
+
3086  GetElemLoc(test, testloc);
+
3087 
+ +
3089  while (++s) {
+
3090  MissionElement* ref = s.value();
+
3091 
+
3092  if (ref && ref != &test && !_stricmp(ref->Region(), rgn->Name())) {
+
3093  GetElemLoc(*ref, refloc);
+
3094 
+
3095  double dx = testloc.x - refloc.x;
+
3096  double dy = testloc.y - refloc.y;
+
3097  double d = dx*dx + dy*dy;
+
3098 
+
3099  if (d <= 64)
+
3100  return true;
+
3101  }
+
3102  }
+
3103  }
+
3104 
+
3105  return false;
+
3106 }
+
3107 
+
3108 void
+ +
3110 {
+
3111  double cx = rect.w/2;
+
3112  double cy = rect.h/2;
+
3113 
+
3114  c = (cx<cy) ? cx : cy;
+
3115  r = system->Radius() * zoom;
+
3116 
+ +
3118 
+
3119  if (view_mode == VIEW_REGION) {
+
3120  if (!rgn) return;
+
3121  r = rgn->Radius() * zoom;
+
3122  }
+
3123 
+
3124  double scale = c/r;
+
3125 
+
3126  double ox = offset_x * scale;
+
3127  double oy = offset_y * scale;
+
3128 
+
3129  double rlx = 0;
+
3130  double rly = 0;
+
3131 
+
3132  if (view_mode == VIEW_SYSTEM) {
+
3133  rgn = system->ActiveRegion();
+
3134 
+
3135  if (rgn) {
+
3136  rlx = rgn->Location().x;
+
3137  rly = rgn->Location().y;
+
3138  }
+
3139  }
+
3140 
+
3141  if (view_mode == VIEW_SYSTEM ||
+
3142  (view_mode == VIEW_REGION && !_stricmp(s.Region(), rgn->Name()))) {
+
3143  double sx = (s.Location().x + rlx) * scale;
+
3144  double sy = (s.Location().y + rly) * scale;
+
3145 
+
3146  shiploc.x = (int) (cx + sx + ox);
+
3147  shiploc.y = (int) (cy + sy + oy);
+
3148  }
+
3149  else {
+
3150  shiploc.x = -1;
+
3151  shiploc.y = -1;
+
3152  }
+
3153 }
+
3154 
+
3155 // +--------------------------------------------------------------------+
+
3156 
+ + +
3159 {
+
3160  OrbitalRegion* result = 0;
+
3161 
+
3162  if (current_region < regions.size())
+
3163  result = (OrbitalRegion*) regions[current_region];
+
3164 
+
3165  return result;
+
3166 }
+
3167 
+
3168 // +--------------------------------------------------------------------+
+
3169 
+
3170 void
+ +
3172 {
+
3173  zoom *= 0.9;
+
3174 
+
3175  if (view_mode == VIEW_SYSTEM) {
+
3176  if (system && zoom * system->Radius() < 2e6) {
+
3177  zoom = 2e6 / system->Radius();
+
3178  }
+
3179  }
+
3180  else if (view_mode == VIEW_REGION) {
+
3181  OrbitalRegion* rgn = GetRegion();
+
3182  if (rgn && zoom * rgn->Radius() < 1e3) {
+
3183  zoom = 1e3 / rgn->Radius();
+
3184  }
+
3185  }
+
3186 }
+
3187 
+
3188 void
+ +
3190 {
+
3191  zoom *= 1.1;
+
3192 
+
3193  if (view_mode == VIEW_SYSTEM) {
+
3194  if (system && zoom * system->Radius() > 500e9) {
+
3195  zoom = 500e9 / system->Radius();
+
3196  }
+
3197  }
+
3198  else if (view_mode == VIEW_REGION) {
+
3199  OrbitalRegion* rgn = GetRegion();
+
3200  if (rgn && zoom * rgn->Radius() > 1e6) {
+
3201  zoom = 1e6 / rgn->Radius();
+
3202  }
+
3203  }
+
3204 }
+
3205 
+
3206 // +--------------------------------------------------------------------+
+
3207 
+
3208 void
+ +
3210 {
+ +
3212  if (dispatch)
+
3213  dispatch->Register(this);
+
3214 }
+
3215 
+
3216 void
+ +
3218 {
+ +
3220  if (dispatch)
+
3221  dispatch->Unregister(this);
+
3222 
+
3223  if (captured) {
+
3224  ReleaseCapture();
+
3225  captured = false;
+
3226  Mouse::Show(true);
+
3227  }
+
3228 
+
3229  dragging = false;
+
3230 }
+
3231 
+
3232 // +--------------------------------------------------------------------+
+
3233 
+
3234 bool
+ +
3236 {
+
3237  if (active_window)
+
3238  return active_window->IsEnabled();
+
3239 
+
3240  return false;
+
3241 }
+
3242 
+
3243 bool
+ +
3245 {
+
3246  if (active_window)
+
3247  return active_window->IsVisible();
+
3248 
+
3249  return false;
+
3250 }
+
3251 
+
3252 bool
+ +
3254 {
+
3255  if (active_window)
+
3256  return active_window->IsFormActive();
+
3257 
+
3258  return false;
+
3259 }
+
3260 
+
3261 Rect
+ +
3263 {
+
3264  if (active_window)
+
3265  return active_window->TargetRect();
+
3266 
+
3267  return Rect();
+
3268 }
+
3269 
+
3270 // +--------------------------------------------------------------------+
+
3271 
+
3272 int
+ +
3274 {
+
3275  if (captured) {
+
3276  EventTarget* test = 0;
+ +
3278  if (dispatch)
+
3279  test = dispatch->GetCapture();
+
3280 
+
3281  if (test != this) {
+
3282  captured = false;
+
3283  Mouse::Show(true);
+
3284  }
+
3285 
+
3286  else {
+
3287  if (dragging) {
+
3288  int delta_x = x - mouse_x;
+
3289  int delta_y = y - mouse_y;
+
3290 
+
3291  offset_x += delta_x * r / c;
+
3292  offset_y += delta_y * r / c;
+
3293 
+
3294  Mouse::SetCursorPos(mouse_x, mouse_y);
+
3295  }
+
3296 
+
3297  else if (view_mode == VIEW_REGION) {
+
3298  double scale = r/c;
+
3299  click_x = (x - rect.x - rect.w/2) * scale - offset_x;
+
3300  click_y = (y - rect.y - rect.h/2) * scale - offset_y;
+
3301 
+
3302  if ((adding_navpt || moving_navpt) && current_navpt) {
+
3303  Point loc = current_navpt->Location();
+
3304  loc.x = click_x;
+
3305  loc.y = click_y;
+
3306  current_navpt->SetLocation(loc);
+ +
3308  }
+
3309 
+
3310  else if (editor && moving_elem && current_elem) {
+
3311  Point loc = current_elem->Location();
+
3312  loc.x = click_x;
+
3313  loc.y = click_y;
+
3314  current_elem->SetLocation(loc);
+
3315  }
+
3316  }
+
3317  }
+
3318  }
+
3319 
+
3320  return active_window->OnMouseMove(x,y);
+
3321 }
+
3322 
+
3323 // +--------------------------------------------------------------------+
+
3324 
+
3325 int
+ +
3327 {
+
3328  if (!captured)
+
3329  captured = SetCapture();
+
3330 
+
3331  if (captured) {
+
3332  dragging = true;
+
3333  mouse_x = x;
+
3334  mouse_y = y;
+
3335  Mouse::Show(false);
+
3336  }
+
3337 
+
3338  return active_window->OnRButtonDown(x, y);
+
3339 }
+
3340 
+
3341 // +--------------------------------------------------------------------+
+
3342 
+
3343 int
+ +
3345 {
+
3346  if (captured) {
+
3347  ReleaseCapture();
+
3348  captured = false;
+
3349  Mouse::Show(true);
+
3350  }
+
3351 
+
3352  dragging = false;
+
3353 
+
3354  return active_window->OnRButtonUp(x, y);
+
3355 }
+
3356 
+
3357 // +--------------------------------------------------------------------+
+
3358 
+ +
3360 {
+
3361  return active_window->OnClick();
+
3362 }
+
3363 
+
3364 int MapView::OnLButtonDown(int x, int y)
+
3365 {
+
3366  if (menu_view && menu_view->IsShown()) {
+
3367  // ignore this event...
+
3368  }
+
3369  else {
+
3370  if (!captured)
+
3371  captured = SetCapture();
+
3372 
+
3373  if (view_mode == VIEW_REGION) {
+
3374  double scale = r/c;
+
3375  click_x = (x - rect.x - rect.w/2) * scale - offset_x;
+
3376  click_y = (y - rect.y - rect.h/2) * scale - offset_y;
+
3377 
+
3378  if (current_navpt) {
+
3379  Point nloc = current_navpt->Location();
+
3380  double dx = nloc.x - click_x;
+
3381  double dy = nloc.y - click_y;
+
3382  double d = sqrt(dx*dx + dy*dy);
+
3383 
+
3384  if (d < 5e3) {
+
3385  moving_navpt = true;
+
3386 
+
3387  if (ship && current_ship && ship != current_ship) {
+
3388  if (ship->GetElement() && current_ship->GetElement()) {
+ +
3390  moving_navpt = false;
+
3391  }
+
3392  }
+
3393  }
+
3394  else if (current_elem && NetLobby::GetInstance()) {
+
3395  moving_navpt = false;
+
3396  }
+
3397  }
+
3398  }
+
3399 
+
3400  else if (editor && current_elem) {
+
3401  Point nloc = current_elem->Location();
+
3402  double dx = nloc.x - click_x;
+
3403  double dy = nloc.y - click_y;
+
3404  double d = sqrt(dx*dx + dy*dy);
+
3405 
+
3406  if (d < 5e3) {
+
3407  moving_elem = true;
+
3408 
+ +
3410  moving_elem = false;
+
3411  }
+
3412  }
+
3413  }
+
3414  }
+
3415  }
+
3416 
+
3417  return active_window->OnLButtonDown(x,y);
+
3418 }
+
3419 
+
3420 int MapView::OnLButtonUp(int x, int y)
+
3421 {
+
3422  bool process_event = false;
+
3423 
+
3424  if (captured) {
+
3425  process_event = true;
+
3426  ReleaseCapture();
+
3427  captured = false;
+
3428  Mouse::Show(true);
+
3429  }
+
3430 
+
3431  if (process_event && !adding_navpt) {
+
3432  if (!moving_navpt && !moving_elem) {
+ +
3434  }
+
3435 
+
3436  if (view_mode == VIEW_REGION) {
+
3437  double scale = r/c;
+
3438  click_x = (x - rect.x - rect.w/2) * scale - offset_x;
+
3439  click_y = (y - rect.y - rect.h/2) * scale - offset_y;
+
3440 
+
3441  if (!scrolling)
+
3442  SelectAt(x,y);
+
3443 
+ +
3445  }
+
3446 
+
3447  else if (!scrolling) {
+
3448  SelectAt(x,y);
+
3449 
+ +
3451  }
+
3452  }
+
3453 
+
3454  if ((adding_navpt || moving_navpt) && current_navpt) {
+ +
3456 
+
3457  Sim* sim = Sim::GetSim();
+
3458  if (sim) {
+
3459  Ship* s = current_ship;
+
3460 
+
3461  if (s && s->GetElement()) {
+
3462  Element* elem = s->GetElement();
+
3463  int index = elem->GetNavIndex(current_navpt);
+
3464 
+
3465  if (index >= 0)
+
3466  NetUtil::SendNavData(false, elem, index-1, current_navpt);
+
3467  }
+
3468  }
+
3469  }
+
3470 
+
3471  adding_navpt = false;
+
3472  moving_navpt = false;
+
3473  moving_elem = false;
+
3474 
+
3475  return active_window->OnLButtonUp(x,y);
+
3476 }
+
3477 
+
3478 
+
+
+ + + + -- cgit v1.1