Skip to content

Commit

Permalink
refactor: DiscoveryService
Browse files Browse the repository at this point in the history
  • Loading branch information
RobbeBryssinck committed Dec 23, 2021
1 parent 4f8fbe0 commit 4f81fcd
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 65 deletions.
12 changes: 8 additions & 4 deletions Code/client/Services/DiscoveryService.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,18 @@ struct DiscoveryService final

private:

void ResetCachedCellData() noexcept;
void VisitExteriorCell(bool aForceTrigger) noexcept;
void VisitInteriorCell(bool aForceTrigger) noexcept;

World& m_world;
entt::dispatcher& m_dispatcher;

Set<uint32_t> m_forms;
int32_t m_centerGridX = 0xFFFF;
int32_t m_centerGridY = 0xFFFF;
int32_t m_currentGridX = 0xFFFF;
int32_t m_currentGridY = 0xFFFF;
int32_t m_centerGridX = 0x7FFFFFFF;
int32_t m_centerGridY = 0x7FFFFFFF;
int32_t m_currentGridX = 0x7FFFFFFF;
int32_t m_currentGridY = 0x7FFFFFFF;
uint32_t m_worldSpaceId = 0;
uint32_t m_interiorCellId = 0;
struct TESForm *m_pLocation = nullptr;
Expand Down
137 changes: 77 additions & 60 deletions Code/client/Services/Generic/DiscoveryService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,87 +35,95 @@ DiscoveryService::DiscoveryService(World& aWorld, entt::dispatcher& aDispatcher)

void DiscoveryService::VisitCell(bool aForceTrigger) noexcept
{
const auto pPlayer = PlayerCharacter::Get();
const PlayerCharacter* pPlayer = PlayerCharacter::Get();
if (!pPlayer)
return;

if (const auto pWorldSpace = pPlayer->GetWorldSpace())
if (pPlayer->GetWorldSpace())
{
m_interiorCellId = 0;
const auto* pTES = TES::Get();
const auto worldSpaceId = pWorldSpace->formID;
VisitExteriorCell(aForceTrigger);
}
else if (pPlayer->GetParentCell())
{
VisitInteriorCell(aForceTrigger);
}

if (m_worldSpaceId != worldSpaceId || aForceTrigger)
{
DetectGridCellChange(pWorldSpace, true);
aForceTrigger = true;
}
// exactly how the game does it too
if (m_pLocation != pPlayer->locationForm)
{
m_dispatcher.trigger(LocationChangeEvent());
m_pLocation = pPlayer->locationForm;
}
}

if (m_centerGridX != pTES->centerGridX || m_centerGridY != pTES->centerGridY)
DetectGridCellChange(pWorldSpace, false);
void DiscoveryService::VisitExteriorCell(bool aForceTrigger) noexcept
{
const auto pWorldSpace = PlayerCharacter::Get()->GetWorldSpace();

if (m_currentGridX != pTES->currentGridX || m_currentGridY != pTES->currentGridY || aForceTrigger)
{
CellChangeEvent cellChangeEvent;
uint32_t baseId = 0;
uint32_t modId = 0;
m_interiorCellId = 0;
const TES* pTES = TES::Get();
const uint32_t worldSpaceId = pWorldSpace->formID;

if (m_world.GetModSystem().GetServerModId(pWorldSpace->formID, modId, baseId))
cellChangeEvent.WorldSpaceId = GameId(modId, baseId);
if (m_worldSpaceId != worldSpaceId || aForceTrigger)
{
DetectGridCellChange(pWorldSpace, true);
aForceTrigger = true;
}

const auto* pCell = ModManager::Get()->GetCellFromCoordinates(pTES->currentGridX, pTES->currentGridY, pWorldSpace, 0);
if (m_centerGridX != pTES->centerGridX || m_centerGridY != pTES->centerGridY)
DetectGridCellChange(pWorldSpace, false);

if (m_world.GetModSystem().GetServerModId(pCell->formID, modId, baseId))
cellChangeEvent.CellId = GameId(modId, baseId);
if (m_currentGridX != pTES->currentGridX || m_currentGridY != pTES->currentGridY || aForceTrigger)
{
CellChangeEvent cellChangeEvent;
uint32_t baseId = 0;
uint32_t modId = 0;

cellChangeEvent.CurrentCoords = GridCellCoords(pTES->currentGridX, pTES->currentGridY);
if (m_world.GetModSystem().GetServerModId(pWorldSpace->formID, modId, baseId))
cellChangeEvent.WorldSpaceId = GameId(modId, baseId);

m_dispatcher.trigger(cellChangeEvent);
m_currentGridX = pTES->currentGridX;
m_currentGridY = pTES->currentGridY;
}
}
else if (const auto pParentCell = pPlayer->GetParentCell())
{
m_worldSpaceId = 0;
m_centerGridX = 0;
m_centerGridY = 0;
m_currentGridX = 0;
m_currentGridY = 0;

const auto cellId = pParentCell->formID;
if (m_interiorCellId != cellId || aForceTrigger)
{
CellChangeEvent cellChangeEvent;
uint32_t baseId = 0;
uint32_t modId = 0;
const TESObjectCELL* pCell = ModManager::Get()->GetCellFromCoordinates(pTES->currentGridX, pTES->currentGridY, pWorldSpace, 0);

if (m_world.GetModSystem().GetServerModId(cellId, modId, baseId))
cellChangeEvent.CellId = GameId(modId, baseId);
if (m_world.GetModSystem().GetServerModId(pCell->formID, modId, baseId))
cellChangeEvent.CellId = GameId(modId, baseId);

m_dispatcher.trigger(cellChangeEvent);
m_interiorCellId = cellId;
}
cellChangeEvent.CurrentCoords = GridCellCoords(pTES->currentGridX, pTES->currentGridY);

m_dispatcher.trigger(cellChangeEvent);
m_currentGridX = pTES->currentGridX;
m_currentGridY = pTES->currentGridY;
}
}

