Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
NetData.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: NetData.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Payload structures for multiplayer network packets
13 */
14 
15 #include "MemDebug.h"
16 #include "NetData.h"
17 #include "NetLink.h"
18 #include "NetMsg.h"
19 #include "RadioMessage.h"
20 #include "Ship.h"
21 #include "Shot.h"
22 #include "Sim.h"
23 #include "Instruction.h"
24 #include "Weapon.h"
25 #include "Element.h"
26 #include "System.h"
27 #include "Power.h"
28 #include "Shield.h"
29 
30 #include "Game.h"
31 
32 // +--------------------------------------------------------------------+
33 // DATA SIZE OFFSET
34 // -------- ----------------- ---------
35 // type: 1 0
36 // size: 1 1
37 // objid: 2 2
38 // loc: 9 (3 x 24 bits) 4
39 // vel: 6 (3 x 16 bits) 13
40 // euler: 4 (3 x 10 bits) 19
41 // status: 1 23
42 
43 const int LOCATION_OFFSET = 8000000;
44 const int VELOCITY_OFFSET = 32000;
45 const double EULER_SCALE = 2*PI / (1<<10);
46 
47 BYTE*
49 {
50  data[ 0] = TYPE;
51  data[ 1] = SIZE;
52 
53  // obj id
54  data[ 2] = (BYTE) ((objid & 0xff00) >> 8);
55  data[ 3] = (BYTE) ((objid & 0x00ff) );
56 
57  // location
58  DWORD x = (DWORD) (((int) location.x + LOCATION_OFFSET) & 0x00ffffff);
59  DWORD y = (DWORD) (((int) location.y + LOCATION_OFFSET) & 0x00ffffff);
60  DWORD z = (DWORD) (((int) location.z + LOCATION_OFFSET) & 0x00ffffff);
61 
62  data[ 4] = (BYTE) ((x & 0x00ff0000) >> 16);
63  data[ 5] = (BYTE) ((x & 0x0000ff00) >> 8);
64  data[ 6] = (BYTE) ((x & 0x000000ff) );
65 
66  data[ 7] = (BYTE) ((y & 0x00ff0000) >> 16);
67  data[ 8] = (BYTE) ((y & 0x0000ff00) >> 8);
68  data[ 9] = (BYTE) ((y & 0x000000ff) );
69 
70  data[10] = (BYTE) ((z & 0x00ff0000) >> 16);
71  data[11] = (BYTE) ((z & 0x0000ff00) >> 8);
72  data[12] = (BYTE) ((z & 0x000000ff) );
73 
74  // velocity
75  WORD vx = (WORD) (((int) velocity.x + VELOCITY_OFFSET) & 0x0000ffff);
76  WORD vy = (WORD) (((int) velocity.y + VELOCITY_OFFSET) & 0x0000ffff);
77  WORD vz = (WORD) (((int) velocity.z + VELOCITY_OFFSET) & 0x0000ffff);
78 
79  data[13] = (BYTE) ((vx & 0xff00) >> 8);
80  data[14] = (BYTE) ((vx & 0x00ff));
81 
82  data[15] = (BYTE) ((vy & 0xff00) >> 8);
83  data[16] = (BYTE) ((vy & 0x00ff));
84 
85  data[17] = (BYTE) ((vz & 0xff00) >> 8);
86  data[18] = (BYTE) ((vz & 0x00ff));
87 
88  // orientation
89  if (_finite(euler.x)) {
90  while (euler.x < 0) euler.x += 2*PI;
91  while (euler.x > 2*PI) euler.x -= 2*PI;
92  }
93  else {
94  euler.x = 0;
95  }
96 
97  if (_finite(euler.y)) {
98  while (euler.y < 0) euler.y += 2*PI;
99  while (euler.y > 2*PI) euler.y -= 2*PI;
100  }
101  else {
102  euler.y = 0;
103  }
104 
105  if (_finite(euler.z)) {
106  while (euler.z < 0) euler.z += 2*PI;
107  while (euler.z > 2*PI) euler.z -= 2*PI;
108  }
109  else {
110  euler.z = 0;
111  }
112 
113  WORD ox = (WORD) (((int) (euler.x / EULER_SCALE)) & 0x000003ff);
114  WORD oy = (WORD) (((int) (euler.y / EULER_SCALE)) & 0x000003ff);
115  WORD oz = (WORD) (((int) (euler.z / EULER_SCALE)) & 0x000003ff);
116 
117  DWORD o = (ox << 20) | (oy << 10) | (oz);
118 
119  data[19] = (BYTE) ((o & 0xff000000) >> 24);
120  data[20] = (BYTE) ((o & 0x00ff0000) >> 16);
121  data[21] = (BYTE) ((o & 0x0000ff00) >> 8);
122  data[22] = (BYTE) ((o & 0x000000ff) );
123 
124  // status bits
125  data[23] = throttle << 7 |
126  augmenter << 6 |
127  gear << 5 |
128  (shield >> 2) & 0x1f;
129 
130  return data;
131 }
132 
133 bool
134 NetObjLoc::Unpack(const BYTE* p)
135 {
136  if (p && p[0] == TYPE && p[1] == SIZE) {
137  CopyMemory(data, p, SIZE);
138 
139  objid = (data[ 2] << 8) |
140  (data[ 3] );
141 
142  int x = (data[ 4] << 16) |
143  (data[ 5] << 8) |
144  (data[ 6] );
145 
146  int y = (data[ 7] << 16) |
147  (data[ 8] << 8) |
148  (data[ 9] );
149 
150  int z = (data[10] << 16) |
151  (data[11] << 8) |
152  (data[12] );
153 
154  int vx = (data[13] << 8) |
155  (data[14] );
156 
157  int vy = (data[15] << 8) |
158  (data[16] );
159 
160  int vz = (data[17] << 8) |
161  (data[18] );
162 
163  DWORD o = (data[19] << 24) |
164  (data[20] << 16) |
165  (data[21] << 8) |
166  (data[22] );
167 
168  WORD ox = (WORD) ((o >> 20) & 0x03ff);
169  WORD oy = (WORD) ((o >> 10) & 0x03ff);
170  WORD oz = (WORD) ((o ) & 0x03ff);
171 
172  throttle = data[23] & 0x80 ? true : false;
173  augmenter = data[23] & 0x40 ? true : false;
174  gear = data[23] & 0x20 ? true : false;
175  shield = (data[23] & 0x1f) << 2;
176 
177  location = Point(x -LOCATION_OFFSET, y -LOCATION_OFFSET, z -LOCATION_OFFSET);
178  velocity = Point(vx-VELOCITY_OFFSET, vy-VELOCITY_OFFSET, vz-VELOCITY_OFFSET);
179  euler = Point(ox*EULER_SCALE, oy*EULER_SCALE, oz*EULER_SCALE);
180  return true;
181  }
182 
183  return false;
184 }
185 
186 // +--------------------------------------------------------------------+
187 
188 BYTE*
190 {
191  ZeroMemory(data, SIZE);
192 
193  data[0] = TYPE;
194  data[1] = SIZE;
195 
196  for (int i = 0; i < name.length() && i < 16; i++)
197  data[2+i] = name[i];
198 
199  for (int i = 0; i < pass.length() && i < 16; i++)
200  data[18+i] = pass[i];
201 
202  for (int i = 0; i < elem.length() && i < 31; i++)
203  data[34+i] = elem[i];
204 
205  data[65] = (BYTE) index;
206 
207  for (int i = 0; i < serno.length() && i < 60; i++)
208  data[66+i] = serno[i];
209 
210  return data;
211 }
212 
213 bool
215 {
216  if (p && p[0] == TYPE && p[1] == SIZE) {
217  CopyMemory(data, p, SIZE);
218 
219  char buf[64];
220 
221  CopyMemory(buf, data+2, 16);
222  buf[16] = 0;
223  name = buf;
224 
225  CopyMemory(buf, data+18, 16);
226  buf[16] = 0;
227  pass = buf;
228 
229  CopyMemory(buf, data+34, 31);
230  buf[31] = 0;
231  elem = buf;
232 
233  index = data[65];
234 
235  CopyMemory(buf, data+66, 60);
236  buf[61] = 0;
237  serno = buf;
238  return true;
239  }
240 
241  return false;
242 }
243 
244 // +--------------------------------------------------------------------+
245 
247 : index(0), integrity(0), respawns(0), decoys(0), probes(0), fuel(0),
248 shield(0), nid(0)
249 {
250  ZeroMemory(ammo, sizeof(ammo));
251 }
252 
253 void
255 {
256  if (a) {
257  CopyMemory(ammo, a, sizeof(ammo));
258  }
259 }
260 
261 void
263 {
264  SetName(s->Name());
265  SetObjID(s->GetObjID());
266 
267  if (s->GetElement()) {
268  SetElement(s->GetElement()->Name());
270  }
271 
272  if (s->GetRegion())
273  SetRegion(s->GetRegion()->Name());
274 
275  SetLocation(s->Location());
276  SetVelocity(s->Velocity());
277  SetIntegrity(s->Integrity());
279 
280  if (s->GetDecoy())
281  SetDecoys(s->GetDecoy()->Ammo());
282 
283  if (s->GetProbeLauncher())
285 
286  if (s->Reactors().size())
287  SetFuel(s->Reactors()[0]->Charge());
288 
289  Shield* shield = s->GetShield();
290  if (shield)
291  SetShield((int) shield->GetPowerLevel());
292 }
293 
294 BYTE*
296 {
297  ZeroMemory(data, SIZE);
298 
299  data[ 0] = TYPE;
300  data[ 1] = SIZE;
301  data[ 2] = (BYTE) ((objid & 0xff00) >> 8);
302  data[ 3] = (BYTE) ((objid & 0x00ff) );
303 
304  float* f = (float*) (data + 4);
305  *f++ = (float) loc.x; // bytes 4 - 7
306  *f++ = (float) loc.y; // bytes 8 - 11
307  *f++ = (float) loc.z; // bytes 12 - 15
308  *f++ = (float) integrity; // bytes 16 - 19
309 
310  for (int i = 0; i < name.length() && i < 16; i++)
311  data[20+i] = name[i];
312 
313  for (int i = 0; i < elem.length() && i < 32; i++)
314  data[36+i] = elem[i];
315 
316  for (int i = 0; i < region.length() && i < 32; i++)
317  data[68+i] = region[i];
318 
319  int* p = (int*) (data + 100);
320  *p++ = respawns; // bytes 100 - 103
321  *p++ = decoys; // bytes 104 - 107
322  *p++ = probes; // bytes 108 - 111
323 
324  data[112]= (BYTE) fuel; // byte 112
325  data[113]= (BYTE) shield; // byte 113
326 
327  BYTE* a = data + 116;
328  for (int i = 0; i < 16; i++) { // bytes 116 - 179
329  if (ammo[i] >= 0) {
330  *a++ = ammo[i];
331  }
332  else {
333  *a++ = 255;
334  }
335  }
336 
337  data[180] = (BYTE) index;
338 
339  f = (float*) (data + 184);
340  *f++ = (float) velocity.x;
341  *f++ = (float) velocity.y;
342  *f++ = (float) velocity.z;
343 
344  return data;
345 }
346 
347 bool
349 {
350  if (p && p[0] == TYPE && p[1] == SIZE) {
351  CopyMemory(data, p, SIZE);
352 
353  objid = (data[2] << 8) | data[3];
354 
355  float* f = (float*) (data + 4);
356  loc.x = *f++;
357  loc.y = *f++;
358  loc.z = *f++;
359  integrity = *f++;
360 
361  char buf[64];
362  CopyMemory(buf, data+20, 16);
363  buf[16] = 0;
364  name = buf;
365 
366  CopyMemory(buf, data+36, 32);
367  buf[16] = 0;
368  elem = buf;
369 
370  CopyMemory(buf, data+68, 32);
371  buf[16] = 0;
372  region = buf;
373 
374  int* p = (int*) (data + 100);
375  respawns = *p++;
376  decoys = *p++;
377  probes = *p++;
378 
379  fuel = data[112];
380  shield = data[113];
381 
382  CopyMemory(ammo, data+116, 16);
383 
384  index = data[180];
385 
386  f = (float*) (data + 184);
387  velocity.x = *f++;
388  velocity.y = *f++;
389  velocity.z = *f++;
390 
391  return true;
392  }
393 
394  return false;
395 }
396 
397 // +--------------------------------------------------------------------+
398 
399 BYTE*
401 {
402  ZeroMemory(data, SIZE);
403 
404  data[0] = TYPE;
405  data[1] = SIZE;
406 
407  data[2] = (BYTE) ((objid & 0xff00) >> 8);
408  data[3] = (BYTE) ((objid & 0x00ff) );
409  data[4] = (BYTE) (disconnected);
410 
411  return data;
412 }
413 
414 bool
416 {
417  if (p && p[0] == TYPE && p[1] == SIZE) {
418  CopyMemory(data, p, SIZE);
419 
420  objid = (data[2] << 8) | data[3];
421  disconnected = data[4] ? true : false;
422 
423  return true;
424  }
425 
426  return false;
427 }
428 
429 // +--------------------------------------------------------------------+
430 
431 BYTE*
433 {
434  ZeroMemory(data, SIZE);
435 
436  data[0] = TYPE;
437  data[1] = SIZE;
438 
439  return data;
440 }
441 
442 bool
443 NetDisconnect::Unpack(const BYTE* p)
444 {
445  if (p && p[0] == TYPE && p[1] == SIZE) {
446  CopyMemory(data, p, SIZE);
447  return true;
448  }
449 
450  return false;
451 }
452 
453 // +--------------------------------------------------------------------+
454 
455 BYTE*
457 {
458  ZeroMemory(data, SIZE);
459 
460  data[0] = TYPE;
461  data[1] = SIZE;
462 
463  data[2] = (BYTE) ((objid & 0xff00) >> 8);
464  data[3] = (BYTE) ((objid & 0x00ff) );
465  data[4] = (BYTE) ((shotid & 0xff00) >> 8);
466  data[5] = (BYTE) ((shotid & 0x00ff) );
467 
468  float* p = (float*) (data + 6);
469  *p = damage;
470 
471  return data;
472 }
473 
474 bool
475 NetObjDamage::Unpack(const BYTE* p)
476 {
477  if (p && p[0] == TYPE && p[1] == SIZE) {
478  CopyMemory(data, p, SIZE);
479 
480  objid = (data[2] << 8) | data[3];
481  shotid = (data[4] << 8) | data[5];
482  damage = *(float*) (data + 6);
483 
484  return true;
485  }
486 
487  return false;
488 }
489 
490 // +--------------------------------------------------------------------+
491 
492 BYTE*
494 {
495  ZeroMemory(data, SIZE);
496 
497  data[0] = TYPE;
498  data[1] = SIZE;
499 
500  data[2] = (BYTE) ((objid & 0xff00) >> 8);
501  data[3] = (BYTE) ((objid & 0x00ff) );
502 
503  float* p = (float*) (data + 4);
504  *p = (float) damage;
505 
506  data[8] = (BYTE) (sysix+1);
507  data[9] = dmgtype;
508 
509  return data;
510 }
511 
512 bool
513 NetSysDamage::Unpack(const BYTE* p)
514 {
515  if (p && p[0] == TYPE && p[1] == SIZE) {
516  CopyMemory(data, p, SIZE);
517 
518  objid = (data[2] << 8) | data[3];
519  damage = *(float*) (data + 4);
520  sysix = data[8];
521  dmgtype = data[9];
522 
523  sysix--;
524  return true;
525  }
526 
527  return false;
528 }
529 
530 // +--------------------------------------------------------------------+
531 
532 BYTE*
534 {
535  ZeroMemory(data, SIZE);
536 
537  data[0] = TYPE;
538  data[1] = SIZE;
539 
540  data[2] = (BYTE) ((objid & 0xff00) >> 8);
541  data[3] = (BYTE) ((objid & 0x00ff) );
542  data[4] = (BYTE) (sysix+1);
543  data[5] = (BYTE) (status);
544  data[6] = (BYTE) (power);
545  data[7] = (BYTE) (reactor);
546 
547  float* f = (float*) (data + 8);
548  *f = (float) avail;
549 
550  return data;
551 }
552 
553 bool
554 NetSysStatus::Unpack(const BYTE* p)
555 {
556  if (p && p[0] == TYPE && p[1] == SIZE) {
557  CopyMemory(data, p, SIZE);
558 
559  objid = (data[2] << 8) | data[3];
560  sysix = data[4];
561  status = data[5];
562  power = data[6];
563  reactor = data[7];
564 
565  float* f = (float*) (data + 8);
566  avail = *f;
567 
568  sysix--;
569  return true;
570  }
571 
572  return false;
573 }
574 
575 // +--------------------------------------------------------------------+
576 
577 BYTE*
579 {
580  ZeroMemory(data, SIZE);
581 
582  data[0] = TYPE;
583  data[1] = SIZE;
584 
585  data[2] = (BYTE) ((objid & 0xff00) >> 8);
586  data[3] = (BYTE) ((objid & 0x00ff) );
587  data[4] = (BYTE) ((kill_id & 0xff00) >> 8);
588  data[5] = (BYTE) ((kill_id & 0x00ff) );
589  data[6] = (BYTE) killtype;
590  data[7] = (BYTE) respawn;
591 
592  float* f = (float*) (data + 8);
593  *f++ = (float) loc.x;
594  *f++ = (float) loc.y;
595  *f++ = (float) loc.z;
596 
597  data[20] = (BYTE) deck;
598 
599  return data;
600 }
601 
602 bool
603 NetObjKill::Unpack(const BYTE* p)
604 {
605  if (p && p[0] == TYPE && p[1] == SIZE) {
606  CopyMemory(data, p, SIZE);
607 
608  objid = (data[2] << 8) | data[3];
609  kill_id = (data[4] << 8) | data[5];
610  killtype = data[6];
611  respawn = data[7] ? true : false;
612 
613  float* f = (float*) (data + 8);
614  loc.x = *f++;
615  loc.y = *f++;
616  loc.z = *f++;
617 
618  deck = data[20];
619 
620  return true;
621  }
622 
623  return false;
624 }
625 
626 // +--------------------------------------------------------------------+
627 
628 BYTE*
630 {
631  ZeroMemory(data, SIZE);
632 
633  data[0] = TYPE;
634  data[1] = SIZE;
635 
636  data[2] = (BYTE) ((objid & 0xff00) >> 8);
637  data[3] = (BYTE) ((objid & 0x00ff) );
638  data[4] = (BYTE) ((fc_src & 0xff00) >> 8);
639  data[5] = (BYTE) ((fc_src & 0x00ff) );
640  data[6] = (BYTE) ((fc_dst & 0xff00) >> 8);
641  data[7] = (BYTE) ((fc_dst & 0x00ff) );
642  data[8] = (BYTE) transtype;
643 
644  float* f = (float*) (data + 12);
645  *f++ = (float) location.x; // bytes 12 - 15
646  *f++ = (float) location.y; // bytes 16 - 19
647  *f++ = (float) location.z; // bytes 20 - 23
648 
649  char* p = (char*) (data + 24);
650  strncpy(p, region.data(), 31);
651 
652  return data;
653 }
654 
655 bool
656 NetObjHyper::Unpack(const BYTE* p)
657 {
658  if (p && p[0] == TYPE && p[1] == SIZE) {
659  CopyMemory(data, p, SIZE);
660 
661  objid = (data[2] << 8) | data[3];
662  fc_src = (data[4] << 8) | data[5];
663  fc_dst = (data[6] << 8) | data[7];
664  transtype = data[8];
665 
666  float* f = (float*) (data + 12);
667  location.x = *f++;
668  location.y = *f++;
669  location.z = *f++;
670 
671  region = (char*) (data + 24);
672 
673  return true;
674  }
675 
676  return false;
677 }
678 
679 // +--------------------------------------------------------------------+
680 
681 BYTE*
683 {
684  ZeroMemory(data, SIZE);
685 
686  data[0] = TYPE;
687  data[1] = SIZE;
688 
689  data[2] = (BYTE) ((objid & 0xff00) >> 8);
690  data[3] = (BYTE) ((objid & 0x00ff) );
691  data[4] = (BYTE) ((tgtid & 0xff00) >> 8);
692  data[5] = (BYTE) ((tgtid & 0x00ff) );
693  data[6] = (BYTE) (sysix+1);
694 
695  return data;
696 }
697 
698 bool
699 NetObjTarget::Unpack(const BYTE* p)
700 {
701  if (p && p[0] == TYPE && p[1] == SIZE) {
702  CopyMemory(data, p, SIZE);
703 
704  objid = (data[2] << 8) | data[3];
705  tgtid = (data[4] << 8) | data[5];
706  sysix = data[6];
707 
708  sysix--;
709  return true;
710  }
711 
712  return false;
713 }
714 
715 // +--------------------------------------------------------------------+
716 
717 BYTE*
719 {
720  ZeroMemory(data, SIZE);
721 
722  data[0] = TYPE;
723  data[1] = SIZE;
724 
725  data[2] = (BYTE) ((objid & 0xff00) >> 8);
726  data[3] = (BYTE) ((objid & 0x00ff) );
727  data[4] = (BYTE) (emcon);
728 
729  return data;
730 }
731 
732 bool
733 NetObjEmcon::Unpack(const BYTE* p)
734 {
735  if (p && p[0] == TYPE && p[1] == SIZE) {
736  CopyMemory(data, p, SIZE);
737 
738  objid = (data[2] << 8) | data[3];
739  emcon = data[4];
740 
741  return true;
742  }
743 
744  return false;
745 }
746 
747 // +--------------------------------------------------------------------+
748 
749 BYTE*
751 {
752  ZeroMemory(data, SIZE);
753 
754  data[0] = TYPE;
755  data[1] = SIZE;
756 
757  data[2] = (BYTE) ((objid & 0xff00) >> 8);
758  data[3] = (BYTE) ((objid & 0x00ff) );
759  data[4] = (BYTE) ((tgtid & 0xff00) >> 8);
760  data[5] = (BYTE) ((tgtid & 0x00ff) );
761  data[6] = (BYTE) (sysix+1);
762  data[7] = (BYTE) index;
763  data[8] = (BYTE) count;
764  data[9] = ((BYTE) decoy << 1) |
765  ((BYTE) probe );
766 
767  return data;
768 }
769 
770 bool
771 NetWepTrigger::Unpack(const BYTE* p)
772 {
773  if (p && p[0] == TYPE && p[1] == SIZE) {
774  CopyMemory(data, p, SIZE);
775 
776  objid = (data[2] << 8) | data[3];
777  tgtid = (data[4] << 8) | data[5];
778  sysix = data[6];
779  index = data[7];
780  count = data[8];
781  decoy = (data[9] & 0x02) ? true : false;
782  probe = (data[9] & 0x01) ? true : false;
783 
784  sysix--;
785  return true;
786  }
787 
788  return false;
789 }
790 
791 // +--------------------------------------------------------------------+
792 
793 BYTE*
795 {
796  ZeroMemory(data, SIZE);
797 
798  data[0] = TYPE;
799  data[1] = SIZE;
800 
801  data[2] = (BYTE) ((objid & 0xff00) >> 8);
802  data[3] = (BYTE) ((objid & 0x00ff) );
803  data[4] = (BYTE) ((tgtid & 0xff00) >> 8);
804  data[5] = (BYTE) ((tgtid & 0x00ff) );
805  data[6] = (BYTE) ((wepid & 0xff00) >> 8);
806  data[7] = (BYTE) ((wepid & 0x00ff) );
807  data[8] = (BYTE) (sysix+1);
808  data[9] = (BYTE) index;
809  data[10] = ((BYTE) decoy << 1) |
810  ((BYTE) probe );
811 
812  return data;
813 }
814 
815 bool
816 NetWepRelease::Unpack(const BYTE* p)
817 {
818  if (p && p[0] == TYPE && p[1] == SIZE) {
819  CopyMemory(data, p, SIZE);
820 
821  objid = (data[2] << 8) | data[3];
822  tgtid = (data[4] << 8) | data[5];
823  wepid = (data[6] << 8) | data[7];
824  sysix = data[8];
825  index = data[9];
826  decoy = (data[10] & 0x02) ? true : false;
827  probe = (data[10] & 0x01) ? true : false;
828 
829  sysix--;
830  return true;
831  }
832 
833  return false;
834 }
835 
836 // +--------------------------------------------------------------------+
837 
838 BYTE*
840 {
841  ZeroMemory(data, SIZE);
842 
843  data[0] = TYPE;
844  data[1] = SIZE;
845  data[2] = (BYTE) ((objid & 0xff00) >> 8);
846  data[3] = (BYTE) ((objid & 0x00ff) );
847 
848  return data;
849 }
850 
851 bool
852 NetWepDestroy::Unpack(const BYTE* p)
853 {
854  if (p && p[0] == TYPE && p[1] == SIZE) {
855  CopyMemory(data, p, SIZE);
856  objid = (data[2] << 8) | data[3];
857  return true;
858  }
859 
860  return false;
861 }
862 
863 // +--------------------------------------------------------------------+
864 
866 {
867  delete radio_message;
868 }
869 
870 void
872 {
873  radio_message = new(__FILE__,__LINE__) RadioMessage(*m);
874 }
875 
876 BYTE*
878 {
879  ZeroMemory(data, SIZE);
880 
881  if (radio_message) {
882  length = 55 + radio_message->Info().length();
883 
884  if (length > SIZE)
885  length = SIZE;
886 
887  data[0] = TYPE;
888  data[1] = (BYTE) length;
889 
890  if (radio_message->Sender()) {
891  objid = radio_message->Sender()->GetObjID();
892  data[2] = (BYTE) ((objid & 0xff00) >> 8);
893  data[3] = (BYTE) ((objid & 0x00ff) );
894  }
895 
896  if (radio_message->DestinationShip()) {
897  DWORD dstid = radio_message->DestinationShip()->GetObjID();
898  data[4] = (BYTE) ((dstid & 0xff00) >> 8);
899  data[5] = (BYTE) ((dstid & 0x00ff) );
900  }
901 
902  data[6] = (BYTE) radio_message->Action();
903  data[7] = (BYTE) radio_message->Channel();
904 
905  if (radio_message->TargetList().size() > 0) {
906  SimObject* tgt = radio_message->TargetList().at(0);
907  DWORD tgtid = tgt->GetObjID();
908  data[8] = (BYTE) ((tgtid & 0xff00) >> 8);
909  data[9] = (BYTE) ((tgtid & 0x00ff) );
910  }
911 
912  float* f = (float*) (data + 10);
913  *f++ = (float) radio_message->Location().x; // bytes 10 - 13
914  *f++ = (float) radio_message->Location().y; // bytes 14 - 17
915  *f++ = (float) radio_message->Location().z; // bytes 18 - 21
916 
917  char* p = (char*) (data + 22);
918 
919  Element* dst_elem = radio_message->DestinationElem();
920  if (dst_elem)
921  strncpy(p, dst_elem->Name().data(), 31);
922 
923  p = (char*) (data + 55);
924  strncpy(p, radio_message->Info().data(), 128);
925 
926  data[SIZE-1] = 0;
927  }
928 
929  return data;
930 }
931 
932 bool
933 NetCommMsg::Unpack(const BYTE* p)
934 {
935  if (p && p[0] == TYPE) {
936  length = p[1];
937  ZeroMemory(data, SIZE);
938  CopyMemory(data, p, length);
939 
940  DWORD dstid = 0;
941  DWORD tgtid = 0;
942  int action = 0;
943  int channel = 0;
944  Point loc;
945  Text elem_name;
946  Text info;
947 
948  objid = (data[2] << 8) | data[3];
949  dstid = (data[4] << 8) | data[5];
950  tgtid = (data[8] << 8) | data[9];
951  action = data[6];
952  channel = data[7];
953 
954  float* f = (float*) (data + 10);
955  loc.x = *f++;
956  loc.y = *f++;
957  loc.z = *f++;
958 
959  elem_name = (char*) (data + 22);
960 
961  if (length > 55)
962  info = (char*) (data + 55);
963 
964  Sim* sim = Sim::GetSim();
965  Ship* src = sim->FindShipByObjID(objid);
966  Ship* dst = sim->FindShipByObjID(dstid);
967  Element* elem = sim->FindElement(elem_name);
968 
969  delete radio_message;
970  if (elem)
971  radio_message = new(__FILE__,__LINE__) RadioMessage(elem, src, action);
972  else
973  radio_message = new(__FILE__,__LINE__) RadioMessage(dst, src, action);
974 
975  radio_message->SetChannel(channel);
976  radio_message->SetLocation(loc);
977  radio_message->SetInfo(info);
978 
979  if (tgtid) {
980  SimObject* tgt = sim->FindShipByObjID(tgtid);
981 
982  if (!tgt)
983  tgt = sim->FindShotByObjID(tgtid);
984 
985  if (tgt)
986  radio_message->AddTarget(tgt);
987  }
988 
989  return true;
990  }
991 
992  return false;
993 }
994 
995 // +--------------------------------------------------------------------+
996 
997 BYTE*
999 {
1000  ZeroMemory(data, SIZE);
1001 
1002  int chatlen = text.length();
1003 
1004  if (chatlen > MAX_CHAT)
1005  chatlen = MAX_CHAT;
1006 
1007  length = HDR_LEN + NAME_LEN + chatlen;
1008 
1009  data[0] = TYPE;
1010  data[1] = (BYTE) length;
1011  data[2] = (BYTE) ((dstid & 0xff00) >> 8);
1012  data[3] = (BYTE) ((dstid & 0x00ff) );
1013 
1014  char* p = (char*) (data + HDR_LEN);
1015  strncpy(p, name.data(), NAME_LEN);
1016 
1017  p = (char*) (data + HDR_LEN + NAME_LEN);
1018  strncpy(p, text.data(), chatlen);
1019 
1020  return data;
1021 }
1022 
1023 bool
1024 NetChatMsg::Unpack(const BYTE* p)
1025 {
1026  if (p && p[0] == TYPE) {
1027  length = p[1];
1028  ZeroMemory(data, SIZE);
1029  CopyMemory(data, p, length);
1030 
1031  dstid = (data[2] << 8) | data[3];
1032 
1033  char buffer[NAME_LEN+1];
1034  ZeroMemory(buffer, NAME_LEN+1);
1035  CopyMemory(buffer, data + HDR_LEN, NAME_LEN);
1036 
1037  name = buffer;
1038 
1039  if (length > HDR_LEN + NAME_LEN)
1040  text = (char*) (data + HDR_LEN + NAME_LEN);
1041 
1042  return true;
1043  }
1044 
1045  return false;
1046 }
1047 
1048 // +--------------------------------------------------------------------+
1049 
1051 { }
1052 
1053 BYTE*
1055 {
1056  ZeroMemory(data, SIZE);
1057 
1058  data[0] = TYPE;
1059  data[1] = SIZE;
1060 
1061  strncpy((char*) (data + 8), name.data(), NAME_LEN-1);
1062 
1063  return data;
1064 }
1065 
1066 bool
1068 {
1069  if (p && p[0] == TYPE) {
1070  ZeroMemory(data, SIZE);
1071  CopyMemory(data, p, SIZE);
1072 
1073  name = (const char*) (data + 8);
1074 
1075  return true;
1076  }
1077 
1078  return false;
1079 }
1080 
1081 // +--------------------------------------------------------------------+
1082 
1084 : iff(0), type(0), intel(0), alert(false), in_flight(false)
1085 {
1086  for (int i = 0; i < 16; i++)
1087  load[i] = -1;
1088 }
1089 
1090 void
1092 {
1093  if (l) {
1094  CopyMemory(load, l, sizeof(load));
1095  }
1096  else {
1097  for (int i = 0; i < 16; i++)
1098  load[i] = -1;
1099  }
1100 }
1101 
1102 void
1104 {
1105  if (s) {
1106  CopyMemory(slots, s, sizeof(slots));
1107  }
1108  else {
1109  for (int i = 0; i < 4; i++)
1110  slots[i] = -1;
1111  }
1112 }
1113 
1114 BYTE*
1116 {
1117  ZeroMemory(data, SIZE);
1118 
1119  data[0] = TYPE;
1120  data[1] = SIZE;
1121 
1122  data[2] = (BYTE) iff;
1123  data[3] = (BYTE) type;
1124  data[4] = (BYTE) intel;
1125  data[5] = (BYTE) obj_code;
1126 
1127  for (int i = 0; i < 16; i++)
1128  data[6+i] = (BYTE) load[i];
1129 
1130  strncpy((char*) (data + 22), name.data(), NAME_LEN-1);
1131  strncpy((char*) (data + 54), commander.data(), NAME_LEN-1);
1132  strncpy((char*) (data + 86), objective.data(), NAME_LEN-1);
1133  strncpy((char*) (data + 118), carrier.data(), NAME_LEN-1);
1134 
1135  data[150] = (BYTE) squadron;
1136  data[151] = (BYTE) slots[0];
1137  data[152] = (BYTE) slots[1];
1138  data[153] = (BYTE) slots[2];
1139  data[154] = (BYTE) slots[3];
1140  data[155] = (BYTE) alert;
1141  data[156] = (BYTE) in_flight;
1142 
1143  return data;
1144 }
1145 
1146 bool
1148 {
1149  if (p && p[0] == TYPE) {
1150  ZeroMemory(data, SIZE);
1151  CopyMemory(data, p, SIZE);
1152 
1153  iff = data[2];
1154  type = data[3];
1155  intel = data[4];
1156  obj_code = data[5];
1157 
1158  for (int i = 0; i < 16; i++) {
1159  load[i] = data[6+i] == 255 ? -1 : data[6+i];
1160  }
1161 
1162  name = (const char*) (data + 22);
1163  commander = (const char*) (data + 54);
1164  objective = (const char*) (data + 86);
1165  carrier = (const char*) (data + 118);
1166 
1167  squadron = data[150];
1168 
1169  for (int i = 0; i < 4; i++) {
1170  slots[i] = data[151+i];
1171  if (slots[i] >= 255)
1172  slots[i] = -1;
1173  }
1174 
1175  alert = data[155] ? true : false;
1176  in_flight = data[156] ? true : false;
1177 
1178  return true;
1179  }
1180 
1181  return false;
1182 }
1183 
1184 // +--------------------------------------------------------------------+
1185 
1186 BYTE*
1188 {
1189  ZeroMemory(data, SIZE);
1190 
1191  data[ 0] = TYPE;
1192  data[ 1] = SIZE;
1193 
1194  DWORD* p = (DWORD*) (data + 4);
1195  *p++ = (DWORD) objid;
1196  *p++ = (DWORD) squadron;
1197  *p++ = (DWORD) slot;
1198 
1199  return data;
1200 }
1201 
1202 bool
1204 {
1205  if (p && p[0] == TYPE) {
1206  ZeroMemory(data, SIZE);
1207  CopyMemory(data, p, SIZE);
1208 
1209  DWORD* p = (DWORD*) (data + 4);
1210  objid = *p++;
1211  squadron = (int) *p++;
1212  slot = (int) *p++;
1213 
1214  return true;
1215  }
1216 
1217  return false;
1218 }
1219 
1220 // +--------------------------------------------------------------------+
1221 
1223 : objid(0), create(true), index(0), navpoint(0)
1224 {
1225 }
1226 
1228 {
1229  delete navpoint;
1230 }
1231 
1232 void
1234 {
1235  if (navpoint) {
1236  delete navpoint;
1237  navpoint = 0;
1238  }
1239 
1240  if (n)
1241  navpoint = new(__FILE__,__LINE__) Instruction(*n);
1242 }
1243 
1244 BYTE*
1246 {
1247  ZeroMemory(data, SIZE);
1248 
1249  data[ 0] = TYPE;
1250  data[ 1] = SIZE;
1251 
1252  data[ 2] = (BYTE) ((objid & 0xff00) >> 8);
1253  data[ 3] = (BYTE) ((objid & 0x00ff) );
1254  data[ 4] = (BYTE) create;
1255  data[ 5] = (BYTE) index;
1256 
1257  if (!navpoint)
1258  return data;
1259 
1260  data[ 6] = (BYTE) navpoint->Action();
1261  data[ 7] = (BYTE) navpoint->Formation();
1262  data[ 8] = (BYTE) navpoint->Status();
1263  data[ 9] = (BYTE) navpoint->EMCON();
1264  data[10] = (BYTE) navpoint->WeaponsFree();
1265  data[11] = (BYTE) navpoint->Farcast();
1266 
1267  Point loc = navpoint->Location();
1268 
1269  float* f = (float*) (data + 12);
1270  *f++ = (float) loc.x; // bytes 12 - 15
1271  *f++ = (float) loc.y; // bytes 16 - 19
1272  *f++ = (float) loc.z; // bytes 20 - 23
1273  *f++ = (float) navpoint->HoldTime(); // bytes 24 - 27
1274  *f++ = (float) navpoint->Speed(); // bytes 28 - 31
1275 
1276  WORD tgtid = 0;
1277  if (navpoint->GetTarget())
1278  tgtid = (WORD) navpoint->GetTarget()->GetObjID();
1279 
1280  data[32] = (BYTE) ((tgtid & 0xff00) >> 8);
1281  data[33] = (BYTE) ((tgtid & 0x00ff) );
1282 
1283  strncpy((char*) (data + 34), navpoint->RegionName(), NAME_LEN-1);
1284  strncpy((char*) (data + 66), navpoint->TargetName(), NAME_LEN-1);
1285  strncpy((char*) (data + 98), elem.data(), NAME_LEN-1);
1286 
1287  return data;
1288 }
1289 
1290 bool
1291 NetNavData::Unpack(const BYTE* p)
1292 {
1293  if (p && p[0] == TYPE) {
1294  ZeroMemory(data, SIZE);
1295  CopyMemory(data, p, SIZE);
1296 
1297  int action;
1298  int formation;
1299  int status;
1300  int emcon;
1301  int wep_free;
1302  int farcast;
1303  int speed;
1304  float hold_time;
1305  Point loc;
1306  WORD tgtid = 0;
1307 
1308  const char* rgn_name = 0;
1309  const char* tgt_name = 0;
1310 
1311  objid = (data[ 2] << 8) |
1312  (data[ 3] );
1313 
1314  tgtid = (data[32] << 8) |
1315  (data[33] );
1316 
1317  create = data[ 4] ? true : false;
1318  index = data[ 5];
1319  action = data[ 6];
1320  formation = data[ 7];
1321  status = data[ 8];
1322  emcon = data[ 9];
1323  wep_free = data[10];
1324  farcast = data[11];
1325 
1326  float* f = (float*) (data + 12);
1327  loc.x = *f++;
1328  loc.y = *f++;
1329  loc.z = *f++;
1330  hold_time = *f++;
1331  speed = (int) *f++;
1332 
1333  rgn_name = (const char*) (data + 34);
1334  tgt_name = (const char*) (data + 66);
1335  elem = (const char*) (data + 98);
1336 
1337  if (navpoint) {
1338  delete navpoint;
1339  navpoint = 0;
1340  }
1341 
1342  Sim* sim = Sim::GetSim();
1343  SimRegion* rgn = 0;
1344 
1345  if (sim)
1346  rgn = sim->FindRegion(rgn_name);
1347 
1348  if (rgn)
1349  navpoint = new(__FILE__,__LINE__) Instruction(rgn, loc, action);
1350  else
1351  navpoint = new(__FILE__,__LINE__) Instruction(rgn_name, loc, action);
1352 
1353  navpoint->SetFormation(formation);
1354  navpoint->SetStatus(status);
1355  navpoint->SetEMCON(emcon);
1356  navpoint->SetWeaponsFree(wep_free);
1357  navpoint->SetFarcast(farcast);
1358  navpoint->SetHoldTime(hold_time);
1359  navpoint->SetSpeed(speed);
1360  navpoint->SetTarget(tgt_name);
1361 
1362  if (tgtid) {
1363  Sim* sim = Sim::GetSim();
1364  Ship* tgt = sim->FindShipByObjID(tgtid);
1365 
1366  if (tgt)
1367  navpoint->SetTarget(tgt);
1368  }
1369 
1370  if (index >= 255)
1371  index = -1;
1372 
1373  return true;
1374  }
1375 
1376  return false;
1377 }
1378 
1379 // +--------------------------------------------------------------------+
1380 
1381 BYTE*
1383 {
1384  ZeroMemory(data, SIZE);
1385 
1386  data[ 0] = TYPE;
1387  data[ 1] = SIZE;
1388 
1389  data[ 2] = (BYTE) ((objid & 0xff00) >> 8);
1390  data[ 3] = (BYTE) ((objid & 0x00ff) );
1391  data[ 4] = (BYTE) index;
1392 
1393  strncpy((char*) (data + 6), elem.data(), 31);
1394 
1395  return data;
1396 }
1397 
1398 bool
1399 NetNavDelete::Unpack(const BYTE* p)
1400 {
1401  if (p && p[0] == TYPE) {
1402  ZeroMemory(data, SIZE);
1403  CopyMemory(data, p, SIZE);
1404  int index = 0;
1405 
1406  objid = (data[ 2] << 8) |
1407  (data[ 3] );
1408 
1409  index = data[4];
1410  elem = (const char*) (data + 6);
1411 
1412  if (index >= 255)
1413  index = -1;
1414 
1415  return true;
1416  }
1417 
1418  return false;
1419 }
1420 
1421 // +--------------------------------------------------------------------+
1422 
1423 BYTE*
1425 {
1426  ZeroMemory(data, SIZE);
1427 
1428  data[0] = TYPE;
1429  data[1] = SIZE;
1430 
1431  data[2] = (BYTE) ((objid & 0xff00) >> 8);
1432  data[3] = (BYTE) ((objid & 0x00ff) );
1433 
1434  float* p = (float*) (data + 4);
1435  *p = damage;
1436 
1437  return data;
1438 }
1439 
1440 bool
1442 {
1443  if (p && p[0] == TYPE && p[1] == SIZE) {
1444  CopyMemory(data, p, SIZE);
1445 
1446  objid = (data[2] << 8) | data[3];
1447  damage = *(float*) (data + 4);
1448 
1449  return true;
1450  }
1451 
1452  return false;
1453 }