diff --git a/zone/attack.cpp b/zone/attack.cpp index 7d6a071a5..0ddd13a96 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -5278,15 +5278,15 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac hit.damage_done += (hit.damage_done * pct_damage_reduction / 100) + (defender->GetFcDamageAmtIncoming(this, 0, true, hit.skill)); - if (defender->shield_ability.shielder_id = GetID()) { + if (defender->shield_ability.shielder_id) { hit.damage_done *= 0.50;//Don't round. - DoShieldDamageOnShielder(defender, hit); + DoShieldDamageOnShielder(defender, hit.damage_done, hit.skill); } CheckNumHitsRemaining(NumHit::OutgoingHitSuccess); } -void Mob::DoShieldDamageOnShielder(Mob* defender, DamageHitInfo &hit) +void Mob::DoShieldDamageOnShielder(Mob* defender, int shielder_damage_taken, EQ::skills::SkillType skillInUse) { if (!defender) { return; @@ -5315,9 +5315,9 @@ void Mob::DoShieldDamageOnShielder(Mob* defender, DamageHitInfo &hit) mitigation = std::max(mitigation, 50); - int shielder_damage_taken = hit.damage_done * 75 / 100; + shielder_damage_taken = shielder_damage_taken * mitigation / 100; - current_shielder->Damage(this, shielder_damage_taken, SPELL_UNKNOWN, hit.skill, true, -1, false, m_specialattacks); + current_shielder->Damage(this, shielder_damage_taken, SPELL_UNKNOWN, skillInUse, true, -1, false, m_specialattacks); current_shielder->CheckNumHitsRemaining(NumHit::OutgoingHitSuccess); } diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index cf28bc9c1..bfdb4553e 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -3488,17 +3488,25 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne case SE_ExtendedShielding: { - if (new_bonus->ExtendedShielding < effect_value) { - new_bonus->ExtendedShielding = effect_value; + if (AdditiveWornBonus) { + new_bonus->ExtendedShielding += effect_value; } + else if (effect_value < 0 && new_bonus->ExtendedShielding > effect_value) + new_bonus->ExtendedShielding = effect_value; + else if (effect_value > 0 && new_bonus->ExtendedShielding < effect_value) + new_bonus->ExtendedShielding = effect_value; break; } case SE_ShieldDuration: { - if (new_bonus->ShieldDuration < effect_value) { - new_bonus->ShieldDuration = effect_value; + if (AdditiveWornBonus) { + new_bonus->ShieldDuration += effect_value; } + else if (effect_value < 0 && new_bonus->ShieldDuration > effect_value) + new_bonus->ShieldDuration = effect_value; + else if (effect_value > 0 && new_bonus->ShieldDuration < effect_value) + new_bonus->ShieldDuration = effect_value; break; } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 860203a19..5aec10749 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12808,8 +12808,8 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app) LogError("OP size error: OP_Shielding expected:[{}] got:[{}]", sizeof(Shielding_Struct), app->size); return; } - //Enforce level - //Augs on shieldd? + + //TODO: Defensive makes it not cast? if (GetLevel() < 30) { return; //Client gives message @@ -12849,7 +12849,13 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app) return; } //AA to increase SPA 230 extended shielding - if (shield_target->CalculateDistance(GetX(), GetY(), GetZ()) > 15.0f) { + + int max_shielder_distance = 15; + int distance_mod = aabonuses.ExtendedShielding + itembonuses.ExtendedShielding + spellbonuses.ExtendedShielding; + max_shielder_distance += max_shielder_distance * distance_mod / 100; + max_shielder_distance = std::max(max_shielder_distance, 1); //Incase of negative effects limit it to range of 1 + + if (shield_target->CalculateDistance(GetX(), GetY(), GetZ()) > static_cast(max_shielder_distance)) { return; //Too far away, no message is given thoughh. //TODO: Timer to enforce distance check } @@ -12864,8 +12870,13 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app) shield_target->shield_ability.shield_target_id = shield_target->GetID(); //Calculate AA for adding time SPA 255 extend shield duration + int shield_duration = 12000; - shield_timer.Start(12000); + shield_duration += (aabonuses.ShieldDuration + itembonuses.ShieldDuration + spellbonuses.ShieldDuration) * 1000; + + shield_duration = std::max(shield_duration, 1000); //Incase of negative modifiers lets just make min duration 1 second. + + shield_timer.Start(shield_duration); return; } diff --git a/zone/mob.h b/zone/mob.h index 9c9d96581..e6ced76de 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1130,7 +1130,7 @@ public: Trade* trade; ShieldAbility_Struct shield_ability; - void DoShieldDamageOnShielder(Mob* defender, DamageHitInfo &hit); + void DoShieldDamageOnShielder(Mob* defender, int shielder_damage_taken, EQ::skills::SkillType skillInUse); inline int GetShielderID() { return shield_ability.shielder_id; } inline int SetShielderID(int ent_id) { shield_ability.shielder_id = ent_id; } inline int GetShieldTargetID() { return shield_ability.shield_target_id; }