OU_GOD2.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  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 : OU_GOD2.CPP
  21. //Description: God Unit - AI functions
  22. #include <OGODRES.h>
  23. #include <ORACERES.h>
  24. #include <OF_CAMP.h>
  25. #include <OU_GOD.h>
  26. //------- Begin of function UnitGod::process_ai --------//
  27. void UnitGod::process_ai()
  28. {
  29. if( !is_ai_all_stop() )
  30. return;
  31. if( info.game_date%7 != sprite_recno%7 )
  32. return;
  33. switch( god_id )
  34. {
  35. case GOD_NORMAN:
  36. think_dragon();
  37. break;
  38. case GOD_MAYA:
  39. think_maya_god();
  40. break;
  41. case GOD_GREEK:
  42. think_phoenix();
  43. break;
  44. case GOD_VIKING:
  45. think_viking_god();
  46. break;
  47. case GOD_PERSIAN:
  48. think_persian_god();
  49. break;
  50. case GOD_CHINESE:
  51. think_chinese_dragon();
  52. break;
  53. case GOD_JAPANESE:
  54. think_japanese_god();
  55. break;
  56. #if(MAX_RACE > 7)
  57. case GOD_EGYPTIAN:
  58. think_egyptian_god();
  59. break;
  60. case GOD_INDIAN:
  61. think_indian_god();
  62. break;
  63. case GOD_ZULU:
  64. think_zulu_god();
  65. break;
  66. #endif
  67. }
  68. }
  69. //------- End of function UnitGod::process_ai --------//
  70. //------- Begin of function UnitGod::think_dragon --------//
  71. void UnitGod::think_dragon()
  72. {
  73. int targetXLoc, targetYLoc;
  74. if( think_god_attack_target(targetXLoc, targetYLoc) )
  75. attack_firm( targetXLoc, targetYLoc );
  76. }
  77. //------- End of function UnitGod::think_dragon --------//
  78. //------- Begin of function UnitGod::think_chinese_dragon --------//
  79. void UnitGod::think_chinese_dragon()
  80. {
  81. int targetXLoc, targetYLoc;
  82. if( think_god_attack_target(targetXLoc, targetYLoc) )
  83. attack_firm( targetXLoc, targetYLoc );
  84. }
  85. //------- End of function UnitGod::think_chinese_dragon --------//
  86. //------- Begin of function UnitGod::think_phoenix --------//
  87. void UnitGod::think_phoenix()
  88. {
  89. int xLoc = m.random(MAX_WORLD_X_LOC);
  90. int yLoc = m.random(MAX_WORLD_Y_LOC);
  91. move_to( xLoc, yLoc );
  92. }
  93. //------- End of function UnitGod::think_phoenix --------//
  94. //------- Begin of function UnitGod::think_viking_god --------//
  95. void UnitGod::think_viking_god()
  96. {
  97. int targetXLoc, targetYLoc;
  98. if( think_god_attack_target(targetXLoc, targetYLoc) )
  99. {
  100. go_cast_power(targetXLoc+1, targetYLoc+1, 2, COMMAND_AI); // 2 - cast power type
  101. }
  102. }
  103. //------- End of function UnitGod::think_viking_god --------//
  104. //------- Begin of function UnitGod::think_persian_god --------//
  105. void UnitGod::think_persian_god()
  106. {
  107. //------- there is no action, now think a new one ------//
  108. Nation* ownNation = nation_array[nation_recno];
  109. Firm* firmPtr;
  110. int curRating, bestRating=0;
  111. int targetXLoc, targetYLoc;
  112. for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- )
  113. {
  114. firmPtr = firm_array[ ownNation->ai_camp_array[i] ];
  115. //----- calculate the injured rating of the camp ----//
  116. Worker* workerPtr = firmPtr->worker_array;
  117. int totalHitPoints = 0;
  118. int totalMaxHitPoints = 0;
  119. for( int j=0 ; j<firmPtr->worker_count ; j++, workerPtr++ )
  120. {
  121. totalHitPoints += workerPtr->hit_points;
  122. totalMaxHitPoints += workerPtr->max_hit_points();
  123. }
  124. if( !totalMaxHitPoints )
  125. continue;
  126. curRating = 100 * (totalMaxHitPoints-totalHitPoints) / totalMaxHitPoints;
  127. //---- if the king is the commander of this camp -----//
  128. if( firmPtr->overseer_recno &&
  129. unit_array[firmPtr->overseer_recno]->rank_id == RANK_KING )
  130. {
  131. curRating += 20;
  132. }
  133. if( curRating > bestRating )
  134. {
  135. bestRating = curRating;
  136. targetXLoc = firmPtr->center_x;
  137. targetYLoc = firmPtr->center_y;
  138. }
  139. }
  140. //-------------------------------------//
  141. if( bestRating )
  142. {
  143. go_cast_power(targetXLoc, targetYLoc, 1, COMMAND_AI); // 1 - cast power type
  144. }
  145. }
  146. //------- End of function UnitGod::think_persian_god --------//
  147. //------- Begin of function UnitGod::think_japanese_god --------//
  148. void UnitGod::think_japanese_god()
  149. {
  150. //------- there is no action, now think a new one ------//
  151. Nation* ownNation = nation_array[nation_recno];
  152. int curRating, bestRating=0;
  153. int targetXLoc, targetYLoc;
  154. //------ think firm target --------//
  155. if( m.random(2)==0 )
  156. {
  157. for( int i=firm_array.size() ; i>0 ; i-- )
  158. {
  159. if( firm_array.is_deleted(i) )
  160. continue;
  161. Firm* firmPtr = firm_array[i];
  162. //------- only cast on camps ---------//
  163. if( firmPtr->firm_id != FIRM_CAMP )
  164. continue;
  165. //------ only cast on hostile and tense nations ------//
  166. if( ownNation->get_relation(firmPtr->nation_recno)->status > NATION_TENSE )
  167. continue;
  168. //------ calculate the rating of the firm -------//
  169. curRating = ((FirmCamp*)firmPtr)->total_combat_level()/10;
  170. if( curRating > bestRating )
  171. {
  172. bestRating = curRating;
  173. targetXLoc = firmPtr->center_x;
  174. targetYLoc = firmPtr->center_y;
  175. }
  176. }
  177. }
  178. else
  179. {
  180. //------ think town target --------//
  181. for( int i=town_array.size() ; i>0 ; i-- )
  182. {
  183. if( town_array.is_deleted(i) )
  184. continue;
  185. Town* townPtr = town_array[i];
  186. //------ only cast on hostile and tense nations ------//
  187. if( townPtr->nation_recno && ownNation->get_relation(townPtr->nation_recno)->status > NATION_TENSE )
  188. continue;
  189. //------ calculate the rating of the firm -------//
  190. curRating = townPtr->population + (100-townPtr->average_loyalty());
  191. if( curRating > bestRating )
  192. {
  193. bestRating = curRating;
  194. targetXLoc = townPtr->center_x;
  195. targetYLoc = townPtr->center_y;
  196. }
  197. }
  198. }
  199. //-------------------------------------//
  200. if( bestRating )
  201. {
  202. go_cast_power(targetXLoc, targetYLoc, 1, COMMAND_AI); // 1 - cast power type
  203. }
  204. }
  205. //------- End of function UnitGod::think_japanese_god --------//
  206. //------- Begin of function UnitGod::think_god_attack_target --------//
  207. //
  208. // <int&> targetXLoc, targetYLoc - reference vars for returning the
  209. // location of the target.
  210. //
  211. // return: <int> 1 - target selected
  212. // 0 - no target selected
  213. //
  214. int UnitGod::think_god_attack_target(int& targetXLoc, int& targetYLoc)
  215. {
  216. Firm* firmPtr;
  217. Nation* ownNation = nation_array[nation_recno];
  218. int curXLoc=next_x_loc(), curYLoc=next_y_loc();
  219. int totalFirm = firm_array.size();
  220. int firmRecno = m.random(totalFirm)+1;
  221. int i;
  222. for( i=totalFirm ; i>0 ; i-- )
  223. {
  224. if( ++firmRecno > totalFirm )
  225. firmRecno = 1;
  226. if( firm_array.is_deleted(firmRecno) )
  227. continue;
  228. firmPtr = firm_array[firmRecno];
  229. if( firmPtr->firm_id == FIRM_MONSTER )
  230. continue;
  231. //-------- only attack enemies ----------//
  232. if( ownNation->get_relation(firmPtr->nation_recno)->status != NATION_HOSTILE )
  233. continue;
  234. //---- only attack enemy base and camp ----//
  235. if( firmPtr->firm_id != FIRM_BASE &&
  236. firmPtr->firm_id != FIRM_CAMP )
  237. {
  238. continue;
  239. }
  240. //------- attack now --------//
  241. targetXLoc = firmPtr->loc_x1;
  242. targetYLoc = firmPtr->loc_y1;
  243. return 1;
  244. }
  245. //----- if there is no enemy to attack, attack Fryhtans ----//
  246. for( i=totalFirm ; i>0 ; i-- )
  247. {
  248. if( ++firmRecno > totalFirm )
  249. firmRecno = 1;
  250. if( firm_array.is_deleted(firmRecno) )
  251. continue;
  252. firmPtr = firm_array[firmRecno];
  253. if( firmPtr->firm_id == FIRM_MONSTER )
  254. {
  255. targetXLoc = firmPtr->loc_x1;
  256. targetYLoc = firmPtr->loc_y1;
  257. return 1;
  258. }
  259. }
  260. //---------------------------------------------------//
  261. return 0;
  262. }
  263. //------- End of function UnitGod::think_god_attack_target --------//
  264. //------- Begin of function UnitGod::think_maya_god --------//
  265. void UnitGod::think_maya_god()
  266. {
  267. //------- there is no action, now think a new one ------//
  268. Nation* ownNation = nation_array[nation_recno];
  269. Firm* firmPtr;
  270. int curRating, bestRating=0;
  271. int targetXLoc, targetYLoc;
  272. for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- )
  273. {
  274. firmPtr = firm_array[ ownNation->ai_camp_array[i] ];
  275. curRating = 0;
  276. if( firmPtr->overseer_recno )
  277. {
  278. Unit* unitPtr = unit_array[firmPtr->overseer_recno];
  279. if( unitPtr->race_id == RACE_MAYA && unitPtr->skill.combat_level < 100 )
  280. curRating += 10;
  281. }
  282. Worker* workerPtr = firmPtr->worker_array;
  283. for( int j=firmPtr->worker_count-1 ; j>=0 ; j--, workerPtr++ )
  284. {
  285. if( workerPtr->race_id == RACE_MAYA && workerPtr->combat_level < 100 )
  286. curRating += 5;
  287. }
  288. if( curRating > bestRating )
  289. {
  290. bestRating = curRating;
  291. targetXLoc = firmPtr->center_x;
  292. targetYLoc = firmPtr->center_y;
  293. }
  294. }
  295. //-------------------------------------//
  296. if( bestRating )
  297. {
  298. go_cast_power(targetXLoc, targetYLoc, 1, COMMAND_AI); // 1 - cast power type
  299. }
  300. }
  301. //------- End of function UnitGod::think_maya_god --------//
  302. #ifdef AMPLUS
  303. //------- Begin of function UnitGod::think_egyptian_god --------//
  304. void UnitGod::think_egyptian_god()
  305. {
  306. Nation* ownNation = nation_array[nation_recno];
  307. int curRating, bestRating=0;
  308. int targetXLoc, targetYLoc;
  309. for( int i=town_array.size() ; i>0 ; i-- )
  310. {
  311. if( town_array.is_deleted(i) )
  312. continue;
  313. Town* townPtr = town_array[i];
  314. //------ only cast on own nations ------//
  315. if( townPtr->nation_recno != nation_recno )
  316. continue;
  317. //------ calculate the rating of the firm -------//
  318. if( townPtr->population > MAX_TOWN_GROWTH_POPULATION - 5 )
  319. continue;
  320. // maximize the total loyalty gain.
  321. curRating = 5 * townPtr->average_loyalty();
  322. // calc rating on the number of people
  323. if( townPtr->population >= MAX_TOWN_GROWTH_POPULATION/2 )
  324. curRating -= (townPtr->population - MAX_TOWN_GROWTH_POPULATION/2) * 300 / MAX_TOWN_GROWTH_POPULATION;
  325. else
  326. curRating -= (MAX_TOWN_GROWTH_POPULATION/2 - townPtr->population) * 300 / MAX_TOWN_GROWTH_POPULATION;
  327. if( curRating > bestRating )
  328. {
  329. bestRating = curRating;
  330. targetXLoc = townPtr->center_x;
  331. targetYLoc = townPtr->center_y;
  332. }
  333. }
  334. //-------------------------------------//
  335. if( bestRating )
  336. {
  337. go_cast_power(targetXLoc, targetYLoc, 1, COMMAND_AI); // 1 - cast power type
  338. }
  339. }
  340. //------- End of function UnitGod::think_egyptian_god --------//
  341. //------- Begin of function UnitGod::think_indian_god --------//
  342. void UnitGod::think_indian_god()
  343. {
  344. Nation* ownNation = nation_array[nation_recno];
  345. // see if any unit near by
  346. int castRadius = 2;
  347. int leftLocX = next_x_loc() - castRadius;
  348. if(leftLocX < 0)
  349. leftLocX = 0;
  350. int rightLocX = next_x_loc() + castRadius;
  351. if(rightLocX >= MAX_WORLD_X_LOC)
  352. rightLocX = MAX_WORLD_X_LOC-1;
  353. int topLocY = next_y_loc() - castRadius;
  354. if(topLocY < 0)
  355. topLocY = 0;
  356. int bottomLocY = next_y_loc() + castRadius;
  357. if(bottomLocY >= MAX_WORLD_Y_LOC)
  358. bottomLocY = MAX_WORLD_Y_LOC-1;
  359. int curRating = 0;
  360. int xLoc, yLoc;
  361. for( yLoc = topLocY; yLoc <= bottomLocY; ++yLoc)
  362. {
  363. for( xLoc = leftLocX; xLoc <= rightLocX; ++xLoc )
  364. {
  365. Location *locPtr = world.get_loc(xLoc, yLoc);
  366. int unitRecno;
  367. Unit *unitPtr;
  368. if( locPtr->has_unit(UNIT_LAND)
  369. && (unitRecno = locPtr->unit_recno(UNIT_LAND))
  370. && !unit_array.is_deleted(unitRecno)
  371. && (unitPtr = unit_array[unitRecno])
  372. && unitPtr->nation_recno // don't affect indepedent unit
  373. && unitPtr->nation_recno != nation_recno
  374. && (unitPtr->loyalty >= 20 && unitPtr->loyalty <= 60 ||
  375. unitPtr->loyalty <= 80 && unitPtr->target_loyalty < 30) )
  376. {
  377. switch( ownNation->get_relation(unitPtr->nation_recno)->status )
  378. {
  379. case NATION_HOSTILE:
  380. curRating += 3;
  381. break;
  382. case NATION_TENSE:
  383. case NATION_NEUTRAL:
  384. // curRating += 0; // unchange
  385. break;
  386. case NATION_FRIENDLY:
  387. curRating -= 1; // actually friendly humans are not affected
  388. break;
  389. case NATION_ALLIANCE:
  390. curRating -= 1; // actually allied humans are not affected
  391. break;
  392. default:
  393. err_here();
  394. }
  395. }
  396. }
  397. }
  398. if( curRating > 1 )
  399. {
  400. // if enemy unit come near, cast
  401. go_cast_power(next_x_loc(), next_y_loc(), 1, COMMAND_AI); // 1 - cast power type
  402. }
  403. else
  404. {
  405. // find any unit suitable, go to that area first
  406. int bestUnitCost = 20000;
  407. for( int unitRecno = unit_array.size(); unitRecno > 0; --unitRecno )
  408. {
  409. Unit *unitPtr;
  410. if( !unit_array.is_deleted(unitRecno)
  411. && (unitPtr = unit_array[unitRecno])
  412. && unitPtr->is_visible()
  413. && unitPtr->mobile_type == UNIT_LAND
  414. && unitPtr->nation_recno // don't affect indepedent unit
  415. && unitPtr->nation_recno != nation_recno
  416. && (unitPtr->loyalty >= 20 && unitPtr->loyalty <= 60 ||
  417. unitPtr->loyalty <= 80 && unitPtr->target_loyalty < 30)
  418. && ownNation->get_relation(unitPtr->nation_recno)->status == NATION_HOSTILE )
  419. {
  420. int cost = m.points_distance(next_x_loc(), next_y_loc(), unitPtr->next_x_loc(), unitPtr->next_y_loc());
  421. if( cost < bestUnitCost )
  422. {
  423. bestUnitCost = cost;
  424. xLoc = unitPtr->next_x_loc();
  425. yLoc = unitPtr->next_y_loc();
  426. }
  427. }
  428. }
  429. if( bestUnitCost < 100 )
  430. {
  431. if( m.points_distance(next_x_loc(), next_y_loc(), xLoc, yLoc) <= god_res[god_id]->cast_power_range )
  432. go_cast_power(xLoc, yLoc, 1, COMMAND_AI); // 1 - cast power type
  433. else
  434. move_to( xLoc, yLoc );
  435. }
  436. else if( m.random(4) == 0 )
  437. {
  438. // move to a near random location
  439. xLoc = next_x_loc() + m.random(100) - 50;
  440. if( xLoc < 0 )
  441. xLoc = 0;
  442. if( xLoc >= MAX_WORLD_X_LOC)
  443. xLoc = MAX_WORLD_X_LOC-1;
  444. yLoc = next_y_loc() + m.random(100) - 50;
  445. if( yLoc < 0 )
  446. yLoc = 0;
  447. if( yLoc >= MAX_WORLD_Y_LOC)
  448. yLoc = MAX_WORLD_Y_LOC-1;
  449. move_to( xLoc, yLoc );
  450. }
  451. }
  452. }
  453. //------- End of function UnitGod::think_indian_god --------//
  454. //------- Begin of function UnitGod::think_zulu_god --------//
  455. void UnitGod::think_zulu_god()
  456. {
  457. //------- there is no action, now think a new one ------//
  458. Nation* ownNation = nation_array[nation_recno];
  459. Firm* firmPtr;
  460. int curRating, bestRating=0;
  461. int targetXLoc, targetYLoc;
  462. for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- )
  463. {
  464. firmPtr = firm_array[ ownNation->ai_camp_array[i] ];
  465. curRating = 0;
  466. Unit* unitPtr;
  467. if( firmPtr->overseer_recno
  468. && (unitPtr = unit_array[firmPtr->overseer_recno])
  469. && unitPtr->race_id == RACE_ZULU // only consider ZULU leader
  470. && unitPtr->skill.skill_level <= 70)
  471. {
  472. if( unitPtr->rank_id == RANK_KING )
  473. curRating += 5000; // weak king need leadership very much
  474. if( unitPtr->skill.skill_level >= 40 )
  475. curRating += 5000 - (unitPtr->skill.skill_level - 40) * 60; // strong leader need not be enhanced
  476. else
  477. curRating += 5000 - (40 - unitPtr->skill.skill_level) * 80; // don't add weak leader
  478. // calculat the benefits to his soldiers
  479. Worker* workerPtr = firmPtr->worker_array;
  480. for( int j=firmPtr->worker_count-1 ; j>=0 ; j--, workerPtr++ )
  481. {
  482. if( workerPtr->race_id == RACE_ZULU )
  483. curRating += (unitPtr->skill.combat_level - workerPtr->combat_level)*2;
  484. else
  485. curRating += unitPtr->skill.combat_level - workerPtr->combat_level;
  486. }
  487. if( curRating > bestRating )
  488. {
  489. bestRating = curRating;
  490. targetXLoc = firmPtr->center_x;
  491. targetYLoc = firmPtr->center_y;
  492. }
  493. }
  494. }
  495. //-------------------------------------//
  496. if( bestRating )
  497. {
  498. go_cast_power(targetXLoc, targetYLoc, 1, COMMAND_AI); // 1 - cast power type
  499. }
  500. }
  501. //------- End of function UnitGod::think_zulu_god --------//
  502. #endif