32 : type(t), id(n), name(s), iff(iff_code), enemy_intel(e),
33 parent(p), value(0), plan_value(0), unit_index(0), combatant(0),
34 expanded(false), sorties(0), kills(0), points(0),
35 current_zone(0), assigned_zone(0), zone_lock(false)
83 if (iff < 1 || iff >= 100)
199 ZeroMemory(p,
sizeof(p));
294 ZeroMemory(p,
sizeof(p));
372 if (type == t && (n < 0 ||
id == n))
376 while (!result && ++group) {
391 clone->combatant = combatant;
392 clone->region = region;
393 clone->location = location;
394 clone->value = value;
395 clone->expanded = expanded;
397 for (
int i = 0; i < units.
size(); i++) {
404 for (
int i = 0; i < components.
size(); i++) {
413 if (units.
size() > 0) {
436 CombatGroup::GetOrdinal()
const
438 static char ordinal[16];
440 int last_two_digits =
id % 100;
442 if (last_two_digits > 10 && last_two_digits < 20) {
443 sprintf_s(ordinal,
"ordinal.%d", last_two_digits);
446 if (suffix != ordinal)
447 sprintf_s(ordinal,
"%d%s",
id, suffix.
data());
449 sprintf_s(ordinal,
"%dth",
id);
452 int last_digit = last_two_digits % 10;
453 sprintf_s(ordinal,
"ordinal.%d", last_digit);
455 if (suffix != ordinal)
456 sprintf_s(ordinal,
"%d%s",
id, suffix.
data());
457 else if (last_digit == 1)
458 sprintf_s(ordinal,
"%dst",
id);
459 else if (last_digit == 2)
460 sprintf_s(ordinal,
"%dnd",
id);
461 else if (last_digit == 3)
462 sprintf_s(ordinal,
"%drd",
id);
464 sprintf_s(ordinal,
"%dth",
id);
473 static char desc[256];
474 static char name_desc[256];
477 sprintf_s(name_desc,
" \"%s\"", (
const char*) name);
482 case FORCE: strcpy_s(desc, (
const char*) name);
break;
484 case FLEET: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.FLEET").data(), name_desc);
break;
485 case CARRIER_GROUP: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.CARRIER_GROUP").data(), name_desc);
break;
486 case BATTLE_GROUP: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.BATTLE_GROUP").data(), name_desc);
break;
489 case WING: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.WING").data(), name_desc);
break;
493 case LCA_SQUADRON: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.LCA_SQUADRON").data(), name_desc);
break;
495 case BATTALION: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.BATTALION").data(), name_desc);
break;
497 case STARBASE: sprintf_s(desc,
"%s %d%s",
Game::GetText(
"CombatGroup.STARBASE").data(),
id, name_desc);
break;
498 case MINEFIELD: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.MINEFIELD").data(), name_desc);
break;
499 case BATTERY: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.BATTERY").data(), name_desc);
break;
500 case MISSILE: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.MISSILE").data(), name_desc);
break;
502 case C3I: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.C3I").data(), name_desc);
break;
503 case COMM_RELAY: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.COMM_RELAY").data(), name_desc);
break;
504 case EARLY_WARNING: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.EARLY_WARNING").data(), name_desc);
break;
506 case ECM: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.ECM").data(), name_desc);
break;
508 case SUPPORT: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.SUPPORT").data(), name_desc);
break;
509 case COURIER: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.COURIER").data(), name_desc);
break;
510 case SUPPLY: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.SUPPLY").data(), name_desc);
break;
511 case REPAIR: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.REPAIR").data(), name_desc);
break;
512 case MEDICAL: sprintf_s(desc,
"%s %s%s", GetOrdinal(),
Game::GetText(
"CombatGroup.MEDICAL").data(), name_desc);
break;
518 case RESOURCE: strcpy_s(desc, (
const char*) name);
break;
527 case PRIVATE: strcpy_s(desc, (
const char*) name);
break;
529 default: sprintf_s(desc,
"%s%s",
Game::GetText(
"CombatGroup.default").data(), name_desc);
break;
538 static char desc[256];
541 case FORCE: strcpy_s(desc, (
const char*) name);
break;
543 case FLEET: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.FLEET").data());
break;
548 case WING: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.WING").data());
break;
554 case BATTALION: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.BATTALION").data());
break;
555 case STATION: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.STATION").data());
break;
556 case STARBASE: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.STARBASE").data());
break;
557 case MINEFIELD: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.MINEFIELD").data());
break;
558 case BATTERY: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.BATTERY").data());
break;
560 case C3I: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.C3I").data());
break;
561 case COMM_RELAY: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.COMM_RELAY").data());
break;
564 case ECM: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.ECM").data());
break;
566 case SUPPORT: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.SUPPORT").data());
break;
567 case COURIER: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.COURIER").data());
break;
568 case MEDICAL: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.MEDICAL").data());
break;
569 case SUPPLY: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.SUPPLY").data());
break;
570 case REPAIR: sprintf_s(desc,
"%s %s", GetOrdinal(),
Game::GetText(
"CombatGroup.abrv.REPAIR").data());
break;
576 case RESOURCE: strcpy_s(desc, (
const char*) name);
break;
585 case PRIVATE: strcpy_s(desc, (
const char*) name);
break;
587 default: sprintf_s(desc,
"%s",
Game::GetText(
"CombatGroup.abrv.default").data());
break;
669 assigned_system =
Text();
734 pThis->live_comp.
clear();
742 pThis->live_comp.
append(comp);
794 if (live.
size() > 0) {
796 while (!result && ntries-- > 0) {
797 int index = rand() % live.
size();
798 result = live[index];
809 while (++comp && !result) {
822 int tmp_index = unit_index;
825 unit_index = tmp_index;
833 if (units.
size() > 0) {
842 if (live.
size() > 0) {
843 return live[unit_index++ % live.
size()];
847 if (components.
size() > 0) {
848 return components[unit_index % components.
size()]->GetNextUnit();
857 if (units.
size() > 0) {
861 if (unit->
Name() == name) {
889 static const char* group_name[] = {
893 "intercept_squadron",
898 "destroyer_squadron",
939 if (!_stricmp(type_name, group_name[i]))
948 return group_name[type];
960 #define GET_DEF_BOOL(n) if (pdef->name()->value()==(#n)) GetDefBool((n), pdef, filename)
961 #define GET_DEF_TEXT(n) if (pdef->name()->value()==(#n)) GetDefText((n), pdef, filename)
962 #define GET_DEF_NUM(n) if (pdef->name()->value()==(#n)) GetDefNumber((n), pdef, filename)
963 #define GET_DEF_VEC(n) if (pdef->name()->value()==(#n)) GetDefVec((n), pdef, filename)
977 Print(
"ERROR: could not parse order of battle '%s'\n", filename);
982 if (!file_type || file_type->
value() !=
"ORDER_OF_BATTLE") {
983 Print(
"ERROR: invalid Order of Battle file '%s'\n", filename);
991 delete term; term = 0;
999 Print(
"WARNING: group struct missing in '%s'\n", filename);
1009 char parent_type[64];
1017 char unit_regnum[16];
1018 char unit_design[64];
1023 int unit_damage = 0;
1024 int unit_heading= 0;
1038 strcpy_s(intel,
"KNOWN");
1046 if (pdef && (iff < 0 || team < 0 || iff == team)) {
1059 else if ((iff == team || team < 0) && pdef->
name()->
value() ==
"unit") {
1061 Print(
"WARNING: unit struct missing for group '%s' in '%s'\n", name, filename);
1066 char unit_region[64];
1068 Vec3 unit_loc =
Vec3(1.0e9f,0.0f,0.0f);
1071 ZeroMemory(unit_region,
sizeof(unit_region));
1072 ZeroMemory(design,
sizeof(design));
1080 else if (pdef->
name()->
value() ==
"regnum") {
1083 else if (pdef->
name()->
value() ==
"region") {
1086 else if (pdef->
name()->
value() ==
"loc") {
1089 else if (pdef->
name()->
value() ==
"type") {
1094 else if (pdef->
name()->
value() ==
"design") {
1097 else if (pdef->
name()->
value() ==
"skin") {
1100 else if (pdef->
name()->
value() ==
"count") {
1103 else if (pdef->
name()->
value() ==
"dead_count") {
1106 else if (pdef->
name()->
value() ==
"damage") {
1109 else if (pdef->
name()->
value() ==
"heading") {
1116 Print(
"ERROR: invalid design '%s' for unit '%s' in '%s'\n", unit_design, unit_name, filename);
1120 CombatUnit* cu =
new(__FILE__,__LINE__)
CombatUnit(unit_name, unit_regnum, unit_class, unit_design, unit_count, iff);
1124 cu->
Kill(unit_dead);
1133 if (iff >= 0 && (iff == team || team < 0)) {
1144 g->combatant = combatant;
1145 g->unit_index = unit_index;
1149 g->location = parent_group->location;
1151 g->location =
Vec3(0,0,0);
1157 if (unit_list.
size()) {
1158 unit_list[0]->SetLeader(
true);
1176 while (p && !carrier) {
1178 carrier = p->units[0];
1188 g->units.
append(unit_list);
1202 Print(
"Order of Battle Loaded (%s).\n", force ? force->
Name().
data() :
"unknown force");
1221 Print(
"ERROR: could not parse order of battle '%s'\n", filename);
1226 if (!file_type || file_type->
value() !=
"SAVEGAME") {
1227 Print(
"ERROR: invalid Save Game file '%s'\n", filename);
1235 delete term; term = 0;
1243 Print(
"WARNING: group struct missing in '%s'\n", filename);
1254 bool zone_locked =
false;
1264 char unit_regnum[16];
1265 char unit_design[64];
1269 int unit_damage = 0;
1270 int unit_heading= 0;
1283 strcpy_s(intel,
"KNOWN");
1291 if (pdef && (iff < 0 || team < 0 || iff == team)) {
1307 else if ((iff == team || team < 0) && pdef->
name()->
value() ==
"unit") {
1309 Print(
"WARNING: unit struct missing for group '%s' in '%s'\n", name, filename);
1314 char unit_region[64];
1316 Vec3 unit_loc=
Vec3(0.0f,0.0f,0.0f);
1319 ZeroMemory(unit_region,
sizeof(unit_region));
1320 ZeroMemory(design,
sizeof(design));
1328 else if (pdef->
name()->
value() ==
"regnum") {
1331 else if (pdef->
name()->
value() ==
"region") {
1334 else if (pdef->
name()->
value() ==
"loc") {
1337 else if (pdef->
name()->
value() ==
"type") {
1342 else if (pdef->
name()->
value() ==
"design") {
1345 else if (pdef->
name()->
value() ==
"count") {
1348 else if (pdef->
name()->
value() ==
"dead_count") {
1351 else if (pdef->
name()->
value() ==
"damage") {
1354 else if (pdef->
name()->
value() ==
"heading") {
1361 Print(
"ERROR: invalid design '%s' for unit '%s' in '%s'\n", unit_design, unit_name, filename);
1366 CombatUnit* cu =
new(__FILE__,__LINE__)
CombatUnit(unit_name, unit_regnum, unit_class, unit_design, unit_count, iff);
1369 cu->
Kill(unit_dead);
1379 if (iff >= 0 && (iff == team || team < 0)) {
1381 if (!force && !_stricmp(name, combatant->
Name())) {
1400 ::Print(
"WARNING: unexpected combat group %s %d '%s' in '%s'\n", type,
id, name, filename);
1405 g->combatant = combatant;
1408 g->unit_index = unit_index;
1418 ::Print(
"WARNING: could not find combat zone '%s' for group %s %d '%s' in '%s'\n", zone, type,
id, name, filename);
1426 if (kills >= 0) g->
SetKills(kills);
1429 if (unit_list.
size()) {
1463 Print(
"Order of Battle Loaded (%s).\n", force ? force->
Name().
data() :
"unknown force");
1476 sprintf_s(buffer,
"%d", (
int) n);
1478 else if (fabs(n) < 1e6) {
1479 int nn = (int) n / 1000;
1480 sprintf_s(buffer,
"%de3", nn);
1484 sprintf_s(buffer,
"%g", n);
1492 int type = u->
Type();
1497 fprintf(f,
"\n unit: {");
1498 fprintf(f,
" name: \"%s\",", u->
Name().
data());
1502 if (u->
Count() > 1) {
1503 fprintf(f,
" count: %d,", u->
Count());
1516 fprintf(f,
" loc:(%s, %s, %s),", x.data(), y.data(), z.data());
1519 fprintf(f,
" dead_count: %d, damage: %d, heading: %d },",
1528 fprintf(f,
"group: {");
1530 fprintf(f,
" id: %d,", g->
GetID());
1531 fprintf(f,
" name: \"%s\",", g->
Name().
data());
1533 fprintf(f,
" iff: %d,", g->
GetIFF());
1534 fprintf(f,
" unit_index: %d,", g->
UnitIndex());
1547 fprintf(f,
" zone_locked: true,");
1555 fprintf(f,
" loc: (%s, %s, %s),", x.
data(), y.data(), z.data());
1560 fprintf(f,
" parent_id:%d,", parent->GetID());
1563 fprintf(f,
" sorties: %d,", g->
Sorties());
1564 fprintf(f,
" kills: %d,", g->
Kills());
1565 fprintf(f,
" points: %d,", g->
Points());
1584 ::fopen_s(&f, filename,
"a+");