aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorr00ty-tc <r00ty-tc@users.noreply.github.com>2016-05-11 10:51:15 +0100
committerr00ty-tc <r00ty-tc@users.noreply.github.com>2016-05-11 11:56:25 +0200
commitde918a0f644794beebff2234b53980b577b27e39 (patch)
tree54d21dce2d9014bf39380958f8c172a1f316a0ae /src/server/game/Entities
parent7e48a023989e50920fe2e115cb57d25095071a17 (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.cpp4
-rw-r--r--src/server/game/Entities/Player/CinematicMgr.cpp171
-rw-r--r--src/server/game/Entities/Player/CinematicMgr.h60
-rw-r--r--src/server/game/Entities/Player/Player.cpp143
-rw-r--r--src/server/game/Entities/Player/Player.h27
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);