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/_sim_8cpp_source.html | 3930 -------------------------------- 1 file changed, 3930 deletions(-) delete mode 100644 Doc/doxygen/html/_sim_8cpp_source.html (limited to 'Doc/doxygen/html/_sim_8cpp_source.html') diff --git a/Doc/doxygen/html/_sim_8cpp_source.html b/Doc/doxygen/html/_sim_8cpp_source.html deleted file mode 100644 index 52fc645..0000000 --- a/Doc/doxygen/html/_sim_8cpp_source.html +++ /dev/null @@ -1,3930 +0,0 @@ - - - - - -Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/Sim.cpp Source File - - - - - - - - - - - - - -
-
- - - - - - -
-
Starshatter_Open -
-
Open source Starshatter engine
-
-
- - - - - -
-
- -
-
-
- -
- - - - -
- -
- -
-
-
Sim.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: Sim.cpp
-
7  AUTHOR: John DiCamillo
-
8 
-
9 
-
10  OVERVIEW
-
11  ========
-
12  Simulation Universe and Region classes
-
13 */
-
14 
-
15 #include "MemDebug.h"
-
16 #include "Sim.h"
-
17 #include "SimEvent.h"
-
18 #include "SimObject.h"
-
19 #include "Starshatter.h"
-
20 #include "StarSystem.h"
-
21 #include "Contact.h"
-
22 #include "Ship.h"
-
23 #include "ShipDesign.h"
-
24 #include "Element.h"
-
25 #include "Instruction.h"
-
26 #include "RadioTraffic.h"
-
27 #include "Shot.h"
-
28 #include "Drone.h"
-
29 #include "Explosion.h"
-
30 #include "Debris.h"
-
31 #include "Asteroid.h"
-
32 #include "Drive.h"
-
33 #include "QuantumDrive.h"
-
34 #include "Sensor.h"
-
35 #include "NavLight.h"
-
36 #include "Shield.h"
-
37 #include "Weapon.h"
-
38 #include "WeaponGroup.h"
-
39 #include "Hangar.h"
-
40 #include "FlightDeck.h"
-
41 #include "Sky.h"
-
42 #include "Grid.h"
-
43 #include "MFD.h"
-
44 #include "AudioConfig.h"
-
45 #include "Mission.h"
-
46 #include "MissionEvent.h"
-
47 #include "CameraDirector.h"
-
48 #include "MusicDirector.h"
-
49 #include "Combatant.h"
-
50 #include "CombatGroup.h"
-
51 #include "CombatUnit.h"
-
52 #include "HUDView.h"
-
53 #include "SeekerAI.h"
-
54 #include "ShipAI.h"
-
55 #include "Power.h"
-
56 #include "Callsign.h"
-
57 #include "GameScreen.h"
-
58 #include "Terrain.h"
-
59 #include "TerrainPatch.h"
-
60 
-
61 #include "NetGame.h"
-
62 #include "NetClientConfig.h"
-
63 #include "NetServerConfig.h"
-
64 #include "NetPlayer.h"
-
65 #include "NetUtil.h"
-
66 #include "NetData.h"
-
67 
-
68 #include "Game.h"
-
69 #include "Sound.h"
-
70 #include "Bolt.h"
-
71 #include "Solid.h"
-
72 #include "Sprite.h"
-
73 #include "Light.h"
-
74 #include "Bitmap.h"
-
75 #include "DataLoader.h"
-
76 #include "ParseUtil.h"
-
77 #include "MouseController.h"
-
78 #include "Player.h"
-
79 #include "Random.h"
-
80 #include "Video.h"
-
81 
-
82 const char* FormatGameTime();
-
83 
-
84 // +--------------------------------------------------------------------+
-
85 
-
86 class SimHyper
-
87 {
-
88 public:
-
89  SimHyper(Ship* o, SimRegion* r, const Point& l, int t, bool h, Ship* fc1, Ship* fc2)
-
90  : ship(o), rgn(r), loc(l), type(t), hyperdrive(h), fc_src(fc1), fc_dst(fc2) { }
-
91 
- - - -
95  int type;
-
96  bool hyperdrive;
- - -
99 };
-
100 
-
101 // +--------------------------------------------------------------------+
-
102 
- -
104 {
-
105 public:
-
106  SimSplash(SimRegion* r, const Point& l, double d, double n)
-
107  : rgn(r), loc(l), damage(d), range(n),
-
108  owner_name("Collateral Damage"), missile(false) { }
-
109 
- - -
112  double damage;
-
113  double range;
- -
115  bool missile;
-
116 };
-
117 
-
118 // +--------------------------------------------------------------------+
-
119 
-
120 static bool first_frame = true;
-
121 Sim* Sim::sim = 0;
-
122 
- -
124 : ctrl(c), test_mode(false), grid_shown(false), dust(0),
-
125 star_system(0), active_region(0), mission(0), netgame(0),
-
126 start_time(0)
-
127 {
- - - - - -
133  MFD::Initialize();
- -
135 
-
136  if (!sim)
-
137  sim = this;
-
138 
- -
140 }
-
141 
- -
143 {
-
144  UnloadMission();
-
145 
-
146  Shot::Close();
- -
148  NavLight::Close();
-
149  Token::close();
-
150  Asteroid::Close();
-
151 
-
152  if (sim == this)
-
153  sim = 0;
-
154 }
-
155 
-
156 // +--------------------------------------------------------------------+
-
157 
-
158 void
- -
160 {
-
161  for (int i = 0; i < regions.size(); i++)
-
162  regions[i]->CommitMission();
-
163 
-
164  if (ShipStats::NumStats() > 0) {
-
165  Print("\n\nFINAL SCORE '%s'\n", (const char*) mission->Name());
-
166  Print("Name Kill1 Kill2 Died Colls Points Cmd Pts\n");
-
167  Print("---------------- ----- ----- ----- ----- ------ ------\n");
-
168 
-
169  int tk1 = 0;
-
170  int tk2 = 0;
-
171  int td = 0;
-
172  int tc = 0;
-
173 
-
174  for (int i = 0; i < ShipStats::NumStats(); i++) {
- -
176  s->Summarize();
-
177 
-
178  Print("%-16s %5d %5d %5d %5d %6d %6d\n",
-
179  s->GetName(),
-
180  s->GetGunKills(),
-
181  s->GetMissileKills(),
-
182  s->GetDeaths(),
-
183  s->GetColls(),
-
184  s->GetPoints(),
-
185  s->GetCommandPoints());
-
186 
-
187  tk1 += s->GetGunKills();
-
188  tk2 += s->GetMissileKills();
-
189  td += s->GetDeaths();
-
190  tc += s->GetColls();
-
191 
-
192  CombatGroup* group = s->GetCombatGroup();
-
193 
-
194  if (group) {
-
195  Combatant* c = group->GetCombatant();
-
196 
-
197  if (c)
-
198  c->AddScore(s->GetPoints());
-
199 
-
200  if (s->GetElementIndex() == 1)
-
201  group->SetSorties(group->Sorties() + 1);
-
202 
-
203  group->SetKills(group->Kills() + s->GetGunKills() + s->GetMissileKills());
-
204  group->SetPoints(group->Points() + s->GetPoints());
-
205  }
-
206 
-
207  if (s->IsPlayer()) {
- -
209  p->ProcessStats(s, start_time);
-
210 
-
211  if (mission && mission->Type() == Mission::TRAINING &&
-
212  s->GetDeaths() == 0 && s->GetColls() == 0)
-
213  p->SetTrained(mission->Identity());
-
214 
-
215  Player::Save(); // save training state right now before we forget!
-
216  }
-
217  }
-
218 
-
219  Print("--------------------------------------------\n");
-
220  Print("TOTAL %5d %5d %5d %5d\n\n", tk1, tk2, td, tc);
-
221 
- -
223  }
-
224 }
-
225 
-
226 // +--------------------------------------------------------------------+
-
227 
-
228 void
- -
230 {
-
231  if (netgame) {
-
232  delete netgame;
-
233  netgame = 0;
-
234  }
-
235 
-
236  HUDView* hud = HUDView::GetInstance();
-
237  if (hud)
-
238  hud->HideAll();
-
239 
- -
241 
-
242  events.destroy();
- -
244  elements.destroy();
-
245  finished.destroy();
-
246 
-
247  if (active_region)
- -
249 
-
250  if (star_system)
- -
252 
-
253  if (mission) {
-
254  mission->SetActive(false);
-
255  mission->SetComplete(true);
-
256  }
-
257 
-
258  regions.destroy();
-
259  scene.Collect();
-
260 
- -
262 
-
263  star_system = 0;
-
264  active_region = 0;
-
265  mission = 0;
-
266 
-
267  // reclaim memory used by radio traffic:
- -
269 
-
270  // release texture memory for 2D screens:
- -
272  if (stars)
-
273  stars->InvalidateTextureCache();
-
274 
- -
276  if (cam_dir)
-
277  cam_dir->SetShip(0);
-
278 
- -
280 }
-
281 
-
282 bool
- -
284 {
-
285  return mission && mission->IsActive();
-
286 }
-
287 
-
288 bool
- -
290 {
-
291  return mission && mission->IsComplete();
-
292 }
-
293 
-
294 // +--------------------------------------------------------------------+
-
295 
-
296 void
-
297 Sim::LoadMission(Mission* m, bool preload_textures)
-
298 {
- -
300 
-
301  if (!mission) {
-
302  mission = m;
-
303  mission->SetActive(true);
-
304 
-
305  if (preload_textures) {
-
306  Video* video = Game::GetVideo();
-
307  List<Model> all_models;
-
308  //List<Bitmap> all_textures;
-
309 
- -
311  while (++elem_iter) {
-
312  MissionElement* elem = elem_iter.value();
-
313  const ShipDesign* design = elem->GetDesign();
-
314 
-
315  if (design) {
-
316  for (int i = 0; i < 4; i++) {
-
317  List<Model>& models = (List<Model>&) design->models[i]; // cast-away const
-
318 
-
319  ListIter<Model> model_iter = models;
-
320  while (++model_iter) {
-
321  Model* model = model_iter.value();
-
322  if (!all_models.contains(model)) {
-
323  all_models.append(model);
-
324  //model->GetAllTextures(all_textures);
-
325 
-
326  ListIter<Surface> surf_iter = model->GetSurfaces();
-
327  while (++surf_iter) {
-
328  Surface* surface = surf_iter.value();
-
329  video->PreloadSurface(surface);
-
330  }
-
331  }
-
332  }
-
333  }
-
334  }
-
335  }
-
336 
-
337  /*
-
338  if (video && all_textures.size() > 0) {
-
339  ::Print("Preloading %d textures into video texture cache\n", all_textures.size());
-
340  ListIter<Bitmap> bmp_iter = all_textures;
-
341  while (++bmp_iter) {
-
342  Bitmap* bmp = bmp_iter.value();
-
343  video->PreloadTexture(bmp);
-
344  }
-
345  }
-
346  */
-
347  }
-
348  }
-
349 }
-
350 
-
351 void
- -
353 {
- -
355 
-
356  if (!mission) {
-
357  Print("Sim::ExecMission() - No mission to execute.\n");
-
358  return;
-
359  }
-
360 
-
361  if (elements.size() || finished.size()) {
-
362  Print("Sim::ExecMission(%s) mission is already executing.\n", mission->Name());
-
363  return;
-
364  }
-
365 
-
366  Print("\nExec Mission: '%s'\n", (const char*) mission->Name());
-
367 
-
368  if (cam_dir)
-
369  cam_dir->Reset();
-
370 
-
371  if (mission->Stardate() > 0)
- -
373 
- - -
376 
-
377  int dust_factor = 0;
-
378 
- -
380  dust_factor = Starshatter::GetInstance()->Dust();
-
381 
-
382  if (star_system->NumDust() * dust_factor) {
-
383  dust = new(__FILE__,__LINE__) Dust(star_system->NumDust() * 2*(dust_factor+1), dust_factor > 1);
- -
385  }
-
386 
-
387  CreateRegions();
-
388  BuildLinks();
-
389  CreateElements();
-
390  CopyEvents();
-
391 
-
392  if (netgame) {
-
393  delete netgame;
-
394  netgame = 0;
-
395  }
-
396 
-
397  first_frame = true;
- -
399 
- -
401 }
-
402 
-
403 // +--------------------------------------------------------------------+
-
404 
-
405 void
- -
407 {
-
408  const char* active_region_name = 0;
-
409 
-
410  if (mission)
-
411  active_region_name = mission->GetRegion();
-
412 
- -
414  while (++iter) {
-
415  StarSystem* sys = iter.value();
-
416 
-
417  // insert objects from star system:
-
418  ListIter<OrbitalBody> star = sys->Bodies();
-
419  while (++star) {
-
420  ListIter<OrbitalBody> planet = star->Satellites();
-
421  while (++planet) {
-
422  ListIter<OrbitalBody> moon = planet->Satellites();
-
423  while (++moon) {
-
424  ListIter<OrbitalRegion> rgn = moon->Regions();
-
425  while (++rgn) {
-
426  SimRegion* sim_region = new(__FILE__,__LINE__) SimRegion(this, rgn.value());
-
427  regions.append(sim_region);
-
428  if (!strcmp(active_region_name, sim_region->Name())) {
-
429  ActivateRegion(sim_region);
-
430  }
-
431  }
-
432  }
-
433 
-
434  ListIter<OrbitalRegion> rgn = planet->Regions();
-
435  while (++rgn) {
-
436  SimRegion* sim_region = new(__FILE__,__LINE__) SimRegion(this, rgn.value());
-
437  regions.append(sim_region);
-
438  if (!strcmp(active_region_name, sim_region->Name())) {
-
439  ActivateRegion(sim_region);
-
440  }
-
441  }
-
442  }
-
443 
-
444  ListIter<OrbitalRegion> rgn = star->Regions();
-
445  while (++rgn) {
-
446  SimRegion* sim_region = new(__FILE__,__LINE__) SimRegion(this, rgn.value());
-
447  regions.append(sim_region);
-
448  if (!strcmp(active_region_name, sim_region->Name())) {
-
449  ActivateRegion(sim_region);
-
450  }
-
451  }
-
452  }
-
453  }
-
454 }
-
455 
-
456 // +--------------------------------------------------------------------+
-
457 
-
458 void
- -
460 {
- -
462  while (++iter) {
-
463  SimRegion* rgn = iter.value();
-
464  OrbitalRegion* orb = rgn->GetOrbitalRegion();
-
465 
-
466  if (orb) {
-
467  ListIter<Text> lnk_iter = orb->Links();
-
468  while (++lnk_iter) {
-
469  Text* t = lnk_iter.value();
-
470 
-
471  SimRegion* tgt = FindRegion(*t);
-
472 
-
473  if (tgt && !rgn->Links().contains(tgt))
-
474  rgn->Links().append(tgt);
-
475  }
-
476  }
-
477  }
-
478 }
-
479 
-
480 void
- -
482 {
- -
484  while (++e_iter) {
-
485  MissionElement* msn_elem = e_iter.value();
-
486 
-
487  // add element to a carrier?
-
488  if (msn_elem->IsSquadron()) {
-
489  Ship* carrier = FindShip(msn_elem->Carrier());
-
490  if (carrier) {
-
491  Hangar* hangar = carrier->GetHangar();
-
492 
-
493  if (hangar) {
-
494  int* def_load = 0;
-
495 
-
496  if (msn_elem->Loadouts().size()) {
-
497  MissionLoad* m = msn_elem->Loadouts().at(0);
-
498 
-
499  if (m->GetName().length()) {
-
500  ShipDesign* dsn = (ShipDesign*) msn_elem->GetDesign();
-
501  ListIter<ShipLoad> sl_iter = dsn->loadouts;
-
502  while (++sl_iter) {
-
503  ShipLoad* sl = sl_iter.value();
-
504 
-
505  if (m->GetName() == sl->name)
-
506  def_load = sl->load;
-
507  }
-
508  }
-
509 
-
510  if (!def_load) {
-
511  def_load = m->GetStations();
-
512  }
-
513  }
-
514 
-
515  hangar->CreateSquadron(msn_elem->Name(), msn_elem->GetCombatGroup(),
-
516  msn_elem->GetDesign(), msn_elem->Count(),
-
517  msn_elem->GetIFF(),
-
518  def_load, msn_elem->MaintCount(), msn_elem->DeadCount());
-
519 
-
520  Element* element = CreateElement(msn_elem->Name(),
-
521  msn_elem->GetIFF(),
-
522  msn_elem->MissionRole());
-
523 
-
524  element->SetCarrier(carrier);
-
525  element->SetCombatGroup(msn_elem->GetCombatGroup());
-
526  element->SetCombatUnit(msn_elem->GetCombatUnit());
-
527  element->SetCount(msn_elem->Count());
-
528  element->SetRogue(false);
-
529  element->SetPlayable(false);
-
530  element->SetLoadout(def_load);
-
531  }
-
532  }
-
533  }
-
534 
-
535  // create the element in space:
-
536  else {
-
537  Ship* carrier = 0;
-
538  Hangar* hangar = 0;
-
539  int squadron = -1;
-
540  int slot = 0;
-
541 
-
542  // first create the package element:
-
543  Element* element = CreateElement(msn_elem->Name(),
-
544  msn_elem->GetIFF(),
-
545  msn_elem->MissionRole());
-
546 
-
547  element->SetPlayer(msn_elem->Player());
-
548  element->SetCombatGroup(msn_elem->GetCombatGroup());
-
549  element->SetCombatUnit(msn_elem->GetCombatUnit());
-
550  element->SetCommandAILevel(msn_elem->CommandAI());
-
551  element->SetHoldTime(msn_elem->HoldTime());
-
552  element->SetZoneLock(msn_elem->ZoneLock() ? true : false);
-
553  element->SetRogue(msn_elem->IsRogue());
-
554  element->SetPlayable(msn_elem->IsPlayable());
-
555  element->SetIntelLevel(msn_elem->IntelLevel());
-
556 
-
557  // if this is the player's element, make sure to activate the region:
-
558  if (msn_elem->Player()) {
-
559  SimRegion* rgn = FindRegion(msn_elem->Region());
-
560 
-
561  if (rgn && rgn != active_region)
-
562  ActivateRegion(rgn);
-
563  }
-
564 
-
565  // if element belongs to a squadron,
-
566  // find the carrier, squadron, flight deck, etc.:
-
567  if (msn_elem->Squadron().length() > 0) {
-
568  MissionElement* squadron_elem = mission->FindElement(msn_elem->Squadron());
-
569 
-
570  if (squadron_elem) {
-
571  element->SetSquadron(msn_elem->Squadron());
-
572 
-
573  Element* cmdr = FindElement(squadron_elem->Carrier());
-
574 
-
575  if (cmdr) {
-
576  element->SetCommander(cmdr);
-
577  carrier = cmdr->GetShip(1);
-
578 
-
579  if (carrier) {
-
580  element->SetCarrier(carrier);
-
581  hangar = carrier->GetHangar();
-
582 
-
583  for (int s = 0; s < hangar->NumSquadrons(); s++) {
-
584  if (hangar->SquadronName(s) == msn_elem->Squadron()) {
-
585  squadron = s;
-
586  break;
-
587  }
-
588  }
-
589  }
-
590  }
-
591  }
-
592  }
-
593 
-
594  else if (msn_elem->Commander().length() > 0) {
-
595  Element* cmdr = FindElement(msn_elem->Commander());
-
596 
-
597  if (cmdr) {
-
598  element->SetCommander(cmdr);
-
599  }
-
600  }
-
601 
-
602  ListIter<Instruction> obj = msn_elem->Objectives();
-
603  while (++obj) {
-
604  Instruction* o = obj.value();
-
605  Instruction* instr = 0;
-
606 
-
607  instr = new(__FILE__,__LINE__) Instruction(*o);
-
608 
-
609  element->AddObjective(instr);
-
610  }
-
611 
-
612  if (msn_elem->Instructions().size() > 0) {
-
613  ListIter<Text> instr = msn_elem->Instructions();
-
614  while (++instr) {
-
615  element->AddInstruction(*instr);
-
616  }
-
617  }
-
618 
-
619  ListIter<Instruction> nav = msn_elem->NavList();
-
620  while (++nav) {
-
621  SimRegion* rgn = FindRegion(nav->RegionName());
-
622 
-
623  if (!rgn)
-
624  rgn = FindRegion(msn_elem->Region());
-
625 
-
626  if (rgn) {
-
627  Instruction* npt = new(__FILE__,__LINE__)
-
628  Instruction(rgn, nav->Location(), nav->Action());
-
629 
-
630  npt->SetStatus(nav->Status());
-
631  npt->SetEMCON(nav->EMCON());
-
632  npt->SetFormation(nav->Formation());
-
633  npt->SetSpeed(nav->Speed());
-
634  npt->SetTarget(nav->TargetName());
-
635  npt->SetHoldTime(nav->HoldTime());
-
636  npt->SetFarcast(nav->Farcast());
-
637 
-
638  element->AddNavPoint(npt);
-
639  }
-
640  }
-
641 
-
642  bool alertPrep = false;
-
643  int* loadout = 0;
-
644  int respawns = msn_elem->RespawnCount();
-
645 
-
646  // if ships are to start on alert,
-
647  // spot them onto the appropriate launch deck:
-
648  if (hangar && element && msn_elem->Count() > 0 && msn_elem->IsAlert()) {
-
649  FlightDeck* deck = 0;
-
650  int queue = 1000;
-
651  const ShipDesign* dsn = msn_elem->GetDesign();
-
652 
-
653  if (dsn) {
-
654  for (int i = 0; i < carrier->NumFlightDecks(); i++) {
-
655  FlightDeck* d = carrier->GetFlightDeck(i);
-
656  int dq = hangar->PreflightQueue(d);
-
657 
-
658  if (d && d->IsLaunchDeck() && d->SpaceLeft(dsn->type) && dq < queue) {
-
659  queue = dq;
-
660  deck = d;
-
661  }
-
662  }
-
663  }
-
664 
-
665  if (deck) {
-
666  alertPrep = true;
-
667 
-
668  // choose best loadout:
-
669  if (msn_elem->Loadouts().size()) {
-
670  MissionLoad* l = msn_elem->Loadouts().at(0);
-
671  if (l->GetName().length()) {
-
672  ListIter<ShipLoad> sl = ((ShipDesign*) dsn)->loadouts;
-
673  while (++sl) {
-
674  if (!_stricmp(sl->name, l->GetName()))
-
675  loadout = sl->load;
-
676  }
-
677  }
-
678 
-
679  else {
-
680  loadout = l->GetStations();
-
681  }
-
682  }
-
683 
-
684  element->SetLoadout(loadout);
-
685 
-
686  for (int i = 0; i < msn_elem->Count(); i++) {
-
687  int squadron = -1;
-
688  int slot = -1;
-
689 
-
690  if (hangar->FindAvailSlot(msn_elem->GetDesign(), squadron, slot)) {
-
691  alertPrep = alertPrep &&
-
692  hangar->GotoAlert(squadron,
-
693  slot,
-
694  deck,
-
695  element,
-
696  loadout,
-
697  true, // package for launch
-
698  true); // expedite
-
699 
-
700  HangarSlot* s = (HangarSlot*) hangar->GetSlot(squadron, slot);
-
701  Ship* alertShip = hangar->GetShip(s);
-
702 
-
703  if (alertShip) {
-
704  alertShip->SetRespawnCount(respawns);
-
705 
-
706  if (msn_elem->Player() == i+1) {
-
707  if (alertShip->GetRegion()) {
-
708  alertShip->GetRegion()->SetPlayerShip(alertShip);
-
709  }
-
710  else {
-
711  ::Print("WARNING: alert ship '%s' region is null\n", alertShip->Name());
-
712  }
-
713  }
-
714  }
-
715  }
-
716  }
-
717  }
-
718  }
-
719 
-
720  if (!alertPrep) {
-
721  // then, create the ships:
-
722  for (int i = 0; i < msn_elem->Count(); i++) {
-
723  MissionShip* msn_ship = 0;
-
724  Text sname = msn_elem->GetShipName(i);
-
725  Text rnum = msn_elem->GetRegistry(i);
-
726  Text rgn_name = msn_elem->Region();
-
727 
-
728  if (msn_elem->Ships().size() > i) {
-
729  msn_ship = msn_elem->Ships()[i];
-
730  sname = msn_ship->Name();
-
731  rnum = msn_ship->RegNum();
-
732  rgn_name = msn_ship->Region();
-
733  }
-
734 
-
735  Point l2 = msn_elem->Location();
-
736 
-
737  if (msn_ship && fabs(msn_ship->Location().x) < 1e9) {
-
738  l2 = msn_ship->Location();
-
739  }
-
740  else if (i) {
-
741  Point offset = RandomPoint();
-
742  offset.z = Random(-1e3, 1e3);
-
743 
-
744  if (msn_elem->Count() < 5)
-
745  offset *= 0.3;
-
746 
-
747  l2 += offset;
-
748  }
-
749 
-
750  // choose best loadout:
-
751  ListIter<MissionLoad> l = msn_elem->Loadouts();
-
752  while (++l) {
-
753  if ((l->GetShip() == i) || (l->GetShip() < 0 && loadout == 0)) {
-
754  if (l->GetName().length()) {
-
755  ListIter<ShipLoad> sl = ((ShipDesign*) msn_elem->GetDesign())->loadouts;
-
756  while (++sl) {
-
757  if (!_stricmp(sl->name, l->GetName()))
-
758  loadout = sl->load;
-
759  }
-
760  }
-
761 
-
762  else {
-
763  loadout = l->GetStations();
-
764  }
-
765  }
-
766  }
-
767 
-
768  element->SetLoadout(loadout);
-
769 
-
770  Ship* ship = CreateShip(sname, rnum,
-
771  (ShipDesign*) msn_elem->GetDesign(),
-
772  rgn_name, l2,
-
773  msn_elem->GetIFF(),
-
774  msn_elem->CommandAI(),
-
775  loadout);
-
776 
-
777  if (ship) {
-
778  double heading = msn_elem->Heading();
-
779  const Skin* skin = msn_elem->GetSkin();
-
780 
-
781  if (msn_ship) {
-
782  heading = msn_ship->Heading();
-
783 
-
784  if (msn_ship->GetSkin())
-
785  skin = msn_ship->GetSkin();
-
786  }
-
787 
-
788  ship->SetRogue(msn_elem->IsRogue());
-
789  ship->SetInvulnerable(msn_elem->IsInvulnerable());
-
790  ship->SetHeading(0, 0, heading + PI);
-
791  ship->SetRespawnCount(respawns);
-
792  ship->UseSkin(skin);
-
793 
-
794  if (!netgame)
-
795  ship->SetRespawnLoc(RandomPoint() * 2);
-
796 
-
797  if (ship->IsStarship())
-
798  ship->SetHelmHeading(heading);
-
799 
-
800  else if (ship->IsAirborne() && ship->AltitudeAGL() > 25)
-
801  ship->SetVelocity(ship->Heading() * 250);
-
802 
-
803  if (element)
-
804  element->AddShip(ship);
-
805 
-
806  if (hangar)
-
807  hangar->FindSlot(ship, squadron, slot, Hangar::ACTIVE);
-
808 
-
809  if (ship->GetRegion() && msn_elem->Player() == i+1)
-
810  ship->GetRegion()->SetPlayerShip(ship);
-
811 
-
812  if (ship->NumFlightDecks()) {
-
813  for (int i = 0; i < ship->NumFlightDecks(); i++) {
-
814  FlightDeck* deck = ship->GetFlightDeck(i);
-
815  if (deck)
-
816  deck->Orient(ship);
-
817  }
-
818  }
-
819 
-
820  if (msn_ship) {
-
821  ship->SetVelocity(msn_ship->Velocity().OtherHand());
-
822  ship->SetIntegrity((float) msn_ship->Integrity());
-
823  ship->SetRespawnCount(msn_ship->Respawns());
-
824 
-
825  if (msn_ship->Ammo()[0] > -10) {
-
826  for (int i = 0; i < 64; i++) {
-
827  Weapon* w = ship->GetWeaponByIndex(i+1);
-
828  if (w)
-
829  w->SetAmmo(msn_ship->Ammo()[i]);
-
830  else
-
831  break;
-
832  }
-
833  }
-
834 
-
835  if (msn_ship->Fuel()[0] > -10) {
-
836  for (int i = 0; i < 4; i++) {
-
837  if (ship->Reactors().size() > i) {
-
838  PowerSource* p = ship->Reactors()[i];
-
839  p->SetCapacity(msn_ship->Fuel()[i]);
-
840  }
-
841  }
-
842  }
-
843 
-
844  if (msn_ship->Decoys() > -10) {
-
845  Weapon* w = ship->GetDecoy();
-
846  if (w)
-
847  w->SetAmmo(msn_ship->Decoys());
-
848  }
-
849 
-
850  if (msn_ship->Probes() > -10) {
-
851  Weapon* w = ship->GetProbeLauncher();
-
852  if (w)
-
853  w->SetAmmo(msn_ship->Probes());
-
854  }
-
855  }
-
856 
-
857  Shield* shield = ship->GetShield();
-
858 
-
859  if (shield) {
-
860  shield->SetPowerLevel(50);
-
861  }
-
862 
-
863  if (ship->Class() > Ship::FRIGATE) {
-
864  ListIter<WeaponGroup> iter = ship->Weapons();
-
865  while (++iter) {
-
866  WeaponGroup* weapon = iter.value();
-
867 
-
868  // anti-air weapon?
-
869  if (weapon->GetDesign()->target_type & Ship::DRONE) {
- -
871  }
-
872  else {
- -
874  }
-
875  }
-
876  }
-
877 
-
878  if (ship->Class() > Ship::DRONE && ship->Class() < Ship::STATION) {
-
879  ShipStats* stats = ShipStats::Find(sname);
-
880  if (stats) {
-
881  char design[64];
-
882  sprintf_s(design, "%s %s", ship->Abbreviation(), ship->Design()->display_name);
-
883  stats->SetType(design);
-
884  stats->SetShipClass(ship->Class());
-
885  stats->SetRole(Mission::RoleName(msn_elem->MissionRole()));
-
886  stats->SetIFF(ship->GetIFF());
-
887  stats->SetRegion(msn_elem->Region());
-
888  stats->SetCombatGroup(msn_elem->GetCombatGroup());
-
889  stats->SetCombatUnit(msn_elem->GetCombatUnit());
-
890  stats->SetPlayer(msn_elem->Player() == i+1);
-
891  stats->SetElementIndex(ship->GetElementIndex());
-
892  }
-
893  }
-
894  } // ship
-
895  } // count
-
896  }
-
897  }
-
898  }
-
899 }
-
900 
-
901 void
- -
903 {
-
904  events.destroy();
-
905 
-
906  if (mission) {
- -
908  while (++iter) {
-
909  MissionEvent* orig = iter.value();
-
910  MissionEvent* event = new(__FILE__,__LINE__) MissionEvent(*orig);
-
911  events.append(event);
-
912  }
-
913  }
-
914 }
-
915 
-
916 // +--------------------------------------------------------------------+
-
917 
-
918 const char*
- -
920 {
-
921  const char* call = "Unidentified";
-
922 
-
923  for (int i = 0; i < 32; i++) {
-
924  call = Callsign::GetCallsign(IFF);
-
925 
-
926  if (!FindElement(call))
-
927  break;
-
928  }
-
929 
-
930  return call;
-
931 }
-
932 
-
933 Element*
-
934 Sim::CreateElement(const char* callsign, int IFF, int type)
-
935 {
-
936  Element* elem = new(__FILE__,__LINE__) Element(callsign, IFF, type);
-
937  elements.append(elem);
-
938  return elem;
-
939 }
-
940 
-
941 void
- -
943 {
-
944  if (elements.contains(elem))
-
945  elements.remove(elem);
-
946 
-
947  delete elem;
-
948 }
-
949 
-
950 Element*
-
951 Sim::FindElement(const char* name)
-
952 {
- -
954 
-
955  while (++iter) {
-
956  Element* elem = iter.value();
-
957  Text ename = elem->Name();
-
958 
-
959  if (ename == name)
-
960  return elem;
-
961  }
-
962 
-
963  return 0;
-
964 }
-
965 
-
966 // +--------------------------------------------------------------------+
-
967 
-
968 int
- -
970 {
-
971  assigned.clear();
-
972 
-
973  if (elem) {
-
974  for (int i = 0; i < elements.size(); i++) {
-
975  Element* e = elements.at(i);
-
976  if (!e->IsSquadron() && e->GetAssignment() == elem)
-
977  assigned.append(e);
-
978  }
-
979  }
-
980 
-
981  return assigned.size();
-
982 }
-
983 
-
984 // +--------------------------------------------------------------------+
-
985 
-
986 Ship*
-
987 Sim::CreateShip(const char* name, const char* reg_num, ShipDesign* design, const char* rgn_name, const Point& loc, int IFF, int cmd_ai, const int* loadout)
-
988 {
-
989  if (!design) {
-
990  Print("WARNING: CreateShip(%s): invalid design\n", name);
-
991  return 0;
-
992  }
-
993 
-
994  SimRegion* rgn = FindRegion(rgn_name);
-
995 
-
996  if (!rgn) {
-
997  return 0;
-
998  }
-
999 
-
1000  Ship* ship = new(__FILE__,__LINE__) Ship(name, reg_num, design, IFF, cmd_ai, loadout);
-
1001  ship->MoveTo(loc.OtherHand());
-
1002 
-
1003  if (rgn) {
-
1004  Print("Inserting Ship(%s) into Region(%s) (%s)\n", ship->Name(), rgn->Name(), FormatGameTime());
-
1005  rgn->InsertObject(ship);
-
1006 
-
1007  if (ship->IsAirborne() && ship->AltitudeAGL() > 25)
-
1008  ship->SetVelocity(ship->Heading() * 250);
-
1009  }
-
1010 
-
1011  return ship;
-
1012 }
-
1013 
-
1014 Ship*
-
1015 Sim::FindShip(const char* name, const char* rgn_name)
-
1016 {
-
1017  Ship* ship = 0;
-
1018 
-
1019  if (rgn_name) {
-
1020  SimRegion* rgn = FindRegion(rgn_name);
-
1021  if (rgn)
-
1022  ship = rgn->FindShip(name);
-
1023  }
-
1024 
-
1025  if (!ship) {
- -
1027  while (++rgn && !ship)
-
1028  ship = rgn->FindShip(name);
-
1029  }
-
1030 
-
1031  return ship;
-
1032 }
-
1033 
-
1034 void
- -
1036 {
-
1037  SimRegion* rgn = ship->GetRegion();
-
1038  if (rgn)
-
1039  rgn->DestroyShip(ship);
-
1040 }
-
1041 
-
1042 void
-
1043 Sim::NetDockShip(Ship* ship, Ship* carrier, FlightDeck* deck)
-
1044 {
-
1045  SimRegion* rgn = ship->GetRegion();
-
1046  if (rgn)
-
1047  rgn->NetDockShip(ship, carrier, deck);
-
1048 }
-
1049 
-
1050 Ship*
- -
1052 {
-
1053  Ship* ship = 0;
-
1054 
- -
1056  while (++rgn && !ship)
-
1057  ship = rgn->FindShipByObjID(objid);
-
1058 
-
1059  return ship;
-
1060 }
-
1061 
-
1062 Shot*
- -
1064 {
-
1065  Shot* shot = 0;
-
1066 
- -
1068  while (++rgn && !shot)
-
1069  shot = rgn->FindShotByObjID(objid);
-
1070 
-
1071  return shot;
-
1072 }
-
1073 
-
1074 // +--------------------------------------------------------------------+
-
1075 
-
1076 Orbital*
-
1077 Sim::FindOrbitalBody(const char* name)
-
1078 {
-
1079  Orbital* body = 0;
-
1080 
-
1081  if (mission) {
- -
1083  while (++iter && !body) {
-
1084  StarSystem* sys = iter.value();
-
1085  body = sys->FindOrbital(name);
-
1086  }
-
1087  }
-
1088 
-
1089  return body;
-
1090 }
-
1091 
-
1092 
-
1093 // +--------------------------------------------------------------------+
-
1094 
-
1095 Shot*
-
1096 Sim::CreateShot(const Point& pos, const Camera& shot_cam, WeaponDesign* design, const Ship* ship, SimRegion* rgn)
-
1097 {
-
1098  Shot* shot = 0;
-
1099 
-
1100  if (design->drone)
-
1101  shot = new(__FILE__,__LINE__) Drone(pos, shot_cam, design, ship);
-
1102  else
-
1103  shot = new(__FILE__,__LINE__) Shot( pos, shot_cam, design, ship);
-
1104 
-
1105  if (rgn)
-
1106  rgn->InsertObject(shot);
-
1107 
-
1108  else if (active_region)
-
1109  active_region->InsertObject(shot);
-
1110 
-
1111  return shot;
-
1112 }
-
1113 
-
1114 // +--------------------------------------------------------------------+
-
1115 
-
1116 Explosion*
-
1117 Sim::CreateExplosion(const Point& pos, const Point& vel, int type, float exp_scale, float part_scale, SimRegion* rgn, SimObject* source, System* sys)
-
1118 {
-
1119  // don't bother creating explosions that can't be seen:
-
1120  if (!rgn || !active_region || rgn != active_region)
-
1121  return 0;
-
1122 
-
1123  Explosion* exp = new(__FILE__,__LINE__) Explosion(type, pos, vel, exp_scale, part_scale, rgn, source);
-
1124 
-
1125  if (rgn)
-
1126  rgn->InsertObject(exp);
-
1127 
-
1128  else if (active_region)
- -
1130 
-
1131  return exp;
-
1132 }
-
1133 
-
1134 // +--------------------------------------------------------------------+
-
1135 
-
1136 Debris*
-
1137 Sim::CreateDebris(const Point& pos, const Point& vel, Model* model, double mass, SimRegion* rgn)
-
1138 {
-
1139  Debris* debris = new(__FILE__,__LINE__) Debris(model, pos, vel, mass);
-
1140 
-
1141  if (rgn)
-
1142  rgn->InsertObject(debris);
-
1143 
-
1144  else if (active_region)
-
1145  active_region->InsertObject(debris);
-
1146 
-
1147  return debris;
-
1148 }
-
1149 
-
1150 // +--------------------------------------------------------------------+
-
1151 
-
1152 Asteroid*
-
1153 Sim::CreateAsteroid(const Point& pos, int t, double mass, SimRegion* rgn)
-
1154 {
-
1155  Asteroid* asteroid = new(__FILE__,__LINE__) Asteroid(t, pos, mass);
-
1156 
-
1157  if (rgn)
-
1158  rgn->InsertObject(asteroid);
-
1159 
-
1160  else if (active_region)
-
1161  active_region->InsertObject(asteroid);
-
1162 
-
1163  return asteroid;
-
1164 }
-
1165 
-
1166 // +--------------------------------------------------------------------+
-
1167 
-
1168 void
- -
1170 {
-
1171  if (ship && ship->GetRegion() && ship->Design()->splash_radius > 1) {
-
1172  SimSplash* splash = new(__FILE__,__LINE__)
-
1173  SimSplash(ship->GetRegion(),
-
1174  ship->Location(),
-
1175  ship->Design()->integrity / 4,
-
1176  ship->Design()->splash_radius);
-
1177 
-
1178  splash->owner_name = ship->Name();
-
1179  splashlist.append(splash);
-
1180  }
-
1181 }
-
1182 
-
1183 // +--------------------------------------------------------------------+
-
1184 
-
1185 void
- -
1187 {
-
1188  if (shot && shot->GetRegion()) {
-
1189  double damage = shot->Damage();
-
1190  if (damage < shot->Design()->damage)
-
1191  damage = shot->Design()->damage;
-
1192 
-
1193  SimSplash* splash = new(__FILE__,__LINE__)
-
1194  SimSplash(shot->GetRegion(),
-
1195  shot->Location(),
-
1196  damage,
-
1197  shot->Design()->lethal_radius);
-
1198 
-
1199  if (shot->Owner())
-
1200  splash->owner_name = shot->Owner()->Name();
-
1201 
-
1202  splash->missile = shot->IsMissile();
-
1203 
-
1204  splashlist.append(splash);
-
1205  CreateExplosion(shot->Location(), Point(), Explosion::SHOT_BLAST, 20.0f, 1.0f, shot->GetRegion());
-
1206  }
-
1207 }
-
1208 
-
1209 // +--------------------------------------------------------------------+
-
1210 
-
1211 void
-
1212 Sim::ShowGrid(int show)
-
1213 {
-
1214  Player* player = Player::GetCurrentPlayer();
-
1215 
-
1216  if (player && player->GridMode() == 0) {
-
1217  show = 0;
-
1218  grid_shown = false;
-
1219  }
-
1220 
- -
1222  while (++rgn) {
-
1223  rgn->ShowGrid(show);
-
1224  }
-
1225 
-
1226  grid_shown = show?true:false;
-
1227 }
-
1228 
-
1229 bool
- -
1231 {
-
1232  return grid_shown;
-
1233 }
-
1234 
-
1235 // +--------------------------------------------------------------------+
-
1236 
- - -
1239 {
-
1240  if (mission)
-
1241  return mission->GetSystemList();
-
1242 
-
1243  static List<StarSystem> dummy_system_list;
-
1244  return dummy_system_list;
-
1245 }
-
1246 
-
1247 // +--------------------------------------------------------------------+
-
1248 
-
1249 void
- -
1251 {
-
1252  if (active_region)
- -
1254 }
-
1255 
-
1256 Ship*
- -
1258 {
-
1259  if (active_region)
-
1260  return active_region->GetPlayerShip();
-
1261 
- -
1263  if (stars && stars->InCutscene()) {
-
1264  Ship* player = 0;
-
1265 
- -
1267  while (++rgn && !player) {
-
1268  player = rgn->GetPlayerShip();
-
1269  }
-
1270 
-
1271  return player;
-
1272  }
-
1273 
-
1274  return 0;
-
1275 }
-
1276 
-
1277 Element*
- -
1279 {
-
1280  Element* elem = 0;
-
1281 
-
1282  for (int i = 0; i < elements.size(); i++) {
-
1283  Element* e = elements[i];
-
1284 
-
1285  if (e->Player() > 0)
-
1286  elem = e;
-
1287  }
-
1288 
-
1289  return elem;
-
1290 }
-
1291 
-
1292 bool
- -
1294 {
-
1295  if (active_region)
-
1296  return active_region->IsSelected(s);
-
1297 
-
1298  return false;
-
1299 }
-
1300 
- - -
1303 {
-
1304  if (active_region)
-
1305  return active_region->GetSelection();
-
1306 
-
1307  static List<Ship> empty;
-
1308  return empty;
-
1309 }
-
1310 
-
1311 void
- -
1313 {
-
1314  if (active_region)
- -
1316 }
-
1317 
-
1318 void
- -
1320 {
-
1321  if (active_region)
- -
1323 }
-
1324 
-
1325 void
- -
1327 {
-
1328  if (active_region)
-
1329  active_region->SetSelection(newsel);
-
1330 }
-
1331 
-
1332 // +--------------------------------------------------------------------+
-
1333 
-
1334 void
- -
1336 {
-
1337  test_mode = t;
-
1338  Ship* pship = GetPlayerShip();
-
1339 
-
1340  if (pship)
-
1341  if (IsTestMode())
-
1342  pship->SetControls(0);
-
1343  else
-
1344  pship->SetControls(ctrl);
-
1345 }
-
1346 
-
1347 // +--------------------------------------------------------------------+
-
1348 
-
1349 SimRegion*
-
1350 Sim::FindRegion(const char* name)
-
1351 {
- -
1353  while (++rgn)
-
1354  if (rgn->name == name)
-
1355  return rgn.value();
-
1356 
-
1357  return 0;
-
1358 }
-
1359 
-
1360 SimRegion*
- -
1362 {
- -
1364  while (++rgn)
-
1365  if (rgn->orbital_region == orgn)
-
1366  return rgn.value();
-
1367 
-
1368  return 0;
-
1369 }
-
1370 
-
1371 // +--------------------------------------------------------------------+
-
1372 
-
1373 SimRegion*
- -
1375 {
-
1376  return FindNearestRegion(object, REAL_SPACE);
-
1377 }
-
1378 
-
1379 SimRegion*
- -
1381 {
-
1382  return FindNearestRegion(object, AIR_SPACE);
-
1383 }
-
1384 
-
1385 SimRegion*
- -
1387 {
-
1388  if (!object) return 0;
-
1389 
-
1390  SimRegion* result = 0;
-
1391  double distance = 1.0e40;
-
1392  Point objloc = object->Location();
-
1393 
-
1394  objloc = objloc.OtherHand();
-
1395 
-
1396  if (object->GetRegion())
-
1397  objloc += object->GetRegion()->Location();
-
1398 
- -
1400  while (++rgn) {
-
1401  if (rgn->Type() == type) {
-
1402  OrbitalRegion* orgn = rgn->GetOrbitalRegion();
-
1403  if (orgn) {
-
1404  double test = fabs((orgn->Location() - objloc).length());
-
1405  if (test < distance) {
-
1406  result = rgn.value();
-
1407  distance = test;
-
1408  }
-
1409  }
-
1410  }
-
1411  }
-
1412 
-
1413  return result;
-
1414 }
-
1415 
-
1416 SimRegion*
- -
1418 {
-
1419  SimRegion* result = 0;
-
1420 
-
1421  if (!body)
-
1422  return result;
-
1423 
- -
1425  while (++rgn && !result) {
-
1426  if (rgn->IsOrbital()) {
-
1427  OrbitalRegion* orgn = rgn->GetOrbitalRegion();
-
1428  if (orgn) {
-
1429  ListIter<OrbitalRegion> iter = body->Regions();
-
1430  while (++iter) {
-
1431  if (iter.value() == orgn)
-
1432  result = rgn.value();
-
1433  }
-
1434  }
-
1435  }
-
1436  }
-
1437 
-
1438  return result;
-
1439 }
-
1440 
-
1441 // +--------------------------------------------------------------------+
-
1442 
-
1443 bool
- -
1445 {
-
1446  if (rgn && active_region != rgn && regions.contains(rgn)) {
-
1447  if (active_region)
- -
1449 
-
1450  if (!active_region || active_region->System() != rgn->System()) {
-
1451  if (active_region)
- -
1453  rgn->System()->Activate(scene);
-
1454  }
-
1455 
-
1456  active_region = rgn;
- -
1458 
-
1459  if (star_system) {
- -
1461  }
-
1462  else {
-
1463  ::Print("WARNING: Sim::ActivateRegion() No star system found for rgn '%s'", rgn->Name());
-
1464  }
-
1465 
- -
1467  return true;
-
1468  }
-
1469 
-
1470  return false;
-
1471 }
-
1472 
-
1473 // +--------------------------------------------------------------------+
-
1474 
-
1475 void
- -
1477 int type, Ship* fc1, Ship* fc2)
-
1478 {
-
1479  bool hyperdrive = false;
-
1480 
-
1481  if (obj->GetQuantumDrive() && obj->GetQuantumDrive()->Subtype() == QuantumDrive::HYPER)
-
1482  hyperdrive = true;
-
1483 
-
1484  jumplist.append(new(__FILE__,__LINE__) SimHyper(obj, rgn, loc, type, hyperdrive, fc1, fc2));
-
1485 }
-
1486 
-
1487 // +--------------------------------------------------------------------+
-
1488 
-
1489 void
-
1490 Sim::ExecFrame(double seconds)
-
1491 {
-
1492  if (first_frame) {
-
1493  first_frame = false;
- -
1495  }
-
1496 
-
1497  if (netgame)
-
1498  netgame->ExecFrame();
-
1499 
-
1500  if (regions.isEmpty()) {
-
1501  active_region = 0;
-
1502  rgn_queue.clear();
-
1503  jumplist.destroy();
-
1504  scene.Collect();
-
1505  return;
-
1506  }
-
1507 
-
1508  ListIter<Element> elem = elements;
-
1509  while (++elem)
-
1510  if (!elem->IsSquadron())
-
1511  elem->ExecFrame(seconds);
-
1512 
- -
1514  while (++rgn)
-
1515  if (rgn.value() != active_region && rgn->NumShips() && !rgn_queue.contains(rgn.value()))
-
1516  rgn_queue.append(rgn.value());
-
1517 
-
1518  // execframe for one inactive sim region:
-
1519  if (rgn_queue.size()) {
-
1520  SimRegion* exec_rgn = rgn_queue.removeIndex(0);
-
1521 
-
1522  while (exec_rgn && (exec_rgn->NumShips() == 0 || exec_rgn == active_region))
-
1523  if (rgn_queue.size())
-
1524  exec_rgn = rgn_queue.removeIndex(0);
-
1525  else
-
1526  exec_rgn = 0;
-
1527 
-
1528  if (exec_rgn)
-
1529  exec_rgn->ExecFrame(seconds);
-
1530  }
-
1531 
-
1532  if (active_region)
-
1533  active_region->ExecFrame(seconds);
-
1534 
-
1535  ExecEvents(seconds);
-
1536  ResolveHyperList();
- -
1538 
-
1539  // GC all the dead objects:
-
1540  scene.Collect();
-
1541 
-
1542  if (!IsTestMode()) {
-
1543  ListIter<Element> e_iter = elements;
-
1544  while (++e_iter) {
-
1545  Element* elem = e_iter.value();
-
1546  if (!elem->IsSquadron() && elem->IsFinished()) {
-
1547  finished.append(e_iter.removeItem());
-
1548  }
-
1549  }
-
1550  }
-
1551 
-
1552  // setup music
-
1553  if (!MusicDirector::IsNoMusic()) {
- -
1555  if (stars && stars->GetGameMode() == Starshatter::PLAY_MODE) {
-
1556  Ship* player_ship = GetPlayerShip();
-
1557  if (player_ship) {
-
1558  int phase = player_ship->GetFlightPhase();
-
1559 
-
1560  if (phase < Ship::ACTIVE) {
- -
1562  }
-
1563 
-
1564  else if (phase > Ship::ACTIVE) {
- -
1566  }
-
1567 
-
1568  else {
-
1569  if (player_ship->IsInCombat()) {
- -
1571  }
-
1572 
-
1573  else {
- -
1575  }
-
1576  }
-
1577  }
-
1578  }
-
1579  }
-
1580 }
-
1581 
-
1582 void
-
1583 Sim::ExecEvents(double seconds)
-
1584 {
- -
1586  while (++iter) {
-
1587  MissionEvent* event = iter.value();
-
1588  event->ExecFrame(seconds);
-
1589  }
-
1590 }
-
1591 
-
1592 void
- -
1594 {
-
1595  // resolve the hyper space transitions:
-
1596  if (jumplist.size()) {
-
1597  Ship* pship = GetPlayerShip();
-
1598 
-
1599  ListIter<SimHyper> j_iter = jumplist;
-
1600  while (++j_iter) {
-
1601  SimHyper* jump = j_iter.value();
-
1602  Ship* jumpship = jump->ship;
-
1603 
-
1604  if (jumpship) {
-
1605  SimRegion* dest = jump->rgn;
-
1606 
-
1607  if (!dest)
-
1608  dest = FindNearestSpaceRegion(jumpship);
-
1609 
-
1610  if (dest) {
-
1611  // bring along fighters on deck:
-
1612  ListIter<FlightDeck> deck = jumpship->FlightDecks();
-
1613  while (++deck) {
-
1614  for (int i = 0; i < deck->NumSlots(); i++) {
-
1615  Ship* s = deck->GetShip(i);
-
1616 
-
1617  if (s) {
-
1618  dest->InsertObject(s);
-
1619  s->ClearTrack();
-
1620  }
-
1621  }
-
1622  }
-
1623 
-
1624  if (jump->type == 0 && !jump->hyperdrive) {
-
1625  // bring along nearby ships:
-
1626  // have to do it in two parts, because inserting the ships
-
1627  // into the destination corrupts the iter over the current
-
1628  // region's list of ships...
-
1629 
-
1630  // part one: gather the ships that will be jumping:
-
1631  List<Ship> riders;
-
1632  ListIter<Ship> neighbor = jumpship->GetRegion()->Ships();
-
1633  while (++neighbor) {
-
1634  if (neighbor->IsDropship()) {
-
1635  Ship* s = neighbor.value();
-
1636  if (s == jumpship) continue;
-
1637 
-
1638  Point delta = s->Location() - jumpship->Location();
-
1639 
-
1640  if (delta.length() < 5e3) {
-
1641  riders.append(s);
-
1642  }
-
1643  }
-
1644  }
-
1645 
-
1646  // part two: now transfer the list to the destination:
-
1647  for (int i = 0; i < riders.size(); i++) {
-
1648  Ship* s = riders[i];
-
1649  Point delta = s->Location() - jumpship->Location();
-
1650  dest->InsertObject(s);
-
1651  s->MoveTo(jump->loc.OtherHand() + delta);
-
1652  s->ClearTrack();
-
1653 
-
1654  if (jump->fc_dst) {
-
1655  double r = jump->fc_dst->Roll();
-
1656  double p = jump->fc_dst->Pitch();
-
1657  double w = jump->fc_dst->Yaw();
-
1658 
-
1659  s->SetAbsoluteOrientation(r, p, w);
-
1660  s->SetVelocity(jump->fc_dst->Heading() * 500);
-
1661  }
-
1662 
- -
1664  }
-
1665  }
-
1666 
-
1667  // now it is safe to move the main jump ship:
-
1668  dest->InsertObject(jumpship);
-
1669  jumpship->MoveTo(jump->loc.OtherHand());
-
1670  jumpship->ClearTrack();
-
1671 
- -
1673  NetUtil::SendObjHyper(jumpship, dest->Name(), jump->loc, jump->fc_src, jump->fc_dst, jump->type);
-
1674 
-
1675  // if using farcaster:
-
1676  if (jump->fc_src) {
-
1677  ::Print("Ship '%s' farcast to '%s'\n", jumpship->Name(), dest->Name());
-
1678  CreateExplosion(jumpship->Location(), Point(0,0,0), Explosion::QUANTUM_FLASH, 1.0f, 0, dest);
-
1679 
-
1680  if (jump->fc_dst) {
-
1681  double r = jump->fc_dst->Roll();
-
1682  double p = jump->fc_dst->Pitch();
-
1683  double w = jump->fc_dst->Yaw();
-
1684 
-
1685  jumpship->SetAbsoluteOrientation(r, p, w);
-
1686  jumpship->SetVelocity(jump->fc_dst->Heading() * 500);
-
1687  }
-
1688 
-
1689  jumpship->SetHelmHeading(jumpship->CompassHeading());
-
1690  jumpship->SetHelmPitch(0);
-
1691  }
-
1692 
-
1693  // break orbit:
-
1694  else if (jump->type == Ship::TRANSITION_DROP_ORBIT) {
-
1695  ::Print("Ship '%s' broke orbit to '%s'\n", jumpship->Name(), dest->Name());
-
1696  jumpship->SetAbsoluteOrientation(0,PI/4,0);
-
1697  jumpship->SetVelocity(jumpship->Heading() * 1.0e3);
-
1698  }
-
1699 
-
1700  // make orbit:
-
1701  else if (jump->type == Ship::TRANSITION_MAKE_ORBIT) {
-
1702  ::Print("Ship '%s' achieved orbit '%s'\n", jumpship->Name(), dest->Name());
-
1703  jumpship->LookAt(Point(0,0,0));
-
1704  jumpship->SetVelocity(jumpship->Heading() * 500.0);
-
1705  }
-
1706 
-
1707  // hyper jump:
-
1708  else {
-
1709  ::Print("Ship '%s' quantum to '%s'\n", jumpship->Name(), dest->Name());
-
1710 
-
1711  if (jump->hyperdrive)
-
1712  CreateExplosion(jumpship->Location(), Point(0,0,0), Explosion::HYPER_FLASH, 1, 1, dest);
-
1713  else
-
1714  CreateExplosion(jumpship->Location(), Point(0,0,0), Explosion::QUANTUM_FLASH, 1, 0, dest);
-
1715 
-
1716  jumpship->LookAt(Point(0,0,0));
-
1717  jumpship->SetVelocity(jumpship->Heading() * 500.0);
-
1718  jumpship->SetHelmHeading(jumpship->CompassHeading());
-
1719  jumpship->SetHelmPitch(0);
-
1720  }
-
1721  }
-
1722 
-
1723  else if (regions.size() > 1) {
-
1724  ::Print("Warning: Unusual jump request for ship '%s'\n", jumpship->Name());
-
1725  regions[1]->InsertObject(jumpship);
-
1726  }
-
1727 
-
1728  Sensor* sensor = jumpship->GetSensor();
-
1729  if (sensor)
-
1730  sensor->ClearAllContacts();
-
1731  }
-
1732  }
-
1733 
-
1734  jumplist.destroy();
-
1735 
-
1736  if (pship && pship->GetRegion()) {
-
1737  if (active_region != pship->GetRegion()) {
-
1738  pship->GetRegion()->SetPlayerShip(pship);
-
1739  }
-
1740  }
-
1741  }
-
1742 }
-
1743 
-
1744 void
- -
1746 {
-
1747  if (splashlist.size()) {
- -
1749  while (++iter) {
-
1750  SimSplash* splash = iter.value();
-
1751 
-
1752  if (!splash->rgn)
-
1753  continue;
-
1754 
-
1755  // damage ships:
-
1756  ListIter<Ship> s_iter = splash->rgn->Ships();
-
1757  while (++s_iter) {
-
1758  Ship* ship = s_iter.value();
-
1759 
-
1760  double distance = (ship->Location() - splash->loc).length();
-
1761 
-
1762  if (distance > 1 && distance < splash->range) {
-
1763  double damage = splash->damage * (1 - distance/splash->range);
-
1764  if (!NetGame::IsNetGameClient()) {
-
1765  ship->InflictDamage(damage);
-
1766  }
-
1767 
-
1768  int ship_destroyed = (!ship->InTransition() && ship->Integrity() < 1.0f);
-
1769 
-
1770  // then delete the ship:
-
1771  if (ship_destroyed) {
- -
1773  Print(" %s Killed %s (%s)\n", (const char*) splash->owner_name, ship->Name(), FormatGameTime());
-
1774 
-
1775  // record the kill
-
1776  ShipStats* killer = ShipStats::Find(splash->owner_name);
-
1777  if (killer) {
-
1778  if (splash->missile)
-
1779  killer->AddEvent(SimEvent::MISSILE_KILL, ship->Name());
-
1780  else
-
1781  killer->AddEvent(SimEvent::GUNS_KILL, ship->Name());
-
1782  }
-
1783 
-
1784  Ship* owner = FindShip(splash->owner_name, splash->rgn->Name());
-
1785  if (owner && owner->GetIFF() != ship->GetIFF()) {
-
1786  if (ship->GetIFF() > 0 || owner->GetIFF() > 1) {
-
1787  killer->AddPoints(ship->Value());
-
1788 
-
1789  Element* elem = owner->GetElement();
-
1790  if (elem) {
-
1791  if (owner->GetElementIndex() > 1) {
-
1792  Ship* s = elem->GetShip(1);
-
1793 
-
1794  if (s) {
-
1795  ShipStats* cmdr_stats = ShipStats::Find(s->Name());
-
1796  if (cmdr_stats) {
-
1797  cmdr_stats->AddCommandPoints(ship->Value()/2);
-
1798  }
-
1799  }
-
1800  }
-
1801 
-
1802  Element* cmdr = elem->GetCommander();
-
1803  if (cmdr) {
-
1804  Ship* s = cmdr->GetShip(1);
-
1805 
-
1806  if (s) {
-
1807  ShipStats* cmdr_stats = ShipStats::Find(s->Name());
-
1808  if (cmdr_stats) {
-
1809  cmdr_stats->AddCommandPoints(ship->Value()/2);
-
1810  }
-
1811  }
-
1812  }
-
1813  }
-
1814  }
-
1815  }
-
1816 
-
1817  ShipStats* killee = ShipStats::Find(ship->Name());
-
1818  if (killee)
-
1819  killee->AddEvent(SimEvent::DESTROYED, splash->owner_name);
-
1820 
-
1821  ship->DeathSpiral();
-
1822  }
-
1823  }
-
1824  }
-
1825 
-
1826  // damage drones:
-
1827  ListIter<Drone> drone_iter = splash->rgn->Drones();
-
1828  while (++drone_iter) {
-
1829  Drone* drone = drone_iter.value();
-
1830 
-
1831  double distance = (drone->Location() - splash->loc).length();
-
1832 
-
1833  if (distance > 1 && distance < splash->range) {
-
1834  double damage = splash->damage * (1 - distance/splash->range);
-
1835  drone->InflictDamage(damage);
-
1836 
-
1837  int destroyed = (drone->Integrity() < 1.0f);
-
1838 
-
1839  // then mark the drone for deletion:
-
1840  if (destroyed) {
-
1841  NetUtil::SendWepDestroy(drone);
-
1842  sim->CreateExplosion(drone->Location(), drone->Velocity(), 21 /* was LARGE_EXP */, 1.0f, 1.0f, splash->rgn);
-
1843  drone->SetLife(0);
-
1844  }
-
1845  }
-
1846  }
-
1847  }
-
1848 
-
1849  splashlist.destroy();
-
1850  }
-
1851 }
-
1852 
-
1853 // +--------------------------------------------------------------------+
-
1854 
-
1855 void
-
1856 Sim::ProcessEventTrigger(int type, int event_id, const char* ship, int param)
-
1857 {
-
1858  Text ship_name = ship;
-
1859 
- -
1861  while (++iter) {
-
1862  MissionEvent* event = iter.value();
-
1863 
-
1864  if (event->IsPending() && event->Trigger() == type) {
-
1865  switch (type) {
- - - - - - -
1872  if (event->TriggerParam() <= param) {
-
1873  if (ship_name.indexOf(event->TriggerShip()) == 0)
-
1874  event->Activate();
-
1875  }
-
1876  break;
-
1877 
- -
1879  if (event->TriggerParam() == param) {
-
1880  if (ship_name.indexOf(event->TriggerShip()) == 0)
-
1881  event->Activate();
-
1882  }
-
1883  break;
-
1884 
- - -
1887  if (event->TriggerParam() == event_id)
-
1888  event->Activate();
-
1889  break;
-
1890  }
-
1891  }
-
1892  }
-
1893 }
-
1894 
-
1895 double
- -
1897 {
-
1898  return (Game::GameTime() - start_time) / 1000.0;
-
1899 }
-
1900 
-
1901 // +--------------------------------------------------------------------+
-
1902 
-
1903 void
- -
1905 {
- -
1907  if (stars && stars->InCutscene()) {
- -
1909  bool end = false;
-
1910  double end_time = 0;
-
1911 
-
1912  while (++iter && !end) {
-
1913  MissionEvent* event = iter.value();
-
1914 
-
1915  if (event->IsPending() || event->IsActive()) {
-
1916  if (event->Event() == MissionEvent::END_SCENE ||
-
1917  event->Event() == MissionEvent::END_MISSION) {
-
1918  end = true;
-
1919  end_time = event->Time();
-
1920  }
-
1921 
-
1922  if (event->Event() == MissionEvent::FIRE_WEAPON) {
-
1923  event->Skip();
-
1924  }
-
1925 
-
1926  else {
-
1927  event->Activate();
-
1928  event->Execute(true);
-
1929  }
-
1930  }
-
1931  }
-
1932 
-
1933  double skip_time = end_time - MissionClock();
-
1934  if (skip_time > 0) {
-
1935  Game::SkipGameTime(skip_time);
-
1936  }
-
1937  }
-
1938 }
-
1939 
-
1940 // +--------------------------------------------------------------------+
-
1941 
-
1942 void
-
1943 Sim::ResolveTimeSkip(double seconds)
-
1944 {
-
1945  double skipped = 0;
-
1946 
-
1947  // allow elements to process hold time, and release as needed:
-
1948  ListIter<Element> elem = elements;
-
1949  while (++elem)
-
1950  elem->ExecFrame(seconds);
-
1951 
-
1952  // step through the skip, ten seconds at a time:
-
1953  if (active_region) {
-
1954  double total_skip = seconds;
-
1955  double frame_skip = 10;
-
1956  Ship* player = GetPlayerShip();
-
1957 
-
1958  while (total_skip > frame_skip) {
-
1959  if (active_region->CanTimeSkip()) {
-
1960  active_region->ResolveTimeSkip(frame_skip);
-
1961  total_skip -= frame_skip;
-
1962  skipped += frame_skip;
-
1963  }
-
1964  // break out early if player runs into bad guys...
-
1965  else {
-
1966  total_skip = 0;
-
1967  }
-
1968  }
-
1969 
-
1970  if (total_skip > 0)
-
1971  active_region->ResolveTimeSkip(total_skip);
-
1972  skipped += total_skip;
-
1973  }
-
1974 
-
1975  // give player control after time skip:
-
1976  Ship* player_ship = GetPlayerShip();
-
1977  if (player_ship) {
-
1978  player_ship->SetAutoNav(false);
-
1979  player_ship->SetThrottle(75);
-
1980 
-
1981  HUDView* hud = HUDView::GetInstance();
-
1982  if (hud)
- -
1984 
-
1985  if (IsTestMode())
-
1986  player_ship->SetControls(0);
-
1987  }
-
1988 
-
1989  Game::SkipGameTime(skipped);
- -
1991 }
-
1992 
-
1993 // +--------------------------------------------------------------------+
-
1994 
- - -
1997 {
- -
1999 
-
2000  ListIter<Element> iter = elements;
-
2001  while (++iter) {
-
2002  Element* elem = iter.value();
-
2003 
-
2004  int num_live_ships = 0;
-
2005 
-
2006  for (int i = 0; i < elem->NumShips(); i++) {
-
2007  Ship* s = elem->GetShip(i+1);
-
2008 
-
2009  if (s && !s->IsDying() && !s->IsDead())
-
2010  num_live_ships++;
-
2011  }
-
2012 
-
2013  if (elem->IsSquadron() || num_live_ships > 0) {
-
2014  MissionElement* msn_elem = CreateMissionElement(elem);
-
2015 
-
2016  if (msn_elem)
-
2017  mission_elements.append(msn_elem);
-
2018  }
-
2019  }
-
2020 
-
2021  return mission_elements;
-
2022 }
-
2023 
- - -
2026 {
-
2027  MissionElement* msn_elem = 0;
-
2028 
-
2029  if (elem->IsSquadron()) {
-
2030  if (!elem->GetCarrier() || elem->GetCarrier()->Integrity() < 1)
-
2031  return msn_elem;
-
2032  }
-
2033 
-
2034  if (elem && !elem->IsNetObserver()) {
-
2035  msn_elem = new(__FILE__,__LINE__) MissionElement;
-
2036 
-
2037  msn_elem->SetName(elem->Name());
-
2038  msn_elem->SetIFF(elem->GetIFF());
-
2039  msn_elem->SetMissionRole(elem->Type());
-
2040 
-
2041  if (elem->IsSquadron() && elem->GetCarrier()) {
-
2042  Ship* carrier = elem->GetCarrier();
-
2043 
-
2044  msn_elem->SetCarrier(carrier->Name());
-
2045  msn_elem->SetCount(elem->GetCount());
-
2046  msn_elem->SetLocation(carrier->Location().OtherHand());
-
2047 
-
2048  if (carrier->GetRegion())
-
2049  msn_elem->SetRegion(carrier->GetRegion()->Name());
-
2050 
-
2051  int squadron_index = 0;
-
2052  Hangar* hangar = FindSquadron(elem->Name(), squadron_index);
-
2053 
-
2054  if (hangar) {
-
2055  msn_elem->SetDeadCount(hangar->NumShipsDead(squadron_index));
-
2056  msn_elem->SetMaintCount(hangar->NumShipsMaint(squadron_index));
-
2057 
-
2058  const ShipDesign* design = hangar->SquadronDesign(squadron_index);
-
2059  msn_elem->SetDesign(design);
-
2060 
-
2061  Text design_path = design->path_name;
-
2062  design_path.setSensitive(false);
-
2063 
-
2064  if (design_path.indexOf("/Mods/Ships") == 0) {
-
2065  design_path = design_path.substring(11, 1000);
-
2066  msn_elem->SetPath(design_path);
-
2067  }
-
2068  }
-
2069  }
-
2070 
-
2071  else {
-
2072  msn_elem->SetSquadron(elem->GetSquadron());
-
2073  msn_elem->SetCount(elem->NumShips());
-
2074  }
-
2075 
-
2076  if (elem->GetCommander())
-
2077  msn_elem->SetCommander(elem->GetCommander()->Name());
-
2078 
-
2079  msn_elem->SetCombatGroup(elem->GetCombatGroup());
-
2080  msn_elem->SetCombatUnit(elem->GetCombatUnit());
-
2081 
-
2082  Ship* ship = elem->GetShip(1);
-
2083  if (ship) {
-
2084  if (ship->GetRegion())
-
2085  msn_elem->SetRegion(ship->GetRegion()->Name());
-
2086 
-
2087  msn_elem->SetLocation(ship->Location().OtherHand());
-
2088  msn_elem->SetDesign(ship->Design());
-
2089 
-
2090  msn_elem->SetPlayer(elem->Player());
-
2091  msn_elem->SetCommandAI(elem->GetCommandAILevel());
-
2092  msn_elem->SetHoldTime((int) elem->GetHoldTime());
-
2093  msn_elem->SetZoneLock(elem->GetZoneLock());
-
2094  msn_elem->SetHeading(ship->CompassHeading());
-
2095 
-
2096  msn_elem->SetPlayable(elem->IsPlayable());
-
2097  msn_elem->SetRogue(elem->IsRogue());
-
2098  msn_elem->SetIntelLevel(elem->IntelLevel());
-
2099 
-
2100  Text design_path = ship->Design()->path_name;
-
2101  design_path.setSensitive(false);
-
2102 
-
2103  if (design_path.indexOf("/Mods/Ships") == 0) {
-
2104  design_path = design_path.substring(11, 1000);
-
2105  msn_elem->SetPath(design_path);
-
2106  }
-
2107 
-
2108  msn_elem->SetRespawnCount(ship->RespawnCount());
-
2109  }
-
2110 
-
2111  MissionLoad* loadout = new(__FILE__,__LINE__) MissionLoad;
-
2112  CopyMemory(loadout->GetStations(), elem->Loadout(), 16 * sizeof(int));
-
2113 
-
2114  msn_elem->Loadouts().append(loadout);
-
2115 
-
2116  int num_obj = elem->NumObjectives();
-
2117  for (int i = 0; i < num_obj; i++) {
-
2118  Instruction* o = elem->GetObjective(i);
-
2119  Instruction* instr = 0;
-
2120 
-
2121  instr = new(__FILE__,__LINE__) Instruction(*o);
-
2122 
-
2123  msn_elem->AddObjective(instr);
-
2124  }
-
2125 
-
2126  int num_inst = elem->NumInstructions();
-
2127  for (int i = 0; i < num_inst; i++) {
-
2128  Text instr = elem->GetInstruction(i);
-
2129  msn_elem->AddInstruction(instr);
-
2130  }
-
2131 
-
2132  ListIter<Instruction> nav_iter = elem->GetFlightPlan();
-
2133  while (++nav_iter) {
-
2134  Instruction* nav = nav_iter.value();
-
2135  Instruction* npt = new(__FILE__,__LINE__)
-
2136  Instruction(nav->RegionName(), nav->Location(), nav->Action());
-
2137 
-
2138  npt->SetFormation(nav->Formation());
-
2139  npt->SetSpeed(nav->Speed());
-
2140  npt->SetTarget(nav->TargetName());
-
2141  npt->SetHoldTime(nav->HoldTime());
-
2142  npt->SetFarcast(nav->Farcast());
-
2143  npt->SetStatus(nav->Status());
-
2144 
-
2145  msn_elem->AddNavPoint(npt);
-
2146  }
-
2147 
-
2148  for (int i = 0; i < elem->NumShips(); i++) {
-
2149  ship = elem->GetShip(i+1);
-
2150 
-
2151  if (ship) {
-
2152  MissionShip* s = new(__FILE__,__LINE__) MissionShip;
-
2153 
-
2154  s->SetName(ship->Name());
-
2155  s->SetRegNum(ship->Registry());
-
2156  s->SetRegion(ship->GetRegion()->Name());
-
2157  s->SetLocation(ship->Location().OtherHand());
-
2158  s->SetVelocity(ship->Velocity().OtherHand());
-
2159 
-
2160  s->SetRespawns(ship->RespawnCount());
-
2161  s->SetHeading(ship->CompassHeading());
-
2162  s->SetIntegrity(ship->Integrity());
-
2163 
-
2164  if (ship->GetDecoy())
-
2165  s->SetDecoys(ship->GetDecoy()->Ammo());
-
2166 
-
2167  if (ship->GetProbeLauncher())
-
2168  s->SetProbes(ship->GetProbeLauncher()->Ammo());
-
2169 
-
2170  int n;
-
2171  int ammo[16];
-
2172  int fuel[4];
-
2173 
-
2174  for (n = 0; n < 16; n++) {
-
2175  Weapon* w = ship->GetWeaponByIndex(n+1);
-
2176 
-
2177  if (w)
-
2178  ammo[n] = w->Ammo();
-
2179  else
-
2180  ammo[n] = -10;
-
2181  }
-
2182 
-
2183  for (n = 0; n < 4; n++) {
-
2184  if (ship->Reactors().size() > n)
-
2185  fuel[n] = ship->Reactors()[n]->Charge();
-
2186  else
-
2187  fuel[n] = -10;
-
2188  }
-
2189 
-
2190  s->SetAmmo(ammo);
-
2191  s->SetFuel(fuel);
-
2192 
-
2193  msn_elem->Ships().append(s);
-
2194  }
-
2195  }
-
2196  }
-
2197 
-
2198  return msn_elem;
-
2199 }
-
2200 
-
2201 Hangar*
-
2202 Sim::FindSquadron(const char* name, int& index)
-
2203 {
-
2204  Hangar* hangar = 0;
-
2205 
- -
2207  while (++iter && !hangar) {
-
2208  SimRegion* rgn = iter.value();
-
2209 
-
2210  ListIter<Ship> s_iter = rgn->Carriers();
-
2211  while (++s_iter && !hangar) {
-
2212  Ship* carrier = s_iter.value();
-
2213  Hangar* h = carrier->GetHangar();
-
2214 
-
2215  for (int i = 0; i < h->NumSquadrons() && !hangar; i++) {
-
2216  if (h->SquadronName(i) == name) {
-
2217  hangar = h;
-
2218  index = i;
-
2219  }
-
2220  }
-
2221  }
-
2222  }
-
2223 
-
2224  return hangar;
-
2225 }
-
2226 
-
2227 // +===================================================================-+
-
2228 
-
2229 SimRegion::SimRegion(Sim* s, const char* n, int t)
-
2230 : sim(s), name(n), type(t), orbital_region(0), star_system(0)
-
2231 , player_ship(0), grid(0), active(false), current_view(0), sim_time(0)
-
2232 , ai_index(0), terrain(0)
-
2233 {
-
2234  if (sim) {
- -
2236  }
-
2237 }
-
2238 
- -
2240 : sim(s), orbital_region(r), type(REAL_SPACE), star_system(0)
-
2241 , player_ship(0), grid(0), active(false), current_view(0), sim_time(0)
-
2242 , ai_index(0), terrain(0)
-
2243 {
-
2244  if (r) {
-
2245  star_system = r->System();
-
2246  }
-
2247 
-
2248  if (orbital_region) {
-
2249  name = orbital_region->Name();
-
2250  grid = new(__FILE__,__LINE__) Grid((int) orbital_region->Radius(),
-
2251  (int) orbital_region->GridSpace());
-
2252 
-
2253 
-
2254  if (orbital_region->Type() == Orbital::TERRAIN) {
- -
2256  terrain = new(__FILE__,__LINE__) Terrain(trgn);
-
2257 
-
2258  type = AIR_SPACE;
-
2259  }
-
2260 
-
2261  else if (orbital_region->Asteroids() > 0) {
- -
2263 
-
2264  for (int i = 0; i < asteroids; i++) {
-
2265  Point init_loc((rand()-16384.0f) * 30,
-
2266  (rand()-16384.0f) * 3,
-
2267  (rand()-16384.0f) * 30);
-
2268  sim->CreateAsteroid(init_loc, i, Random(1e7, 1e8), this);
-
2269  }
-
2270  }
-
2271  }
-
2272  else {
-
2273  name = Game::GetText("Unknown");
-
2274  }
-
2275 }
-
2276 
- -
2278 {
- -
2280  delete terrain;
-
2281  explosions.destroy();
-
2282  shots.destroy();
-
2283  ships.destroy();
-
2284  debris.destroy();
-
2285  asteroids.destroy();
-
2286  dead_ships.destroy();
-
2287 
-
2288  for (int i = 0; i < 5; i++)
-
2289  track_database[i].destroy();
-
2290 }
-
2291 
-
2292 int
- -
2294 {
- -
2296 }
-
2297 
-
2298 int
- -
2300 {
- -
2302 }
-
2303 
-
2304 // +--------------------------------------------------------------------+
-
2305 
-
2306 void
- -
2308 {
-
2309  // there can only be a player ship when playing the game locally
-
2310  if (Starshatter::GetInstance()) {
-
2311  int player_index = ships.index(ship);
-
2312 
-
2313  if (player_index >= 0) {
-
2314  if (sim->GetActiveRegion() != this)
-
2315  sim->ActivateRegion(this);
-
2316 
-
2317  AttachPlayerShip(player_index);
-
2318  }
-
2319 
-
2320  else {
-
2321  Print("SimRegion %s could not set player ship '%s' - not in region\n",
-
2322  name.data(), ship ? ship->Name() : "(null)");
-
2323  }
-
2324  }
-
2325 
-
2326  // if this is a stand-alone server, set player ship to null
-
2327  else {
-
2328  if (player_ship)
- -
2330 
-
2331  current_view = -1;
-
2332  player_ship = 0;
-
2333  }
-
2334 }
-
2335 
-
2336 void
- -
2338 {
-
2339  if (player_ship)
- -
2341 
-
2342  current_view = index;
- -
2344 
- -
2346  if (cam_dir)
-
2347  cam_dir->SetShip(player_ship);
-
2348 
-
2349  if (sim->dust)
- -
2351 
-
2352  if (!sim->IsTestMode())
- -
2354 
- -
2356  if (mouse_con)
-
2357  mouse_con->SetActive(false);
-
2358 }
-
2359 
-
2360 void
- -
2362 {
-
2363  if (ships.size()) {
-
2364  int original_view = current_view;
-
2365 
-
2366  do {
-
2367  current_view++;
-
2368  if (current_view >= ships.size()) {
-
2369  current_view = 0;
-
2370  }
-
2371  }
-
2372  while (ships[current_view]->Life() == 0 && current_view != original_view);
-
2373 
-
2374  if (current_view != original_view) {
-
2375  ClearSelection();
-
2376 
-
2377  if (!sim->IsTestMode())
- -
2379 
-
2380  if (player_ship->Rep())
-
2381  player_ship->Rep()->Show();
-
2382 
- -
2384  }
-
2385  }
-
2386 }
-
2387 
-
2388 bool
- -
2390 {
-
2391  return selection.contains(s);
-
2392 }
-
2393 
- - -
2396 {
-
2397  return selection;
-
2398 }
-
2399 
-
2400 void
- -
2402 {
-
2403  selection.clear();
-
2404  selection.append(newsel);
-
2405 }
-
2406 
-
2407 void
- -
2409 {
-
2410  selection.clear();
-
2411 }
-
2412 
-
2413 void
- -
2415 {
-
2416  if (!newsel ||
-
2417  newsel->GetFlightPhase() < Ship::ACTIVE ||
-
2418  newsel->GetFlightPhase() >= Ship::RECOVERY)
-
2419  return;
-
2420 
-
2421  if (!selection.contains(newsel))
-
2422  selection.append(newsel);
-
2423 }
-
2424 
-
2425 // +--------------------------------------------------------------------+
-
2426 
-
2427 void
- -
2429 {
-
2430  if (!sim) return;
-
2431 
-
2432  ListIter<Ship> ship = ships;
-
2433  while (++ship)
-
2434  ship->Activate(sim->scene);
-
2435 
-
2436  ListIter<Shot> shot = shots;
-
2437  while (++shot)
-
2438  shot->Activate(sim->scene);
-
2439 
- -
2441  while (++exp)
-
2442  exp->Activate(sim->scene);
-
2443 
-
2444  ListIter<Debris> deb = debris;
-
2445  while (++deb)
-
2446  deb->Activate(sim->scene);
-
2447 
- -
2449  while (++a)
-
2450  a->Activate(sim->scene);
-
2451 
-
2452  if (grid)
- -
2454 
-
2455  if (terrain)
- -
2457 
-
2458  player_ship = 0;
-
2459  active = true;
-
2460 }
-
2461 
-
2462 // +--------------------------------------------------------------------+
-
2463 
-
2464 void
- -
2466 {
-
2467  if (!sim) return;
-
2468 
-
2469  ListIter<Ship> ship = ships;
-
2470  while (++ship)
-
2471  ship->Deactivate(sim->scene);
-
2472 
-
2473  ListIter<Shot> shot = shots;
-
2474  while (++shot)
-
2475  shot->Deactivate(sim->scene);
-
2476 
- -
2478  while (++exp)
-
2479  exp->Deactivate(sim->scene);
-
2480 
-
2481  ListIter<Debris> deb = debris;
-
2482  while (++deb)
-
2483  deb->Deactivate(sim->scene);
-
2484 
- -
2486  while (++a)
-
2487  a->Deactivate(sim->scene);
-
2488 
-
2489  if (grid)
- -
2491 
-
2492  if (terrain)
- -
2494 
-
2495  player_ship = 0;
-
2496  active = false;
-
2497 
-
2498  for (int i = 0; i < 5; i++)
-
2499  track_database[i].destroy();
-
2500 }
-
2501 
-
2502 // +--------------------------------------------------------------------+
-
2503 
-
2504 void
- -
2506 {
-
2507  if (!sim) return;
-
2508 
-
2509  double seconds = secs;
-
2510 
-
2511  // DON'T REALLY KNOW WHAT PURPOSE THIS SERVES....
-
2512  if (!active) {
-
2513  double max_frame = 3 * Game::GetMaxFrameLength();
-
2514  long new_time = Game::GameTime();
-
2515  double delta = new_time - sim_time;
-
2516  seconds = delta / 1000.0;
-
2517 
-
2518  if (seconds > max_frame)
-
2519  seconds = max_frame;
-
2520  }
-
2521 
- -
2523 
-
2524  if (orbital_region)
- -
2526 
- -
2528 
-
2529  Point ref;
-
2530 
-
2531  if (active && cam_dir) {
-
2532  ref = cam_dir->GetCamera()->Pos();
-
2533  UpdateSky(seconds, ref);
-
2534  }
-
2535 
-
2536  if (terrain)
-
2537  terrain->ExecFrame(seconds);
-
2538 
-
2539  UpdateTracks(seconds);
-
2540  UpdateShips(seconds);
-
2541  UpdateShots(seconds);
-
2542  UpdateExplosions(seconds);
-
2543 
-
2544  if (!Game::Paused()) {
-
2545  DamageShips();
-
2546  DockShips();
-
2547 
-
2548  if (active) {
-
2549  CollideShips();
-
2550  CrashShips();
-
2551  }
-
2552 
-
2553  DestroyShips();
-
2554  }
-
2555 
-
2556  if (active && cam_dir && player_ship) {
-
2557  Sound::SetListener(*(cam_dir->GetCamera()), player_ship->Velocity());
-
2558  }
-
2559 }
-
2560 
-
2561 // +--------------------------------------------------------------------+
-
2562 
-
2563 void
- -
2565 {
-
2566  if (grid) {
-
2567  if (show)
-
2568  grid->Show();
-
2569  else
-
2570  grid->Hide();
-
2571  }
-
2572 }
-
2573 
-
2574 // +--------------------------------------------------------------------+
-
2575 
-
2576 void
-
2577 SimRegion::UpdateSky(double seconds, const Point& ref)
-
2578 {
-
2579  Dust* dust = sim->dust;
-
2580 
-
2581  if (dust) {
- -
2583  dust->Hide();
-
2584  }
-
2585  else {
-
2586  dust->Show();
-
2587 
-
2588  dust->ExecFrame(seconds, ref);
-
2589 
-
2590  if (player_ship && dust->Hidden()) {
-
2591  dust->Reset(player_ship->Location());
-
2592  dust->Show();
-
2593  }
-
2594  }
-
2595  }
-
2596 
- -
2598  while (++a) {
-
2599  a->ExecFrame(seconds);
-
2600  }
-
2601 }
-
2602 
-
2603 // +--------------------------------------------------------------------+
-
2604 
-
2605 void
-
2606 SimRegion::UpdateShips(double seconds)
-
2607 {
-
2608  int ship_index = 0;
-
2609  if (ai_index > ships.size())
-
2610  ai_index = 0;
-
2611 
-
2612  ListIter<Ship> ship_iter = ships;
-
2613  Ship* ship = 0;
-
2614 
-
2615  while (++ship_iter) {
-
2616  ship = ship_iter.value();
-
2617 
-
2618  if (ship_index == ai_index || ship == player_ship)
-
2619  ship->SetAIMode(2);
-
2620  else
-
2621  ship->SetAIMode(1);
-
2622 
-
2623  ship->ExecFrame(seconds);
-
2624  ship_index++;
-
2625  }
-
2626 
-
2627  ai_index++;
-
2628 }
-
2629 
-
2630 // +--------------------------------------------------------------------+
-
2631 
-
2632 void
-
2633 SimRegion::UpdateShots(double seconds)
-
2634 {
-
2635  ListIter<Shot> shot_iter = shots;
-
2636  while (++shot_iter) {
-
2637  Shot* shot = shot_iter.value();
-
2638  shot->ExecFrame(seconds);
-
2639 
-
2640  if (shot->Design()->flak) {
-
2641  SeekerAI* seeker = (SeekerAI*) shot->GetDirector();
-
2642 
-
2643  if (shot->Life() < 0.02 || seeker && seeker->Overshot()) {
-
2644  shot->SetFuse(0.001); // set lifetime to ~zero
-
2645  sim->CreateSplashDamage(shot);
-
2646  }
-
2647  }
-
2648 
-
2649  if (shot->Life() < 0.01) { // died of old age
- -
2651 
-
2652  if (shot->IsDrone())
-
2653  drones.remove((Drone*) shot);
-
2654 
-
2655  shot_iter.removeItem();
-
2656  delete shot;
-
2657  shot = 0;
-
2658  }
-
2659  }
-
2660 }
-
2661 
-
2662 // +--------------------------------------------------------------------+
-
2663 
-
2664 void
- -
2666 {
-
2667  ListIter<Explosion> exp_iter = explosions;
-
2668  while (++exp_iter) {
-
2669  Explosion* exp = exp_iter.value();
-
2670  exp->ExecFrame(seconds);
-
2671 
-
2672  if (exp->Life() < 0.01) { // died of old age
-
2673  exp_iter.removeItem();
-
2674  delete exp;
-
2675  }
-
2676  }
-
2677 
-
2678  ListIter<Debris> debris_iter = debris;
-
2679  while (++debris_iter) {
-
2680  Debris* d = debris_iter.value();
-
2681  d->ExecFrame(seconds);
-
2682 
-
2683  if (d->Life() < 0.01) { // died of old age
-
2684  debris_iter.removeItem();
-
2685  delete d;
-
2686  }
-
2687  }
-
2688 }
-
2689 
-
2690 // +--------------------------------------------------------------------+
-
2691 // Check for collisions between ships and shots, and apply damage.
-
2692 // Also look for damage to drones and debris.
-
2693 
-
2694 void
- -
2696 {
-
2697  if (ships.size() == 0 || shots.size() == 0)
-
2698  return;
-
2699 
-
2700  Point impact;
-
2701 
-
2702  // FOR EACH SHOT IN THE REGION:
-
2703  ListIter<Shot> shot_iter = shots;
-
2704  while (++shot_iter) {
-
2705  Shot* shot = shot_iter.value();
-
2706  const Ship* owner = shot->Owner();
-
2707  const char* owner_name;
-
2708 
-
2709  if (owner)
-
2710  owner_name = owner->Name();
-
2711  else
-
2712  owner_name = "[KIA]";
-
2713 
-
2714  // CHECK FOR COLLISION WITH A SHIP:
-
2715  ListIter<Ship> ship_iter = ships;
-
2716  while (shot && ++ship_iter) {
-
2717  Ship* ship = ship_iter.value();
-
2718  int hit = ship->HitBy(shot, impact);
-
2719 
-
2720  if (hit) {
-
2721  // recon imager:
-
2722  if (shot->Damage() < 0) {
-
2723  ShipStats* shooter = ShipStats::Find(owner_name);
-
2724  if (shooter) {
-
2725  shooter->AddEvent(SimEvent::SCAN_TARGET, ship->Name());
-
2726  }
-
2727  }
-
2728 
-
2729  // live round:
-
2730  else if (shot->Damage() > 0) {
-
2731  int ship_destroyed = (!ship->InTransition() && ship->Integrity() < 1.0f);
-
2732 
-
2733  // then delete the ship:
-
2734  if (ship_destroyed) {
- -
2736  Director* director;
-
2737 
-
2738  Print(" %s Killed %s (%s)\n", owner_name, ship->Name(), FormatGameTime());
-
2739 
-
2740  if (owner)
-
2741  director = owner->GetDirector();
-
2742 
-
2743  // alert the killer
-
2744  if (director && director->Type() > SteerAI::SEEKER && director->Type() < SteerAI::GROUND) {
-
2745  ShipAI* shipAI = (ShipAI*) director;
-
2746  shipAI->Splash(ship);
-
2747  }
-
2748 
-
2749  // record the kill
-
2750  ShipStats* killer = ShipStats::Find(owner_name);
-
2751  if (killer) {
-
2752  if (shot->IsMissile())
-
2753  killer->AddEvent(SimEvent::MISSILE_KILL, ship->Name());
-
2754  else
-
2755  killer->AddEvent(SimEvent::GUNS_KILL, ship->Name());
-
2756  }
-
2757 
-
2758  if (owner && owner->GetIFF() != ship->GetIFF()) {
-
2759  if (ship->GetIFF() > 0 || owner->GetIFF() > 1) {
-
2760  killer->AddPoints(ship->Value());
-
2761 
-
2762  Element* elem = owner->GetElement();
-
2763  if (elem) {
-
2764  if (owner->GetElementIndex() > 1) {
-
2765  Ship* s = elem->GetShip(1);
-
2766 
-
2767  if (s) {
-
2768  ShipStats* cmdr_stats = ShipStats::Find(s->Name());
-
2769  if (cmdr_stats) {
-
2770  cmdr_stats->AddCommandPoints(ship->Value()/2);
-
2771  }
-
2772  }
-
2773  }
-
2774 
-
2775  Element* cmdr = elem->GetCommander();
-
2776  if (cmdr) {
-
2777  Ship* s = cmdr->GetShip(1);
-
2778 
-
2779  if (s) {
-
2780  ShipStats* cmdr_stats = ShipStats::Find(s->Name());
-
2781  if (cmdr_stats) {
-
2782  cmdr_stats->AddCommandPoints(ship->Value()/2);
-
2783  }
-
2784  }
-
2785  }
-
2786  }
-
2787  }
-
2788  }
-
2789 
-
2790  ShipStats* killee = ShipStats::Find(ship->Name());
-
2791  if (killee)
-
2792  killee->AddEvent(SimEvent::DESTROYED, owner_name);
-
2793 
-
2794  ship->DeathSpiral();
-
2795  }
-
2796  }
-
2797 
-
2798  // finally, consume the shot:
-
2799  if (!shot->IsBeam()) {
-
2800  if (owner) {
-
2801  ShipStats* stats = ShipStats::Find(owner_name);
-
2802  if (shot->Design()->primary)
-
2803  stats->AddGunHit();
-
2804  else if (shot->Damage() > 0)
-
2805  stats->AddMissileHit();
-
2806  }
-
2807 
- -
2809 
-
2810  if (shot->IsDrone())
-
2811  drones.remove((Drone*) shot);
-
2812 
-
2813  shot_iter.removeItem();
-
2814  delete shot;
-
2815  shot = 0;
-
2816  }
-
2817  else if (!shot->HitTarget()) {
-
2818  shot->SetHitTarget(true);
-
2819 
-
2820  if (owner) {
-
2821  ShipStats* stats = ShipStats::Find(owner_name);
-
2822  if (shot->Design()->primary)
-
2823  stats->AddGunHit();
-
2824  }
-
2825  }
-
2826  }
-
2827  }
-
2828 
-
2829  // CHECK FOR COLLISION WITH A DRONE:
-
2830  if (shot && shot->Design()->target_type & Ship::DRONE) {
-
2831  ListIter<Drone> drone_iter = drones;
-
2832  while (shot && ++drone_iter) {
-
2833  Drone* d = drone_iter.value();
-
2834 
-
2835  if (d == shot || d->Owner() == owner)
-
2836  continue;
-
2837 
-
2838  int hit = d->HitBy(shot, impact);
-
2839  if (hit) {
-
2840  int destroyed = (d->Integrity() < 1.0f);
-
2841 
-
2842  // then mark the drone for deletion:
-
2843  if (destroyed) {
- -
2845  sim->CreateExplosion(d->Location(), d->Velocity(), 21, 1.0f, 1.0f, this);
-
2846  d->SetLife(0);
-
2847  }
-
2848 
-
2849  // finally, consume the shot:
-
2850  if (!shot->IsBeam()) {
-
2851  if (owner) {
-
2852  ShipStats* stats = ShipStats::Find(owner_name);
-
2853  if (shot->Design()->primary)
-
2854  stats->AddGunHit();
-
2855  else
-
2856  stats->AddMissileHit();
-
2857  }
-
2858 
- -
2860 
-
2861  if (shot->IsDrone())
-
2862  drones.remove((Drone*) shot);
-
2863 
-
2864  shot_iter.removeItem();
-
2865  delete shot;
-
2866  shot = 0;
-
2867  }
-
2868  }
-
2869  }
-
2870  }
-
2871 
-
2872  // CHECK FOR COLLISION WITH DEBRIS:
-
2873  ListIter<Debris> debris_iter = debris;
-
2874  while (shot && ++debris_iter) {
-
2875  Debris* d = debris_iter.value();
-
2876 
-
2877  if (d->Radius() < 50)
-
2878  continue;
-
2879 
-
2880  int hit = d->HitBy(shot, impact);
-
2881  if (hit) {
-
2882  int destroyed = (d->Integrity() < 1.0f);
-
2883 
-
2884  // then delete the debris:
-
2885  if (destroyed) {
-
2886  sim->CreateExplosion(d->Location(), d->Velocity(), Explosion::LARGE_EXPLOSION, 1.0f, 1.0f, this);
-
2887  debris_iter.removeItem();
-
2888  delete d;
-
2889  }
-
2890 
-
2891  // finally, consume the shot:
-
2892  if (!shot->IsBeam()) {
- -
2894  if (shot->IsDrone())
-
2895  drones.remove((Drone*) shot);
-
2896 
-
2897  shot_iter.removeItem();
-
2898  delete shot;
-
2899  shot = 0;
-
2900  }
-
2901  }
-
2902  }
-
2903 
-
2904  // CHECK FOR COLLISION WITH ASTEROIDS:
-
2905  ListIter<Asteroid> a_iter = asteroids;
-
2906  while (shot && ++a_iter) {
-
2907  Asteroid* a = a_iter.value();
-
2908 
-
2909  int hit = a->HitBy(shot, impact);
-
2910  if (hit) {
-
2911  if (!shot->IsBeam()) {
-
2912  if (shot->IsDrone())
-
2913  drones.remove((Drone*) shot);
-
2914 
-
2915  shot_iter.removeItem();
-
2916  delete shot;
-
2917  shot = 0;
-
2918  }
-
2919  }
-
2920  }
-
2921  }
-
2922 }
-
2923 
-
2924 // +--------------------------------------------------------------------+
-
2925 
-
2926 void
- -
2928 {
-
2929  if (ships.size() < 2 && debris.size() < 1)
-
2930  return;
-
2931 
-
2932  List<Ship> kill_list;
-
2933 
-
2934  int s_index = 0;
-
2935 
-
2936  ListIter<Ship> ship_iter = ships;
-
2937  while (++ship_iter) {
-
2938  Ship* ship = ship_iter.value();
-
2939 
-
2940  if (ship->InTransition() ||
-
2941  ship->GetFlightPhase() < Ship::ACTIVE ||
-
2942  ship->MissionClock() < 10000 ||
-
2943  ship->IsNetObserver())
-
2944  continue;
-
2945 
-
2946  int t_index = 0;
-
2947  ListIter<Ship> targ_iter = ships;
-
2948  while (++targ_iter) {
-
2949  Ship* targ = targ_iter.value();
-
2950 
-
2951  if (t_index++ <= s_index) continue;
-
2952 
-
2953  if (targ == ship) continue;
-
2954 
-
2955  if (targ->InTransition() ||
-
2956  targ->GetFlightPhase() < Ship::ACTIVE ||
-
2957  targ->MissionClock() < 10000 ||
-
2958  targ->IsNetObserver())
-
2959  continue;
-
2960 
-
2961  // ignore AI fighter collisions:
-
2962  if (ship->IsDropship() &&
-
2963  ship != player_ship &&
-
2964  targ->IsDropship() &&
-
2965  targ != player_ship)
-
2966  continue;
-
2967 
-
2968  // don't collide with own runway!
-
2969  if (ship->IsAirborne() && ship->GetCarrier() == targ)
-
2970  continue;
-
2971  if (targ->IsAirborne() && targ->GetCarrier() == ship)
-
2972  continue;
-
2973 
-
2974  // impact:
-
2975  if (ship->CollidesWith(*targ)) {
-
2976  Vec3 tv1 = targ->Velocity();
-
2977  Vec3 sv1 = ship->Velocity();
-
2978 
-
2979  Physical::SemiElasticCollision(*ship, *targ);
-
2980 
-
2981  Vec3 tv2 = targ->Velocity();
-
2982  Vec3 sv2 = ship->Velocity();
-
2983 
-
2984  double dvs = (sv2-sv1).length();
-
2985  double dvt = (tv2-tv1).length();
-
2986 
-
2987  if (dvs > 20) dvs *= dvs;
-
2988  if (dvt > 20) dvt *= dvt;
-
2989 
-
2990  if (!NetGame::IsNetGameClient()) {
-
2991  double old_integrity = ship->Integrity();
-
2992  ship->InflictDamage(dvs);
-
2993  double hull_damage = old_integrity - ship->Integrity();
-
2994  NetUtil::SendObjDamage(ship, hull_damage);
-
2995 
-
2996  old_integrity = targ->Integrity();
-
2997  targ->InflictDamage(dvt);
-
2998  hull_damage = old_integrity - targ->Integrity();
-
2999  NetUtil::SendObjDamage(targ, hull_damage);
-
3000  }
-
3001 
-
3002  // then delete the ship:
-
3003  if (targ->Integrity() < 1.0f) {
- -
3005  Print(" ship %s died in collision with %s (%s)\n", targ->Name(), ship->Name(), FormatGameTime());
-
3006  if (!kill_list.contains(targ)) {
-
3007  ShipStats* r = ShipStats::Find(targ->Name());
-
3008  if (r) r->AddEvent(SimEvent::COLLIDE, ship->Name());
-
3009 
-
3010  if (targ->GetIFF() > 0 && ship->GetIFF() != targ->GetIFF()) {
-
3011  r = ShipStats::Find(ship->Name());
-
3012  if (r) r->AddPoints(targ->Value());
-
3013  }
-
3014 
-
3015  kill_list.insert(targ);
-
3016  }
-
3017  }
-
3018 
-
3019  if (ship->Integrity() < 1.0f) {
- -
3021  Print(" ship %s died in collision with %s (%s)\n", ship->Name(), targ->Name(), FormatGameTime());
-
3022  if (!kill_list.contains(ship)) {
-
3023  ShipStats* r = ShipStats::Find(ship->Name());
-
3024  if (r) r->AddEvent(SimEvent::COLLIDE, targ->Name());
-
3025 
-
3026  if (ship->GetIFF() > 0 && ship->GetIFF() != targ->GetIFF()) {
-
3027  r = ShipStats::Find(targ->Name());
-
3028  if (r) r->AddPoints(ship->Value());
-
3029  }
-
3030 
-
3031  kill_list.insert(ship);
-
3032  }
-
3033  }
-
3034  }
-
3035  }
-
3036 
-
3037  ListIter<Debris> debris_iter = debris;
-
3038  while (++debris_iter) {
-
3039  Debris* d = debris_iter.value();
-
3040 
-
3041  if (d->Radius() < 50)
-
3042  continue;
-
3043 
-
3044  if (ship->CollidesWith(*d)) {
-
3045  Vec3 tv1 = d->Velocity();
-
3046  Vec3 sv1 = ship->Velocity();
-
3047 
-
3048  Physical::SemiElasticCollision(*ship, *d);
-
3049 
-
3050  Vec3 tv2 = d->Velocity();
-
3051  Vec3 sv2 = ship->Velocity();
-
3052 
-
3053  if (!NetGame::IsNetGameClient()) {
-
3054  ship->InflictDamage((sv2-sv1).length());
-
3055  }
-
3056 
-
3057  d->InflictDamage((tv2-tv1).length());
-
3058 
-
3059  // then delete the debris:
-
3060  if (d->Integrity() < 1.0f) {
-
3061  sim->CreateExplosion(d->Location(), d->Velocity(), Explosion::LARGE_EXPLOSION, 1.0f, 1.0f, this);
-
3062  debris_iter.removeItem();
-
3063  delete d;
-
3064  }
-
3065 
-
3066  if (ship->Integrity() < 1.0f) {
-
3067  if (!kill_list.contains(ship)) {
-
3068  ShipStats* r = ShipStats::Find(ship->Name());
-
3069  if (r) r->AddEvent(SimEvent::COLLIDE, Game::GetText("DEBRIS"));
-
3070 
-
3071  kill_list.insert(ship);
-
3072  }
-
3073  }
-
3074  }
-
3075  }
-
3076 
-
3077  ListIter<Asteroid> a_iter = asteroids;
-
3078  while (++a_iter) {
-
3079  Asteroid* a = a_iter.value();
-
3080 
-
3081  if (ship->CollidesWith(*a)) {
-
3082  Vec3 sv1 = ship->Velocity();
-
3083  Physical::SemiElasticCollision(*ship, *a);
-
3084  Vec3 sv2 = ship->Velocity();
-
3085 
-
3086  if (!NetGame::IsNetGameClient()) {
-
3087  ship->InflictDamage((sv2-sv1).length() * 10);
-
3088  }
-
3089 
-
3090  if (ship->Integrity() < 1.0f) {
-
3091  if (!kill_list.contains(ship)) {
-
3092  ShipStats* r = ShipStats::Find(ship->Name());
-
3093  if (r) r->AddEvent(SimEvent::COLLIDE, Game::GetText("ASTEROID"));
-
3094 
-
3095  kill_list.insert(ship);
-
3096  }
-
3097  }
-
3098  }
-
3099  }
-
3100 
-
3101  s_index++;
-
3102  }
-
3103 
-
3104  ListIter<Ship> killed(kill_list);
-
3105  while (++killed) {
-
3106  Ship* kill = killed.value();
-
3107  kill->DeathSpiral();
-
3108  }
-
3109 }
-
3110 
-
3111 // +--------------------------------------------------------------------+
-
3112 
-
3113 void
- -
3115 {
- -
3117  return;
-
3118 
-
3119  ListIter<Ship> ship_iter = ships;
-
3120  while (++ship_iter) {
-
3121  Ship* ship = ship_iter.value();
-
3122 
-
3123  if (!ship->IsGroundUnit() &&
-
3124  !ship->InTransition() &&
-
3125  ship->Class() != Ship::LCA &&
-
3126  ship->AltitudeAGL() < ship->Radius()/2) {
-
3127  if (ship->GetFlightPhase() == Ship::ACTIVE || ship->GetFlightPhase() == Ship::APPROACH) {
-
3128  ship->InflictDamage(1e6);
-
3129 
-
3130  if (ship->Integrity() < 1.0f) {
-
3131  Print(" ship destroyed by crash: %s (%s)\n", ship->Name(), FormatGameTime());
-
3132  ShipStats* r = ShipStats::Find(ship->Name());
-
3133  if (r) r->AddEvent(SimEvent::CRASH);
-
3134 
-
3135  ship->DeathSpiral();
-
3136  }
-
3137  }
-
3138  }
-
3139  }
-
3140 
-
3141  ListIter<Shot> shot_iter = shots;
-
3142  while (++shot_iter) {
-
3143  Shot* shot = shot_iter.value();
-
3144 
-
3145  if (shot->IsBeam() || shot->IsDecoy())
-
3146  continue;
-
3147 
-
3148  if (shot->AltitudeMSL() < 5e3 &&
-
3149  shot->AltitudeAGL() < 5) {
-
3150 
-
3151  // shot hit the ground, destroy it:
- -
3153 
-
3154  if (shot->IsDrone())
-
3155  drones.remove((Drone*) shot);
-
3156 
-
3157  shot_iter.removeItem();
-
3158  delete shot;
-
3159  }
-
3160  }
-
3161 }
-
3162 
-
3163 // +--------------------------------------------------------------------+
-
3164 
-
3165 void
- -
3167 {
-
3168  ListIter<Ship> ship_iter = ships;
-
3169  while (++ship_iter) {
-
3170  Ship* ship = ship_iter.value();
-
3171 
-
3172  if (ship->IsDead()) {
-
3173  // must use the iterator to remove the current
-
3174  // item from the container:
-
3175  ship_iter.removeItem();
-
3176  DestroyShip(ship);
-
3177  }
-
3178  }
-
3179 }
-
3180 
-
3181 // +--------------------------------------------------------------------+
-
3182 
-
3183 void
- -
3185 {
-
3186  if (!ship) return;
-
3187 
-
3188  Ship* spawn = 0;
-
3189 
-
3190  ships.remove(ship);
-
3191  carriers.remove(ship);
-
3192  selection.remove(ship);
-
3193 
-
3194  Text rgn_name;
-
3195  if (ship->GetRegion())
-
3196  rgn_name = ship->GetRegion()->Name();
-
3197 
-
3198  bool player_destroyed = (player_ship == ship);
-
3199 
-
3200  char ship_name[64];
-
3201  char ship_reg[64];
-
3202  strcpy_s(ship_name, ship->Name());
-
3203  strcpy_s(ship_reg, ship->Registry());
-
3204 
-
3205  ShipDesign* ship_design = (ShipDesign*) ship->Design();
-
3206  int ship_iff = ship->GetIFF();
-
3207  int cmd_ai = ship->GetCommandAILevel();
-
3208  bool respawn = sim->IsTestMode() && !ship->IsGroundUnit();
-
3209  bool observe = false;
-
3210 
-
3211  if (!respawn)
-
3212  respawn = ship->RespawnCount() > 0;
-
3213 
-
3214  if (sim->netgame) {
-
3215  if (!respawn)
-
3216  observe = player_destroyed;
-
3217  }
-
3218 
-
3219  if (respawn || observe) {
-
3220  if (!sim->netgame || !respawn)
-
3221  ship->SetRespawnLoc(RandomPoint() * 2);
-
3222 
-
3223  Point spawn_loc = ship->RespawnLoc();
-
3224 
-
3225  if (ship->IsAirborne() && spawn_loc.z < 5e3)
-
3226  spawn_loc.z = Random(8e3, 10e3);
-
3227 
-
3228  spawn = sim->CreateShip(ship_name, ship_reg, ship_design, rgn_name, spawn_loc, ship_iff, cmd_ai, observe ? 0 : ship->GetLoadout());
-
3229  spawn->SetRespawnCount(ship->RespawnCount() - 1);
-
3230  spawn->SetNetObserver(observe);
-
3231 
-
3232  if (sim->netgame && respawn)
-
3233  sim->netgame->Respawn(ship->GetObjID(), spawn);
-
3234 
-
3235  int n = strlen(ship_name);
-
3236  if (ship_name[n-2] == ' ' && isdigit(ship_name[n-1]))
-
3237  ship_name[n-2] = 0;
-
3238 
-
3239  Element* elem = sim->FindElement(ship_name);
-
3240  if (elem)
-
3241  elem->AddShip(spawn, ship->GetOrigElementIndex());
-
3242  else
-
3243  Print("Warning: No Element found for '%s' on respawn.\n", ship_name);
-
3244 
-
3245  if (player_destroyed)
-
3246  SetPlayerShip(spawn);
-
3247  }
-
3248  else {
-
3249  // close mission, return to menu:
-
3250  if (player_destroyed) {
- -
3252  if (stars)
- -
3254  }
-
3255  }
-
3256 
- -
3258 
-
3259  dead_ships.insert(ship);
-
3260  ship->Destroy();
-
3261 }
-
3262 
-
3263 // +--------------------------------------------------------------------+
-
3264 
-
3265 void
- -
3267 {
-
3268  if (!ship || !carrier || !deck) return;
-
3269 
-
3270  deck->Dock(ship);
-
3271 }
-
3272 
-
3273 // +--------------------------------------------------------------------+
-
3274 
-
3275 Ship*
-
3276 SimRegion::FindShip(const char* ship_name)
-
3277 {
-
3278  Ship* ship = 0;
-
3279 
-
3280  if (ship_name && *ship_name) {
-
3281  int name_len = strlen(ship_name);
-
3282 
-
3283  ListIter<Ship> ship_iter = ships;
-
3284  while (++ship_iter && !ship) {
-
3285  Ship* test = ship_iter.value();
-
3286  if (!strncmp(test->Name(), ship_name, name_len)) {
-
3287  int test_len = strlen(test->Name());
-
3288 
-
3289  // The only fuzzy match is for element indices.
-
3290  // The desired name "Alpha" matches "Alpha 1" and "Alpha 2"
-
3291  // but not "Alpha-Centauri"
-
3292 
-
3293  if (test_len > name_len && test->Name()[name_len] != ' ')
-
3294  continue;
-
3295 
-
3296  ship = test;
-
3297  }
-
3298  }
-
3299  }
-
3300 
-
3301  return ship;
-
3302 }
-
3303 
-
3304 Ship*
- -
3306 {
-
3307  Ship* ship = 0;
-
3308 
-
3309  ListIter<Ship> ship_iter = ships;
-
3310  while (++ship_iter && !ship) {
-
3311  Ship* test = ship_iter.value();
-
3312  if (test->GetObjID() == objid)
-
3313  ship = test;
-
3314  }
-
3315 
-
3316  return ship;
-
3317 }
-
3318 
-
3319 Shot*
- -
3321 {
-
3322  Shot* shot = 0;
-
3323 
-
3324  ListIter<Shot> shot_iter = shots;
-
3325  while (++shot_iter && !shot) {
-
3326  Shot* test = shot_iter.value();
-
3327  if (test->GetObjID() == objid)
-
3328  shot = test;
-
3329  }
-
3330 
-
3331  if (!shot) {
-
3332  ListIter<Drone> drone_iter = drones;
-
3333  while (++drone_iter && !shot) {
-
3334  Drone* test = drone_iter.value();
-
3335  if (test->GetObjID() == objid)
-
3336  shot = test;
-
3337  }
-
3338  }
-
3339 
-
3340  return shot;
-
3341 }
-
3342 
-
3343 // +--------------------------------------------------------------------+
-
3344 
-
3345 void
- -
3347 {
-
3348  if (ships.size() == 0)
-
3349  return;
-
3350 
-
3351  ListIter<Ship> ship_iter = ships;
-
3352  while (++ship_iter) {
-
3353  Ship* ship = ship_iter.value();
-
3354  int docked = (ship->GetFlightPhase() == Ship::DOCKED);
-
3355 
-
3356  if (docked) {
- -
3358 
-
3359  // who did this ship dock with?
-
3360  Ship* carrier = ship->GetCarrier();
-
3361 
-
3362  if (carrier) {
-
3363  ShipStats* s = ShipStats::Find(ship->Name());
-
3364  if (s) {
-
3365  if (ship->IsAirborne())
-
3366  s->AddEvent(SimEvent::LAND, carrier->Name());
-
3367  else
-
3368  s->AddEvent(SimEvent::DOCK, carrier->Name());
-
3369  }
-
3370 
-
3371  ShipStats* c = ShipStats::Find(carrier->Name());
-
3372  if (c) c->AddEvent(SimEvent::RECOVER_SHIP, ship->Name());
-
3373  }
-
3374 
-
3375  // then delete the ship:
-
3376  int player_docked = (player_ship == ship);
-
3377  char ship_name[33];
-
3378  strcpy_s(ship_name, ship->Name());
-
3379 
-
3380  selection.remove(ship);
-
3381  dead_ships.insert(ship_iter.removeItem());
-
3382  ship->Destroy();
-
3383 
-
3384  if (player_docked) {
-
3385  // close mission, return to menu:
- -
3387  if (stars)
- -
3389  }
-
3390 
-
3391  if (carrier)
-
3392  Print(" %s Docked with %s\n", ship_name, carrier->Name());
-
3393  }
-
3394  }
-
3395 }
-
3396 
-
3397 // +--------------------------------------------------------------------+
-
3398 
-
3399 void
- -
3401 {
-
3402  if (!ship) return;
-
3403 
-
3404  SimRegion* orig = ship->GetRegion();
-
3405 
-
3406  if (orig != this) {
-
3407  if (orig != 0) {
-
3408  if (orig->active)
-
3409  ship->Deactivate(sim->scene);
-
3410 
-
3411  orig->ships.remove(ship);
-
3412  orig->carriers.remove(ship);
-
3413  orig->selection.remove(ship);
-
3414  }
-
3415 
-
3416  ships.append(ship);
-
3417 
-
3418  if (ship->NumFlightDecks())
-
3419  carriers.append(ship);
-
3420 
-
3421  TranslateObject(ship);
-
3422  ship->SetRegion(this);
-
3423 
-
3424  if (active)
-
3425  ship->Activate(sim->scene);
-
3426  }
-
3427 }
-
3428 
-
3429 void
- -
3431 {
-
3432  if (!shot) return;
-
3433 
-
3434  SimRegion* orig = shot->GetRegion();
-
3435 
-
3436  if (orig != this) {
-
3437  if (orig != 0)
-
3438  orig->shots.remove(shot);
-
3439 
-
3440  shots.append(shot);
-
3441  if (shot->IsDrone())
-
3442  drones.append((Drone*) shot);
-
3443 
-
3444  TranslateObject(shot);
-
3445  shot->SetRegion(this);
-
3446 
-
3447  if (active)
-
3448  shot->Activate(sim->scene);
-
3449  }
-
3450 }
-
3451 
-
3452 void
- -
3454 {
-
3455  if (!exp) return;
-
3456 
-
3457  SimRegion* orig = exp->GetRegion();
-
3458 
-
3459  if (orig != this) {
-
3460  if (orig != 0)
-
3461  orig->explosions.remove(exp);
-
3462 
-
3463  explosions.append(exp);
-
3464  TranslateObject(exp);
-
3465  exp->SetRegion(this);
-
3466 
-
3467  if (active)
-
3468  exp->Activate(sim->scene);
-
3469  }
-
3470 }
-
3471 
-
3472 void
- -
3474 {
-
3475  if (!d) return;
-
3476 
-
3477  SimRegion* orig = d->GetRegion();
-
3478 
-
3479  if (orig != this) {
-
3480  if (orig != 0)
-
3481  orig->debris.remove(d);
-
3482 
-
3483  debris.append(d);
-
3484  TranslateObject(d);
-
3485  d->SetRegion(this);
-
3486 
-
3487  if (active)
-
3488  d->Activate(sim->scene);
-
3489  }
-
3490 }
-
3491 
-
3492 void
- -
3494 {
-
3495  if (!a) return;
-
3496 
-
3497  SimRegion* orig = a->GetRegion();
-
3498 
-
3499  if (orig != this) {
-
3500  if (orig != 0)
-
3501  orig->asteroids.remove(a);
-
3502 
-
3503  asteroids.append(a);
-
3504  TranslateObject(a);
-
3505  a->SetRegion(this);
-
3506 
-
3507  if (active)
-
3508  a->Activate(sim->scene);
-
3509  }
-
3510 }
-
3511 
-
3512 // +--------------------------------------------------------------------+
-
3513 
-
3514 void
- -
3516 {
-
3517  if (orbital_region)
- -
3519 
-
3520  if (object) {
-
3521  SimRegion* orig = object->GetRegion();
-
3522  if (orig) {
-
3523  Point delta = Location() - orig->Location();
-
3524  delta = delta.OtherHand();
-
3525  object->TranslateBy(delta);
-
3526  }
-
3527  }
-
3528 }
-
3529 
-
3530 // +--------------------------------------------------------------------+
-
3531 
- - -
3534 {
-
3535  if (iff >= 0 && iff < 5)
-
3536  return track_database[iff];
-
3537 
-
3538  static List<Contact> empty;
-
3539  return empty;
-
3540 }
-
3541 
-
3542 void
- -
3544 {
-
3545  for (int i = 0; i < 5; i++) {
-
3546  ListIter<Contact> track_iter = track_database[i];
-
3547 
-
3548  while (++track_iter) {
-
3549  Contact* t = track_iter.value();
-
3550  Ship* c_ship = t->GetShip();
-
3551  Shot* c_shot = t->GetShot();
-
3552  double c_life = 0;
-
3553 
-
3554  if (c_ship) {
-
3555  c_life = c_ship->Life();
-
3556 
-
3557  // look for quantum jumps and orbit transitions:
-
3558  if (c_ship->GetRegion() != this || c_ship->IsNetObserver())
-
3559  c_life = 0;
-
3560  }
-
3561 
-
3562  else if (c_shot)
-
3563  c_life = c_shot->Life();
-
3564 
-
3565  if (t->Age() < 0 || c_life == 0) {
-
3566  track_iter.removeItem();
-
3567  delete t;
-
3568  }
-
3569 
-
3570  else {
-
3571  t->Reset();
-
3572  }
-
3573  }
-
3574  }
-
3575 }
-
3576 
-
3577 // +--------------------------------------------------------------------+
-
3578 
-
3579 bool
- -
3581 {
-
3582  bool ok = false;
-
3583 
-
3584  if (player_ship) {
-
3585  ok = true;
-
3586 
-
3587  for (int i = 0; ok && i < ships.size(); i++) {
-
3588  Ship* s = ships[i];
-
3589 
-
3590  if (s != player_ship && s->GetIFF() && s->GetIFF() != player_ship->GetIFF()) {
-
3591  double dist = Point(s->Location() - player_ship->Location()).length();
-
3592 
-
3593  if (s->IsStarship())
-
3594  ok = dist > 60e3;
-
3595  else
-
3596  ok = dist > 30e3;
-
3597  }
-
3598  }
-
3599  }
-
3600 
-
3601  return ok;
-
3602 }
-
3603 
-
3604 // +--------------------------------------------------------------------+
-
3605 
-
3606 void
- -
3608 {
-
3609  for (int i = 0; i < ships.size(); i++) {
-
3610  Ship* ship = ships[i];
-
3611  Ship* ward = ship->GetWard();
-
3612 
-
3613  // remember to burn fuel and fix stuff...
-
3614  ship->ExecSystems(seconds);
-
3615  ship->ExecMaintFrame(seconds);
-
3616 
-
3617  ship->ClearTrack();
-
3618  ListIter<Contact> contact = ship->ContactList();
-
3619  while (++contact)
-
3620  contact->ClearTrack();
-
3621 
-
3622  if (ship->IsStatic())
-
3623  continue;
-
3624 
-
3625  // if ship is cleared inbound, land him:
-
3626  InboundSlot* inbound = ship->GetInbound();
-
3627  if (inbound) {
-
3628  if (inbound->Cleared()) {
-
3629  FlightDeck* deck = inbound->GetDeck();
-
3630 
-
3631  if (deck) {
-
3632  ship->SetCarrier((Ship*) deck->GetCarrier(), deck);
- -
3634  ship->Stow();
-
3635  deck->Clear(inbound->Index());
-
3636  }
-
3637  }
-
3638 
-
3639  // cleared or not, once you're inbound, don't seek navpoints:
-
3640  continue;
-
3641  }
-
3642 
-
3643  if (ship->GetHangar()) {
-
3644  ship->GetHangar()->ExecFrame(seconds);
-
3645 
-
3646  List<FlightDeck>& flight_decks = ship->FlightDecks();
-
3647  for (int n = 0; n < flight_decks.size(); n++)
-
3648  flight_decks[n]->ExecFrame(seconds);
-
3649  }
-
3650 
-
3651  Instruction* navpt = ship->GetNextNavPoint();
-
3652  Point dest = ship->Location();
-
3653  double speed = 500;
-
3654  double space = 2.0e3 * (ship->GetElementIndex() - 1);
-
3655 
-
3656  if (ship->IsStarship())
-
3657  space *= 5;
-
3658 
-
3659  if (navpt && navpt->Action() == Instruction::LAUNCH) {
-
3660  ship->SetNavptStatus(navpt, Instruction::COMPLETE);
-
3661  navpt = ship->GetNextNavPoint();
-
3662  }
-
3663 
-
3664  if (navpt) {
-
3665  dest = navpt->Location().OtherHand();
-
3666  speed = navpt->Speed();
-
3667  }
-
3668 
-
3669  else if (ward) {
-
3670  Point delta = ship->Location() - ward->Location();
-
3671  delta.y = 0;
-
3672 
-
3673  if (delta.length() > 25e3) {
-
3674  delta.Normalize();
-
3675  dest = ward->Location() + delta * 25e3;
-
3676  }
-
3677  }
-
3678 
-
3679  Point delta = dest - ship->Location();
-
3680  Point unit = delta;
-
3681  double dist = unit.Normalize() - space;
-
3682 
-
3683  if (dist > 1e3) {
-
3684  if (speed < 50)
-
3685  speed = 500;
-
3686 
-
3687  double etr = dist / speed;
-
3688 
-
3689  if (etr > seconds)
-
3690  etr = seconds;
-
3691 
-
3692  Point trans = unit * (speed * etr);
-
3693 
-
3694  if (ship->GetFuelLevel() > 1) {
-
3695  ship->MoveTo(ship->Location() + trans);
-
3696  ship->SetVelocity(unit * speed);
-
3697  }
-
3698  ship->LookAt(dest);
-
3699 
-
3700  if (ship->IsStarship()) {
- -
3702  ship->SetHelmHeading(ship->CompassHeading());
-
3703  ship->SetHelmPitch(ship->CompassPitch());
-
3704  }
-
3705  }
-
3706 
-
3707  else if (navpt && navpt->Status() <= Instruction::ACTIVE) {
-
3708  ship->SetNavptStatus(navpt, Instruction::COMPLETE);
-
3709  }
-
3710 
-
3711  if (ward) {
-
3712  Point ward_heading = ward->Heading();
-
3713  ward_heading.y = 0;
-
3714  ward_heading.Normalize();
-
3715 
-
3716  if (ship->GetFuelLevel() > 1) {
-
3717  ship->SetVelocity(ward->Velocity());
-
3718  }
-
3719  ship->LookAt(ship->Location() + ward_heading * 1e6);
-
3720 
-
3721  if (ship->IsStarship()) {
- -
3723  ship->SetHelmHeading(ship->CompassHeading());
-
3724  ship->SetHelmPitch(ship->CompassPitch());
-
3725  }
-
3726  }
-
3727 
-
3728  if (dist > 1 || ward) {
-
3729  for (int j = 0; j < ships.size(); j++) {
-
3730  Ship* test = ships[j];
-
3731 
-
3732  if (ship != test && test->Mass() >= ship->Mass()) {
-
3733  Point delta = ship->Location() - test->Location();
-
3734 
-
3735  if (delta.length() < ship->Radius() * 2 + test->Radius() * 2) {
-
3736  ship->MoveTo(test->Location() + RandomPoint().OtherHand());
-
3737  }
-
3738  }
-
3739  }
-
3740  }
-
3741  }
-
3742 
-
3743  DockShips();
-
3744 }
-
3745 
-
3746 // +--------------------------------------------------------------------+
-
3747 
-
3748 void
- -
3750 {
-
3751  for (int i = 0; i < dead_ships.size(); i++) {
-
3752  Ship* s = dead_ships[i];
-
3753 
-
3754  if (s->GetCombatUnit() && s->GetFlightPhase() != Ship::DOCKED)
-
3755  s->GetCombatUnit()->Kill(1);
-
3756  }
-
3757 
-
3758  for (int i = 0; i < ships.size(); i++) {
-
3759  Ship* s = ships[i];
-
3760  CombatUnit* u = s->GetCombatUnit();
-
3761 
-
3762  if (u) {
-
3763  Point u_loc = s->Location().OtherHand();
-
3764  if (u_loc.z > 20e3)
-
3765  u_loc.z = 20e3;
-
3766  else if (u_loc.z < -20e3)
-
3767  u_loc.z = -20e3;
-
3768 
-
3769  if (u->IsStarship()) {
-
3770  u->SetRegion(s->GetRegion()->Name());
-
3771  u->MoveTo(u_loc);
-
3772  }
-
3773 
-
3774  if (!u->IsDropship()) {
-
3775  if (s->Integrity() < 1)
-
3776  u->Kill(1);
-
3777  else
-
3778  u->SetSustainedDamage(s->Design()->integrity - s->Integrity());
-
3779  }
-
3780 
-
3781  CombatGroup* g = u->GetCombatGroup();
-
3782  if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) {
-
3783  if (!g->IsZoneLocked())
-
3784  g->SetRegion(s->GetRegion()->Name());
-
3785  else
-
3786  u->SetRegion(g->GetRegion());
-
3787 
-
3788  g->MoveTo(u_loc);
-
3789  }
-
3790  }
-
3791  }
-
3792 }
-
3793 
-
3794 // +--------------------------------------------------------------------+
-
3795 
-
3796 const char* FormatGameTime()
-
3797 {
-
3798  static char txt[64];
-
3799 
-
3800  int t = Game::GameTime();
-
3801 
-
3802  int h = ( t / 3600000);
-
3803  int m = ((t - h*3600000) / 60000);
-
3804  int s = ((t - h*3600000 - m*60000) / 1000);
-
3805  int e = ( t - h*3600000 - m*60000 - s*1000);
-
3806 
-
3807  if (h > 0)
-
3808  sprintf_s(txt, "%02d:%02d:%02d.%03d", h,m,s,e);
-
3809  else
-
3810  sprintf_s(txt, "%02d:%02d.%03d", m,s,e);
-
3811 
-
3812  return txt;
-
3813 }
-
-
- - - - -- cgit v1.1