/** * Thanks to Simon for his early research on the racing system. */ #pragma once #include "BitStream.h" #include "Entity.h" #include "Component.h" #include "eReplicaComponentType.h" /** * Information for each player in the race */ struct RacingPlayerInfo { /** * The ID of the player */ LWOOBJID playerID; /** * The ID of the car the player is driving */ LWOOBJID vehicleID; /** * The rank of a player */ uint32_t rank; /** * Whether the player has finished loading or not */ bool playerLoaded; /** * Scripted activity component score */ float data[10]{}; /** * Point that the player will respawn at if they smash their car */ NiPoint3 respawnPosition; /** * Rotation that the player will respawn at if they smash their car */ NiQuaternion respawnRotation; /** * The index in the respawn point the player is now at */ uint32_t respawnIndex; /** * The number of laps the player has completed */ uint32_t lap; /** * Whether or not the player has finished the race */ uint32_t finished; /** * Unused */ uint16_t reachedPoints; /** * The fastest lap time of the player */ time_t bestLapTime = 0; /** * The current lap time of the player */ time_t lapTime = 0; /** * The number of times this player smashed their car */ uint32_t smashedTimes = 0; /** * Whether or not the player should be smashed if the game is reloaded */ bool noSmashOnReload = false; /** * Whether or not this player has collected their rewards from completing the race */ bool collectedRewards = false; /** * Unused */ time_t raceTime = 0; }; /** * Component that's attached to a manager entity in each race zone that loads player vehicles, keep scores, etc. */ class RacingControlComponent : public Component { public: static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_CONTROL; RacingControlComponent(Entity* parentEntity); ~RacingControlComponent(); void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags); void Update(float deltaTime); /** * Invoked when a player loads into the zone. */ void OnPlayerLoaded(Entity* player); /** * Initalize the player's vehicle. * * @param player The player who's vehicle to initialize. * @param initialLoad Is this the first time the player is loading in this race? */ void LoadPlayerVehicle(Entity* player, uint32_t positionNumber, bool initialLoad = false); /** * Invoked when the client says it has loaded in. */ void OnRacingClientReady(Entity* player); /** * Invoked when the client says it should be smashed. */ void OnRequestDie(Entity* player); /** * Invoked when the player has finished respawning. */ void OnRacingPlayerInfoResetFinished(Entity* player); /** * Invoked when the player responds to the GUI. */ void HandleMessageBoxResponse(Entity* player, int32_t button, const std::string& id); /** * Get the racing data from a player's LWOOBJID. */ RacingPlayerInfo* GetPlayerData(LWOOBJID playerID); /** * Formats a time to a string, currently unused * @param time the time to format * @return the time formatted as string */ static std::string FormatTimeString(time_t time); private: /** * The players that are currently racing */ std::vector m_RacingPlayers; /** * The paths that are followed for the camera scenes */ std::u16string m_PathName; /** * The ID of the activity for participating in this race */ uint32_t m_ActivityID; /** * The world the players return to when they finish the race */ uint32_t m_MainWorld; /** * The number of laps that are remaining for the winning player */ uint16_t m_RemainingLaps; /** * The ID of the player that's currently winning the race */ LWOOBJID m_LeadingPlayer; /** * The overall best lap from all the players */ float m_RaceBestLap; /** * The overall best time from all the players */ float m_RaceBestTime; /** * Whether or not the race has started */ bool m_Started; /** * The time left until the race will start */ float m_StartTimer; /** * The time left for loading the players */ float m_LoadTimer; /** * Whether or not all players have loaded */ bool m_Loaded; /** * The number of loaded players */ uint32_t m_LoadedPlayers; /** * All the players that are in the lobby, loaded or not */ std::vector m_LobbyPlayers; /** * The number of players that have finished the race */ uint32_t m_Finished; /** * The time the race was started */ time_t m_StartTime; /** * Timer for tracking how long a player was alone in this race */ float m_EmptyTimer; bool m_SoloRacing; bool m_DirtyEndOfRaceInfo; bool m_DirtyRaceInfo; bool m_DirtyPathName; bool m_DirtyRank; bool m_DirtyLoadPlayer; bool m_DirtyLobby; /** * Value for message box response to know if we are exiting the race via the activity dialogue */ const int32_t m_ActivityExitConfirm = 1; };