diff --git a/src/game/Creature.h b/src/game/Creature.h index 9711cd6fe..c962ff6c6 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -429,11 +429,29 @@ class MANGOS_DLL_SPEC Creature : public Unit void AI_SendMoveToPacket(float x, float y, float z, uint32 time, MonsterMovementFlags MovementFlags, uint8 type); CreatureAI* AI() { return i_AI; } - void AddMonsterMoveFlag(MonsterMovementFlags f) { m_monsterMoveFlags = MonsterMovementFlags(m_monsterMoveFlags | f); } - void RemoveMonsterMoveFlag(MonsterMovementFlags f) { m_monsterMoveFlags = MonsterMovementFlags(m_monsterMoveFlags & ~f); } + void AddMonsterMoveFlag(MonsterMovementFlags f) + { + bool need_walk_sync = (f & MONSTER_MOVE_WALK) != (m_monsterMoveFlags & MONSTER_MOVE_WALK); + m_monsterMoveFlags = MonsterMovementFlags(m_monsterMoveFlags | f); + if (need_walk_sync) + UpdateWalkMode(this,false); + } + void RemoveMonsterMoveFlag(MonsterMovementFlags f) + { + bool need_walk_sync = (f & MONSTER_MOVE_WALK) != (m_monsterMoveFlags & MONSTER_MOVE_WALK); + m_monsterMoveFlags = MonsterMovementFlags(m_monsterMoveFlags & ~f); + if (need_walk_sync) + UpdateWalkMode(this,false); + } bool HasMonsterMoveFlag(MonsterMovementFlags f) const { return m_monsterMoveFlags & f; } MonsterMovementFlags GetMonsterMoveFlags() const { return m_monsterMoveFlags; } - void SetMonsterMoveFlags(MonsterMovementFlags f) { m_monsterMoveFlags = f; } + void SetMonsterMoveFlags(MonsterMovementFlags f) + { + bool need_walk_sync = (f & MONSTER_MOVE_WALK) != (m_monsterMoveFlags & MONSTER_MOVE_WALK); + m_monsterMoveFlags = f; // need set before + if (need_walk_sync) + UpdateWalkMode(this,false); + } void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 4528ae0ca..9555fc50d 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -299,9 +299,6 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight()) plMover->HandleFall(movementInfo); - if ((opcode == MSG_MOVE_SET_WALK_MODE || opcode == MSG_MOVE_SET_RUN_MODE) && plMover) - plMover->UpdateWalkModeForPets(movementInfo.HasMovementFlag(MOVEMENTFLAG_WALK_MODE)); - if (plMover && (movementInfo.HasMovementFlag(MOVEMENTFLAG_SWIMMING) != plMover->IsInWater())) { // now client not include swimming flag in case jumping under water @@ -323,6 +320,10 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) plMover->m_movementInfo = movementInfo; plMover->UpdateFallInformationIfNeed(movementInfo, opcode); + // after move info set + if ((opcode == MSG_MOVE_SET_WALK_MODE || opcode == MSG_MOVE_SET_RUN_MODE)) + plMover->UpdateWalkMode(plMover,false); + if(plMover->isMovingOrTurning()) plMover->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index dabf4ca23..0044a8a45 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -293,7 +293,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana); } - UpdateWalkModeForPets(owner->HasMovementFlag(MOVEMENTFLAG_WALK_MODE)); + UpdateWalkMode(owner); AIM_Initialize(); map->Add((Creature*)this); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 98747f8ae..90c85779e 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3524,8 +3524,7 @@ void Spell::EffectSummon(uint32 i) spawnCreature->GetCharmInfo()->SetPetNumber(pet_number, false); - if (m_caster->GetTypeId() == TYPEID_PLAYER) - spawnCreature->UpdateWalkModeForPets(((Player*)m_caster)->HasMovementFlag(MOVEMENTFLAG_WALK_MODE)); + spawnCreature->UpdateWalkMode(m_caster); spawnCreature->AIM_Initialize(); spawnCreature->InitPetCreateSpells(); @@ -4393,8 +4392,7 @@ void Spell::EffectSummonPet(uint32 i) NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000); NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); - if (m_caster->GetTypeId() == TYPEID_PLAYER) - NewSummon->UpdateWalkModeForPets(((Player*)m_caster)->HasMovementFlag(MOVEMENTFLAG_WALK_MODE)); + NewSummon->UpdateWalkMode(m_caster); NewSummon->GetCharmInfo()->SetPetNumber(pet_number, true); // this enables pet details window (Shift+P) diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp index 5aceaf944..83862e24d 100644 --- a/src/game/TargetedMovementGenerator.cpp +++ b/src/game/TargetedMovementGenerator.cpp @@ -226,10 +226,23 @@ void ChaseMovementGenerator::Reset(T &owner) } //-----------------------------------------------// +template<> +void FollowMovementGenerator::_updateWalkMode(Creature &u) +{ + if (i_target.isValid() && u.isPet()) + u.UpdateWalkMode(i_target.getTarget()); +} + +template<> +void FollowMovementGenerator::_updateWalkMode(Player &) +{ +} + template<> void FollowMovementGenerator::Initialize(Player &owner) { owner.addUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE); + _updateWalkMode(owner); _setTargetLocation(owner); } @@ -237,6 +250,7 @@ template<> void FollowMovementGenerator::Initialize(Creature &owner) { owner.addUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE); + _updateWalkMode(owner); if (((Creature*)&owner)->canFly()) owner.AddMonsterMoveFlag(MONSTER_MOVE_FLY); @@ -248,12 +262,14 @@ template void FollowMovementGenerator::Finalize(T &owner) { owner.clearUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE); + _updateWalkMode(owner); } template void FollowMovementGenerator::Interrupt(T &owner) { owner.clearUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE); + _updateWalkMode(owner); } template diff --git a/src/game/TargetedMovementGenerator.h b/src/game/TargetedMovementGenerator.h index 5fd78cd8c..0c2d9e33c 100644 --- a/src/game/TargetedMovementGenerator.h +++ b/src/game/TargetedMovementGenerator.h @@ -89,7 +89,7 @@ class MANGOS_DLL_SPEC ChaseMovementGenerator : public TargetedMovementGeneratorM static void _clearUnitStateMove(T &u) { u.clearUnitState(UNIT_STAT_CHASE_MOVE); } static void _addUnitStateMove(T &u) { u.addUnitState(UNIT_STAT_CHASE_MOVE); } - bool _lostTarget(T &u) const { return u.getVictim() != i_target.getTarget(); } + bool _lostTarget(T &u) const { return u.getVictim() != GetTarget(); } void _reachTarget(T &); }; @@ -114,6 +114,8 @@ class MANGOS_DLL_SPEC FollowMovementGenerator : public TargetedMovementGenerator static void _addUnitStateMove(T &u) { u.addUnitState(UNIT_STAT_FOLLOW_MOVE); } bool _lostTarget(T &) const { return false; } void _reachTarget(T &) {} + private: + void _updateWalkMode(T &u); }; #endif diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c1e90a439..9b6dface5 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10394,19 +10394,23 @@ bool Unit::canDetectInvisibilityOf(Unit const* u) const return false; } -struct UpdateWalkModeForPetsHelper +struct UpdateWalkModeHelper { - explicit UpdateWalkModeForPetsHelper(bool _on) : on(_on) {} - void operator()(Unit* unit) const { unit->UpdateWalkModeForPets(on); } - bool on; + explicit UpdateWalkModeHelper(Unit* _source) : source(_source) {} + void operator()(Unit* unit) const { unit->UpdateWalkMode(source, true); } + Unit* source; }; -void Unit::UpdateWalkModeForPets(bool on) +void Unit::UpdateWalkMode(Unit* source, bool self) { if (GetTypeId() == TYPEID_PLAYER) - ((Player*)this)->CallForAllControlledUnits(UpdateWalkModeForPetsHelper(on),false,true,true,true); - else + ((Player*)this)->CallForAllControlledUnits(UpdateWalkModeHelper(source),false,true,true,true); + else if (self) { + bool on = source->GetTypeId() == TYPEID_PLAYER + ? ((Player*)source)->HasMovementFlag(MOVEMENTFLAG_WALK_MODE) + : ((Creature*)source)->HasMonsterMoveFlag(MONSTER_MOVE_WALK); + if (on) { if (((Creature*)this)->isPet() && hasUnitState(UNIT_STAT_FOLLOW)) @@ -10417,9 +10421,9 @@ void Unit::UpdateWalkModeForPets(bool on) if (((Creature*)this)->isPet()) ((Creature*)this)->RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); } - - CallForAllControlledUnits(UpdateWalkModeForPetsHelper(on),false,true,true); } + else + CallForAllControlledUnits(UpdateWalkModeHelper(source),false,true,true); } void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) diff --git a/src/game/Unit.h b/src/game/Unit.h index c279d4471..dc214155d 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -448,10 +448,6 @@ enum UnitState UNIT_STAT_IN_FLIGHT | UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING, - UNIT_STAT_MOVE_INTERRUPRED= UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED | - UNIT_STAT_IN_FLIGHT | UNIT_STAT_DISTRACTED | - UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING, - // not react at move in sight or other UNIT_STAT_CAN_NOT_REACT = UNIT_STAT_STUNNED | UNIT_STAT_DIED | UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING, @@ -1561,7 +1557,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage); void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, bool canReflect = false); - void UpdateWalkModeForPets(bool on); + void UpdateWalkMode(Unit* source, bool self = true); void UpdateSpeed(UnitMoveType mtype, bool forced); float GetSpeed( UnitMoveType mtype ) const; float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 439740229..53a6e6cfa 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9208" + #define REVISION_NR "9209" #endif // __REVISION_NR_H__