OREBEL.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  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 : OREBEL.CPP
  21. //Description : Object Rebel
  22. #include <OPOWER.h>
  23. #include <OGAME.h>
  24. #include <OUNIT.h>
  25. #include <OFIRM.h>
  26. #include <OTOWN.h>
  27. #include <ONEWS.h>
  28. #include <OREBEL.h>
  29. #include <ORACERES.h>
  30. #include <ONATION.h>
  31. //--------- Begin of function RebelArray::RebelArray ----------//
  32. RebelArray::RebelArray() : DynArrayB(sizeof(Rebel*), 10, DEFAULT_REUSE_INTERVAL_DAYS)
  33. {
  34. }
  35. //--------- End of function RebelArray::RebelArary ----------//
  36. //------- Begin of function RebelArray::~RebelArray ----------//
  37. //
  38. RebelArray::~RebelArray()
  39. {
  40. deinit();
  41. }
  42. //--------- End of function RebelArray::~RebelArray ----------//
  43. //--------- Begin of function RebelArray::init ----------//
  44. //
  45. void RebelArray::init()
  46. {
  47. }
  48. //---------- End of function RebelArray::init ----------//
  49. //--------- Begin of function RebelArray::deinit ----------//
  50. //
  51. void RebelArray::deinit()
  52. {
  53. if( size()==0 )
  54. return;
  55. //----- delete Rebel objects ------//
  56. Rebel* rebelPtr;
  57. for( int i=1 ; i<=size() ; i++ )
  58. {
  59. rebelPtr = (Rebel*) get_ptr(i);
  60. if( rebelPtr )
  61. delete rebelPtr;
  62. }
  63. //-------- zap the array -----------//
  64. zap();
  65. }
  66. //---------- End of function RebelArray::deinit ----------//
  67. //------- Begin of function RebelArray::create_rebel ---------//
  68. //
  69. // Create a rebel group. If there are a rebel group nearby
  70. // with the same objectives, join the rebel group without
  71. // creating a new one.
  72. //
  73. // <int> unitRecno - recno of the rebel leader
  74. // <int> hostileNationRecno - the recno of the now hostile nation which
  75. // the people rebels from.
  76. // [int] actionMode - rebel action mode (default: REBEL_IDLE)
  77. // [int] actionPara - action parameters (default: 0)
  78. //
  79. // return: <int> rebelRecno - recno of the rebel group
  80. //
  81. int RebelArray::create_rebel(int unitRecno, int hostileNationRecno, int actionMode, int actionPara)
  82. {
  83. //------------------------------------------//
  84. // See if there are a rebel group nearby
  85. // with the same objectives, join the rebel
  86. // group without creating a new one.
  87. //------------------------------------------//
  88. int rebelRecno = m.random(rebel_array.size())+1;
  89. Rebel* rebelPtr;
  90. for( int i=size() ; i>=1 ; i-- )
  91. {
  92. if( ++rebelRecno > rebel_array.size() )
  93. rebelRecno = 1;
  94. if( rebel_array.is_deleted(rebelRecno) )
  95. continue;
  96. rebelPtr = rebel_array[rebelRecno];
  97. if( rebelPtr->action_mode == actionMode &&
  98. rebelPtr->action_para == actionPara )
  99. {
  100. rebelPtr->join(unitRecno); // join the rebel group
  101. return rebelRecno;
  102. }
  103. }
  104. //-------- create a new rebel group ---------//
  105. rebelPtr = new Rebel;
  106. rebelPtr->leader_unit_recno = unitRecno;
  107. rebelPtr->action_mode = actionMode;
  108. rebelPtr->action_para = actionPara;
  109. rebelPtr->mobile_rebel_count = 1;
  110. rebelPtr->set_hostile_nation(hostileNationRecno);
  111. linkin(&rebelPtr);
  112. rebelPtr->rebel_recno = recno();
  113. unit_array[unitRecno]->set_mode( UNIT_MODE_REBEL, recno() );
  114. return recno();
  115. }
  116. //-------- End of function RebelArray::create_rebel ---------//
  117. //------- Begin of function RebelArray::del_rebel ---------//
  118. //
  119. void RebelArray::del_rebel(int rebelRecno)
  120. {
  121. Rebel* rebelPtr = operator[](rebelRecno);
  122. delete rebelPtr;
  123. linkout(rebelRecno);
  124. }
  125. //-------- End of function RebelArray::del_rebel ---------//
  126. //--------- Begin of function RebelArray::stop_attack_town ---------//
  127. void RebelArray::stop_attack_town(short townRecno)
  128. {
  129. Rebel *rebelPtr;
  130. for(int i=size(); i>0; --i)
  131. {
  132. rebelPtr = (Rebel*) get_ptr(i);
  133. if(rebelPtr && rebelPtr->action_mode==REBEL_ATTACK_TOWN)
  134. {
  135. if(rebelPtr->action_para==townRecno)
  136. {
  137. rebelPtr->set_action(REBEL_IDLE);
  138. rebelPtr->stop_all_rebel_unit();
  139. break;
  140. }
  141. }
  142. }
  143. }
  144. //-------- End of function RebelArray::stop_attack_town ---------//
  145. //--------- Begin of function RebelArray::stop_attack_firm ---------//
  146. void RebelArray::stop_attack_firm(short firmRecno)
  147. {
  148. Rebel *rebelPtr;
  149. for(int i=size(); i>0; --i)
  150. {
  151. rebelPtr = (Rebel*) get_ptr(i);
  152. if(rebelPtr && rebelPtr->action_mode==REBEL_ATTACK_FIRM)
  153. {
  154. if(rebelPtr->action_para==firmRecno)
  155. {
  156. rebelPtr->set_action(REBEL_IDLE);
  157. rebelPtr->stop_all_rebel_unit();
  158. return;
  159. }
  160. }
  161. }
  162. }
  163. //-------- End of function RebelArray::stop_attack_firm ---------//
  164. //### begin alex 20/8 ###//
  165. //--------- Begin of function RebelArray::stop_attack_nation ---------//
  166. void RebelArray::stop_attack_nation(short nationRecno)
  167. {
  168. Rebel *rebelPtr;
  169. for(int i=size(); i>0; i--)
  170. {
  171. rebelPtr = (Rebel*) get_ptr(i);
  172. if(rebelPtr)
  173. rebelPtr->reset_hostile_nation(nationRecno);
  174. }
  175. }
  176. //-------- End of function RebelArray::stop_attack_nation ---------//
  177. //#### end alex 20/8 ####//
  178. //--------- Begin of function RebelArray::next_day ---------//
  179. //
  180. void RebelArray::next_day()
  181. {
  182. int i;
  183. Rebel *rebelPtr;
  184. for( i=size() ; i>0 ; i-- )
  185. {
  186. rebelPtr = (Rebel*) get_ptr(i);
  187. if( rebelPtr )
  188. rebelPtr->next_day();
  189. }
  190. }
  191. //----------- End of function RebelArray::next_day ---------//
  192. //--------- Begin of function RebelArray::drop_rebel_identity -------//
  193. //
  194. // 4 fates for a rebel unit:
  195. //
  196. // - the rebel gets killed
  197. // - the rebel group settles down in a town
  198. // - the rebel surrender a nation
  199. // - the rebel group merges with another rebel group
  200. //
  201. // This function handle the fate that the unit gets killed.
  202. //
  203. void RebelArray::drop_rebel_identity(int unitRecno)
  204. {
  205. Unit* unitPtr = unit_array[unitRecno];
  206. err_when( unitPtr->unit_mode != UNIT_MODE_REBEL );
  207. err_when( rebel_array.is_deleted(unitPtr->unit_mode_para) );
  208. //---- decrease the unit count of the rebel group ----//
  209. int rebelRecno = unitPtr->unit_mode_para;
  210. Rebel* rebelPtr = rebel_array[rebelRecno];
  211. rebelPtr->mobile_rebel_count--;
  212. unitPtr->set_mode(0); // drop its rebel identity
  213. //----- if all rebels are dead and the rebel doesn't occupy a town, del the rebel group ----//
  214. if( rebelPtr->mobile_rebel_count==0 && rebelPtr->town_recno==0 )
  215. {
  216. del_rebel(rebelRecno);
  217. return;
  218. }
  219. //----- when the rebel leader is killed -----//
  220. if( rebelPtr->leader_unit_recno == unitRecno )
  221. rebelPtr->process_leader_quit();
  222. }
  223. //----------- End of function RebelArray::drop_rebel_identity --------//
  224. //--------- Begin of function Rebel::process_leader_quit -------//
  225. //
  226. void Rebel::process_leader_quit()
  227. {
  228. //-------------------------------------------//
  229. //
  230. // When the rebel leader gets killed, a new rebel unit
  231. // in the group is elected as the new leader.
  232. //
  233. // Some the rebel units leave the rebel group to:
  234. // surrender to a nation (moving into a town as town people)
  235. //
  236. //-------------------------------------------//
  237. //----- select a new unit as the leader ------//
  238. leader_unit_recno = 0;
  239. if( mobile_rebel_count>0 ) // it must at least be 2: the dying leader + one rebel soldier
  240. {
  241. select_new_leader();
  242. }
  243. else
  244. {
  245. err_when( !town_recno ); // if mobile_label_count is 0, the rebel group must have a town
  246. // if the rebel has a town, leader_unit_recno can be 0
  247. }
  248. //------ some the rebel units leave the rebel group -----//
  249. if( mobile_rebel_count>1 )
  250. {
  251. //---- surrender to a nation ----//
  252. int maxReputation=0, bestNationRecno=0;
  253. Nation* nationPtr;
  254. int i;
  255. for( i=nation_array.size() ; i>0 ; i-- )
  256. {
  257. if( nation_array.is_deleted(i) )
  258. continue;
  259. nationPtr = nation_array[i];
  260. if( nationPtr->reputation > maxReputation )
  261. {
  262. maxReputation = (int) nationPtr->reputation;
  263. bestNationRecno = i;
  264. }
  265. }
  266. if( !bestNationRecno ) // no nation has a positive reputation
  267. return;
  268. //------- process the rebel units -------//
  269. Unit* unitPtr;
  270. for( i=unit_array.size() ; i>0 ; i-- )
  271. {
  272. if( unit_array.is_deleted(i) )
  273. continue;
  274. unitPtr = unit_array[i];
  275. if( unitPtr->unit_mode == UNIT_MODE_REBEL &&
  276. unitPtr->unit_mode_para == leader_unit_recno )
  277. {
  278. unitPtr->set_mode(0);
  279. unitPtr->change_nation(bestNationRecno);
  280. }
  281. }
  282. }
  283. }
  284. //-------- End of function Rebel::process_leader_quit --------//
  285. //--------- Begin of function Rebel::select_new_leader -------//
  286. //
  287. int Rebel::select_new_leader()
  288. {
  289. if( mobile_rebel_count==0 )
  290. return 0;
  291. Unit* unitPtr;
  292. int i;
  293. for( i=unit_array.size() ; i>0 ; i-- )
  294. {
  295. if( unit_array.is_deleted(i) )
  296. continue;
  297. unitPtr = unit_array[i];
  298. if( unitPtr->unit_mode==UNIT_MODE_REBEL &&
  299. unitPtr->unit_mode_para == rebel_recno )
  300. {
  301. err_when( unitPtr->hit_points<=0 );
  302. unitPtr->set_rank(RANK_GENERAL);
  303. leader_unit_recno = i;
  304. break;
  305. }
  306. }
  307. if( !leader_unit_recno )
  308. return 0;
  309. //--- update the leader_unit_renco of all units in this rebel group ---//
  310. for( i=unit_array.size() ; i>0 ; i-- )
  311. {
  312. if( unit_array.is_deleted(i) )
  313. continue;
  314. unitPtr = unit_array[i];
  315. if( unitPtr->unit_mode==UNIT_MODE_REBEL &&
  316. unitPtr->unit_mode_para == rebel_recno )
  317. {
  318. unitPtr->leader_unit_recno = leader_unit_recno;
  319. }
  320. }
  321. return 0;
  322. }
  323. //-------- End of function Rebel::select_new_leader --------//
  324. //-------- Begin of function RebelArray::settle_town -------//
  325. //
  326. // A unit settle_towns from its rebel group.
  327. //
  328. // <int> unitRecno - recno of the unit going to settle in the town
  329. // <int> townRecno - recno of the town this unit settles
  330. //
  331. void RebelArray::settle_town(int unitRecno, int townRecno)
  332. {
  333. Unit* unitPtr = unit_array[unitRecno];
  334. err_when( unitPtr->unit_mode != UNIT_MODE_REBEL );
  335. err_when( rebel_array.is_deleted(unitPtr->unit_mode_para) );
  336. //---- decrease the unit count of the rebel group ----//
  337. int rebelRecno = unitPtr->unit_mode_para;
  338. Rebel* rebelPtr = rebel_array[rebelRecno];
  339. rebelPtr->mobile_rebel_count--;
  340. //--------- settle in a town ----------//
  341. // err_when( rebelPtr->town_recno && rebelPtr->town_recno != townRecno ); // one rebel group only allow settle in a town, error when trying to settle in more than one town
  342. Town* townPtr = town_array[townRecno];
  343. if( rebelPtr->town_recno==0 && townPtr->rebel_recno==0 )
  344. {
  345. rebelPtr->town_recno = townRecno;
  346. townPtr->rebel_recno = rebelRecno;
  347. }
  348. }
  349. //----------- End of function RebelArray::settle_town --------//
  350. //--------- Begin of function Rebel::Rebel --------//
  351. //
  352. Rebel::Rebel()
  353. {
  354. memset( this, 0, sizeof(Rebel) );
  355. hostile_nation_bits = 0;
  356. }
  357. //----------- End of function Rebel::Rebel ---------//
  358. //--------- Begin of function Rebel::~Rebel --------//
  359. //
  360. Rebel::~Rebel()
  361. {
  362. Unit* unitPtr;
  363. for( int i=unit_array.size() ; i>0 ; i-- )
  364. {
  365. if( unit_array.is_deleted(i) )
  366. continue;
  367. unitPtr = unit_array[i];
  368. if( unitPtr->unit_mode == UNIT_MODE_REBEL &&
  369. unitPtr->unit_mode_para == rebel_recno )
  370. {
  371. unitPtr->set_mode(0);
  372. }
  373. }
  374. }
  375. //----------- End of function Rebel::~Rebel ---------//
  376. //--------- Begin of function Rebel::join ---------//
  377. //
  378. // A unit joins this rebel group as a rebel member.
  379. // The rebel leader exists since the creation of this rebel group.
  380. //
  381. void Rebel::join(int unitRecno)
  382. {
  383. Unit* unitPtr = unit_array[unitRecno];
  384. err_when( unitPtr->nation_recno );
  385. err_when( unitPtr->spy_recno );
  386. unitPtr->set_mode( UNIT_MODE_REBEL, rebel_recno );
  387. mobile_rebel_count++;
  388. }
  389. //----------- End of function Rebel::join ---------//
  390. //--------- Begin of function Rebel::think_cur_action ---------//
  391. //
  392. void Rebel::think_cur_action()
  393. {
  394. //------ if the rebel is attacking a town -------//
  395. if( action_mode == REBEL_ATTACK_TOWN )
  396. {
  397. //----- the town has already been captured -----//
  398. if( town_array.is_deleted(action_para) || town_array[action_para]->nation_recno == 0 )
  399. {
  400. //--- stop all units that are still attacking the town ---//
  401. stop_all_rebel_unit();
  402. set_action(REBEL_IDLE);
  403. }
  404. }
  405. //----- if the rebel should be attacking a firm -----//
  406. if( action_mode == REBEL_ATTACK_FIRM )
  407. {
  408. if( firm_array.is_deleted(action_para) || firm_array[action_para]->nation_recno == 0 )
  409. {
  410. //--- stop all units that are still attacking the firm ---//
  411. stop_all_rebel_unit();
  412. set_action(REBEL_IDLE);
  413. }
  414. }
  415. }
  416. //----------- End of function Rebel::think_cur_action ---------//
  417. //--------- Begin of function Rebel::next_day ---------//
  418. //
  419. void Rebel::next_day()
  420. {
  421. //---- if the rebels has a town and this rebel is a defender from a town ----//
  422. if( town_recno )
  423. {
  424. //--- check if the rebel town is destroyed ----//
  425. if( town_array.is_deleted(town_recno) )
  426. {
  427. town_recno = 0;
  428. //--- if the town has been destroyed, the rebel group becomes mobile again, and a new leader needs to be selected.
  429. if( mobile_rebel_count>0 && leader_unit_recno==0 )
  430. {
  431. select_new_leader();
  432. }
  433. }
  434. err_when( town_recno && town_array[town_recno]->rebel_recno != rebel_recno );
  435. return; // don't think new action as this rebel defender need to go back to its town.
  436. }
  437. //------- no rebels left in the group --------//
  438. if( town_recno==0 && mobile_rebel_count==0 )
  439. {
  440. rebel_array.del_rebel(rebel_recno);
  441. return;
  442. }
  443. //---------------------------------------------//
  444. err_when( mobile_rebel_count==0 && town_recno==0 ); // if both are zero, this rebel group should have been deleted.
  445. if( mobile_rebel_count > 0 ) // if there are mobile rebel units on the map
  446. {
  447. if( action_mode==REBEL_IDLE )
  448. think_new_action(); // think about a new action
  449. else
  450. think_cur_action(); // think if there should be any changes to the current action
  451. }
  452. else // if there are no mobile rebel units
  453. {
  454. if( town_recno > 0 )
  455. {
  456. if( info.game_date%30 == rebel_recno%30 ) // if the rebel has a town
  457. think_town_action();
  458. }
  459. }
  460. }
  461. //----------- End of function Rebel::next_day ---------//
  462. //--------- Begin of function Rebel::think_new_action ---------//
  463. //
  464. void Rebel::think_new_action()
  465. {
  466. if(unit_array.is_deleted(leader_unit_recno))
  467. return;
  468. int rc;
  469. switch( m.random(4) )
  470. {
  471. case 0:
  472. rc = think_settle_new();
  473. break;
  474. case 1:
  475. rc = think_settle_to();
  476. break;
  477. case 2:
  478. rc = think_capture_attack_town();
  479. break;
  480. case 3:
  481. rc = think_attack_firm();
  482. break;
  483. }
  484. if( rc )
  485. execute_new_action();
  486. }
  487. //----------- End of function Rebel::think_new_action ---------//
  488. //--------- Begin of function Rebel::think_settle_new ---------//
  489. //
  490. int Rebel::think_settle_new()
  491. {
  492. //------- get the leader unit's info -----------//
  493. Unit* leaderUnit = unit_array[leader_unit_recno];
  494. int leaderXLoc=leaderUnit->cur_x_loc(), leaderYLoc=leaderUnit->cur_y_loc();
  495. //----------------------------------------------//
  496. int xLoc2 = leaderXLoc + STD_TOWN_LOC_WIDTH - 1;
  497. int yLoc2 = leaderYLoc + STD_TOWN_LOC_HEIGHT - 1;
  498. if( xLoc2 >= MAX_WORLD_X_LOC )
  499. {
  500. xLoc2 = MAX_WORLD_X_LOC - 1;
  501. leaderXLoc = xLoc2 - STD_TOWN_LOC_WIDTH + 1;
  502. }
  503. if( yLoc2 >= MAX_WORLD_Y_LOC )
  504. {
  505. yLoc2 = MAX_WORLD_Y_LOC - 1;
  506. leaderYLoc = yLoc2 - STD_TOWN_LOC_HEIGHT + 1;
  507. }
  508. int regionId = world.get_region_id( leaderXLoc, leaderYLoc );
  509. if( world.locate_space( leaderXLoc, leaderYLoc, xLoc2, yLoc2, STD_TOWN_LOC_WIDTH, STD_TOWN_LOC_HEIGHT, UNIT_LAND, regionId, 1 ) )
  510. {
  511. action_mode = REBEL_SETTLE_NEW;
  512. action_para = leaderXLoc;
  513. action_para2 = leaderYLoc;
  514. return 1;
  515. }
  516. return 0;
  517. }
  518. //----------- End of function Rebel::think_settle_new ---------//
  519. //--------- Begin of function Rebel::think_settle_to ---------//
  520. //
  521. // Think about settling to an existing rebel town.
  522. //
  523. int Rebel::think_settle_to()
  524. {
  525. int i, townRecno;
  526. Town* townPtr;
  527. Unit* leaderUnit = unit_array[leader_unit_recno];
  528. int curRegionId = world.get_region_id(leaderUnit->cur_x_loc(), leaderUnit->cur_y_loc());
  529. townRecno = m.random(town_array.size())+1;
  530. for( i=1 ; i<=town_array.size() ; i++ )
  531. {
  532. if( ++townRecno > town_array.size() )
  533. townRecno = 1;
  534. if( town_array.is_deleted(townRecno) )
  535. continue;
  536. townPtr = town_array[townRecno];
  537. if( !townPtr->rebel_recno )
  538. continue;
  539. if( world.get_region_id(townPtr->loc_x1, townPtr->loc_y1) != curRegionId )
  540. continue;
  541. if( leaderUnit->race_id == townPtr->majority_race() )
  542. {
  543. action_mode = REBEL_SETTLE_TO;
  544. action_para = townPtr->loc_x1;
  545. action_para2 = townPtr->loc_y1;
  546. return 1;
  547. }
  548. }
  549. return 0;
  550. }
  551. //----------- End of function Rebel::think_settle_to ---------//
  552. //--------- Begin of function Rebel::think_capture_attack_town ---------//
  553. //
  554. int Rebel::think_capture_attack_town()
  555. {
  556. //------- get the leader unit's info -----------//
  557. Unit* leaderUnit = unit_array[leader_unit_recno];
  558. int leaderXLoc = leaderUnit->cur_x_loc(), leaderYLoc=leaderUnit->cur_y_loc();
  559. int curRegionId = world.get_region_id(leaderUnit->cur_x_loc(), leaderUnit->cur_y_loc());
  560. //----------------------------------------------//
  561. int actionMode = REBEL_ATTACK_TOWN;
  562. int townRecno, bestTownRecno=0;
  563. int townDistance, closestTownDistance=0x7FFF;
  564. Town* townPtr;
  565. for( int i=town_array.size() ; i>0 ; i-- )
  566. {
  567. townRecno = m.random(town_array.size())+1;
  568. if( town_array.is_deleted(townRecno) )
  569. continue;
  570. townPtr = town_array[townRecno];
  571. if( !is_hostile_nation(townPtr->nation_recno) )
  572. continue;
  573. if( world.get_region_id(townPtr->loc_x1, townPtr->loc_y1) != curRegionId )
  574. continue;
  575. townDistance = m.points_distance( leaderXLoc, leaderYLoc,
  576. townPtr->center_x, townPtr->center_y );
  577. if( townDistance < closestTownDistance )
  578. {
  579. closestTownDistance = townDistance;
  580. bestTownRecno = townRecno;
  581. }
  582. }
  583. if( bestTownRecno )
  584. {
  585. action_mode = actionMode;
  586. action_para = bestTownRecno; // attack this town
  587. return 1;
  588. }
  589. return 0;
  590. }
  591. //----------- End of function Rebel::think_capture_attack_town ---------//
  592. //--------- Begin of function Rebel::think_attack_firm ---------//
  593. //
  594. int Rebel::think_attack_firm()
  595. {
  596. //------- get the leader unit's info -----------//
  597. Unit* leaderUnit = unit_array[leader_unit_recno];
  598. int leaderXLoc=leaderUnit->cur_x_loc(), leaderYLoc=leaderUnit->cur_y_loc();
  599. int curRegionId = world.get_region_id(leaderUnit->cur_x_loc(), leaderUnit->cur_y_loc());
  600. //----------------------------------------------//
  601. int firmRecno, bestFirmRecno=0;
  602. int firmDistance, closestFirmDistance=0x7FFF;
  603. Firm* firmPtr;
  604. for( int i=firm_array.size() ; i>0 ; i-- )
  605. {
  606. firmRecno = m.random(firm_array.size())+1;
  607. if( firm_array.is_deleted(firmRecno) )
  608. continue;
  609. firmPtr = firm_array[firmRecno];
  610. if( !is_hostile_nation(firmPtr->nation_recno) )
  611. continue;
  612. if( world.get_region_id(firmPtr->loc_x1, firmPtr->loc_y1) != curRegionId )
  613. continue;
  614. firmDistance = m.points_distance( leaderXLoc, leaderYLoc,
  615. firmPtr->center_x, firmPtr->center_y );
  616. if( firmDistance < closestFirmDistance )
  617. {
  618. closestFirmDistance = firmDistance;
  619. bestFirmRecno = firmRecno;
  620. }
  621. }
  622. if( bestFirmRecno )
  623. {
  624. action_mode = REBEL_ATTACK_FIRM;
  625. action_para = bestFirmRecno; // attack this town
  626. return 1;
  627. }
  628. return 0;
  629. }
  630. //----------- End of function Rebel::think_attack_firm ---------//
  631. //--------- Begin of function Rebel::execute_new_action -------//
  632. //
  633. // Called by think_new_action(), execute the action immediately right
  634. // after a new action has been decided.
  635. //
  636. void Rebel::execute_new_action()
  637. {
  638. //----- create an recno array of the rebel units ----//
  639. short* rebelRecnoArray = (short*) mem_add( mobile_rebel_count * sizeof(short) );
  640. Unit* unitPtr;
  641. int rebelCount=0;
  642. #ifdef DEBUG
  643. int dieUnit = 0;
  644. #endif
  645. for( int i=unit_array.size() ; i>=1 ; i-- )
  646. {
  647. if( unit_array.is_deleted(i) )
  648. {
  649. #ifdef DEBUG
  650. if(!unit_array.SpriteArray::is_deleted(i))
  651. dieUnit++;
  652. #endif
  653. continue;
  654. }
  655. unitPtr = unit_array[i];
  656. if( unitPtr->unit_mode == UNIT_MODE_REBEL &&
  657. unitPtr->unit_mode_para == rebel_recno )
  658. {
  659. err_when( rebelCount >= mobile_rebel_count );
  660. rebelRecnoArray[rebelCount++] = i;
  661. }
  662. }
  663. #ifdef DEBUG
  664. if(rebelCount+dieUnit != mobile_rebel_count)
  665. int debug = 0;
  666. #endif
  667. if( !rebelCount )
  668. {
  669. mem_del( rebelRecnoArray );
  670. return; // all rebel units are dead
  671. }
  672. //-------- execute the new action now --------//
  673. Town* townPtr;
  674. Firm* firmPtr;
  675. switch( action_mode )
  676. {
  677. case REBEL_ATTACK_TOWN:
  678. err_when( town_array.is_deleted(action_para) || town_array[action_para]->nation_recno==0 ); // these should have been checked before calling this function
  679. townPtr = town_array[action_para];
  680. // ##### patch begin Gilbert 5/8 ######//
  681. unit_array.attack( townPtr->loc_x1, townPtr->loc_y1, 0, rebelRecnoArray, rebelCount, COMMAND_AI, 0 );
  682. // ##### patch end Gilbert 5/8 ######//
  683. break;
  684. case REBEL_ATTACK_FIRM:
  685. err_when( firm_array.is_deleted(action_para) || firm_array[action_para]->nation_recno==0 ); // these should have been checked before calling this function
  686. firmPtr = firm_array[action_para];
  687. // ##### patch begin Gilbert 5/8 ######//
  688. unit_array.attack( firmPtr->loc_x1, firmPtr->loc_y1, 0, rebelRecnoArray, rebelCount, COMMAND_AI, 0 );
  689. // ##### patch end Gilbert 5/8 ######//
  690. break;
  691. case REBEL_SETTLE_NEW:
  692. unit_array.settle( action_para, action_para2, 0, 1, rebelRecnoArray, rebelCount ); // action_para & action_para2 is the destination location
  693. break;
  694. case REBEL_SETTLE_TO:
  695. unit_array.assign( action_para, action_para2, 0, 1, rebelRecnoArray, rebelCount);
  696. break;
  697. }
  698. mem_del( rebelRecnoArray );
  699. }
  700. //-------- End of function Rebel::execute_new_action ---------//
  701. //--------- Begin of function Rebel::think_town_action ---------//
  702. //
  703. // Call this function to think about the new actions of this
  704. // rebel group when all members of the rebel has settled down
  705. // into a town.
  706. //
  707. void Rebel::think_town_action()
  708. {
  709. if( town_recno==0 || mobile_rebel_count>0 ) // only when all rebel units has settled in the town
  710. return;
  711. //----- neutralize to an independent town -----//
  712. if( m.random(10)==0 )
  713. {
  714. turn_indepedent();
  715. }
  716. //---------- form a nation ---------//
  717. else if( m.random(10)==0 )
  718. {
  719. if( town_array[town_recno]->population >= 20 &&
  720. nation_array.can_form_new_ai_nation() )
  721. {
  722. town_array[town_recno]->form_new_nation();
  723. }
  724. }
  725. }
  726. //----------- End of function Rebel::think_town_action ---------//
  727. //--------- Begin of function Rebel::turn_indepedent ---------//
  728. //
  729. // The rebel town turns into an indepedent town.
  730. //
  731. void Rebel::turn_indepedent()
  732. {
  733. err_when( town_recno==0 || mobile_rebel_count>0 ); // only when all rebel units has settled in the town
  734. town_array[town_recno]->rebel_recno = 0;
  735. //------ remove this rebel group from rebel_array ------//
  736. rebel_array.del_rebel(rebel_recno);
  737. }
  738. //----------- End of function Rebel::turn_indepedent ---------//
  739. //--------- Begin of function Rebel::stop_all_rebel_unit ---------//
  740. //
  741. void Rebel::stop_all_rebel_unit()
  742. {
  743. Unit* unitPtr;
  744. for( int i=unit_array.size() ; i>=1 ; i-- )
  745. {
  746. if( unit_array.is_deleted(i) )
  747. continue;
  748. unitPtr = unit_array[i];
  749. if( unitPtr->unit_mode == UNIT_MODE_REBEL &&
  750. unitPtr->unit_mode_para == rebel_recno )
  751. {
  752. unitPtr->stop();
  753. }
  754. }
  755. }
  756. //----------- End of function Rebel::stop_all_rebel_unit ---------//
  757. //--------- Begin of function Rebel::town_being_attacked ---------//
  758. //
  759. // This rebel group's town is being attacked.
  760. //
  761. void Rebel::town_being_attacked(int attackerUnitRecno)
  762. {
  763. err_when( !town_recno );
  764. //----------------------------------------------//
  765. //
  766. // Set the hostile_nation_recno. So that if the rebel
  767. // town is destroyed and there are rebel units left,
  768. // they can form a rebel group again and battle with
  769. // the attacking nation.
  770. //
  771. //----------------------------------------------//
  772. set_hostile_nation(unit_array[attackerUnitRecno]->nation_recno);
  773. }
  774. //----------- End of function Rebel::town_being_attacked ---------//
  775. //--------- Begin of function Rebel::set_hostile_nation ---------//
  776. void Rebel::set_hostile_nation(short nationRecno)
  777. {
  778. if(nationRecno==0)
  779. return;
  780. err_when(nationRecno>7); // only 8 bits
  781. hostile_nation_bits |= (0x1 << nationRecno);
  782. }
  783. //----------- End of function Rebel::set_hostile_nation ---------//
  784. //--------- Begin of function Rebel::reset_hostile_nation ---------//
  785. void Rebel::reset_hostile_nation(short nationRecno)
  786. {
  787. if(nationRecno==0)
  788. return;
  789. err_when(nationRecno>7); // only 8 bits
  790. hostile_nation_bits &= ~(0x1 << nationRecno);
  791. }
  792. //----------- End of function Rebel::reset_hostile_nation ---------//
  793. //--------- Begin of function Rebel::is_hostile_nation ---------//
  794. // return 1 for hostile nation
  795. // return 0 otherwise
  796. //
  797. int Rebel::is_hostile_nation(short nationRecno)
  798. {
  799. if(nationRecno==0)
  800. return 0;
  801. err_when(nationRecno>7); // only 8 bits
  802. return (hostile_nation_bits & (0x1 << nationRecno));
  803. }
  804. //----------- End of function Rebel::is_hostile_nation ---------//
  805. //--------- Begin of function Unit::process_rebel ---------//
  806. //
  807. // Note: this is a Unit member function, not a Rebel member function,
  808. // it is called by Unit::process_idle();
  809. //
  810. void Unit::process_rebel()
  811. {
  812. Rebel* rebelPtr = rebel_array[unit_mode_para];
  813. switch( rebelPtr->action_mode )
  814. {
  815. case REBEL_ATTACK_TOWN:
  816. if( town_array.is_deleted(rebelPtr->action_para) ) // if the town has been destroyed.
  817. rebelPtr->set_action(REBEL_IDLE);
  818. else
  819. {
  820. Town* townPtr = town_array[rebelPtr->action_para];
  821. attack_town( townPtr->loc_x1, townPtr->loc_y1 );
  822. }
  823. break;
  824. case REBEL_SETTLE_NEW:
  825. if( !world.can_build_town(rebelPtr->action_para, rebelPtr->action_para2, sprite_recno) )
  826. {
  827. Location* locPtr = world.get_loc(rebelPtr->action_para, rebelPtr->action_para2);
  828. if( locPtr->is_town() &&
  829. town_array[locPtr->town_recno()]->rebel_recno == rebelPtr->rebel_recno )
  830. {
  831. rebelPtr->action_mode = REBEL_SETTLE_TO;
  832. }
  833. else
  834. {
  835. rebelPtr->action_mode = REBEL_IDLE;
  836. }
  837. }
  838. else
  839. {
  840. settle( rebelPtr->action_para, rebelPtr->action_para2 );
  841. }
  842. break;
  843. case REBEL_SETTLE_TO:
  844. assign( rebelPtr->action_para, rebelPtr->action_para2 );
  845. break;
  846. }
  847. }
  848. //----------- End of function Unit::process_rebel -----------//
  849. #ifdef DEBUG
  850. //------- Begin of function RebelArray::operator[] -----//
  851. Rebel* RebelArray::operator[](int recNo)
  852. {
  853. Rebel* rebelPtr = (Rebel*) get_ptr(recNo);
  854. if( !rebelPtr )
  855. err.run( "RebelArray[] is deleted" );
  856. return rebelPtr;
  857. }
  858. //--------- End of function RebelArray::operator[] ----//
  859. #endif