//╒═════════════════════════════════════════════════════════════════════════════╕ //│ Author: Ben Rollinson Date: 14/09/11 │ //╞═════════════════════════════════════════════════════════════════════════════╡ //│ │ //│ Mission Repeat System - Public Script Interface │ //│ │ //│ This header contains all public script commands used by │ //│ the mission repeat system. This system allows replaying of │ //│ missions that have already been completed by the player. │ //│ │ //╘═════════════════════════════════════════════════════════════════════════════╛ USING "rage_builtins.sch" USING "globals.sch" USING "commands_entity.sch" USING "commands_stats.sch" USING "commands_dlc.sch" USING "commands_decorator.sch" USING "dlc_mission_stat_private.sch" #IF USE_CLF_DLC USING "mission_stat_generated_private_CLF.sch" #ENDIF #IF NOT USE_CLF_DLC USING "mission_stat_generated_private.sch" #ENDIF #IF NOT USE_SP_DLC USING "randomchar_private_gta5.sch" #ENDIF /// PURPOSE: /// this has to live here to fix cyclic header /// PARAMS: /// paramMission - /// RETURNS: /// FUNC TEXT_LABEL_7 GET_SP_MISSION_NAME_LABEL(SP_MISSIONS paramMission) TEXT_LABEL_7 txtMissionName = "M_" txtMissionName += g_sMissionStaticData[paramMission].statID #IF NOT USE_SP_DLC //Special case for the Jewelry Heist. Work out if we should use the A or B choice label. IF paramMission = SP_HEIST_JEWELRY_2 SWITCH g_savedGlobals.sFlow.controls.intIDs[FLOWINT_HEIST_CHOICE_JEWEL] CASE HEIST_CHOICE_JEWEL_STEALTH txtMissionName += "A" BREAK CASE HEIST_CHOICE_JEWEL_HIGH_IMPACT txtMissionName += "B" BREAK DEFAULT txtMissionName += "A" BREAK ENDSWITCH ENDIF #ENDIF RETURN txtMissionName ENDFUNC /// PURPOSE: /// update's the eyefind news story state enum /// PARAMS: /// iMissionindex - mission /// bIsRCMission - if this is an RC mission else SP #IF USE_CLF_DLC PROC UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATECLF(INT iMissionindex, BOOL bIsRCMission) EYEFIND_NEWS_STORY_STATE_ENUM eNewStoryState = EYEFIND_NEWS_STORY_STATE_INVALID SP_MISSIONS eSPMission = INT_TO_ENUM(SP_MISSIONS, iMissionindex) //Story Mission IF eSPMission = SP_MISSION_CLF_TRAIN ENDIF eNewStoryState = eNewStoryState bIsRCMission = bIsRCMission ENDPROC #ENDIF #IF USE_NRM_DLC PROC UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATENRM(INT iMissionindex, BOOL bIsRCMission) EYEFIND_NEWS_STORY_STATE_ENUM eNewStoryState = EYEFIND_NEWS_STORY_STATE_INVALID SP_MISSIONS eSPMission = INT_TO_ENUM(SP_MISSIONS, iMissionindex) //Story Mission IF eSPMission = SP_MISSION_NRM_SUR_START ELIF eSPMission = SP_MISSION_NRM_SUR_AMANDA ELIF eSPMission = SP_MISSION_NRM_SUR_TRACEY ELIF eSPMission = SP_MISSION_NRM_SUR_MICHAEL ELIF eSPMission = SP_MISSION_NRM_SUR_HOME ELIF eSPMission = SP_MISSION_NRM_SUR_JIMMY ELIF eSPMission = SP_MISSION_NRM_SUR_PARTY ELIF eSPMission = SP_MISSION_NRM_SUR_CURE ELIF eSPMission = SP_MISSION_NRM_RESCUE_ENG ELIF eSPMission = SP_MISSION_NRM_RESCUE_MED ELIF eSPMission = SP_MISSION_NRM_RESCUE_GUN ELIF eSPMission = SP_MISSION_NRM_SUP_FUEL ELIF eSPMission = SP_MISSION_NRM_SUP_AMMO ELIF eSPMission = SP_MISSION_NRM_SUP_MEDS ELIF eSPMission = SP_MISSION_NRM_SUP_FOOD ELIF eSPMission = SP_MISSION_NRM_RADIO_A ELIF eSPMission = SP_MISSION_NRM_RADIO_B ELIF eSPMission = SP_MISSION_NRM_RADIO_C ENDIF eNewStoryState = eNewStoryState bIsRCMission = bIsRCMission ENDPROC #ENDIF PROC UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATE(INT iMissionindex, BOOL bIsRCMission) #IF USE_CLF_DLC UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATECLF(iMissionindex,bIsRCMission) #ENDIF #IF USE_NRM_DLC UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATENRM(iMissionindex,bIsRCMission) #ENDIF #IF NOT USE_SP_DLC EYEFIND_NEWS_STORY_STATE_ENUM eNewStoryState = EYEFIND_NEWS_STORY_STATE_INVALID // RC mission IF bIsRCMission g_eRC_MissionIDs eRcMission = INT_TO_ENUM(g_eRC_MissionIDs, iMissionindex) IF eRcMission = RC_PAPARAZZO_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_PAP1 ELIF eRcMission = RC_PAPARAZZO_3A eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_PAP3A ELIF eRcMission = RC_PAPARAZZO_3B eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_PAP3B ELIF eRcMission = RC_DREYFUSS_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_DRF1 ELIF eRcMission = RC_EPSILON_8 eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_EPN8 ELIF eRcMission = RC_NIGEL_1A eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_NIG1A ELIF eRcMission = RC_NIGEL_1B eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_NIG1B ELIF eRcMission = RC_NIGEL_1C eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_NIG1C ELIF eRcMission = RC_NIGEL_1D eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_NIG1D ELIF eRcMission = RC_NIGEL_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_NIG2 ELIF eRcMission = RC_NIGEL_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_NIG3 ELIF eRcMission = RC_EXTREME_4 eNewStoryState = EYEFIND_NEWS_STORY_STATE_RC_EXT4 ENDIF // Story Mission ELSE SP_MISSIONS eSPMission = INT_TO_ENUM(SP_MISSIONS, iMissionindex) //Story Mission IF eSPMission = SP_MISSION_PROLOGUE eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_PRO ELIF eSPMission = SP_MISSION_ARMENIAN_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_ARM2 ELIF eSPMission = SP_MISSION_ARMENIAN_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_ARM3 ELIF eSPMission = SP_MISSION_FAMILY_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FAM1 ELIF eSPMission = SP_MISSION_FAMILY_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FAM3 ELIF eSPMission = SP_MISSION_LAMAR eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_LAM1 ELIF eSPMission = SP_MISSION_LESTER_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_LST1 ELIF eSPMission = SP_MISSION_TREVOR_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_TRE2 ELIF eSPMission = SP_MISSION_CHINESE_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_CHI1 ELIF eSPMission = SP_MISSION_CHINESE_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_CHI2 ELIF eSPMission = SP_MISSION_TREVOR_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_TRE3 ELIF eSPMission = SP_MISSION_FAMILY_4 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FAM4 ELIF eSPMission = SP_MISSION_FBI_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FIB2 ELIF eSPMission = SP_MISSION_FBI_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FIB3 ELIF eSPMission = SP_MISSION_FRANKLIN_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FRA1 ELIF eSPMission = SP_MISSION_FBI_4 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FIB4 ELIF eSPMission = SP_MISSION_CARSTEAL_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_CARS2 ELIF eSPMission = SP_MISSION_SOLOMON_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_SOL1 ELIF eSPMission = SP_MISSION_MARTIN_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_MTN1 ELIF eSPMission = SP_MISSION_CARSTEAL_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_CARS3 ELIF eSPMission = SP_MISSION_EXILE_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_EXL1 ELIF eSPMission = SP_MISSION_EXILE_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_EXL3 ELIF eSPMission = SP_MISSION_FBI_5 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FIB5 ELIF eSPMission = SP_MISSION_MICHAEL_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_MIC1 ELIF eSPMission = SP_MISSION_SOLOMON_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_SOL2 ELIF eSPMission = SP_MISSION_FAMILY_6 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FAM6 ELIF eSPMission = SP_MISSION_MICHAEL_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_MIC3 ELIF eSPMission = SP_MISSION_SOLOMON_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_SOL3 ELIF eSPMission = SP_MISSION_MICHAEL_4 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_MIC4 ELIF eSPMission = SP_MISSION_FINALE_C2 // story only makes sense if player takes C2 (save Mike and Trev) eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_FINALE //Assasinations ELIF eSPMission = SP_MISSION_ASSASSIN_1 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_ASS1 ELIF eSPMission = SP_MISSION_ASSASSIN_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_ASS2 ELIF eSPMission = SP_MISSION_ASSASSIN_3 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_ASS3 ELIF eSPMission = SP_MISSION_ASSASSIN_4 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_ASS4 ELIF eSPMission = SP_MISSION_ASSASSIN_5 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_ASS5 //Shrink ELIF eSPMission = SP_MISSION_SHRINK_5 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_SHK5 // Heist ELIF eSPMission = SP_HEIST_JEWELRY_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_H_JWL ELIF eSPMission = SP_HEIST_DOCKS_2A OR eSPMission = SP_HEIST_DOCKS_2B eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_H_DOCK ELIF eSPMission = SP_HEIST_RURAL_2 eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_H_RB2A ELIF eSPMission = SP_HEIST_AGENCY_3A OR eSPMission = SP_HEIST_AGENCY_3B eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_H_AG3A ELIF eSPMission = SP_HEIST_FINALE_2A or eSPMission = SP_HEIST_FINALE_2B eNewStoryState = EYEFIND_NEWS_STORY_STATE_SP_H_BS2A ENDIF ENDIF IF eNewStoryState != EYEFIND_NEWS_STORY_STATE_INVALID g_savedGlobals.sFinanceData.eCurrentEyeFindNewsStoryState = eNewStoryState CPRINTLN(DEBUG_INTERNET, GET_THIS_SCRIPT_NAME(), " UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATE() : updated eCurrentEyeFindNewsStoryState = ", eNewStoryState) ENDIF #ENDIF ENDPROC /// PURPOSE: /// Checks if a the player is playing barber chair anims or doing barber intro /// RETURNS: /// TRUE if player playing haircut anims. FALSE otherwise FUNC BOOL IS_PLAYER_IN_BARBER_CHAIR_OR_DOING_BARBER_INTRO() IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) AND NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@barbers","player_intro") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@barbers","player_base") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@barbers","player_enterchair") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@barbers","player_exitchair") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@barbers","player_idle_a") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@barbers","player_idle_b") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@barbers","player_idle_c") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@barbers","player_idle_d") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@hair_dressers","player_intro") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@hair_dressers","player_base") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@hair_dressers","player_enterchair") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@hair_dressers","player_exitchair") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@hair_dressers","player_idle_a") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@hair_dressers","player_idle_b") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@hair_dressers","player_idle_c") OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(),"misshair_shop@hair_dressers","player_idle_d") RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Checks if a player is in the mod shop /// RETURNS: /// TRUE if in shop. FALSE otherwise FUNC BOOL IS_PLAYER_BROWSING_MOD_SHOP() RETURN IS_BIT_SET(g_iRepeatPlayBits, ENUM_TO_INT(RPB_PLAYER_BROWSING_MOD_SHOP)) ENDFUNC /// PURPOSE: /// Checks if a player is browsing tattoos in a tattoo shop /// RETURNS: /// TRUE if in shop. FALSE otherwise FUNC BOOL IS_PLAYER_BROWSING_TATTOO_SHOP() RETURN IS_BIT_SET(g_iRepeatPlayBits, ENUM_TO_INT(RPB_PLAYER_BROWSING_TATTOO_SHOP)) ENDFUNC /// PURPOSE: /// Checks if a mission is being replayed via the "Replay Mission" pause menu /// RETURNS: /// TRUE if repeat play is active. FALSE otherwise FUNC BOOL IS_REPEAT_PLAY_ACTIVE(BOOL bIgnoreBenchmark = FALSE) //Also return true if running the benchmark script - considered a replay IF (NOT bIgnoreBenchmark) AND GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("benchmark"))>0 RETURN TRUE ENDIF RETURN IS_BIT_SET(g_iRepeatPlayBits, ENUM_TO_INT(RPB_ACTIVE)) ENDFUNC /// PURPOSE: /// Tells the repeat play controller to launch repeat play of mission specified /// PARAMS: /// iMissionIndex - index of appropriate array /// eMissionType - CP_GROUP_MISSIONS / CP_GROUP_MISSIONS PROC LaunchRepeatPlay(INT iMissionIndex, enumGrouping eMissionType) g_RepeatPlayData.iMissionIndex = iMissionIndex g_RepeatPlayData.eMissionType = eMissionType //Ensure RC mission leave area flags are activated as soon as we start setting up a repeat play. IF eMissionType = CP_GROUP_RANDOMCHARS IF iMissionIndex >= 0 AND iMissionIndex < ENUM_TO_INT(MAX_RC_MISSIONS) g_RandomChars[iMissionIndex].rcLeaveAreaCheck = TRUE ENDIF ENDIF SET_BIT(g_iRepeatPlayBits, ENUM_TO_INT(RPB_ACTIVE)) ENDPROC /// PURPOSE: /// Checks if repeat play is active and if it is this RC that is being repeat played /// PARAMS: /// iMissionIndex - index of RC in RC array /// RETURNS: /// TRUE if this RC mission is being repeat played, FALSE otherwise FUNC BOOL IsThisRCBeingRepeatPlayed(INT iMissionIndex) IF IS_REPEAT_PLAY_ACTIVE() IF g_RepeatPlayData.eMissionType = CP_GROUP_RANDOMCHARS IF g_RepeatPlayData.iMissionIndex = iMissionIndex // This RC is being repeat played RETURN TRUE ENDIF ENDIF ENDIF // This RC is not being repeat played RETURN FALSE ENDFUNC /// PURPOSE: /// Returns the text label of the mission name for selected mission /// PARAMS: /// iMissionIndex - index of appropriate array /// eMissionType - CP_GROUP_MISSIONS / CP_GROUP_MISSIONS /// RETURNS: /// the text label of the mission name #IF USE_CLF_DLC FUNC TEXT_LABEL_7 GetRepeatPlayMissionNameCLF(INT iMissionIndex, enumGrouping eMissionType) TEXT_LABEL_7 tMissionNameLabel = "" SWITCH eMissionType CASE CP_GROUP_MISSIONS // other missions tMissionNameLabel = "M_" tMissionNameLabel += g_sMissionStaticData[iMissionIndex].statID BREAK DEFAULT CPRINTLN(DEBUG_REPEAT,"GetRepeatPlayMissionName passed a mission type that isn't repeat playable: ", eMissionType) BREAK ENDSWITCH RETURN tMissionNameLabel ENDFUNC #ENDIF #IF USE_NRM_DLC FUNC TEXT_LABEL_7 GetRepeatPlayMissionNameNRM(INT iMissionIndex, enumGrouping eMissionType) TEXT_LABEL_7 tMissionNameLabel = "" SWITCH eMissionType CASE CP_GROUP_MISSIONS // other missions tMissionNameLabel = "M_" tMissionNameLabel += g_sMissionStaticData[iMissionIndex].statID BREAK DEFAULT CPRINTLN(DEBUG_REPEAT,"GetRepeatPlayMissionName passed a mission type that isn't repeat playable: ", eMissionType) BREAK ENDSWITCH RETURN tMissionNameLabel ENDFUNC #ENDIF FUNC TEXT_LABEL_7 GetRepeatPlayMissionName(INT iMissionIndex, enumGrouping eMissionType) #IF USE_CLF_DLC RETURN GetRepeatPlayMissionNameCLF(iMissionIndex,eMissionType) #ENDIF #IF USE_NRM_DLC RETURN GetRepeatPlayMissionNameNRM(iMissionIndex,eMissionType) #ENDIF #IF NOT USE_SP_DLC TEXT_LABEL_7 tMissionNameLabel = "" SWITCH eMissionType CASE CP_GROUP_MISSIONS // Special case to overwrite the Gauntlet mission names IF (INT_TO_ENUM(SP_MISSIONS, iMissionIndex) = SP_HEIST_FINALE_PREP_C1 OR INT_TO_ENUM(SP_MISSIONS, iMissionIndex) = SP_HEIST_FINALE_PREP_C2 OR INT_TO_ENUM(SP_MISSIONS, iMissionIndex) = SP_HEIST_FINALE_PREP_C3) tMissionNameLabel += g_sMissionStaticData[iMissionIndex].statID tMissionNameLabel += "A" ELSE // other missions tMissionNameLabel = "M_" tMissionNameLabel += g_sMissionStaticData[iMissionIndex].statID //Special case for the Jewelry Heist. IF INT_TO_ENUM(SP_MISSIONS, iMissionIndex) = SP_HEIST_JEWELRY_2 tMissionNameLabel += "A" ENDIF ENDIF BREAK CASE CP_GROUP_RANDOMCHARS tMissionNameLabel = GET_RC_MISSION_NAME_LABEL(INT_TO_ENUM(g_eRC_MissionIDs, iMissionIndex)) BREAK DEFAULT CPRINTLN(DEBUG_REPEAT,"GetRepeatPlayMissionName passed a mission type that isn't repeat playable: ", eMissionType) BREAK ENDSWITCH RETURN tMissionNameLabel #ENDIF ENDFUNC /// PURPOSE: /// Returns the number of stats this mission has associated with it /// PARAMS: /// iMissionIndex - index of appropriate array /// eMissionType - CP_GROUP_MISSIONS / CP_GROUP_MISSIONS /// RETURNS: /// int = number of stats this mission has FUNC INT GetRepeatPlayMissionStatCount(INT iMissionIndex, enumGrouping eMissionType) SWITCH eMissionType CASE CP_GROUP_MISSIONS RETURN g_sMissionStaticData[iMissionIndex].statCount BREAK #IF NOT USE_SP_DLC CASE CP_GROUP_RANDOMCHARS RETURN GET_NUMBER_OF_STATS_FOR_RC_MISSION(INT_TO_ENUM(g_eRC_MissionIDs, iMissionIndex)) BREAK #ENDIF DEFAULT CPRINTLN(DEBUG_REPEAT,"GetRepeatPlayMissionStatCount passed a mission type that isn't repeat playable: ", eMissionType) BREAK ENDSWITCH RETURN 0 // not repeatable mission ENDFUNC /// PURPOSE: /// Returns the specified stat associated with this mission /// PARAMS: /// iMissionIndex - index of appropriate array /// eMissionType - CP_GROUP_MISSIONS / CP_GROUP_MISSIONS /// iStatIndex - the stat we want /// RETURNS: /// ENUM_MISSION_STATS the specified stat FUNC ENUM_MISSION_STATS GetRepeatPlayMissionStat(INT iMissionIndex, enumGrouping eMissionType, INT iStatIndex) SWITCH eMissionType CASE CP_GROUP_MISSIONS RETURN g_sMissionStaticData[iMissionIndex].stats[iStatIndex] BREAK #IF NOT USE_SP_DLC CASE CP_GROUP_RANDOMCHARS RETURN GET_NTH_STAT_FOR_RC_MISSION(INT_TO_ENUM(g_eRC_MissionIDs, iMissionIndex), iStatIndex) BREAK #ENDIF DEFAULT CPRINTLN(DEBUG_REPEAT,"GetRepeatPlayMissionStatIndex passed a mission type that isn't repeat playable: ", eMissionType) BREAK ENDSWITCH RETURN EMPTY_MISSION_STAT // not repeatable mission ENDFUNC /// PURPOSE: /// Gets the total number of missions used in repeat play unlocking that have been completed /// If anything else gets added to repeat play unlocking, it needs adding here /// RETURNS: /// INT missions completed + RCs completed FUNC INT GetTotalCompletionOrder() #IF USE_CLF_DLC RETURN g_savedGlobalsClifford.sFlowCustom.iMissionsCompleted #ENDIF #IF USE_NRM_DLC RETURN g_savedGlobalsnorman.sFlowCustom.iMissionsCompleted #ENDIF #IF NOT USE_SP_DLC RETURN g_savedGlobals.sFlowCustom.iMissionsCompleted + g_savedGlobals.sRandomChars.iRCMissionsCompleted #ENDIF ENDFUNC /// PURPOSE: /// Sets the repeat play completion order for this RC mission /// PARAMS: /// iMissionID - the RC mission that has been completed PROC UpdateRCMissionRepeatCompletionOrder(INT iMissionID) UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATE(iMissionID, TRUE) // Update repeat play variables, so we know the playthrough order the player has used g_savedGlobals.sRandomChars.savedRC[iMissionID].iCompletionOrder = GetTotalCompletionOrder() CPRINTLN(DEBUG_REPEAT,"URCMCO iMissionID ", iMissionID," iCompletionOrder = ", g_savedGlobals.sRandomChars.savedRC[iMissionID].iCompletionOrder) g_savedGlobals.sRandomChars.iRCMissionsCompleted++ ENDPROC /// PURPOSE: /// Sets the repeat play completion order for this story mission /// PARAMS: /// iMissionID - the stroy mission that has been completed /// eMissionCompletionOrderStat - stat enum for social club /// bOtherFinales - set this to TRUE for the other finales. /// when the player passes one of the 3 finales, the other 2 will get force added to the completion list /// so we don't need all of the functionality in here, as the player hasn't really passed them PROC UpdateStoryMissionCompletionOrder_CLF(INT iMissionID, STATSENUM eMissionCompletionOrderStat, BOOL bOtherFinales = FALSE) IF bOtherFinales = FALSE //disabled for agent T currently // UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATE(iMissionID, FALSE) ENDIF // Update repeat play variables, so we know the playthrough order the player has used g_savedGlobalsClifford.sFlow.missionSavedData[iMissionID].iCompletionOrder = GetTotalCompletionOrder() g_savedGlobalsClifford.sFlowCustom.iMissionsCompleted++ IF bOtherFinales = FALSE // only update the stat is this mission isnt flagged with MF_INDEX_NO_COMP_ORDER IF NOT IS_BIT_SET(g_sMissionStaticData[iMissionID].settingsBitset, MF_INDEX_NO_COMP_ORDER) // Update the missions completion order stat IF eMissionCompletionOrderStat != CITIES_PASSED //CITIES_PASSED used as a default/null value as no enum exists for this purpose. STAT_SET_INT(eMissionCompletionOrderStat, g_savedGlobalsClifford.sFlowCustom.iMissionsCompleted) //Send a presence event to notify friends we have passed this mission (and pass our score). IF NOT g_flowUnsaved.bUpdatingGameflow PRESENCE_EVENT_UPDATESTAT_INT(eMissionCompletionOrderStat, g_savedGlobalsClifford.sFlow.missionSavedData[iMissionID].iScore) ENDIF ENDIF ENDIF ENDIF CPRINTLN(DEBUG_REPEAT,"USMCO CLF iMissionID ", iMissionID, " iCompletionOrder = ", g_savedGlobalsClifford.sFlow.missionSavedData[iMissionID].iCompletionOrder) ENDPROC /// PURPOSE: /// Sets the repeat play completion order for this story mission /// PARAMS: /// iMissionID - the stroy mission that has been completed /// eMissionCompletionOrderStat - stat enum for social club /// bOtherFinales - set this to TRUE for the other finales. /// when the player passes one of the 3 finales, the other 2 will get force added to the completion list /// so we don't need all of the functionality in here, as the player hasn't really passed them PROC UpdateStoryMissionCompletionOrder_NRM(INT iMissionID, STATSENUM eMissionCompletionOrderStat, BOOL bOtherFinales = FALSE) IF bOtherFinales = FALSE //disabled for agent T currently // UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATE(iMissionID, FALSE) ENDIF // Update repeat play variables, so we know the playthrough order the player has used g_savedGlobalsnorman.sFlow.missionSavedData[iMissionID].iCompletionOrder = GetTotalCompletionOrder() g_savedGlobalsnorman.sFlowCustom.iMissionsCompleted++ IF bOtherFinales = FALSE // only update the stat is this mission isnt flagged with MF_INDEX_NO_COMP_ORDER IF NOT IS_BIT_SET(g_sMissionStaticData[iMissionID].settingsBitset, MF_INDEX_NO_COMP_ORDER) // Update the missions completion order stat IF eMissionCompletionOrderStat != CITIES_PASSED //CITIES_PASSED used as a default/null value as no enum exists for this purpose. STAT_SET_INT(eMissionCompletionOrderStat, g_savedGlobalsnorman.sFlowCustom.iMissionsCompleted) //Send a presence event to notify friends we have passed this mission (and pass our score). IF NOT g_flowUnsaved.bUpdatingGameflow PRESENCE_EVENT_UPDATESTAT_INT(eMissionCompletionOrderStat, g_savedGlobalsnorman.sFlow.missionSavedData[iMissionID].iScore) ENDIF ENDIF ENDIF ENDIF CPRINTLN(DEBUG_REPEAT,"USMCO CLF iMissionID ", iMissionID, " iCompletionOrder = ", g_savedGlobalsnorman.sFlow.missionSavedData[iMissionID].iCompletionOrder) ENDPROC /// PURPOSE: /// Sets the repeat play completion order for this story mission /// PARAMS: /// iMissionID - the stroy mission that has been completed /// eMissionCompletionOrderStat - stat enum for social club /// bOtherFinales - set this to TRUE for the other finales. /// when the player passes one of the 3 finales, the other 2 will get force added to the completion list /// so we don't need all of the functionality in here, as the player hasn't really passed them PROC UpdateStoryMissionCompletionOrder(INT iMissionID, STATSENUM eMissionCompletionOrderStat, BOOL bOtherFinales = FALSE) #IF USE_CLF_DLC UpdateStoryMissionCompletionOrder_CLF(iMissionID,eMissionCompletionOrderStat,bOtherFinales) EXIT #ENDIF #IF USE_NRM_DLC UpdateStoryMissionCompletionOrder_NRM(iMissionID,eMissionCompletionOrderStat,bOtherFinales) EXIT #ENDIF IF bOtherFinales = FALSE UPDATE_EYEFIND_CURRENT_NEWS_STORY_STATE(iMissionID, FALSE) ENDIF // Update repeat play variables, so we know the playthrough order the player has used g_savedGlobals.sFlow.missionSavedData[iMissionID].iCompletionOrder = GetTotalCompletionOrder() g_savedGlobals.sFlowCustom.iMissionsCompleted++ IF bOtherFinales = FALSE // only update the stat is this mission isnt flagged with MF_INDEX_NO_COMP_ORDER IF NOT IS_BIT_SET(g_sMissionStaticData[iMissionID].settingsBitset, MF_INDEX_NO_COMP_ORDER) // Update the missions completion order stat IF eMissionCompletionOrderStat != CITIES_PASSED //CITIES_PASSED used as a default/null value as no enum exists for this purpose. STAT_SET_INT(eMissionCompletionOrderStat, g_savedGlobals.sFlowCustom.iMissionsCompleted) //Send a presence event to notify friends we have passed this mission (and pass our score). IF NOT g_flowUnsaved.bUpdatingGameflow PRESENCE_EVENT_UPDATESTAT_INT(eMissionCompletionOrderStat, g_savedGlobals.sFlow.missionSavedData[iMissionID].iScore) ENDIF ENDIF ENDIF ENDIF CPRINTLN(DEBUG_REPEAT,"USMCO iMissionID ", iMissionID, " iCompletionOrder = ", g_savedGlobals.sFlow.missionSavedData[iMissionID].iCompletionOrder) ENDPROC /// PURPOSE: /// Checks if this story / RC mission is repeatable /// PARAMS: /// iMissionID - mission we are checking /// eMissionType - the mission type /// RETURNS: /// TRUE if mission is repeatable, FALSE otherwise FUNC BOOL IsMissionRepeatable(INT iMissionID, enumGrouping eMissionType) SWITCH eMissionType CASE CP_GROUP_MISSIONS RETURN NOT IS_BIT_SET(g_sMissionStaticData[iMissionID].settingsBitset, MF_INDEX_NO_REPEAT) BREAK #IF NOT USE_SP_DLC CASE CP_GROUP_RANDOMCHARS RETURN IS_RC_REPEATABLE(INT_TO_ENUM(g_eRC_MissionIDs, iMissionID)) BREAK #ENDIF DEFAULT CPRINTLN(DEBUG_REPEAT,"HasMissionBeenCompleted passed a mission type that isn't repeat playable: ", eMissionType) BREAK ENDSWITCH RETURN FALSE // invalid ENDFUNC /// PURPOSE: /// Checks if this mission is one of the 3 finales /// PARAMS: /// iMissionID - mission ID of story mission (must be checked 1st) /// RETURNS: /// TRUE if finale mission. FALSE otherwise #IF USE_CLF_DLC FUNC BOOL IS_FINALE_MISSIONCLF(INT iMissionID) SP_MISSIONS eMission = INT_TO_ENUM(SP_MISSIONS, iMissionID) IF eMission = SP_MISSION_CLF_FIN RETURN TRUE ENDIF RETURN FALSE ENDFUNC #ENDIF #IF USE_NRM_DLC FUNC BOOL IS_FINALE_MISSIONNRM(INT iMissionID) SP_MISSIONS eMission = INT_TO_ENUM(SP_MISSIONS, iMissionID) IF eMission = SP_MISSION_NRM_SUR_CURE RETURN TRUE ENDIF RETURN FALSE ENDFUNC #ENDIF FUNC BOOL IS_FINALE_MISSION(INT iMissionID) #IF USE_CLF_DLC return IS_FINALE_MISSIONCLF(iMissionID) #ENDIF #IF USE_NRM_DLC return IS_FINALE_MISSIONNRM(iMissionID) #ENDIF #IF NOT USE_SP_DLC SP_MISSIONS eMission = INT_TO_ENUM(SP_MISSIONS, iMissionID) IF eMission = SP_MISSION_FINALE_A OR eMission = SP_MISSION_FINALE_B OR eMission = SP_MISSION_FINALE_C1 OR eMission = SP_MISSION_FINALE_C2 RETURN TRUE ENDIF RETURN FALSE #ENDIF ENDFUNC /// PURPOSE: /// Returns whether or not the player has completed one of the 3 finales /// RETURNS: /// TRUE if a finale has been completed. FALSE otherwise FUNC BOOL HAVE_ANY_FINALES_BEEN_COMPLETED() #IF USE_CLF_DLC IF g_savedGlobalsClifford.sFlow.missionSavedData[SP_MISSION_CLF_FIN].completed = TRUE RETURN TRUE ENDIF #ENDIF #IF USE_NRM_DLC IF g_savedGlobalsnorman.sFlow.missionSavedData[SP_MISSION_NRM_SUR_CURE].completed = TRUE RETURN TRUE ENDIF #ENDIF #IF NOT USE_SP_DLC IF g_savedGlobals.sFlow.missionSavedData[SP_MISSION_FINALE_A].completed = TRUE OR g_savedGlobals.sFlow.missionSavedData[SP_MISSION_FINALE_B].completed = TRUE OR g_savedGlobals.sFlow.missionSavedData[SP_MISSION_FINALE_C1].completed = TRUE OR g_savedGlobals.sFlow.missionSavedData[SP_MISSION_FINALE_C2].completed = TRUE RETURN TRUE ENDIF #ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Checks if this story / RC mission has been completed /// PARAMS: /// iMissionID - mission we are checking /// eMissionType - the mission type /// RETURNS: /// TRUE if mission complete, FALSE otherwise FUNC BOOL HasMissionBeenCompleted(INT iMissionID, enumGrouping eMissionType) SWITCH eMissionType CASE CP_GROUP_MISSIONS IF IS_FINALE_MISSION(iMissionID) // If 1 finale complete, they're all complete RETURN HAVE_ANY_FINALES_BEEN_COMPLETED() ELSE // normal mission, do normal check #IF USE_CLF_DLC RETURN g_savedGlobalsClifford.sFlow.missionSavedData[iMissionID].completed #ENDIF #IF USE_NRM_DLC RETURN g_savedGlobalsnorman.sFlow.missionSavedData[iMissionID].completed #ENDIF #IF NOT USE_SP_DLC RETURN g_savedGlobals.sFlow.missionSavedData[iMissionID].completed #ENDIF ENDIF BREAK #IF NOT USE_SP_DLC CASE CP_GROUP_RANDOMCHARS RETURN IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[iMissionID].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)) BREAK #ENDIF DEFAULT CPRINTLN(DEBUG_REPEAT,"HasMissionBeenCompleted passed a mission type that isn't repeat playable: ", eMissionType) BREAK ENDSWITCH RETURN FALSE // invalid ENDFUNC /// PURPOSE: /// Checks if the mission hasn't already been completed and adds to repeat play list. /// THIS IS ONLY TO BE CALLED BY ADD_ALL_FINALES_TO_REPEAT_PLAY!!!!! PROC ADD_MISSION_TO_REPEAT_PLAY(SP_MISSIONS eMission) INT iMissionID = ENUM_TO_INT(eMission) IF g_savedGlobals.sFlow.missionSavedData[iMissionID].completed = FALSE CPRINTLN(DEBUG_REPEAT, "Adding finale to list: ", eMission) UpdateStoryMissionCompletionOrder(iMissionID, CITIES_PASSED, TRUE) // CITIES_PASSED is null / default value and isnt used ELSE // mission already completed CPRINTLN(DEBUG_REPEAT, "Finale already completed: ", eMission) ENDIF ENDPROC /// PURPOSE: /// Called once one of the finale missions has been completed. /// Adds all of the finales to the repeat play list PROC ADD_ALL_FINALES_TO_REPEAT_PLAY() #IF NOT USE_SP_DLC ADD_MISSION_TO_REPEAT_PLAY(SP_MISSION_FINALE_A) ADD_MISSION_TO_REPEAT_PLAY(SP_MISSION_FINALE_B) ADD_MISSION_TO_REPEAT_PLAY(SP_MISSION_FINALE_C1) ADD_MISSION_TO_REPEAT_PLAY(SP_MISSION_FINALE_C2) #ENDIF ENDPROC /// PURPOSE: /// Gets the completion order for this story / RC mission /// PARAMS: /// iMissionID - mission we are checking /// eMissionType - the mission type /// RETURNS: /// the completion order of this mission. (The point in the playthrough that mission was completed) FUNC INT GetMissionCompletionOrder(INT iMissionID, enumGrouping eMissionType) SWITCH eMissionType CASE CP_GROUP_MISSIONS #IF USE_CLF_DLC RETURN g_savedGlobalsClifford.sFlow.missionSavedData[iMissionID].iCompletionOrder #ENDIF #IF USE_NRM_DLC RETURN g_savedGlobalsnorman.sFlow.missionSavedData[iMissionID].iCompletionOrder #ENDIF #IF NOT USE_SP_DLC RETURN g_savedGlobals.sFlow.missionSavedData[iMissionID].iCompletionOrder #ENDIF BREAK #IF NOT USE_SP_DLC CASE CP_GROUP_RANDOMCHARS RETURN g_savedGlobals.sRandomChars.savedRC[iMissionID].iCompletionOrder BREAK #ENDIF DEFAULT CPRINTLN(DEBUG_REPEAT,"HasMissionBeenCompleted passed a mission type that isn't repeat playable: ", eMissionType) BREAK ENDSWITCH RETURN -1 // invalid ENDFUNC /// PURPOSE: /// Gets the number of missions of this type /// PARAMS: /// eMissionType - the mission type /// RETURNS: /// Number of missions of this type (SP_MISSION_MAX or MAX_RC_MISSIONS) FUNC INT GetMaxMissionsOfType(enumGrouping eMissionType) SWITCH eMissionType CASE CP_GROUP_MISSIONS RETURN ENUM_TO_INT(SP_MISSION_MAX) BREAK #IF NOT USE_SP_DLC CASE CP_GROUP_RANDOMCHARS RETURN ENUM_TO_INT(MAX_RC_MISSIONS) BREAK #ENDIF DEFAULT CPRINTLN(DEBUG_REPEAT,"HasMissionBeenCompleted passed a mission type that isn't repeat playable: ", eMissionType) BREAK ENDSWITCH RETURN -1 // invalid ENDFUNC // --------------------------HEIST FUNCTIONS ------------------------------------------------------------ /// PURPOSE: /// Returns which heist this mission is a part of /// PARAMS: /// eMission - the mission we are checking /// RETURNS: /// the index of the heist this mission is part of or index of "NO_HEISTS" #IF NOT USE_SP_DLC FUNC INT GET_HEIST_FROM_MISSION_ID(SP_MISSIONS eMission) SWITCH eMission // ------AGENCY------ CASE SP_HEIST_AGENCY_1 CASE SP_HEIST_AGENCY_2 CASE SP_HEIST_AGENCY_PREP_1 CASE SP_HEIST_AGENCY_3A CASE SP_HEIST_AGENCY_3B RETURN HEIST_AGENCY BREAK // ------DOCKS / PORT OF LS------ CASE SP_HEIST_DOCKS_1 CASE SP_HEIST_DOCKS_2A CASE SP_HEIST_DOCKS_2B RETURN HEIST_DOCKS BREAK // ------FINALE / BIG SCORE------ CASE SP_HEIST_FINALE_1 CASE SP_HEIST_FINALE_2_INTRO CASE SP_HEIST_FINALE_PREP_A CASE SP_HEIST_FINALE_PREP_B CASE SP_HEIST_FINALE_PREP_C1 CASE SP_HEIST_FINALE_PREP_C2 CASE SP_HEIST_FINALE_PREP_C3 CASE SP_HEIST_FINALE_PREP_D CASE SP_HEIST_FINALE_2A CASE SP_HEIST_FINALE_2B RETURN HEIST_FINALE BREAK // ------JEWELLRY / JEWEL STORE------ CASE SP_HEIST_JEWELRY_1 CASE SP_HEIST_JEWELRY_PREP_1A CASE SP_HEIST_JEWELRY_PREP_2A CASE SP_HEIST_JEWELRY_PREP_1B CASE SP_HEIST_JEWELRY_2 RETURN HEIST_JEWEL BREAK // ------RURAL / PALETO------ CASE SP_HEIST_RURAL_1 CASE SP_HEIST_RURAL_2 RETURN HEIST_RURAL_BANK BREAK DEFAULT RETURN NO_HEISTS // other missions do not have an associated heist BREAK ENDSWITCH RETURN NO_HEISTS ENDFUNC #ENDIF /// PURPOSE: /// Adds a decor to a vehicle /// PARAMS: /// veh - /// RETURNS: /// FUNC BOOL SET_VEHICLE_IGNORED_BY_QUICK_SAVE(VEHICLE_INDEX veh) IF NOT DECOR_EXIST_ON(veh, "IgnoredByQuickSave") IF DECOR_SET_BOOL(veh, "IgnoredByQuickSave", TRUE) RETURN TRUE ENDIF ELSE RETURN TRUE ENDIF RETURN FALSE ENDFUNC