diff --git a/src/game/Entities/Unit.cpp b/src/game/Entities/Unit.cpp index fd0bcdd8a91..9c75b3e1a0c 100644 --- a/src/game/Entities/Unit.cpp +++ b/src/game/Entities/Unit.cpp @@ -13250,8 +13250,8 @@ void Unit::UpdateAllowedPositionZ(float x, float y, float& z, Map* atMap /*=null if (!atMap) atMap = GetMap(); - // non fly unit don't must be in air - // non swim unit must be at ground (mostly speedup, because it don't must be in water and water level check less fast + // non flying unit must not be in the air + // non swimming unit must be on the ground (mostly speedup, because it can't be in water and water level check less fast) if (!CanFly()) { bool canSwim = CanSwim(); @@ -13274,6 +13274,8 @@ void Unit::UpdateAllowedPositionZ(float x, float y, float& z, Map* atMap /*=null if (z < groundZ) z = groundZ; } + + z += GetHoverOffset(); } void Unit::AdjustZForCollision(float x, float y, float& z, float halfHeight) const @@ -14004,6 +14006,23 @@ void Unit::SetHover(bool enable) m_movementInfo.RemoveMovementFlag(MOVEFLAG_HOVER); } + float hoverHeight = GetHoverHeight(); + + if (enable) + { + if (hoverHeight && GetPositionZ() - GetMap()->GetHeight(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ()) < hoverHeight) + Relocate(GetPositionX(), GetPositionY(), GetPositionZ() + hoverHeight); + } + else + { + if (IsAlive() || !IsUnit()) + { + float newZ = std::max(GetMap()->GetHeight(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ()), GetPositionZ() - hoverHeight); + UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ); + Relocate(GetPositionX(), GetPositionY(), newZ); + } + } + if (!IsInWorld()) // is sent on add to map return; diff --git a/src/game/Entities/Unit.h b/src/game/Entities/Unit.h index 85bf45cf240..d412bad63fe 100644 --- a/src/game/Entities/Unit.h +++ b/src/game/Entities/Unit.h @@ -133,8 +133,11 @@ enum UnitVisFlags // These flags seem to be related to miscellaneous animations enum UnitMiscFlags { + UNIT_BYTE1_FLAG_GROUND = 0x00, UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01, UNIT_BYTE1_FLAG_FLY_ANIM = 0x02, // Creature that can fly and are not on the ground appear to have this flag. If they are on the ground, flag is not present. + UNIT_BYTE1_FLAG_REAL_FLY_ANIM= 0x03, + UNIT_BYTE1_FLAG_SUBMERGED = 0x04, UNIT_BYTE1_FLAG_ALL = 0xFF }; @@ -2493,6 +2496,16 @@ class Unit : public WorldObject virtual bool CanWalk() const = 0; virtual bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_FLYING); } + float GetHoverOffset() const + { + return m_movementInfo.HasMovementFlag(MOVEFLAG_HOVER) ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f; + } + + float GetHoverHeight() const + { + return GetFloatValue(UNIT_FIELD_HOVERHEIGHT); + } + // Take possession of an unit (pet, creature, ...) bool TakePossessOf(Unit* possessed); @@ -2540,6 +2553,11 @@ class Unit : public WorldObject virtual void SetBaseRunSpeed(float speed, bool /*force*/ = true) { m_baseSpeedRun = speed; } float GetBaseRunSpeed() { return m_baseSpeedRun; } + void SetHoverHeight(float hoverHeight) + { + SetFloatValue(UNIT_FIELD_HOVERHEIGHT, hoverHeight); + } + bool IsSpellProccingHappening() const { return m_spellProcsHappening; } void AddDelayedHolderDueToProc(SpellAuraHolder* holder) { m_delayedSpellAuraHolders.push_back(holder); } diff --git a/src/game/MotionGenerators/MotionMaster.cpp b/src/game/MotionGenerators/MotionMaster.cpp index ce84eff9dff..3301c20f8fc 100644 --- a/src/game/MotionGenerators/MotionMaster.cpp +++ b/src/game/MotionGenerators/MotionMaster.cpp @@ -580,7 +580,6 @@ bool MotionMaster::MoveFall(ObjectGuid guid/* = ObjectGuid()*/, uint32 relayId/* // use larger distance for vmap height search than in most other cases float tz = m_owner->GetMap()->GetHeight(m_owner->GetPhaseMask(), x, y, z); - if (tz <= INVALID_HEIGHT) { DEBUG_LOG("MotionMaster::MoveFall: unable retrive a proper height at map %u (x: %f, y: %f, z: %f).", m_owner->GetMap()->GetId(), x, y, z); diff --git a/src/game/Movement/MoveSplineInit.cpp b/src/game/Movement/MoveSplineInit.cpp index 519142c3aa1..005b6561961 100644 --- a/src/game/Movement/MoveSplineInit.cpp +++ b/src/game/Movement/MoveSplineInit.cpp @@ -217,8 +217,8 @@ namespace Movement MoveSplineInit::MoveSplineInit(Unit& m) : unit(m) { // mix existing state into new - args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEFLAG_WALK_MODE); - args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_CAN_FLY | MOVEFLAG_HOVER | MOVEFLAG_FLYING | MOVEFLAG_LEVITATING)); + args.flags.walkmode = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_WALK_MODE | MOVEFLAG_HOVER)); + args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEFLAG_CAN_FLY | MOVEFLAG_FLYING | MOVEFLAG_LEVITATING)); } void MoveSplineInit::SetFacing(const WorldObject* target)