From 695a7402ad809410f74cef08af5f184ecff84d9c Mon Sep 17 00:00:00 2001 From: Footman Date: Fri, 12 Feb 2021 13:42:41 +0300 Subject: [PATCH] fix(Core): creature movement bugs (#4544) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix UpdateEnvironmentIfNeeded was changing flying creature status all the time. closes: #4447 - fix hovering state was causing bugs at #4466 - add animation state priority: fly > hover > ground Co-authored-by: Wotex Co-authored-by: Francesco Borzì Co-authored-by: Patrick Lewis --- .../rev_1613069340138846000.sql | 3 ++ .../game/Entities/Creature/Creature.cpp | 28 +++++++++++++++---- src/server/game/Entities/Creature/Creature.h | 2 ++ src/server/game/Entities/Unit/Unit.cpp | 27 ++++++++++++------ .../IcecrownCitadel/boss_sindragosa.cpp | 8 +++--- .../IcecrownCitadel/icecrown_citadel.cpp | 23 +++++++-------- 6 files changed, 61 insertions(+), 30 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1613069340138846000.sql diff --git a/data/sql/updates/pending_db_world/rev_1613069340138846000.sql b/data/sql/updates/pending_db_world/rev_1613069340138846000.sql new file mode 100644 index 000000000..619c52a05 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1613069340138846000.sql @@ -0,0 +1,3 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1613069340138846000'); + +UPDATE `creature_template` SET `InhabitType`=1 WHERE `entry`=36725; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index d74c71841..dc6cb97bb 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2758,6 +2758,8 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/) if (!packetOnly && !Unit::SetDisableGravity(disable)) return false; + applyInhabitFlags(); + if (!movespline->Initialized()) return true; @@ -2767,6 +2769,26 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/) return true; } +void Creature::applyInhabitFlags() +{ + if (IsAlive() && !HasUnitState(UNIT_STATE_ROOT) && !HasUnitMovementFlag(MOVEMENTFLAG_ROOT)) + { + if (IsLevitating()) + { + SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_FLY); + return; + } + + if (IsHovering()) + { + SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_HOVER); + return; + } + + SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_GROUND); + } +} + bool Creature::SetSwim(bool enable) { if (!Unit::SetSwim(enable)) @@ -2873,11 +2895,7 @@ bool Creature::SetHover(bool enable, bool packetOnly /*= false*/) if (!packetOnly && !Unit::SetHover(enable)) return false; - //! Unconfirmed for players: - if (enable) - SetByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_HOVER); - else - RemoveByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_HOVER); + applyInhabitFlags(); if (!movespline->Initialized()) return true; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index d87a30385..eba29952b 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -832,6 +832,8 @@ private: Spell const* _focusSpell; ///> Locks the target during spell cast for proper facing bool _isMissingSwimmingFlagOutOfCombat; + + void applyInhabitFlags(); }; class AssistDelayEvent : public BasicEvent diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e0f5d2557..509dcc3d5 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3816,28 +3816,39 @@ void Unit::UpdateEnvironmentIfNeeded(const uint8 option) changed = true; } } - else if (c->CanFly() && isInAir) + else if (c->CanFly() && isInAir && !c->IsFalling()) { - if (!c->IsFalling() && (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY) || !HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY) || !HasUnitMovementFlag(MOVEMENTFLAG_HOVER))) + + if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY) || !HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY)) { SetCanFly(true); SetDisableGravity(true); - if (IsAlive() && (c->CanHover() || HasAuraType(SPELL_AURA_HOVER))) - SetHover(true); changed = true; } + + if (IsHovering() && !HasAuraType(SPELL_AURA_HOVER)) + { + SetHover(false); + changed = true; + } + } else { - if (HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY) || HasUnitMovementFlag(MOVEMENTFLAG_FLYING) || HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) + if (HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY) || HasUnitMovementFlag(MOVEMENTFLAG_FLYING)) { SetCanFly(false); RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING); - if (!HasAuraType(SPELL_AURA_HOVER)) - SetHover(false); changed = true; } - if (HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY) && !HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) + + if (!IsHovering() && IsAlive() && (c->CanHover() || HasAuraType(SPELL_AURA_HOVER))) + { + SetHover(true); + changed = true; + } + + if (HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY) && !HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING)) { SetDisableGravity(false); changed = true; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index e0938e9a4..b8de30481 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -282,7 +282,6 @@ public: if (!_summoned) { me->SetDisableGravity(true); - me->SetHover(true); me->SetCanFly(true); } } @@ -355,7 +354,6 @@ public: if (_summoned) { me->SetDisableGravity(false); - me->SetHover(false); me->SetCanFly(false); } } @@ -452,8 +450,8 @@ public: break; case POINT_LAND_GROUND: { + _isInAirPhase = false; me->SetDisableGravity(false); - me->SetHover(false); me->SetCanFly(false); me->SetSpeed(MOVE_RUN, me->GetCreatureTemplate()->speed_run); me->SetReactState(REACT_AGGRESSIVE); @@ -594,6 +592,7 @@ public: me->SetControlled(false, UNIT_STATE_ROOT); } + _isInAirPhase = true; _didFirstFlyPhase = true; Talk(SAY_AIR_PHASE); me->SetReactState(REACT_PASSIVE); @@ -659,7 +658,7 @@ public: me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos, 10.0f); break; case EVENT_THIRD_PHASE_CHECK: - if (!me->HasByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_HOVER)) + if (!_isInAirPhase) { Talk(SAY_PHASE_2); events.ScheduleEvent(EVENT_ICE_TOMB, urand(7000, 10000)); @@ -697,6 +696,7 @@ public: bool _didFirstFlyPhase; bool _isBelow20Pct; bool _isThirdPhase; + bool _isInAirPhase; }; CreatureAI* GetAI(Creature* creature) const override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index ab42db630..0c2c7cc3f 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -3316,8 +3316,6 @@ public: npc_icc_nerubar_broodkeeperAI(Creature* creature) : ScriptedAI(creature) { me->SetDisableGravity(true); - me->SetCanFly(true); - me->SetHover(true); _didWebBeam = false; me->m_SightDistance = 100.0f; // for MoveInLineOfSight distance } @@ -3338,16 +3336,18 @@ public: if (!_didWebBeam && who->GetTypeId() == TYPEID_PLAYER && me->GetExactDist2d(who) < 70.0f) { _didWebBeam = true; - float nx = me->GetPositionX() + cos(me->GetOrientation()) * 2.0f; - float ny = me->GetPositionY() + sin(me->GetOrientation()) * 2.0f; - float nz = me->GetMap()->GetHeight(nx, ny, 50.0f); + float nx = me->GetPositionX(); + float ny = me->GetPositionY(); + float nz = me->GetFloorZ(); me->SetHomePosition(nx, ny, nz, me->GetOrientation()); me->CastSpell(me, SPELL_WEB_BEAM, false); me->GetMotionMaster()->MovePoint(1, nx, ny, nz, false); return; } - if (me->HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY)) + + if (me->IsLevitating()) return; + ScriptedAI::MoveInLineOfSight(who); } @@ -3358,11 +3358,9 @@ public: void JustReachedHome() override { - if (me->IsHovering()) + if (me->IsLevitating()) { me->SetDisableGravity(false); - me->SetCanFly(false); - me->SetHover(false); me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); } } @@ -3371,11 +3369,10 @@ public: { if (type == POINT_MOTION_TYPE && id == 1) { - if (me->IsHovering()) + if (me->IsLevitating()) { me->SetDisableGravity(false); - me->SetCanFly(false); - me->SetHover(false); + me->SetOrientation(0.0f); me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); } } @@ -3383,7 +3380,7 @@ public: bool CanAIAttack(const Unit* /*target*/) const override { - return !me->HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); + return !me->IsLevitating(); } void UpdateAI(uint32 diff) override