diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 294f3b3e10..37b5651b85 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -2368,7 +2368,10 @@ SkillGain.Weapon = 1 # SkillChance.Yellow # SkillChance.Green # SkillChance.Grey -# Description: Chance to increase skill based on recipe color. +# Description: Chance to increase skill based on difficulty. +# Crafting recipes interpolate between the orange and grey +# chances. Yellow and green chances apply to gathering and +# scripted skill gains. # Default: 100 - (SkillChance.Orange) # 75 - (SkillChance.Yellow) # 25 - (SkillChance.Green) diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 0d9b4f3a2b..e569ce5d90 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -764,6 +764,28 @@ inline int SkillGainChance(uint32 SkillValue, uint32 GrayLevel, return sWorld->getIntConfig(CONFIG_SKILL_CHANCE_ORANGE) * 10; } +inline int32 CraftSkillGainChance(uint32 skillValue, uint32 grayLevel, uint32 yellowLevel) +{ + int32 orangeChance = sWorld->getIntConfig(CONFIG_SKILL_CHANCE_ORANGE) * 10; + int32 grayChance = sWorld->getIntConfig(CONFIG_SKILL_CHANCE_GREY) * 10; + + // Invalid or equal thresholds cannot be interpolated. Preserve the + // previous orange/gray boundary behavior for malformed DBC entries. + if (grayLevel <= yellowLevel) + return skillValue < grayLevel ? orangeChance : grayChance; + + if (skillValue <= yellowLevel) + return orangeChance; + if (skillValue >= grayLevel) + return grayChance; + + // Crafting skill-up chance falls linearly from orange at the yellow + // threshold to gray at the gray threshold. The green threshold is the + // midpoint of that range and therefore has a 50% chance by default. + return grayChance + int32(int64(grayLevel - skillValue) * (orangeChance - grayChance) / + (grayLevel - yellowLevel)); +} + bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator) { @@ -855,12 +877,9 @@ bool Player::UpdateCraftSkill(uint32 spellid) return UpdateSkillPro( _spell_idx->second->SkillLine, - SkillGainChance(SkillValue, - _spell_idx->second->TrivialSkillLineRankHigh, - (_spell_idx->second->TrivialSkillLineRankHigh + - _spell_idx->second->TrivialSkillLineRankLow) / - 2, - _spell_idx->second->TrivialSkillLineRankLow), + CraftSkillGainChance(SkillValue, + _spell_idx->second->TrivialSkillLineRankHigh, + _spell_idx->second->TrivialSkillLineRankLow), craft_skill_gain); } }