From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- .../_campaign_mission_fighter_8cpp_source.html | 2272 ++++++++++++++++++++ 1 file changed, 2272 insertions(+) create mode 100644 Doc/doxygen/html/_campaign_mission_fighter_8cpp_source.html (limited to 'Doc/doxygen/html/_campaign_mission_fighter_8cpp_source.html') diff --git a/Doc/doxygen/html/_campaign_mission_fighter_8cpp_source.html b/Doc/doxygen/html/_campaign_mission_fighter_8cpp_source.html new file mode 100644 index 0000000..93d9396 --- /dev/null +++ b/Doc/doxygen/html/_campaign_mission_fighter_8cpp_source.html @@ -0,0 +1,2272 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/CampaignMissionFighter.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
CampaignMissionFighter.cpp
+
+
+Go to the documentation of this file.
1 /* Project Starshatter 4.5
+
2  Destroyer Studios LLC
+
3  Copyright (C) 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: Stars.exe
+
6  FILE: CampaignMissionFighter.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  CampaignMissionFighter generates missions and mission
+
13  info for the player's FIGHTER SQUADRON as part of a
+
14  dynamic campaign.
+
15 */
+
16 
+
17 #include "MemDebug.h"
+
18 #include "CampaignMissionFighter.h"
+
19 #include "CampaignMissionRequest.h"
+
20 #include "Campaign.h"
+
21 #include "Combatant.h"
+
22 #include "CombatAssignment.h"
+
23 #include "CombatGroup.h"
+
24 #include "CombatUnit.h"
+
25 #include "CombatZone.h"
+
26 #include "Callsign.h"
+
27 #include "Galaxy.h"
+
28 #include "Mission.h"
+
29 #include "MissionTemplate.h"
+
30 #include "Instruction.h"
+
31 #include "Ship.h"
+
32 #include "ShipDesign.h"
+
33 #include "Starshatter.h"
+
34 #include "StarSystem.h"
+
35 #include "Player.h"
+
36 
+
37 #include "Random.h"
+
38 
+
39 static int pkg_id = 1000;
+
40 extern int dump_missions;
+
41 
+
42 // +--------------------------------------------------------------------+
+
43 
+ +
45 : campaign(c), squadron(0), mission(0), player_elem(0),
+
46 strike_group(0), strike_target(0), prime_target(0),
+
47 carrier_elem(0), ward(0), escort(0), airborne(false), airbase(false),
+
48 ownside(0), enemy(-1), mission_type(0), mission_info(0)
+
49 {
+
50  if (!campaign || !campaign->GetPlayerGroup()) {
+
51  ::Print("ERROR - CMF campaign=0x%08x player_group=0x%08x\n",
+ +
53  return;
+
54  }
+
55 
+
56  CombatGroup* player_group = campaign->GetPlayerGroup();
+
57 
+
58  switch (player_group->Type()) {
+
59  case CombatGroup::WING: {
+
60  CombatGroup* wing = player_group;
+
61  ListIter<CombatGroup> iter = wing->GetComponents();
+
62 
+
63  while (++iter) {
+
64  if (iter->Type() == CombatGroup::FIGHTER_SQUADRON) {
+
65  squadron = iter.value();
+
66  }
+
67  }
+
68  }
+
69  break;
+
70 
+ + + +
74  squadron = player_group;
+
75  break;
+
76 
+
77  default:
+
78  ::Print("ERROR - CMF invalid player group: %s IFF %d\n",
+
79  player_group->GetDescription(),
+
80  player_group->GetIFF());
+
81  break;
+
82  }
+
83 
+
84  if (squadron) {
+
85  CombatGroup* carrier = squadron->FindCarrier();
+
86 
+
87  if (carrier && carrier->Type() == CombatGroup::STARBASE) {
+
88  airbase = true;
+
89  }
+
90  }
+
91 }
+
92 
+ +
94 
+
95 // +--------------------------------------------------------------------+
+
96 
+
97 void
+ +
99 {
+
100  if (!campaign || !squadron || !req)
+
101  return;
+
102 
+
103  ::Print("\n-----------------------------------------------\n");
+
104  if (req->Script().length())
+
105  ::Print("CMF CreateMission() request: %s '%s'\n",
+
106  Mission::RoleName(req->Type()),
+
107  (const char*) req->Script());
+
108 
+
109  else
+
110  ::Print("CMF CreateMission() request: %s %s\n",
+
111  Mission::RoleName(req->Type()),
+
112  req->GetObjective() ? req->GetObjective()->Name().data() : "(no target)");
+
113 
+
114  request = req;
+
115  mission_info = 0;
+
116 
+
117  if (request->GetPrimaryGroup()) {
+
118  switch (request->GetPrimaryGroup()->Type()) {
+ + + +
122  squadron = request->GetPrimaryGroup();
+
123  break;
+
124  }
+
125  }
+
126 
+
127  ownside = squadron->GetIFF();
+
128 
+
129  for (int i = 0; i < campaign->GetCombatants().size(); i++) {
+
130  int iff = campaign->GetCombatants().at(i)->GetIFF();
+
131  if (iff > 0 && iff != ownside) {
+
132  enemy = iff;
+
133  break;
+
134  }
+
135  }
+
136 
+
137  static int id_key = 1;
+
138  GenerateMission(id_key++);
+ +
140 
+
141  MissionInfo* info = DescribeMission();
+
142 
+
143  if (info) {
+
144  campaign->GetMissionList().append(info);
+
145 
+
146  ::Print("CMF Created %03d '%s' %s\n\n",
+
147  info->id,
+
148  (const char*) info->name,
+ +
150 
+
151  if (dump_missions) {
+
152  Text script = mission->Serialize();
+
153  char fname[32];
+
154 
+
155  sprintf_s(fname, "msn%03d.def", info->id);
+
156  FILE* f;
+
157  fopen_s(&f, fname, "w");
+
158  if (f) {
+
159  fprintf(f, "%s\n", script.data());
+
160  fclose(f);
+
161  }
+
162  }
+
163  }
+
164  else {
+
165  ::Print("CMF failed to create mission.\n");
+
166  }
+
167 }
+
168 
+
169 // +--------------------------------------------------------------------+
+
170 
+
171 Mission*
+ +
173 {
+
174  bool found = false;
+
175 
+
176  SelectType();
+
177 
+
178  if (request && request->Script().length()) {
+
179  MissionTemplate* mt = new(__FILE__,__LINE__) MissionTemplate(id, request->Script(), campaign->Path());
+
180  if (mt)
+ +
182  mission = mt;
+
183  found = true;
+
184  }
+
185 
+
186  else {
+ +
188  found = mission_info != 0;
+
189 
+
190  if (found) {
+
191  MissionTemplate* mt = new(__FILE__,__LINE__) MissionTemplate(id, mission_info->script, campaign->Path());
+
192  if (mt)
+ +
194  mission = mt;
+
195  }
+
196  else {
+
197  mission = new(__FILE__,__LINE__) Mission(id);
+
198  if (mission)
+ +
200  }
+
201  }
+
202 
+
203  if (!mission) {
+
204  Exit();
+
205  return 0;
+
206  }
+
207 
+
208  char name[64];
+
209  sprintf_s(name, "Fighter Mission %d", id);
+
210 
+
211  mission->SetName(name);
+ + +
214 
+
215  SelectRegion();
+ +
217  CreatePatrols();
+
218 
+
219  if (!found) {
+ +
221  mission->SetOK(true);
+
222  mission->Validate();
+
223  }
+
224 
+
225  else {
+
226  mission->Load();
+
227 
+
228  if (mission->IsOK()) {
+ + +
231  ward = mission->GetWard();
+
232 
+ +
234 
+
235  if (player_elem && p)
+ +
237  }
+
238 
+
239  // if there was a problem, scrap the mission
+
240  // and start over:
+
241  else {
+
242  delete mission;
+
243 
+
244  mission = new(__FILE__,__LINE__) Mission(id);
+ +
246  mission->SetName(name);
+ + +
249 
+
250  SelectRegion();
+ + +
253 
+
254  mission->SetOK(true);
+
255  mission->Validate();
+
256  }
+
257  }
+
258 
+
259  return mission;
+
260 }
+
261 
+
262 // +--------------------------------------------------------------------+
+
263 
+
264 bool
+ +
266 {
+
267  bool ground = false;
+
268 
+
269  if (obj) {
+
270  CombatGroup* pgroup = campaign->GetPlayerGroup();
+
271 
+
272  if (pgroup) {
+
273  CombatZone* zone = pgroup->GetAssignedZone();
+
274 
+
275  if (zone) {
+
276  StarSystem* system = campaign->GetSystem(zone->System());
+
277 
+
278  if (system) {
+
279  OrbitalRegion* region = system->FindRegion(obj->GetRegion());
+
280 
+
281  if (region && region->Type() == Orbital::TERRAIN) {
+
282  ground = true;
+
283  }
+
284  }
+
285  }
+
286  }
+
287  }
+
288 
+
289  return ground;
+
290 }
+
291 
+
292 // +--------------------------------------------------------------------+
+
293 
+
294 void
+ +
296 {
+
297  int type = Mission::PATROL;
+
298 
+
299  if (request) {
+
300  type = request->Type();
+
301  if (type == Mission::STRIKE) {
+ +
303 
+
304  // verify that objective is a ground target:
+ +
306  type = Mission::ASSAULT;
+
307  }
+
308  }
+
309 
+
310  else if (type == Mission::ESCORT_STRIKE) {
+ +
312  if (!strike_group || strike_group->CalcValue() < 1) {
+
313  type = Mission::SWEEP;
+
314  strike_group = 0;
+
315  }
+
316  }
+
317  }
+
318 
+
319  mission_type = type;
+
320 }
+
321 
+
322 void
+ +
324 {
+ +
326 
+
327  if (!zone)
+
328  zone = squadron->GetCurrentZone();
+
329 
+
330  if (zone) {
+ +
332  mission->SetRegion(*zone->GetRegions().at(0));
+
333 
+ +
335 
+
336  if (zone->GetRegions().size() > 1) {
+
337  air_region = *zone->GetRegions().at(1);
+
338 
+
339  StarSystem* system = mission->GetStarSystem();
+
340  OrbitalRegion* rgn = 0;
+
341 
+
342  if (system)
+
343  rgn = system->FindRegion(air_region);
+
344 
+
345  if (!rgn || rgn->Type() != Orbital::TERRAIN)
+
346  air_region = "";
+
347  }
+
348 
+
349  if (air_region.length() > 0) {
+ +
351  airborne = true;
+
352  }
+
353 
+
354  else if (mission->Type() >= Mission::AIR_PATROL &&
+ +
356  airborne = true;
+
357  }
+
358 
+
359  else if (mission->Type() == Mission::STRIKE ||
+ +
361  if (strike_group) {
+ +
363 
+ +
365  airborne = true;
+
366  }
+
367  }
+
368 
+
369  if (airbase) {
+ +
371  }
+
372  }
+
373  }
+
374 
+
375  else {
+
376  ::Print("WARNING: CMF - No zone for '%s'\n", squadron->Name().data());
+
377 
+
378  StarSystem* s = campaign->GetSystemList()[0];
+
379 
+ +
381  mission->SetRegion(s->Regions()[0]->Name());
+
382  }
+
383 
+
384  if (!airborne) {
+
385  switch (mission->Type()) {
+ + + +
389  default: break;
+
390  }
+
391  }
+
392 }
+
393 
+
394 // +--------------------------------------------------------------------+
+
395 
+
396 void
+ +
398 {
+ +
400  while (++z_iter) {
+
401  CombatZone* z = z_iter.value();
+
402 
+
403  ListIter<ZoneForce> iter = z->GetForces();
+
404  while (++iter) {
+
405  ZoneForce* force = iter.value();
+
406  ListIter<CombatGroup> group = force->GetGroups();
+
407 
+
408  while (++group) {
+
409  CombatGroup* g = group.value();
+
410 
+
411  switch (g->Type()) {
+ + + + +
416  CreateSquadron(g);
+
417  break;
+
418 
+ + + +
422  CreateElements(g);
+
423  break;
+
424 
+ + + + + + + + +
433  case CombatGroup::SUPPLY:
+
434  case CombatGroup::REPAIR:
+
435  CreateElements(g);
+
436  break;
+
437 
+ + + + + + + + + + + +
449  CreateElements(g);
+
450  break;
+
451  }
+
452  }
+
453  }
+
454  }
+
455 }
+
456 
+
457 // +--------------------------------------------------------------------+
+
458 
+
459 void
+ +
461 {
+
462  CreateWards();
+ +
464  CreateTargets();
+
465  CreateEscorts();
+
466 
+
467  if (player_elem) {
+
468  Instruction* obj = new(__FILE__,__LINE__) Instruction(mission->GetRegion(),
+
469  Point(0,0,0),
+ +
471 
+
472  if (obj)
+ +
474  }
+
475 }
+
476 
+
477 // +--------------------------------------------------------------------+
+
478 
+
479 void
+ +
481 {
+
482  MissionElement* elem = 0;
+
483  List<CombatUnit>& units = g->GetUnits();
+
484 
+
485  CombatUnit* cmdr = 0;
+
486 
+
487  for (int i = 0; i < units.size(); i++) {
+
488  elem = CreateSingleElement(g, units[i]);
+
489 
+
490  if (elem) {
+
491  if (!cmdr) {
+
492  cmdr = units[i];
+
493  }
+
494  else {
+
495  elem->SetCommander(cmdr->Name());
+
496 
+
497  if (g->Type() == CombatGroup::CARRIER_GROUP &&
+
498  elem->MissionRole() == Mission::ESCORT) {
+
499  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ESCORT, cmdr->Name());
+
500  if (obj)
+
501  elem->AddObjective(obj);
+
502  }
+
503  }
+
504 
+
505  mission->AddElement(elem);
+
506  }
+
507  }
+
508 }
+
509 
+ + +
512 {
+
513  if (!g || g->IsReserve()) return 0;
+
514  if (!u || u->LiveCount() < 1) return 0;
+
515 
+
516  // make sure this unit is actually in the right star system:
+
517  Galaxy* galaxy = Galaxy::GetInstance();
+
518  if (galaxy) {
+
519  if (galaxy->FindSystemByRegion(u->GetRegion()) !=
+
520  galaxy->FindSystemByRegion(squadron->GetRegion())) {
+
521  return 0;
+
522  }
+
523  }
+
524 
+
525  // make sure this unit isn't already in the mission:
+ +
527  while (++e_iter) {
+
528  MissionElement* elem = e_iter.value();
+
529 
+
530  if (elem->GetCombatUnit() == u)
+
531  return 0;
+
532  }
+
533 
+
534  MissionElement* elem = new(__FILE__,__LINE__) MissionElement;
+
535  if (!elem) {
+
536  Exit();
+
537  return 0;
+
538  }
+
539 
+
540  if (u->Name().length())
+
541  elem->SetName(u->Name());
+
542  else
+
543  elem->SetName(u->DesignName());
+
544 
+
545  elem->SetElementID(pkg_id++);
+
546 
+
547  elem->SetDesign(u->GetDesign());
+
548  elem->SetCount(u->LiveCount());
+
549  elem->SetIFF(u->GetIFF());
+
550  elem->SetIntelLevel(g->IntelLevel());
+
551  elem->SetRegion(u->GetRegion());
+
552  elem->SetHeading(u->GetHeading());
+
553 
+
554  int unit_index = g->GetUnits().index(u);
+
555  Point base_loc = u->Location();
+
556  bool exact = u->IsStatic(); // exact unit-level placement
+
557 
+
558  if (base_loc.length() < 1) {
+
559  base_loc = g->Location();
+
560  exact = false;
+
561  }
+
562 
+
563  if (unit_index < 0 || unit_index > 0 && !exact) {
+
564  Point loc = RandomDirection();
+
565 
+
566  if (!u->IsStatic()) {
+
567  while (fabs(loc.y) > fabs(loc.x))
+
568  loc = RandomDirection();
+
569 
+
570  loc *= 10e3 + 9e3 * unit_index;
+
571  }
+
572  else {
+
573  loc *= 2e3 + 2e3 * unit_index;
+
574  }
+
575 
+
576  elem->SetLocation(base_loc + loc);
+
577  }
+
578  else {
+
579  elem->SetLocation(base_loc);
+
580  }
+
581 
+
582  if (g->Type() == CombatGroup::CARRIER_GROUP) {
+
583  if (u->Type() == Ship::CARRIER) {
+ +
585 
+
586  if (squadron && elem->GetCombatGroup() == squadron->FindCarrier())
+
587  carrier_elem = elem;
+
588 
+
589  else if (!carrier_elem && u->GetIFF() == squadron->GetIFF())
+
590  carrier_elem = elem;
+
591  }
+
592  else {
+ +
594  }
+
595  }
+
596  else if (u->Type() == Ship::STATION ||
+
597  u->Type() == Ship::STARBASE) {
+ +
599 
+
600  if (squadron && elem->GetCombatGroup() == squadron->FindCarrier()) {
+
601  carrier_elem = elem;
+
602 
+
603  if (u->Type() == Ship::STARBASE)
+
604  airbase = true;
+
605  }
+
606  }
+
607  else if (u->Type() == Ship::FARCASTER) {
+ +
609 
+
610  // link farcaster to other terminus:
+
611  Text name = u->Name();
+
612  int dash = -1;
+
613 
+
614  for (int i = 0; i < (int) name.length(); i++)
+
615  if (name[i] == '-')
+
616  dash = i;
+
617 
+
618  Text src = name.substring(0, dash);
+
619  Text dst = name.substring(dash+1, name.length() - (dash+1));
+
620 
+
621  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::VECTOR, dst + "-" + src);
+
622  elem->AddObjective(obj);
+
623  }
+
624  else if ((u->Type() & Ship::STARSHIPS) != 0) {
+ +
626  }
+
627 
+
628  elem->SetCombatGroup(g);
+
629  elem->SetCombatUnit(u);
+
630 
+
631  return elem;
+
632 }
+
633 
+
634 CombatUnit*
+ +
636 {
+
637  CombatGroup* carrier = g->FindCarrier();
+
638 
+
639  if (carrier && carrier->GetUnits().size()) {
+ +
641 
+
642  if (carrier_elem)
+
643  return carrier->GetUnits().at(0);
+
644  }
+
645 
+
646  return 0;
+
647 }
+
648 
+
649 void
+ +
651 {
+
652  if (!g || g->IsReserve()) return;
+
653 
+
654  CombatUnit* fighter = g->GetUnits().at(0);
+
655  CombatUnit* carrier = FindCarrier(g);
+
656 
+
657  if (!fighter || !carrier) return;
+
658 
+
659  int live_count = fighter->LiveCount();
+
660  int maint_count = (live_count > 4) ? live_count / 2 : 0;
+
661 
+
662  MissionElement* elem = new(__FILE__,__LINE__) MissionElement;
+
663 
+
664  if (!elem) {
+
665  Exit();
+
666  return;
+
667  }
+
668 
+
669  elem->SetName(g->Name());
+
670  elem->SetElementID(pkg_id++);
+
671 
+
672  elem->SetDesign(fighter->GetDesign());
+
673  elem->SetCount(fighter->Count());
+
674  elem->SetDeadCount(fighter->DeadCount());
+
675  elem->SetMaintCount(maint_count);
+
676  elem->SetIFF(fighter->GetIFF());
+
677  elem->SetIntelLevel(g->IntelLevel());
+
678  elem->SetRegion(fighter->GetRegion());
+
679 
+
680  elem->SetCarrier(carrier->Name());
+
681  elem->SetCommander(carrier->Name());
+
682  elem->SetLocation(carrier->Location() + RandomPoint());
+
683 
+
684  elem->SetCombatGroup(g);
+
685  elem->SetCombatUnit(fighter);
+
686 
+
687  mission->AddElement(elem);
+
688 }
+
689 
+
690 void
+ +
692 {
+
693  int pkg_size = 2;
+
694 
+ +
696  if (request && request->GetObjective()) {
+
697  int tgt_type = request->GetObjective()->Type();
+
698 
+
699  if (tgt_type >= CombatGroup::FLEET && tgt_type <= CombatGroup::CARRIER_GROUP)
+
700  pkg_size = 4;
+
701 
+
702  if (tgt_type == CombatGroup::STATION || tgt_type == CombatGroup::STARBASE)
+
703  pkg_size = 4;
+
704  }
+
705  }
+
706 
+
707  MissionElement* elem = CreateFighterPackage(g, pkg_size, mission->Type());
+
708 
+
709  if (elem) {
+ +
711  elem->SetAlert(p ? !p->FlyingStart() : true);
+
712  elem->SetPlayer(1);
+
713 
+
714  if (ward) {
+
715  Point approach = elem->Location() - ward->Location();
+
716  approach.Normalize();
+
717 
+
718  Point pickup = ward->Location() + approach * 50e3;
+
719  double delta = (pickup - elem->Location()).length();
+
720 
+
721  if (delta > 30e3) {
+
722  Instruction* n = new(__FILE__,__LINE__) Instruction(elem->Region(), pickup, Instruction::ESCORT);
+
723  n->SetTarget(ward->Name());
+
724  n->SetSpeed(750);
+
725  elem->AddNavPoint(n);
+
726  }
+
727 
+
728  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ESCORT, ward->Name());
+
729 
+
730  switch (mission->Type()) {
+ +
732  obj->SetTargetDesc(Text("the star freighter ") + ward->Name());
+
733  break;
+
734 
+ +
736  obj->SetTargetDesc(Text("the shuttle ") + ward->Name());
+
737  break;
+
738 
+ +
740  obj->SetTargetDesc(Text("the ") + ward->Name() + Text(" strike package"));
+
741  break;
+
742 
+
743  case Mission::DEFEND:
+
744  obj->SetTargetDesc(Text("the ") + ward->Name());
+
745  break;
+
746 
+
747  default:
+
748  if (ward->GetCombatGroup()) {
+
749  obj->SetTargetDesc(Text("the ") + ward->GetCombatGroup()->GetDescription());
+
750  }
+
751  else {
+
752  obj->SetTargetDesc(Text("the ") + ward->Name());
+
753  }
+
754  break;
+
755  }
+
756 
+
757  elem->AddObjective(obj);
+
758  }
+
759 
+
760  mission->AddElement(elem);
+
761 
+
762  player_elem = elem;
+
763  }
+
764 }
+
765 
+
766 // +--------------------------------------------------------------------+
+
767 
+
768 void
+ +
770 {
+
771  List<MissionElement> patrols;
+
772 
+ +
774  while (++iter) {
+
775  MissionElement* squad_elem = iter.value();
+
776  CombatGroup* squadron = squad_elem->GetCombatGroup();
+
777  CombatUnit* unit = squad_elem->GetCombatUnit();
+
778 
+
779  if (!squad_elem->IsSquadron() || !squadron || !unit || unit->LiveCount() < 4)
+
780  continue;
+
781 
+
782  if (squadron->Type() == CombatGroup::INTERCEPT_SQUADRON ||
+
783  squadron->Type() == CombatGroup::FIGHTER_SQUADRON) {
+
784 
+
785  StarSystem* system = mission->GetStarSystem();
+
786  CombatGroup* base = squadron->FindCarrier();
+
787 
+
788  if (!base)
+
789  continue;
+
790 
+
791  OrbitalRegion* region = system->FindRegion(base->GetRegion());
+
792 
+
793  if (!region)
+
794  continue;
+
795 
+
796  int patrol_type = Mission::PATROL;
+
797  Point base_loc;
+
798 
+
799  if (region->Type() == Orbital::TERRAIN) {
+
800  patrol_type = Mission::AIR_PATROL;
+
801 
+
802  if (RandomChance(2,3))
+
803  continue;
+
804  }
+
805 
+
806  base_loc = base->Location() + RandomPoint() * 1.5;
+
807 
+
808  if (region->Type() == Orbital::TERRAIN)
+
809  base_loc += Point(0, 0, 14.0e3);
+
810 
+
811  MissionElement* elem = CreateFighterPackage(squadron, 2, patrol_type);
+
812  if (elem) {
+ +
814  elem->SetRegion(base->GetRegion());
+
815  elem->SetLocation(base_loc);
+
816  patrols.append(elem);
+
817  }
+
818  }
+
819  }
+
820 
+
821  iter.attach(patrols);
+
822  while (++iter)
+
823  mission->AddElement(iter.value());
+
824 }
+
825 
+
826 // +--------------------------------------------------------------------+
+
827 
+
828 void
+ +
830 {
+
831  switch (mission->Type()) {
+ + + +
835  default: break;
+
836  }
+
837 }
+
838 
+
839 void
+ +
841 {
+
842  if (!mission || !mission->GetStarSystem()) return;
+
843 
+
844  CombatUnit* carrier = FindCarrier(squadron);
+
845  CombatGroup* freight = 0;
+
846 
+
847  if (request)
+
848  freight = request->GetObjective();
+
849 
+
850  if (!freight)
+ +
852 
+
853  if (!freight || freight->CalcValue() < 1) return;
+
854 
+
855  CombatUnit* unit = freight->GetNextUnit();
+
856  if (!unit) return;
+
857 
+
858  MissionElement* elem = CreateSingleElement(freight, unit);
+
859  if (!elem) return;
+
860 
+ + +
863  elem->SetRegion(squadron->GetRegion());
+
864 
+
865  if (carrier)
+
866  elem->SetLocation(carrier->Location() + RandomPoint() * 2);
+
867 
+
868  ward = elem;
+
869  mission->AddElement(elem);
+
870 
+
871 
+
872  StarSystem* system = mission->GetStarSystem();
+
873  OrbitalRegion* rgn1 = system->FindRegion(elem->Region());
+
874  Point delta = rgn1->Location() - rgn1->Primary()->Location();
+
875  Point npt_loc = elem->Location();
+
876  Instruction* n = 0;
+
877 
+
878  delta.Normalize();
+
879  delta *= 200.0e3;
+
880 
+
881  npt_loc += delta;
+
882 
+
883  n = new(__FILE__,__LINE__) Instruction(elem->Region(),
+
884  npt_loc,
+ +
886 
+
887  if (n) {
+
888  n->SetSpeed(500);
+
889  elem->AddNavPoint(n);
+
890  }
+
891 
+
892  Text rgn2 = elem->Region();
+
893  List<CombatZone>& zones = campaign->GetZones();
+
894  if (zones[zones.size()-1]->HasRegion(rgn2))
+
895  rgn2 = *zones[0]->GetRegions()[0];
+
896  else
+
897  rgn2 = *zones[zones.size()-1]->GetRegions()[0];
+
898 
+
899  n = new(__FILE__,__LINE__) Instruction(rgn2,
+
900  Point(0, 0, 0),
+ +
902 
+
903  if (n) {
+
904  n->SetSpeed(750);
+
905  elem->AddNavPoint(n);
+
906  }
+
907 }
+
908 
+
909 void
+ +
911 {
+
912  if (!mission || !mission->GetStarSystem()) return;
+
913 
+
914  CombatUnit* carrier = FindCarrier(squadron);
+ +
916 
+
917  if (!shuttle || shuttle->CalcValue() < 1) return;
+
918 
+
919  List<CombatUnit>& units = shuttle->GetUnits();
+
920 
+ +
922  if (!elem) return;
+
923 
+ +
925  elem->SetRegion(orb_region);
+
926  elem->Loadouts().destroy();
+
927 
+
928  if (carrier)
+
929  elem->SetLocation(carrier->Location() + RandomPoint() * 2);
+
930 
+
931  ward = elem;
+
932  mission->AddElement(elem);
+
933 
+
934  // if there is terrain nearby, then have the shuttle fly down to it:
+
935  if (air_region.length() > 0) {
+
936  StarSystem* system = mission->GetStarSystem();
+
937  OrbitalRegion* rgn1 = system->FindRegion(elem->Region());
+
938  Point delta = rgn1->Location() - rgn1->Primary()->Location();
+
939  Point npt_loc = elem->Location();
+
940  Instruction* n = 0;
+
941 
+
942  delta.Normalize();
+
943  delta *= -200.0e3;
+
944 
+
945  npt_loc += delta;
+
946 
+
947  n = new(__FILE__,__LINE__) Instruction(elem->Region(),
+
948  npt_loc,
+ +
950 
+
951  if (n) {
+
952  n->SetSpeed(500);
+
953  elem->AddNavPoint(n);
+
954  }
+
955 
+
956  n = new(__FILE__,__LINE__) Instruction(air_region,
+
957  Point(0, 0, 10.0e3),
+ +
959 
+
960  if (n) {
+
961  n->SetSpeed(500);
+
962  elem->AddNavPoint(n);
+
963  }
+
964  }
+
965 
+
966  // otherwise, escort the shuttle in for a landing on the carrier:
+
967  else if (carrier) {
+
968  Point src = carrier->Location() + RandomDirection() * 150e3;
+
969  Point dst = carrier->Location() + RandomDirection() * 25e3;
+
970  Instruction* n = 0;
+
971 
+
972  elem->SetLocation(src);
+
973 
+
974  n = new(__FILE__,__LINE__) Instruction(elem->Region(), dst, Instruction::DOCK);
+
975  if (n) {
+
976  n->SetTarget(carrier->Name());
+
977  n->SetSpeed(500);
+
978  elem->AddNavPoint(n);
+
979  }
+
980  }
+
981 }
+
982 
+
983 void
+ +
985 {
+
986  if (!mission || !mission->GetStarSystem()) return;
+
987 
+
988  CombatUnit* carrier = FindCarrier(squadron);
+
989  CombatGroup* strike = strike_group;
+
990 
+
991  if (!strike || strike->CalcValue() < 1) return;
+
992 
+
993  List<CombatUnit>& units = strike->GetUnits();
+
994 
+
995  int type = Mission::ASSAULT;
+
996 
+
997  if (airborne)
+
998  type = Mission::STRIKE;
+
999 
+
1000  MissionElement* elem = CreateFighterPackage(strike, 2, type);
+
1001  if (!elem) return;
+
1002 
+
1003  if (strike->GetParent() == squadron->GetParent()) {
+ +
1005  elem->SetAlert(p ? !p->FlyingStart() : true);
+
1006  }
+
1007 
+
1008  elem->SetIntelLevel(Intel::KNOWN);
+
1009  elem->SetRegion(squadron->GetRegion());
+
1010 
+
1011  if (strike_target) {
+
1012  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ASSAULT, strike_target->Name());
+
1013 
+
1014  if (obj) {
+
1015  if (airborne)
+ +
1017 
+
1018  elem->AddObjective(obj);
+
1019  }
+
1020  }
+
1021 
+
1022  ward = elem;
+
1023  mission->AddElement(elem);
+
1024 
+
1025 
+
1026  StarSystem* system = mission->GetStarSystem();
+
1027  OrbitalRegion* rgn1 = system->FindRegion(elem->Region());
+
1028  Point delta = rgn1->Location() - rgn1->Primary()->Location();
+
1029  Point npt_loc = elem->Location();
+
1030  Instruction* n = 0;
+
1031 
+
1032  if (airborne) {
+
1033  delta.Normalize();
+
1034  delta *= -30.0e3;
+
1035  npt_loc += delta;
+
1036 
+
1037  n = new(__FILE__,__LINE__) Instruction(elem->Region(),
+
1038  npt_loc,
+ +
1040  if (n) {
+
1041  n->SetSpeed(500);
+
1042  elem->AddNavPoint(n);
+
1043  }
+
1044 
+
1045  npt_loc = Point(0, 0, 10.0e3);
+
1046 
+
1047  n = new(__FILE__,__LINE__) Instruction(air_region,
+
1048  npt_loc,
+ +
1050  if (n) {
+
1051  n->SetSpeed(500);
+
1052  elem->AddNavPoint(n);
+
1053  }
+
1054  }
+
1055 
+
1056  // IP:
+
1057  if (strike_target) {
+
1058  delta = strike_target->Location() - npt_loc;
+
1059  delta.Normalize();
+
1060  delta *= 15.0e3;
+
1061 
+
1062  npt_loc = strike_target->Location() + delta + Point(0, 0, 8.0e3);
+
1063 
+
1064  n = new(__FILE__,__LINE__) Instruction(strike_target->GetRegion(),
+
1065  npt_loc,
+ +
1067  if (n) {
+
1068  n->SetSpeed(500);
+
1069  elem->AddNavPoint(n);
+
1070  }
+
1071  }
+
1072 
+
1073  if (airborne) {
+
1074  n = new(__FILE__,__LINE__) Instruction(air_region,
+
1075  Point(0, 0, 30.0e3),
+ +
1077  if (n) {
+
1078  n->SetSpeed(500);
+
1079  elem->AddNavPoint(n);
+
1080  }
+
1081  }
+
1082 
+
1083  if (carrier) {
+
1084  n = new(__FILE__,__LINE__) Instruction(elem->Region(),
+
1085  carrier->Location() - Point(0, -20.0e3, 0),
+ +
1087  if (n) {
+
1088  n->SetSpeed(500);
+
1089  elem->AddNavPoint(n);
+
1090  }
+
1091  }
+
1092 
+
1093  // find the strike target element:
+
1094  if (strike_target) {
+ +
1096  }
+
1097 }
+
1098 
+
1099 // +--------------------------------------------------------------------+
+
1100 
+
1101 void
+ +
1103 {
+
1104  bool escort_needed = false;
+
1105 
+ +
1107  if (request && request->GetObjective()) {
+
1108  int tgt_type = request->GetObjective()->Type();
+
1109 
+
1110  if (tgt_type == CombatGroup::CARRIER_GROUP ||
+
1111  tgt_type == CombatGroup::STATION ||
+
1112  tgt_type == CombatGroup::STARBASE)
+
1113 
+
1114  escort_needed = true;
+
1115  }
+
1116  }
+
1117 
+
1118  if (player_elem && escort_needed) {
+ +
1120 
+
1121  if (s && s->IsAssignable()) {
+ +
1123 
+
1124  if (elem) {
+
1125  Point offset = Point(2.0e3, 2.0e3, 1.0e3);
+
1126 
+ +
1128  while (++npt_iter) {
+
1129  Instruction* npt = npt_iter.value();
+
1130  Instruction* n = new(__FILE__,__LINE__) Instruction(npt->RegionName(),
+
1131  npt->Location() + offset,
+ +
1133  if (n) {
+
1134  n->SetSpeed(npt->Speed());
+
1135  elem->AddNavPoint(n);
+
1136  }
+
1137  }
+
1138 
+
1139  mission->AddElement(elem);
+
1140  }
+
1141  }
+
1142  }
+
1143 }
+
1144 
+
1145 // +--------------------------------------------------------------------+
+
1146 
+
1147 void
+ +
1149 {
+
1150  switch (mission->Type()) {
+
1151  default:
+
1152  case Mission::DEFEND:
+
1153  case Mission::PATROL: CreateTargetsPatrol(); break;
+
1154  case Mission::SWEEP: CreateTargetsSweep(); break;
+ + +
1157 
+
1158  case Mission::ESCORT:
+ + +
1161  case Mission::STRIKE: CreateTargetsStrike(); break;
+
1162  case Mission::ASSAULT: CreateTargetsAssault(); break;
+
1163  }
+
1164 }
+
1165 
+
1166 void
+ +
1168 {
+
1169  if (!squadron || !player_elem) return;
+
1170 
+
1171  Text region = squadron->GetRegion();
+
1172  Point base_loc = player_elem->Location();
+
1173  Point patrol_loc;
+
1174 
+
1175  if (airborne)
+
1176  base_loc = RandomPoint() * 2 + Point(0, 0, 12.0e3);
+
1177 
+
1178  else if (carrier_elem)
+
1179  base_loc = carrier_elem->Location();
+
1180 
+
1181  if (airborne) {
+
1182  if (!airbase)
+ +
1184  region = air_region;
+
1185  patrol_loc = base_loc +
+
1186  RandomDirection() * Random( 60e3, 100e3);
+
1187  }
+
1188  else {
+
1189  patrol_loc = base_loc +
+
1190  RandomDirection() * Random(110e3, 160e3);
+
1191  }
+
1192 
+
1193  Instruction* n = new(__FILE__,__LINE__) Instruction(region,
+
1194  patrol_loc,
+ +
1196  if (n)
+ +
1198 
+
1199  int ntargets = (int) Random(2.0,5.1);
+
1200 
+
1201  while (ntargets > 0) {
+
1202  int t = CreateRandomTarget(region, patrol_loc);
+
1203  ntargets -= t;
+
1204  if (t < 1) break;
+
1205  }
+
1206 
+
1207  if (airborne && !airbase) {
+ +
1209  }
+
1210 
+
1211  Instruction* obj = new(__FILE__,__LINE__) Instruction(*n);
+
1212  obj->SetTargetDesc("inbound enemy units");
+
1213  player_elem->AddObjective(obj);
+
1214 
+
1215  if (carrier_elem && !airborne) {
+
1216  obj = new(__FILE__,__LINE__) Instruction(Instruction::DEFEND, carrier_elem->Name());
+
1217  if (obj) {
+
1218  obj->SetTargetDesc(Text("the ") + carrier_elem->Name() + " battle group");
+
1219  player_elem->AddObjective(obj);
+
1220  }
+
1221  }
+
1222 }
+
1223 
+
1224 void
+ +
1226 {
+
1227  if (!squadron || !player_elem) return;
+
1228 
+
1229  double traverse = PI;
+
1230  double a = Random(-PI/2, PI/2);
+
1231  Point base_loc = player_elem->Location();
+
1232  Point sweep_loc = base_loc;
+
1233  Text region = player_elem->Region();
+
1234  Instruction* n = 0;
+
1235 
+
1236  if (carrier_elem)
+
1237  base_loc = carrier_elem->Location();
+
1238 
+
1239  if (airborne) {
+ +
1241  region = air_region;
+
1242  sweep_loc = RandomPoint() + Point(0, 0, 10.0e3); // keep it airborne!
+
1243  }
+
1244 
+
1245  sweep_loc += Point(sin(a), -cos(a), 0) * 100.0e3;
+
1246 
+
1247  n = new(__FILE__,__LINE__) Instruction(region,
+
1248  sweep_loc,
+ +
1250  if (n) {
+
1251  n->SetSpeed(750);
+ +
1253  }
+
1254 
+
1255  int index = 0;
+
1256  int ntargets = 6;
+
1257 
+
1258  while (traverse > 0) {
+
1259  double a1 = Random(PI/4, PI/2);
+
1260  traverse -= a1;
+
1261  a += a1;
+
1262 
+
1263  sweep_loc += Point(sin(a), -cos(a), 0) * 80.0e3;
+
1264 
+
1265  n = new(__FILE__,__LINE__) Instruction(region,
+
1266  sweep_loc,
+ +
1268  if (n) {
+
1269  n->SetSpeed(750);
+ + +
1272  }
+
1273 
+
1274  if (ntargets && RandomChance()) {
+
1275  ntargets -= CreateRandomTarget(region, sweep_loc);
+
1276  }
+
1277 
+
1278  index++;
+
1279  }
+
1280 
+
1281  if (ntargets > 0)
+
1282  CreateRandomTarget(region, sweep_loc);
+
1283 
+
1284  if (airborne && !airbase) {
+ +
1286  region = player_elem->Region();
+
1287  }
+
1288 
+
1289  sweep_loc = base_loc;
+
1290  sweep_loc.y += 30.0e3;
+
1291 
+
1292  n = new(__FILE__,__LINE__) Instruction(region,
+
1293  sweep_loc,
+ +
1295  if (n) {
+
1296  n->SetSpeed(750);
+ +
1298  }
+
1299 
+
1300  Instruction* obj = new(__FILE__,__LINE__) Instruction(region,
+
1301  sweep_loc,
+ +
1303  if (obj) {
+
1304  obj->SetTargetDesc("enemy patrols");
+
1305  player_elem->AddObjective(obj);
+
1306  }
+
1307 
+
1308  if (carrier_elem && !airborne) {
+
1309  obj = new(__FILE__,__LINE__) Instruction(Instruction::DEFEND, carrier_elem->Name());
+
1310  if (obj) {
+
1311  obj->SetTargetDesc(Text("the ") + carrier_elem->Name() + " battle group");
+
1312  player_elem->AddObjective(obj);
+
1313  }
+
1314  }
+
1315 }
+
1316 
+
1317 void
+ +
1319 {
+
1320  if (!squadron || !player_elem) return;
+
1321 
+
1322  CombatUnit* carrier = FindCarrier(squadron);
+ + +
1325 
+
1326  if (!s || !s2) return;
+
1327 
+
1328  int ninbound = 2 + (int) (RandomIndex() < 5);
+
1329  bool second = ninbound > 2;
+
1330  Text attacker;
+
1331 
+
1332  while (ninbound--) {
+ +
1334  if (elem) {
+
1335  elem->SetIntelLevel(Intel::KNOWN);
+
1336  elem->Loadouts().destroy();
+
1337  elem->Loadouts().append(new(__FILE__,__LINE__) MissionLoad(-1, "Hvy Ship Strike"));
+
1338 
+
1339  if (carrier) {
+
1340  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ASSAULT, carrier->Name());
+
1341  if (obj) {
+
1342  elem->AddObjective(obj);
+
1343  elem->SetLocation(carrier->Location() + RandomPoint() * 6);
+
1344  }
+
1345  }
+
1346  else {
+
1347  elem->SetLocation(squadron->Location() + RandomPoint() * 5);
+
1348  }
+
1349 
+
1350  mission->AddElement(elem);
+
1351 
+
1352  attacker = elem->Name();
+
1353 
+
1354  if (!prime_target) {
+
1355  prime_target = elem;
+
1356  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::INTERCEPT, attacker);
+
1357  if (obj) {
+
1358  obj->SetTargetDesc(Text("inbound strike package '") + elem->Name() + "'");
+
1359  player_elem->AddObjective(obj);
+
1360  }
+
1361  }
+
1362 
+ +
1364  if (e2) {
+ +
1366  e2->SetLocation(elem->Location() + RandomPoint() * 0.25);
+
1367 
+
1368  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ESCORT, elem->Name());
+
1369  if (obj)
+
1370  e2->AddObjective(obj);
+
1371  mission->AddElement(e2);
+
1372  }
+
1373  }
+
1374  }
+
1375 
+
1376  if (second) {
+
1377  // second friendly fighter package
+ +
1379 
+
1380  if (s) {
+ +
1382  if (elem) {
+ +
1384  elem->SetAlert(p ? !p->FlyingStart() : true);
+
1385 
+
1386  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::INTERCEPT, attacker);
+
1387  if (obj)
+
1388  elem->AddObjective(obj);
+
1389  mission->AddElement(elem);
+
1390  }
+
1391  }
+
1392  }
+
1393 
+
1394  if (carrier && !airborne) {
+
1395  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::DEFEND, carrier->Name());
+
1396  if (obj) {
+
1397  obj->SetTargetDesc(Text("the ") + carrier->Name() + " battle group");
+
1398  player_elem->AddObjective(obj);
+
1399  }
+
1400  }
+
1401 }
+
1402 
+
1403 void
+ +
1405 {
+
1406  if (!squadron || !player_elem) return;
+
1407 
+
1408  if (!ward) {
+ +
1410  return;
+
1411  }
+
1412 
+
1413  CombatUnit* carrier = FindCarrier(squadron);
+ + +
1416 
+
1417  if (!s) s = s2;
+
1418 
+
1419  if (!s || !s2) return;
+
1420 
+ +
1422  if (elem) {
+
1423  elem->SetIntelLevel(Intel::KNOWN);
+
1424 
+
1425  elem->SetLocation(ward->Location() + RandomPoint() * 5);
+
1426 
+
1427  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ASSAULT, ward->Name());
+
1428  if (obj)
+
1429  elem->AddObjective(obj);
+
1430  mission->AddElement(elem);
+
1431 
+ +
1433  if (e2) {
+ +
1435  e2->SetLocation(elem->Location() + RandomPoint() * 0.25);
+
1436 
+
1437  Instruction* obj2 = new(__FILE__,__LINE__) Instruction(Instruction::ESCORT, elem->Name());
+
1438  if (obj2)
+
1439  e2->AddObjective(obj2);
+
1440  mission->AddElement(e2);
+
1441  }
+
1442  }
+
1443 
+
1444  Instruction* obj3 = new(__FILE__,__LINE__) Instruction(mission->GetRegion(),
+
1445  Point(0,0,0),
+ +
1447 
+
1448  if (obj3) {
+
1449  obj3->SetTargetDesc("enemy patrols");
+
1450  player_elem->AddObjective(obj3);
+
1451  }
+
1452 }
+
1453 
+
1454 void
+ +
1456 {
+ +
1458 }
+
1459 
+
1460 // +--------------------------------------------------------------------+
+
1461 
+
1462 void
+ +
1464 {
+
1465  if (!squadron || !player_elem) return;
+
1466 
+
1467  if (ward) {
+
1468  Point offset = Point(2.0e3, 2.0e3, 1.0e3);
+
1469 
+
1470  ListIter<Instruction> npt_iter = ward->NavList();
+
1471  while (++npt_iter) {
+
1472  Instruction* npt = npt_iter.value();
+
1473  Instruction* n = new(__FILE__,__LINE__) Instruction(npt->RegionName(),
+
1474  npt->Location() + offset,
+ +
1476  if (n) {
+
1477  n->SetSpeed(npt->Speed());
+ +
1479  }
+
1480  }
+
1481  }
+
1482 }
+
1483 
+
1484 // +--------------------------------------------------------------------+
+
1485 
+
1486 void
+ +
1488 {
+
1489  if (!squadron || !player_elem) return;
+
1490 
+
1491  if (request && request->GetObjective())
+ +
1493 
+
1494  if (strike_target && strike_group) {
+ +
1496 
+ +
1498  while (++e_iter) {
+
1499  MissionElement* elem = e_iter.value();
+
1500 
+
1501  if (elem->GetCombatGroup() == strike_target) {
+
1502  prime_target = elem;
+
1503  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::STRIKE, elem->Name());
+
1504  if (obj) {
+
1505  obj->SetTargetDesc(Text("preplanned target '") + elem->Name() + "'");
+
1506  player_elem->AddObjective(obj);
+
1507  }
+
1508 
+
1509  // create flight plan:
+
1510  RLoc rloc;
+
1511  Point loc = Point(0, 0, 15e3);
+
1512  Instruction* n = 0;
+
1513 
+ +
1515 
+
1516  // target approach and strike:
+
1517  Point delta = prime_target->Location() - loc;
+
1518 
+
1519  if (delta.length() >= 100e3) {
+
1520  Point mid = loc + delta * 0.5;
+
1521  mid.z = 10.0e3;
+
1522 
+
1523  rloc.SetReferenceLoc(0);
+
1524  rloc.SetBaseLocation(mid);
+
1525  rloc.SetDistance(20e3);
+
1526  rloc.SetDistanceVar(5e3);
+
1527  rloc.SetAzimuth(90*DEGREES);
+
1528  rloc.SetAzimuthVar(25*DEGREES);
+
1529 
+
1530  n = new(__FILE__,__LINE__) Instruction(prime_target->Region(),
+
1531  Point(),
+ +
1533  if (n) {
+
1534  n->SetSpeed(750);
+
1535  n->GetRLoc() = rloc;
+ +
1537  }
+
1538 
+
1539  loc = mid;
+
1540  }
+
1541 
+
1542  delta = loc - prime_target->Location();
+
1543  delta.Normalize();
+
1544  delta *= 25.0e3;
+
1545 
+
1546  loc = prime_target->Location() + delta;
+
1547  loc.z = 8.0e3;
+
1548 
+
1549  n = new(__FILE__,__LINE__) Instruction(prime_target->Region(),
+
1550  loc,
+ +
1552  if (n) {
+
1553  n->SetSpeed(500);
+ +
1555  }
+
1556 
+
1557  // exeunt:
+
1558  rloc.SetReferenceLoc(0);
+
1559  rloc.SetBaseLocation(Point(0, 0, 30.0e3));
+
1560  rloc.SetDistance(50e3);
+
1561  rloc.SetDistanceVar(5e3);
+
1562  rloc.SetAzimuth(-90*DEGREES);
+
1563  rloc.SetAzimuthVar(25*DEGREES);
+
1564 
+
1565  n = new(__FILE__,__LINE__) Instruction(prime_target->Region(),
+
1566  Point(),
+ +
1568  if (n) {
+
1569  n->SetSpeed(750);
+
1570  n->GetRLoc() = rloc;
+ +
1572  }
+
1573 
+
1574  if (carrier_elem) {
+
1575  rloc.SetReferenceLoc(0);
+ +
1577  rloc.SetDistance(60e3);
+
1578  rloc.SetDistanceVar(10e3);
+
1579  rloc.SetAzimuth(180*DEGREES);
+
1580  rloc.SetAzimuthVar(30*DEGREES);
+
1581 
+
1582  n = new(__FILE__,__LINE__) Instruction(carrier_elem->Region(),
+
1583  Point(),
+ +
1585  if (n) {
+
1586  n->SetSpeed(750);
+
1587  n->GetRLoc() = rloc;
+ +
1589  }
+
1590  }
+
1591 
+
1592  break;
+
1593  }
+
1594  }
+
1595  }
+
1596 }
+
1597 
+
1598 // +--------------------------------------------------------------------+
+
1599 
+
1600 void
+ +
1602 {
+
1603  if (!squadron || !player_elem) return;
+
1604 
+
1605  CombatGroup* assigned = 0;
+
1606 
+
1607  if (request)
+
1608  assigned = request->GetObjective();
+
1609 
+
1610  if (assigned) {
+
1611  if (assigned->Type() > CombatGroup::WING && assigned->Type() < CombatGroup::FLEET) {
+ +
1613  }
+
1614  else {
+
1615  CreateElements(assigned);
+
1616  }
+
1617 
+
1618  // select the prime target element - choose the lowest ranking
+
1619  // unit of a DESRON, CBG, or CVBG:
+
1620 
+ +
1622  while (++e_iter) {
+
1623  MissionElement* elem = e_iter.value();
+
1624 
+
1625  if (elem->GetCombatGroup() == assigned) {
+
1626  if (!prime_target || assigned->Type() <= CombatGroup::CARRIER_GROUP) {
+
1627  prime_target = elem;
+
1628  }
+
1629  }
+
1630  }
+
1631 
+
1632  if (prime_target) {
+
1633  MissionElement* elem = prime_target;
+
1634 
+
1635  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ASSAULT, elem->Name());
+
1636  if (obj) {
+
1637  obj->SetTargetDesc(Text("preplanned target '") + elem->Name() + "'");
+
1638  player_elem->AddObjective(obj);
+
1639  }
+
1640 
+
1641  // create flight plan:
+
1642  RLoc rloc;
+
1643  Vec3 dummy(0,0,0);
+
1644  Instruction* instr = 0;
+
1645  Point loc = player_elem->Location();
+
1646  Point tgt = elem->Location();
+
1647  Point mid;
+
1648 
+
1649  CombatGroup* tgt_group = elem->GetCombatGroup();
+
1650  if (tgt_group && tgt_group->GetFirstUnit() && tgt_group->IsMovable()) {
+
1651  tgt = tgt_group->GetFirstUnit()->Location();
+
1652  }
+
1653 
+
1654  if (carrier_elem)
+
1655  loc = carrier_elem->Location();
+
1656 
+
1657  mid = loc + (elem->Location() - loc) * 0.5;
+
1658 
+
1659  rloc.SetReferenceLoc(0);
+
1660  rloc.SetBaseLocation(mid);
+
1661  rloc.SetDistance(40e3);
+
1662  rloc.SetDistanceVar(5e3);
+
1663  rloc.SetAzimuth(90*DEGREES);
+
1664  rloc.SetAzimuthVar(45*DEGREES);
+
1665 
+
1666  instr = new(__FILE__,__LINE__) Instruction(elem->Region(), dummy, Instruction::VECTOR);
+
1667  if (instr) {
+
1668  instr->SetSpeed(750);
+
1669  instr->GetRLoc() = rloc;
+
1670 
+
1671  player_elem->AddNavPoint(instr);
+
1672 
+
1673  if (RandomChance()) {
+
1674  CreateRandomTarget(elem->Region(), rloc.Location());
+
1675  }
+
1676  }
+
1677 
+
1678  rloc.SetReferenceLoc(0);
+
1679  rloc.SetBaseLocation(tgt);
+
1680  rloc.SetDistance(60e3);
+
1681  rloc.SetDistanceVar(5e3);
+
1682  rloc.SetAzimuth(120*DEGREES);
+
1683  rloc.SetAzimuthVar(15*DEGREES);
+
1684 
+
1685  instr = new(__FILE__,__LINE__) Instruction(elem->Region(), dummy, Instruction::ASSAULT);
+
1686  if (instr) {
+
1687  instr->SetSpeed(750);
+
1688  instr->GetRLoc() = rloc;
+
1689  instr->SetTarget(elem->Name());
+
1690 
+
1691  player_elem->AddNavPoint(instr);
+
1692  }
+
1693 
+
1694  if (carrier_elem) {
+
1695  rloc.SetReferenceLoc(0);
+
1696  rloc.SetBaseLocation(loc);
+
1697  rloc.SetDistance(30e3);
+
1698  rloc.SetDistanceVar(0);
+
1699  rloc.SetAzimuth(180*DEGREES);
+
1700  rloc.SetAzimuthVar(60*DEGREES);
+
1701 
+
1702  instr = new(__FILE__,__LINE__) Instruction(carrier_elem->Region(), dummy, Instruction::RTB);
+
1703  if (instr) {
+
1704  instr->SetSpeed(500);
+
1705  instr->GetRLoc() = rloc;
+
1706 
+
1707  player_elem->AddNavPoint(instr);
+
1708  }
+
1709  }
+
1710  }
+
1711  }
+
1712 }
+
1713 
+
1714 // +--------------------------------------------------------------------+
+
1715 
+
1716 int
+ +
1718 {
+
1719  if (!mission) return 0;
+
1720 
+
1721  int ntargets = 0;
+
1722  int ttype = RandomIndex();
+
1723  bool oca = (mission->Type() == Mission::SWEEP);
+
1724 
+
1725  if (ttype < 8) {
+
1726  CombatGroup* s = 0;
+
1727 
+
1728  if (ttype < 4)
+ +
1730  else
+ +
1732 
+
1733  if (s) {
+ +
1735  if (elem) {
+
1736  elem->SetIntelLevel(Intel::KNOWN);
+
1737  elem->SetRegion(rgn);
+
1738  elem->SetLocation(base_loc + RandomPoint() * 1.5);
+
1739  mission->AddElement(elem);
+
1740  ntargets++;
+
1741  }
+
1742  }
+
1743  }
+
1744  else if (ttype < 12) {
+
1745  if (oca) {
+ +
1747 
+
1748  if (s) {
+ +
1750  if (elem) {
+
1751  elem->SetIntelLevel(Intel::KNOWN);
+
1752  elem->SetRegion(rgn);
+
1753  elem->SetLocation(base_loc + RandomPoint() * 2);
+
1754  mission->AddElement(elem);
+
1755  ntargets++;
+
1756 
+ +
1758 
+
1759  if (s2) {
+ +
1761  if (e2) {
+ +
1763  e2->SetRegion(rgn);
+
1764  e2->SetLocation(elem->Location() + RandomPoint() * 0.5);
+
1765 
+
1766  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ESCORT, elem->Name());
+
1767  if (obj)
+
1768  e2->AddObjective(obj);
+
1769  mission->AddElement(e2);
+
1770  ntargets++;
+
1771  }
+
1772  }
+
1773  }
+
1774  }
+
1775  }
+
1776  else {
+ +
1778 
+
1779  if (s) {
+ +
1781  if (elem) {
+
1782  elem->SetIntelLevel(Intel::KNOWN);
+
1783  elem->SetRegion(rgn);
+
1784  elem->SetLocation(base_loc + RandomPoint() * 1.3);
+
1785  mission->AddElement(elem);
+
1786  ntargets++;
+
1787  }
+
1788  }
+
1789  }
+
1790  }
+
1791  else if (ttype < 15) {
+
1792  if (oca) {
+
1793  CombatGroup* s = 0;
+
1794 
+
1795  if (airborne)
+ +
1797  else
+ +
1799 
+
1800  if (s) {
+ +
1802  if (elem) {
+
1803  elem->SetIntelLevel(Intel::KNOWN);
+
1804  elem->SetRegion(rgn);
+
1805  elem->SetLocation(base_loc + RandomPoint() * 2);
+
1806  mission->AddElement(elem);
+
1807  ntargets++;
+
1808 
+ +
1810 
+
1811  if (s2) {
+ +
1813  if (e2) {
+ +
1815  e2->SetRegion(rgn);
+
1816  e2->SetLocation(elem->Location() + RandomPoint() * 0.5);
+
1817 
+
1818  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ESCORT, elem->Name());
+
1819  if (obj)
+
1820  e2->AddObjective(obj);
+
1821  mission->AddElement(e2);
+
1822  ntargets++;
+
1823  }
+
1824  }
+
1825  }
+
1826  }
+
1827  }
+
1828  else {
+ +
1830 
+
1831  if (s) {
+ +
1833  if (elem) {
+
1834  elem->SetIntelLevel(Intel::KNOWN);
+
1835  elem->SetRegion(rgn);
+
1836  elem->SetLocation(base_loc + RandomPoint() * 1.1);
+
1837  mission->AddElement(elem);
+
1838  ntargets++;
+
1839 
+ +
1841 
+
1842  if (s2) {
+ +
1844  if (e2) {
+ +
1846  e2->SetRegion(rgn);
+
1847  e2->SetLocation(elem->Location() + RandomPoint() * 0.5);
+
1848 
+
1849  Instruction* obj = new(__FILE__,__LINE__) Instruction(Instruction::ESCORT, elem->Name());
+
1850  if (obj)
+
1851  e2->AddObjective(obj);
+
1852  mission->AddElement(e2);
+
1853  ntargets++;
+
1854  }
+
1855  }
+
1856  }
+
1857  }
+
1858  }
+
1859  }
+
1860  else {
+ +
1862 
+
1863  if (s) {
+ +
1865  if (elem) {
+
1866  elem->SetIntelLevel(Intel::KNOWN);
+
1867  elem->SetRegion(rgn);
+
1868  elem->SetLocation(base_loc + RandomPoint() * 2);
+
1869  mission->AddElement(elem);
+
1870  ntargets++;
+
1871  }
+
1872  }
+
1873  }
+
1874 
+
1875  return ntargets;
+
1876 }
+
1877 
+
1878 // +--------------------------------------------------------------------+
+
1879 
+
1880 void
+ +
1882 {
+
1883  if (!mission || !elem) return;
+
1884  if (!mission->GetStarSystem()) return;
+
1885 
+
1886  MissionElement* carrier = mission->FindElement(elem->Commander());
+
1887  StarSystem* system = mission->GetStarSystem();
+
1888  OrbitalRegion* rgn1 = system->FindRegion(elem->Region());
+
1889  OrbitalRegion* rgn2 = system->FindRegion(air_region);
+
1890  Point npt_loc = elem->Location();
+
1891  Instruction* n = 0;
+ +
1893 
+
1894  int flying_start = p ? p->FlyingStart() : 0;
+
1895 
+
1896  if (carrier && !flying_start) {
+
1897  npt_loc = carrier->Location() + Point(1e3, -5e3, 0);
+
1898  }
+
1899 
+
1900  if (rgn1 && rgn2) {
+
1901  double delta_t = mission->Start() - campaign->GetTime();
+
1902  Point r1 = rgn1->PredictLocation(delta_t);
+
1903  Point r2 = rgn2->PredictLocation(delta_t);
+
1904 
+
1905  Point delta = r2 - r1;
+
1906 
+
1907  delta.y *= -1;
+
1908  delta.Normalize();
+
1909  delta *= 10e3;
+
1910 
+
1911  npt_loc += delta;
+
1912 
+
1913  n = new(__FILE__,__LINE__) Instruction(elem->Region(),
+
1914  npt_loc,
+ +
1916  if (n) {
+
1917  n->SetSpeed(750);
+
1918  elem->AddNavPoint(n);
+
1919  }
+
1920  }
+
1921 
+
1922  n = new(__FILE__,__LINE__) Instruction(air_region,
+
1923  Point(0, 0, 15e3),
+ +
1925  if (n) {
+
1926  n->SetSpeed(750);
+
1927  elem->AddNavPoint(n);
+
1928  }
+
1929 }
+
1930 
+
1931 void
+ +
1933 {
+
1934  Instruction* n = new(__FILE__,__LINE__) Instruction(air_region,
+
1935  Point(0, 0, 30.0e3),
+ +
1937  if (n) {
+
1938  n->SetSpeed(750);
+
1939  elem->AddNavPoint(n);
+
1940  }
+
1941 }
+
1942 
+
1943 // +--------------------------------------------------------------------+
+
1944 
+ + +
1947 {
+
1948  if (!squadron) return 0;
+
1949 
+
1950  CombatUnit* fighter = squadron->GetUnits().at(0);
+
1951  CombatUnit* carrier = FindCarrier(squadron);
+
1952 
+
1953  if (!fighter)
+
1954  return 0;
+
1955 
+
1956  int avail = fighter->LiveCount();
+
1957  int actual = count;
+
1958 
+
1959  if (avail < actual)
+
1960  actual = avail;
+
1961 
+
1962  if (avail < 1) {
+
1963  ::Print("CMF - Insufficient fighters in squadron '%s' - %d required, %d available\n",
+
1964  squadron->Name().data(), count, avail);
+
1965  return 0;
+
1966  }
+
1967 
+
1968  MissionElement* elem = new(__FILE__,__LINE__) MissionElement;
+
1969  if (!elem) {
+
1970  Exit();
+
1971  return 0;
+
1972  }
+
1973 
+
1974  elem->SetName(Callsign::GetCallsign(fighter->GetIFF()));
+
1975  elem->SetElementID(pkg_id++);
+
1976 
+
1977  if (carrier) {
+
1978  elem->SetCommander(carrier->Name());
+
1979  elem->SetHeading(carrier->GetHeading());
+
1980  }
+
1981  else {
+
1982  elem->SetHeading(fighter->GetHeading());
+
1983  }
+
1984 
+
1985  elem->SetDesign(fighter->GetDesign());
+
1986  elem->SetCount(actual);
+
1987  elem->SetIFF(fighter->GetIFF());
+
1988  elem->SetIntelLevel(squadron->IntelLevel());
+
1989  elem->SetRegion(fighter->GetRegion());
+
1990  elem->SetSquadron(squadron->Name());
+
1991  elem->SetMissionRole(role);
+
1992 
+
1993  switch (role) {
+
1994  case Mission::ASSAULT:
+
1995  if (request->GetObjective() &&
+ +
1997  elem->Loadouts().append(new(__FILE__,__LINE__) MissionLoad(-1, "Rockets"));
+
1998  else
+
1999  elem->Loadouts().append(new(__FILE__,__LINE__) MissionLoad(-1, "Ship Strike"));
+
2000  break;
+
2001 
+
2002  case Mission::STRIKE:
+
2003  elem->Loadouts().append(new(__FILE__,__LINE__) MissionLoad(-1, "Ground Strike"));
+
2004  break;
+
2005 
+
2006  default:
+
2007  elem->Loadouts().append(new(__FILE__,__LINE__) MissionLoad(-1, "ACM Medium Range"));
+
2008  break;
+
2009  }
+
2010 
+
2011  if (carrier) {
+
2012  Point offset = RandomPoint() * 0.3;
+
2013  offset.y = fabs(offset.y);
+
2014  offset.z += 2e3;
+
2015  elem->SetLocation(carrier->Location() + offset);
+
2016  }
+
2017  else {
+
2018  elem->SetLocation(fighter->Location() + RandomPoint());
+
2019  }
+
2020 
+
2021  elem->SetCombatGroup(squadron);
+
2022  elem->SetCombatUnit(fighter);
+
2023 
+
2024  return elem;
+
2025 }
+
2026 
+
2027 // +--------------------------------------------------------------------+
+
2028 
+
2029 static CombatGroup* FindCombatGroup(CombatGroup* g, int type)
+
2030 {
+
2031  if (g->IntelLevel() <= Intel::RESERVE)
+
2032  return 0;
+
2033 
+
2034  if (g->GetUnits().size() > 0) {
+
2035  for (int i = 0; i < g->GetUnits().size(); i++) {
+
2036  CombatUnit* u = g->GetUnits().at(i);
+
2037  if (g->Type() == type && u->LiveCount() > 0)
+
2038  return g;
+
2039  }
+
2040  }
+
2041 
+
2042  CombatGroup* result = 0;
+
2043 
+
2044  ListIter<CombatGroup> subgroup = g->GetComponents();
+
2045  while (++subgroup && !result)
+
2046  result = FindCombatGroup(subgroup.value(), type);
+
2047 
+
2048  return result;
+
2049 }
+
2050 
+
2051 // +--------------------------------------------------------------------+
+
2052 
+
2053 CombatGroup*
+ +
2055 {
+
2056  if (!squadron) return 0;
+
2057 
+
2058  CombatGroup* result = 0;
+ +
2060 
+
2061  if (campaign) {
+
2062  ListIter<Combatant> combatant = campaign->GetCombatants();
+
2063  while (++combatant && !result) {
+
2064  if (combatant->GetIFF() == iff) {
+
2065  result = ::FindCombatGroup(combatant->GetForce(), type);
+
2066 
+
2067  if (result && result->CountUnits() < 1) {
+
2068  result = 0;
+
2069  }
+
2070  }
+
2071  }
+
2072  }
+
2073 
+
2074  return result;
+
2075 }
+
2076 
+
2077 // +--------------------------------------------------------------------+
+
2078 
+
2079 void
+ +
2081 {
+
2082  if (!mission || !player_elem) return;
+
2083 
+ +
2085  if (ward) mission->SetWard(ward);
+
2086 
+
2087  Text objectives;
+
2088 
+
2089  for (int i = 0; i < player_elem->Objectives().size(); i++) {
+
2090  Instruction* obj = player_elem->Objectives().at(i);
+
2091  objectives += "* ";
+
2092  objectives += obj->GetDescription();
+
2093  objectives += ".\n";
+
2094  }
+
2095 
+
2096  mission->SetObjective(objectives);
+
2097 }
+
2098 
+
2099 // +--------------------------------------------------------------------+
+
2100 
+
2101 MissionInfo*
+ +
2103 {
+
2104  if (!mission || !player_elem) return 0;
+
2105 
+
2106  char name[256];
+
2107  char player_info[256];
+
2108 
+ +
2110  sprintf_s(name, "MSN-%03d %s", mission->Identity(), mission_info->name.data());
+
2111  else if (ward)
+
2112  sprintf_s(name, "MSN-%03d %s %s", mission->Identity(), Game::GetText(mission->TypeName()).data(), ward->Name().data());
+
2113  else if (prime_target)
+
2114  sprintf_s(name, "MSN-%03d %s %s %s", mission->Identity(), Game::GetText(mission->TypeName()).data(),
+ +
2116  prime_target->Name().data());
+
2117  else
+
2118  sprintf_s(name, "MSN-%03d %s", mission->Identity(), Game::GetText(mission->TypeName()).data());
+
2119 
+
2120  if (player_elem) {
+
2121  sprintf_s(player_info, "%d x %s %s '%s'",
+
2122  player_elem->Count(),
+
2123  (const char*) player_elem->GetDesign()->abrv,
+
2124  (const char*) player_elem->GetDesign()->name,
+
2125  (const char*) player_elem->Name());
+
2126  }
+
2127 
+
2128  MissionInfo* info = new(__FILE__,__LINE__) MissionInfo;
+
2129 
+
2130  info->id = mission->Identity();
+
2131  info->mission = mission;
+
2132  info->name = name;
+
2133  info->type = mission->Type();
+
2134  info->player_info = player_info;
+
2135  info->description = mission->Objective();
+
2136  info->start = mission->Start();
+
2137 
+
2138  if (mission->GetStarSystem())
+
2139  info->system = mission->GetStarSystem()->Name();
+
2140  info->region = mission->GetRegion();
+
2141 
+
2142  mission->SetName(name);
+
2143 
+
2144  return info;
+
2145 }
+
2146 
+
2147 // +--------------------------------------------------------------------+
+
2148 
+
2149 void
+ +
2151 {
+ +
2153  if (stars)
+ +
2155 }
+
+
+ + + + -- cgit v1.1