CvTacticalAI::SelectPosture(CvTacticalDominanceZone *, AITacticalPosture)
- Defined in
- CvTacticalAI.cpp, line 923
- Class
- CvTacticalAI
- Hook name
CivHooks::CvTacticalAI_SelectPosture
Hooks
static bool BeforeCvTacticalAI_SelectPosture(CvTacticalAI* self, CvTacticalDominanceZone* pZone, AITacticalPosture eLastPosture, AITacticalPosture& result);static void AfterCvTacticalAI_SelectPosture(CvTacticalAI* self, CvTacticalDominanceZone* pZone, AITacticalPosture eLastPosture, AITacticalPosture& result);static AITacticalPosture ReplaceCvTacticalAI_SelectPosture(AITacticalPosture (*original)(CvTacticalAI*, CvTacticalDominanceZone*, AITacticalPosture), CvTacticalAI* self, CvTacticalDominanceZone* pZone, AITacticalPosture eLastPosture);CivRegisterBefore<CivHooks::CvTacticalAI_SelectPosture>(host, &BeforeCvTacticalAI_SelectPosture);CivRegisterAfter<CivHooks::CvTacticalAI_SelectPosture>(host, &AfterCvTacticalAI_SelectPosture);CivRegisterReplace<CivHooks::CvTacticalAI_SelectPosture>(host, &ReplaceCvTacticalAI_SelectPosture);
Code
922/// Select a posture for a specific zone923AITacticalPosture CvTacticalAI::SelectPosture(CvTacticalDominanceZone* pZone, AITacticalPosture eLastPosture)924{925 AITacticalPosture eChosenPosture = AI_TACTICAL_POSTURE_NONE;926 int iDominancePercentage = GC.getGame().GetTacticalAnalysisMap()->GetDominancePercentage();927 eTacticalDominanceFlags eRangedDominance = TACTICAL_DOMINANCE_EVEN;928 eTacticalDominanceFlags eUnitCountDominance = TACTICAL_DOMINANCE_EVEN;929 int iRatio;930931 // Compute who is dominant in various areas932 // Ranged strength933 if(pZone->GetEnemyRangedStrength() <= 0)934 {935 eRangedDominance = TACTICAL_DOMINANCE_FRIENDLY;936 }937 else938 {939 iRatio = (pZone->GetFriendlyRangedStrength() * 100) / pZone->GetEnemyRangedStrength();940 if(iRatio > 100 + iDominancePercentage)941 {942 eRangedDominance = TACTICAL_DOMINANCE_FRIENDLY;943 }944 else if(iRatio < 100 - iDominancePercentage)945 {946 eRangedDominance = TACTICAL_DOMINANCE_ENEMY;947 }948 }949950 // Number of units951 if(pZone->GetEnemyUnitCount() <= 0)952 {953 eUnitCountDominance = TACTICAL_DOMINANCE_FRIENDLY;954 }955 else956 {957 iRatio = (pZone->GetFriendlyUnitCount() * 100) / pZone->GetEnemyUnitCount();958 if(iRatio > 100 + iDominancePercentage)959 {960 eUnitCountDominance = TACTICAL_DOMINANCE_FRIENDLY;961 }962 else if(iRatio < 100 - iDominancePercentage)963 {964 eUnitCountDominance = TACTICAL_DOMINANCE_ENEMY;965 }966 }967968 // Choice based on whose territory this is969 switch(pZone->GetTerritoryType())970 {971 case TACTICAL_TERRITORY_ENEMY:972 {973 bool bTemporaryZone = false;974 CvCity *pClosestCity = pZone->GetClosestCity();975976 // Always push again for a few turns after each operation reaches destination977 if (pClosestCity)978 {979 bTemporaryZone = m_pPlayer->GetTacticalAI()->IsTemporaryZoneCity(pClosestCity);980 }981982 // Withdraw if enemy dominant overall or we have nothing but ranged left983 if(!bTemporaryZone && (pZone->GetDominanceFlag() == TACTICAL_DOMINANCE_ENEMY || pZone->GetFriendlyRangedUnitCount() == pZone->GetFriendlyUnitCount()))984 {985 eChosenPosture = AI_TACTICAL_POSTURE_WITHDRAW;986 }987988 // Temporary zone: want Steamroll of Surgical Strike so we close in on city989 else if (bTemporaryZone)990 {991 if (pZone->GetDominanceFlag() != TACTICAL_DOMINANCE_ENEMY)992 {993 eChosenPosture = AI_TACTICAL_POSTURE_STEAMROLL;994 }995 else996 {997 eChosenPosture = AI_TACTICAL_POSTURE_SURGICAL_CITY_STRIKE;998 }999 }10001001 // Destroy units then assault - for first time need dominance in total strength but not enemy dominance in ranged units OR just double total strength1002 else if(pZone->GetEnemyUnitCount() > 0 && pZone->GetDominanceFlag() == TACTICAL_DOMINANCE_FRIENDLY &&1003 (eRangedDominance != TACTICAL_DOMINANCE_ENEMY || pZone->GetFriendlyStrength() > pZone->GetEnemyStrength() * 2))1004 {1005 eChosenPosture = AI_TACTICAL_POSTURE_STEAMROLL;1006 }10071008 // - less stringent if continuing this from a previous turn1009 else if(eLastPosture == AI_TACTICAL_POSTURE_STEAMROLL && pZone->GetDominanceFlag() == TACTICAL_DOMINANCE_FRIENDLY && pZone->GetEnemyUnitCount() > 0)1010 {1011 eChosenPosture = AI_TACTICAL_POSTURE_STEAMROLL;1012 }10131014 // Sit and bombard - for first time need dominance in ranged strength and total unit count1015 else if(eRangedDominance == TACTICAL_DOMINANCE_FRIENDLY && eUnitCountDominance != TACTICAL_DOMINANCE_ENEMY)1016 {1017 eChosenPosture = AI_TACTICAL_POSTURE_SIT_AND_BOMBARD;1018 }10191020 // - less stringent if continuing this from a previous turn1021 else if(eLastPosture == AI_TACTICAL_POSTURE_SIT_AND_BOMBARD && eRangedDominance != TACTICAL_DOMINANCE_ENEMY && eUnitCountDominance != TACTICAL_DOMINANCE_ENEMY)1022 {1023 eChosenPosture = AI_TACTICAL_POSTURE_SIT_AND_BOMBARD;1024 }10251026 // Go right after the city - need tactical dominance1027 else if(pZone->GetDominanceFlag() == TACTICAL_DOMINANCE_FRIENDLY)1028 {1029 eChosenPosture = AI_TACTICAL_POSTURE_SURGICAL_CITY_STRIKE;1030 }10311032 // Exploit flanks - for first time need dominance in unit count1033 else if(eUnitCountDominance == TACTICAL_DOMINANCE_FRIENDLY && pZone->GetEnemyUnitCount() > 1)1034 {1035 eChosenPosture = AI_TACTICAL_POSTURE_EXPLOIT_FLANKS;1036 }10371038 // - less stringent if continuing this from a previous turn1039 else if(eLastPosture == AI_TACTICAL_POSTURE_EXPLOIT_FLANKS && eUnitCountDominance != TACTICAL_DOMINANCE_ENEMY && pZone->GetEnemyUnitCount() > 1)1040 {1041 eChosenPosture = AI_TACTICAL_POSTURE_EXPLOIT_FLANKS;1042 }10431044 // Default for this zone1045 else1046 {1047 eChosenPosture = AI_TACTICAL_POSTURE_SURGICAL_CITY_STRIKE;1048 }1049 break;1050 }10511052 case TACTICAL_TERRITORY_NEUTRAL:1053 case TACTICAL_TERRITORY_NO_OWNER:1054 {1055 if(eRangedDominance == TACTICAL_DOMINANCE_FRIENDLY && eUnitCountDominance != TACTICAL_DOMINANCE_ENEMY)1056 {1057 eChosenPosture = AI_TACTICAL_POSTURE_ATTRIT_FROM_RANGE;1058 }10591060 // - less stringent if continuing this from a previous turn1061 else if(eLastPosture == AI_TACTICAL_POSTURE_ATTRIT_FROM_RANGE && eRangedDominance != TACTICAL_DOMINANCE_ENEMY)1062 {1063 eChosenPosture = AI_TACTICAL_POSTURE_ATTRIT_FROM_RANGE;1064 }10651066 // Exploit flanks - for first time need dominance in unit count1067 else if(eUnitCountDominance == TACTICAL_DOMINANCE_FRIENDLY && pZone->GetEnemyUnitCount() > 0)1068 {1069 eChosenPosture = AI_TACTICAL_POSTURE_EXPLOIT_FLANKS;1070 }10711072 // - less stringent if continuing this from a previous turn1073 else if(eLastPosture == AI_TACTICAL_POSTURE_EXPLOIT_FLANKS && eUnitCountDominance != TACTICAL_DOMINANCE_ENEMY && pZone->GetEnemyUnitCount() > 0)1074 {1075 eChosenPosture = AI_TACTICAL_POSTURE_EXPLOIT_FLANKS;1076 }10771078 // Default for this zone1079 else1080 {1081 eChosenPosture = AI_TACTICAL_POSTURE_EXPLOIT_FLANKS;1082 }1083 break;10841085 break;1086 }1087 case TACTICAL_TERRITORY_FRIENDLY:1088 {1089 if(eRangedDominance == TACTICAL_DOMINANCE_FRIENDLY && pZone->GetFriendlyRangedUnitCount() > 1)1090 {1091 eChosenPosture = AI_TACTICAL_POSTURE_ATTRIT_FROM_RANGE;1092 }10931094 // - less stringent if continuing this from a previous turn1095 else if(eLastPosture == AI_TACTICAL_POSTURE_ATTRIT_FROM_RANGE && pZone->GetFriendlyRangedUnitCount() > 1 && eRangedDominance != TACTICAL_DOMINANCE_ENEMY)1096 {1097 eChosenPosture = AI_TACTICAL_POSTURE_ATTRIT_FROM_RANGE;1098 }10991100 // Exploit flanks - for first time need dominance in unit count1101 else if(eUnitCountDominance == TACTICAL_DOMINANCE_FRIENDLY && pZone->GetEnemyUnitCount() > 0)1102 {1103 eChosenPosture = AI_TACTICAL_POSTURE_EXPLOIT_FLANKS;1104 }11051106 // - less stringent if continuing this from a previous turn1107 else if(eLastPosture == AI_TACTICAL_POSTURE_EXPLOIT_FLANKS && eUnitCountDominance != TACTICAL_DOMINANCE_ENEMY && pZone->GetEnemyUnitCount() > 0)1108 {1109 eChosenPosture = AI_TACTICAL_POSTURE_EXPLOIT_FLANKS;1110 }11111112 // Counterattack - for first time must be stronger or even with enemy having a ranged advantage1113 else if(pZone->GetDominanceFlag() == TACTICAL_DOMINANCE_FRIENDLY ||1114 pZone->GetDominanceFlag() == TACTICAL_DOMINANCE_EVEN && eRangedDominance == TACTICAL_DOMINANCE_ENEMY)1115 {1116 eChosenPosture = AI_TACTICAL_POSTURE_COUNTERATTACK;1117 }11181119 // - less stringent if continuing this from a previous turn1120 else if(eLastPosture == AI_TACTICAL_POSTURE_COUNTERATTACK && pZone->GetDominanceFlag() != TACTICAL_DOMINANCE_ENEMY)1121 {1122 eChosenPosture = AI_TACTICAL_POSTURE_COUNTERATTACK;1123 }11241125 // Default for this zone1126 else1127 {1128 eChosenPosture = AI_TACTICAL_POSTURE_HEDGEHOG;1129 }1130 break;1131 }1132 case TACTICAL_TERRITORY_TEMP_ZONE:1133 {1134 // Land or water?1135 if(pZone->IsWater())1136 {1137 eChosenPosture = AI_TACTICAL_POSTURE_SHORE_BOMBARDMENT;1138 }1139 else1140 {1141 // Should be a barbarian camp1142 eChosenPosture = AI_TACTICAL_POSTURE_EXPLOIT_FLANKS;1143 }1144 }1145 }11461147 return eChosenPosture;1148}
Calls
- CvGame::GetTacticalAnalysisMap()
- CvGlobals::getGame()
- CvPlayer::GetTacticalAI() const
- CvTacticalAI::IsTemporaryZoneCity(CvCity *)
- CvTacticalAnalysisMap::GetDominancePercentage() const
- CvTacticalDominanceZone::GetClosestCity() const
- CvTacticalDominanceZone::GetDominanceFlag() const
- CvTacticalDominanceZone::GetEnemyRangedStrength() const
- CvTacticalDominanceZone::GetEnemyStrength() const
- CvTacticalDominanceZone::GetEnemyUnitCount() const
- CvTacticalDominanceZone::GetFriendlyRangedStrength() const
- CvTacticalDominanceZone::GetFriendlyRangedUnitCount() const
- CvTacticalDominanceZone::GetFriendlyStrength() const
- CvTacticalDominanceZone::GetFriendlyUnitCount() const
- CvTacticalDominanceZone::GetTerritoryType() const
- CvTacticalDominanceZone::IsWater() const