diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 88 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 7 | ||||
-rw-r--r-- | src/server/game/Handlers/MovementHandler.cpp | 4 | ||||
-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 | ||||
-rw-r--r-- | src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp | 13 |
9 files changed, 60 insertions, 99 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 3a061c816bc..9cdef4266d4 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -404,6 +404,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); } @@ -1096,11 +1097,7 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 phaseMask, u } //! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there - if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - { - //! Relocate again with updated Z coord - m_positionZ += GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - } + m_positionZ += GetHoverOffset(); LastUsedScriptID = GetScriptId(); @@ -1631,7 +1628,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; @@ -2975,7 +2972,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 61d2da10c88..4f124f96e15 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -390,9 +390,6 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const *data << object->GetPositionX(); *data << object->GetPositionY(); - if (isType(TYPEMASK_UNIT)) - *data << unit->GetPositionZMinusOffset(); - else *data << object->GetPositionZ(); if (transport) @@ -405,9 +402,6 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const { *data << object->GetPositionX(); *data << object->GetPositionY(); - if (isType(TYPEMASK_UNIT)) - *data << unit->GetPositionZMinusOffset(); - else *data << object->GetPositionZ(); } @@ -1463,7 +1457,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 @@ -1472,66 +1468,44 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const if (GetTransport()) return; - switch (GetTypeId()) + if (Unit const* unit = ToUnit()) { - case TYPEID_UNIT: + if (!unit->CanFly()) { - // 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: - { - // 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 @@ -2322,7 +2296,7 @@ float WorldObject::SelectBestZForDestination(float x, float y, float z, bool exc if (Unit const* unit = ToUnit()) { float const ground = GetFloorZ(); - bool const isInAir = (G3D::fuzzyGt(unit->GetPositionZMinusOffset(), ground + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(unit->GetPositionZMinusOffset(), ground - GROUND_HEIGHT_TOLERANCE)); + bool const isInAir = (G3D::fuzzyGt(unit->GetPositionZ(), ground + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(unit->GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE)); if (unit->IsFlying() && isInAir) return z; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e811a87e227..c55e6f49459 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -545,7 +545,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); @@ -11979,15 +11979,6 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id) } } -float Unit::GetPositionZMinusOffset() const -{ - float offset = 0.0f; - if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - offset = GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - - return GetPositionZ() - offset; -} - void Unit::SetControlled(bool apply, UnitState state) { if (apply) @@ -13549,7 +13540,7 @@ void Unit::_ExitVehicle(Position const* exitPosition) void Unit::BuildMovementPacket(ByteBuffer *data) const { - Unit::BuildMovementPacket(Position(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), GetOrientation()), m_movementInfo.transport.pos, m_movementInfo, data); + Unit::BuildMovementPacket(*this, m_movementInfo.transport.pos, m_movementInfo, data); } void Unit::BuildMovementPacket(Position const& pos, Position const& transportPos, MovementInfo const& movementInfo, ByteBuffer* data) @@ -13959,7 +13950,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 (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && GetTransGUID()) init.DisableTransportPathTransformations(); // It makes no sense to target global orientation init.SetFacing(ori); @@ -13974,7 +13965,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 d464861f2ea..9186551a23d 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1596,8 +1596,6 @@ class TC_GAME_API Unit : public WorldObject uint16 GetExtraUnitMovementFlags() const { return m_movementInfo.flags2; } void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.flags2 = f; } - float GetPositionZMinusOffset() const; - void SetControlled(bool apply, UnitState state); void ApplyControlStatesIfNeeded(); @@ -1675,6 +1673,11 @@ class TC_GAME_API Unit : public WorldObject bool IsFalling() const; virtual bool CanSwim() const; + float GetHoverOffset() const + { + return HasUnitMovementFlag(MOVEMENTFLAG_HOVER) ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f; + } + void RewardRage(uint32 damage, uint32 weaponSpeedHitFactor, bool attacker); 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 5f641d6951d..720733249e3 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -86,9 +86,7 @@ void WorldSession::HandleMoveWorldportAck() return; } - float z = loc.GetPositionZ(); - if (GetPlayer()->HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - z += GetPlayer()->GetFloatValue(UNIT_FIELD_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 589dce1ed32..347882d34c6 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1029,12 +1029,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 UNIT_FIELD_HOVERHEIGHT sent in object updates - if (player->HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - z += player->GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - player->Relocate(x, y, z, orientation); if (player->IsVehicle()) player->GetVehicleKit()->RelocatePassengers(); @@ -1065,12 +1059,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 UNIT_FIELD_HOVERHEIGHT sent in object updates - if (creature->HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - z += creature->GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - // 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 131c96cce22..c10870703fa 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -356,7 +356,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); @@ -499,7 +499,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); } @@ -600,7 +600,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 809c8b8bccd..dd72838c247 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -52,6 +52,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 de0a16e1910..4de930e56b6 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -125,29 +125,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 { |