Hooks
static bool BeforeCvUnit_setHasPromotion(CvUnit* self, PromotionTypes eIndex, bool bNewValue);static void AfterCvUnit_setHasPromotion(CvUnit* self, PromotionTypes eIndex, bool bNewValue);static void ReplaceCvUnit_setHasPromotion(void (*original)(CvUnit*, PromotionTypes, bool), CvUnit* self, PromotionTypes eIndex, bool bNewValue);CivRegisterBefore<CivHooks::CvUnit_setHasPromotion>(host, &BeforeCvUnit_setHasPromotion);CivRegisterAfter<CivHooks::CvUnit_setHasPromotion>(host, &AfterCvUnit_setHasPromotion);CivRegisterReplace<CivHooks::CvUnit_setHasPromotion>(host, &ReplaceCvUnit_setHasPromotion);
Code
20838void CvUnit::setHasPromotion(PromotionTypes eIndex, bool bNewValue)20839{20840 VALIDATE_OBJECT20841 int iChange;20842 int iI;2084320844 if(isHasPromotion(eIndex) != bNewValue)20845 {20846 CvPromotionEntry& thisPromotion = *GC.getPromotionInfo(eIndex);2084720848#if defined(MOD_GLOBAL_CANNOT_EMBARK)20849 if (bNewValue && MOD_GLOBAL_CANNOT_EMBARK && getUnitInfo().CannotEmbark()) {20850 if (thisPromotion.IsAllowsEmbarkation() || thisPromotion.IsEmbarkedAllWater()) {20851 return;20852#if defined(MOD_PROMOTIONS_DEEP_WATER_EMBARKATION)20853 } else if (MOD_PROMOTIONS_DEEP_WATER_EMBARKATION && thisPromotion.IsEmbarkedDeepWater()) {20854 return;20855#endif20856 }20857 }20858#endif2085920860#if defined(MOD_BUGFIX_MINOR)20861 // Firaxis only use the CanMoveAllTerrain promotion in the Smokey Skies scenario,20862 // which doesn't have the situation where the player discovers Optics ...20863 if (bNewValue && canMoveAllTerrain()) {20864 if (thisPromotion.IsAllowsEmbarkation() || thisPromotion.IsEmbarkedAllWater()) {20865 return;20866#if defined(MOD_PROMOTIONS_DEEP_WATER_EMBARKATION)20867 } else if (MOD_PROMOTIONS_DEEP_WATER_EMBARKATION && thisPromotion.IsEmbarkedDeepWater()) {20868 return;20869#endif20870 }20871 }20872#endif2087320874 m_Promotions.SetPromotion(eIndex, bNewValue);20875 iChange = ((isHasPromotion(eIndex)) ? 1 : -1);2087620877 // Promotions will set Invisibility once but not change it later20878 if(getInvisibleType() == NO_INVISIBLE && thisPromotion.GetInvisibleType() != NO_INVISIBLE)20879 {20880 setInvisibleType((InvisibleTypes) thisPromotion.GetInvisibleType());20881 }20882 if(getSeeInvisibleType() == NO_INVISIBLE && thisPromotion.GetSeeInvisibleType() != NO_INVISIBLE)20883 {20884 setSeeInvisibleType((InvisibleTypes) thisPromotion.GetSeeInvisibleType());20885 }2088620887 changeBlitzCount((thisPromotion.IsBlitz()) ? iChange : 0);20888 changeAmphibCount((thisPromotion.IsAmphib()) ? iChange : 0);20889 changeRiverCrossingNoPenaltyCount((thisPromotion.IsRiver()) ? iChange : 0);20890 changeEnemyRouteCount((thisPromotion.IsEnemyRoute()) ? iChange : 0);20891 changeRivalTerritoryCount((thisPromotion.IsRivalTerritory()) ? iChange : 0);20892 changeMustSetUpToRangedAttackCount((thisPromotion.IsMustSetUpToRangedAttack()) ? iChange : 0);20893 changeRangedSupportFireCount((thisPromotion.IsRangedSupportFire()) ? iChange : 0);20894 changeAlwaysHealCount((thisPromotion.IsAlwaysHeal()) ? iChange : 0);20895 changeHealOutsideFriendlyCount((thisPromotion.IsHealOutsideFriendly()) ? iChange : 0);20896 changeHillsDoubleMoveCount((thisPromotion.IsHillsDoubleMove()) ? iChange : 0);20897 changeIgnoreTerrainCostCount((thisPromotion.IsIgnoreTerrainCost()) ? iChange : 0);20898#if defined(MOD_API_PLOT_BASED_DAMAGE)20899 changeIgnoreTerrainDamageCount((thisPromotion.IsIgnoreTerrainDamage()) ? iChange : 0);20900 changeIgnoreFeatureDamageCount((thisPromotion.IsIgnoreFeatureDamage()) ? iChange : 0);20901 changeExtraTerrainDamageCount((thisPromotion.IsExtraTerrainDamage()) ? iChange : 0);20902 changeExtraFeatureDamageCount((thisPromotion.IsExtraFeatureDamage()) ? iChange : 0);20903#endif20904#if defined(MOD_PROMOTIONS_IMPROVEMENT_BONUS)20905 if (MOD_PROMOTIONS_IMPROVEMENT_BONUS) {20906 if (thisPromotion.GetNearbyImprovementCombatBonus() > 0) {20907 SetNearbyImprovementCombatBonus(thisPromotion.GetNearbyImprovementCombatBonus());20908 SetNearbyImprovementBonusRange(thisPromotion.GetNearbyImprovementBonusRange());20909 SetCombatBonusImprovement(thisPromotion.GetCombatBonusImprovement());20910 }20911 }20912#endif20913#if defined(MOD_PROMOTIONS_CROSS_MOUNTAINS)20914 if (MOD_PROMOTIONS_CROSS_MOUNTAINS) {20915 changeCanCrossMountainsCount((thisPromotion.CanCrossMountains()) ? iChange : 0);20916 }20917#endif20918#if defined(MOD_PROMOTIONS_CROSS_OCEANS)20919 if (MOD_PROMOTIONS_CROSS_OCEANS) {20920 changeCanCrossOceansCount((thisPromotion.CanCrossOceans()) ? iChange : 0);20921 }20922#endif20923#if defined(MOD_PROMOTIONS_CROSS_ICE)20924 if (MOD_PROMOTIONS_CROSS_ICE) {20925 changeCanCrossIceCount((thisPromotion.CanCrossIce()) ? iChange : 0);20926 }20927#endif20928#if defined(MOD_PROMOTIONS_GG_FROM_BARBARIANS)20929 if (MOD_PROMOTIONS_GG_FROM_BARBARIANS) {20930 changeGGFromBarbariansCount((thisPromotion.IsGGFromBarbarians()) ? iChange : 0);20931 }20932#endif20933 ChangeRoughTerrainEndsTurnCount((thisPromotion.IsRoughTerrainEndsTurn()) ? iChange : 0);20934 ChangeHoveringUnitCount((thisPromotion.IsHoveringUnit()) ? iChange : 0);20935 changeFlatMovementCostCount((thisPromotion.IsFlatMovementCost()) ? iChange : 0);20936 changeCanMoveImpassableCount((thisPromotion.IsCanMoveImpassable()) ? iChange : 0);20937 changeOnlyDefensiveCount((thisPromotion.IsOnlyDefensive()) ? iChange : 0);20938 changeNoDefensiveBonusCount((thisPromotion.IsNoDefensiveBonus()) ? iChange : 0);20939 changeNoCaptureCount((thisPromotion.IsNoCapture()) ? iChange : 0);20940 changeNukeImmuneCount((thisPromotion.IsNukeImmune()) ? iChange: 0);20941 changeHiddenNationalityCount((thisPromotion.IsHiddenNationality()) ? iChange: 0);20942 changeAlwaysHostileCount((thisPromotion.IsAlwaysHostile()) ? iChange: 0);20943 changeNoRevealMapCount((thisPromotion.IsNoRevealMap()) ? iChange: 0);20944 ChangeReconCount((thisPromotion.IsRecon()) ? iChange: 0);20945 changeCanMoveAllTerrainCount((thisPromotion.CanMoveAllTerrain()) ? iChange: 0);20946 changeCanMoveAfterAttackingCount((thisPromotion.IsCanMoveAfterAttacking()) ? iChange: 0);20947 ChangeAirSweepCapableCount((thisPromotion.IsAirSweepCapable()) ? iChange: 0);20948 ChangeEmbarkAbilityCount((thisPromotion.IsAllowsEmbarkation()) ? iChange: 0);20949 ChangeRangeAttackIgnoreLOSCount((thisPromotion.IsRangeAttackIgnoreLOS()) ? iChange: 0);20950 ChangeHealIfDefeatExcludeBarbariansCount((thisPromotion.IsHealIfDefeatExcludeBarbarians()) ? iChange: 0);20951 changeHealOnPillageCount((thisPromotion.IsHealOnPillage()) ? iChange : 0);20952 changeFreePillageMoveCount((thisPromotion.IsFreePillageMoves()) ? iChange: 0);20953 ChangeEmbarkAllWaterCount((thisPromotion.IsEmbarkedAllWater()) ? iChange: 0);20954#if defined(MOD_PROMOTIONS_DEEP_WATER_EMBARKATION)20955 ChangeEmbarkDeepWaterCount((thisPromotion.IsEmbarkedDeepWater()) ? iChange: 0);20956#endif20957 ChangeCityAttackOnlyCount((thisPromotion.IsCityAttackOnly()) ? iChange: 0);20958 ChangeCaptureDefeatedEnemyCount((thisPromotion.IsCaptureDefeatedEnemy()) ? iChange: 0);20959 ChangeCanHeavyChargeCount((thisPromotion.IsCanHeavyCharge()) ? iChange : 0);2096020961 ChangeEmbarkExtraVisibility((thisPromotion.GetEmbarkExtraVisibility()) * iChange);20962 ChangeEmbarkDefensiveModifier((thisPromotion.GetEmbarkDefenseModifier()) * iChange);20963 ChangeCapitalDefenseModifier((thisPromotion.GetCapitalDefenseModifier()) * iChange);20964 ChangeCapitalDefenseFalloff((thisPromotion.GetCapitalDefenseFalloff()) * iChange);20965 ChangeCityAttackPlunderModifier((thisPromotion.GetCityAttackPlunderModifier()) * iChange);20966 ChangeReligiousStrengthLossRivalTerritory((thisPromotion.GetReligiousStrengthLossRivalTerritory()) * iChange);20967 ChangeTradeMissionInfluenceModifier((thisPromotion.GetTradeMissionInfluenceModifier()) * iChange);20968 ChangeTradeMissionGoldModifier((thisPromotion.GetTradeMissionGoldModifier()) * iChange);20969 changeDropRange(thisPromotion.GetDropRange() * iChange);20970 changeExtraVisibilityRange(thisPromotion.GetVisibilityChange() * iChange);20971#if defined(MOD_PROMOTIONS_VARIABLE_RECON)20972 changeExtraReconRange(thisPromotion.GetReconChange() * iChange);20973#endif20974 changeExtraMoves(thisPromotion.GetMovesChange() * iChange);20975 changeExtraMoveDiscount(thisPromotion.GetMoveDiscountChange() * iChange);20976 changeExtraNavalMoves(thisPromotion.GetExtraNavalMoves() * iChange);20977 changeHPHealedIfDefeatEnemy(thisPromotion.GetHPHealedIfDefeatEnemy() * iChange);20978 ChangeGoldenAgeValueFromKills(thisPromotion.GetGoldenAgeValueFromKills() * iChange);20979 changeExtraWithdrawal(thisPromotion.GetExtraWithdrawal() * iChange);20980 changeExtraRange(thisPromotion.GetRangeChange() * iChange);20981 ChangeRangedAttackModifier(thisPromotion.GetRangedAttackModifier() * iChange);20982 ChangeInterceptionCombatModifier(thisPromotion.GetInterceptionCombatModifier() * iChange);20983 ChangeInterceptionDefenseDamageModifier(thisPromotion.GetInterceptionDefenseDamageModifier() * iChange);20984 ChangeAirSweepCombatModifier(thisPromotion.GetAirSweepCombatModifier() * iChange);20985 changeExtraIntercept(thisPromotion.GetInterceptChanceChange() * iChange);20986 changeExtraEvasion(thisPromotion.GetEvasionChange() * iChange);20987 changeExtraEnemyHeal(thisPromotion.GetEnemyHealChange() * iChange);20988 changeExtraNeutralHeal(thisPromotion.GetNeutralHealChange() * iChange);20989 changeExtraFriendlyHeal(thisPromotion.GetFriendlyHealChange() * iChange);20990 changeSameTileHeal(thisPromotion.GetSameTileHealChange() * iChange);20991 changeAdjacentTileHeal(thisPromotion.GetAdjacentTileHealChange() * iChange);20992 changeEnemyDamageChance(thisPromotion.GetEnemyDamageChance() * iChange);20993 changeNeutralDamageChance(thisPromotion.GetNeutralDamageChance() * iChange);20994 changeEnemyDamage(thisPromotion.GetEnemyDamage() * iChange);20995 changeNeutralDamage(thisPromotion.GetNeutralDamage() * iChange);20996 changeNearbyEnemyCombatMod(thisPromotion.GetNearbyEnemyCombatMod() * iChange);20997 changeNearbyEnemyCombatRange(thisPromotion.GetNearbyEnemyCombatRange() * iChange);20998 ChangeAdjacentModifier(thisPromotion.GetAdjacentMod() * iChange);20999 changeAttackModifier(thisPromotion.GetAttackMod() * iChange);21000 changeDefenseModifier(thisPromotion.GetDefenseMod() * iChange);21001 changeExtraCombatPercent(thisPromotion.GetCombatPercent() * iChange);21002 changeExtraCityAttackPercent(thisPromotion.GetCityAttackPercent() * iChange);21003 changeExtraCityDefensePercent(thisPromotion.GetCityDefensePercent() * iChange);21004 changeExtraRangedDefenseModifier(thisPromotion.GetRangedDefenseMod() * iChange);21005 changeExtraHillsAttackPercent(thisPromotion.GetHillsAttackPercent() * iChange);21006 changeExtraHillsDefensePercent(thisPromotion.GetHillsDefensePercent() * iChange);21007 changeExtraOpenAttackPercent(thisPromotion.GetOpenAttackPercent() * iChange);21008 changeExtraOpenRangedAttackMod(thisPromotion.GetOpenRangedAttackMod() * iChange);21009 changeExtraRoughAttackPercent(thisPromotion.GetRoughAttackPercent() * iChange);21010 changeExtraRoughRangedAttackMod(thisPromotion.GetRoughRangedAttackMod() * iChange);21011 changeExtraAttackFortifiedMod(thisPromotion.GetAttackFortifiedMod() * iChange);21012 changeExtraAttackWoundedMod(thisPromotion.GetAttackWoundedMod() * iChange);21013 ChangeFlankAttackModifier(thisPromotion.GetFlankAttackModifier() * iChange);21014 changeExtraOpenDefensePercent(thisPromotion.GetOpenDefensePercent() * iChange);21015 changeExtraRoughDefensePercent(thisPromotion.GetRoughDefensePercent() * iChange);21016 changeExtraAttacks(thisPromotion.GetExtraAttacks() * iChange);21017 ChangeNumInterceptions(thisPromotion.GetNumInterceptionChange() * iChange);2101821019 ChangeGreatGeneralCount(thisPromotion.IsGreatGeneral() ? iChange: 0);21020 ChangeGreatAdmiralCount(thisPromotion.IsGreatAdmiral() ? iChange: 0);21021#if defined(MOD_PROMOTIONS_AURA_CHANGE)21022 ChangeAuraRangeChange(thisPromotion.GetAuraRangeChange() * iChange);21023 ChangeAuraEffectChange(thisPromotion.GetAuraEffectChange() * iChange);21024#endif21025 changeGreatGeneralModifier(thisPromotion.GetGreatGeneralModifier() * iChange);21026 ChangeGreatGeneralReceivesMovementCount(thisPromotion.IsGreatGeneralReceivesMovement() ? iChange: 0);21027 ChangeGreatGeneralCombatModifier(thisPromotion.GetGreatGeneralCombatModifier() * iChange);2102821029 ChangeIgnoreGreatGeneralBenefitCount(thisPromotion.IsIgnoreGreatGeneralBenefit() ? iChange: 0);21030 ChangeIgnoreZOCCount(thisPromotion.IsIgnoreZOC() ? iChange: 0);2103121032#if defined(MOD_UNITS_NO_SUPPLY)21033 changeNoSupply(thisPromotion.IsNoSupply() ? iChange : 0);21034#endif2103521036#if defined(MOD_UNITS_MAX_HP)21037 changeMaxHitPointsChange(thisPromotion.GetMaxHitPointsChange() * iChange);21038 changeMaxHitPointsModifier(thisPromotion.GetMaxHitPointsModifier() * iChange);21039#endif2104021041 ChangeSapperCount((thisPromotion.IsSapper() ? iChange: 0));2104221043 changeFriendlyLandsModifier(thisPromotion.GetFriendlyLandsModifier() * iChange);21044 changeFriendlyLandsAttackModifier(thisPromotion.GetFriendlyLandsAttackModifier() * iChange);21045 changeOutsideFriendlyLandsModifier(thisPromotion.GetOutsideFriendlyLandsModifier() * iChange);21046 changeUpgradeDiscount(thisPromotion.GetUpgradeDiscount() * iChange);21047 changeExperiencePercent(thisPromotion.GetExperiencePercent() * iChange);21048 changeCargoSpace(thisPromotion.GetCargoChange() * iChange);2104921050#if defined(MOD_PROMOTIONS_UNIT_NAMING)21051 if (MOD_PROMOTIONS_UNIT_NAMING) {21052 if (thisPromotion.IsUnitNaming(getUnitType())) {21053 thisPromotion.GetUnitName(getUnitType(), m_strUnitName);21054 }21055 }21056#endif2105721058 for(iI = 0; iI < GC.getNumTerrainInfos(); iI++)21059 {21060 changeExtraTerrainAttackPercent(((TerrainTypes)iI), (thisPromotion.GetTerrainAttackPercent(iI) * iChange));21061 changeExtraTerrainDefensePercent(((TerrainTypes)iI), (thisPromotion.GetTerrainDefensePercent(iI) * iChange));21062 changeTerrainDoubleMoveCount(((TerrainTypes)iI), ((thisPromotion.GetTerrainDoubleMove(iI)) ? iChange : 0));21063#if defined(MOD_PROMOTIONS_HALF_MOVE)21064 changeTerrainHalfMoveCount(((TerrainTypes)iI), ((thisPromotion.GetTerrainHalfMove(iI)) ? iChange : 0));21065#endif21066 changeTerrainImpassableCount(((TerrainTypes)iI), ((thisPromotion.GetTerrainImpassable(iI)) ? iChange : 0));21067 }2106821069 for(iI = 0; iI < GC.getNumFeatureInfos(); iI++)21070 {21071 changeExtraFeatureAttackPercent(((FeatureTypes)iI), (thisPromotion.GetFeatureAttackPercent(iI) * iChange));21072 changeExtraFeatureDefensePercent(((FeatureTypes)iI), (thisPromotion.GetFeatureDefensePercent(iI) * iChange));21073 changeFeatureDoubleMoveCount(((FeatureTypes)iI), ((thisPromotion.GetFeatureDoubleMove(iI)) ? iChange : 0));21074#if defined(MOD_PROMOTIONS_HALF_MOVE)21075 changeFeatureHalfMoveCount(((FeatureTypes)iI), ((thisPromotion.GetFeatureHalfMove(iI)) ? iChange : 0));21076#endif21077 changeFeatureImpassableCount(((FeatureTypes)iI), ((thisPromotion.GetFeatureImpassable(iI)) ? iChange : 0));21078 }2107921080#if defined(MOD_API_UNIFIED_YIELDS)21081 for(iI = 0; iI < NUM_YIELD_TYPES; iI++)21082 {21083 changeYieldFromKills(((YieldTypes)iI), (thisPromotion.GetYieldFromKills(iI) * iChange));21084 changeYieldFromBarbarianKills(((YieldTypes)iI), (thisPromotion.GetYieldFromBarbarianKills(iI) * iChange));21085 }21086#endif2108721088 for(iI = 0; iI < GC.getNumUnitCombatClassInfos(); iI++)21089 {21090 changeExtraUnitCombatModifier(((UnitCombatTypes)iI), (thisPromotion.GetUnitCombatModifierPercent(iI) * iChange));21091 }2109221093 for(iI = 0; iI < GC.getNumUnitClassInfos(); iI++)21094 {21095 CvUnitClassInfo* pkUnitClassInfo = GC.getUnitClassInfo((UnitClassTypes)iI);21096 if(!pkUnitClassInfo)21097 {21098 continue;21099 }2110021101 changeUnitClassModifier(((UnitClassTypes)iI), (thisPromotion.GetUnitClassModifierPercent(iI) * iChange));21102 }2110321104 for(iI = 0; iI < NUM_DOMAIN_TYPES; iI++)21105 {21106 changeExtraDomainModifier(((DomainTypes)iI), (thisPromotion.GetDomainModifierPercent(iI) * iChange));21107 }2110821109 if(IsSelected())21110 {21111 DLLUI->setDirty(SelectionButtons_DIRTY_BIT, true);21112 DLLUI->setDirty(UnitInfo_DIRTY_BIT, true);21113 if (thisPromotion.GetEmbarkExtraVisibility() || thisPromotion.IsNoRevealMap() || thisPromotion.GetVisibilityChange())21114 GC.getMap().updateDeferredFog();21115 }2111621117#if !defined(NO_ACHIEVEMENTS)21118 PromotionTypes eBuffaloChest =(PromotionTypes) GC.getInfoTypeForString("PROMOTION_BUFFALO_CHEST", true /*bHideAssert*/);21119 PromotionTypes eBuffaloLoins =(PromotionTypes) GC.getInfoTypeForString("PROMOTION_BUFFALO_LOINS", true /*bHideAssert*/);2112021121 const PlayerTypes eActivePlayer = GC.getGame().getActivePlayer();21122 if(getOwner() == eActivePlayer && ((eIndex == eBuffaloChest && isHasPromotion(eBuffaloLoins)) || (eIndex == eBuffaloLoins && isHasPromotion(eBuffaloChest))))21123 {21124 gDLL->UnlockAchievement(ACHIEVEMENT_XP2_27);21125 }21126#endif21127 }21128}