From 97edb09fba533416a81b4caaa0303213d3209aee Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Mon, 13 Feb 2023 01:25:59 -0500 Subject: [PATCH] [Rules] Add Group/Raid Experience Rules (#2850) # Notes - Add `Character:EnableGroupMemberEXPModifier`, enables or disables member-based experience modifiers in groups, default `true`. - Add `Character:EnableRaidEXPModifier`, enables or disables member-based experience modifiers in raids, default `true`. - Add `Character:EnableRaidMemberEXPModifier`, enables or disables member-based experience modifiers in raids, default `true`. --- common/ruletypes.h | 5 ++++- zone/exp.cpp | 46 ++++++++++++++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/common/ruletypes.h b/common/ruletypes.h index 967a77081..547ac345e 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -197,10 +197,13 @@ 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_BOOL(Character, EnableGroupEXPModifier, true, "Enable or disable the group experience modifier based on number of players in group, default is true") +RULE_BOOL(Character, EnableGroupEXPModifier, true, "Enable or disable the group experience modifier in group, default is true") +RULE_BOOL(Character, EnableGroupMemberEXPModifier, true, "Enable or disable the group member experience modifier based on number of players in group, default is true") RULE_REAL(Character, GroupMemberEXPModifier, 0.2, "Sets the group experience modifier per members between 2 and 5, default is 0.2") RULE_REAL(Character, FullGroupEXPModifier, 2.16, "Sets the group experience modifier for a full group, default is 2.16") RULE_BOOL(Character, IgnoreLevelBasedHasteCaps, false, "Ignores hard coded level based haste caps.") +RULE_BOOL(Character, EnableRaidEXPModifier, true, "Enable or disable the raid experience modifier, default is true") +RULE_BOOL(Character, EnableRaidMemberEXPModifier, true, "Enable or disable the raid experience modifier based on members in raid, default is true") RULE_CATEGORY_END() RULE_CATEGORY(Mercs) diff --git a/zone/exp.cpp b/zone/exp.cpp index 9aa4a7648..a9d40ec61 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -1115,11 +1115,11 @@ void Group::SplitExp(const uint64 exp, Mob* other) { return; } - auto group_experience = exp; + auto group_experience = exp; const auto highest_level = GetHighestLevel(); auto group_modifier = 1.0f; - if (RuleB(Character, EnableGroupEXPModifier)) { + if (RuleB(Character, EnableGroupMemberEXPModifier)) { if (EQ::ValueWithin(member_count, 2, 5)) { group_modifier = 1 + RuleR(Character, GroupMemberEXPModifier) * (member_count - 1); // 2 = 1.2x, 3 = 1.4x, 4 = 1.6x, 5 = 1.8x } else if (member_count == 6) { @@ -1128,11 +1128,18 @@ void Group::SplitExp(const uint64 exp, Mob* other) { } if (EQ::ValueWithin(member_count, 2, 6)) { - group_experience += static_cast( - static_cast(exp) * - group_modifier * - RuleR(Character, GroupExpMultiplier) - ); + if (RuleB(Character, EnableGroupEXPModifier)) { + group_experience += static_cast( + static_cast(exp) * + group_modifier * + RuleR(Character, GroupExpMultiplier) + ); + } else { + group_experience += static_cast( + static_cast(exp) * + group_modifier + ); + } } const uint8 consider_level = Mob::GetLevelCon(highest_level, other->GetLevel()); @@ -1142,8 +1149,8 @@ void Group::SplitExp(const uint64 exp, Mob* other) { for (const auto& m : members) { if (m && m->IsClient()) { - const int32 diff = m->GetLevel() - highest_level; - int32 max_diff = -(m->GetLevel() * 15 / 10 - m->GetLevel()); + const int32 diff = m->GetLevel() - highest_level; + int32 max_diff = -(m->GetLevel() * 15 / 10 - m->GetLevel()); if (max_diff > -5) { max_diff = -5; @@ -1172,23 +1179,30 @@ void Raid::SplitExp(const uint64 exp, Mob* other) { return; } - auto raid_experience = exp; + auto raid_experience = exp; const auto highest_level = GetHighestLevel(); - raid_experience = static_cast( - static_cast(raid_experience) * - (1.0f - RuleR(Character, RaidExpMultiplier)) - ); + if (RuleB(Character, EnableRaidEXPModifier)) { + raid_experience = static_cast( + static_cast(raid_experience) * + (1.0f - RuleR(Character, RaidExpMultiplier)) + ); + } const auto consider_level = Mob::GetLevelCon(highest_level, other->GetLevel()); if (consider_level == CON_GRAY) { return; } + uint32 member_modifier = 1; + if (RuleB(Character, EnableRaidMemberEXPModifier)) { + member_modifier = member_count; + } + for (const auto& m : members) { if (m.member) { const int32 diff = m.member->GetLevel() - highest_level; - int32 max_diff = -(m.member->GetLevel() * 15 / 10 - m.member->GetLevel()); + int32 max_diff = -(m.member->GetLevel() * 15 / 10 - m.member->GetLevel()); if (max_diff > -5) { max_diff = -5; @@ -1196,7 +1210,7 @@ void Raid::SplitExp(const uint64 exp, Mob* other) { if (diff >= max_diff) { const uint64 tmp = (m.member->GetLevel() + 3) * (m.member->GetLevel() + 3) * 75 * 35 / 10; - const uint64 tmp2 = (raid_experience / member_count) + 1; + const uint64 tmp2 = (raid_experience / member_modifier) + 1; m.member->AddEXP(tmp < tmp2 ? tmp : tmp2, consider_level); } }