OMONSRES.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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 : OMONSRES.CPP
  21. //Description : Monster resource class
  22. #include <OSYS.h>
  23. #include <OGAMESET.h>
  24. #include <OWORLD.h>
  25. #include <OSPRTRES.h>
  26. #include <OUNIT.h>
  27. #include <OUNITRES.h>
  28. #include <OTOWN.h>
  29. #include <OFIRM.h>
  30. #include <OF_MONS.h>
  31. #include <OMONSRES.h>
  32. #if(defined(GERMAN) || defined(FRENCH) || defined(SPANISH))
  33. #include <OTRANSL.h>
  34. #endif
  35. //---------- #define constant ------------//
  36. #define MONSTER_DB "MONSTER"
  37. //------- Begin of function MonsterRes::MonsterRes -----------//
  38. MonsterRes::MonsterRes()
  39. {
  40. init_flag=0;
  41. }
  42. //--------- End of function MonsterRes::MonsterRes -----------//
  43. //---------- Begin of function MonsterRes::init -----------//
  44. //
  45. // This function must be called after a map is generated.
  46. //
  47. void MonsterRes::init()
  48. {
  49. deinit();
  50. //------- load database information --------//
  51. load_monster_info();
  52. init_flag=1;
  53. }
  54. //---------- End of function MonsterRes::init -----------//
  55. //---------- Begin of function MonsterRes::deinit -----------//
  56. void MonsterRes::deinit()
  57. {
  58. if( init_flag )
  59. {
  60. mem_del(monster_info_array);
  61. init_flag=0;
  62. }
  63. }
  64. //---------- End of function MonsterRes::deinit -----------//
  65. //------- Begin of function MonsterRes::load_monster_info -------//
  66. //
  67. // Read in information of MONSTER.DBF into memory array
  68. //
  69. void MonsterRes::load_monster_info()
  70. {
  71. MonsterRec *monsterRec;
  72. MonsterInfo *monsterInfo;
  73. int i;
  74. Database *dbMonster = game_set.open_db(MONSTER_DB);
  75. monster_count = (short) dbMonster->rec_count();
  76. monster_info_array = (MonsterInfo*) mem_add( sizeof(MonsterInfo)*monster_count );
  77. //------ read in monster information array -------//
  78. memset( monster_info_array, 0, sizeof(MonsterInfo) * monster_count );
  79. for( i=0 ; i<monster_count ; i++ )
  80. {
  81. monsterRec = (MonsterRec*) dbMonster->read(i+1);
  82. monsterInfo = monster_info_array+i;
  83. monsterInfo->monster_id = i+1;
  84. m.rtrim_fld( monsterInfo->name, monsterRec->name, monsterRec->NAME_LEN );
  85. #if(defined(GERMAN) || defined(FRENCH) || defined(SPANISH))
  86. translate.multi_to_win(monsterInfo->name, monsterInfo->NAME_LEN);
  87. #endif
  88. monsterInfo->unit_id = m.atoi(monsterRec->unit_id , monsterRec->UNIT_ID_LEN);
  89. monsterInfo->level = monsterRec->level - '0';
  90. err_when( monsterInfo->level < 1 || monsterInfo->level > MAX_MONSTER_LEVEL );
  91. m.rtrim_fld( monsterInfo->firm_build_code, monsterRec->firm_build_code, monsterRec->FIRM_BUILD_CODE_LEN );
  92. //---- set the monster_id in UnitInfo ----//
  93. unit_res[monsterInfo->unit_id]->is_monster = 1;
  94. }
  95. }
  96. //--------- End of function MonsterRes::load_monster_info ---------//
  97. //---------- Begin of function MonsterRes::init_active_monster -----------//
  98. void MonsterRes::init_active_monster()
  99. {
  100. int monsterId;
  101. int activeCount=0;
  102. int loopCount=0;
  103. //----- reset the active_monster_array ----//
  104. memset( active_monster_array, 0, sizeof(active_monster_array) );
  105. //------- in the demo, the active monsters are fixed -----//
  106. #ifdef DEMO
  107. active_monster_array[0] = 4;
  108. active_monster_array[1] = 11;
  109. active_monster_array[2] = 12;
  110. #endif
  111. //-------- set active monsters -------//
  112. while(1)
  113. {
  114. err_when( ++loopCount > 1000 );
  115. monsterId = m.random(monster_count)+1;
  116. //--- check if this monster id. is already in the active monster array ---//
  117. int i;
  118. for( i=0 ; i<activeCount ; i++ )
  119. {
  120. if( active_monster_array[i] == monsterId )
  121. break;
  122. }
  123. //------- if it's a new one --------//
  124. if( i==activeCount )
  125. {
  126. active_monster_array[activeCount] = monsterId;
  127. if( ++activeCount == MAX_ACTIVE_MONSTER )
  128. return;
  129. }
  130. }
  131. }
  132. //---------- End of function MonsterRes::init_active_monster -----------//
  133. //---------- Begin of function MonsterRes::operator[] -----------//
  134. MonsterInfo* MonsterRes::operator[](int monsterId)
  135. {
  136. err_if( monsterId<1 || monsterId>monster_count )
  137. err_now( "MonsterRes::operator[]" );
  138. return monster_info_array+monsterId-1;
  139. }
  140. //------------ End of function MonsterRes::operator[] -----------//
  141. //---------- Begin of function MonsterRes::generate -----------//
  142. void MonsterRes::generate(int generateCount)
  143. {
  144. int monsterId;
  145. for( int i=0 ; i<generateCount ; i++ )
  146. {
  147. monsterId = active_monster_array[m.random(MAX_ACTIVE_MONSTER)];
  148. monster_res[monsterId]->create_firm_monster();
  149. }
  150. }
  151. //---------- End of function MonsterRes::generate -----------//
  152. //------- Begin of function MonsterInfo::create_firm_monster --------//
  153. //
  154. int MonsterInfo::create_firm_monster()
  155. {
  156. #define MIN_MONSTER_CIVILIAN_DISTANCE 10 // the minimum distance between monster firms and civilian towns & firms
  157. if( !firm_build_code[0] ) // this monster does not have a home
  158. return 0;
  159. //------- locate a home place for the monster group ------//
  160. FirmInfo* firmInfo = firm_res[FIRM_MONSTER];
  161. int xLoc=0, yLoc=0;
  162. char teraMask = UnitRes::mobile_type_to_mask(UNIT_LAND);
  163. if( !world.locate_space_random(xLoc, yLoc, MAX_WORLD_X_LOC-1,
  164. MAX_WORLD_Y_LOC-1, firmInfo->loc_width+2, firmInfo->loc_height+2, // leave at least one location space around the building
  165. MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC, 0, 1, teraMask) )
  166. {
  167. return 0;
  168. }
  169. //------- don't place it too close to any towns or firms ------//
  170. for( int townRecno=town_array.size() ; townRecno>0 ; townRecno-- )
  171. {
  172. if( town_array.is_deleted(townRecno) )
  173. continue;
  174. Town* townPtr = town_array[townRecno];
  175. if( m.points_distance(xLoc, yLoc, townPtr->center_x,
  176. townPtr->center_y) < MIN_MONSTER_CIVILIAN_DISTANCE )
  177. {
  178. return 0;
  179. }
  180. }
  181. for( int firmRecno=firm_array.size() ; firmRecno>0 ; firmRecno-- )
  182. {
  183. if( firm_array.is_deleted(firmRecno) )
  184. continue;
  185. Firm* firmPtr = firm_array[firmRecno];
  186. if( m.points_distance(xLoc, yLoc, firmPtr->center_x,
  187. firmPtr->center_y) < MIN_MONSTER_CIVILIAN_DISTANCE )
  188. {
  189. return 0;
  190. }
  191. }
  192. return build_firm_monster(xLoc+1, yLoc+1);
  193. }
  194. //---------- End of function MonsterInfo::create_firm_monster -----------//
  195. //------- Begin of function MonsterInfo::build_firm_monster --------//
  196. // [int] fullHitPoints - build with full hit points (default = 1)
  197. //
  198. int MonsterInfo::build_firm_monster(int xLoc, int yLoc, int fullHitPoints)
  199. {
  200. //----- if this monster has a home building, create it first -----//
  201. FirmMonster* firmPtr=NULL;
  202. int firmRecno = firm_array.build_firm(xLoc, yLoc, 0, FIRM_MONSTER, firm_build_code);
  203. if( !firmRecno )
  204. return 0;
  205. firmPtr = (FirmMonster*) firm_array[firmRecno];
  206. if(fullHitPoints)
  207. firmPtr->complete_construction();
  208. else
  209. {
  210. firmPtr->hit_points = (float) 0.1;
  211. firmPtr->under_construction = 1;
  212. }
  213. firmPtr->set_king(monster_id, 100);
  214. //-------- create monster generals ---------//
  215. int generalCount = m.random(2)+1; // 1 to 3 generals in a monster firm
  216. if( m.random(5)==0 ) // 20% chance of having 3 generals.
  217. generalCount=3;
  218. for( int i=0 ; i<generalCount ; i++ )
  219. firmPtr->recruit_general();
  220. firmPtr->monster_id = monster_id;
  221. return firmRecno;
  222. }
  223. //---------- End of function MonsterInfo::build_firm_monster -----------//
  224. //--------- Begin of function MonsterRes::stop_attack_nation -------//
  225. void MonsterRes::stop_attack_nation(short nationRecno)
  226. {
  227. FirmMonster* firmMonster;
  228. for(int i=firm_array.size(); i>0; i--)
  229. {
  230. if( firm_array.is_deleted(i) || firm_array[i]->firm_id != FIRM_MONSTER )
  231. continue;
  232. firmMonster = (FirmMonster*) firm_array[i];
  233. firmMonster->reset_hostile_nation(nationRecno);
  234. }
  235. }
  236. //----------- End of function MonsterRes::stop_attack_nation ---------//