OAI_MONS.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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 : OAI_MONS.CPP
  21. //Description: AI functions for dealing with the monsters.
  22. #include <OF_MONS.h>
  23. #include <ONATION.h>
  24. #include <OCONFIG.h>
  25. #include <OMONSRES.h>
  26. //--------- Begin of function Nation::think_attack_monster --------//
  27. int Nation::think_attack_monster()
  28. {
  29. if( config.monster_type == OPTION_MONSTER_NONE ) // no monsters in the game
  30. return 0;
  31. //--- if the AI has run out of money and is currently cheating, it will have a urgent need to attack monsters to get money ---//
  32. int useAllCamp = income_365days(INCOME_CHEAT) > 0;
  33. if( !useAllCamp ) // use all camps to attack the monster
  34. {
  35. if( !is_at_war() )
  36. {
  37. if( cash < 500 && military_rank_rating() >= 75-pref_attack_monster/4 ) // 50 to 75
  38. useAllCamp = 1 ;
  39. }
  40. }
  41. if( !useAllCamp )
  42. {
  43. if( military_rank_rating() < 50-pref_attack_monster/4 ) // don't attack if the military strength is too low, 25 to 50
  44. return 0;
  45. }
  46. //------- select a monster target ---------//
  47. int targetCombatLevel;
  48. int targetFirmRecno = think_monster_target(targetCombatLevel);
  49. if( !targetFirmRecno )
  50. return 0;
  51. targetCombatLevel = targetCombatLevel * 150 / 100; // X 150%
  52. //--- we need to use veteran soldiers to attack powerful monsters ---//
  53. FirmMonster* targetFirm = (FirmMonster*) firm_array[targetFirmRecno];
  54. int monsterLevel = monster_res[targetFirm->monster_id]->level;
  55. int attackerMinCombatLevel = 0;
  56. if( targetCombatLevel > 100 ) // if the nation's cash runs very low, it will attack anyway
  57. attackerMinCombatLevel = 20 + monsterLevel*3;
  58. //--- call ai_attack_target() to attack the target town ---//
  59. return ai_attack_target(targetFirm->loc_x1, targetFirm->loc_y1, targetCombatLevel, 0, 0, attackerMinCombatLevel, 0, useAllCamp );
  60. }
  61. //---------- End of function Nation::think_attack_monster --------//
  62. //--------- Begin of function Nation::think_monster_target --------//
  63. //
  64. // Think about the best monster target in the given region.
  65. //
  66. // <int&> targetCombatLevel - var for returning the total combat level of the target firm.
  67. //
  68. int Nation::think_monster_target(int& targetCombatLevel)
  69. {
  70. if( !largest_town_recno )
  71. return 0;
  72. Town* largestTown = town_array[largest_town_recno];
  73. Firm* firmPtr;
  74. int combatLevel;
  75. int curRating, bestRating= -10000, bestFirmRecno=0, hasWar;
  76. for( int firmRecno=firm_array.size() ; firmRecno>0 ; firmRecno-- )
  77. {
  78. if( firm_array.is_deleted(firmRecno) )
  79. continue;
  80. firmPtr = firm_array[firmRecno];
  81. if( firmPtr->firm_id != FIRM_MONSTER ||
  82. firmPtr->region_id != largestTown->region_id )
  83. {
  84. continue;
  85. }
  86. //----- take into account of the mobile units around this town -----//
  87. int mobileCombatLevel = mobile_defense_combat_level(firmPtr->center_x, firmPtr->center_y, firmPtr->nation_recno, 1, hasWar);
  88. if( mobileCombatLevel == -1 ) // do not attack this town because a battle is already going on
  89. continue;
  90. curRating = 3 * m.points_distance( largestTown->center_x, largestTown->center_y,
  91. firmPtr->center_x, firmPtr->center_y );
  92. combatLevel = mobileCombatLevel +
  93. ((FirmMonster*)firmPtr)->total_combat_level();
  94. curRating -= combatLevel;
  95. //---------------------------------//
  96. if( curRating > bestRating )
  97. {
  98. targetCombatLevel = combatLevel;
  99. bestRating = curRating;
  100. bestFirmRecno = firmRecno;
  101. }
  102. }
  103. return bestFirmRecno;
  104. }
  105. //---------- End of function Nation::think_monster_target --------//