diff options
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 80 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 15 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 7 | ||||
-rw-r--r-- | src/server/game/Handlers/MovementHandler.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Movement/MotionMaster.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp | 1 | ||||
-rwxr-xr-x | src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp | 13 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp | 2 |
10 files changed, 59 insertions, 93 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 40e26027ba0..329ec612800 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -446,6 +446,7 @@ void Creature::RemoveCorpse(bool setSpawnTime, bool destroyForNearbyPlayers) transport->CalculatePassengerPosition(x, y, z, &o); } + UpdateAllowedPositionZ(x, y, z); SetHomePosition(x, y, z, o); GetMap()->CreatureRelocation(this, x, y, z, o); } @@ -1151,11 +1152,7 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, Posit LoadCreaturesAddon(); //! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there - if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - { - //! Relocate again with updated Z coord - m_positionZ += m_unitData->HoverHeight; - } + m_positionZ += GetHoverOffset(); LastUsedScriptID = GetScriptId(); @@ -1769,7 +1766,7 @@ bool Creature::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, return false; //We should set first home position, because then AI calls home movement - SetHomePosition(data->spawnPoint); + SetHomePosition(*this); m_deathState = ALIVE; @@ -3112,7 +3109,7 @@ void Creature::UpdateMovementFlags() // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc) float ground = GetFloorZ(); - bool isInAir = (G3D::fuzzyGt(GetPositionZMinusOffset(), ground + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetPositionZMinusOffset(), ground - GROUND_HEIGHT_TOLERANCE)); // Can be underground too, prevent the falling + bool isInAir = (G3D::fuzzyGt(GetPositionZ(), ground + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE)); // Can be underground too, prevent the falling if (GetCreatureTemplate()->InhabitType & INHABIT_AIR && isInAir && !IsFalling()) { diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index e4e13390c78..985d079826c 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1303,7 +1303,9 @@ Position WorldObject::GetRandomPoint(Position const& srcPos, float distance) con void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const { - z = GetMapHeight(x, y, z); + float new_z = GetMapHeight(x, y, z); + if (new_z > INVALID_HEIGHT) + z = new_z + (isType(TYPEMASK_UNIT) ? static_cast<Unit const*>(this)->GetHoverOffset() : 0.0f); } void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const @@ -1312,66 +1314,44 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const if (GetTransport()) return; - switch (GetTypeId()) + if (Unit const* unit = ToUnit()) { - case TYPEID_UNIT: - { - // 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 - if (!ToCreature()->CanFly()) - { - bool canSwim = ToCreature()->CanSwim(); - float ground_z = z; - float max_z = canSwim - ? GetMapWaterOrGroundLevel(x, y, z, &ground_z) - : (ground_z = GetMapHeight(x, y, z)); - if (max_z > INVALID_HEIGHT) - { - if (z > max_z) - z = max_z; - else if (z < ground_z) - z = ground_z; - } - } - else - { - float ground_z = GetMapHeight(x, y, z); - if (std::fabs(z - ground_z) < GetCollisionHeight()) - z = ground_z; - } - break; - } - case TYPEID_PLAYER: + if (!unit->CanFly()) { - // for server controlled moves playr work same as creature (but it can always swim) - if (!ToPlayer()->CanFly()) - { - float ground_z = z; - float max_z = GetMapWaterOrGroundLevel(x, y, z, &ground_z); - if (max_z > INVALID_HEIGHT) - { - if (z > max_z) - z = max_z; - else if (z < ground_z) - z = ground_z; - } - } + bool canSwim = unit->CanSwim(); + float ground_z = z; + float max_z; + if (canSwim) + max_z = GetMapWaterOrGroundLevel(x, y, z, &ground_z); else + max_z = ground_z = GetMapHeight(x, y, z); + + if (max_z > INVALID_HEIGHT) { - float ground_z = GetMapHeight(x, y, z); - if (std::fabs(z - ground_z) < GetCollisionHeight()) + // hovering units cannot go below their hover height + float hoverOffset = unit->GetHoverOffset(); + max_z += hoverOffset; + ground_z += hoverOffset; + + if (z > max_z) + z = max_z; + else if (z < ground_z) z = ground_z; } - break; } - default: + else { - float ground_z = GetMapHeight(x, y, z); - if (ground_z > INVALID_HEIGHT) + float ground_z = GetMapHeight(x, y, z) + unit->GetHoverOffset(); + if (z < ground_z) z = ground_z; - break; } } + else + { + float ground_z = GetMapHeight(x, y, z); + if (ground_z > INVALID_HEIGHT) + z = ground_z; + } } float WorldObject::GetGridActivationRange() const diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2115fc96aa3..20a398649bd 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -566,7 +566,7 @@ bool Unit::IsWithinMeleeRange(Unit const* obj) const float dx = GetPositionX() - obj->GetPositionX(); float dy = GetPositionY() - obj->GetPositionY(); - float dz = GetPositionZMinusOffset() - obj->GetPositionZMinusOffset(); + float dz = GetPositionZ() - obj->GetPositionZ(); float distsq = dx*dx + dy*dy + dz*dz; float maxdist = GetMeleeRange(obj) + GetTotalAuraModifier(SPELL_AURA_MOD_AUTOATTACK_RANGE); @@ -11574,15 +11574,6 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId) } } -float Unit::GetPositionZMinusOffset() const -{ - float offset = 0.0f; - if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - offset = m_unitData->HoverHeight; - - return GetPositionZ() - offset; -} - void Unit::SetControlled(bool apply, UnitState state) { if (apply) @@ -13294,7 +13285,7 @@ void Unit::SetFacingTo(float ori, bool force) return; Movement::MoveSplineInit init(this); - init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), false); + init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ(), false); if (GetTransport()) init.DisableTransportPathTransformations(); // It makes no sense to target global orientation init.SetFacing(ori); @@ -13309,7 +13300,7 @@ void Unit::SetFacingToObject(WorldObject const* object, bool force) /// @todo figure out under what conditions creature will move towards object instead of facing it where it currently is. Movement::MoveSplineInit init(this); - init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), false); + init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ(), false); init.SetFacing(GetAngle(object)); // when on transport, GetAngle will still return global coordinates (and angle) that needs transforming init.Launch(); } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 75d7e60897e..da63f0558c7 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1768,8 +1768,6 @@ class TC_GAME_API Unit : public WorldObject void SetExtraUnitMovementFlags(uint32 f) { m_movementInfo.SetExtraMovementFlags(f); } bool IsSplineEnabled() const; - float GetPositionZMinusOffset() const; - void SetControlled(bool apply, UnitState state); void ApplyControlStatesIfNeeded(); @@ -1828,6 +1826,11 @@ class TC_GAME_API Unit : public WorldObject bool IsFalling() const; virtual bool CanSwim() const; + float GetHoverOffset() const + { + return HasUnitMovementFlag(MOVEMENTFLAG_HOVER) ? *m_unitData->HoverHeight : 0.0f; + } + void RewardRage(uint32 baseRage); virtual float GetFollowAngle() const { return static_cast<float>(M_PI/2); } diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 9fe6808defb..ac873eb6d01 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -90,10 +90,7 @@ void WorldSession::HandleMoveWorldportAck() return; } - float z = loc.GetPositionZ(); - if (GetPlayer()->HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - z += GetPlayer()->m_unitData->HoverHeight; - + float z = loc.GetPositionZ() + GetPlayer()->GetHoverOffset(); GetPlayer()->Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation()); GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ()); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 10a1eb2e6ce..fc2c950b57c 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1138,12 +1138,6 @@ void Map::PlayerRelocation(Player* player, float x, float y, float z, float orie Cell old_cell(player->GetPositionX(), player->GetPositionY()); Cell new_cell(x, y); - //! If hovering, always increase our server-side Z position - //! Client automatically projects correct position based on Z coord sent in monster move - //! and HoverHeight sent in object updates - if (player->HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - z += player->m_unitData->HoverHeight; - player->Relocate(x, y, z, orientation); if (player->IsVehicle()) player->GetVehicleKit()->RelocatePassengers(); @@ -1173,12 +1167,6 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa if (!respawnRelocationOnFail && !getNGrid(new_cell.GridX(), new_cell.GridY())) return; - //! If hovering, always increase our server-side Z position - //! Client automatically projects correct position based on Z coord sent in monster move - //! and HoverHeight sent in object updates - if (creature->HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - z += creature->m_unitData->HoverHeight; - Cell old_cell = creature->GetCurrentCell(); // delay creature move for grid/cell to grid/cell moves if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell)) diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 7df25b72817..d7be55b03e7 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -346,7 +346,7 @@ void MotionMaster::MoveCloserAndStop(uint32 id, Unit* target, float distance) { // we are already close enough. We just need to turn toward the target without changing position. Movement::MoveSplineInit init(_owner); - init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZMinusOffset()); + init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); init.SetFacing(target); init.Launch(); Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); @@ -510,7 +510,7 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool if (_owner->IsFlying()) point.z = z; else - point.z = _owner->GetMapHeight(point.x, point.y, z); + point.z = _owner->GetMapHeight(point.x, point.y, z) + _owner->GetHoverOffset(); init.Path().push_back(point); } @@ -615,7 +615,7 @@ void MotionMaster::MoveFall(uint32 id /*=0*/) } Movement::MoveSplineInit init(_owner); - init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz, false); + init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz + _owner->GetHoverOffset(), false); init.SetFall(); init.Launch(); Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp index 191877289c8..df1adb19684 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -51,6 +51,7 @@ void HomeMovementGenerator<Creature>::SetTargetLocation(Creature* owner) owner->GetHomePosition(x, y, z, o); init.SetFacing(o); } + owner->UpdateAllowedPositionZ(x, y, z); init.MoveTo(x, y, z); init.SetWalk(false); init.Launch(); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 0465c958990..102a4728fc9 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -124,29 +124,38 @@ void TargetedMovementGenerator<T, D>::SetTargetLocation(T* owner, bool updateDes float x, y, z; if (updateDestination || !_path) { + float size = owner->GetCombatReach(); + float hoverDiff = owner->GetHoverOffset() - GetTarget()->GetHoverOffset(); if (!_offset) { if (GetTarget()->IsWithinDistInMap(owner, CONTACT_DISTANCE)) return; - GetTarget()->GetContactPoint(owner, x, y, z); + if (hoverDiff) + size = size > hoverDiff ? std::sqrt(size * size - hoverDiff * hoverDiff) : 0.0f; + + GetTarget()->GetNearPoint(owner, x, y, z, size, CONTACT_DISTANCE, GetTarget()->GetAngle(owner)); } else { float distance = _offset + 1.0f; - float size = owner->GetCombatReach(); if (owner->IsPet() && GetTarget()->GetTypeId() == TYPEID_PLAYER) { distance = 1.0f; size = 1.0f; } + else if (hoverDiff) + size = size > hoverDiff ? std::sqrt(size * size - hoverDiff * hoverDiff) : 0.0f; if (GetTarget()->IsWithinDistInMap(owner, distance)) return; GetTarget()->GetClosePoint(x, y, z, size, _offset, _angle); } + + if (owner->IsHovering()) + owner->UpdateAllowedPositionZ(x, y, z); } else { diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 250e2f64cac..062b5c4a003 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -613,7 +613,7 @@ class boss_mimiron : public CreatureScript { if (Creature* aerial = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AERIAL_COMMAND_UNIT))) { - aerial->GetMotionMaster()->MoveLand(0, (aerial->GetPositionX(), aerial->GetPositionY(), aerial->GetPositionZMinusOffset())); + aerial->GetMotionMaster()->MoveLand(0, (aerial->GetPositionX(), aerial->GetPositionY(), aerial->GetPositionZ())); aerial->SetAnimTier(UNIT_BYTE1_FLAG_NONE, false); aerial->CastSpell(vx001, SPELL_MOUNT_VX_001); aerial->CastSpell(aerial, SPELL_HALF_HEAL); |