//Compile out Title Update changes to header functions. //Must be before includes. //CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R. USING "rage_builtins.sch" USING "BailBond_common.sch" USING "email_public.sch" USING "Flow_Mission_Data_Public.sch" USING "flow_public_game.sch" USING "ambience_run_checks.sch" USING "flow_help_public.sch" USING "achievement_public.sch" ////////////////////////////////////////////////////////////////////////////////////////// // // // MISSION NAME : Bail Bond launcher // // AUTHOR : Ahron Mason // // DESCRIPTION : Launches bailbond mission scripts and handles their emails // // // ////////////////////////////////////////////////////////////////////////////////////////// CONST_FLOAT DEFAULT_BAIL_BOND_LAUNCH_RANGE 150.0 CONST_INT MISSION_TRIGGER_TIME_DELAY_HOURS_DROPPED_OFF 4 // delay on passing a mission by dropping bail jumper off before the next is offered - 4 hour B*1215234 CONST_INT MISSION_TRIGGER_TIME_DELAY_HOURS_KILLED 8 // delay on passing a mission by killing bail jumper before the next is offered - 8 hour CONST_INT TIME_DELAY_MISSION_REMINDER_EMAIL_IN_DAYS 10 // delay before Maude sends the player a reminder about the bail bond - B*1270376 CONST_INT MISSION_TRIGGER_TIME_DELAY_HOURS_FAILED 8 // delay on failing a mission before the mission is reoffered CONST_INT MISSION_TRIGGER_TIME_DELAY_MINS_CLEANUP 1 // delay on a mission cleaning up with out the player's knowledge, before it can be reoffered CONST_INT LAUNCHER_DELAY_TIME 2000 CONST_INT LAUNCHER_DELAY_TIME_LONG 4000 BAIL_BOND_LAUNCH_DATA sBailBondLaunchData BOOL bBailBondHelpMessageQueued = FALSE // used to prime help message BOOL bBailBondShardAnimOut structPedsForConversation sLauncherDialogue // used to trigger Trevor comment TIMEOFDAY currentTimeOfDay // used to setup the time delays for the mission triggering THREADID tBailBondMissionThread // used to request and start the mission script SCALEFORM_INDEX scaleFormMissionPassed BOOL bTriggeredMissionPassedJingle BOOL bMissionPassedScreen_DeliveredMessage INT iTimerMissionPassedScreenDisplayTime STRING sMissionPassedScreen_BailJumpersName = "" ENUM BAILBOND_LAUNCHER_STATE_ENUM BBL_STATE_SEND_TRIGGER_EMAIL, BBL_STATE_TRIGGER_MISSION, BBL_STATE_MISSION_ACTIVE, BBL_STATE_MISSION_FAILED, BBL_STATE_DELAY_NEXT_MISSION, BBL_STATE_SEND_FINAL_EMAIL, BBL_STATE_FINAL_BAIL_JUMPER_DELIVERED ENDENUM ENUM BAILBOND_LAUNCHER_MISSION_PASSED_SCREEN_STATE_ENUM BBL_MPSS_INACTIVE = 0, BBL_MPSS_REQUEST_SCALEFORM, BBL_MPSS_LOADING_SCALEFORM, BBL_MPSS_DISPLAY_SCALEFORM, BBL_MPSS_CLEANUP_SCALEFORM ENDENUM BAILBOND_LAUNCHER_MISSION_PASSED_SCREEN_STATE_ENUM eMissionPassedScreenState /// PURPOSE: /// get the specific bail bond's mission completed bit flag /// PARAMS: /// eBailBondID - the specific bail bond /// RETURNS: /// INT - the specific bit flag converted from BAILBOND_LAUNCHER_BIT_FLAGS_ENUM FUNC INT GET_BAIL_BOND_MISSION_COMPLETED_BIT_FLAG(BAILBOND_ID eBailBondID) SWITCH eBailBondID CASE BBI_QUARRY RETURN ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_QUARRY) CASE BBI_FARM RETURN ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_FARM) CASE BBI_MOUNTAIN RETURN ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_MOUNTAIN) CASE BBI_HOBO RETURN ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_HOBO) ENDSWITCH SCRIPT_ASSERT("BailBond_Launcher.sc : GET_BAIL_BOND_MISSION_COMPLETED_BIT_FLAG invalid parameter eBailBondID") RETURN ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_QUARRY) ENDFUNC /// PURPOSE: /// get the specific bail bond's mission passed type bit flag /// PARAMS: /// eBailBondID - the specific bail bond /// RETURNS: /// INT - the specific bit flag converted from BAILBOND_LAUNCHER_BIT_FLAGS_ENUM FUNC INT GET_BAIL_BOND_PASSED_TYPE_KILLED_BIT_FLAG(BAILBOND_ID eBailBondID) SWITCH eBailBondID CASE BBI_QUARRY RETURN ENUM_TO_INT(BBL_BIT_FLAG_PASSED_TYPE_KILLED_QUARRY) CASE BBI_FARM RETURN ENUM_TO_INT(BBL_BIT_FLAG_PASSED_TYPE_KILLED_FARM) CASE BBI_MOUNTAIN RETURN ENUM_TO_INT(BBL_BIT_FLAG_PASSED_TYPE_KILLED_MOUNTAIN) CASE BBI_HOBO RETURN ENUM_TO_INT(BBL_BIT_FLAG_PASSED_TYPE_KILLED_HOBO) ENDSWITCH SCRIPT_ASSERT("BailBond_Launcher.sc : GET_BAIL_BOND_PASSED_TYPE_KILLED_BIT_FLAG invalid parameter eBailBondID") RETURN ENUM_TO_INT(BBL_BIT_FLAG_PASSED_TYPE_KILLED_QUARRY) ENDFUNC /// PURPOSE: /// get the specific bail bond script name ready for requesting the script /// PARAMS: /// eBailBondID - the specific bail bond /// RETURNS: /// TEXT_LABEL_23 - the string FUNC TEXT_LABEL_23 GET_BAIL_BOND_SCRIPT_NAME(BAILBOND_ID eBailBondID) TEXT_LABEL_23 tlReturningName SWITCH eBailBondID CASE BBI_QUARRY tlReturningName = "BailBond1" BREAK CASE BBI_FARM tlReturningName = "BailBond2" BREAK CASE BBI_MOUNTAIN tlReturningName = "BailBond3" BREAK CASE BBI_HOBO tlReturningName = "BailBond4" BREAK DEFAULT SCRIPT_ASSERT("BailBond_Launcher.sc : GET_BAIL_BOND_SCRIPT_NAME invalid parameter eBailBondID") BREAK ENDSWITCH RETURN tlReturningName ENDFUNC /// PURPOSE: /// get the bail jumper's name /// PARAMS: /// eBailBondID - the specific bail bond /// RETURNS: /// STRING - jumper's name FUNC STRING GET_BAIL_JUMPERS_NAME(BAILBOND_ID eBailBondID) SWITCH eBailBondID CASE BBI_QUARRY RETURN "BBS_BJ1" // ~w~Ralph Ostrowski~s~ BREAK CASE BBI_FARM RETURN "BBS_BJ2" // ~w~Larry Tupper~s~ BREAK CASE BBI_MOUNTAIN RETURN "BBS_BJ3" // ~w~Glenn Scoville~s~ BREAK CASE BBI_HOBO RETURN "BBS_BJ4" // ~w~Curtis Weaver~s~ BREAK DEFAULT SCRIPT_ASSERT("BailBond_Launcher : GET_BAIL_JUMPERS_NAME() invalid BAILBOND_ID") BREAK ENDSWITCH RETURN "" ENDFUNC /// PURPOSE: /// get the bail bond's launch position, used in the range check and passed into the mission scrip args /// PARAMS: /// eBailBondID - the specific bail bond /// RETURNS: /// Vector - The specific bail bond's launch position FUNC VECTOR GET_BAIL_BOND_LAUNCH_POSITION(BAILBOND_ID eBailBondID) SWITCH eBailBondID CASE BBI_QUARRY RETURN << 2956.3489, 2795.9553, 39.9217 >> CASE BBI_FARM RETURN << 162.5572, 2289.1577, 93.1489 >> CASE BBI_MOUNTAIN RETURN << 515.50, 5494.33, 766.77 >> CASE BBI_HOBO RETURN << 1427.9722, 6351.1392, 22.9853 >> ENDSWITCH SCRIPT_ASSERT("BailBond_Launcher.sc : GET_BAIL_BOND_LAUNCH_POSITION invalid parameter eBailBondID") RETURN << 0.0, 0.0, 0.0 >> ENDFUNC /// PURPOSE: /// Get the specific bail bond's launch range /// range may need to vary based on setup, currently all set to DEFAULT_BAIL_BOND_LAUNCH_RANGE /// PARAMS: /// eBailBondID - the specific bail bond /// RETURNS: /// float for the launch range FUNC FLOAT GET_BAIL_BOND_LAUNCH_RANGE(BAILBOND_ID eBailBondID) SWITCH eBailBondID CASE BBI_QUARRY RETURN DEFAULT_BAIL_BOND_LAUNCH_RANGE CASE BBI_FARM RETURN DEFAULT_BAIL_BOND_LAUNCH_RANGE CASE BBI_MOUNTAIN RETURN DEFAULT_BAIL_BOND_LAUNCH_RANGE CASE BBI_HOBO RETURN DEFAULT_BAIL_BOND_LAUNCH_RANGE ENDSWITCH SCRIPT_ASSERT("BailBond_Launcher.sc : GET_BAIL_BOND_LAUNCH_RANGE invalid parameter eBailBondID") RETURN DEFAULT_BAIL_BOND_LAUNCH_RANGE ENDFUNC /// PURPOSE: /// get the BAILBOND_ID of the current active mission /// RETURNS: /// the mission's BAILBOND_ID FUNC BAILBOND_ID GET_CURRENT_ACTIVE_BAIL_BOND_ID() INT i // cycle the mission order to find the current bailbond ID FOR i = 0 TO (ENUM_TO_INT(MAX_BAILBOND_IDS) - 1) IF NOT IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, i) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : GET_CURRENT_ACTIVE_BAIL_BOND_ID mission set from 1st set chain, BAILBOND_ID = ", i) RETURN i ENDIF ENDFOR CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : GET_CURRENT_ACTIVE_BAIL_BOND_ID all missions registed as completed.") RETURN MAX_BAILBOND_IDS ENDFUNC /// PURPOSE: /// uses candidate ID system to try to get permission to run /// PARAMS: /// iMissionCandidateID - the missions candidate ID /// RETURNS: /// TRUE if the bail bond mission has permission to run, FALSE otherwise FUNC BOOL REQUEST_PERMISSION_TO_RUN_BAIL_BOND_MISSION(INT &iMissionCandidateID) m_enumMissionCandidateReturnValue eLaunchRequest = Request_Mission_Launch(iMissionCandidateID, MCTID_MUST_LAUNCH, MISSION_TYPE_RANDOM_CHAR) #IF IS_DEBUG_BUILD IF (eLaunchRequest = MCRET_DENIED) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : REQUEST_PERMISSION_TO_RUN_BAIL_BOND_MISSION: ", "MCRET_DENIED: frame = ", GET_FRAME_COUNT()) ENDIF IF (eLaunchRequest = MCRET_PROCESSING) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : REQUEST_PERMISSION_TO_RUN_BAIL_BOND_MISSION: ", "MCRET_PROCESSING: frame = ", GET_FRAME_COUNT()) ENDIF IF (eLaunchRequest = MCRET_ACCEPTED) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : REQUEST_PERMISSION_TO_RUN_BAIL_BOND_MISSION: ", "MCRET_ACCEPTED: iMissionCandidateID = ", iMissionCandidateID, " frame = ", GET_FRAME_COUNT()) ENDIF #ENDIF IF eLaunchRequest = MCRET_ACCEPTED RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// requests and starts the new script for the specific bail bond mission /// PARAMS: /// eBailBondID - the specific bailbond PROC START_NEW_BAIL_BOND_MISSION_SCRIPT(BAILBOND_ID eBailBondID) TEXT_LABEL_23 tl23_MissionScriptName = GET_BAIL_BOND_SCRIPT_NAME(eBailBondID) REQUEST_SCRIPT(tl23_MissionScriptName) WHILE NOT HAS_SCRIPT_LOADED(tl23_MissionScriptName) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : START_NEW_BAIL_BOND_MISSION_SCRIPT : loading requested mission script : ", tl23_MissionScriptName, " ...") REQUEST_SCRIPT(tl23_MissionScriptName) WAIT(0) ENDWHILE //Request_Mission_Launch() tBailBondMissionThread = START_NEW_SCRIPT_WITH_ARGS(tl23_MissionScriptName, sBailBondLaunchData, SIZE_OF(sBailBondLaunchData), MISSION_STACK_SIZE) SET_SCRIPT_AS_NO_LONGER_NEEDED(tl23_MissionScriptName) ENDPROC /// PURPOSE: /// request and starts new script for post bail bond handing of Maude's cleanup PROC START_NEW_MAUDE_POST_BAILBOND_SCRIPT() TEXT_LABEL_23 tl23_MaudePostBailBond_ScriptName = "Maude_PostBailBond" TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME(tl23_MaudePostBailBond_ScriptName) REQUEST_SCRIPT(tl23_MaudePostBailBond_ScriptName) WHILE NOT HAS_SCRIPT_LOADED(tl23_MaudePostBailBond_ScriptName) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : START_NEW_MAUDE_POST_BAILBOND_SCRIPT : loading requested mission script : ", tl23_MaudePostBailBond_ScriptName, " ...") REQUEST_SCRIPT(tl23_MaudePostBailBond_ScriptName) WAIT(0) ENDWHILE START_NEW_SCRIPT(tl23_MaudePostBailBond_ScriptName, DEFAULT_STACK_SIZE) // B*1466024 - needed upping from MINI_STACK_SIZE as dialogue was pushing it over the limit SET_SCRIPT_AS_NO_LONGER_NEEDED(tl23_MaudePostBailBond_ScriptName) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : START_NEW_MAUDE_POST_BAILBOND_SCRIPT : new script thread started : ", tl23_MaudePostBailBond_ScriptName, " ...") ENDPROC /// PURPOSE: /// updates values to reset state PROC RESET_MISSION_PASSED_SPLASH_SCREEN() eMissionPassedScreenState = BBL_MPSS_INACTIVE bTriggeredMissionPassedJingle = FALSE bMissionPassedScreen_DeliveredMessage = FALSE iTimerMissionPassedScreenDisplayTime = 0 ENDPROC /// PURPOSE: /// set the mission passed screen to display /// PARAMS: /// bDeliveredMessage - TRUE if bail jumper was taken to Maude, FALSE if he was killed PROC SET_MISSION_PASSED_SCREEN_TO_DISPLAY(BOOL bDeliveredMessage) eMissionPassedScreenState = BBL_MPSS_REQUEST_SCALEFORM bMissionPassedScreen_DeliveredMessage = bDeliveredMessage ENDPROC /// PURPOSE: /// checks to make sure it's safe to display the mission passed splash screen /// RETURNS: /// TRUE if safe to display FUNC BOOL IS_SAFE_TO_DISPLAY_MISSION_PASSED_SCREEN() IF NOT IS_PLAYER_PLAYING(PLAYER_ID()) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : IS_SAFE_TO_DISPLAY_MISSION_PASSED_SCREEN : return FALSE - IS_PLAYER_PLAYING") RETURN FALSE ENDIF IF IS_PED_INJURED(PLAYER_PED_ID()) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : IS_SAFE_TO_DISPLAY_MISSION_PASSED_SCREEN : return FALSE - IS_PED_INJURED") RETURN FALSE ENDIF IF IS_PLAYER_BEING_ARRESTED(PLAYER_ID()) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : IS_SAFE_TO_DISPLAY_MISSION_PASSED_SCREEN : return FALSE - IS_PLAYER_BEING_ARRESTED") RETURN FALSE ENDIF IF (GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_TREVOR) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : IS_SAFE_TO_DISPLAY_MISSION_PASSED_SCREEN : return FALSE - GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_TREVOR") RETURN FALSE ENDIF IF IS_CUTSCENE_PLAYING() CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : IS_SAFE_TO_DISPLAY_MISSION_PASSED_SCREEN : return FALSE - IS_CUTSCENE_PLAYING") RETURN FALSE ENDIF RETURN TRUE ENDFUNC /// PURPOSE: /// Handles displaying the mission passed message /// RETURNS: PROC DISPLAY_MISSION_PASSED_SPLASH_SCREEN() // state only gets set when a mission is passed IF eMissionPassedScreenState != BBL_MPSS_INACTIVE // cleanup splash screen state if it's not safe to display it IF NOT IS_SAFE_TO_DISPLAY_MISSION_PASSED_SCREEN() eMissionPassedScreenState = BBL_MPSS_CLEANUP_SCALEFORM CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : DISPLAY_MISSION_PASSED_SPLASH_SCREEN : force cleanup for IS_SAFE_TO_DISPLAY_MISSION_PASSED_SCREEN return FALSE") ENDIF SWITCH eMissionPassedScreenState CASE BBL_MPSS_REQUEST_SCALEFORM scaleFormMissionPassed = REQUEST_SCALEFORM_MOVIE("MIDSIZED_MESSAGE") eMissionPassedScreenState = BBL_MPSS_LOADING_SCALEFORM CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : HAS_MISSION_PASSED_SPLASH_SCREEN_BEEN_DISPLAYED : BBL_MPSS_REQUEST_SCALEFORM > BBL_MPSS_LOADING_SCALEFORM") BREAK CASE BBL_MPSS_LOADING_SCALEFORM // set the message to be displayed STRING sPassedMessage IF bMissionPassedScreen_DeliveredMessage sPassedMessage = "BBS_MPD" // ~w~BAIL JUMPER DELIVERED~s~ ELSE sPassedMessage = "BBS_MPK" // ~w~BAIL JUMPER KILLED~s~ ENDIF IF HAS_SCALEFORM_MOVIE_LOADED(scaleFormMissionPassed) BEGIN_SCALEFORM_MOVIE_METHOD(scaleFormMissionPassed, "SHOW_SHARD_MIDSIZED_MESSAGE") BEGIN_TEXT_COMMAND_SCALEFORM_STRING("BBS_MP") // PASSED END_TEXT_COMMAND_SCALEFORM_STRING() BEGIN_TEXT_COMMAND_SCALEFORM_STRING(sPassedMessage) // Bail Jumper Delivered: / Bail Jumper Killed: ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL(sMissionPassedScreen_BailJumpersName) // END_TEXT_COMMAND_SCALEFORM_STRING() END_SCALEFORM_MOVIE_METHOD() iTimerMissionPassedScreenDisplayTime = GET_GAME_TIMER() eMissionPassedScreenState = BBL_MPSS_DISPLAY_SCALEFORM CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : HAS_MISSION_PASSED_SPLASH_SCREEN_BEEN_DISPLAYED : BBL_MPSS_LOADING_SCALEFORM > BBL_MPSS_DISPLAY_SCALEFORM") ENDIF BREAK CASE BBL_MPSS_DISPLAY_SCALEFORM IF HAS_SCALEFORM_MOVIE_LOADED(scaleFormMissionPassed) DRAW_SCALEFORM_MOVIE_FULLSCREEN(scaleFormMissionPassed, 255, 255, 255, 255) SET_SCRIPT_GFX_DRAW_ORDER(GFX_ORDER_AFTER_HUD) // trigger mission passed jingle IF NOT bTriggeredMissionPassedJingle PLAY_SOUND_FRONTEND(-1, "CHECKPOINT_UNDER_THE_BRIDGE", "HUD_MINI_GAME_SOUNDSET", FALSE) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : HAS_MISSION_PASSED_SPLASH_SCREEN_BEEN_DISPLAYED : BBL_MPSS_DISPLAY_SCALEFORM jingle triggered") bTriggeredMissionPassedJingle = TRUE ENDIF ENDIF IF (GET_GAME_TIMER() - iTimerMissionPassedScreenDisplayTime) > DEFAULT_GOD_TEXT_TIME - 500 IF NOT bBailBondShardAnimOut // animating the shard out BEGIN_SCALEFORM_MOVIE_METHOD(scaleFormMissionPassed, "SHARD_ANIM_OUT") // color of the flash SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(HUD_COLOUR_WHITE)) // length of time of the animation SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(0.33) END_SCALEFORM_MOVIE_METHOD() CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : HAS_MISSION_PASSED_SPLASH_SCREEN_BEEN_DISPLAYED : BBL_MPSS_DISPLAY_SCALEFORM -> SHARD_ANIMOUT") bBailBondShardAnimOut = TRUE ENDIF ENDIF // check how long the message has been displayed for IF (GET_GAME_TIMER() - iTimerMissionPassedScreenDisplayTime) > DEFAULT_GOD_TEXT_TIME eMissionPassedScreenState = BBL_MPSS_CLEANUP_SCALEFORM CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : HAS_MISSION_PASSED_SPLASH_SCREEN_BEEN_DISPLAYED : BBL_MPSS_DISPLAY_SCALEFORM -> BBL_MPSS_CLEANUP_SCALEFORM") ENDIF BREAK CASE BBL_MPSS_CLEANUP_SCALEFORM SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(scaleFormMissionPassed) bBailBondShardAnimOut = FALSE RESET_MISSION_PASSED_SPLASH_SCREEN() BREAK ENDSWITCH ENDIF ENDPROC /// PURPOSE: /// intialise the launcher data for the specific bail bond mission we are trying to launch PROC INIT_LAUNCHER_DATA_FOR_CURRENT_BAIL_BOND() tBailBondMissionThread = NULL sBailBondLaunchData.eBailBondID = INT_TO_ENUM(BAILBOND_ID, g_savedGlobals.sBailBondData.iCurrentMission) sBailBondLaunchData.vStartPoint = GET_BAIL_BOND_LAUNCH_POSITION(sBailBondLaunchData.eBailBondID) sBailBondLaunchData.fStartRange = GET_BAIL_BOND_LAUNCH_RANGE(sBailBondLaunchData.eBailBondID) sBailBondLaunchData.iMissionCandidateID = -1 // Set if Trevor killed the previous bail jumper INT iPreviousMission = g_savedGlobals.sBailBondData.iCurrentMission iPreviousMission-- IF iPreviousMission >= 0 AND IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, GET_BAIL_BOND_PASSED_TYPE_KILLED_BIT_FLAG(INT_TO_ENUM(BAILBOND_ID, iPreviousMission))) sBailBondLaunchData.bTrevorKilledPreviousBailJumper = TRUE CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : INIT_LAUNCHER_DATA_FOR_CURRENT_BAIL_BOND() set killed previous bail jumper. iPreviousMission was : ", iPreviousMission) ELSE sBailBondLaunchData.bTrevorKilledPreviousBailJumper = FALSE CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : INIT_LAUNCHER_DATA_FOR_CURRENT_BAIL_BOND() set NOT killed previous bail jumper. iPreviousMission was : ", iPreviousMission) ENDIF sBailBondLaunchData.bDoneTrevorReadsEmailDialogue = HAS_DYNAMIC_EMAIL_BEEN_READ_BY_PRIMARY_TARGET(DYNAMIC_THREAD_BAIL_BONDS, GET_CURRENT_EMAIL(sBailBondLaunchData.eBailBondID)) // if the email has already been done then don't play the dialogue CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : INIT_LAUNCHER_DATA_FOR_CURRENT_BAIL_BOND() setup for mission : ", g_savedGlobals.sBailBondData.iCurrentMission) ENDPROC /// PURPOSE: /// intialise the launcher PROC INIT_BAIL_BOND_LAUNCHER() // first time in the launcher we need to setup a delay in the initial email from Maude being sent IF g_savedGlobals.sBailBondData.iCurrentMission = 0 IF g_savedGlobals.sBailBondData.iLauncherState = -1 // initialised state // launch the post mission Maude script for completion of RC - Maude 1 //START_NEW_MAUDE_POST_BAILBOND_SCRIPT()// - now handled by Maude 1 leave area stage // ensure all the bit flags are set to their default values // mission completed flags CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_QUARRY)) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_FARM)) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_MOUNTAIN)) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_HOBO)) // mission passed flags CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_PASSED_TYPE_KILLED_QUARRY)) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_PASSED_TYPE_KILLED_FARM)) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_PASSED_TYPE_KILLED_MOUNTAIN)) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_PASSED_TYPE_KILLED_HOBO)) // common launcher flags CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_SENT_MISSION_REMINDER_EMAIL)) // setup the time delay before the next bail bond triggers currentTimeOfDay = GET_CURRENT_TIMEOFDAY() ADD_TIME_TO_TIMEOFDAY(currentTimeOfDay, 0, 0, 1, 0, 0, 0) // B*1215223 - only one hour delay for the first email g_savedGlobals.sBailBondData.timeMissionStamp = currentTimeOfDay // set the inital launcher state to delaying mission g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_DELAY_NEXT_MISSION) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : first time launched. setup delay initial mission email") ENDIF ENDIF // we don't want to return to mission active state if the launcher was terminated, so revert back to trigger mission state IF g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_MISSION_ACTIVE) g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_TRIGGER_MISSION) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : revert mission active launcher state to trigger mission") ENDIF // if the launcher has been re launched in the trigger mission state - clear the bit for having to initial leave the mission area IF g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_TRIGGER_MISSION) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : cleared bit set BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK for launcher restarting in BBL_STATE_TRIGGER_MISSION state") ENDIF // make sure the mission passed splash screen is reset RESET_MISSION_PASSED_SPLASH_SCREEN() // set the launcher data based off the current mission INIT_LAUNCHER_DATA_FOR_CURRENT_BAIL_BOND() // ensure Maude has been added to Trevor's phonebook, in flow this will happen on completion of Maude 1 ADD_CONTACT_TO_PHONEBOOK(CHAR_MAUDE, TREVOR_BOOK, FALSE) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : INIT_BAIL_BOND_LAUNCHER done") ENDPROC /// PURPOSE: /// check the global save data to see if all the bail bond mission has been completed /// RETURNS: /// TRUE if all have been completed FUNC BOOL HAVE_ALL_BAIL_BOND_MISSION_BEEN_COMPLETED() INT i FOR i = 0 TO (ENUM_TO_INT(MAX_BAILBOND_IDS) - 1) IF NOT IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, i) RETURN FALSE ENDIF ENDFOR CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : HAVE_ALL_BAIL_BOND_MISSION_BEEN_COMPLETED - return TRUE - all missions registered as completed") RETURN TRUE ENDFUNC /// PURPOSE: /// set the order for the bail bond missions to play out /// there is an initial chain which play out in a set order /// the remaining missions play in a random picked order FUNC INT GET_NEXT_BAIL_BOND_MISSION() INT i //Set Mission Order - if the player hasn't completed the next mission in the chain yet return the value FOR i = 0 TO (ENUM_TO_INT(MAX_BAILBOND_IDS) - 1) IF NOT IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, i) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : GET_NEXT_BAIL_BOND_MISSION - Mission from set order. returning : ", i) RETURN i ENDIF ENDFOR SCRIPT_ASSERT("BailBond_Launcher.sc : GET_NEXT_BAIL_BOND_MISSION invalid next mission") RETURN -1 ENDFUNC /// PURPOSE: /// handles displaying the help text for the first time a bail bond email has been read PROC HANDLE_ONE_TIME_BAIL_BOND_HELP_MESSAGE(BAILBOND_ID eBailBondID) // B*1353646 - only allow this message prior to first mission being completed IF g_savedGlobals.sBailBondData.iCurrentMission = 0 IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_BAILBOND_HELP_FIRST_MESSAGE) IF NOT bBailBondHelpMessageQueued IF HAS_DYNAMIC_EMAIL_BEEN_READ_BY_PRIMARY_TARGET(DYNAMIC_THREAD_BAIL_BONDS, GET_CURRENT_EMAIL(eBailBondID)) ADD_HELP_TO_FLOW_QUEUE("AM_H_BAILBONDS", FHP_MEDIUM, 0, FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_TREVOR) // Trevor can do a bail bond job by visiting a suspect's last known location. A larger reward is given if a suspect is captured alive. bBailBondHelpMessageQueued = TRUE CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : ome time help message queued") ENDIF ELSE SWITCH GET_FLOW_HELP_MESSAGE_STATUS("AM_H_BAILBONDS") CASE FHS_EXPIRED bBailBondHelpMessageQueued = FALSE CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : ome time help message expired before displaying") BREAK CASE FHS_DISPLAYED SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_BAILBOND_HELP_FIRST_MESSAGE) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : ome time help message displayed") BREAK ENDSWITCH ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// get the current reminder email message enum for the specific bail bond /// PARAMS: /// eBailBondID - the specific bailbond /// RETURNS: /// EMAIL_MESSAGE_ENUMS - for the specfic bail bond FUNC EMAIL_MESSAGE_ENUMS GET_CURRENT_REMINDER_EMAIL(BAILBOND_ID eBailBondID) SWITCH eBailBondID CASE BBI_QUARRY RETURN EMAIL_BAIL_BONS_REMINDER_1 CASE BBI_FARM RETURN EMAIL_BAIL_BONS_REMINDER_2 CASE BBI_MOUNTAIN RETURN EMAIL_BAIL_BONS_REMINDER_3 CASE BBI_HOBO RETURN EMAIL_BAIL_BONS_REMINDER_4 ENDSWITCH SCRIPT_ASSERT("BailBond_Launcher.sc : GET_CURRENT_REMINDER_EMAIL invalid parameter eBailBondID") RETURN EMAIL_BAIL_BONS_REMINDER_1 ENDFUNC /// PURPOSE: /// get the current email message enum for the specific bail bond /// PARAMS: /// eBailBondID - the specific bailbond /// RETURNS: /// EMAIL_MESSAGE_ENUMS - for the specfic bail bond FUNC STRING GET_CURRENT_EMAIL_INTRO_STRING(BAILBOND_ID eBailBondID, BOOL bSentPreivousBailJumperKilledEmail) SWITCH eBailBondID CASE BBI_QUARRY IF bSentPreivousBailJumperKilledEmail RETURN "BBONDS_DMAIL_K1" ELSE RETURN "BBONDS_DMAIL_N1" ENDIF BREAK CASE BBI_FARM IF bSentPreivousBailJumperKilledEmail RETURN "BBONDS_DMAIL_K2" ELSE RETURN "BBONDS_DMAIL_N2" ENDIF BREAK CASE BBI_MOUNTAIN IF bSentPreivousBailJumperKilledEmail RETURN "BBONDS_DMAIL_K3" ELSE RETURN "BBONDS_DMAIL_N3" ENDIF BREAK CASE BBI_HOBO IF bSentPreivousBailJumperKilledEmail RETURN "BBONDS_DMAIL_K4" ELSE RETURN "BBONDS_DMAIL_N4" ENDIF BREAK ENDSWITCH SCRIPT_ASSERT("BailBond_Launcher.sc : GET_CURRENT_EMAIL_INTRO_STRING invalid parameter eBailBondID") RETURN "NULL" ENDFUNC /// PURPOSE: /// get the current email message enum for the specific bail bond /// PARAMS: /// eBailBondID - the specific bailbond /// RETURNS: /// EMAIL_MESSAGE_ENUMS - for the specfic bail bond FUNC STRING GET_CURRENT_EMAIL_BULK_STRING(BAILBOND_ID eBailBondID) SWITCH eBailBondID CASE BBI_QUARRY RETURN "BBONDS_DMAIL_C1" CASE BBI_FARM RETURN "BBONDS_DMAIL_C2" CASE BBI_MOUNTAIN RETURN "BBONDS_DMAIL_C3" CASE BBI_HOBO RETURN "BBONDS_DMAIL_C4" ENDSWITCH SCRIPT_ASSERT("BailBond_Launcher.sc : GET_CURRENT_EMAIL_BULK_STRING invalid parameter eBailBondID") RETURN "NULL" ENDFUNC /// PURPOSE: /// sends the relevant email in the bail bond thread for the current bail bond /// RETURNS: /// TRUE if FIRE_EMAIL_INTO_DYNAMIC_THREAD returns TRUE FUNC BOOL SENT_BAIL_BOND_EMAIL(BAILBOND_ID eBailBondID, BOOL bSentAlternativeEmail) EMAIL_MESSAGE_ENUMS eEmailMessage = GET_CURRENT_EMAIL(eBailBondID) STRING sEmailIntro = GET_CURRENT_EMAIL_INTRO_STRING(eBailBondID, bSentAlternativeEmail) STRING sEmailBulk = GET_CURRENT_EMAIL_BULK_STRING(eBailBondID) IF FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_BAIL_BONDS, eEmailMessage, TRUE)//bool added to denote that you're about to override the content OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(DYNAMIC_THREAD_BAIL_BONDS, sEmailIntro, FALSE) ADD_CONTENT_FOR_DYNAMIC_THREAD_SUBSTRING(DYNAMIC_THREAD_BAIL_BONDS, sEmailBulk) PUSH_FEEDIFICATION_OF_DYNAMIC_THREAD(DYNAMIC_THREAD_BAIL_BONDS) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SENT_BAIL_BOND_EMAIL return TRUE : eEmailMessage = ", eEmailMessage, " : sEmailIntro = ", sEmailIntro, " : sEmailBulk = ", sEmailBulk) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// sends the final email in the bail bond thread for the current bail bond /// RETURNS: /// TRUE if FIRE_EMAIL_INTO_DYNAMIC_THREAD returns TRUE FUNC BOOL SENT_FINAL_BAIL_BOND_EMAIL() EMAIL_MESSAGE_ENUMS eEmailMessage = EMAIL_BAIL_BONDS_FINAL STRING sEmailIntro = "BBONDS_DMAIL_K5" STRING sEmailBulk = "BBONDS_DMAIL_C5" IF FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_BAIL_BONDS, eEmailMessage, TRUE)//bool added to denote that you're about to override the content OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(DYNAMIC_THREAD_BAIL_BONDS, sEmailIntro, FALSE) ADD_CONTENT_FOR_DYNAMIC_THREAD_SUBSTRING(DYNAMIC_THREAD_BAIL_BONDS, sEmailBulk) PUSH_FEEDIFICATION_OF_DYNAMIC_THREAD(DYNAMIC_THREAD_BAIL_BONDS) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SENT_FINAL_BAIL_BOND_EMAIL return TRUE : eEmailMessage = ", eEmailMessage, " : sEmailIntro = ", sEmailIntro, " : sEmailBulk = ", sEmailBulk) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Check if the player has left Maude's place so she can send the mission trigger email /// Maude's position taken from x:\gta5\script\dev\singleplayer\scripts\RandomChar\Maude\initial_scenes_Maude.sch /// RETURNS: /// TRUE if player is safe distance away from Maude FUNC BOOL IS_PLAYER_SAFE_DISTANCE_FROM_MAUDE_TO_TRIGGER_EMAIL() IF IS_PLAYER_DEAD(GET_PLAYER_INDEX()) RETURN FALSE ENDIF VECTOR vPlayerPos = GET_PLAYER_COORDS(GET_PLAYER_INDEX()) IF (VDIST2(vPlayerPos, <<2727.58, 4144.19, 43.95>>) >= (50.0 * 50.0)) // 50 metres away RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// triggers the reminder email from Maude if the player hasn't launched the mission within set period of time /// PARAMS: /// eBailBondID - the current bail bond misison PROC HANDLE_MISSION_REMINDER_EMAIL(BAILBOND_ID eBailBondID) IF NOT IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_SENT_MISSION_REMINDER_EMAIL)) IF IS_NOW_AFTER_TIMEOFDAY(g_savedGlobals.sBailBondData.timeMissionStamp) IF IS_PLAYER_SAFE_DISTANCE_FROM_MAUDE_TO_TRIGGER_EMAIL() IF PRIVATE_Is_Safe_To_Start_Communication(BIT_TREVOR, CHAR_MAUDE, CPR_MEDIUM) // send reminder email EMAIL_MESSAGE_ENUMS eEmailMessage = GET_CURRENT_REMINDER_EMAIL(eBailBondID) IF FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_BAIL_BONDS, eEmailMessage, FALSE) SET_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_SENT_MISSION_REMINDER_EMAIL)) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : HANDLE_MISSION_REMINDER_EMAIL : reminder sent eEmailMessage = ", eEmailMessage) ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Check if the player is within the mission trigger range /// RETURNS: /// FALSE if we shouldn't proceed, TRUE if the player is in range FUNC BOOL IS_PLAYER_IN_BAIL_BOND_RANGE() IF IS_ENTITY_DEAD(PLAYER_PED_ID()) RETURN FALSE ENDIF // **** DEBUG only force the function to return TRUE to ensure the email is sent through if mission has been debug launched #IF IS_DEBUG_BUILD IF INT_TO_ENUM(BAILBOND_LAUNCHER_STATE_ENUM, g_savedGlobals.sBailBondData.iLauncherState) = BBL_STATE_SEND_TRIGGER_EMAIL // this flag gets automatically set by the debug launch menu IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) RETURN FALSE ENDIF ENDIF #ENDIF VECTOR vPlayerPos = GET_PLAYER_COORDS(GET_PLAYER_INDEX()) FLOAT fRange = sBailBondLaunchData.fStartRange // B*1434425 - increase range for player approach in chopper / plane IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF IS_PED_IN_ANY_HELI(PLAYER_PED_ID()) OR IS_PED_IN_ANY_PLANE(PLAYER_PED_ID()) IF IS_ENTITY_IN_AIR(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())) fRange += 50.0 IF fRange > 200.0 fRange = 200.0 // cap the range to max 200.0 ENDIF ENDIF ENDIF ENDIF IF (VDIST2(vPlayerPos, sBailBondLaunchData.vStartPoint) <= (fRange * fRange)) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Does any necessary cleanup and terminates the launcher's thread. PROC Script_Cleanup() // Clear bail bond help text IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("AM_H_BAILBONDS") CLEAR_HELP() ENDIF REMOVE_PED_FOR_DIALOGUE(sLauncherDialogue, 2) // remove Trevor from the dialogue - added with HANDLE_TREVOR_DIALOGUE_FOR_READING_TRIGGER_EMAIL SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(scaleFormMissionPassed) IF sBailBondLaunchData.iMissionCandidateID != NO_CANDIDATE_ID CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : Script_Cleanup() : MISSION_OVER(iMissionCandidateID) : iMissionCandidateID = ", sBailBondLaunchData.iMissionCandidateID, " frame = ", GET_FRAME_COUNT()) MISSION_OVER(sBailBondLaunchData.iMissionCandidateID) ENDIF CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : Terminate thread - Script Cleanup") TERMINATE_THIS_THREAD() ENDPROC /// PURPOSE: /// deals with the results of the bail bond mission /// PARAMS: /// eBailBondMissionOverState - info on how the bail bond ended PROC HANDLE_BAIL_BOND_MISSION_OVER_STATE(BAIL_BOND_MISSION_OVER_STATE eMissionOverState) INT iTimeDelay // What state did the mission end in? SWITCH eMissionOverState CASE BBMOS_PASSED_KILLED FALLTHRU CASE BBMOS_PASSED_DELIVERED // set the global save data SET_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, GET_BAIL_BOND_MISSION_COMPLETED_BIT_FLAG(sBailBondLaunchData.eBailBondID)) // set the mission passed type and reward IF eMissionOverState = BBMOS_PASSED_KILLED // set the mission passed screen to display - FALSE for delivered SET_MISSION_PASSED_SCREEN_TO_DISPLAY(FALSE) iTimeDelay = MISSION_TRIGGER_TIME_DELAY_HOURS_KILLED SET_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, GET_BAIL_BOND_PASSED_TYPE_KILLED_BIT_FLAG(sBailBondLaunchData.eBailBondID)) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_MISSION_ACTIVE - ", "Pass type set to killed") ELSE // set the mission passed screen to display - TRUE for delivered SET_MISSION_PASSED_SCREEN_TO_DISPLAY(TRUE) iTimeDelay = MISSION_TRIGGER_TIME_DELAY_HOURS_DROPPED_OFF CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, GET_BAIL_BOND_PASSED_TYPE_KILLED_BIT_FLAG(sBailBondLaunchData.eBailBondID)) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_MISSION_ACTIVE - ", "Pass type set to normal") // credit Trevors bank account straight away if he gave the bail jumper to Maude otherwise delay until next email CREDIT_BANK_ACCOUNT(CHAR_TREVOR, BAAC_BAIL_BONDS, 10000) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_MISSION_ACTIVE -> ", "Trevor account credited for normal mission passed") // [AG]: Achievement Unlocked - Wanted: Alive or Alive IF g_bShitskipAccepted = FALSE AWARD_ACHIEVEMENT(ACH27) // Wanted: Alive or Alive ENDIF ENDIF //set the mission passed screen to display eMissionPassedScreenState = BBL_MPSS_REQUEST_SCALEFORM // set the bail jumper's name to be displayed on the mission passed screen sMissionPassedScreen_BailJumpersName = GET_BAIL_JUMPERS_NAME(sBailBondLaunchData.eBailBondID) // Reset replay variables, so the game knows we are no longer on a replay Reset_All_Replay_Variables() CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBMOS_PASSED : MISSION_OVER(iMissionCandidateID) : iMissionCandidateID = ", sBailBondLaunchData.iMissionCandidateID, " frame = ", GET_FRAME_COUNT()) MISSION_OVER(sBailBondLaunchData.iMissionCandidateID) // Are all bail bonds completed launcher? If so terminate launcher and remove from relaunch list IF HAVE_ALL_BAIL_BOND_MISSION_BEEN_COMPLETED() // terminate the launcher if Trevor delivered the final bail jumper to Maude // otherwise if the player killed the bail jumper we send one final email from Maude IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, GET_BAIL_BOND_PASSED_TYPE_KILLED_BIT_FLAG(sBailBondLaunchData.eBailBondID)) // setup the time delay before final email from Maude is sent currentTimeOfDay = GET_CURRENT_TIMEOFDAY() ADD_TIME_TO_TIMEOFDAY(currentTimeOfDay, 0, 0, iTimeDelay, 0, 0, 0) g_savedGlobals.sBailBondData.timeMissionStamp = currentTimeOfDay g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_SEND_FINAL_EMAIL) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_MISSION_ACTIVE -> BBMOS_PASSED_KILLED -> ", "BBL_STATE_SEND_FINAL_EMAIL") MAKE_AUTOSAVE_REQUEST() ELSE g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_FINAL_BAIL_JUMPER_DELIVERED) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_MISSION_ACTIVE -> BBMOS_PASSED_DELIVERED -> ", "BBL_STATE_FINAL_BAIL_JUMPER_DELIVERED") MAKE_AUTOSAVE_REQUEST() ENDIF ELSE // update the new mission g_savedGlobals.sBailBondData.iCurrentMission = GET_NEXT_BAIL_BOND_MISSION() // reset bit flag for player needing to be out of the mission area before we start checking his approach CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) // update the launcher data for the next mission INIT_LAUNCHER_DATA_FOR_CURRENT_BAIL_BOND() // setup the time delay before the next bail bond triggers currentTimeOfDay = GET_CURRENT_TIMEOFDAY() ADD_TIME_TO_TIMEOFDAY(currentTimeOfDay, 0, 0, iTimeDelay, 0, 0, 0) g_savedGlobals.sBailBondData.timeMissionStamp = currentTimeOfDay g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_DELAY_NEXT_MISSION) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_MISSION_ACTIVE -> BBMOS_PASSED -> ", "BBL_STATE_DELAY_NEXT_MISSION") MAKE_AUTOSAVE_REQUEST() ENDIF // launch the post mission script to handle Maude's cleanup IF eMissionOverState != BBMOS_PASSED_KILLED START_NEW_MAUDE_POST_BAILBOND_SCRIPT() ENDIF BREAK CASE BBMOS_FAILED // wait to see if a replay gets accepted or rejected IF (g_replay.replayStageID = RS_ACTIVE) // accepted replay, relaunch mission // use: g_bLaunchMinigameReplay START_NEW_BAIL_BOND_MISSION_SCRIPT(sBailBondLaunchData.eBailBondID) ELIF (g_replay.replayStageID = RS_NOT_REQUIRED) // rejected replay, clean up candidateID etc. // Reset replay variables, so the game knows we are no longer on a replay Reset_All_Replay_Variables() CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBMOS_FAILED : MISSION_OVER(iMissionCandidateID) : iMissionCandidateID = ", sBailBondLaunchData.iMissionCandidateID, " frame = ", GET_FRAME_COUNT()) MISSION_OVER(sBailBondLaunchData.iMissionCandidateID) // reset bit flag for player needing to be out of the mission area before we start checking his approach CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) // setup the time delay before the mission can be retriggered currentTimeOfDay = GET_CURRENT_TIMEOFDAY() iTimeDelay = MISSION_TRIGGER_TIME_DELAY_HOURS_FAILED ADD_TIME_TO_TIMEOFDAY(currentTimeOfDay, 0, 0, iTimeDelay, 0, 0, 0) g_savedGlobals.sBailBondData.timeMissionStamp = currentTimeOfDay g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_MISSION_FAILED) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_MISSION_ACTIVE -> BBMOS_FAILED -> ", "BBL_STATE_MISSION_FAILED") Reset_All_Replay_Variables() MAKE_AUTOSAVE_REQUEST() ENDIF BREAK CASE BBMOS_CLEANUP // Reset replay variables, so the game knows we are no longer on a replay Reset_All_Replay_Variables() CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBMOS_CLEANUP : MISSION_OVER(iMissionCandidateID) : iMissionCandidateID = ", sBailBondLaunchData.iMissionCandidateID, " frame = ", GET_FRAME_COUNT()) MISSION_OVER(sBailBondLaunchData.iMissionCandidateID) // reset bit flag for player needing to be out of the mission area before we start checking his approach CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_TRIGGER_MISSION) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_MISSION_ACTIVE -> BBMOS_CLEANUP -> ", "BBL_STATE_TRIGGER_MISSION") BREAK ENDSWITCH ENDPROC SCRIPT //prevent multiple bail bond launcher threads running (this shouldn't happen if things are setup correctly) IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(GET_HASH_OF_THIS_SCRIPT_NAME()) > 1 CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : Terminate thread - script instance already running!") SCRIPT_ASSERT("BailBond_Launcher.sc : Terminate thread - script instance already running!") TERMINATE_THIS_THREAD() ENDIF // ensure the script is going to be relaunched on a new sp session (so this comes before HAS_FORCE_CLEANUP_OCCURRED) Register_Script_To_Relaunch_List(LAUNCH_BIT_BAIL_BOND_CONTROLLER) IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_SP_TO_MP | FORCE_CLEANUP_FLAG_DEBUG_MENU) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : forced cleanup occured") Script_Cleanup() ENDIF // Hold up whilst updating gameflow via debug menu #IF IS_DEBUG_BUILD IF g_flowUnsaved.bUpdatingGameflow WAIT(0) ENDIF #ENDIF INIT_BAIL_BOND_LAUNCHER() WHILE TRUE DISPLAY_MISSION_PASSED_SPLASH_SCREEN() SWITCH INT_TO_ENUM(BAILBOND_LAUNCHER_STATE_ENUM, g_savedGlobals.sBailBondData.iLauncherState) // Send the email which triggers the mission unlocking CASE BBL_STATE_SEND_TRIGGER_EMAIL IF IS_PLAYER_SAFE_DISTANCE_FROM_MAUDE_TO_TRIGGER_EMAIL() IF NOT IS_PLAYER_IN_BAIL_BOND_RANGE() // B*1302953 - Suppress emails from being received when already in bail bond area. IF PRIVATE_Is_Safe_To_Start_Communication(BIT_TREVOR, CHAR_MAUDE, CPR_MEDIUM) // B*1265531 - ensure game state is safe to send email IF SENT_BAIL_BOND_EMAIL(sBailBondLaunchData.eBailBondID, sBailBondLaunchData.bTrevorKilledPreviousBailJumper) // if the last bail jumper was killed, player doesn't get reward until now when he gets the next email from Maude IF sBailBondLaunchData.bTrevorKilledPreviousBailJumper CREDIT_BANK_ACCOUNT(CHAR_TREVOR, BAAC_BAIL_BONDS, 5000) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_SEND_TRIGGER_EMAIL -> ", "Trevor account credited smaller amount for") ENDIF // store current time to send reminder email from Maude if player doesn't trigger mission with in set amount of time currentTimeOfDay = GET_CURRENT_TIMEOFDAY() ADD_TIME_TO_TIMEOFDAY(currentTimeOfDay, 0, 0, 0, TIME_DELAY_MISSION_REMINDER_EMAIL_IN_DAYS, 0, 0) g_savedGlobals.sBailBondData.timeMissionStamp = currentTimeOfDay CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_SENT_MISSION_REMINDER_EMAIL)) g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_TRIGGER_MISSION) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_SEND_TRIGGER_EMAIL -> ", "BBL_STATE_TRIGGER_MISSION") ENDIF ELSE //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME) ENDIF ELSE //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME) ENDIF ELSE //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME) ENDIF BREAK // Awaiting player to trigger the mission CASE BBL_STATE_TRIGGER_MISSION // only process everything if the play char is Trevor IF (GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR) HANDLE_TREVOR_DIALOGUE_FOR_READING_TRIGGER_EMAIL(sBailBondLaunchData, sLauncherDialogue) HANDLE_ONE_TIME_BAIL_BOND_HELP_MESSAGE(sBailBondLaunchData.eBailBondID) // ensure the player isn't already with in range when we begin the launch checks IF NOT IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) IF NOT IS_PLAYER_IN_BAIL_BOND_RANGE() SET_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_TRIGGER_MISSION -> ", "Bit set BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK") ELSE //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME) ENDIF ELSE IF IS_PLAYER_IN_BAIL_BOND_RANGE() IF IS_BAIL_BOND_SAFE_TO_LAUNCH() IF REQUEST_PERMISSION_TO_RUN_BAIL_BOND_MISSION(sBailBondLaunchData.iMissionCandidateID) START_NEW_BAIL_BOND_MISSION_SCRIPT(sBailBondLaunchData.eBailBondID) // Store start snapshot if this isn't a replay IF NOT IS_REPLAY_IN_PROGRESS() Store_Minigame_Replay_Starting_Snapshot(GET_THIS_SCRIPT_NAME(), TRUE) ENDIF g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_MISSION_ACTIVE) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_TRIGGER_MISSION -> ", "BBL_STATE_MISSION_ACTIVE") ENDIF ELSE // check if the initial leave area check needs resetting if player is within range whilst we aren't allowed to launch IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_TRIGGER_MISSION -> ", "player in range whilst not safe to launch. Bit cleared BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK") // Debug only : ensure Bail Bond will wait in launch state #IF IS_DEBUG_BUILD IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DEBUG_LAUNCHED)) SET_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_TRIGGER_MISSION -> ", "DEBUG override. Bit reset BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK") ENDIF #ENDIF ENDIF //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME) ENDIF ELSE // triggers the reminder email from Maude if the player hasn't launched the mission within set period of time HANDLE_MISSION_REMINDER_EMAIL(sBailBondLaunchData.eBailBondID) //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME) ENDIF ENDIF ELSE // check if the initial leave area check needs resetting for player swapping chars IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) CLEAR_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_TRIGGER_MISSION -> ", "player Char != Trevor. Bit cleared BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK") // Debug only : ensure Bail Bond will wait in launch state #IF IS_DEBUG_BUILD IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DEBUG_LAUNCHED)) SET_BIT(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK)) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_TRIGGER_MISSION -> ", "DEBUG override. Bit reset BBL_BIT_FLAG_DONE_INITIAL_LEAVE_AREA_CHECK") ENDIF #ENDIF ENDIF //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME_LONG) ENDIF BREAK // Mission is running, waiting for it to end. CASE BBL_STATE_MISSION_ACTIVE IF NOT IS_THREAD_ACTIVE(tBailBondMissionThread) HANDLE_BAIL_BOND_MISSION_OVER_STATE(eBailBondMissionOverState) ENDIF BREAK // Player failed the mission, handle him leaving the area before re-offered CASE BBL_STATE_MISSION_FAILED IF IS_NOW_AFTER_TIMEOFDAY(g_savedGlobals.sBailBondData.timeMissionStamp) g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_TRIGGER_MISSION) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_MISSION_FAILED -> ", "BBL_STATE_TRIGGER_MISSION") ENDIF BREAK // Player passed the mission, handle delay till next bail bond is offered CASE BBL_STATE_DELAY_NEXT_MISSION // B*1354295 - wait for mission passed splash to finish before doing any further checks / waits IF eMissionPassedScreenState = BBL_MPSS_INACTIVE IF IS_NOW_AFTER_TIMEOFDAY(g_savedGlobals.sBailBondData.timeMissionStamp) g_savedGlobals.sBailBondData.iLauncherState = ENUM_TO_INT(BBL_STATE_SEND_TRIGGER_EMAIL) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_DELAY_NEXT_MISSION -> ", "BBL_STATE_SEND_TRIGGER_EMAIL") ENDIF ENDIF BREAK // In the event Trevor kills the final bail jumper instead of taking them to Maude, finish off with an Email from Maude CASE BBL_STATE_SEND_FINAL_EMAIL // B*1354295 - wait for mission passed splash to finish before doing any further checks / waits IF eMissionPassedScreenState = BBL_MPSS_INACTIVE IF IS_NOW_AFTER_TIMEOFDAY(g_savedGlobals.sBailBondData.timeMissionStamp) IF IS_PLAYER_SAFE_DISTANCE_FROM_MAUDE_TO_TRIGGER_EMAIL() IF PRIVATE_Is_Safe_To_Start_Communication(BIT_TREVOR, CHAR_MAUDE, CPR_MEDIUM) // B*1265531 - ensure game state is safe to send email IF SENT_FINAL_BAIL_BOND_EMAIL() // player doesn't get reward until now when he gets the final email from Maude CREDIT_BANK_ACCOUNT(CHAR_TREVOR, BAAC_BAIL_BONDS, 5000) CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_SEND_FINAL_EMAIL - ", "All bail bonds completed and Maude final email sent - launcher safe to terminate") REMOVE_SCRIPT_FROM_RELAUNCH_LIST(LAUNCH_BIT_BAIL_BOND_CONTROLLER) MAKE_AUTOSAVE_REQUEST() Script_Cleanup() ENDIF ELSE //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME) ENDIF ELSE //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME) ENDIF ELSE //delay rechecking conditions, so this isn't spamming every frame WAIT(LAUNCHER_DELAY_TIME) ENDIF ENDIF BREAK // extra launcher state needed to delay terminate script until mission passed message has finishing displaying CASE BBL_STATE_FINAL_BAIL_JUMPER_DELIVERED IF eMissionPassedScreenState = BBL_MPSS_INACTIVE CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : BBL_STATE_FINAL_BAIL_JUMPER_DELIVERED - ", "All bail bonds completed - launcher safe to terminate") REMOVE_SCRIPT_FROM_RELAUNCH_LIST(LAUNCH_BIT_BAIL_BOND_CONTROLLER) Script_Cleanup() ENDIF BREAK ENDSWITCH WAIT(0) ENDWHILE ENDSCRIPT