diff --git a/classes.cpp b/classes.cpp index 47ea757..083c3f7 100644 --- a/classes.cpp +++ b/classes.cpp @@ -46,6 +46,16 @@ #include "rage/rlMetric.hpp" #include "rage/tlsContext.hpp" #include "rage/vector.hpp" +#include "script/globals/ACEData.hpp" +#include "script/globals/ACEHostData.hpp" +#include "script/globals/FetchManagerHostData.hpp" +#include "script/globals/FMEManagerHostData.hpp" +#include "script/globals/GunForHireMissionData.hpp" +#include "script/globals/MPHostData.hpp" +#include "script/globals/NetCampHostData.hpp" +#include "script/globals/PlayerPersonaData.hpp" +#include "script/globals/PlayerStatusSyncData.hpp" +#include "script/globals/SessionManagerPlayerData.hpp" #include "script/scrNativeHandler.hpp" #include "script/scrThread.hpp" #include "script/scrThreadContext.hpp" diff --git a/rage/Guid.hpp b/rage/Guid.hpp index 76bc42c..12e65b0 100644 --- a/rage/Guid.hpp +++ b/rage/Guid.hpp @@ -34,7 +34,7 @@ public: *this = g; } - inline constexpr Any *get() { return reinterpret_cast(&m_Buffer); } + inline constexpr void *get() { return reinterpret_cast(&m_Buffer); } private: alignas(8) uint64_t m_Buffer[Len]; diff --git a/script/globals/ACEData.hpp b/script/globals/ACEData.hpp new file mode 100644 index 0000000..d4cc3b4 --- /dev/null +++ b/script/globals/ACEData.hpp @@ -0,0 +1,176 @@ +#pragma once +#include "script/types.hpp" +#include "SessionManagerPlayerData.hpp" + +enum class ACEHostState +{ + INVALID = -1, + INIT, + UPDATE +}; + +enum class ACESlotType +{ + TRAIN, + GFH_POSSE_VERSUS, + AMBIENT_CONTENT, + DEATHMATCH, + MAX +}; + +enum class ACEClientRequestState +{ + INVALID = -1, + PUSHED, + STARTED, + EVALUATED, + PROCESSED +}; + +enum class ACERequestOwner +{ + INVALID = -1, + GUN_FOR_HIRE, + TRAIN_MANAGER, + FETCH_MANAGER, + FMA_MANAGER, + COACH_JOB_MANAGER, + PLAYER_DATA, + AMBIENT_DEATHMATCH, + NET_BEAT, + END +}; + +enum class ACERequestType +{ + INVALID = -1, + ADD_MISSION, + UPDATE_MISSION_LAUNCH_DATA, + UPDATE_MISSION_PRIORITY, + UPDATE_MISSION_SLOT_TYPE, + UPDATE_GFH_UID_AND_LAUNCH_FLAGS, + SET_LAUNCH_CONFIG_FLAGS, + SWITCH_MISSION_TO_UID_AND_SET_LAUNCH_DATA, + REMOVE_MISSION +}; + +enum class ACERequestResult +{ + PROCESSING, + SUCCESS, + FAILURE +}; + +enum class ACESlotPriority +{ + EMPTY = -1, + CLEANUP, + LOW, + HIGH, + CRITICAL +}; + +enum class ACEConfigFlags +{ + USE_LAUNCHER, + USE_GANG_SYNC, + USE_SCRIPT_LAUNCHER = 4, + USE_PROC_THREAD = 6, + USE_BEAT_THREAD +}; + +enum class ACEHostMissionState +{ + INVALID = -1, + DISABLED, + IDLE, + MISSION_RUNNING, + PRE_CLEANUP, + SYNC_FLAGS, + CLEANUP, + COMPLETED +}; + +enum class ACEHostRuntimeState +{ + INVALID = -1, + DISABLED, + IDLE, + ACTIVE, + CLEANUP +}; + +struct ACE_MISSION_IDENTIFIER_DATA +{ + SCR_GUID UID; + SCR_INT GangId; + SCR_INT PosseVersusSlotId; + SCR_INT GunForHireIndex; + SCR_INT DeathmatchSlotId; + SCR_GUID GFHDeed; + SCR_BITSET ContentLocks; // actually named (e)ContentLock but that'll break the linux build + SCR_INT ExpectedSlotType; +}; +static_assert(sizeof(ACE_MISSION_IDENTIFIER_DATA) == 10 * 8); + +struct ACE_MISSION_LOCATION_DATA +{ + SCR_INT Location; + SCR_INT InstanceId; + SCR_INT VolumeLockSize; + SCR_INT LaunchDistance; +}; + +struct ACE_MISSION_DATA +{ + constexpr static int INVALID_EXPIRE_TIME = -15; + + SCR_HASH ScriptHash; + SCR_INT StackSize; + SCR_INT Radius; + SCR_INT PAD_0003; + SCR_INT ExpireTime; + PLAYER_INDEX StartingPlayer; + SCR_BITSET ConfigFlags; + SCR_INT NumLocations; // always 1 + SCR_ARRAY Locations; + alignas(8) ACEHostMissionState State; + SCR_INT BeatParameter2; + SCR_INT BeatParameter3; + SCR_INT BeatParameter4; +}; +static_assert(sizeof(ACE_MISSION_DATA) == 17 * 8); + +// TODO: what is this actually called? +struct ACE_MISSION_SLOT_DATA +{ + alignas(8) ACESlotType Type; + alignas(8) ACESlotPriority Priority; + uint64_t PAD_0002[3]; // seemingly unused + ACE_MISSION_IDENTIFIER_DATA IdentifierData; +}; +static_assert(sizeof(ACE_MISSION_SLOT_DATA) == 15 * 8); + +struct ACE_MISSION_REQUEST +{ + alignas(8) ACEClientRequestState State; + SCR_INT RequestIndex; + alignas(8) ACERequestOwner Owner; + PLAYER_INDEX PlayerOwner; + SCR_INT RequestIndex2; // apparently + alignas(8) ACERequestType RequestType; + alignas(8) ACERequestResult Result; + SCR_INT Timestamp; + ACE_MISSION_SLOT_DATA SlotData; + ACE_MISSION_DATA MissionData; +}; +static_assert(sizeof(ACE_MISSION_REQUEST) == 40 * 8); + +struct ACE_DATA +{ + SCR_INT MaxItems; + SCR_INT QueueAdd; + SCR_INT QueueMod; + SCR_ARRAY Requests; +}; +static_assert(sizeof(ACE_DATA) == 204 * 8); \ No newline at end of file diff --git a/script/globals/ACEHostData.hpp b/script/globals/ACEHostData.hpp new file mode 100644 index 0000000..9163d90 --- /dev/null +++ b/script/globals/ACEHostData.hpp @@ -0,0 +1,60 @@ +#pragma once +#include "script/types.hpp" + +#include "ACEData.hpp" + +struct ACE_MISSION_QUEUE +{ + SCR_INT NumItems; + SCR_INT QueueHead; + SCR_ARRAY Requests; +}; +static_assert(sizeof(ACE_MISSION_QUEUE) == 203 * 8); + +struct ACE_MISSIONS +{ + SCR_ARRAY Slots; + SCR_ARRAY Datas; +}; + +struct ACE_MISSION_LOCATION_RUNTIME_DATA +{ + alignas(8) ACEHostRuntimeState State; + SCR_INT VolumeLockState; + SCR_INT VolumeLockRequestId; + +}; +static_assert(sizeof(ACE_MISSION_LOCATION_RUNTIME_DATA) == 3 * 8); + +// TODO: find actual names +struct ACE_MISSION_RUNTIME_DATA +{ + SCR_ARRAY Locations; + SCR_INT StartingGangId; + PLAYER_INDEX StartingPlayer; +}; +static_assert(sizeof(ACE_MISSION_RUNTIME_DATA) == 6 * 8); + +struct ACE_HOST_RUNTIME_DATA +{ + SCR_ARRAY RuntimeMissionDatas; + SCR_ARRAY SlotIndices; + SCR_INT NumSlots; +}; +static_assert(sizeof(ACE_HOST_RUNTIME_DATA) == 500 * 8); + +struct ACE_HOST_DATA +{ + alignas(8) ACEHostState State; + SCR_INT LastValidateTime; + alignas(8) ACESlotType ValidatingSlot; + SCR_ARRAY(ACESlotType::MAX)> MaxMissionsInSlot; + SCR_ARRAY(ACESlotType::MAX)> AllMissionsInSlot; + SCR_ARRAY(ACESlotType::MAX)> ValidMissionsInSlot; + SCR_ARRAY(ACESlotType::MAX)> WrongMissionsInSlot; + SCR_ARRAY(ACESlotType::MAX)> OverflowMissionsInSlot; + ACE_MISSION_QUEUE MissionQueue; + ACE_MISSIONS Missions; + ACE_HOST_RUNTIME_DATA RuntimeData; +}; +static_assert(sizeof(ACE_HOST_DATA) == 3005 * 8); \ No newline at end of file diff --git a/script/globals/FMEManagerHostData.hpp b/script/globals/FMEManagerHostData.hpp new file mode 100644 index 0000000..4684ac1 --- /dev/null +++ b/script/globals/FMEManagerHostData.hpp @@ -0,0 +1,74 @@ +#pragma once +#include "script/types.hpp" + +enum class FMERunningState +{ + INVALID, + INIT, + LAUNCH_OFFLINE, + MATCHMAKE, + LAUNCH_ONLINE, + MAIN, + CLEANUP +}; + +enum class FMEEvent +{ + INVALID = -1, + FIRST, + CHALLENGES, + DEAD_DROP, + GOLDEN_HAT, + HOT_PROPERTY, + KING_OF_THE_CASTLE, + KING_OF_THE_RAILS, + WILDLIFE_PHOTOGRAPHER, + THEMED_ESCAPED_CONVICTS, + THEMED_ROUND_UP, + THEMED_SUPPLY_TRAIN, + THEMED_WRECKAGE, + THEMED_CONDOR_EGG, + THEMED_ANIMAL_TAGGING, + THEMED_LAST, + PV_CHALLENGE_HERBALIST, + PV_CHALLENGE_BIGGEST_FISH, + PV_CHALLENGE_FLYING_BIRD, + HUNT_THE_POSSE_LEADER, + MAX +}; + +struct FME_VOLUME_LOCK +{ + SCR_INT RequestId; + SCR_INT RequestId2; // ??? +}; + +struct FME_EVENT +{ + alignas(8) FMERunningState State; + alignas(8) FMEEvent Event; + SCR_INT LocationId; + SCR_INT VariationId; + SCR_INT PAD_0004; // random int for volume stuff? + SCR_GUID UID; + PLAYER_INDEX LaunchPlayer; + SCR_INT PAD_0008; // unused + FME_VOLUME_LOCK VolumeLock; + SCR_INT PAD_0011; // unused + SCR_DATE LaunchWindowDate; + SCR_DATE ExpirationDate; +}; +static_assert(sizeof(FME_EVENT) == 26 * 8); + +struct FME_MANAGER_HOST_DATA +{ + SCR_INT State; + SCR_ARRAY Events; + SCR_DATE LaunchDate; + SCR_DATE ThemedLaunchDate; + alignas(8) FMEEvent LaunchingEvent; + alignas(8) FMEEvent LaunchingThemedEvent; + SCR_INT NumLaunchesToday; + SCR_INT NumThemedLaunchesToday; +}; +static_assert(sizeof(FME_MANAGER_HOST_DATA) == 228 * 8); \ No newline at end of file diff --git a/script/globals/FetchManagerHostData.hpp b/script/globals/FetchManagerHostData.hpp new file mode 100644 index 0000000..a687d3b --- /dev/null +++ b/script/globals/FetchManagerHostData.hpp @@ -0,0 +1,128 @@ +#pragma once +#include "script/types.hpp" +#include "GunForHireMissionData.hpp" +#include "ACEData.hpp" + +enum class MissionLaunchType +{ + INVALID = -1, + PLAYER_LAUNCHED, + DYNAMIC_UNACCEPTED, + AMBIENT_TRAIN, + MAX +}; + +enum class MissionState +{ + INVALID = -1, + INIT, + WAITING_FOR_SLOT, + RUNNING, + CLEANUP +}; + +enum class MissionFlags +{ + IS_AGGRO, + LAUNCHED, + CLEANED_UP, + IS_FORCE_PASSIVE, + IS_STARTED, + IS_ACTIVE, + IS_COMPLETED, + IS_RECONCILING, + IN_LAUNCH_RADIUS, + CHECKED_SHUTDOWN_RADIUS, + OUTSIDE_SHUTDOWN_RADIUS, + NOT_RUNNING_THREAD, + ONLINE_STREAMING_COMPLETE, + ALLOW_DISABLED_LAW, + FORCE_DELETE, + SPAWN_COMPLETED, + FORCE_HIDE_UI, + ACCEPTED, + FAILED_TO_ACCEPT, + IS_RELAUNCH, + CHECKED_ONLINE_THREAD, + GLOBAL_SIGNAL_READY, + PREVENT_THREAD_SHUTDOWN, + SHUTDOWN_DETECTED, + INHERITED_MISSION_FROM_POSSE, + ACTIVE_PLAYERS_LEFT, + TALKED_TO_DYNAMIC_MISSION_GIVER, + GAVE_IGNORED_MISSION_GIVER_HONOR, + DELETE_EXISTING_VOLUME_LOCKS, + REQUESTED_ACE_SLOT, + FORCE_SHUTDOWN_PRIMARY_TEAM, + IS_INSTANCED +}; + +enum class SaleBit +{ + INVALID = 31, + SIZE_VERY_SMALL = 0, + SIZE_SMALL, + SIZE_MEDIUM, + SIZE_LARGE, + STRENGTH_WEAK, + STRENGTH_AVERAGE, + STRENGTH_STRONG, + ORDER_ANY, + ORDER_UNFLAVORED, + ORDER_REGULAR, + ORDER_IMPROVED, + ORDER_SPECIAL, + STORY_MISSION_COMPLETE +}; + +struct MISSION_SALE_DATA +{ + SCR_BITSET Flags; + SCR_INT NumGoods; // used only for CAMP_SELL +}; + +struct FETCH_MANAGER_MISSION +{ + SCR_INT MissionIndex; // seemingly obtained from the server + alignas(8) MissionLaunchType LaunchType; + alignas(8) MissionState State; + SCR_BITSET Flags; + SCR_INT ACESlot; + SCR_INT CampIndex; + SCR_INT Location; + SCR_INT GFHLocation; + SCR_INT BeatIndex; + SCR_INT Instance; // maybe, a random integer from 0 to 65535 + SCR_INT StartTime; + SCR_INT GangMembers; + SCR_INT RequiredRelGroups; // whatever that means + SCR_INT GangId; + SCR_INT LaunchPlayers; + PLAYER_INDEX Owner; + PLAYER_INDEX Target; // ??? + PLAYER_INDEX SecondaryPlayer; + PLAYER_INDEX BountyTarget; // ??? + SCR_VEC3 Position; // used only for CAMP_RAID + GFH_TARGET_DATA TargetData; + MISSION_SALE_DATA SaleData; +}; +static_assert(sizeof(FETCH_MANAGER_MISSION) == 28 * 8); + +struct FETCH_MISSION_THREAD +{ + SCR_INT MissionIndex; + SCR_BOOL CleanedUp; +}; + +struct FETCH_MANAGER_HOST_DATA +{ + SCR_ARRAY Missions; + SCR_ARRAY(MissionLaunchType::MAX)> RunningMissionsOfType; + SCR_ARRAY MissionsThreads; + ACE_DATA ACEData; + SCR_INT State; // init, streaming, running + SCR_INT PAD_0585; + SCR_INT ViableTargets; + SCR_INT NumRunningMissions; +}; +static_assert(sizeof(FETCH_MANAGER_HOST_DATA) == 588 * 8); \ No newline at end of file diff --git a/script/globals/GunForHireMissionData.hpp b/script/globals/GunForHireMissionData.hpp new file mode 100644 index 0000000..4965414 --- /dev/null +++ b/script/globals/GunForHireMissionData.hpp @@ -0,0 +1,87 @@ +#pragma once +#include "script/types.hpp" +#include "ACEData.hpp" + +enum class GFHState +{ + INVALID = -1, + IDLE, + WAITING_FOR_ACE_TO_ADD, + WAIT_FOR_UID, + PENDING, + RUNNING, + ENDING, + WAITING_FOR_ACE_TO_REMOVE, + CLEANING_UP_MISSION, + WAIT_FOR_PLAYERS_TO_CLEAR, + CLEAN_INVALID_GANG +}; + +enum class GFHGangType +{ + INVALID = -1, + PRIMARY, + RIVAL +}; + +enum class GFHGangFlag +{ + NONE, + IS_ON_INSTANCED_MISSION, + IS_RELAUNCHED_MISSION, + CLEANUP_MISSION_FOR_RELAUNCH +}; + +struct GFH_TARGET_DATA +{ + SCR_INT Target; + SCR_INT Instance; + SCR_INT Class; + SCR_INT Subclass; +}; +static_assert(sizeof(GFH_TARGET_DATA) == 4 * 8); + +struct GFH_GANG_MISSION_DATA +{ + SCR_INT GiverIndex; // TODO: find an enum for this one + SCR_INT LocationIndex; + alignas(8) GFHState State; + SCR_INT MissionIndex; // -1 = INVALID, and 70 = MAX. That's all we know + SCR_INT PAD_0004; + SCR_GUID UID; + SCR_INT ACEAddStartTime; + SCR_BITSET GangFlags; + GFH_TARGET_DATA Data; +}; +static_assert(sizeof(GFH_GANG_MISSION_DATA) == 13 * 8); + +struct GFH_GANG_DATA +{ + SCR_INT GangId; + SCR_INT ACESlot; + alignas(8) GFHState State; + GFH_GANG_MISSION_DATA MissionData; +}; +static_assert(sizeof(GFH_GANG_DATA) == 16 * 8); + +struct GFH_MISSION_DATA +{ + SCR_ARRAY GangDatas; + ACE_DATA ACEData; +}; +static_assert(sizeof(GFH_MISSION_DATA) == 717 * 8); + +enum class GFHLocationGiverHostState +{ + INVALID = -1, + INIT, + RUNNING, + DISABLED +}; + +struct GFH_LOCATION_GIVER_DATA +{ + alignas(8) GFHLocationGiverHostState State; + SCR_INT TimeInitialized; +}; +static_assert(sizeof(GFH_LOCATION_GIVER_DATA) == 2 * 8); \ No newline at end of file diff --git a/script/globals/MPHostData.hpp b/script/globals/MPHostData.hpp new file mode 100644 index 0000000..ceff441 --- /dev/null +++ b/script/globals/MPHostData.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "script/types.hpp" + +enum class MPGameState +{ + INVALID = -1, + GAME_INIT, + LOAD_INIT_THREADS, + LOAD_MAIN_THREADS, + ROUTE_TRANSITION, + CREATE_PLAYER_CAMP, + VERIFY_MADAM_NAZAR, + CHECK_FOR_INVITE, + SPAWN_PLAYER, + MAIN_UPDATE_FIRST_FRAME, + MAIN_UPDATE, + END, + ALL_LEAVE +}; + +struct MP_HOST_DATA +{ + alignas(8) MPGameState GameState; +}; +static_assert(sizeof(MP_HOST_DATA) == 1 * 8); \ No newline at end of file diff --git a/script/globals/NetCampHostData.hpp b/script/globals/NetCampHostData.hpp new file mode 100644 index 0000000..6fcdec6 --- /dev/null +++ b/script/globals/NetCampHostData.hpp @@ -0,0 +1,128 @@ +#pragma once +#include "script/types.hpp" +#include "rage/joaat.hpp" + +enum class CampState +{ + INVALID = -1, + WAITING, + RUNNING, + CLEANUP +}; + +enum class CampLocationIndex : std::uint32_t +{ + GRIZZLIES_CAMP = rage::joaat("GRIZZLIES_CAMP"), + BAYOU_NAWAS_CAMP = rage::joaat("BAYOU_NAWAS_CAMP"), + BIG_VALLEY_CAMP = rage::joaat("BIG_VALLEY_CAMP"), + CHOLLA_SPRINGS_CAMP = rage::joaat("CHOLLA_SPRINGS_CAMP"), + CUMBERLAND_FOREST_CAMP = rage::joaat("CUMBERLAND_FOREST_CAMP"), + GAPTOOTH_RIDGE_CAMP = rage::joaat("GAPTOOTH_RIDGE_CAMP"), + GREAT_PLAINS_CAMP = rage::joaat("GREAT_PLAINS_CAMP"), + HEARTLAND_CAMP = rage::joaat("HEARTLAND_CAMP"), + HENNIGANS_STEAD_CAMP = rage::joaat("HENNIGANS_STEAD_CAMP"), + RIO_BRAVO_CAMP = rage::joaat("RIO_BRAVO_CAMP"), + ROANOKE_RIDGE_CAMP = rage::joaat("ROANOKE_RIDGE_CAMP"), + SCARLETT_MEADOWS_CAMP = rage::joaat("SCARLETT_MEADOWS_CAMP"), + TALL_TREES_CAMP = rage::joaat("TALL_TREES_CAMP"), +}; + +enum class CampBit +{ + IS_LAUNCHED, + IS_ATTACKING, + IS_ACTIVE, + BLIP_DISABLED, + WHITE_FLAG_RAISED, + WHITE_FLAG_LOCKED_LOWERED, + SHOW_BLIPS_HIDDEN, + IS_FOLLOWER_STOLEN, + SUPPRESS_FOLLOWER, + FOLLOWER_DEAD, + IS_CAMPWORKS_LAUNCHED, + WHITE_FLAG_RAISED_PRE_CONTENT, + WHITE_FLAG_LOCKED_FOR_CONTENT +}; + +enum class CampContentType +{ + NONE, + NET_BEAT, + DYNAMIC_MISSION, + TRADER_MISSION, + CAMP_RAID +}; + +struct CAMP_LOCATION +{ + SCR_INT Size; // tents and the main camp + alignas(8) CampLocationIndex Index; + SCR_INT Instance; // or similar +}; + +struct CAMP_CONTENT +{ + SCR_BOOL Active; // actually a bitset with a single bit + alignas(8) CampContentType Type; +}; + +struct CAMP_VOLUME_LOCKS +{ + SCR_INT CampRequestId; + SCR_INT AllRequestId; +}; + +struct NET_HOST_CAMP +{ + alignas(8) CampState State; + CAMP_LOCATION Location; + uint64_t PAD_0004[3]; + SCR_BITSET Flags; + uint64_t PAD_0008; + PLAYER_INDEX Owner; // likely the posse leader + SCR_ARRAY TentOwners; // or residents + CAMP_CONTENT ActiveContent; + SCR_VEC3 Position; + CAMP_VOLUME_LOCKS VolumeLocks; + SCR_INT RelationshipBits; + SCR_INT LastVolumeUpdateTime; +}; +static_assert(sizeof(NET_HOST_CAMP) == 27 * 8); + +enum class CampRequestState +{ + INVALID = -1, + INIT, + WAIT_FOR_VOLUME_LOCKS, + VERIFY, + UPDATE_CAMP_SIZE, + FIND_NEW_CAMP_IN_DISTRICT, + FIND_NEW_CAMP_ANYWHERE, + COMPLETE +}; + +struct NET_HOST_CAMP_REQUEST +{ + alignas(8) CampRequestState State; + CAMP_LOCATION Location; + SCR_INT RequestId; + SCR_INT Flags; // TODO + SCR_INT PlacementAttempts; +}; +static_assert(sizeof(NET_HOST_CAMP_REQUEST) == 7 * 8); + +enum class CampManagerHostState +{ + INIT, + STREAM, + RUNNING +}; + +struct NetCampHostData +{ + SCR_ARRAY Camps; + SCR_ARRAY CampRequests; + alignas(8) CampManagerHostState State; + SCR_INT CampPlayerBitset; +}; +static_assert(sizeof(NetCampHostData) == 1092 * 8); \ No newline at end of file diff --git a/script/globals/PlayerPersonaData.hpp b/script/globals/PlayerPersonaData.hpp new file mode 100644 index 0000000..d0aaa89 --- /dev/null +++ b/script/globals/PlayerPersonaData.hpp @@ -0,0 +1,102 @@ +#pragma once +#include "script/types.hpp" +#include "rage/joaat.hpp" + +enum class AbilityType : std::uint32_t +{ + STRANGE_MEDICINE = rage::joaat("NET_PLAYER_ABILITY__STRANGE_MEDICINE"), + FOCUS_FIRE = rage::joaat("NET_PLAYER_ABILITY__FOCUS_FIRE"), + NECESSITY_BREEDS = rage::joaat("NET_PLAYER_ABILITY__NECESSITY_BREEDS"), + THE_GIFT_OF_FOCUS = rage::joaat("NET_PLAYER_ABILITY__THE_GIFT_OF_FOCUS"), + RIDE_LIKE_THE_WIND = rage::joaat("NET_PLAYER_ABILITY__RIDE_LIKE_THE_WIND"), + FOOL_ME_ONCE = rage::joaat("NET_PLAYER_ABILITY__FOOL_ME_ONCE"), + GUNSLINGERS_CHOICE = rage::joaat("NET_PLAYER_ABILITY__GUNSLINGERS_CHOICE"), + COME_BACK_STRONGER = rage::joaat("NET_PLAYER_ABILITY__COME_BACK_STRONGER"), + WINNING_STREAK = rage::joaat("NET_PLAYER_ABILITY__WINNING_STREAK"), + KICK_IN_THE_BUTT = rage::joaat("NET_PLAYER_ABILITY__KICK_IN_THE_BUTT"), + PEAK_CONDITION = rage::joaat("NET_PLAYER_ABILITY__PEAK_CONDITION"), + THE_SHORT_GAME = rage::joaat("NET_PLAYER_ABILITY__THE_SHORT_GAME"), + OVERRIDE_REVENGE_SLOW_TIME = rage::joaat("NET_PLAYER_ABILITY__OVERRIDE_REVENGE_SLOW_TIME"), + IRON_LUNG = rage::joaat("NET_PLAYER_ABILITY__IRON_LUNG"), + THE_UNBLINKING_EYE = rage::joaat("NET_PLAYER_ABILITY__THE_UNBLINKING_EYE"), + INVALID = 0, + FRIENDS_FOR_LIFE = rage::joaat("NET_PLAYER_ABILITY__FRIENDS_FOR_LIFE"), + NEVER_WITHOUT_ONE = rage::joaat("NET_PLAYER_ABILITY__NEVER_WITHOUT_ONE"), + OF_SINGLE_PURPOSE = rage::joaat("NET_PLAYER_ABILITY__OF_SINGLE_PURPOSE"), + A_MOMENT_TO_RECUPERATE = rage::joaat("NET_PLAYER_ABILITY__A_MOMENT_TO_RECUPERATE"), + SLIPPERY_BASTARD = rage::joaat("NET_PLAYER_ABILITY__SLIPPERY_BASTARD"), + PAINT_IT_BLACK = rage::joaat("NET_PLAYER_ABILITY__PAINT_IT_BLACK"), + TAKE_THE_PAIN_AWAY = rage::joaat("NET_PLAYER_ABILITY__TAKE_THE_PAIN_AWAY"), + EYE_FOR_AN_EYE = rage::joaat("NET_PLAYER_ABILITY__EYE_FOR_AN_EYE"), + COLD_BLOODED = rage::joaat("NET_PLAYER_ABILITY__COLD_BLOODED"), + HUNKER_DOWN = rage::joaat("NET_PLAYER_ABILITY__HUNKER_DOWN"), + QUITE_AN_INSPIRATION = rage::joaat("NET_PLAYER_ABILITY__QUITE_AN_INSPIRATION"), + TO_FIGHT_ANOTHER_DAY = rage::joaat("NET_PLAYER_ABILITY__TO_FIGHT_ANOTHER_DAY"), + HORSEMAN = rage::joaat("NET_PLAYER_ABILITY__HORSEMAN"), + LIVE_FOR_THE_FIGHT = rage::joaat("NET_PLAYER_ABILITY__LIVE_FOR_THE_FIGHT"), + HANGMAN = rage::joaat("NET_PLAYER_ABILITY__HANGMAN"), + STRENGTH_IN_NUMBERS = rage::joaat("NET_PLAYER_ABILITY__STRENGTH_IN_NUMBERS"), + SLOW_AND_STEADY = rage::joaat("NET_PLAYER_ABILITY__SLOW_AND_STEADY"), + LANDONS_PATIENCE = rage::joaat("NET_PLAYER_ABILITY__LANDONS_PATIENCE"), + SHARPSHOOTER = rage::joaat("NET_PLAYER_ABILITY__SHARPSHOOTER") +}; + +enum class OutfitTheme +{ + NONE, + CITY, + RUGGED, + MAX +}; + +enum class ClothingFlag +{ + IS_ANIMAL +}; + +struct METAPED_PLAYER_CLOTHING_DATA +{ + SCR_HASH Model; + SCR_INT PAD_0001; + alignas(8) OutfitTheme GangOutfitTheme; + SCR_HASH Outfit; + SCR_HASH OverrideOutfit; // or mission outfit + SCR_HASH HeadItem; + SCR_HASH FacialHairItem; + SCR_HASH HairItem; + SCR_HASH EyesItem; + SCR_HASH TeethItem; + SCR_BITSET Flags; +}; +static_assert(sizeof(METAPED_PLAYER_CLOTHING_DATA) == 11 * 8); + +struct ABILITY_EQUIP_DATA +{ + alignas(8) AbilityType Type; + SCR_INT Tier; + SCR_INT PAD_0002; +}; + +struct HONOR_INFO +{ + SCR_INT GrossHonor; + SCR_INT HonorLevel; // not sure how these values are different, if at all +}; + +// WARNING: many of these fields are overwritten every tick +struct PLAYER_PERSONA_DATA_ENTRY +{ + SCR_INT Rank; + GAMER_HANDLE Handle; + HONOR_INFO HonorInfo; + SCR_ARRAY Abilities; + METAPED_PLAYER_CLOTHING_DATA ClothingData; + SCR_FLOAT DistanceMultiplier; // unknown usage +}; +static_assert(sizeof(PLAYER_PERSONA_DATA_ENTRY) == 30 * 8); + +struct PLAYER_PERSONA_DATA +{ + SCR_ARRAY Entries; +}; +static_assert(sizeof(PLAYER_PERSONA_DATA) == 961 * 8); \ No newline at end of file diff --git a/script/globals/PlayerStatusSyncData.hpp b/script/globals/PlayerStatusSyncData.hpp new file mode 100644 index 0000000..22f9ad9 --- /dev/null +++ b/script/globals/PlayerStatusSyncData.hpp @@ -0,0 +1,457 @@ +#pragma once +#include "script/types.hpp" + +enum class PlayerStatus +{ + INITIALIZATION, + PLAYING, + JUST_DIED, + DEAD, + RESPAWN, + POST_RESPAWN, + RESPAWN_INIT, + RESPAWN_FADE_WAIT, + RESPAWN_INVENTORY_OVERRIDE_WAIT, + RESPAWN_FIND_DESIRED_SPAWN, + RESPAWN_RESURRECT, + RESPAWN_UPDATE_TELEPORT, + RESPAWN_STREAM_LOCATION, + RESPAWN_REGION_RESET, + RESPAWN_REGION_WAIT_FOR_RESET, + RESPAWN_CREATE_PERSONAL_TRANSPORT, + RESPAWN_INITIALIZE_PLAYER, + RESPAWN_STREAM_WEAPONS, + RESPAWN_ALLOW_WEAPONS_TO_EQUIP, + RESPAWN_ON_SOMETHING, + RESPAWN_VALIDATE_SCENARIO, + RESPAWN_ARBITRARY_STREAM_WAIT, + RESPAWN_EXIT, + DEAD_INIT, + DEAD_SHOW_DEATH, + DEAD_EXIT, + INVALID, + CLEANUP +}; + +enum class ParentStatus +{ + INITIALIZATION, + PLAYING, + JUST_DIED, + DEAD, + RESPAWN, + POST_RESPAWN +}; + +enum class ScanState +{ + INIT, + FIND_DESIRED_SPAWN, + START_SPAWN_SEARCH, + PROCESS_SPAWN_SEARCH, + VERIFY_SPAWN_LOCATION, + CLEANUP, + COMPLETE +}; + +// TODO +enum class PlayerFlags +{ + SPECTATING = 5, + DEAD_EYE_ACTIVE = 9, + IN_JAIL = 20 +}; + +enum class PlayerStatusFlags +{ + FORCE_RESPAWN, + IN_RESPAWN_SEQUENCE, + BYPASS_RESSURRECT_AND_TELEPORT, + FORCE_RESPAWN_DESIRED, + FORCE_RESPAWN_ABSOLUTE, + FORCE_RESPAWN_AT_CAMP, + FORCE_RESPAWN_IN_MOONSHINE, + FORCE_RESPAWN_JAIL, + FORCE_RESPAWN_FAST_TRAVEL_STATION, + FORCE_RESPAWN_TRADE, + FORCE_RESPAWN_DEBUG, + FORCE_RESPAWN_ASAP, + SCRIPT_CONTROL_OVERRIDE, + MODE_OVERRIDE, + MISSION_OVERRIDE, + VERSUS_OVERRIDE, + GENERIC_SPAWN_FAR_ONCE, + PAUSE_RESPAWN_FADE_UP, + SKIP_RESPAWN_FADE_IN, + SKIP_RESPAWN_FADE_OUT, + SKIP_LOADING_SCREEN_SHUTDOWN, + DISABLE_POST_FX, + DISABLE_POST_FX_ONCE, + CLEANUP_MATCHMAKING_POST_FX, + RESPAWN_INVISIBLE_ONCE, + RESPAWN_WITHOUT_CONTROL_ONCE, + REQUEST_SCRIPT_CONTROL_INFO, + PREVENT_REGION_RESET, + HIDE_SPECTATOR_UI, + SKIP_SPECTATOR_MODE_ON_DEATH, + DISABLE_SPECTATOR_MODE_ON_DEATH, + INVISIBLE_TO_SPECTATOR_CAM, + DISABLE_DEATH_CAM_HOLD_TIME, + MAINTAIN_DEATH_CAM_ON_RESPAWN, + DISABLE_LOCKON, + DISABLE_FIRING, + SECURITY_CLIENT, + PREVENT_RESPAWN_INVINCIBILITY, + CAMP_RELOAD, + RESPAWN_GHOSTTOWN, + FAKE_GAMER_TAG, + REQUEST_CUSTOM_INVENTORY_CONFIG, + RESPAWN_USE_CUSTOM_INVENTORY_CONFIG, + REQUEST_CUSTOM_AMMO_UI_CONFIG, + RESPAWN_USE_CUSTOM_AMMO_UI_CONFIG, + DISABLE_DROP_WEAPONS_ON_DEATH, + DISABLE_LOOTING, + ACTIVATE_CUSTOM_CAM_ON_RESPAWN, + REQUEST_CUSTOM_SPAWN_CONFIG, + RESPAWN_USE_CUSTOM_SPAWN_CONFIG, + USE_CUSTOM_POSITION_WITH_MOUNT, + RESPAWN_WITH_COUPON, + RESPAWN_WITH_COUPON_ONCE, + RESPAWN_WITH_HUB, + RESPAWN_WITH_HUB_ONCE, + RESPAWN_WITH_HANDHELD = 59, + RESPAWN_WITH_HANDHELD_ONCE, + RESPAWN_WITH_BLACKBOARD, + RESPAWN_WITH_BLACKBOARD_ONCE, + RESPAWN_WITH_ANIMATION, + RESPAWN_WITH_ANIMATION_ONCE, + RESPAWN_WITH_MOUNT, + RESPAWN_WITH_MOUNT_ONCE, + RESPAWN_WITH_RESPOT_DISABLED, + RESPAWN_WITH_RESPOT_DISABLED_ONCE, + RESPAWN_ON_MOUNT, + RESPAWN_ON_MOUNT_ONCE, + RESPAWN_ON_TARGET_MOUNT, + RESPAWN_ON_TARGET_MOUNT_ONCE, + DESTROY_MOUNT_ON_RESPAWN, + RESPAWN_ON_VEHICLE, + RESPAWN_ON_VEHICLE_ONCE, + DESTROY_VEHICLE_ON_RESPAWN, + RESPAWN_WITH_VEHICLE, + RESPAWN_WITH_VEHICLE_ONCE, + RESPAWN_ON_VEHICLE_NAVMESH, + RESPAWN_ON_VEHICLE_NAVMESH_ONCE, + RESPAWN_ON_TRAIN, + RESPAWN_ON_TRAIN_ONCE, + RESPAWN_ON_TARGET_TRAIN, + RESPAWN_ON_TARGET_TRAIN_ONCE, + RESPAWN_ON_TARGET_VEHICLE, + RESPAWN_ON_TARGET_VEHICLE_ONCE, + RESPAWN_USE_ADJUSTED_OFFSET_FOR_TRANSPORT, + RESPAWN_USE_ADJUSTED_OFFSET_FOR_TRANSPORT_ONCE, + RESPAWN_DISABLE_WATER_FAILSAFE, + RESPAWN_SPAWN_IN_WATER, + RESPAWN_SPAWN_IN_WATER_ONCE, + RESPAWN_WITH_RANDOM_SEED, + RESPAWN_SPAWN_NEAR_LOCATION_ONCE, + DONT_RESPAWN_IN_VOLUME_LOCKS_ONCE, + REGENERATE_PEDSHOT_ONCE, + RESPAWN_WITH_DESIRED_WEAPON_IN_HAND, + RESPAWN_WITH_DESIRED_WEAPON_IN_HAND_ONCE, + RESPAWN_WITH_BEST_WEAPON_IN_HAND, + RESPAWN_WITH_BEST_WEAPON_IN_HAND_ONCE, + RESPAWN_WITH_LAST_WEAPON_IN_HAND, + RESPAWN_WITH_LAST_WEAPON_IN_HAND_ONCE, + RESPAWN_WITH_NO_WEAPON_IN_HAND, + RESPAWN_WITH_NO_WEAPON_IN_HAND_ONCE, + RESPAWN_WITH_NO_WEAPON_PROCESSING, + RESPAWN_WITH_NO_WEAPON_PROCESSING_ONCE, + RESPAWN_WITH_NO_ANIMAL_INVULNERABILITY, + RESPAWN_WITH_NO_ANIMAL_INVULNERABILITY_ONCE, + PREVENT_MOUNT_RELEASE, + DONT_USE_ALPHA_FADE_ON_RESPAWN, + DONT_USE_ALPHA_FADE_ON_RESPAWN_ONCE, + RESPAWN_LEAVES_ALIVE_PED_ONCE, + FORCE_COLLISION_WHEN_RESPOT_TIMER_FINISHED, + ALLOW_INCAPACITATION, + STORE_DAMAGE_EVENT, + PAY_BOUNTY_ON_RESPAWN, + RESPAWN_PRESERVE_DEADEYE, + RESPAWN_PRESERVE_HEALTH, + RESPAWN_SANS_WEAPONS, + REGISTER_LOADOUT_OVERRIDE_ON_RESPAWN, + REQUEST_LOADOUT_OVERRIDE_REGISTRATION, + CLEAR_LOADOUT_OVERRIDE_ON_RESPAWN, + REFRESH_WEAPONS_IN_HAND, + REFRESH_LOADOUT, + REFRESH_INVENTORY_OVERRIDE, + REFRESH_OUTFIT_OVERRIDE, + REFRESH_AMMO_TYPE_UNLOCKS, + SPECIAL_ABILITY_OVERRIDE_DEACTIVATION, + SPECIAL_ABILITY_DEACTIVATE_ON_CANCEL, + RESPAWN_NO_COMPONENT_LOAD, + RESPAWN_NO_EXPRESSION_LOAD, + RESPAWN_BLOCK_TEAM_RESET, + PAUSE_RELATIONSHIP_UPDATE, + DONT_PROCESS_FAST_INSTANCING, + RESPAWN_INTO_FAST_INSTANCE, + GANG_FEUDS_ARE_UNLOCKED, + OVERRIDE_PLAYER_ABILITIES, + DESTROY_CORPSE_ON_RESPAWN_ONCE, + DESTROY_CORPSE_ON_RESPAWN, + KEEP_CORPSE_ON_RESPAWN_ONCE, + KEEP_CORPSE_ON_RESPAWN, + CANNOT_BE_CARRIED_WHEN_DEAD, + CLEANUP_TRANSITION_SETTINGS, + DONT_CLEAR_DRUNK_FOR_SPAWNING_OR_CUTSCENES = 144, + DONT_SESSION_ON_RESPAWN_ONCE, + MAX +}; + +// TODO: move this somewhere else +enum class Region +{ + INVALID = -1, + BAY_CRAWDADWILLIES, + BAY_MACOMBS_END, + BAY_MERKINSWALLER, + BAY_LAGRAS, + BAY_LAKAY, + BAY_SAINT_DENIS, + BAY_ORANGE_PLANTATION, + BAY_SERIAL_KILLER, + BAY_SERENDIPITY, + BAY_SHADYBELLE, + BAY_SILTWATERSTRAND, + BGV_APPLESEEDTIMBER, + BGV_BERYLS_DREAM, + BGV_BLACKBONEFOREST_TRAPPER, + BGV_DAKOTARIVER_TRAPPER, + BGV_FORTRIGGS, + BGV_HANGINGDOG, + BGV_LONEMULESTEAD, + BGV_MISSING_HUSBAND, + BGV_MONTO_REST, + BGV_OWANJILA_DAM, + BGV_PAINTEDSKY, + BGV_PRONGHORN, + BGV_RIGGS_STATION, + BGV_SHACK, + BGV_SHEPHERDS_RISE, + BGV_STRAWBERRY, + BGV_VALLEY_VIEW, + BGV_WALLACE_STATION, + BGV_OLD_MAN_JONES, + BGV_WATSONSCABIN, + BLU_CANEBREAK_MANOR, + BLU_COPPERHEAD, + BLU_SISIKA, + BLU_TRAVELLING_SALESMAN, + CML_BACCHUSBRIDGE, + CML_DINO_LADY, + CML_OLDFORTWALLACE, + CML_SIXPOINTCABIN, + GRT_BEECHERS, + GRT_BLACKWATER, + GRT_QUAKERS_COVE, + GRZ_ADLERRANCH, + GRZ_DEAD_RIVAL, + GRZ_CHEZPORTER, + GRZ_COLTER, + GRZ_FROZEN_EXPLORER, + GRZ_MILLESANI_CLAIM, + GRZ_MOUNTAIN_MAN, + GRZ_MOUNT_HAGEN_PEAK, + GRZ_STARVING_CHILDREN, + GRZ_TEMPEST_RIM, + GRZ_WINTERMINING_TOWN, + GRZ_CALUMETRAVINE, + GRE_CIVIL_WAR_BRIDE, + GRZ_COHUTTA, + GRZ_COTORRA_SPRINGS, + GRZ_GUNFIGHT, + GRZ_THELOFT, + GRE_VETERAN, + GRZ_WAPITI, + GRZ_TRAVELLING_SALESMAN, + GUA_AGUASDULCES, + GUA_CAMP, + GUA_CINCOTORRES, + GUA_LACAPILLA, + GUA_MANICATO, + HRT_ABANDONED_MILL, + ROA_BEECHERS_C, + HRT_CARMODYDELL, + HRT_CORNWALLKEROSENE, + HRT_CROP_FARM, + HRT_CUMBERLANDFALLS, + HRT_DOWNSRANCH, + HRT_EMERALDRANCH, + HRT_GRANGERS_HOGGERY, + HRT_HORSESHOEOVERLOOK, + HRT_LARNEDSOD, + HRT_LOONY_CULT, + HRT_LUCKYSCABIN, + HRT_SWANSONS_STATION, + HRT_VALENTINE, + ROA_ABERDEENPIGFARM, + ROA_ANNESBURG, + ROA_BEAVERHOLLOW, + ROA_BLACK_BALSAM_RISE, + ROA_BRANDYWINE_DROP, + ROA_BUTCHERCREEK, + ROA_DOVERHILL, + ROA_HAPPY_FAMILY, + ROA_ISOLATIONIST, + ROA_MACLEANSHOUSE, + ROA_MOSSY_FLATS, + ROA_ROANOKE_VALLEY, + ROA_ROCKYSEVEN, + ROA_TRAPPER, + ROA_OLD_MAN_JONES, + ROA_VANHORNMANSION, + ROA_VANHORNPOST, + SCM_BRAITHWAITEMANOR, + SCM_BULGERGLADE, + SCM_CALIGAHALL, + SCM_CATFISHJACKSONS, + SCM_CLEMENSCOVE, + SCM_CLEMENSPOINT, + SCM_COMPSONS_STEAD, + SCM_DAIRY_FARM, + SCM_HORSE_SHOP, + SCM_LONNIESSHACK, + SCM_LOVE_TRIANGLE, + SCM_RADLEYS_PASTURE, + SCM_RHODES, + SCM_SLAVE_PEN, + TAL_AURORA_BASIN, + TAL_DEAD_SETTLER, + TAL_COCHINAY, + TAL_MANZANITAPOST, + TAL_PACIFICUNIONRR, + TAL_TANNERSREACH, + TAL_TRAPPER, + GAP_GAPTOOTH_BREACH, + GAP_TUMBLEWEED, + GAP_RATHSKELLER_FORK, + RIO_BENEDICT_POINT, + RIO_FORT_MERCER, + RIO_PLAIN_VIEW, + RIO_TRAVELLING_SALESMAN, + CHO_ARMADILLO, + CHO_COOTS_CHAPEL, + CHO_DON_JULIO_HOUSE, + CHO_RILEYS_CHARGE, + CHO_RIDGEWOOD_FARM, + CHO_TWIN_ROCKS, + CHO_TRAVELLING_SALESMAN, + CHO_TRAPPER, + HEN_MACFARLANES_RANCH, + HEN_THIEVES_LANDING, + HEN_TRAVELLING_SALESMAN, + HEN_HARRIET, + CENTRALUNIONRR, + MAX +}; + +enum class District +{ + INVALID = -1, + BAYOU_NWA, + BIG_VALLEY, + BLUEGILL_MARSH, + CUMBERLAND_FOREST, + GREAT_PLAINS, + GRIZZLIES, + GRIZZLIES_EAST, + GRIZZLIES_WEST, + GUAMA, + HEARTLAND, + ROANOKE_RIDGE, + SCARLETT_MEADOWS, + TALL_TREES, + GAPTOOTH_RIDGE, + RIO_BRAVO, + CHOLLA_SPRINGS, + HENNIGANS_STEAD +}; + +// seriously move this somewhere else +enum class Language +{ + UNDEFINED = -1, + ENGLISH, + FRENCH, + GERMAN, + ITALIAN, + SPANISH, + PORTUGESE, + POLISH, + RUSSIAN, + KOREAN, + CHINESE_TRAD, + JAPANESE, + MEXICAN, + CHINESE_SIMP +}; + +enum class PassiveState +{ + NOT_PASSIVE, + WAITING_FOR_PASSIVE, + PASSIVE, + WAITING_FOR_NOT_PASSIVE, + FORCED_FROM_PASSIVE +}; + +enum class AnimalTransformationFlag +{ + IS_ANIMAL, + PENDING_TRANSFORMATION_TO_HUMAN +}; + +struct ANIMAL_TRANSFORMATION_DATA +{ + SCR_INT TransitionTimestamp; + SCR_BITSET Flags; +}; + +// WARNING: the first 20 fields of this struct are overwritten every tick from another global +struct PLAYER_STATUS_SYNC_DATA_ENTRY +{ + alignas(8) PlayerStatus Status; + alignas(8) ParentStatus ParentStatus; // essentially a condensed version of Status + alignas(8) ScanState ScanState; + SCR_BITSET Flags; + SCR_BITSET_LARGE(PlayerStatusFlags::MAX)> StatusFlags; + alignas(8) Region CurrentRegion; + alignas(8) District CurrentDistrict; + TEXT_LABEL_31 FakeGamerTag; + SCR_BOOL CompletedFirstRespawn; + alignas(8) Language PlayerLanguage; // can't name this Language because GCC + SCR_FLOAT GangNotoriety; + PLAYER_INDEX SpectateTarget; + // ---------------------------------------------------------------------------------------------- + GAMER_HANDLE LastPlayerKilledHandle; + SCR_INT LastPlayerKilledTime; + PLAYER_INDEX LastPlayerKilled; + GAMER_HANDLE LastPlayerKilledByHandle; + GAMER_HANDLE LastPlayerKilledByHandle2; // seemingly the same thing + SCR_INT LastPlayerKilledByTime; + PLAYER_INDEX LastPlayerKilledBy; + SCR_FLOAT Notoriety; + SCR_INT PassiveRequestTime; + SCR_INT PassiveUpdateTime; + alignas(8) PassiveState PassiveState; + SCR_BOOL PassivePenaltyApplied; + SCR_INT NotorietyFlags; + ANIMAL_TRANSFORMATION_DATA AnimalTransformationData; +}; +static_assert(sizeof(PLAYER_STATUS_SYNC_DATA_ENTRY) == 38 * 8); + +struct PLAYER_STATUS_SYNC_DATA +{ + SCR_ARRAY Entries; +}; +static_assert(sizeof(PLAYER_STATUS_SYNC_DATA) == 1217 * 8); \ No newline at end of file diff --git a/script/globals/SessionManagerPlayerData.hpp b/script/globals/SessionManagerPlayerData.hpp new file mode 100644 index 0000000..7b300ee --- /dev/null +++ b/script/globals/SessionManagerPlayerData.hpp @@ -0,0 +1,36 @@ +#pragma once +#include "script/types.hpp" +#include "rage/joaat.hpp" +#include "PlayerStatusSyncData.hpp" + +enum class ContentLock +{ + PROC_MISSIONS, + GANG_EVENTS, + SHOPS, + HIDEOUTS, + CAMPS, + REGIONS, + TRAINS, + FM_ACTIVITIES, + STORY_MISSIONS, + PROPERTIES, + GUN_FOR_HIRE, + MINIGAMES, + PLAYER_BOUNTIES, + AMBIENT_ROAD_POPULATION +}; + +struct SESSION_MANAGER_PLAYER_DATA_ENTRY +{ + SCR_BITSET ContentLocks; + uint64_t PAD_0001[3]; // unused? + SCR_BITSET_LARGE(Region::MAX), 30, 7> LockedRegions; +}; +static_assert(sizeof(SESSION_MANAGER_PLAYER_DATA_ENTRY) == 12 * 8); + +struct SESSION_MANAGER_PLAYER_DATA +{ + SCR_ARRAY Entries; +}; +static_assert(sizeof(SESSION_MANAGER_PLAYER_DATA) == 385 * 8); \ No newline at end of file diff --git a/script/types.hpp b/script/types.hpp index a0dff1c..8d24e2a 100644 --- a/script/types.hpp +++ b/script/types.hpp @@ -58,8 +58,6 @@ template struct SCR_TEXT_LABEL { alignas(8) char Data[SIZE]; -private: - alignas(8) char _PAD[SIZE]; public: operator char* () { return Data; } }; @@ -102,6 +100,46 @@ struct SCR_BITSET } }; +/// This is very untested, beware! +/// MODULUS should be 32 for maximum efficiency but most Rockstar scripts use 31 +template +struct SCR_BITSET_LARGE +{ + SCR_ARRAY Array; + + bool IsSet(T val) + { + return Array[(int)val / MODULUS] & (1 << ((int)val % MODULUS)); + } + + void Set(T val) + { + Array[(int)val / MODULUS] |= (1 << ((int)val % MODULUS)); + } + + void Clear(T val) + { + Array[(int)val / MODULUS] &= ~(1 << ((int)val % MODULUS)); + } +}; + +struct SCR_DATE +{ + SCR_INT Year; + SCR_INT Month; + SCR_INT Day; + SCR_INT Hour; + SCR_INT Minute; + SCR_INT Second; + SCR_INT Millisecond; +}; + +struct SCR_GUID +{ + SCR_INT Element1; + SCR_INT Element2; +}; + struct Color3 { SCR_INT R; @@ -110,10 +148,10 @@ struct Color3 }; static_assert(sizeof(Color3) == 3 * 8); -// serialized bitbuffer data of rage::rlGamerHandle + some padding for last gen compatibility +// serialized bitbuffer data of rage::rlGamerHandle struct GAMER_HANDLE { private: - uint64_t Data[13]; + uint64_t Data[2]; }; -static_assert(sizeof(GAMER_HANDLE) == 13 * 8); +static_assert(sizeof(GAMER_HANDLE) == 2 * 8); \ No newline at end of file