diff --git a/src/game/Object/Pet.cpp b/src/game/Object/Pet.cpp index 6ea6c0df..80c2056d 100644 --- a/src/game/Object/Pet.cpp +++ b/src/game/Object/Pet.cpp @@ -2056,3 +2056,77 @@ void Pet::ApplyModeFlags(PetModeFlags mode, bool apply) data << uint32(m_petModeFlags); ((Player*)owner)->GetSession()->SendPacket(&data); } + +void Pet::UpdateSpeed(UnitMoveType mtype, bool forced, float ratio) +{ + Unit* unitOwner = GetOwner(); + Player *owner = unitOwner ? unitOwner->ToPlayer() : NULL; + if (!owner) + return Unit::UpdateSpeed(mtype, forced, ratio); // NPC pets are usual creatures + + int32 main_speed_mod = 0; + float stack_bonus = 1.0f; + float non_stack_bonus = 1.0f; + + switch (mtype) + { + case MOVE_WALK: + break; + case MOVE_RUN: + { + main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SPEED); + stack_bonus = GetTotalAuraMultiplier(SPELL_AURA_MOD_SPEED_ALWAYS); + non_stack_bonus = (100.0f + GetMaxPositiveAuraModifier(SPELL_AURA_MOD_SPEED_NOT_STACK)) / 100.0f; + break; + } + case MOVE_RUN_BACK: + return; + case MOVE_SWIM: + { + main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SWIM_SPEED); + break; + } + case MOVE_SWIM_BACK: + return; + default: + sLog.outError("Pet::UpdateSpeed: Unsupported move type (%d)", mtype); + return; + } + + float bonus = non_stack_bonus > stack_bonus ? non_stack_bonus : stack_bonus; + if (owner->IsMounted()) + bonus = owner->GetSpeedRate(mtype); //for mounted player, base speed of pet is the same + + // now we ready for speed calculation + float speed = main_speed_mod ? bonus * (100.0f + main_speed_mod) / 100.0f : bonus; + + switch (mtype) + { + case MOVE_RUN: + case MOVE_SWIM: + { + // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need + // TODO: possible affect only on MOVE_RUN + if (int32 normalization = GetMaxPositiveAuraModifier(SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED)) + { + // Use speed from aura + float max_speed = normalization / baseMoveSpeed[mtype]; + if (speed > max_speed) + { speed = max_speed; } + } + break; + } + default: + break; + } + + // Apply strongest slow aura mod to speed + int32 slow = GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED); + if (slow) + { speed *= (100.0f + slow) / 100.0f; } + + if (mtype == MOVE_RUN) + speed *= 1.14286f; + + SetSpeedRate(mtype, speed * ratio, forced); +} diff --git a/src/game/Object/Pet.h b/src/game/Object/Pet.h index f05f22b0..ce07dbdc 100644 --- a/src/game/Object/Pet.h +++ b/src/game/Object/Pet.h @@ -228,6 +228,7 @@ class Pet : public Creature void UpdateMaxPower(Powers power) override; void UpdateAttackPowerAndDamage(bool ranged = false) override; void UpdateDamagePhysical(WeaponAttackType attType) override; + void UpdateSpeed(UnitMoveType mtype, bool forced, float ratio = 1.0f) override; bool CanTakeMoreActiveSpells(uint32 SpellIconID); void ToggleAutocast(uint32 spellid, bool apply); diff --git a/src/game/Object/Unit.cpp b/src/game/Object/Unit.cpp index f8cf7288..b7fa5733 100644 --- a/src/game/Object/Unit.cpp +++ b/src/game/Object/Unit.cpp @@ -6873,25 +6873,6 @@ bool Unit::CanDetectInvisibilityOf(Unit const* u) const void Unit::UpdateSpeed(UnitMoveType mtype, bool forced, float ratio) { - // not in combat pet have same speed as owner - //switch (mtype) - //{ - // case MOVE_RUN: - // case MOVE_WALK: - // case MOVE_SWIM: - // if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->IsPet() && hasUnitState(UNIT_STAT_FOLLOW)) - // { - // if (Unit* owner = GetOwner()) - // { - // SetSpeedRate(mtype, owner->GetSpeedRate(mtype), forced); - // return; - // } - // } - // break; - // default: - // break; - //} - int32 main_speed_mod = 0; float stack_bonus = 1.0f; float non_stack_bonus = 1.0f; @@ -6901,7 +6882,6 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced, float ratio) case MOVE_WALK: break; case MOVE_RUN: - { if (IsMounted()) // Use on mount auras { main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED); @@ -6915,14 +6895,11 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced, float ratio) non_stack_bonus = (100.0f + GetMaxPositiveAuraModifier(SPELL_AURA_MOD_SPEED_NOT_STACK)) / 100.0f; } break; - } case MOVE_RUN_BACK: return; case MOVE_SWIM: - { main_speed_mod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SWIM_SPEED); break; - } case MOVE_SWIM_BACK: return; default: @@ -6938,7 +6915,6 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced, float ratio) { case MOVE_RUN: case MOVE_SWIM: - { // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need // TODO: possible affect only on MOVE_RUN if (int32 normalization = GetMaxPositiveAuraModifier(SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED)) @@ -6949,7 +6925,6 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced, float ratio) { speed = max_speed; } } break; - } default: break; } diff --git a/src/game/Object/Unit.h b/src/game/Object/Unit.h index 0ab6bda7..6aa70c98 100644 --- a/src/game/Object/Unit.h +++ b/src/game/Object/Unit.h @@ -3596,7 +3596,7 @@ class Unit : public WorldObject void CalculateDamageAbsorbAndResist(Unit* pCaster, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32* absorb, uint32* resist, bool canReflect = false); void CalculateAbsorbResistBlock(Unit* pCaster, SpellNonMeleeDamage* damageInfo, SpellEntry const* spellProto, WeaponAttackType attType = BASE_ATTACK); - void UpdateSpeed(UnitMoveType mtype, bool forced, float ratio = 1.0f); + virtual void UpdateSpeed(UnitMoveType mtype, bool forced, float ratio = 1.0f); float GetSpeed(UnitMoveType mtype) const; float GetSpeedRate(UnitMoveType mtype) const { return m_speed_rate[mtype]; } void SetSpeedRate(UnitMoveType mtype, float rate, bool forced = false);