Files
2025-09-29 00:52:08 +02:00

217 lines
13 KiB
XML
Executable File

//╒═════════════════════════════════════════════════════════════════════════════╕
//│ Author: Ben Rollinson Date: 13/09/13 │
//╞═════════════════════════════════════════════════════════════════════════════╡
//│ │
//│ GTAV savegame version patching │
//│ │
//╘═════════════════════════════════════════════════════════════════════════════╛
USING "rage_builtins.sch"
USING "globals.sch"
USING "player_ped_public.sch"
PROC SWAP_COMPLETION_PERCENTAGE_ENTRY_ARRAY_INDEXES(enumCompletionPercentageEntries eEntry1, enumCompletionPercentageEntries eEntry2)
TEXT_LABEL txtLabelTemp
FLOAT fWeightingTemp
BOOL bMarkedAsCompleteTemp
enumGrouping eGroupingTemp
enumChoiceMiss eChoiceMissionTemp
INT iEnumAndVariationDataTemp
enumSCCluster eSocialClubClusterDisplayTemp
FLOAT fDefinedLocationXTemp
FLOAT fDefinedLocationYTemp
txtLabelTemp = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_Label
fWeightingTemp = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_Weighting
bMarkedAsCompleteTemp = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_Marked_As_Complete
eGroupingTemp = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_Grouping
eChoiceMissionTemp = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_ChoiceMission
iEnumAndVariationDataTemp = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_EnumAndVariationData
eSocialClubClusterDisplayTemp = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_SocialClubClusterDisplay
fDefinedLocationXTemp = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_DefinedLocationX
fDefinedLocationYTemp = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_DefinedLocationY
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_Label = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_Label
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_Weighting = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_Weighting
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_Marked_As_Complete = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_Marked_As_Complete
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_Grouping = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_Grouping
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_ChoiceMission = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_ChoiceMission
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_EnumAndVariationData = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_EnumAndVariationData
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_SocialClubClusterDisplay = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_SocialClubClusterDisplay
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_DefinedLocationX = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_DefinedLocationX
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry1].CP_DefinedLocationY = g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_DefinedLocationY
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_Label = txtLabelTemp
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_Weighting = fWeightingTemp
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_Marked_As_Complete = bMarkedAsCompleteTemp
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_Grouping = eGroupingTemp
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_ChoiceMission = eChoiceMissionTemp
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_EnumAndVariationData = iEnumAndVariationDataTemp
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_SocialClubClusterDisplay = eSocialClubClusterDisplayTemp
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_DefinedLocationX = fDefinedLocationXTemp
g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[eEntry2].CP_DefinedLocationY = fDefinedLocationYTemp
ENDPROC
PROC APPLY_VER_1_0_PATCHING()
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Applying save ver 1.0 patching.")
//Fix for rare command override bug where certain heist setup missions can be unflagged as completed
//after they've been passed in the flow.
IF g_savedGlobals.sFlow.controls.intIDs[FLOWINT_HEIST_CHOICE_JEWEL] != HEIST_CHOICE_EMPTY
IF NOT g_savedGlobals.sFlow.missionSavedData[SP_HEIST_JEWELRY_1].completed
SCRIPT_ASSERT("Jewel Store Job Setup save bug discovered. Patching.")
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Jewel Store Job Setup save bug discovered. Patching.")
g_savedGlobals.sFlow.missionSavedData[SP_HEIST_JEWELRY_1].completed = TRUE
ENDIF
ENDIF
IF g_savedGlobals.sFlow.controls.intIDs[FLOWINT_HEIST_CHOICE_DOCKS] != HEIST_CHOICE_EMPTY
IF NOT g_savedGlobals.sFlow.missionSavedData[SP_HEIST_DOCKS_1].completed
SCRIPT_ASSERT("Port of LS Setup save bug discovered. Patching.")
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Port of LS Setup save bug discovered. Patching.")
g_savedGlobals.sFlow.missionSavedData[SP_HEIST_DOCKS_1].completed = TRUE
ENDIF
ENDIF
IF g_savedGlobals.sFlow.controls.intIDs[FLOWINT_HEIST_CHOICE_RURAL] != HEIST_CHOICE_EMPTY
IF NOT g_savedGlobals.sFlow.missionSavedData[SP_HEIST_RURAL_1].completed
SCRIPT_ASSERT("Paleto Score Setup save bug discovered. Patching.")
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Paleto Score Setup save bug discovered. Patching.")
g_savedGlobals.sFlow.missionSavedData[SP_HEIST_RURAL_1].completed = TRUE
ENDIF
ENDIF
IF g_savedGlobals.sFlow.controls.intIDs[FLOWINT_HEIST_CHOICE_AGENCY] != HEIST_CHOICE_EMPTY
IF NOT g_savedGlobals.sFlow.missionSavedData[SP_HEIST_AGENCY_2].completed
SCRIPT_ASSERT("Bureau Raid Mug Architect save bug discovered. Patching.")
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Bureau Raid Mug Architect save bug discovered. Patching.")
g_savedGlobals.sFlow.missionSavedData[SP_HEIST_AGENCY_2].completed = TRUE
ENDIF
ENDIF
IF g_savedGlobals.sFlow.controls.intIDs[FLOWINT_HEIST_CHOICE_FINALE] != HEIST_CHOICE_EMPTY
IF NOT g_savedGlobals.sFlow.missionSavedData[SP_HEIST_FINALE_2_INTRO].completed
SCRIPT_ASSERT("Big Score Setup save bug discovered. Patching.")
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Big Score Setup save bug discovered. Patching.")
g_savedGlobals.sFlow.missionSavedData[SP_HEIST_FINALE_2_INTRO].completed = TRUE
ENDIF
ENDIF
//Fix for 1619825. Array ordering for Rampages was changed to fix 1542450. This means when loading a
//v1.0 save, rampage global data is out of sync.
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Resyncing rampage completion percentage global data.")
SWAP_COMPLETION_PERCENTAGE_ENTRY_ARRAY_INDEXES(CP_OJ_RAM2, CP_OJ_RAM5)
SWAP_COMPLETION_PERCENTAGE_ENTRY_ARRAY_INDEXES(CP_OJ_RAM2, CP_OJ_RAM4)
SWAP_COMPLETION_PERCENTAGE_ENTRY_ARRAY_INDEXES(CP_OJ_RAM2, CP_OJ_RAM3)
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Save ver 1.0 patching completed.")
ENDPROC
PROC APPLY_VER_1_1_PATCHING()
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Applying save ver 1.1 patching.")
//Nothing to patch.
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Save ver 1.1 patching completed.")
ENDPROC
PROC APPLY_VERSION_PRE_1_5_PATCH()
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Applying pre 1.4 patching.")
// Setting the bit for shrink complete as this bitset wasnt in the pre 1.4 versions of the game.
// Failsafe to unlock Dr Freidlander in DM if managed to complete the missions before the bit could have been set.
IF GET_MISSION_COMPLETE_STATE( SP_MISSION_SHRINK_1 )
OR GET_MISSION_COMPLETE_STATE( SP_MISSION_SHRINK_2 )
OR GET_MISSION_COMPLETE_STATE( SP_MISSION_SHRINK_3 )
OR GET_MISSION_COMPLETE_STATE( SP_MISSION_SHRINK_4 )
OR GET_MISSION_COMPLETE_STATE( SP_MISSION_SHRINK_5 )
SET_BIT( g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_SHRINK_SESSION_ATTENDED )
ENDIF
ENDPROC
PROC CHECK_VER_1_5_SITE_BUYABLE_VEHICLE()
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Check for SBV ver 1.5 difference.")
enumCharacterList ePed
REPEAT 3 ePed
SITE_BUYABLE_VEHICLE veh
FOR veh = BV_DLC_BOXVILLE4 TO BV_MP_SURGE
IF IS_BIT_SET(g_savedGlobals.sBuyableVehicleSavedData.g_bOwnedVehicleStates[veh], ENUM_TO_INT(ePed))
CLEAR_BIT(g_savedGlobals.sBuyableVehicleSavedData.g_bOwnedVehicleStates[veh], ENUM_TO_INT(ePed))
INT iNewVeh = ENUM_TO_INT(veh) + (ENUM_TO_INT(BV_MP_SURGE) - ENUM_TO_INT(BV_DLC_BOXVILLE4))+1
SET_BIT(g_savedGlobals.sBuyableVehicleSavedData.g_bOwnedVehicleStates[iNewVeh], ENUM_TO_INT(ePed))
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Check ver 1.5 heist SBV ", veh, " changed to ", iNewVeh, " in savegame.")
ENDIF
ENDFOR
ENDREPEAT
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Save ver 1.5 SBV checked.")
ENDPROC
PROC APPLY_VER_1_5_PATCHING()
//Ver 1.5 was missing the iDLCHangarVehicles from g_savedGlobals.sShopData.iContentChecks_Vehicles
INT iHangarVehicles, iMarinaVehicles, iHeliVehicles
STAT_GET_INT(CONTENT_HANGER_VEH,iHangarVehicles)
STAT_GET_INT(CONTENT_MARINA_VEH, iMarinaVehicles)
STAT_GET_INT(CONTENT_HELI_VEH, iHeliVehicles)
IF iHangarVehicles >= 0 AND iMarinaVehicles >= 0 AND iHeliVehicles >= 0
CPRINTLN(DEBUG_INIT,"<SAVE-PATCH> ver 1.5 save detected, patching iContentChecks_Vehicles")
g_savedGlobals.sShopData.iContentChecks_Vehicles -= iHangarVehicles
ENDIF
ENDPROC
PROC APPLY_1_7_PATCHING()
// Previous version had locations unlocked by default in Director mode. Ensuring that the new patch resets this bitset for achievement unlock.
// See B* 2407407.
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Applying 1.7 patching as save game is less than 1.7 - Clearing location revealed bitset from DM. RBJ.")
g_savedGlobals.sDirectorModeData.iBitsetTravelLocationRevealed = 0
ENDPROC
// If we add new character enums then the null property owners can become real character enums.
// We need to catch this and set them back to the null value CHAR_BLANK_ENTRY. This should always be run as
// a patch for the latest
PROC APPLY_PROPERTY_OWNER_PATCHING()
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Applying property owner patching.")
INT iPropertyIndex
REPEAT COUNT_OF(PROPERTY_ENUM) iPropertyIndex
IF NOT IS_PLAYER_PED_PLAYABLE(g_savedGlobals.sPropertyData.propertyOwnershipData[iPropertyIndex].charOwner)
IF g_savedGlobals.sPropertyData.propertyOwnershipData[iPropertyIndex].charOwner != NO_CHARACTER
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Patching owner for property ", iPropertyIndex, " to be CHAR_BLANK_ENTRY.")
g_savedGlobals.sPropertyData.propertyOwnershipData[iPropertyIndex].charOwner = NO_CHARACTER
ENDIF
ENDIF
ENDREPEAT
CPRINTLN(DEBUG_INIT, "<SAVE-PATCH> Property owner patching completed.")
ENDPROC
PROC APPLY_SAVEGAME_PATCHING(FLOAT fOldVersion)
APPLY_PROPERTY_OWNER_PATCHING()
IF fOldVersion = 1.0
APPLY_VER_1_0_PATCHING()
ENDIF
IF fOldVersion <= 1.1
APPLY_VER_1_1_PATCHING()
ENDIF
IF fOldVersion < 1.5
APPLY_VERSION_PRE_1_5_PATCH()
ENDIF
IF fOldVersion <= 1.5
CHECK_VER_1_5_SITE_BUYABLE_VEHICLE()
ENDIF
IF fOldVersion = 1.5
APPLY_VER_1_5_PATCHING()
ENDIF
IF fOldVersion < 1.7
APPLY_1_7_PATCHING()
ENDIF
ENDPROC