Hooks
static bool BeforeCvTacticalAI_PlotCaptureCityMoves(CvTacticalAI* self, bool& result);static void AfterCvTacticalAI_PlotCaptureCityMoves(CvTacticalAI* self, bool& result);static bool ReplaceCvTacticalAI_PlotCaptureCityMoves(bool (*original)(CvTacticalAI*), CvTacticalAI* self);CivRegisterBefore<CivHooks::CvTacticalAI_PlotCaptureCityMoves>(host, &BeforeCvTacticalAI_PlotCaptureCityMoves);CivRegisterAfter<CivHooks::CvTacticalAI_PlotCaptureCityMoves>(host, &AfterCvTacticalAI_PlotCaptureCityMoves);CivRegisterReplace<CivHooks::CvTacticalAI_PlotCaptureCityMoves>(host, &ReplaceCvTacticalAI_PlotCaptureCityMoves);
Code
2017/// Assign a group of units to take down each city we can capture2018bool CvTacticalAI::PlotCaptureCityMoves()2019{2020 int iRequiredDamage;2021 bool bAttackMade = false;2022 bool bLog = GC.getLogging() && GC.getAILogging();20232024 // See how many moves of this type we can execute2025 CvTacticalTarget* pTarget;2026 pTarget = GetFirstZoneTarget(AI_TACTICAL_TARGET_CITY);2027 while(pTarget != NULL)2028 {2029 // See what units we have who can reach target this turn2030 CvPlot* pPlot = GC.getMap().plot(pTarget->GetTargetX(), pTarget->GetTargetY());2031 if(pPlot != NULL)2032 {2033 m_CurrentMoveCities.clear();20342035#if defined(MOD_AI_SMART_V3)2036 if (MOD_AI_SMART_V3)2037 {2038 CvCity* pCity = pPlot->getPlotCity();2039 2040 if(pCity != NULL)2041 {2042 //If don't have units to actually conquer, get out.2043 if(!FindUnitsWithinStrikingDistance(pPlot, 1, 0, true /*bNoRangedUnits*/, false /*bNavalOnly*/, false /*bMustMoveThrough*/, true /*bIncludeBlockedUnits*/))2044 {2045 if(bLog)2046 {2047 CvString strLogString;2048 strLogString = "PlotCaptureCityMoves: Not attacking city because are no units able to take city near."; 2049 LogTacticalMessage(strLogString);2050 }2051 return bAttackMade;2052 }20532054 // Do we have enough firepower to destroy it?2055 iRequiredDamage = pCity->GetMaxHitPoints() - pCity->getDamage();2056 pTarget->SetAuxIntData(iRequiredDamage);2057 //AMS: If we have the city already down to minimum, don't use ranged... Only try to capture.2058 bool bSelectNoRanged = (iRequiredDamage <= 1);20592060 if(bLog && bSelectNoRanged)2061 {2062 CvString strLogString;2063 strLogString.Format("City is at 1HP at X: %d, Y: %d", pPlot->getX(), pPlot->getY());2064 LogTacticalMessage(strLogString);2065 }20662067 if(FindUnitsWithinStrikingDistance(pPlot, 1, 0, bSelectNoRanged /*bNoRangedUnits*/, false /*bNavalOnly*/, false /*bMustMoveThrough*/, true /*bIncludeBlockedUnits*/))2068 {2069 if(ComputeTotalExpectedDamage(pTarget, pPlot) >= (iRequiredDamage / 2)) // risky2070 {2071 // Log result2072 if(bLog)2073 {2074 CvString strPlayerName, strCityName, strLogString, strTemp;2075 strPlayerName = GET_PLAYER(pCity->getOwner()).getCivilizationShortDescription();2076 strCityName = pCity->getName();2077 strLogString.Format("Attacking city of ");2078 strLogString += strCityName;2079 strTemp.Format(" to capture, X: %d, Y: %d,", pCity->getX(), pCity->getY());2080 strLogString += strTemp + strPlayerName;2081 LogTacticalMessage(strLogString);2082 }20832084 // If so, execute enough moves to take it2085 ExecuteAttack(pTarget, pPlot, false, false);2086 bAttackMade = true;20872088 // Did it work? If so, don't need a temporary dominance zone if had one here2089 if(pPlot->getOwner() == m_pPlayer->GetID())2090 {2091 DeleteTemporaryZone(pPlot);2092 }2093 }2094 }2095 }2096 }2097 else2098 {2099#endif2100 if(FindUnitsWithinStrikingDistance(pPlot, 1, 0, false /*bNoRangedUnits*/, false /*bNavalOnly*/, false /*bMustMoveThrough*/, true /*bIncludeBlockedUnits*/))2101 {2102 // Do we have enough firepower to destroy it?2103 CvCity* pCity = pPlot->getPlotCity();2104 if(pCity != NULL)2105 {2106 iRequiredDamage = pCity->GetMaxHitPoints() - pCity->getDamage();2107 pTarget->SetAuxIntData(iRequiredDamage);2108 if(ComputeTotalExpectedDamage(pTarget, pPlot) >= (iRequiredDamage / 2)) // risky2109 {2110 // Log result2111 if(bLog)2112 {2113 CvString strPlayerName, strCityName, strLogString, strTemp;2114 strPlayerName = GET_PLAYER(pCity->getOwner()).getCivilizationShortDescription();2115 strCityName = pCity->getName();2116 strLogString.Format("Attacking city of ");2117 strLogString += strCityName;2118 strTemp.Format(" to capture, X: %d, Y: %d,", pCity->getX(), pCity->getY());2119 strLogString += strTemp + strPlayerName;2120 LogTacticalMessage(strLogString);2121 }21222123 // If so, execute enough moves to take it2124 ExecuteAttack(pTarget, pPlot, false, false);2125 bAttackMade = true;21262127 // Did it work? If so, don't need a temporary dominance zone if had one here2128 if(pPlot->getOwner() == m_pPlayer->GetID())2129 {2130 DeleteTemporaryZone(pPlot);2131 }2132 }2133 }2134 }2135#if defined(MOD_AI_SMART_V3)2136 }2137#endif2138 }2139 pTarget = GetNextZoneTarget();2140 }2141 return bAttackMade;2142}