diff --git a/common/ruletypes.h b/common/ruletypes.h index bb52f203e..c3d7f8703 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -606,6 +606,8 @@ RULE_BOOL(Combat, BashTwoHanderUseShoulderAC, false, "Enable to use shoulder AC RULE_REAL(Combat, BashACBonusDivisor, 25.0, "this divides the AC value contribution to bash damage, lower to increase damage") RULE_BOOL(Combat, UseMobStaticOffenseSkill, false, "Toggle to enabled the use of a static offense skill for Mobs. DEFAULT: false") RULE_BOOL(Combat, UseEnhancedMobStaticWeaponSkill, false, "Toggle to enabled the use of an enhanced (slightly higher hit rate) static weapon skill for Mobs. DEFAULT: false") +RULE_INT(Combat, PCAttackPowerScaling, 100, "Applies scaling to PC Attack Power (75 = 75%). DEFAULT: 100 to not adjust existing Servers") +RULE_INT(Combat, PCAccuracyAvoidanceMod2Scale, 100, "Scale Factor for PC Accuracy and Avoidance (Mod2, found on items). Found a value of 100 to make both too strong (75 = x0.75). DEFAULT: 100 to not adjust existing Servers") RULE_CATEGORY_END() RULE_CATEGORY(NPC) diff --git a/zone/attack.cpp b/zone/attack.cpp index 2bda7549e..86b1c3fb9 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -194,8 +194,15 @@ int Mob::GetTotalToHit(EQ::skills::SkillType skill, int chance_mod) // unsure on the stacking order of these effects, rather hard to parse // item mod2 accuracy isn't applied to range? Theory crafting and parses back it up I guess // mod2 accuracy -- flat bonus - if (skill != EQ::skills::SkillArchery && skill != EQ::skills::SkillThrowing) + if (skill != EQ::skills::SkillArchery && skill != EQ::skills::SkillThrowing) { accuracy += itembonuses.HitChance; + } else { + // Applying a scale factor as sources suggest Accuracy should reduce number of missing by 0.1% per point, so 150 = 15% reduction in misses. + // Based on my calculator 150 Accuracy was reducing misses by too much (closer to 20%) + // NOTE: This doesn't mean if you have a 30% miss chance you now miss 15%. It means if you have a 30% miss chance you now have a 30% * (100% - 15%) = 30% * 85% = 25.5% miss chance + // Using same scale factor for Avoidance and Accuracy since they impact the formula about the same. + accuracy += itembonuses.HitChance * RuleI(Combat, PCAccuracyAvoidanceMod2Scale) / 100; + } //518 Increase ATK accuracy by percentage, stackable auto atkhit_bonus = itembonuses.Attack_Accuracy_Max_Percent + aabonuses.Attack_Accuracy_Max_Percent + spellbonuses.Attack_Accuracy_Max_Percent; @@ -987,10 +994,20 @@ int Mob::offense(EQ::skills::SkillType skill) break; } - if (stat_bonus >= 75) + if (stat_bonus >= 75) { offense += (2 * stat_bonus - 150) / 3; + } + + // GetATK() = ATK + itembonuses.ATK + spellbonuses.ATK. However, ATK appears to already be itembonuses.ATK + spellbonuses.ATK for PCs, so as is, it is double counting attack + // This causes attack to be significantly more important than it should be based on era rule of thumbs. I do not want to change the GetATK() function in case doing so breaks something, + // so instead I am just adding a /2 to remedy the double counting. NPCs do not have this issue, so they are broken up. + // PCAttackPowerScaling is used to help bring attack power further in line with era estimates. + if (IsOfClientBotMerc()) { + offense += (GetATK() / 2 + GetPetATKBonusFromOwner()) * RuleI(Combat, PCAttackPowerScaling) / 100; + } else { + offense += GetATK(); + } - offense += GetATK() + GetPetATKBonusFromOwner(); return offense; } diff --git a/zone/tune.cpp b/zone/tune.cpp index 68f648c4b..9b2904704 100644 --- a/zone/tune.cpp +++ b/zone/tune.cpp @@ -1124,17 +1124,28 @@ int64 Mob::Tuneoffense(EQ::skills::SkillType skill, int atk_override, int add_at break; } - if (stat_bonus >= 75) + if (stat_bonus >= 75) { offense += (2 * stat_bonus - 150) / 3; + } int32 tune_atk = GetATK(); + + // GetATK() = ATK + itembonuses.ATK + spellbonuses.ATK. However, ATK appears to already be itembonuses.ATK + spellbonuses.ATK for PCs, so as is, it is double counting attack + // This causes attack to be significantly more important than it should be based on era rule of thumbs. I do not want to change the GetATK() function in case doing so breaks something, + // so instead I am just adding a /2 to remedy the double counting. NPCs do not have this issue, so they are broken up. + // PCAttackPowerScaling is used to help bring attack power further in line with era estimates. + if (IsOfClientBotMerc()) { + offense += (GetATK() / 2 + GetPetATKBonusFromOwner()) * RuleI(Combat, PCAttackPowerScaling) / 100; + } else { + offense += GetATK(); + } + if (atk_override) { tune_atk = atk_override; } tune_atk += add_atk; - offense += tune_atk + GetPetATKBonusFromOwner(); return offense; } @@ -1267,8 +1278,15 @@ int64 Mob::TuneGetTotalToHit(EQ::skills::SkillType skill, int chance_mod, int ac // unsure on the stacking order of these effects, rather hard to parse // item mod2 accuracy isn't applied to range? Theory crafting and parses back it up I guess // mod2 accuracy -- flat bonus - if (skill != EQ::skills::SkillArchery && skill != EQ::skills::SkillThrowing) + if (skill != EQ::skills::SkillArchery && skill != EQ::skills::SkillThrowing) { accuracy += itembonuses.HitChance; + } else { + // Applying a scale factor as sources suggest Accuracy should reduce number of missing by 0.1% per point, so 150 = 15% reduction in misses. + // Based on my calculator 150 Accuracy was reducing misses by too much (closer to 20%) + // NOTE: This doesn't mean if you have a 30% miss chance you now miss 15%. It means if you have a 30% miss chance you now have a 30% * (100% - 15%) = 30% * 85% = 25.5% miss chance + // Using same scale factor for Avoidance and Accuracy since they impact the formula about the same. + accuracy += itembonuses.HitChance * RuleI(Combat, PCAccuracyAvoidanceMod2Scale) / 100; + } //518 Increase ATK accuracy by percentage, stackable auto atkhit_bonus = itembonuses.Attack_Accuracy_Max_Percent + aabonuses.Attack_Accuracy_Max_Percent + spellbonuses.Attack_Accuracy_Max_Percent;