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/_radio_handler_8cpp_source.html | 675 +++++++++++++++++++++++ 1 file changed, 675 insertions(+) create mode 100644 Doc/doxygen/html/_radio_handler_8cpp_source.html (limited to 'Doc/doxygen/html/_radio_handler_8cpp_source.html') diff --git a/Doc/doxygen/html/_radio_handler_8cpp_source.html b/Doc/doxygen/html/_radio_handler_8cpp_source.html new file mode 100644 index 0000000..ce73d1c --- /dev/null +++ b/Doc/doxygen/html/_radio_handler_8cpp_source.html @@ -0,0 +1,675 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/RadioHandler.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
RadioHandler.cpp
+
+
+Go to the documentation of this file.
1 /* Project Starshatter 5.0
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2007. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: Stars.exe
+
6  FILE: RadioHandler.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Radio message handler class implementation
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "RadioHandler.h"
+
17 #include "RadioMessage.h"
+
18 #include "RadioTraffic.h"
+
19 #include "Instruction.h"
+
20 
+
21 #include "Contact.h"
+
22 #include "Element.h"
+
23 #include "Mission.h"
+
24 #include "Ship.h"
+
25 #include "ShipDesign.h"
+
26 #include "Sim.h"
+
27 #include "StarSystem.h"
+
28 #include "Power.h"
+
29 #include "Drive.h"
+
30 #include "Shield.h"
+
31 #include "Hangar.h"
+
32 #include "FlightDeck.h"
+
33 #include "WeaponGroup.h"
+
34 #include "SteerAI.h"
+
35 
+
36 #include "Text.h"
+
37 #include "Game.h"
+
38 
+
39 // +----------------------------------------------------------------------+
+
40 
+ +
42 { }
+
43 
+ +
45 { }
+
46 
+
47 // +----------------------------------------------------------------------+
+
48 
+
49 bool
+ +
51 {
+
52  if (!s || !msg || !msg->Sender())
+
53  return false;
+
54 
+
55  if (s->Class() >= Ship::FARCASTER && s->Class() <= Ship::C3I)
+
56  return false;
+
57 
+
58  if (msg->Sender()->IsRogue()) {
+
59  Ship* sender = (Ship*) msg->Sender(); // cast-away const
+
60  RadioMessage* nak = new(__FILE__,__LINE__) RadioMessage(sender, s, RadioMessage::NACK);
+ +
62  return false;
+
63  }
+
64 
+
65  bool respond = (s != msg->Sender());
+
66 
+
67  // SPECIAL CASE:
+
68  // skip navpoint must be processed by elem leader,
+
69  // even if the elem leader sent the message:
+
70 
+
71  if (msg->Action() == RadioMessage::SKIP_NAVPOINT && !respond)
+
72  ProcessMessageAction(msg, s);
+
73 
+
74  if (!ProcessMessageOrders(msg, s))
+
75  respond = respond && ProcessMessageAction(msg, s);
+
76 
+
77  return respond;
+
78 }
+
79 
+
80 // +----------------------------------------------------------------------+
+
81 
+
82 bool
+ +
84 {
+
85  bool result = false;
+
86 
+
87  switch (action) {
+
88  default:
+
89  case RadioMessage::NONE:
+
90  case RadioMessage::ACK:
+
91  case RadioMessage::NACK: result = false; break;
+
92 
+
93  // target mgt:
+ + + +
97  case RadioMessage::IDENTIFY: result = true; break;
+
98 
+
99  // combat mgt:
+ + +
102  case RadioMessage::FORM_UP: result = true; break;
+
103 
+ + +
106  case RadioMessage::LAUNCH_PROBE: result = false; break;
+
107 
+
108  // formation mgt:
+ + + +
112  case RadioMessage::GO_TRAIL: result = true; break;
+
113 
+
114  // mission mgt:
+
115  case RadioMessage::MOVE_PATROL: result = true; break;
+
116  case RadioMessage::SKIP_NAVPOINT: result = false; break;
+
117  case RadioMessage::RESUME_MISSION: result = true; break;
+
118 
+
119  case RadioMessage::RTB:
+ + +
122  case RadioMessage::FARCAST_TO: result = true; break;
+
123 
+
124  // sensor mgt:
+ + +
127  case RadioMessage::GO_EMCON3: result = true; break;
+
128 
+
129  // support:
+ + +
132  case RadioMessage::PICTURE: result = false; break;
+
133 
+
134  // traffic control:
+ + + + +
139  case RadioMessage::CALL_WAVE_OFF: result = false; break;
+
140  }
+
141 
+
142  return result;
+
143 }
+
144 
+
145 // +----------------------------------------------------------------------+
+
146 
+
147 bool
+ +
149 {
+
150  Instruction* instruction = ship->GetRadioOrders();
+
151  int action = 0;
+
152 
+
153  if (msg && msg->Action() == RadioMessage::RESUME_MISSION) {
+
154  instruction->SetAction(RadioMessage::NONE);
+
155  instruction->SetFormation(-1);
+
156  instruction->SetWeaponsFree(true);
+
157  if (instruction->GetTarget()) {
+
158  instruction->ClearTarget();
+
159  ship->DropTarget();
+
160  }
+
161  return true;
+
162  }
+
163 
+
164  if (msg && IsOrder(msg->Action())) {
+
165  int posture_only = false;
+
166 
+
167  action = msg->Action();
+
168 
+
169  if (action == RadioMessage::FORM_UP)
+
170  action = RadioMessage::WEP_HOLD;
+
171 
+
172  // target orders => drop current target:
+
173  if (action >= RadioMessage::ATTACK &&
+
174  action <= RadioMessage::COVER_ME ||
+
175  action == RadioMessage::WEP_HOLD ||
+
176  action >= RadioMessage::DOCK_WITH &&
+
177  action <= RadioMessage::FARCAST_TO) {
+
178 
+
179  if (ship != msg->Sender())
+
180  ship->DropTarget();
+
181 
+
182  Director* dir = ship->GetDirector();
+
183  if (dir && dir->Type() >= SteerAI::SEEKER && dir->Type() <= SteerAI::GROUND) {
+
184  SteerAI* ai = (SteerAI*) dir;
+
185  ai->SetTarget(0);
+
186  }
+
187 
+
188  // farcast and quantum jump radio messages:
+
189  if (action >= RadioMessage::QUANTUM_TO) {
+
190  Sim* sim = Sim::GetSim();
+
191 
+
192  if (sim) {
+
193  SimRegion* rgn = sim->FindRegion(msg->Info());
+
194 
+
195  if (rgn) {
+
196  instruction->SetAction(action);
+
197  instruction->SetLocation(Point(0,0,0));
+
198  instruction->SetRegion(rgn);
+
199  instruction->SetFarcast(action == RadioMessage::FARCAST_TO);
+
200  instruction->SetWeaponsFree(false);
+
201  return true;
+
202  }
+
203  }
+
204  }
+
205  }
+
206 
+
207  // formation orders => set formation:
+
208  if (action >= RadioMessage::GO_DIAMOND &&
+
209  action <= RadioMessage::GO_TRAIL) {
+
210 
+
211  switch (action) {
+ +
213  case RadioMessage::GO_SPREAD: instruction->SetFormation(Instruction::SPREAD); break;
+
214  case RadioMessage::GO_BOX: instruction->SetFormation(Instruction::BOX); break;
+
215  case RadioMessage::GO_TRAIL: instruction->SetFormation(Instruction::TRAIL); break;
+
216  }
+
217 
+
218  posture_only = true;
+
219  }
+
220 
+
221  // emcon orders => set emcon:
+
222  if (action >= RadioMessage::GO_EMCON1 &&
+
223  action <= RadioMessage::GO_EMCON3) {
+
224 
+
225  switch (msg->Action()) {
+
226  case RadioMessage::GO_EMCON1: instruction->SetEMCON(1); break;
+
227  case RadioMessage::GO_EMCON2: instruction->SetEMCON(2); break;
+
228  case RadioMessage::GO_EMCON3: instruction->SetEMCON(3); break;
+
229  }
+
230 
+
231  posture_only = true;
+
232  }
+
233 
+
234  if (!posture_only) {
+
235  instruction->SetAction(action);
+
236  instruction->ClearTarget();
+
237 
+
238  if (msg->TargetList().size() > 0) {
+
239  SimObject* msg_tgt = msg->TargetList().at(0);
+
240  instruction->SetTarget(msg_tgt);
+
241  instruction->SetLocation(msg_tgt->Location());
+
242  }
+
243 
+
244  else if (action == RadioMessage::COVER_ME) {
+
245  instruction->SetTarget((Ship*) msg->Sender());
+
246  instruction->SetLocation(msg->Sender()->Location());
+
247  }
+
248 
+
249  else if (action == RadioMessage::MOVE_PATROL) {
+
250  instruction->SetLocation(msg->Location());
+
251  }
+
252 
+
253  // handle element engagement:
+
254  if (action == RadioMessage::ATTACK && msg->TargetList().size() > 0) {
+
255  Element* elem = msg->DestinationElem();
+
256 
+
257  if (!elem && msg->DestinationShip())
+
258  elem = msg->DestinationShip()->GetElement();
+
259 
+
260  if (elem) {
+
261  SimObject* msg_tgt = msg->TargetList().at(0);
+
262  if (msg_tgt && msg_tgt->Type() == SimObject::SIM_SHIP) {
+
263  Element* tgt = ((Ship*) msg_tgt)->GetElement();
+
264  elem->SetAssignment(tgt);
+
265 
+
266  if (msg->TargetList().size() > 1)
+
267  instruction->SetTarget(tgt->Name().data());
+
268  else
+
269  instruction->SetTarget(msg_tgt);
+
270  }
+
271  else {
+
272  elem->ResumeAssignment();
+
273  }
+
274  }
+
275  }
+
276 
+
277  else if (action == RadioMessage::RESUME_MISSION) {
+
278  Element* elem = msg->DestinationElem();
+
279 
+
280  if (!elem && msg->DestinationShip())
+
281  elem = msg->DestinationShip()->GetElement();
+
282 
+
283  if (elem) {
+
284  elem->ResumeAssignment();
+
285  }
+
286  }
+
287  }
+
288 
+
289  instruction->SetWeaponsFree(action <= RadioMessage::WEP_FREE);
+
290  return true;
+
291  }
+
292 
+
293  return false;
+
294 }
+
295 
+
296 // +----------------------------------------------------------------------+
+
297 
+
298 bool
+ +
300 {
+
301  if (!msg) return false;
+
302 
+
303  if (msg->Action() == RadioMessage::CALL_INBOUND)
+
304  return Inbound(msg, ship);
+
305 
+
306  if (msg->Action() == RadioMessage::CALL_FINALS)
+
307  return true; // acknowledge
+
308 
+ +
310  return Picture(msg, ship);
+
311 
+ +
313  return Support(msg, ship);
+
314 
+
315  if (msg->Action() == RadioMessage::SKIP_NAVPOINT)
+
316  return SkipNavpoint(msg, ship);
+
317 
+
318  if (msg->Action() == RadioMessage::LAUNCH_PROBE)
+
319  return LaunchProbe(msg, ship);
+
320 
+
321  return false;
+
322 }
+
323 
+
324 bool
+ +
326 {
+
327  // Find next Instruction:
+
328  Instruction* navpt = ship->GetNextNavPoint();
+
329  int elem_index = ship->GetElementIndex();
+
330 
+
331  if (navpt && elem_index < 2) {
+
332  ship->SetNavptStatus(navpt, Instruction::SKIPPED);
+
333  }
+
334 
+
335  return true;
+
336 }
+
337 
+
338 bool
+ +
340 {
+
341  if (ship && ship->GetProbeLauncher()) {
+
342  ship->LaunchProbe();
+
343  return ship->GetProbe() != 0;
+
344  }
+
345 
+
346  return false;
+
347 }
+
348 
+
349 bool
+ +
351 {
+
352  Ship* inbound = (Ship*) msg->Sender();
+
353  Hangar* hangar = ship->GetHangar();
+
354  FlightDeck* deck = 0;
+
355  int squadron = -1;
+
356  int slot = -1;
+
357  bool same_rgn = false;
+
358 
+
359  if (inbound && inbound->GetRegion() == ship->GetRegion())
+
360  same_rgn = true;
+
361 
+
362  // is the sender already inbound to us?
+
363  if (inbound->GetInbound() &&
+
364  inbound->GetInbound()->GetDeck() &&
+
365  inbound->GetInbound()->GetDeck()->GetCarrier() == ship) {
+
366  InboundSlot* islot = inbound->GetInbound();
+
367  deck = islot->GetDeck();
+
368  squadron = islot->Squadron();
+
369  slot = islot->Index();
+
370  }
+
371 
+
372  // otherwise, find space for sender:
+
373  else {
+
374  if (hangar && same_rgn) {
+
375  if (hangar->FindSlot(inbound, squadron, slot)) {
+
376  int shortest_queue = 1000;
+
377 
+
378  for (int i = 0; i < ship->NumFlightDecks(); i++) {
+
379  FlightDeck* d = ship->GetFlightDeck(i);
+
380  if (d->IsRecoveryDeck()) {
+
381  int nwaiting = d->GetRecoveryQueue().size();
+
382 
+
383  if (nwaiting < shortest_queue) {
+
384  deck = d;
+
385  shortest_queue = nwaiting;
+
386  }
+
387  }
+
388  }
+
389  }
+
390  }
+
391  }
+
392 
+
393  // if no space (or not a carrier!) wave sender off:
+
394  if (!deck || !same_rgn || squadron < 0 || slot < 0) {
+
395  RadioMessage* wave_off = new(__FILE__,__LINE__) RadioMessage(inbound, ship, RadioMessage::NACK);
+
396  if (!hangar)
+
397  wave_off->SetInfo(Game::GetText("RadioHandler.no-hangar"));
+
398 
+
399  else if (!same_rgn) {
+
400  char info[256];
+
401  sprintf_s(info, Game::GetText("RadioHandler.too-far-away").data(), ship->GetRegion()->Name());
+
402  wave_off->SetInfo(info);
+
403  }
+
404 
+
405  else
+
406  wave_off->SetInfo(Game::GetText("RadioHandler.all-full"));
+
407 
+
408  RadioTraffic::Transmit(wave_off);
+
409  return false;
+
410  }
+
411 
+
412  // put sender in recovery queue, if not already there:
+
413  InboundSlot* inbound_slot = inbound->GetInbound();
+
414  int sequence = 0;
+
415 
+
416  if (!inbound_slot) {
+
417  inbound_slot = new(__FILE__,__LINE__) InboundSlot(inbound, deck, squadron, slot);
+
418  sequence = deck->Inbound(inbound_slot);
+
419  }
+
420  else {
+
421  sequence = inbound_slot->Index();
+
422  }
+
423 
+
424  // inform sender of status:
+
425  RadioMessage* approach = new(__FILE__,__LINE__) RadioMessage(inbound, ship, RadioMessage::CALL_APPROACH);
+
426 
+
427  if (inbound_slot->Cleared()) {
+
428  char info[256];
+
429  sprintf_s(info, Game::GetText("RadioHandler.cleared").data(), deck->Name());
+
430  approach->SetInfo(info);
+
431  }
+
432  else if (sequence) {
+
433  char info[256];
+
434  sprintf_s(info, Game::GetText("RadioHandler.sequenced").data(), sequence, deck->Name());
+
435  approach->SetInfo(info);
+
436  }
+
437 
+
438  RadioTraffic::Transmit(approach);
+
439 
+
440  return false;
+
441 }
+
442 
+
443 bool
+ +
445 {
+
446  if (!ship) return false;
+
447 
+
448  // try to find some enemy fighters in the area:
+
449  Ship* tgt = 0;
+
450  double range = 1e9;
+
451 
+
452  ListIter<Contact> iter = ship->ContactList();
+
453  while (++iter) {
+
454  Contact* c = iter.value();
+
455  int iff = c->GetIFF(ship);
+
456  Ship* s = c->GetShip();
+
457 
+
458  if (s && s->IsDropship() && s->IsHostileTo(ship)) {
+
459  double s_range = Point(msg->Sender()->Location() - s->Location()).length();
+
460  if (!tgt || s_range < range) {
+
461  tgt = s;
+
462  range = s_range;
+
463  }
+
464  }
+
465  }
+
466 
+
467  // found some:
+
468  if (tgt) {
+
469  Element* sender = msg->Sender()->GetElement();
+
470  Element* tgt_elem = tgt->GetElement();
+
471  RadioMessage* response = new(__FILE__,__LINE__) RadioMessage(sender, ship, RadioMessage::ATTACK);
+
472 
+
473  if (tgt_elem) {
+
474  for (int i = 1; i <= tgt_elem->NumShips(); i++)
+
475  response->AddTarget(tgt_elem->GetShip(i));
+
476  }
+
477  else {
+
478  response->AddTarget(tgt);
+
479  }
+
480 
+
481  RadioTraffic::Transmit(response);
+
482  }
+
483 
+
484  // nobody worth killin':
+
485  else {
+
486  Ship* sender = (Ship*) msg->Sender(); // cast-away const
+
487  RadioMessage* response = new(__FILE__,__LINE__) RadioMessage(sender, ship, RadioMessage::PICTURE);
+
488  RadioTraffic::Transmit(response);
+
489  }
+
490 
+
491  return false;
+
492 }
+
493 
+
494 bool
+ +
496 {
+
497  if (!ship) return false;
+
498 
+
499  // try to find some fighters with time on their hands...
+
500  Element* help = 0;
+
501  Element* cmdr = ship->GetElement();
+
502  Element* baby = msg->Sender()->GetElement();
+
503  SimRegion* rgn = msg->Sender()->GetRegion();
+
504 
+
505  for (int i = 0; i < rgn->Ships().size(); i++) {
+
506  Ship* s = rgn->Ships().at(i);
+
507  Element* e = s->GetElement();
+
508 
+
509  if (e && s->IsDropship() &&
+
510  e->Type() == Mission::PATROL &&
+
511  e != baby &&
+
512  cmdr->CanCommand(e) &&
+ +
514  help = e;
+
515  break;
+
516  }
+
517  }
+
518 
+
519  // found some:
+
520  if (help) {
+
521  RadioMessage* escort = new(__FILE__,__LINE__) RadioMessage(help, ship, RadioMessage::ESCORT);
+
522  escort->TargetList().append(msg->Sender());
+
523  RadioTraffic::Transmit(escort);
+
524 
+
525  Text ok = Game::GetText("RadioHandler.help-enroute");
+
526  Ship* sender = (Ship*) msg->Sender(); // cast-away const
+
527  RadioMessage* response = new(__FILE__,__LINE__) RadioMessage(sender, ship, RadioMessage::ACK);
+
528  response->SetInfo(ok);
+
529  RadioTraffic::Transmit(response);
+
530  }
+
531 
+
532  // no help in sight:
+
533  else {
+
534  Text nope = Game::GetText("RadioHandler.no-help-for-you");
+
535  Ship* sender = (Ship*) msg->Sender(); // cast-away const
+
536  RadioMessage* response = new(__FILE__,__LINE__) RadioMessage(sender, ship, RadioMessage::NACK);
+
537  response->SetInfo(nope);
+
538  RadioTraffic::Transmit(response);
+
539  }
+
540 
+
541  return false;
+
542 }
+
543 
+
544 // +----------------------------------------------------------------------+
+
545 
+
546 void
+ +
548 {
+
549  if (s && msg && msg->Sender() && msg->Action()) {
+
550  if (msg->Action() >= RadioMessage::ACK && msg->Action() <= RadioMessage::NACK)
+
551  return; // nothing to say here
+
552 
+
553  Ship* sender = (Ship*) msg->Sender(); // cast-away const
+
554  RadioMessage* ack = new(__FILE__,__LINE__) RadioMessage(sender, s, RadioMessage::ACK);
+ +
556  }
+
557 }
+
558 
+
+
+ + + + -- cgit v1.1