diff --git a/common/ruletypes.h b/common/ruletypes.h index e7817f4bb..4acd79dbd 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -174,6 +174,8 @@ RULE_INT(Character, ResurrectionSicknessSpellID, 756, "756 is Default Resurrecti RULE_BOOL(Character, EnableBardMelody, true, "Enable Bard /melody by default, to disable change to false for a classic experience.") RULE_BOOL(Character, EnableRangerAutoFire, true, "Enable Ranger /autofire by default, to disable change to false for a classic experience.") RULE_BOOL(Character, EnableTGB, true, "Enable /tgb (Target Group Buff) by default, to disable change to false for a classic experience.") +RULE_INT(Character, SkillUpMaximumChancePercentage, 25, "Maximum chance to improve a combat skill, before skill-specific modifiers. This should be greater than SkillUpMinimumChancePercentage.") +RULE_INT(Character, SkillUpMinimumChancePercentage, 2, "Minimum chance to improve a combat skill, after skill-specific modifiers. This should be lesser than SkillUpMaximumChancePercentage.") RULE_INT(Character, WarriorTrackingDistanceMultiplier, 0, "If you want warriors to be able to track, increase this above 0. 0 disables tracking packets.") RULE_INT(Character, ClericTrackingDistanceMultiplier, 0, "If you want clerics to be able to track, increase this above 0. 0 disables tracking packets.") RULE_INT(Character, PaladinTrackingDistanceMultiplier, 0, "If you want paladins to be able to track, increase this above 0. 0 disables tracking packets.") diff --git a/zone/client.cpp b/zone/client.cpp index 7a1a43d65..2857f86db 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2422,7 +2422,7 @@ bool Client::CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who, return false; if (skillid > EQ::skills::HIGHEST_SKILL) return false; - int skillval = GetRawSkill(skillid); + int skillval = GetRawSkill(skillid); int maxskill = GetMaxSkillAfterSpecializationRules(skillid, MaxSkill(skillid)); std::string export_string = fmt::format( "{} {}", @@ -2447,23 +2447,26 @@ bool Client::CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who, // Make sure we're not already at skill cap if (skillval < maxskill) { - // the higher your current skill level, the harder it is - int32 Chance = 10 + chancemodi + ((252 - skillval) / 20); - - Chance = (Chance * RuleI(Character, SkillUpModifier) / 100); - - Chance = mod_increase_skill_chance(Chance, against_who); - - if(Chance < 1) - Chance = 1; // Make it always possible + double Chance = 0; + if (RuleI(Character, SkillUpMaximumChancePercentage) + chancemodi - RuleI(Character, SkillUpMinimumChancePercentage) <= RuleI(Character, SkillUpMinimumChancePercentage)) { + Chance = RuleI(Character, SkillUpMinimumChancePercentage); + } + else { + // f(x) = (max - min + modification) * .99^skillval + min + // This results in a exponential decay where as you skill up, you lose a slight chance to skill up, ranging from your modified maximum to approaching your minimum + // This result is increased by the existing SkillUpModifier rule + double working_chance = (((RuleI(Character, SkillUpMaximumChancePercentage) - RuleI(Character, SkillUpMinimumChancePercentage) + chancemodi) * (pow(0.99, skillval))) + RuleI(Character, SkillUpMinimumChancePercentage)); + Chance = (working_chance * RuleI(Character, SkillUpModifier) / 100); + Chance = mod_increase_skill_chance(Chance, against_who); + } if(zone->random.Real(0, 99) < Chance) { SetSkill(skillid, GetRawSkill(skillid) + 1); - LogSkills("Skill [{}] at value [{}] successfully gain with [{}]% chance (mod [{}])", skillid, skillval, Chance, chancemodi); + LogSkills("Skill [{}] at value [{}] successfully gain with [{}] chance (mod [{}])", skillid, skillval, Chance, chancemodi); return true; } else { - LogSkills("Skill [{}] at value [{}] failed to gain with [{}]% chance (mod [{}])", skillid, skillval, Chance, chancemodi); + LogSkills("Skill [{}] at value [{}] failed to gain with [{}] chance (mod [{}])", skillid, skillval, Chance, chancemodi); } } else { LogSkills("Skill [{}] at value [{}] cannot increase due to maxmum [{}]", skillid, skillval, maxskill); diff --git a/zone/client.h b/zone/client.h index 598d12f6a..4962d1e8f 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1566,7 +1566,7 @@ public: int mod_client_damage(int damage, EQ::skills::SkillType skillinuse, int hand, const EQ::ItemInstance* weapon, Mob* other); bool mod_client_message(char* message, uint8 chan_num); bool mod_can_increase_skill(EQ::skills::SkillType skillid, Mob* against_who); - int16 mod_increase_skill_chance(int16 chance, Mob* against_who); + double mod_increase_skill_chance(double chance, Mob* against_who); int mod_bindwound_percent(int max_percent, Mob* bindmob); int mod_bindwound_hp(int bindhps, Mob* bindmob); int mod_client_haste(int h); diff --git a/zone/mod_functions.cpp b/zone/mod_functions.cpp index b4951f76d..5091da606 100644 --- a/zone/mod_functions.cpp +++ b/zone/mod_functions.cpp @@ -61,7 +61,7 @@ bool Client::mod_client_message(char* message, uint8 chan_num) { return(true); } bool Client::mod_can_increase_skill(EQ::skills::SkillType skillid, Mob* against_who) { return(false); } //chance of general skill increase, rolled against 0-99 where higher chance is better. -int16 Client::mod_increase_skill_chance(int16 chance, Mob* against_who) { return(chance); } +double Client::mod_increase_skill_chance(double chance, Mob* against_who) { return(chance); } //Max percent of health you can bind wound starting with default value for class, item, and AA bonuses int Client::mod_bindwound_percent(int max_percent, Mob* bindmob) { return(max_percent); }