Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
WepView.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: WepView.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  View class for Tactical HUD Overlay
13 */
14 
15 #include "MemDebug.h"
16 #include "WepView.h"
17 #include "HUDView.h"
18 #include "HUDSounds.h"
19 #include "Ship.h"
20 #include "Computer.h"
21 #include "NavSystem.h"
22 #include "Drive.h"
23 #include "Power.h"
24 #include "Shield.h"
25 #include "Contact.h"
26 #include "ShipDesign.h"
27 #include "Shot.h"
28 #include "Drone.h"
29 #include "Weapon.h"
30 #include "Sim.h"
31 #include "StarSystem.h"
32 #include "WeaponGroup.h"
33 
34 #include "CameraView.h"
35 #include "Color.h"
36 #include "Window.h"
37 #include "Video.h"
38 #include "Screen.h"
39 #include "DataLoader.h"
40 #include "Scene.h"
41 #include "FontMgr.h"
42 #include "Graphic.h"
43 #include "Keyboard.h"
44 #include "Mouse.h"
45 #include "Game.h"
46 #include "FormatUtil.h"
47 
48 static Bitmap tac_left;
49 static Bitmap tac_right;
50 static Bitmap tac_button;
51 static Bitmap tac_man;
52 static Bitmap tac_aut;
53 static Bitmap tac_def;
54 
55 static BYTE* tac_left_shade;
56 static BYTE* tac_right_shade;
57 static BYTE* tac_button_shade;
58 static BYTE* tac_man_shade;
59 static BYTE* tac_aut_shade;
60 static BYTE* tac_def_shade;
61 
62 static Color hud_color = Color::Black;
63 static Color txt_color = Color::Black;
64 
65 static bool mouse_in = false;
66 
67 static Font* hud_font = 0;
68 static Font* big_font = 0;
69 
70 // +--------------------------------------------------------------------+
71 
73 
74 // +--------------------------------------------------------------------+
75 
77 : View(c), sim(0), ship(0), target(0), active_region(0),
78 transition(false), mode(0), mouse_down(0)
79 {
80  wep_view = this;
81 
82  sim = Sim::GetSim();
83 
84  HUDView::PrepareBitmap("TAC_left.pcx", tac_left, tac_left_shade);
85  HUDView::PrepareBitmap("TAC_right.pcx", tac_right, tac_right_shade);
86  HUDView::PrepareBitmap("TAC_button.pcx", tac_button, tac_button_shade);
87  HUDView::PrepareBitmap("MAN.pcx", tac_man, tac_man_shade);
88  HUDView::PrepareBitmap("AUTO.pcx", tac_aut, tac_aut_shade);
89  HUDView::PrepareBitmap("DEF.pcx", tac_def, tac_def_shade);
90 
96 
97  OnWindowMove();
98 
99  hud_font = FontMgr::Find("HUD");
100  big_font = FontMgr::Find("GUI");
101 
103  if (hud)
105 }
106 
108 {
109  tac_left.ClearImage();
110  tac_right.ClearImage();
111  tac_button.ClearImage();
112  tac_man.ClearImage();
113  tac_aut.ClearImage();
114  tac_def.ClearImage();
115 
116  delete [] tac_left_shade;
117  delete [] tac_right_shade;
118  delete [] tac_button_shade;
119  delete [] tac_man_shade;
120  delete [] tac_aut_shade;
121  delete [] tac_def_shade;
122 
123  tac_left_shade = 0;
124  tac_right_shade = 0;
125  tac_button_shade = 0;
126  tac_man_shade = 0;
127  tac_aut_shade = 0;
128  tac_def_shade = 0;
129 
130  wep_view = 0;
131 }
132 
133 void
135 {
136  width = window->Width();
137  height = window->Height();
138  xcenter = (width / 2.0) - 0.5;
139  ycenter = (height / 2.0) + 0.5;
140 
141  int btn_loc = width/2 - 147 - 45;
142  int man_loc = width/2 - 177 - 16;
143  int aut_loc = width/2 - 145 - 16;
144  int def_loc = width/2 - 115 - 16;
145 
146  int index = 0;
147 
148  for (int i = 0; i < MAX_WEP; i++) {
149  btn_rect[index++] = Rect(btn_loc, 30, 90, 20);
150  btn_rect[index++] = Rect(man_loc, 56, 32, 8);
151  btn_rect[index++] = Rect(aut_loc, 56, 32, 8);
152  btn_rect[index++] = Rect(def_loc, 56, 32, 8);
153 
154  btn_loc += 98;
155  man_loc += 98;
156  aut_loc += 98;
157  def_loc += 98;
158  }
159 }
160 
161 // +--------------------------------------------------------------------+
162 
163 bool
165 {
166  if (obj == ship) {
167  ship = 0;
168  target = 0;
169  }
170  else if (obj == target) {
171  target = 0;
172  }
173 
174  return SimObserver::Update(obj);
175 }
176 
177 const char*
179 {
180  return "WepView";
181 }
182 
183 // +--------------------------------------------------------------------+
184 
185 void
187 {
188  sim = Sim::GetSim();
189  if (!sim || !hud || hud->GetHUDMode() == HUDView::HUD_MODE_OFF)
190  return;
191 
192  if (ship != sim->GetPlayerShip()) {
193  ship = sim->GetPlayerShip();
194 
195  if (ship) {
196  if (ship->Life() == 0 || ship->IsDying() || ship->IsDead()) {
197  ship = 0;
198  }
199  else {
200  Observe(ship);
201  }
202  }
203  }
204 
205  if (mode < 1)
206  return;
207 
208  if (ship) {
209  // no tactical overlay for fighters:
210  if (ship->Design() && !ship->Design()->wep_screen) {
211  mode = 0;
212  return;
213  }
214 
215  // no hud in transition:
216  if (ship->InTransition()) {
217  transition = true;
218  return;
219  }
220 
221  else if (transition) {
222  transition = false;
223  RestoreOverlay();
224  }
225 
226  if (target != ship->GetTarget()) {
227  target = ship->GetTarget();
228  if (target) Observe(target);
229  }
230 
231  DrawOverlay();
232  }
233  else {
234  if (target) {
235  target = 0;
236  }
237  }
238 }
239 
240 // +--------------------------------------------------------------------+
241 
242 void
244 {
245  int hud_mode = 1;
246 
247  // update the position of HUD elements that are
248  // part of the 3D scene (like fpm and lcos sprites)
249 
250  if (hud) {
251  if (hud_color != hud->GetHUDColor()) {
252  hud_color = hud->GetHUDColor();
253  SetColor(hud_color);
254  }
255 
257  hud_mode = 0;
258  }
259 
260  if (ship && !transition && mode > 0 && hud_mode > 0) {
261  if (mode > 0) {
262  DoMouseFrame();
263  }
264  }
265 }
266 
267 // +--------------------------------------------------------------------+
268 
269 void
271 {
272  if (mode != m) {
273  mode = m;
274 
275  if (hud)
277 
278  RestoreOverlay();
279  }
280 }
281 
282 void
284 {
286 }
287 
288 void
290 {
291  if (mode > 0) {
293  }
294 
295  else {
297  }
298 }
299 
300 // +--------------------------------------------------------------------+
301 
302 void
304 {
306 
307  if (hud) {
308  hud_color = hud->GetHUDColor();
309  txt_color = hud->GetTextColor();
310  }
311  else {
312  hud_color = c;
313  txt_color = c;
314  }
315 
316  HUDView::ColorizeBitmap(tac_left, tac_left_shade, hud_color);
317  HUDView::ColorizeBitmap(tac_right, tac_right_shade, hud_color);
318  HUDView::ColorizeBitmap(tac_button, tac_button_shade, hud_color);
319  HUDView::ColorizeBitmap(tac_man, tac_man_shade, hud_color);
320  HUDView::ColorizeBitmap(tac_aut, tac_aut_shade, hud_color);
321  HUDView::ColorizeBitmap(tac_def, tac_def_shade, hud_color);
322 }
323 
324 // +--------------------------------------------------------------------+
325 
326 void
328 {
329  int cx = width/2;
330  int cy = 0;
331  int w = tac_left.Width();
332  int h = tac_left.Height();
333 
334  window->DrawBitmap(cx-w, cy, cx, cy+h, &tac_left, Video::BLEND_ALPHA);
335  window->DrawBitmap(cx, cy, cx+w, cy+h, &tac_right, Video::BLEND_ALPHA);
336 
337  if (ship) {
338  List<WeaponGroup>& weapons = ship->Weapons();
339  for (int i = 0; i < MAX_WEP; i++) {
340  if (weapons.size() > i) {
341  // draw main fire button:
342  Rect r = btn_rect[i*4];
343 
344  w = tac_button.Width();
345  h = tac_button.Height();
346  cx = r.x + r.w/2 - w/2;
347  cy = r.y + r.h/2 - h/2;
348 
349  r.Deflate(5,5);
350 
351  big_font->SetColor(txt_color);
352  window->SetFont(big_font);
353  window->DrawBitmap(cx, cy, cx+w, cy+h, &tac_button, Video::BLEND_ALPHA);
354  window->DrawText(weapons[i]->Name(), 0, r, DT_SINGLELINE | DT_CENTER);
355 
356  r.Inflate(5,5);
357 
358  // draw firing orders:
359  int o = weapons[i]->GetFiringOrders();
360  w = tac_man.Width();
361  h = tac_man.Height();
362 
363  Color c0 = Color::Gray;
364  Color c1 = Color::White;
365 
366  r = btn_rect[i*4 + 1];
367  cx = r.x + r.w/2 - w/2;
368  cy = r.y + r.h/2 - h/2;
369  window->FadeBitmap(cx, cy, cx+w, cy+h, &tac_man, (o==0 ? c1 : c0), Video::BLEND_ALPHA);
370 
371  r = btn_rect[i*4 + 2];
372  cx = r.x + r.w/2 - w/2;
373  cy = r.y + r.h/2 - h/2;
374  window->FadeBitmap(cx, cy, cx+w, cy+h, &tac_aut, (o==1 ? c1 : c0), Video::BLEND_ALPHA);
375 
376  r = btn_rect[i*4 + 3];
377  cx = r.x + r.w/2 - w/2;
378  cy = r.y + r.h/2 - h/2;
379  window->FadeBitmap(cx, cy, cx+w, cy+h, &tac_def, (o==2 ? c1 : c0), Video::BLEND_ALPHA);
380  }
381  }
382 
383  Rect tgt_rect;
384  tgt_rect.x = width/2 + 73;
385  tgt_rect.y = 74;
386  tgt_rect.w = 100;
387  tgt_rect.h = 15;
388 
389  Text subtxt;
390  Color stat = hud_color;
391  static DWORD blink = Game::RealTime();
392 
393  if (ship->GetTarget()) {
394  if (ship->GetSubTarget()) {
395  int blink_delta = Game::RealTime() - blink;
396 
397  System* sys = ship->GetSubTarget();
398  subtxt = sys->Abbreviation();
399  switch (sys->Status()) {
400  case System::DEGRADED: stat = Color(255,255, 0); break;
401  case System::CRITICAL:
402  case System::DESTROYED: stat = Color(255, 0, 0); break;
403  case System::MAINT:
404  if (blink_delta < 250)
405  stat = Color(8,8,8);
406  break;
407  }
408 
409  if (blink_delta > 500)
410  blink = Game::RealTime();
411  }
412 
413  else
414  subtxt = ship->GetTarget()->Name();
415  }
416  else {
417  subtxt = "NO TGT";
418  }
419 
420  subtxt.toUpper();
421 
422  hud_font->SetColor(stat);
423  window->SetFont(hud_font);
424  window->DrawText(subtxt.data(), subtxt.length(), tgt_rect, DT_SINGLELINE | DT_CENTER);
425  }
426 }
427 
428 // +--------------------------------------------------------------------+
429 
430 void
432 {
433  static int mouse_down = false;
434  static int mouse_down_x = 0;
435  static int mouse_down_y = 0;
436 
437  int x = Mouse::X();
438  int y = Mouse::Y();
439 
440  // coarse-grained test: is mouse in overlay at all?
441  if (x < width/2-256 || x > width/2+256 || y > 90) {
442  mouse_in = false;
443  return;
444  }
445 
446  mouse_in = true;
447 
448  if (Mouse::LButton()) {
449  if (!mouse_down) {
450  mouse_down = true;
451  mouse_down_x = x;
452  mouse_down_y = y;
453  }
454 
455  // check weapons buttons:
456  int max_wep = ship->Weapons().size();
457 
458  if (max_wep > MAX_WEP)
459  max_wep = MAX_WEP;
460 
461  for (int i = 0; i < max_wep; i++) {
462  int index = i * 4;
463 
464  if (CheckButton(index, mouse_down_x, mouse_down_y)) {
465  ship->FireWeapon(i);
466  return;
467  }
468 
469  else if (CheckButton(index + 1, mouse_down_x, mouse_down_y)) {
470  ship->Weapons()[i]->SetFiringOrders(Weapon::MANUAL);
471  return;
472  }
473 
474  else if (CheckButton(index + 2, mouse_down_x, mouse_down_y)) {
475  ship->Weapons()[i]->SetFiringOrders(Weapon::AUTO);
476  return;
477  }
478 
479  else if (CheckButton(index + 3, mouse_down_x, mouse_down_y)) {
480  ship->Weapons()[i]->SetFiringOrders(Weapon::POINT_DEFENSE);
481  return;
482  }
483  }
484  }
485 
486  else if (mouse_down) {
487  mouse_down = false;
488  mouse_down_x = 0;
489  mouse_down_y = 0;
490 
491  // check subtarget buttons:
492  if (ship->GetTarget()) {
493  Rect r(width/2+50, 70, 20, 20);
494  if (r.Contains(x,y)) {
495  CycleSubTarget(-1);
496  return;
497  }
498 
499  r.x = width/2 + 180;
500  if (r.Contains(x,y)) {
501  CycleSubTarget(1);
502  return;
503  }
504  }
505  }
506 }
507 
508 bool
509 WepView::CheckButton(int index, int x, int y)
510 {
511  if (index >= 0 && index < MAX_BTN) {
512  return btn_rect[index].Contains(x,y)?true:false;
513  }
514 
515  return false;
516 }
517 
518 void
520 {
521  if (ship->GetTarget() == 0 || ship->GetTarget()->Type() != SimObject::SIM_SHIP)
522  return;
523 
524  ship->CycleSubTarget(direction);
525 }
526 
527 bool
529 {
530  return mouse_in;
531 }