From b829170121d3657369904ec62d8065606777a9ce Mon Sep 17 00:00:00 2001 From: Aki Date: Fri, 1 Oct 2021 18:54:04 +0200 Subject: Removed doxygen generated docs They can be rebuild anytime and are considered a build artifact/binary. --- Doc/doxygen/html/_flight_deck_8cpp_source.html | 1303 ------------------------ 1 file changed, 1303 deletions(-) delete mode 100644 Doc/doxygen/html/_flight_deck_8cpp_source.html (limited to 'Doc/doxygen/html/_flight_deck_8cpp_source.html') diff --git a/Doc/doxygen/html/_flight_deck_8cpp_source.html b/Doc/doxygen/html/_flight_deck_8cpp_source.html deleted file mode 100644 index c81e714..0000000 --- a/Doc/doxygen/html/_flight_deck_8cpp_source.html +++ /dev/null @@ -1,1303 +0,0 @@ - - - - - -Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/FlightDeck.cpp Source File - - - - - - - - - - - - - -
-
- - - - - - -
-
Starshatter_Open -
-
Open source Starshatter engine
-
-
- - - - - -
-
- -
-
-
- -
- - - - -
- -
- -
-
-
FlightDeck.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: FlightDeck.cpp
-
7  AUTHOR: John DiCamillo
-
8 
-
9 
-
10  OVERVIEW
-
11  ========
-
12  Everything needed to launch and recover space craft...
-
13 */
-
14 
-
15 #include "MemDebug.h"
-
16 #include "FlightDeck.h"
-
17 #include "Ship.h"
-
18 #include "ShipCtrl.h"
-
19 #include "ShipDesign.h"
-
20 #include "Element.h"
-
21 #include "Mission.h"
-
22 #include "MissionEvent.h"
-
23 #include "Drive.h"
-
24 #include "Sim.h"
-
25 #include "Instruction.h"
-
26 #include "Hoop.h"
-
27 #include "LandingGear.h"
-
28 #include "RadioMessage.h"
-
29 #include "RadioTraffic.h"
-
30 #include "SimEvent.h"
-
31 #include "AudioConfig.h"
-
32 #include "CameraDirector.h"
-
33 #include "Combatant.h"
-
34 #include "CombatGroup.h"
-
35 #include "CombatUnit.h"
-
36 
-
37 #include "NetData.h"
-
38 #include "NetUtil.h"
-
39 
-
40 #include "Game.h"
-
41 #include "Solid.h"
-
42 #include "Light.h"
-
43 #include "Sound.h"
-
44 #include "DataLoader.h"
-
45 
-
46 static Sound* tire_sound = 0;
-
47 static Sound* catapult_sound = 0;
-
48 
-
49 // +======================================================================+
-
50 
- -
52 {
-
53 public:
-
54  FlightDeckSlot() : ship(0), state(0), sequence(0), time(0), filter(0xf) { }
-
55  int operator == (const FlightDeckSlot& that) const { return this == &that; }
-
56 
- - - -
60 
-
61  int state;
-
62  int sequence;
-
63  double time;
-
64  double clearance;
-
65  DWORD filter;
-
66 };
-
67 
-
68 // +======================================================================+
-
69 
-
70 InboundSlot::InboundSlot(Ship* s, FlightDeck* d, int squad, int index)
-
71 : ship(s), deck(d), squadron(squad), slot(index), cleared(0), final(0), approach(0)
-
72 {
-
73  if (ship)
-
74  Observe(ship);
-
75 
-
76  if (deck && deck->GetCarrier())
-
77  Observe((SimObject*) deck->GetCarrier());
-
78 }
-
79 
-
80 int InboundSlot::operator < (const InboundSlot& that) const
-
81 {
-
82  double dthis = 0;
-
83  double dthat = 0;
-
84 
-
85  if (ship == that.ship) {
-
86  return false;
-
87  }
-
88 
-
89  if (cleared && !that.cleared) {
-
90  return true;
-
91  }
-
92 
-
93  if (!cleared && that.cleared) {
-
94  return false;
-
95  }
-
96 
-
97  if (ship && deck && that.ship) {
-
98  dthis = Point(ship->Location() - deck->MountLocation()).length();
-
99  dthat = Point(that.ship->Location() - deck->MountLocation()).length();
-
100  }
-
101 
-
102  if (dthis == dthat) {
-
103  return (DWORD) this < (DWORD) &that;
-
104  }
-
105 
-
106  return dthis < dthat;
-
107 }
-
108 
- -
110 {
-
111  double dthis = 0;
-
112  double dthat = 0;
-
113 
-
114  if (ship == that.ship)
-
115  return true;
-
116 
-
117  if (cleared && !that.cleared)
-
118  return true;
-
119 
-
120  if (!cleared && that.cleared)
-
121  return false;
-
122 
-
123  if (ship && deck && that.ship) {
-
124  dthis = Point(ship->Location() - deck->MountLocation()).length();
-
125  dthat = Point(that.ship->Location() - deck->MountLocation()).length();
-
126  }
-
127 
-
128  return dthis <= dthat;
-
129 }
-
130 
- -
132 {
-
133  return this == &that;
-
134 }
-
135 
-
136 void InboundSlot::Clear(bool c)
-
137 {
-
138  if (ship)
-
139  cleared = c;
-
140 }
-
141 
- -
143 {
-
144  if (ship && deck) {
-
145  return Point(ship->Location() - deck->MountLocation()).length();
-
146  }
-
147 
-
148  return 1e9;
-
149 }
-
150 
-
151 // +----------------------------------------------------------------------+
-
152 
-
153 bool
- -
155 {
-
156  if (obj->Type() == SimObject::SIM_SHIP) {
-
157  Ship* s = (Ship*) obj;
-
158 
-
159  if (s == ship) {
-
160  ship = 0;
-
161  }
-
162 
-
163  // Actually, this can't happen. The flight deck
-
164  // owns the slot. When the carrier is destroyed,
-
165  // the flight decks and slots are destroyed before
-
166  // the carrier updates the observers.
-
167 
-
168  // I'm leaving this block in, just in case.
-
169 
-
170  else if (deck && s == deck->GetCarrier()) {
-
171  ship = 0;
-
172  deck = 0;
-
173  }
-
174  }
-
175 
-
176  return SimObserver::Update(obj);
-
177 }
-
178 
-
179 const char*
- -
181 {
-
182  return "InboundSlot";
-
183 }
-
184 
-
185 // +======================================================================+
-
186 
- -
188 : System(FLIGHT_DECK, FLIGHT_DECK_LAUNCH, "Flight Deck", 1, 1),
-
189 carrier(0), index(0), num_slots(0), slots(0), cycle_time(5), num_hoops(0), hoops(0),
-
190 azimuth(0), light(0), num_catsounds(0), num_approach_pts(0)
-
191 {
-
192  name = Game::GetText("sys.flight-deck");
-
193  abrv = Game::GetText("sys.flight-deck.abrv");
-
194 }
-
195 
-
196 // +----------------------------------------------------------------------+
-
197 
- -
199 : System(s),
-
200 carrier(0), index(0), start_rel(s.start_rel),
-
201 end_rel(s.end_rel), cam_rel(s.cam_rel),
-
202 cycle_time(s.cycle_time),
-
203 num_slots(s.num_slots), slots(0),
-
204 num_hoops(0), hoops(0), azimuth(s.azimuth), light(0),
-
205 num_catsounds(0), num_approach_pts(s.num_approach_pts)
-
206 {
-
207  Mount(s);
-
208 
-
209  slots = new(__FILE__,__LINE__) FlightDeckSlot[num_slots];
-
210  for (int i = 0; i < num_slots; i++) {
-
211  slots[i].spot_rel = s.slots[i].spot_rel;
-
212  slots[i].filter = s.slots[i].filter;
-
213  }
-
214 
-
215  for (int i = 0; i < NUM_APPROACH_PTS; i++)
-
216  approach_rel[i] = s.approach_rel[i];
-
217 
-
218  for (int i = 0; i < 2; i++)
-
219  runway_rel[i] = s.runway_rel[i];
-
220 
-
221  if (s.light) {
-
222  light = new(__FILE__,__LINE__) Light(*s.light);
-
223  }
-
224 }
-
225 
-
226 // +--------------------------------------------------------------------+
-
227 
- -
229 {
-
230  if (hoops && num_hoops) {
-
231  for (int i = 0; i < num_hoops; i++) {
-
232  Hoop* h = &hoops[i];
-
233  Scene* scene = h->GetScene();
-
234  if (scene)
-
235  scene->DelGraphic(h);
-
236  }
-
237  }
-
238 
-
239  delete [] slots;
-
240  delete [] hoops;
-
241 
- -
243 
- -
245 }
-
246 
-
247 // +--------------------------------------------------------------------+
-
248 
-
249 void
- -
251 {
-
252  static int initialized = 0;
-
253  if (initialized) return;
-
254 
-
255  DataLoader* loader = DataLoader::GetLoader();
-
256  loader->SetDataPath("Sounds/");
-
257 
-
258  const int SOUND_FLAGS = Sound::LOCALIZED |
- -
260 
-
261  loader->LoadSound("Tires.wav", tire_sound, SOUND_FLAGS);
-
262  loader->LoadSound("Catapult.wav", catapult_sound, SOUND_FLAGS);
-
263  loader->SetDataPath(0);
-
264 
-
265  if (tire_sound)
-
266  tire_sound->SetMaxDistance(2.5e3f);
-
267 
-
268  if (catapult_sound)
-
269  catapult_sound->SetMaxDistance(0.5e3f);
-
270 
-
271  initialized = 1;
-
272 }
-
273 
-
274 // +--------------------------------------------------------------------+
-
275 
-
276 void
- -
278 {
-
279  delete tire_sound;
-
280  delete catapult_sound;
-
281 
-
282  tire_sound = 0;
-
283  catapult_sound = 0;
-
284 }
-
285 
-
286 // +--------------------------------------------------------------------+
-
287 
-
288 void
-
289 FlightDeck::ExecFrame(double seconds)
-
290 {
-
291  System::ExecFrame(seconds);
-
292 
-
293  bool advance_queue = false;
-
294  long max_vol = AudioConfig::EfxVolume();
-
295  long volume = -1000;
-
296  Sim* sim = Sim::GetSim();
-
297 
-
298  if (volume > max_vol)
-
299  volume = max_vol;
-
300 
-
301  // update ship status:
-
302  for (int i = 0; i < num_slots; i++) {
-
303  FlightDeckSlot* slot = &slots[i];
-
304  Ship* slot_ship = 0;
-
305 
-
306  if (slot->ship == 0) {
-
307  slot->state = CLEAR;
-
308  }
-
309  else {
-
310  slot_ship = slot->ship;
-
311  slot_ship->SetThrottle(0);
-
312  }
-
313 
-
314  switch (slot->state) {
-
315  case CLEAR:
-
316  if (slot->time > 0) {
-
317  slot->time -= seconds;
-
318  }
-
319  else if (IsRecoveryDeck()) {
-
320  GrantClearance();
-
321  }
-
322  break;
-
323 
-
324  case READY: {
-
325  Camera c;
-
326  c.Clone(carrier->Cam());
-
327  c.Yaw(azimuth);
-
328 
-
329  if (slot_ship) {
-
330  slot_ship->CloneCam(c);
-
331  slot_ship->MoveTo(slot->spot_loc);
-
332  slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance);
-
333  slot_ship->SetVelocity(carrier->Velocity());
-
334  }
-
335  slot->time = 0;
-
336  }
-
337  break;
-
338 
-
339  case QUEUED:
-
340  if (slot->time > 0) {
-
341  Camera c;
-
342  c.Clone(carrier->Cam());
-
343  c.Yaw(azimuth);
-
344 
-
345  slot->time -= seconds;
-
346  if (slot_ship) {
-
347  slot_ship->CloneCam(c);
-
348  slot_ship->MoveTo(slot->spot_loc);
-
349  slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance);
-
350  slot_ship->SetFlightPhase(Ship::ALERT);
-
351  }
-
352  }
-
353 
-
354  if (slot->sequence == 1 && slot->time <= 0) {
-
355  bool clear_for_launch = true;
-
356  for (int i = 0; i < num_slots; i++)
-
357  if (slots[i].state == LOCKED)
-
358  clear_for_launch = false;
-
359 
-
360  if (clear_for_launch) {
-
361  slot->sequence = 0;
-
362  slot->state = LOCKED;
-
363  slot->time = cycle_time;
-
364  if (slot_ship)
-
365  slot_ship->SetFlightPhase(Ship::LOCKED);
-
366  num_catsounds = 0;
-
367 
-
368  advance_queue = true;
-
369  }
-
370  }
-
371  break;
-
372 
-
373  case LOCKED:
-
374  if (slot->time > 0) {
-
375  slot->time -= seconds;
-
376 
-
377  if (slot_ship) {
-
378  double ct4 = cycle_time/4;
-
379 
-
380  double dx = start_rel.x - slot->spot_rel.x;
-
381  double dy = start_rel.z - slot->spot_rel.z;
-
382  double dyaw = atan2(dx,dy) - azimuth;
-
383 
-
384  Camera c;
-
385  c.Clone(carrier->Cam());
-
386  c.Yaw(azimuth);
-
387 
-
388  // rotate:
-
389  if (slot->time > 3*ct4) {
-
390  double step = 1 - (slot->time - 3*ct4) / ct4;
-
391  c.Yaw(dyaw * step);
-
392  slot_ship->CloneCam(c);
-
393  slot_ship->MoveTo(slot->spot_loc);
-
394  slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance);
-
395 
-
396  if (carrier->IsGroundUnit()) {
-
397  slot_ship->SetThrottle(25);
-
398  }
-
399 
-
400  else if (num_catsounds < 1) {
-
401  if (catapult_sound) {
-
402  Sound* sound = catapult_sound->Duplicate();
-
403  sound->SetLocation(slot_ship->Location());
-
404  sound->SetVolume(volume);
-
405  sound->Play();
-
406  }
-
407  num_catsounds = 1;
-
408  }
-
409  }
-
410 
-
411  // translate:
-
412  else if (slot->time > 2*ct4) {
-
413  double step = (slot->time - 2*ct4) / ct4;
-
414 
-
415  Point loc = start_point +
-
416  (slot->spot_loc - start_point) * step;
-
417 
-
418  c.Yaw(dyaw);
-
419  slot_ship->CloneCam(c);
-
420  slot_ship->MoveTo(loc);
-
421  slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance);
-
422 
-
423  if (carrier->IsGroundUnit()) {
-
424  slot_ship->SetThrottle(25);
-
425  }
-
426 
-
427  else if (num_catsounds < 2) {
-
428  if (catapult_sound) {
-
429  Sound* sound = catapult_sound->Duplicate();
-
430  sound->SetLocation(slot_ship->Location());
-
431  sound->SetVolume(volume);
-
432  sound->Play();
-
433  }
-
434  num_catsounds = 2;
-
435  }
-
436  }
-
437 
-
438  // rotate:
-
439  else if (slot->time > ct4) {
-
440  double step = (slot->time - ct4) / ct4;
-
441  c.Yaw(dyaw*step);
-
442  slot_ship->CloneCam(c);
-
443  slot_ship->MoveTo(start_point);
-
444  slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance);
-
445 
-
446  if (carrier->IsGroundUnit()) {
-
447  slot_ship->SetThrottle(25);
-
448  }
-
449 
-
450  else if (num_catsounds < 3) {
-
451  if (catapult_sound) {
-
452  Sound* sound = catapult_sound->Duplicate();
-
453  sound->SetLocation(slot_ship->Location());
-
454  sound->SetVolume(volume);
-
455  sound->Play();
-
456  }
-
457  num_catsounds = 3;
-
458  }
-
459  }
-
460 
-
461  // wait:
-
462  else {
-
463  slot_ship->SetThrottle(100);
-
464  slot_ship->CloneCam(c);
-
465  slot_ship->MoveTo(start_point);
-
466  slot_ship->TranslateBy(carrier->Cam().vup() * slot->clearance);
-
467  }
-
468 
-
469  slot_ship->SetFlightPhase(Ship::LOCKED);
-
470  }
-
471  }
-
472  else {
-
473  slot->state = LAUNCH;
-
474  slot->time = 0;
-
475 
-
476  }
-
477  break;
-
478 
-
479  case LAUNCH:
-
480  LaunchShip(slot_ship);
-
481  break;
-
482 
-
483  case DOCKING:
-
484  if (slot_ship && !slot_ship->IsAirborne()) {
-
485  // do arresting gear stuff:
-
486  if (slot_ship->GetFlightModel() == Ship::FM_ARCADE)
-
487  slot_ship->ArcadeStop();
-
488 
-
489  slot_ship->SetVelocity(carrier->Velocity());
-
490  }
-
491 
-
492  if (slot->time > 0) {
-
493  slot->time -= seconds;
-
494  }
-
495  else {
-
496  if (slot_ship) {
-
497  slot_ship->SetFlightPhase(Ship::DOCKED);
-
498  slot_ship->Stow();
-
499 
- -
501  }
-
502 
-
503  Clear(i);
-
504  }
-
505  break;
-
506 
-
507  default:
-
508  break;
-
509  }
-
510  }
-
511 
-
512  if (advance_queue) {
-
513  for (int i = 0; i < num_slots; i++) {
-
514  FlightDeckSlot* slot = &slots[i];
-
515  if (slot->state == QUEUED && slot->sequence > 1)
-
516  slot->sequence--;
-
517  }
-
518  }
-
519 }
-
520 
-
521 bool
- -
523 {
-
524  FlightDeckSlot* slot = 0;
-
525  Sim* sim = Sim::GetSim();
-
526 
-
527  if (slot_ship) {
-
528  for (int i = 0; i < num_slots; i++) {
-
529  if (slots[i].ship == slot_ship)
-
530  slot = &(slots[i]);
-
531  }
-
532 
-
533  // only suggest a launch point if no flight plan has been filed...
-
534  if (slot_ship->GetElement()->FlightPlanLength() == 0) {
-
535  Point departure = end_point;
-
536  departure = departure.OtherHand();
-
537 
-
538  Instruction* launch_point = new(__FILE__,__LINE__)
- -
540  launch_point->SetSpeed(350);
-
541 
-
542  slot_ship->SetLaunchPoint(launch_point);
-
543  }
-
544 
-
545  if (!slot_ship->IsAirborne()) {
-
546  Point cat;
-
547  if (fabs(azimuth) < 5*DEGREES) {
-
548  cat = carrier->Heading() * 300;
-
549  }
-
550  else {
-
551  Camera c;
-
552  c.Clone(carrier->Cam());
-
553  c.Yaw(azimuth);
-
554  cat = c.vpn() * 300;
-
555  }
-
556 
-
557  slot_ship->SetVelocity(carrier->Velocity() + cat);
-
558  slot_ship->SetFlightPhase(Ship::LAUNCH);
-
559  }
-
560  else {
-
561  slot_ship->SetFlightPhase(Ship::TAKEOFF);
-
562  }
-
563 
-
564  Director* dir = slot_ship->GetDirector();
-
565  if (dir && dir->Type() == ShipCtrl::DIR_TYPE) {
-
566  ShipCtrl* ctrl = (ShipCtrl*) dir;
-
567  ctrl->Launch();
-
568  }
-
569 
- -
571  if (c) c->AddEvent(SimEvent::LAUNCH_SHIP, slot_ship->Name());
-
572 
-
573  ShipStats* stats = ShipStats::Find(slot_ship->Name());
-
574  if (stats) {
-
575  stats->SetRegion(carrier->GetRegion()->Name());
-
576  stats->SetType(slot_ship->Design()->name);
-
577 
-
578  if (slot_ship->GetElement()) {
-
579  Element* elem = slot_ship->GetElement();
-
580  stats->SetRole(Mission::RoleName(elem->Type()));
-
581  stats->SetCombatGroup(elem->GetCombatGroup());
-
582  stats->SetCombatUnit(elem->GetCombatUnit());
-
583  stats->SetElementIndex(slot_ship->GetElementIndex());
-
584  }
-
585 
-
586  stats->SetIFF(slot_ship->GetIFF());
- -
588 
-
589  if (slot_ship == sim->GetPlayerShip())
-
590  stats->SetPlayer(true);
-
591  }
-
592 
- -
594 
-
595  if (slot) {
-
596  slot->ship = 0;
-
597  slot->state = CLEAR;
-
598  slot->sequence = 0;
-
599  slot->time = 0;
-
600  }
-
601 
-
602  return true;
-
603  }
-
604 
-
605  return false;
-
606 }
-
607 
-
608 // +----------------------------------------------------------------------+
-
609 
-
610 void
- -
612 {
- -
614  light = new(__FILE__,__LINE__) Light((float) l);
-
615 }
-
616 
-
617 void
- -
619 {
-
620  if (i >= 0 && i < NUM_APPROACH_PTS) {
-
621  approach_rel[i] = loc;
-
622 
-
623  if (i >= num_approach_pts)
-
624  num_approach_pts = i+1;
-
625  }
-
626 }
-
627 
-
628 void
- -
630 {
-
631  if (i >= 0 && i < 2)
-
632  runway_rel[i] = loc;
-
633 }
-
634 
-
635 void
- -
637 {
-
638  start_rel = loc;
-
639 }
-
640 
-
641 void
- -
643 {
-
644  end_rel = loc;
-
645 }
-
646 
-
647 void
- -
649 {
-
650  cam_rel = loc;
-
651 }
-
652 
-
653 // +----------------------------------------------------------------------+
-
654 
-
655 void
-
656 FlightDeck::AddSlot(const Point& spot, DWORD filter)
-
657 {
-
658  if (!slots)
-
659  slots = new(__FILE__,__LINE__) FlightDeckSlot[10];
-
660 
-
661  slots[num_slots].spot_rel = spot;
-
662  slots[num_slots].filter = filter;
-
663  num_slots++;
-
664 }
-
665 
-
666 // +----------------------------------------------------------------------+
-
667 
-
668 void
- -
670 {
-
671  cycle_time = t;
-
672 }
-
673 
-
674 // +----------------------------------------------------------------------+
-
675 
-
676 void
- -
678 {
-
679  System::Orient(rep);
-
680 
-
681  Matrix orientation = rep->Cam().Orientation();
-
682  Point loc = rep->Location();
-
683 
-
684  start_point = (start_rel * orientation) + loc;
-
685  end_point = (end_rel * orientation) + loc;
-
686  cam_loc = (cam_rel * orientation) + loc;
-
687 
-
688  for (int i = 0; i < num_approach_pts; i++)
-
689  approach_point[i] = (approach_rel[i] * orientation) + loc;
-
690 
-
691  for (int i = 0; i < num_slots; i++)
-
692  slots[i].spot_loc = (slots[i].spot_rel * orientation) + loc;
-
693 
-
694  if (IsRecoveryDeck()) {
-
695  if (carrier->IsAirborne()) {
-
696  runway_point[0] = (runway_rel[0] * orientation) + loc;
-
697  runway_point[1] = (runway_rel[1] * orientation) + loc;
-
698  }
-
699 
-
700  if (num_hoops < 1) {
-
701  num_hoops = 4;
-
702  hoops = new(__FILE__,__LINE__) Hoop[num_hoops];
-
703  }
-
704 
-
705  Point hoop_vec = start_point - end_point;
-
706  double hoop_d = hoop_vec.Normalize() / num_hoops;
-
707 
-
708  orientation.Yaw(azimuth);
-
709 
-
710  for (int i = 0; i < num_hoops; i++) {
-
711  hoops[i].MoveTo(end_point + hoop_vec * (i+1) * hoop_d);
-
712  hoops[i].SetOrientation(orientation);
-
713  }
-
714  }
-
715 
-
716  if (light)
- -
718 }
-
719 
-
720 // +----------------------------------------------------------------------+
-
721 
-
722 int
-
723 FlightDeck::SpaceLeft(int type) const
-
724 {
-
725  int space_left = 0;
-
726 
-
727  for (int i = 0; i < num_slots; i++)
-
728  if (slots[i].ship == 0 && (slots[i].filter & type))
-
729  space_left++;
-
730 
-
731  return space_left;
-
732 }
-
733 
-
734 // +----------------------------------------------------------------------+
-
735 
-
736 bool
-
737 FlightDeck::Spot(Ship* s, int& index)
-
738 {
-
739  if (!s)
-
740  return false;
-
741 
-
742  if (index < 0) {
-
743  for (int i = 0; i < num_slots; i++) {
-
744  if (slots[i].ship == 0 && (slots[i].filter & s->Class())) {
-
745  index = i;
-
746  break;
-
747  }
-
748  }
-
749  }
-
750 
-
751  if (index >= 0 && index < num_slots && slots[index].ship == 0) {
-
752  slots[index].state = READY;
-
753  slots[index].ship = s;
-
754  slots[index].clearance = 0;
-
755 
-
756  if (s->GetGear())
-
757  slots[index].clearance = s->GetGear()->GetClearance();
-
758 
-
759  if (IsRecoveryDeck() && !s->IsAirborne()) {
-
760  s->SetVelocity(s->Velocity() * 0.01); // hit the brakes!
-
761  }
-
762 
-
763  if (!IsRecoveryDeck()) {
-
764  Camera work;
-
765  work.Clone(carrier->Cam());
-
766  work.Yaw(azimuth);
-
767 
-
768  s->CloneCam(work);
-
769  s->MoveTo(slots[index].spot_loc);
-
770 
-
771  LandingGear* g = s->GetGear();
-
772  if (g) {
- -
774  g->ExecFrame(0);
- -
776  }
-
777 
- -
779  }
-
780 
-
781  s->SetCarrier(carrier, this);
-
782  Observe(s);
-
783 
-
784  return true;
-
785  }
-
786 
-
787  return false;
-
788 }
-
789 
-
790 bool
- -
792 {
-
793  if (index >= 0 && index < num_slots && slots[index].ship != 0) {
-
794  Ship* s = slots[index].ship;
-
795 
-
796  slots[index].ship = 0;
- -
798  slots[index].state = CLEAR;
-
799 
- -
801  while (++iter) {
-
802  if (iter->GetShip() == s) {
-
803  delete iter.removeItem(); // ??? SHOULD DELETE HERE ???
-
804  break;
-
805  }
-
806  }
-
807 
-
808  return true;
-
809  }
-
810 
-
811  return false;
-
812 }
-
813 
-
814 // +----------------------------------------------------------------------+
-
815 
-
816 bool
- -
818 {
-
819  if (subtype == FLIGHT_DECK_LAUNCH && index >= 0 && index < num_slots) {
-
820  FlightDeckSlot* slot = &slots[index];
-
821 
-
822  if (slot->ship && slot->state == READY) {
-
823  int last = 0;
-
824  FlightDeckSlot* last_slot = 0;
-
825  FlightDeckSlot* lock_slot = 0;
-
826 
-
827  for (int i = 0; i < num_slots; i++) {
-
828  FlightDeckSlot* s = &slots[i];
-
829 
-
830  if (s->state == QUEUED && s->sequence > last) {
-
831  last = s->sequence;
-
832  last_slot = s;
-
833  }
-
834 
-
835  else if (s->state == LOCKED) {
-
836  lock_slot = s;
-
837  }
-
838  }
-
839 
-
840  // queue the slot for launch:
-
841  slot->state = QUEUED;
-
842  slot->sequence = last + 1;
-
843  slot->time = 0;
-
844 
-
845  if (last_slot)
-
846  slot->time = last_slot->time + cycle_time;
-
847 
-
848  else if (lock_slot)
-
849  slot->time = lock_slot->time;
-
850 
-
851  return true;
-
852  }
-
853  }
-
854 
-
855  return false;
-
856 }
-
857 
-
858 // +----------------------------------------------------------------------+
-
859 
-
860 bool
- -
862 {
-
863  if (s && subtype == FLIGHT_DECK_RECOVERY) {
-
864  if (OverThreshold(s)) {
-
865  if (s->GetFlightPhase() < Ship::RECOVERY) {
- -
867  s->SetCarrier(carrier, this); // let ship know which flight deck it's in (needed for dock cam)
-
868  }
-
869 
-
870  // are we there yet?
- -
872  if (slots[0].ship == 0) { // only need to ask this on approach
-
873  double dock_distance = (s->Location() - MountLocation()).length();
-
874 
-
875  if (s->IsAirborne()) {
-
876  double altitude = s->Location().y - MountLocation().y;
-
877  if (dock_distance < Radius()*3 && altitude < s->Radius())
-
878  Dock(s);
-
879  }
-
880  else {
-
881  if (dock_distance < s->Radius())
-
882  Dock(s);
-
883  }
-
884  }
-
885  }
-
886 
-
887  return true;
-
888  }
-
889  else {
-
890  if (s->GetFlightPhase() == Ship::RECOVERY)
- -
892  }
-
893  }
-
894 
-
895  return false;
-
896 }
-
897 
-
898 bool
- -
900 {
-
901  if (s && subtype == FLIGHT_DECK_RECOVERY && slots[0].time <= 0) {
-
902  int index = 0;
-
903  if (Spot(s, index)) {
- -
905  s->SetCarrier(carrier, this);
-
906 
-
907  // hard landings?
-
908  if (Ship::GetLandingModel() == 0) {
-
909  double base_damage = s->Design()->integrity;
-
910 
-
911  // did player do something stupid?
-
912  if (s->GetGear() && !s->IsGearDown()) {
-
913  Print("FlightDeck::Dock(%s) Belly landing!\n", s->Name());
-
914  s->InflictDamage(0.5 * base_damage);
-
915  }
-
916 
-
917  double docking_deflection = fabs(carrier->Cam().vup().y - s->Cam().vup().y);
-
918 
-
919  if (docking_deflection > 0.35) {
-
920  Print("Landing upside down? y = %.3f\n", docking_deflection);
-
921  s->InflictDamage(0.8 * base_damage);
-
922  }
-
923 
-
924  // did incoming ship exceed safe landing parameters?
-
925  if (s->IsAirborne()) {
-
926  if (s->Velocity().y < -20) {
-
927  Print("FlightDeck::Dock(%s) Slammed it!\n", s->Name());
-
928  s->InflictDamage(0.1 * base_damage);
-
929  }
-
930  }
-
931 
-
932  // did incoming ship exceed safe docking speed?
-
933  else {
-
934  Point delta_v = s->Velocity() - carrier->Velocity();
-
935  double excess = (delta_v.length() - 100);
-
936 
-
937  if (excess > 0)
-
938  s->InflictDamage(excess);
-
939  }
-
940  }
-
941 
-
942  if (s->IsAirborne()) {
-
943  if (s == Sim::GetSim()->GetPlayerShip() && tire_sound) {
-
944  Sound* sound = tire_sound->Duplicate();
-
945  sound->Play();
-
946  }
-
947  }
-
948 
-
949  if (s->GetDrive())
-
950  s->GetDrive()->PowerOff();
-
951 
- -
953  slots[index].time = 5;
-
954 
-
955  if (s->IsAirborne())
-
956  slots[index].time = 7.5;
-
957  return true;
-
958  }
-
959  }
-
960 
-
961  return false;
-
962 }
-
963 
-
964 int
- -
966 {
-
967  if (s && s->GetShip()) {
-
968  Ship* inbound = s->GetShip();
-
969 
-
970  if (recovery_queue.contains(s)) {
-
971  InboundSlot* orig = s;
-
972  s = recovery_queue.find(s);
-
973  delete orig;
-
974  }
-
975  else {
- -
977  Observe(s->GetShip());
-
978  }
-
979 
-
980  inbound->SetInbound(s);
-
981 
-
982  // find the best initial approach point for this ship:
-
983  double current_distance = 1e9;
-
984  for (int i = 0; i < num_approach_pts; i++) {
-
985  double distance = Point(inbound->Location() - approach_point[i]).length();
-
986  if (distance < current_distance) {
-
987  current_distance = distance;
-
988  s->SetApproach(i);
-
989  }
-
990  }
-
991 
-
992  Point offset(rand()-16000, rand()-16000, rand()-16000);
-
993  offset.Normalize();
-
994  offset *= 200;
-
995 
-
996  s->SetOffset(offset);
-
997 
-
998  // *** DEBUG ***
-
999  // PrintQueue();
-
1000 
-
1001  // if the new guy is first in line, and the deck is almost ready,
-
1002  // go ahead and clear him for approach now
-
1003  recovery_queue.sort();
-
1004  if (recovery_queue[0] == s && !s->Cleared() && slots[0].time <= 3)
-
1005  s->Clear();
-
1006 
-
1007  return recovery_queue.index(s) + 1;
-
1008  }
-
1009 
-
1010  return 0;
-
1011 }
-
1012 
-
1013 void
- -
1015 {
-
1016  if (recovery_queue.size() > 0) {
-
1017  if (recovery_queue[0]->Cleared() && recovery_queue[0]->Distance() > 45e3) {
-
1018  recovery_queue[0]->Clear(false);
-
1019  }
-
1020 
-
1021  if (!recovery_queue[0]->Cleared()) {
-
1022  recovery_queue.sort();
-
1023 
-
1024  if (recovery_queue[0]->Distance() < 35e3) {
-
1025  recovery_queue[0]->Clear();
-
1026 
-
1027  Ship* dst = recovery_queue[0]->GetShip();
-
1028 
-
1029  RadioMessage* clearance = new(__FILE__,__LINE__) RadioMessage(dst, carrier, RadioMessage::CALL_CLEARANCE);
-
1030  clearance->SetInfo(Text("for final approach to ") + Name());
-
1031  RadioTraffic::Transmit(clearance);
-
1032  }
-
1033  }
-
1034  }
-
1035 }
-
1036 
-
1037 // +----------------------------------------------------------------------+
-
1038 
-
1039 void
- -
1041 {
-
1042  Print("\nRecovery Queue for %s\n", Name());
-
1043  if (recovery_queue.size() < 1) {
-
1044  Print(" (empty)\n\n");
-
1045  return;
-
1046  }
-
1047 
-
1048  for (int i = 0; i < recovery_queue.size(); i++) {
-
1049  InboundSlot* s = recovery_queue.at(i);
-
1050 
-
1051  if (!s) {
-
1052  Print(" %2d. null\n", i);
-
1053  }
-
1054  else if (!s->GetShip()) {
-
1055  Print(" %2d. ship is null\n", i);
-
1056  }
-
1057  else {
-
1058  double d = Point(s->GetShip()->Location() - MountLocation()).length();
-
1059  Print(" %2d. %c %-20s %8d km\n", i, s->Cleared()?'*':' ', s->GetShip()->Name(), (int) (d/1000));
-
1060  }
-
1061  }
-
1062 
-
1063  Print("\n");
-
1064 }
-
1065 
-
1066 // +----------------------------------------------------------------------+
-
1067 
-
1068 Ship*
-
1069 FlightDeck::GetShip(int index) const
-
1070 {
-
1071  if (index >= 0 && index < num_slots)
-
1072  return slots[index].ship;
-
1073 
-
1074  return 0;
-
1075 }
-
1076 
-
1077 double
- -
1079 {
-
1080  if (index >= 0 && index < num_slots)
-
1081  return slots[index].time;
-
1082 
-
1083  return 0;
-
1084 }
-
1085 
-
1086 
-
1087 int
-
1088 FlightDeck::State(int index) const
-
1089 {
-
1090  if (index >= 0 && index < num_slots)
-
1091  return slots[index].state;
-
1092 
-
1093  return 0;
-
1094 }
-
1095 
-
1096 int
-
1097 FlightDeck::Sequence(int index) const
-
1098 {
-
1099  if (index >= 0 && index < num_slots)
-
1100  return slots[index].sequence;
-
1101 
-
1102  return 0;
-
1103 }
-
1104 
-
1105 // +----------------------------------------------------------------------+
-
1106 
-
1107 bool
- -
1109 {
-
1110  if (obj->Type() == SimObject::SIM_SHIP) {
-
1111  Ship* s = (Ship*) obj;
-
1112 
- -
1114  while (++iter) {
-
1115  InboundSlot* recovery_slot = iter.value();
-
1116 
-
1117  if (recovery_slot->GetShip() == s || recovery_slot->GetShip() == 0) {
-
1118  delete iter.removeItem();
-
1119  }
-
1120  }
-
1121 
-
1122  for (int i = 0; i < num_slots; i++) {
-
1123  FlightDeckSlot* slot = &slots[i];
-
1124 
-
1125  if (slot->ship == s) {
-
1126  slot->ship = 0;
-
1127  slot->state = 0;
-
1128  slot->sequence = 0;
-
1129  slot->time = 0;
-
1130  break;
-
1131  }
-
1132  }
-
1133  }
-
1134 
-
1135  return SimObserver::Update(obj);
-
1136 }
-
1137 
-
1138 const char*
- -
1140 {
-
1141  return Name();
-
1142 }
-
1143 
-
1144 // +----------------------------------------------------------------------+
-
1145 
-
1146 bool
- -
1148 {
-
1149  if (carrier->IsAirborne()) {
-
1150  if (s->AltitudeAGL() > s->Radius() * 4)
-
1151  return false;
-
1152 
-
1153  const Point& sloc = s->Location();
-
1154 
-
1155  // is ship between the markers?
-
1156  double distance = 1e9;
-
1157 
-
1158  Point d0 = runway_point[0] - sloc;
-
1159  Point d1 = runway_point[1] - sloc;
-
1160  double d = d0 * d1;
-
1161  bool between = (d0 * d1) < 0;
-
1162 
-
1163  if (between) {
-
1164  // distance from point to line:
-
1165  Point src = runway_point[0];
-
1166  Point dir = runway_point[1] - src;
-
1167  Point w = (sloc - src).cross(dir);
-
1168 
-
1169  distance = w.length() / dir.length();
-
1170  }
-
1171 
-
1172  return distance < Radius();
-
1173  }
-
1174 
-
1175  else {
-
1176  return (s->Location() - MountLocation()).length() < (s->Radius() + Radius());
-
1177  }
-
1178 }
-
1179 
-
1180 // +----------------------------------------------------------------------+
-
1181 
-
1182 bool
- -
1184 {
-
1185  return (p - MountLocation()).length() < Radius();
-
1186 }
-
-
- - - - -- cgit v1.1