Hooks
static bool BeforeCvPolicyAI_ChooseNextPolicy(CvPolicyAI* self, CvPlayer* pPlayer, int& result);static void AfterCvPolicyAI_ChooseNextPolicy(CvPolicyAI* self, CvPlayer* pPlayer, int& result);static int ReplaceCvPolicyAI_ChooseNextPolicy(int (*original)(CvPolicyAI*, CvPlayer*), CvPolicyAI* self, CvPlayer* pPlayer);CivRegisterBefore<CivHooks::CvPolicyAI_ChooseNextPolicy>(host, &BeforeCvPolicyAI_ChooseNextPolicy);CivRegisterAfter<CivHooks::CvPolicyAI_ChooseNextPolicy>(host, &AfterCvPolicyAI_ChooseNextPolicy);CivRegisterReplace<CivHooks::CvPolicyAI_ChooseNextPolicy>(host, &ReplaceCvPolicyAI_ChooseNextPolicy);
Code
145/// Choose a player's next policy purchase (could be opening a branch)146int CvPolicyAI::ChooseNextPolicy(CvPlayer* pPlayer)147{148 RandomNumberDelegate fcn;149 fcn = MakeDelegate(&GC.getGame(), &CvGame::getJonRandNum);150 int iRtnValue = (int)NO_POLICY;151 int iPolicyLoop;152 vector<int> aLevel3Tenets;153154 bool bMustChooseTenet = (pPlayer->GetNumFreeTenets() > 0);155156 // Create a new vector holding only policies we can currently adopt157 m_AdoptablePolicies.clear();158159 // Loop through adding the adoptable policies160 for(iPolicyLoop = 0; iPolicyLoop < m_pCurrentPolicies->GetPolicies()->GetNumPolicies(); iPolicyLoop++)161 {162 if(m_pCurrentPolicies->CanAdoptPolicy((PolicyTypes) iPolicyLoop) && (!bMustChooseTenet || m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetLevel() > 0))163 {164 int iWeight = 0;165166 iWeight += m_PolicyAIWeights.GetWeight(iPolicyLoop);167168 // Does this policy finish a branch for us?169 if(m_pCurrentPolicies->WillFinishBranchIfAdopted((PolicyTypes) iPolicyLoop))170 {171 int iPolicyBranch = m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetPolicyBranchType();172 if(iPolicyBranch != NO_POLICY_BRANCH_TYPE)173 {174 int iFinisherPolicy = m_pCurrentPolicies->GetPolicies()->GetPolicyBranchEntry(iPolicyBranch)->GetFreeFinishingPolicy();175 if(iFinisherPolicy != NO_POLICY)176 {177 iWeight += m_PolicyAIWeights.GetWeight(iFinisherPolicy);178 }179 }180 }181 m_AdoptablePolicies.push_back(iPolicyLoop + GC.getNumPolicyBranchInfos(), iWeight);182183 if (m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetLevel() == 3)184 {185 aLevel3Tenets.push_back(iPolicyLoop);186 }187 }188 }189190 // Did we already start a branch in the set that is mutually exclusive?191 bool bStartedAMutuallyExclusiveBranch = false;192 for(int iBranchLoop = 0; iBranchLoop < GC.getNumPolicyBranchInfos(); iBranchLoop++)193 {194 const PolicyBranchTypes ePolicyBranch = static_cast<PolicyBranchTypes>(iBranchLoop);195 CvPolicyBranchEntry* pkPolicyBranchInfo = GC.getPolicyBranchInfo(ePolicyBranch);196 if(pkPolicyBranchInfo)197 {198 if(pPlayer->GetPlayerPolicies()->IsPolicyBranchUnlocked(ePolicyBranch))199 {200 if(pkPolicyBranchInfo->IsMutuallyExclusive())201 {202 bStartedAMutuallyExclusiveBranch = true;203 }204 }205 }206 }207208 AIGrandStrategyTypes eCultureGrandStrategy = (AIGrandStrategyTypes) GC.getInfoTypeForString("AIGRANDSTRATEGY_CULTURE");209 AIGrandStrategyTypes eCurrentGrandStrategy = pPlayer->GetGrandStrategyAI()->GetActiveGrandStrategy();210211 // Loop though the branches adding each as another possibility212 if (!bMustChooseTenet)213 {214 for(int iBranchLoop = 0; iBranchLoop < GC.getNumPolicyBranchInfos(); iBranchLoop++)215 {216 const PolicyBranchTypes ePolicyBranch = static_cast<PolicyBranchTypes>(iBranchLoop);217 CvPolicyBranchEntry* pkPolicyBranchInfo = GC.getPolicyBranchInfo(ePolicyBranch);218 if(pkPolicyBranchInfo)219 {220 if(bStartedAMutuallyExclusiveBranch && pkPolicyBranchInfo->IsMutuallyExclusive())221 {222 continue;223 }224225 if(pPlayer->GetPlayerPolicies()->CanUnlockPolicyBranch(ePolicyBranch) && !pPlayer->GetPlayerPolicies()->IsPolicyBranchUnlocked(ePolicyBranch))226 {227 int iBranchWeight = 0;228229 // Does this branch actually help us, based on game options?230 if(IsBranchEffectiveInGame(ePolicyBranch))231 {232 iBranchWeight += WeighBranch(ePolicyBranch);233234 iBranchWeight *= (100 - m_iPolicyWeightPercentDropNewBranch);235 iBranchWeight /= 100;236#if defined(MOD_AI_SMART_V3)237 if (MOD_AI_SMART_V3 && !pPlayer->GetPlayerPolicies()->IsEraPrereqBranch(ePolicyBranch))238 {239 iBranchWeight *= 80;240 iBranchWeight /= 100;241 }242#endif243 if(eCurrentGrandStrategy == eCultureGrandStrategy)244 {245 iBranchWeight /= 3;246 }247 }248249 m_AdoptablePolicies.push_back(iBranchLoop, iBranchWeight);250 }251 }252 }253 }254255 m_AdoptablePolicies.SortItems();256 LogPossiblePolicies();257258 // If there were any Level 3 tenets found, consider going for the one that matches our victory strategy259 if (aLevel3Tenets.size() > 0)260 {261 vector<int>::const_iterator it;262 for (it = aLevel3Tenets.begin(); it != aLevel3Tenets.end(); it++)263 {264 CvPolicyEntry *pEntry;265 pEntry = m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(*it);266 if (pEntry)267 {268 AIGrandStrategyTypes eGrandStrategy = pPlayer->GetGrandStrategyAI()->GetActiveGrandStrategy();269 if (eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_CONQUEST"))270 {271 if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_OFFENSE")) > 0)272 {273 LogPolicyChoice((PolicyTypes)*it);274 return (*it) + GC.getNumPolicyBranchInfos();275 }276 }277 else if(eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_SPACESHIP"))278 {279 if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_SPACESHIP")) > 0)280 {281 LogPolicyChoice((PolicyTypes)*it);282 return (*it) + GC.getNumPolicyBranchInfos();283 }284 }285 else if(eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_UNITED_NATIONS"))286 {287 if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_DIPLOMACY")) > 0)288 {289 LogPolicyChoice((PolicyTypes)*it);290 return (*it) + GC.getNumPolicyBranchInfos();291 }292 }293 else if(eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_CULTURE"))294 {295 if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_CULTURE")) > 0)296 {297 LogPolicyChoice((PolicyTypes)*it);298 return (*it) + GC.getNumPolicyBranchInfos();299 }300 }301 }302 }303 }304305 CvAssertMsg(m_AdoptablePolicies.GetTotalWeight() >= 0, "Total weights of considered policies should not be negative! Please send Anton your save file and version.");306307 // If total weight is above 0, choose one above a threshold308 if(m_AdoptablePolicies.GetTotalWeight() > 0)309 {310 int iNumChoices = GC.getGame().getHandicapInfo().GetPolicyNumOptions();311 iRtnValue = m_AdoptablePolicies.ChooseFromTopChoices(iNumChoices, &fcn, "Choosing policy from Top Choices");312 }313 // Total weight may be 0 if the only branches and policies left are ones that are ineffective in our game, but we gotta pick something314 else if(m_AdoptablePolicies.GetTotalWeight() == 0 && m_AdoptablePolicies.size() > 0)315 {316 iRtnValue = m_AdoptablePolicies.ChooseAtRandom(&fcn, "Choosing policy at random (no good choices)");317 }318319 // Log our choice320 if(iRtnValue != (int)NO_POLICY)321 {322 if(iRtnValue >= GC.getNumPolicyBranchInfos())323 {324 LogPolicyChoice((PolicyTypes)(iRtnValue - GC.getNumPolicyBranchInfos()));325 }326 else327 {328 LogBranchChoice((PolicyBranchTypes)iRtnValue);329 }330 }331332 return iRtnValue;333}