// exactly how the game does it too
if (m_pLocation != pPlayer->locationForm)
void DiscoveryService::VisitInteriorCell(bool aForceTrigger) noexcept
{
ResetCachedCellData();

const uint32_t cellId = PlayerCharacter::Get()->GetParentCell()->formID;
if (m_interiorCellId != cellId || aForceTrigger)
{
m_dispatcher.trigger(LocationChangeEvent());
m_pLocation = pPlayer->locationForm;
CellChangeEvent cellChangeEvent;
uint32_t baseId = 0;
uint32_t modId = 0;

if (m_world.GetModSystem().GetServerModId(cellId, modId, baseId))
cellChangeEvent.CellId = GameId(modId, baseId);

m_dispatcher.trigger(cellChangeEvent);
m_interiorCellId = cellId;
}
}

void DiscoveryService::DetectGridCellChange(TESWorldSpace* aWorldSpace, bool aNewGridCell) noexcept
{
const auto* pTES = TES::Get();
const TES* pTES = TES::Get();

GridCellChangeEvent changeEvent;
const auto worldSpaceId = aWorldSpace->formID;
const uint32_t worldSpaceId = aWorldSpace->formID;
changeEvent.WorldSpaceId = worldSpaceId;

const auto startGridX = pTES->centerGridX - GridCellCoords::m_gridsToLoad / 2;
const auto startGridY = pTES->centerGridY - GridCellCoords::m_gridsToLoad / 2;
const int32_t startGridX = pTES->centerGridX - GridCellCoords::m_gridsToLoad / 2;
const int32_t startGridY = pTES->centerGridY - GridCellCoords::m_gridsToLoad / 2;
for (int32_t i = 0; i < GridCellCoords::m_gridsToLoad; ++i)
{
for (int32_t j = 0; j < GridCellCoords::m_gridsToLoad; ++j)
Expand All @@ -129,7 +137,7 @@ void DiscoveryService::DetectGridCellChange(TESWorldSpace* aWorldSpace, bool aNe
}
}

const auto* pCell = ModManager::Get()->GetCellFromCoordinates(startGridX + i, startGridY + j, aWorldSpace, 0);
const TESObjectCELL* pCell = ModManager::Get()->GetCellFromCoordinates(startGridX + i, startGridY + j, aWorldSpace, 0);

if (!pCell)
{
Expand All @@ -145,7 +153,7 @@ void DiscoveryService::DetectGridCellChange(TESWorldSpace* aWorldSpace, bool aNe
}
}

const auto* pCell = ModManager::Get()->GetCellFromCoordinates(pTES->centerGridX, pTES->centerGridY, aWorldSpace, 0);
const TESObjectCELL* pCell = ModManager::Get()->GetCellFromCoordinates(pTES->centerGridX, pTES->centerGridY, aWorldSpace, 0);

uint32_t baseId = 0;
uint32_t modId = 0;
Expand Down Expand Up @@ -182,13 +190,13 @@ void DiscoveryService::VisitForms() noexcept

};

auto* const pProcessLists = ProcessLists::Get();
ProcessLists* const pProcessLists = ProcessLists::Get();
if (!pProcessLists)
return;

for (uint32_t i = 0; i < pProcessLists->HighActorHandleArray.length; ++i)
{
auto* const pRefr = TESObjectREFR::GetByHandle(pProcessLists->HighActorHandleArray[i]);
TESObjectREFR* const pRefr = TESObjectREFR::GetByHandle(pProcessLists->HighActorHandleArray[i]);
if (pRefr)
{
if (pRefr->GetNiNode())
Expand All @@ -202,7 +210,7 @@ void DiscoveryService::VisitForms() noexcept
visitor(PlayerCharacter::Get());

// We dispatch removal events first to prevent needless reallocations
for (auto formId : s_previousForms)
for (uint32_t formId : s_previousForms)
{
m_dispatcher.trigger(ReferenceRemovedEvent(formId));
m_forms.erase(formId);
Expand Down Expand Up @@ -232,3 +240,12 @@ BSTEventResult DiscoveryService::OnEvent(const TESLoadGameEvent*, const EventDis
return BSTEventResult::kOk;
}

void DiscoveryService::ResetCachedCellData() noexcept
{
m_worldSpaceId = 0;
m_centerGridX = 0x7FFFFFFF;
m_centerGridY = 0x7FFFFFFF;
m_currentGridX = 0x7FFFFFFF;
m_currentGridY = 0x7FFFFFFF;
}

3 changes: 2 additions & 1 deletion Code/client/Services/Generic/TestService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,13 @@ void TestService::OnUpdate(const UpdateEvent& acUpdateEvent) noexcept
{
s_f8Pressed = true;


/*
auto* pActor = (Actor*)TESForm::GetById(0xFF000DA5);
pActor->SetWeaponDrawnEx(true);
//PlaceActorInWorld();
/*
const auto pPlayerBaseForm = static_cast<TESNPC*>(PlayerCharacter::Get()->baseForm);
//const auto pNpc = TESNPC::Create(data, pPlayerBaseForm->GetChangeFlags());
Expand Down

0 comments on commit 4f81fcd

Please sign in to comment.