[Rule] Backstab Haste Correction (#4337)

- Haste should only provide a max of a 2 s reduction to Backstab cooldown, but it seems that while BackstabReuseTimer can be reduced, there is another timer (repop on the button) that is controlling the actual cooldown.  I'm not sure how this is implemented, but it is impacted by spell haste (including bard v2 and v3), but not worn haste. This code applies an adjustment to backstab accuracy to compensate for this so that Rogue DPS doesn't significantly outclass other classes.
This commit is contained in:
Fryguy 2024-05-26 11:34:36 -04:00 committed by GitHub
parent 0bceee5622
commit 68f40c9255
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 3 deletions

View File

@ -613,6 +613,7 @@ RULE_BOOL(Combat, UseEnhancedMobStaticWeaponSkill, false, "Toggle to enabled the
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_BOOL(Combat, AllowRaidTargetBlind, false, "Toggle to allow raid targets to be blinded, default is false (Live-like)")
RULE_BOOL(Combat, RogueBackstabHasteCorrection, false, "Toggle to enable correction for Haste impacting Backstab DPS too much. DEFAULT: false")
RULE_CATEGORY_END()
RULE_CATEGORY(NPC)

View File

@ -257,10 +257,40 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 bas
my_hit.offense = offense(my_hit.skill);
my_hit.tohit = GetTotalToHit(my_hit.skill, 0);
// Rogue Backstab Haste Correction
// Haste should only provide a max of a 2 s reduction to Backstab cooldown, but it seems that while BackstabReuseTimer can be reduced, there is another timer (repop on the button)
// that is controlling the actual cooldown. I'm not sure how this is implemented, but it is impacted by spell haste (including bard v2 and v3), but not worn haste.
// This code applies an adjustment to backstab accuracy to compensate for this so that Rogue DPS doesn't significantly outclass other classes.
if (
RuleB(Combat, RogueBackstabHasteCorrection) &&
skill == EQ::skills::SkillBackstab &&
GetHaste() > 100
) {
int haste_spell = spellbonuses.haste - spellbonuses.inhibitmelee + spellbonuses.hastetype2 + spellbonuses.hastetype3;
int haste_worn = itembonuses.haste;
// Compute Intended Cooldown. 100% Spell = 1 s reduction (max), 40% Worn = 1 s reduction (max).
int reduction_intended_spell = haste_spell > 100 ? 100 : haste_spell;
int reduction_intended_worn = 2.5 * (haste_worn > 40 ? 40 : haste_worn);
int16 intended_cooldown = 1000 - reduction_intended_spell - reduction_intended_worn;
// Compute Actual Cooldown. Actual only impacted by spell haste ( + v2 + v3), and is 10 s / (100 + haste)
int actual_cooldown = 100000 / (100 + haste_spell);
// Compute Accuracy Adjustment
int backstab_accuracy_adjust = actual_cooldown * 1000 / intended_cooldown;
// orig_accuracy = my_hit.tohit;
int adjusted_accuracy = my_hit.tohit * backstab_accuracy_adjust / 1000;
my_hit.tohit = adjusted_accuracy;
}
my_hit.hand = EQ::invslot::slotPrimary; // Avoid checks hand for throwing/archery exclusion, primary should
// work for most
if (skill == EQ::skills::SkillThrowing || skill == EQ::skills::SkillArchery)
if (skill == EQ::skills::SkillThrowing || skill == EQ::skills::SkillArchery) {
my_hit.hand = EQ::invslot::slotRange;
}
DoAttack(who, my_hit);
@ -268,16 +298,20 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 bas
who->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, skill, false);
// Make sure 'this' has not killed the target and 'this' is not dead (Damage shield ect).
if (!GetTarget())
if (!GetTarget()) {
return;
if (HasDied())
}
if (HasDied()) {
return;
}
TryCastOnSkillUse(who, skill);
if (HasSkillProcs()) {
TrySkillProc(who, skill, ReuseTime * 1000);
}
if (my_hit.damage_done > 0 && HasSkillProcSuccess()) {
TrySkillProc(who, skill, ReuseTime * 1000, true);
}