Hooks
static bool BeforeCvTeamTechs_SetResearchProgressTimes100(CvTeamTechs* self, TechTypes eIndex, int iNewValue, PlayerTypes ePlayer, int iPlayerOverflow, int iPlayerOverflowDivisorTimes100);static void AfterCvTeamTechs_SetResearchProgressTimes100(CvTeamTechs* self, TechTypes eIndex, int iNewValue, PlayerTypes ePlayer, int iPlayerOverflow, int iPlayerOverflowDivisorTimes100);static void ReplaceCvTeamTechs_SetResearchProgressTimes100(void (*original)(CvTeamTechs*, TechTypes, int, PlayerTypes, int, int), CvTeamTechs* self, TechTypes eIndex, int iNewValue, PlayerTypes ePlayer, int iPlayerOverflow, int iPlayerOverflowDivisorTimes100);CivRegisterBefore<CivHooks::CvTeamTechs_SetResearchProgressTimes100>(host, &BeforeCvTeamTechs_SetResearchProgressTimes100);CivRegisterAfter<CivHooks::CvTeamTechs_SetResearchProgressTimes100>(host, &AfterCvTeamTechs_SetResearchProgressTimes100);CivRegisterReplace<CivHooks::CvTeamTechs_SetResearchProgressTimes100>(host, &ReplaceCvTeamTechs_SetResearchProgressTimes100);
Code
2058/// Accessor: set research done on one tech (in hundredths)2059#if defined(MOD_BUGFIX_RESEARCH_OVERFLOW)2060void CvTeamTechs::SetResearchProgressTimes100(TechTypes eIndex, int iNewValue, PlayerTypes ePlayer, int iPlayerOverflow, int iPlayerOverflowDivisorTimes100)2061#else2062void CvTeamTechs::SetResearchProgressTimes100(TechTypes eIndex, int iNewValue, PlayerTypes ePlayer)2063#endif2064{2065 CvAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");2066 CvAssertMsg(eIndex < GC.getNumTechInfos(), "eIndex is expected to be within maximum bounds (invalid Index)");2067 CvAssertMsg(ePlayer >= 0, "eIndex is expected to be non-negative (invalid Index)");2068 CvAssertMsg(ePlayer < MAX_PLAYERS, "ePlayer is expected to be within maximum bounds (invalid Index)");20692070 if(GetResearchProgressTimes100(eIndex) != iNewValue)2071 {2072 m_paiResearchProgress[eIndex] = iNewValue;2073 CvAssert(GetResearchProgressTimes100(eIndex) >= 0);20742075 if(m_pTeam->GetID() == GC.getGame().getActiveTeam())2076 {2077 GC.GetEngineUserInterface()->setDirty(GameData_DIRTY_BIT, true);2078 GC.GetEngineUserInterface()->setDirty(Score_DIRTY_BIT, true);2079 }20802081#if defined(MOD_BUGFIX_RESEARCH_NAN)2082 long long iResearchProgress = GetResearchProgressTimes100(eIndex);2083 long long iResearchCost = GetResearchCost(eIndex) * 100;2084#else2085 int iResearchProgress = GetResearchProgressTimes100(eIndex);2086 int iResearchCost = GetResearchCost(eIndex) * 100;2087#endif20882089 // Player modifiers to cost2090 int iResearchMod = std::max(1, GET_PLAYER(ePlayer).calculateResearchModifier(eIndex));2091 iResearchCost = (iResearchCost * 100) / iResearchMod;2092 int iNumCitiesMod = GC.getMap().getWorldInfo().GetNumCitiesTechCostMod(); // Default is 40, gets smaller on larger maps2093 iNumCitiesMod = iNumCitiesMod * GET_PLAYER(ePlayer).GetMaxEffectiveCities(/*bIncludePuppets*/ true);2094 iResearchCost = iResearchCost * (100 + iNumCitiesMod) / 100;2095 2096#if defined(MOD_BUGFIX_RESEARCH_NAN)2097 int iOverflow = (int) (iResearchProgress - iResearchCost);2098#else2099 int iOverflow = iResearchProgress - iResearchCost;2100#endif21012102#if defined(MOD_BUGFIX_RESEARCH_OVERFLOW)2103 if (!MOD_BUGFIX_RESEARCH_OVERFLOW) {2104#endif2105 // April 2014 Balance Patch change - EFB2106 // Don't allow the overflow to get out of hand2107 int iMaxOverflow = GetMaxResearchOverflow(eIndex, ePlayer);2108 if (iOverflow > iMaxOverflow)2109 {2110 iOverflow = iMaxOverflow;2111 }2112#if defined(MOD_BUGFIX_RESEARCH_OVERFLOW)2113 }2114#endif21152116 if(iOverflow >= 0)2117 {2118#if defined(MOD_BUGFIX_RESEARCH_OVERFLOW)2119 if (MOD_BUGFIX_RESEARCH_OVERFLOW) {2120 // iNewValue = iPlayerBeakersThisTurn + ((iPlayerOverflow * iPlayerOverflowDivisorTimes100) / 100)2121 if (iOverflow > iPlayerOverflow) {2122 // If we completed the tech using only iBeakersThisTurn, we need to hand back the remaining iPlayerBeakersThisTurn and the scaled down iPlayerOverflow2123 iOverflow = (iOverflow - iPlayerOverflow) + (iPlayerOverflow * 100 / iPlayerOverflowDivisorTimes100); 2124 } else {2125 // Otherwise we used all of iBeakersThisTurn and some of iPlayerOverflow, so we need to hand back the scaled down iOverflow2126 iOverflow = iOverflow * 100 / iPlayerOverflowDivisorTimes100;2127 }2128 }2129#endif2130 GET_PLAYER(ePlayer).changeOverflowResearchTimes100(iOverflow);2131 m_pTeam->setHasTech(eIndex, true, ePlayer, true, true);2132 SetNoTradeTech(eIndex, true);21332134 // Mark city specialization dirty2135 GET_PLAYER(ePlayer).GetCitySpecializationAI()->SetSpecializationsDirty(SPECIALIZATION_UPDATE_RESEARCH_COMPLETE);21362137 // Culture bonus for Player researching a Tech2138 PlayerTypes eLoopPlayer;2139 int iCulture;2140 TeamTypes eTeamID = m_pTeam->GetID();2141 for(int iPlayerLoop = 0; iPlayerLoop < MAX_MAJOR_CIVS; iPlayerLoop++)2142 {2143 eLoopPlayer = (PlayerTypes) iPlayerLoop;2144 CvPlayerAI& kLoopPlayer = GET_PLAYER(eLoopPlayer);21452146 if(kLoopPlayer.getTeam() == eTeamID)2147 {2148 iCulture = kLoopPlayer.GetCulturePerTechResearched();2149 if(iCulture != 0)2150 {2151 kLoopPlayer.changeJONSCulture(iCulture);2152 }2153 }2154 }2155 }2156 }2157}