mirror of
https://github.com/Jous99/F4MP.git
synced 2026-01-12 16:50:54 +01:00
107 lines
3.6 KiB
C++
107 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include <Events/EventDispatcher.h>
|
|
#include <Games/Events.h>
|
|
|
|
#include <Structs/GridCellCoords.h>
|
|
|
|
struct World;
|
|
|
|
struct ConnectedEvent;
|
|
struct GameService;
|
|
|
|
struct PreUpdateEvent;
|
|
struct ActorSpawnedEvent;
|
|
|
|
struct TESObjectREFR;
|
|
struct TESWorldSpace;
|
|
|
|
/**
|
|
* Responsible for discovering loaded actors, dispatching cell changes,
|
|
* and notifying the rest of the client about newly discovered actors.
|
|
*/
|
|
struct DiscoveryService final : BSTEventSink<TESLoadGameEvent>
|
|
{
|
|
DiscoveryService(World& aWorld, entt::dispatcher& aDispatcher) noexcept;
|
|
~DiscoveryService() noexcept = default;
|
|
|
|
TP_NOCOPYMOVE(DiscoveryService);
|
|
|
|
protected:
|
|
/**
|
|
* Checks whether the cell has changed, and if so,
|
|
* notify the client about the new location.
|
|
* @param aForceTrigger Forcefully notify the client about the current location
|
|
*/
|
|
void VisitCell(bool aForceTrigger = false) noexcept;
|
|
/**
|
|
* Checks whether the grid cell has shifted, and if so,
|
|
* notify the client about the newly loaded cells.
|
|
* @param aWorldSpace The world space that the grid cell is in.
|
|
* @param aNewCellGrid True if the player just walked into the new world space.
|
|
*/
|
|
void DetectGridCellChange(TESWorldSpace* aWorldSpace, bool aNewCellGrid) noexcept;
|
|
/**
|
|
* @brief Dispatches (un)loaded actors.
|
|
*/
|
|
void VisitForms() noexcept;
|
|
|
|
/**
|
|
* On each update, check whether the actor list or locational data has changed.
|
|
* @param acPreUpdateEvent Update on PreUpdateEvent so that the actors are dispatched before anything else.
|
|
*/
|
|
void OnUpdate(const PreUpdateEvent& acPreUpdateEvent) noexcept;
|
|
|
|
/**
|
|
* On connect, forcefully dispatch the loaded actors and locational data.
|
|
*/
|
|
void OnConnected(const ConnectedEvent& acEvent) noexcept;
|
|
|
|
/**
|
|
* When the game finishes loading, forcefully dispatch the loaded actors and locational data.
|
|
* This is a fix for the event that the player dies, and needs to rebroadcast its data.
|
|
* TODO(cosideci): this system is incomplete.
|
|
*/
|
|
BSTEventResult OnEvent(const TESLoadGameEvent*, const EventDispatcher<TESLoadGameEvent>*) override;
|
|
|
|
private:
|
|
/**
|
|
* Resets cached exterior cell data.
|
|
* TODO(cosideci): confirm the usage of this function
|
|
*/
|
|
void ResetCachedCellData() noexcept;
|
|
/**
|
|
* Checks whether the exterior cell grid has changed, and if so,
|
|
* notify the client about the new location.
|
|
* @param aForceTrigger Forcefully notify the client about the current location
|
|
*/
|
|
void VisitExteriorCell(bool aForceTrigger) noexcept;
|
|
/**
|
|
* Checks whether the interior cell has changed, and if so,
|
|
* notify the client about the new location.
|
|
* @param aForceTrigger Forcefully notify the client about the current location
|
|
*/
|
|
void VisitInteriorCell(bool aForceTrigger) noexcept;
|
|
|
|
World& m_world;
|
|
entt::dispatcher& m_dispatcher;
|
|
|
|
//! @brief Cached actor forms detected in the previous frame.
|
|
Set<uint32_t> m_forms;
|
|
/**
|
|
* The center grid coordinates are the coordinates of the cell in the cell grid
|
|
* where the cells around it in a 5 by 5 grid (by default) are loaded.
|
|
*/
|
|
GridCellCoords m_centerGrid{};
|
|
/**
|
|
* The current grid coordinates are the coordinates of the cell that is currently
|
|
* actually occupied by the player.
|
|
*/
|
|
GridCellCoords m_currentGrid{};
|
|
uint32_t m_worldSpaceId = 0;
|
|
uint32_t m_interiorCellId = 0;
|
|
struct TESForm* m_pLocation = nullptr;
|
|
|
|
entt::scoped_connection m_preUpdateConnection;
|
|
entt::scoped_connection m_connectedConnection;
|
|
};
|