OF_CAMP2.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515
  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 : OF_CAMP2.CPP
  21. //Description : Firm Military Camp - AI functions
  22. #include <ONATION.h>
  23. #include <OINFO.h>
  24. #include <OCONFIG.h>
  25. #include <OTOWN.h>
  26. #include <OSPY.h>
  27. #include <OUNIT.h>
  28. #include <OF_CAMP.h>
  29. //--------- Begin of function FirmCamp::init_derived ---------//
  30. void FirmCamp::init_derived()
  31. {
  32. patrol_unit_count = 0;
  33. coming_unit_count = 0;
  34. ai_capture_town_recno = 0;
  35. ai_recruiting_soldier = 1;
  36. }
  37. //----------- End of function FirmCamp::init_derived -----------//
  38. //--------- Begin of function FirmCamp::process_ai ---------//
  39. void FirmCamp::process_ai()
  40. {
  41. if( info.game_date%15==firm_recno%15 ) // do not call too often as the penalty of accumulation is 10 days
  42. think_use_cash_to_capture();
  43. //------- assign overseer and workers -------//
  44. if( info.game_date%15==firm_recno%15 ) // do not call too often because when an AI action is queued, it will take a while to carry it out
  45. think_recruit();
  46. //---- if this firm is currently trying to capture a town ----//
  47. if( ai_capture_town_recno )
  48. {
  49. should_close_flag = 0; // disable should_close_flag when trying to capture a firm, should_close_flag is set in process_common_ai()
  50. if( nation_array[nation_recno]->attack_camp_count==0 && // only when attack_camp_count==0, the attack mission is complete
  51. patrol_unit_count==0 )
  52. {
  53. ai_capture_town_recno = 0;
  54. defense_flag = 1; // turn it on again after the capturing plan is finished
  55. return;
  56. }
  57. // process_ai_capturing();
  58. return;
  59. }
  60. //--- if the firm is empty and should be closed, sell/destruct it now ---//
  61. if( should_close_flag )
  62. {
  63. if( worker_count==0 )
  64. {
  65. ai_del_firm();
  66. return;
  67. }
  68. }
  69. //----- think about assigning a better commander -----//
  70. if( info.game_date%30==firm_recno%30 )
  71. think_assign_better_commander();
  72. //----- think about changing links to foreign town -----//
  73. if( info.game_date%30==firm_recno%30 )
  74. think_change_town_link();
  75. //------ think about attacking enemies nearby -------//
  76. int checkInterval = 13 - nation_array[nation_recno]->pref_military_development/10;
  77. if( info.game_date%checkInterval == firm_recno%checkInterval )
  78. think_attack_nearby_enemy();
  79. //------ think about capturing independent town -------//
  80. static short interval_days_array[] = { 60, 30, 20, 10 };
  81. int intervalDays = interval_days_array[config.ai_aggressiveness-1];
  82. if( info.game_date%intervalDays == firm_recno%intervalDays ) // do not call too often because when an AI action is queued, it will take a while to carry it out
  83. think_capture();
  84. //---------------------------------------//
  85. if( info.game_date%30 == firm_recno%30 )
  86. {
  87. ai_reset_defense_mode(); // reset defense mode if all soldiers are dead
  88. }
  89. }
  90. //----------- End of function FirmCamp::process_ai -----------//
  91. //--------- Begin of function FirmCamp::ai_reset_defense_mode ---------//
  92. void FirmCamp::ai_reset_defense_mode()
  93. {
  94. if(ai_status!=CAMP_IN_DEFENSE)
  95. return;
  96. //------------------------------------------------------------//
  97. // reset defense mode if all soldiers are dead
  98. //------------------------------------------------------------//
  99. DefenseUnit *defPtr = defense_array;
  100. Unit *unitPtr;
  101. int found=0;
  102. for(int i=0; i<=MAX_WORKER; i++, defPtr++)
  103. {
  104. if(!defPtr->unit_recno)
  105. continue; // empty slot
  106. if(unit_array.is_deleted(defPtr->unit_recno))
  107. continue;
  108. unitPtr = unit_array[defPtr->unit_recno];
  109. if(unitPtr->nation_recno==nation_recno && unitPtr->action_misc==ACTION_MISC_DEFENSE_CAMP_RECNO &&
  110. unitPtr->action_misc_para==firm_recno) // is a soldier of this camp
  111. found++;
  112. }
  113. if(!found)
  114. {
  115. set_employ_worker(1); // all soldiers have died, reset defense mode to employ new workers
  116. memset(defense_array, 0, sizeof(DefenseUnit)*(MAX_WORKER+1));
  117. }
  118. }
  119. //----------- End of function FirmCamp::ai_reset_defense_mode -----------//
  120. //--------- Begin of function FirmCamp::process_ai_capturing ---------//
  121. //
  122. // This function is called when the AI is in the process of
  123. // attacking and capturing the independent town this camp is
  124. // linked to.
  125. //
  126. void FirmCamp::process_ai_capturing()
  127. {
  128. err_when( patrol_unit_count <= 0 ); // this function shouldn't be called at all if patrol_unit_count==0
  129. err_when( patrol_unit_count>9 );
  130. if( !ai_capture_town_recno )
  131. return;
  132. if( think_capture_return() ) // if the capturing units should now return to their base.
  133. return;
  134. //--- there are still town defender out there, order idle units to attack them ---//
  135. Unit* unitPtr;
  136. Town* townPtr = town_array[ai_capture_town_recno];
  137. if( townPtr->town_defender_count > 0 )
  138. {
  139. for( int i=patrol_unit_count ; i>0 ; i-- )
  140. {
  141. unitPtr = unit_array[ patrol_unit_array[i-1] ];
  142. if( unitPtr->cur_action == SPRITE_IDLE )
  143. ai_attack_town_defender(unitPtr);
  144. }
  145. }
  146. //--- if the town is still not captured but all mobile town defenders are destroyed, attack the town again ---//
  147. if( townPtr->town_defender_count == 0 )
  148. {
  149. //----- have one of the units attack the town ----//
  150. short unitArray[1];
  151. err_when( patrol_unit_count<=0 );
  152. unitArray[0] = patrol_unit_array[ m.random(patrol_unit_count) ];
  153. err_when( unit_array.is_deleted(unitArray[0]) );
  154. if( townPtr->nation_recno )
  155. nation_array[nation_recno]->set_relation_should_attack( townPtr->nation_recno, 1, COMMAND_AI );
  156. // ##### patch begin Gilbert 5/8 ######//
  157. unit_array.attack(townPtr->loc_x1, townPtr->loc_y1, 0, unitArray, 1, COMMAND_AI, 0);
  158. // ##### patch end Gilbert 5/8 ######//
  159. }
  160. }
  161. //----------- End of function FirmCamp::process_ai_capturing -----------//
  162. //------ Begin of function FirmCamp::ai_attack_town_defender ------//
  163. //
  164. void FirmCamp::ai_attack_town_defender(Unit* attackerUnit)
  165. {
  166. int shouldAttackUnit=0;
  167. if( attackerUnit->cur_action == SPRITE_IDLE )
  168. shouldAttackUnit = 1;
  169. else if( attackerUnit->cur_action == SPRITE_ATTACK )
  170. {
  171. //--- if this unit is currently attacking the town, ask it to attack a defender unit ---//
  172. Town* townPtr = town_array[ai_capture_town_recno];
  173. if( attackerUnit->action_x_loc==townPtr->loc_x1 && attackerUnit->action_y_loc==townPtr->loc_y1 )
  174. shouldAttackUnit = 1;
  175. }
  176. if( !shouldAttackUnit )
  177. return;
  178. //---- if there are still town defenders out there ---//
  179. int unitCount = unit_array.size();
  180. int unitRecno = m.random(unitCount)+1; // scan randomly
  181. short unitArray[1];
  182. Unit* targetUnit;
  183. for( int i=0 ; i<unitCount ; i++ )
  184. {
  185. if( ++unitRecno > unitCount )
  186. unitRecno = 1;
  187. if( unit_array.is_deleted(unitRecno) )
  188. continue;
  189. targetUnit = unit_array[unitRecno];
  190. if( targetUnit->unit_mode == UNIT_MODE_DEFEND_TOWN &&
  191. targetUnit->unit_mode_para == ai_capture_town_recno )
  192. {
  193. unitArray[0] = attackerUnit->sprite_recno;
  194. if( targetUnit->nation_recno )
  195. nation_array[nation_recno]->set_relation_should_attack( targetUnit->nation_recno, 1, COMMAND_AI );
  196. // ##### patch begin Gilbert 5/8 ######//
  197. unit_array.attack( targetUnit->next_x_loc(), targetUnit->next_y_loc(),
  198. 0, unitArray, 1, COMMAND_AI, targetUnit->sprite_recno );
  199. // ##### patch end Gilbert 5/8 ######//
  200. break;
  201. }
  202. }
  203. }
  204. //-------- End of function FirmCamp::ai_attack_town_defender ------//
  205. //--------- Begin of function FirmCamp::think_recruit ---------//
  206. //
  207. // Think about recruiting an overseer and soliders to this base.
  208. //
  209. void FirmCamp::think_recruit()
  210. {
  211. if( patrol_unit_count ) // if there are units of this camp patrolling outside
  212. return;
  213. Nation* nationPtr = nation_array[nation_recno];
  214. ai_recruiting_soldier = 1; // the AI is currently trying to recruit soldiers
  215. //---- if there are currently units coming to this firm ----//
  216. if( coming_unit_count > 0 )
  217. {
  218. Unit* unitPtr;
  219. for( int i=0 ; i<coming_unit_count ; i++ )
  220. {
  221. if( unit_array.is_deleted( coming_unit_array[i] ) )
  222. continue;
  223. unitPtr = unit_array[ coming_unit_array[i] ];
  224. //--- check if any of them are still on their way to this firm ---//
  225. if( unitPtr->nation_recno == nation_recno &&
  226. unitPtr->action_mode == ACTION_ASSIGN_TO_FIRM )
  227. {
  228. //--- if so, do not do anything unit they are all done ---//
  229. return;
  230. }
  231. }
  232. coming_unit_count = 0;
  233. }
  234. //-- if this camp is empty, think about move a whole troop from a useless camp (should_ai_close()==1)
  235. if( !overseer_recno && worker_count==0 &&
  236. nationPtr->firm_should_close_array[FIRM_CAMP-1] > 0 )
  237. {
  238. FirmCamp *firmCamp, *bestCampPtr=NULL;
  239. int bestRating=0, curRating;
  240. //--- see if there are any useless camps around and pick the most suitable one ---//
  241. for( int i=nationPtr->ai_camp_count-1 ; i>=0 ; i-- )
  242. {
  243. firmCamp = (FirmCamp*) firm_array[ nationPtr->ai_camp_array[i] ];
  244. err_when( firmCamp->firm_id != FIRM_CAMP );
  245. if( firmCamp->region_id != region_id )
  246. continue;
  247. if( firmCamp->should_close_flag &&
  248. (firmCamp->overseer_recno || firmCamp->worker_count>0) )
  249. {
  250. curRating = 100 - m.points_distance( center_x, center_y,
  251. firmCamp->center_x, firmCamp->center_y );
  252. if( curRating > bestRating )
  253. {
  254. bestRating = curRating;
  255. bestCampPtr = firmCamp;
  256. }
  257. }
  258. }
  259. //--------- start the move now -------//
  260. if( bestCampPtr )
  261. {
  262. bestCampPtr->patrol();
  263. if( bestCampPtr->patrol_unit_count==0 ) // there could be chances that there are no some for mobilizing the units
  264. return;
  265. //--- set coming_unit_count for later checking ---//
  266. err_when( sizeof(coming_unit_array) != sizeof(patrol_unit_array) );
  267. memcpy( coming_unit_array, bestCampPtr->patrol_unit_array, sizeof(coming_unit_array) );
  268. coming_unit_count = bestCampPtr->patrol_unit_count;
  269. //---- order the unit to move to this camp now ---//
  270. unit_array.assign(loc_x1, loc_y1, 0, COMMAND_AI, bestCampPtr->patrol_unit_array, bestCampPtr->patrol_unit_count);
  271. //------ delete the camp as it no longer has any use ----//
  272. bestCampPtr->ai_del_firm();
  273. return;
  274. }
  275. }
  276. //------- get an overseer if there isn't any right now -----//
  277. if( !overseer_recno )
  278. nationPtr->add_action(loc_x1, loc_y1, -1, -1, ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP);
  279. //---- think about the no. of workers needed for this base ----//
  280. int combatDiff;
  281. if( overseer_recno == nationPtr->king_unit_recno ) // recruit as many soldiers as possible if the commander is the king
  282. {
  283. combatDiff = 1000;
  284. }
  285. else if( nationPtr->total_jobless_population > 20 + (100-nationPtr->pref_military_development) / 3 ) // 20 to 53
  286. {
  287. combatDiff = 1000; // recruit as many as possible
  288. }
  289. else
  290. {
  291. int combatLevelNeeded = ai_combat_level_needed();
  292. combatDiff = combatLevelNeeded - total_combat_level();
  293. }
  294. if( combatDiff > 0 )
  295. {
  296. ai_recruit(combatDiff);
  297. }
  298. else
  299. {
  300. if( overseer_recno )
  301. ai_recruiting_soldier = 0; // this firm has enough soldiers already
  302. }
  303. }
  304. //----------- End of function FirmCamp::think_recruit ----------//
  305. //--------- Begin of function FirmCamp::ai_recruit ---------//
  306. //
  307. // <int> recruitCombatLevel - the combat level needed to be added.
  308. //
  309. // return: <int> 1-succeeded, 0-failed.
  310. //
  311. int FirmCamp::ai_recruit(int recruitCombatLevel)
  312. {
  313. if( worker_count == MAX_WORKER || !overseer_recno )
  314. return 0;
  315. int recruitCount = max( 1, recruitCombatLevel / 20 );
  316. recruitCount = min( recruitCount, MAX_WORKER-worker_count );
  317. //--- first try to recruit soldiers directly from a linked village ---//
  318. int majorityRace = majority_race();
  319. int raceId;
  320. int loopCount=0;
  321. Town* townPtr;
  322. for( int i=0 ; i<linked_town_count ; i++ )
  323. {
  324. townPtr = town_array[ linked_town_array[i] ];
  325. if( townPtr->nation_recno != nation_recno || !townPtr->jobless_population )
  326. continue;
  327. //-- recruit majority race first, but will also consider other races --//
  328. raceId = max( 1, majorityRace );
  329. for( int j=0 ; j<MAX_RACE ; j++ )
  330. {
  331. if( ++raceId > MAX_RACE )
  332. raceId = 1;
  333. //--- if the loyalty is too low, reward before recruiting ---//
  334. if( townPtr->jobless_race_pop_array[raceId-1] > 0 &&
  335. townPtr->race_loyalty_array[raceId-1] < 40 )
  336. {
  337. if( townPtr->accumulated_reward_penalty > 30 ) // if the reward penalty is too high, do reward
  338. break;
  339. townPtr->reward(COMMAND_AI);
  340. }
  341. //---- recruit the soldiers we needed ----//
  342. while( townPtr->can_recruit(raceId) )
  343. {
  344. err_when( ++loopCount > 1000 );
  345. pull_town_people(townPtr->town_recno, COMMAND_AI, raceId, 1); // last 1-force pulling people from the town to the firm
  346. if( --recruitCount == 0 )
  347. return 1;
  348. }
  349. }
  350. }
  351. //------ next, try to recruit from remote villages -----//
  352. if( recruitCount > 0 )
  353. nation_array[nation_recno]->add_action(loc_x1, loc_y1, -1, -1, ACTION_AI_ASSIGN_WORKER, FIRM_CAMP, recruitCount);
  354. return 1;
  355. }
  356. //----------- End of function FirmCamp::ai_recruit ----------//
  357. //--------- Begin of function FirmCamp::ai_combat_level_needed ---------//
  358. //
  359. // Think about the no. of soldiers needed by this base.
  360. //
  361. int FirmCamp::ai_combat_level_needed()
  362. {
  363. Town* townPtr;
  364. int combatNeeded=0;
  365. Nation* nationPtr = nation_array[nation_recno];
  366. //------- scan for linked towns ---------//
  367. for( int i=0 ; i<linked_town_count ; i++ )
  368. {
  369. townPtr = town_array[ linked_town_array[i] ];
  370. //------- this is its own town -------//
  371. if( townPtr->nation_recno == nation_recno )
  372. {
  373. if( townPtr->should_ai_migrate() ) // no need for this if this town is going to migrate
  374. continue;
  375. combatNeeded += townPtr->population * 10; // 30 people need 300 combat levels
  376. if( townPtr->is_base_town )
  377. combatNeeded += townPtr->population * 10; // double the combat level need for base town
  378. }
  379. }
  380. //--- if the overseer is the king, increase its combat level needed ---//
  381. if( overseer_recno && unit_array[overseer_recno]->rank_id == RANK_KING )
  382. combatNeeded = max(400, combatNeeded);
  383. //---------------------------------------//
  384. return combatNeeded;
  385. }
  386. //----------- End of function FirmCamp::ai_combat_level_needed ----------//
  387. //--------- Begin of function FirmCamp::total_combat_level ---------//
  388. //
  389. // Total combat level of all soldiers and commander in the base.
  390. // The leadership of the general also applies to the final combat level.
  391. //
  392. // return: <int> the total combat level - it is the sum of hit points
  393. // of all the units in the camp.
  394. //
  395. int FirmCamp::total_combat_level()
  396. {
  397. int totalCombatLevel=0;
  398. Worker* workerPtr = worker_array;
  399. for( int i=0 ; i<worker_count ; i++, workerPtr++ )
  400. {
  401. totalCombatLevel += workerPtr->hit_points; // use it points instead of combat level because hit_points represent both combat level and hit points left
  402. err_when( totalCombatLevel < 0 );
  403. //---- the combat level of weapons are higher ------//
  404. UnitInfo* unitInfo = unit_res[workerPtr->unit_id];
  405. if( unitInfo->unit_class == UNIT_CLASS_WEAPON )
  406. totalCombatLevel += (unitInfo->weapon_power + workerPtr->extra_para - 1) * 30; // extra_para keeps the weapon version
  407. err_when( totalCombatLevel < 0 );
  408. }
  409. if( overseer_recno )
  410. {
  411. Unit* unitPtr = unit_array[overseer_recno];
  412. //--- the commander's leadership effects over the soldiers ---//
  413. totalCombatLevel += totalCombatLevel * unitPtr->skill.skill_level / 150; // divided by 150 instead of 100 because while the attacking ability of the unit is affected by the general, the hit points isn't, so we shouldn't do a direct multiplication.
  414. //------ the leader's own hit points ------//
  415. totalCombatLevel += (int) unitPtr->hit_points;
  416. err_when( totalCombatLevel < 0 );
  417. }
  418. return totalCombatLevel;
  419. }
  420. //----------- End of function FirmCamp::total_combat_level ----------//
  421. //--------- Begin of function FirmCamp::average_combat_level ---------//
  422. //
  423. int FirmCamp::average_combat_level()
  424. {
  425. int personCount = worker_count + (overseer_recno>0);
  426. if( personCount > 0 )
  427. return total_combat_level() / personCount;
  428. else
  429. return 0;
  430. }
  431. //----------- End of function FirmCamp::average_combat_level ----------//
  432. //--------- Begin of function FirmCamp::ai_should_close ---------//
  433. //
  434. // Whether this AI firm should be closed or not.
  435. //
  436. int FirmCamp::ai_should_close()
  437. {
  438. return linked_town_count==0 && linked_firm_count==0;
  439. }
  440. //----------- End of function FirmCamp::ai_should_close ----------//
  441. //--------- Begin of function FirmCamp::think_capture ---------//
  442. //
  443. // Think about capturing towns.
  444. //
  445. void FirmCamp::think_capture()
  446. {
  447. if( is_attack_camp ) // if this camp has been assigned to an attack mission already
  448. return;
  449. int targetTownRecno = think_capture_target_town();
  450. if( !targetTownRecno )
  451. return;
  452. //----- if the target town is a nation town -----//
  453. Town* targetTown = town_array[targetTownRecno];
  454. Nation* ownNation = nation_array[nation_recno];
  455. if( targetTown->nation_recno )
  456. {
  457. //--- if there are any defenses (camps and mobile units) on the target town, destroy them all first -----//
  458. if( ownNation->attack_enemy_town_defense(targetTown) != -1 ) // only proceed further when the result is -1, which means no defense on the target town, no attacking is needed.
  459. return;
  460. }
  461. //------ check if the town people will go out to defend -----//
  462. float thisResistance, resistanceDiff;
  463. int defenseCombatLevel=0;
  464. for( int i=0 ; i<MAX_RACE ; i++ )
  465. {
  466. if( targetTown->race_pop_array[i] < 5 ) // if the pop count is lower than 5, ingore it
  467. continue;
  468. if( targetTown->nation_recno )
  469. {
  470. thisResistance = targetTown->race_loyalty_array[i];
  471. resistanceDiff = thisResistance - MIN_NATION_DEFEND_LOYALTY;
  472. }
  473. else
  474. {
  475. thisResistance = targetTown->race_resistance_array[i][nation_recno-1];
  476. resistanceDiff = thisResistance - MIN_INDEPENDENT_DEFEND_LOYALTY;
  477. }
  478. if( resistanceDiff >= 0 )
  479. {
  480. float resistanceDecPerDefender = thisResistance/targetTown->race_pop_array[i]; // resistance decrease per new defender
  481. int defenderCount = int(resistanceDiff / resistanceDecPerDefender)+1; // no. of defenders will go out if you attack this town
  482. defenseCombatLevel += targetTown->town_combat_level * 2 * defenderCount; // *2 is defenseCombatLevel is actually the sum of hit points, not combat level
  483. }
  484. }
  485. //--- try using spies if there are defense forces and the nation likes to use spies ---//
  486. if( defenseCombatLevel > 0 ) // && ownNation->pref_spy >= 50 && m.random(3)==0 ) // 1/3 chance of using spies here, otherwise only use spies when we are not strong enough to take over the village by force
  487. {
  488. if( targetTown->nation_recno==0 ) // if the camp is trying to capture an independent town, the leadership and race id. of the overseer matters.
  489. {
  490. if( think_assign_better_overseer(targetTown) ) // a better general is being assigned to this firm, wait for it
  491. return;
  492. if( think_capture_use_spy(targetTown) )
  493. return;
  494. if( defenseCombatLevel > 100+ownNation->pref_military_courage &&
  495. resistanceDiff > (100-ownNation->pref_peacefulness)/5 ) // depending on the peacefulness, the nation won't attack if resistance > (0-20)
  496. {
  497. return;
  498. }
  499. }
  500. else
  501. {
  502. //--- don't attack if the target nation's military rating is higher than ours ---//
  503. if( nation_array[targetTown->nation_recno]->military_rank_rating()
  504. > ownNation->military_rank_rating() )
  505. {
  506. return;
  507. }
  508. }
  509. }
  510. //------ send out troops to capture the target town now ----//
  511. int rc;
  512. if( targetTown->nation_recno )
  513. rc = ai_capture_enemy_town(targetTown, defenseCombatLevel);
  514. else
  515. rc = ai_capture_independent_town(targetTown, defenseCombatLevel);
  516. //-- use the same approach to capture both enemy and independent towns --//
  517. if( rc )
  518. {
  519. ai_capture_town_recno = targetTownRecno;
  520. defense_flag = 0; // turn off the defense flag during capturing so the general is staying in the base to influence the town
  521. //--- as the current commander has been out to attack the town by ai_attack_target(), we need to assign him back to the camp for influencing the town and eventually capture it ---//
  522. if( !overseer_recno && targetTown->nation_recno && patrol_unit_count>0 )
  523. unit_array[ patrol_unit_array[0] ]->assign(loc_x1, loc_y1);
  524. }
  525. }
  526. //----------- End of function FirmCamp::think_capture -----------//
  527. //--------- Begin of function FirmCamp::think_capture_target_town ---------//
  528. //
  529. // Think about which town to capture.
  530. //
  531. // Return: <int> recno of the target town.
  532. //
  533. int FirmCamp::think_capture_target_town()
  534. {
  535. if( !linked_town_count || !overseer_recno )
  536. return 0;
  537. //--- if there are any units currently being assigned to this camp ---//
  538. if( nation_array[nation_recno]->is_action_exist( loc_x1, loc_y1, -1, -1, ACTION_AI_ASSIGN_WORKER, FIRM_CAMP ) )
  539. return 0;
  540. //-- decide which town to attack (only when the camp is linked to more than one town ---//
  541. int curResistance, curTargetResistance, resistanceDec;
  542. int i, minResistance=100, bestTownRecno=0;
  543. Town* townPtr;
  544. int prefPeacefulness = nation_array[nation_recno]->pref_peacefulness;
  545. Nation* ownNation = nation_array[nation_recno];
  546. int overseerRaceId = unit_array[overseer_recno]->race_id;
  547. for( i=0 ; i<linked_town_count ; i++ )
  548. {
  549. townPtr = town_array[ linked_town_array[i] ];
  550. if( townPtr->nation_recno == nation_recno )
  551. continue;
  552. //------- if it's an independent town -------//
  553. if( !townPtr->nation_recno ) // only capture independent town
  554. {
  555. curResistance = townPtr->average_resistance(nation_recno);
  556. curTargetResistance = townPtr->average_target_resistance(nation_recno);
  557. resistanceDec = curResistance - curTargetResistance;
  558. //------- if the resistance is decreasing ---------//
  559. if( resistanceDec > 0 &&
  560. curResistance > 25-25*ownNation->pref_peacefulness/100 && // for nation that has a high peacefulness preference they will wait for the loyalty to fall and try not to attack the town unless necessary
  561. townPtr->race_pop_array[overseerRaceId-1] >= 5 ) // if it's less than 5, don't count it, as that it will be easy to attack
  562. {
  563. continue; // let it decrease until it can no longer decrease
  564. }
  565. }
  566. else //-------- if it's a nation town ---------//
  567. {
  568. NationRelation* nationRelation = ownNation->get_relation(townPtr->nation_recno);
  569. if( nationRelation->status != NATION_HOSTILE )
  570. continue;
  571. curResistance = townPtr->average_loyalty();
  572. }
  573. //--------------------------------------//
  574. if( curResistance < minResistance )
  575. {
  576. minResistance = curResistance;
  577. bestTownRecno = townPtr->town_recno;
  578. }
  579. }
  580. return bestTownRecno;
  581. }
  582. //--------- End of function FirmCamp::think_capture_target_town --------//
  583. //--------- Begin of function FirmCamp::ai_capture_independent_town -------//
  584. //
  585. // Try to capture the given independent town.
  586. //
  587. int FirmCamp::ai_capture_independent_town(Town* targetTown, int defenseCombatLevel)
  588. {
  589. //---- see if the force is strong enough to attack the town ----//
  590. Nation* nationPtr = nation_array[nation_recno];
  591. int curCombatLevel = total_combat_level(); // total combat level
  592. int combatDiff = defenseCombatLevel * (150+nationPtr->pref_force_projection/2) / 100
  593. - curCombatLevel; // try to recruit soldiers based on the force projection perference
  594. if( combatDiff > 0 )
  595. {
  596. if( ai_recruit(combatDiff) ) // try to recruit new soldiers to increase the combat ability of the troop
  597. return 0;
  598. }
  599. combatDiff = defenseCombatLevel * (200-nationPtr->pref_military_courage/2) / 100
  600. - curCombatLevel;
  601. //---------- attack the target town now ----------//
  602. if( nation_array[nation_recno]->ai_attack_target(targetTown->loc_x1, targetTown->loc_y1, defenseCombatLevel, 0, 0, 0, firm_recno) )
  603. return 1;
  604. return 0;
  605. }
  606. //--------- End of function FirmCamp::ai_capture_independent_town --------//
  607. //--------- Begin of function FirmCamp::think_capture_return ---------//
  608. //
  609. // Think about if the capturing units should now return to their base.
  610. //
  611. int FirmCamp::think_capture_return()
  612. {
  613. //----- if the target town is destroyed ------//
  614. int returnCamp=0;
  615. if( town_array.is_deleted(ai_capture_town_recno) )
  616. {
  617. returnCamp = 1;
  618. }
  619. else //---- check whether the town has been captured ----//
  620. {
  621. Town* townPtr = town_array[ai_capture_town_recno];
  622. if( townPtr->nation_recno == nation_recno ) // the town has been captured
  623. returnCamp = 1;
  624. }
  625. //-------- if should return to the camp now ---------//
  626. if( returnCamp )
  627. {
  628. Unit* unitPtr;
  629. for( int i=0; i<patrol_unit_count ; i++ )
  630. {
  631. unitPtr = unit_array[ patrol_unit_array[i] ];
  632. if( unitPtr->is_visible() )
  633. unitPtr->assign(loc_x1, loc_y1);
  634. }
  635. ai_capture_town_recno = 0; // turn it on again after the capturing plan is finished
  636. defense_flag = 1;
  637. return 1;
  638. }
  639. return 0;
  640. }
  641. //----------- End of function FirmCamp::think_capture_return -----------//
  642. //--------- Begin of function FirmCamp::think_assign_better_overseer -------//
  643. //
  644. int FirmCamp::think_assign_better_overseer(Town* targetTown)
  645. {
  646. //----- check if there is already a queued action -----//
  647. Nation* ownNation = nation_array[nation_recno];
  648. if( ownNation->is_action_exist( loc_x1, loc_y1, -1, -1,
  649. ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP ) )
  650. {
  651. return 1; // there is a queued action being processed already
  652. }
  653. //------ get the two most populated races of the town ----//
  654. int mostRaceId1, mostRaceId2;
  655. targetTown->get_most_populated_race(mostRaceId1, mostRaceId2);
  656. //-- if the resistance of the majority race has already dropped to its lowest possible --//
  657. if( targetTown->race_resistance_array[mostRaceId1-1][nation_recno-1] <=
  658. (float) (targetTown->race_target_resistance_array[mostRaceId1-1][nation_recno-1]+1) )
  659. {
  660. if( targetTown->race_resistance_array[mostRaceId1-1][nation_recno-1] > 30 )
  661. {
  662. if( think_assign_better_overseer2(targetTown->town_recno, mostRaceId1) )
  663. return 1;
  664. }
  665. }
  666. //-- if the resistance of the 2nd majority race has already dropped to its lowest possible --//
  667. if( targetTown->race_resistance_array[mostRaceId2-1][nation_recno-1] <=
  668. (float) (targetTown->race_target_resistance_array[mostRaceId2-1][nation_recno-1]+1) )
  669. {
  670. if( targetTown->race_resistance_array[mostRaceId2-1][nation_recno-1] > 30 )
  671. {
  672. if( think_assign_better_overseer2(targetTown->town_recno, mostRaceId2) )
  673. return 1;
  674. }
  675. }
  676. return 0;
  677. }
  678. //--------- End of function FirmCamp::think_assign_better_overseer --------//
  679. //--------- Begin of function FirmCamp::think_assign_better_overseer2 -------//
  680. //
  681. int FirmCamp::think_assign_better_overseer2(int targetTownRecno, int raceId)
  682. {
  683. int reduceResistance;
  684. Nation* ownNation = nation_array[nation_recno];
  685. int bestUnitRecno = ownNation->find_best_capturer(targetTownRecno, raceId, reduceResistance);
  686. if( !bestUnitRecno || bestUnitRecno==overseer_recno ) // if we already got the best one here
  687. return 0;
  688. //---- only assign new overseer if the new one's leadership is significantly higher than the current one ----//
  689. if( overseer_recno &&
  690. unit_array[bestUnitRecno]->skill.skill_level < unit_array[overseer_recno]->skill.skill_level + 15 )
  691. {
  692. return 0;
  693. }
  694. //------ check what the best unit is -------//
  695. if( !ownNation->mobilize_capturer(bestUnitRecno) )
  696. return 0;
  697. //---------- add the action to the queue now ----------//
  698. int actionRecno = ownNation->add_action( loc_x1, loc_y1, -1, -1,
  699. ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP, 1, bestUnitRecno );
  700. if( actionRecno )
  701. ownNation->process_action(actionRecno);
  702. return 1;
  703. }
  704. //--------- End of function FirmCamp::think_assign_better_overseer2 --------//
  705. //--------- Begin of function FirmCamp::ai_capture_enemy_town -------//
  706. //
  707. // When capturing an enemy town, the commander should stay in the
  708. // command base to influence the village and reinforcement should be
  709. // sent instead of using the troop in the base for attacking the enemies.
  710. //
  711. int FirmCamp::ai_capture_enemy_town(Town* targetTown, int defenseCombatLevel)
  712. {
  713. int useAllCamp;
  714. Nation* ownNation = nation_array[nation_recno];
  715. Nation* targetNation = nation_array[targetTown->nation_recno];
  716. int ourMilitary = ownNation->military_rank_rating();
  717. int enemyMilitary = targetNation->military_rank_rating();
  718. //--- use all camps to attack if we have money and we are stronger than the enemy ---//
  719. if( ourMilitary - enemyMilitary > 30 && ownNation->ai_should_spend(ownNation->pref_military_courage/2) )
  720. useAllCamp = 1;
  721. //---- use all camps to attack the enemy if the enemy is a human player
  722. else if( config.ai_aggressiveness >= OPTION_MEDIUM &&
  723. !targetNation->is_ai() && ourMilitary > enemyMilitary )
  724. {
  725. if( config.ai_aggressiveness >= OPTION_HIGH ||
  726. ownNation->pref_peacefulness < 50 )
  727. {
  728. useAllCamp = 1;
  729. }
  730. }
  731. return nation_array[nation_recno]->ai_attack_target(targetTown->loc_x1, targetTown->loc_y1,
  732. defenseCombatLevel, 0, 0, 0, firm_recno, useAllCamp );
  733. }
  734. //--------- End of function FirmCamp::ai_capture_enemy_town --------//
  735. //--------- Begin of function FirmCamp::think_capture_use_spy ---------//
  736. //
  737. // Think about using spies for capturing the target town.
  738. //
  739. int FirmCamp::think_capture_use_spy(Town* targetTown)
  740. {
  741. Nation* ownNation = nation_array[nation_recno];
  742. //------ get the two most populated races of the town ----//
  743. int mostRaceId1, mostRaceId2;
  744. targetTown->get_most_populated_race(mostRaceId1, mostRaceId2);
  745. //-- get the current number of our spies in this town and see if we need more --//
  746. int spyCount;
  747. int curSpyLevel = spy_array.total_spy_skill_level( SPY_TOWN, targetTown->town_recno, nation_recno, spyCount );
  748. //--------------------------------------------//
  749. int rc=0;
  750. if( think_capture_use_spy2(targetTown, mostRaceId1, curSpyLevel ) )
  751. rc = 1;
  752. if( mostRaceId2 )
  753. {
  754. if( think_capture_use_spy2(targetTown, mostRaceId2, curSpyLevel ) )
  755. rc = 1;
  756. }
  757. return rc;
  758. }
  759. //----------- End of function FirmCamp::think_capture_use_spy -----------//
  760. //--------- Begin of function FirmCamp::think_capture_use_spy2 ---------//
  761. //
  762. // Think about using spies for capturing the target town.
  763. //
  764. int FirmCamp::think_capture_use_spy2(Town* targetTown, int raceId, int curSpyLevel)
  765. {
  766. Nation* ownNation = nation_array[nation_recno];
  767. int curResistance, targetResistance;
  768. if( targetTown->nation_recno )
  769. {
  770. curResistance = (int) targetTown->race_loyalty_array[raceId-1];
  771. targetResistance = targetTown->race_target_loyalty_array[raceId-1];
  772. }
  773. else
  774. {
  775. curResistance = (int) targetTown->race_resistance_array[raceId-1][nation_recno-1];
  776. targetResistance = targetTown->race_target_resistance_array[raceId-1][nation_recno-1];
  777. }
  778. int minResistance = min(curResistance, targetResistance);
  779. //----- if the resistance is low enough, don't have to use spies -----//
  780. if( targetTown->nation_recno )
  781. {
  782. if( minResistance < MIN_NATION_DEFEND_LOYALTY )
  783. return 0;
  784. }
  785. else
  786. {
  787. if( minResistance < MIN_INDEPENDENT_DEFEND_LOYALTY )
  788. return 0;
  789. }
  790. //----- if the needed spy level > current spy level, assign more spies ----//
  791. int neededSpyLevel = minResistance * (50+ownNation->pref_spy) / 50;
  792. if( neededSpyLevel > curSpyLevel )
  793. return ownNation->ai_assign_spy_to_town(targetTown->town_recno, raceId);
  794. return 0;
  795. }
  796. //----------- End of function FirmCamp::think_capture_use_spy2 -----------//
  797. //--------- Begin of function FirmCamp::ai_update_link_status ---------//
  798. //
  799. // Updating link status of this firm with towns.
  800. //
  801. // It's a overloaded function of Firm::ai_update_link_status().
  802. //
  803. void FirmCamp::ai_update_link_status()
  804. {
  805. Nation* ownNation = nation_array[nation_recno];
  806. //------ always enable links to all towns -----//
  807. for( int i=0 ; i<linked_town_count ; i++ )
  808. {
  809. Town* townPtr = town_array[linked_town_array[i]];
  810. //---- don't try to capture other nation's towns unless the AI is at war or tense with the nation ----//
  811. if( townPtr->nation_recno &&
  812. ownNation->get_relation_status(townPtr->nation_recno) <= NATION_TENSE ) // hostile or tense
  813. {
  814. continue;
  815. }
  816. toggle_town_link( i+1, 1, COMMAND_AI );
  817. //------------------------------------------------------------------//
  818. // Here we only update this camp's link to the town.
  819. // The town's link to this firm is updated in Town::update_target_loyalty().
  820. //------------------------------------------------------------------//
  821. }
  822. }
  823. //----------- End of function FirmCamp::ai_update_link_status ----------//
  824. //------- Begin of function FirmCamp::ai_has_excess_worker -------//
  825. //
  826. // Return whether this firm has any excessive soldiers or not.
  827. //
  828. int FirmCamp::ai_has_excess_worker()
  829. {
  830. if( linked_town_count==0 )
  831. return 1;
  832. if( ai_capture_town_recno ) // no if the camp is trying to capture an independent town
  833. return 0;
  834. if( is_attack_camp ) // no if the camp is trying to capture an independent town
  835. return 0;
  836. if( should_close_flag )
  837. return 1;
  838. return 0;
  839. // return total_combat_level() > ai_combat_level_needed()+100;
  840. }
  841. //--------- End of function FirmCamp::ai_has_excess_worker -------//
  842. //------- Begin of function FirmCamp::think_use_cash_to_capture -------//
  843. //
  844. // Think about using money to decrease the resistance of the
  845. // independent villagers.
  846. //
  847. int FirmCamp::think_use_cash_to_capture()
  848. {
  849. if( !nation_array[nation_recno]->should_use_cash_to_capture() )
  850. return 0;
  851. //-------------------------------------//
  852. Town* townPtr;
  853. for( int i=0 ; i<linked_town_count ; i++ )
  854. {
  855. townPtr = town_array[ linked_town_array[i] ];
  856. if( townPtr->nation_recno == nation_recno )
  857. continue;
  858. if( townPtr->accumulated_enemy_grant_penalty > 0 )
  859. continue;
  860. if( townPtr->can_grant_to_non_own_town(nation_recno) )
  861. townPtr->grant_to_non_own_town(nation_recno, COMMAND_AI);
  862. }
  863. return 1;
  864. }
  865. //--------- End of function FirmCamp::think_use_cash_to_capture -------//
  866. //------- Begin of function FirmCamp::think_linked_town_change_nation ------//
  867. //
  868. // This function is called by Town::set_nation() when a town linked
  869. // to this firm has changed nation.
  870. //
  871. // <int> linkedTownRecno - the recno of the town that has changed nation.
  872. // <int> oldNationRecno - the old nation recno of the town
  873. // <int> newNationRecno - the new nation recno of the town
  874. //
  875. void FirmCamp::think_linked_town_change_nation(int linkedTownRecno, int oldNationRecno, int newNationRecno)
  876. {
  877. //-----------------------------------------------//
  878. //
  879. // If we are trying to capture an independent town and our
  880. // enemies have managed to capture it first.
  881. //
  882. //-----------------------------------------------//
  883. Nation* ownNation = nation_array[nation_recno];
  884. if( oldNationRecno==0 && newNationRecno>0 && newNationRecno != nation_recno )
  885. {
  886. Town* townPtr = town_array[linkedTownRecno];
  887. //--- if the town does not have any protection, then don't remove this camp ---//
  888. if( townPtr->protection_available()==0 )
  889. return;
  890. should_close_flag = 1;
  891. ownNation->firm_should_close_array[firm_id-1]++;
  892. }
  893. }
  894. //-------- End of function FirmCamp::think_linked_town_change_nation ------//
  895. //------- Begin of function FirmCamp::think_attack_nearby_enemy -------//
  896. //
  897. // Think about attacking enemies near this cmap.
  898. //
  899. int FirmCamp::think_attack_nearby_enemy()
  900. {
  901. //------------------------------------------//
  902. Nation* nationPtr = nation_array[nation_recno];
  903. int scanRange = 6 + nationPtr->pref_military_courage/20; // 6 to 11
  904. int xLoc1 = loc_x1 - scanRange;
  905. int yLoc1 = loc_y1 - scanRange;
  906. int xLoc2 = loc_x2 + scanRange;
  907. int yLoc2 = loc_y2 + scanRange;
  908. xLoc1 = max( xLoc1, 0 );
  909. yLoc1 = max( yLoc1, 0 );
  910. xLoc2 = min( xLoc2, MAX_WORLD_X_LOC-1 );
  911. yLoc2 = min( yLoc2, MAX_WORLD_Y_LOC-1 );
  912. //------------------------------------------//
  913. int enemyCombatLevel=0; // the higher the rating, the easier we can attack the target town.
  914. int xLoc, yLoc;
  915. int enemyXLoc= -1, enemyYLoc;
  916. Unit* unitPtr;
  917. Location* locPtr;
  918. for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
  919. {
  920. locPtr = world.get_loc(xLoc1, yLoc);
  921. for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
  922. {
  923. //--- if there is an enemy unit here ---//
  924. if( locPtr->has_unit(UNIT_LAND) )
  925. {
  926. unitPtr = unit_array[ locPtr->unit_recno(UNIT_LAND) ];
  927. if( !unitPtr->nation_recno )
  928. continue;
  929. //--- if the unit is idle and he is our enemy ---//
  930. if( unitPtr->cur_action == SPRITE_ATTACK &&
  931. nationPtr->get_relation_status(unitPtr->nation_recno) == NATION_HOSTILE )
  932. {
  933. err_when( unitPtr->nation_recno == nation_recno );
  934. enemyCombatLevel += (int) unitPtr->hit_points;
  935. if( enemyXLoc == -1 || m.random(5)==0 )
  936. {
  937. enemyXLoc = xLoc;
  938. enemyYLoc = yLoc;
  939. }
  940. }
  941. }
  942. }
  943. }
  944. if( enemyCombatLevel==0 )
  945. return 0;
  946. err_when( enemyXLoc < 0 );
  947. //--------- attack the target now -----------//
  948. if( worker_count > 0 )
  949. {
  950. patrol_all_soldier();
  951. if( patrol_unit_count > 0 )
  952. {
  953. // ###### patch begin Gilbert 5/8 ########//
  954. unit_array.attack(enemyXLoc, enemyYLoc, 0, patrol_unit_array, patrol_unit_count, COMMAND_AI,
  955. world.get_loc(enemyXLoc, enemyYLoc)->unit_recno(UNIT_LAND));
  956. // ###### patch end Gilbert 5/8 ########//
  957. return 1;
  958. }
  959. }
  960. return 0;
  961. }
  962. //-------- End of function FirmCamp::think_attack_nearby_enemy -------//
  963. //------- Begin of function FirmCamp::think_change_town_link -------//
  964. //
  965. // Think about changing links to foreign towns.
  966. //
  967. void FirmCamp::think_change_town_link()
  968. {
  969. Nation* ownNation = nation_array[nation_recno];
  970. for( int i=linked_town_count-1 ; i>=0 ; i-- )
  971. {
  972. Town* townPtr = town_array[ linked_town_array[i] ];
  973. //--- only change links to foreign towns, links to own towns are always on ---//
  974. if( townPtr->nation_recno == nation_recno )
  975. continue;
  976. //---- only enable links to non-friendly towns ----//
  977. int enableFlag = townPtr->nation_recno==0 ||
  978. ownNation->get_relation(townPtr->nation_recno)->status == NATION_HOSTILE;
  979. toggle_town_link( i+1, enableFlag, COMMAND_AI );
  980. }
  981. }
  982. //--------- End of function FirmCamp::think_change_town_link -------//
  983. //------- Begin of function FirmCamp::think_assign_better_commander -------//
  984. //
  985. // Assign a better commander to this camp.
  986. //
  987. int FirmCamp::think_assign_better_commander()
  988. {
  989. //----- if there is already an overseer being assigned to the camp ---//
  990. Nation* ownNation = nation_array[nation_recno];
  991. int actionRecno = ownNation->is_action_exist(loc_x1, loc_y1, -1, -1,
  992. ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP);
  993. //--- if there is already one existing ---//
  994. if( actionRecno )
  995. {
  996. //--- if the action still is already being processed, don't bother with it ---//
  997. if( ownNation->get_action(actionRecno)->processing_instance_count > 0 )
  998. return 0;
  999. //--- however, if the action hasn't been processed, we still try to use the approach here ---//
  1000. }
  1001. //-------------------------------------------------//
  1002. Firm* firmPtr;
  1003. Worker* workerPtr;
  1004. int bestRaceId = best_commander_race();
  1005. int bestFirmRecno=0, bestWorkerId;
  1006. int bestLeadership=0;
  1007. if( overseer_recno )
  1008. {
  1009. bestLeadership = cur_commander_leadership(bestRaceId)
  1010. + 10 + ownNation->pref_loyalty_concern/10; // nations that have higher loyalty concern will not switch commander too frequently
  1011. }
  1012. //--- locate for a soldier who has a higher leadership ---//
  1013. for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- )
  1014. {
  1015. firmPtr = firm_array[ ownNation->ai_camp_array[i] ];
  1016. if( firmPtr->region_id != region_id )
  1017. continue;
  1018. workerPtr = firmPtr->worker_array;
  1019. for( int j=1 ; j<=firmPtr->worker_count ; j++, workerPtr++ )
  1020. {
  1021. if( !workerPtr->race_id )
  1022. continue;
  1023. int workerLeadership = workerPtr->skill_level;
  1024. if( workerPtr->race_id != bestRaceId )
  1025. workerLeadership /= 2;
  1026. if( workerLeadership > bestLeadership )
  1027. {
  1028. bestLeadership = workerLeadership;
  1029. bestFirmRecno = firmPtr->firm_recno;
  1030. bestWorkerId = j;
  1031. }
  1032. }
  1033. }
  1034. if( bestFirmRecno == 0 )
  1035. return 0;
  1036. //-------- assign the overseer now -------//
  1037. int unitRecno = firm_array[bestFirmRecno]->mobilize_worker(bestWorkerId, COMMAND_AI);
  1038. if( !unitRecno )
  1039. return 0;
  1040. Unit* unitPtr = unit_array[unitRecno];
  1041. unitPtr->set_rank(RANK_GENERAL);
  1042. //---- if there is already an existing but unprocessed one, delete it first ---//
  1043. if( actionRecno )
  1044. ownNation->del_action(actionRecno);
  1045. return ownNation->add_action(loc_x1, loc_y1, -1, -1, ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP, 1, unitRecno);
  1046. }
  1047. //-------- End of function FirmCamp::think_assign_better_commander ---------//
  1048. //------- Begin of function FirmCamp::cur_commander_leadership -------//
  1049. //
  1050. // [int] bestRaceId - if this is given, it will be used, otherwise
  1051. // it will use best_commander_race().
  1052. //
  1053. // Return the commander leadership
  1054. //
  1055. int FirmCamp::cur_commander_leadership(int bestRaceId)
  1056. {
  1057. int commanderLeadership=0;
  1058. //--- get the current leadership of the commander ----//
  1059. if( overseer_recno )
  1060. {
  1061. if( !bestRaceId )
  1062. bestRaceId = best_commander_race();
  1063. Unit* unitCommander = unit_array[overseer_recno];
  1064. if( unitCommander->race_id == bestRaceId )
  1065. commanderLeadership = unitCommander->skill.skill_level;
  1066. else
  1067. commanderLeadership = unitCommander->skill.skill_level / 2; // divided by 2 if the race doesn't match
  1068. }
  1069. return commanderLeadership;
  1070. }
  1071. //-------- End of function FirmCamp::cur_commander_leadership ---------//
  1072. //------- Begin of function FirmCamp::new_commander_leadership -------//
  1073. //
  1074. // <int> newRaceId - the race id. of the would-be commander.
  1075. // <int> newSkillLevel - the skill level of the would-be commander.
  1076. //
  1077. // Return the commander leadership if the unit is assigned to this camp.
  1078. //
  1079. int FirmCamp::new_commander_leadership(int newRaceId, int newSkillLevel)
  1080. {
  1081. int commanderLeadership=0;
  1082. int bestRaceId = best_commander_race();
  1083. //--- get the current leadership of the commander ----//
  1084. if( overseer_recno )
  1085. {
  1086. if( newRaceId == bestRaceId )
  1087. commanderLeadership = newSkillLevel;
  1088. else
  1089. commanderLeadership = newSkillLevel / 2; // divided by 2 if the race doesn't match
  1090. }
  1091. return commanderLeadership;
  1092. }
  1093. //-------- End of function FirmCamp::new_commander_leadership ---------//
  1094. //------- Begin of function FirmCamp::best_commander_race -------//
  1095. //
  1096. // Return what race the commander should be for this camp.
  1097. //
  1098. int FirmCamp::best_commander_race()
  1099. {
  1100. //---------------------------------------------//
  1101. //
  1102. // If this camp is the commanding camp of a town,
  1103. // then return the majority race of the town.
  1104. //
  1105. // A camp is the commanding camp of a town when
  1106. // it is the closest camp to the town.
  1107. //
  1108. //---------------------------------------------//
  1109. for( int i=linked_town_count-1 ; i>=0 ; i-- )
  1110. {
  1111. Town* townPtr = town_array[ linked_town_array[i] ];
  1112. if( townPtr->closest_own_camp() == firm_recno )
  1113. return townPtr->majority_race();
  1114. }
  1115. //----- check if this camp is trying to capture an independent town ---//
  1116. int targetTownRecno = think_capture_target_town();
  1117. if( targetTownRecno && town_array[targetTownRecno]->nation_recno==0 )
  1118. return town_array[targetTownRecno]->majority_race();
  1119. //----- Otherwise return the majority race of this camp -----//
  1120. return majority_race();
  1121. }
  1122. //-------- End of function FirmCamp::best_commander_race ---------//