Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Instruction.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: Instruction.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Navigation Point class implementation
13 */
14 
15 #include "MemDebug.h"
16 #include "Instruction.h"
17 #include "Element.h"
18 #include "RadioMessage.h"
19 #include "Ship.h"
20 #include "Sim.h"
21 
22 #include "Game.h"
23 #include "Text.h"
24 
25 // +----------------------------------------------------------------------+
26 
27 Instruction::Instruction(int act, const char* tgt)
28 : region(0), action(act), formation(0), tgt_name(tgt),
29 status(PENDING), speed(0), target(0), emcon(0), wep_free(0),
30 priority(PRIMARY), farcast(0), hold_time(0)
31 { }
32 
33 Instruction::Instruction(const char* rgn, Point loc, int act)
34 : region(0), action(act), formation(0),
35 status(PENDING), speed(0), target(0), emcon(0), wep_free(0),
36 priority(PRIMARY), farcast(0), hold_time(0)
37 {
38  rgn_name = rgn;
39  rloc.SetBaseLocation(loc);
40  rloc.SetDistance(0);
41 }
42 
44 : region(rgn), action(act), formation(0),
45 status(PENDING), speed(0), target(0), emcon(0), wep_free(0),
46 priority(PRIMARY), farcast(0), hold_time(0)
47 {
48  rgn_name = region->Name();
49  rloc.SetBaseLocation(loc);
50  rloc.SetDistance(0);
51 }
52 
54 : region(instr.region), rgn_name(instr.rgn_name),
55 rloc(instr.rloc), action(instr.action),
56 formation(instr.formation), status(instr.status), speed(instr.speed),
57 target(0), tgt_name(instr.tgt_name), tgt_desc(instr.tgt_desc),
58 emcon(instr.emcon), wep_free(instr.wep_free),
59 priority(instr.priority), farcast(instr.farcast),
60 hold_time(instr.hold_time)
61 {
62  SetTarget(instr.target);
63 }
64 
66 { }
67 
68 // +--------------------------------------------------------------------+
69 
72 {
73  rgn_name = n.rgn_name;
74  region = n.region;
75  rloc = n.rloc;
76  action = n.action;
77  formation = n.formation;
78  status = n.status;
79  speed = n.speed;
80 
81  tgt_name = n.tgt_name;
82  tgt_desc = n.tgt_desc;
83  target = 0;
84  emcon = n.emcon;
85  wep_free = n.wep_free;
86  priority = n.priority;
87  farcast = n.farcast;
88  hold_time = n.hold_time;
89 
90  SetTarget(n.target);
91  return *this;
92 }
93 
94 // +--------------------------------------------------------------------+
95 
96 Point
98 {
99  Instruction* pThis = (Instruction*) this;
100  return pThis->rloc.Location();
101 }
102 
103 void
105 {
108  rloc.SetDistance(0);
109 }
110 
111 // +----------------------------------------------------------------------+
112 
113 SimObject*
115 {
116  if (!target && tgt_name.length() > 0) {
117  Sim* sim = Sim::GetSim();
118 
119  if (sim) {
120  Ship* s = sim->FindShip(tgt_name, rgn_name);
121 
122  if (s) {
123  target = s;
124  Observe(target);
125  }
126  }
127  }
128 
129  return target;
130 }
131 
132 void
134 {
135  if (n && *n && tgt_name != n) {
136  tgt_name = n;
137  tgt_desc = n;
138 
139  if (target)
140  target = 0;
141  }
142 }
143 
144 void
146 {
147  if (s && target != s) {
148  tgt_name = s->Name();
149  target = s;
150  Observe(target);
151  }
152 }
153 
154 void
156 {
157  if (d && *d)
158  tgt_desc = d;
159 }
160 
161 void
163 {
164  if (target) {
165  target = 0;
166  tgt_name = "";
167  tgt_desc = "";
168  }
169 }
170 
171 // +----------------------------------------------------------------------+
172 
173 bool
175 {
176  if (target == obj)
177  target = 0;
178 
179  return SimObserver::Update(obj);
180 }
181 
182 const char*
184 {
185  return "Instruction";
186 }
187 
188 // +----------------------------------------------------------------------+
189 
190 void
192 {
193  Sim* sim = Sim::GetSim();
194 
195  switch (action) {
196  case VECTOR:
197  break;
198 
199  case LAUNCH:
200  if (ship->GetFlightPhase() == Ship::ACTIVE)
202  break;
203 
204  case DOCK:
205  case RTB:
206  if (sim->GetPlayerShip() == ship &&
207  (ship->GetFlightPhase() == Ship::DOCKING ||
208  ship->GetFlightPhase() == Ship::DOCKED))
210  else if (ship->Integrity() < 1)
211  SetStatus(FAILED);
212  break;
213 
214  case DEFEND:
215  case ESCORT:
216  {
217  bool found = false;
218  bool safe = true;
219 
220  ListIter<Element> iter = sim->GetElements();
221  while (++iter && !found) {
222  Element* e = iter.value();
223 
224  if (e->IsFinished() || e->IsSquadron())
225  continue;
226 
227  if (e->Name() == tgt_name ||
228  (e->GetCommander() && e->GetCommander()->Name() == tgt_name)) {
229 
230  found = true;
231 
232  for (int i = 0; i < e->NumShips(); i++) {
233  Ship* s = e->GetShip(i+1);
234 
235  if (s && s->Integrity() < 1)
236  SetStatus(FAILED);
237  }
238 
239  if (status == PENDING) {
240  // if the element had a flight plan, and all nav points
241  // have been addressed, then the element is safe
242  if (e->FlightPlanLength() > 0) {
243  if (e->GetNextNavPoint() == 0)
245  else
246  safe = false;
247  }
248  }
249  }
250  }
251 
252  if (status == PENDING && safe &&
253  sim->GetPlayerShip() == ship &&
254  (ship->GetFlightPhase() == Ship::DOCKING ||
255  ship->GetFlightPhase() == Ship::DOCKED)) {
257  }
258  }
259  break;
260 
261  case PATROL:
262  case SWEEP:
263  {
264  Sim* sim = Sim::GetSim();
265  bool alive = false;
266 
267  ListIter<Element> iter = sim->GetElements();
268  while (++iter) {
269  Element* e = iter.value();
270 
271  if (e->IsFinished() || e->IsSquadron())
272  continue;
273 
274  if (e->GetIFF() && e->GetIFF() != ship->GetIFF()) {
275  for (int i = 0; i < e->NumShips(); i++) {
276  Ship* s = e->GetShip(i+1);
277 
278  if (s && s->Integrity() >= 1)
279  alive = true;
280  }
281  }
282  }
283 
284  if (status == PENDING && !alive) {
286  }
287  }
288  break;
289 
290  case INTERCEPT:
291  case STRIKE:
292  case ASSAULT:
293  {
294  Sim* sim = Sim::GetSim();
295  bool alive = false;
296 
297  ListIter<Element> iter = sim->GetElements();
298  while (++iter) {
299  Element* e = iter.value();
300 
301  if (e->IsFinished() || e->IsSquadron())
302  continue;
303 
304  if (e->Name() == tgt_name) {
305  for (int i = 0; i < e->NumShips(); i++) {
306  Ship* s = e->GetShip(i+1);
307 
308  if (s && s->Integrity() >= 1)
309  alive = true;
310  }
311  }
312  }
313 
314  if (status == PENDING && !alive) {
316  }
317  }
318  break;
319 
320  case RECON:
321  break;
322 
323  default:
324  break;
325  }
326 }
327 
328 void
330 {
331  status = s;
332 }
333 
334 // +----------------------------------------------------------------------+
335 
336 const char*
338 {
339  static char desc[256];
340 
341  switch (action) {
342  case VECTOR:
343  if (farcast)
344  sprintf_s(desc, Game::GetText("instr.short.farcast").data(), rgn_name.data());
345  else
346  sprintf_s(desc, Game::GetText("instr.short.vector").data(), rgn_name.data());
347  break;
348 
349  case LAUNCH:
350  sprintf_s(desc, Game::GetText("instr.short.launch").data(), tgt_name.data());
351  break;
352 
353  case DOCK:
354  sprintf_s(desc, Game::GetText("instr.short.dock").data(), tgt_name.data());
355  break;
356 
357  case RTB:
358  sprintf_s(desc, Game::GetText("instr.short.return-to-base").data());
359  break;
360 
361  case DEFEND:
362  if (priority == PRIMARY) {
363  sprintf_s(desc, Game::GetText("instr.short.defend").data(), ActionName(action), tgt_desc.data());
364  }
365  else {
366  sprintf_s(desc, Game::GetText("instr.short.protect").data(), tgt_desc.data());
367  }
368  break;
369 
370  case ESCORT:
371  if (priority == PRIMARY) {
372  sprintf_s(desc, Game::GetText("instr.short.escort").data(), ActionName(action), tgt_desc.data());
373  }
374  else {
375  sprintf_s(desc, Game::GetText("instr.short.protect").data(), tgt_desc.data());
376  }
377  break;
378 
379  case PATROL:
380  sprintf_s(desc, Game::GetText("instr.short.patrol").data(),
381  tgt_desc.data(),
382  rgn_name.data());
383  break;
384 
385  case SWEEP:
386  sprintf_s(desc, Game::GetText("instr.short.sweep").data(),
387  tgt_desc.data(),
388  rgn_name.data());
389  break;
390 
391  case INTERCEPT:
392  sprintf_s(desc, Game::GetText("instr.short.intercept").data(), tgt_desc.data());
393  break;
394 
395  case STRIKE:
396  sprintf_s(desc, Game::GetText("instr.short.strike").data(), tgt_desc.data());
397  break;
398 
399  case ASSAULT:
400  sprintf_s(desc, Game::GetText("instr.short.assault").data(), tgt_desc.data());
401  break;
402 
403  case RECON:
404  sprintf_s(desc, Game::GetText("instr.short.recon").data(), tgt_desc.data());
405  break;
406 
407  default:
408  sprintf_s(desc, "%s", ActionName(action));
409  break;
410  }
411 
412  if (status != PENDING) {
413  strcat_s(desc, " - ");
414  strcat_s(desc, Game::GetText(StatusName(status)));
415  }
416 
417  return desc;
418 }
419 
420 // +----------------------------------------------------------------------+
421 
422 const char*
424 {
425  static char desc[1024];
426 
427  switch (action) {
428  case VECTOR:
429  if (farcast)
430  sprintf_s(desc, Game::GetText("instr.long.farcast").data(), rgn_name.data());
431  else
432  sprintf_s(desc, Game::GetText("instr.long.vector").data(), rgn_name.data());
433  break;
434 
435  case LAUNCH:
436  sprintf_s(desc, Game::GetText("instr.long.launch").data(), tgt_name.data());
437  break;
438 
439  case DOCK:
440  sprintf_s(desc, Game::GetText("instr.long.dock").data(), tgt_name.data());
441  break;
442 
443  case RTB:
444  sprintf_s(desc, Game::GetText("instr.long.return-to-base").data());
445  break;
446 
447  case DEFEND:
448  if (priority == PRIMARY) {
449  sprintf_s(desc, Game::GetText("instr.long.defend").data(), ActionName(action), tgt_desc.data());
450  }
451  else {
452  sprintf_s(desc, Game::GetText("instr.long.protect").data(), tgt_desc.data());
453  }
454  break;
455 
456  case ESCORT:
457  if (priority == PRIMARY) {
458  sprintf_s(desc, Game::GetText("instr.long.escort").data(), ActionName(action), tgt_desc.data());
459  }
460  else {
461  sprintf_s(desc, Game::GetText("instr.long.protect").data(), tgt_desc.data());
462  }
463  break;
464 
465  case PATROL:
466  sprintf_s(desc, Game::GetText("instr.long.patrol").data(),
467  tgt_desc.data(),
468  rgn_name.data());
469  break;
470 
471  case SWEEP:
472  sprintf_s(desc, Game::GetText("instr.long.sweep").data(),
473  tgt_desc.data(),
474  rgn_name.data());
475  break;
476 
477  case INTERCEPT:
478  sprintf_s(desc, Game::GetText("instr.long.intercept").data(), tgt_desc.data());
479  break;
480 
481  case STRIKE:
482  sprintf_s(desc, Game::GetText("instr.long.strike").data(), tgt_desc.data());
483  break;
484 
485  case ASSAULT:
486  sprintf_s(desc, Game::GetText("instr.long.assault").data(), tgt_desc.data());
487  break;
488 
489  case RECON:
490  sprintf_s(desc, Game::GetText("instr.long.recon").data(), tgt_desc.data());
491  break;
492 
493  default:
494  sprintf_s(desc, "%s", ActionName(action));
495  break;
496  }
497 
498  if (status != PENDING) {
499  strcat_s(desc, " - ");
500  strcat_s(desc, Game::GetText(StatusName(status)));
501  }
502 
503  return desc;
504 }
505 
506 // +----------------------------------------------------------------------+
507 
508 const char*
510 {
511  switch (a) {
512  case VECTOR: return "Vector";
513  case LAUNCH: return "Launch";
514  case DOCK: return "Dock";
515  case RTB: return "RTB";
516 
517  case DEFEND: return "Defend";
518  case ESCORT: return "Escort";
519  case PATROL: return "Patrol";
520  case SWEEP: return "Sweep";
521  case INTERCEPT: return "Intercept";
522  case STRIKE: return "Strike";
523  case ASSAULT: return "Assault";
524  case RECON: return "Recon";
525 
526  default: return "Unknown";
527  }
528 }
529 
530 const char*
532 {
533  switch (s) {
534  case PENDING: return "Pending";
535  case ACTIVE: return "Active";
536  case SKIPPED: return "Skipped";
537  case ABORTED: return "Aborted";
538  case FAILED: return "Failed";
539  case COMPLETE: return "Complete";
540 
541  default: return "Unknown";
542  }
543 }
544 
545 const char*
547 {
548  switch (f) {
549  case DIAMOND: return "Diamond";
550  case SPREAD: return "Spread";
551  case BOX: return "Box";
552  case TRAIL: return "Trail";
553 
554  default: return "Unknown";
555  }
556 }
557 
558 const char*
560 {
561  switch (p) {
562  case PRIMARY: return "Primary";
563  case SECONDARY: return "Secondary";
564  case BONUS: return "Bonus";
565 
566  default: return "Unknown";
567  }
568 }
569