Hooks
static bool BeforeCvUnit_changeExperienceTimes100(CvUnit* self, int iChangeTimes100, int iMax, bool bFromCombat, bool bInBorders, bool bUpdateGlobal);static void AfterCvUnit_changeExperienceTimes100(CvUnit* self, int iChangeTimes100, int iMax, bool bFromCombat, bool bInBorders, bool bUpdateGlobal);static void ReplaceCvUnit_changeExperienceTimes100(void (*original)(CvUnit*, int, int, bool, bool, bool), CvUnit* self, int iChangeTimes100, int iMax, bool bFromCombat, bool bInBorders, bool bUpdateGlobal);CivRegisterBefore<CivHooks::CvUnit_changeExperienceTimes100>(host, &BeforeCvUnit_changeExperienceTimes100);CivRegisterAfter<CivHooks::CvUnit_changeExperienceTimes100>(host, &AfterCvUnit_changeExperienceTimes100);CivRegisterReplace<CivHooks::CvUnit_changeExperienceTimes100>(host, &ReplaceCvUnit_changeExperienceTimes100);
Code
17144#if defined(MOD_UNITS_XP_TIMES_100)17145void CvUnit::changeExperienceTimes100(int iChangeTimes100, int iMax, bool bFromCombat, bool bInBorders, bool bUpdateGlobal)17146#else17147void CvUnit::changeExperience(int iChange, int iMax, bool bFromCombat, bool bInBorders, bool bUpdateGlobal)17148#endif17149{17150 VALIDATE_OBJECT17151 // Barbs don't get XP or Promotions17152#if defined(MOD_UNITS_XP_TIMES_100)17153 if (isBarbarian() && iChangeTimes100 > 0)17154#else17155 if (isBarbarian() && iChange > 0)17156#endif17157 {17158 return;17159 }1716017161#if defined(MOD_UNITS_XP_TIMES_100)17162 // Checking limits.h for the values of MAX_INT and MAX_LONG they are the same, so we need to use "long long" and hence MAX_LLONG17163 long long lMaxTimes100 = (iMax == -1) ? INT_MAX : (iMax * 100LL);17164 int iMaxTimes100 = (lMaxTimes100 > ((long long)INT_MAX)) ? INT_MAX : (int)lMaxTimes100;17165 17166 int iUnitExperienceTimes100 = iChangeTimes100;17167#else17168 int iUnitExperience = iChange;17169#endif17170 PromotionTypes eNewPromotion = NO_PROMOTION;1717117172 if(bFromCombat)17173 {17174 CvPlayer& kPlayer = GET_PLAYER(getOwner());1717517176 // Promotion that changes after combat?17177 for (int iI = 0; iI < GC.getNumPromotionInfos(); iI++)17178 {17179 const PromotionTypes eLoopPromotion = static_cast<PromotionTypes>(iI);17180 CvPromotionEntry* pkPromotionInfo = GC.getPromotionInfo(eLoopPromotion);17181 if(pkPromotionInfo)17182 {17183 if (pkPromotionInfo->HasPostCombatPromotions() && m_Promotions.HasPromotion(eLoopPromotion))17184 {17185 eNewPromotion = m_Promotions.ChangePromotionAfterCombat(eLoopPromotion);17186 setHasPromotion(eLoopPromotion, false);1718717188 if (eNewPromotion != NO_PROMOTION)17189 {17190 setHasPromotion(eNewPromotion, true);1719117192#if defined(MOD_EVENTS_UNIT_UPGRADES)17193 if (MOD_EVENTS_UNIT_UPGRADES) {17194 GAMEEVENTINVOKE_HOOK(GAMEEVENT_UnitPromoted, getOwner(), GetID(), eNewPromotion);17195 }17196#endif1719717198 CvPromotionEntry* pkNewPromotionInfo = GC.getPromotionInfo(eNewPromotion);17199 Localization::String localizedText = Localization::Lookup(pkNewPromotionInfo->GetDescriptionKey());17200#if defined(SHOW_PLOT_POPUP)17201 SHOW_PLOT_POPUP(plot(), getOwner(), localizedText.toUTF8(), 0.0f);17202#else17203 float fDelay = GC.getPOST_COMBAT_TEXT_DELAY() * 2;17204 DLLUI->AddPopupText(getX(), getY(), localizedText.toUTF8(), fDelay);17205#endif17206 }17207 }17208 }17209 }1721017211 // Player Great General/Admiral mod17212 int iCombatExperienceMod;17213 if (getDomainType() == DOMAIN_SEA)17214 {17215 iCombatExperienceMod = 100 + kPlayer.getGreatAdmiralRateModifier();17216 }17217 else17218 {17219 iCombatExperienceMod = 100 + kPlayer.getGreatGeneralRateModifier();17220 }1722117222 // Unit XP mod17223#if defined(MOD_UNITS_XP_TIMES_100)17224 int iPlayerBonusXpTimes100 = (iChangeTimes100 * kPlayer.getExpModifier()) / 100;17225 if (!MOD_UNITS_XP_TIMES_100) {17226 // If NOT using XP times 100, remove any fractional part17227 iPlayerBonusXpTimes100 -= (iPlayerBonusXpTimes100 % 100);17228 }17229 iUnitExperienceTimes100 += iPlayerBonusXpTimes100;17230#else17231 iUnitExperience += (iChange * kPlayer.getExpModifier()) / 100;17232#endif1723317234 // Great General & Unit XP mod in borders17235 if (bInBorders && getDomainType() == DOMAIN_LAND)17236 {17237 // In-borders GG mod17238 iCombatExperienceMod += kPlayer.getDomesticGreatGeneralRateModifier() + kPlayer.getExpInBorderModifier();17239#if defined(MOD_UNITS_XP_TIMES_100)17240 int iBorderBonusXpTimes100 = (iChangeTimes100 * kPlayer.getExpInBorderModifier()) / 100;17241 if (!MOD_UNITS_XP_TIMES_100) {17242 // If NOT using XP times 100, remove any fractional part17243 iBorderBonusXpTimes100 -= (iBorderBonusXpTimes100 % 100);17244 }17245 iUnitExperienceTimes100 += iBorderBonusXpTimes100;17246#else17247 iUnitExperience += (iChange * kPlayer.getExpInBorderModifier()) / 100;17248#endif17249 }1725017251 if(bUpdateGlobal)17252 {17253 // Add Unit GG mod17254 if (getDomainType() == DOMAIN_LAND) 17255 {17256 iCombatExperienceMod += getGreatGeneralModifier();17257 }1725817259 if(iMax == -1)17260 {17261 if(getDomainType() == DOMAIN_SEA)17262 {17263#if defined(MOD_GLOBAL_LOCAL_GENERALS)17264#if defined(MOD_UNITS_XP_TIMES_100)17265 kPlayer.changeNavalCombatExperienceTimes100((iChangeTimes100 * iCombatExperienceMod) / 100, (MOD_GLOBAL_LOCAL_GENERALS ? this : NULL));17266#else17267 kPlayer.changeNavalCombatExperience((iChange * iCombatExperienceMod) / 100, (MOD_GLOBAL_LOCAL_GENERALS ? this : NULL));17268#endif17269#else17270#if defined(MOD_UNITS_XP_TIMES_100)17271 kPlayer.changeNavalCombatExperienceTimes100((iChangeTimes100 * iCombatExperienceMod) / 100);17272#else17273 kPlayer.changeNavalCombatExperience((iChange * iCombatExperienceMod) / 100);17274#endif17275#endif17276 }17277 else17278 {17279#if defined(MOD_GLOBAL_LOCAL_GENERALS)17280#if defined(MOD_UNITS_XP_TIMES_100)17281 kPlayer.changeCombatExperienceTimes100((iChangeTimes100 * iCombatExperienceMod) / 100, (MOD_GLOBAL_LOCAL_GENERALS ? this : NULL));17282#else17283 kPlayer.changeCombatExperience((iChange * iCombatExperienceMod) / 100, (MOD_GLOBAL_LOCAL_GENERALS ? this : NULL));17284#endif17285#else17286#if defined(MOD_UNITS_XP_TIMES_100)17287 kPlayer.changeCombatExperienceTimes100((iChangeTimes100 * iCombatExperienceMod) / 100);17288#else17289 kPlayer.changeCombatExperience((iChange * iCombatExperienceMod) / 100);17290#endif17291#endif17292 }17293 }17294 else17295 {17296#if defined(MOD_UNITS_XP_TIMES_100)17297 int iModdedChangeTimes100 = min(iMaxTimes100 - m_iExperienceTimes100, iChangeTimes100);17298 if (iModdedChangeTimes100 > 0)17299#else17300 int iModdedChange = min(iMax - m_iExperience, iChange);17301 if (iModdedChange > 0)17302#endif17303 {17304 if(getDomainType() == DOMAIN_SEA)17305 {17306#if defined(MOD_GLOBAL_LOCAL_GENERALS)17307#if defined(MOD_UNITS_XP_TIMES_100)17308 kPlayer.changeNavalCombatExperienceTimes100((iModdedChangeTimes100 * iCombatExperienceMod) / 100, (MOD_GLOBAL_LOCAL_GENERALS ? this : NULL));17309#else17310 kPlayer.changeNavalCombatExperience((iModdedChange * iCombatExperienceMod) / 100, (MOD_GLOBAL_LOCAL_GENERALS ? this : NULL));17311#endif17312#else17313#if defined(MOD_UNITS_XP_TIMES_100)17314 kPlayer.changeNavalCombatExperienceTimes100((iModdedChangeTimes100 * iCombatExperienceMod) / 100);17315#else17316 kPlayer.changeNavalCombatExperience((iModdedChange * iCombatExperienceMod) / 100);17317#endif17318#endif17319 }17320 else17321 {17322#if defined(MOD_GLOBAL_LOCAL_GENERALS)17323#if defined(MOD_UNITS_XP_TIMES_100)17324 kPlayer.changeCombatExperienceTimes100((iModdedChangeTimes100 * iCombatExperienceMod) / 100, (MOD_GLOBAL_LOCAL_GENERALS ? this : NULL));17325#else17326 kPlayer.changeCombatExperience((iModdedChange * iCombatExperienceMod) / 100, (MOD_GLOBAL_LOCAL_GENERALS ? this : NULL));17327#endif17328#else17329#if defined(MOD_UNITS_XP_TIMES_100)17330 kPlayer.changeCombatExperienceTimes100((iModdedChangeTimes100 * iCombatExperienceMod) / 100);17331#else17332 kPlayer.changeCombatExperience((iModdedChange * iCombatExperienceMod) / 100);17333#endif17334#endif17335 }17336 }17337 }17338 }1733917340 if(getExperiencePercent() != 0)17341 {17342#if defined(MOD_UNITS_XP_TIMES_100)17343 int iUnitBonusXpTimes100 = (iUnitExperienceTimes100 * std::max(0, getExperiencePercent())) / 100;17344 if (!MOD_UNITS_XP_TIMES_100) {17345 // If NOT using XP times 100, remove any fractional part17346 iUnitBonusXpTimes100 -= (iUnitBonusXpTimes100 % 100);17347 }17348 iUnitExperienceTimes100 += iUnitBonusXpTimes100;17349#else17350 iUnitExperience *= std::max(0, 100 + getExperiencePercent());17351 iUnitExperience /= 100;17352#endif17353 }17354 }1735517356#if defined(MOD_UNITS_XP_TIMES_100)17357 setExperienceTimes100((getExperienceTimes100() + iUnitExperienceTimes100), iMax);17358#else17359 setExperience((getExperience() + iUnitExperience), iMax);17360#endif17361}