diff --git a/zone/attack.cpp b/zone/attack.cpp index efb90cd95..2bf150d9c 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3863,7 +3863,7 @@ int64 Mob::ReduceAllDamage(int64 damage) if (spellbonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_MITIGIATION]) { int64 end_absorb = spellbonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_MITIGIATION] + itembonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_MITIGIATION] + aabonuses.EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_MITIGIATION]; - int64 end_absorb_cap = spellbonuses.EnduranceAbsorbPercentCap + itembonuses.EnduranceAbsorbPercentCap + aabonuses.EnduranceAbsorbPercentDamage; + int32 end_absorb_cap = spellbonuses.EnduranceAbsorbPercentCap + itembonuses.EnduranceAbsorbPercentCap + aabonuses.EnduranceAbsorbPercentCap; int64 damage_reduced = damage * end_absorb / 100; //If hit for 1000, at 10% then lower damage by 100; if (damage_reduced > end_absorb_cap) damage_reduced = end_absorb_cap; @@ -4304,61 +4304,6 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons damage = 0; } - //send damage packet before updating hp to prevent double damage bugs and make the game feel more responsive. - if (!iBuffTic) { //buff ticks do not send damage, instead they just call SendHPUpdate(), which is done above - static EQApplicationPacket p(OP_Damage, sizeof(CombatDamage_Struct)); - auto a = (CombatDamage_Struct *) p.pBuffer; - a->target = GetID(); - - if (!attacker) { - a->source = 0; - } else if (attacker->IsClient() && attacker->CastToClient()->GMHideMe()) { - a->source = 0; - } else { - a->source = attacker->GetID(); - } - - a->type = (EQ::ValueWithin(skill_used, EQ::skills::Skill1HBlunt, EQ::skills::Skill2HPiercing)) ? - SkillDamageTypes[skill_used] : SkillDamageTypes[EQ::skills::SkillHandtoHand]; // was 0x1c - a->damage = damage; - a->spellid = spell_id; - - if (special == eSpecialAttacks::AERampage) { - a->special = 1; - } else if (special == eSpecialAttacks::Rampage) { - a->special = 2; - } else { - a->special = 0; - } - - a->hit_heading = attacker ? attacker->GetHeading() : 0.0f; - if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() && - (IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) { - a->force = EQ::skills::GetSkillMeleePushForce(skill_used); - - if (RuleR(Combat, MeleePushForceClientPercent) && IsClient()) { - a->force += a->force * RuleR(Combat, MeleePushForceClientPercent); - } - - if (RuleR(Combat, MeleePushForcePetPercent) && IsPet()) { - a->force += a->force * RuleR(Combat, MeleePushForcePetPercent); - } - - if (IsNPC()) { - if (!RuleB(Combat, NPCtoNPCPush) && attacker && attacker->IsNPC()) { - a->force = 0.0f; // 2013 change that disabled NPC vs NPC push - } else { - a->force *= 0.10f; // force against NPCs is divided by 10 I guess? ex bash is 0.3, parsed 0.03 against an NPC - } - - if (ForcedMovement == 0 && a->force != 0.0f && position_update_melee_push_timer.Check()) { - m_Delta.x += a->force * g_Math.FastSin(a->hit_heading); - m_Delta.y += a->force * g_Math.FastCos(a->hit_heading); - ForcedMovement = 3; - } - } - } - } SetHP(int64(GetHP() - damage)); @@ -4593,64 +4538,61 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons } } } //end `if damage was done` - else { - if (!iBuffTic) { //buff ticks do not send damage, instead they just call SendHPUpdate(), which is done above - static EQApplicationPacket p(OP_Damage, sizeof(CombatDamage_Struct)); - auto a = (CombatDamage_Struct *) p.pBuffer; - a->target = GetID(); - if (!attacker) { - a->source = 0; - } else if (attacker->IsClient() && attacker->CastToClient()->GMHideMe()) { - a->source = 0; - } else { - a->source = attacker->GetID(); + + //send damage packet before updating hp to prevent double damage bugs and make the game feel more responsive. + if (!iBuffTic) { //buff ticks do not send damage, instead they just call SendHPUpdate(), which is done above + static EQApplicationPacket p(OP_Damage, sizeof(CombatDamage_Struct)); + auto a = (CombatDamage_Struct *) p.pBuffer; + a->target = GetID(); + if (!attacker) { + a->source = 0; + } else if (attacker->IsClient() && attacker->CastToClient()->GMHideMe()) { + a->source = 0; + } else { + a->source = attacker->GetID(); + } + + a->type = (EQ::ValueWithin(skill_used, EQ::skills::Skill1HBlunt, EQ::skills::Skill2HPiercing)) ? + SkillDamageTypes[skill_used] : SkillDamageTypes[EQ::skills::SkillHandtoHand]; // was 0x1c + a->damage = damage; + a->spellid = spell_id; + + if (special == eSpecialAttacks::AERampage) { + a->special = 1; + } else if (special == eSpecialAttacks::Rampage) { + a->special = 2; + } else { + a->special = 0; + } + + a->hit_heading = attacker ? attacker->GetHeading() : 0.0f; + if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() && + (IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) { + a->force = EQ::skills::GetSkillMeleePushForce(skill_used); + + if (RuleR(Combat, MeleePushForceClientPercent) && IsClient()) { + a->force += a->force * RuleR(Combat, MeleePushForceClientPercent); } - a->type = (EQ::ValueWithin(skill_used, EQ::skills::Skill1HBlunt, EQ::skills::Skill2HPiercing)) ? - SkillDamageTypes[skill_used] : SkillDamageTypes[EQ::skills::SkillHandtoHand]; // was 0x1c - a->damage = damage; - a->spellid = spell_id; - - if (special == eSpecialAttacks::AERampage) { - a->special = 1; - } else if (special == eSpecialAttacks::Rampage) { - a->special = 2; - } else { - a->special = 0; + if (RuleR(Combat, MeleePushForcePetPercent) && IsPet()) { + a->force += a->force * RuleR(Combat, MeleePushForcePetPercent); } - a->hit_heading = attacker ? attacker->GetHeading() : 0.0f; - if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() && - (IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) { - a->force = EQ::skills::GetSkillMeleePushForce(skill_used); - - if (RuleR(Combat, MeleePushForceClientPercent) && IsClient()) { - a->force += a->force * RuleR(Combat, MeleePushForceClientPercent); + if (IsNPC()) { + if (!RuleB(Combat, NPCtoNPCPush) && attacker && attacker->IsNPC()) { + a->force = 0.0f; // 2013 change that disabled NPC vs NPC push + } else { + a->force *= 0.10f; // force against NPCs is divided by 10 I guess? ex bash is 0.3, parsed 0.03 against an NPC } - if (RuleR(Combat, MeleePushForcePetPercent) && IsPet()) { - a->force += a->force * RuleR(Combat, MeleePushForcePetPercent); - } - - if (IsNPC()) { - if (!RuleB(Combat, NPCtoNPCPush) && attacker && attacker->IsNPC()) { - a->force = 0.0f; // 2013 change that disabled NPC vs NPC push - } else { - a->force *= 0.10f; // force against NPCs is divided by 10 I guess? ex bash is 0.3, parsed 0.03 against an NPC - } - - if (ForcedMovement == 0 && a->force != 0.0f && position_update_melee_push_timer.Check()) { - m_Delta.x += a->force * g_Math.FastSin(a->hit_heading); - m_Delta.y += a->force * g_Math.FastCos(a->hit_heading); - ForcedMovement = 3; - } + if (ForcedMovement == 0 && a->force != 0.0f && position_update_melee_push_timer.Check()) { + m_Delta.x += a->force * g_Math.FastSin(a->hit_heading); + m_Delta.y += a->force * g_Math.FastCos(a->hit_heading); + ForcedMovement = 3; } } } - } - - //Note: if players can become pets, they will not receive damage messages of their own //this was done to simplify the code here (since we can only effectively skip one mob on queue) @@ -4879,6 +4821,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons ); } } + SendHPUpdate(true); } void Mob::HealDamage(uint64 amount, Mob* caster, uint16 spell_id) diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 5ccfe6b43..24b004cbf 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -3117,7 +3117,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne new_bonus->EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_MITIGIATION] = effect_value; new_bonus->EnduranceAbsorbPercentDamage[SBIndex::ENDURANCE_ABSORD_DRAIN_PER_HP] = limit_value; } - new_bonus->EnduranceAbsorbPercent += max_value; + new_bonus->EnduranceAbsorbPercentCap += max_value; break; } diff --git a/zone/common.h b/zone/common.h index b548ba639..c9f30ec51 100644 --- a/zone/common.h +++ b/zone/common.h @@ -493,7 +493,7 @@ struct StatBonuses { uint32 ManaAbsorbPercentDamage; // 0 = Mitigation value uint32 ManaAbsorbPercentDamageCap; // 0 = Mitigation value int32 EnduranceAbsorbPercentDamage[2]; // 0 = Mitigation value 1 = Percent Endurance drain per HP lost - uint32 EnduranceAbsorbPercentCap; + int32 EnduranceAbsorbPercentCap; int32 ShieldBlock; // Chance to Shield Block int32 BlockBehind; // Chance to Block Behind (with our without shield) bool CriticalRegenDecay; // increase critical regen chance, decays based on spell level cast