mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 22:58:34 +00:00
[Skills] Configurable Exponential Decay Formula for Skill Up (#1887)
* [Skills] Exponential Decay Skill Up Formula Added an exponential decay skill up formula option. The current, linear, formula results in negative chances to skill up, which have been mitigated via a multiplier and minimum of 1% * [Skills]Configurable Exponential Decay Formala for Skill Up What this fixes: The existing formula for determining whether or not to skill up could result in negative chances, and made an assumption around the number 252. This would ultimately result in an override that would set the chance to 1. My fix: I created 2 new rules: Character:SkillUpMaximumChancePercentage Character:SkillUpMinimumChancePercentage I changed the forumla to: chance = ((max - min + skill_modification) * (.99^skill)) + min This results in an exponential decay that starts at skill-modified maximum and approaches minimum. I decided that max-min+skill_modification should never be less than min I also decided to continue to apply the Character:SkillUpModifier rule post-calculation. I do not really think this is necessary anymore, given this new formula, but we can discuss removing it. I chose 25 and 2 as default maximum and minimum based on feel. Related method signature fix: Client::mod_increase_skill_chance was changed to return a double and accept a double as an input for chance. This matches the actual data types provided while calling the method and eliminates some type coersion and resultant truncation. Right now, this method doesn't do anything, but in the future we could implement skill-specific training dummies that accelerate skill ups. I deduce that this is the purpose of this method call. * [Skills]Configurable Exponential Decay Formula for Skill Up What this fixes: The existing formula for determining whether or not to skill up could result in negative chances, and made an assumption around the number 252. This would ultimately result in an override that would set the chance to 1. My fix: I created 2 new rules: Character:SkillUpMaximumChancePercentage Character:SkillUpMinimumChancePercentage I changed the forumla to: chance = ((max - min + skill_modification) * (.99^skill)) + min This results in an exponential decay that starts at skill-modified maximum and approaches minimum. I decided that max-min+skill_modification should never be less than min I also decided to continue to apply the Character:SkillUpModifier rule post-calculation. I do not really think this is necessary anymore, given this new formula, but we can discuss removing it. I chose 25 and 2 as default maximum and minimum based on feel. Related method signature fix: Client::mod_increase_skill_chance was changed to return a double and accept a double as an input for chance. This matches the actual data types provided while calling the method and eliminates some type coersion and resultant truncation. Right now, this method doesn't do anything, but in the future we could implement skill-specific training dummies that accelerate skill ups. I deduce that this is the purpose of this method call. * fixup! [Skills]Configurable Exponential Decay Formula for Skill Up * fixup! [Skills]Configurable Exponential Decay Formula for Skill Up
This commit is contained in:
+15
-12
@@ -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);
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
@@ -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); }
|
||||
|
||||
Reference in New Issue
Block a user