diff --git a/src/game/Entities/Player.cpp b/src/game/Entities/Player.cpp index 1e3b6127e8..c02b06108d 100644 --- a/src/game/Entities/Player.cpp +++ b/src/game/Entities/Player.cpp @@ -6282,15 +6282,25 @@ int32 Player::CalculateReputationGain(ReputationSource source, int32 rep, int32 uint32 currentLevel = GetLevel(); - if (MaNGOS::XP::IsTrivialLevelDifference(currentLevel, creatureOrQuestLevel)) - percent *= minRate; - else + // Level zero seems to be treated as always equal to players current level in IsTrivialLevelDifference therefore I have skipped level difference penalty computations for that value + if (creatureOrQuestLevel > 0) { - // Pre-3.0.8: Declines with 20% for each level if 6 levels or more below the player down to a minimum (default: 20%) - const uint32 treshold = (creatureOrQuestLevel + 5); + if (source == REPUTATION_SOURCE_KILL) + { + if (MaNGOS::XP::IsTrivialLevelDifference(currentLevel, creatureOrQuestLevel)) + { + const uint32 greenRange = MaNGOS::XP::GetQuestGreenRange(currentLevel); + percent *= std::max(minRate, (1.0f - (0.2f * (currentLevel - greenRange - creatureOrQuestLevel)))); + } + } + else if (source == REPUTATION_SOURCE_QUEST) + { + // Pre-3.0.8: Declines with 20% for each level if 6 levels or more below the player down to a minimum (default: 20%) + const uint32 treshold = (creatureOrQuestLevel + 5); - if (currentLevel > treshold) - percent *= std::max(minRate, (1.0f - (0.2f * (currentLevel - treshold)))); + if (currentLevel > treshold) + percent *= std::max(minRate, (1.0f - (0.2f * (currentLevel - treshold)))); + } } if (percent <= 0.0f) diff --git a/src/game/Tools/Formulas.h b/src/game/Tools/Formulas.h index bc3e06fa92..b449edd3b7 100644 --- a/src/game/Tools/Formulas.h +++ b/src/game/Tools/Formulas.h @@ -271,6 +271,36 @@ namespace MaNGOS return false; } + inline uint32 GetQuestGreenRange(uint32 unitLvl) + { + switch (unitLvl / 5) + { + case 0: // 0-4 + case 1: // 5-9 + return 4; + case 2: // 10-14 + case 3: // 15-19 + return 5; + case 4: // 20-24 + case 5: // 25-29 + return 6; + case 6: // 30-34 + case 7: // 35-39 + return 7; + case 8: // 40-44 + return 8; + case 9: // 45-49 + return 9; + case 10: // 50-54 + return 10; + case 11: // 55-59 + return 11; + default: // 60+ + return 12; + } + return false; + } + enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY }; inline uint32 GetGrayLevel(uint32 pl_level)