diff --git a/zone/attack.cpp b/zone/attack.cpp index d605a0da6..62625cac5 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1217,7 +1217,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b if (other->CheckHitChance(this, skillinuse, Hand, hit_chance_bonus)) { other->MeleeMitigation(this, damage, min_hit, opts); if (damage > 0) - CommonOutgoingHitSuccess(other, damage, skillinuse); + CommonOutgoingHitSuccess(other, damage, skillinuse,opts); Log.Out(Logs::Detail, Logs::Combat, "Final damage after all reductions: %d", damage); } else { Log.Out(Logs::Detail, Logs::Combat, "Attack missed. Damage set to 0."); @@ -1746,7 +1746,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool if(other->IsClient() && other->CastToClient()->IsSitting()) { Log.Out(Logs::Detail, Logs::Combat, "Client %s is sitting. Hitting for max damage (%d).", other->GetName(), (max_dmg+eleBane)); damage = (max_dmg+eleBane); - damage += (itembonuses.HeroicSTR / 10) + (damage * other->GetSkillDmgTaken(skillinuse) / 100) + GetSkillDmgAmt(skillinuse); + damage += (itembonuses.HeroicSTR / 10) + (damage * other->GetSkillDmgTaken(skillinuse, opts) / 100) + GetSkillDmgAmt(skillinuse); if(opts) { damage *= opts->damage_percent; @@ -1777,7 +1777,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool } else { if (other->CheckHitChance(this, skillinuse, Hand, hit_chance_bonus)) { other->MeleeMitigation(this, damage, min_dmg+eleBane, opts); - CommonOutgoingHitSuccess(other, damage, skillinuse); + CommonOutgoingHitSuccess(other, damage, skillinuse, opts); } else { damage = 0; } @@ -4055,7 +4055,7 @@ void Mob::DoRiposte(Mob *defender) } } -void Mob::ApplyMeleeDamageBonus(uint16 skill, int32 &damage){ +void Mob::ApplyMeleeDamageBonus(uint16 skill, int32 &damage,ExtraAttackOptions *opts){ if(!RuleB(Combat, UseIntervalAC)){ if(IsNPC()){ //across the board NPC damage bonuses. @@ -4068,7 +4068,13 @@ void Mob::ApplyMeleeDamageBonus(uint16 skill, int32 &damage){ } } - damage += damage * GetMeleeDamageMod_SE(skill) / 100; + int dmgbonusmod = 0; + + dmgbonusmod += GetMeleeDamageMod_SE(skill); + if (opts) + dmgbonusmod += opts->melee_damage_bonus_flat; + + damage += damage * dmgbonusmod / 100; } bool Mob::HasDied() { @@ -4426,14 +4432,14 @@ int32 Mob::RuneAbsorb(int32 damage, uint16 type) return damage; } -void Mob::CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes skillInUse) +void Mob::CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes skillInUse, ExtraAttackOptions *opts) { if (!defender) return; - ApplyMeleeDamageBonus(skillInUse, damage); - damage += (damage * defender->GetSkillDmgTaken(skillInUse) / 100) + (GetSkillDmgAmt(skillInUse) + defender->GetFcDamageAmtIncoming(this, 0, true, skillInUse)); - TryCriticalHit(defender, skillInUse, damage); + ApplyMeleeDamageBonus(skillInUse, damage, opts); + damage += (damage * defender->GetSkillDmgTaken(skillInUse, opts) / 100) + (GetSkillDmgAmt(skillInUse) + defender->GetFcDamageAmtIncoming(this, 0, true, skillInUse)); + TryCriticalHit(defender, skillInUse, damage,opts); CheckNumHitsRemaining(NumHit::OutgoingHitSuccess); } diff --git a/zone/common.h b/zone/common.h index bcae779a9..8a6d9c783 100644 --- a/zone/common.h +++ b/zone/common.h @@ -614,7 +614,8 @@ struct ExtraAttackOptions { : damage_percent(1.0f), damage_flat(0), armor_pen_percent(0.0f), armor_pen_flat(0), crit_percent(1.0f), crit_flat(0.0f), - hate_percent(1.0f), hate_flat(0), hit_chance(0) + hate_percent(1.0f), hate_flat(0), hit_chance(0), + melee_damage_bonus_flat(0), skilldmgtaken_bonus_flat(0) { } float damage_percent; @@ -626,6 +627,9 @@ struct ExtraAttackOptions { float hate_percent; int hate_flat; int hit_chance; + int melee_damage_bonus_flat; + int skilldmgtaken_bonus_flat; + }; #endif diff --git a/zone/mob.cpp b/zone/mob.cpp index 13a246ee4..05b6b828a 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -3786,7 +3786,7 @@ int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining) return value; } -int16 Mob::GetSkillDmgTaken(const SkillUseTypes skill_used) +int16 Mob::GetSkillDmgTaken(const SkillUseTypes skill_used, ExtraAttackOptions *opts) { int skilldmg_mod = 0; @@ -3796,6 +3796,9 @@ int16 Mob::GetSkillDmgTaken(const SkillUseTypes skill_used) skilldmg_mod += SkillDmgTaken_Mod[skill_used] + SkillDmgTaken_Mod[HIGHEST_SKILL+1]; + if (opts) + skilldmg_mod += opts->skilldmgtaken_bonus_flat; + if(skilldmg_mod < -100) skilldmg_mod = -100; diff --git a/zone/mob.h b/zone/mob.h index a3b759864..845b5fd00 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -160,13 +160,13 @@ public: uint32 TryHeadShot(Mob* defender, SkillUseTypes skillInUse); uint32 TryAssassinate(Mob* defender, SkillUseTypes skillInUse, uint16 ReuseTime); virtual void DoRiposte(Mob* defender); - void ApplyMeleeDamageBonus(uint16 skill, int32 &damage); + void ApplyMeleeDamageBonus(uint16 skill, int32 &damage,ExtraAttackOptions *opts = nullptr); virtual void MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttackOptions *opts = nullptr); virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating); bool CombatRange(Mob* other); virtual inline bool IsBerserk() { return false; } // only clients void RogueEvade(Mob *other); - void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes skillInUse); + void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes skillInUse,ExtraAttackOptions *opts = nullptr); void BreakInvisibleSpells(); void CommonBreakInvisibleFromCombat(); bool HasDied(); @@ -645,7 +645,7 @@ public: int32 GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining); int32 GetFcDamageAmtIncoming(Mob *caster, uint32 spell_id, bool use_skill = false, uint16 skill=0); int32 GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spell_id); - int16 GetSkillDmgTaken(const SkillUseTypes skill_used); + int16 GetSkillDmgTaken(const SkillUseTypes skill_used,ExtraAttackOptions *opts=nullptr); void DoKnockback(Mob *caster, uint32 pushback, uint32 pushup); int16 CalcResistChanceBonus(); int16 CalcFearResistChance();