#ifndef CHARACTERCOMPONENT_H #define CHARACTERCOMPONENT_H #include "dCommonVars.h" #include "RakNetTypes.h" #include "Character.h" #include "Component.h" #include #include "CDMissionsTable.h" #include "tinyxml2.h" #include "eReplicaComponentType.h" #include #include "Loot.h" enum class eGameActivity : uint32_t; class Item; /** * The statistics that can be achieved per zone */ struct ZoneStatistics { uint64_t m_AchievementsCollected; int64_t m_BricksCollected; uint64_t m_CoinsCollected; uint64_t m_EnemiesSmashed; uint64_t m_QuickBuildsCompleted; bool operator==(const ZoneStatistics& rhs) const = default; }; /** * The IDs of each of the possible statistics */ enum StatisticID { CurrencyCollected = 1, BricksCollected, SmashablesSmashed, QuickBuildsCompleted, EnemiesSmashed, RocketsUsed, MissionsCompleted, PetsTamed, ImaginationPowerUpsCollected, LifePowerUpsCollected, ArmorPowerUpsCollected, MetersTraveled, TimesSmashed, TotalDamageTaken, TotalDamageHealed, TotalArmorRepaired, TotalImaginationRestored, TotalImaginationUsed, DistanceDriven, TimeAirborneInCar, RacingImaginationPowerUpsCollected, RacingImaginationCratesSmashed, RacingCarBoostsActivated, RacingTimesWrecked, RacingSmashablesSmashed, RacesFinished, FirstPlaceRaceFinishes, }; /** * Represents a character, including their rockets and stats */ class CharacterComponent final : public Component { public: static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER; CharacterComponent(Entity* parent, Character* character, const SystemAddress& systemAddress); ~CharacterComponent() override; void LoadFromXml(const tinyxml2::XMLDocument& doc) override; void UpdateXml(tinyxml2::XMLDocument& doc) override; void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override; /** * Updates the rocket configuration using a LOT string separated by commas * @param config the rocket config to use */ void SetLastRocketConfig(std::u16string config); /** * Find a player's rocket * @param player the entity that triggered the event * @return rocket */ Item* GetRocket(Entity* player); /** * Equip a player's rocket * @param player the entity that triggered the event * @return rocket */ Item* RocketEquip(Entity* player); /** * Find a player's rocket and unequip it * @param player the entity that triggered the event */ void RocketUnEquip(Entity* player); /** * Gets the universe score of the entity * @return the universe score of the entity */ const int64_t GetUScore() const { return m_Uscore; } /** * Sets the universe score for this entity * @param uscore the universe score to set */ void SetUScore(int64_t uscore) { m_Uscore = uscore; } /** * Gets the current activity that the character is partaking in, see ScriptedActivityComponent for more details * @return the current activity that the character is partaking in */ const eGameActivity GetCurrentActivity() const { return m_CurrentActivity; } /** * Set the current activity of the character, see ScriptedActivityComponent for more details * @param currentActivity the activity to set */ void SetCurrentActivity(eGameActivity currentActivity) { m_CurrentActivity = currentActivity; m_DirtyCurrentActivity = true; } /** * Gets if the entity is currently racing * @return whether the entity is currently racing */ const bool GetIsRacing() const { return m_IsRacing; } /** * Sets the state of whether the character is racing * @param isRacing whether the character is racing */ void SetIsRacing(bool isRacing) { m_IsRacing = isRacing; } /** * Gets whether this character has PvP enabled, allowing combat between players * @return */ bool GetPvpEnabled() const; /** * Returns the characters lifetime reputation * @return The lifetime reputation of this character. */ int64_t GetReputation() { return m_Reputation; }; /** * Sets the lifetime reputation of the character to newValue * @param newValue the value to set reputation to */ void SetReputation(int64_t newValue) { m_Reputation = newValue; }; /** * Sets the current value of PvP combat being enabled * @param value whether to enable PvP combat */ void SetPvpEnabled(bool value); /** * Gets the object ID of the rocket that was last used, allowing it to be rendered on launch pads * @return the object ID of the rocket that was last used, if available */ LWOOBJID GetLastRocketItemID() const { return m_LastRocketItemID; } /** * Sets the object ID of the last used rocket * @param lastRocketItemID the object ID of the last used rocket */ void SetLastRocketItemID(LWOOBJID lastRocketItemID) { m_LastRocketItemID = lastRocketItemID; } /** * Gets the name of this character * @return the name of this character */ std::string GetName() const { return m_Character->GetName(); } /** * Sets the GM level of the character, should be called in the entity. Here it's set for serialization * @param gmlevel the gm level to set */ void SetGMLevel(eGameMasterLevel gmlevel); /** * Initializes the player statistics from the string stored in the XML * @param statisticsString the string to parse */ void InitializeStatisticsFromString(const std::string& statisticsString); /** * Initializes all the statistics with empty stats when there's no stats available up until that point */ void InitializeEmptyStatistics(); /** * Turns character statistics into a stats string * @return the statistics of the character as a string, in order, split by semicolon (;) */ std::string StatisticsToString() const; /** * Updates the statistics for when a user completes a mission * @param mission the mission info to track */ void TrackMissionCompletion(bool isAchievement); /** * Handles statistics related to collecting heart flags and imagination bricks * @param lot the lot of the object that was collected */ void TrackLOTCollection(LOT lot); /** * Handles a change in health and updates the statistics * @param health the health delta */ void TrackHealthDelta(int32_t health); /** * Handles a change in imagination and updates the statistics * @param imagination the imagination delta */ void TrackImaginationDelta(int32_t imagination); /** * Handles a change in armor and updates the statistics * @param armor the armor delta */ void TrackArmorDelta(int32_t armor); /** * Handles completing a rebuild by updating the statistics */ void TrackQuickBuildComplete(); /** * Tracks a player completing the race, also updates stats * @param won whether the player won the race */ void TrackRaceCompleted(bool won); /** * Tracks an updated position for a player */ void TrackPositionUpdate(const NiPoint3& newPosition); /** * Handles a zone statistic update * @param zoneID the zone that the stat belongs to * @param name the name of the stat * @param value the delta update for the stat */ void HandleZoneStatisticsUpdate(LWOMAPID zoneID, const std::u16string& name, int32_t value); /** * Allows one to generically update a statistic * @param updateID the 1-indexed ID of the statistic in the order of definition below * @param updateValue the value to update the statistic with */ void UpdatePlayerStatistic(StatisticID updateID, uint64_t updateValue = 1); /** * Add a venture vision effect to the player minimap. */ void AddVentureVisionEffect(std::string ventureVisionType); /** * Remove a venture vision effect from the player minimap. * When an effect hits 0 active effects, it is deactivated. */ void RemoveVentureVisionEffect(std::string ventureVisionType); /** * Update the client minimap to reveal the specified factions */ void UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const; void SetCurrentInteracting(LWOOBJID objectID) { m_CurrentInteracting = objectID; }; LWOOBJID GetCurrentInteracting() { return m_CurrentInteracting; }; /** * Sends a player to another zone with an optional clone ID * * @param zoneId zoneID for the new instance. * @param cloneId cloneID for the new instance. */ void SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId = 0) const; const SystemAddress& GetSystemAddress() const; const NiPoint3& GetRespawnPosition() const { return m_respawnPos; }; void SetRespawnPos(const NiPoint3& position); const NiQuaternion& GetRespawnRotation() const { return m_respawnRot; }; void SetRespawnRot(const NiQuaternion& rotation); std::map& GetDroppedLoot() { return m_DroppedLoot; }; uint64_t GetDroppedCoins() const { return m_DroppedCoins; }; void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; }; const std::array& GetClaimCodes() const { return m_ClaimCodes; }; const std::map& GetZoneStatistics() const { return m_ZoneStatistics; }; const std::u16string& GetLastRocketConfig() const { return m_LastRocketConfig; }; uint64_t GetTotalTimePlayed() const { return m_TotalTimePlayed; }; /** * Character info regarding this character, including clothing styles, etc. */ Character* m_Character; private: /** * The map of active venture vision effects */ std::map m_ActiveVentureVisionEffects; /** * Whether this character is racing */ bool m_IsRacing; /** * Possessible type, used by the shooting gallery */ uint8_t m_PossessableType = 1; /** * Universe score of the entity */ int64_t m_Uscore; /** * The lifetime reputation earned by the entity */ int64_t m_Reputation; /** * Whether the character is landing by rocket */ bool m_IsLanding; /** * The configuration of the last used rocket, essentially a string of LOTs separated by commas */ std::u16string m_LastRocketConfig; /** * Whether the GM info has been changed */ bool m_DirtyGMInfo = false; /** * Whether PvP is enabled for this entity */ bool m_PvpEnabled; /** * Whether this entity is a GM */ bool m_IsGM; /** * The current GM level of this character (anything > 0 counts as a GM) */ eGameMasterLevel m_GMLevel; /** * Whether the character has HF enabled */ bool m_EditorEnabled; /** * The level of the character in HF */ eGameMasterLevel m_EditorLevel; /** * Whether the currently active activity has been changed */ bool m_DirtyCurrentActivity = false; /** * The ID of the curently active activity */ eGameActivity m_CurrentActivity; /** * Whether the social info has been changed */ bool m_DirtySocialInfo = false; /** * The guild this character is in */ LWOOBJID m_GuildID; /** * The name of the guild this character is in */ std::u16string m_GuildName; /** * Whether this character is a lego club member */ bool m_IsLEGOClubMember; /** * The country code that the character is from */ int m_CountryCode; /** * Returns whether the landing animation is enabled for a certain zone * @param zoneID the zone to check for * @return whether the landing animation is enabled for that zone */ bool LandingAnimDisabled(int zoneID); /** * Returns the statistics for a certain statistics ID, from a statistics string * @param split the statistics string to look in * @param index the statistics ID in the string * @return the integer value of this statistic, parsed from the string */ static uint64_t GetStatisticFromSplit(std::vector split, uint32_t index); /** * Gets all the statistics for a certain map, if it doesn't exist, it creates empty stats * @param mapID the ID of the zone to get statistics for * @return the statistics for the zone */ ZoneStatistics& GetZoneStatisticsForMap(const LWOMAPID mapID); /** * The last time we saved this character, used to update the total time played */ time_t m_LastUpdateTimestamp; /** * The total time the character has played, in MS */ uint64_t m_TotalTimePlayed; /** * The total amount of currency collected by this character */ uint64_t m_CurrencyCollected; /** * The total amount of bricks collected by this character */ int64_t m_BricksCollected; /** * The total amount of entities smashed by this character */ uint64_t m_SmashablesSmashed; /** * The total amount of quickbuilds completed by this character */ uint64_t m_QuickBuildsCompleted; /** * The total amount of enemies killd by this character */ uint64_t m_EnemiesSmashed; /** * The total amount of rockets used by this character */ uint64_t m_RocketsUsed; /** * The total amount of missions completed by this character */ uint64_t m_MissionsCompleted; /** * The total number of pets tamed by this character */ uint64_t m_PetsTamed; /** * The total amount of imagination powerups collected by this character, this includes the ones in racing */ uint64_t m_ImaginationPowerUpsCollected; /** * The total amount of life powerups collected (note: not the total amount of life gained) */ uint64_t m_LifePowerUpsCollected; /** * The total amount of armor powerups collected (note: not the total amount of armor gained) */ uint64_t m_ArmorPowerUpsCollected; /** * Total amount of meters traveled by this character */ uint64_t m_MetersTraveled; /** * Total amount of times this character was smashed, either by other entities or by going out of bounds */ uint64_t m_TimesSmashed; /** * The total amount of damage inflicted on this character */ uint64_t m_TotalDamageTaken; /** * The total amount of damage healed by this character (excludes armor polish, etc) */ uint64_t m_TotalDamageHealed; /** * Total amount of armor repaired by this character */ uint64_t m_TotalArmorRepaired; /** * Total amount of imagination resored by this character */ uint64_t m_TotalImaginationRestored; /** * Total amount of imagination used by this character */ uint64_t m_TotalImaginationUsed; /** * Amount of distance driven, mutually exclusively tracked to meters travelled based on whether the charcter * is currently driving */ uint64_t m_DistanceDriven; /** * Time airborne in a car, currently untracked. * Honestly, who even cares about this. */ uint64_t m_TimeAirborneInCar; /** * Amount of imagination powerups found on racing tracks being collected, generally triggered by scripts */ uint64_t m_RacingImaginationPowerUpsCollected; /** * Total amount of racing imagination crates smashed, generally tracked by scripts */ uint64_t m_RacingImaginationCratesSmashed; /** * The amount of times this character triggered a car boost */ uint64_t m_RacingCarBoostsActivated; /** * The amount of times a car of this character was wrecked */ uint64_t m_RacingTimesWrecked; /** * The amount of entities smashed by the character while driving */ uint64_t m_RacingSmashablesSmashed; /** * The total amount of races completed by this character */ uint64_t m_RacesFinished; /** * The total amount of races won by this character */ uint64_t m_FirstPlaceRaceFinishes; /** * Special stats which are tracked per zone */ std::map m_ZoneStatistics{}; /** * ID of the last rocket used */ LWOOBJID m_LastRocketItemID = LWOOBJID_EMPTY; LWOOBJID m_CurrentInteracting = LWOOBJID_EMPTY; std::array m_ClaimCodes{}; void AwardClaimCodes(); SystemAddress m_SystemAddress; NiPoint3 m_respawnPos; NiQuaternion m_respawnRot; std::map m_DroppedLoot; uint64_t m_DroppedCoins = 0; }; #endif // CHARACTERCOMPONENT_H