diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index d126ff9d89..82d9512f95 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2957,7 +2957,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsPlayer(target)) continue; - target->ToPlayer()->SendCinematicStart(e.action.cinematic.entry); + target->ToPlayer()->GetCinematicMgr().StartCinematic(e.action.cinematic.entry); } break; } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 32e4500301..7885b3bfc5 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1703,7 +1703,7 @@ void GameObject::Use(Unit* user) Player* player = user->ToPlayer(); if (info->camera.cinematicId) - player->SendCinematicStart(info->camera.cinematicId); + player->GetCinematicMgr().StartCinematic(info->camera.cinematicId); if (info->camera.eventID) { @@ -2142,7 +2142,32 @@ void GameObject::SendCustomAnim(uint32 anim) SendMessageToSet(&data, true); } -bool GameObject::IsInRange(float x, float y, float z, float radius) const +bool GameObject::IsInRange2d(float x, float y, float radius) const +{ + GameObjectDisplayInfoEntry const* info = sGameObjectDisplayInfoStore.LookupEntry(m_goInfo->displayId); + if (!info) + return IsWithinDist2d(x, y, radius); + + float sinA = std::sin(GetOrientation()); + float cosA = cos(GetOrientation()); + float dx = x - GetPositionX(); + float dy = y - GetPositionY(); + float dist = std::sqrt(dx * dx + dy * dy); + //! Check if the distance between the 2 objects is 0, can happen if both objects are on the same position. + //! The code below this check wont crash if dist is 0 because 0/0 in float operations is valid, and returns infinite + if (G3D::fuzzyEq(dist, 0.0f)) + return true; + + float scale = GetObjectScale(); + float sinB = dx / dist; + float cosB = dy / dist; + dx = dist * (cosA * cosB + sinA * sinB); + dy = dist * (cosA * sinB - sinA * cosB); + return dx < (info->maxX * scale) + radius && dx >(info->minX * scale) - radius + && dy < (info->maxY * scale) + radius && dy >(info->minY * scale) - radius; +} + +bool GameObject::IsInRange3d(float x, float y, float z, float radius) const { GameObjectDisplayInfoEntry const* info = sGameObjectDisplayInfoStore.LookupEntry(m_goInfo->displayId); if (!info) @@ -2217,6 +2242,11 @@ void GameObject::UpdatePackedRotation() m_packedRotation = z | (y << 21) | (x << 42); } +bool GameObject::IsWithinSightRange(Position const& pos, float dist) const +{ + return IsInRange2d(pos.GetPositionX(), pos.GetPositionY(), dist); +} + void GameObject::SetWorldRotation(G3D::Quat const& rot) { G3D::Quat rotation = rot; diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index efcb662490..8c4a943e05 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -284,7 +284,8 @@ public: void CastSpell(Unit* target, uint32 spell); void SendCustomAnim(uint32 anim); - [[nodiscard]] bool IsInRange(float x, float y, float z, float radius) const; + bool IsInRange2d(float x, float y, float radius) const; + bool IsInRange3d(float x, float y, float z, float radius) const; void ModifyHealth(int32 change, Unit* attackerOrHealer = nullptr, uint32 spellId = 0); void SetDestructibleBuildingModifyState(bool allow) { m_allowModifyDestructibleBuilding = allow; } @@ -418,8 +419,11 @@ private: { //! Following check does check 3d distance dist2compare += obj->GetObjectSize(); - return IsInRange(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), dist2compare); + return IsInRange3d(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), dist2compare); } + + bool IsWithinSightRange(Position const& pos, float dist) const override; + GameObjectAI* m_AI; bool m_saveStateOnDb = false; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 98e5b890a4..9cd58f197b 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1362,6 +1362,12 @@ bool WorldObject::IsWithinDist2d(const Position* pos, float dist) const return IsInDist2d(pos, dist + GetObjectSize()); } +// Visibility always uses 2d checks, factors in self-object size already. Gameobjects will override this for custom calc +bool WorldObject::IsWithinSightRange(Position const& pos, float dist) const +{ + return IsInDist2d(&pos, dist + GetObjectSize()); +} + // use only if you will sure about placing both object at same map bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D, bool incOwnRadius, bool incTargetRadius) const { @@ -1674,7 +1680,7 @@ float WorldObject::GetGridActivationRange() const { if (ToPlayer()) { - if (ToPlayer()->GetCinematicMgr()->IsOnCinematic()) + if (ToPlayer()->GetCinematicMgr().IsOnCinematic()) { return DEFAULT_VISIBILITY_INSTANCE; } @@ -1725,7 +1731,7 @@ float WorldObject::GetSightRange(WorldObject const* target) const return VISIBILITY_DIST_WINTERGRASP; else if (target->IsVisibilityOverridden()) return target->GetVisibilityOverrideDistance(); - else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic()) + else if (ToPlayer()->GetCinematicMgr().IsOnCinematic()) return DEFAULT_VISIBILITY_INSTANCE; else return GetMap()->GetVisibilityRange(); @@ -1794,10 +1800,10 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo if (distanceCheck) { bool corpseCheck = false; - WorldObject const* viewpoint = this; + Position const* sightPosition = this; if (Player const* thisPlayer = ToPlayer()) { - viewpoint = thisPlayer->GetSeer(); + sightPosition = &thisPlayer->GetSightPosition(); if (Creature const* creature = obj->ToCreature()) { @@ -1843,8 +1849,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo return false; } - // Xinef: check reversely obj vs viewpoint, object could be a gameObject which overrides _IsWithinDist function to include gameobject size - if (!corpseCheck && !viewpoint->IsWithinDist(obj, GetSightRange(obj), false)) + if (!corpseCheck && !obj->IsWithinSightRange(*sightPosition, GetSightRange(obj))) return false; } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index d2da4b5231..4a635175da 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -543,6 +543,7 @@ public: bool IsWithinDist3d(const Position* pos, float dist) const; [[nodiscard]] bool IsWithinDist2d(float x, float y, float dist) const; bool IsWithinDist2d(const Position* pos, float dist) const; + virtual bool IsWithinSightRange(Position const& pos, float dist) const; // use only if you will sure about placing both object at same map bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true, bool incOwnRadius = true, bool incTargetRadius = true) const; bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true, bool incOwnRadius = true, bool incTargetRadius = true) const; diff --git a/src/server/game/Entities/Player/CinematicMgr.cpp b/src/server/game/Entities/Player/CinematicMgr.cpp index d8091d9180..1cce91ed2b 100644 --- a/src/server/game/Entities/Player/CinematicMgr.cpp +++ b/src/server/game/Entities/Player/CinematicMgr.cpp @@ -17,92 +17,84 @@ #include "CinematicMgr.h" #include "M2Stores.h" -#include "MotionMaster.h" #include "Player.h" -CinematicMgr::CinematicMgr(Player* playerref) +CinematicMgr::CinematicMgr(Player& player) : _player(player) { - player = playerref; - m_cinematicDiff = 0; - m_lastCinematicCheck = 0; - m_activeCinematicCameraId = 0; - m_cinematicLength = 0; - m_cinematicCamera = nullptr; - m_remoteSightPosition = Position(0.0f, 0.0f, 0.0f); - m_CinematicObject = nullptr; + _cinematicDiff = 0; + _activeCinematicCameraId = 0; + _cinematicCamera = nullptr; + _remoteSightPosition = Position(0.0f, 0.0f, 0.0f); + _cinematicUpdateTimer.SetInterval(CINEMATIC_UPDATEDIFF); } -CinematicMgr::~CinematicMgr() +void CinematicMgr::StartCinematic(uint32 const cinematicSequenceId) { - if (m_cinematicCamera && m_activeCinematicCameraId) - EndCinematic(); + _player.SendCinematicStart(cinematicSequenceId); + if (CinematicSequencesEntry const* sequence = sCinematicSequencesStore.LookupEntry(cinematicSequenceId)) + SetActiveCinematicCamera(sequence->cinematicCamera); } -void CinematicMgr::BeginCinematic() +void CinematicMgr::StartCinematicCamera() { // Sanity check for active camera set - if (m_activeCinematicCameraId == 0) + if (_activeCinematicCameraId == 0) return; - if (std::vector const* flyByCameras = GetFlyByCameras(m_activeCinematicCameraId)) + if (std::vector const* flyByCameras = GetFlyByCameras(_activeCinematicCameraId)) { // Initialize diff, and set camera - m_cinematicDiff = 0; - m_cinematicCamera = flyByCameras; + _cinematicDiff = 0; + _cinematicUpdateTimer.Reset(); + _cinematicCamera = flyByCameras; - auto camitr = m_cinematicCamera->begin(); - if (camitr != m_cinematicCamera->end()) + auto camitr = _cinematicCamera->begin(); + if (camitr != _cinematicCamera->end()) { Position const& pos = camitr->locations; if (!pos.IsPositionValid()) return; - player->GetMap()->LoadGrid(pos.GetPositionX(), pos.GetPositionY()); - m_CinematicObject = player->SummonCreature(VISUAL_WAYPOINT, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 120000); - if (m_CinematicObject) - { - m_CinematicObject->setActive(true); - player->SetViewpoint(m_CinematicObject, true); - } - - // Get cinematic length - m_cinematicLength = flyByCameras->back().timeStamp; + _player.GetMap()->LoadGridsInRange(pos, MAX_VISIBILITY_DISTANCE); + _remoteSightPosition.Relocate(pos); + _player.UpdateVisibilityForPlayer(); } } } void CinematicMgr::EndCinematic() { - if (m_activeCinematicCameraId == 0) + if (_activeCinematicCameraId == 0) return; - m_cinematicDiff = 0; - m_cinematicCamera = nullptr; - m_activeCinematicCameraId = 0; - if (m_CinematicObject) - { - if (WorldObject* vpObject = player->GetViewpoint()) - if (vpObject == m_CinematicObject) - player->SetViewpoint(m_CinematicObject, false); - - m_CinematicObject->AddObjectToRemoveList(); - } + _cinematicDiff = 0; + _cinematicUpdateTimer.Reset(); + _cinematicCamera = nullptr; + _activeCinematicCameraId = 0; + _player.UpdateVisibilityForPlayer(); } -void CinematicMgr::UpdateCinematicLocation(uint32 /*diff*/) +void CinematicMgr::UpdateCinematic(uint32 const diff) { - if (m_activeCinematicCameraId == 0 || !m_cinematicCamera || m_cinematicCamera->size() == 0) + if (_activeCinematicCameraId == 0 || !_cinematicCamera || _cinematicCamera->empty()) return; + _cinematicDiff += diff; + _cinematicUpdateTimer.Update(diff); + if (!_cinematicUpdateTimer.Passed()) + return; + + _cinematicUpdateTimer.Reset(); + Position lastPosition; uint32 lastTimestamp = 0; Position nextPosition; uint32 nextTimestamp = 0; // Obtain direction of travel - for (FlyByCamera cam : *m_cinematicCamera) + for (FlyByCamera const& cam : *_cinematicCamera) { - if (cam.timeStamp > m_cinematicDiff) + if (cam.timeStamp > _cinematicDiff) { nextPosition.Relocate(cam.locations); nextTimestamp = cam.timeStamp; @@ -113,26 +105,25 @@ void CinematicMgr::UpdateCinematicLocation(uint32 /*diff*/) } float angle = lastPosition.GetAbsoluteAngle(&nextPosition); angle -= lastPosition.GetOrientation(); - if (angle < 0) - angle += 2 * float(M_PI); + angle = Position::NormalizeOrientation(angle); // Look for position around 2 second ahead of us. - int32 workDiff = m_cinematicDiff; + int32 workDiff = _cinematicDiff; // Modify result based on camera direction (Humans for example, have the camera point behind) workDiff += static_cast(float(CINEMATIC_LOOKAHEAD) * cos(angle)); // Get an iterator to the last entry in the cameras, to make sure we don't go beyond the end - auto endItr = m_cinematicCamera->rbegin(); - if (endItr != m_cinematicCamera->rend() && workDiff > static_cast(endItr->timeStamp)) + auto endItr = _cinematicCamera->rbegin(); + if (endItr != _cinematicCamera->rend() && workDiff > static_cast(endItr->timeStamp)) workDiff = endItr->timeStamp; // Never try to go back in time before the start of cinematic! if (workDiff < 0) - workDiff = m_cinematicDiff; + workDiff = _cinematicDiff; // Obtain the previous and next waypoint based on timestamp - for (FlyByCamera cam : *m_cinematicCamera) + for (FlyByCamera const& cam : *_cinematicCamera) { if (static_cast(cam.timeStamp) >= workDiff) { @@ -157,12 +148,15 @@ void CinematicMgr::UpdateCinematicLocation(uint32 /*diff*/) Position interPosition(lastPosition.m_positionX + (xDiff * (float(interDiff) / float(timeDiff))), lastPosition.m_positionY + (yDiff * (float(interDiff) / float(timeDiff))), lastPosition.m_positionZ + (zDiff * (float(interDiff) / float(timeDiff)))); - // Advance (at speed) to this position. The remote sight object is used - // to send update information to player in cinematic - if (m_CinematicObject && interPosition.IsPositionValid()) - m_CinematicObject->MonsterMoveWithSpeed(interPosition.m_positionX, interPosition.m_positionY, interPosition.m_positionZ, 500.0f); + // Advance _remoteSightPosition to new position + if (interPosition.IsPositionValid()) + { + _player.GetMap()->LoadGridsInRange(interPosition, MAX_VISIBILITY_DISTANCE); + _remoteSightPosition.Relocate(interPosition); + _player.UpdateVisibilityForPlayer(); + } // If we never received an end packet 10 seconds after the final timestamp then force an end - if (m_cinematicDiff > m_cinematicLength + 10 * IN_MILLISECONDS) + if (_cinematicDiff > _cinematicCamera->back().timeStamp + 10 * IN_MILLISECONDS) EndCinematic(); } diff --git a/src/server/game/Entities/Player/CinematicMgr.h b/src/server/game/Entities/Player/CinematicMgr.h index 1dffe9957f..3409854d05 100644 --- a/src/server/game/Entities/Player/CinematicMgr.h +++ b/src/server/game/Entities/Player/CinematicMgr.h @@ -20,7 +20,7 @@ #include "Define.h" #include "Position.h" -#include "TemporarySummon.h" +#include "Timer.h" #include constexpr auto CINEMATIC_UPDATEDIFF = 500; @@ -31,31 +31,27 @@ struct FlyByCamera; class AC_GAME_API CinematicMgr { - friend class Player; public: - explicit CinematicMgr(Player* playerref); - ~CinematicMgr(); + explicit CinematicMgr(Player& player); + ~CinematicMgr() = default; // Cinematic camera data and remote sight functions - uint32 GetActiveCinematicCamera() const { return m_activeCinematicCameraId; } - void SetActiveCinematicCamera(uint32 cinematicCameraId = 0) { m_activeCinematicCameraId = cinematicCameraId; } - bool IsOnCinematic() const { return (m_cinematicCamera != nullptr); } - void BeginCinematic(); + void StartCinematic(uint32 const cinematicSequenceId); + uint32 GetActiveCinematicCamera() const { return _activeCinematicCameraId; } + void SetActiveCinematicCamera(uint32 cinematicCameraId = 0) { _activeCinematicCameraId = cinematicCameraId; } + bool IsOnCinematic() const { return (_cinematicCamera != nullptr); } + void StartCinematicCamera(); void EndCinematic(); - void UpdateCinematicLocation(uint32 diff); + void UpdateCinematic(uint32 const diff); + Position const& GetRemoteSightPosition() const { return _remoteSightPosition; } private: - // Remote location information - Player* player; - -protected: - uint32 m_cinematicDiff; - uint32 m_lastCinematicCheck; - uint32 m_activeCinematicCameraId; - uint32 m_cinematicLength; - std::vector const* m_cinematicCamera; - Position m_remoteSightPosition; - TempSummon* m_CinematicObject; + Player& _player; + uint32 _cinematicDiff; + uint32 _activeCinematicCameraId; + std::vector const* _cinematicCamera; + Position _remoteSightPosition; + IntervalTimer _cinematicUpdateTimer; }; #endif diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 8f1ac60580..44e6a734e4 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -154,7 +154,7 @@ static uint32 copseReclaimDelay[MAX_DEATH_COUNT] = { 30, 60, 120 }; #ifdef _MSC_VER #pragma warning(disable:4355) #endif -Player::Player(WorldSession* session): Unit(), m_mover(this) +Player::Player(WorldSession* session): Unit(), m_mover(this), _cinematicMgr(*this) { #ifdef _MSC_VER #pragma warning(default:4355) @@ -395,8 +395,6 @@ Player::Player(WorldSession* session): Unit(), m_mover(this) m_creationTime = 0s; - _cinematicMgr = new CinematicMgr(this); - m_achievementMgr = new AchievementMgr(this); m_reputationMgr = new ReputationMgr(this); @@ -462,7 +460,6 @@ Player::~Player() delete m_runes; delete m_achievementMgr; delete m_reputationMgr; - delete _cinematicMgr; sWorldSessionMgr->DecreasePlayerCount(); @@ -5688,10 +5685,6 @@ void Player::SendCinematicStart(uint32 CinematicSequenceId) const WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4); data << uint32(CinematicSequenceId); SendDirectMessage(&data); - if (CinematicSequencesEntry const* sequence = sCinematicSequencesStore.LookupEntry(CinematicSequenceId)) - { - _cinematicMgr->SetActiveCinematicCamera(sequence->cinematicCamera); - } } void Player::SendMovieStart(uint32 MovieId) @@ -13201,6 +13194,14 @@ WorldObject* Player::GetViewpoint() const return nullptr; } +Position const& Player::GetSightPosition() const +{ + if (_cinematicMgr.IsOnCinematic()) + return _cinematicMgr.GetRemoteSightPosition(); + + return *m_seer; +} + bool Player::CanUseBattlegroundObject(GameObject* gameobject) const { // It is possible to call this method will a nullptr pointer, only skipping faction check. @@ -16270,7 +16271,10 @@ bool Player::IsWorldObjectOutOfSightRange(WorldObject const* target) const } // Check if out of range - return !m_seer->IsWithinDist(target, GetSightRange(target), false); + if (!target->IsWithinSightRange(GetSightPosition(), GetSightRange(target))) + return true; + + return false; } std::string Player::GetPlayerName() diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7d1ad43d67..45c5dc5532 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1393,7 +1393,8 @@ public: [[nodiscard]] TradeData* GetTradeData() const { return m_trade; } void TradeCancel(bool sendback, TradeStatus status = TRADE_STATUS_TRADE_CANCELED); - CinematicMgr* GetCinematicMgr() const { return _cinematicMgr; } + CinematicMgr& GetCinematicMgr() { return _cinematicMgr; } + CinematicMgr const& GetCinematicMgr() const { return _cinematicMgr; } void UpdateEnchantTime(uint32 time); void UpdateSoulboundTradeItems(); @@ -2384,6 +2385,7 @@ public: WorldObject* GetSeer() const { return m_seer; } void SetViewpoint(WorldObject* target, bool apply); [[nodiscard]] WorldObject* GetViewpoint() const; + Position const& GetSightPosition() const; void StopCastingCharm(Aura* except = nullptr); void StopCastingBindSight(Aura* except = nullptr); @@ -2978,7 +2980,7 @@ private: Item* _StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool update); Item* _LoadItem(CharacterDatabaseTransaction trans, uint32 zoneId, uint32 timeDiff, Field* fields); - CinematicMgr* _cinematicMgr; + CinematicMgr _cinematicMgr; typedef GuidSet RefundableItemsSet; RefundableItemsSet m_refundableItems; diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index b276e461d0..ce2fde0517 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -68,14 +68,8 @@ void Player::Update(uint32 p_time) m_nextMailDelivereTime = time_t(0); } - // Update cinematic location, if 500ms have passed and we're doing a - // cinematic now. - _cinematicMgr->m_cinematicDiff += p_time; - if (_cinematicMgr->m_cinematicCamera && _cinematicMgr->m_activeCinematicCameraId && GetMSTimeDiffToNow(_cinematicMgr->m_lastCinematicCheck) > CINEMATIC_UPDATEDIFF) - { - _cinematicMgr->m_lastCinematicCheck = getMSTime(); - _cinematicMgr->UpdateCinematicLocation(p_time); - } + // Update cinematic camera (if needed) + _cinematicMgr.UpdateCinematic(p_time); // used to implement delayed far teleports SetMustDelayTeleport(true); @@ -1608,8 +1602,8 @@ void Player::UpdateVisibilityForPlayer(bool mapChange) m_seer = this; Acore::VisibleNotifier notifier(*this, mapChange); - Cell::VisitObjects(m_seer, notifier, GetSightRange()); - Cell::VisitFarVisibleObjects(m_seer, notifier, VISIBILITY_DISTANCE_GIGANTIC); + Cell::VisitObjects(GetSightPosition().GetPositionX(), GetSightPosition().GetPositionY(), GetMap(), notifier, GetSightRange()); + Cell::VisitFarVisibleObjects(GetSightPosition().GetPositionX(), GetSightPosition().GetPositionY(), GetMap(), notifier, VISIBILITY_DISTANCE_GIGANTIC); notifier.SendToSelf(); if (mapChange) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8712c7514f..391bb12e30 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16325,8 +16325,8 @@ void Unit::ExecuteDelayedUnitRelocationEvent() GetMap()->LoadGridsInRange(*player, MAX_VISIBILITY_DISTANCE); Acore::PlayerRelocationNotifier notifier(*player); - Cell::VisitObjects(viewPoint, notifier, player->GetSightRange()); - Cell::VisitFarVisibleObjects(viewPoint, notifier, VISIBILITY_DISTANCE_GIGANTIC); + Cell::VisitObjects(player->GetSightPosition().GetPositionX(), player->GetSightPosition().GetPositionY(), player->GetMap(), notifier, player->GetSightRange()); + Cell::VisitFarVisibleObjects(player->GetSightPosition().GetPositionX(), player->GetSightPosition().GetPositionY(), player->GetMap(), notifier, VISIBILITY_DISTANCE_GIGANTIC); notifier.SendToSelf(); this->AddToNotify(NOTIFY_AI_RELOCATION); diff --git a/src/server/game/Grids/Cells/Cell.h b/src/server/game/Grids/Cells/Cell.h index 72097e7e7d..d077a19c66 100644 --- a/src/server/game/Grids/Cells/Cell.h +++ b/src/server/game/Grids/Cells/Cell.h @@ -107,6 +107,7 @@ struct Cell template static void VisitObjects(float x, float y, Map* map, T& visitor, float radius); template static void VisitFarVisibleObjects(WorldObject const* obj, T& visitor, float radius); + template static void VisitFarVisibleObjects(float x, float y, Map* map, T& visitor, float radius); private: template void VisitCircle(TypeContainerVisitor&, Map&, CellCoord const&, CellCoord const&) const; diff --git a/src/server/game/Grids/Cells/CellImpl.h b/src/server/game/Grids/Cells/CellImpl.h index 4bc1a66ed5..3fe62948df 100644 --- a/src/server/game/Grids/Cells/CellImpl.h +++ b/src/server/game/Grids/Cells/CellImpl.h @@ -164,11 +164,7 @@ inline void Cell::VisitCircle(TypeContainerVisitor& visitor, Map& template inline void Cell::VisitObjects(WorldObject const* center_obj, T& visitor, float radius) { - CellCoord p(Acore::ComputeCellCoord(center_obj->GetPositionX(), center_obj->GetPositionY())); - Cell cell(p); - - TypeContainerVisitor gnotifier(visitor); - cell.Visit(p, gnotifier, *center_obj->GetMap(), *center_obj, radius); + VisitObjects(center_obj->GetPositionX(), center_obj->GetPositionY(), center_obj->GetMap(), visitor, radius); } template @@ -184,11 +180,17 @@ inline void Cell::VisitObjects(float x, float y, Map* map, T& visitor, float rad template inline void Cell::VisitFarVisibleObjects(WorldObject const* center_obj, T& visitor, float radius) { - CellCoord p(Acore::ComputeCellCoord(center_obj->GetPositionX(), center_obj->GetPositionY())); + VisitFarVisibleObjects(center_obj->GetPositionX(), center_obj->GetPositionY(), center_obj->GetMap(), visitor, radius); +} + +template +inline void Cell::VisitFarVisibleObjects(float x, float y, Map* map, T& visitor, float radius) +{ + CellCoord p(Acore::ComputeCellCoord(x, y)); Cell cell(p); TypeContainerVisitor gnotifier(visitor); - cell.Visit(p, gnotifier, *center_obj->GetMap(), *center_obj, radius); + cell.Visit(p, gnotifier, *map, x, y, radius); } #endif diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index 36ed177442..28f87f2863 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -192,7 +192,7 @@ void MessageDistDeliverer::Visit(VisiblePlayersMap const& m) for (auto const& kvPair : m) { Player const* target = kvPair.second; - if (i_distSq != 0.0f && target->m_seer->GetExactDist2dSq(i_source) > i_distSq) + if (i_distSq != 0.0f && target->GetSightPosition().GetExactDist2dSq(i_source) > i_distSq) continue; // @todo: Might not need this check anymore diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index e3271e3059..838ed4048e 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -1384,7 +1384,7 @@ namespace Acore AnyPlayerExactPositionInGameObjectRangeCheck(GameObject const* go, float range) : _go(go), _range(range) {} bool operator()(Player* u) { - if (!_go->IsInRange(u->GetPositionX(), u->GetPositionY(), u->GetPositionZ(), _range)) + if (!_go->IsInRange3d(u->GetPositionX(), u->GetPositionY(), u->GetPositionZ(), _range)) return false; return true; @@ -1604,7 +1604,7 @@ namespace Acore bool operator() (GameObject* go) { if (!entry || (go->GetGOInfo() && go->GetGOInfo()->entry == entry)) - return go->IsInRange(x, y, z, range); + return go->IsInRange3d(x, y, z, range); else return false; } private: diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 2a605bcdbf..d1f558025f 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -872,9 +872,9 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder) if (ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass())) { if (cEntry->CinematicSequence) - pCurrChar->SendCinematicStart(cEntry->CinematicSequence); + pCurrChar->GetCinematicMgr().StartCinematic(cEntry->CinematicSequence); else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) - pCurrChar->SendCinematicStart(rEntry->CinematicSequence); + pCurrChar->GetCinematicMgr().StartCinematic(rEntry->CinematicSequence); // send new char string if not empty std::string_view newCharString = sWorld->getStringConfig(CONFIG_NEW_CHAR_STRING); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index c90c3ff0e0..bfe454add9 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -947,14 +947,14 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) void WorldSession::HandleCompleteCinematic(WorldPacket& /*recv_data*/) { - // If player has sight bound to visual waypoint NPC we should remove it - GetPlayer()->GetCinematicMgr()->EndCinematic(); + // End the current cinematic and restore the normal player view + GetPlayer()->GetCinematicMgr().EndCinematic(); } void WorldSession::HandleNextCinematicCamera(WorldPacket& /*recv_data*/) { // Sent by client when cinematic actually begun. So we begin the server side process - GetPlayer()->GetCinematicMgr()->BeginCinematic(); + GetPlayer()->GetCinematicMgr().StartCinematicCamera(); } void WorldSession::HandleSetActionBarToggles(WorldPacket& recv_data) diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 2e85d484f5..55113a8068 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -379,8 +379,8 @@ void OpcodeTable::Initialize() /*0x0F8*/ DEFINE_HANDLER(CMSG_TRIGGER_CINEMATIC_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); /*0x0F9*/ DEFINE_HANDLER(CMSG_OPENING_CINEMATIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); /*0x0FA*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_NEVER); - /*0x0FB*/ DEFINE_HANDLER(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera ); - /*0x0FC*/ DEFINE_HANDLER(CMSG_COMPLETE_CINEMATIC, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCompleteCinematic ); + /*0x0FB*/ DEFINE_HANDLER(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleNextCinematicCamera ); + /*0x0FC*/ DEFINE_HANDLER(CMSG_COMPLETE_CINEMATIC, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCompleteCinematic ); /*0x0FD*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER); /*0x0FE*/ DEFINE_HANDLER(CMSG_TUTORIAL_FLAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialFlag ); /*0x0FF*/ DEFINE_HANDLER(CMSG_TUTORIAL_CLEAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialClear ); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 63e2c5c0b2..34163da51b 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -9069,7 +9069,7 @@ namespace Acore { if (target->IsGameObject()) { - if (!target->ToGameObject()->IsInRange(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range)) + if (!target->ToGameObject()->IsInRange3d(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range)) return false; } else if (!target->IsWithinDist3d(_position, _range)) diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index cd1fc6702d..156c0373a5 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -137,7 +137,7 @@ public: handler->PSendSysMessage("{} waypoints dumped", flyByCameras->size()); } - handler->GetPlayer()->SendCinematicStart(cinematicId); + handler->GetPlayer()->GetCinematicMgr().StartCinematic(cinematicId); return true; }