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/_tactical_view_8cpp_source.html | 1612 ++++++++++++++++++++++ 1 file changed, 1612 insertions(+) create mode 100644 Doc/doxygen/html/_tactical_view_8cpp_source.html (limited to 'Doc/doxygen/html/_tactical_view_8cpp_source.html') diff --git a/Doc/doxygen/html/_tactical_view_8cpp_source.html b/Doc/doxygen/html/_tactical_view_8cpp_source.html new file mode 100644 index 0000000..cf6e041 --- /dev/null +++ b/Doc/doxygen/html/_tactical_view_8cpp_source.html @@ -0,0 +1,1612 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/TacticalView.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
TacticalView.cpp
+
+
+Go to the documentation of this file.
1 /* Project Starshatter 5.0
+
2  Destroyer Studios LLC
+
3  Copyright (C) 1997-2007. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: Stars.exe
+
6  FILE: TacticalView.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  View class for Tactical Data Readout HUD Overlay
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "TacticalView.h"
+
17 #include "QuantumView.h"
+
18 #include "RadioView.h"
+
19 #include "RadioMessage.h"
+
20 #include "RadioTraffic.h"
+
21 #include "HUDSounds.h"
+
22 #include "HUDView.h"
+
23 #include "WepView.h"
+
24 #include "CameraDirector.h"
+
25 #include "Ship.h"
+
26 #include "ShipCtrl.h"
+
27 #include "ShipDesign.h"
+
28 #include "QuantumDrive.h"
+
29 #include "Farcaster.h"
+
30 #include "Instruction.h"
+
31 #include "Element.h"
+
32 #include "Contact.h"
+
33 #include "Sim.h"
+
34 #include "Starshatter.h"
+
35 #include "GameScreen.h"
+
36 #include "MenuView.h"
+
37 
+
38 #include "Projector.h"
+
39 #include "Color.h"
+
40 #include "Window.h"
+
41 #include "Video.h"
+
42 #include "DataLoader.h"
+
43 #include "Scene.h"
+
44 #include "FontMgr.h"
+
45 #include "Keyboard.h"
+
46 #include "Mouse.h"
+
47 #include "MouseController.h"
+
48 #include "Menu.h"
+
49 #include "Game.h"
+
50 #include "FormatUtil.h"
+
51 
+
52 static Color hud_color = Color::Black;
+
53 static Color txt_color = Color::Black;
+
54 
+
55 // +--------------------------------------------------------------------+
+
56 
+ +
58 
+
59 // +--------------------------------------------------------------------+
+
60 
+ +
62 : View(c), gamescreen(parent), ship(0), camview(0), projector(0),
+
63 mouse_down(0), right_down(0), shift_down(0),
+
64 show_move(0), show_action(0), active_menu(0), menu_view(0),
+
65 msg_ship(0), base_alt(0), move_alt(0)
+
66 {
+
67  tac_view = this;
+
68  sim = Sim::GetSim();
+
69 
+
70  width = window->Width();
+
71  height = window->Height();
+
72  xcenter = (width / 2.0) - 0.5;
+
73  ycenter = (height / 2.0) + 0.5;
+
74  font = FontMgr::Find("HUD");
+
75 
+ +
77 
+
78  mouse_start.x = 0;
+
79  mouse_start.y = 0;
+
80  mouse_action.x = 0;
+
81  mouse_action.y = 0;
+
82 
+
83  menu_view = new(__FILE__,__LINE__) MenuView(window);
+
84 }
+
85 
+ +
87 {
+
88  delete menu_view;
+
89  tac_view = 0;
+
90 }
+
91 
+
92 void
+ +
94 {
+
95  width = window->Width();
+
96  height = window->Height();
+
97  xcenter = (width / 2.0) - 0.5;
+
98  ycenter = (height / 2.0) + 0.5;
+
99 
+
100  if (menu_view)
+ +
102 }
+
103 
+
104 // +--------------------------------------------------------------------+
+
105 
+
106 bool
+ +
108 {
+
109  if (obj == ship) {
+
110  ship = 0;
+
111  }
+
112 
+
113  if (obj == msg_ship) {
+
114  msg_ship = 0;
+
115  }
+
116 
+
117  return SimObserver::Update(obj);
+
118 }
+
119 
+
120 const char*
+ +
122 {
+
123  return "TacticalView";
+
124 }
+
125 
+
126 void
+ +
128 {
+
129  projector = p;
+
130 }
+
131 
+
132 // +--------------------------------------------------------------------+
+
133 
+
134 void
+ +
136 {
+
137  sim = Sim::GetSim();
+
138 
+
139  if (sim) {
+
140  bool rebuild = false;
+
141 
+
142  if (ship != sim->GetPlayerShip()) {
+
143  ship = sim->GetPlayerShip();
+
144 
+
145  if (ship) {
+
146  if (ship->Life() == 0 || ship->IsDying() || ship->IsDead()) {
+
147  ship = 0;
+
148  }
+
149  else {
+
150  Observe(ship);
+
151  }
+
152  }
+
153 
+
154  rebuild = true;
+
155  }
+
156 
+
157  if (ship) {
+
158  if (current_sector != ship->GetRegion()->Name())
+
159  rebuild = true;
+
160 
+
161  if (rebuild) {
+
162  BuildMenu();
+ +
164  }
+
165  }
+
166  }
+
167 
+
168  if (!ship || ship->InTransition())
+
169  return;
+
170 
+
171  DrawMouseRect();
+
172 
+
173  if (sim) {
+ +
175 
+
176  if (sel.size()) {
+
177  while (++sel) {
+
178  Ship* selection = sel.value();
+
179 
+
180  // draw selection rect on selected ship:
+
181  if (selection && selection->Rep())
+
182  DrawSelection(selection);
+
183  }
+
184 
+ + +
187 
+
188  if ((!rv || !rv->IsMenuShown()) && (!qv || !qv->IsMenuShown())) {
+
189  sel.reset();
+
190 
+
191  if (sel.size() == 1) {
+
192  DrawSelectionInfo(sel.next());
+
193  }
+
194  else {
+
195  DrawSelectionList(sel);
+
196  }
+
197  }
+
198  }
+
199  }
+
200 
+
201  DrawMenu();
+
202 
+
203  if (show_move) {
+
204  Mouse::Show(false);
+
205  DrawMove();
+
206  }
+
207  else if (show_action) {
+
208  Mouse::Show(false);
+
209  DrawAction();
+
210  }
+
211 }
+
212 
+
213 // +--------------------------------------------------------------------+
+
214 
+
215 void
+ +
217 {
+
218  HUDView* hud = HUDView::GetInstance();
+
219  if (hud) {
+
220  if (hud_color != hud->GetTextColor()) {
+
221  hud_color = hud->GetTextColor();
+
222  SetColor(hud_color);
+
223  }
+
224  }
+
225 }
+
226 
+
227 // +--------------------------------------------------------------------+
+
228 
+
229 void
+ +
231 {
+
232  HUDView* hud = HUDView::GetInstance();
+
233 
+
234  if (hud) {
+
235  hud_color = hud->GetHUDColor();
+
236  txt_color = hud->GetTextColor();
+
237  }
+
238  else {
+
239  hud_color = c;
+
240  txt_color = c;
+
241  }
+
242 }
+
243 
+
244 // +--------------------------------------------------------------------+
+
245 
+
246 void
+ +
248 {
+
249  if (mouse_rect.w > 0 && mouse_rect.h > 0) {
+
250  Color c = hud_color * 0.66;
+
251 
+
252  if (shift_down)
+
253  c = Color::Orange;
+
254 
+ +
256  }
+
257 }
+
258 
+
259 // +--------------------------------------------------------------------+
+
260 
+
261 void
+ +
263 {
+
264  if (!seln)
+
265  return;
+
266 
+
267  Graphic* g = seln->Rep();
+
268  Rect r = g->ScreenRect();
+
269 
+
270  Point mark_pt = seln->Location();
+
271 
+
272  projector->Transform(mark_pt);
+
273 
+
274  // clip:
+
275  if (mark_pt.z > 1.0) {
+
276  projector->Project(mark_pt);
+
277 
+
278  int x = (int) mark_pt.x;
+
279  int y = r.y;
+
280 
+
281  if (y >= 2000)
+
282  y = (int) mark_pt.y;
+
283 
+
284  if (x > 4 && x < width-4 &&
+
285  y > 4 && y < height-4) {
+
286 
+
287  const int BAR_LENGTH = 40;
+
288 
+
289  // life bars:
+
290  int sx = x - BAR_LENGTH/2;
+
291  int sy = y - 8;
+
292 
+
293  double hull_strength = seln->HullStrength() / 100.0;
+
294 
+
295  int hw = (int) (BAR_LENGTH * hull_strength);
+
296  int sw = (int) (BAR_LENGTH * (seln->ShieldStrength() / 100.0));
+
297 
+
298  if (hw < 0) hw = 0;
+
299  if (sw < 0) sw = 0;
+
300 
+ +
302 
+
303  if (hull_strength < 0.30) s = System::CRITICAL;
+
304  else if (hull_strength < 0.60) s = System::DEGRADED;
+
305 
+ +
307  Color sc = hud_color;
+
308 
+
309  window->FillRect(sx, sy, sx+hw, sy+1, hc);
+
310  window->FillRect(sx, sy+3, sx+sw, sy+4, sc);
+
311  }
+
312  }
+
313 }
+
314 
+
315 // +--------------------------------------------------------------------+
+
316 
+
317 void
+ +
319 {
+
320  if (!ship || !seln) return;
+
321 
+
322  Rect label_rect(width-140, 10, 90, 12);
+
323  Rect info_rect(width-100, 10, 90, 12);
+
324 
+
325  if (width >= 800) {
+
326  label_rect.x -= 20;
+
327  info_rect.x -= 20;
+
328  info_rect.w += 20;
+
329  }
+
330 
+
331  static char name[64];
+
332  static char design[64];
+
333  static char shield[32];
+
334  static char hull[32];
+
335  static char range[32];
+
336  static char heading[32];
+
337  static char speed[32];
+
338  static char orders[64];
+
339  static char psv[32];
+
340  static char act[32];
+
341 
+
342  int show_labels = width > 640;
+
343  int full_info = true;
+
344  int shield_val = seln->ShieldStrength();
+
345  int hull_val = seln->HullStrength();
+
346 
+
347  if (shield_val < 0) shield_val = 0;
+
348  if (hull_val < 0) hull_val = 0;
+
349 
+
350  sprintf_s(name, "%s", seln->Name());
+
351 
+
352  if (show_labels) {
+
353  sprintf_s(shield, "%s %03d", Game::GetText("HUDView.symbol.shield").data(), shield_val);
+
354  sprintf_s(hull, "%s %03d", Game::GetText("HUDView.symbol.hull").data(), hull_val);
+
355  }
+
356  else {
+
357  sprintf_s(shield, "%03d", shield_val);
+
358  sprintf_s(hull, "%03d", hull_val);
+
359  }
+
360 
+
361  FormatNumberExp(range, Point(seln->Location()-ship->Location()).length()/1000);
+
362  strcat_s(range, " km");
+
363  sprintf_s(heading, "%03d %s", (int) (seln->CompassHeading() / DEGREES), Game::GetText("HUDView.symbol.degrees").data());
+
364 
+
365  double ss = seln->Velocity().length();
+
366  if (seln->Velocity() * seln->Heading() < 0)
+
367  ss = -ss;
+
368 
+
369  FormatNumberExp(speed, ss);
+
370  strcat_s(speed, " m/s");
+
371 
+
372  Contact* contact = 0;
+
373 
+
374  // always recognize ownside:
+
375  if (seln->GetIFF() != ship->GetIFF()) {
+ +
377  while (++c) {
+
378  if (c->GetShip() == seln) {
+
379  contact = c.value();
+
380  if (c->GetIFF(ship) > seln->GetIFF()) {
+
381  sprintf_s(name, "%s %04d", Game::GetText("TacView.contact").data(), seln->GetContactID());
+
382  full_info = false;
+
383  }
+
384 
+
385  break;
+
386  }
+
387  }
+
388  }
+
389 
+
390  if (show_labels) {
+
391  font->SetColor(txt_color);
+
392  font->SetAlpha(1);
+
393 
+
394  font->DrawText(Game::GetText("TacView.name"), 5, label_rect, DT_LEFT);
+
395  label_rect.y += 10;
+
396  font->DrawText(Game::GetText("TacView.type"), 5, label_rect, DT_LEFT);
+
397  label_rect.y += 10;
+
398 
+
399  if (full_info) {
+
400  font->DrawText(Game::GetText("TacView.shield"), 5, label_rect, DT_LEFT);
+
401  label_rect.y += 10;
+
402  font->DrawText(Game::GetText("TacView.hull"), 5, label_rect, DT_LEFT);
+
403  label_rect.y += 10;
+
404  }
+
405 
+
406  font->DrawText(Game::GetText("TacView.range"), 4, label_rect, DT_LEFT);
+
407  label_rect.y += 10;
+
408 
+
409  if (full_info) {
+
410  font->DrawText(Game::GetText("TacView.speed"), 4, label_rect, DT_LEFT);
+
411  label_rect.y += 10;
+
412  font->DrawText(Game::GetText("TacView.heading"), 4, label_rect, DT_LEFT);
+
413  label_rect.y += 10;
+
414  }
+
415  else {
+
416  font->DrawText(Game::GetText("TacView.passive"), 4, label_rect, DT_LEFT);
+
417  label_rect.y += 10;
+
418  font->DrawText(Game::GetText("TacView.active"), 4, label_rect, DT_LEFT);
+
419  label_rect.y += 10;
+
420  }
+
421  }
+
422 
+
423  font->DrawText(name, 0, info_rect, DT_LEFT);
+
424  info_rect.y += 10;
+
425 
+
426  if (full_info) {
+
427  sprintf_s(design, "%s %s", seln->Abbreviation(), seln->Design()->display_name);
+
428  font->DrawText(design, 0, info_rect, DT_LEFT);
+
429  info_rect.y += 10;
+
430  }
+
431  else {
+
432  if (seln->IsStarship())
+
433  font->DrawText(Game::GetText("TacView.starship"), 8, info_rect, DT_LEFT);
+
434  else
+
435  font->DrawText(Game::GetText("TacView.fighter"), 7, info_rect, DT_LEFT);
+
436 
+
437  info_rect.y += 10;
+
438  }
+
439 
+
440  if (full_info) {
+
441  font->DrawText(shield, 0, info_rect, DT_LEFT);
+
442  info_rect.y += 10;
+
443 
+
444  font->DrawText(hull, 0, info_rect, DT_LEFT);
+
445  info_rect.y += 10;
+
446  }
+
447 
+
448  font->DrawText(range, 0, info_rect, DT_LEFT);
+
449  info_rect.y += 10;
+
450 
+
451  if (full_info) {
+
452  font->DrawText(speed, 0, info_rect, DT_LEFT);
+
453  info_rect.y += 10;
+
454 
+
455  font->DrawText(heading, 0, info_rect, DT_LEFT);
+
456  info_rect.y += 10;
+
457 
+
458  if (seln->GetIFF() == ship->GetIFF()) {
+
459  Instruction* instr = seln->GetRadioOrders();
+
460  if (instr && instr->Action()) {
+
461  strcpy_s(orders, RadioMessage::ActionName(instr->Action()));
+
462 
+
463  if (instr->Action() == RadioMessage::QUANTUM_TO) {
+
464  strcat_s(orders, " ");
+
465  strcat_s(orders, instr->RegionName());
+
466  }
+
467  }
+
468  else {
+
469  *orders = 0;
+
470  }
+
471 
+
472  if (*orders) {
+
473  if (show_labels) {
+
474  font->DrawText(Game::GetText("TacView.orders"), 5, label_rect, DT_LEFT);
+
475  label_rect.y += 10;
+
476  }
+
477 
+
478  font->DrawText(orders, 0, info_rect, DT_LEFT);
+
479  info_rect.y += 10;
+
480  }
+
481  }
+
482  }
+
483  else {
+
484  sprintf_s(psv, "%03d", (int) (contact->PasReturn() * 100.0));
+
485  sprintf_s(act, "%03d", (int) (contact->ActReturn() * 100.0));
+
486 
+
487  if (contact->Threat(ship))
+
488  strcat_s(psv, " !");
+
489 
+
490  font->DrawText(psv, 0, info_rect, DT_LEFT);
+
491  info_rect.y += 10;
+
492  font->DrawText(act, 0, info_rect, DT_LEFT);
+
493  info_rect.y += 10;
+
494  }
+
495 
+
496  /*** XXX DEBUG
+
497 font->DrawText(seln->GetDirectorInfo(), 0, info_rect, DT_LEFT);
+
498 info_rect.y += 10;
+
499 /***/
+
500 }
+
501 
+
502 // +--------------------------------------------------------------------+
+
503 
+
504 void
+ +
506 {
+
507  int index = 0;
+
508  Rect info_rect(width-100, 10, 90, 12);
+
509 
+
510  while (++seln) {
+
511  char name[64];
+
512  sprintf_s(name, "%s", seln->Name());
+
513 
+
514  // always recognize ownside:
+
515  if (seln->GetIFF() != ship->GetIFF()) {
+ +
517  while (++c) {
+
518  if (c->GetShip() == seln.value()) {
+
519  if (c->GetIFF(ship) > seln->GetIFF()) {
+
520  sprintf_s(name, "%s %04d", Game::GetText("TacView.contact").data(), seln->GetContactID());
+
521  }
+
522 
+
523  break;
+
524  }
+
525  }
+
526  }
+
527 
+
528  font->DrawText(name, 0, info_rect, DT_LEFT);
+
529  info_rect.y += 10;
+
530  index++;
+
531 
+
532  if (index >= 10)
+
533  break;
+
534  }
+
535 }
+
536 
+
537 // +--------------------------------------------------------------------+
+
538 
+
539 void
+ +
541 {
+
542  static DWORD rbutton_latch = 0;
+
543 
+ +
545 
+
546  if (stars->InCutscene())
+
547  return;
+
548 
+
549  if (Mouse::RButton()) {
+ +
551  if (!right_down && (!mouse_con || !mouse_con->Active())) {
+
552  rbutton_latch = Game::RealTime();
+
553  right_down = true;
+
554  }
+
555  }
+
556  else {
+
557  if (sim && right_down && (Game::RealTime() - rbutton_latch < 250)) {
+
558  Ship* seln = WillSelectAt(Mouse::X(), Mouse::Y());
+
559 
+
560  if (seln && sim->IsSelected(seln) &&
+
561  seln->GetIFF() == ship->GetIFF() &&
+
562  ship->GetElement()->CanCommand(seln->GetElement())) {
+
563 
+
564  msg_ship = seln;
+
565  Observe(msg_ship);
+
566  }
+
567 
+
568  else if (ship && seln == ship &&
+
569  (!ship->GetDirector() ||
+ +
571 
+
572  msg_ship = seln;
+
573  }
+
574 
+
575  else {
+
576  msg_ship = 0;
+
577  }
+
578  }
+
579 
+
580  right_down = false;
+
581  }
+
582 
+
583  if (menu_view)
+ +
585 
+ +
587 
+
588  if (!mouse_con || !mouse_con->Active()) {
+
589  if (Mouse::LButton()) {
+
590  if (!mouse_down) {
+
591  mouse_start.x = Mouse::X();
+
592  mouse_start.y = Mouse::Y();
+
593 
+
594  shift_down = Keyboard::KeyDown(VK_SHIFT);
+
595  }
+
596 
+
597  else {
+
598  if (Mouse::X() < mouse_start.x) {
+
599  mouse_rect.x = Mouse::X();
+ +
601  }
+
602  else {
+ + +
605  }
+
606 
+
607  if (Mouse::Y() < mouse_start.y) {
+
608  mouse_rect.y = Mouse::Y();
+ +
610  }
+
611  else {
+ + +
614  }
+
615 
+
616  // don't draw seln rectangle while zooming:
+
617  if (Mouse::RButton() || show_move || show_action) {
+
618  mouse_rect.w = 0;
+
619  mouse_rect.h = 0;
+
620  }
+
621 
+
622  else {
+ +
624  }
+
625  }
+
626 
+
627  mouse_down = true;
+
628  }
+
629 
+
630  else {
+
631  if (mouse_down) {
+
632  int mouse_x = Mouse::X();
+
633  int mouse_y = Mouse::Y();
+
634 
+
635  if (menu_view && menu_view->GetAction()) {
+ +
637  Mouse::Show(true);
+
638  }
+
639  else if (show_move) {
+
640  SendMove();
+
641  show_move = false;
+
642  Mouse::Show(true);
+
643  }
+
644  else if (show_action) {
+
645  SendAction();
+
646  show_action = false;
+
647  Mouse::Show(true);
+
648  }
+
649  else {
+ +
651  int dx = (int) fabs((double) (mouse_x - mouse_start.x));
+
652  int dy = (int) fabs((double) (mouse_y - mouse_start.y));
+
653 
+
654  static DWORD click_time = 0;
+
655 
+
656  if (dx < 3 && dy < 3) {
+
657  bool hit = SelectAt(mouse_x, mouse_y);
+
658 
+
659  if (ship->IsStarship() && Game::RealTime() - click_time < 350)
+
660  SetHelm(hit);
+
661 
+
662  click_time = Game::RealTime();
+
663  }
+
664  }
+
665  }
+
666 
+
667  mouse_rect = Rect();
+
668  mouse_down = false;
+
669  }
+
670  }
+
671  }
+
672 
+
673  if (show_action && !mouse_down && !right_down) {
+
674  mouse_action.x = Mouse::X();
+
675  mouse_action.y = Mouse::Y();
+
676  }
+
677 }
+
678 
+
679 // +--------------------------------------------------------------------+
+
680 
+
681 bool
+ +
683 {
+
684  if (!ship) return false;
+
685 
+
686  Ship* selection = WillSelectAt(x,y);
+
687 
+
688  if (selection && shift_down)
+
689  ship->SetTarget(selection);
+
690 
+
691  else if (sim && selection)
+
692  sim->SetSelection(selection);
+
693 
+
694  return selection != 0;
+
695 }
+
696 
+
697 // +--------------------------------------------------------------------+
+
698 
+
699 bool
+ +
701 {
+
702  bool result = false;
+
703 
+
704  if (!ship || !sim) return result;
+
705 
+
706  if (rect.w > 8 || rect.h > 8)
+
707  sim->ClearSelection();
+
708 
+
709  // check distance to each contact:
+
710  List<Contact>& contact_list = ship->ContactList();
+
711 
+
712  for (int i = 0; i < ship->NumContacts(); i++) {
+
713  Ship* test = contact_list[i]->GetShip();
+
714 
+
715  if (test && test != ship) {
+
716 
+
717  Point test_loc = test->Location();
+
718  projector->Transform(test_loc);
+
719 
+
720  if (test_loc.z > 1) {
+
721  projector->Project(test_loc);
+
722 
+
723  if (rect.Contains((int) test_loc.x, (int) test_loc.y)) {
+
724  // shift-select targets:
+
725  if (shift_down) {
+
726  if (test->GetIFF() == 0 || test->GetIFF() == ship->GetIFF())
+
727  continue;
+
728 
+
729  ship->SetTarget(test);
+
730  result = true;
+
731  }
+
732  else {
+
733  sim->AddSelection(test);
+
734  result = true;
+
735  }
+
736  }
+
737  }
+
738  }
+
739  }
+
740 
+
741  // select self only in orbit cam
+ +
743  Point test_loc = ship->Location();
+
744  projector->Transform(test_loc);
+
745 
+
746  if (test_loc.z > 1) {
+
747  projector->Project(test_loc);
+
748 
+
749  if (rect.Contains((int) test_loc.x, (int) test_loc.y)) {
+ +
751  result = true;
+
752  }
+
753  }
+
754  }
+
755 
+
756  return result;
+
757 }
+
758 
+
759 // +--------------------------------------------------------------------+
+
760 
+
761 Ship*
+ +
763 {
+
764  Ship* selection = 0;
+
765 
+
766  if (ship) {
+
767  // check distance to each contact:
+
768  List<Contact>& contact_list = ship->ContactList();
+
769 
+
770  for (int i = 0; i < ship->NumContacts(); i++) {
+
771  Ship* test = contact_list[i]->GetShip();
+
772 
+
773  if (test) {
+
774  // shift-select targets:
+
775  if (shift_down) {
+
776  if (test->GetIFF() == 0 || test->GetIFF() == ship->GetIFF())
+
777  continue;
+
778  }
+
779 
+
780  Graphic* g = test->Rep();
+
781  if (g) {
+
782  Rect r = g->ScreenRect();
+
783 
+
784  if (r.x == 2000 && r.y == 2000 && r.w == 0 && r.h == 0) {
+
785  if (projector) {
+
786  Point loc = test->Location();
+
787  projector->Transform(loc);
+
788  projector->Project(loc);
+
789 
+
790  r.x = (int) loc.x;
+
791  r.y = (int) loc.y;
+
792  }
+
793  }
+
794 
+
795  if (r.w < 20 || r.h < 20)
+
796  r.Inflate(20,20);
+
797  else
+
798  r.Inflate(10,10);
+
799 
+
800  if (r.Contains(x,y)) {
+
801  selection = test;
+
802  break;
+
803  }
+
804  }
+
805  }
+
806  }
+
807 
+
808  if (!selection && !shift_down) {
+
809  Graphic* g = ship->Rep();
+
810  if (g) {
+
811  Rect r = g->ScreenRect();
+
812 
+
813  if (r.Contains(x,y)) {
+
814  selection = ship;
+
815  }
+
816  }
+
817  }
+
818  }
+
819 
+ +
821  selection = 0;
+
822 
+
823  return selection;
+
824 }
+
825 
+
826 // +--------------------------------------------------------------------+
+
827 
+
828 void
+
829 TacticalView::SetHelm(bool approach)
+
830 {
+
831  Point delta;
+
832 
+
833  // double-click on ship: set helm to approach
+
834  if (sim && approach) {
+
835  ListIter<Ship> iter = sim->GetSelection();
+
836  ++iter;
+
837  Ship* selection = iter.value();
+
838 
+
839  if (selection != ship) {
+
840  delta = selection->Location() - ship->Location();
+
841  delta.Normalize();
+
842  }
+
843  }
+
844 
+
845  // double-click on space: set helm in direction
+
846  if (delta.length() < 1) {
+
847  int mx = Mouse::X();
+
848  int my = Mouse::Y();
+
849 
+
850  if (projector) {
+
851  double focal_dist = width / tan(projector->XAngle());
+
852 
+
853  delta = projector->vpn() * focal_dist +
+
854  projector->vup() * -1 * (my-height/2) +
+
855  projector->vrt() * (mx-width/2);
+
856 
+
857  delta.Normalize();
+
858  }
+
859 
+
860  else {
+
861  return;
+
862  }
+
863  }
+
864 
+
865  double az = atan2(fabs(delta.x), delta.z);
+
866  double el = asin(delta.y);
+
867 
+
868  if (delta.x < 0)
+
869  az *= -1;
+
870 
+
871  az += PI;
+
872 
+
873  if (az >= 2*PI)
+
874  az -= 2*PI;
+
875 
+
876  ship->SetHelmHeading(az);
+
877  ship->SetHelmPitch(el);
+
878 }
+
879 
+
880 // +====================================================================+
+
881 //
+
882 // TACTICAL COMMUNICATIONS MENU:
+
883 //
+
884 
+
885 static Menu* main_menu = 0;
+
886 static Menu* view_menu = 0;
+
887 static Menu* emcon_menu = 0;
+
888 
+
889 static Menu* fighter_menu = 0;
+
890 static Menu* starship_menu = 0;
+
891 static Menu* action_menu = 0;
+
892 static Menu* formation_menu = 0;
+
893 static Menu* sensors_menu = 0;
+
894 static Menu* quantum_menu = 0;
+
895 static Menu* farcast_menu = 0;
+
896 
+
897 static Element* dst_elem = 0;
+
898 
+
899 enum VIEW_MENU {
+
900  VIEW_FORWARD = 1000,
+ + + + + + + + + +
910 };
+
911 
+
912 const int QUANTUM = 2000;
+
913 const int FARCAST = 2001;
+
914 
+
915 void
+ +
917 {
+
918  static int initialized = 0;
+
919  if (initialized) return;
+
920 
+
921  view_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.view"));
+
922  view_menu->AddItem(Game::GetText("TacView.item.forward"), VIEW_FORWARD);
+
923  view_menu->AddItem(Game::GetText("TacView.item.chase"), VIEW_CHASE);
+
924  view_menu->AddItem(Game::GetText("TacView.item.orbit"), VIEW_ORBIT);
+
925  view_menu->AddItem(Game::GetText("TacView.item.padlock"), VIEW_PADLOCK);
+
926 
+
927  emcon_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.emcon"));
+
928 
+
929  quantum_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.quantum"));
+
930  farcast_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.farcast"));
+
931 
+
932  main_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.main"));
+
933 
+
934  action_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.action"));
+
935  action_menu->AddItem(Game::GetText("TacView.item.engage"), RadioMessage::ATTACK);
+
936  action_menu->AddItem(Game::GetText("TacView.item.bracket"), RadioMessage::BRACKET);
+
937  action_menu->AddItem(Game::GetText("TacView.item.escort"), RadioMessage::ESCORT);
+
938  action_menu->AddItem(Game::GetText("TacView.item.identify"), RadioMessage::IDENTIFY);
+
939  action_menu->AddItem(Game::GetText("TacView.item.hold"), RadioMessage::WEP_HOLD);
+
940 
+
941  formation_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.formation"));
+
942  formation_menu->AddItem(Game::GetText("TacView.item.diamond"), RadioMessage::GO_DIAMOND);
+
943  formation_menu->AddItem(Game::GetText("TacView.item.spread"), RadioMessage::GO_SPREAD);
+
944  formation_menu->AddItem(Game::GetText("TacView.item.box"), RadioMessage::GO_BOX);
+
945  formation_menu->AddItem(Game::GetText("TacView.item.trail"), RadioMessage::GO_TRAIL);
+
946 
+
947  sensors_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.emcon"));
+
948  sensors_menu->AddItem(Game::GetText("TacView.item.emcon-1"), RadioMessage::GO_EMCON1);
+
949  sensors_menu->AddItem(Game::GetText("TacView.item.emcon-2"), RadioMessage::GO_EMCON2);
+
950  sensors_menu->AddItem(Game::GetText("TacView.item.emcon-3"), RadioMessage::GO_EMCON3);
+
951  sensors_menu->AddItem(Game::GetText("TacView.item.probe"), RadioMessage::LAUNCH_PROBE);
+
952 
+
953  fighter_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.context"));
+
954  fighter_menu->AddMenu(Game::GetText("TacView.item.action"), action_menu);
+
955  fighter_menu->AddMenu(Game::GetText("TacView.item.formation"), formation_menu);
+
956  fighter_menu->AddMenu(Game::GetText("TacView.item.sensors"), sensors_menu);
+
957  fighter_menu->AddItem(Game::GetText("TacView.item.patrol"), RadioMessage::MOVE_PATROL);
+
958  fighter_menu->AddItem(Game::GetText("TacView.item.cancel"), RadioMessage::RESUME_MISSION);
+
959  fighter_menu->AddItem("", 0);
+
960  fighter_menu->AddItem(Game::GetText("TacView.item.rtb"), RadioMessage::RTB);
+
961  fighter_menu->AddItem(Game::GetText("TacView.item.dock"), RadioMessage::DOCK_WITH);
+
962  fighter_menu->AddMenu(Game::GetText("TacView.item.farcast"), farcast_menu);
+
963 
+
964  starship_menu = new(__FILE__,__LINE__) Menu(Game::GetText("TacView.menu.context"));
+
965  starship_menu->AddMenu(Game::GetText("TacView.item.action"), action_menu);
+
966  starship_menu->AddMenu(Game::GetText("TacView.item.sensors"), sensors_menu);
+
967  starship_menu->AddItem(Game::GetText("TacView.item.patrol"), RadioMessage::MOVE_PATROL);
+
968  starship_menu->AddItem(Game::GetText("TacView.item.cancel"), RadioMessage::RESUME_MISSION);
+
969  starship_menu->AddItem("", 0);
+
970  starship_menu->AddMenu(Game::GetText("TacView.item.quantum"), quantum_menu);
+
971  starship_menu->AddMenu(Game::GetText("TacView.item.farcast"), farcast_menu);
+
972 
+
973  initialized = 1;
+
974 }
+
975 
+
976 void
+ +
978 {
+
979  delete view_menu;
+
980  delete emcon_menu;
+
981  delete main_menu;
+
982  delete fighter_menu;
+
983  delete starship_menu;
+
984  delete action_menu;
+
985  delete formation_menu;
+
986  delete sensors_menu;
+
987  delete quantum_menu;
+
988  delete farcast_menu;
+
989 }
+
990 
+
991 // +--------------------------------------------------------------------+
+
992 
+
993 void
+ +
995 {
+ +
997 
+
998  switch (action) {
+ +
1000  show_move = true;
+
1001  base_alt = 0;
+
1002  move_alt = 0;
+
1003 
+
1004  if (msg_ship) base_alt = msg_ship->Location().y;
+
1005  break;
+
1006 
+
1007  case RadioMessage::ATTACK:
+
1008  case RadioMessage::BRACKET:
+
1009  case RadioMessage::ESCORT:
+ + +
1012  show_action = action;
+
1013  break;
+
1014 
+ + +
1017  case RadioMessage::RTB:
+ + +
1020  case RadioMessage::GO_BOX:
+ + + + + +
1026  if (msg_ship) {
+
1027  Element* elem = msg_ship->GetElement();
+
1028  RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(elem, ship, action);
+
1029  if (msg)
+ +
1031  }
+
1032  else if (ship) {
+
1033  if (action == RadioMessage::GO_EMCON1)
+
1034  ship->SetEMCON(1);
+
1035  else if (action == RadioMessage::GO_EMCON2)
+
1036  ship->SetEMCON(2);
+
1037  else if (action == RadioMessage::GO_EMCON3)
+
1038  ship->SetEMCON(3);
+
1039  else if (action == RadioMessage::LAUNCH_PROBE)
+
1040  ship->LaunchProbe();
+
1041  }
+
1042  break;
+
1043 
+ +
1045  case VIEW_CHASE: stars->PlayerCam(CameraDirector::MODE_CHASE); break;
+
1046  case VIEW_PADLOCK: stars->PlayerCam(CameraDirector::MODE_TARGET); break;
+
1047  case VIEW_ORBIT: stars->PlayerCam(CameraDirector::MODE_ORBIT); break;
+
1048 
+
1049  case VIEW_NAV: gamescreen->ShowNavDlg(); break;
+
1050  case VIEW_WEP: gamescreen->ShowWeaponsOverlay(); break;
+
1051  case VIEW_ENG: gamescreen->ShowEngDlg(); break;
+
1052  case VIEW_INS: HUDView::GetInstance()->CycleHUDInst(); break;
+
1053  case VIEW_FLT: gamescreen->ShowFltDlg(); break;
+
1054 
+
1055  case VIEW_CMD: if (ship && ship->IsStarship()) {
+
1056  ship->CommandMode();
+
1057  }
+
1058  break;
+
1059 
+
1060  case QUANTUM: if (sim) {
+
1061  Ship* s = msg_ship;
+
1062 
+
1063  if (!s)
+
1064  s = ship;
+
1065 
+
1066  if (s && s->GetQuantumDrive()) {
+
1067  QuantumDrive* quantum = s->GetQuantumDrive();
+
1068  if (quantum) {
+
1069  MenuItem* menu_item = menu_view->GetMenuItem();
+
1070  Text rgn_name = menu_item->GetText();
+
1071  SimRegion* rgn = sim->FindRegion(rgn_name);
+
1072 
+
1073  if (rgn) {
+
1074  if (s == ship) {
+
1075  quantum->SetDestination(rgn, Point(0,0,0));
+
1076  quantum->Engage();
+
1077  }
+
1078 
+
1079  else {
+
1080  Element* elem = msg_ship->GetElement();
+
1081  RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(elem, ship, RadioMessage::QUANTUM_TO);
+
1082  if (msg) {
+
1083  msg->SetInfo(rgn_name);
+ +
1085  }
+
1086  }
+
1087  }
+
1088  }
+
1089  }
+
1090  }
+
1091  break;
+
1092 
+
1093  case FARCAST: if (sim && msg_ship) {
+
1094  MenuItem* menu_item = menu_view->GetMenuItem();
+
1095  Text rgn_name = menu_item->GetText();
+
1096  SimRegion* rgn = sim->FindRegion(rgn_name);
+
1097 
+
1098  if (rgn) {
+
1099  Element* elem = msg_ship->GetElement();
+
1100  RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(elem, ship, RadioMessage::FARCAST_TO);
+
1101  if (msg) {
+
1102  msg->SetInfo(rgn_name);
+ +
1104  }
+
1105  }
+
1106  }
+
1107  break;
+
1108 
+
1109  default:
+
1110  break;
+
1111  }
+
1112 }
+
1113 
+
1114 // +--------------------------------------------------------------------+
+
1115 
+
1116 void
+ +
1118 {
+
1119  main_menu->ClearItems();
+
1120  quantum_menu->ClearItems();
+
1121  farcast_menu->ClearItems();
+
1122  emcon_menu->ClearItems();
+
1123 
+
1124  if (!ship)
+
1125  return;
+
1126 
+
1127  // prepare quantum and farcast menus:
+ +
1129  while (++iter) {
+
1130  SimRegion* rgn = iter.value();
+
1131  if (rgn != ship->GetRegion() && rgn->Type() != SimRegion::AIR_SPACE)
+
1132  quantum_menu->AddItem(rgn->Name(), QUANTUM);
+
1133  }
+
1134 
+
1135  if (ship->GetRegion()) {
+
1136  ListIter<Ship> iter = ship->GetRegion()->Ships();
+
1137  while (++iter) {
+
1138  Ship* s = iter.value();
+
1139 
+
1140  if (s && s->GetFarcaster()) {
+
1141  Farcaster* farcaster = s->GetFarcaster();
+
1142 
+
1143  // ensure that the farcaster is connected:
+
1144  farcaster->ExecFrame(0);
+
1145 
+
1146  // now find the destination
+
1147  const Ship* dest = farcaster->GetDest();
+
1148 
+
1149  if (dest && dest->GetRegion()) {
+
1150  SimRegion* rgn = dest->GetRegion();
+
1151  farcast_menu->AddItem(rgn->Name(), FARCAST);
+
1152  }
+
1153  }
+
1154  }
+
1155  }
+
1156 
+
1157  // build the main menu:
+
1158  main_menu->AddMenu(Game::GetText("TacView.item.camera"), view_menu);
+
1159  main_menu->AddItem("", 0);
+
1160  main_menu->AddItem(Game::GetText("TacView.item.instructions"), VIEW_INS);
+
1161  main_menu->AddItem(Game::GetText("TacView.item.navigation"), VIEW_NAV);
+
1162 
+
1163  if (ship->Design()->repair_screen)
+
1164  main_menu->AddItem(Game::GetText("TacView.item.engineering"), VIEW_ENG);
+
1165 
+
1166  if (ship->Design()->wep_screen)
+
1167  main_menu->AddItem(Game::GetText("TacView.item.weapons"), VIEW_WEP);
+
1168 
+
1169  if (ship->NumFlightDecks() > 0)
+
1170  main_menu->AddItem(Game::GetText("TacView.item.flight"), VIEW_FLT);
+
1171 
+
1172  emcon_menu->AddItem(Game::GetText("TacView.item.emcon-1"), RadioMessage::GO_EMCON1);
+
1173  emcon_menu->AddItem(Game::GetText("TacView.item.emcon-2"), RadioMessage::GO_EMCON2);
+
1174  emcon_menu->AddItem(Game::GetText("TacView.item.emcon-3"), RadioMessage::GO_EMCON3);
+
1175 
+
1176  if (ship->GetProbeLauncher())
+
1177  emcon_menu->AddItem(Game::GetText("TacView.item.probe"), RadioMessage::LAUNCH_PROBE);
+
1178 
+
1179  main_menu->AddItem("", 0);
+
1180  main_menu->AddMenu(Game::GetText("TacView.item.sensors"), emcon_menu);
+
1181 
+
1182  if (sim && ship->GetQuantumDrive()) {
+
1183  main_menu->AddItem("", 0);
+
1184  main_menu->AddMenu(Game::GetText("TacView.item.quantum"), quantum_menu);
+
1185  }
+
1186 
+
1187  if (ship->IsStarship()) {
+
1188  main_menu->AddItem("", 0);
+
1189  main_menu->AddItem(Game::GetText("TacView.item.command"), VIEW_CMD);
+
1190  }
+
1191 }
+
1192 
+
1193 // +--------------------------------------------------------------------+
+
1194 
+
1195 void
+ +
1197 {
+
1198  active_menu = 0;
+
1199 
+
1200  if (ship)
+
1201  active_menu = main_menu;
+
1202 
+
1203  if (msg_ship) {
+
1204  if (msg_ship->IsStarship())
+
1205  active_menu = starship_menu;
+
1206  else if (msg_ship->IsDropship())
+
1207  active_menu = fighter_menu;
+
1208  }
+
1209 
+
1210  if (menu_view) {
+
1211  menu_view->SetBackColor(hud_color);
+
1212  menu_view->SetTextColor(txt_color);
+ +
1214  menu_view->Refresh();
+
1215  }
+
1216 }
+
1217 
+
1218 // +--------------------------------------------------------------------+
+
1219 
+
1220 bool
+ +
1222 {
+
1223  int mx = Mouse::X();
+
1224  int my = Mouse::Y();
+
1225 
+
1226  if (projector) {
+
1227  double focal_dist = width / tan(projector->XAngle());
+
1228  Point focal_vect = projector->vpn() * focal_dist +
+
1229  projector->vup() * -1 * (my-height/2) +
+
1230  projector->vrt() * (mx-width/2);
+
1231 
+
1232  focal_vect.Normalize();
+
1233 
+
1234  if (Keyboard::KeyDown(VK_SHIFT)) {
+
1235  if (Mouse::RButton())
+
1236  return true;
+
1237 
+
1238  if (fabs(focal_vect.x) > fabs(focal_vect.z)) {
+
1239  double dx = move_loc.x - projector->Pos().x;
+
1240  double t = -1 * ((projector->Pos().x - dx) / focal_vect.x);
+
1241 
+
1242  if (t > 0) {
+
1243  Point p = projector->Pos() + focal_vect * t;
+
1244  move_alt = p.y - base_alt;
+
1245  }
+
1246  }
+
1247  else {
+
1248  double dz = move_loc.z - projector->Pos().z;
+
1249  double t = -1 * ((projector->Pos().z - dz) / focal_vect.z);
+
1250  Point p = projector->Pos() + focal_vect * t;
+
1251 
+
1252  if (t > 0) {
+
1253  Point p = projector->Pos() + focal_vect * t;
+
1254  move_alt = p.y - base_alt;
+
1255  }
+
1256  }
+
1257 
+
1258  if (move_alt > 25e3)
+
1259  move_alt = 25e3;
+
1260  else if (move_alt < -25e3)
+
1261  move_alt = -25e3;
+
1262 
+
1263  return true;
+
1264  }
+
1265  else {
+
1266  if (fabs(focal_vect.y) > 1e-5) {
+
1267  if (Mouse::RButton())
+
1268  return true;
+
1269 
+
1270  bool clamp = false;
+
1271  double t = -1 * ((projector->Pos().y - base_alt) / focal_vect.y);
+
1272 
+
1273  while (t <= 0 && my < height-1) {
+
1274  my++;
+
1275  clamp = true;
+
1276 
+
1277  focal_vect = projector->vpn() * focal_dist +
+
1278  projector->vup() * -1 * (my-height/2) +
+
1279  projector->vrt() * (mx-width/2);
+
1280 
+
1281  focal_vect.Normalize();
+
1282  t = -1 * ((projector->Pos().y - base_alt) / focal_vect.y);
+
1283  }
+
1284 
+
1285  if (t > 0) {
+
1286  if (clamp)
+
1287  Mouse::SetCursorPos(mx, my);
+
1288 
+
1289  move_loc = projector->Pos() + focal_vect * t;
+
1290  }
+
1291 
+
1292  return true;
+
1293  }
+
1294  }
+
1295  }
+
1296 
+
1297  return false;
+
1298 }
+
1299 
+
1300 void
+ +
1302 {
+
1303  if (!projector || !show_move || !msg_ship) return;
+
1304 
+
1305  Point origin = msg_ship->Location();
+
1306 
+
1307  if (GetMouseLoc3D()) {
+
1308  Point dest = move_loc;
+
1309 
+
1310  double distance = (dest - origin).length();
+
1311 
+
1312  projector->Transform(origin);
+
1313  projector->Project(origin);
+
1314 
+
1315  int x0 = (int) origin.x;
+
1316  int y0 = (int) origin.y;
+
1317 
+
1318  projector->Transform(dest);
+
1319  projector->Project(dest);
+
1320 
+
1321  int x = (int) dest.x;
+
1322  int y = (int) dest.y;
+
1323 
+
1324  window->DrawEllipse(x-10, y-10, x+10, y+10, Color::White);
+
1325  window->DrawLine(x0, y0, x, y, Color::White);
+
1326 
+
1327  char range[32];
+
1328  Rect range_rect(x+12, y-8, 120, 20);
+
1329 
+
1330  if (fabs(move_alt) > 1) {
+
1331  dest = move_loc;
+
1332  dest.y += move_alt;
+
1333  distance = (dest - msg_ship->Location()).length();
+
1334 
+
1335  projector->Transform(dest);
+
1336  projector->Project(dest);
+
1337 
+
1338  int x1 = (int) dest.x;
+
1339  int y1 = (int) dest.y;
+
1340 
+
1341  window->DrawEllipse(x1-10, y1-10, x1+10, y1+10, Color::White);
+
1342  window->DrawLine(x0, y0, x1, y1, Color::White);
+
1343  window->DrawLine(x1, y1, x, y, Color::White);
+
1344 
+
1345  range_rect.x = x1+12;
+
1346  range_rect.y = y1-8;
+
1347  }
+
1348 
+
1349  FormatNumber(range, distance);
+ +
1351  font->DrawText(range, 0, range_rect, DT_LEFT | DT_SINGLELINE);
+
1352  font->SetColor(txt_color);
+
1353  }
+
1354 }
+
1355 
+
1356 void
+ +
1358 {
+
1359  if (!projector || !show_move || !msg_ship) return;
+
1360 
+
1361  if (GetMouseLoc3D()) {
+
1362  Element* elem = msg_ship->GetElement();
+
1363  RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(elem, ship, RadioMessage::MOVE_PATROL);
+
1364  Point dest = move_loc;
+
1365  dest.y += move_alt;
+
1366  msg->SetLocation(dest);
+ + +
1369  }
+
1370 }
+
1371 
+
1372 // +--------------------------------------------------------------------+
+
1373 
+
1374 static int invalid_action = false;
+
1375 
+
1376 void
+ +
1378 {
+
1379  if (!projector || !show_action || !msg_ship) return;
+
1380 
+
1381  Point origin = msg_ship->Location();
+
1382  projector->Transform(origin);
+
1383  projector->Project(origin);
+
1384 
+
1385  int x0 = (int) origin.x;
+
1386  int y0 = (int) origin.y;
+
1387 
+
1388  int mx = mouse_action.x;
+
1389  int my = mouse_action.y;
+
1390  int r = 10;
+
1391 
+
1392  int enemy = 2;
+
1393  if (ship->GetIFF() > 1)
+
1394  enemy = 1;
+
1395 
+
1396  Ship* tgt = WillSelectAt(mx, my);
+
1397  int tgt_iff = 0;
+
1398 
+
1399  if (tgt)
+
1400  tgt_iff = tgt->GetIFF();
+
1401 
+
1402  Color c = Color::White;
+
1403 
+
1404  switch (show_action) {
+
1405  case RadioMessage::ATTACK:
+
1406  case RadioMessage::BRACKET:
+
1407  c = Ship::IFFColor(enemy);
+
1408  if (tgt) {
+
1409  if (tgt_iff == ship->GetIFF() || tgt_iff == 0)
+
1410  r = 0;
+
1411  }
+
1412  break;
+
1413 
+
1414  case RadioMessage::ESCORT:
+ +
1416  c = ship->MarkerColor();
+
1417  if (tgt) {
+
1418  if (tgt_iff == enemy)
+
1419  r = 0;
+
1420 
+
1421  // must have a hangar to dock with...
+
1422  if (show_action == RadioMessage::DOCK_WITH && tgt->GetHangar() == 0)
+
1423  r = 0;
+
1424  }
+
1425  break;
+
1426 
+
1427  default:
+
1428  if (tgt) {
+
1429  if (tgt_iff == ship->GetIFF())
+
1430  r = 0;
+
1431  }
+
1432  break;
+
1433  }
+
1434 
+
1435  if (tgt && r) {
+
1436  if ((Game::RealTime()/200) & 1)
+
1437  r = 20;
+
1438  else
+
1439  r = 15;
+
1440  }
+
1441 
+
1442  if (r) {
+
1443  invalid_action = false;
+
1444  window->DrawEllipse(mx-r, my-r, mx+r, my+r, c);
+
1445  }
+
1446 
+
1447  else {
+
1448  invalid_action = true;
+
1449  window->DrawLine(mx-10, my-10, mx+10, my+10, c);
+
1450  window->DrawLine(mx+10, my-10, mx-10, my+10, c);
+
1451  }
+
1452 
+
1453  window->DrawLine(x0, y0, mx, my, c);
+
1454 }
+
1455 
+
1456 void
+ +
1458 {
+
1459  if (!show_action || !msg_ship || invalid_action) {
+ +
1461  return;
+
1462  }
+
1463 
+
1464  int mx = mouse_action.x;
+
1465  int my = mouse_action.y;
+
1466 
+
1467  Ship* tgt = WillSelectAt(mx, my);
+
1468 
+
1469  if (tgt) {
+
1470  Element* elem = msg_ship->GetElement();
+
1471  RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(elem, ship, show_action);
+
1472 
+
1473  /***
+
1474  Element* tgt_elem = tgt->GetElement();
+
1475 
+
1476  if (tgt_elem) {
+
1477  for (int i = 1; i <= tgt_elem->NumShips(); i++)
+
1478  msg->AddTarget(tgt_elem->GetShip(i));
+
1479  }
+
1480  else {
+
1481  msg->AddTarget(tgt);
+
1482  }
+
1483  ***/
+
1484 
+
1485  msg->AddTarget(tgt);
+
1486 
+ + +
1489  }
+
1490  else {
+ +
1492  }
+
1493 }
+
1494 
+
1495 
+
+
+ + + + -- cgit v1.1