00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "../client.h"
00028 #include "../cl_shared.h"
00029 #include "../ui/ui_main.h"
00030 #include "../ui/node/ui_node_linechart.h"
00031 #include "../../shared/parse.h"
00032 #include "cp_campaign.h"
00033 #include "cp_map.h"
00034 #include "cp_ufo.h"
00035 #include "save/save_nation.h"
00036
00037 nation_t *NAT_GetNationByIDX (const int index)
00038 {
00039 assert(index >= 0);
00040 assert(index < ccs.numNations);
00041
00042 return &ccs.nations[index];
00043 }
00044
00050 nation_t *NAT_GetNationByID (const char *nationID)
00051 {
00052 int i;
00053
00054 if (!nationID) {
00055 Com_Printf("NAT_GetNationByID: NULL nationID\n");
00056 return NULL;
00057 }
00058 for (i = 0; i < ccs.numNations; i++) {
00059 nation_t *nation = &ccs.nations[i];
00060 if (!strcmp(nation->id, nationID))
00061 return nation;
00062 }
00063
00064 Com_Printf("NAT_GetNationByID: Could not find nation '%s'\n", nationID);
00065
00066
00067 return NULL;
00068 }
00069
00070
00076 void NAT_UpdateHappinessForAllNations (void)
00077 {
00078 const linkedList_t *list = ccs.missions;
00079
00080 for (;list; list = list->next) {
00081 const mission_t *mission = (mission_t *)list->data;
00082 nation_t *nation = MAP_GetNation(mission->pos);
00083
00084
00085
00086 if (nation) {
00087 float happinessFactor;
00088 switch (mission->stage) {
00089 case STAGE_TERROR_MISSION:
00090 case STAGE_SUBVERT_GOV:
00091 case STAGE_RECON_GROUND:
00092 case STAGE_SPREAD_XVI:
00093 case STAGE_HARVEST:
00094 happinessFactor = HAPPINESS_ALIEN_MISSION_LOSS;
00095 break;
00096 default:
00097
00098
00099 continue;
00100 }
00101
00102 NAT_SetHappiness(nation, nation->stats[0].happiness + happinessFactor);
00103 Com_DPrintf(DEBUG_CLIENT, "Happiness of nation %s decreased: %.02f\n", nation->name, nation->stats[0].happiness);
00104 }
00105 }
00106 }
00107
00115 int NAT_GetFunding (const nation_t* const nation, int month)
00116 {
00117 return nation->maxFunding * nation->stats[month].happiness;
00118 }
00119
00126 const char* NAT_GetHappinessString (const nation_t* nation)
00127 {
00128 if (nation->stats[0].happiness < 0.015)
00129 return _("Giving up");
00130 else if (nation->stats[0].happiness < 0.025)
00131 return _("Furious");
00132 else if (nation->stats[0].happiness < 0.04)
00133 return _("Angry");
00134 else if (nation->stats[0].happiness < 0.06)
00135 return _("Mad");
00136 else if (nation->stats[0].happiness < 0.10)
00137 return _("Upset");
00138 else if (nation->stats[0].happiness < 0.20)
00139 return _("Tolerant");
00140 else if (nation->stats[0].happiness < 0.30)
00141 return _("Neutral");
00142 else if (nation->stats[0].happiness < 0.50)
00143 return _("Content");
00144 else if (nation->stats[0].happiness < 0.70)
00145 return _("Pleased");
00146 else if (nation->stats[0].happiness < 0.95)
00147 return _("Happy");
00148 else
00149 return _("Exuberant");
00150 }
00151
00157 void NAT_SetHappiness (nation_t *nation, const float happiness)
00158 {
00159 const char *oldString = NAT_GetHappinessString(nation);
00160 const char *newString;
00161 const float oldHappiness = nation->stats[0].happiness;
00162 const float middleHappiness = (ccs.curCampaign->minhappiness + 1.0) / 2;
00163 notify_t notifyType = NT_NUM_NOTIFYTYPE;
00164
00165 nation->stats[0].happiness = happiness;
00166 if (nation->stats[0].happiness < 0.0f)
00167 nation->stats[0].happiness = 0.0f;
00168 else if (nation->stats[0].happiness > 1.0f)
00169 nation->stats[0].happiness = 1.0f;
00170
00171 newString = NAT_GetHappinessString(nation);
00172
00173 if (oldString != newString) {
00174 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer),
00175 _("Nation %s changed happiness from %s to %s"), _(nation->name), oldString, newString);
00176 notifyType = NT_HAPPINESS_CHANGED;
00177 } else if (oldHappiness > middleHappiness && happiness < middleHappiness) {
00178 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer),
00179 _("Nation %s changed happiness to %s"), _(nation->name), newString);
00180 notifyType = NT_HAPPINESS_PLEASED;
00181 } else if (happiness < ccs.curCampaign->minhappiness && oldHappiness > ccs.curCampaign->minhappiness) {
00182 Com_sprintf(cp_messageBuffer, sizeof(cp_messageBuffer),
00183 _("Happiness of nation %s is %s and less than minimal happiness allowed to the campaign"), _(nation->name), newString);
00184 notifyType = NT_HAPPINESS_MIN;
00185 } else {
00186 return;
00187 }
00188
00189 MSO_CheckAddNewMessage(notifyType, _("Nation changed happiness"), cp_messageBuffer, qfalse, MSG_STANDARD, NULL);
00190 }
00191
00196 qboolean NAT_SaveXML (mxml_node_t *p)
00197 {
00198 int i;
00199 mxml_node_t *n = mxml_AddNode(p, SAVE_NATION_NATIONS);
00200
00201 for (i = 0; i < ccs.numNations; i++) {
00202 nation_t *nation = NAT_GetNationByIDX(i);
00203 mxml_node_t *s;
00204 int j;
00205
00206 if (!nation)
00207 continue;
00208
00209 s = mxml_AddNode(n, SAVE_NATION_NATION);
00210 mxml_AddString(s, SAVE_NATION_ID, nation->id);
00211 for (j = 0; j < MONTHS_PER_YEAR; j++) {
00212 mxml_node_t *ss;
00213
00214 if (!nation->stats[j].inuse)
00215 continue;
00216
00217 ss = mxml_AddNode(s, SAVE_NATION_MONTH);
00218 mxml_AddInt(ss, SAVE_NATION_MONTH_IDX, j);
00219 mxml_AddFloat(ss, SAVE_NATION_HAPPINESS, ccs.nations[i].stats[j].happiness);
00220 mxml_AddInt(ss, SAVE_NATION_XVI, ccs.nations[i].stats[j].xviInfection);
00221 }
00222 }
00223 return qtrue;
00224 }
00225
00230 qboolean NAT_LoadXML (mxml_node_t * p)
00231 {
00232 mxml_node_t *n;
00233 mxml_node_t *s;
00234
00235 n = mxml_GetNode(p, SAVE_NATION_NATIONS);
00236 if (!n)
00237 return qfalse;
00238
00239
00240 for (s = mxml_GetNode(n, SAVE_NATION_NATION); s; s = mxml_GetNextNode(s, n, SAVE_NATION_NATION)) {
00241 mxml_node_t *ss;
00242 nation_t *nation = NAT_GetNationByID(mxml_GetString(s, SAVE_NATION_ID));
00243
00244 if (!nation)
00245 return qfalse;
00246
00247
00248 for (ss = mxml_GetNode(s, SAVE_NATION_MONTH); ss; ss = mxml_GetNextNode(ss, s, SAVE_NATION_MONTH)) {
00249 int monthIDX = mxml_GetInt(ss, SAVE_NATION_MONTH_IDX, MONTHS_PER_YEAR);
00250
00251 if (monthIDX < 0 || monthIDX >= MONTHS_PER_YEAR)
00252 return qfalse;
00253
00254 nation->stats[monthIDX].inuse = qtrue;
00255 nation->stats[monthIDX].happiness = mxml_GetFloat(ss, SAVE_NATION_HAPPINESS, 0.0);
00256 nation->stats[monthIDX].xviInfection = mxml_GetInt(ss, SAVE_NATION_XVI, 0);
00257 }
00258 }
00259 return qtrue;
00260 }
00261
00262
00263
00264
00265
00266 static const value_t nation_vals[] = {
00267 {"name", V_TRANSLATION_STRING, offsetof(nation_t, name), 0},
00268 {"pos", V_POS, offsetof(nation_t, pos), MEMBER_SIZEOF(nation_t, pos)},
00269 {"color", V_COLOR, offsetof(nation_t, color), MEMBER_SIZEOF(nation_t, color)},
00270 {"funding", V_INT, offsetof(nation_t, maxFunding), MEMBER_SIZEOF(nation_t, maxFunding)},
00271 {"happiness", V_FLOAT, offsetof(nation_t, stats[0].happiness), MEMBER_SIZEOF(nation_t, stats[0].happiness)},
00272 {"soldiers", V_INT, offsetof(nation_t, maxSoldiers), MEMBER_SIZEOF(nation_t, maxSoldiers)},
00273 {"scientists", V_INT, offsetof(nation_t, maxScientists), MEMBER_SIZEOF(nation_t, maxScientists)},
00274
00275 {NULL, 0, 0, 0}
00276 };
00277
00286 void CL_ParseNations (const char *name, const char **text)
00287 {
00288 const char *errhead = "CL_ParseNations: unexpected end of file (nation ";
00289 nation_t *nation;
00290 const value_t *vp;
00291 const char *token;
00292 int i;
00293
00294 if (ccs.numNations >= MAX_NATIONS) {
00295 Com_Printf("CL_ParseNations: nation number exceeding maximum number of nations: %i\n", MAX_NATIONS);
00296 return;
00297 }
00298
00299
00300 for (i = 0; i < ccs.numNations; i++)
00301 if (!strncmp(name, ccs.nations[i].id, sizeof(ccs.nations[i].id)))
00302 break;
00303 if (i < ccs.numNations) {
00304 Com_Printf("CL_ParseNations: nation def \"%s\" with same name found, second ignored\n", name);
00305 return;
00306 }
00307
00308
00309 nation = &ccs.nations[ccs.numNations];
00310 memset(nation, 0, sizeof(*nation));
00311 nation->idx = ccs.numNations;
00312 ccs.numNations++;
00313
00314 Com_DPrintf(DEBUG_CLIENT, "...found nation %s\n", name);
00315 nation->id = Mem_PoolStrDup(name, cp_campaignPool, 0);
00316
00317 nation->stats[0].inuse = qtrue;
00318
00319
00320 token = Com_Parse(text);
00321
00322 if (!*text || *token != '{') {
00323 Com_Printf("CL_ParseNations: nation def \"%s\" without body ignored\n", name);
00324 ccs.numNations--;
00325 return;
00326 }
00327
00328 do {
00329 token = Com_EParse(text, errhead, name);
00330 if (!*text)
00331 break;
00332 if (*token == '}')
00333 break;
00334
00335
00336 for (vp = nation_vals; vp->string; vp++)
00337 if (!strcmp(token, vp->string)) {
00338
00339 token = Com_EParse(text, errhead, name);
00340 if (!*text)
00341 return;
00342
00343 switch (vp->type) {
00344 case V_TRANSLATION_STRING:
00345 token++;
00346 case V_CLIENT_HUNK_STRING:
00347 Mem_PoolStrDupTo(token, (char**) ((char*)nation + (int)vp->ofs), cp_campaignPool, 0);
00348 break;
00349 default:
00350 if (Com_EParseValue(nation, token, vp->type, vp->ofs, vp->size) == -1)
00351 Com_Printf("CL_ParseNations: Wrong size for value %s\n", vp->string);
00352 break;
00353 }
00354 break;
00355 }
00356
00357 if (!vp->string) {
00358 Com_Printf("CL_ParseNations: unknown token \"%s\" ignored (nation %s)\n", token, name);
00359 Com_EParse(text, errhead, name);
00360 }
00361 } while (*text);
00362 }
00363
00364 static const value_t city_vals[] = {
00365 {"name", V_TRANSLATION_STRING, offsetof(city_t, name), 0},
00366 {"pos", V_POS, offsetof(city_t, pos), MEMBER_SIZEOF(city_t, pos)},
00367
00368 {NULL, 0, 0, 0}
00369 };
00370
00379 void CL_ParseCities (const char *name, const char **text)
00380 {
00381 const char *errhead = "CL_ParseCities: unexpected end of file (nation ";
00382 city_t newCity;
00383 linkedList_t *cities;
00384 const value_t *vp;
00385 const char *token;
00386
00387
00388 for (cities = ccs.cities; cities != NULL; cities = cities->next) {
00389 const city_t *cty = (city_t*) cities->data;
00390
00391 assert(cty);
00392 if (!strcmp(name, cty->id))
00393 break;
00394 }
00395 if (cities != NULL) {
00396 Com_Printf("CL_ParseCities: city def \"%s\" with same name found, second ignored\n", name);
00397 return;
00398 }
00399
00400
00401 memset(&newCity, 0, sizeof(newCity));
00402 newCity.idx = ccs.numCities;
00403 ccs.numCities++;
00404
00405 Com_DPrintf(DEBUG_CLIENT, "...found city %s\n", name);
00406 newCity.id = Mem_PoolStrDup(name, cp_campaignPool, 0);
00407
00408
00409 token = Com_Parse(text);
00410
00411 if (!*text || *token != '{') {
00412 Com_Printf("CL_ParseCities: city def \"%s\" without body ignored\n", name);
00413 ccs.numCities--;
00414 return;
00415 }
00416
00417 do {
00418 token = Com_EParse(text, errhead, name);
00419 if (!*text)
00420 break;
00421 if (*token == '}')
00422 break;
00423
00424
00425 for (vp = city_vals; vp->string; vp++)
00426 if (!strcmp(token, vp->string)) {
00427
00428 token = Com_EParse(text, errhead, name);
00429 if (!*text)
00430 return;
00431
00432 switch (vp->type) {
00433 case V_TRANSLATION_STRING:
00434 token++;
00435 case V_CLIENT_HUNK_STRING:
00436 Mem_PoolStrDupTo(token, (char**) ((char*)&newCity + (int)vp->ofs), cp_campaignPool, 0);
00437 break;
00438 default:
00439 if (Com_EParseValue(&newCity, token, vp->type, vp->ofs, vp->size) == -1)
00440 Com_Printf("CL_ParseCities: Wrong size for value %s\n", vp->string);
00441 break;
00442 }
00443 break;
00444 }
00445
00446 if (!vp->string) {
00447 Com_Printf("CL_ParseCities: unknown token \"%s\" ignored (nation %s)\n", token, name);
00448 Com_EParse(text, errhead, name);
00449 }
00450 } while (*text);
00451
00452
00453 LIST_Add(&ccs.cities, (byte*) &newCity, sizeof(newCity));
00454 }
00455
00460 qboolean NAT_ScriptSanityCheck (void)
00461 {
00462 int i;
00463 int error = 0;
00464 linkedList_t *cities;
00465
00466
00467 for (cities = ccs.cities; cities != NULL; cities = cities->next) {
00468 int mapIdx;
00469 city_t *city = (city_t*) cities->data;
00470 const vec2_t pos = {city->pos[0], city->pos[1]};
00471 qboolean cityCanBeUsed = qfalse;
00472 qboolean parametersFit = qfalse;
00473 ufoType_t ufoTypes[UFO_MAX];
00474 int numTypes;
00475
00476 if (!city->name) {
00477 error++;
00478 Com_Printf("...... city '%s' has no name\n", city->id);
00479 }
00480
00481 numTypes = CP_TerrorMissionAvailableUFOs(NULL, ufoTypes);
00482
00483 for (mapIdx = 0; mapIdx < cls.numMDs; mapIdx++) {
00484 const mapDef_t const *md = Com_GetMapDefByIDX(mapIdx);
00485
00486 if (md->storyRelated)
00487 continue;
00488
00489 if (MAP_PositionFitsTCPNTypes(pos, md->terrains, md->cultures, md->populations, NULL)) {
00490
00491
00492 parametersFit = qtrue;
00493
00494
00495 if (!md->ufos) {
00496 continue;
00497 }
00498
00499
00500 for (i = numTypes - 1 ; i >= 0; i--) {
00501 if (LIST_ContainsString(md->ufos, Com_UFOTypeToShortName(ufoTypes[i]))) {
00502 REMOVE_ELEM(ufoTypes, i, numTypes);
00503 }
00504 }
00505 }
00506 if (numTypes == 0) {
00507 cityCanBeUsed = qtrue;
00508 break;
00509 }
00510 }
00511
00512 if (!cityCanBeUsed) {
00513 error++;
00514 Com_Printf("...... city '%s' can't be used in game: it has no map fitting parameters\n", city->id);
00515 if (parametersFit) {
00516 Com_Printf(" (No map fitting");
00517 for (i = 0 ; i < numTypes; i++)
00518 Com_Printf(" %s", Com_UFOTypeToShortName(ufoTypes[i]));
00519 Com_Printf(")\n");
00520 }
00521 MAP_PrintParameterStringByPos(pos);
00522 }
00523 }
00524
00525 return !error;
00526 }
00527
00528
00529
00530
00531
00532
00533 static void CP_NationStatsClick_f (void)
00534 {
00535 int num;
00536
00537 if (Cmd_Argc() < 2) {
00538 Com_Printf("Usage: %s <num>\n", Cmd_Argv(0));
00539 return;
00540 }
00541
00542
00543 num = atoi(Cmd_Argv(1));
00544 if (num < 0 || num >= ccs.numNations)
00545 return;
00546
00547 UI_PushWindow("nations", NULL);
00548 Cbuf_AddText(va("nation_select %i;", num));
00549 }
00550
00552 static screenPoint_t fundingPts[MAX_NATIONS][MONTHS_PER_YEAR];
00553 static int usedFundPtslist = 0;
00555 static screenPoint_t colorLinePts[MAX_NATIONS][2];
00556 static int usedColPtslists = 0;
00557
00558 static const vec4_t graphColors[MAX_NATIONS] = {
00559 {1.0, 0.5, 0.5, 1.0},
00560 {0.5, 1.0, 0.5, 1.0},
00561 {0.5, 0.5, 1.0, 1.0},
00562 {1.0, 0.0, 0.0, 1.0},
00563 {0.0, 1.0, 0.0, 1.0},
00564 {0.0, 0.0, 1.0, 1.0},
00565 {1.0, 1.0, 0.0, 1.0},
00566 {0.0, 1.0, 1.0, 1.0}
00567 };
00568 static const vec4_t graphColorSelected = {1, 1, 1, 1};
00569
00577 static int CL_NationsMaxFunding (void)
00578 {
00579 int m, n;
00580 int max = 0;
00581
00582 for (n = 0; n < ccs.numNations; n++) {
00583 const nation_t *nation = &ccs.nations[n];
00584 for (m = 0; m < MONTHS_PER_YEAR; m++) {
00585 if (nation->stats[m].inuse) {
00586 const int funding = NAT_GetFunding(nation, m);
00587 if (max < funding)
00588 max = funding;
00589 } else {
00590
00591 break;
00592 }
00593 }
00594 }
00595 return max;
00596 }
00597
00598 static int selectedNation = 0;
00599
00600 static lineStrip_t fundingLineStrip[MAX_NATIONS];
00601
00611 static void CL_NationDrawStats (const nation_t *nation, uiNode_t *node, lineStrip_t *funding, int maxFunding, int color)
00612 {
00613 int width, height, dx;
00614 int m;
00615 int minFunding = 0;
00616 int ptsNumber = 0;
00617 float dy;
00618
00619 if (!nation || !node)
00620 return;
00621
00623 width = (int)node->size[0];
00624 height = (int)node->size[1];
00625 dx = (int)(width / MONTHS_PER_YEAR);
00626
00627 if (minFunding != maxFunding)
00628 dy = (float) height / (maxFunding - minFunding);
00629 else
00630 dy = 0;
00631
00632
00634 for (m = 0; m < MONTHS_PER_YEAR; m++) {
00635 if (nation->stats[m].inuse) {
00636 const int fund = NAT_GetFunding(nation, m);
00637 fundingPts[usedFundPtslist][m].x = (m * dx);
00638 fundingPts[usedFundPtslist][m].y = height - dy * (fund - minFunding);
00639 ptsNumber++;
00640 } else {
00641 break;
00642 }
00643 }
00644
00645
00646 if (ptsNumber == 1) {
00647
00648 fundingPts[usedFundPtslist][1].x = fundingPts[usedFundPtslist][0].x + (int)(0.5 * width / MONTHS_PER_YEAR);
00649 fundingPts[usedFundPtslist][1].y = fundingPts[usedFundPtslist][0].y;
00650 ptsNumber++;
00651 }
00652
00653
00654 funding->pointList = (int*)fundingPts[usedFundPtslist];
00655 funding->numPoints = ptsNumber;
00656 if (color < 0) {
00657 Cvar_Set("mn_nat_symbol", va("nations/%s", ccs.nations[selectedNation].id));
00658 Vector4Copy(graphColorSelected, funding->color);
00659 } else {
00660 Vector4Copy(graphColors[color], funding->color);
00661 }
00662
00663 usedFundPtslist++;
00664 }
00665
00666 static lineStrip_t colorLineStrip[MAX_NATIONS];
00667
00672 static void CL_NationStatsUpdate_f (void)
00673 {
00674 int i;
00675 uiNode_t *colorNode;
00676 uiNode_t *graphNode;
00677 int dy = 10;
00678
00679 usedColPtslists = 0;
00680
00681 colorNode = UI_GetNodeByPath("nations.nation_graph_colors");
00682 if (colorNode) {
00683 dy = (int)(colorNode->size[1] / MAX_NATIONS);
00684 }
00685
00686 for (i = 0; i < ccs.numNations; i++) {
00687 nation_t *nation = &ccs.nations[i];
00688 lineStrip_t *color = &colorLineStrip[i];
00689 const int funding = NAT_GetFunding(nation, 0);
00690
00691 memset(color, 0, sizeof(*color));
00692
00693 if (i > 0)
00694 colorLineStrip[i - 1].next = color;
00695
00696 if (selectedNation == i) {
00697 UI_ExecuteConfunc("nation_marksel %i", i);
00698 } else {
00699 UI_ExecuteConfunc("nation_markdesel %i", i);
00700 }
00701 Cvar_Set(va("mn_nat_name%i",i), _(nation->name));
00702 Cvar_Set(va("mn_nat_fund%i",i), va("%i", funding));
00703
00704 if (colorNode) {
00705 colorLinePts[usedColPtslists][0].x = 0;
00706 colorLinePts[usedColPtslists][0].y = (int)colorNode->size[1] - (int)colorNode->size[1] + dy * i;
00707 colorLinePts[usedColPtslists][1].x = (int)colorNode->size[0];
00708 colorLinePts[usedColPtslists][1].y = colorLinePts[usedColPtslists][0].y;
00709
00710 color->pointList = (int*)colorLinePts[usedColPtslists];
00711 color->numPoints = 2;
00712
00713 if (i == selectedNation) {
00714 Vector4Copy(graphColorSelected, color->color);
00715 } else {
00716 Vector4Copy(graphColors[i], color->color);
00717 }
00718
00719 usedColPtslists++;
00720 }
00721 }
00722
00723 UI_RegisterLineStrip(LINESTRIP_COLOR, &colorLineStrip[0]);
00724
00725
00726 for (i = ccs.numNations; i < MAX_NATIONS; i++) {
00727 UI_ExecuteConfunc("nation_hide %i", i);
00728 }
00729
00732
00733 graphNode = UI_GetNodeByPath("nations.nation_graph_funding");
00734 if (graphNode) {
00735 const int maxFunding = CL_NationsMaxFunding();
00736 usedFundPtslist = 0;
00737 for (i = 0; i < ccs.numNations; i++) {
00738 nation_t *nation = &ccs.nations[i];
00739 lineStrip_t *funding = &fundingLineStrip[i];
00740
00741
00742 memset(funding, 0, sizeof(funding));
00743
00744 if (i > 0)
00745 fundingLineStrip[i - 1].next = funding;
00746
00747 if (i == selectedNation) {
00748 CL_NationDrawStats(nation, graphNode, funding, maxFunding, -1);
00749 } else {
00750 CL_NationDrawStats(nation, graphNode, funding, maxFunding, i);
00751 }
00752 }
00753
00754 UI_RegisterLineStrip(LINESTRIP_FUNDING, &fundingLineStrip[0]);
00755 }
00756 }
00757
00761 static void CL_NationSelect_f (void)
00762 {
00763 int nat;
00764
00765 if (Cmd_Argc() < 2) {
00766 Com_Printf("Usage: %s <nat_idx>\n", Cmd_Argv(0));
00767 return;
00768 }
00769
00770 nat = atoi(Cmd_Argv(1));
00771 if (nat < 0 || nat >= ccs.numNations) {
00772 Com_Printf("Invalid nation index: %is\n",nat);
00773 return;
00774 }
00775
00776 selectedNation = nat;
00777 CL_NationStatsUpdate_f();
00778 }
00779
00780 #ifdef DEBUG
00781
00785 static void NAT_ListCities_f (void)
00786 {
00787 linkedList_t *cities;
00788
00789 for (cities = ccs.cities; cities != NULL; cities =cities->next) {
00790 const city_t const *city = (city_t*) cities->data;
00791
00792 assert(city);
00793 Com_Printf("City '%s' -- position (%0.1f, %0.1f)\n", city->id, city->pos[0], city->pos[1]);
00794 MAP_PrintParameterStringByPos(city->pos);
00795 }
00796 }
00797
00802 static void NAT_NationList_f (void)
00803 {
00804 int i;
00805 for (i = 0; i < ccs.numNations; i++) {
00806 Com_Printf("Nation ID: %s\n", ccs.nations[i].id);
00807 Com_Printf("...max-funding %i c\n", ccs.nations[i].maxFunding);
00808 Com_Printf("...happiness %0.2f\n", ccs.nations[i].stats[0].happiness);
00809 Com_Printf("...xviInfection %i\n", ccs.nations[i].stats[0].xviInfection);
00810 Com_Printf("...max-soldiers %i\n", ccs.nations[i].maxSoldiers);
00811 Com_Printf("...max-scientists %i\n", ccs.nations[i].maxScientists);
00812 Com_Printf("...color r:%.2f g:%.2f b:%.2f a:%.2f\n", ccs.nations[i].color[0], ccs.nations[i].color[1], ccs.nations[i].color[2], ccs.nations[i].color[3]);
00813 Com_Printf("...pos x:%.0f y:%.0f\n", ccs.nations[i].pos[0], ccs.nations[i].pos[1]);
00814 }
00815 }
00816 #endif
00817
00818 void NAT_InitStartup (void)
00819 {
00820 Cmd_AddCommand("nation_stats_click", CP_NationStatsClick_f, NULL);
00821 Cmd_AddCommand("nation_update", CL_NationStatsUpdate_f, "Shows the current nation list + statistics.");
00822 Cmd_AddCommand("nation_select", CL_NationSelect_f, "Select nation and display all relevant information for it.");
00823 #ifdef DEBUG
00824 Cmd_AddCommand("debug_listcities", NAT_ListCities_f, "Debug function to list all cities in game.");
00825 Cmd_AddCommand("debug_listnations", NAT_NationList_f, "List all nations on the game console");
00826 #endif
00827 }
00828