//╒═════════════════════════════════════════════════════════════════════════════╕ //│ 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, " 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, " 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, " 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, " 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, " 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, " 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, " 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 ver 1.0 patching completed.") ENDPROC PROC APPLY_VER_1_1_PATCHING() CPRINTLN(DEBUG_INIT, " Applying save ver 1.1 patching.") //Nothing to patch. CPRINTLN(DEBUG_INIT, " Save ver 1.1 patching completed.") ENDPROC PROC APPLY_VERSION_PRE_1_5_PATCH() CPRINTLN(DEBUG_INIT, " 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, " 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, " Check ver 1.5 heist SBV ", veh, " changed to ", iNewVeh, " in savegame.") ENDIF ENDFOR ENDREPEAT CPRINTLN(DEBUG_INIT, " 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," 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, " 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, " 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, " Patching owner for property ", iPropertyIndex, " to be CHAR_BLANK_ENTRY.") g_savedGlobals.sPropertyData.propertyOwnershipData[iPropertyIndex].charOwner = NO_CHARACTER ENDIF ENDIF ENDREPEAT CPRINTLN(DEBUG_INIT, " 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