Core/Instances: Save instance entrance based on completed encounters

This commit is contained in:
Shauren
2021-01-16 22:17:11 +01:00
parent 1e99011edf
commit 4cbaaa3435
5 changed files with 41 additions and 9 deletions

View File

@@ -346,6 +346,9 @@ InstanceLock* InstanceLockMgr::UpdateInstanceLockForPlayer(CharacterDatabaseTran
if (!entries.MapDifficulty->IsUsingEncounterLocks())
instanceLock->GetData()->CompletedEncountersMask |= updateEvent.InstanceCompletedEncountersMask;
if (updateEvent.EntranceWorldSafeLocId)
instanceLock->GetData()->EntranceWorldSafeLocId = *updateEvent.EntranceWorldSafeLocId;
if (instanceLock->IsExpired())
{
ASSERT(instanceLock->IsExtended(), "Instance lock must have been extended to create instance map from it");
@@ -393,6 +396,9 @@ void InstanceLockMgr::UpdateSharedInstanceLock(CharacterDatabaseTransaction tran
updateEvent.InstanceId, updateEvent.CompletedEncounter->ID, updateEvent.CompletedEncounter->Name[sWorld->GetDefaultDbcLocale()]);
}
if (updateEvent.EntranceWorldSafeLocId)
sharedData->EntranceWorldSafeLocId = *updateEvent.EntranceWorldSafeLocId;
trans->PAppend("DELETE FROM instance2 WHERE instanceId=%u",
sharedData->InstanceId);
std::string escapedData = sharedData->Data;

View File

@@ -23,6 +23,7 @@
#include "Duration.h"
#include "Hash.h"
#include "ObjectGuid.h"
#include "Optional.h"
#include <unordered_map>
/*
@@ -173,8 +174,10 @@ struct TC_GAME_API MapDb2Entries
struct InstanceLockUpdateEvent
{
InstanceLockUpdateEvent(uint32 instanceId, std::string newData, uint32 instanceCompletedEncountersMask, DungeonEncounterEntry const* completedEncounter)
: InstanceId(instanceId), NewData(std::move(newData)), InstanceCompletedEncountersMask(instanceCompletedEncountersMask), CompletedEncounter(completedEncounter) { }
InstanceLockUpdateEvent(uint32 instanceId, std::string newData, uint32 instanceCompletedEncountersMask, DungeonEncounterEntry const* completedEncounter,
Optional<uint32> entranceWorldSafeLocId) :
InstanceId(instanceId), NewData(std::move(newData)), InstanceCompletedEncountersMask(instanceCompletedEncountersMask), CompletedEncounter(completedEncounter),
EntranceWorldSafeLocId(entranceWorldSafeLocId) { }
InstanceLockUpdateEvent(InstanceLockUpdateEvent const& other) = delete;
InstanceLockUpdateEvent(InstanceLockUpdateEvent&& other) noexcept;
@@ -186,6 +189,7 @@ struct InstanceLockUpdateEvent
std::string NewData;
uint32 InstanceCompletedEncountersMask;
DungeonEncounterEntry const* CompletedEncounter;
Optional<uint32> EntranceWorldSafeLocId;
};
// TOTALLY NOT THREADSAFE YET

View File

@@ -521,6 +521,19 @@ std::string InstanceScript::UpdateAdditionalSaveData(std::string const& oldData,
return writer.GetString();
}
Optional<uint32> InstanceScript::GetEntranceLocationForCompletedEncounters(uint32 completedEncountersMask) const
{
if (!instance->GetMapDifficulty()->IsUsingEncounterLocks())
return _entranceId;
return ComputeEntranceLocationForCompletedEncounters(completedEncountersMask);
}
Optional<uint32> InstanceScript::ComputeEntranceLocationForCompletedEncounters(uint32 /*completedEncountersMask*/) const
{
return { };
}
void InstanceScript::HandleGameObject(ObjectGuid guid, bool open, GameObject* go /*= nullptr*/)
{
if (!go)

View File

@@ -21,6 +21,7 @@
#include "ZoneScript.h"
#include "Common.h"
#include "Duration.h"
#include "Optional.h"
#include <array>
#include <map>
#include <set>
@@ -197,6 +198,8 @@ class TC_GAME_API InstanceScript : public ZoneScript
std::string UpdateBossStateSaveData(std::string const& oldData, UpdateBossStateSaveDataEvent const& event);
std::string UpdateAdditionalSaveData(std::string const& oldData, UpdateAdditionalSaveDataEvent const& event);
Optional<uint32> GetEntranceLocationForCompletedEncounters(uint32 completedEncountersMask) const;
virtual Optional<uint32> ComputeEntranceLocationForCompletedEncounters(uint32 completedEncountersMask) const;
virtual void Update(uint32 /*diff*/) { }
void UpdateCombatResurrection(uint32 diff);

View File

@@ -3017,8 +3017,8 @@ void InstanceMap::UpdateInstanceLock(UpdateBossStateSaveDataEvent const& updateS
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
if (entries.IsInstanceIdBound())
sInstanceLockMgr.UpdateSharedInstanceLock(trans,
{ GetInstanceId(), i_data->GetSaveData(), instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter });
sInstanceLockMgr.UpdateSharedInstanceLock(trans, InstanceLockUpdateEvent(GetInstanceId(), i_data->GetSaveData(),
instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter, i_data->GetEntranceLocationForCompletedEncounters(instanceCompletedEncounters)));
for (MapReference& mapReference : m_mapRefManager)
{
@@ -3029,13 +3029,18 @@ void InstanceMap::UpdateInstanceLock(UpdateBossStateSaveDataEvent const& updateS
InstanceLock const* playerLock = sInstanceLockMgr.FindActiveInstanceLock(player->GetGUID(), entries);
std::string const* oldData = nullptr;
uint32 playerCompletedEncounters = 0;
if (playerLock)
{
oldData = &playerLock->GetData()->Data;
playerCompletedEncounters = playerLock->GetData()->CompletedEncountersMask | (1u << updateSaveDataEvent.DungeonEncounter->Bit);
}
bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired();
InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries,
{ GetInstanceId(), i_data->UpdateBossStateSaveData(oldData ? *oldData : "", updateSaveDataEvent), instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter });
InstanceLockUpdateEvent(GetInstanceId(), i_data->UpdateBossStateSaveData(oldData ? *oldData : "", updateSaveDataEvent),
instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter, i_data->GetEntranceLocationForCompletedEncounters(playerCompletedEncounters)));
if (isNewLock)
{
@@ -3062,8 +3067,8 @@ void InstanceMap::UpdateInstanceLock(UpdateAdditionalSaveDataEvent const& update
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
if (entries.IsInstanceIdBound())
sInstanceLockMgr.UpdateSharedInstanceLock(trans,
{ GetInstanceId(), i_data->GetSaveData(), instanceCompletedEncounters, nullptr });
sInstanceLockMgr.UpdateSharedInstanceLock(trans, InstanceLockUpdateEvent(GetInstanceId(), i_data->GetSaveData(),
instanceCompletedEncounters, nullptr, {}));
for (MapReference& mapReference : m_mapRefManager)
{
@@ -3080,7 +3085,8 @@ void InstanceMap::UpdateInstanceLock(UpdateAdditionalSaveDataEvent const& update
bool isNewLock = !playerLock || !playerLock->GetData()->CompletedEncountersMask || playerLock->IsExpired();
InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries,
{ GetInstanceId(), i_data->UpdateAdditionalSaveData(oldData ? *oldData : "", updateSaveDataEvent), instanceCompletedEncounters, nullptr });
InstanceLockUpdateEvent(GetInstanceId(), i_data->UpdateAdditionalSaveData(oldData ? *oldData : "", updateSaveDataEvent),
instanceCompletedEncounters, nullptr, {}));
if (isNewLock)
{
@@ -3106,7 +3112,7 @@ void InstanceMap::CreateInstanceLockForPlayer(Player* player)
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries,
{ GetInstanceId(), i_data->GetSaveData(), i_instanceLock->GetData()->CompletedEncountersMask, nullptr });
InstanceLockUpdateEvent(GetInstanceId(), i_data->GetSaveData(), i_instanceLock->GetData()->CompletedEncountersMask, nullptr, {}));
CharacterDatabase.CommitTransaction(trans);