Hooks
static bool BeforeCvAdvisorRecommender_UpdateTechRecommendations(CvAdvisorRecommender* self, PlayerTypes ePlayer);static void AfterCvAdvisorRecommender_UpdateTechRecommendations(CvAdvisorRecommender* self, PlayerTypes ePlayer);static void ReplaceCvAdvisorRecommender_UpdateTechRecommendations(void (*original)(CvAdvisorRecommender*, PlayerTypes), CvAdvisorRecommender* self, PlayerTypes ePlayer);CivRegisterBefore<CivHooks::CvAdvisorRecommender_UpdateTechRecommendations>(host, &BeforeCvAdvisorRecommender_UpdateTechRecommendations);CivRegisterAfter<CivHooks::CvAdvisorRecommender_UpdateTechRecommendations>(host, &AfterCvAdvisorRecommender_UpdateTechRecommendations);CivRegisterReplace<CivHooks::CvAdvisorRecommender_UpdateTechRecommendations>(host, &ReplaceCvAdvisorRecommender_UpdateTechRecommendations);
Code
201void CvAdvisorRecommender::UpdateTechRecommendations(PlayerTypes ePlayer)202{203 ResetTechs();204 CvPlayerTechs* pPlayerTechs = GET_PLAYER(ePlayer).GetPlayerTechs();205 CvTechAI* pPlayerTechAI = pPlayerTechs->GetTechAI();206207 RandomNumberDelegate fcn;208 int iTechLoop;209210 // Use the synchronous random number generate211 // Asynchronous one would be:212 fcn = MakeDelegate(&GC.getGame(), &CvGame::getAsyncRandNum);213 //fcn = MakeDelegate (&GC.getGame(), &CvGame::getJonRandNum);214215 // Loop through adding the researchable techs216 for(iTechLoop = 0; iTechLoop < pPlayerTechs->GetTechs()->GetNumTechs(); iTechLoop++)217 {218 TechTypes eTech = (TechTypes)iTechLoop;219 if(pPlayerTechs->CanResearch(eTech))220 {221 m_aResearchableTechs.push_back(iTechLoop, pPlayerTechAI->GetWeight(eTech));222 }223 }224225 // weigh by cost226 for(int iI = 0; iI < m_aResearchableTechs.size(); iI++)227 {228 TechTypes eTech = (TechTypes) m_aResearchableTechs.GetElement(iI);229 int iTurnsLeft = 0;230231 iTurnsLeft = pPlayerTechs->GetResearchTurnsLeft(eTech, true);232233 double fWeightDivisor;234235 // 10 turns will add 0.02; 80 turns will add 0.16236 double fAdditionalTurnCostFactor = GC.getAI_RESEARCH_WEIGHT_MOD_PER_TURN_LEFT() * iTurnsLeft; // 0.015237 double fTotalCostFactor = GC.getAI_RESEARCH_WEIGHT_BASE_MOD() + fAdditionalTurnCostFactor; // 0.15238239 fWeightDivisor = pow((double) iTurnsLeft, fTotalCostFactor);240241 // if the tech is free, then we don't want inverse the weighting. More expensive techs = better.242 int iNewWeight = 0;243 if(GET_PLAYER(ePlayer).GetNumFreeTechs() == 0)244 {245 iNewWeight = int(double(m_aResearchableTechs.GetWeight(iI)) / fWeightDivisor);246 }247 else248 {249 iNewWeight = m_aResearchableTechs.GetWeight(iI) * max(iTurnsLeft / 2, 1);250 }251252 // Now actually change the weight253 m_aResearchableTechs.SetWeight(iI, iNewWeight);254 }255256 m_aResearchableTechs.SortItems();257258 // move techs into final round!259 for(int i = 0; i < NUM_ADVISOR_TYPES; i++)260 {261 // if index is out of bounds262 if(i >= m_aResearchableTechs.size())263 {264 break;265 }266267 m_aFinalRoundTechs.push_back(m_aResearchableTechs.GetElement(i), m_aResearchableTechs.GetWeight(i));268 }269270 for(int i = 0; i < m_aFinalRoundTechs.size(); i++)271 {272 m_aFinalRoundTechs.SortItems();273274 TechTypes eTech = (TechTypes)m_aFinalRoundTechs.GetElement(0);275 int iScore = m_aFinalRoundTechs.GetWeight(0);276277 AdvisorTypes eAvailableAdvisor = FindUnassignedAdvisorForTech(ePlayer, eTech);278 if(eAvailableAdvisor != NO_ADVISOR_TYPE)279 {280 m_aRecommendedTechs[eAvailableAdvisor] = eTech;281 }282283 m_aFinalRoundTechs.SetWeight(0, iScore / 2);284 }285}