//Don't include anything but globals/builtin from this header. //Otherwise madness. USING "rage_builtins.sch" USING "globals.sch" /* MISSION_TYPE_STORY MISSION_TYPE_SPMC MISSION_TYPE_STORY_PREP MISSION_TYPE_STORY_FRIENDS MISSION_TYPE_RANDOM_CHAR MISSION_TYPE_RANDOM_EVENT MISSION_TYPE_FRIEND_ACTIVITY MISSION_TYPE_FRIEND_ACTIVITY_WITH_MG MISSION_TYPE_FRIEND_SQUAD MISSION_TYPE_MINIGAME MISSION_TYPE_MINIGAME_FRIENDS MISSION_TYPE_RAMPAGE MISSION_TYPE_SWITCH MISSION_TYPE_EXILE MISSION_TYPE_ANIMAL MISSION_TYPE_DIRECTOR MISSION_TYPE_OFF_MISSION MISSION_TYPE_SWITCH MISSION_TYPE_GRIEFING MISSION_TYPE_CLF_CAR MISSION_TYPE_SHOP_BLIPS_AVAILABILITY ALREADY RUNNING S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC S No No No No Yes No No No No No No Yes No No No No No SP No No No No Yes Yes No Yes No No No Yes No No No No No SF No No No No Yes Yes No Yes No No No Yes No No No No No RC No No No No No No No No No No No Yes No No No No No WANTS RE No No No No No No No No No No No No No No No No No TO TRIG FA No No No No Yes No No No No No No No No No No No No FAMG No No No No No Yes No No No No No No No No No No No FS No No No No Yes No No No No No No No No No No No No MG No No No No Yes No No No No No No No No No No No No MGF No No No No Yes Yes No Yes No No No Yes No No No No No RA No No No No Yes No No No No No No No No No No No No SW No No No No Yes No No No No No No Yes Yes No No No No EX No No No No Yes Yes No Yes No No No No No No No No No AN No No No No Yes No No No No No No No No No No No No DI No No No No Yes No No No No No No No No No No No No PG No No No No Yes Yes No Yes No No No No No No No No No CC No No No No Yes Yes No Yes No No No No No No No No No KEY S Story mission SP Story heist prep mission SF Story mission with friends mode //drops back into friend FA afterwards RC Random Character Mission RE Random Event FA Friend Activity FAMG Friend Activity Minigame FS Friend Squad (battle buddies) MG Minigame MGF Minigame with friends mode //drops back into friend FA afterwards RA Rampage SW Switch EX Exile City Denial AN Playing as an animal (NextGen Specific) DI Director Mode (NextGen Specific) PG Griefing events CC CLF Car (Clifford DLC Specific) */ #IF IS_DEBUG_BUILD FUNC STRING GET_MISSION_TYPE_DEBUG_STRING(MISSION_CANDIDATE_MISSION_TYPE_ENUM paramMissionType) SWITCH paramMissionType CASE MISSION_TYPE_STORY RETURN "STORY" BREAK CASE MISSION_TYPE_STORY_PREP RETURN "STORY_PREP" BREAK CASE MISSION_TYPE_STORY_FRIENDS RETURN "STORY_FRIENDS" BREAK CASE MISSION_TYPE_RANDOM_CHAR RETURN "RANDOM_CHAR" BREAK CASE MISSION_TYPE_RANDOM_EVENT RETURN "RANDOM_EVENT" BREAK CASE MISSION_TYPE_FRIEND_ACTIVITY RETURN "FRIEND_ACTIVITY" BREAK CASE MISSION_TYPE_FRIEND_ACTIVITY_WITH_MG RETURN "FRIEND_ACTIVITY_WITH_MG" BREAK CASE MISSION_TYPE_FRIEND_SQUAD RETURN "FRIEND_SQUAD" BREAK CASE MISSION_TYPE_MINIGAME RETURN "MINIGAME" BREAK CASE MISSION_TYPE_MINIGAME_FRIENDS RETURN "MINIGAME_FRIENDS" BREAK CASE MISSION_TYPE_RAMPAGE RETURN "RAMPAGE" BREAK CASE MISSION_TYPE_OFF_MISSION RETURN "OFF_MISSION" BREAK CASE MISSION_TYPE_SWITCH RETURN "SWITCH" BREAK CASE MISSION_TYPE_EXILE RETURN "EXILE" BREAK CASE MISSION_TYPE_ANIMAL RETURN "ANIMAL" BREAK CASE MISSION_TYPE_DIRECTOR RETURN "DIRECTOR_MODE" BREAK CASE MISSION_TYPE_SPMC RETURN "SP_CREATOR" BREAK CASE MISSION_TYPE_GRIEFING RETURN "GRIEFING" BREAK #IF USE_CLF_DLC CASE MISSION_TYPE_CLF_CAR RETURN "CLF_CAR" BREAK #ENDIF ENDSWITCH SCRIPT_ASSERT("GET_MISSION_TYPE_DEBUG_STRING: MISSION_CANDIDATE_MISSION_TYPE_ENUM does not have a debug string assigned.") RETURN "INVALID" ENDFUNC #ENDIF FUNC BOOL CAN_MISSION_TYPE_START_AGAINST_TYPE(MISSION_CANDIDATE_MISSION_TYPE_ENUM paramTesting, MISSION_CANDIDATE_MISSION_TYPE_ENUM paramCurrentlyOnMission) IF paramCurrentlyOnMission = MISSION_TYPE_OFF_MISSION RETURN TRUE // Anything can try to launch when nothing is running ENDIF IF paramTesting = MISSION_TYPE_OFF_MISSION SCRIPT_ASSERT("CAN_MISSION_TYPE_START_AGAINST_CURRENT_TYPE: MISSION_TYPE_OFF_MISSION is not ever launchable!") RETURN FALSE // Anything can try to launch when nothing is running ENDIF SWITCH paramTesting // This should never be launched // Used to hide shop blips on minigame CASE MISSION_TYPE_SHOP_BLIPS_AVAILABILITY SWITCH paramCurrentlyOnMission CASE MISSION_TYPE_MINIGAME CASE MISSION_TYPE_MINIGAME_FRIENDS CASE MISSION_TYPE_FRIEND_ACTIVITY_WITH_MG CASE MISSION_TYPE_ANIMAL CASE MISSION_TYPE_DIRECTOR RETURN FALSE BREAK ENDSWITCH RETURN TRUE BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // S No No No No Yes No No No No No No Yes No No No No No CASE MISSION_TYPE_STORY SWITCH paramCurrentlyOnMission CASE MISSION_TYPE_RANDOM_EVENT CASE MISSION_TYPE_SWITCH RETURN TRUE BREAK ENDSWITCH BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // SP No No No No Yes Yes No Yes No No No Yes No No No No No // SF No No No No Yes Yes No Yes No No No Yes No No No No No CASE MISSION_TYPE_STORY_PREP CASE MISSION_TYPE_STORY_FRIENDS SWITCH paramCurrentlyOnMission CASE MISSION_TYPE_RANDOM_EVENT CASE MISSION_TYPE_FRIEND_ACTIVITY CASE MISSION_TYPE_FRIEND_SQUAD CASE MISSION_TYPE_SWITCH RETURN TRUE BREAK ENDSWITCH BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // RC No No No No No No No No No No No Yes No No No No No CASE MISSION_TYPE_RANDOM_CHAR IF paramCurrentlyOnMission = MISSION_TYPE_SWITCH RETURN TRUE ENDIF BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // RE No No No No No No No No No No No No No No No No No CASE MISSION_TYPE_RANDOM_EVENT BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // FA No No No No Yes No No No No No No No No No No No No // FS No No No No Yes No No No No No No No No No No No No CASE MISSION_TYPE_FRIEND_ACTIVITY CASE MISSION_TYPE_FRIEND_SQUAD IF paramCurrentlyOnMission = MISSION_TYPE_RANDOM_EVENT RETURN TRUE ENDIF BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN PG AC // FAMG No No No No No Yes No No No No No No No No No No No CASE MISSION_TYPE_FRIEND_ACTIVITY_WITH_MG IF paramCurrentlyOnMission = MISSION_TYPE_FRIEND_ACTIVITY RETURN TRUE ENDIF BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // MG No No No No Yes No No No No No No No No No No No No CASE MISSION_TYPE_MINIGAME IF paramCurrentlyOnMission = MISSION_TYPE_RANDOM_EVENT RETURN TRUE ENDIF BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // MGF No No No No Yes Yes No Yes No No No Yes No No No No No CASE MISSION_TYPE_MINIGAME_FRIENDS SWITCH paramCurrentlyOnMission CASE MISSION_TYPE_RANDOM_EVENT CASE MISSION_TYPE_FRIEND_ACTIVITY CASE MISSION_TYPE_SWITCH RETURN TRUE BREAK ENDSWITCH BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // RA No No No No Yes No No No No No No No No No No No No CASE MISSION_TYPE_RAMPAGE IF paramCurrentlyOnMission = MISSION_TYPE_RANDOM_EVENT RETURN TRUE ENDIF BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // SW No No No No Yes No No No No No No Yes Yes No No No No CASE MISSION_TYPE_SWITCH SWITCH paramCurrentlyOnMission CASE MISSION_TYPE_SWITCH //Switch missions can overlap sometimes. CASE MISSION_TYPE_EXILE //#1435067 CASE MISSION_TYPE_RANDOM_EVENT //#1443316 RETURN TRUE BREAK ENDSWITCH BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // EX No No No No Yes Yes No Yes No No No No No No No No No // PG No No No No Yes Yes No Yes No No No No No No No No No CASE MISSION_TYPE_GRIEFING CASE MISSION_TYPE_EXILE SWITCH paramCurrentlyOnMission CASE MISSION_TYPE_RANDOM_EVENT CASE MISSION_TYPE_FRIEND_ACTIVITY CASE MISSION_TYPE_FRIEND_SQUAD RETURN TRUE BREAK ENDSWITCH BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // AN No No No No Yes No No No No No No No No No No No No CASE MISSION_TYPE_ANIMAL SWITCH paramCurrentlyOnMission CASE MISSION_TYPE_RANDOM_EVENT RETURN TRUE BREAK ENDSWITCH BREAK // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // DI No No No No Yes No No No No No No No No No No No No CASE MISSION_TYPE_DIRECTOR SWITCH paramCurrentlyOnMission CASE MISSION_TYPE_RANDOM_EVENT RETURN TRUE BREAK ENDSWITCH BREAK #IF USE_CLF_DLC // S SP SF RC RE FA FAMG FS MG MGF RA SW EX AN DI PG CC // CC No No No No Yes Yes No Yes No No No No No No No No No CASE MISSION_TYPE_CLF_CAR SWITCH paramCurrentlyOnMission CASE MISSION_TYPE_RANDOM_EVENT CASE MISSION_TYPE_FRIEND_ACTIVITY CASE MISSION_TYPE_FRIEND_SQUAD RETURN TRUE BREAK ENDSWITCH BREAK #ENDIF ENDSWITCH // Otherwise it can't launch RETURN FALSE ENDFUNC FUNC BOOL CAN_MISSION_TYPE_START_AGAINST_CURRENT_TYPE(MISSION_CANDIDATE_MISSION_TYPE_ENUM Type) RETURN CAN_MISSION_TYPE_START_AGAINST_TYPE(Type, g_OnMissionState) ENDFUNC /// PURPOSE: /// Would mission of type X be blocked by any currently running missions? /// PARAMS: /// myType - would this mission type be blocked /// RETURNS: /// TRUE/FALSE FUNC BOOL IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_CANDIDATE_MISSION_TYPE_ENUM myType = MISSION_TYPE_STORY) IF g_OnMissionState = MISSION_TYPE_OFF_MISSION RETURN FALSE ENDIF IF CAN_MISSION_TYPE_START_AGAINST_CURRENT_TYPE(myType) RETURN FALSE ENDIF //Otherwise its on mission to the requesting script RETURN TRUE ENDFUNC /// PURPOSE: /// Is mission of type X currently running? /// PARAMS: /// myType - is this mission type running /// RETURNS: /// TRUE/FALSE FUNC BOOL IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_CANDIDATE_MISSION_TYPE_ENUM myType) RETURN g_OnMissionState = myType ENDFUNC /// PURPOSE: /// Are we in any state other than off mission? FUNC BOOL IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE() IF g_OnMissionState = MISSION_TYPE_OFF_MISSION RETURN FALSE ENDIF RETURN TRUE ENDFUNC /* INT g_iCurrentCandidatesInList = 0 m_structMissionCandidate g_listCandidates[MAX_MISSION_CANDIDATES] MISSION_CANDIDATE_MISSION_TYPE_ENUM g_OnMissionState = MISSION_TYPE_OFF_MISSION m_enumMissionCandidateTypeID type MISSION_CANDIDATE_MISSION_TYPE_ENUM missionType */ PROC BindCandidateTerminationToScript(INT &id, THREADID threadToWatch) //THREADID RegisteredBy IF g_iCurrentCandidatesInList = 0 PRINTLN("BindCandidateTerminationToScriptHash: No candidates") EXIT ENDIF IF id = NO_CANDIDATE_ID PRINTLN("BindCandidateTerminationToScriptHash: Invalid ID") EXIT ENDIF INT i = 0 REPEAT g_iCurrentCandidatesInList i IF g_listCandidates[i].mcid = id g_listCandidates[i].terminationThread = threadToWatch PRINTLN("BindCandidateTerminationToScriptHash: Bound thread to index ", i) ENDIF ENDREPEAT PRINTLN("BindCandidateTerminationToScriptHash: Purged passed ID because not found") id = NO_CANDIDATE_ID ENDPROC FUNC m_enumMissionCandidateReturnValue Request_Mission_Launch( INT &id, m_enumMissionCandidateTypeID type, MISSION_CANDIDATE_MISSION_TYPE_ENUM missionType, BOOL bSkipSwitchCheck = FALSE, THREADID threadToWatch = NULL) #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_TRIGGER, " Script ", GET_THIS_SCRIPT_NAME(), " requesting a mission launch of type ", GET_MISSION_TYPE_DEBUG_STRING(missionType), ".") #ENDIF IF type = MCTID_RETRACTED PRINTLN("Request_Mission_Launch: type set as revoked, request denied.") RETURN MCRET_DENIED ENDIF //Delay any decisions while switching. IF NOT bSkipSwitchCheck //cyclical headers so direct check IF (g_sPlayerPedRequest.eState = PR_STATE_PROCESSING)//IS_PLAYER_PED_SWITCH_IN_PROGRESS() RETURN MCRET_PROCESSING ENDIF ENDIF ///////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// //is it must launch type? If so do exactly the old thing IF type = MCTID_MUST_LAUNCH CPRINTLN(DEBUG_TRIGGER, " Candidate controller is fast-tracking a MUST_LAUNCH mission.") //Instantly give this mission an ID. IF IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) CPRINTLN(DEBUG_TRIGGER, " Must launch mission was rejected as we are already on mission.") RETURN MCRET_DENIED ENDIF g_nextMissionCandidateID++ id = g_nextMissionCandidateID // Return player control now acceptance has been issued, as it was previously taken away during pending // SET_PLAYER_CONTROL(GET_PLAYER_INDEX(),TRUE) SET_PLAYER_INVINCIBLE(GET_PLAYER_INDEX(), FALSE) // Tell the char switch it can listen again g_sSelectorUI.bDisabled = FALSE //direct access because including the header makes for a circular include //Terminate all random events as we go on mission. IF missionType != MISSION_TYPE_RANDOM_EVENT FORCE_CLEANUP(FORCE_CLEANUP_FLAG_RANDOM_EVENTS) ENDIF //Set the mission flag true. g_OnMissionState = missionType// = TRUE g_iCurrentlyRunningCandidateID = id g_CurrentlyRunningCandidateThread = threadToWatch g_iCurrentCandidatesInList = 0 RETURN MCRET_ACCEPTED ENDIF ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// //MCRET_DENIED, //MCRET_ACCEPTED, //MCRET_PROCESSING //is the ID in the list already? IF id != NO_CANDIDATE_ID IF g_iCurrentCandidatesInList > 0 INT i = 0 REPEAT g_iCurrentCandidatesInList i IF g_listCandidates[i].mcid = id //its in the list so its being processed #IF IS_DEBUG_BUILD IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("candidate_controller")) < 1 SCRIPT_ASSERT("Request_Mission_Launch detected candidate_controller is not running, this is a problem. Pass this bug to Default Levels.") ENDIF #ENDIF RETURN MCRET_PROCESSING ENDIF ENDREPEAT ELSE //is it already running? IF g_iCurrentlyRunningCandidateID = id RETURN MCRET_ACCEPTED ENDIF ENDIF //it wasn't in the list, and wasn't running so it was old id = NO_CANDIDATE_ID ENDIF //is the ID a new ID? IF id = NO_CANDIDATE_ID //is it able to even have a chance of launch at this point IF NOT CAN_MISSION_TYPE_START_AGAINST_CURRENT_TYPE(missionType) CPRINTLN(DEBUG_TRIGGER, " Request_Mission_Launch: Would not be able to start with this type, denied.") RETURN MCRET_DENIED ENDIF //is there space to assign it a slot IF g_iCurrentCandidatesInList = MAX_MISSION_CANDIDATES CPRINTLN(DEBUG_TRIGGER, " Mission candidate request slots maxed out.") CPRINTLN(DEBUG_TRIGGER, " No slots left, denied.") RETURN MCRET_DENIED ENDIF //assign it a slot g_nextMissionCandidateID++ id = g_nextMissionCandidateID g_listCandidates[g_iCurrentCandidatesInList].mcid = g_nextMissionCandidateID g_listCandidates[g_iCurrentCandidatesInList].type = type g_listCandidates[g_iCurrentCandidatesInList].missionType = missionType g_listCandidates[g_iCurrentCandidatesInList].terminationThread = NULL ++g_iCurrentCandidatesInList IF threadToWatch != NULL BindCandidateTerminationToScript(id,threadToWatch) ENDIF ENDIF RETURN MCRET_PROCESSING ENDFUNC PROC RetractCandidateRequest(INT &id) IF g_iCurrentCandidatesInList = 0 PRINTLN("RetractCandidateRequest: No candidates to revoke") EXIT ENDIF IF id = NO_CANDIDATE_ID PRINTLN("RetractCandidateRequest: Invalid ID") EXIT ENDIF INT i = 0 REPEAT g_iCurrentCandidatesInList i IF g_listCandidates[i].mcid = id g_listCandidates[i].type = MCTID_RETRACTED PRINTLN("RetractCandidateRequest: Revoked index ", i) ENDIF ENDREPEAT PRINTLN("RetractCandidateRequest: Purged passed ID") id = NO_CANDIDATE_ID ENDPROC /// PURPOSE: /// Informs the system that a mission has finished /// PARAMS: /// id - The ID of the mission to register as over PROC Mission_Over(INT &id) //registers the current mission as over, id required for authentication CPRINTLN(DEBUG_TRIGGER, " Mission over called by script ", GET_THIS_SCRIPT_NAME(), ".") IF id = NO_CANDIDATE_ID CPRINTLN(DEBUG_TRIGGER, " Mission Over called with NO_CANDIDATE_ID as the value.") EXIT ENDIF IF NOT (id = g_iCurrentlyRunningCandidateID) CPRINTLN(DEBUG_TRIGGER, " Attempting to end mission with differing index to the one that was allowed to start, revoking issued ID.") CPRINTLN(DEBUG_TRIGGER, "id = ", id, " we were expecting ", g_iCurrentlyRunningCandidateID) //SCRIPT_ASSERT("Attempting to end mission with differing index to the one that was allowed to start, revoking issued ID") id = NO_CANDIDATE_ID EXIT ENDIF id = NO_CANDIDATE_ID //this ID isn't useful anymore g_iCurrentCandidatesInList = 0 g_CurrentlyRunningCandidateThread = NULL //Note that this is also changed directly in Triggered_Mission_Has_Terminated g_OnMissionState = MISSION_TYPE_OFF_MISSION//IS_CURRENTLY_ON_MISSION_TO_TYPE() = FALSE //Tell stat system mission replay state doesn't matter anymore g_bMissionStatSystemResponseToReplayNeeded = FALSE g_bMissionStatSystemResponseToShitskipNeeded = FALSE ENDPROC PROC Force_Mission_Over() CPRINTLN(DEBUG_TRIGGER, " !!Force_Mission_Over called, forcibly overriding the mission status!!") g_OnMissionState = MISSION_TYPE_OFF_MISSION//IS_CURRENTLY_ON_MISSION_TO_TYPE() = FALSE //Tell stat system mission replay state doesn't matter anymore g_bMissionStatSystemResponseToReplayNeeded = FALSE g_bMissionStatSystemResponseToShitskipNeeded = FALSE ENDPROC FUNC BOOL Should_Network_Queues_Be_Blocked_For_Mission_Type(MISSION_CANDIDATE_MISSION_TYPE_ENUM eMissionType) SWITCH eMissionType CASE MISSION_TYPE_STORY CASE MISSION_TYPE_STORY_PREP CASE MISSION_TYPE_STORY_FRIENDS CASE MISSION_TYPE_RANDOM_CHAR CASE MISSION_TYPE_FRIEND_ACTIVITY_WITH_MG CASE MISSION_TYPE_MINIGAME CASE MISSION_TYPE_MINIGAME_FRIENDS CASE MISSION_TYPE_RAMPAGE CASE MISSION_TYPE_ANIMAL CASE MISSION_TYPE_DIRECTOR CASE MISSION_TYPE_SWITCH CASE MISSION_TYPE_GRIEFING #IF USE_CLF_DLC CASE MISSION_TYPE_CLF_CAR #ENDIF RETURN TRUE BREAK ENDSWITCH RETURN FALSE ENDFUNC