[Rule] Legacy Compute Defense against modern agi based defense. (#4349)

* [Rule] Legacy Compute Defense against modern agi based defense.

In new code, AGI becomes a large contributor to avoidance at low levels, since AGI isn't capped by Level but Defense is A scale factor is implemented for PCs to reduce the effect of AGI at low levels.  This isn't applied to NPCs since they can be easily controlled via the Database.

* `snake_case`

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
This commit is contained in:
Fryguy 2024-05-26 20:27:18 -04:00 committed by GitHub
parent c50fda0f73
commit 992a5cc132
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 22 deletions

View File

@ -614,6 +614,7 @@ RULE_INT(Combat, PCAttackPowerScaling, 100, "Applies scaling to PC Attack Power
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_BOOL(Combat, LegacyComputeDefense, false, "Trim AGI Scaling of defense mostly for lower levels to help compensate for the newer agi based defense system. Default: False")
RULE_CATEGORY_END()
RULE_CATEGORY(NPC)

View File

@ -256,19 +256,44 @@ int Mob::GetTotalToHit(EQ::skills::SkillType skill, int chance_mod)
int Mob::compute_defense()
{
int defense = GetSkill(EQ::skills::SkillDefense) * 400 / 225;
defense += (8000 * (GetAGI() - 40)) / 36000;
if (IsOfClientBot()) {
defense += itembonuses.heroic_agi_avoidance;
// In new code, AGI becomes a large contributor to avoidance at low levels, since AGI isn't capped by Level but Defense is
// A scale factor is implemented for PCs to reduce the effect of AGI at low levels. This isn't applied to NPCs since they can be
// easily controlled via the Database.
if (RuleB(Combat, LegacyComputeDefense)) {
int agi_scale_factor = 1000;
if (IsOfClientBot()) {
agi_scale_factor = std::min(1000, static_cast<int>(GetLevel()) * 1000 / 70); // Scales Agi Contribution for PC's Level, max Contribution at Level 70
}
defense += agi_scale_factor * (800 * (GetAGI() - 40)) / 3600 / 1000;
if (IsOfClientBot()) {
defense += GetHeroicAGI() / 10;
}
defense += itembonuses.AvoidMeleeChance * RuleI(Combat, PCAccuracyAvoidanceMod2Scale) / 100; // item mod2
} else {
defense += (8000 * (GetAGI() - 40)) / 36000;
if (IsOfClientBot()) {
defense += itembonuses.heroic_agi_avoidance;
}
defense += itembonuses.AvoidMeleeChance; // item mod2
}
//516 SE_AC_Mitigation_Max_Percent
auto ac_bonus = itembonuses.AC_Mitigation_Max_Percent + aabonuses.AC_Mitigation_Max_Percent + spellbonuses.AC_Mitigation_Max_Percent;
if (ac_bonus)
if (ac_bonus) {
defense += round(static_cast<double>(defense) * static_cast<double>(ac_bonus) * 0.0001);
}
defense += itembonuses.AvoidMeleeChance; // item mod2
if (IsNPC())
if (IsNPC()) {
defense += CastToNPC()->GetAvoidanceRating();
}
if (IsClient()) {
double reduction = CastToClient()->GetIntoxication() / 2.0;

View File

@ -1347,7 +1347,7 @@ int64 Mob::TuneGetTotalToHit(EQ::skills::SkillType skill, int chance_mod, int ac
hit_bonus += spellbonuses.increase_archery + aabonuses.increase_archery + itembonuses.increase_archery;
hit_bonus -= hit_bonus * RuleR(Combat, ArcheryHitPenalty);
}
accuracy = (accuracy * (100 + hit_bonus)) / 100;
return accuracy;
}
@ -1381,31 +1381,43 @@ int64 Mob::TuneGetTotalDefense(int avoidance_override, int add_avoidance)
int64 Mob::Tunecompute_defense(int avoidance_override, int add_avoidance)
{
int defense = GetSkill(EQ::skills::SkillDefense) * 400 / 225;
defense += (8000 * (GetAGI() - 40)) / 36000;
if (IsOfClientBot()) {
if (avoidance_override) {
defense = avoidance_override;
// In new code, AGI becomes a large contributor to avoidance at low levels, since AGI isn't capped by Level but Defense is
// A scale factor is implemented for PCs to reduce the effect of AGI at low levels. This isn't applied to NPCs since they can be
// easily controlled via the Database.
if (RuleB(Combat, LegacyComputeDefense)) {
int agi_scale_factor = 1000;
if (IsOfClientBot()) {
agi_scale_factor = std::min(1000, static_cast<int>(GetLevel()) * 1000 / 70); // Scales Agi Contribution for PC's Level, max Contribution at Level 70
}
else {
defense += agi_scale_factor * (800 * (GetAGI() - 40)) / 3600 / 1000;
if (IsOfClientBot()) {
defense += GetHeroicAGI() / 10;
}
defense += itembonuses.AvoidMeleeChance * RuleI(Combat, PCAccuracyAvoidanceMod2Scale) / 100; // item mod2
} else {
defense += (8000 * (GetAGI() - 40)) / 36000;
if (IsOfClientBot()) {
defense += itembonuses.heroic_agi_avoidance;
}
defense += add_avoidance; //1 pt = 10 heroic agi
defense += itembonuses.AvoidMeleeChance; // item mod2
}
//516 SE_AC_Mitigation_Max_Percent
auto ac_bonus = itembonuses.AC_Mitigation_Max_Percent + aabonuses.AC_Mitigation_Max_Percent + spellbonuses.AC_Mitigation_Max_Percent;
if (ac_bonus)
if (ac_bonus) {
defense += round(static_cast<double>(defense) * static_cast<double>(ac_bonus) * 0.0001);
}
defense += itembonuses.AvoidMeleeChance; // item mod2
if (IsNPC()) {
if (avoidance_override) {
defense += avoidance_override;
}
else {
defense += CastToNPC()->GetAvoidanceRating();
}
defense += add_avoidance;
defense += CastToNPC()->GetAvoidanceRating();
}
if (IsClient()) {