diff --git a/common/ruletypes.h b/common/ruletypes.h index 78b0d35ff..0567a5743 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -196,6 +196,7 @@ RULE_BOOL(Character, OnInviteReceiveAlreadyinGroupMessage, true, "If you want cl RULE_BOOL(Character, PetZoneWithOwner, true, "Should Pets Zone with Owner") RULE_BOOL(Character, FullManaOnDeath, true, "On death set mana to full") RULE_BOOL(Character, FullEndurOnDeath, true, "On death set endurance to full") +RULE_INT(Character, ExperiencePercentCapPerKill, -1, "Caps the percentage of experience that can be gained per kill. -1 disables the cap; 0 blocks all (non-aa) xp.") RULE_CATEGORY_END() RULE_CATEGORY(Mercs) diff --git a/zone/exp.cpp b/zone/exp.cpp index df0faf276..9fa7e1a94 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -496,6 +496,16 @@ void Client::CalculateExp(uint32 in_add_exp, uint32 &add_exp, uint32 &add_aaxp, } add_exp = GetEXP() + add_exp; + + //Enforce Percent XP Cap per kill, if rule is enabled + int kill_percent_xp_cap = RuleI(Character, ExperiencePercentCapPerKill); + if (kill_percent_xp_cap >= 0) { + auto experience_for_level = (GetEXPForLevel(GetLevel() + 1) - GetEXPForLevel(GetLevel())); + auto exp_percent = static_cast(std::ceil(static_cast(add_exp / experience_for_level) * 100.0f)); + if (exp_percent > kill_percent_xp_cap) { + add_exp = static_cast(std::floor(experience_for_level * (kill_percent_xp_cap / 100.0f))); + } + } } void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {