mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
203 lines
6.7 KiB
C++
203 lines
6.7 KiB
C++
/*
|
|
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
|
*
|
|
* 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 "PersonalPhaseTracker.h"
|
|
#include "Log.h"
|
|
#include "Map.h"
|
|
#include "MapUtils.h"
|
|
#include "Object.h"
|
|
#include "ObjectGridLoader.h"
|
|
#include "ObjectMgr.h"
|
|
|
|
/*********************************************************/
|
|
/*** PlayerPersonalPhasesTracker ***/
|
|
/*********************************************************/
|
|
|
|
void PlayerPersonalPhasesTracker::RegisterTrackedObject(uint32 phaseId, WorldObject* object)
|
|
{
|
|
_spawns[phaseId].Objects.insert(object);
|
|
}
|
|
|
|
void PlayerPersonalPhasesTracker::UnregisterTrackedObject(WorldObject* object)
|
|
{
|
|
for (auto& [_, spawns] : _spawns)
|
|
spawns.Objects.erase(object);
|
|
}
|
|
|
|
void PlayerPersonalPhasesTracker::OnOwnerPhasesChanged(WorldObject const* owner)
|
|
{
|
|
PhaseShift const& phaseShift = owner->GetPhaseShift();
|
|
|
|
// Loop over all our tracked phases. If any don't exist - delete them
|
|
for (auto& [phaseId, spawns] : _spawns)
|
|
if (!spawns.DurationRemaining && !phaseShift.HasPhase(phaseId))
|
|
spawns.DurationRemaining = PersonalPhaseSpawns::DELETE_TIME_DEFAULT;
|
|
|
|
// loop over all owner phases. If any exist and marked for deletion - reset delete
|
|
for (PhaseShift::PhaseRef const& phaseRef : phaseShift.GetPhases())
|
|
if (PersonalPhaseSpawns* spawns = Trinity::Containers::MapGetValuePtr(_spawns, phaseRef.Id))
|
|
spawns->DurationRemaining.reset();
|
|
}
|
|
|
|
void PlayerPersonalPhasesTracker::MarkAllPhasesForDeletion()
|
|
{
|
|
for (auto& [_, spawns] : _spawns)
|
|
spawns.DurationRemaining = PersonalPhaseSpawns::DELETE_TIME_DEFAULT;
|
|
}
|
|
|
|
void PlayerPersonalPhasesTracker::Update(Map* map, uint32 diff)
|
|
{
|
|
for (auto itr = _spawns.begin(); itr != _spawns.end(); )
|
|
{
|
|
if (itr->second.DurationRemaining)
|
|
{
|
|
itr->second.DurationRemaining = *itr->second.DurationRemaining - Milliseconds(diff);
|
|
if (itr->second.DurationRemaining <= Milliseconds::zero())
|
|
{
|
|
DespawnPhase(map, itr->second);
|
|
itr = _spawns.erase(itr);
|
|
continue;
|
|
}
|
|
}
|
|
++itr;
|
|
}
|
|
}
|
|
|
|
bool PlayerPersonalPhasesTracker::IsGridLoadedForPhase(uint32 gridId, uint32 phaseId) const
|
|
{
|
|
if (PersonalPhaseSpawns const* spawns = Trinity::Containers::MapGetValuePtr(_spawns, phaseId))
|
|
return spawns->Grids.find(gridId) != spawns->Grids.cend();
|
|
|
|
return false;
|
|
}
|
|
|
|
void PlayerPersonalPhasesTracker::SetGridLoadedForPhase(uint32 gridId, uint32 phaseId)
|
|
{
|
|
PersonalPhaseSpawns& group = _spawns[phaseId];
|
|
group.Grids.insert(gridId);
|
|
}
|
|
|
|
void PlayerPersonalPhasesTracker::SetGridUnloaded(uint32 gridId)
|
|
{
|
|
for (auto itr = _spawns.begin(); itr != _spawns.end(); )
|
|
{
|
|
itr->second.Grids.erase(gridId);
|
|
if (itr->second.IsEmpty())
|
|
itr = _spawns.erase(itr);
|
|
else
|
|
++itr;
|
|
}
|
|
}
|
|
|
|
void PlayerPersonalPhasesTracker::DespawnPhase(Map* map, PersonalPhaseSpawns& spawns)
|
|
{
|
|
for (WorldObject* obj : spawns.Objects)
|
|
map->AddObjectToRemoveList(obj);
|
|
|
|
spawns.Objects.clear();
|
|
spawns.Grids.clear();
|
|
}
|
|
|
|
/*********************************************************/
|
|
/*** MultiPersonalPhaseTracker ***/
|
|
/*********************************************************/
|
|
|
|
void MultiPersonalPhaseTracker::LoadGrid(PhaseShift const& phaseShift, NGridType& grid, Map* map, Cell const& cell)
|
|
{
|
|
if (!phaseShift.HasPersonalPhase())
|
|
return;
|
|
|
|
PersonalPhaseGridLoader loader(grid, map, cell, phaseShift.GetPersonalGuid());
|
|
PlayerPersonalPhasesTracker& playerTracker = _playerData[phaseShift.GetPersonalGuid()];
|
|
|
|
for (PhaseShift::PhaseRef const& phaseRef : phaseShift.GetPhases())
|
|
{
|
|
if (!phaseRef.IsPersonal())
|
|
continue;
|
|
|
|
if (!sObjectMgr->HasPersonalSpawns(map->GetId(), map->GetDifficultyID(), phaseRef.Id))
|
|
continue;
|
|
|
|
if (playerTracker.IsGridLoadedForPhase(grid.GetGridId(), phaseRef.Id))
|
|
continue;
|
|
|
|
TC_LOG_DEBUG("maps", "Loading personal phase objects (phase {}) in grid[{}, {}] for map {} instance {}",
|
|
phaseRef.Id, cell.GridX(), cell.GridY(), map->GetId(), map->GetInstanceId());
|
|
|
|
loader.Load(phaseRef.Id);
|
|
|
|
playerTracker.SetGridLoadedForPhase(grid.GetGridId(), phaseRef.Id);
|
|
}
|
|
|
|
if (loader.GetLoadedGameObjects())
|
|
map->Balance();
|
|
}
|
|
|
|
void MultiPersonalPhaseTracker::UnloadGrid(NGridType& grid)
|
|
{
|
|
for (auto itr = _playerData.begin(); itr != _playerData.end(); )
|
|
{
|
|
itr->second.SetGridUnloaded(grid.GetGridId());
|
|
if (itr->second.IsEmpty())
|
|
itr = _playerData.erase(itr);
|
|
else
|
|
++itr;
|
|
}
|
|
}
|
|
|
|
void MultiPersonalPhaseTracker::RegisterTrackedObject(uint32 phaseId, ObjectGuid const& phaseOwner, WorldObject* object)
|
|
{
|
|
ASSERT(phaseId);
|
|
ASSERT(!phaseOwner.IsEmpty());
|
|
ASSERT(object);
|
|
|
|
_playerData[phaseOwner].RegisterTrackedObject(phaseId, object);
|
|
}
|
|
|
|
void MultiPersonalPhaseTracker::UnregisterTrackedObject(WorldObject* object)
|
|
{
|
|
if (PlayerPersonalPhasesTracker* playerTracker = Trinity::Containers::MapGetValuePtr(_playerData, object->GetPhaseShift().GetPersonalGuid()))
|
|
playerTracker->UnregisterTrackedObject(object);
|
|
}
|
|
|
|
void MultiPersonalPhaseTracker::OnOwnerPhaseChanged(WorldObject const* phaseOwner, NGridType* grid, Map* map, Cell const& cell)
|
|
{
|
|
if (PlayerPersonalPhasesTracker* playerTracker = Trinity::Containers::MapGetValuePtr(_playerData, phaseOwner->GetGUID()))
|
|
playerTracker->OnOwnerPhasesChanged(phaseOwner);
|
|
|
|
if (grid)
|
|
LoadGrid(phaseOwner->GetPhaseShift(), *grid, map, cell);
|
|
}
|
|
|
|
void MultiPersonalPhaseTracker::MarkAllPhasesForDeletion(ObjectGuid const& phaseOwner)
|
|
{
|
|
if (PlayerPersonalPhasesTracker* playerTracker = Trinity::Containers::MapGetValuePtr(_playerData, phaseOwner))
|
|
playerTracker->MarkAllPhasesForDeletion();
|
|
}
|
|
|
|
void MultiPersonalPhaseTracker::Update(Map* map, uint32 diff)
|
|
{
|
|
for (auto itr = _playerData.begin(); itr != _playerData.end(); )
|
|
{
|
|
itr->second.Update(map, diff);
|
|
if (itr->second.IsEmpty())
|
|
itr = _playerData.erase(itr);
|
|
else
|
|
++itr;
|
|
}
|
|
}
|