From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_mission_8cpp_source.html | 2278 ++++++++++++++++++++++++++++ 1 file changed, 2278 insertions(+) create mode 100644 Doc/doxygen/html/_mission_8cpp_source.html (limited to 'Doc/doxygen/html/_mission_8cpp_source.html') diff --git a/Doc/doxygen/html/_mission_8cpp_source.html b/Doc/doxygen/html/_mission_8cpp_source.html new file mode 100644 index 0000000..74269e9 --- /dev/null +++ b/Doc/doxygen/html/_mission_8cpp_source.html @@ -0,0 +1,2278 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/Mission.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
Mission.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: Mission.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Mission classes
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "Mission.h"
+
17 #include "MissionEvent.h"
+
18 #include "StarSystem.h"
+
19 #include "Galaxy.h"
+
20 #include "Starshatter.h"
+
21 #include "Ship.h"
+
22 #include "ShipDesign.h"
+
23 #include "Element.h"
+
24 #include "Instruction.h"
+
25 #include "WeaponDesign.h"
+
26 #include "Sim.h"
+
27 
+
28 #include "Game.h"
+
29 #include "DataLoader.h"
+
30 #include "ParseUtil.h"
+
31 #include "FormatUtil.h"
+
32 #include "Random.h"
+
33 #include "Skin.h"
+
34 
+
35 // +--------------------------------------------------------------------+
+
36 
+
37 Mission::Mission(int identity, const char* fname, const char* pname)
+
38 : id(identity), type(0), team(1), ok(false), active(false), complete(false),
+
39 star_system(0), start(33 * 3600), stardate(0), target(0), ward(0),
+
40 current(0), degrees(false)
+
41 {
+
42  objective = Game::GetText("Mission.unspecified");
+
43  sitrep = Game::GetText("Mission.unknown");
+
44 
+
45  if (fname)
+
46  strcpy_s(filename, fname);
+
47  else
+
48  ZeroMemory(filename, sizeof(filename));
+
49 
+
50  if (pname)
+
51  strcpy_s(path, pname);
+
52  else
+
53  strcpy_s(path, "Missions/");
+
54 }
+
55 
+ +
57 {
+
58  ::Print("Mission::~Mission() id = %d name = '%s'\n", id, name.data());
+
59  elements.destroy();
+
60  events.destroy();
+
61 }
+
62 
+
63 // +--------------------------------------------------------------------+
+
64 
+
65 const char*
+ +
67 {
+
68  return subtitles;
+
69 }
+
70 
+
71 // +--------------------------------------------------------------------+
+
72 
+
73 void
+ +
75 {
+
76  if (elem)
+
77  elements.append(elem);
+
78 }
+
79 
+
80 // +--------------------------------------------------------------------+
+
81 
+ +
83 Mission::FindElement(const char* name)
+
84 {
+ +
86  while (++iter) {
+
87  MissionElement* elem = iter.value();
+
88 
+
89  if (elem->Name() == name)
+
90  return elem;
+
91  }
+
92 
+
93  return 0;
+
94 }
+
95 
+
96 // +--------------------------------------------------------------------+
+
97 
+
98 void
+ +
100 {
+
101  if (elem_index > 0 && elem_index < elements.size()) {
+
102  MissionElement* elem1 = elements.at(elem_index-1);
+
103  MissionElement* elem2 = elements.at(elem_index);
+
104 
+
105  elements.at(elem_index-1) = elem2;
+
106  elements.at(elem_index) = elem1;
+
107  }
+
108 }
+
109 
+
110 void
+ +
112 {
+
113  if (elem_index >= 0 && elem_index < elements.size()-1) {
+
114  MissionElement* elem1 = elements.at(elem_index);
+
115  MissionElement* elem2 = elements.at(elem_index+1);
+
116 
+
117  elements.at(elem_index) = elem2;
+
118  elements.at(elem_index+1) = elem1;
+
119  }
+
120 }
+
121 
+
122 // +--------------------------------------------------------------------+
+
123 
+
124 void
+ +
126 {
+
127  if (event_index > 0 && event_index < events.size()) {
+
128  MissionEvent* event1 = events.at(event_index-1);
+
129  MissionEvent* event2 = events.at(event_index);
+
130 
+
131  events.at(event_index-1) = event2;
+
132  events.at(event_index) = event1;
+
133  }
+
134 }
+
135 
+
136 void
+ +
138 {
+
139  if (event_index >= 0 && event_index < events.size()-1) {
+
140  MissionEvent* event1 = events.at(event_index);
+
141  MissionEvent* event2 = events.at(event_index+1);
+
142 
+
143  events.at(event_index) = event2;
+
144  events.at(event_index+1) = event1;
+
145  }
+
146 }
+
147 
+
148 // +--------------------------------------------------------------------+
+
149 
+
150 void
+ +
152 {
+
153  if (star_system != s) {
+
154  star_system = s;
+
155 
+
156  if (!system_list.contains(s))
+
157  system_list.append(s);
+
158  }
+
159 }
+
160 
+
161 void
+ +
163 {
+
164  star_system = 0;
+
165  system_list.clear();
+
166 }
+
167 
+
168 // +--------------------------------------------------------------------+
+
169 
+
170 void
+ +
172 {
+ +
174  while (++elem) {
+
175  MissionElement* element = elem.value();
+
176  if (element == player_element)
+
177  element->player = 1;
+
178  else
+
179  element->player = 0;
+
180  }
+
181 }
+
182 
+ + +
185 {
+
186  MissionElement* p = 0;
+
187 
+ +
189  while (++elem) {
+
190  if (elem->player > 0)
+
191  p = elem.value();
+
192  }
+
193 
+
194  return p;
+
195 }
+
196 
+
197 // +--------------------------------------------------------------------+
+
198 
+ +
200 Mission::FindEvent(int event_type) const
+
201 {
+
202  Mission* pThis = (Mission*) this;
+
203  ListIter<MissionEvent> iter = pThis->events;
+
204  while (++iter) {
+
205  MissionEvent* event = iter.value();
+
206 
+
207  if (event->Event() == event_type)
+
208  return event;
+
209  }
+
210 
+
211  return 0;
+
212 }
+
213 
+
214 void
+ +
216 {
+
217  if (event)
+
218  events.append(event);
+
219 }
+
220 
+
221 // +--------------------------------------------------------------------+
+
222 
+
223 bool
+
224 Mission::Load(const char* fname, const char* pname)
+
225 {
+
226  ok = false;
+
227 
+
228  if (fname)
+
229  strcpy_s(filename, fname);
+
230 
+
231  if (pname)
+
232  strcpy_s(path, pname);
+
233 
+
234  if (!filename[0]) {
+
235  Print("\nCan't Load Mission, script unspecified.\n");
+
236  return ok;
+
237  }
+
238 
+
239  // wipe existing mission before attempting to load...
+
240  elements.destroy();
+
241  events.destroy();
+
242 
+
243  Print("\nLoad Mission: '%s'\n", filename);
+
244 
+
245  DataLoader* loader = DataLoader::GetLoader();
+
246  bool old_fs = loader->IsFileSystemEnabled();
+
247  BYTE* block = 0;
+
248 
+
249  loader->UseFileSystem(true);
+
250  loader->SetDataPath(path);
+
251  loader->LoadBuffer(filename, block, true);
+
252  loader->SetDataPath(0);
+
253  loader->UseFileSystem(old_fs);
+
254 
+
255  ok = ParseMission((const char*) block);
+
256 
+
257  loader->ReleaseBuffer(block);
+
258  Print("Mission Loaded.\n\n");
+
259 
+
260  if (ok)
+
261  Validate();
+
262 
+
263  return ok;
+
264 }
+
265 
+
266 // +--------------------------------------------------------------------+
+
267 
+
268 bool
+
269 Mission::ParseMission(const char* block)
+
270 {
+
271  Parser parser(new(__FILE__,__LINE__) BlockReader(block));
+
272  Term* term = parser.ParseTerm();
+
273  char err[256];
+
274 
+
275  if (!term) {
+
276  sprintf_s(err, "ERROR: could not parse '%s'\n", filename);
+
277  AddError(err);
+
278  return ok;
+
279  }
+
280  else {
+
281  TermText* file_type = term->isText();
+
282  if (!file_type || file_type->value() != "MISSION") {
+
283  sprintf_s(err, "ERROR: invalid mission file '%s'\n", filename);
+
284  AddError(err);
+
285  term->print(10);
+
286  return ok;
+
287  }
+
288  }
+
289 
+
290  ok = true;
+
291 
+
292  char target_name[256];
+
293  char ward_name[256];
+
294 
+
295  target_name[0] = 0;
+
296  ward_name[0] = 0;
+
297 
+
298  do {
+
299  delete term; term = 0;
+
300  term = parser.ParseTerm();
+
301 
+
302  if (term) {
+
303  TermDef* def = term->isDef();
+
304  if (def) {
+
305  Text defname = def->name()->value();
+
306  defname.setSensitive(false);
+
307 
+
308  if (defname == "name") {
+
309  GetDefText(name, def, filename);
+ +
311  }
+
312 
+
313  else if (defname == "desc") {
+
314  GetDefText(desc, def, filename);
+
315  if (desc.length() > 0 && desc.length() < 32)
+ +
317  }
+
318 
+
319  else if (defname == "type") {
+
320  char typestr[64];
+
321  GetDefText(typestr, def, filename);
+
322  type = TypeFromName(typestr);
+
323  }
+
324 
+
325  else if (defname == "system") {
+
326  char sysname[64];
+
327  GetDefText(sysname, def, filename);
+
328 
+
329  Galaxy* galaxy = Galaxy::GetInstance();
+
330 
+
331  if (galaxy) {
+
332  SetStarSystem(galaxy->GetSystem(sysname));
+
333  }
+
334  }
+
335 
+
336  else if (defname == "degrees")
+
337  GetDefBool(degrees, def, filename);
+
338 
+
339  else if (defname == "region")
+
340  GetDefText(region, def, filename);
+
341 
+
342  else if (defname == "objective") {
+ +
344  if (objective.length() > 0 && objective.length() < 32)
+ +
346  }
+
347 
+
348  else if (defname == "sitrep") {
+
349  GetDefText(sitrep, def, filename);
+
350  if (sitrep.length() > 0 && sitrep.length() < 32)
+ +
352  }
+
353 
+
354  else if (defname == "subtitles") {
+
355  Text subtitles_path;
+
356  DataLoader* loader = DataLoader::GetLoader();
+
357  BYTE* block = 0;
+
358 
+
359  GetDefText(subtitles_path, def, filename);
+
360  loader->SetDataPath(0);
+
361  loader->LoadBuffer(subtitles_path, block, true);
+
362 
+
363  subtitles = Text("\n") + (const char*) block;
+
364 
+
365  loader->ReleaseBuffer(block);
+
366  }
+
367 
+
368  else if (defname == "start")
+
369  GetDefTime(start, def, filename);
+
370 
+
371  else if (defname == "stardate")
+ +
373 
+
374  else if (defname == "team")
+
375  GetDefNumber(team, def, filename);
+
376 
+
377  else if (defname == "target")
+
378  GetDefText(target_name, def, filename);
+
379 
+
380  else if (defname == "ward")
+
381  GetDefText(ward_name, def, filename);
+
382 
+
383  else if ((defname == "element") ||
+
384  (defname == "ship") ||
+
385  (defname == "station")) {
+
386 
+
387  if (!def->term() || !def->term()->isStruct()) {
+
388  sprintf_s(err, "ERROR: element struct missing in '%s'\n", filename);
+
389  AddError(err);
+
390  }
+
391  else {
+
392  TermStruct* val = def->term()->isStruct();
+
393  MissionElement* elem = ParseElement(val);
+
394  AddElement(elem);
+
395  }
+
396  }
+
397 
+
398  else if (defname == "event") {
+
399  if (!def->term() || !def->term()->isStruct()) {
+
400  sprintf_s(err, "ERROR: event struct missing in '%s'\n", filename);
+
401  AddError(err);
+
402  }
+
403  else {
+
404  TermStruct* val = def->term()->isStruct();
+
405  MissionEvent* event = ParseEvent(val);
+
406  AddEvent(event);
+
407  }
+
408  }
+
409  } // def
+
410  } // term
+
411  }
+
412  while (term);
+
413 
+
414  if (ok) {
+
415  if (target_name[0])
+
416  target = FindElement(target_name);
+
417 
+
418  if (ward_name[0])
+
419  ward = FindElement(ward_name);
+
420  }
+
421 
+
422  return ok;
+
423 }
+
424 
+
425 // +--------------------------------------------------------------------+
+
426 
+
427 bool
+ +
429 {
+
430  Validate();
+
431 
+
432  if (!filename[0] || !path[0]) {
+
433  AddError(Game::GetText("Mission.error.no-file"));
+
434  return ok;
+
435  }
+
436 
+
437  Text content = Serialize();
+
438 
+
439  if (content.length() < 8) {
+
440  AddError(Game::GetText("Mission.error.no-serial"));
+
441  return ok;
+
442  }
+
443 
+
444  if (!_stricmp(path, "mods/missions/")) {
+
445  CreateDirectory("Mods", 0);
+
446  CreateDirectory("Mods/Missions", 0);
+
447  }
+
448 
+
449  else if (!_stricmp(path, "multiplayer/")) {
+
450  CreateDirectory("Multiplayer", 0);
+
451  }
+
452 
+
453  char fname[256];
+
454  sprintf_s(fname, "%s%s", path, filename);
+
455  FILE* f;
+
456  fopen_s(&f, fname, "w");
+
457  if (f) {
+
458  fwrite(content.data(), content.length(), 1, f);
+
459  fclose(f);
+
460  }
+
461 
+
462  return ok;
+
463 }
+
464 
+
465 // +--------------------------------------------------------------------+
+
466 
+
467 void
+ +
469 {
+
470  char err[256];
+
471 
+
472  ok = true;
+
473 
+
474  if (elements.isEmpty()) {
+
475  sprintf_s(err, Game::GetText("Mission.error.no-elem").data(), filename);
+
476  AddError(err);
+
477  }
+
478  else {
+
479  bool found_player = false;
+
480 
+
481  for (int i = 0; i < elements.size(); i++) {
+
482  MissionElement* elem = elements.at(i);
+
483 
+
484  if (elem->Name().length() < 1) {
+
485  sprintf_s(err, Game::GetText("Mission.error.unnamed-elem").data(), filename);
+
486  AddError(err);
+
487  }
+
488 
+
489  if (elem->Player() > 0) {
+
490  if (!found_player) {
+
491  found_player = true;
+
492 
+
493  if (elem->Region() != GetRegion()) {
+
494  sprintf_s(err, Game::GetText("Mission.error.wrong-sector").data(),
+
495  elem->Name().data(),
+
496  GetRegion());
+
497  AddError(err);
+
498  }
+
499  }
+
500  else {
+
501  sprintf_s(err, Game::GetText("Mission.error.extra-player").data(),
+
502  elem->Name().data(),
+
503  filename);
+
504  AddError(err);
+
505  }
+
506  }
+
507  }
+
508 
+
509  if (!found_player) {
+
510  sprintf_s(err, Game::GetText("Mission.error.no-player").data(), filename);
+
511  AddError(err);
+
512  }
+
513  }
+
514 }
+
515 
+
516 void
+ +
518 {
+
519  ::Print(err);
+
520  errmsg += err;
+
521 
+
522  ok = false;
+
523 }
+
524 
+
525 // +--------------------------------------------------------------------+
+
526 
+
527 #define MSN_CHECK(x) if (!_stricmp(n, #x)) result = Mission::x;
+
528 
+
529 int
+
530 Mission::TypeFromName(const char* n)
+
531 {
+
532  int result = -1;
+
533 
+ +
535  else MSN_CHECK(SWEEP)
+
536  else MSN_CHECK(INTERCEPT)
+
537  else MSN_CHECK(AIR_PATROL)
+
538  else MSN_CHECK(AIR_SWEEP)
+ +
540  else MSN_CHECK(STRIKE)
+
541  else MSN_CHECK(ASSAULT)
+
542  else MSN_CHECK(DEFEND)
+
543  else MSN_CHECK(ESCORT)
+ + + +
547  else MSN_CHECK(INTEL)
+
548  else MSN_CHECK(SCOUT)
+
549  else MSN_CHECK(RECON)
+
550  else MSN_CHECK(BLOCKADE)
+
551  else MSN_CHECK(FLEET)
+
552  else MSN_CHECK(BOMBARDMENT)
+
553  else MSN_CHECK(FLIGHT_OPS)
+
554  else MSN_CHECK(TRANSPORT)
+
555  else MSN_CHECK(CARGO)
+
556  else MSN_CHECK(TRAINING)
+
557  else MSN_CHECK(OTHER)
+
558 
+
559  if (result < PATROL) {
+
560  for (int i = PATROL; i <= OTHER && result < PATROL; i++) {
+
561  if (!_stricmp(n, RoleName(i))) {
+
562  result = i;
+
563  }
+
564  }
+
565  }
+
566 
+
567  return result;
+
568 }
+
569 
+
570 // +--------------------------------------------------------------------+
+
571 
+
572 static int elem_id = 351;
+
573 
+ + +
576 {
+
577  Text design;
+
578  Text skin_name;
+
579  Text role_name;
+
580  int deck = 1;
+
581  char err[256];
+
582 
+
583  MissionElement* element = new(__FILE__,__LINE__) MissionElement();
+
584  element->rgn_name = region;
+
585  element->elem_id = elem_id++;
+
586 
+
587  current = element;
+
588 
+
589  for (int i = 0; i < val->elements()->size(); i++) {
+
590  TermDef* pdef = val->elements()->at(i)->isDef();
+
591  if (pdef) {
+
592  Text defname = pdef->name()->value();
+
593  defname.setSensitive(false);
+
594 
+
595  if (defname == "name")
+
596  GetDefText(element->name, pdef, filename);
+
597 
+
598  else if (defname == "carrier")
+
599  GetDefText(element->carrier, pdef, filename);
+
600 
+
601  else if (defname == "commander")
+
602  GetDefText(element->commander, pdef, filename);
+
603 
+
604  else if (defname == "squadron")
+
605  GetDefText(element->squadron, pdef, filename);
+
606 
+
607  else if (defname == "path")
+
608  GetDefText(element->path, pdef, filename);
+
609 
+
610  else if (defname == "design") {
+
611  GetDefText(design, pdef, filename);
+
612  element->design = ShipDesign::Get(design, element->path);
+
613 
+
614  if (!element->design) {
+
615  sprintf_s(err, Game::GetText("Mission.error.unknown-ship").data(), design.data(), filename);
+
616  AddError(err);
+
617  }
+
618  }
+
619 
+
620  else if (defname == "skin") {
+
621  if (!element->design) {
+
622  sprintf_s(err, Game::GetText("Mission.error.out-of-order").data(), filename);
+
623  AddError(err);
+
624  }
+
625 
+
626  else if (pdef->term()->isText()) {
+
627  GetDefText(skin_name, pdef, filename);
+
628  element->skin = element->design->FindSkin(skin_name);
+
629  }
+
630 
+
631  else if (pdef->term()->isStruct()) {
+
632  sprintf_s(err, Game::GetText("Mission.error.bad-skin").data(), filename);
+
633  AddError(err);
+
634  }
+
635  }
+
636 
+
637  else if (defname == "mission") {
+
638  GetDefText(role_name, pdef, filename);
+
639  element->mission_role = TypeFromName(role_name);
+
640  }
+
641 
+
642  else if (defname == "intel") {
+
643  GetDefText(role_name, pdef, filename);
+
644  element->intel = Intel::IntelFromName(role_name);
+
645  }
+
646 
+
647  else if (defname == "loc") {
+
648  Vec3 loc;
+
649  GetDefVec(loc, pdef, filename);
+
650  element->SetLocation(loc);
+
651  }
+
652 
+
653  else if (defname == "rloc") {
+
654  if (pdef->term()->isStruct()) {
+
655  RLoc* rloc = ParseRLoc(pdef->term()->isStruct());
+
656  element->SetRLoc(*rloc);
+
657  delete rloc;
+
658  }
+
659  }
+
660 
+
661  else if (defname.indexOf("head") == 0) {
+
662  if (pdef->term()->isArray()) {
+
663  Vec3 head;
+
664  GetDefVec(head, pdef, filename);
+
665  if (degrees) head.z *= (float) DEGREES;
+
666  element->heading = head.z;
+
667  }
+
668  else if (pdef->term()->isNumber()) {
+
669  double heading = 0;
+
670  GetDefNumber(heading, pdef, filename);
+
671  if (degrees) heading *= DEGREES;
+
672  element->heading = heading;
+
673  }
+
674  }
+
675 
+
676  else if (defname == "region" || defname == "rgn")
+
677  GetDefText(element->rgn_name, pdef, filename);
+
678 
+
679  else if (defname == "iff")
+
680  GetDefNumber(element->IFF_code, pdef, filename);
+
681 
+
682  else if (defname == "count")
+
683  GetDefNumber(element->count, pdef, filename);
+
684 
+
685  else if (defname == "maint_count")
+
686  GetDefNumber(element->maint_count, pdef, filename);
+
687 
+
688  else if (defname == "dead_count")
+
689  GetDefNumber(element->dead_count, pdef, filename);
+
690 
+
691  else if (defname == "player")
+
692  GetDefNumber(element->player, pdef, filename);
+
693 
+
694  else if (defname == "alert")
+
695  GetDefBool(element->alert, pdef, filename);
+
696 
+
697  else if (defname == "playable")
+
698  GetDefBool(element->playable, pdef, filename);
+
699 
+
700  else if (defname == "rogue")
+
701  GetDefBool(element->rogue, pdef, filename);
+
702 
+
703  else if (defname == "invulnerable")
+
704  GetDefBool(element->invulnerable, pdef, filename);
+
705 
+
706  else if (defname == "command_ai")
+
707  GetDefNumber(element->command_ai, pdef, filename);
+
708 
+
709  else if (defname.indexOf("respawn") == 0)
+
710  GetDefNumber(element->respawns, pdef, filename);
+
711 
+
712  else if (defname.indexOf("hold") == 0)
+
713  GetDefNumber(element->hold_time, pdef, filename);
+
714 
+
715  else if (defname.indexOf("zone") == 0) {
+
716  if (pdef->term() && pdef->term()->isBool()) {
+
717  bool locked = false;
+
718  GetDefBool(locked, pdef, filename);
+
719  element->zone_lock = locked;
+
720  }
+
721  else {
+
722  GetDefNumber(element->zone_lock, pdef, filename);
+
723  }
+
724  }
+
725 
+
726  else if (defname == "objective") {
+
727  if (!pdef->term() || !pdef->term()->isStruct()) {
+
728  sprintf_s(err, Game::GetText("Mission.error.no-objective").data(), element->name.data(), filename);
+
729  AddError(err);
+
730  }
+
731  else {
+
732  TermStruct* val = pdef->term()->isStruct();
+
733  Instruction* obj = ParseInstruction(val, element);
+
734  element->objectives.append(obj);
+
735  }
+
736  }
+
737 
+
738  else if (defname == "instr") {
+
739  Text* obj = new(__FILE__,__LINE__) Text;
+
740  if (GetDefText(*obj, pdef, filename))
+
741  element->instructions.append(obj);
+
742  else
+
743  delete obj;
+
744  }
+
745 
+
746  else if (defname == "ship") {
+
747  if (!pdef->term() || !pdef->term()->isStruct()) {
+
748  sprintf_s(err, Game::GetText("Mission.error.no-ship").data(), element->name.data(), filename);
+
749  AddError(err);
+
750  }
+
751  else {
+
752  TermStruct* val = pdef->term()->isStruct();
+
753  MissionShip* s = ParseShip(val, element);
+
754  element->ships.append(s);
+
755 
+
756  if (s->Integrity() < 0 && element->design)
+
757  s->SetIntegrity(element->design->integrity);
+
758  }
+
759  }
+
760 
+
761  else if (defname == "order" || defname == "navpt") {
+
762  if (!pdef->term() || !pdef->term()->isStruct()) {
+
763  sprintf_s(err, Game::GetText("Mission.error.no-navpt").data(), element->name.data(), filename);
+
764  AddError(err);
+
765  }
+
766  else {
+
767  TermStruct* val = pdef->term()->isStruct();
+
768  Instruction* npt = ParseInstruction(val, element);
+
769  element->navlist.append(npt);
+
770  }
+
771  }
+
772 
+
773  else if (defname == "loadout") {
+
774  if (!pdef->term() || !pdef->term()->isStruct()) {
+
775  sprintf_s(err, Game::GetText("Mission.error.no-loadout").data(), element->name.data(), filename);
+
776  AddError(err);
+
777  }
+
778  else {
+
779  TermStruct* val = pdef->term()->isStruct();
+
780  ParseLoadout(val, element);
+
781  }
+
782  }
+
783  }
+
784  }
+
785 
+
786  if (element->name.length() < 1) {
+
787  sprintf_s(err, Game::GetText("Mission.error.unnamed-elem").data(), filename);
+
788  AddError(err);
+
789  }
+
790 
+
791  else if (element->design == 0) {
+
792  sprintf_s(err, Game::GetText("Mission.error.unknown-ship").data(), element->name.data(), filename);
+
793  AddError(err);
+
794  }
+
795 
+
796  current = 0;
+
797 
+
798  return element;
+
799 }
+
800 
+ + +
803 {
+
804  MissionEvent* event = new(__FILE__,__LINE__) MissionEvent;
+
805  Text event_name;
+
806  Text trigger_name;
+
807  static int event_id = 1;
+
808  static double event_time = 0;
+
809 
+
810  for (int i = 0; i < val->elements()->size(); i++) {
+
811  TermDef* pdef = val->elements()->at(i)->isDef();
+
812  if (pdef) {
+
813  Text defname = pdef->name()->value();
+
814  defname.setSensitive(false);
+
815 
+
816  if (defname == "event") {
+
817  GetDefText(event_name, pdef, filename);
+
818  event->event = MissionEvent::EventForName(event_name);
+
819  }
+
820 
+
821  else if (defname == "trigger") {
+
822  GetDefText(trigger_name, pdef, filename);
+
823  event->trigger = MissionEvent::TriggerForName(trigger_name);
+
824  }
+
825 
+
826  else if (defname == "id")
+
827  GetDefNumber(event_id, pdef, filename);
+
828 
+
829  else if (defname == "time")
+
830  GetDefNumber(event_time, pdef, filename);
+
831 
+
832  else if (defname == "delay")
+
833  GetDefNumber(event->delay, pdef, filename);
+
834 
+
835  else if (defname == "event_param" || defname == "param" || defname == "color") {
+
836  ZeroMemory(event->event_param, sizeof(event->event_param));
+
837 
+
838  if (pdef->term()->isNumber()) {
+
839  GetDefNumber(event->event_param[0], pdef, filename);
+
840  event->event_nparams = 1;
+
841  }
+
842 
+
843  else if (pdef->term()->isArray()) {
+
844  std::vector<float> plist;
+
845  GetDefArray(plist, pdef, filename);
+
846 
+
847  for (int i = 0; i < 10 && i < (int)plist.size(); i++) {
+
848  float f = plist[i];
+
849  event->event_param[i] = (int) f;
+
850  event->event_nparams = i + 1;
+
851  }
+
852  }
+
853  }
+
854 
+
855  else if (defname == "trigger_param") {
+
856  ZeroMemory(event->trigger_param, sizeof(event->trigger_param));
+
857 
+
858  if (pdef->term()->isNumber()) {
+
859  GetDefNumber(event->trigger_param[0], pdef, filename);
+
860  event->trigger_nparams = 1;
+
861  }
+
862 
+
863  else if (pdef->term()->isArray()) {
+
864  std::vector<float> plist;
+
865  GetDefArray(plist, pdef, filename);
+
866 
+
867  for (int i = 0; i < 10 && i < (int)plist.size(); i++) {
+
868  float f = plist[i];
+
869  event->trigger_param[i] = (int) f;
+
870  event->trigger_nparams = i + 1;
+
871  }
+
872  }
+
873  }
+
874 
+
875  else if (defname == "event_ship" || defname == "ship")
+
876  GetDefText(event->event_ship, pdef, filename);
+
877 
+
878  else if (defname == "event_source" || defname == "source" || defname == "font")
+
879  GetDefText(event->event_source, pdef, filename);
+
880 
+
881  else if (defname == "event_target" || defname == "target" || defname == "image")
+
882  GetDefText(event->event_target, pdef, filename);
+
883 
+
884  else if (defname == "event_message" || defname == "message") {
+
885  Text raw_msg;
+
886  GetDefText(raw_msg, pdef, filename);
+
887  raw_msg = Game::GetText(raw_msg);
+
888  event->event_message = FormatTextEscape(raw_msg);
+
889  }
+
890 
+
891  else if (defname == "event_chance" || defname == "chance")
+
892  GetDefNumber(event->event_chance, pdef, filename);
+
893 
+
894  else if (defname == "event_sound" || defname == "sound")
+
895  GetDefText(event->event_sound, pdef, filename);
+
896 
+
897  else if (defname == "loc" || defname == "vec" || defname == "fade")
+
898  GetDefVec(event->event_point, pdef, filename);
+
899 
+
900  else if (defname == "rect")
+
901  GetDefRect(event->event_rect, pdef, filename);
+
902 
+
903  else if (defname == "trigger_ship")
+
904  GetDefText(event->trigger_ship, pdef, filename);
+
905 
+
906  else if (defname == "trigger_target")
+
907  GetDefText(event->trigger_target, pdef, filename);
+
908  }
+
909  }
+
910 
+
911  event->id = event_id++;
+
912  event->time = event_time;
+
913  return event;
+
914 }
+
915 
+ + +
918 {
+
919  MissionShip* msn_ship = new(__FILE__,__LINE__) MissionShip;
+
920 
+
921  Text name;
+
922  Text skin_name;
+
923  Text regnum;
+
924  Text region;
+
925  char err[256];
+
926  Vec3 loc(-1.0e9f, -1.0e9f, -1.0e9f);
+
927  Vec3 vel(-1.0e9f, -1.0e9f, -1.0e9f);
+
928  int respawns = -1;
+
929  double heading = -1e9;
+
930  double integrity = -1;
+
931  int ammo[16];
+
932  int fuel[4];
+
933  int i;
+
934 
+
935  for (i = 0; i < 16; i++)
+
936  ammo[i] = -10;
+
937 
+
938  for (i = 0; i < 4; i++)
+
939  fuel[i] = -10;
+
940 
+
941  for (i = 0; i < val->elements()->size(); i++) {
+
942  TermDef* pdef = val->elements()->at(i)->isDef();
+
943  if (pdef) {
+
944  Text defname = pdef->name()->value();
+
945  defname.setSensitive(false);
+
946 
+
947  if (defname == "name")
+
948  GetDefText(name, pdef, filename);
+
949 
+
950  else if (defname == "skin") {
+
951  if (!element || !element->design) {
+
952  sprintf_s(err, Game::GetText("Mission.error.out-of-order").data(), filename);
+
953  AddError(err);
+
954  }
+
955 
+
956  else if (pdef->term()->isText()) {
+
957  GetDefText(skin_name, pdef, filename);
+
958  msn_ship->skin = element->design->FindSkin(skin_name);
+
959  }
+
960 
+
961  else if (pdef->term()->isStruct()) {
+
962  sprintf_s(err, Game::GetText("Mission.error.bad-skin").data(), filename);
+
963  AddError(err);
+
964  }
+
965  }
+
966 
+
967  else if (defname == "regnum")
+
968  GetDefText(regnum, pdef, filename);
+
969 
+
970  else if (defname == "region")
+
971  GetDefText(region, pdef, filename);
+
972 
+
973  else if (defname == "loc")
+
974  GetDefVec(loc, pdef, filename);
+
975 
+
976  else if (defname == "velocity")
+
977  GetDefVec(vel, pdef, filename);
+
978 
+
979  else if (defname == "respawns")
+
980  GetDefNumber(respawns, pdef, filename);
+
981 
+
982  else if (defname == "heading") {
+
983  if (pdef->term()->isArray()) {
+
984  Vec3 h;
+
985  GetDefVec(h, pdef, filename);
+
986  if (degrees) h.z *= (float) DEGREES;
+
987  heading = h.z;
+
988  }
+
989  else if (pdef->term()->isNumber()) {
+
990  double h = 0;
+
991  GetDefNumber(h, pdef, filename);
+
992  if (degrees) h *= DEGREES;
+
993  heading = h;
+
994  }
+
995  }
+
996 
+
997  else if (defname == "integrity")
+
998  GetDefNumber(integrity, pdef, filename);
+
999 
+
1000  else if (defname == "ammo")
+
1001  GetDefArray(ammo, 16, pdef, filename);
+
1002 
+
1003  else if (defname == "fuel")
+
1004  GetDefArray(fuel, 4, pdef, filename);
+
1005  }
+
1006  }
+
1007 
+
1008  msn_ship->SetName(name);
+
1009  msn_ship->SetRegNum(regnum);
+
1010  msn_ship->SetRegion(region);
+
1011  msn_ship->SetIntegrity(integrity);
+
1012 
+
1013  if (loc.x > -1e9)
+
1014  msn_ship->SetLocation(loc);
+
1015 
+
1016  if (vel.x > -1e9)
+
1017  msn_ship->SetVelocity(vel);
+
1018 
+
1019  if (respawns > -1)
+
1020  msn_ship->SetRespawns(respawns);
+
1021 
+
1022  if (heading > -1e9)
+
1023  msn_ship->SetHeading(heading);
+
1024 
+
1025  if (ammo[0] > -10)
+
1026  msn_ship->SetAmmo(ammo);
+
1027 
+
1028  if (fuel[0] > -10)
+
1029  msn_ship->SetFuel(fuel);
+
1030 
+
1031  return msn_ship;
+
1032 }
+
1033 
+
1034 Instruction*
+ +
1036 {
+
1037  int order = Instruction::VECTOR;
+
1038  int status = Instruction::PENDING;
+
1039  int formation = 0;
+
1040  int speed = 0;
+
1041  int priority = 1;
+
1042  int farcast = 0;
+
1043  int hold = 0;
+
1044  int emcon = 0;
+
1045  Vec3 loc(0,0,0);
+
1046  RLoc* rloc = 0;
+
1047  Text order_name;
+
1048  Text status_name;
+
1049  Text order_rgn_name;
+
1050  Text tgt_name;
+
1051  Text tgt_desc;
+
1052 
+
1053  for (int i = 0; i < val->elements()->size(); i++) {
+
1054  TermDef* pdef = val->elements()->at(i)->isDef();
+
1055  if (pdef) {
+
1056  Text defname = pdef->name()->value();
+
1057  defname.setSensitive(false);
+
1058 
+
1059  if (defname == "cmd") {
+
1060  GetDefText(order_name, pdef, filename);
+
1061 
+
1062  for (int cmd = 0; cmd < Instruction::NUM_ACTIONS; cmd++)
+
1063  if (!_stricmp(order_name, Instruction::ActionName(cmd)))
+
1064  order = cmd;
+
1065  }
+
1066 
+
1067  else if (defname == "status") {
+
1068  GetDefText(status_name, pdef, filename);
+
1069 
+
1070  for (int n = 0; n < Instruction::NUM_STATUS; n++)
+
1071  if (!_stricmp(status_name, Instruction::StatusName(n)))
+
1072  status = n;
+
1073  }
+
1074 
+
1075  else if (defname == "loc") {
+
1076  GetDefVec(loc, pdef, filename);
+
1077  }
+
1078 
+
1079  else if (defname == "rloc") {
+
1080  if (pdef->term()->isStruct())
+
1081  rloc = ParseRLoc(pdef->term()->isStruct());
+
1082  }
+
1083 
+
1084  else if (defname == "rgn") {
+
1085  GetDefText(order_rgn_name, pdef, filename);
+
1086  }
+
1087  else if (defname == "speed") {
+
1088  GetDefNumber(speed, pdef, filename);
+
1089  }
+
1090  else if (defname == "formation") {
+
1091  GetDefNumber(formation, pdef, filename);
+
1092  }
+
1093  else if (defname == "emcon") {
+
1094  GetDefNumber(emcon, pdef, filename);
+
1095  }
+
1096  else if (defname == "priority") {
+
1097  GetDefNumber(priority, pdef, filename);
+
1098  }
+
1099  else if (defname == "farcast") {
+
1100  if (pdef->term()->isBool()) {
+
1101  bool f = false;
+
1102  GetDefBool(f, pdef, filename);
+
1103  farcast = f;
+
1104  }
+
1105  else {
+
1106  GetDefNumber(farcast, pdef, filename);
+
1107  }
+
1108  }
+
1109  else if (defname == "tgt") {
+
1110  GetDefText(tgt_name, pdef, filename);
+
1111  }
+
1112  else if (defname == "tgt_desc") {
+
1113  GetDefText(tgt_desc, pdef, filename);
+
1114  }
+
1115  else if (defname.indexOf("hold") == 0) {
+
1116  GetDefNumber(hold, pdef, filename);
+
1117  }
+
1118  }
+
1119  }
+
1120 
+
1121  Text rgn;
+
1122 
+
1123  if (order_rgn_name.length() > 0)
+
1124  rgn = order_rgn_name;
+
1125 
+
1126  else if (element->navlist.size() > 0)
+
1127  rgn = element->navlist[element->navlist.size()-1]->RegionName();
+
1128 
+
1129  else
+
1130  rgn = region;
+
1131 
+
1132  if (tgt_desc.length() && tgt_name.length())
+
1133  tgt_desc = tgt_desc + " " + tgt_name;
+
1134 
+
1135  Instruction* instr = new(__FILE__,__LINE__) Instruction(rgn, loc, order);
+
1136 
+
1137  instr->SetStatus(status);
+
1138  instr->SetEMCON(emcon);
+
1139  instr->SetFormation(formation);
+
1140  instr->SetSpeed(speed);
+
1141  instr->SetTarget(tgt_name);
+
1142  instr->SetTargetDesc(tgt_desc);
+
1143  instr->SetPriority(priority-1);
+
1144  instr->SetFarcast(farcast);
+
1145  instr->SetHoldTime(hold);
+
1146 
+
1147  if (rloc) {
+
1148  instr->GetRLoc() = *rloc;
+
1149  delete rloc;
+
1150  }
+
1151 
+
1152  return instr;
+
1153 }
+
1154 
+
1155 void
+ +
1157 {
+
1158  int ship = -1;
+
1159  int stations[16];
+
1160  Text name;
+
1161 
+
1162  ZeroMemory(stations, sizeof(stations));
+
1163 
+
1164  for (int i = 0; i < val->elements()->size(); i++) {
+
1165  TermDef* pdef = val->elements()->at(i)->isDef();
+
1166  if (pdef) {
+
1167  Text defname = pdef->name()->value();
+
1168  defname.setSensitive(false);
+
1169 
+
1170  if (defname == "ship") {
+
1171  GetDefNumber(ship, pdef, filename);
+
1172  }
+
1173  else if (defname == "name") {
+
1174  GetDefText(name, pdef, filename);
+
1175  }
+
1176  else if (defname == "stations") {
+
1177  GetDefArray(stations, 16, pdef, filename);
+
1178  }
+
1179  }
+
1180  }
+
1181 
+
1182  MissionLoad* load = new(__FILE__,__LINE__) MissionLoad(ship);
+
1183 
+
1184  if (name.length())
+
1185  load->SetName(name);
+
1186 
+
1187  for (int i = 0; i < 16; i++)
+
1188  load->SetStation(i, stations[i]);
+
1189 
+
1190  element->loadouts.append(load);
+
1191 }
+
1192 
+
1193 RLoc*
+ +
1195 {
+
1196  Vec3 base_loc;
+
1197  RLoc* rloc = new(__FILE__,__LINE__) RLoc;
+
1198  RLoc* ref = 0;
+
1199 
+
1200  double dex = 0;
+
1201  double dex_var = 5e3;
+
1202  double az = 0;
+
1203  double az_var = 3.1415;
+
1204  double el = 0;
+
1205  double el_var = 0.1;
+
1206 
+
1207  for (int i = 0; i < val->elements()->size(); i++) {
+
1208  TermDef* pdef = val->elements()->at(i)->isDef();
+
1209  if (pdef) {
+
1210  Text defname = pdef->name()->value();
+
1211  defname.setSensitive(false);
+
1212 
+
1213  if (defname == "dex") {
+
1214  GetDefNumber(dex, pdef, filename);
+
1215  rloc->SetDistance(dex);
+
1216  }
+
1217  else if (defname == "dex_var") {
+
1218  GetDefNumber(dex_var, pdef, filename);
+
1219  rloc->SetDistanceVar(dex_var);
+
1220  }
+
1221  else if (defname == "az") {
+
1222  GetDefNumber(az, pdef, filename);
+
1223  if (degrees) az *= DEGREES;
+
1224  rloc->SetAzimuth(az);
+
1225  }
+
1226  else if (defname == "az_var") {
+
1227  GetDefNumber(az_var, pdef, filename);
+
1228  if (degrees) az_var *= DEGREES;
+
1229  rloc->SetAzimuthVar(az_var);
+
1230  }
+
1231  else if (defname == "el") {
+
1232  GetDefNumber(el, pdef, filename);
+
1233  if (degrees) el *= DEGREES;
+
1234  rloc->SetElevation(el);
+
1235  }
+
1236  else if (defname == "el_var") {
+
1237  GetDefNumber(el_var, pdef, filename);
+
1238  if (degrees) el_var *= DEGREES;
+
1239  rloc->SetElevationVar(el_var);
+
1240  }
+
1241  else if (defname == "loc") {
+
1242  GetDefVec(base_loc, pdef, filename);
+
1243  rloc->SetBaseLocation(base_loc);
+
1244  }
+
1245 
+
1246  else if (defname == "ref") {
+
1247  Text refstr;
+
1248  GetDefText(refstr, pdef, filename);
+
1249 
+
1250  int sep = refstr.indexOf(':');
+
1251 
+
1252  if (sep >= 0) {
+
1253  Text elem_name = refstr.substring(0, sep);
+
1254  Text nav_name = refstr.substring(sep+1, refstr.length());
+
1255  MissionElement* elem = 0;
+
1256 
+
1257  if (elem_name == "this")
+
1258  elem = current;
+
1259  else
+
1260  elem = FindElement(elem_name);
+
1261 
+
1262  if (elem && elem->NavList().size() > 0) {
+
1263  int index = atoi(nav_name)-1;
+
1264  if (index < 0)
+
1265  index = 0;
+
1266  else if (index >= elem->NavList().size())
+
1267  index = elem->NavList().size()-1;
+
1268 
+
1269  ref = &elem->NavList()[index]->GetRLoc();
+
1270  rloc->SetReferenceLoc(ref);
+
1271  }
+
1272  else {
+
1273  ::Print("Warning: no ref found for rloc '%s' in elem '%s'\n", refstr.data(), current->Name().data());
+
1274  rloc->SetBaseLocation(RandomPoint());
+
1275  }
+
1276  }
+
1277  else {
+
1278  MissionElement* elem = 0;
+
1279 
+
1280  if (refstr == "this")
+
1281  elem = current;
+
1282  else
+
1283  elem = FindElement(refstr);
+
1284 
+
1285  if (elem) {
+
1286  ref = &elem->GetRLoc();
+
1287  rloc->SetReferenceLoc(ref);
+
1288  }
+
1289  else {
+
1290  ::Print("Warning: no ref found for rloc '%s' in elem '%s'\n", refstr.data(), current->Name().data());
+
1291  rloc->SetBaseLocation(RandomPoint());
+
1292  }
+
1293  }
+
1294  }
+
1295  }
+
1296  }
+
1297 
+
1298  return rloc;
+
1299 }
+
1300 
+
1301 const char*
+ +
1303 {
+
1304  switch (role) {
+
1305  case PATROL: return "Patrol";
+
1306  case SWEEP: return "Sweep";
+
1307  case INTERCEPT: return "Intercept";
+
1308  case AIR_PATROL: return "Airborne Patrol";
+
1309  case AIR_SWEEP: return "Airborne Sweep";
+
1310  case AIR_INTERCEPT: return "Airborne Intercept";
+
1311  case STRIKE: return "Strike";
+
1312  case ASSAULT: return "Assault";
+
1313  case DEFEND: return "Defend";
+
1314  case ESCORT: return "Escort";
+
1315  case ESCORT_FREIGHT: return "Freight Escort";
+
1316  case ESCORT_SHUTTLE: return "Shuttle Escort";
+
1317  case ESCORT_STRIKE: return "Strike Escort";
+
1318  case INTEL: return "Intel";
+
1319  case SCOUT: return "Scout";
+
1320  case RECON: return "Recon";
+
1321  case BLOCKADE: return "Blockade";
+
1322  case FLEET: return "Fleet";
+
1323  case BOMBARDMENT: return "Attack";
+
1324  case FLIGHT_OPS: return "Flight Ops";
+
1325  case TRANSPORT: return "Transport";
+
1326  case CARGO: return "Cargo";
+
1327  case TRAINING: return "Training";
+
1328  default:
+
1329  case OTHER: return "Misc";
+
1330  }
+
1331 }
+
1332 
+
1333 // +--------------------------------------------------------------------+
+
1334 
+
1335 Text
+
1336 Mission::Serialize(const char* player_elem, int player_index)
+
1337 {
+
1338  Text s = "MISSION\n\nname: \"";
+
1339  s += SafeString(Name());
+
1340 
+
1341  if (desc.length()) {
+
1342  s += "\"\ndesc: \"";
+
1343  s += SafeString(desc);
+
1344  }
+
1345 
+
1346  s += "\"\ntype: \"";
+
1347  s += SafeString(TypeName());
+
1348 
+
1349  ListIter<StarSystem> sys_iter = system_list;
+
1350  while (++sys_iter) {
+
1351  StarSystem* sys = sys_iter.value();
+
1352 
+
1353  if (sys != star_system) {
+
1354  s += "\"\nsystem: \"";
+
1355  s += sys->Name();
+
1356  }
+
1357  }
+
1358 
+
1359  s += "\"\nsystem: \"";
+
1360  if (GetStarSystem())
+
1361  s += SafeString(GetStarSystem()->Name());
+
1362  else
+
1363  s += "null";
+
1364 
+ +
1366 
+
1367  Sim* sim = Sim::GetSim();
+
1368  if (sim && sim->GetElements().size() > 0)
+
1369  iter = sim->GetMissionElements();
+
1370 
+
1371  s += "\"\n";
+
1372 
+
1373  bool region_set = false;
+
1374  if (player_elem && *player_elem) {
+
1375  // set the mission region to that of the active player
+
1376  while (++iter) {
+
1377  MissionElement* e = iter.value();
+
1378  if (e->Name() == player_elem) {
+
1379  char buf[32];
+
1380  sprintf_s(buf, "team: %d\n", e->GetIFF());
+
1381  s += buf;
+
1382 
+
1383  s += "region: \"";
+
1384  s += SafeString(e->Region());
+
1385  s += "\"\n\n";
+
1386 
+
1387  region_set = true;
+
1388  break;
+
1389  }
+
1390  }
+
1391 
+
1392  iter.reset();
+
1393  }
+
1394 
+
1395  if (!region_set) {
+
1396  s += "region: \"";
+
1397  s += SafeString(GetRegion());
+
1398  s += "\"\n\n";
+
1399  }
+
1400 
+
1401  if (Objective() && *Objective()) {
+
1402  s += "objective: \"";
+
1403  s += SafeString(Objective());
+
1404  s += "\"\n\n";
+
1405  }
+
1406 
+
1407  if (Situation() && *Situation()) {
+
1408  s += "sitrep: \"";
+
1409  s += SafeString(Situation());
+
1410  s += "\"\n\n";
+
1411  }
+
1412 
+
1413  char buffer[256];
+
1414  FormatTime(buffer, Start());
+
1415 
+
1416  s += "start: \"";
+
1417  s += buffer;
+
1418  s += "\"\n\n";
+
1419  s += "degrees: true\n\n";
+
1420 
+
1421  while (++iter) {
+
1422  MissionElement* elem = iter.value();
+
1423 
+
1424  s += "element: {\n";
+
1425  s += " name: \"";
+
1426  s += SafeString(elem->Name());
+
1427  s += "\"\n";
+
1428 
+
1429  if (elem->Path().length()) {
+
1430  s += " path: \"";
+
1431  s += SafeString(elem->Path());
+
1432  s += "\"\n";
+
1433  }
+
1434 
+
1435  if (elem->GetDesign()) {
+
1436  s += " design: \"";
+
1437  s += SafeString(elem->GetDesign()->name);
+
1438  s += "\"\n";
+
1439  }
+
1440 
+
1441  if (elem->GetSkin()) {
+
1442  s += " skin: \"";
+
1443  s += SafeString(elem->GetSkin()->Name());
+
1444  s += "\"\n";
+
1445  }
+
1446 
+
1447  if (elem->Squadron().length()) {
+
1448  s += " squadron: \"";
+
1449  s += SafeString(elem->Squadron());
+
1450  s += "\"\n";
+
1451  }
+
1452 
+
1453  if (elem->Carrier().length()) {
+
1454  s += " carrier: \"";
+
1455  s += SafeString(elem->Carrier());
+
1456  s += "\"\n";
+
1457  }
+
1458 
+
1459  if (elem->Commander().length()) {
+
1460  s += " commander: \"";
+
1461  s += SafeString(elem->Commander());
+
1462  s += "\"\n";
+
1463  }
+
1464 
+
1465  s += " mission: \"";
+
1466  s += elem->RoleName();
+
1467  s += "\"\n\n";
+
1468 
+
1469  if (elem->IntelLevel()) {
+
1470  s += " intel: \"";
+
1471  s += Intel::NameFromIntel(elem->IntelLevel());
+
1472  s += "\"\n";
+
1473  }
+
1474 
+
1475  sprintf_s(buffer, " count: %d\n", elem->Count());
+
1476  s += buffer;
+
1477 
+
1478  if (elem->MaintCount()) {
+
1479  sprintf_s(buffer, " maint_count: %d\n", elem->MaintCount());
+
1480  s += buffer;
+
1481  }
+
1482 
+
1483  if (elem->DeadCount()) {
+
1484  sprintf_s(buffer, " dead_count: %d\n", elem->DeadCount());
+
1485  s += buffer;
+
1486  }
+
1487 
+
1488  if (elem->RespawnCount()) {
+
1489  sprintf_s(buffer, " respawn_count: %d\n", elem->RespawnCount());
+
1490  s += buffer;
+
1491  }
+
1492 
+
1493  if (elem->HoldTime()) {
+
1494  sprintf_s(buffer, " hold_time: %d\n", elem->HoldTime());
+
1495  s += buffer;
+
1496  }
+
1497 
+
1498  if (elem->ZoneLock()) {
+
1499  sprintf_s(buffer, " zone_lock: %d\n", elem->ZoneLock());
+
1500  s += buffer;
+
1501  }
+
1502 
+
1503  if (elem->IsAlert()) {
+
1504  s += " alert: true\n";
+
1505  }
+
1506 
+
1507  if (!elem->IsSquadron()) {
+
1508  sprintf_s(buffer, " command_ai:%d\n", elem->CommandAI());
+
1509  s += buffer;
+
1510  }
+
1511 
+
1512  sprintf_s(buffer, " iff: %d\n", elem->GetIFF());
+
1513  s += buffer;
+
1514 
+
1515  if (player_elem) {
+
1516  if (elem->Name() == player_elem) {
+
1517  if (player_index < 1)
+
1518  player_index = 1;
+
1519 
+
1520  sprintf_s(buffer, " player: %d\n", player_index);
+
1521  s += buffer;
+
1522  }
+
1523  }
+
1524 
+
1525  else {
+
1526  if (elem->Player()) {
+
1527  sprintf_s(buffer, " player: %d\n", elem->Player());
+
1528  s += buffer;
+
1529  }
+
1530  }
+
1531 
+
1532  if (!elem->IsSquadron()) {
+
1533  if (elem->IsPlayable())
+
1534  s += " playable: true\n";
+
1535  else
+
1536  s += " playable: false\n";
+
1537  }
+
1538 
+
1539 
+
1540  s += " region: \"";
+
1541  s += elem->Region();
+
1542  s += "\"\n";
+
1543 
+
1544  sprintf_s(buffer, " loc: (%.0f, %.0f, %.0f)\n",
+
1545  elem->Location().x,
+
1546  elem->Location().y,
+
1547  elem->Location().z);
+
1548  s += buffer;
+
1549 
+
1550  if (elem->Heading() != 0) {
+
1551  sprintf_s(buffer, " head: %d\n", (int) (elem->Heading()/DEGREES));
+
1552  s += buffer;
+
1553  }
+
1554 
+
1555  if (elem->Loadouts().size()) {
+
1556  s += "\n";
+
1557 
+
1558  ListIter<MissionLoad> load_iter = elem->Loadouts();
+
1559  while (++load_iter) {
+
1560  MissionLoad* load = load_iter.value();
+
1561 
+
1562  sprintf_s(buffer, " loadout: { ship: %d, ", load->GetShip());
+
1563  s += buffer;
+
1564 
+
1565  if (load->GetName().length()) {
+
1566  s += "name: \"";
+
1567  s += SafeString(load->GetName());
+
1568  s += "\" }\n";
+
1569  }
+
1570  else {
+
1571  s += "stations: (";
+
1572 
+
1573  for (int i = 0; i < 16; i++) {
+
1574  sprintf_s(buffer, "%d", load->GetStation(i));
+
1575  s += buffer;
+
1576 
+
1577  if (i < 15)
+
1578  s += ", ";
+
1579  }
+
1580 
+
1581  s += ") }\n";
+
1582  }
+
1583  }
+
1584  }
+
1585 
+
1586  if (elem->Objectives().size()) {
+
1587  s += "\n";
+
1588 
+
1589  ListIter<Instruction> obj_iter = elem->Objectives();
+
1590  while (++obj_iter) {
+
1591  Instruction* inst = obj_iter.value();
+
1592 
+
1593  s += " objective: { cmd: ";
+
1594  s += Instruction::ActionName(inst->Action());
+
1595  s += ", tgt: \"";
+
1596  s += SafeString(inst->TargetName());
+
1597  s += "\" }\n";
+
1598  }
+
1599  }
+
1600 
+
1601  if (elem->NavList().size()) {
+
1602  s += "\n";
+
1603 
+
1604  ListIter<Instruction> nav_iter = elem->NavList();
+
1605  while (++nav_iter) {
+
1606  Instruction* inst = nav_iter.value();
+
1607 
+
1608  s += " navpt: { cmd: ";
+
1609  s += Instruction::ActionName(inst->Action());
+
1610  s += ", status: ";
+
1611  s += Instruction::StatusName(inst->Status());
+
1612 
+
1613  if (inst->TargetName() && *inst->TargetName()) {
+
1614  s += ", tgt: \"";
+
1615  s += SafeString(inst->TargetName());
+
1616  s += "\"";
+
1617  }
+
1618 
+
1619  sprintf_s(buffer, ", loc: (%.0f, %.0f, %.0f), speed: %d",
+
1620  inst->Location().x,
+
1621  inst->Location().y,
+
1622  inst->Location().z,
+
1623  inst->Speed());
+
1624  s += buffer;
+
1625 
+
1626  if (inst->RegionName() && *inst->RegionName()) {
+
1627  s += ", rgn: \"";
+
1628  s += inst->RegionName();
+
1629  s += "\"";
+
1630  }
+
1631 
+
1632  if (inst->HoldTime()) {
+
1633  sprintf_s(buffer, ", hold: %d", (int) inst->HoldTime());
+
1634  s += buffer;
+
1635  }
+
1636 
+
1637  if (inst->Farcast()) {
+
1638  s += ", farcast: true";
+
1639  }
+
1640 
+
1641  if (inst->Formation() > Instruction::DIAMOND) {
+
1642  sprintf_s(buffer, ", formation: %d", (int) inst->Formation());
+
1643  s += buffer;
+
1644  }
+
1645 
+
1646  if (inst->Priority() > Instruction::PRIMARY) {
+
1647  sprintf_s(buffer, ", priority: %d", (int) inst->Priority());
+
1648  s += buffer;
+
1649  }
+
1650 
+
1651  s += " }\n";
+
1652  }
+
1653  }
+
1654 
+
1655  if (elem->Instructions().size()) {
+
1656  s += "\n";
+
1657 
+
1658  ListIter<Text> i_iter = elem->Instructions();
+
1659  while (++i_iter) {
+
1660  s += " instr: \"";
+
1661  s += SafeString(*i_iter.value());
+
1662  s += "\"\n";
+
1663  }
+
1664  }
+
1665 
+
1666  if (elem->Ships().size()) {
+
1667  ListIter<MissionShip> s_iter = elem->Ships();
+
1668  while (++s_iter) {
+
1669  MissionShip* ship = s_iter.value();
+
1670 
+
1671  s += "\n ship: {\n";
+
1672 
+
1673  if (ship->Name().length()) {
+
1674  s += " name: \"";
+
1675  s += SafeString(ship->Name());
+
1676  s += "\"\n";
+
1677  }
+
1678 
+
1679  if (ship->RegNum().length()) {
+
1680  s += " regnum: \"";
+
1681  s += SafeString(ship->RegNum());
+
1682  s += "\"\n";
+
1683  }
+
1684 
+
1685  if (ship->Region().length()) {
+
1686  s += " region: \"";
+
1687  s += SafeString(ship->Region());
+
1688  s += "\"\n";
+
1689  }
+
1690 
+
1691  if (fabs(ship->Location().x) < 1e9) {
+
1692  sprintf_s(buffer, " loc: (%.0f, %.0f, %.0f),\n",
+
1693  ship->Location().x,
+
1694  ship->Location().y,
+
1695  ship->Location().z);
+
1696  s += buffer;
+
1697  }
+
1698 
+
1699  if (fabs(ship->Velocity().x) < 1e9) {
+
1700  sprintf_s(buffer, " velocity: (%.1f, %.1f, %.1f),\n",
+
1701  ship->Velocity().x,
+
1702  ship->Velocity().y,
+
1703  ship->Velocity().z);
+
1704  s += buffer;
+
1705  }
+
1706 
+
1707  if (ship->Respawns() > -1) {
+
1708  sprintf_s(buffer, " respawns: %d,\n", ship->Respawns());
+
1709  s += buffer;
+
1710  }
+
1711 
+
1712  if (ship->Heading() > -1e9) {
+
1713  sprintf_s(buffer, " heading: %d,\n", (int) (ship->Heading()/DEGREES));
+
1714  s += buffer;
+
1715  }
+
1716 
+
1717  if (ship->Integrity() > -1) {
+
1718  sprintf_s(buffer, " integrity: %d,\n", (int) ship->Integrity());
+
1719  s += buffer;
+
1720  }
+
1721 
+
1722  if (ship->Decoys() > -1) {
+
1723  sprintf_s(buffer, " decoys: %d,\n", ship->Decoys());
+
1724  s += buffer;
+
1725  }
+
1726 
+
1727  if (ship->Probes() > -1) {
+
1728  sprintf_s(buffer, " probes: %d,\n", ship->Probes());
+
1729  s += buffer;
+
1730  }
+
1731 
+
1732  if (ship->Ammo()[0] > -10) {
+
1733  s += "\n ammo: (";
+
1734 
+
1735  for (int i = 0; i < 16; i++) {
+
1736  sprintf_s(buffer, "%d", ship->Ammo()[i]);
+
1737  s += buffer;
+
1738 
+
1739  if (i < 15)
+
1740  s += ", ";
+
1741  }
+
1742 
+
1743  s += ")\n";
+
1744  }
+
1745 
+
1746  if (ship->Fuel()[0] > -10) {
+
1747  s += "\n fuel: (";
+
1748 
+
1749  for (int i = 0; i < 4; i++) {
+
1750  sprintf_s(buffer, "%d", ship->Fuel()[i]);
+
1751  s += buffer;
+
1752 
+
1753  if (i < 3)
+
1754  s += ", ";
+
1755  }
+
1756 
+
1757  s += ")\n";
+
1758  }
+
1759 
+
1760  s += " }\n";
+
1761  }
+
1762  }
+
1763 
+
1764  s += "}\n\n";
+
1765  }
+
1766 
+ +
1768  while (++iter2) {
+
1769  MissionEvent* event = iter2.value();
+
1770 
+
1771  s += "event: {\n";
+
1772 
+
1773  s += " id: ";
+
1774  sprintf_s(buffer, "%d", event->EventID());
+
1775  s += buffer;
+
1776  s += ",\n time: ";
+
1777  sprintf_s(buffer, "%.1f", event->Time());
+
1778  s += buffer;
+
1779  s += ",\n delay: ";
+
1780  sprintf_s(buffer, "%.1f", event->Delay());
+
1781  s += buffer;
+
1782  s += ",\n event: ";
+
1783  s += event->EventName();
+
1784  s += "\n";
+
1785 
+
1786  if (event->EventShip().length()) {
+
1787  s += " event_ship: \"";
+
1788  s += SafeString(event->EventShip());
+
1789  s += "\"\n";
+
1790  }
+
1791 
+
1792  if (event->EventSource().length()) {
+
1793  s += " event_source: \"";
+
1794  s += SafeString(event->EventSource());
+
1795  s += "\"\n";
+
1796  }
+
1797 
+
1798  if (event->EventTarget().length()) {
+
1799  s += " event_target: \"";
+
1800  s += SafeString(event->EventTarget());
+
1801  s += "\"\n";
+
1802  }
+
1803 
+
1804  if (event->EventSound().length()) {
+
1805  s += " event_sound: \"";
+
1806  s += SafeString(event->EventSound());
+
1807  s += "\"\n";
+
1808  }
+
1809 
+
1810  if (event->EventMessage().length()) {
+
1811  s += " event_message: \"";
+
1812  s += SafeString(event->EventMessage());
+
1813  s += "\"\n";
+
1814  }
+
1815 
+
1816  if (event->EventParam()) {
+
1817  sprintf_s(buffer, "%d", event->EventParam());
+
1818  s += " event_param: ";
+
1819  s += buffer;
+
1820  s += "\n";
+
1821  }
+
1822 
+
1823  if (event->EventChance()) {
+
1824  sprintf_s(buffer, "%d", event->EventChance());
+
1825  s += " event_chance: ";
+
1826  s += buffer;
+
1827  s += "\n";
+
1828  }
+
1829 
+
1830  s += " trigger: \"";
+
1831  s += event->TriggerName();
+
1832  s += "\"\n";
+
1833 
+
1834  if (event->TriggerShip().length()) {
+
1835  s += " trigger_ship: \"";
+
1836  s += SafeString(event->TriggerShip());
+
1837  s += "\"\n";
+
1838  }
+
1839 
+
1840  if (event->TriggerTarget().length()) {
+
1841  s += " trigger_target: \"";
+
1842  s += SafeString(event->TriggerTarget());
+
1843  s += "\"\n";
+
1844  }
+
1845 
+
1846  Text param_str = event->TriggerParamStr();
+
1847 
+
1848  if (param_str.length()) {
+
1849  s += " trigger_param: ";
+
1850  s += param_str;
+
1851  s += "\n";
+
1852  }
+
1853 
+
1854  s += "}\n\n";
+
1855  }
+
1856 
+
1857  s += "// EOF\n";
+
1858 
+
1859  return s;
+
1860 }
+
1861 
+
1862 // +====================================================================+
+
1863 
+
1864 static int elem_idkey = 1;
+
1865 
+ +
1867 : id (elem_idkey++),
+
1868 elem_id(0), design(0), skin(0), count(1), maint_count(0), dead_count(0),
+
1869 IFF_code(0), player(0), alert(false), playable(false), rogue(false), invulnerable(false),
+
1870 respawns(0), hold_time(0), zone_lock(0), heading(0), mission_role(Mission::OTHER),
+
1871 intel(Intel::SECRET), command_ai(1), combat_group(0), combat_unit(0)
+
1872 {
+
1873 }
+
1874 
+ +
1876 {
+
1877  ships.destroy();
+
1878  objectives.destroy();
+ +
1880  navlist.destroy();
+
1881  loadouts.destroy();
+
1882 }
+
1883 
+
1884 Text
+ +
1886 {
+
1887  if (design)
+
1888  return design->abrv;
+
1889 
+
1890  return "UNK";
+
1891 }
+
1892 
+
1893 Text
+ +
1895 {
+
1896  if (index < 0 || index >= ships.size()) {
+
1897  if (count > 1) {
+
1898  char sname[256];
+
1899  sprintf_s(sname, "%s %d", (const char*) name, index+1);
+
1900  return sname;
+
1901  }
+
1902  else {
+
1903  return name;
+
1904  }
+
1905  }
+
1906 
+
1907  return ships.at(index)->Name();
+
1908 }
+
1909 
+
1910 Text
+ +
1912 {
+
1913  if (index < 0 || index >= ships.size()) {
+
1914  return Text();
+
1915  }
+
1916 
+
1917  return ships.at(index)->RegNum();
+
1918 }
+
1919 
+
1920 Text
+ +
1922 {
+ +
1924 }
+
1925 
+
1926 Color
+ +
1928 {
+
1929  return Ship::IFFColor(IFF_code);
+
1930 }
+
1931 
+
1932 bool
+ +
1934 {
+
1935  int design_type = 0;
+
1936  if (GetDesign())
+
1937  design_type = GetDesign()->type;
+
1938 
+
1939  return design_type >= Ship::STATION;
+
1940 }
+
1941 
+
1942 bool
+ +
1944 {
+
1945  int design_type = 0;
+
1946  if (GetDesign())
+
1947  design_type = GetDesign()->type;
+
1948 
+
1949  return (design_type & Ship::GROUND_UNITS) ? true : false;
+
1950 }
+
1951 
+
1952 bool
+ +
1954 {
+
1955  int design_type = 0;
+
1956  if (GetDesign())
+
1957  design_type = GetDesign()->type;
+
1958 
+
1959  return (design_type & Ship::STARSHIPS) ? true : false;
+
1960 }
+
1961 
+
1962 bool
+ +
1964 {
+
1965  int design_type = 0;
+
1966  if (GetDesign())
+
1967  design_type = GetDesign()->type;
+
1968 
+
1969  return (design_type & Ship::DROPSHIPS) ? true : false;
+
1970 }
+
1971 
+
1972 bool
+ +
1974 {
+
1975  const ShipDesign* design = GetDesign();
+
1976  if (design && design->flight_decks.size() > 0)
+
1977  return true;
+
1978 
+
1979  return false;
+
1980 }
+
1981 
+
1982 bool
+ +
1984 {
+
1985  if (carrier.length() > 0)
+
1986  return true;
+
1987 
+
1988  return false;
+
1989 }
+
1990 
+
1991 // +--------------------------------------------------------------------+
+
1992 
+
1993 Point
+ +
1995 {
+
1996  MissionElement* pThis = (MissionElement*) this;
+
1997  return pThis->rloc.Location();
+
1998 }
+
1999 
+
2000 void
+ +
2002 {
+
2003  rloc.SetBaseLocation(l);
+
2004  rloc.SetReferenceLoc(0);
+
2005  rloc.SetDistance(0);
+
2006 }
+
2007 
+
2008 void
+ +
2010 {
+
2011  rloc = r;
+
2012 }
+
2013 
+
2014 // +----------------------------------------------------------------------+
+
2015 
+
2016 void
+ +
2018 {
+
2019  if (pt && !navlist.contains(pt)) {
+
2020  if (afterPoint) {
+
2021  int index = navlist.index(afterPoint);
+
2022 
+
2023  if (index > -1)
+
2024  navlist.insert(pt, index+1);
+
2025  else
+
2026  navlist.append(pt);
+
2027  }
+
2028 
+
2029  else {
+
2030  navlist.append(pt);
+
2031  }
+
2032  }
+
2033 }
+
2034 
+
2035 void
+ +
2037 {
+
2038  if (pt)
+
2039  delete navlist.remove(pt);
+
2040 }
+
2041 
+
2042 void
+ +
2044 {
+
2045  navlist.destroy();
+
2046 }
+
2047 
+
2048 // +----------------------------------------------------------------------+
+
2049 
+
2050 int
+ +
2052 {
+
2053  int index = 0;
+
2054 
+
2055  if (navlist.size() > 0) {
+ +
2057  while (++navpt) {
+
2058  index++;
+
2059  if (navpt.value() == n)
+
2060  return index;
+
2061  }
+
2062  }
+
2063 
+
2064  return 0;
+
2065 }
+
2066 
+
2067 // +====================================================================+
+
2068 
+
2069 MissionLoad::MissionLoad(int s, const char* n)
+
2070 : ship(s)
+
2071 {
+
2072  for (int i = 0; i < 16; i++)
+
2073  load[i] = -1; // default: no weapon mounted
+
2074 
+
2075  if (n)
+
2076  name = n;
+
2077 }
+
2078 
+ +
2080 {
+
2081 }
+
2082 
+
2083 // +--------------------------------------------------------------------+
+
2084 
+
2085 int
+ +
2087 {
+
2088  return ship;
+
2089 }
+
2090 
+
2091 void
+ +
2093 {
+
2094  ship = s;
+
2095 }
+
2096 
+
2097 Text
+ +
2099 {
+
2100  return name;
+
2101 }
+
2102 
+
2103 void
+ +
2105 {
+
2106  name = n;
+
2107 }
+
2108 
+
2109 int*
+ +
2111 {
+
2112  return load;
+
2113 }
+
2114 
+
2115 int
+ +
2117 {
+
2118  if (index >= 0 && index < 16)
+
2119  return load[index];
+
2120 
+
2121  return 0;
+
2122 }
+
2123 
+
2124 void
+
2125 MissionLoad::SetStation(int index, int selection)
+
2126 {
+
2127  if (index >= 0 && index < 16)
+
2128  load[index] = selection;
+
2129 }
+
2130 
+
2131 
+
2132 // +====================================================================+
+
2133 
+ +
2135 : loc(-1e9, -1e9, -1e9), respawns(0), heading(0), integrity(100),
+
2136 decoys(-10), probes(-10), skin(0)
+
2137 {
+
2138  for (int i = 0; i < 16; i++)
+
2139  ammo[i] = -10;
+
2140 
+
2141  for (int i = 0; i < 4; i++)
+
2142  fuel[i] = -10;
+
2143 }
+
2144 
+
2145 void
+ +
2147 {
+
2148  if (a) {
+
2149  for (int i = 0; i < 16; i++)
+
2150  ammo[i] = a[i];
+
2151  }
+
2152 }
+
2153 
+
2154 void
+ +
2156 {
+
2157  if (f) {
+
2158  for (int i = 0; i < 4; i++)
+
2159  fuel[i] = f[i];
+
2160  }
+
2161 }
+
+
+ + + + -- cgit v1.1