diff options
| author | r00ty-tc <r00ty-tc@users.noreply.github.com> | 2016-04-14 01:34:17 +0200 |
|---|---|---|
| committer | r00ty-tc <r00ty-tc@users.noreply.github.com> | 2016-04-14 01:34:17 +0200 |
| commit | 87b4533046d337fe05d7891c3632d34f8811b73e (patch) | |
| tree | cb0d9cac227a6ab0a099d83387c1320a52b369a1 /src/server/game/Entities/Player | |
| parent | afaa8e2c6035d5279521b3087a54e85a0961ff59 (diff) | |
[Core/Maps] Activate creatures and objects during opening cinematics and other flyby
cameras (sunwell etc).
Requires re-running map extractor to extract camera m2 files from data
files. These are very small.
Closes #4755
Closes #16772
Diffstat (limited to 'src/server/game/Entities/Player')
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 144 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 21 |
2 files changed, 162 insertions, 3 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 8b50d1fb406..c58f2c940fc 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -96,6 +96,9 @@ #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, @@ -535,6 +538,14 @@ Player::Player(WorldSession* session): Unit(true) _activeCheats = CHEAT_NONE; 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; + m_achievementMgr = new AchievementMgr(this); m_reputationMgr = new ReputationMgr(this); } @@ -1224,7 +1235,15 @@ void Player::Update(uint32 p_time) m_spellModTakingSpell = nullptr; } - //used to implement delayed far teleport + // 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) + { + m_lastCinematicCheck = getMSTime(); + UpdateCinematicLocation(p_time); + } + + //used to implement delayed far teleports SetCanDelayTeleport(true); Unit::Update(p_time); SetCanDelayTeleport(false); @@ -6398,11 +6417,13 @@ void Player::SendDirectMessage(WorldPacket const* data) const m_session->SendPacket(data); } -void Player::SendCinematicStart(uint32 CinematicSequenceId) const +void Player::SendCinematicStart(uint32 CinematicSequenceId) { WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4); data << uint32(CinematicSequenceId); SendDirectMessage(&data); + if (const CinematicSequencesEntry* sequence = sCinematicSequencesStore.LookupEntry(CinematicSequenceId)) + SetActiveCinematicCamera(sequence->cinematicCamera); } void Player::SendMovieStart(uint32 MovieId) const @@ -26189,6 +26210,125 @@ 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 b8719d3e927..fd0fac69674 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2129,7 +2129,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void ResummonPetTemporaryUnSummonedIfAny(); bool IsPetNeedBeTemporaryUnsummoned() const; - void SendCinematicStart(uint32 CinematicSequenceId) const; + void SendCinematicStart(uint32 CinematicSequenceId); void SendMovieStart(uint32 MovieId) const; /*********************************************************/ @@ -2265,6 +2265,17 @@ 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; @@ -2590,6 +2601,14 @@ 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); |
