ONATIONA.cpp 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Filename : ONATIONA.CPP
  21. //Description : Object Nation Array
  22. #include <COLOR.h>
  23. #include <OPOWER.h>
  24. #include <OGAME.h>
  25. #include <OF_CAMP.h>
  26. #include <OUNIT.h>
  27. #include <OINFO.h>
  28. #include <OSYS.h>
  29. #include <ORACERES.h>
  30. #include <OSPY.h>
  31. #include <ONATIONA.h>
  32. #include <OREMOTE.h>
  33. #include <OLOG.h>
  34. //### begin alex 22/9 ###//
  35. #ifdef DEBUG
  36. #include <OFONT.h>
  37. static unsigned long last_nation_ai_profile_time = 0L;
  38. static unsigned long nation_ai_profile_time = 0L;
  39. static unsigned long last_nation_profile_time = 0L;
  40. static unsigned long nation_profile_time = 0L;
  41. #endif
  42. //#### end alex 22/9 ####//
  43. //--------- Begin of function NationArray::NationArray ---------//
  44. //
  45. NationArray::NationArray() : DynArrayB( sizeof(Nation*), MAX_NATION )
  46. {
  47. }
  48. //----------- End of function NationArray::NationArray ---------//
  49. //--------- Begin of function NationArray::~NationArray ---------//
  50. //
  51. NationArray::~NationArray()
  52. {
  53. deinit();
  54. }
  55. //----------- End of function NationArray::~NationArray ---------//
  56. //--------- Begin of function NationArray::init ---------//
  57. //
  58. void NationArray::init()
  59. {
  60. nation_count = 0;
  61. ai_nation_count = 0;
  62. last_del_nation_date = 0;
  63. nation_peace_days = 0;
  64. last_alliance_id = 0;
  65. nation_color_array[0] = (char) V_WHITE; // if nation_recno==0, the color is white
  66. nation_power_color_array[0] = (char) VGA_GRAY+10; // if nation_recno==0, the color is white
  67. nation_power_color_array[MAX_NATION+1] = (char) VGA_GRAY+10; // if Location::power_nation_recno==MAX_NATION+1, this means there are more than one nation have influence over this location.
  68. }
  69. //----------- End of function NationArray::init ---------//
  70. //--------- Begin of function NationArray::deinit ---------//
  71. //
  72. // Called by ~NationArray when game terminate
  73. // and NationArray::read_file() when loading game
  74. //
  75. void NationArray::deinit()
  76. {
  77. int i; // can't call the destructor of Firm, must call deinit()
  78. for( i=size() ; i>0 ; i-- )
  79. {
  80. if( !is_deleted(i) )
  81. del_nation(i);
  82. }
  83. zap(); // clean up the array
  84. }
  85. //----------- End of function NationArray::deinit ---------//
  86. //--------- Begin of function NationArray::new_nation ---------//
  87. //
  88. // <int> nationType = NATION_OWN, NATION_AI, or NATION_REMOTE
  89. // <int> raceId = id. of the race
  90. // <int> colorSchemeId = the color scheme id. of the nation
  91. // [unsigned long] dpPlayerId = DirectPlayer player id. (only for multiplayer game)
  92. //
  93. // return : <int> nationRecno = the recno. of the newly added nation
  94. //
  95. int NationArray::new_nation(int nationType, int raceId, int colorSchemeId, unsigned long dpPlayerId)
  96. {
  97. err_when( info.game_date < last_del_nation_date + NEW_NATION_INTERVAL_DAYS );
  98. //--------------------------------------------------------//
  99. int nationRecno = create_nation();
  100. Nation* nationPtr = nation_array[nationRecno];
  101. if( nationType == NATION_OWN )
  102. {
  103. player_ptr = nationPtr; // for ~nation_array to quick access
  104. player_recno = nationRecno;
  105. info.default_viewing_nation_recno = nationRecno;
  106. info.viewing_nation_recno = nationRecno;
  107. }
  108. //--- we must call init() after setting ai_type & nation_res_id ----//
  109. nationPtr->init(nationType, raceId, colorSchemeId, dpPlayerId);
  110. //--- store the colors of all nations into a single array for later fast access ---//
  111. nation_color_array[nationPtr->nation_recno] = nationPtr->nation_color;
  112. nation_power_color_array[nationPtr->nation_recno] = nationPtr->nation_color; // use a lighter color for the nation power area
  113. //-------------------------------------------//
  114. nation_count++;
  115. if( nationType == NATION_AI )
  116. ai_nation_count++;
  117. last_new_nation_date = info.game_date;
  118. //---------- update statistic ----------//
  119. update_statistic();
  120. return nationRecno;
  121. }
  122. //----------- End of function NationArray::new_nation ---------//
  123. // ######## begin Gilbert 18/8 #########//
  124. //--------- Begin of function NationArray::new_nation ---------//
  125. //
  126. // used in creating human players in multi-player game
  127. // return : <int> nationRecno = the recno. of the newly added nation
  128. //
  129. int NationArray::new_nation(NewNationPara& nationPara)
  130. {
  131. err_when( info.game_date < last_del_nation_date + NEW_NATION_INTERVAL_DAYS );
  132. //--------------------------------------------------------//
  133. int nationRecno = create_nation();
  134. Nation* nationPtr = nation_array[nationRecno];
  135. err_when( nationRecno != nationPara.nation_recno );
  136. err_when( !remote.is_enable() );
  137. char nationType =
  138. nationPara.dp_player_id == remote.self_player_id() ? NATION_OWN : NATION_REMOTE;
  139. if( nationType == NATION_OWN )
  140. {
  141. player_ptr = nationPtr; // for ~nation_array to quick access
  142. player_recno = nationRecno;
  143. info.default_viewing_nation_recno = nationRecno;
  144. info.viewing_nation_recno = nationRecno;
  145. }
  146. //--- we must call init() after setting ai_type & nation_res_id ----//
  147. nationPtr->init(nationType, nationPara.race_id, nationPara.color_scheme, nationPara.dp_player_id);
  148. //--- store the colors of all nations into a single array for later fast access ---//
  149. nation_color_array[nationPtr->nation_recno] = nationPtr->nation_color;
  150. nation_power_color_array[nationPtr->nation_recno] = nationPtr->nation_color; // use a lighter color for the nation power area
  151. //-------------------------------------------//
  152. nation_count++;
  153. if( nationType == NATION_AI )
  154. ai_nation_count++;
  155. //---------- update statistic ----------//
  156. update_statistic();
  157. return nationRecno;
  158. }
  159. //----------- End of function NationArray::new_nation ---------//
  160. // ######## end Gilbert 18/8 #########//
  161. //--------- Begin of function NationArray::create_nation ---------//
  162. //
  163. // <int> nationType = NATION_OWN, NATION_AI
  164. //
  165. // return : <int> nationRecno = the recno. of the newly added nation
  166. //
  167. int NationArray::create_nation()
  168. {
  169. Nation *nationPtr = new Nation; // NATION_OWN, NATION_REMOTE also use
  170. // may be switched to player nation and verse vice
  171. linkin(&nationPtr);
  172. err_when( size() > MAX_NATION );
  173. nationPtr->nation_recno = recno();
  174. return recno();
  175. }
  176. //----------- End of function NationArray::create_nation ---------//
  177. //--------- Begin of function NationArray::nation_class_size ---------//
  178. //
  179. // Return the size of the nation class
  180. //
  181. // <int> nationType = nation type, e.g. NATION_OWN, NATION_AI
  182. //
  183. int NationArray::nation_class_size()
  184. {
  185. return sizeof(Nation); // NATION_OWN, NATION_REMOTE also use
  186. // Nation object because a AI nation
  187. // may be switched to player nation and verse vice
  188. }
  189. //----------- End of function NationArray::nation_class_size ---------//
  190. //--------- Begin of function NationArray::del_nation ---------//
  191. //
  192. // <int> recNo = the no. of the record to be deleted
  193. // (default : current record no.)
  194. //
  195. void NationArray::del_nation(int recNo)
  196. {
  197. //-----------------------------------------//
  198. Nation* nationPtr = nation_array[recNo]; // operator[] will check for deleted nation error, can't use operator() because it use firm_array()->nation_recno
  199. nation_count--;
  200. if( nationPtr->nation_type == NATION_AI )
  201. ai_nation_count--;
  202. last_del_nation_date = info.game_date;
  203. //------ delete and linkout the nation ------//
  204. nationPtr->deinit();
  205. delete nationPtr;
  206. go(recNo);
  207. *( (Nation**) get() ) = NULL; // Nullify the pointer
  208. linkout();
  209. //---- if the nation to be deleted is the player's nation ---//
  210. if( recNo==player_recno )
  211. {
  212. player_ptr = NULL;
  213. player_recno = 0;
  214. if( !sys.signal_exit_flag )
  215. sys.set_view_mode(MODE_NORMAL); // set the view mode to normal mode to prevent possible problems
  216. }
  217. //---------- update statistic ----------//
  218. update_statistic(); // as max_overall_nation_recno and others may be pointing to the deleted nation
  219. }
  220. //----------- End of function NationArray::del_nation ---------//
  221. //--------- Begin of function NationArray::process ---------//
  222. //
  223. void NationArray::process()
  224. {
  225. int i;
  226. Nation *nationPtr;
  227. for( i=size() ; i>0 ; i-- )
  228. {
  229. nationPtr = (Nation*) get_ptr(i);
  230. if( !nationPtr )
  231. continue;
  232. //--------- process nation --------//
  233. if( i%FRAMES_PER_DAY == int(sys.frame_count%FRAMES_PER_DAY) ) // only process each firm once per day
  234. {
  235. //### begin alex 22/9 ###//
  236. #ifdef DEBUG
  237. unsigned long profileStartTime = m.get_time();
  238. #endif
  239. //#### end alex 22/9 ####//
  240. // ###### begin Gilbert 6/9 ######//
  241. LOG_MSG(i);
  242. LOG_MSG("begin next_day");
  243. nationPtr->next_day();
  244. LOG_MSG("end next_day");
  245. LOG_MSG(m.get_random_seed());
  246. // ###### end Gilbert 6/9 ######//
  247. //### begin alex 22/9 ###//
  248. #ifdef DEBUG
  249. nation_profile_time += m.get_time() - profileStartTime;
  250. #endif
  251. //#### end alex 22/9 ####//
  252. if( nation_array.is_deleted(i) )
  253. continue;
  254. // ###### begin Gilbert 6/9 ######//
  255. if( nationPtr->nation_type == NATION_AI )
  256. {
  257. #ifdef DEBUG
  258. unsigned long profileAiStartTime = m.get_time();
  259. #endif
  260. LOG_MSG( "begin process_ai");
  261. nationPtr->process_ai();
  262. LOG_MSG( "end process_ai");
  263. LOG_MSG( m.get_random_seed());
  264. #ifdef DEBUG
  265. nation_profile_time += m.get_time() - profileStartTime;
  266. #endif
  267. }
  268. // ###### end Gilbert 6/9 ######//
  269. }
  270. }
  271. if( sys.frame_count%FRAMES_PER_DAY==0 )
  272. nation_peace_days++;
  273. }
  274. //----------- End of function NationArray::process ---------//
  275. //--------- Begin of function NationArray::next_month ---------//
  276. //
  277. void NationArray::next_month()
  278. {
  279. int i;
  280. Nation *nationPtr;
  281. // ###### begin Gilbert 6/9 ########//
  282. LOG_MSG("begin NationArray::next_month");
  283. for( i=size() ; i>0 ; i-- )
  284. {
  285. nationPtr = (Nation*) get_ptr(i);
  286. if( nationPtr ) // nationPtr == NULL, if it's deleted
  287. {
  288. LOG_MSG(i);
  289. nationPtr->next_month();
  290. LOG_MSG(m.get_random_seed() );
  291. }
  292. }
  293. LOG_MSG("end NationArray::next_month");
  294. // ###### end Gilbert 6/9 ########//
  295. //------- update statistic -----------//
  296. update_statistic();
  297. }
  298. //---------- End of function NationArray::next_month ----------//
  299. //--------- Begin of function NationArray::next_year ---------//
  300. //
  301. void NationArray::next_year()
  302. {
  303. int i;
  304. Nation *nationPtr;
  305. // ###### begin Gilbert 6/9 ########//
  306. LOG_MSG("begin NationArray::next_year");
  307. for( i=size() ; i>0 ; i-- )
  308. {
  309. nationPtr = (Nation*) get_ptr(i);
  310. if( nationPtr ) // nationPtr == NULL, if it's deleted
  311. {
  312. LOG_MSG(i);
  313. nationPtr->next_year();
  314. LOG_MSG(m.get_random_seed() );
  315. }
  316. }
  317. LOG_MSG("end NationArray::next_year");
  318. // ###### end Gilbert 6/9 ########//
  319. }
  320. //---------- End of function NationArray::next_year ----------//
  321. //-------- Begin of function NationArray::random_unused_race --------//
  322. //
  323. // Randomly pick a race id. that hasn't been used by existing nations.
  324. //
  325. int NationArray::random_unused_race()
  326. {
  327. //----- figure out which race has been used, which has not -----//
  328. char usedRaceArray[MAX_RACE];
  329. int usedCount=0;
  330. memset( usedRaceArray, 0, sizeof(usedRaceArray) );
  331. int i;
  332. for( i=1 ; i<=nation_array.size() ; i++ )
  333. {
  334. if( nation_array.is_deleted(i) )
  335. continue;
  336. usedRaceArray[ nation_array[i]->race_id-1 ] = 1;
  337. usedCount++;
  338. }
  339. err_when( usedCount == MAX_RACE );
  340. //----- pick a race randomly from the unused list -----//
  341. int pickedInstance = m.random(MAX_RACE-usedCount)+1;
  342. int usedId=0;
  343. for( i=0 ; i<MAX_RACE ; i++ )
  344. {
  345. if( !usedRaceArray[i] )
  346. {
  347. usedId++;
  348. if( usedId == pickedInstance )
  349. return i+1;
  350. }
  351. }
  352. err_here();
  353. return 0;
  354. }
  355. //--------- End of function NationArray::random_unused_race ---------//
  356. //-------- Begin of function NationArray::random_unused_color --------//
  357. //
  358. // Randomly pick a color that hasn't been used by existing nations.
  359. //
  360. int NationArray::random_unused_color()
  361. {
  362. //----- figure out which race has been used, which has not -----//
  363. char usedColorArray[MAX_COLOR_SCHEME];
  364. int usedCount=0;
  365. memset( usedColorArray, 0, sizeof(usedColorArray) );
  366. int i;
  367. for( i=1 ; i<=nation_array.size() ; i++ )
  368. {
  369. if( nation_array.is_deleted(i) )
  370. continue;
  371. usedColorArray[ nation_array[i]->color_scheme_id-1 ] = 1;
  372. usedCount++;
  373. }
  374. err_when( usedCount == MAX_COLOR_SCHEME );
  375. //----- pick a race randomly from the unused list -----//
  376. int pickedInstance = m.random(MAX_COLOR_SCHEME-usedCount)+1;
  377. int usedId=0;
  378. for( i=0 ; i<MAX_COLOR_SCHEME ; i++ )
  379. {
  380. if( !usedColorArray[i] )
  381. {
  382. usedId++;
  383. if( usedId == pickedInstance )
  384. return i+1;
  385. }
  386. }
  387. err_here();
  388. return 0;
  389. }
  390. //--------- End of function NationArray::random_unused_color ---------//
  391. //-------- Begin of function NationArray::can_form_new_ai_nation --------//
  392. //
  393. // Return whether a new nation can be formed now.
  394. //
  395. int NationArray::can_form_new_ai_nation()
  396. {
  397. return config.new_nation_emerge &&
  398. nation_array.ai_nation_count < config.ai_nation_count &&
  399. nation_array.nation_count < MAX_NATION &&
  400. info.game_date > last_del_nation_date + NEW_NATION_INTERVAL_DAYS &&
  401. info.game_date > last_new_nation_date + NEW_NATION_INTERVAL_DAYS;
  402. }
  403. //--------- End of function NationArray::can_form_new_ai_nation ---------//
  404. //------- Begin of function NationArray::update_statistic ------//
  405. //
  406. void NationArray::update_statistic()
  407. {
  408. //----- reset statistic vars first ------//
  409. int i;
  410. Nation *nationPtr;
  411. for( i=size() ; i>0 ; i-- )
  412. {
  413. if( nation_array.is_deleted(i) )
  414. continue;
  415. nationPtr = nation_array[i];
  416. nationPtr->total_population = 0;
  417. nationPtr->total_jobless_population = 0;
  418. nationPtr->largest_town_recno = 0;
  419. nationPtr->largest_town_pop = 0;
  420. nationPtr->total_spy_count = 0;
  421. nationPtr->total_ship_combat_level = 0;
  422. }
  423. //------ calculate town statistic -------//
  424. independent_town_count = 0;
  425. memset( independent_town_count_race_array, 0, sizeof(independent_town_count_race_array) ); // the no. of independent towns each race has
  426. Town* townPtr;
  427. for( i=town_array.size() ; i>0 ; i-- )
  428. {
  429. if( town_array.is_deleted(i) )
  430. continue;
  431. townPtr = town_array[i];
  432. if( townPtr->nation_recno )
  433. {
  434. Nation* nationPtr = nation_array[townPtr->nation_recno];
  435. nationPtr->total_population += townPtr->population;
  436. nationPtr->total_jobless_population += townPtr->jobless_population;
  437. if( townPtr->population > nationPtr->largest_town_pop )
  438. {
  439. nationPtr->largest_town_pop = townPtr->population;
  440. nationPtr->largest_town_recno = i;
  441. }
  442. }
  443. else
  444. {
  445. independent_town_count++;
  446. //--- the no. of independent towns each race has ---//
  447. for( int j=0 ; j<MAX_RACE ; j++ )
  448. {
  449. if( townPtr->race_pop_array[j] >= 6 ) // only count it if the pop of the race >= 6
  450. independent_town_count_race_array[j]++;
  451. }
  452. }
  453. }
  454. //------ calculate spy statistic -------//
  455. for( i=spy_array.size() ; i>0 ; i-- )
  456. {
  457. if( spy_array.is_deleted(i) )
  458. continue;
  459. nation_array[ spy_array[i]->true_nation_recno ]->total_spy_count++;
  460. }
  461. //--- update nation rating (this must be called after the above code, which update vars like total_population ---//
  462. for( i=size() ; i>0 ; i-- )
  463. {
  464. if( nation_array.is_deleted(i) )
  465. continue;
  466. nation_array[i]->update_nation_rating();
  467. }
  468. //------ update the military rating of all nations -----//
  469. update_military_rating();
  470. //------ update the total_human_count of all nations -----//
  471. // #ifdef DEBUG
  472. // update_total_human_count(); //**BUGHERE this function to be deleted after checking
  473. // #endif
  474. //--------- update nation maximum ----------//
  475. max_nation_population = 0;
  476. all_nation_population = 0;
  477. max_nation_units = 0;
  478. max_nation_humans = 0;
  479. max_nation_generals = 0;
  480. max_nation_weapons = 0;
  481. max_nation_ships = 0;
  482. max_nation_spies = 0;
  483. max_nation_firms = 0;
  484. max_nation_tech_level = 0;
  485. max_population_rating = -0x7FFF;
  486. max_military_rating = -0x7FFF;
  487. max_economic_rating = -0x7FFF;
  488. max_reputation = -0x7FFF;
  489. max_kill_monster_score = -0x7FFF;
  490. max_overall_rating = -0x7FFF;
  491. max_population_nation_recno = 0;
  492. max_military_nation_recno = 0;
  493. max_economic_nation_recno = 0;
  494. max_reputation_nation_recno = 0;
  495. max_kill_monster_nation_recno = 0;
  496. max_overall_nation_recno = 0;
  497. for( i=size() ; i>0 ; i-- )
  498. {
  499. nationPtr = (Nation*) get_ptr(i);
  500. if( !nationPtr ) // nationPtr == NULL, if it's deleted
  501. continue;
  502. all_nation_population += nationPtr->total_population;
  503. if( nationPtr->total_population > max_nation_population )
  504. max_nation_population = nationPtr->total_population;
  505. if( nationPtr->total_unit_count > max_nation_units )
  506. max_nation_units = nationPtr->total_unit_count;
  507. if( nationPtr->total_human_count > max_nation_humans )
  508. max_nation_humans = nationPtr->total_human_count;
  509. if( nationPtr->total_general_count > max_nation_generals )
  510. max_nation_generals = nationPtr->total_general_count;
  511. if( nationPtr->total_weapon_count > max_nation_weapons )
  512. max_nation_weapons = nationPtr->total_weapon_count;
  513. if( nationPtr->total_ship_count > max_nation_ships )
  514. max_nation_ships = nationPtr->total_ship_count;
  515. if( nationPtr->total_spy_count > max_nation_spies )
  516. max_nation_spies = nationPtr->total_spy_count;
  517. if( nationPtr->total_firm_count > max_nation_firms )
  518. max_nation_firms = nationPtr->total_firm_count;
  519. if( nationPtr->total_tech_level() > max_nation_tech_level )
  520. max_nation_tech_level = nationPtr->total_tech_level();
  521. //----- update maximum nation rating ------//
  522. if( nationPtr->population_rating > max_population_rating )
  523. {
  524. max_population_rating = nationPtr->population_rating;
  525. max_population_nation_recno = i;
  526. }
  527. if( nationPtr->military_rating > max_military_rating )
  528. {
  529. max_military_rating = nationPtr->military_rating;
  530. max_military_nation_recno = i;
  531. }
  532. if( nationPtr->economic_rating > max_economic_rating )
  533. {
  534. max_economic_rating = nationPtr->economic_rating;
  535. max_economic_nation_recno = i;
  536. }
  537. if( (int) nationPtr->reputation > max_reputation )
  538. {
  539. max_reputation = (int) nationPtr->reputation;
  540. max_reputation_nation_recno = i;
  541. }
  542. if( (int) nationPtr->kill_monster_score > max_kill_monster_score )
  543. {
  544. max_kill_monster_score = (int) nationPtr->kill_monster_score;
  545. max_kill_monster_nation_recno = i;
  546. }
  547. if( (int) nationPtr->overall_rating > max_overall_rating )
  548. {
  549. max_overall_rating = (int) nationPtr->overall_rating;
  550. max_overall_nation_recno = i;
  551. }
  552. }
  553. }
  554. //------- End of function NationArray::update_statistic -------//
  555. //------- Begin of function NationArray::update_military_rating ------//
  556. //
  557. void NationArray::update_military_rating()
  558. {
  559. int nationCombatLevelArray[MAX_NATION];
  560. memset( nationCombatLevelArray, 0, sizeof(nationCombatLevelArray) );
  561. //------ calculate firm statistic -------//
  562. Firm* firmPtr;
  563. int i;
  564. for( i=firm_array.size() ; i>0 ; i-- )
  565. {
  566. if( firm_array.is_deleted(i) )
  567. continue;
  568. firmPtr = firm_array[i];
  569. if( firmPtr->nation_recno == 0 ||
  570. firmPtr->firm_id != FIRM_CAMP )
  571. {
  572. continue;
  573. }
  574. nationCombatLevelArray[firmPtr->nation_recno-1] +=
  575. ((FirmCamp*)firmPtr)->total_combat_level() +
  576. ((firmPtr->overseer_recno>0) + firmPtr->worker_count) * 20; // 20 is the base military points for a unit, so the nation that has many more units can be reflected in the military rating
  577. }
  578. //------ calculate unit statistic -------//
  579. Unit* unitPtr;
  580. for( i=unit_array.size() ; i>0 ; i-- )
  581. {
  582. if( unit_array.is_deleted(i) )
  583. continue;
  584. unitPtr = unit_array[i];
  585. if( unitPtr->nation_recno == 0 )
  586. continue;
  587. //---- if this unit is a ship, increase total_ship_combat_level ----//
  588. if( unit_res[unitPtr->unit_id]->unit_class == UNIT_CLASS_SHIP )
  589. {
  590. nation_array[unitPtr->nation_recno]->total_ship_combat_level += (int) unitPtr->hit_points;
  591. }
  592. //----------------------------------//
  593. if( unitPtr->unit_mode == UNIT_MODE_OVERSEE ) // firm commanders are counted above with firm_array
  594. continue;
  595. int addPoints = (int) unitPtr->hit_points;
  596. UnitInfo* unitInfo = unit_res[unitPtr->unit_id];
  597. if( unitInfo->unit_class == UNIT_CLASS_WEAPON )
  598. addPoints += (unitInfo->weapon_power + unitPtr->get_weapon_version() - 1) * 30;
  599. if( unitPtr->leader_unit_recno && !unit_array.is_deleted(unitPtr->leader_unit_recno) )
  600. addPoints += addPoints * unit_array[unitPtr->leader_unit_recno]->skill.skill_level / 100;
  601. nationCombatLevelArray[unitPtr->nation_recno-1] += addPoints + 20; // 20 is the base military points for a unit, so the nation that has many more units can be reflected in the military rating
  602. }
  603. //------ update nation statistic ------//
  604. for( i=size() ; i>0 ; i-- )
  605. {
  606. if( nation_array.is_deleted(i) )
  607. continue;
  608. nation_array[i]->military_rating = nationCombatLevelArray[i-1]/50;
  609. }
  610. }
  611. //------- End of function NationArray::update_military_rating -------//
  612. //------- Begin of function NationArray::update_total_human_count ------//
  613. //
  614. // Update total human count as there are some bugs in calculation of
  615. // total human count. This function is used for on-fly correcting
  616. // the problem.
  617. //
  618. void NationArray::update_total_human_count()
  619. {
  620. int totalHumanCountArray[MAX_NATION];
  621. memset( totalHumanCountArray, 0, sizeof(totalHumanCountArray) );
  622. //------ calculate firm statistic -------//
  623. Firm* firmPtr;
  624. int i;
  625. for( i=firm_array.size() ; i>0 ; i-- )
  626. {
  627. if( firm_array.is_deleted(i) )
  628. continue;
  629. firmPtr = firm_array[i];
  630. if( firmPtr->nation_recno == 0 )
  631. continue;
  632. if( firmPtr->firm_id == FIRM_CAMP || firmPtr->firm_id == FIRM_BASE )
  633. {
  634. for( int j=firmPtr->worker_count-1 ; j>=0 ; j-- )
  635. {
  636. if( firmPtr->worker_array[j].race_id )
  637. {
  638. totalHumanCountArray[firmPtr->nation_recno-1]++;
  639. }
  640. }
  641. }
  642. }
  643. //------ calculate unit statistic -------//
  644. Unit* unitPtr;
  645. for( i=unit_array.size() ; i>0 ; i-- )
  646. {
  647. if( unit_array.is_truly_deleted(i) )
  648. continue;
  649. unitPtr = unit_array[i];
  650. if( unitPtr->nation_recno && unitPtr->race_id &&
  651. unitPtr->rank_id != RANK_KING ) // does not count kings
  652. {
  653. totalHumanCountArray[unitPtr->nation_recno-1]++;
  654. }
  655. }
  656. //------ update nation statistic ------//
  657. for( i=size() ; i>0 ; i-- )
  658. {
  659. if( nation_array.is_deleted(i) )
  660. continue;
  661. #ifdef DEBUG
  662. err_when( nation_array[i]->total_human_count != totalHumanCountArray[i-1] );
  663. #else
  664. if( nation_array[i]->total_human_count != totalHumanCountArray[i-1] )
  665. nation_array[i]->total_human_count = totalHumanCountArray[i-1];
  666. #endif
  667. }
  668. }
  669. //------- End of function NationArray::update_total_human_count -------//
  670. //-------- Begin of function NationArray::get_human_name --------//
  671. //
  672. // <int> nationNameId - name id. of the nation
  673. // [int] firstWordOnly - whether only return the first word of the name or not.
  674. // (default: 0)
  675. //
  676. char* NationArray::get_human_name(int nationNameId, int firstWordOnly)
  677. {
  678. int nationRecno = -nationNameId;
  679. err_when( nationRecno < 1 || nationRecno > MAX_NATION );
  680. static char humanNameOneWord[HUMAN_NAME_LEN+1];
  681. char* humanName = human_name_array[nationRecno-1];
  682. if( firstWordOnly )
  683. {
  684. int i;
  685. for( i=0 ; i<HUMAN_NAME_LEN && humanName[i] && humanName[i]!=' ' ; i++ )
  686. humanNameOneWord[i] = humanName[i];
  687. humanNameOneWord[i] = NULL;
  688. return humanNameOneWord;
  689. }
  690. else
  691. {
  692. return humanName;
  693. }
  694. }
  695. //--------- End of function NationArray::get_human_name ---------//
  696. //-------- Begin of function NationArray::set_human_name --------//
  697. //
  698. void NationArray::set_human_name(int nationRecno, char* nameStr)
  699. {
  700. err_when( nationRecno < 1 || nationRecno > MAX_NATION );
  701. strncpy( human_name_array[nationRecno-1], nameStr, HUMAN_NAME_LEN );
  702. human_name_array[nationRecno-1][HUMAN_NAME_LEN] = NULL;
  703. }
  704. //--------- End of function NationArray::set_human_name ---------//
  705. //------- Begin of function NationArray::disp_nation_color ------//
  706. //
  707. // Display a nation color in a rectangular box.
  708. //
  709. void NationArray::disp_nation_color(int x, int y, int nationColor)
  710. {
  711. vga.active_buf->bar( x, y-2, x+12, y+10, nationColor );
  712. vga.active_buf->rect( x, y-2, x+12, y+10, 1, nationColor+2 );
  713. }
  714. //------- End of function NationArray::disp_nation_color -------//
  715. //------- Begin of function NationBase::should_attack ------//
  716. //
  717. char NationArray::should_attack(short attackingNation, short attackedNation)
  718. {
  719. if( attackingNation == attackedNation )
  720. return 0;
  721. if( attackingNation == 0 || attackedNation == 0 )
  722. return 1;
  723. if( nation_array.is_deleted(attackingNation) || nation_array.is_deleted(attackedNation) )
  724. return 0;
  725. return this->operator[](attackingNation)->get_relation_should_attack(attackedNation);
  726. }
  727. //------- End of function NationBase::should_attack -------//
  728. #ifdef DEBUG
  729. //------- Begin of function NationArray::operator[] -----//
  730. Nation* NationArray::operator[](int recNo)
  731. {
  732. Nation* nationPtr = (Nation*) get_ptr(recNo);
  733. if( !nationPtr )
  734. err.run( "NationArray[] is deleted" );
  735. return nationPtr;
  736. }
  737. //--------- End of function NationArray::operator[] ----//
  738. //------- Begin of function NationArray::operator~ -----//
  739. Nation* NationArray::operator~()
  740. {
  741. if( !player_recno || !player_ptr )
  742. err.run( "~NationArray error" );
  743. return player_ptr;
  744. }
  745. //--------- End of function NationArray::operator~ ----//
  746. #endif
  747. //### begin alex 22/9 ###//
  748. //--------- Begin of function NationArray::draw_profile ---------//
  749. void NationArray::draw_profile()
  750. {
  751. #ifdef DEBUG
  752. static unsigned long lastDrawTime = m.get_time();
  753. if(m.get_time() >= lastDrawTime + 1000)
  754. {
  755. last_nation_ai_profile_time = nation_ai_profile_time;
  756. nation_ai_profile_time = 0L;
  757. last_nation_profile_time = nation_profile_time;
  758. nation_profile_time = 0L;
  759. lastDrawTime = m.get_time();
  760. }
  761. String str;
  762. str = "Nation: ";
  763. font_news.disp( ZOOM_X1+10, ZOOM_Y1+30, str, MAP_X2);
  764. str = "";
  765. str += last_nation_ai_profile_time;
  766. font_news.disp( ZOOM_X1+60, ZOOM_Y1+30, str, MAP_X2);
  767. str = "";
  768. str += last_nation_profile_time;
  769. font_news.disp( ZOOM_X1+100, ZOOM_Y1+30, str, MAP_X2);
  770. #endif
  771. }
  772. //----------- End of function NationArray::draw_profile -----------//
  773. //#### end alex 22/9 ####//