OREGIONS.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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 : OREGIONS.CPP
  21. // Description : functions on RegionStat
  22. #include <stdlib.h>
  23. #include <ONATION.h>
  24. #include <OSITE.h>
  25. #include <OFIRM.h>
  26. #include <OTOWN.h>
  27. #include <OUNIT.h>
  28. #include <OREGIONS.h>
  29. //-------- Begin of function RegionArray::init_region_stat -------//
  30. void RegionArray::init_region_stat()
  31. {
  32. //------ count the no. of regions with statistic -----//
  33. //
  34. // Only include land regions that are big enough.
  35. //
  36. //----------------------------------------------------//
  37. region_stat_count=0;
  38. RegionInfo* regionInfo;
  39. int i;
  40. for( i=1 ; i<=region_info_count ; i++ )
  41. {
  42. regionInfo = region_array[i];
  43. if( regionInfo->region_size >= MIN_STAT_REGION_SIZE && // regions are sorted by their sizes
  44. regionInfo->region_type == REGION_LAND )
  45. {
  46. region_stat_count++;
  47. }
  48. }
  49. err_when( region_stat_count==0 );
  50. //-------- init the region_stat_array ---------//
  51. region_stat_array = (RegionStat*) mem_add( region_stat_count * sizeof(RegionStat) );
  52. memset( region_stat_array, 0, region_stat_count * sizeof(RegionStat) );
  53. int regionStatId=1;
  54. for( i=1 ; i<=region_info_count ; i++ )
  55. {
  56. regionInfo = get_sorted_region(i);
  57. if( regionInfo->region_type != REGION_LAND )
  58. continue;
  59. err_when( regionStatId<1 || regionStatId>region_stat_count );
  60. region_stat_array[regionStatId-1].region_id = regionInfo->region_id;
  61. regionInfo->region_stat_id = regionStatId;
  62. if( ++regionStatId > region_stat_count )
  63. break;
  64. }
  65. err_when( regionStatId != region_stat_count+1 ); // no all regionStat get their region_id
  66. for( i=0 ; i<region_stat_count ; i++ )
  67. region_stat_array[i].init();
  68. update_region_stat();
  69. }
  70. //--------- End of function RegionArray::init_region_stat -------//
  71. //--------- Begin of function RegionArray::update_region_stat -------//
  72. void RegionArray::update_region_stat()
  73. {
  74. for( int i=0 ; i<region_stat_count ; i++ )
  75. region_stat_array[i].update_stat();
  76. }
  77. //--------- End of function RegionArray::update_region_stat -------//
  78. //--------- Begin of function RegionStat::init -------//
  79. void RegionStat::init()
  80. {
  81. //------- init reachable region array ------//
  82. reachable_region_count=0;
  83. for( int seaRegionId=1 ; seaRegionId<=region_array.region_info_count ; seaRegionId++ )
  84. {
  85. if( region_array[seaRegionId]->region_type != REGION_SEA )
  86. continue;
  87. if( !region_array.is_adjacent(region_id, seaRegionId) )
  88. continue;
  89. //--- scan thru all big regions (regions in region_stat_array) ---//
  90. RegionStat* regionStat = region_array.region_stat_array;
  91. for( int i=1 ; i<=region_array.region_stat_count ; i++, regionStat++ )
  92. {
  93. if( regionStat->region_id==region_id )
  94. continue;
  95. if( region_array.is_adjacent(seaRegionId, regionStat->region_id) )
  96. {
  97. reachable_region_array[reachable_region_count].sea_region_id = seaRegionId;
  98. reachable_region_array[reachable_region_count].land_region_stat_id = i;
  99. if( ++reachable_region_count == MAX_REACHABLE_REGION_PER_STAT )
  100. return;
  101. }
  102. }
  103. }
  104. }
  105. //--------- End of function RegionStat::init -------//
  106. //--------- Begin of function RegionStat::update_stat -------//
  107. void RegionStat::update_stat()
  108. {
  109. //------ save useful constant info ------//
  110. int regionId = region_id;
  111. RegionPath reachableRegionArray[MAX_REACHABLE_REGION_PER_STAT];
  112. char reachableRegionCount = reachable_region_count;
  113. err_when( sizeof(reachable_region_array) != sizeof(reachableRegionArray) );
  114. memcpy( reachableRegionArray, reachable_region_array, sizeof(reachable_region_array) );
  115. memset( this, 0, sizeof(RegionStat) ); // reset all data
  116. region_id = regionId;
  117. reachable_region_count = reachableRegionCount;
  118. memcpy( reachable_region_array, reachableRegionArray, sizeof(reachable_region_array) );
  119. //--------- update firm stat ---------//
  120. Firm* firmPtr;
  121. int i;
  122. for( i=firm_array.size() ; i>0 ; i-- )
  123. {
  124. if( firm_array.is_deleted(i) )
  125. continue;
  126. firmPtr = firm_array[i];
  127. if( firmPtr->region_id != region_id )
  128. continue;
  129. if( firmPtr->nation_recno==0 ) // monster firms
  130. continue;
  131. err_when( firmPtr->firm_id < 1 || firmPtr->firm_id > MAX_FIRM_TYPE );
  132. err_when( firmPtr->nation_recno < 1 || firmPtr->nation_recno > MAX_NATION );
  133. firm_type_count_array[firmPtr->firm_id-1]++;
  134. firm_nation_count_array[firmPtr->nation_recno-1]++;
  135. total_firm_count++;
  136. if( firmPtr->firm_id == FIRM_CAMP )
  137. camp_nation_count_array[firmPtr->nation_recno-1]++;
  138. if( firmPtr->firm_id == FIRM_HARBOR )
  139. harbor_nation_count_array[firmPtr->nation_recno-1]++;
  140. if( firmPtr->firm_id == FIRM_MINE )
  141. mine_nation_count_array[firmPtr->nation_recno-1]++;
  142. }
  143. //--------- update town stat ---------//
  144. Town* townPtr;
  145. for( i=town_array.size() ; i>0 ; i-- )
  146. {
  147. if( town_array.is_deleted(i) )
  148. continue;
  149. townPtr = town_array[i];
  150. if( townPtr->region_id != region_id )
  151. continue;
  152. if( townPtr->nation_recno )
  153. {
  154. err_when( townPtr->nation_recno < 1 || townPtr->nation_recno > MAX_NATION );
  155. town_nation_count_array[townPtr->nation_recno-1]++;
  156. if( townPtr->is_base_town )
  157. base_town_nation_count_array[townPtr->nation_recno-1]++;
  158. nation_population_array[townPtr->nation_recno-1] += townPtr->population;
  159. nation_jobless_population_array[townPtr->nation_recno-1] += townPtr->jobless_population;
  160. }
  161. else
  162. independent_town_count++;
  163. total_town_count++;
  164. }
  165. //--------- update unit stat ---------//
  166. Unit* unitPtr;
  167. for( i=unit_array.size() ; i>0 ; i-- )
  168. {
  169. if( unit_array.is_deleted(i) )
  170. continue;
  171. unitPtr = unit_array[i];
  172. if( unitPtr->region_id() != region_id )
  173. continue;
  174. if( unitPtr->nation_recno )
  175. unit_nation_count_array[unitPtr->nation_recno-1]++;
  176. else
  177. independent_unit_count++;
  178. total_unit_count++;
  179. }
  180. //--------- update site count --------//
  181. Site* sitePtr;
  182. for( i=site_array.size() ; i>0 ; i-- )
  183. {
  184. if( site_array.is_deleted(i) )
  185. continue;
  186. sitePtr = site_array[i];
  187. if( sitePtr->region_id != region_id )
  188. continue;
  189. if( sitePtr->site_type == SITE_RAW )
  190. raw_count++;
  191. site_count++;
  192. }
  193. //----- update each nation's presence on the region -----//
  194. for( i=0 ; i<nation_array.size() ; i++ )
  195. {
  196. if( nation_array.is_deleted(i+1) )
  197. continue;
  198. if( firm_nation_count_array[i] > 0 ||
  199. town_nation_count_array[i] > 0 ||
  200. unit_nation_count_array[i] > 0 )
  201. {
  202. nation_is_present_array[i] = 1;
  203. nation_presence_count++;
  204. }
  205. }
  206. }
  207. //--------- End of function RegionStat::update_stat -------//
  208. //--------- Begin of function RegionArray::get_sea_path_region_id -------//
  209. //
  210. // Return the region id. of the sea path between the two given regions.
  211. //
  212. int RegionArray::get_sea_path_region_id(int regionId1, int regionId2)
  213. {
  214. RegionStat* regionStat = region_array.get_region_stat(regionId1);
  215. int regionStatId2 = region_array[regionId2]->region_stat_id;
  216. RegionPath* regionPath = regionStat->reachable_region_array;
  217. for( int i=0 ; i<regionStat->reachable_region_count ; i++, regionPath++ )
  218. {
  219. if( regionPath->land_region_stat_id == regionStatId2 )
  220. return regionPath->sea_region_id;
  221. }
  222. return 0;
  223. }
  224. //--------- End of function RegionArray::get_sea_path_region_id -------//
  225. //--------- Begin of function RegionArray::nation_has_base_town -------//
  226. //
  227. // Return whether the given nation has a base town in the given region.
  228. //
  229. int RegionArray::nation_has_base_town(int regionId, int nationRecno)
  230. {
  231. RegionStat* regionStat = region_array.region_stat_array;
  232. for( int i=1 ; i<=region_array.region_stat_count ; i++, regionStat++ )
  233. {
  234. if( regionStat->region_id != regionId )
  235. continue;
  236. return regionStat->base_town_nation_count_array[nationRecno-1] > 0;
  237. }
  238. return 0;
  239. }
  240. //--------- End of function RegionArray::nation_has_base_town -------//