OUNITRES.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  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 : OUNITRES.CPP
  21. //Description : Object Sprite Frame Resource
  22. #include <ALL.h>
  23. #include <OSTR.h>
  24. #include <OSYS.h>
  25. #include <OGAMESET.h>
  26. #include <ONATION.h>
  27. #include <OSPRTRES.h>
  28. #include <OUNITRES.h>
  29. #if(defined(GERMAN) || defined(FRENCH) || defined(SPANISH))
  30. #include <OTRANSL.h>
  31. #endif
  32. #ifdef NO_DEBUG_UNIT
  33. #undef err_when
  34. #undef err_here
  35. #undef err_if
  36. #undef err_else
  37. #undef err_now
  38. #define err_when(cond)
  39. #define err_here()
  40. #define err_if(cond)
  41. #define err_else
  42. #define err_now(msg)
  43. #undef DEBUG
  44. #endif
  45. //-------- define file name -----------//
  46. #define UNIT_DB "UNIT"
  47. #define UNIT_ATTACK_DB "UNITATTK"
  48. //-------- Begin of function UnitRes::init ---------//
  49. void UnitRes::init()
  50. {
  51. deinit();
  52. //----- open unit bitmap resource file -------//
  53. String str;
  54. str = DIR_RES;
  55. str += "I_UNITLI.RES";
  56. res_large_icon.init_imported(str, 1); // 1-don't read all into buffer
  57. str = DIR_RES;
  58. str += "I_UNITGI.RES";
  59. res_general_icon.init_imported(str, 1); // 1-don't read all into buffer
  60. str = DIR_RES;
  61. str += "I_UNITKI.RES";
  62. res_king_icon.init_imported(str, 1); // 1-don't read all into buffer
  63. str = DIR_RES;
  64. str += "I_UNITSI.RES";
  65. res_small_icon.init_imported(str, 1); // 1-don't read all into buffer
  66. // ######## begin Gilbert 17/10 ##########//
  67. str = DIR_RES;
  68. str += "I_UNITTI.RES";
  69. res_general_small_icon.init_imported(str, 1); // 1-don't read all into buffer
  70. str = DIR_RES;
  71. str += "I_UNITUI.RES";
  72. res_king_small_icon.init_imported(str, 1); // 1-don't read all into buffer
  73. // ######## end Gilbert 17/10 ##########//
  74. //------- load database information --------//
  75. load_info();
  76. load_attack_info();
  77. //---------- set vars -----------//
  78. mobile_monster_count = 0;
  79. init_flag=1;
  80. }
  81. //--------- End of function UnitRes::init ----------//
  82. //-------- Begin of function UnitRes::deinit ---------//
  83. void UnitRes::deinit()
  84. {
  85. if( init_flag )
  86. {
  87. mem_del(unit_info_array);
  88. mem_del(attack_info_array);
  89. res_large_icon.deinit();
  90. res_general_icon.deinit();
  91. res_king_icon.deinit();
  92. res_small_icon.deinit();
  93. // ######## begin Gilbert 17/10 ##########//
  94. res_general_small_icon.deinit();
  95. res_king_small_icon.deinit();
  96. // ######## end Gilbert 17/10 ##########//
  97. init_flag=0;
  98. }
  99. }
  100. //--------- End of function UnitRes::deinit ----------//
  101. //------- Begin of function UnitRes::load_info ---------//
  102. void UnitRes::load_info()
  103. {
  104. Database *dbUnit = game_set.open_db(UNIT_DB);
  105. UnitRec *unitRec;
  106. UnitInfo *unitInfo;
  107. long bitmapOffset;
  108. int i;
  109. unit_info_count = dbUnit->rec_count();
  110. unit_info_array = (UnitInfo*) mem_add(sizeof(UnitInfo) * unit_info_count);
  111. memset( unit_info_array, 0, sizeof(UnitInfo)*unit_info_count );
  112. //--------- read in frame information ---------//
  113. for( i=0 ; i<dbUnit->rec_count() ; i++ )
  114. {
  115. unitRec = (UnitRec*) dbUnit->read(i+1);
  116. unitInfo = unit_info_array+i;
  117. m.rtrim_fld( unitInfo->name, unitRec->name, unitRec->NAME_LEN );
  118. #if(defined(GERMAN) || defined(FRENCH) || defined(SPANISH))
  119. translate.multi_to_win(unitInfo->name, unitInfo->NAME_LEN);
  120. #endif
  121. unitInfo->unit_id = i+1;
  122. unitInfo->sprite_id = m.atoi(unitRec->sprite_id, unitRec->SPRITE_ID_LEN);
  123. unitInfo->dll_sprite_id = m.atoi(unitRec->dll_sprite_id, unitRec->SPRITE_ID_LEN);
  124. unitInfo->race_id = m.atoi(unitRec->race_id , unitRec->RACE_ID_LEN);
  125. unitInfo->unit_class = unitRec->unit_class[0];
  126. unitInfo->mobile_type = unitRec->mobile_type;
  127. unitInfo->visual_range = m.atoi(unitRec->visual_range, unitRec->UNIT_PARA_LEN);
  128. unitInfo->visual_extend = m.atoi(unitRec->visual_extend , unitRec->UNIT_PARA_LEN);
  129. unitInfo->shealth = m.atoi(unitRec->shealth , unitRec->UNIT_PARA_LEN);
  130. unitInfo->hit_points = m.atoi(unitRec->hit_points , unitRec->UNIT_PARA_LEN);
  131. unitInfo->armor = m.atoi(unitRec->armor , unitRec->UNIT_PARA_LEN);
  132. unitInfo->build_days = m.atoi(unitRec->build_days, unitRec->BUILD_DAYS_LEN);
  133. unitInfo->year_cost = m.atoi(unitRec->year_cost, unitRec->YEAR_COST_LEN);
  134. unitInfo->build_cost = unitInfo->year_cost;
  135. if( unitInfo->unit_class == UNIT_CLASS_WEAPON )
  136. unitInfo->weapon_power = unitRec->weapon_power-'0';
  137. unitInfo->carry_unit_capacity = m.atoi(unitRec->carry_unit_capacity, unitRec->CARRY_CAPACITY_LEN);
  138. unitInfo->carry_goods_capacity = m.atoi(unitRec->carry_goods_capacity, unitRec->CARRY_CAPACITY_LEN);
  139. unitInfo->free_weapon_count = m.atoi(unitRec->free_weapon_count, unitRec->FREE_WEAPON_COUNT_LEN);
  140. unitInfo->vehicle_id = m.atoi(unitRec->vehicle_id , unitRec->SPRITE_ID_LEN);
  141. unitInfo->vehicle_unit_id = m.atoi(unitRec->vehicle_unit_id, unitRec->SPRITE_ID_LEN);
  142. unitInfo->transform_unit_id = m.atoi(unitRec->transform_unit_id , unitRec->SPRITE_ID_LEN);
  143. unitInfo->transform_combat_level = m.atoi(unitRec->transform_combat_level, unitRec->UNIT_PARA_LEN);
  144. unitInfo->guard_combat_level = m.atoi(unitRec->guard_combat_level, unitRec->UNIT_PARA_LEN);
  145. memcpy( &bitmapOffset, unitRec->large_icon_ptr, sizeof(long) );
  146. unitInfo->soldier_icon_ptr = res_large_icon.read_imported(bitmapOffset);
  147. if( unitRec->general_icon_file_name[0] != '\0' && unitRec->general_icon_file_name[0] != ' ')
  148. {
  149. memcpy( &bitmapOffset, unitRec->general_icon_ptr, sizeof(long) );
  150. unitInfo->general_icon_ptr = res_general_icon.read_imported(bitmapOffset);
  151. }
  152. else
  153. {
  154. unitInfo->general_icon_ptr = unitInfo->soldier_icon_ptr;
  155. }
  156. if( unitRec->king_icon_file_name[0] != '\0' && unitRec->king_icon_file_name[0] != ' ')
  157. {
  158. memcpy( &bitmapOffset, unitRec->king_icon_ptr, sizeof(long) );
  159. unitInfo->king_icon_ptr = res_king_icon.read_imported(bitmapOffset);
  160. }
  161. else
  162. {
  163. unitInfo->king_icon_ptr = unitInfo->soldier_icon_ptr;
  164. }
  165. // ###### begin Gilbert 17/10 ######//
  166. memcpy( &bitmapOffset, unitRec->small_icon_ptr, sizeof(long) );
  167. unitInfo->soldier_small_icon_ptr = res_small_icon.read_imported(bitmapOffset);
  168. if( unitRec->general_small_icon_file_name[0] != '\0' && unitRec->general_small_icon_file_name[0] != ' ')
  169. {
  170. memcpy( &bitmapOffset, unitRec->general_small_icon_ptr, sizeof(long) );
  171. unitInfo->general_small_icon_ptr = res_general_small_icon.read_imported(bitmapOffset);
  172. }
  173. else
  174. {
  175. unitInfo->general_small_icon_ptr = unitInfo->soldier_small_icon_ptr;
  176. }
  177. if( unitRec->king_small_icon_file_name[0] != '\0' && unitRec->king_small_icon_file_name[0] != ' ')
  178. {
  179. memcpy( &bitmapOffset, unitRec->king_small_icon_ptr, sizeof(long) );
  180. unitInfo->king_small_icon_ptr = res_king_small_icon.read_imported(bitmapOffset);
  181. }
  182. else
  183. {
  184. unitInfo->king_small_icon_ptr = unitInfo->soldier_small_icon_ptr;
  185. }
  186. // ###### end Gilbert 17/10 ######//
  187. unitInfo->first_attack = m.atoi(unitRec->first_attack, unitRec->UNIT_PARA_LEN);
  188. unitInfo->attack_count = m.atoi(unitRec->attack_count, unitRec->UNIT_PARA_LEN);
  189. unitInfo->die_effect_id = m.atoi(unitRec->die_effect_id, unitRec->UNIT_PARA_LEN);
  190. if( unitRec->all_know=='1' )
  191. memset( unitInfo->nation_tech_level_array, 1, sizeof(unitInfo->nation_tech_level_array) );
  192. }
  193. //--------- set vehicle info ---------//
  194. for( i=0 ; i<unit_info_count ; i++ )
  195. {
  196. unitInfo = unit_info_array+i;
  197. if( unitInfo->vehicle_unit_id )
  198. {
  199. unit_info_array[ unitInfo->vehicle_unit_id-1 ].vehicle_id = unitInfo->vehicle_id;
  200. unit_info_array[ unitInfo->vehicle_unit_id-1 ].solider_id = i+1;
  201. }
  202. }
  203. }
  204. //-------- End of function UnitRes::load_info ---------//
  205. //------- Begin of function UnitRes::load_attack_info ---------//
  206. void UnitRes::load_attack_info()
  207. {
  208. Database *dbUnitAttack = game_set.open_db(UNIT_ATTACK_DB);
  209. UnitAttackRec *attackRec;
  210. AttackInfo *attackInfo;
  211. int i;
  212. attack_info_count = dbUnitAttack->rec_count();
  213. attack_info_array = (AttackInfo*) mem_add(sizeof(AttackInfo) * attack_info_count);
  214. memset( attack_info_array, 0, sizeof(AttackInfo)*attack_info_count );
  215. //--------- read in frame information ---------//
  216. for( i=0 ; i<dbUnitAttack->rec_count() ; i++ )
  217. {
  218. attackRec = (UnitAttackRec*) dbUnitAttack->read(i+1);
  219. attackInfo = attack_info_array+i;
  220. attackInfo->combat_level = m.atoi(attackRec->combat_level , attackRec->COMBAT_LEVEL_LEN);
  221. attackInfo->attack_delay = m.atoi(attackRec->attack_delay , attackRec->UNIT_PARA_LEN);
  222. attackInfo->attack_range = m.atoi(attackRec->attack_range , attackRec->UNIT_PARA_LEN);
  223. attackInfo->attack_damage = m.atoi(attackRec->attack_damage , attackRec->UNIT_PARA_LEN);
  224. attackInfo->pierce_damage = m.atoi(attackRec->pierce_damage , attackRec->UNIT_PARA_LEN);
  225. attackInfo->bullet_out_frame = m.atoi(attackRec->bullet_out_frame, attackRec->UNIT_PARA_LEN);
  226. attackInfo->bullet_speed = m.atoi(attackRec->bullet_speed , attackRec->UNIT_PARA_LEN);
  227. attackInfo->bullet_radius = m.atoi(attackRec->bullet_radius , attackRec->UNIT_PARA_LEN);
  228. attackInfo->bullet_sprite_id = m.atoi(attackRec->bullet_sprite_id, attackRec->UNIT_PARA_LEN);
  229. attackInfo->dll_bullet_sprite_id = m.atoi(attackRec->dll_bullet_sprite_id, attackRec->UNIT_PARA_LEN);
  230. attackInfo->eqv_attack_next = m.atoi(attackRec->eqv_attack_next, attackRec->UNIT_PARA_LEN);
  231. attackInfo->min_power = m.atoi(attackRec->min_power, attackRec->UNIT_PARA_LEN);
  232. attackInfo->consume_power = m.atoi(attackRec->consume_power, attackRec->UNIT_PARA_LEN);
  233. attackInfo->fire_radius = m.atoi(attackRec->fire_radius, attackRec->UNIT_PARA_LEN);
  234. attackInfo->effect_id = m.atoi(attackRec->effect_id, attackRec->UNIT_PARA_LEN);
  235. }
  236. }
  237. //-------- End of function UnitRes::load_attack_info ---------//
  238. //-------- Begin of function UnitRes::mobile_type_to_mask --------//
  239. char UnitRes::mobile_type_to_mask(int mobileType)
  240. {
  241. switch( mobileType)
  242. {
  243. case UNIT_LAND:
  244. return 1;
  245. case UNIT_SEA:
  246. return 2;
  247. case UNIT_AIR:
  248. return 3;
  249. default:
  250. err_here();
  251. return 0;
  252. }
  253. }
  254. //-------- End of function UnitRes::mobile_type_to_mask --------//
  255. //-------- Begin of function UnitInfo::is_loaded -------//
  256. int UnitInfo::is_loaded()
  257. {
  258. return sprite_res[sprite_id]->is_loaded();
  259. }
  260. //--------- End of function UnitInfo::is_loaded --------//
  261. //---- Begin of function UnitInfo::inc_nation_unit_count ----//
  262. void UnitInfo::inc_nation_unit_count(int nationRecno)
  263. {
  264. err_when( nationRecno<1 || nationRecno>nation_array.size() );
  265. nation_unit_count_array[nationRecno-1]++;
  266. //------- increase the nation's unit count ---------//
  267. Nation* nationPtr = nation_array[nationRecno];
  268. nationPtr->total_unit_count++;
  269. if( unit_class==UNIT_CLASS_WEAPON )
  270. {
  271. nationPtr->total_weapon_count++;
  272. }
  273. else if( unit_class==UNIT_CLASS_SHIP )
  274. {
  275. nationPtr->total_ship_count++;
  276. }
  277. else if( race_id )
  278. {
  279. nationPtr->total_human_count++;
  280. }
  281. }
  282. //----- End of function UnitInfo::inc_nation_unit_count -----//
  283. //---- Begin of function UnitInfo::dec_nation_unit_count ----//
  284. void UnitInfo::dec_nation_unit_count(int nationRecno)
  285. {
  286. err_when( nationRecno<0 || nationRecno>MAX_NATION );
  287. if( nationRecno )
  288. {
  289. nation_unit_count_array[nationRecno-1]--;
  290. err_when( nation_unit_count_array[nationRecno-1] < 0 );
  291. //------ decrease the nation's unit count -------//
  292. Nation* nationPtr = nation_array[nationRecno];
  293. nationPtr->total_unit_count--;
  294. err_when( nationPtr->total_unit_count < 0 );
  295. if( unit_class==UNIT_CLASS_WEAPON )
  296. {
  297. nationPtr->total_weapon_count--;
  298. err_when( nationPtr->total_weapon_count < 0 );
  299. }
  300. else if( unit_class==UNIT_CLASS_SHIP )
  301. {
  302. nationPtr->total_ship_count--;
  303. err_when( nationPtr->total_ship_count < 0 );
  304. }
  305. else if( race_id )
  306. {
  307. nationPtr->total_human_count--;
  308. err_when( nationPtr->total_human_count < 0 );
  309. if( nationPtr->total_human_count < 0 )
  310. nationPtr->total_human_count = 0;
  311. }
  312. }
  313. }
  314. //----- End of function UnitInfo::dec_nation_unit_count -----//
  315. //---- Begin of function UnitInfo::inc_nation_general_count ----//
  316. void UnitInfo::inc_nation_general_count(int nationRecno)
  317. {
  318. err_when( nationRecno<1 || nationRecno>nation_array.size() );
  319. nation_general_count_array[nationRecno-1]++;
  320. nation_array[nationRecno]->total_general_count++;
  321. }
  322. //----- End of function UnitInfo::inc_nation_general_count -----//
  323. //---- Begin of function UnitInfo::dec_nation_general_count ----//
  324. void UnitInfo::dec_nation_general_count(int nationRecno)
  325. {
  326. err_when( nationRecno<0 || nationRecno>MAX_NATION );
  327. if( nationRecno )
  328. {
  329. nation_general_count_array[nationRecno-1]--;
  330. nation_array[nationRecno]->total_general_count--;
  331. }
  332. err_when( nation_general_count_array[nationRecno-1] < 0 );
  333. }
  334. //----- End of function UnitInfo::dec_nation_general_count -----//
  335. //-------- Begin of function UnitInfo::unit_change_nation -------//
  336. //
  337. // Call this function when a unit changes its nation. This
  338. // function updates the unit count vars in the UnitInfo.
  339. //
  340. // <int> newNationRecno - the new nation recno
  341. // <int> oldNationRecno - the original nation recno
  342. // <int> rankId - the rank of the unit.
  343. //
  344. void UnitInfo::unit_change_nation(int newNationRecno, int oldNationRecno, int rankId)
  345. {
  346. //---- update nation_unit_count_array[] ----//
  347. if( oldNationRecno )
  348. {
  349. if( rankId != RANK_KING )
  350. dec_nation_unit_count(oldNationRecno);
  351. if( rankId == RANK_GENERAL )
  352. dec_nation_general_count(oldNationRecno);
  353. }
  354. if( newNationRecno )
  355. {
  356. if( rankId != RANK_KING )
  357. inc_nation_unit_count(newNationRecno);
  358. if( rankId == RANK_GENERAL ) // if the new rank is general
  359. inc_nation_general_count(newNationRecno);
  360. }
  361. }
  362. //--------- End of function UnitInfo::unit_change_nation --------//
  363. #ifdef DEBUG
  364. //-------- Begin of function UnitRes::get_attack_info -------//
  365. AttackInfo* UnitRes::get_attack_info(int attackId)
  366. {
  367. if( attackId<1 || attackId>attack_info_count )
  368. err.run( "UnitRes::get_attack_info[]" );
  369. return attack_info_array+attackId-1;
  370. }
  371. //--------- End of function UnitRes::get_attack_info --------//
  372. //-------- Begin of function UnitRes::operator[] -------//
  373. UnitInfo* UnitRes::operator[](int unitId)
  374. {
  375. if( unitId<1 || unitId>unit_info_count )
  376. err.run( "UnitRes::operator[]" );
  377. return unit_info_array+unitId-1;
  378. }
  379. //--------- End of function UnitRes::operator[] --------//
  380. #endif
  381. //-------- Begin of function UnitInfo::get_large_icon_ptr -------//
  382. char *UnitInfo::get_large_icon_ptr(char rankId)
  383. {
  384. switch( rankId )
  385. {
  386. case RANK_KING:
  387. return king_icon_ptr;
  388. case RANK_GENERAL:
  389. return general_icon_ptr;
  390. case RANK_SOLDIER:
  391. default:
  392. return soldier_icon_ptr;
  393. }
  394. }
  395. //-------- End of function UnitInfo::get_large_icon_ptr -------//
  396. // ##### begin Gilbert 17/10 ########//
  397. // -------- Begin of function UnitInfo::get_small_icon_ptr --------//
  398. char *UnitInfo::get_small_icon_ptr(char rankId)
  399. {
  400. switch( rankId )
  401. {
  402. case RANK_KING:
  403. return king_small_icon_ptr;
  404. case RANK_GENERAL:
  405. return general_small_icon_ptr;
  406. case RANK_SOLDIER:
  407. default:
  408. return soldier_small_icon_ptr;
  409. }
  410. }
  411. // -------- End of function UnitInfo::get_small_icon_ptr --------//
  412. // ##### end Gilbert 17/10 ########//