OUNITAI.cpp 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294
  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 : OUNITAI.CPP
  21. //Description : Object Unit AI
  22. #include <OSYS.h>
  23. #include <OSPY.h>
  24. #include <OREBEL.h>
  25. #include <OUNIT.h>
  26. #include <OCONFIG.h>
  27. #include <OREGIONS.h>
  28. #include <OF_CAMP.h>
  29. #include <ONATION.h>
  30. #ifdef NO_DEBUG_UNIT
  31. #undef err_when
  32. #undef err_here
  33. #undef err_if
  34. #undef err_else
  35. #undef err_now
  36. #define err_when(cond)
  37. #define err_here()
  38. #define err_if(cond)
  39. #define err_else
  40. #define err_now(msg)
  41. #undef DEBUG
  42. #endif
  43. //--------- Begin of function Unit::process_ai --------//
  44. //
  45. // [int] forceExecute - whether force execute all AI functions
  46. // without checking day interavals.
  47. // (default: 0)
  48. //
  49. void Unit::process_ai()
  50. {
  51. err_when( !nation_recno );
  52. //-*********** simulate aat ************-//
  53. #ifdef DEBUG
  54. if(debug_sim_game_type)
  55. return;
  56. #endif
  57. //-*********** simulate aat ************-//
  58. //------ the aggressive_mode of AI units is always 1 ------//
  59. aggressive_mode = 1;
  60. //------- handle Seek Path failures ------//
  61. if( ai_handle_seek_path_fail() )
  62. return;
  63. //--- if it's a spy from other nation, don't control it ---//
  64. if( spy_recno && true_nation_recno() != nation_recno )
  65. {
  66. //--- a random chance of the AI catching the spy and resign it ---//
  67. if( is_visible() && m.random(365 * FRAMES_PER_DAY)==0 ) // if the unit stay outside for one year, it will get caught
  68. {
  69. stop2();
  70. resign(COMMAND_AI);
  71. return;
  72. }
  73. if( !spy_array[spy_recno]->notify_cloaked_nation_flag ) // if notify_cloaked_nation_flag is 1, the nation will take it as its own spies
  74. return;
  75. }
  76. //----- think about rewarding this unit -----//
  77. if( race_id && rank_id != RANK_KING &&
  78. info.game_date%5 == sprite_recno%5 )
  79. {
  80. think_reward();
  81. }
  82. //-----------------------------------------//
  83. if( !is_visible() )
  84. return;
  85. //--- if the unit has stopped, but ai_action_id hasn't been reset ---//
  86. if( cur_action==SPRITE_IDLE && action_mode==ACTION_STOP &&
  87. action_mode2==ACTION_STOP && ai_action_id )
  88. {
  89. nation_array[nation_recno]->action_failure(ai_action_id, sprite_recno);
  90. err_when( ai_action_id ); // it should have been reset
  91. }
  92. //---- King flees under attack or surrounded by enemy ---//
  93. if( race_id && rank_id==RANK_KING )
  94. {
  95. if( think_king_flee() )
  96. return;
  97. }
  98. //---- General flees under attack or surrounded by enemy ---//
  99. if( race_id && rank_id==RANK_GENERAL &&
  100. info.game_date%7 == sprite_recno%7 )
  101. {
  102. if( think_general_flee() )
  103. return;
  104. }
  105. //-- let Unit::next_day() process it process original_action_mode --//
  106. if( original_action_mode )
  107. return;
  108. //------ if the unit is not stop right now ------//
  109. if( !is_ai_all_stop() )
  110. {
  111. think_stop_chase();
  112. return;
  113. }
  114. //-----------------------------------------//
  115. if( mobile_type==UNIT_LAND )
  116. {
  117. if( ai_escape_fire() )
  118. return;
  119. }
  120. //---------- if this is your spy --------//
  121. if( spy_recno && true_nation_recno()==nation_recno )
  122. think_spy_action();
  123. //------ if this unit is from a camp --------//
  124. if( home_camp_firm_recno )
  125. {
  126. Firm* firmCamp = firm_array[home_camp_firm_recno];
  127. int rc;
  128. if( rank_id == RANK_SOLDIER )
  129. rc = firmCamp->worker_count < MAX_WORKER;
  130. else
  131. rc = !firmCamp->overseer_recno;
  132. if( rc )
  133. {
  134. if( return_camp() )
  135. return;
  136. }
  137. home_camp_firm_recno = 0; // the camp is already occupied by somebody
  138. }
  139. //----------------------------------------//
  140. if( race_id && rank_id==RANK_KING )
  141. {
  142. think_king_action();
  143. }
  144. else if( race_id && rank_id==RANK_GENERAL )
  145. {
  146. think_general_action();
  147. }
  148. else
  149. {
  150. if( unit_res[unit_id]->unit_class == UNIT_CLASS_WEAPON )
  151. {
  152. if( info.game_date%15 == sprite_recno%15 ) // don't call too often as the action may fail and it takes a while to call the function each time
  153. {
  154. think_weapon_action(); //-- ships AI are called in UnitMarine --//
  155. }
  156. }
  157. else if( race_id )
  158. {
  159. //--- if previous attempts for new action failed, don't call think_normal_human_action() so frequently then ---//
  160. if( ai_no_suitable_action )
  161. {
  162. if( info.game_date%15 != sprite_recno%15 ) // don't call too often as the action may fail and it takes a while to call the function each time
  163. return;
  164. }
  165. //---------------------------------//
  166. if( !think_normal_human_action() )
  167. {
  168. ai_no_suitable_action = 1; // set this flag so think_normal_human_action() won't be called continously
  169. if( !leader_unit_recno ) // only when the unit is not led by a commander
  170. {
  171. resign(COMMAND_AI);
  172. }
  173. else
  174. {
  175. ai_move_to_nearby_town();
  176. }
  177. }
  178. }
  179. }
  180. }
  181. //---------- End of function Unit::process_ai --------//
  182. //--------- Begin of function Unit::think_stop_chase --------//
  183. int Unit::think_stop_chase()
  184. {
  185. //-----------------------------------------------------//
  186. //
  187. // Stop the chase if the target is being far away from
  188. // its original attacking location.
  189. //
  190. //-----------------------------------------------------//
  191. if( !(action_mode==ACTION_ATTACK_UNIT && ai_original_target_x_loc>=0) )
  192. return 0;
  193. if( unit_array.is_deleted(action_para) )
  194. {
  195. stop2();
  196. return 1;
  197. }
  198. Unit* targetUnit = unit_array[action_para];
  199. if( !targetUnit->is_visible() )
  200. {
  201. stop2();
  202. return 1;
  203. }
  204. //----------------------------------------//
  205. int aiChaseDistance = 10 + nation_array[nation_recno]->pref_military_courage/20; // chase distance: 10 to 15
  206. int curDistance = m.points_distance( targetUnit->next_x_loc(), targetUnit->next_y_loc(),
  207. ai_original_target_x_loc, ai_original_target_y_loc );
  208. if( curDistance <= aiChaseDistance )
  209. return 0;
  210. //--------- stop the unit ----------------//
  211. stop2();
  212. //--- if this unit leads a troop, stop the action of all troop members as well ---//
  213. int leaderUnitRecno;
  214. if( leader_unit_recno )
  215. leaderUnitRecno = leader_unit_recno;
  216. else
  217. leaderUnitRecno = sprite_recno;
  218. TeamInfo* teamInfo = unit_array[leaderUnitRecno]->team_info;
  219. if( teamInfo )
  220. {
  221. for( int i=teamInfo->member_count-1 ; i>=0 ; i-- )
  222. {
  223. int unitRecno = teamInfo->member_unit_array[i];
  224. if( unit_array.is_deleted(unitRecno) )
  225. continue;
  226. unit_array[unitRecno]->stop2();
  227. }
  228. }
  229. return 1;
  230. }
  231. //---------- End of function Unit::think_stop_chase --------//
  232. //--------- Begin of function Unit::is_ai_all_stop --------//
  233. int Unit::is_ai_all_stop()
  234. {
  235. return cur_action==SPRITE_IDLE && action_mode==ACTION_STOP &&
  236. action_mode2==ACTION_STOP && !ai_action_id;
  237. }
  238. //---------- End of function Unit::is_ai_all_stop --------//
  239. //--------- Begin of function Unit::ai_move_to_nearby_town --------//
  240. void Unit::ai_move_to_nearby_town()
  241. {
  242. //---- look for towns to assign to -----//
  243. Nation* ownNation = nation_array[nation_recno];
  244. Town *townPtr, *bestTown=NULL;
  245. int regionId = world.get_region_id( next_x_loc(), next_y_loc() );
  246. int curDistance, curRating, bestRating=0;
  247. int curXLoc = next_x_loc(), curYLoc = next_y_loc();
  248. for( int i=town_array.size() ; i>0 ; i-- ) // can't use ai_town_array[] because this function will be called by Unit::betray() when a unit defected to the player's kingdom
  249. {
  250. if( town_array.is_deleted(i) )
  251. continue;
  252. townPtr = town_array[i];
  253. if( townPtr->nation_recno != nation_recno )
  254. continue;
  255. if( townPtr->region_id != regionId )
  256. continue;
  257. //-------------------------------------//
  258. curDistance = m.points_distance(curXLoc, curYLoc, townPtr->center_x, townPtr->center_y );
  259. if( curDistance < 10 ) // no need to move if the unit is already close enough to the town.
  260. return;
  261. curRating = 100 - 100 * curDistance / MAX_WORLD_X_LOC;
  262. curRating += townPtr->population;
  263. //-------------------------------------//
  264. if( curRating > bestRating )
  265. {
  266. bestRating = curRating;
  267. bestTown = townPtr;
  268. }
  269. }
  270. if( bestTown )
  271. move_to_town_surround(bestTown->loc_x1, bestTown->loc_y1, sprite_info->loc_width, sprite_info->loc_height);
  272. }
  273. //---------- End of function Unit::ai_move_to_nearby_town --------//
  274. //--------- Begin of function Unit::ai_escape_fire --------//
  275. //
  276. // Move away if the unit currently stands on a burning ground.
  277. //
  278. int Unit::ai_escape_fire()
  279. {
  280. if(cur_action!=SPRITE_IDLE)
  281. return 0;
  282. if(mobile_type!=UNIT_LAND)
  283. return 0;
  284. Location *locPtr = world.get_loc(next_x_loc(), next_y_loc());
  285. if( !locPtr->fire_str() )
  286. return 0;
  287. //--------------------------------------------//
  288. int checkLimit = 400; // checking for 400 location
  289. int xShift, yShift, checkXLoc, checkYLoc;
  290. int curXLoc = next_x_loc();
  291. int curYLoc = next_y_loc();
  292. for(int i=2; i<checkLimit; i++)
  293. {
  294. m.cal_move_around_a_point(i, 20, 20, xShift, yShift);
  295. checkXLoc = curXLoc + xShift;
  296. checkYLoc = curYLoc + yShift;
  297. if(checkXLoc<0 || checkXLoc>=MAX_WORLD_X_LOC || checkYLoc<0 || checkYLoc>=MAX_WORLD_Y_LOC)
  298. continue;
  299. if(!locPtr->can_move(mobile_type))
  300. continue;
  301. locPtr = world.get_loc(checkXLoc, checkYLoc);
  302. if( locPtr->fire_str()==0 ) // move to a safe place now
  303. {
  304. move_to(checkXLoc, checkYLoc);
  305. return 1;
  306. }
  307. }
  308. return 0;
  309. }
  310. //---------- End of function Unit::ai_escape_fire --------//
  311. //--------- Begin of function Unit::think_spy_action --------//
  312. void Unit::think_spy_action()
  313. {
  314. ai_move_to_nearby_town(); // just move it to one of our towns
  315. }
  316. //---------- End of function Unit::think_spy_action --------//
  317. //--------- Begin of function Unit::think_king_action --------//
  318. int Unit::think_king_action()
  319. {
  320. return think_leader_action();
  321. }
  322. //---------- End of function Unit::think_king_action --------//
  323. //--------- Begin of function Unit::think_general_action --------//
  324. int Unit::think_general_action()
  325. {
  326. if( think_leader_action() )
  327. return 1;
  328. //--- if the general is not assigned to a camp due to its low competency ----//
  329. Nation* ownNation = nation_array[nation_recno];
  330. int rc = 0;
  331. if( team_info->member_count <= 1 )
  332. {
  333. rc = 1;
  334. }
  335. //--- if the skill of the general and the number of soldiers he commands is not large enough to justify building a new camp ---//
  336. else if( skill.skill_level + team_info->member_count*4
  337. < 40 + ownNation->pref_keep_general/5 ) // 40 to 60
  338. {
  339. rc = 1;
  340. }
  341. //-- think about splitting the team and assign them into other forts --//
  342. else if( ownNation->ai_has_too_many_camp() )
  343. {
  344. rc = 1;
  345. }
  346. //--------- demote the general to soldier and disband the troop -------//
  347. if( rc )
  348. {
  349. set_rank(RANK_SOLDIER);
  350. return think_normal_human_action();
  351. }
  352. return 0;
  353. }
  354. //---------- End of function Unit::think_general_action --------//
  355. //--------- Begin of function Unit::think_leader_action --------//
  356. //
  357. // Think about the action of a leader (either a general or a king).
  358. //
  359. int Unit::think_leader_action()
  360. {
  361. Nation* nationPtr = nation_array[nation_recno];
  362. FirmCamp *firmCamp, *bestCamp=NULL;
  363. int curRating, bestRating=10, delActionRecno=0;
  364. int curXLoc = next_x_loc(), curYLoc = next_y_loc();
  365. int curRegionId = world.get_region_id( curXLoc, curYLoc );
  366. if( rank_id == RANK_KING ) // if this unit is the king, always assign it to a camp regardless of whether the king is a better commander than the existing one
  367. bestRating = -1000;
  368. err_when( skill.skill_id != SKILL_LEADING );
  369. //----- think about which camp to move to -----//
  370. for( int i=nationPtr->ai_camp_count-1 ; i>=0 ; i-- )
  371. {
  372. firmCamp = (FirmCamp*) firm_array[ nationPtr->ai_camp_array[i] ];
  373. if( firmCamp->region_id != curRegionId )
  374. continue;
  375. //--- if the commander of this camp is the king, never replace him ---//
  376. if( firmCamp->overseer_recno == nationPtr->king_unit_recno )
  377. continue;
  378. //-------------------------------------//
  379. int curLeadership = firmCamp->cur_commander_leadership();
  380. int newLeadership = firmCamp->new_commander_leadership(race_id, skill.skill_level);
  381. curRating = newLeadership - curLeadership;
  382. //-------------------------------------//
  383. if( curRating > bestRating )
  384. {
  385. //--- if there is already somebody being assigned to it ---//
  386. int actionRecno=0;
  387. if( rank_id != RANK_KING ) // don't check this if the current unit is the king
  388. {
  389. actionRecno = nationPtr->is_action_exist(firmCamp->loc_x1, firmCamp->loc_y1,
  390. -1, -1, ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP);
  391. if( actionRecno && nationPtr->get_action(actionRecno)->processing_instance_count )
  392. continue;
  393. }
  394. bestRating = curRating;
  395. bestCamp = firmCamp;
  396. delActionRecno = actionRecno;
  397. }
  398. }
  399. if( !bestCamp )
  400. return 0;
  401. //----- delete an unprocessed queued action if there is any ----//
  402. if( delActionRecno )
  403. nationPtr->del_action(delActionRecno);
  404. //--------- move to the camp now ---------//
  405. //-- if there is room in the camp to host all soldiers led by this general --//
  406. if( team_info->member_count-1 <= MAX_WORKER-bestCamp->worker_count )
  407. {
  408. validate_team();
  409. unit_array.assign( bestCamp->loc_x1, bestCamp->loc_y1, 0, COMMAND_AI,
  410. team_info->member_unit_array, team_info->member_count );
  411. return 1;
  412. }
  413. else //--- otherwise assign the general only ---//
  414. {
  415. return nationPtr->add_action(bestCamp->loc_x1, bestCamp->loc_y1, -1, -1, ACTION_AI_ASSIGN_OVERSEER, FIRM_CAMP, 1, sprite_recno);
  416. }
  417. return 0;
  418. }
  419. //---------- End of function Unit::think_leader_action --------//
  420. //--------- Begin of function Unit::think_normal_human_action --------//
  421. int Unit::think_normal_human_action()
  422. {
  423. if( home_camp_firm_recno )
  424. return 0;
  425. if( leader_unit_recno &&
  426. unit_array[leader_unit_recno]->is_visible() ) // if the unit is led by a commander, let the commander makes the decision. If the leader has been assigned to a firm, don't consider it as a leader anymore
  427. {
  428. return 0;
  429. }
  430. err_when( !race_id );
  431. err_when( !nation_recno );
  432. //---- think about assign the unit to a firm that needs workers ----//
  433. Nation* ownNation = nation_array[nation_recno];
  434. Firm *firmPtr, *bestFirm=NULL;
  435. int regionId = world.get_region_id( next_x_loc(), next_y_loc() );
  436. int skillId = skill.skill_id;
  437. int skillLevel = skill.skill_level;
  438. int i, curRating, bestRating=0;
  439. int curXLoc = next_x_loc(), curYLoc = next_y_loc();
  440. if( skill.skill_id )
  441. {
  442. for( i=firm_array.size() ; i>0 ; i-- )
  443. {
  444. if( firm_array.is_deleted(i) )
  445. continue;
  446. firmPtr = firm_array[i];
  447. if( firmPtr->nation_recno != nation_recno )
  448. continue;
  449. if( firmPtr->region_id != regionId )
  450. continue;
  451. curRating = 0;
  452. if( skill.skill_id == SKILL_CONSTRUCTION ) // if this is a construction worker
  453. {
  454. if( firmPtr->builder_recno ) // assign the construction worker to this firm as an residental builder
  455. continue;
  456. }
  457. else
  458. {
  459. if( !firmPtr->worker_array ||
  460. firmPtr->firm_skill_id != skillId )
  461. {
  462. continue;
  463. }
  464. //----- if the firm is full of worker ------//
  465. if( firmPtr->is_worker_full() )
  466. {
  467. //---- get the lowest skill worker of the firm -----//
  468. Worker* workerPtr = firmPtr->worker_array;
  469. int minSkill=100;
  470. for( int j=0 ; j<firmPtr->worker_count ; j++, workerPtr++ )
  471. {
  472. if( workerPtr->skill_level < minSkill )
  473. minSkill = workerPtr->skill_level;
  474. }
  475. //------------------------------//
  476. if( firmPtr->majority_race() == race_id )
  477. {
  478. if( skill.skill_level < minSkill+10 )
  479. continue;
  480. }
  481. else //-- for different race, only assign if the skill is significantly higher than the existing ones --//
  482. {
  483. if( skill.skill_level < minSkill+30 )
  484. continue;
  485. }
  486. }
  487. else
  488. {
  489. curRating += 300; // if the firm is not full, rating + 300
  490. }
  491. }
  492. //-------- calculate the rating ---------//
  493. curRating += world.distance_rating( curXLoc, curYLoc, firmPtr->center_x, firmPtr->center_y );
  494. if( firmPtr->majority_race() == race_id )
  495. curRating += 70;
  496. curRating += (MAX_WORKER - firmPtr->worker_count) * 10;
  497. //-------------------------------------//
  498. if( curRating > bestRating )
  499. {
  500. bestRating = curRating;
  501. bestFirm = firmPtr;
  502. }
  503. }
  504. if( bestFirm )
  505. {
  506. assign(bestFirm->loc_x1, bestFirm->loc_y1);
  507. return 1;
  508. }
  509. }
  510. //---- look for towns to assign to -----//
  511. bestRating = 0;
  512. int hasTownInRegion=0;
  513. Town *townPtr, *bestTown=NULL;
  514. for( i=town_array.size() ; i>0 ; i-- ) // can't use ai_town_array[] because this function will be called by Unit::betray() when a unit defected to the player's kingdom
  515. {
  516. if( town_array.is_deleted(i) )
  517. continue;
  518. townPtr = town_array[i];
  519. if( townPtr->nation_recno != nation_recno )
  520. continue;
  521. if( townPtr->region_id != regionId )
  522. continue;
  523. hasTownInRegion = 1;
  524. if( townPtr->population >= MAX_TOWN_POPULATION || !townPtr->is_base_town )
  525. continue;
  526. //--- only assign to towns of the same race ---//
  527. if( ownNation->pref_town_harmony > 50 )
  528. {
  529. if( townPtr->majority_race() != race_id )
  530. continue;
  531. }
  532. //-------- calculate the rating ---------//
  533. curRating = world.distance_rating(curXLoc, curYLoc, townPtr->center_x, townPtr->center_y );
  534. curRating += 300 * townPtr->race_pop_array[race_id-1] / townPtr->population; // racial homogenous bonus
  535. curRating += MAX_TOWN_POPULATION - townPtr->population;
  536. //-------------------------------------//
  537. if( curRating > bestRating )
  538. {
  539. bestRating = curRating;
  540. bestTown = townPtr;
  541. }
  542. }
  543. if( bestTown )
  544. {
  545. assign(bestTown->loc_x1, bestTown->loc_y1);
  546. return 1;
  547. }
  548. //----- if we don't have any existing towns in this region ----//
  549. if( !hasTownInRegion )
  550. {
  551. //#ifdef AMPLUS
  552. // --- if region is too small don't consider this area, stay in the island forever --//
  553. if( region_array[regionId]->region_stat_id == 0 )
  554. return 0;
  555. //#endif
  556. //-- if we also don't have any existing camps in this region --//
  557. if( region_array.get_region_stat(regionId)->camp_nation_count_array[nation_recno-1]==0 )
  558. {
  559. //---- try to build one if this unit can ----//
  560. if( ownNation->cash > firm_res[FIRM_CAMP]->setup_cost &&
  561. firm_res[FIRM_CAMP]->can_build(sprite_recno) &&
  562. !leader_unit_recno ) // if this unit is commanded by a leader, let the leader build the camp
  563. {
  564. ai_build_camp();
  565. }
  566. }
  567. else // if there is already a camp in this region, try to settle a new town next to the camp
  568. {
  569. ai_settle_new_town();
  570. }
  571. return 1; // if we don't have any town in this region, return 1, so this unit won't be resigned and so it can wait for other units to set up camps and villages later ---//
  572. }
  573. return 0;
  574. }
  575. //---------- End of function Unit::think_normal_human_action --------//
  576. //--------- Begin of function Unit::think_weapon_action --------//
  577. int Unit::think_weapon_action()
  578. {
  579. //---- first try to assign the weapon to an existing camp ----//
  580. if( think_assign_weapon_to_camp() )
  581. return 1;
  582. //----- if no camp to assign, build a new one ------//
  583. if( think_build_camp() )
  584. return 1;
  585. return 0;
  586. }
  587. //---------- End of function Unit::think_weapon_action --------//
  588. //--------- Begin of function Unit::think_assign_weapon_to_camp --------//
  589. int Unit::think_assign_weapon_to_camp()
  590. {
  591. Nation *nationPtr = nation_array[nation_recno];
  592. FirmCamp *firmCamp, *bestCamp=NULL;
  593. int curRating=0, bestRating=0;
  594. int regionId = world.get_region_id( next_x_loc(), next_y_loc() );
  595. int curXLoc = next_x_loc(), curYLoc = next_y_loc();
  596. for( int i=0 ; i<nationPtr->ai_camp_count ; i++ )
  597. {
  598. firmCamp = (FirmCamp*) firm_array[ nationPtr->ai_camp_array[i] ];
  599. if( firmCamp->region_id != regionId || firmCamp->is_worker_full() )
  600. continue;
  601. //-------- calculate the rating ---------//
  602. curRating = world.distance_rating(curXLoc, curYLoc, firmCamp->center_x, firmCamp->center_y );
  603. curRating += (MAX_WORKER - firmCamp->worker_count) * 10;
  604. //-------------------------------------//
  605. if( curRating > bestRating )
  606. {
  607. bestRating = curRating;
  608. bestCamp = firmCamp;
  609. }
  610. }
  611. //-----------------------------------//
  612. if( bestCamp )
  613. {
  614. assign(bestCamp->loc_x1, bestCamp->loc_y1);
  615. return 1;
  616. }
  617. return 0;
  618. }
  619. //---------- End of function Unit::think_assign_weapon_to_camp --------//
  620. //--------- Begin of function Unit::think_build_camp --------//
  621. //
  622. // Think about building a camp next to the town which is
  623. // closest to the unit.
  624. //
  625. int Unit::think_build_camp()
  626. {
  627. //---- select a town to build the camp ---//
  628. Nation* ownNation = nation_array[nation_recno];
  629. Town *townPtr, *bestTown=NULL;
  630. int curRating=0, bestRating=0;
  631. int regionId = world.get_region_id( next_x_loc(), next_y_loc() );
  632. int curXLoc = next_x_loc(), curYLoc = next_y_loc();
  633. for( int i=ownNation->ai_town_count-1 ; i>=0 ; i-- )
  634. {
  635. townPtr = town_array[ ownNation->ai_town_array[i] ];
  636. if( townPtr->region_id != regionId )
  637. continue;
  638. if( !townPtr->is_base_town || townPtr->no_neighbor_space )
  639. continue;
  640. curRating = world.distance_rating(curXLoc, curYLoc, townPtr->center_x, townPtr->center_y );
  641. if( curRating > bestRating )
  642. {
  643. bestRating = curRating;
  644. bestTown = townPtr;
  645. }
  646. }
  647. if( bestTown )
  648. return bestTown->ai_build_neighbor_firm(FIRM_CAMP);
  649. return 0;
  650. }
  651. //---------- End of function Unit::think_build_camp --------//
  652. //--------- Begin of function Unit::think_reward --------//
  653. int Unit::think_reward()
  654. {
  655. Nation* ownNation = nation_array[nation_recno];
  656. //----------------------------------------------------------//
  657. // The need to secure high loyalty on this unit is based on:
  658. // -its skill
  659. // -its combat level
  660. // -soldiers commanded by this unit
  661. //----------------------------------------------------------//
  662. if( spy_recno && true_nation_recno() == nation_recno ) // if this is a spy of ours
  663. {
  664. return 0; // Spy::think_reward() will handle this.
  665. }
  666. int curLoyalty = loyalty;
  667. int neededLoyalty;
  668. //----- if this unit is on a mission ------/
  669. if( ai_action_id )
  670. {
  671. neededLoyalty = UNIT_BETRAY_LOYALTY+10;
  672. }
  673. //----- otherwise only reward soldiers and generals ------//
  674. else if( skill.skill_id == SKILL_LEADING )
  675. {
  676. //----- calculate the needed loyalty --------//
  677. neededLoyalty = commanded_soldier_count()*5 + skill.skill_level;
  678. if( unit_mode == UNIT_MODE_OVERSEE ) // if this unit is an overseer
  679. {
  680. if( loyalty < UNIT_BETRAY_LOYALTY ) // if this unit's loyalty is < betrayel level, reward immediately
  681. {
  682. reward(nation_recno); // reward it immediatley if it's an overseer, don't check ai_should_spend()
  683. return 1;
  684. }
  685. neededLoyalty += 30;
  686. }
  687. neededLoyalty = max( UNIT_BETRAY_LOYALTY+10, neededLoyalty ); // 10 points above the betray loyalty level to prevent betrayal
  688. neededLoyalty = min( 100, neededLoyalty );
  689. }
  690. else
  691. {
  692. return 0;
  693. }
  694. //------- if the loyalty is already high enough ------//
  695. if( curLoyalty >= neededLoyalty )
  696. return 0;
  697. //---------- see how many cash & profit we have now ---------//
  698. int rewardNeedRating = neededLoyalty - curLoyalty;
  699. if( curLoyalty < UNIT_BETRAY_LOYALTY+5 )
  700. rewardNeedRating += 50;
  701. if( ownNation->ai_should_spend(rewardNeedRating) )
  702. {
  703. reward(nation_recno);
  704. return 1;
  705. }
  706. return 0;
  707. }
  708. //---------- End of function Unit::think_reward --------//
  709. //--------- Begin of function Unit::ai_leader_being_attacked --------//
  710. //
  711. // This function is called when the king is under attack.
  712. //
  713. // <int> attackerUnitRecno - recno of the attacker unit.
  714. //
  715. void Unit::ai_leader_being_attacked(int attackerUnitRecno)
  716. {
  717. err_when( !team_info );
  718. if( unit_array[attackerUnitRecno]->nation_recno == nation_recno ) // this can happen when the unit has just changed nation
  719. return;
  720. //------------------------------------//
  721. int rc=0, callIntervalDays;
  722. if( rank_id == RANK_KING )
  723. {
  724. rc = 1;
  725. callIntervalDays = 7;
  726. }
  727. else if( rank_id == RANK_GENERAL )
  728. {
  729. rc = skill.skill_level >= 30 + (100-nation_array[nation_recno]->pref_keep_general)/2; // 30 to 80
  730. callIntervalDays = 15; // don't call too freqently
  731. }
  732. if( rc )
  733. {
  734. if( info.game_date > team_info->ai_last_request_defense_date + callIntervalDays )
  735. {
  736. team_info->ai_last_request_defense_date = info.game_date;
  737. nation_array[nation_recno]->ai_defend(attackerUnitRecno);
  738. }
  739. }
  740. }
  741. //---------- End of function Unit::ai_leader_being_attacked --------//
  742. //--------- Begin of function Unit::think_king_flee --------//
  743. //
  744. // Note: we still need to keep think_king_action() because
  745. // between these two functions, a number of things
  746. // may be done, like returning home camp. We only
  747. // carry out actions in this function if the king
  748. // is in danger and urgently need to flee.
  749. //
  750. int Unit::think_king_flee()
  751. {
  752. if( force_move_flag && cur_action != SPRITE_IDLE ) // the king is already fleeing now
  753. return 1;
  754. //------- if the king is alone --------//
  755. Nation* ownNation = nation_array[nation_recno];
  756. //------------------------------------------------//
  757. // When the king is alone and there is no assigned action OR
  758. // when the king is injured, the king will flee
  759. // back to its camp.
  760. //------------------------------------------------//
  761. if( ( team_info->member_count==0 && !ai_action_id ) ||
  762. hit_points < 125-ownNation->pref_military_courage/4 )
  763. {
  764. //------------------------------------------//
  765. //
  766. // If the king is currently under attack, flee
  767. // to the nearest camp with the maximum protection.
  768. //
  769. //------------------------------------------//
  770. Firm *firmCamp, *bestCamp=NULL;
  771. int curRating, bestRating=0;
  772. int curXLoc = next_x_loc(), curYLoc = next_y_loc();
  773. int curRegionId = world.get_region_id( curXLoc, curYLoc );
  774. if( cur_action == SPRITE_ATTACK )
  775. {
  776. for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- )
  777. {
  778. firmCamp = (FirmCamp*) firm_array[ ownNation->ai_camp_array[i] ];
  779. if( firmCamp->region_id != curRegionId )
  780. continue;
  781. if( firmCamp->overseer_recno && rank_id!=RANK_KING ) // if there is already a commander in this camp. However if this is the king, than ingore this
  782. continue;
  783. curRating = world.distance_rating( curXLoc, curYLoc,
  784. firmCamp->center_x, firmCamp->center_y );
  785. if( curRating > bestRating )
  786. {
  787. bestRating = curRating;
  788. bestCamp = firmCamp;
  789. }
  790. }
  791. }
  792. else if( home_camp_firm_recno ) // if there is a home for the king
  793. {
  794. bestCamp = firm_array[home_camp_firm_recno];
  795. }
  796. //------------------------------------//
  797. if( bestCamp )
  798. {
  799. if( config.ai_aggressiveness > OPTION_LOW )
  800. force_move_flag = 1;
  801. assign( bestCamp->loc_x1, bestCamp->loc_y1 );
  802. }
  803. else // if the king is neither under attack or has a home camp, then call the standard think_leader_action()
  804. {
  805. think_leader_action();
  806. }
  807. return cur_action != SPRITE_IDLE;
  808. }
  809. return 0;
  810. }
  811. //---------- End of function Unit::think_king_flee --------//
  812. //--------- Begin of function Unit::think_general_flee --------//
  813. int Unit::think_general_flee()
  814. {
  815. if( force_move_flag && cur_action != SPRITE_IDLE ) // the general is already fleeing now
  816. return 1;
  817. //------- if the general is alone --------//
  818. Nation* ownNation = nation_array[nation_recno];
  819. //------------------------------------------------//
  820. // When the general is alone and there is no assigned action OR
  821. // when the general is injured, the general will flee
  822. // back to its camp.
  823. //------------------------------------------------//
  824. if( ( team_info->member_count==0 && !ai_action_id ) ||
  825. hit_points < max_hit_points * (75+ownNation->pref_military_courage/2) / 200 ) // 75 to 125 / 200
  826. {
  827. //------------------------------------------//
  828. //
  829. // If the general is currently under attack, flee
  830. // to the nearest camp with the maximum protection.
  831. //
  832. //------------------------------------------//
  833. Firm *firmCamp, *bestCamp=NULL;
  834. int curRating, bestRating=0;
  835. int curXLoc = next_x_loc(), curYLoc = next_y_loc();
  836. int curRegionId = world.get_region_id( curXLoc, curYLoc );
  837. if( cur_action == SPRITE_ATTACK )
  838. {
  839. for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- )
  840. {
  841. firmCamp = (FirmCamp*) firm_array[ ownNation->ai_camp_array[i] ];
  842. if( firmCamp->region_id != curRegionId )
  843. continue;
  844. curRating = world.distance_rating( curXLoc, curYLoc,
  845. firmCamp->center_x, firmCamp->center_y );
  846. if( curRating > bestRating )
  847. {
  848. bestRating = curRating;
  849. bestCamp = firmCamp;
  850. }
  851. }
  852. }
  853. else if( home_camp_firm_recno ) // if there is a home for the general
  854. {
  855. bestCamp = firm_array[home_camp_firm_recno];
  856. }
  857. //------------------------------------//
  858. if( bestCamp )
  859. {
  860. if( bestCamp->overseer_recno ) // if there is already an overseer there, just move close to the camp for protection
  861. {
  862. if( config.ai_aggressiveness > OPTION_LOW )
  863. force_move_flag = 1;
  864. move_to( bestCamp->loc_x1, bestCamp->loc_y1 );
  865. }
  866. else
  867. assign( bestCamp->loc_x1, bestCamp->loc_y1 );
  868. }
  869. else // if the general is neither under attack or has a home camp, then call the standard think_leader_action()
  870. {
  871. think_leader_action();
  872. }
  873. return cur_action != SPRITE_IDLE;
  874. }
  875. return 0;
  876. }
  877. //---------- End of function Unit::think_general_flee --------//
  878. //--------- Begin of function Unit::ai_build_camp --------//
  879. //
  880. // Order this unit to build a camp in its region.
  881. //
  882. int Unit::ai_build_camp()
  883. {
  884. //--- to prevent building more than one camp at the same time ---//
  885. int curRegionId = region_id();
  886. Nation* ownNation = nation_array[nation_recno];
  887. if( ownNation->is_action_exist( ACTION_AI_BUILD_FIRM, FIRM_CAMP, curRegionId ) )
  888. return 0;
  889. //------- locate a place for the camp --------//
  890. FirmInfo* firmInfo = firm_res[FIRM_CAMP];
  891. int xLoc=0, yLoc=0;
  892. char teraMask = UnitRes::mobile_type_to_mask(UNIT_LAND);
  893. if( world.locate_space_random(xLoc, yLoc, MAX_WORLD_X_LOC-1,
  894. MAX_WORLD_Y_LOC-1, firmInfo->loc_width+2, firmInfo->loc_height+2, // leave at least one location space around the building
  895. MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC, curRegionId, 1, teraMask) )
  896. {
  897. return ownNation->add_action( xLoc, yLoc, -1, -1,
  898. ACTION_AI_BUILD_FIRM, FIRM_CAMP, 1, sprite_recno );
  899. }
  900. return 0;
  901. }
  902. //---------- End of function Unit::ai_build_camp --------//
  903. //--------- Begin of function Unit::ai_settle_new_town --------//
  904. //
  905. // Settle a new village next to one of the camps in this region.
  906. //
  907. int Unit::ai_settle_new_town()
  908. {
  909. //----- locate a suitable camp for the new town to settle next to ----//
  910. Nation* ownNation = nation_array[nation_recno];
  911. FirmCamp* firmCamp, *bestCamp=NULL;
  912. int curRegionId = region_id();
  913. int curRating, bestRating=0;
  914. for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- )
  915. {
  916. firmCamp = (FirmCamp*) firm_array[ ownNation->ai_camp_array[i] ];
  917. if( firmCamp->region_id != curRegionId )
  918. continue;
  919. curRating = firmCamp->total_combat_level();
  920. if( curRating > bestRating )
  921. {
  922. bestRating = curRating;
  923. bestCamp = firmCamp;
  924. }
  925. }
  926. if( !bestCamp )
  927. return 0;
  928. //--------- settle a new town now ---------//
  929. int xLoc=bestCamp->loc_x1;
  930. int yLoc=bestCamp->loc_y1;
  931. if( world.locate_space(xLoc, yLoc, bestCamp->loc_x2, bestCamp->loc_y2,
  932. STD_TOWN_LOC_WIDTH, STD_TOWN_LOC_HEIGHT,
  933. UNIT_LAND, curRegionId, 1 ) ) // 1-build flag
  934. {
  935. settle( xLoc, yLoc );
  936. return 1;
  937. }
  938. return 0;
  939. }
  940. //---------- End of function Unit::ai_settle_new_town --------//
  941. //--------- Begin of function Unit::ai_handle_seek_path_fail --------//
  942. //
  943. // This function is used for handling cases when AI units are not
  944. // able to seek a path successfully.
  945. //
  946. int Unit::ai_handle_seek_path_fail()
  947. {
  948. if( seek_path_fail_count < 5 ) // wait unit it has failed many times
  949. return 0;
  950. //----- try to move to a new location -----//
  951. if( seek_path_fail_count==5 )
  952. {
  953. stop2(); // stop the unit and think for new action
  954. return 0;
  955. }
  956. //--- if the seek path has failed too many times, resign the unit ---//
  957. int resignFlag = 0;
  958. if( rank_id == RANK_SOLDIER && !leader_unit_recno )
  959. {
  960. if( seek_path_fail_count>=7 )
  961. resignFlag = 1;
  962. }
  963. else if( rank_id == RANK_GENERAL )
  964. {
  965. if( seek_path_fail_count >= 7+skill.skill_level/10 )
  966. resignFlag = 1;
  967. }
  968. if( resignFlag && is_visible() )
  969. {
  970. resign(COMMAND_AI);
  971. return 1;
  972. }
  973. else
  974. return 0;
  975. }
  976. //---------- End of function Unit::ai_handle_seek_path_fail --------//