diff --git a/common/ruletypes.h b/common/ruletypes.h index cb73f3983..977ef9cdc 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -432,8 +432,10 @@ RULE_BOOL(Spells, AlwaysSendTargetsBuffs, false, "Ignore Leadership Alternate Ab RULE_BOOL(Spells, FlatItemExtraSpellAmt, false, "Allow SpellDmg stat to affect all spells, regardless of cast time/cooldown/etc") RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false, "Ignore the 5 level spread on applying SpellDmg") RULE_BOOL(Spells, ItemExtraSpellAmtCalcAsPercent, false, "Apply the Item stats Spell Dmg and Heal Amount as Percentage-based modifiers instead of flat additions") -RULE_REAL(Spells, BreakFeignDeathWhenCastOn, 2.0, "Percentage that fd will break when you resist a spell") -RULE_REAL(Spells, BreakSneakWhenCastOn, 2.0, "Percentage that sneak will break when you resist a spell") +RULE_REAL(Spells, BreakFeignDeathWhenCastOn, 2.0, "Percentage that Feign Death will break when you resist a spell") +RULE_REAL(Spells, BreakSneakWhenCastOn, 2.0, "Percentage that Sneak will break when you resist a spell") +RULE_BOOL(Spells, EnableResistSoftCap, false, "Enabled resist softcap and can be adjusted by rule, SpellResistSoftCap") +RULE_INT(Spells, SpellResistSoftCap, 255, "Softcap for spell resists.") RULE_BOOL(Spells, AllowItemTGB, false, "Target group buff (/tgb) doesn't work with items on live, custom servers want it though") RULE_BOOL(Spells, NPCInnateProcOverride, true, "NPC innate procs override the target type to single target") RULE_BOOL(Spells, OldRainTargets, false, "Use old incorrectly implemented maximum targets for rains") diff --git a/zone/spells.cpp b/zone/spells.cpp index 4b5564973..9e703a45a 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -5187,8 +5187,22 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use //Add our level, resist and -spell resist modifier to our roll chance resist_chance += level_mod; - resist_chance += resist_modifier; - resist_chance += target_resist; + if (RuleB(Spells, EnableResistSoftCap)) { + int soft_cap_level_modifier; + + if (GetLevel() > 60) { + soft_cap_level_modifier = (GetLevel() - 60) * 10; + } + + if ((target_resist + resist_modifier) > (RuleI(Spells, SpellResistSoftCap) + soft_cap_level_modifier)) { + resist_chance += RuleI(Spells, SpellResistSoftCap) + soft_cap_level_modifier; + } else { + resist_chance += target_resist + resist_modifier; + } + } else { + resist_chance += resist_modifier; + resist_chance += target_resist; + } //Do our min and max resist checks. if(resist_chance > spells[spell_id].max_resist && spells[spell_id].max_resist != 0) @@ -5221,13 +5235,11 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use } //Finally our roll - int roll = zone->random.Int(0, 200); - if(roll > resist_chance) - { + int roll = zone->random.Int(0, RuleB(Spells, EnableResistSoftCap) ? RuleI(Spells, SpellResistSoftCap) : 200); + + if(roll > resist_chance) { return 100; - } - else - { + } else { //This is confusing but it's basically right //It skews partial resists up over 100 more often than not if(!IsPartialResistableSpell(spell_id))