From 8219cc9ea01f32fd65f9f1f3af47f88194f736bd Mon Sep 17 00:00:00 2001 From: Vayle <76063792+Valorith@users.noreply.github.com> Date: Sun, 25 Dec 2022 15:59:05 -0500 Subject: [PATCH] [Rules] Rule to allow cap on % XP gain per kill (#2667) * [Rules] Add rule to limit single kill xp gain Adds a rule to allow server operators to restrict XP gain/kill to a specified % of their current level. * Logic correction * Commenting * Logic tweaks * Rule description update * Logic adjustment Changed to allow xp cap > 100% and -1 = disabled * Formatting * Removed extra space * Formatting Renamed rule to be more clear. Updated rule description. Minor formatting tweaks. Implemented use of descriptive bools. * Data type adjustment * Removed Bools * Update exp.cpp * Update exp.cpp * Update exp.cpp * Update exp.cpp Co-authored-by: Alex King <89047260+Kinglykrab@users.noreply.github.com> --- common/ruletypes.h | 1 + zone/exp.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+) 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) {