Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
RadioTraffic.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: RadioTraffic.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Radio message handler class implementation
13 */
14 
15 #include "MemDebug.h"
16 #include "RadioTraffic.h"
17 #include "RadioMessage.h"
18 #include "RadioView.h"
19 #include "RadioVox.h"
20 #include "Instruction.h"
21 #include "Ship.h"
22 #include "Contact.h"
23 #include "Element.h"
24 #include "Sim.h"
25 #include "NetGame.h"
26 #include "NetData.h"
27 
28 #include "Game.h"
29 #include "Text.h"
30 
31 // +----------------------------------------------------------------------+
32 
34 
35 // +----------------------------------------------------------------------+
36 
38 {
39  radio_traffic = this;
40 }
41 
43 {
44  traffic.destroy();
45 }
46 
47 // +----------------------------------------------------------------------+
48 
49 void
51 {
52  if (!radio_traffic)
53  radio_traffic = new(__FILE__,__LINE__) RadioTraffic;
54 }
55 
56 void
58 {
59  delete radio_traffic;
60  radio_traffic = 0;
61 }
62 
63 // +--------------------------------------------------------------------+
64 
65 void
67 {
68  if (!ship) return;
69 
70  Element* elem = ship->GetElement();
71 
72  if (elem) {
73  if (action >= RadioMessage::REQUEST_PICTURE) {
74  Ship* controller = ship->GetController();
75 
76  if (controller && !ship->IsStarship()) {
77  RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(controller, ship, action);
78  Transmit(msg);
79  }
80  }
81  else if (action >= RadioMessage::SPLASH_1 && action <= RadioMessage::DISTRESS) {
82  RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage((Element*) 0, ship, action);
83  Transmit(msg);
84  }
85  else {
86  RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(elem, ship, action);
87 
88  if (action == RadioMessage::ATTACK || action == RadioMessage::ESCORT)
89  msg->AddTarget(ship->GetTarget());
90 
91  Transmit(msg);
92  }
93  }
94 }
95 
96 // +----------------------------------------------------------------------+
97 
98 void
100 {
101  if (msg && radio_traffic) {
102  NetGame* net_game = NetGame::GetInstance();
103  if (net_game) {
104  NetCommMsg net_msg;
105  net_msg.SetRadioMessage(msg);
106  net_game->SendData(&net_msg);
107  }
108 
110  }
111 }
112 
113 // +----------------------------------------------------------------------+
114 
115 void
117 {
118  if (!msg) return;
119 
120  Sim* sim = Sim::GetSim();
121  Ship* player = sim->GetPlayerShip();
122  int iff = 0;
123 
124  if (player)
125  iff = player->GetIFF();
126 
127  if (msg->DestinationShip()) {
128  traffic.append(msg);
129 
130  if (msg->Channel() == 0 || msg->Channel() == iff)
131  DisplayMessage(msg);
132 
134  msg->DestinationShip()->HandleRadioMessage(msg);
135  }
136 
137  else if (msg->DestinationElem()) {
138  traffic.append(msg);
139 
140  if (msg->Channel() == 0 || msg->Channel() == iff)
141  DisplayMessage(msg);
142 
144  msg->DestinationElem()->HandleRadioMessage(msg);
145  }
146 
147  else {
148  if (msg->Channel() == 0 || msg->Channel() == iff)
149  DisplayMessage(msg);
150 
151  delete msg;
152  }
153 }
154 
155 // +----------------------------------------------------------------------+
156 
157 Text
158 RadioTraffic::TranslateVox(const char* phrase)
159 {
160  Text vox = "vox.";
161  vox += phrase;
162  vox.toLower();
163  vox = Game::GetText(vox);
164 
165  if (vox.contains("vox.")) // failed to translate
166  return Text(phrase); // return the original text
167 
168  return vox;
169 }
170 
171 void
173 {
174  if (!msg) return;
175 
176  char txt_buf[256]; txt_buf[0] = 0;
177  char msg_buf[128]; msg_buf[0] = 0;
178  char src_buf[64]; src_buf[0] = 0;
179  char dst_buf[64]; dst_buf[0] = 0;
180  char act_buf[64]; act_buf[0] = 0;
181  int vox_channel = 0;
182 
183  Ship* dst_ship = msg->DestinationShip();
184  Element* dst_elem = msg->DestinationElem();
185 
186  // BUILD SRC AND DST BUFFERS -------------------
187 
188  if (msg->Sender()) {
189  const Ship* sender = msg->Sender();
190 
191  // orders to self?
192  if (dst_elem && dst_elem->NumShips() == 1 && dst_elem->GetShip(1) == sender) {
193  if (msg->Action() >= RadioMessage::CALL_ENGAGING) {
194  sprintf_s(src_buf, "%s", sender->Name());
195 
196  if (sender->IsStarship())
197  vox_channel = (sender->Identity()%3) + 5;
198  }
199  }
200 
201  // orders to other ships:
202  else {
203  if (sender->IsStarship()) {
204  vox_channel = (sender->Identity()%3) + 5;
205  }
206  else {
207  vox_channel = sender->GetElementIndex();
208  }
209 
210  if (msg->Action() >= RadioMessage::CALL_ENGAGING) {
211  sprintf_s(src_buf, "%s", sender->Name());
212  }
213  else {
214  sprintf_s(src_buf, "This is %s", sender->Name());
215 
216  if (dst_ship) {
217  // internal announcement
218  if (dst_ship->GetElement() == sender->GetElement()) {
219  dst_elem = sender->GetElement();
220  int index = sender->GetElementIndex();
221 
222  if (index > 1 && dst_elem) {
223  sprintf_s(dst_buf, "%s Leader", (const char*) dst_elem->Name());
224  sprintf_s(src_buf, "this is %s %d", (const char*) dst_elem->Name(), index);
225  }
226  else {
227  sprintf_s(src_buf, "this is %s leader", (const char*) dst_elem->Name());
228  }
229  }
230 
231  else {
232  strcpy_s(dst_buf, (const char*) dst_ship->Name());
233  src_buf[0] = tolower(src_buf[0]);
234  }
235  }
236 
237  else if (dst_elem) {
238  // flight
239  if (dst_elem->NumShips() > 1) {
240  sprintf_s(dst_buf, "%s Flight", (const char*) dst_elem->Name());
241 
242  // internal announcement
243  if (sender->GetElement() == dst_elem) {
244  int index = sender->GetElementIndex();
245 
246  if (index > 1) {
247  sprintf_s(dst_buf, "%s Leader", (const char*) dst_elem->Name());
248  sprintf_s(src_buf, "this is %s %d", (const char*) dst_elem->Name(), index);
249  }
250  else {
251  sprintf_s(src_buf, "this is %s leader", (const char*) dst_elem->Name());
252  }
253  }
254  }
255 
256  // solo
257  else {
258  strcpy_s(dst_buf, (const char*) dst_elem->Name());
259  src_buf[0] = tolower(src_buf[0]);
260  }
261  }
262  }
263  }
264  }
265 
266  // BUILD ACTION AND TARGET BUFFERS -------------------
267 
268  SimObject* target = 0;
269 
270  strcpy_s(act_buf, RadioMessage::ActionName(msg->Action()));
271 
272  if (msg->TargetList().size() > 0)
273  target = msg->TargetList()[0];
274 
275  if (msg->Action() == RadioMessage::ACK ||
276  msg->Action() == RadioMessage::NACK) {
277 
278  if (dst_ship == msg->Sender()) {
279  src_buf[0] = 0;
280  dst_buf[0] = 0;
281 
282  if (msg->Action() == RadioMessage::ACK)
283  sprintf_s(msg_buf, "%s.", TranslateVox("Acknowledged").data());
284  else
285  sprintf_s(msg_buf, "%s.", TranslateVox("Unable").data());
286  }
287  else if (msg->Sender()) {
288  dst_buf[0] = 0;
289 
290  if (msg->Info().length()) {
291  sprintf_s(msg_buf, "%s. %s",
292  TranslateVox(act_buf).data(),
293  (const char*) msg->Info());
294  }
295  else {
296  sprintf_s(msg_buf, "%s.", TranslateVox(act_buf).data());
297  }
298  }
299  else {
300  if (msg->Info().length()) {
301  sprintf_s(msg_buf, "%s. %s",
302  TranslateVox(act_buf).data(),
303  (const char*) msg->Info());
304  }
305  else {
306  sprintf_s(msg_buf, "%s.", TranslateVox(act_buf).data());
307  }
308  }
309  }
310 
311  else if (msg->Action() == RadioMessage::MOVE_PATROL) {
312  sprintf_s(msg_buf, TranslateVox("Move patrol.").data());
313  }
314 
315  else if (target && dst_ship && msg->Sender()) {
316  Contact* c = msg->Sender()->FindContact(target);
317 
318  if (c && c->GetIFF(msg->Sender()) > 10) {
319  sprintf_s(msg_buf, "%s %s.", TranslateVox(act_buf).data(), TranslateVox("unknown contact").data());
320  }
321 
322  else {
323  sprintf_s(msg_buf, "%s %s.",
324  TranslateVox(act_buf).data(),
325  target->Name());
326  }
327  }
328 
329  else if (target) {
330  sprintf_s(msg_buf, "%s %s.",
331  TranslateVox(act_buf).data(),
332  target->Name());
333  }
334 
335  else if (msg->Info().length()) {
336  sprintf_s(msg_buf, "%s %s",
337  TranslateVox(act_buf).data(),
338  (const char*) msg->Info());
339  }
340 
341  else {
342  strcpy_s(msg_buf, TranslateVox(act_buf).data());
343  }
344 
345  char last_char = msg_buf[strlen(msg_buf)-1];
346  if (last_char != '!' && last_char != '.' && last_char != '?')
347  strcat_s(msg_buf, ".");
348 
349  // final format:
350  if (dst_buf[0] && src_buf[0]) {
351  sprintf_s(txt_buf, "%s %s. %s", TranslateVox(dst_buf).data(), TranslateVox(src_buf).data(), msg_buf);
352  txt_buf[0] = toupper(txt_buf[0]);
353  }
354 
355  else if (src_buf[0]) {
356  sprintf_s(txt_buf, "%s. %s", TranslateVox(src_buf).data(), msg_buf);
357  txt_buf[0] = toupper(txt_buf[0]);
358  }
359 
360  else if (dst_buf[0]) {
361  sprintf_s(txt_buf, "%s %s", TranslateVox(dst_buf).data(), msg_buf);
362  txt_buf[0] = toupper(txt_buf[0]);
363  }
364 
365  else {
366  strcpy_s(txt_buf, msg_buf);
367  }
368 
369  // vox:
370  const char* path[8] = { "1", "1", "2", "3", "4", "5", "6", "7" };
371 
372  RadioVox* vox = new(__FILE__,__LINE__) RadioVox(vox_channel, path[vox_channel], txt_buf);
373 
374  if (vox) {
375  vox->AddPhrase(dst_buf);
376  vox->AddPhrase(src_buf);
377  vox->AddPhrase(act_buf);
378 
379  if (!vox->Start()) {
380  RadioView::Message(txt_buf);
381  delete vox;
382  }
383  }
384 }
385 
386 // +----------------------------------------------------------------------+
387 
388 void
390 {
391  if (radio_traffic)
393 }