Hooks
static bool BeforeCvPlayerPolicies_GetNumPoliciesOwned(const CvPlayerPolicies* self, bool bExcludeOrphans, bool bExcludeFree, int& result);static void AfterCvPlayerPolicies_GetNumPoliciesOwned(const CvPlayerPolicies* self, bool bExcludeOrphans, bool bExcludeFree, int& result);static int ReplaceCvPlayerPolicies_GetNumPoliciesOwned(int (*original)(const CvPlayerPolicies*, bool, bool), const CvPlayerPolicies* self, bool bExcludeOrphans, bool bExcludeFree);CivRegisterBefore<CivHooks::CvPlayerPolicies_GetNumPoliciesOwned>(host, &BeforeCvPlayerPolicies_GetNumPoliciesOwned);CivRegisterAfter<CivHooks::CvPlayerPolicies_GetNumPoliciesOwned>(host, &AfterCvPlayerPolicies_GetNumPoliciesOwned);CivRegisterReplace<CivHooks::CvPlayerPolicies_GetNumPoliciesOwned>(host, &ReplaceCvPlayerPolicies_GetNumPoliciesOwned);
Code
2945/// Returns number of policies purchased by this player2946#if defined(MOD_BUGFIX_DUMMY_POLICIES)2947//2948// Firaxis assume that EVERY policy is attached to a branch, either directly (Policies.PolicyBranchType is not NULL),2949// or indirectly (by reference from PolicyBranchTypes.FreePolicy or PolicyBranchTypes.FreeFinishingPolicy)2950//2951// However, modders (being sneaky little buggers) have discovered that policies don't need to be attached to branches2952// (that is they are orphans) and can use them as dummy policies as a way of getting access to the bonuses in the2953// Policies table for civilization unique attributes (UAs) etc. They (mainly me!) have also discovered an exploit2954// to grant policies without affecting the cost of the next policy (SetNumFreePolicies 1 - 0 magic)2955//2956// This however leads to a number of issues - buildings (eg Prora) give happiness boost for the dummy policies,2957// overall score gets a boost from the dummy policies, etc2958//2959// We could write a method that calculates if a policy is an orphan (doesn't reference the PolicyBranchType2960// table either directly or indirectly) but that would then break every existing mod that uses dummy policies and2961// the free policy exploit. So we'll add a column to the Policies table to explicitly flag a policy as a dummy.2962// That way, existing mods are unaffected, new mods can use the new database column, the new Grant/Revoke/Swap API2963// and not have to bother with the free policy exploit. Happiness all round :)2964//2965#if defined(MOD_API_EXTENSIONS)2966int CvPlayerPolicies::GetNumPoliciesOwned(bool bExcludeOrphans, bool bExcludeFree) const2967#else2968int CvPlayerPolicies::GetNumPoliciesOwned(bool bExcludeOrphans) const2969#endif2970#else2971#if defined(MOD_API_EXTENSIONS)2972int CvPlayerPolicies::GetNumPoliciesOwned(bool bExcludeFree) const2973#else2974int CvPlayerPolicies::GetNumPoliciesOwned() const2975#endif2976#endif2977{2978 int rtnValue = 0;29792980 for(int i = 0; i < m_pPolicies->GetNumPolicies(); i++)2981 {2982 // Do we have this policy?2983 if(m_pabHasPolicy[i])2984 {2985#if defined(MOD_API_EXTENSIONS)2986 if (bExcludeFree && m_pabFreePolicy[i]) continue;2987#endif2988#if defined(MOD_BUGFIX_DUMMY_POLICIES)2989 // Exclude orphans2990 if ((MOD_BUGFIX_DUMMY_POLICIES && bExcludeOrphans && m_pPolicies->GetPolicyEntry(i)->IsDummy())) continue;2991#endif2992 rtnValue++;2993 }2994 }29952996 return rtnValue;2997}