//------------------------------------------------------------------------------ void CvDllNetMessageHandler::ResponseResearch(PlayerTypes ePlayer, TechTypes eTech, int iDiscover, PlayerTypes ePlayerToStealFrom, bool bShift) { CvPlayerAI& kPlayer = GET_PLAYER(ePlayer); CvTeam& kTeam = GET_TEAM(kPlayer.getTeam()); // Free tech if(iDiscover > 0) { // Make sure we can research this tech for free if(kPlayer.GetPlayerTechs()->CanResearchForFree(eTech)) { kTeam.setHasTech(eTech, true, ePlayer, true, true); if(iDiscover > 1) { if(ePlayer == GC.getGame().getActivePlayer()) { kPlayer.chooseTech(iDiscover - 1); } } kPlayer.SetNumFreeTechs(max(0, iDiscover - 1)); } } // Stealing tech else if(ePlayerToStealFrom != NO_PLAYER) { // make sure we can still take a tech CvAssertMsg(kPlayer.GetEspionage()->m_aiNumTechsToStealList[ePlayerToStealFrom] > 0, "No techs to steal from player"); CvAssertMsg(kPlayer.GetEspionage()->m_aaPlayerStealableTechList[ePlayerToStealFrom].size() > 0, "No techs to be stolen from this player"); CvAssertMsg(kPlayer.GetPlayerTechs()->CanResearch(eTech), "Player can't research this technology"); CvAssertMsg(GET_TEAM(GET_PLAYER(ePlayerToStealFrom).getTeam()).GetTeamTechs()->HasTech(eTech), "ePlayerToStealFrom does not have the requested tech"); if (kPlayer.GetEspionage()->m_aiNumTechsToStealList[ePlayerToStealFrom] > 0) { kTeam.setHasTech(eTech, true, ePlayer, true, true); kPlayer.GetEspionage()->m_aiNumTechsToStealList[ePlayerToStealFrom]--; } } // Normal tech else { CvPlayerTechs* pPlayerTechs = kPlayer.GetPlayerTechs(); CvTeamTechs* pTeamTechs = kTeam.GetTeamTechs(); if(eTech == NO_TECH) { kPlayer.clearResearchQueue(); } else if(pPlayerTechs->CanEverResearch(eTech)) { if((pTeamTechs->HasTech(eTech) || pPlayerTechs->IsResearchingTech(eTech)) && !bShift) { kPlayer.clearResearchQueue(); } kPlayer.pushResearch(eTech, !bShift); } } }
//------------------------------------------------------------------------------ bool CvDllPlayer::GetCurrentResearchTech(TechTypes* pkTech, int *pkTurnsLeft) const { CvPlayerTechs* pkTechs = m_pPlayer->GetPlayerTechs(); if (pkTechs) { if (pkTech) *pkTech = pkTechs->GetCurrentResearch(); if (pkTurnsLeft) *pkTurnsLeft = pkTechs->GetResearchTurnsLeft(pkTechs->GetCurrentResearch(), false); return true; } return false; }
void CvAdvisorRecommender::UpdateTechRecommendations (PlayerTypes ePlayer) { ResetTechs(); CvPlayerTechs* pPlayerTechs = GET_PLAYER(ePlayer).GetPlayerTechs(); CvTechAI* pPlayerTechAI = pPlayerTechs->GetTechAI(); RandomNumberDelegate fcn; int iTechLoop; // Use the synchronous random number generate // Asynchronous one would be: fcn = MakeDelegate (&GC.getGame(), &CvGame::getAsyncRandNum); //fcn = MakeDelegate (&GC.getGame(), &CvGame::getJonRandNum); // Loop through adding the researchable techs for (iTechLoop = 0; iTechLoop < pPlayerTechs->GetTechs()->GetNumTechs(); iTechLoop++) { TechTypes eTech = (TechTypes)iTechLoop; if (pPlayerTechs->CanResearch(eTech)) { m_aResearchableTechs.push_back (iTechLoop, pPlayerTechAI->GetWeight(eTech)); } } // weigh by cost for (int iI = 0; iI < m_aResearchableTechs.size(); iI++) { TechTypes eTech = (TechTypes) m_aResearchableTechs.GetElement(iI); int iTurnsLeft = 0; iTurnsLeft = pPlayerTechs->GetResearchTurnsLeft(eTech, true); double fWeightDivisor; // 10 turns will add 0.02; 80 turns will add 0.16 double fAdditionalTurnCostFactor = GC.getAI_RESEARCH_WEIGHT_MOD_PER_TURN_LEFT() * iTurnsLeft; // 0.015 double fTotalCostFactor = GC.getAI_RESEARCH_WEIGHT_BASE_MOD() + fAdditionalTurnCostFactor; // 0.15 fWeightDivisor = pow((double) iTurnsLeft, fTotalCostFactor); // if the tech is free, then we don't want inverse the weighting. More expensive techs = better. int iNewWeight = 0; if (GET_PLAYER(ePlayer).GetNumFreeTechs() == 0) { iNewWeight = int(double(m_aResearchableTechs.GetWeight(iI)) / fWeightDivisor); } else { iNewWeight = m_aResearchableTechs.GetWeight(iI) * max(iTurnsLeft / 2, 1); } // Now actually change the weight m_aResearchableTechs.SetWeight(iI, iNewWeight); } m_aResearchableTechs.SortItems(); // move techs into final round! for (int i = 0; i < NUM_ADVISOR_TYPES; i++) { // if index is out of bounds if (i >= m_aResearchableTechs.size()) { break; } m_aFinalRoundTechs.push_back(m_aResearchableTechs.GetElement(i), m_aResearchableTechs.GetWeight(i)); } for (int i = 0; i < m_aFinalRoundTechs.size(); i++) { m_aFinalRoundTechs.SortItems(); TechTypes eTech = (TechTypes)m_aFinalRoundTechs.GetElement(0); int iScore = m_aFinalRoundTechs.GetWeight(0); AdvisorTypes eAvailableAdvisor = FindUnassignedAdvisorForTech(ePlayer, eTech); if (eAvailableAdvisor != NO_ADVISOR_TYPE) { m_aRecommendedTechs[eAvailableAdvisor] = eTech; } m_aFinalRoundTechs.SetWeight(0, iScore / 2); } }