Hooks
static bool BeforeCvTacticalAI_PlotDamageCityMoves(CvTacticalAI* self, bool& result);static void AfterCvTacticalAI_PlotDamageCityMoves(CvTacticalAI* self, bool& result);static bool ReplaceCvTacticalAI_PlotDamageCityMoves(bool (*original)(CvTacticalAI*), CvTacticalAI* self);CivRegisterBefore<CivHooks::CvTacticalAI_PlotDamageCityMoves>(host, &BeforeCvTacticalAI_PlotDamageCityMoves);CivRegisterAfter<CivHooks::CvTacticalAI_PlotDamageCityMoves>(host, &AfterCvTacticalAI_PlotDamageCityMoves);CivRegisterReplace<CivHooks::CvTacticalAI_PlotDamageCityMoves>(host, &ReplaceCvTacticalAI_PlotDamageCityMoves);
Code
2144/// Assign a group of units to take down each city we can capture2145bool CvTacticalAI::PlotDamageCityMoves()2146{2147 int iRequiredDamage;2148 bool bAttackMade = false;2149 bool bLog = GC.getLogging() && GC.getAILogging();21502151 // See how many moves of this type we can execute2152 CvTacticalTarget* pTarget;2153 pTarget = GetFirstZoneTarget(AI_TACTICAL_TARGET_CITY);2154 while(pTarget != NULL)2155 {2156 // See what units we have who can reach target this turn2157 CvPlot* pPlot = GC.getMap().plot(pTarget->GetTargetX(), pTarget->GetTargetY());2158 if(pPlot != NULL)2159 {2160 m_CurrentMoveCities.clear();21612162#if defined(MOD_AI_SMART_V3)2163 if (MOD_AI_SMART_V3)2164 {2165 CvCity* pCity = pPlot->getPlotCity();21662167 if(pCity != NULL)2168 {2169 //If don't have units nearby to actually conquer, and bad dominance flag, get out.2170 if(!FindUnitsWithinStrikingDistance(pPlot, 2, 0, true /*bNoRangedUnits*/, false /*bNavalOnly*/, false /*bMustMoveThrough*/, true /*bIncludeBlockedUnits*/))2171 {2172 CvTacticalDominanceZone* pZone;2173 pZone = m_pMap->GetZoneByCity(pCity, false);2174 if (pZone != NULL)2175 {2176 if (pZone->GetDominanceFlag() == TACTICAL_DOMINANCE_ENEMY)2177 {2178 return bAttackMade;2179 }2180 if(bLog)2181 {2182 CvString strLogString;2183 strLogString = "PlotDamageCityMoves: Not damaging city because Bad dominance and no units able to take city near."; 2184 LogTacticalMessage(strLogString);2185 }2186 }2187 else2188 {2189 return bAttackMade;2190 }2191 }21922193 iRequiredDamage = pCity->GetMaxHitPoints() - pCity->getDamage();2194 pTarget->SetAuxIntData(iRequiredDamage);2195 //AMS: If we have the city already down to minimum, don't use ranged... Only try to capture.2196 bool bSelectNoRanged = (iRequiredDamage <= 1);21972198 if(bLog)2199 {2200 CvString strLogString;2201 strLogString.Format("City is at 1HP at X: %d, Y: %d", pPlot->getX(), pPlot->getY());2202 LogTacticalMessage(strLogString);2203 }22042205 if(FindUnitsWithinStrikingDistance(pPlot, 1, 0, bSelectNoRanged /*bNoRangedUnits*/, false /*bNavalOnly*/, false /*bMustMoveThrough*/, true /*bIncludeBlockedUnits*/))2206 {2207 // Don't want to hammer away to try and take down a city for more than 8 turns2208 if(ComputeTotalExpectedDamage(pTarget, pPlot) > (iRequiredDamage / 8))2209 {2210 // Log result2211 if(bLog)2212 {2213 CvString strPlayerName, strCityName, strLogString, strTemp;2214 strPlayerName = GET_PLAYER(pCity->getOwner()).getCivilizationShortDescription();2215 strCityName = pCity->getName();2216 strLogString.Format("Attacking city of ");2217 strLogString += strCityName;2218 strTemp.Format(" to damage, X: %d, Y: %d,", pCity->getX(), pCity->getY());2219 strLogString += strTemp + strPlayerName;2220 LogTacticalMessage(strLogString);2221 }22222223 // If so, execute enough moves to take it2224 ExecuteAttack(pTarget, pPlot, false, true);2225 bAttackMade = true;2226 }2227 }2228 }2229 }2230 else2231 {2232#endif2233 if(FindUnitsWithinStrikingDistance(pPlot, 1, 0, false /*bNoRangedUnits*/, false /*bNavalOnly*/, false /*bMustMoveThrough*/, true /*bIncludeBlockedUnits*/))2234 {2235 CvCity* pCity = pPlot->getPlotCity();2236 if(pCity != NULL)2237 {2238 iRequiredDamage = pCity->GetMaxHitPoints() - pCity->getDamage();2239 pTarget->SetAuxIntData(iRequiredDamage);22402241 // Don't want to hammer away to try and take down a city for more than 8 turns2242 if(ComputeTotalExpectedDamage(pTarget, pPlot) > (iRequiredDamage / 8))2243 {2244 // Log result2245 if(bLog)2246 {2247 CvString strPlayerName, strCityName, strLogString, strTemp;2248 strPlayerName = GET_PLAYER(pCity->getOwner()).getCivilizationShortDescription();2249 strCityName = pCity->getName();2250 strLogString.Format("Attacking city of ");2251 strLogString += strCityName;2252 strTemp.Format(" to damage, X: %d, Y: %d,", pCity->getX(), pCity->getY());2253 strLogString += strTemp + strPlayerName;2254 LogTacticalMessage(strLogString);2255 }22562257 // If so, execute enough moves to take it2258 ExecuteAttack(pTarget, pPlot, false, true);2259 bAttackMade = true;2260 }2261 }2262 }2263#if defined(MOD_AI_SMART_V3)2264 }2265#endif2266 }2267 pTarget = GetNextZoneTarget();2268 }2269 return bAttackMade;2270}