diff options
| author | r00ty-tc <r00ty-tc@users.noreply.github.com> | 2016-05-11 10:51:15 +0100 |
|---|---|---|
| committer | r00ty-tc <r00ty-tc@users.noreply.github.com> | 2016-05-11 11:56:25 +0200 |
| commit | de918a0f644794beebff2234b53980b577b27e39 (patch) | |
| tree | 54d21dce2d9014bf39380958f8c172a1f316a0ae /src/server/game/Entities | |
| parent | 7e48a023989e50920fe2e115cb57d25095071a17 (diff) | |
Core/Maps - Improvements to Cinematic function
- Moves to own class for reading, storage and player subclass
- Proper destruction handling for player (ensure cinematic is ended)
- Timeout for cinematic if it reaches past the end without completing
- boost::filesystem::path used for path/filename transform
- Correct for assert trigger under certain circumstances
- Other changes previously suggested
Diffstat (limited to 'src/server/game/Entities')
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/CinematicMgr.cpp | 171 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/CinematicMgr.h | 60 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 143 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 27 |
5 files changed, 248 insertions, 157 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 45952ba51ac..a2f519a681c 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1471,7 +1471,7 @@ float WorldObject::GetGridActivationRange() const { if (ToPlayer()) { - if (ToPlayer()->IsOnCinematic()) + if (ToPlayer()->GetCinematicMgr()->IsOnCinematic()) return DEFAULT_VISIBILITY_INSTANCE; return GetMap()->GetVisibilityRange(); } @@ -1504,7 +1504,7 @@ float WorldObject::GetSightRange(const WorldObject* target) const { if (target && target->isActiveObject() && !target->ToPlayer()) return MAX_VISIBILITY_DISTANCE; - else if (ToPlayer()->IsOnCinematic()) + else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic()) return DEFAULT_VISIBILITY_INSTANCE; else return GetMap()->GetVisibilityRange(); diff --git a/src/server/game/Entities/Player/CinematicMgr.cpp b/src/server/game/Entities/Player/CinematicMgr.cpp new file mode 100644 index 00000000000..07bf733c9ff --- /dev/null +++ b/src/server/game/Entities/Player/CinematicMgr.cpp @@ -0,0 +1,171 @@ +/* +* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> +* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "CinematicMgr.h" +#include "Creature.h" +#include "Player.h" +#include "TemporarySummon.h" + +CinematicMgr::CinematicMgr(Player* playerref) +{ + player = playerref; + m_cinematicDiff = 0; + m_lastCinematicCheck = 0; + m_activeCinematicCameraId = 0; + m_cinematicCamera = nullptr; + m_remoteSightPosition = Position(0.0f, 0.0f, 0.0f); + m_CinematicObject = nullptr; +} + +CinematicMgr::~CinematicMgr() +{ + if (m_cinematicCamera && m_activeCinematicCameraId) + EndCinematic(); +} + +void CinematicMgr::BeginCinematic() +{ + // Sanity check for active camera set + if (m_activeCinematicCameraId == 0) + return; + + auto itr = sFlyByCameraStore.find(m_activeCinematicCameraId); + if (itr != sFlyByCameraStore.end()) + { + // Initialize diff, and set camera + m_cinematicDiff = 0; + m_cinematicCamera = &itr->second; + + auto camitr = m_cinematicCamera->begin(); + if (camitr != m_cinematicCamera->end()) + { + Position pos(camitr->locations.x, camitr->locations.y, camitr->locations.z, camitr->locations.w); + if (!pos.IsPositionValid()) + return; + + player->GetMap()->LoadGrid(camitr->locations.x, camitr->locations.y); + m_CinematicObject = player->SummonCreature(VISUAL_WAYPOINT, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 5 * MINUTE * IN_MILLISECONDS); + if (m_CinematicObject) + { + m_CinematicObject->setActive(true); + player->SetViewpoint(m_CinematicObject, true); + } + + // Get cinematic length + FlyByCameraCollection::const_reverse_iterator camrevitr = m_cinematicCamera->rbegin(); + if (camrevitr != m_cinematicCamera->rend()) + m_cinematicLength = camrevitr->timeStamp; + } + } +} + +void CinematicMgr::EndCinematic() +{ + if (m_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(); + } +} + +void CinematicMgr::UpdateCinematicLocation(uint32 /*diff*/) +{ + if (m_activeCinematicCameraId == 0 || !m_cinematicCamera || m_cinematicCamera->size() == 0) + return; + + Position lastPosition; + uint32 lastTimestamp = 0; + Position nextPosition; + uint32 nextTimestamp = 0; + + // Obtain direction of travel + for (FlyByCamera cam : *m_cinematicCamera) + { + if (cam.timeStamp > m_cinematicDiff) + { + nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); + nextTimestamp = cam.timeStamp; + break; + } + lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); + lastTimestamp = cam.timeStamp; + } + float angle = lastPosition.GetAngle(&nextPosition); + angle -= lastPosition.GetOrientation(); + if (angle < 0) + angle += 2 * float(M_PI); + + // Look for position around 2 second ahead of us. + int32 workDiff = m_cinematicDiff; + + // Modify result based on camera direction (Humans for example, have the camera point behind) + workDiff += static_cast<int32>(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 + FlyByCameraCollection::const_reverse_iterator endItr = m_cinematicCamera->rbegin(); + if (endItr != m_cinematicCamera->rend() && workDiff > static_cast<int32>(endItr->timeStamp)) + workDiff = endItr->timeStamp; + + // Never try to go back in time before the start of cinematic! + if (workDiff < 0) + workDiff = m_cinematicDiff; + + // Obtain the previous and next waypoint based on timestamp + for (FlyByCamera cam : *m_cinematicCamera) + { + if (static_cast<int32>(cam.timeStamp) >= workDiff) + { + nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); + nextTimestamp = cam.timeStamp; + break; + } + lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); + lastTimestamp = cam.timeStamp; + } + + // Never try to go beyond the end of the cinematic + if (workDiff > static_cast<int32>(nextTimestamp)) + workDiff = static_cast<int32>(nextTimestamp); + + // Interpolate the position for this moment in time (or the adjusted moment in time) + uint32 timeDiff = nextTimestamp - lastTimestamp; + uint32 interDiff = workDiff - lastTimestamp; + float xDiff = nextPosition.m_positionX - lastPosition.m_positionX; + float yDiff = nextPosition.m_positionY - lastPosition.m_positionY; + float zDiff = nextPosition.m_positionZ - lastPosition.m_positionZ; + 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, false, true); + + // 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) + EndCinematic(); +} diff --git a/src/server/game/Entities/Player/CinematicMgr.h b/src/server/game/Entities/Player/CinematicMgr.h new file mode 100644 index 00000000000..ab067afa042 --- /dev/null +++ b/src/server/game/Entities/Player/CinematicMgr.h @@ -0,0 +1,60 @@ +/* +* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> +* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef CinematicMgr_h__ +#define CinematicMgr_h__ + +#include "Define.h" +#include "Object.h" +#include "M2Stores.h" + +#define CINEMATIC_LOOKAHEAD (2 * IN_MILLISECONDS) +#define CINEMATIC_UPDATEDIFF 500 + +class Player; + +class TC_GAME_API CinematicMgr +{ + friend class Player; +public: + explicit CinematicMgr(Player* playerref); + ~CinematicMgr(); + + // 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 EndCinematic(); + void UpdateCinematicLocation(uint32 diff); + +private: + // Remote location information + Player* player; + +protected: + uint32 m_cinematicDiff; + uint32 m_lastCinematicCheck; + uint32 m_activeCinematicCameraId; + uint32 m_cinematicLength; + FlyByCameraCollection* m_cinematicCamera; + Position m_remoteSightPosition; + TempSummon* m_CinematicObject; +}; + +#endif
\ No newline at end of file diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 281427a18f4..9ed101bf52e 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -96,9 +96,6 @@ #define SKILL_PERM_BONUS(x) int16(PAIR32_HIPART(x)) #define MAKE_SKILL_BONUS(t, p) MAKE_PAIR32(t, p) -#define CINEMATIC_LOOKAHEAD (2 * IN_MILLISECONDS) -#define CINEMATIC_UPDATEDIFF 500 - enum CharacterFlags { CHARACTER_FLAG_NONE = 0x00000000, @@ -529,12 +526,7 @@ Player::Player(WorldSession* session): Unit(true) healthBeforeDuel = 0; manaBeforeDuel = 0; - m_cinematicDiff = 0; - m_lastCinematicCheck = 0; - m_activeCinematicCameraId = 0; - m_cinematicCamera = nullptr; - m_remoteSightPosition = Position(0.0f, 0.0f, 0.0f); - m_CinematicObject = nullptr; + _cinematicMgr = new CinematicMgr(this); m_achievementMgr = new AchievementMgr(this); m_reputationMgr = new ReputationMgr(this); @@ -1226,11 +1218,11 @@ void Player::Update(uint32 p_time) } // Update cinematic location, if 500ms have passed and we're doing a cinematic now. - m_cinematicDiff += p_time; - if (m_cinematicCamera && m_activeCinematicCameraId && GetMSTimeDiffToNow(m_lastCinematicCheck) > CINEMATIC_UPDATEDIFF) + _cinematicMgr->m_cinematicDiff += p_time; + if (_cinematicMgr->m_cinematicCamera && _cinematicMgr->m_activeCinematicCameraId && GetMSTimeDiffToNow(_cinematicMgr->m_lastCinematicCheck) > CINEMATIC_UPDATEDIFF) { - m_lastCinematicCheck = getMSTime(); - UpdateCinematicLocation(p_time); + _cinematicMgr->m_lastCinematicCheck = getMSTime(); + _cinematicMgr->UpdateCinematicLocation(p_time); } //used to implement delayed far teleports @@ -6398,13 +6390,13 @@ void Player::SendDirectMessage(WorldPacket const* data) const m_session->SendPacket(data); } -void Player::SendCinematicStart(uint32 CinematicSequenceId) +void Player::SendCinematicStart(uint32 CinematicSequenceId) const { WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4); data << uint32(CinematicSequenceId); SendDirectMessage(&data); - if (const CinematicSequencesEntry* sequence = sCinematicSequencesStore.LookupEntry(CinematicSequenceId)) - SetActiveCinematicCamera(sequence->cinematicCamera); + if (CinematicSequencesEntry const* sequence = sCinematicSequencesStore.LookupEntry(CinematicSequenceId)) + _cinematicMgr->SetActiveCinematicCamera(sequence->cinematicCamera); } void Player::SendMovieStart(uint32 MovieId) const @@ -26243,125 +26235,6 @@ float Player::GetCollisionHeight(bool mounted) const } } -void Player::BeginCinematic() -{ - // Sanity check for active camera set - if (m_activeCinematicCameraId == 0) - return; - - auto itr = sFlyByCameraStore.find(m_activeCinematicCameraId); - if (itr != sFlyByCameraStore.end()) - { - // Initialize diff, and set camera - m_cinematicDiff = 0; - m_cinematicCamera = &itr->second; - - auto camitr = m_cinematicCamera->begin(); - if (camitr != m_cinematicCamera->end()) - { - Position pos(camitr->locations.x, camitr->locations.y, camitr->locations.z, camitr->locations.w); - if (!pos.IsPositionValid()) - return; - - m_mapRef->LoadGrid(camitr->locations.x, camitr->locations.y); - m_CinematicObject = SummonCreature(VISUAL_WAYPOINT, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000); - if (m_CinematicObject) - { - m_CinematicObject->setActive(true); - SetViewpoint(m_CinematicObject, true); - } - } - } -} - -void Player::EndCinematic() -{ - m_cinematicDiff = 0; - m_cinematicCamera = nullptr; - m_activeCinematicCameraId = 0; - if (m_CinematicObject) - { - if (m_seer && m_seer == m_CinematicObject) - SetViewpoint(m_CinematicObject, false); - m_CinematicObject->AddObjectToRemoveList(); - } -} - -void Player::UpdateCinematicLocation(uint32 /*diff*/) -{ - Position lastPosition; - uint32 lastTimestamp = 0; - Position nextPosition; - uint32 nextTimestamp = 0; - - if (m_cinematicCamera->size() == 0) - return; - - // Obtain direction of travel - for (FlyByCamera cam : *m_cinematicCamera) - { - if (cam.timeStamp > m_cinematicDiff) - { - nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); - nextTimestamp = cam.timeStamp; - break; - } - lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); - lastTimestamp = cam.timeStamp; - } - float angle = lastPosition.GetAngle(&nextPosition); - angle -= lastPosition.GetOrientation(); - if (angle < 0) - angle += 2 * float(M_PI); - - // Look for position around 2 second ahead of us. - int32 workDiff = m_cinematicDiff; - - // Modify result based on camera direction (Humans for example, have the camera point behind) - workDiff += static_cast<int32>(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 - FlyByCameraCollection::const_reverse_iterator endItr = m_cinematicCamera->rbegin(); - if (endItr != m_cinematicCamera->rend() && workDiff > static_cast<int32>(endItr->timeStamp)) - workDiff = endItr->timeStamp; - - // Never try to go back in time before the start of cinematic! - if (workDiff < 0) - workDiff = m_cinematicDiff; - - // Obtain the previous and next waypoint based on timestamp - for (FlyByCamera cam : *m_cinematicCamera) - { - if (static_cast<int32>(cam.timeStamp) >= workDiff) - { - nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); - nextTimestamp = cam.timeStamp; - break; - } - lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); - lastTimestamp = cam.timeStamp; - } - - // Never try to go beyond the end of the cinematic - if (workDiff > static_cast<int32>(nextTimestamp)) - workDiff = static_cast<int32>(nextTimestamp); - - // Interpolate the position for this moment in time (or the adjusted moment in time) - uint32 timeDiff = nextTimestamp - lastTimestamp; - uint32 interDiff = workDiff - lastTimestamp; - float xDiff = nextPosition.m_positionX - lastPosition.m_positionX; - float yDiff = nextPosition.m_positionY - lastPosition.m_positionY; - float zDiff = nextPosition.m_positionZ - lastPosition.m_positionZ; - 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, 200.0f, false, true); -} - - std::string Player::GetMapAreaAndZoneString() const { uint32 areaId = GetAreaId(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7657c0d4b7f..372a49b4f9d 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -30,6 +30,7 @@ #include "SpellHistory.h" #include "Unit.h" #include "TradeData.h" +#include "CinematicMgr.h" #include <limits> #include <string> @@ -1026,6 +1027,7 @@ struct ResurrectionData class TC_GAME_API Player : public Unit, public GridObject<Player> { friend class WorldSession; + friend class CinematicMgr; friend void Item::AddToUpdateQueueOf(Player* player); friend void Item::RemoveFromUpdateQueueOf(Player* player); public: @@ -1274,6 +1276,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> TradeData* GetTradeData() const { return m_trade; } void TradeCancel(bool sendback); + CinematicMgr* GetCinematicMgr() const { return _cinematicMgr; } + void UpdateEnchantTime(uint32 time); void UpdateSoulboundTradeItems(); void AddTradeableItem(Item* item); @@ -2129,7 +2133,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void ResummonPetTemporaryUnSummonedIfAny(); bool IsPetNeedBeTemporaryUnsummoned() const; - void SendCinematicStart(uint32 CinematicSequenceId); + void SendCinematicStart(uint32 CinematicSequenceId) const; void SendMovieStart(uint32 MovieId) const; uint32 DoRandomRoll(uint32 minimum, uint32 maximum); @@ -2267,17 +2271,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> std::string GetMapAreaAndZoneString() const; std::string GetCoordsMapAreaAndZoneString() const; - // 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 EndCinematic(); - void UpdateCinematicLocation(uint32 diff); - - std::string GetMapAreaAndZoneString(); - std::string GetCoordsMapAreaAndZoneString(); - protected: // Gamemaster whisper whitelist GuidList WhisperList; @@ -2537,6 +2530,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> Item* _StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool update); Item* _LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, Field* fields); + CinematicMgr* _cinematicMgr; + GuidSet m_refundableItems; void SendRefundInfo(Item* item); void RefundItem(Item* item); @@ -2603,14 +2598,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> uint32 manaBeforeDuel; WorldLocation _corpseLocation; - - // Remote location information - uint32 m_cinematicDiff; - uint32 m_lastCinematicCheck; - uint32 m_activeCinematicCameraId; - FlyByCameraCollection* m_cinematicCamera; - Position m_remoteSightPosition; - Creature* m_CinematicObject; }; TC_GAME_API void AddItemsSetItem(Player* player, Item* item); |
