////////////////////////////////////////////////////////////////////////////////////////// // // // MISSION NAME : selector_public.sch // // AUTHOR : Kenneth Ross // // DESCRIPTION : Functionality for character swapping. // // See selector.sc for example use. // // // ////////////////////////////////////////////////////////////////////////////////////////// USING "rage_builtins.sch" USING "globals.sch" USING "commands_player.sch" USING "commands_streaming.sch" USING "commands_camera.sch" USING "script_player.sch" USING "commands_graphics.sch" USING "commands_pad.sch" USING "commands_ped.sch" USING "commands_interiors.sch" USING "commands_stats.sch" USING "script_MATHS.sch" USING "player_ped_public.sch" USING "cellphone_public.sch" USING "net_comms_public.sch" USING "mission_control_public.sch" USING "comms_control_public.sch" USING "flow_public_core.sch" USING "drunk_public.sch" USING "menu_public.sch" USING "shop_public.sch" USING "stats_private.sch" USING "net_spectator_cam_common.sch" USING "net_spectator_variables.sch" USING "respawn_location_private.sch" USING "Transition_Controller.sch" /// PURPOSE: Returns TRUE if a camera from the RUN_CAM_SPLINE_x procs is currently active FUNC BOOL IS_SELECTOR_CAM_ACTIVE() RETURN g_bSelectorCamActive ENDFUNC /// PURPOSE: Sets if a switch cam is active or not. This gets called automatically within the RUN_CAM_SPLINE_x procs. PROC SET_SELECTOR_CAM_ACTIVE(BOOL bIsActive) #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF PRINTLN("SET_SELECTOR_CAM_ACTIVE(", bIsActive, ") called by ", GET_THIS_SCRIPT_NAME()) g_bSelectorCamActive = bIsActive ENDPROC /// PURPOSE: Returns if a script is wanting the transition to happen FUNC BOOL IS_TRANSITION_MENU_TRIGGERED() RETURN g_bBringUpMPHud ENDFUNC /// PURPOSE: Sets if a switch cam is active or not. This gets called automatically within the RUN_CAM_SPLINE_x procs. PROC TRIGGER_TRANSITION_MENU_ACTIVE(BOOL bIsActive) #IF IS_DEBUG_BUILD IF bIsActive DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << TRIGGER_TRANSITION_MENU_ACTIVE - TRUE >> ") ELSE DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << TRIGGER_TRANSITION_MENU_ACTIVE - FALSE >> ") ENDIF #ENDIF g_bBringUpMPHud = bIsActive ENDPROC /// PURPOSE: Returns if a script is wanting the transition to happen FUNC BOOL IS_CREATOR_MENU_TRIGGERED() RETURN g_bBringUpMainCreator ENDFUNC /// PURPOSE: Sets if a switch cam is active or not. This gets called automatically within the RUN_CAM_SPLINE_x procs. PROC TRIGGER_CREATOR_MENU_ACTIVE(BOOL bIsActive) #IF IS_DEBUG_BUILD IF bIsActive DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << TRIGGER_CREATOR_MENU_ACTIVE - TRUE >> ") ELSE DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << TRIGGER_CREATOR_MENU_ACTIVE - FALSE >> ") ENDIF #ENDIF g_bBringUpMainCreator = bIsActive ENDPROC /// PURPOSE: Sets if a switch cam is active or not. This gets called automatically within the RUN_CAM_SPLINE_x procs. PROC TELL_TRANSITION_BAIL_HAPPENED(BOOL bBailHappened) #IF IS_DEBUG_BUILD IF bBailHappened DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT("<>") ELSE DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT("<>") ENDIF #ENDIF g_Private_BailHappened = bBailHappened ENDPROC /// PURPOSE: Returns if a script is wanting the transition to happen FUNC BOOL DID_A_BAIL_HAPPEN() RETURN g_Private_BailHappened ENDFUNC /// PURPOSE: Sets if a switch cam is active or not. This gets called automatically within the RUN_CAM_SPLINE_x procs. PROC TELL_TRANSITION_MAYBE_FRONTEND_QUIT_MP(BOOL bQuitFrontend) g_Private_QuitMPThroughMenu = bQuitFrontend ENDPROC /// PURPOSE: Returns if a script is wanting the transition to happen FUNC BOOL DID_FRONTEND_QUIT_MP() RETURN g_Private_QuitMPThroughMenu ENDFUNC /// PURPOSE: Block the selector buttons so that we dont perform any actions in game PROC PROCESS_SELECTOR_INPUT_BLOCKS() DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_RADIO_WHEEL) IF !g_bBrowserVisible//1084004 SET_INPUT_EXCLUSIVE(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) ENDIF SET_INPUT_EXCLUSIVE(PLAYER_CONTROL, INPUT_WEAPON_WHEEL_UD) SET_INPUT_EXCLUSIVE(PLAYER_CONTROL, INPUT_WEAPON_WHEEL_LR) IF NOT IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL) SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_FRONTEND_X) SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_FRONTEND_Y) SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL) SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT) ENDIF DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_HEADLIGHT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK2) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_CIN_CAM) ENDPROC /// PURPOSE: Checks to see if player is currently pressing the selector UI button /// RETURNS: TRUE if the player is pressing the button, FALSE if they are not FUNC BOOL IS_SELECTOR_UI_BUTTON_PRESSED(BOOL bOnlyCheckEnabledControls = TRUE) // TODO 2031031: Don't allow the selector to be activated while holding // aim on the sniper scope view. Avoid conflict with zoom -Ben R IF GET_ALLOW_MOVEMENT_WHILE_ZOOMED() IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_AIMING_THROUGH_SNIPER_SCOPE(PLAYER_PED_ID()) IF IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_AIM) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_AIM) RETURN FALSE ENDIF ENDIF ENDIF ENDIF // TODO 2060410: Implement replay recording in character select UI // - pressing a recording button closes the switch UI so dont process until dpad down is released #IF USE_REPLAY_RECORDING_TRIGGERS IF g_sSelectorUI.bMustReleaseSelectorUIButton RETURN FALSE ENDIF #ENDIF IF IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) OR (NOT bOnlyCheckEnabledControls AND IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL)) RETURN TRUE ELSE // PC Character switch shortcut keys IF IS_PC_VERSION() IF IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF IF NOT bOnlyCheckEnabledControls IF IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) OR IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) OR IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) OR IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDIF ENDFUNC /// PURPOSE: Checks to see if player has just pressed the selector UI button /// RETURNS: TRUE if the player has just pressed the button, FALSE if they have not FUNC BOOL IS_SELECTOR_UI_BUTTON_JUST_PRESSED(BOOL bOnlyCheckEnabledControls = TRUE) // TODO 2060410: Implement replay recording in character select UI // - pressing a recording button closes the switch UI so dont process until dpad down is released #IF USE_REPLAY_RECORDING_TRIGGERS IF g_sSelectorUI.bMustReleaseSelectorUIButton RETURN FALSE ENDIF #ENDIF IF IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) OR (NOT bOnlyCheckEnabledControls AND IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL)) RETURN TRUE ELSE // PC Character switch shortcut keys IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL) IF IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) OR IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) OR IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) OR IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF IF NOT bOnlyCheckEnabledControls IF IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) OR IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) OR IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) OR IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDIF ENDFUNC /// PURPOSE: Checks to see if player has just released the selector UI button /// RETURNS: TRUE if the player has just released the button, FALSE if they have not FUNC BOOL IS_SELECTOR_UI_BUTTON_JUST_RELEASED(BOOL bOnlyCheckEnabledControls = TRUE) // TODO 2060410: Implement replay recording in character select UI // - pressing a recording button closes the switch UI so dont process until dpad down is released #IF USE_REPLAY_RECORDING_TRIGGERS IF g_sSelectorUI.bMustReleaseSelectorUIButton RETURN FALSE ENDIF #ENDIF IF IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) OR (NOT bOnlyCheckEnabledControls AND IS_DISABLED_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL)) RETURN TRUE ELSE // PC Character switch shortcut keys IF IS_PC_VERSION() // Don't switch unless ALL the player switch keys are not pressed. // Michael IF IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) IF NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF // Franklin ELIF IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) IF NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF // Trevor ELIF IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) IF NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF // MP ELIF IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) IF NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) RETURN TRUE ENDIF ENDIF IF NOT bOnlyCheckEnabledControls // Michael IF IS_DISABLED_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) IF NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) AND NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) AND NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF // Franklin ELIF IS_DISABLED_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) IF NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) AND NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) AND NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF // Trevor ELIF IS_DISABLED_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) IF NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) AND NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) AND NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) RETURN TRUE ENDIF // MP ELIF IS_DISABLED_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MULTIPLAYER) IF NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) AND NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) AND NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) RETURN TRUE ENDIF ENDIF ENDIF // IF NOT bOnlyCheckEnabledControl ENDIF // IF IS_PC_VERSION() RETURN FALSE ENDIF ENDFUNC /// PURPOSE: Returns if a script is wanting the transition to happen FUNC BOOL IS_TRANSITION_TELLING_CREATOR_TO_CLEANUP() RETURN g_bTransitionTellCreatorToCleanup ENDFUNC /// PURPOSE: Sets if a switch cam is active or not. This gets called automatically within the RUN_CAM_SPLINE_x procs. PROC TRIGGER_TRANSITION_TELL_CREATOR_TO_CLEANUP(BOOL bIsActive) #IF IS_DEBUG_BUILD IF bIsActive DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << TRIGGER_TRANSITION_TELL_CREATOR_TO_CLEANUP - TRUE >> ") ELSE DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << TRIGGER_TRANSITION_TELL_CREATOR_TO_CLEANUP - FALSE >> ") ENDIF #ENDIF g_bTransitionTellCreatorToCleanup = bIsActive ENDPROC /// PURPOSE: Returns if a script is wanting the transition to happen FUNC BOOL IS_TRANSITION_NEED_TO_REPOSITION_SP_GUY() RETURN g_bTransitionNeedToPositionSPGuy ENDFUNC /// PURPOSE: Sets if a switch cam is active or not. This gets called automatically within the RUN_CAM_SPLINE_x procs. PROC TRIGGER_TRANSITION_NEED_TO_REPOSITION_SP_GUY(BOOL bIsActive) #IF IS_DEBUG_BUILD IF bIsActive DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << TRIGGER_TRANSITION_NEED_TO_REPOSITION_SP_GUY - TRUE >> ") ELSE DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << TRIGGER_TRANSITION_NEED_TO_REPOSITION_SP_GUY - FALSE >> ") ENDIF #ENDIF g_bTransitionNeedToPositionSPGuy = bIsActive ENDPROC /// PURPOSE: Returns if a script is wanting the transition to block the music stop FUNC BOOL IS_TRANSITION_BLOCKING_MUSIC_STOP() RETURN g_bTransitionBlockMusicStop ENDFUNC /// PURPOSE: Sets to true to block the GTA_ONLINE_STOP_SCORE being called when a transtion starts. PROC SET_TRANSITION_LAUNCH_BLOCKING_MUSIC_STOP(BOOL bIsActive) #IF IS_DEBUG_BUILD IF bIsActive DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << SET_TRANSITION_LAUNCH_BLOCKING_MUSIC_STOP - TRUE >> ") ELSE DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT(" << SET_TRANSITION_LAUNCH_BLOCKING_MUSIC_STOP - FALSE >> ") ENDIF #ENDIF g_bTransitionBlockMusicStop = bIsActive ENDPROC /// PURPOSE: Returns the ped enum equivalent to selector slot enum FUNC enumCharacterList GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(SELECTOR_SLOTS_ENUM eSlot) IF eSlot = SELECTOR_PED_MICHAEL RETURN CHAR_MICHAEL ELIF eSlot = SELECTOR_PED_TREVOR RETURN CHAR_TREVOR ELIF eSlot = SELECTOR_PED_FRANKLIN RETURN CHAR_FRANKLIN ENDIF RETURN NO_CHARACTER ENDFUNC /// PURPOSE: Returns the selector slot equivalent to the ped enum FUNC SELECTOR_SLOTS_ENUM GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(enumCharacterList ePed) IF ePed = CHAR_MICHAEL RETURN SELECTOR_PED_MICHAEL ELIF ePed = CHAR_TREVOR RETURN SELECTOR_PED_TREVOR ELIF ePed = CHAR_FRANKLIN RETURN SELECTOR_PED_FRANKLIN ELIF ePed = NO_CHARACTER RETURN SELECTOR_PED_MULTIPLAYER ENDIF RETURN NUMBER_OF_SELECTOR_PEDS ENDFUNC /// PURPOSE: Returns the z coord for the speicified camera FUNC FLOAT GET_SELECTOR_CAM_Z_HEIGHT(CAMERA_INDEX selectorCamID) IF DOES_CAM_EXIST(selectorCamID) VECTOR vCoords = GET_CAM_COORD(selectorCamID) RETURN (vCoords.z) ENDIF RETURN 0.0 ENDFUNC /// PURPOSE: Works out the offset vector for a destination cam based on the ZOOM_LEVEL /// NOTE: Only to be used in selector_public.sch FUNC VECTOR GET_OFFSET_FOR_DEST_CAM(PED_INDEX ped) // These offsets were calculated in game using the displacement vector // of the gameplay camera coords and the player coords. // This displacement was then transformed to the players local coord system by // doting the with the players rotation vectors. // Offsets are just an estimate and only suited for prototype version. VECTOR vOffset = << 0.247654, -2.8853, 0.528659 >> // Make sure the ped is alive IF NOT IS_PED_INJURED(ped) // Check if we need to use VEHICLE_ZOOM_LEVEL IF IS_PED_IN_ANY_VEHICLE(ped) // Grab the VEHICLE_ZOOM_LEVEL SWITCH GET_FOLLOW_VEHICLE_CAM_ZOOM_LEVEL() CASE VEHICLE_ZOOM_LEVEL_NEAR vOffset = << -0.414898, -6.52417, 1.48257 >> BREAK CASE VEHICLE_ZOOM_LEVEL_MEDIUM vOffset = << -0.409924, -7.87737, 1.5684 >> BREAK CASE VEHICLE_ZOOM_LEVEL_FAR vOffset = << -0.403982, -9.22678, 1.65399 >> BREAK CASE VEHICLE_ZOOM_LEVEL_BONNET vOffset = << -0.353964, 1.23187, 0.561746 >> BREAK ENDSWITCH // Have to use PED_ZOOM_LEVEL ELSE // Grab the PED_ZOOM_LEVEL SWITCH GET_FOLLOW_PED_CAM_ZOOM_LEVEL() CASE PED_ZOOM_LEVEL_NEAR // 0 vOffset = << 0.231316, -1.91668, 0.535791 >> BREAK CASE PED_ZOOM_LEVEL_MEDIUM //1 vOffset = << 0.247654, -2.8853, 0.528659 >> BREAK CASE PED_ZOOM_LEVEL_FAR //2 vOffset = << 0.263986, -3.85184, 0.521533 >> BREAK ENDSWITCH ENDIF ENDIF // #IF USE_TU_CHANGES IF g_SpawnData.fCamHeading = 180 vOffset.y = -vOffset.y ENDIF // #ENDIF // #IF NOT USE_TU_CHANGES // IF g_SpawnData_OLD.fCamHeading = 180 // vOffset.y = -vOffset.y // ENDIF // #ENDIF RETURN vOffset ENDFUNC /// PURPOSE: Returns the current phase of the selector cam. Ranges from 0.0 to 1.0 FUNC FLOAT GET_SELECTOR_CAM_PHASE(SELECTOR_CAM_STRUCT &sCamDetails) IF DOES_CAM_EXIST(sCamDetails.camID) IF IS_CAM_INTERPOLATING(sCamDetails.camID) RETURN GET_CAM_SPLINE_PHASE(sCamDetails.camID) ENDIF ENDIF RETURN 0.0 ENDFUNC /// PURPOSE: Returns the current phase of the selector cam. Ranges from 0.0 to 1.0 FUNC BOOL SET_SELECTOR_CAM_PHASE(SELECTOR_CAM_STRUCT &sCamDetails, FLOAT fPhase) IF DOES_CAM_EXIST(sCamDetails.camID) IF IS_CAM_INTERPOLATING(sCamDetails.camID) SET_CAM_SPLINE_PHASE(sCamDetails.camID, fPhase) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Destroys any existing selector cams and resets all the control flags PROC CLEANUP_SELECTOR_CAM(SELECTOR_CAM_STRUCT &sCamDetails) INT i IF DOES_CAM_EXIST(sCamDetails.camID) DESTROY_CAM(sCamDetails.camID) SET_SELECTOR_CAM_ACTIVE(FALSE) ENDIF IF DOES_CAM_EXIST(sCamDetails.camTo) DESTROY_CAM(sCamDetails.camTo) ENDIF IF DOES_CAM_EXIST(sCamDetails.camSky) DESTROY_CAM(sCamDetails.camSky) ENDIF REPEAT NUM_SELECTOR_INTERP_CAMS i IF DOES_CAM_EXIST(sCamDetails.camID) DESTROY_CAM(sCamDetails.camInterpIDs[i]) ENDIF ENDREPEAT sCamDetails.bSplineCreated = FALSE sCamDetails.bSplineActive = FALSE sCamDetails.bSplineComplete = FALSE sCamDetails.bOKToSwitchPed = FALSE sCamDetails.bPedSwitched = FALSE sCamDetails.bRun = FALSE sCamDetails.bIsPhoneDisabled = FALSE sCamDetails.iInterpCams = 0 sCamDetails.iSplineDuration = 0 sCamDetails.fMaxHeight = 0 // //# 1524219 // CASCADE_SHADOWS_SET_AIRCRAFT_MODE(FALSE) // PRINTLN("CASCADE_SHADOWS_SET_AIRCRAFT_MODE(FALSE) called by ", GET_THIS_SCRIPT_NAME()) #IF IS_DEBUG_BUILD IF DOES_CAM_EXIST(sCamDetails.camCodeTransition) DESTROY_CAM(sCamDetails.camCodeTransition) ENDIF sCamDetails.bUsingCodeCam = FALSE #ENDIF ENDPROC #IF IS_DEBUG_BUILD /// PURPOSE: This is a temp debug func which tests the new START_CAM_TRANSITION command. /// To use this in game, set the g_bUseTransitionCamera flag to TRUE in RAG>>Script>>Selector Globals. FUNC BOOL test_cam_transition(SELECTOR_CAM_STRUCT &camDetails) // Create the camera IF NOT camDetails.bSplineCreated IF NOT IS_PED_INJURED(PLAYER_PED_ID()) AND NOT IS_PED_INJURED(camDetails.pedTo) PRINTSTRING("\n Setting up transition camera")PRINTNL() IF DOES_CAM_EXIST(camDetails.camCodeTransition) DESTROY_CAM(camDetails.camCodeTransition) ENDIF camDetails.camCodeTransition = CREATE_CAM("DEFAULT_SCENE_TRANSITION_CAMERA") SET_CAM_ACTIVE(camDetails.camCodeTransition, TRUE) PRINTSTRING("\n Starting scene transition")PRINTNL() START_CAM_TRANSITION(camDetails.camCodeTransition, GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(camDetails.pedTo)) RENDER_SCRIPT_CAMS(TRUE, TRUE) camDetails.fMaxHeight = GET_SELECTOR_CAM_Z_HEIGHT(camDetails.camCodeTransition) camDetails.bSplineCreated = TRUE camDetails.bSplineActive = TRUE camDetails.iActivateTimer = GET_GAME_TIMER() camDetails.bUsingCodeCam = TRUE SET_SELECTOR_CAM_ACTIVE(TRUE) ELSE camDetails.bSplineComplete = TRUE // Error ENDIF ENDIF PRINTLN("GENERIC_PED_SCENE - (1) camDetails.bSplineActive: ", camDetails.bSplineActive) // Wait for the transition to complete IF camDetails.bSplineActive PRINTLN("GENERIC_PED_SCENE - (1) DOES_CAM_EXIST(camDetails.camCodeTransition): ", DOES_CAM_EXIST(camDetails.camCodeTransition)) IF DOES_CAM_EXIST(camDetails.camCodeTransition) PRINTLN("GENERIC_PED_SCENE - (1) IS_CAM_TRANSITIONING(camDetails.camCodeTransition): ", IS_CAM_TRANSITIONING(camDetails.camCodeTransition)) IF NOT IS_CAM_TRANSITIONING(camDetails.camCodeTransition) camDetails.bSplineComplete = TRUE ELSE PRINTSTRING("\n Scene transition phase = ") PRINTFLOAT(GET_CAM_TRANSITION_PHASE(camDetails.camCodeTransition)) PRINTNL() PRINTLN("GENERIC_PED_SCENE - (1) GET_CAM_TRANSITION_PHASE(camDetails.camCodeTransition): ", GET_CAM_TRANSITION_PHASE(camDetails.camCodeTransition)) PRINTLN("GENERIC_PED_SCENE - (1) g_sSelectorUI.debug_fSwitchPedAfterPhase: ", g_sSelectorUI.debug_fSwitchPedAfterPhase) IF GET_CAM_TRANSITION_PHASE(camDetails.camCodeTransition) > g_sSelectorUI.debug_fSwitchPedAfterPhase camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (1)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF ENDIF ENDIF ELSE camDetails.bSplineComplete = TRUE // Error ENDIF ENDIF // Cleanup the camera IF camDetails.bSplineComplete RENDER_SCRIPT_CAMS(FALSE, FALSE) IF DOES_CAM_EXIST(camDetails.camCodeTransition) SET_CAM_ACTIVE(camDetails.camCodeTransition, FALSE) DESTROY_CAM(camDetails.camCodeTransition) ENDIF DISABLE_CELLPHONE(camDetails.bIsPhoneDisabled) // Reset all the camera values incase they have to be used again camDetails.bSplineCreated = FALSE camDetails.bSplineActive = FALSE camDetails.bSplineComplete = FALSE camDetails.bOKToSwitchPed = FALSE camDetails.bPedSwitched = FALSE camDetails.bRun = FALSE camDetails.iInterpCams = 0 camDetails.iSplineDuration = 0 camDetails.bUsingCodeCam = FALSE IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) SET_PLAYER_INVINCIBLE(PLAYER_ID(), FALSE) SET_ENTITY_VISIBLE(PLAYER_PED_ID(), TRUE) //FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE) SET_PED_CAN_BE_TARGETTED(PLAYER_PED_ID(), TRUE) IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) SET_ENTITY_COLLISION(PLAYER_PED_ID(), TRUE) ENDIF ENDIF // If we didnt switch players then reset the proofs IF NOT IS_PED_INJURED(camDetails.pedTo) SET_ENTITY_INVINCIBLE(camDetails.pedTo, FALSE) ENDIF SET_SELECTOR_CAM_ACTIVE(FALSE) RETURN FALSE // Cam complete ENDIF // Hide the HUD HIDE_HUD_AND_RADAR_THIS_FRAME() //CLEAR_REMINDER_MESSAGE() //#1421176 RETURN TRUE ENDFUNC #ENDIF FUNC STRING GET_SKYSWOOP_STRING(SKYSWOOP aSwoopStage) SWITCH aSwoopStage CASE SKYSWOOP_NONE RETURN "SKYSWOOP_NONE" CASE SKYSWOOP_GOINGUP RETURN "SKYSWOOP_GOINGUP" CASE SKYSWOOP_INSKYSTATIC RETURN "SKYSWOOP_INSKYSTATIC" CASE SKYSWOOP_INSKYMOVING RETURN "SKYSWOOP_INSKYMOVING" CASE SKYSWOOP_GOINGDOWN RETURN "SKYSWOOP_GOINGDOWN" ENDSWITCH RETURN "" ENDFUNC /// PURPOSE: /// Extra function to tell the MP HUD where the swooping camera is at /// PARAMS: /// aStage - PROC SET_SKYSWOOP_STAGE(SKYSWOOP aStage) #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() NET_PRINT("SET_SKYSWOOP_STAGE() - Called = ")NET_PRINT(GET_SKYSWOOP_STRING(aStage)) NET_NL() // if going to the SKYSWOOP_GOINGDOWN then re-init the stuck in sky timer #IF FEATURE_SHORTEN_SKY_HANG IF (aStage = SKYSWOOP_GOINGDOWN) AND NOT (g_TransitionData.SwoopStage = SKYSWOOP_GOINGDOWN) IF HAS_NETWORK_TIME_STARTED() g_iHangingInSkyState = 0 g_HangingInSkyTimer = GET_NETWORK_TIME() PRINTLN("[Hanginginsky] SET_SKYSWOOP_STAGE(SKYSWOOP_GOINGDOWN) - resetting timer ") ENDIF ENDIF #ENDIF #ENDIF #IF USE_FINAL_PRINTS PRINTLN_FINAL(" SET_SKYSWOOP_STAGE() - Called = ", GET_SKYSWOOP_STRING(aStage)) #ENDIF IF aStage = SKYSWOOP_NONE g_b_skyCamPausedForOutroLastFrame = FALSE ENDIF g_TransitionData.SwoopStage = aStage ENDPROC PROC DESTROY_TRANSITION_CAMERA(SELECTOR_CAM_STRUCT &camDetails, BOOL bLeaveScriptCamRendering = FALSE) camDetails.bSplineCreated = FALSE camDetails.bSplineActive = FALSE camDetails.bSplineComplete = FALSE camDetails.bOKToSwitchPed = FALSE camDetails.bPedSwitched = FALSE camDetails.bRun = FALSE IF DOES_CAM_EXIST(camDetails.camID) IF IS_CAM_ACTIVE(camDetails.camID) SET_SELECTOR_CAM_ACTIVE(FALSE) ENDIF DESTROY_CAM(camDetails.camID) ENDIF #IF IS_DEBUG_BUILD // IF NOT TRUE // SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0) // SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) // ENDIF #ENDIF IF NOT (g_drunkCameraActive) STOP_GAMEPLAY_CAM_SHAKING(TRUE) SET_GAMEPLAY_CAM_MOTION_BLUR_SCALING_THIS_UPDATE(0) SET_GAMEPLAY_CAM_MAX_MOTION_BLUR_STRENGTH_THIS_UPDATE(0) ENDIF // #IF USE_TU_CHANGES g_SpawnData.fCamHeading = 0.0 // #ENDIF // #IF NOT USE_TU_CHANGES // g_SpawnData_OLD.fCamHeading = 0.0 // #ENDIF IF NOT bLeaveScriptCamRendering RENDER_SCRIPT_CAMS(FALSE, FALSE, 0) ENDIF ENDPROC PROC KILL_SKYCAM(BOOL DoSwitchCameraPart = TRUE, BOOL bLeaveScriptCamRendering = FALSE) DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT("KILL_SKYCAM() - Called ") DESTROY_TRANSITION_CAMERA(g_SkyCamData,bLeaveScriptCamRendering) #IF USE_TU_CHANGES DONT_RENDER_IN_GAME_UI(FALSE) NET_NL()NET_PRINT(" KILL_SKYCAM: DONT_RENDER_IN_GAME_UI(FALSE) ") BOOL bDoCodeCamera = TRUE IF DoSwitchCameraPart IF bDoCodeCamera = TRUE // IF IS_SWITCH_TO_MULTI_FIRSTPART_FINISHED() NET_NL()NET_PRINT("KILL_SKYCAM() - STOP_PLAYER_SWITCH called ") // SWITCH_TO_MULTI_SECONDPART(PLAYER_PED_ID()) STOP_PLAYER_SWITCH() SET_SKYSWOOP_STAGE(SKYSWOOP_NONE) IF DOES_ENTITY_EXIST(PlayerSwitchLeftBehindPed) IF DOES_ENTITY_BELONG_TO_THIS_SCRIPT(PlayerSwitchLeftBehindPed, FALSE) IF NOT IS_ENTITY_A_MISSION_ENTITY(PlayerSwitchLeftBehindPed) SET_ENTITY_AS_MISSION_ENTITY(PlayerSwitchLeftBehindPed, FALSE) NET_NL()NET_PRINT("KILL_SKYCAM: NOT IS_ENTITY_A_MISSION_ENTITY(PlayerSwitchLeftBehindPed)") ELSE NET_NL()NET_PRINT("KILL_SKYCAM: IS_ENTITY_A_MISSION_ENTITY(PlayerSwitchLeftBehindPed)") ENDIF NET_NL()NET_PRINT(" KILL_SKYCAM: DELETE_PED(PlayerSwitchLeftBehindPed) ") DELETE_PED(PlayerSwitchLeftBehindPed) ENDIF ENDIF // ENDIF ENDIF ENDIF #ENDIF //Must not be changed. -BenR #IF NOT USE_TU_CHANGES BOOL bDoCodeCamera = TRUE IF DoSwitchCameraPart IF bDoCodeCamera = TRUE NET_NL()NET_PRINT("KILL_SKYCAM() - STOP_PLAYER_SWITCH called ") STOP_PLAYER_SWITCH() ENDIF ENDIF SET_SKYSWOOP_STAGE(SKYSWOOP_NONE) #ENDIF ENDPROC PROC TAKE_CONTROL_OF_TRANSITION(BOOL DoSwitchCameraPart = TRUE, BOOL bKillSkycam = TRUE) DEBUG_PRINTCALLSTACK() NET_NL()NET_PRINT("TAKE_CONTROL_OF_TRANSITION(")NET_PRINT_BOOL(DoSwitchCameraPart)NET_PRINT(") - Called ") IF bKillSkycam CLEAR_BIT(g_BossSpecData.specCamData.iBitSet, SPEC_CAM_BS_DEACTIVATED_DUE_TO_SKYSWOOP_UP) #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_SPECTATOR, "=== CAM === TAKE_CONTROL_OF_TRANSITION called we are killing the skycam and therefore do not need this data anymore; SPEC_CAM_BS_DEACTIVATED_DUE_TO_SKYSWOOP_UP.") #ENDIF KILL_SKYCAM(DoSwitchCameraPart) ENDIF HUD_CHANGE_STATE(HUD_STATE_NO_DISPLAY) TRANSITION_CHANGE_STATE(TRANSITION_STATE_TERMINATE_MAINTRANSITION) ENDPROC //PROC RUN_TUTORIAL_TANSITION_FAILSAFE() // HUD_CHANGE_STATE(HUD_STATE_NO_DISPLAY) // TRANSITION_CHANGE_STATE(TRANSITION_STATE_CNC_SWOOP_DOWN) //ENDPROC /// PURPOSE: Obtains the gamplay game relative heading to a look at pos /// /// NOTES: /// Author: Lawrence Kerr func float get_final_gameplay_cam_relative_heading_to_look_at_pos(ped_index &ped_to, vector look_at_pos) if not is_ped_injured(ped_to) vector target_vec target_vec = look_at_pos - get_entity_coords(ped_to) return (get_heading_from_vector_2d(target_vec.x, target_vec.y) - get_entity_heading(ped_to)) else #IF IS_DEBUG_BUILD SCRIPT_ASSERT("Cannot get heading as ped to is dead.") PRINTSTRING("\nCannot get heading as ped to is dead.") PRINTNL() #ENDIF endif return 0.0 endfunc /// PURPOSE: Sets up a camera spline between player and ped. /// /// NOTES: camDetails.camID will be created in this func unless the calling script has created a custom camera. /// Calling script should set camDetails.pedTo to the ped that they want to hot-swap to. /// If eInterpType is SELECTOR_CAM_DEFAULT then the interp type will be determined automatically. /// Uses bool values to control the process and then returns FALSE when the spline is complete. /// Should be called each frame from calling script until FALSE is returned. /// To not alter the gameplay cam set fDestCamRelative... params to a number outside the range -360.0 to 360.0 FUNC BOOL RUN_CAM_SPLINE_FROM_PLAYER_TO_PED(SELECTOR_CAM_STRUCT &camDetails, FLOAT fDestCamRelativePitch = 0.0, FLOAT fDestCamRelativeHeading = 0.0, SELECTOR_CAM_INTERP_TYPE eInterpType = SELECTOR_CAM_DEFAULT, INT iInterpBackToGameDurationOverride = -1, INT iInterpToCamOverride = 0, INT iStraightInterpTime = 800) /////////////////////////////////////////////////////////////////////////// ///*********************************************************************/// /// Test script for the new hotswap camera set up by code /// /// /// #IF IS_DEBUG_BUILD IF g_sSelectorUI.debug_bUseTransitionCamera OR camDetails.bUsingCodeCam IF (camDetails.bSplineCreated AND camDetails.bUsingCodeCam) OR (NOT camDetails.bSplineCreated) RETURN test_cam_transition(camDetails) ENDIF ENDIF #ENDIF ///*********************************************************************/// /////////////////////////////////////////////////////////////////////////// BOOL bFinalNodeUpdated INT iCamCount /////////////////////////////////////////////////////// /// Setup the spline nodes IF NOT camDetails.bSplineCreated IF NOT IS_PED_INJURED(PLAYER_PED_ID()) AND NOT IS_PED_INJURED(camDetails.pedTo) camDetails.iSplineDuration = 0 INT iDuration FLOAT fSkyNodeAngle, fMaxCamZ, fRotZ BOOL bPlayerVeh, bPedVeh VEHICLE_INDEX vehPlayer, vehPed VECTOR vCamRot VECTOR vTargetRelativePosition VECTOR vHorizontalDelta VECTOR vPedPos = GET_ENTITY_COORDS(camDetails.pedTo) VECTOR vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) FLOAT fPedDist2D = GET_DISTANCE_BETWEEN_COORDS(vPlayerPos, vPedPos, FALSE) FLOAT fPedDist3D = GET_DISTANCE_BETWEEN_COORDS(vPlayerPos, vPedPos, TRUE) // Determine what type of cam we will use IF eInterpType = SELECTOR_CAM_DEFAULT IF fPedDist3D < 8.0 camDetails.camType = SELECTOR_CAM_STRAIGHT_INTERP ELIF fPedDist2D < 30.0 camDetails.camType = SELECTOR_CAM_SHORT_SPLINE ELSE camDetails.camType = SELECTOR_CAM_LONG_SPLINE ENDIF ELSE camDetails.camType = eInterpType ENDIF // Make sure the spline camera has been created IF NOT DOES_CAM_EXIST(camDetails.camID) camDetails.camID = CREATE_CAM("DEFAULT_SPLINE_CAMERA", FALSE) ENDIF // Destory all the previous interp cams FOR iCamCount = 0 TO NUM_SELECTOR_INTERP_CAMS-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR // Set up the camera based on type SWITCH camDetails.camType CASE SELECTOR_CAM_STRAIGHT_INTERP // Grab vehicle state and the final rotation IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) vehPlayer = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) bPlayerVeh = TRUE ENDIF IF IS_PED_IN_ANY_VEHICLE(camDetails.pedTo) vehPed = GET_VEHICLE_PED_IS_USING(camDetails.pedTo) bPedVeh = TRUE fRotZ = GET_ENTITY_HEADING(vehPed) IF fRotZ > 180.0 fRotZ -= 360.0 ENDIF ELSE fRotZ = GET_ENTITY_HEADING(camDetails.pedTo) IF fRotZ > 180.0 fRotZ -= 360.0 ENDIF ENDIF vCamRot = GET_FINAL_RENDERED_CAM_ROT() // Initial camera behind the player camDetails.iInterpCams = 0 SET_CAM_FOV(camDetails.camID, GET_FINAL_RENDERED_CAM_FOV()) IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition) ELSE vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(PLAYER_PED_ID(), GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), vTargetRelativePosition) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], vCamRot) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 0, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 0 // Destination camera behind the ped IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPedVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPed, GET_OFFSET_FOR_DEST_CAM(camDetails.pedTo)) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], camDetails.pedTo, GET_OFFSET_FOR_DEST_CAM(camDetails.pedTo)) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], << -0.951428, 0.0, fRotZ >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], iStraightInterpTime, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += iStraightInterpTime camDetails.bSplineCreated = TRUE BREAK CASE SELECTOR_CAM_SHORT_SPLINE // Calculate the max node height IF vPlayerPos.z > vPedPos.z // Player higher fMaxCamZ = FMAX(vPlayerPos.z + 5.0, vPedPos.z + fPedDist2D) ELSE // Ped higher fMaxCamZ = FMAX(vPedPos.z + 5.0, vPlayerPos.z + fPedDist2D) ENDIF // Calculate the appropriate translation of the sky node towards the destination ped fSkyNodeAngle = 10.0 vHorizontalDelta = vPedPos - vPlayerPos vHorizontalDelta.z = 0.0 vHorizontalDelta = GET_VECTOR_OF_LENGTH(vHorizontalDelta, FMIN(fMaxCamZ * TAN(fSkyNodeAngle), fPedDist2D / 3.0)) // Calculate the duration of the spline when up in the sky iDuration = ROUND((fPedDist3D / ((30.0 - 7.5) / (800.0 - 200.0)))+500.0) // Grab vehicle state and the final rotation IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) vehPlayer = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) bPlayerVeh = TRUE ENDIF IF IS_PED_IN_ANY_VEHICLE(camDetails.pedTo) vehPed = GET_VEHICLE_PED_IS_USING(camDetails.pedTo) bPedVeh = TRUE fRotZ = GET_ENTITY_HEADING(vehPed) IF fRotZ > 180.0 fRotZ -= 360.0 ENDIF ELSE fRotZ = GET_ENTITY_HEADING(camDetails.pedTo) IF fRotZ > 180.0 fRotZ -= 360.0 ENDIF ENDIF vCamRot = GET_FINAL_RENDERED_CAM_ROT() // Initial camera behind the player camDetails.iInterpCams = 0 SET_CAM_FOV(camDetails.camID, GET_FINAL_RENDERED_CAM_FOV()) IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition) ELSE vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(PLAYER_PED_ID(), GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), vTargetRelativePosition) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], vCamRot) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 0, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 0 // Camera 5m above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition+<<0.0, 0.0, 15.0>>) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), <<0.0, 0.0, 5.0>>, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 // Camera in sky above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, <<0.0, 0.0, fMaxCamZ>> + vHorizontalDelta, FALSE) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), <<0.0, 0.0, fMaxCamZ>> + vHorizontalDelta, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 // Camera in sky above ped IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPedVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPed, <<0.0, 0.0, fMaxCamZ>> - vHorizontalDelta, FALSE) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], camDetails.pedTo, <<0.0, 0.0, fMaxCamZ>> - vHorizontalDelta, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, fRotZ >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], iDuration, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += iDuration // Camera 5m above ped IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPedVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPed, <<0.0, 0.0, 15.0>>, FALSE) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], camDetails.pedTo, <<0.0, 0.0, 5.0>>, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, fRotZ>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 // Destination camera behind the ped IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPedVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPed, GET_OFFSET_FOR_DEST_CAM(camDetails.pedTo)) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], camDetails.pedTo, GET_OFFSET_FOR_DEST_CAM(camDetails.pedTo)) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], << -0.951428, 0.0, fRotZ >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 camDetails.bSplineCreated = TRUE BREAK CASE SELECTOR_CAM_LONG_SPLINE // Calculate the max node height fMaxCamZ = 450.0 IF vPlayerPos.z > vPedPos.z // Player higher fMaxCamZ = FMAX(fMaxCamZ, vPlayerPos.z+25.0) ELSE // Ped higher fMaxCamZ = FMAX(fMaxCamZ, vPedPos.z+25.0) ENDIF // Calculate the appropriate translation of the sky node towards the destination ped fSkyNodeAngle = 20.0 vHorizontalDelta = vPedPos - vPlayerPos vHorizontalDelta.z = 0.0 vHorizontalDelta = GET_VECTOR_OF_LENGTH(vHorizontalDelta, FMIN(fMaxCamZ * TAN(fSkyNodeAngle), fPedDist2D / 3.0)) // Calculate the duration of the spline when up in the sky fPedDist3D = CLAMP(fPedDist3D, 50.0, 4000.0) iDuration = ROUND((fPedDist3D / ((4000.0 - 50.0) / (2000.0 - 1000.0)))+1000.0) // Grab vehicle state and the final rotation IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) vehPlayer = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) bPlayerVeh = TRUE ENDIF IF IS_PED_IN_ANY_VEHICLE(camDetails.pedTo) vehPed = GET_VEHICLE_PED_IS_USING(camDetails.pedTo) bPedVeh = TRUE fRotZ = GET_ENTITY_HEADING(vehPed) IF fRotZ > 180.0 fRotZ -= 360.0 ENDIF ELSE fRotZ = GET_ENTITY_HEADING(camDetails.pedTo) IF fRotZ > 180.0 fRotZ -= 360.0 ENDIF ENDIF vCamRot = GET_FINAL_RENDERED_CAM_ROT() // Initial camera behind the player camDetails.iInterpCams = 0 SET_CAM_FOV(camDetails.camID, GET_FINAL_RENDERED_CAM_FOV()) IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition) ELSE vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(PLAYER_PED_ID(), GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), vTargetRelativePosition) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], vCamRot) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 0, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 0 // Camera 5m above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition+<<0.0, 0.0, 15.0>>) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), <<0.0, 0.0, 5.0>>, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 // Camera in sky above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, <<0.0, 0.0, fMaxCamZ>> + vHorizontalDelta, FALSE) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), <<0.0, 0.0, fMaxCamZ>> + vHorizontalDelta, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 800, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 800 // Camera in sky above ped IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPedVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPed, <<0.0, 0.0, fMaxCamZ>> - vHorizontalDelta, FALSE) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], camDetails.pedTo, <<0.0, 0.0, fMaxCamZ>> - vHorizontalDelta, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, fRotZ >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], iDuration, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += iDuration // Camera 5m above ped IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPedVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPed, <<0.0, 0.0, 15.0>>, FALSE) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], camDetails.pedTo, <<0.0, 0.0, 5.0>>, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, fRotZ>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 800, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 800 // Destination camera behind the ped IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPedVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPed, GET_OFFSET_FOR_DEST_CAM(camDetails.pedTo)) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], camDetails.pedTo, GET_OFFSET_FOR_DEST_CAM(camDetails.pedTo)) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], << -0.951428, 0.0, fRotZ >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 camDetails.bSplineCreated = TRUE BREAK ENDSWITCH ELSE // Let scripter know that there is a problem IF IS_PED_INJURED(PLAYER_PED_ID()) #IF IS_DEBUG_BUILD SCRIPT_ASSERT("Cannot create spline cam as player is dead.") PRINTSTRING("\nCannot create spline cam as player is dead.")PRINTNL() #ENDIF ELIF IS_PED_INJURED(camDetails.pedTo) #IF IS_DEBUG_BUILD SCRIPT_ASSERT("Cannot create spline cam as selector ped is dead.") PRINTSTRING("\nCannot create spline cam as selector ped is dead.")PRINTNL() #ENDIF ENDIF // Problem with peds so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Activate the camera IF camDetails.bSplineCreated AND NOT camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) AND NOT IS_PED_INJURED(camDetails.pedTo) camDetails.pedFrom = PLAYER_PED_ID() SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) SET_ENTITY_INVINCIBLE(camDetails.pedFrom, TRUE) SET_ENTITY_INVINCIBLE(camDetails.pedTo, TRUE) camDetails.bIsPhoneDisabled = IS_CELLPHONE_DISABLED() DISABLE_CELLPHONE(TRUE) // IF camDetails.camType = SELECTOR_CAM_SHORT_SPLINE // OR camDetails.camType = SELECTOR_CAM_LONG_SPLINE // //# 1524219 // CASCADE_SHADOWS_SET_AIRCRAFT_MODE(TRUE) // PRINTLN("CASCADE_SHADOWS_SET_AIRCRAFT_MODE(TRUE) called by ", GET_THIS_SCRIPT_NAME()) // ENDIF // IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 SET_CAM_ACTIVE(camDetails.camInterpIDs[iCamCount], TRUE) ENDFOR ENDIF TAKE_CONTROL_OF_TRANSITION(FALSE) SET_CAM_ACTIVE(camDetails.camID, TRUE) IF iInterpToCamOverride = 0 RENDER_SCRIPT_CAMS(true, FALSE) ELif iInterpToCamOverride > 0 RENDER_SCRIPT_CAMS(true, TRUE, iInterpToCamOverride) ENDIF // SFX - Heading up IF NOT g_sSelectorUI.bSFX_BlockAudioCalls IF camDetails.camType = SELECTOR_CAM_LONG_SPLINE PLAY_SOUND(-1, "CHARACTER_CHANGE_UP_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_UP_MASTER") IF (g_sSelectorUI.iSFX_Sky = -1) g_sSelectorUI.iSFX_Sky = GET_SOUND_ID() g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) ENDIF PLAY_SOUND(g_sSelectorUI.iSFX_Sky, "CHARACTER_CHANGE_SKY_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_SKY_MASTER ", g_sSelectorUI.iSFX_Sky) START_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") IF IS_AUDIO_SCENE_ACTIVE("CHARACTER_CHANGE_IN_SKY_SCENE") PRINTLN("CHARACTER_CHANGE_IN_SKY_SCENE...active!!!") ELSE PRINTLN("CHARACTER_CHANGE_IN_SKY_SCENE...is NOT active!!!") ENDIF ELIF camDetails.camType = SELECTOR_CAM_SHORT_SPLINE IF (g_sSelectorUI.iSFX_Sky = -1) g_sSelectorUI.iSFX_Sky = GET_SOUND_ID() g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) ENDIF PLAY_SOUND(g_sSelectorUI.iSFX_Sky, "All", "SHORT_PLAYER_SWITCH_SOUND_SET") PRINTLN("SWITCH UI - playing sound: All SHORT_PLAYER_SWITCH_SOUND_SET") ENDIF ENDIF camDetails.fMaxHeight = GET_SELECTOR_CAM_Z_HEIGHT(camDetails.camID) camDetails.iActivateTimer = GET_GAME_TIMER() camDetails.bSplineActive = TRUE SET_SELECTOR_CAM_ACTIVE(TRUE) // Process player timecycle modifier IF GET_ENTITY_MODEL(camDetails.pedTo) = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) SET_NEXT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(CHAR_MICHAEL)) ELIF GET_ENTITY_MODEL(camDetails.pedTo) = GET_PLAYER_PED_MODEL(CHAR_TREVOR) SET_NEXT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(CHAR_TREVOR)) ELIF GET_ENTITY_MODEL(camDetails.pedTo) = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN) SET_NEXT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(CHAR_FRANKLIN)) ELSE SET_NEXT_PLAYER_TCMODIFIER("") ENDIF SET_PLAYER_TCMODIFIER_TRANSITION(0.0) ELSE // Problem with peds so cleanup camDetails.bSplineComplete = TRUE #IF IS_DEBUG_BUILD SCRIPT_ASSERT("Cannot activate spline camera as player or ped is dead.") PRINTSTRING("\nCannot activate spline camera as player or ped is dead.")PRINTNL() #ENDIF ENDIF ELSE // Problem with camera so cleanup camDetails.bSplineComplete = TRUE #IF IS_DEBUG_BUILD SCRIPT_ASSERT("Cannot activate spline camera as camera doesn't exist.") PRINTSTRING("\nCannot activate spline camera as camera doesn't exist.")PRINTNL() #ENDIF ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup when the spline has finished IF camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) // Update the player timecycle modifier SET_PLAYER_TCMODIFIER_TRANSITION(GET_CAM_SPLINE_PHASE(camDetails.camID)) BOOL bOKToContinue = TRUE IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) bOKToContinue = FALSE ENDIF ENDFOR ENDIF PRINTLN("GENERIC_PED_SCENE - (3) bOKToContinue: ", bOKToContinue) IF bOKToContinue PRINTLN("GENERIC_PED_SCENE - (3) IS_CAM_INTERPOLATING(camDetails.camID): ", IS_CAM_INTERPOLATING(camDetails.camID)) IF IS_CAM_INTERPOLATING(camDetails.camID) // SFX - Heading down IF NOT g_sSelectorUI.bSFX_BlockAudioCalls IF camDetails.camType = SELECTOR_CAM_LONG_SPLINE FLOAT fCurrentHeight = GET_SELECTOR_CAM_Z_HEIGHT(camDetails.camID) IF (fCurrentHeight > camDetails.fMaxHeight) camDetails.fMaxHeight = fCurrentHeight ELIF (camDetails.fMaxHeight > fCurrentHeight+1.0) IF g_sSelectorUI.iSFX_HeadDown = -1 g_sSelectorUI.iSFX_HeadDown = GET_SOUND_ID() g_sSelectorUI.iSFX_HeadDown_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PLAY_SOUND(g_sSelectorUI.iSFX_HeadDown, "CHARACTER_CHANGE_DOWN_MASTER") ENDIF IF (g_sSelectorUI.iSFX_Sky != -1) AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PRINTLN("SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 STOP_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") ENDIF ENDIF ENDIF ENDIF PRINTLN("GENERIC_PED_SCENE - (2) GET_CAM_SPLINE_PHASE(camDetails.camID): ", GET_CAM_SPLINE_PHASE(camDetails.camID)) PRINTLN("GENERIC_PED_SCENE - (2) IS_CAM_RENDERING(camDetails.camID): ", IS_CAM_RENDERING(camDetails.camID)) // Allow ped switch IF GET_CAM_SPLINE_PHASE(camDetails.camID) > 0.5 AND IS_CAM_RENDERING(camDetails.camID) camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (2)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF ENDIF // Update final spline node IF camDetails.bOKToSwitchPed IF PLAYER_PED_ID() = camDetails.pedTo IF NOT IS_PED_INJURED(camDetails.pedTo) IF camDetails.iInterpCams >= 1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams - 1]) IF IS_PED_IN_ANY_VEHICLE(camDetails.pedTo) VEHICLE_INDEX vehPed = GET_VEHICLE_PED_IS_USING(camDetails.pedTo) VECTOR vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPed, GET_GAMEPLAY_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams - 1], vehPed, vTargetRelativePosition) ELSE VECTOR vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(camDetails.pedTo, GET_GAMEPLAY_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams - 1], camDetails.pedTo, vTargetRelativePosition) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams - 1], GET_GAMEPLAY_CAM_ROT()) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams - 1], GET_GAMEPLAY_CAM_FOV()) bFinalNodeUpdated = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ELSE PRINTLN("GENERIC_PED_SCENE - (3) camDetails.bOKToSwitchPed: ", camDetails.bOKToSwitchPed) // Allow ped switch IF NOT camDetails.bOKToSwitchPed camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (3)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF ELSE camDetails.bSplineComplete = TRUE ENDIF ENDIF ENDIF ELSE // Problem with camera so cleanup camDetails.bSplineComplete = TRUE #IF IS_DEBUG_BUILD SCRIPT_ASSERT("Cannot run spline camera as camera doesn't exist.") PRINTSTRING("\nCannot run spline camera as camera doesn't exist.")PRINTNL() #ENDIF ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup the camera IF camDetails.bSplineComplete IF DOES_CAM_EXIST(camDetails.camID) DESTROY_CAM(camDetails.camID) ENDIF IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR ENDIF DISABLE_CELLPHONE(camDetails.bIsPhoneDisabled) // //# 1524219 // CASCADE_SHADOWS_SET_AIRCRAFT_MODE(FALSE) // PRINTLN("CASCADE_SHADOWS_SET_AIRCRAFT_MODE(FALSE) called by ", GET_THIS_SCRIPT_NAME()) // Reset all the camera values incase they have to be used again camDetails.bSplineCreated = FALSE camDetails.bSplineActive = FALSE camDetails.bSplineComplete = FALSE camDetails.bOKToSwitchPed = FALSE camDetails.bPedSwitched = FALSE camDetails.bRun = FALSE camDetails.iInterpCams = 0 camDetails.iSplineDuration = 0 // SFX - Cleanup IF (g_sSelectorUI.iSFX_Sky != -1) AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PRINTLN("SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 ENDIF IF (g_sSelectorUI.iSFX_HeadDown != -1) AND g_sSelectorUI.iSFX_HeadDown_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) STOP_SOUND(g_sSelectorUI.iSFX_HeadDown) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_HeadDown) g_sSelectorUI.iSFX_HeadDown = -1 g_sSelectorUI.iSFX_HeadDown_ScriptHash = 0 ENDIF // Set the relative heading/pitch if the calling scipt used a custom camera // If specified out of range then do no set IF fDestCamRelativeHeading <= 360 AND fDestCamRelativeHeading >= - 360 SET_GAMEPLAY_CAM_RELATIVE_HEADING(fDestCamRelativeHeading) ENDIF IF fDestCamRelativePitch <= 360 AND fDestCamRelativePitch >= -360 SET_GAMEPLAY_CAM_RELATIVE_PITCH(fDestCamRelativePitch) ENDIF IF NOT (g_drunkCameraActive) STOP_GAMEPLAY_CAM_SHAKING(TRUE) SET_GAMEPLAY_CAM_MOTION_BLUR_SCALING_THIS_UPDATE(0) SET_GAMEPLAY_CAM_MAX_MOTION_BLUR_STRENGTH_THIS_UPDATE(0) ENDIF IF iInterpBackToGameDurationOverride = -1 IF bFinalNodeUpdated RENDER_SCRIPT_CAMS(FALSE, TRUE, 100) ELSE RENDER_SCRIPT_CAMS(FALSE, TRUE, 1000) ENDIF ELSE IF iInterpBackToGameDurationOverride = 0 RENDER_SCRIPT_CAMS(FALSE, FALSE) ELSE RENDER_SCRIPT_CAMS(FALSE, TRUE, iInterpBackToGameDurationOverride) ENDIF ENDIF IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) SET_ENTITY_VISIBLE(PLAYER_PED_ID(), TRUE) //FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE) SET_PED_CAN_BE_TARGETTED(PLAYER_PED_ID(), TRUE) IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) SET_ENTITY_COLLISION(PLAYER_PED_ID(), TRUE) ENDIF ENDIF SET_SKYSWOOP_STAGE(SKYSWOOP_NONE) // Reset proofs IF NOT IS_PED_INJURED(camDetails.pedFrom) SET_ENTITY_INVINCIBLE(camDetails.pedFrom, FALSE) ENDIF IF NOT IS_PED_INJURED(camDetails.pedTo) SET_ENTITY_INVINCIBLE(camDetails.pedTo, FALSE) ENDIF // Update the player timecycle modifier SET_CURRENT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(GET_CURRENT_PLAYER_PED_ENUM())) SET_SELECTOR_CAM_ACTIVE(FALSE) RETURN FALSE // Cam complete ENDIF // Hide the HUD HIDE_HUD_AND_RADAR_THIS_FRAME() //CLEAR_REMINDER_MESSAGE() //#1421176 RETURN TRUE // Cam still running ENDFUNC /// PURPOSE: Sets up a camera spline between player and scripted camera. /// /// NOTES: camDetails.camID will be initialised/activated in this func. /// Calling script should create a camera with valid coords/rot/fov etc. and assign it to camDetails.camTo. /// Uses bool values to control the process and then returns FALSE when the spline is complete, /// and the scripted camera becomes active. /// Should be called each frame from calling script until FALSE is returned. /// interpDurFinalCam sets the duration that it will take to interp to the final cam after running the spline FUNC BOOL RUN_CAM_SPLINE_FROM_PLAYER_TO_CAM(SELECTOR_CAM_STRUCT &camDetails, INT interpDurFinalCam = 400,INT iInterpToCamOverride = 0) INT iCamCount /////////////////////////////////////////////////////// /// Setup the spline nodes IF NOT camDetails.bSplineCreated IF NOT IS_PED_INJURED(PLAYER_PED_ID()) AND DOES_CAM_EXIST(camDetails.camTo) camDetails.iSplineDuration = 0 INT iDuration FLOAT fSkyNodeAngle, fMaxCamZ, fRotZ BOOL bPlayerVeh VEHICLE_INDEX vehPlayer VECTOR vCamRot VECTOR vTargetRelativePosition VECTOR vHorizontalDelta VECTOR vCamToPos = GET_CAM_COORD(camDetails.camTo) VECTOR vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) FLOAT fPedDist2D = GET_DISTANCE_BETWEEN_COORDS(vPlayerPos, vCamToPos, FALSE) FLOAT fPedDist3D = GET_DISTANCE_BETWEEN_COORDS(vPlayerPos, vCamToPos, TRUE) // Make sure the spline camera has been created IF NOT DOES_CAM_EXIST(camDetails.camID) camDetails.camID = CREATE_CAM("DEFAULT_SPLINE_CAMERA", FALSE) ENDIF // Destory all the previous interp cams FOR iCamCount = 0 TO NUM_SELECTOR_INTERP_CAMS-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR // Calculate the max node height fMaxCamZ = 450.0 IF vPlayerPos.z > vCamToPos.z // Player higher fMaxCamZ = FMAX(fMaxCamZ, vPlayerPos.z+25.0) ELSE // Cam higher fMaxCamZ = FMAX(fMaxCamZ, vCamToPos.z+25.0) ENDIF // Calculate the appropriate translation of the sky node towards the destination ped fSkyNodeAngle = 20.0 vHorizontalDelta = vCamToPos - vPlayerPos vHorizontalDelta.z = 0.0 vHorizontalDelta = GET_VECTOR_OF_LENGTH(vHorizontalDelta, FMIN(fMaxCamZ * TAN(fSkyNodeAngle), fPedDist2D / 3.0)) // Calculate the duration of the spline when up in the sky fPedDist3D = CLAMP(fPedDist3D, 50.0, 4000.0) iDuration = ROUND((fPedDist3D / ((4000.0 - 50.0) / (2000.0 - 1000.0)))+1000.0) // Grab vehicle state and the final rotation IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) vehPlayer = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) bPlayerVeh = TRUE ENDIF vCamRot = GET_CAM_ROT(camDetails.camTo) fRotZ = vCamRot.z IF fRotZ > 180.0 fRotZ -= 360.0 ENDIF vCamRot = GET_FINAL_RENDERED_CAM_ROT() // Initial camera behind the player camDetails.iInterpCams = 0 SET_CAM_FOV(camDetails.camID, GET_FINAL_RENDERED_CAM_FOV()) IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition) ELSE vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(PLAYER_PED_ID(), GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), vTargetRelativePosition) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], vCamRot) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 0, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 0 // Camera 5m above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition+<<0.0, 0.0, 15.0>>) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), <<0.0, 0.0, 5.0>>, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 // Camera in sky above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, <<0.0, 0.0, fMaxCamZ>> + vHorizontalDelta, FALSE) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), <<0.0, 0.0, fMaxCamZ>> + vHorizontalDelta, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 800, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 800 // Camera in sky above cam IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF SET_CAM_COORD(camDetails.camInterpIDs[camDetails.iInterpCams], GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(GET_CAM_COORD(camDetails.camTo), fRotZ, <<0.0, 0.0, fMaxCamZ>> - vHorizontalDelta)) SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, fRotZ >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], iDuration, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += iDuration // Camera 5m above cam IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF SET_CAM_COORD(camDetails.camInterpIDs[camDetails.iInterpCams], GET_CAM_COORD(camDetails.camTo)+<<0.0, 0.0, 5.0>>) SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, fRotZ>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 800, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 800 // Destination camera at camTo position IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF SET_CAM_COORD(camDetails.camInterpIDs[camDetails.iInterpCams], GET_CAM_COORD(camDetails.camTo)) SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], GET_CAM_ROT(camDetails.camTo)) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_CAM_FOV(camDetails.camTo)) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], interpDurFinalCam, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += interpDurFinalCam camDetails.bSplineCreated = TRUE ELSE // Problem with peds so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Activate the camera IF camDetails.bSplineCreated AND NOT camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) camDetails.bIsPhoneDisabled = IS_CELLPHONE_DISABLED() DISABLE_CELLPHONE(TRUE) // //# 1524219 // CASCADE_SHADOWS_SET_AIRCRAFT_MODE(TRUE) // PRINTLN("CASCADE_SHADOWS_SET_AIRCRAFT_MODE(TRUE) called by ", GET_THIS_SCRIPT_NAME()) IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 SET_CAM_ACTIVE(camDetails.camInterpIDs[iCamCount], TRUE) ENDFOR ENDIF TAKE_CONTROL_OF_TRANSITION(FALSE) SET_CAM_ACTIVE(camDetails.camID, TRUE) //SET_WIDESCREEN_BORDERS(TRUE, 500) if iInterpToCamOverride = 0 RENDER_SCRIPT_CAMS(TRUE, FALSE) else RENDER_SCRIPT_CAMS(TRUE, true,iInterpToCamOverride) endif // SFX - Heading up IF NOT g_sSelectorUI.bSFX_BlockAudioCalls IF camDetails.camType = SELECTOR_CAM_LONG_SPLINE PLAY_SOUND(-1, "CHARACTER_CHANGE_UP_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_UP_MASTER") IF (g_sSelectorUI.iSFX_Sky = -1) g_sSelectorUI.iSFX_Sky = GET_SOUND_ID() g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) ENDIF PLAY_SOUND(g_sSelectorUI.iSFX_Sky, "CHARACTER_CHANGE_SKY_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_SKY_MASTER ", g_sSelectorUI.iSFX_Sky) START_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") IF IS_AUDIO_SCENE_ACTIVE("CHARACTER_CHANGE_IN_SKY_SCENE") PRINTLN("CHARACTER_CHANGE_IN_SKY_SCENE...active!!!") ELSE PRINTLN("CHARACTER_CHANGE_IN_SKY_SCENE...is NOT active!!!") ENDIF ENDIF ENDIF camDetails.fMaxHeight = GET_SELECTOR_CAM_Z_HEIGHT(camDetails.camID) camDetails.iActivateTimer = GET_GAME_TIMER() camDetails.bSplineActive = TRUE SET_SELECTOR_CAM_ACTIVE(TRUE) ELSE // Problem with player so cleanup camDetails.bSplineComplete = TRUE ENDIF ELSE // Problem with camera so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup when the spline has finished IF camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) BOOL bOKToContinue = TRUE IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) bOKToContinue = FALSE ENDIF ENDFOR ENDIF PRINTLN("GENERIC_PED_SCENE - (4) bOKToContinue: ", bOKToContinue) IF bOKToContinue PRINTLN("GENERIC_PED_SCENE - (4) IS_CAM_INTERPOLATING(camDetails.camID): ", IS_CAM_INTERPOLATING(camDetails.camID)) IF IS_CAM_INTERPOLATING(camDetails.camID) // SFX - Heading down IF NOT g_sSelectorUI.bSFX_BlockAudioCalls IF camDetails.camType = SELECTOR_CAM_LONG_SPLINE FLOAT fCurrentHeight = GET_SELECTOR_CAM_Z_HEIGHT(camDetails.camID) IF (fCurrentHeight > camDetails.fMaxHeight) camDetails.fMaxHeight = fCurrentHeight ELIF (camDetails.fMaxHeight > fCurrentHeight+1.0) IF g_sSelectorUI.iSFX_HeadDown = -1 g_sSelectorUI.iSFX_HeadDown = GET_SOUND_ID() g_sSelectorUI.iSFX_HeadDown_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PLAY_SOUND(g_sSelectorUI.iSFX_HeadDown, "CHARACTER_CHANGE_DOWN_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_DOWN_MASTER") ENDIF IF (g_sSelectorUI.iSFX_Sky != -1) AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PRINTLN("SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 STOP_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") ENDIF ENDIF ENDIF ENDIF PRINTLN("GENERIC_PED_SCENE - (4) GET_CAM_SPLINE_PHASE(camDetails.camID): ", GET_CAM_SPLINE_PHASE(camDetails.camID)) PRINTLN("GENERIC_PED_SCENE - (4) IS_CAM_RENDERING(camDetails.camID): ", IS_CAM_RENDERING(camDetails.camID)) // Allow ped switch IF GET_CAM_SPLINE_PHASE(camDetails.camID) > 0.5 AND IS_CAM_RENDERING(camDetails.camID) camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (4)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF ENDIF ELSE camDetails.bSplineComplete = TRUE ENDIF ENDIF ELSE // Problem with camera so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF //////////////////////////////////////////////////////////////////// /// Cleanup the spline camera and activate scripted camera IF camDetails.bSplineComplete IF DOES_CAM_EXIST(camDetails.camID) DESTROY_CAM(camDetails.camID) ENDIF IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR ENDIF // Reset all the camera values incase they have to be used again camDetails.bSplineCreated = FALSE camDetails.bSplineActive = FALSE camDetails.bSplineComplete = FALSE camDetails.bOKToSwitchPed = FALSE camDetails.bPedSwitched = FALSE camDetails.bRun = FALSE camDetails.iInterpCams = 0 camDetails.iSplineDuration = 0 // SFX - Cleanup IF (g_sSelectorUI.iSFX_Sky != -1) AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PRINTLN("SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 ENDIF IF (g_sSelectorUI.iSFX_HeadDown != -1) AND g_sSelectorUI.iSFX_HeadDown_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) STOP_SOUND(g_sSelectorUI.iSFX_HeadDown) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_HeadDown) g_sSelectorUI.iSFX_HeadDown = -1 g_sSelectorUI.iSFX_HeadDown_ScriptHash = 0 ENDIF DISABLE_CELLPHONE(camDetails.bIsPhoneDisabled) // //# 1524219 // CASCADE_SHADOWS_SET_AIRCRAFT_MODE(FALSE) // PRINTLN("CASCADE_SHADOWS_SET_AIRCRAFT_MODE(FALSE) called by ", GET_THIS_SCRIPT_NAME()) // This func will end with the scripted camera being set to active IF DOES_CAM_EXIST(camDetails.camTo) SET_CAM_ACTIVE(camDetails.camTo, TRUE) ENDIF SET_SELECTOR_CAM_ACTIVE(FALSE) RETURN FALSE // Cam complete ENDIF // Hide the HUD HIDE_HUD_AND_RADAR_THIS_FRAME() //CLEAR_REMINDER_MESSAGE() //#1421176 RETURN TRUE // Cam still running ENDFUNC /// PURPOSE: Sets up a camera spline between player and a camera positioned in the sky /// /// NOTES: camDetails.camID will be initialised/activated in this func. /// Calling script should create a camera with valid coords/rot/fov etc. and assign it to camDetails.camSky. /// Uses bool values to control the process and then returns FALSE when the spline is complete, /// and the scripted camera becomes active. /// Should be called each frame from calling script until FALSE is returned. FUNC BOOL RUN_CAM_SPLINE_FROM_PLAYER_TO_SKY_CAM(SELECTOR_CAM_STRUCT &camDetails, FLOAT fSpeedMultiplier = 1.0) INT iCamCount /////////////////////////////////////////////////////// /// Setup the spline nodes IF NOT camDetails.bSplineCreated //IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF DOES_CAM_EXIST(camDetails.camSky) camDetails.iSplineDuration = 0 INT iDuration FLOAT fDist3D VECTOR vCamRot, vTargetRelativePosition BOOL bPlayerVeh VEHICLE_INDEX vehPlayer PED_INDEX pedPlayer IF IS_A_SPECTATOR_CAM_ACTIVE() = FALSE pedPlayer = PLAYER_PED_ID() ELSE pedPlayer = GET_SPECTATOR_CURRENT_FOCUS_PED() ENDIF // Make sure the spline camera has been created IF DOES_CAM_EXIST(camDetails.camID) DESTROY_CAM(camDetails.camID) ENDIF camDetails.camID = CREATE_CAM("DEFAULT_SPLINE_CAMERA", FALSE) // Destory all the previous interp cams FOR iCamCount = 0 TO NUM_SELECTOR_INTERP_CAMS-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR // Calculate the duration of the spline IF NOT IS_ENTITY_DEAD(pedPlayer) fDist3D = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(pedPlayer),GET_CAM_COORD(camDetails.camSky)) ELSE fDist3D = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(pedPlayer, FALSE),GET_CAM_COORD(camDetails.camSky)) ENDIF fDist3D = CLAMP(fDist3D, 50.0, 4000.0) iDuration = ROUND( (( fDist3D / ((4000.0 - 50.0) / (2000.0 - 1000.0)))+400.0) * fSpeedMultiplier ) // Grab vehicle state and the final rotation IF IS_PED_IN_ANY_VEHICLE(pedPlayer) vehPlayer = GET_VEHICLE_PED_IS_USING(pedPlayer) bPlayerVeh = TRUE ENDIF vCamRot = GET_FINAL_RENDERED_CAM_ROT() // Initial camera behind the player camDetails.iInterpCams = 0 SET_CAM_FOV(camDetails.camID, GET_FINAL_RENDERED_CAM_FOV()) IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition) ELSE vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(pedPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], pedPlayer, vTargetRelativePosition) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], vCamRot) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 0, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 0 // Camera 5m above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition+<<0.0, 0.0, 15.0>>) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], pedPlayer, <<0.0, 0.0, 5.0>>, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 // Camera 75m above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, <<0.0, 0.0, 75.0>>, FALSE) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], pedPlayer, <<0.0, 0.0, 75.0>>, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 // Camera in sky at the specified location // VECTOR EndCamPos = GET_CAM_COORD(camDetails.camSky) // EndCamPos.x = 0 VECTOR EndCamRos = GET_CAM_ROT(camDetails.camSky) EndCamRos.x = 21 //17 // 15 ADD_CAM_SPLINE_NODE(camDetails.camID, GET_CAM_COORD(camDetails.camSky), EndCamRos, iDuration) camDetails.iSplineDuration += iDuration camDetails.bSplineCreated = TRUE ELSE NET_NL()NET_PRINT("Problem with camera: camDetails.camSky doesn't exist ") // Problem with player ped or sky cam so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Activate the camera IF camDetails.bSplineCreated AND NOT camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) // IF NOT IS_PED_INJURED(PLAYER_PED_ID()) // SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) // camDetails.bIsPhoneDisabled = IS_CELLPHONE_DISABLED() IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 SET_CAM_ACTIVE(camDetails.camInterpIDs[iCamCount], TRUE) ENDFOR ENDIF SET_CAM_ACTIVE(camDetails.camID, TRUE) RENDER_SCRIPT_CAMS(TRUE, FALSE) // IF NETWORK_IS_IN_SESSION() // camDetails.iMPActivateTimer = // ELSE // camDetails.iMPActivateTimer = GET_GAME_TIMER() // ENDIF // SFX - Heading up IF NOT g_sSelectorUI.bSFX_BlockAudioCalls PLAY_SOUND(-1, "CHARACTER_CHANGE_UP_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_UP_MASTER") IF (g_sSelectorUI.iSFX_Sky = -1) g_sSelectorUI.iSFX_Sky = GET_SOUND_ID() g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) ENDIF PLAY_SOUND(g_sSelectorUI.iSFX_Sky, "CHARACTER_CHANGE_SKY_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_SKY_MASTER ", g_sSelectorUI.iSFX_Sky) START_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") IF IS_AUDIO_SCENE_ACTIVE("CHARACTER_CHANGE_IN_SKY_SCENE") PRINTLN("CHARACTER_CHANGE_IN_SKY_SCENE...active!!!") ELSE PRINTLN("CHARACTER_CHANGE_IN_SKY_SCENE...is NOT active!!!") ENDIF ENDIF camDetails.fMaxHeight = GET_SELECTOR_CAM_Z_HEIGHT(camDetails.camID) camDetails.bSplineActive = TRUE SET_SELECTOR_CAM_ACTIVE(TRUE) // ELSE // NET_NL()NET_PRINT("Problem with Transition camera: Player is injured") // Problem with player so cleanup // camDetails.bSplineComplete = TRUE // ENDIF ELSE NET_NL()NET_PRINT("Problem with Transition camera: camDetails.camID doesn't exist ") // Problem with camera so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup when the spline has finished IF camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) BOOL bOKToContinue = TRUE IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) bOKToContinue = FALSE ENDIF ENDFOR ENDIF PRINTLN("GENERIC_PED_SCENE - (5) bOKToContinue: ", bOKToContinue) IF bOKToContinue PRINTLN("GENERIC_PED_SCENE - (5) IS_CAM_INTERPOLATING(camDetails.camID): ", IS_CAM_INTERPOLATING(camDetails.camID)) IF IS_CAM_INTERPOLATING(camDetails.camID) PRINTLN("GENERIC_PED_SCENE - (5) GET_CAM_SPLINE_PHASE(camDetails.camID): ", GET_CAM_SPLINE_PHASE(camDetails.camID)) PRINTLN("GENERIC_PED_SCENE - (5) IS_CAM_RENDERING(camDetails.camID): ", IS_CAM_RENDERING(camDetails.camID)) // Allow ped switch IF GET_CAM_SPLINE_PHASE(camDetails.camID) > 0.5 AND IS_CAM_RENDERING(camDetails.camID) camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (5)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF ENDIF ELSE NET_NL()NET_PRINT("RUN_CAM_SPLINE_FROM_PLAYER_TO_SKY_CAM: IS_CAM_INTERPOLATING = FALSE Completed Spline ") camDetails.bSplineComplete = TRUE ENDIF ENDIF ELSE NET_NL()NET_PRINT("Problem with Transition camera: camDetails.camID doesn't exist second ") // Problem with camera so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup the camera IF camDetails.bSplineComplete NET_NL()NET_PRINT("Cleanup the Transition camera") IF DOES_CAM_EXIST(camDetails.camID) // copy over details to the camSky IF DOES_CAM_EXIST(camDetails.camSky) g_TransitionData.vSkyCamPos = GET_CAM_COORD(camDetails.camID) g_TransitionData.vSkyCamRot = GET_CAM_ROT(camDetails.camID) g_TransitionData.fSkyCamFOV = GET_CAM_FOV(camDetails.camID) SET_CAM_COORD(camDetails.camSky, g_TransitionData.vSkyCamPos) SET_CAM_ROT(camDetails.camSky, g_TransitionData.vSkyCamRot) SET_CAM_FOV(camDetails.camSky, g_TransitionData.fSkyCamFOV) ENDIF DESTROY_CAM(camDetails.camID) ENDIF IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR ENDIF // Reset all the camera values incase they have to be used again camDetails.bSplineCreated = FALSE camDetails.bSplineActive = FALSE camDetails.bSplineComplete = FALSE camDetails.bOKToSwitchPed = FALSE camDetails.bPedSwitched = FALSE camDetails.bRun = FALSE camDetails.iInterpCams = 0 camDetails.iSplineDuration = 0 // SFX - Cleanup IF (g_sSelectorUI.iSFX_Sky != -1) AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PRINTLN("SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 ENDIF // Reset the gameplay cam state SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) IF NOT (g_drunkCameraActive) STOP_GAMEPLAY_CAM_SHAKING(TRUE) SET_GAMEPLAY_CAM_MOTION_BLUR_SCALING_THIS_UPDATE(0) SET_GAMEPLAY_CAM_MAX_MOTION_BLUR_STRENGTH_THIS_UPDATE(0) ENDIF // This func will end with the scripted camera being set to active IF DOES_CAM_EXIST(camDetails.camSky) SET_CAM_ACTIVE(camDetails.camSky, TRUE) ENDIF SET_SELECTOR_CAM_ACTIVE(FALSE) RETURN FALSE // Cam complete ENDIF // Hide the HUD HIDE_HUD_AND_RADAR_THIS_FRAME() //CLEAR_REMINDER_MESSAGE() //#1421176 RETURN TRUE // Cam still running ENDFUNC /// PURPOSE: Sets up a camera spline between the active camer which should be in the sky and the player /// /// NOTES: camDetails.camID will be initialised/activated in this func. /// Calling script should ensure that camDetails.camSky is the current active camera. /// Uses bool values to control the process and then returns FALSE when the spline is complete. /// Should be called each frame from calling script until FALSE is returned. FUNC BOOL RUN_CAM_SPLINE_FROM_SKY_TO_PLAYER(SELECTOR_CAM_STRUCT &camDetails, FLOAT fPlayerLocationHeight) BOOL bFinalNodeUpdated INT iCamCount VECTOR vSkyCamCoord = <<99999, 99999, 99999>> /////////////////////////////////////////////////////// /// Setup the spline nodes IF NOT camDetails.bSplineCreated IF NOT IS_PED_INJURED(PLAYER_PED_ID()) AND DOES_CAM_EXIST(camDetails.camSky) camDetails.iSplineDuration = 0 INT iDuration FLOAT fDist3D, fRotZ VECTOR vCamPos, vPlayerPos, vTargetRelativePosition BOOL bPlayerVeh VEHICLE_INDEX vehPlayer // Make sure the spline camera has been created IF DOES_CAM_EXIST(camDetails.camID) DESTROY_CAM(camDetails.camID) ENDIF camDetails.camID = CREATE_CAM("DEFAULT_SPLINE_CAMERA", FALSE) // Destory all the previous interp cams FOR iCamCount = 0 TO NUM_SELECTOR_INTERP_CAMS-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR // Calculate the duration of the spline vCamPos = GET_CAM_COORD(camDetails.camSky) IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) ELSE vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE) ENDIF fDist3D = GET_DISTANCE_BETWEEN_COORDS(vPlayerPos, vCamPos) fDist3D = CLAMP(fDist3D, 50.0, 4000.0) iDuration = ROUND( (( fDist3D / ((4000.0 - 50.0) / (2000.0 - 1000.0)))+1000.0)) // Grab vehicle state and the final rotation IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) vehPlayer = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) bPlayerVeh = TRUE fRotZ = GET_ENTITY_HEADING(vehPlayer) IF fRotZ > 180.0 fRotZ -= 360.0 ENDIF ELSE fRotZ = GET_ENTITY_HEADING(PLAYER_PED_ID()) IF fRotZ > 180.0 fRotZ -= 360.0 ENDIF ENDIF // Initial camera is a copy of the active camera camDetails.iInterpCams = 0 SET_CAM_FOV(camDetails.camID, GET_CAM_FOV(camDetails.camSky)) ADD_CAM_SPLINE_NODE(camDetails.camID, GET_CAM_COORD(camDetails.camSky), GET_CAM_ROT(camDetails.camSky), 0, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iSplineDuration += 0 // Camera in sky above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, << vPlayerPos.x, vPlayerPos.y, vCamPos.z >>) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition, FALSE) ELSE vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(PLAYER_PED_ID(), << vPlayerPos.x, vPlayerPos.y, vCamPos.z >>) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), vTargetRelativePosition, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, fRotZ >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], iDuration, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += iDuration // Camera 85m above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, <<0.0, 0.0, 85.0>>, FALSE) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), <<0.0, 0.0, 85.0>>, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, fRotZ>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 800, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 800 // Camera 5m above player IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPlayer, GET_FINAL_RENDERED_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, vTargetRelativePosition+<<0.0, 0.0, 15.0>>) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), <<0.0, 0.0, 5.0>>, FALSE) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, fRotZ>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 800, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 800 // Destination camera behind the ped IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF IF bPlayerVeh ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], vehPlayer, GET_OFFSET_FOR_DEST_CAM(PLAYER_PED_ID())) ELSE ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams], PLAYER_PED_ID(), GET_OFFSET_FOR_DEST_CAM(PLAYER_PED_ID())) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], << -0.951428, 0.0, fRotZ >>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 camDetails.bSplineCreated = TRUE ELSE // Problem with player ped so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Activate the camera IF camDetails.bSplineCreated AND NOT camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) IF DOES_CAM_EXIST(camDetails.camSky) DESTROY_CAM(camDetails.camSky) ENDIF // IF NOT IS_PED_INJURED(PLAYER_PED_ID()) // SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 SET_CAM_ACTIVE(camDetails.camInterpIDs[iCamCount], TRUE) ENDFOR ENDIF SET_CAM_ACTIVE(camDetails.camID, TRUE) RENDER_SCRIPT_CAMS(TRUE, FALSE) // SFX - Heading down IF NOT g_sSelectorUI.bSFX_BlockAudioCalls PLAY_SOUND(-1, "CHARACTER_CHANGE_DOWN_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_DOWN_MASTER") IF g_sSelectorUI.iSFX_Sky != -1 AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PRINTLN("SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 STOP_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") ENDIF ENDIF camDetails.bSplineActive = TRUE SET_SELECTOR_CAM_ACTIVE(TRUE) // Process player timecycle modifier IF GET_ENTITY_MODEL(PLAYER_PED_ID()) = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) SET_NEXT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(CHAR_MICHAEL)) ELIF GET_ENTITY_MODEL(PLAYER_PED_ID()) = GET_PLAYER_PED_MODEL(CHAR_TREVOR) SET_NEXT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(CHAR_TREVOR)) ELIF GET_ENTITY_MODEL(PLAYER_PED_ID()) = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN) SET_NEXT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(CHAR_FRANKLIN)) ELSE SET_NEXT_PLAYER_TCMODIFIER("") ENDIF SET_PLAYER_TCMODIFIER_TRANSITION(0.0) // ELSE // // Problem with player so cleanup // camDetails.bSplineComplete = TRUE // ENDIF ELSE // Problem with camera so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup when the spline has finished IF camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) // Update the player timecycle modifier SET_PLAYER_TCMODIFIER_TRANSITION(GET_CAM_SPLINE_PHASE(camDetails.camID)) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF GET_ROOM_KEY_FROM_ENTITY(PLAYER_PED_ID()) != 0 vSkyCamCoord = GET_CAM_COORD(camDetails.camID) IF vSkyCamCoord.z <= 0 vSkyCamCoord.z = 99999 ENDIF //NET_NL()NET_PRINT(" - CHECK B - PLAYER IN INTERIOR - vSkyCamCoord.z = ")NET_PRINT_FLOAT(vSkyCamCoord.z)NET_PRINT(" fPlayerLocationHeight = ")NET_PRINT_FLOAT(fPlayerLocationHeight)NET_NL() ENDIF //NET_NL()NET_PRINT(" - CHECK B - RoomKey = ")NET_PRINT_INT(GET_ROOM_KEY_FROM_ENTITY(PLAYER_PED_ID()))NET_NL() ENDIF IF vSkyCamCoord.z < fPlayerLocationHeight camDetails.bSplineComplete = TRUE NET_PRINT("vSkyCamCoord.z < fPlayerLocationHeight - camDetails.bSplineComplete = TRUE") ELSE BOOL bOKToContinue = TRUE IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) bOKToContinue = FALSE ENDIF ENDFOR ENDIF IF bOKToContinue IF IS_CAM_INTERPOLATING(camDetails.camID) // Update final spline node IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF camDetails.iInterpCams >= 1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams - 1]) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) VEHICLE_INDEX vehPed = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) VECTOR vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPed, GET_GAMEPLAY_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams - 1], vehPed, vTargetRelativePosition) ELSE VECTOR vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(PLAYER_PED_ID(), GET_GAMEPLAY_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams - 1], PLAYER_PED_ID(), vTargetRelativePosition) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams - 1], GET_GAMEPLAY_CAM_ROT()) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams - 1], GET_GAMEPLAY_CAM_FOV()) bFinalNodeUpdated = TRUE ENDIF ENDIF ENDIF ELSE camDetails.bSplineComplete = TRUE ENDIF ENDIF ENDIF ELSE // Problem with camera so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup the camera IF camDetails.bSplineComplete IF DOES_CAM_EXIST(camDetails.camID) DESTROY_CAM(camDetails.camID) ENDIF IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR ENDIF // Reset all the camera values incase they have to be used again camDetails.bSplineCreated = FALSE camDetails.bSplineActive = FALSE camDetails.bSplineComplete = FALSE camDetails.bOKToSwitchPed = FALSE camDetails.bPedSwitched = FALSE camDetails.bRun = FALSE camDetails.iInterpCams = 0 camDetails.iSplineDuration = 0 // SFX - Cleanup IF (g_sSelectorUI.iSFX_Sky != -1) AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PRINTLN("SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 ENDIF IF (g_sSelectorUI.iSFX_HeadDown != -1) AND g_sSelectorUI.iSFX_HeadDown_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) STOP_SOUND(g_sSelectorUI.iSFX_HeadDown) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_HeadDown) g_sSelectorUI.iSFX_HeadDown = -1 g_sSelectorUI.iSFX_HeadDown_ScriptHash = 0 ENDIF SET_GAMEPLAY_CAM_RELATIVE_HEADING(g_SpawnData.fCamHeading) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) IF NOT (g_drunkCameraActive) STOP_GAMEPLAY_CAM_SHAKING(TRUE) SET_GAMEPLAY_CAM_MOTION_BLUR_SCALING_THIS_UPDATE(0) SET_GAMEPLAY_CAM_MAX_MOTION_BLUR_STRENGTH_THIS_UPDATE(0) ENDIF g_SpawnData.fCamHeading = 0.0 //Check if we should do the game cam interp BOOL bGameCamInterp = FALSE IF vSkyCamCoord.z = 99999 bGameCamInterp = TRUE ENDIF IF bFinalNodeUpdated RENDER_SCRIPT_CAMS(FALSE, bGameCamInterp, 100, TRUE, TRUE) ELSE RENDER_SCRIPT_CAMS(FALSE, bGameCamInterp, 1000, TRUE, TRUE) ENDIF IF NOT NETWORK_IS_GAME_IN_PROGRESS()// only do this in sp - added by NeilF 27/06/2011 IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) SET_PLAYER_INVINCIBLE(PLAYER_ID(), FALSE) SET_ENTITY_VISIBLE(PLAYER_PED_ID(), TRUE) //FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE) SET_PED_CAN_BE_TARGETTED(PLAYER_PED_ID(), TRUE) IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) SET_ENTITY_COLLISION(PLAYER_PED_ID(), TRUE) ENDIF ClearInsideDisplacedInteriorFlag() ENDIF ENDIF SET_SELECTOR_CAM_ACTIVE(FALSE) // Update the player timecycle modifier SET_CURRENT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(GET_CURRENT_PLAYER_PED_ENUM())) RETURN FALSE // Cam complete ENDIF // Hide the HUD HIDE_HUD_AND_RADAR_THIS_FRAME() //CLEAR_REMINDER_MESSAGE() //#1421176 RETURN TRUE // Cam still running ENDFUNC /// PURPOSE: Sets up a camera spline between player and a camera positioned in the sky /// /// NOTES: camDetails.camID will be initialised/activated in this func. /// Calling script should create a camera with valid coords/rot/fov etc. and assign it to camDetails.camSky. /// Uses bool values to control the process and then returns FALSE when the spline is complete, /// and the scripted camera becomes active. /// Should be called each frame from calling script until FALSE is returned. FUNC BOOL RUN_CAM_SPLINE_FROM_RENDERED_CAM_TO_SKY_CAM(SELECTOR_CAM_STRUCT &camDetails, FLOAT fSpeedMultiplier = 1.0) INT iCamCount /////////////////////////////////////////////////////// /// Setup the spline nodes IF NOT camDetails.bSplineCreated //IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF DOES_CAM_EXIST(camDetails.camSky) camDetails.iSplineDuration = 0 INT iDuration FLOAT fDist3D VECTOR vCamRot // Make sure the spline camera has been created IF DOES_CAM_EXIST(camDetails.camID) DESTROY_CAM(camDetails.camID) ENDIF camDetails.camID = CREATE_CAM("DEFAULT_SPLINE_CAMERA", FALSE) // Destory all the previous interp cams FOR iCamCount = 0 TO NUM_SELECTOR_INTERP_CAMS-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR // Calculate the duration of the spline fDist3D = GET_DISTANCE_BETWEEN_COORDS(GET_FINAL_RENDERED_CAM_COORD(),GET_CAM_COORD(camDetails.camSky)) fDist3D = CLAMP(fDist3D, 50.0, 4000.0) iDuration = ROUND( (( fDist3D / ((4000.0 - 50.0) / (2000.0 - 1000.0)))+400.0) * fSpeedMultiplier ) // Grab the final rotation vCamRot = GET_FINAL_RENDERED_CAM_ROT() // Initial camera is a copy of the final rendered cam camDetails.iInterpCams = 0 SET_CAM_FOV(camDetails.camID, GET_FINAL_RENDERED_CAM_FOV()) IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF SET_CAM_COORD(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_COORD()) SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_ROT()) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 0, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 0 // Camera 5m above cam IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF SET_CAM_COORD(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_COORD() + <<0.0, 0.0, 5.0>>) SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 // Camera 75m above cam IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams]) camDetails.camInterpIDs[camDetails.iInterpCams] = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE) ENDIF SET_CAM_COORD(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_COORD() + <<0.0, 0.0, 75.0>>) SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams], <<-87.5, 0.0, vCamRot.z>>) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams], GET_FINAL_RENDERED_CAM_FOV()) ADD_CAM_SPLINE_NODE_USING_CAMERA(camDetails.camID, camDetails.camInterpIDs[camDetails.iInterpCams], 400, CAM_SPLINE_NODE_SMOOTH_ROT) camDetails.iInterpCams++ camDetails.iSplineDuration += 400 // Camera in sky at the specified location // VECTOR EndCamPos = GET_CAM_COORD(camDetails.camSky) // EndCamPos.x = 0 VECTOR EndCamRos = GET_CAM_ROT(camDetails.camSky) EndCamRos.x = 17 // 15 ADD_CAM_SPLINE_NODE(camDetails.camID, GET_CAM_COORD(camDetails.camSky), EndCamRos, iDuration) camDetails.iSplineDuration += iDuration camDetails.bSplineCreated = TRUE ELSE NET_NL()NET_PRINT("Problem with camera: camDetails.camSky doesn't exist ") // Problem with player ped or sky cam so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Activate the camera IF camDetails.bSplineCreated AND NOT camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) // IF NOT IS_PED_INJURED(PLAYER_PED_ID()) // SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) // camDetails.bIsPhoneDisabled = IS_CELLPHONE_DISABLED() IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 SET_CAM_ACTIVE(camDetails.camInterpIDs[iCamCount], TRUE) ENDFOR ENDIF SET_CAM_ACTIVE(camDetails.camID, TRUE) RENDER_SCRIPT_CAMS(TRUE, FALSE) IF NETWORK_IS_IN_SESSION() camDetails.iActivateTimerNetwork = GET_NETWORK_TIME() ELSE camDetails.iActivateTimer = GET_GAME_TIMER() ENDIF // SFX - Heading up IF NOT g_sSelectorUI.bSFX_BlockAudioCalls PLAY_SOUND(-1, "CHARACTER_CHANGE_UP_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_UP_MASTER") IF (g_sSelectorUI.iSFX_Sky = -1) g_sSelectorUI.iSFX_Sky = GET_SOUND_ID() g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) ENDIF PLAY_SOUND(g_sSelectorUI.iSFX_Sky, "CHARACTER_CHANGE_SKY_MASTER") PRINTLN("SWITCH UI - playing sound: CHARACTER_CHANGE_SKY_MASTER ", g_sSelectorUI.iSFX_Sky) START_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") IF IS_AUDIO_SCENE_ACTIVE("CHARACTER_CHANGE_IN_SKY_SCENE") PRINTLN("CHARACTER_CHANGE_IN_SKY_SCENE...active!!!") ELSE PRINTLN("CHARACTER_CHANGE_IN_SKY_SCENE...is NOT active!!!") ENDIF ENDIF camDetails.fMaxHeight = GET_SELECTOR_CAM_Z_HEIGHT(camDetails.camID) camDetails.bSplineActive = TRUE SET_SELECTOR_CAM_ACTIVE(TRUE) // ELSE // NET_NL()NET_PRINT("Problem with Transition camera: Player is injured") // Problem with player so cleanup // camDetails.bSplineComplete = TRUE // ENDIF ELSE NET_NL()NET_PRINT("Problem with Transition camera: camDetails.camID doesn't exist ") // Problem with camera so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup when the spline has finished IF camDetails.bSplineActive IF DOES_CAM_EXIST(camDetails.camID) BOOL bOKToContinue = TRUE IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF NOT DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) bOKToContinue = FALSE ENDIF ENDFOR ENDIF PRINTLN("GENERIC_PED_SCENE - (6) bOKToContinue: ", bOKToContinue) IF bOKToContinue PRINTLN("GENERIC_PED_SCENE - (6) IS_CAM_INTERPOLATING(camDetails.camID): ", IS_CAM_INTERPOLATING(camDetails.camID)) IF IS_CAM_INTERPOLATING(camDetails.camID) PRINTLN("GENERIC_PED_SCENE - (6) GET_CAM_SPLINE_PHASE(camDetails.camID): ", GET_CAM_SPLINE_PHASE(camDetails.camID)) PRINTLN("GENERIC_PED_SCENE - (6) IS_CAM_RENDERING(camDetails.camID): ", IS_CAM_RENDERING(camDetails.camID)) // Allow ped switch IF GET_CAM_SPLINE_PHASE(camDetails.camID) > 0.5 AND IS_CAM_RENDERING(camDetails.camID) camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (6)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF ENDIF ELSE NET_NL()NET_PRINT("RUN_CAM_SPLINE_FROM_PLAYER_TO_SKY_CAM: IS_CAM_INTERPOLATING = FALSE Completed Spline ") camDetails.bSplineComplete = TRUE ENDIF ENDIF ELSE NET_NL()NET_PRINT("Problem with Transition camera: camDetails.camID doesn't exist second ") // Problem with camera so cleanup camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup the camera IF camDetails.bSplineComplete NET_NL()NET_PRINT("Cleanup the Transition camera") IF DOES_CAM_EXIST(camDetails.camID) // copy over details to the camSky IF DOES_CAM_EXIST(camDetails.camSky) g_TransitionData.vSkyCamPos = GET_CAM_COORD(camDetails.camID) g_TransitionData.vSkyCamRot = GET_CAM_ROT(camDetails.camID) g_TransitionData.fSkyCamFOV = GET_CAM_FOV(camDetails.camID) SET_CAM_COORD(camDetails.camSky, g_TransitionData.vSkyCamPos) SET_CAM_ROT(camDetails.camSky, g_TransitionData.vSkyCamRot) SET_CAM_FOV(camDetails.camSky, g_TransitionData.fSkyCamFOV) ENDIF DESTROY_CAM(camDetails.camID) ENDIF IF camDetails.iInterpCams > 0 FOR iCamCount = 0 TO camDetails.iInterpCams-1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[iCamCount]) DESTROY_CAM(camDetails.camInterpIDs[iCamCount]) ENDIF ENDFOR ENDIF // Reset all the camera values incase they have to be used again camDetails.bSplineCreated = FALSE camDetails.bSplineActive = FALSE camDetails.bSplineComplete = FALSE camDetails.bOKToSwitchPed = FALSE camDetails.bPedSwitched = FALSE camDetails.bRun = FALSE camDetails.iInterpCams = 0 camDetails.iSplineDuration = 0 // SFX - Cleanup IF (g_sSelectorUI.iSFX_Sky != -1) AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PRINTLN("SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 ENDIF // Reset the gameplay cam state SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) IF NOT (g_drunkCameraActive) STOP_GAMEPLAY_CAM_SHAKING(TRUE) SET_GAMEPLAY_CAM_MOTION_BLUR_SCALING_THIS_UPDATE(0) SET_GAMEPLAY_CAM_MAX_MOTION_BLUR_STRENGTH_THIS_UPDATE(0) ENDIF // This func will end with the scripted camera being set to active IF DOES_CAM_EXIST(camDetails.camSky) SET_CAM_ACTIVE(camDetails.camSky, TRUE) ENDIF SET_SELECTOR_CAM_ACTIVE(FALSE) RETURN FALSE // Cam complete ENDIF // Hide the HUD HIDE_HUD_AND_RADAR_THIS_FRAME() //CLEAR_REMINDER_MESSAGE() //#1421176 RETURN TRUE // Cam still running ENDFUNC #IF IS_DEBUG_BUILD FUNC STRING DEBUG_GET_PLAYER_SWITCH_STATE(SWITCH_STATE eState) SWITCH eState CASE SWITCH_STATE_INTRO RETURN "SWITCH_STATE_INTRO" CASE SWITCH_STATE_PREP_DESCENT RETURN "SWITCH_STATE_PREP_DESCENT" CASE SWITCH_STATE_PREP_FOR_CUT RETURN "SWITCH_STATE_PREP_FOR_CUT" CASE SWITCH_STATE_JUMPCUT_ASCENT RETURN "SWITCH_STATE_JUMPCUT_ASCENT" CASE SWITCH_STATE_WAITFORINPUT_INTRO RETURN "SWITCH_STATE_WAITFORINPUT_INTRO" CASE SWITCH_STATE_WAITFORINPUT RETURN "SWITCH_STATE_WAITFORINPUT" CASE SWITCH_STATE_WAITFORINPUT_OUTRO RETURN "SWITCH_STATE_WAITFORINPUT_OUTRO" CASE SWITCH_STATE_PAN RETURN "SWITCH_STATE_PAN" CASE SWITCH_STATE_JUMPCUT_DESCENT RETURN "SWITCH_STATE_JUMPCUT_DESCENT" CASE SWITCH_STATE_OUTRO_HOLD RETURN "SWITCH_STATE_OUTRO_HOLD" CASE SWITCH_STATE_OUTRO_SWOOP RETURN "SWITCH_STATE_OUTRO_SWOOP" CASE SWITCH_STATE_ESTABLISHING_SHOT RETURN "SWITCH_STATE_ESTABLISHING_SHOT" CASE SWITCH_STATE_FINISHED RETURN "SWITCH_STATE_FINISHED" ENDSWITCH RETURN "" ENDFUNC #ENDIF PROC naughty_SET_VEHICLE_LIMIT_SPEED_WHEN_PLAYER_INACTIVE(VEHICLE_INDEX VehicleIndex, BOOL bVal) IF IS_ENTITY_A_MISSION_ENTITY(VehicleIndex) SET_VEHICLE_LIMIT_SPEED_WHEN_PLAYER_INACTIVE(VehicleIndex, bVal) ELSE SET_ENTITY_AS_MISSION_ENTITY(VehicleIndex, TRUE, FALSE) SET_VEHICLE_LIMIT_SPEED_WHEN_PLAYER_INACTIVE(VehicleIndex, bVal) SET_VEHICLE_AS_NO_LONGER_NEEDED(VehicleIndex) ENDIF ENDPROC /// PURPOSE: FUNC BOOL PRIVATE_RunPlayerSwitch(SELECTOR_CAM_STRUCT &camDetails, CAMERA_INDEX camTo, SWITCH_TYPE eSwitchType = SWITCH_TYPE_AUTO, INT iSwitchFlags = 0, FLOAT fDestCamRelativePitch = 999.0,FLOAT fDestCamRelativeHeading = 999.0, BOOL bPauseBeforePan = FALSE, BOOL bPauseBeforeOutro = FALSE, STRING establishingShotName = NULL, EULER_ROT_ORDER RotOrder = EULER_YXZ, BOOL bMultiplayerSwitch = FALSE, BOOL bOverrideShortRangeSwitchStyle = FALSE, SHORT_SWITCH_STYLE shortRangeSwitchStyle = SHORT_SWITCH_STYLE_ROTATION) SWITCH_FLAGS eSwitchFlags = INT_TO_ENUM(SWITCH_FLAGS, iSwitchFlags) /////////////////////////////////////////////////////// /// Activate the camera IF NOT camDetails.bSplineActive //#1362143 & #1374002 IF IS_SAFE_TO_START_PLAYER_SWITCH() IF NOT bMultiplayerSwitch camDetails.pedFrom = PLAYER_PED_ID() //Always from player ENDIF IF (NOT IS_PED_INJURED(camDetails.pedFrom) OR bMultiplayerSwitch) AND NOT IS_PED_INJURED(camDetails.pedTo) camDetails.iSplineDuration = 0 //Switch starting. Block lead-ins from streaming in. g_bBlockTriggerSceneLoadDuringSwitch = TRUE CPRINTLN(DEBUG_SWITCH, "Player switch starting. Setting lead-in load block flag.") IF NOT bMultiplayerSwitch //926174 IF IS_PED_SITTING_IN_ANY_VEHICLE(camDetails.pedFrom) VEHICLE_INDEX vehFrom = GET_VEHICLE_PED_IS_IN(camDetails.pedFrom) naughty_SET_VEHICLE_LIMIT_SPEED_WHEN_PLAYER_INACTIVE(vehFrom, FALSE) ENDIF SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) SET_ENTITY_INVINCIBLE(camDetails.pedFrom, TRUE) SET_ENTITY_INVINCIBLE(camDetails.pedTo, TRUE) ENDIF camDetails.bIsPhoneDisabled = IS_CELLPHONE_DISABLED() DISABLE_CELLPHONE(TRUE) // //# 1524219 // CASCADE_SHADOWS_SET_AIRCRAFT_MODE(TRUE) // CPRINTLN(DEBUG_SWITCH, "CASCADE_SHADOWS_SET_AIRCRAFT_MODE(TRUE) called by ", GET_THIS_SCRIPT_NAME()) IF bPauseBeforePan eSwitchFlags |= SWITCH_FLAG_PAUSE_BEFORE_PAN ENDIF IF bPauseBeforeOutro eSwitchFlags |= SWITCH_FLAG_PAUSE_BEFORE_OUTRO ENDIF IF DOES_CAM_EXIST(camTo) OR NOT IS_STRING_NULL_OR_EMPTY(establishingShotName) eSwitchFlags |= SWITCH_FLAG_SKIP_OUTRO ENDIF IF IS_TRANSITION_ACTIVE() eSwitchFlags |= SWITCH_FLAG_SKIP_INTRO ENDIF IF NOT IS_PLAYER_SWITCH_IN_PROGRESS() // TAKE_CONTROL_OF_TRANSITION(FALSE) // camDetails.bTakenContolOfTransition = TRUE START_PLAYER_SWITCH(camDetails.pedFrom, camDetails.pedTo, eSwitchFlags, eSwitchType) IF bOverrideShortRangeSwitchStyle SET_PLAYER_SHORT_SWITCH_STYLE(shortRangeSwitchStyle) ENDIF #IF IS_DEBUG_BUILD VECTOR vPedFromCoords = GET_ENTITY_COORDS(camDetails.pedFrom) VECTOR vPedToCoords = GET_ENTITY_COORDS(camDetails.pedTo) CPRINTLN(DEBUG_SWITCH, "<", GET_THIS_SCRIPT_NAME(), ":fc ", GET_FRAME_COUNT(), "> START_PLAYER_SWITCH(", vPedFromCoords, ", ", vPedToCoords, ", ", Get_String_From_Switch_Flags(eSwitchFlags), ", ", Get_String_From_Switch_Type(eSwitchType), ")") #ENDIF SWITCH GET_PLAYER_PED_ENUM(camDetails.pedFrom) CASE CHAR_MICHAEL ANIMPOSTFX_STOP_AND_FLUSH_REQUESTS("SwitchHUDMichaelOut") BREAK CASE CHAR_FRANKLIN ANIMPOSTFX_STOP_AND_FLUSH_REQUESTS("SwitchHUDMichaelOut") BREAK CASE CHAR_TREVOR ANIMPOSTFX_STOP_AND_FLUSH_REQUESTS("SwitchHUDTrevorOut") BREAK ENDSWITCH ANIMPOSTFX_STOP_AND_FLUSH_REQUESTS("SwitchHUDOut") ELSE IF IS_SWITCH_TO_MULTI_FIRSTPART_FINISHED() SWITCH_TO_MULTI_SECONDPART(camDetails.pedTo) #IF USE_TU_CHANGES SET_SKYSWOOP_STAGE(SKYSWOOP_NONE) #ENDIF #IF IS_DEBUG_BUILD VECTOR vPedFromCoords = GET_ENTITY_COORDS(camDetails.pedFrom) VECTOR vPedToCoords = GET_ENTITY_COORDS(camDetails.pedTo) CPRINTLN(DEBUG_SWITCH, "<", GET_THIS_SCRIPT_NAME(), ":fc ", GET_FRAME_COUNT(), "> SWITCH_TO_MULTI_SECONDPART(", vPedFromCoords, ", ", vPedToCoords, ", ", Get_String_From_Switch_Flags(eSwitchFlags), ", ", Get_String_From_Switch_Type(eSwitchType), ")") #ENDIF ELSE #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_SWITCH, "\nCannot start a non-multipart switch while a switch is in progress.") CASSERTLN(DEBUG_SWITCH, "Cannot start a non-multipart switch while a switch is in progress.") #ENDIF RETURN FALSE ENDIF ENDIF IF DOES_CAM_EXIST(camTo) IF GET_IDEAL_PLAYER_SWITCH_TYPE(GET_ENTITY_COORDS(camDetails.pedFrom), GET_ENTITY_COORDS(camDetails.pedTo)) <> SWITCH_TYPE_SHORT #IF IS_DEBUG_BUILD //954886 CONST_FLOAT fMaxDistFromPedToCam_a 65.0 //Distance from destPedPos to destOutroPos should be less than 70m (if overridden outro) /* CONST_FLOAT fMaxDistFromPedToCam_b 135.0 //Distance from establishingShotPos to destPedPos should be less than 140m */ CONST_FLOAT fMaxDistFromPedToCam_c 135.0 //Distance from establishingShotPos to destOutroPos should be less than 140m (if overridden outro) FLOAT fMaxDistFromPedToCam = fMaxDistFromPedToCam_a IF NOT IS_STRING_NULL_OR_EMPTY(establishingShotName) fMaxDistFromPedToCam = fMaxDistFromPedToCam_c ENDIF VECTOR vDiffFromPedToCam vDiffFromPedToCam = GET_CAM_COORD(camTo) - GET_ENTITY_COORDS(camDetails.pedTo) IF VMAG2(vDiffFromPedToCam) > (fMaxDistFromPedToCam*fMaxDistFromPedToCam) VECTOR vCreateCoords, vecCamEndOff vCreateCoords = GET_ENTITY_COORDS(camDetails.pedTo) vecCamEndOff = GET_CAM_COORD(camTo) - vCreateCoords SET_CAM_COORD(camTo, vCreateCoords + (vecCamEndOff*0.75)) VECTOR vCamToCoords = GET_CAM_COORD(camTo) VECTOR vPedToCoords = GET_ENTITY_COORDS(camDetails.pedTo) CASSERTLN(DEBUG_SWITCH, "Distance between camTo[", vCamToCoords, "] and pedTo[", vPedToCoords, "] is too large: ", VMAG(vDiffFromPedToCam)) ENDIF #ENDIF SET_PLAYER_SWITCH_OUTRO(GET_CAM_COORD(camTo), GET_CAM_ROT(camTo, RotOrder), GET_CAM_FOV(camTo), GET_CAM_FAR_CLIP(camTo), RotOrder) ENDIF ENDIF IF NOT IS_STRING_NULL_OR_EMPTY(establishingShotName) SET_PLAYER_SWITCH_ESTABLISHING_SHOT(establishingShotName) #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_SWITCH, "SET_PLAYER_SWITCH_ESTABLISHING_SHOT(", establishingShotName, ")") #ENDIF ENDIF // SFX - Heading up IF NOT g_sSelectorUI.bSFX_BlockAudioCalls PLAY_SOUND(-1, "CHARACTER_CHANGE_UP_MASTER") CPRINTLN(DEBUG_SWITCH, "SWITCH UI - playing sound: CHARACTER_CHANGE_UP_MASTER") IF GET_IDEAL_PLAYER_SWITCH_TYPE(GET_ENTITY_COORDS(camDetails.pedFrom), GET_ENTITY_COORDS(camDetails.pedTo)) = SWITCH_TYPE_SHORT PLAY_SOUND(-1, "slow", "SHORT_PLAYER_SWITCH_SOUND_SET") CPRINTLN(DEBUG_SWITCH, "SWITCH UI - playing sound: slow SHORT_PLAYER_SWITCH_SOUND_SET") ELSE CPRINTLN(DEBUG_SWITCH, "SWITCH UI - DON'T play sound: slow SHORT_PLAYER_SWITCH_SOUND_SET!!!") ENDIF IF (g_sSelectorUI.iSFX_Sky = -1) g_sSelectorUI.iSFX_Sky = GET_SOUND_ID() ENDIF g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) PLAY_SOUND(g_sSelectorUI.iSFX_Sky, "CHARACTER_CHANGE_SKY_MASTER") CPRINTLN(DEBUG_SWITCH, "SWITCH UI - playing sound: CHARACTER_CHANGE_SKY_MASTER: ", g_sSelectorUI.iSFX_Sky, " [", g_sSelectorUI.iSFX_Sky_ScriptHash, ":\"", GET_THIS_SCRIPT_NAME(), "\"]") START_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") IF IS_AUDIO_SCENE_ACTIVE("CHARACTER_CHANGE_IN_SKY_SCENE") CPRINTLN(DEBUG_SWITCH, "start CHARACTER_CHANGE_IN_SKY_SCENE...active!!!") ELSE CPRINTLN(DEBUG_SWITCH, "start CHARACTER_CHANGE_IN_SKY_SCENE...is NOT active!!!") ENDIF ENDIF // SFX - Cleanup IF (g_sSelectorUI.iSFX_Sky != -1) AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) CPRINTLN(DEBUG_SWITCH, "SWITCH UI - need to cleanup iSFX_Sky ", g_sSelectorUI.iSFX_Sky, ", ", g_sSelectorUI.iSFX_Sky_ScriptHash) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 ELSE CPRINTLN(DEBUG_SWITCH, "SWITCH UI - no need to cleanup iSFX_Sky ", g_sSelectorUI.iSFX_Sky, ", ", g_sSelectorUI.iSFX_Sky_ScriptHash) ENDIF /* camDetails.fMaxHeight = GET_SELECTOR_CAM_Z_HEIGHT(camDetails.camID) */ camDetails.iActivateTimer = GET_GAME_TIMER() camDetails.bSplineActive = TRUE SET_SELECTOR_CAM_ACTIVE(TRUE) SET_MINIMAP_IN_SPECTATOR_MODE(TRUE, camDetails.pedFrom) IF (GET_FOLLOW_PED_CAM_VIEW_MODE() = CAM_VIEW_MODE_CINEMATIC) CPRINTLN(DEBUG_SWITCH, "Set follow ped cam view mode - third person.") SET_FOLLOW_PED_CAM_VIEW_MODE(CAM_VIEW_MODE_THIRD_PERSON) ENDIF IF (GET_FOLLOW_VEHICLE_CAM_VIEW_MODE() = CAM_VIEW_MODE_CINEMATIC) CPRINTLN(DEBUG_SWITCH, "Set follow veh cam view mode - third person.") SET_FOLLOW_VEHICLE_CAM_VIEW_MODE(CAM_VIEW_MODE_THIRD_PERSON) ENDIF // IF (GET_FOLLOW_VEHICLE_CAM_ZOOM_LEVEL() = VEHICLE_ZOOM_LEVEL_CINEMATIC) // OR (GET_FOLLOW_VEHICLE_CAM_ZOOM_LEVEL() = VEHICLE_ZOOM_LEVEL_BONNET) // CPRINTLN(DEBUG_SWITCH, "Set follow veh cam zoom level - medium.") // SET_FOLLOW_VEHICLE_CAM_ZOOM_LEVEL(VEHICLE_ZOOM_LEVEL_MEDIUM) // ENDIF IF NOT bMultiplayerSwitch // Process player timecycle modifier IF GET_ENTITY_MODEL(camDetails.pedTo) = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) SET_NEXT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(CHAR_MICHAEL)) ELIF GET_ENTITY_MODEL(camDetails.pedTo) = GET_PLAYER_PED_MODEL(CHAR_TREVOR) SET_NEXT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(CHAR_TREVOR)) ELIF GET_ENTITY_MODEL(camDetails.pedTo) = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN) SET_NEXT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(CHAR_FRANKLIN)) ELSE SET_NEXT_PLAYER_TCMODIFIER("") ENDIF SET_PLAYER_TCMODIFIER_TRANSITION(0.0) ENDIF ELSE // Problem with peds so cleanup camDetails.bSplineComplete = TRUE #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_SWITCH, "\nCannot run switch as pedFrom or pedTo is dead.") IF (NOT IS_PED_INJURED(camDetails.pedFrom) OR bMultiplayerSwitch) CPRINTLN(DEBUG_SWITCH, " pedFrom alive or bMultiplayerSwitch") ELSE CPRINTLN(DEBUG_SWITCH, " NOT (pedFrom alive or bMultiplayerSwitch)!!!") ENDIF IF NOT IS_PED_INJURED(camDetails.pedTo) CPRINTLN(DEBUG_SWITCH, " pedTo alive") ELSE CPRINTLN(DEBUG_SWITCH, " NOT (pedTo alive)!!!") ENDIF SCRIPT_ASSERT("Cannot run switch as player or ped is dead.") #ENDIF ENDIF ELSE // Problem with IS_SAFE_TO_START_PLAYER_SWITCH() so cleanup camDetails.bSplineComplete = TRUE #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_SWITCH, "\nNot safe to start a switch???") SCRIPT_ASSERT("Not safe to start a switch???") #ENDIF ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup when the spline has finished IF camDetails.bSplineActive /* // Update the player timecycle modifier SET_PLAYER_TCMODIFIER_TRANSITION(GET_CAM_SPLINE_PHASE(camDetails.camID)) */ PRINTLN("GENERIC_PED_SCENE - IS_PLAYER_SWITCH_IN_PROGRESS: ", IS_PLAYER_SWITCH_IN_PROGRESS()) IF IS_PLAYER_SWITCH_IN_PROGRESS() #IF IS_DEBUG_BUILD IF g_bDrawLiteralSceneString SWITCH_TYPE eThisSwitchType STRING sThisSwitchType eThisSwitchType = GET_PLAYER_SWITCH_TYPE() sThisSwitchType = Get_String_From_Switch_Type(eThisSwitchType) SWITCH_STATE eThisSwitchState STRING sThisSwitchState IF (eThisSwitchType <> SWITCH_TYPE_SHORT) eThisSwitchState = GET_PLAYER_SWITCH_STATE() sThisSwitchState = Get_String_From_Switch_State(eThisSwitchState) ELSE eThisSwitchState = INT_TO_ENUM(SWITCH_STATE, -1) SWITCH GET_PLAYER_SHORT_SWITCH_STATE() CASE SHORT_SWITCH_STATE_INTRO sThisSwitchState = "SHORT_SWITCH_STATE_INTRO" BREAK CASE SHORT_SWITCH_STATE_OUTRO sThisSwitchState = "SHORT_SWITCH_STATE_OUTRO" BREAK ENDSWITCH ENDIF TEXT_LABEL_63 sLiteral sLiteral = "" sLiteral += "type:" sLiteral += GET_STRING_FROM_STRING(sThisSwitchType, GET_LENGTH_OF_LITERAL_STRING("SWITCH_TYPE_"), GET_LENGTH_OF_LITERAL_STRING(sThisSwitchType)) sLiteral += ", " IF (eThisSwitchType <> SWITCH_TYPE_SHORT) sLiteral += "state:" sLiteral += GET_STRING_FROM_STRING(sThisSwitchState, GET_LENGTH_OF_LITERAL_STRING("SWITCH_STATE_"), GET_LENGTH_OF_LITERAL_STRING(sThisSwitchState)) IF (eThisSwitchState <> SWITCH_STATE_ESTABLISHING_SHOT) sLiteral += ": " sLiteral += GET_PLAYER_SWITCH_JUMP_CUT_INDEX() ELSE sLiteral += " \"" sLiteral += establishingShotName sLiteral += "\"" ENDIF ELSE sLiteral += "state:" sLiteral += GET_STRING_FROM_STRING(sThisSwitchState, GET_LENGTH_OF_LITERAL_STRING("SHORT_SWITCH_STATE_"), GET_LENGTH_OF_LITERAL_STRING(sThisSwitchState)) ENDIF SET_TEXT_SCALE(0.4, 0.4) SET_TEXT_COLOUR(255, 255, 255, 255) SET_TEXT_JUSTIFICATION(FONT_CENTRE) SET_TEXT_OUTLINE() DISPLAY_TEXT_WITH_LITERAL_STRING(0.5, 0.925, "STRING", sLiteral) ENDIF #ENDIF // SFX - Heading down IF NOT g_sSelectorUI.bSFX_BlockAudioCalls /* FLOAT fCurrentHeight = GET_SELECTOR_CAM_Z_HEIGHT(camDetails.camID) IF (fCurrentHeight > camDetails.fMaxHeight) camDetails.fMaxHeight = fCurrentHeight ELIF (camDetails.fMaxHeight > fCurrentHeight+1.0) IF g_sSelectorUI.iSFX_HeadDown = -1 g_sSelectorUI.iSFX_HeadDown = GET_SOUND_ID() PLAY_SOUND(g_sSelectorUI.iSFX_HeadDown, "CHARACTER_CHANGE_DOWN_MASTER") ENDIF IF (g_sSelectorUI.iSFX_Sky != -1) CPRINTLN(DEBUG_SWITCH, "SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 STOP_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") ENDIF ENDIF */ ENDIF IF IS_BITMASK_AS_ENUM_SET(iSwitchFlags, SWITCH_FLAG_PAUSE_BEFORE_DESCENT) IF NOT IS_SWITCH_READY_FOR_DESCENT() CPRINTLN(DEBUG_SWITCH, "not IS_SWITCH_READY_FOR_DESCENT???") ELSE CPRINTLN(DEBUG_SWITCH, "IS_SWITCH_READY_FOR_DESCENT [", g_iPauseOnOutro, ", ", g_iPausedOnOutroGametime, "]") IF (g_iPauseOnOutro = 0) ALLOW_PLAYER_SWITCH_DESCENT() ENDIF ENDIF ENDIF PRINTLN("GENERIC_PED_SCENE - (7) GET_PLAYER_SWITCH_TYPE: ", Get_String_From_Switch_Type(GET_PLAYER_SWITCH_TYPE())) IF (GET_PLAYER_SWITCH_TYPE() = SWITCH_TYPE_SHORT) SWITCH GET_PLAYER_SHORT_SWITCH_STATE() CASE SHORT_SWITCH_STATE_INTRO PRINTLN("GENERIC_PED_SCENE - (7) GET_PLAYER_SHORT_SWITCH_STATE: SHORT_SWITCH_STATE_INTRO") BREAK CASE SHORT_SWITCH_STATE_OUTRO PRINTLN("GENERIC_PED_SCENE - (7) GET_PLAYER_SHORT_SWITCH_STATE: SHORT_SWITCH_STATE_OUTRO") BREAK ENDSWITCH ENDIF // Allow ped switch IF (GET_PLAYER_SWITCH_TYPE() = SWITCH_TYPE_SHORT) IF (GET_PLAYER_SHORT_SWITCH_STATE() >= SHORT_SWITCH_STATE_OUTRO) PRINTLN("GENERIC_PED_SCENE - (7) camDetails.bOKToSwitchPed: ", camDetails.bOKToSwitchPed) IF NOT camDetails.bOKToSwitchPed FLUSH_TEXT_MESSAGE_FEED_ENTRIES() //1007225 camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (7)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF ENDIF IF NOT camDetails.bTakenContolOfTransition CPRINTLN(DEBUG_SWITCH, "TAKE_CONTROL_OF_TRANSITION...short range!!!") TAKE_CONTROL_OF_TRANSITION(FALSE) camDetails.bTakenContolOfTransition = TRUE ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD PRINTLN("GENERIC_PED_SCENE - (8) GET_PLAYER_SWITCH_STATE: ", DEBUG_GET_PLAYER_SWITCH_STATE(GET_PLAYER_SWITCH_STATE())) #ENDIF IF (GET_PLAYER_SWITCH_STATE() >= SWITCH_STATE_JUMPCUT_DESCENT) PRINTLN("GENERIC_PED_SCENE - (8) camDetails.bOKToSwitchPed: ", camDetails.bOKToSwitchPed) IF NOT camDetails.bOKToSwitchPed FLUSH_TEXT_MESSAGE_FEED_ENTRIES() //1007225 camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (8)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF ENDIF ENDIF #IF USE_TU_CHANGES PRINTLN("GENERIC_PED_SCENE - (9) camDetails.bOKToSwitchPed: ", camDetails.bOKToSwitchPed) IF NOT camDetails.bOKToSwitchPed PRINTLN("GENERIC_PED_SCENE - (9) IS_SWITCH_SKIPPING_DESCENT: ", IS_SWITCH_SKIPPING_DESCENT()) #IF IS_DEBUG_BUILD PRINTLN("GENERIC_PED_SCENE - (9) GET_PLAYER_SWITCH_STATE: ", DEBUG_GET_PLAYER_SWITCH_STATE(GET_PLAYER_SWITCH_STATE())) #ENDIF IF IS_SWITCH_SKIPPING_DESCENT() //#1649473 AND (GET_PLAYER_SWITCH_STATE() = SWITCH_STATE_JUMPCUT_ASCENT) VECTOR vPlayerCoords = GET_ENTITY_COORDS(PLAYER_PED_ID()) VECTOR vCamCoords = GET_FINAL_RENDERED_CAM_COORD() FLOAT fDistToProgress = 20.0 FLOAT fCamDist2 = VDIST2(vPlayerCoords, vCamCoords) PRINTLN("GENERIC_PED_SCENE - (9) fCamDist2: ", fCamDist2) PRINTLN("GENERIC_PED_SCENE - (9) (fDistToProgress*fDistToProgress): ", (fDistToProgress*fDistToProgress)) IF fCamDist2 < (fDistToProgress*fDistToProgress) FLUSH_TEXT_MESSAGE_FEED_ENTRIES() camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (9)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF ENDIF ENDIF ENDIF #ENDIF IF NOT camDetails.bTakenContolOfTransition IF GET_PLAYER_SWITCH_STATE() > SWITCH_STATE_PREP_FOR_CUT CPRINTLN(DEBUG_SWITCH, "TAKE_CONTROL_OF_TRANSITION...med/long range!!!") TAKE_CONTROL_OF_TRANSITION(FALSE) camDetails.bTakenContolOfTransition = TRUE ENDIF ENDIF IF NOT camDetails.bSetShadowSampleBox3x3 IF GET_PLAYER_SWITCH_STATE() >= SWITCH_STATE_JUMPCUT_ASCENT CPRINTLN(DEBUG_SWITCH, "CASCADE_SHADOWS_SET_SHADOW_SAMPLE_TYPE(\"CSM_ST_BOX3x3\")...med/long range!!!") CASCADE_SHADOWS_SET_SHADOW_SAMPLE_TYPE("CSM_ST_BOX3x3") camDetails.bSetShadowSampleBox3x3 = TRUE ENDIF ENDIF ENDIF /* // Update final spline node IF camDetails.bOKToSwitchPed IF PLAYER_PED_ID() = camDetails.pedTo IF NOT IS_PED_INJURED(camDetails.pedTo) IF camDetails.iInterpCams >= 1 IF DOES_CAM_EXIST(camDetails.camInterpIDs[camDetails.iInterpCams - 1]) IF IS_PED_IN_ANY_VEHICLE(camDetails.pedTo) VEHICLE_INDEX vehPed = GET_VEHICLE_PED_IS_USING(camDetails.pedTo) VECTOR vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehPed, GET_GAMEPLAY_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams - 1], vehPed, vTargetRelativePosition) ELSE VECTOR vTargetRelativePosition = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(camDetails.pedTo, GET_GAMEPLAY_CAM_COORD()) ATTACH_CAM_TO_ENTITY(camDetails.camInterpIDs[camDetails.iInterpCams - 1], camDetails.pedTo, vTargetRelativePosition) ENDIF SET_CAM_ROT(camDetails.camInterpIDs[camDetails.iInterpCams - 1], GET_GAMEPLAY_CAM_ROT()) SET_CAM_FOV(camDetails.camInterpIDs[camDetails.iInterpCams - 1], GET_GAMEPLAY_CAM_FOV()) bFinalNodeUpdated = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF */ ELSE PRINTLN("GENERIC_PED_SCENE - (10) camDetails.bOKToSwitchPed: ", camDetails.bOKToSwitchPed) // Allow ped switch IF NOT camDetails.bOKToSwitchPed camDetails.bOKToSwitchPed = TRUE PRINTLN("GENERIC_PED_SCENE - Setting bOKToSwitchPed to TRUE (10)") #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF FLUSH_TEXT_MESSAGE_FEED_ENTRIES() //1007225 ENDIF IF NOT camDetails.bTakenContolOfTransition CPRINTLN(DEBUG_SWITCH, "TAKE_CONTROL_OF_TRANSITION...fall through!!!") TAKE_CONTROL_OF_TRANSITION(FALSE) camDetails.bTakenContolOfTransition = TRUE ENDIF camDetails.bSplineComplete = TRUE ENDIF ENDIF /////////////////////////////////////////////////////// /// Cleanup the camera IF camDetails.bSplineComplete PED_REQUEST_SCENE_ENUM eScene eScene = Get_Player_Timetable_Scene_In_Progress() IF (eScene <> PR_SCENE_Fa_PHONECALL_ARM3) AND (eScene <> PR_SCENE_Fa_PHONECALL_FAM1) AND (eScene <> PR_SCENE_Fa_PHONECALL_FAM3) AND (eScene <> PR_SCENE_Ta_CARSTEAL4) DISABLE_CELLPHONE(camDetails.bIsPhoneDisabled) ENDIF // //# 1524219 // CASCADE_SHADOWS_SET_AIRCRAFT_MODE(FALSE) // CPRINTLN(DEBUG_SWITCH, "CASCADE_SHADOWS_SET_AIRCRAFT_MODE(FALSE) called by ", GET_THIS_SCRIPT_NAME()) IF camDetails.bSetShadowSampleBox3x3 CASCADE_SHADOWS_CLEAR_SHADOW_SAMPLE_TYPE() camDetails.bSetShadowSampleBox3x3 = FALSE ENDIF // Reset all the camera values incase they have to be used again camDetails.bSplineActive = FALSE camDetails.bSplineComplete = FALSE camDetails.bOKToSwitchPed = FALSE camDetails.bPedSwitched = FALSE camDetails.bRun = FALSE camDetails.iInterpCams = 0 camDetails.iSplineDuration = 0 // SFX - Cleanup IF (g_sSelectorUI.iSFX_Sky != -1) AND g_sSelectorUI.iSFX_Sky_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) CPRINTLN(DEBUG_SWITCH, "SWITCH UI - stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky, ", ", g_sSelectorUI.iSFX_Sky_ScriptHash) STOP_SOUND(g_sSelectorUI.iSFX_Sky) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_Sky) g_sSelectorUI.iSFX_Sky = -1 g_sSelectorUI.iSFX_Sky_ScriptHash = 0 ELSE CPRINTLN(DEBUG_SWITCH, "SWITCH UI - don't stop iSFX_Sky ", g_sSelectorUI.iSFX_Sky, ", ", g_sSelectorUI.iSFX_Sky_ScriptHash) ENDIF IF IS_AUDIO_SCENE_ACTIVE("CHARACTER_CHANGE_IN_SKY_SCENE") CPRINTLN(DEBUG_SWITCH, "stop CHARACTER_CHANGE_IN_SKY_SCENE...is STILL active!!!") STOP_AUDIO_SCENE("CHARACTER_CHANGE_IN_SKY_SCENE") ELSE CPRINTLN(DEBUG_SWITCH, "stop CHARACTER_CHANGE_IN_SKY_SCENE...was not active!!!") ENDIF IF (g_sSelectorUI.iSFX_HeadDown != -1) AND g_sSelectorUI.iSFX_HeadDown_ScriptHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) CPRINTLN(DEBUG_SWITCH, "STOP_SOUND iSFX_HeadDown: ", g_sSelectorUI.iSFX_HeadDown, ", ", GET_THIS_SCRIPT_NAME()) STOP_SOUND(g_sSelectorUI.iSFX_HeadDown) RELEASE_SOUND_ID(g_sSelectorUI.iSFX_HeadDown) g_sSelectorUI.iSFX_HeadDown = -1 g_sSelectorUI.iSFX_HeadDown_ScriptHash = 0 ENDIF // Set the relative heading/pitch if the calling scipt used a custom camera // If specified out of range then do no set IF fDestCamRelativeHeading <= 360 AND fDestCamRelativeHeading >= - 360 SET_GAMEPLAY_CAM_RELATIVE_HEADING(fDestCamRelativeHeading) ENDIF IF fDestCamRelativePitch <= 360 AND fDestCamRelativePitch >= -360 SET_GAMEPLAY_CAM_RELATIVE_PITCH(fDestCamRelativePitch) ENDIF IF NOT (g_drunkCameraActive) STOP_GAMEPLAY_CAM_SHAKING(TRUE) SET_GAMEPLAY_CAM_MOTION_BLUR_SCALING_THIS_UPDATE(0) SET_GAMEPLAY_CAM_MAX_MOTION_BLUR_STRENGTH_THIS_UPDATE(0) ENDIF IF NOT bMultiplayerSwitch IF NOT IS_PED_INJURED(camDetails.pedFrom) SET_ENTITY_VISIBLE(camDetails.pedFrom, TRUE) SET_PED_CAN_BE_TARGETTED(camDetails.pedFrom, TRUE) IF NOT IS_PED_IN_ANY_VEHICLE(camDetails.pedFrom) SET_ENTITY_COLLISION(camDetails.pedFrom, TRUE) ENDIF //926174 IF IS_PED_SITTING_IN_ANY_VEHICLE(camDetails.pedFrom) VEHICLE_INDEX vehFrom = GET_VEHICLE_PED_IS_IN(camDetails.pedFrom) naughty_SET_VEHICLE_LIMIT_SPEED_WHEN_PLAYER_INACTIVE(vehFrom, TRUE) ENDIF ENDIF ENDIF SET_SKYSWOOP_STAGE(SKYSWOOP_NONE) IF NOT bMultiplayerSwitch // Reset proofs IF (NOT IS_PED_INJURED(camDetails.pedFrom) OR bMultiplayerSwitch) SET_ENTITY_INVINCIBLE(camDetails.pedFrom, FALSE) CPRINTLN(DEBUG_SWITCH, "SET_ENTITY_INVINCIBLE(", GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM(camDetails.pedFrom)), ", FALSE) //pedFrom") ELSE CPRINTLN(DEBUG_SWITCH, "NOT SET_ENTITY_INVINCIBLE(camDetails.pedFrom, FALSE)") ENDIF IF NOT IS_PED_INJURED(camDetails.pedTo) SET_ENTITY_INVINCIBLE(camDetails.pedTo, FALSE) CPRINTLN(DEBUG_SWITCH, "SET_ENTITY_INVINCIBLE(", GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM(camDetails.pedTo)), ", FALSE) //pedTo") ELSE CPRINTLN(DEBUG_SWITCH, "NOT SET_ENTITY_INVINCIBLE(camDetails.pedTo, FALSE)") ENDIF SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) ClearInsideDisplacedInteriorFlag() // Update the player timecycle modifier SET_CURRENT_PLAYER_TCMODIFIER(GET_PLAYER_PED_TIMECYCLE_MODIFIER(GET_CURRENT_PLAYER_PED_ENUM())) ENDIF SET_SELECTOR_CAM_ACTIVE(FALSE) SET_MINIMAP_IN_SPECTATOR_MODE(FALSE, NULL) RETURN FALSE // Cam complete ENDIF // Hide the HUD HIDE_HUD_AND_RADAR_THIS_FRAME() //CLEAR_REMINDER_MESSAGE() //#1421176 RETURN TRUE // Cam still running ENDFUNC // PURPOSE: FUNC BOOL RUN_SWITCH_CAM_FROM_PLAYER_TO_PED(SELECTOR_CAM_STRUCT &camDetails, SWITCH_TYPE eSwitchType = SWITCH_TYPE_AUTO, INT iSwitchFlags = 0, FLOAT fDestCamRelativePitch = 999.0,FLOAT fDestCamRelativeHeading = 999.0, BOOL bPauseBeforePan = FALSE, BOOL bPauseBeforeOutro = FALSE, STRING establishingShotName = NULL, BOOL bOverrideShortRangeSwitchStyle = FALSE, SHORT_SWITCH_STYLE shortRangeSwitchStyle = SHORT_SWITCH_STYLE_ROTATION) //camDetails.pedFrom = PLAYER_PED_ID() //Always from player RETURN PRIVATE_RunPlayerSwitch(camDetails, NULL, eSwitchType, iSwitchFlags, fDestCamRelativePitch ,fDestCamRelativeHeading, bPauseBeforePan, bPauseBeforeOutro, establishingShotName, DEFAULT, FALSE, bOverrideShortRangeSwitchStyle, shortRangeSwitchStyle) // Adding this extra return case as the DEFAULT param breaks intelisense... RETURN TRUE ENDFUNC // PURPOSE: FUNC BOOL RUN_SWITCH_CAM_FROM_PLAYER_TO_PED_SHORT_RANGE(SELECTOR_CAM_STRUCT &camDetails, INT iSwitchFlags = 0, FLOAT fDestCamRelativePitch = 999.0,FLOAT fDestCamRelativeHeading = 999.0) //camDetails.pedFrom = PLAYER_PED_ID() //Always from player RETURN PRIVATE_RunPlayerSwitch(camDetails, NULL, SWITCH_TYPE_SHORT, iSwitchFlags, fDestCamRelativePitch ,fDestCamRelativeHeading, DEFAULT, DEFAULT, DEFAULT, EULER_MAX, FALSE) // Adding this extra return case as the DEFAULT param breaks intelisense... RETURN TRUE ENDFUNC // PURPOSE: FUNC BOOL RUN_SWITCH_CAM_FROM_PLAYER_TO_PED_LONG_RANGE(SELECTOR_CAM_STRUCT &camDetails, INT iSwitchFlags = 0, FLOAT fDestCamRelativePitch = 999.0,FLOAT fDestCamRelativeHeading = 999.0) //camDetails.pedFrom = PLAYER_PED_ID() //Always from player RETURN PRIVATE_RunPlayerSwitch(camDetails, NULL, SWITCH_TYPE_LONG, iSwitchFlags, fDestCamRelativePitch ,fDestCamRelativeHeading, DEFAULT, DEFAULT, DEFAULT, EULER_MAX, FALSE) // Adding this extra return case as the DEFAULT param breaks intelisense... RETURN TRUE ENDFUNC // PURPOSE: FUNC BOOL NET_RUN_SWITCH_CAM_FROM_PED_TO_PED_LONG_RANGE(SELECTOR_CAM_STRUCT &camDetails, INT iSwitchFlags = 0, FLOAT fDestCamRelativePitch = 999.0,FLOAT fDestCamRelativeHeading = 999.0) RETURN PRIVATE_RunPlayerSwitch(camDetails, NULL, SWITCH_TYPE_LONG, iSwitchFlags, fDestCamRelativePitch ,fDestCamRelativeHeading, DEFAULT, DEFAULT, DEFAULT, EULER_MAX, TRUE) // Adding this extra return case as the DEFAULT param breaks intelisense... RETURN TRUE ENDFUNC // PURPOSE: FUNC BOOL NET_RUN_SWITCH_CAM_FROM_PED_TO_PED(SELECTOR_CAM_STRUCT &camDetails, FLOAT fDestCamRelativePitch = 999.0,FLOAT fDestCamRelativeHeading = 999.0) RETURN PRIVATE_RunPlayerSwitch(camDetails, NULL, SWITCH_TYPE_AUTO, 0, fDestCamRelativePitch ,fDestCamRelativeHeading, DEFAULT, DEFAULT, DEFAULT, EULER_MAX, TRUE) // Adding this extra return case as the DEFAULT param breaks intelisense... RETURN TRUE ENDFUNC // PURPOSE: FUNC BOOL RUN_SWITCH_CAM_FROM_PLAYER_TO_CAM(SELECTOR_CAM_STRUCT &camDetails, CAMERA_INDEX camTo, SWITCH_TYPE eSwitchType = SWITCH_TYPE_AUTO, INT iSwitchFlags = 0, FLOAT fDestCamRelativePitch = 999.0, FLOAT fDestCamRelativeHeading = 999.0, BOOL bPauseBeforePan = FALSE, BOOL bPauseBeforeOutro = FALSE, STRING establishingShotName = NULL, EULER_ROT_ORDER RotOrder = EULER_YXZ) //camDetails.pedFrom = PLAYER_PED_ID() //Always from player RETURN PRIVATE_RunPlayerSwitch(camDetails, camTo, eSwitchType, iSwitchFlags, fDestCamRelativePitch, fDestCamRelativeHeading, bPauseBeforePan, bPauseBeforeOutro, establishingShotName, RotOrder, FALSE) // Adding this extra return case as the DEFAULT param breaks intelisense... RETURN TRUE ENDFUNC // PURPOSE: FUNC BOOL RUN_SWITCH_CAM_FROM_PLAYER_TO_CAM_SHORT_RANGE(SELECTOR_CAM_STRUCT &camDetails, CAMERA_INDEX camTo, INT iSwitchFlags = 0, FLOAT fDestCamRelativePitch = 999.0, FLOAT fDestCamRelativeHeading = 999.0, EULER_ROT_ORDER RotOrder = EULER_YXZ) //camDetails.pedFrom = PLAYER_PED_ID() //Always from player RETURN PRIVATE_RunPlayerSwitch(camDetails, camTo, SWITCH_TYPE_SHORT, iSwitchFlags, fDestCamRelativePitch,fDestCamRelativeHeading, DEFAULT, DEFAULT, DEFAULT, RotOrder, FALSE) // Adding this extra return case as the DEFAULT param breaks intelisense... RETURN TRUE ENDFUNC // PURPOSE: FUNC BOOL RUN_SWITCH_CAM_FROM_PLAYER_TO_CAM_LONG_RANGE(SELECTOR_CAM_STRUCT &camDetails, CAMERA_INDEX camTo, INT iSwitchFlags = 0, FLOAT fDestCamRelativePitch = 999.0, FLOAT fDestCamRelativeHeading = 999.0, EULER_ROT_ORDER RotOrder = EULER_YXZ) //camDetails.pedFrom = PLAYER_PED_ID() //Always from player RETURN PRIVATE_RunPlayerSwitch(camDetails, camTo, SWITCH_TYPE_LONG, iSwitchFlags, fDestCamRelativePitch,fDestCamRelativeHeading, DEFAULT, DEFAULT, DEFAULT, RotOrder, FALSE) // Adding this extra return case as the DEFAULT param breaks intelisense... RETURN TRUE ENDFUNC /// PURPOSE: Changes the player ped to selectorPeds.pedID[selectorPeds.eNewSelectorPed] /// /// NOTE: The players ped ID will be changed to the selector peds ped ID and vice versa FUNC BOOL TAKE_CONTROL_OF_SELECTOR_PED(SELECTOR_PED_STRUCT &selectorPeds, BOOL bKeepPlayerReplacement = TRUE, BOOL bKeepTasks = FALSE, TAKE_CONTROL_OF_PED_FLAGS eFlags = TCF_NONE) // Ensure a selection has been made IF NOT selectorPeds.bInitialised #IF IS_DEBUG_BUILD PRINTLN("TAKE_CONTROL_OF_SELECTOR_PED") PRINTLN("...player = ", GET_PLAYER_PED_STRING(GET_CURRENT_PLAYER_PED_ENUM())) PRINTLN("...selected ped = ", GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(selectorPeds.eNewSelectorPed))) SCRIPT_ASSERT("TAKE_CONTROL_OF_SELECTOR_PED - Ped selection has not taken place. See Kenneth R.") #ENDIF // Bail out if no-one was set. IF selectorPeds.eNewSelectorPed = NUMBER_OF_SELECTOR_PEDS PRINTLN("GENERIC_PED_SCENE - TAKE_CONTROL_OF_SELECTOR_PED - Returning TRUE") RETURN TRUE ENDIF ENDIF PRINTLN("GENERIC_PED_SCENE - TAKE_CONTROL_OF_SELECTOR_PED - IS_PED_INJURED(selectorPeds.pedID[selectorPeds.eNewSelectorPed]): ", IS_PED_INJURED(selectorPeds.pedID[selectorPeds.eNewSelectorPed])) PRINTLN("GENERIC_PED_SCENE - TAKE_CONTROL_OF_SELECTOR_PED - IS_PED_INJURED(PLAYER_PED_ID()): ", IS_PED_INJURED(PLAYER_PED_ID())) IF selectorPeds.pedID[selectorPeds.eNewSelectorPed] != PLAYER_PED_ID() PRINTLN("GENERIC_PED_SCENE - TAKE_CONTROL_OF_SELECTOR_PED - ectorPeds.pedID[selectorPeds.eNewSelectorPed] != PLAYER_PED_ID()") ELSE PRINTLN("GENERIC_PED_SCENE - TAKE_CONTROL_OF_SELECTOR_PED - ectorPeds.pedID[selectorPeds.eNewSelectorPed] = PLAYER_PED_ID()") ENDIF IF NOT IS_PED_INJURED(selectorPeds.pedID[selectorPeds.eNewSelectorPed]) AND NOT IS_PED_INJURED(PLAYER_PED_ID()) AND selectorPeds.pedID[selectorPeds.eNewSelectorPed] != PLAYER_PED_ID() ////////////////////////////////////////////////////////////////////////////////// /// *** Temp fix so that the player doesn't lose control /// IF NOT bKeepTasks IF IS_PED_RAGDOLL(PLAYER_PED_ID()) AND NOT IS_ENTITY_ON_FIRE(PLAYER_PED_ID()) AND NOT IS_PED_GETTING_INTO_A_VEHICLE(PLAYER_PED_ID()) CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID()) ELSE CLEAR_PED_TASKS(PLAYER_PED_ID()) ENDIF IF IS_PED_RAGDOLL(selectorPeds.pedID[selectorPeds.eNewSelectorPed]) AND NOT IS_ENTITY_ON_FIRE(selectorPeds.pedID[selectorPeds.eNewSelectorPed]) AND NOT IS_PED_GETTING_INTO_A_VEHICLE(selectorPeds.pedID[selectorPeds.eNewSelectorPed]) CLEAR_PED_TASKS_IMMEDIATELY(selectorPeds.pedID[selectorPeds.eNewSelectorPed]) ELSE CLEAR_PED_TASKS(selectorPeds.pedID[selectorPeds.eNewSelectorPed]) ENDIF ENDIF /// ////////////////////////////////////////////////////////////////////////////////// PED_INDEX originalPlayerPedID enumCharacterList ePedRep, ePedSel ////////////////////////////////////////////////////////////////////////////////// /// [1] Store the current players details /// originalPlayerPedID = PLAYER_PED_ID() ePedRep = GET_CURRENT_PLAYER_PED_ENUM() IF (NOT selectorPeds.bAmbient) // OR (selectorPeds.bAmbient) // AND g_sPlayerPedRequest.eType <> PR_TYPE_AMBIENT) STORE_PLAYER_PED_INFO(originalPlayerPedID) ENDIF UNREGISTER_PLAYER_PED_WITH_AUTOMATIC_DOORS(ePedRep, originalPlayerPedID) SET_PED_CONFIG_FLAG(originalPlayerPedID, PCF_WillFlyThroughWindscreen, TRUE) SET_PED_CONFIG_FLAG(originalPlayerPedID, PCF_WillTakeDamageWhenVehicleCrashes, TRUE) CPRINTLN(DEBUG_FLOW, "SWITCH from script ", GET_THIS_SCRIPT_NAME(), " setting ped flags for old player ped.") CPRINTLN(DEBUG_FLOW, "Set WillFlyThroughWindscreen to TRUE for PED_INDEX[",NATIVE_TO_INT(originalPlayerPedID),"].") CPRINTLN(DEBUG_FLOW, "Set WillTakeDamageWhenVehicleCrashes to TRUE for PED_INDEX[",NATIVE_TO_INT(originalPlayerPedID),"].") ////////////////////////////////////////////////////////////////////////////////// /// [2] Store the selector peds details /// ePedSel = GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(selectorPeds.eNewSelectorPed) STORE_PLAYER_PED_INFO(selectorPeds.pedID[selectorPeds.eNewSelectorPed]) // Track selected peds health perc so we can ensure player has 25%+ when we switch FLOAT fSelectedPedHealthPerc = (((TO_FLOAT(GET_ENTITY_HEALTH(selectorPeds.pedID[selectorPeds.eNewSelectorPed]))-100.0) / (TO_FLOAT(GET_PED_MAX_HEALTH(selectorPeds.pedID[selectorPeds.eNewSelectorPed]))-100.0)) * 100.0) ////////////////////////////////////////////////////////////////////////////////// /// [3] Replace selector ped with player /// #IF IS_DEBUG_BUILD PRINTSTRING("\n Changing current player character from ")PRINTSTRING(GET_PLAYER_PED_STRING(ePedRep))PRINTSTRING(" to ")PRINTSTRING(GET_PLAYER_PED_STRING(ePedSel))PRINTNL()PRINTNL() #ENDIF #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Changing current player character from ", ENUM_TO_INT(ePedRep), " to ", ENUM_TO_INT(ePedSel), ".") #ENDIF SWITCH GET_PLAYER_PED_ENUM(PLAYER_PED_ID()) CASE CHAR_MICHAEL IF ANIMPOSTFX_IS_RUNNING("BulletTime") ANIMPOSTFX_STOP("BulletTime") ENDIF IF ANIMPOSTFX_IS_RUNNING("BulletTimeOut") ANIMPOSTFX_STOP("BulletTimeOut") ENDIF BREAK CASE CHAR_FRANKLIN IF ANIMPOSTFX_IS_RUNNING("DrivingFocus") ANIMPOSTFX_STOP("DrivingFocus") ENDIF IF ANIMPOSTFX_IS_RUNNING("DrivingFocusOut") ANIMPOSTFX_STOP("DrivingFocusOut") ENDIF BREAK CASE CHAR_TREVOR IF ANIMPOSTFX_IS_RUNNING("REDMIST") ANIMPOSTFX_STOP("REDMIST") ENDIF IF ANIMPOSTFX_IS_RUNNING("REDMISTOut") ANIMPOSTFX_STOP("REDMISTOut") ENDIF BREAK ENDSWITCH // B* 2312133 - Should fix Assert 2. IF IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM()) IF IS_SPECIAL_ABILITY_ACTIVE(PLAYER_ID()) SPECIAL_ABILITY_DEACTIVATE_FAST(PLAYER_ID()) ENDIF ENDIF CDEBUG1LN(DEBUG_INIT_SP, " - selector_public - Changing player ped.") CHANGE_PLAYER_PED(PLAYER_ID(), selectorPeds.pedID[selectorPeds.eNewSelectorPed], bKeepTasks, FALSE) // Prevent cash from displaying (bug 1234294) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_CASH) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_CASH_CHANGE) IF (eFlags & TCF_CLEAR_TASK_INTERRUPT_CHECKS) != TCF_NONE SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_WaitingForPlayerControlInterrupt, FALSE) ENDIF // Increment switch count for current mission if manual switch took place IF IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) IF g_sSelectorUI.bManualSelection // NOTE: We can use GET_THIS_SCRIPT_NAME() to get the current mission // but it's probably safer to stay in sync with the flow. // Determine the current running mission INT availableMissionIndex #IF USE_CLF_DLC REPEAT MAX_MISSIONS_AVAILABLE_TU availableMissionIndex IF IS_BIT_SET(g_availableMissionsTU[availableMissionIndex].bitflags, BITS_AVAILABLE_MISSION_RUNNING) INT theCoreVarsIndex = g_availableMissionsTU[availableMissionIndex].index #ENDIF #IF USE_NRM_DLC REPEAT MAX_MISSIONS_AVAILABLE_TU availableMissionIndex IF IS_BIT_SET(g_availableMissionsTU[availableMissionIndex].bitflags, BITS_AVAILABLE_MISSION_RUNNING) INT theCoreVarsIndex = g_availableMissionsTU[availableMissionIndex].index #ENDIF #IF NOT USE_SP_DLC REPEAT MAX_MISSIONS_AVAILABLE availableMissionIndex IF IS_BIT_SET(g_availableMissions[availableMissionIndex].bitflags, BITS_AVAILABLE_MISSION_RUNNING) INT theCoreVarsIndex = g_availableMissions[availableMissionIndex].index #ENDIF TEXT_LABEL_63 tlStatName tlStatName = "MISS_SWITCH_" tlStatName += g_sMissionStaticData[g_flowUnsaved.coreVars[theCoreVarsIndex].iValue1].scriptName PRINTLN("STAT_INCREMENT - ", tlStatName) STAT_INCREMENT(INT_TO_ENUM(STATSENUM, GET_HASH_KEY(tlStatName)), 1) //Necessary to keep intellisense happy. #IF USE_CLF_DLC ENDIF ENDREPEAT #ENDIF #IF USE_NRM_DLC ENDIF ENDREPEAT #ENDIF #IF NOT USE_SP_DLC ENDIF ENDREPEAT #ENDIF ENDIF ENDIF // Clear the manual selection flag (also gets cleared when we force a switch with SET_CURRENT_SELECTOR_PED()) g_sSelectorUI.bManualSelection = FALSE ////////////////////////////////////////////////////////////////////////////////// /// [4] Update the references that we have to the selector peds /// selectorPeds.ePreviousSelectorPed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(ePedRep) // If the ePreviousSelectorPed points to an invalid slot, we must be returning from multi-player IF selectorPeds.ePreviousSelectorPed = NUMBER_OF_SELECTOR_PEDS selectorPeds.ePreviousSelectorPed = SELECTOR_PED_MULTIPLAYER ENDIF selectorPeds.pedID[selectorPeds.ePreviousSelectorPed] = originalPlayerPedID selectorPeds.pedID[selectorPeds.eNewSelectorPed] = NULL // currently points to the player's ped index selectorPeds.eCurrentSelectorPed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(ePedSel) selectorPeds.eNewSelectorPed = NUMBER_OF_SELECTOR_PEDS ////////////////////////////////////////////////////////////////////////////////// /// [5] Update the players info /// PED_INDEX currentPlayerPedID = PLAYER_PED_ID() //FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE) SET_ENTITY_VISIBLE(PLAYER_PED_ID(), TRUE) //RESTORE_PLAYER_PED_COMPONENT_VARIATIONS(currentPlayerPedID) //RESTORE_PLAYER_PED_PROPS(currentPlayerPedID) //RESTORE_PLAYER_PED_WEAPONS(currentPlayerPedID) //RESTORE_PLAYER_PED_ARMOUR(currentPlayerPedID RESTORE_PLAYER_PED_HEALTH(currentPlayerPedID) SET_PED_CAN_LOSE_PROPS_ON_DAMAGE(currentPlayerPedID, FALSE) // Make sure the player now has atleast 25% when we switch to them IF fSelectedPedHealthPerc < 25.0 AND NOT IS_PED_SWIMMING_UNDER_WATER(PLAYER_PED_ID()) PRINTLN("Players health is low so increasing to 25%") SET_ENTITY_HEALTH(PLAYER_PED_ID(), ROUND(((25.0 / 100.0) * (TO_FLOAT(GET_PED_MAX_HEALTH(PLAYER_PED_ID())) - 100.0)) + 100.0)) ENDIF ////////////////////////////////////////////////////////////////////////////////// /// [6] Update the previous players info /// IF bKeepPlayerReplacement IF DOES_ENTITY_EXIST(originalPlayerPedID) //FREEZE_ENTITY_POSITION(originalPlayerPedID, FALSE) SET_ENTITY_VISIBLE(originalPlayerPedID, TRUE) //RESTORE_PLAYER_PED_COMPONENT_VARIATIONS(originalPlayerPedID) //RESTORE_PLAYER_PED_PROPS(originalPlayerPedID) //RESTORE_PLAYER_PED_WEAPONS(originalPlayerPedID) //RESTORE_PLAYER_PED_ARMOUR(originalPlayerPedID) RESTORE_PLAYER_PED_HEALTH(originalPlayerPedID) SET_PED_CAN_LOSE_PROPS_ON_DAMAGE(originalPlayerPedID, FALSE) SET_PED_STEALTH_MOVEMENT(originalPlayerPedID, FALSE) ENDIF ELSE IF DOES_ENTITY_EXIST(originalPlayerPedID) // B* 2312133 - Should fix Assert 3. INT iEntityInstanceID STRING strEntityScript = GET_ENTITY_SCRIPT(originalPlayerPedID, iEntityInstanceID) CDEBUG1LN(DEBUG_INIT_SP, " - selector_public - strEntityScript: ", strEntityScript) IF NOT IS_STRING_NULL(strEntityScript) // Ensure that the entity is owned by script IF NOT ARE_STRINGS_EQUAL(strEntityScript, GET_THIS_SCRIPT_NAME()) CDEBUG1LN(DEBUG_INIT_SP, " - selector_public - strEntityScript is from a different script.") CDEBUG1LN(DEBUG_INIT_SP, " - selector_public - Setting originalPlayerPedID to be owned by this script.") SET_ENTITY_AS_MISSION_ENTITY(originalPlayerPedID, FALSE, TRUE) // Ensure that the entity is owned by THIS script ENDIF PRINTLN("TAKE_CONTROL_OF_SELECTOR_PED - Deleting previous player ped") DELETE_PED(originalPlayerPedID) ENDIF ENDIF ENDIF // Player switched so perform some maintenance routines. g_bPerformCustomStatUpdate = TRUE UPDATE_PED_AMMO_SO_IT_IS_NOT_INFINITE(PLAYER_PED_ID()) UPDATE_PLAYER_PED_BLIP_NAME() UPDATE_PLAYER_CHARACTER_RELATIONSHIPS(ePedSel) UPDATE_PLAYER_PED_VARIATION_STATS() UPDATE_ALL_PLAYER_STAT_SETTINGS(ePedSel) Update_Savehouse_Door_States(GET_CLOSEST_SAVEHOUSE(GET_ENTITY_COORDS(PLAYER_PED_ID()), NO_CHARACTER, FALSE)) RESET_PLAYER_STAMINA(PLAYER_ID()) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(PLAYER_PED_ID(), FALSE) SET_PED_CAN_BE_DRAGGED_OUT(PLAYER_PED_ID(), TRUE) //Reinstate player's scuba gear and parachute state. #IF USE_CLF_DLC IF IS_PLAYER_PLAYING(PLAYER_ID()) SET_AUTO_GIVE_PARACHUTE_WHEN_ENTER_PLANE(PLAYER_ID(), true) SET_AUTO_GIVE_SCUBA_GEAR_WHEN_EXIT_VEHICLE(PLAYER_ID(), true) ENDIF #ENDIF #IF USE_NRM_DLC IF IS_PLAYER_PLAYING(PLAYER_ID()) SET_AUTO_GIVE_PARACHUTE_WHEN_ENTER_PLANE(PLAYER_ID(), true) SET_AUTO_GIVE_SCUBA_GEAR_WHEN_EXIT_VEHICLE(PLAYER_ID(), true) ENDIF #ENDIF #IF NOT USE_SP_DLC IF IS_PLAYER_PLAYING(PLAYER_ID()) SET_AUTO_GIVE_PARACHUTE_WHEN_ENTER_PLANE(PLAYER_ID(), GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_AIR_VEHICLE_PARACHUTE_UNLOCKED)) ENDIF IF IS_PLAYER_PLAYING(PLAYER_ID()) SET_AUTO_GIVE_SCUBA_GEAR_WHEN_EXIT_VEHICLE(PLAYER_ID(), GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_WATER_VEHICLE_SCUBA_GEAR_UNLOCKED)) ENDIF #ENDIF REGISTER_PLAYER_PED_WITH_AUTOMATIC_DOORS(ePedSel, currentPlayerPedID) IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_FRIENDS) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_PREP) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_RANDOM_CHAR) CPRINTLN(DEBUG_FLOW, "SWITCH from script ", GET_THIS_SCRIPT_NAME(), " setting ped flags for new player while on Story or RC mission.") CPRINTLN(DEBUG_FLOW, "Set WillFlyThroughWindscreen to FALSE for PED_INDEX[",NATIVE_TO_INT(currentPlayerPedID),"].") CPRINTLN(DEBUG_FLOW, "Set WillTakeDamageWhenVehicleCrashes to FALSE for PED_INDEX[",NATIVE_TO_INT(currentPlayerPedID),"].") SET_PED_CONFIG_FLAG(currentPlayerPedID, PCF_WillFlyThroughWindscreen, FALSE) SET_PED_CONFIG_FLAG(currentPlayerPedID, PCF_WillTakeDamageWhenVehicleCrashes, FALSE) ELSE CPRINTLN(DEBUG_FLOW, "SWITCH from script ", GET_THIS_SCRIPT_NAME(), " setting ped flags for new player while not on mission.") CPRINTLN(DEBUG_FLOW, "Set WillFlyThroughWindscreen to TRUE for PED_INDEX[",NATIVE_TO_INT(currentPlayerPedID),"].") CPRINTLN(DEBUG_FLOW, "Set WillTakeDamageWhenVehicleCrashes to TRUE for PED_INDEX[",NATIVE_TO_INT(currentPlayerPedID),"].") SET_PED_CONFIG_FLAG(currentPlayerPedID, PCF_WillFlyThroughWindscreen, TRUE) SET_PED_CONFIG_FLAG(currentPlayerPedID, PCF_WillTakeDamageWhenVehicleCrashes, TRUE) ENDIF IF NOT IS_SELECTOR_CAM_ACTIVE() UPDATE_PLAYER_PED_TIMECYCLE_MODIFIER() ENDIF //Clear lead-in streaming block. g_bBlockTriggerSceneLoadDuringSwitch = FALSE CPRINTLN(DEBUG_TRIGGER, "Player ped just switched. Clearing lead-in load block flag.") RETURN TRUE // Player now taken control of selector ped // Problems with peds ELSE IF IS_PED_INJURED(PLAYER_PED_ID()) PRINTLN("Cannot take control of selector ped as the PLAYER is dead or do not exist.") #IF IS_DEBUG_BUILD CWARNINGLN(DEBUG_TRIGGER, "Cannot take control of selector ped as the PLAYER is dead or do not exist.") #ENDIF ENDIF IF IS_PED_INJURED(selectorPeds.pedID[selectorPeds.eNewSelectorPed]) PRINTLN("Cannot take control of selector ped as the PED is dead or do not exist.") #IF IS_DEBUG_BUILD CWARNINGLN(DEBUG_TRIGGER, "Cannot take control of selector ped as the PED is dead or do not exist.") #ENDIF ENDIF IF (PLAYER_PED_ID() = selectorPeds.pedID[selectorPeds.eNewSelectorPed]) PRINTLN("Cannot take control of selector ped as PLAYER = PED[", GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(selectorPeds.eNewSelectorPed)), "].") #IF IS_DEBUG_BUILD CWARNINGLN(DEBUG_TRIGGER, "Cannot take control of selector ped as PLAYER = PED[", GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(selectorPeds.eNewSelectorPed)), "].") #ENDIF ENDIF ENDIF RETURN FALSE // Come across an error ENDFUNC ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// SELECTOR UI COMMANDS /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PURPOSE: Returns TRUE if the selector is disabled FUNC BOOL IS_SELECTOR_DISABLED() RETURN (g_sSelectorUI.bDisabled OR g_sSelectorUI.bDisabledThisFrame) ENDFUNC // PURPOSE: Returns TRUE if the selector UI is on screen FUNC BOOL IS_SELECTOR_ONSCREEN(BOOL bFullUI = TRUE) IF bFullUI RETURN (g_sSelectorUI.bOnScreen AND g_sSelectorUI.eUIStateCurrent = SELECTOR_UI_FULL) ELSE RETURN (g_sSelectorUI.bOnScreen) ENDIF ENDFUNC FUNC BOOL IS_REPLAY_RECORDING_FEED_BUTTONS_ONSCREEN() RETURN (g_sSelectorUI.bFeedAddedForRecording) ENDFUNC // PURPOSE: Allow the selector hud to operate PROC ENABLE_SELECTOR() #IF IS_DEBUG_BUILD PRINTSTRING("\n ENABLE_SELECTOR() called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL() #ENDIF g_sSelectorUI.bDisabled = FALSE ENDPROC // PURPOSE: Prevent the selector hud from working PROC DISABLE_SELECTOR() #IF IS_DEBUG_BUILD PRINTSTRING("\n DISABLE_SELECTOR() called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL() #ENDIF g_sSelectorUI.bDisabled = TRUE ENDPROC // PURPOSE: Prevent the selector hud from working PROC DISABLE_SELECTOR_THIS_FRAME() #IF IS_DEBUG_BUILD IF IS_STRING_NULL_OR_EMPTY(g_sSelectorUI.tlDisableScript) OR NOT ARE_STRINGS_EQUAL(GET_THIS_SCRIPT_NAME(), g_sSelectorUI.tlDisableScript) DEBUG_PRINTCALLSTACK() PRINTSTRING("\n DISABLE_SELECTOR_THIS_FRAME() called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL() g_sSelectorUI.tlDisableScript = GET_THIS_SCRIPT_NAME() ENDIF #ENDIF g_sSelectorUI.bDisabledThisFrame = TRUE ENDPROC // PURPOSE: Prevent the selector hud from overriding the players position on the map PROC DISABLE_SELECTOR_MAP_UPDATE_THIS_FRAME() g_sSelectorUI.bDisableMapOverrideThisFrame = TRUE ENDPROC // PURPOSE: Prevent the selector hud from rendering PROC HIDE_SELECTOR_THIS_FRAME(BOOL bHide = TRUE, BOOL bAllowSelection = FALSE) #IF IS_DEBUG_BUILD IF IS_STRING_NULL_OR_EMPTY(g_sSelectorUI.tlHideScript) OR NOT ARE_STRINGS_EQUAL(GET_THIS_SCRIPT_NAME(), g_sSelectorUI.tlHideScript) IF bHide PRINTSTRING("\n HIDE_SELECTOR_THIS_FRAME(TRUE) called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL() ELSE PRINTSTRING("\n HIDE_SELECTOR_THIS_FRAME(FALSE) called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL() ENDIF g_sSelectorUI.tlHideScript = GET_THIS_SCRIPT_NAME() ENDIF #ENDIF g_sSelectorUI.bHiddenThisFrame = bHide g_sSelectorUI.bAllowSelectionWhenHidden = bAllowSelection ENDPROC // PURPOSE: Prevent the selector hud from rendering PROC FORCE_LOAD_SELECTOR_THIS_FRAME() g_sSelectorUI.bForceLoadThisFrame = TRUE ENDPROC PROC DISABLE_SELECTOR_QUICK_SWITCH_TO_DAMAGED_PED(BOOL bDisable) #IF IS_DEBUG_BUILD IF bDisable PRINTSTRING("\n DISABLE_SELECTOR_QUICK_SWITCH_TO_DAMAGED_PED(TRUE) called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL() ELSE PRINTSTRING("\n DISABLE_SELECTOR_QUICK_SWITCH_TO_DAMAGED_PED(FALSE) called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL() ENDIF #ENDIF g_sSelectorUI.bBlockQuickSwitchToDamagedPed = bDisable ENDPROC // PURPOSE: Allow the selector sfx to play PROC ENABLE_SELECTOR_SFX() #IF IS_DEBUG_BUILD PRINTSTRING("\n ENABLE_SELECTOR_SFX() called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL() #ENDIF g_sSelectorUI.bSFX_BlockAudioCalls = FALSE ENDPROC // PURPOSE: Prevent the selector sfx from playing PROC DISABLE_SELECTOR_SFX() #IF IS_DEBUG_BUILD PRINTSTRING("\n DISABLE_SELECTOR_SFX() called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL() #ENDIF g_sSelectorUI.bSFX_BlockAudioCalls = TRUE ENDPROC /// PURPOSE: Allows a specific icon to be displayed on the SWITCH UI /// NTOE: COMMAND NOW OBSOLETE PROC SET_SELECTOR_PED_ACTIVITY(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, SELECTOR_ACTIVITY_ENUM eActivity) IF ePed <> ePEd AND eActivity != eActivity AND sSelectorPeds.bAmbient ENDIF ENDPROC /// PURPOSE: Allows a specific icon to be displayed on the SWITCH UI PROC SET_SELECTOR_PED_ICON(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, SELECTOR_ICON_ENUM eIcon) IF ePed <> NUMBER_OF_SELECTOR_PEDS sSelectorPeds.eIcons[ePed] = eIcon ENDIF ENDPROC /// PURPOSE: Sets the fake selector ped state so we can override ui. PROC SET_SELECTOR_PED_FAKE_STATE(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, SELECTOR_STATE_ENUM eState) IF ePed <> NUMBER_OF_SELECTOR_PEDS sSelectorPeds.eFakeState[ePed] = eState g_sSelectorUI.bFakeStateUpdated = TRUE ENDIF ENDPROC /// PURPOSE: Sets the hint flag so that we can indicate who the player should select PROC SET_SELECTOR_PED_HINT(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, BOOL bHinted = TRUE) IF ePed <> NUMBER_OF_SELECTOR_PEDS sSelectorPeds.bDisplayHint[ePed] = bHinted ENDIF ENDPROC /// PURPOSE: Sets the damaged flag so that we can indicate who the player should select PROC SET_SELECTOR_PED_DAMAGED(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, BOOL bDamaged = TRUE) IF ePed <> NUMBER_OF_SELECTOR_PEDS sSelectorPeds.bDisplayDamage[ePed] = bDamaged ENDIF ENDPROC /// PURPOSE: Sets the priority order when making auto selection /// NOTE: QUICK SWITCH PROC SET_SELECTOR_PED_PRIORITY(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed1, SELECTOR_SLOTS_ENUM ePed2, SELECTOR_SLOTS_ENUM ePed3) sSelectorPeds.bUseCustomAutoSelectOption = TRUE sSelectorPeds.eAutoSelectOption1 = ePed1 sSelectorPeds.eAutoSelectOption2 = ePed2 sSelectorPeds.eAutoSelectOption3 = ePed3 ENDPROC /// PURPOSE: Sets the auto selection priority to use default PROC CLEAR_SELECTOR_PED_PRIORITY(SELECTOR_PED_STRUCT &sSelectorPeds) sSelectorPeds.bUseCustomAutoSelectOption = FALSE ENDPROC /// PURPOSE: Blocks the selector ped from being selected PROC SET_SELECTOR_PED_BLOCKED(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, BOOL bBlockPed = TRUE) IF ePed <> NUMBER_OF_SELECTOR_PEDS sSelectorPeds.bBlockSelectorPed[ePed] = bBlockPed #IF IS_DEBUG_BUILD PRINTSTRING("\n SET_SELECTOR_PED_BLOCKED - ")PRINTSTRING(GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(ePed))) IF bBlockPed PRINTSTRING(" blocked")PRINTNL() ELSE PRINTSTRING(" unblocked")PRINTNL() ENDIF #ENDIF ENDIF ENDPROC /// PURPOSE: Checks to see if a selector ped can be selected at this point in the flow FUNC BOOL IS_SELECTOR_PED_INTRODUCED_IN_FLOWclf(SELECTOR_SLOTS_ENUM ePed) IF g_savedGlobalsClifford.sFlow.isGameflowActive OR IS_REPEAT_PLAY_ACTIVE() // this is also needed for repeat play // Allow last known player ped when in multiplayer IF (NOT g_bInMultiplayer) OR (g_bInMultiplayer AND ePed != GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_LAST_KNOWN_PLAYER_PED_ENUM())) // Introduced? IF ePed = SELECTOR_PED_MICHAEL OR ePed = SELECTOR_PED_FRANKLIN RETURN FALSE ENDIF ENDIF ENDIF RETURN TRUE ENDFUNC FUNC BOOL IS_SELECTOR_PED_INTRODUCED_IN_FLOWNRM(SELECTOR_SLOTS_ENUM ePed) IF g_savedGlobalsnorman.sFlow.isGameflowActive OR IS_REPEAT_PLAY_ACTIVE() // this is also needed for repeat play // Allow last known player ped when in multiplayer IF (NOT g_bInMultiplayer) OR (g_bInMultiplayer AND ePed != GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_LAST_KNOWN_PLAYER_PED_ENUM())) // Introduced? // IF ePed = SELECTOR_PED_TREVOR // OR ePed = SELECTOR_PED_FRANKLIN // RETURN FALSE // ENDIF ENDIF ENDIF RETURN TRUE ENDFUNC FUNC BOOL IS_SELECTOR_PED_INTRODUCED_IN_FLOW(SELECTOR_SLOTS_ENUM ePed) #IF USE_CLF_DLC return IS_SELECTOR_PED_INTRODUCED_IN_FLOWclf(ePed) #ENDIF #if USE_NRM_DLC return IS_SELECTOR_PED_INTRODUCED_IN_FLOWNRM(ePed) #endif #if not USE_CLF_DLC #if not USE_NRM_DLC IF g_savedGlobals.sFlow.isGameflowActive OR g_bMagDemoActive OR IS_REPEAT_PLAY_ACTIVE() // this is also needed for repeat play // Allow last known player ped when in multiplayer IF (NOT g_bInMultiplayer) OR (g_bInMultiplayer AND ePed != GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_LAST_KNOWN_PLAYER_PED_ENUM())) // Introduced? IF (ePed = SELECTOR_PED_MICHAEL AND NOT Get_Mission_Flow_Flag_State(FLOWFLAG_PLAYER_PED_INTRODUCED_M)) OR (ePed = SELECTOR_PED_FRANKLIN AND NOT Get_Mission_Flow_Flag_State(FLOWFLAG_PLAYER_PED_INTRODUCED_F)) OR (ePed = SELECTOR_PED_TREVOR AND NOT Get_Mission_Flow_Flag_State(FLOWFLAG_PLAYER_PED_INTRODUCED_T)) RETURN FALSE ENDIF ENDIF ENDIF RETURN TRUE #endif #endif ENDFUNC /// PURPOSE: Checks to see if a selector ped can be selected at this point in the flow FUNC BOOL IS_SELECTOR_PED_AVAILABLE_IN_FLOW(SELECTOR_SLOTS_ENUM ePed) #IF USE_CLF_DLC //CLF check IF g_bLoadedClifford if ePed = SELECTOR_PED_FRANKLIN or ePed = SELECTOR_PED_MICHAEL RETURN FALSE ELSE RETURN TRUE ENDIF ENDIF #ENDIF IF g_savedGlobals.sFlow.isGameflowActive OR g_bMagDemoActive #IF NOT DEFINED(USE_SELECTOR_CHANGES) // Allow last known player ped when in multiplayer IF (NOT g_bInMultiplayer) OR (g_bInMultiplayer AND ePed != GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_LAST_KNOWN_PLAYER_PED_ENUM())) #ENDIF // Available? IF NOT IS_PLAYER_PED_AVAILABLE(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(ePed)) RETURN FALSE ENDIF #IF NOT DEFINED(USE_SELECTOR_CHANGES) ENDIF #ENDIF ENDIF RETURN TRUE ENDFUNC /// PURPOSE: Checks to see if the specified player character is the same as the current selection FUNC BOOL HAS_SELECTOR_PED_BEEN_SELECTED(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM eSelectedPed) IF sSelectorPeds.bInitialised IF eSelectedPed = sSelectorPeds.eNewSelectorPed RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Checks to see if the specified player character is the same as the current selection FUNC BOOL HAS_ANY_SELECTOR_PED_BEEN_SELECTED(SELECTOR_PED_STRUCT &sSelectorPeds) IF sSelectorPeds.bInitialised IF sSelectorPeds.eNewSelectorPed <> NUMBER_OF_SELECTOR_PEDS AND sSelectorPeds.eNewSelectorPed <> SELECTOR_PED_MULTIPLAYER RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Checks to see if the multiplayer option has been selected FUNC BOOL HAS_MULTIPLAYER_BEEN_SELECTED(SELECTOR_PED_STRUCT &sSelectorPeds) IF sSelectorPeds.bInitialised IF sSelectorPeds.eNewSelectorPed = SELECTOR_PED_MULTIPLAYER RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC FUNC INT GET_SELECTOR_UI_SLOT_FOR_SELECTOR_PED(SELECTOR_SLOTS_ENUM ePed) IF ePed = SELECTOR_PED_MICHAEL RETURN 3 // Left ELIF ePed = SELECTOR_PED_FRANKLIN RETURN 0 // Top ELIF ePed = SELECTOR_PED_TREVOR RETURN 1 // Right ELIF ePed = SELECTOR_PED_MULTIPLAYER RETURN 2 // Bottom ENDIF RETURN 0 ENDFUNC FUNC SELECTOR_SLOTS_ENUM GET_SELECTOR_PED_FROM_UI_SLOT(INT iSlot) IF iSlot = 3 RETURN SELECTOR_PED_MICHAEL // Left ELIF iSlot = 0 RETURN SELECTOR_PED_FRANKLIN // Top ELIF iSlot = 1 RETURN SELECTOR_PED_TREVOR // Right ELIF iSlot = 2 RETURN SELECTOR_PED_MULTIPLAYER // Bottom ENDIF RETURN SELECTOR_PED_MICHAEL ENDFUNC PROC DISPLAY_SELECTOR_PED_AUTOSWITCH_UI(SELECTOR_SLOTS_ENUM eAutoSwitchPed) // This is currently placeholder - disabling for now. EXIT PRINTLN("DISPLAY_SELECTOR_PED_AUTOSWITCH_UI - called for selector ped ", eAutoSwitchPed) #IF IS_DEBUG_BUILD DEBUG_PRINTCALLSTACK() #ENDIF g_sSelectorUI.bShowAutoSwitch = TRUE g_sSelectorUI.iAutoSwitchSlot = GET_SELECTOR_UI_SLOT_FOR_SELECTOR_PED(eAutoSwitchPed) g_sSelectorUI.iAutoSwitchTimer = GET_GAME_TIMER() ENDPROC /// PURPOSE: Sets the enum of the ped we want to take control of /// NOTE: This is the alternative to using the interface FUNC BOOL MAKE_SELECTOR_PED_SELECTION(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM eSelectedPed) // Reset the selected ped IF NOT sSelectorPeds.bInitialised sSelectorPeds.eNewSelectorPed = NUMBER_OF_SELECTOR_PEDS sSelectorPeds.bInitialised = TRUE ENDIF IF eSelectedPed <> SELECTOR_PED_MICHAEL AND eSelectedPed <> SELECTOR_PED_TREVOR AND eSelectedPed <> SELECTOR_PED_FRANKLIN #IF IS_DEBUG_BUILD PRINTLN("\n***") PRINTLN("NO CHARACTER has been selected for SWITCH!") PRINTLN("***\n") #ENDIF ELSE #IF IS_DEBUG_BUILD PRINTLN("MAKE_SELECTOR_PED_SELECTION: ped=", ENUM_TO_INT(eSelectedPed), ", current=", GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_CURRENT_PLAYER_PED_ENUM()) = eSelectedPed, ", fake available=", (sSelectorPeds.eFakeState[eSelectedPed] = SELECTOR_STATE_AVAILABLE), ", fake current=", (sSelectorPeds.eFakeState[eSelectedPed] = SELECTOR_STATE_CURRENT), ", introduced=", IS_SELECTOR_PED_INTRODUCED_IN_FLOW(eSelectedPed), ", available=", IS_SELECTOR_PED_AVAILABLE_IN_FLOW(eSelectedPed), ", blocked=", sSelectorPeds.bBlockSelectorPed[eSelectedPed], // ", injured=", IS_PED_INJURED(sSelectorPeds.pedID[eSelectedPed]), ", wantedlevel=", GET_PLAYER_WANTED_LEVEL(PLAYER_ID())) #ENDIF BOOL bUsingFakePed = (sSelectorPeds.eFakeState[eSelectedPed] = SELECTOR_STATE_AVAILABLE) IF GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_CURRENT_PLAYER_PED_ENUM()) <> eSelectedPed OR bUsingFakePed // If we are in ambient mode then make sure the ped is available BOOL bPedAvailable = FALSE #IF USE_CLF_DLC IF bUsingFakePed OR (sSelectorPeds.eIcons[eSelectedPed] != SELECTOR_ICON_DEFAULT) OR (IS_SELECTOR_PED_INTRODUCED_IN_FLOW(eSelectedPed) AND IS_SELECTOR_PED_AVAILABLE_IN_FLOW(eSelectedPed) AND NOT sSelectorPeds.bBlockSelectorPed[eSelectedPed]) #ENDIF #IF USE_NRM_DLC IF bUsingFakePed OR (sSelectorPeds.eIcons[eSelectedPed] != SELECTOR_ICON_DEFAULT) OR (IS_SELECTOR_PED_INTRODUCED_IN_FLOW(eSelectedPed) AND IS_SELECTOR_PED_AVAILABLE_IN_FLOW(eSelectedPed) AND NOT sSelectorPeds.bBlockSelectorPed[eSelectedPed]) #ENDIF #IF NOT USE_SP_DLC IF bUsingFakePed OR (sSelectorPeds.eIcons[eSelectedPed] != SELECTOR_ICON_DEFAULT) OR (IS_SELECTOR_PED_INTRODUCED_IN_FLOW(eSelectedPed) AND IS_SELECTOR_PED_AVAILABLE_IN_FLOW(eSelectedPed) AND NOT sSelectorPeds.bBlockSelectorPed[eSelectedPed]) #ENDIF IF (NOT sSelectorPeds.bAmbient) IF (NOT IS_PED_INJURED(sSelectorPeds.pedID[eSelectedPed]) OR bUsingFakePed) IF (sSelectorPeds.eFakeState[eSelectedPed] <> SELECTOR_STATE_UNAVAILABLE) AND (sSelectorPeds.eFakeState[eSelectedPed] <> SELECTOR_STATE_CURRENT) PRINTLN("bPedAvailable = TRUE [NOT sSelectorPeds.bAmbient]") bPedAvailable = TRUE ENDIF ENDIF ELSE // Fix for bug #725557 - Don't let player switch with wanted level see imran // - Still need UI to display so we can select multiplayer. IF NOT IS_PED_INJURED(PLAYER_PED_ID()) AND (NETWORK_IS_GAME_IN_PROGRESS() OR GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0) //#IF NOT USE_TU_CHANGES AND NOT IS_BIT_SET(g_sPlayerPedRequest.iBitsetPedInLeadIn, ENUM_TO_INT(eSelectedPed)) //Block switching to player's created in lead-ins. //#ENDIF PRINTLN("bPedAvailable = TRUE [sSelectorPeds.bAmbient]") bPedAvailable = TRUE ENDIF ENDIF #IF USE_CLF_DLC // allow stats to display when we boot into debug ELIF NOT (IS_BIT_SET(g_savedGlobalsClifford.sFlow.strandSavedVars[STRAND_CLF].savedBitflags, SAVED_BITS_STRAND_ACTIVATED) AND NOT IS_REPEAT_PLAY_ACTIVE()) IF (sSelectorPeds.bAmbient) bPedAvailable = TRUE IF eSelectedPed = SELECTOR_PED_FRANKLIN OR eSelectedPed = SELECTOR_PED_MICHAEL PRINTLN("bPedAvailable = TRUE [USE_CLF_DLC]") bPedAvailable = FALSE ENDIF ENDIF ENDIF #ENDIF #IF USE_NRM_DLC // allow stats to display when we boot into debug ELIF NOT (IS_BIT_SET(g_savedGlobalsnorman.sFlow.strandSavedVars[STRAND_NRM_SURVIVE].savedBitflags, SAVED_BITS_STRAND_ACTIVATED) AND NOT IS_REPEAT_PLAY_ACTIVE()) IF (sSelectorPeds.bAmbient) PRINTLN("bPedAvailable = TRUE [USE_NRM_DLC]") bPedAvailable = TRUE ENDIF ENDIF #ENDIF #IF NOT USE_SP_DLC // allow stats to display when we boot into debug ELIF NOT (IS_BIT_SET(g_savedGlobals.sFlow.strandSavedVars[STRAND_PROLOGUE].savedBitflags, SAVED_BITS_STRAND_ACTIVATED) AND NOT g_bMagDemoActive AND NOT IS_REPEAT_PLAY_ACTIVE()) IF (sSelectorPeds.bAmbient) PRINTLN("bPedAvailable = TRUE [NOT USE_SP_DLC]") bPedAvailable = TRUE ENDIF ENDIF #ENDIF IF bPedAvailable #IF IS_DEBUG_BUILD PRINTLN("\n***") PRINTLN(GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(eSelectedPed)), " has been selected for SWITCH [fc ", GET_FRAME_COUNT(), "]!") PRINTLN("***\n") #ENDIF sSelectorPeds.eNewSelectorPed = eSelectedPed #IF NOT USE_TU_CHANGES IF NOT g_sSelectorUI.bOnScreen DISPLAY_SELECTOR_PED_AUTOSWITCH_UI(eSelectedPed) ENDIF #ENDIF RETURN TRUE ENDIF ENDIF ENDIF // Set this flag to false to prevent the take control command from hitting array overrun. sSelectorPeds.bInitialised = FALSE RETURN FALSE ENDFUNC /// PURPOSE: Sets the enum of the ped we want to take control of /// NOTE: This is the alternative to using the interface FUNC BOOL MAKE_DIRECTOR_MODE_SELECTOR_PED_SELECTION(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM eSelectedPed) // Reset the selected ped IF NOT sSelectorPeds.bInitialised sSelectorPeds.eNewSelectorPed = NUMBER_OF_SELECTOR_PEDS sSelectorPeds.bInitialised = TRUE ENDIF #IF IS_DEBUG_BUILD PRINTLN("MAKE_DIRECTOR_MODE_SELECTOR_PED_SELECTION: ped=", ENUM_TO_INT(eSelectedPed), ", current=", GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_CURRENT_PLAYER_PED_ENUM()) = eSelectedPed, ", introduced=", IS_SELECTOR_PED_INTRODUCED_IN_FLOW(eSelectedPed), ", available=", IS_SELECTOR_PED_AVAILABLE_IN_FLOW(eSelectedPed)) #ENDIF // If we are in ambient mode then make sure the ped is available BOOL bPedAvailable = FALSE #IF USE_CLF_DLC IF eSelectedPed = SELECTOR_PED_MULTIPLAYER OR eSelectedPed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(g_savedGlobalsClifford.sPlayerData.sInfo.eLastKnownPed) #ENDIF #IF USE_NRM_DLC IF eSelectedPed = SELECTOR_PED_MULTIPLAYER OR eSelectedPed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(g_savedGlobalsnorman.sPlayerData.sInfo.eLastKnownPed) #ENDIF #IF NOT USE_SP_DLC IF eSelectedPed = SELECTOR_PED_MULTIPLAYER OR eSelectedPed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(g_savedGlobals.sPlayerData.sInfo.eLastKnownPed) #ENDIF // Fix for bug #725557 - Don't let player switch with wanted level see imran // - Still need UI to display so we can select multiplayer. IF NOT IS_PED_INJURED(PLAYER_PED_ID()) PRINTLN("bPedAvailable = TRUE [sSelectorPeds.bAmbient]") bPedAvailable = TRUE ENDIF #IF USE_CLF_DLC ENDIF #ENDIF #IF USE_NRM_DLC ENDIF #ENDIF #IF NOT USE_SP_DLC ENDIF #ENDIF IF bPedAvailable #IF IS_DEBUG_BUILD PRINTLN("\n***") PRINTLN(GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(eSelectedPed)), " has been selected for SWITCH [fc ", GET_FRAME_COUNT(), "]!") PRINTLN("***\n") #ENDIF sSelectorPeds.eNewSelectorPed = eSelectedPed RETURN TRUE ENDIF // Set this flag to false to prevent the take control command from hitting array overrun. sSelectorPeds.bInitialised = FALSE RETURN FALSE ENDFUNC FUNC BOOL ARE_ANY_EXTERNAL_WARNING_SCREENS_RUNNING() IF IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_TRANSITION_JOIN_FAILED) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_DROPINVITE_UNDERAGE) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_DROPINVITE_STILL_ON_TUTORIAL) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_DROPINVITE_NO_CHARACTERS) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_DROPINVITE_SESSION_FULL) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_TRANSITION_CLOUD_DOWN) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_TRANSITION_CLOUD_UP) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_DROPINVITE_GTAO_NOT_AVAIL) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_DROPINVITE_SP_PROLOGUE_NOT_DONE) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_DROPINVITE_SAME_SESSION) OR IS_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_DROPINVITE_SAVE_ISSUE) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Sets the multiplayer flag to TRUE /// NOTE: This is the alternative to using the interface FUNC BOOL MAKE_MULTIPLAYER_SELECTION(SELECTOR_PED_STRUCT &sSelectorPeds) // Fix for bug 1596720 - remove text completely IF NOT IS_GTA_ONLINE_AVAILABLE(TRUE) #IF IS_DEBUG_BUILD PRINTLN("\n***") PRINTLN("Multiplayer not available!") PRINTLN("***\n") #ENDIF RETURN FALSE ENDIF // Reset the selected ped IF NOT sSelectorPeds.bInitialised sSelectorPeds.eNewSelectorPed = NUMBER_OF_SELECTOR_PEDS sSelectorPeds.bInitialised = TRUE ENDIF IF (NOT NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()) // Make sure the block flag is not set and it is an ambient update IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MULTIPLAYER] AND sSelectorPeds.bAmbient AND NOT g_bMagDemoActive #IF USE_TU_CHANGES AND IS_GTA_ONLINE_AVAILABLE() #ENDIF #IF IS_DEBUG_BUILD PRINTLN("\n***") PRINTLN("Multiplayer has been selected for SWITCH!") PRINTLN("***\n") #ENDIF sSelectorPeds.eNewSelectorPed = SELECTOR_PED_MULTIPLAYER RETURN TRUE #IF USE_TU_CHANGES ELSE IF IS_GTA_ONLINE_AVAILABLE() = FALSE AND ARE_ANY_EXTERNAL_WARNING_SCREENS_RUNNING() = FALSE MULTIPLAYER_ACCESS_CODE nAccessCode SCRIPT_NETWORK_CAN_ACCESS_MULTIPLAYER(nAccessCode) #IF IS_DEBUG_BUILD PRINTLN("\n***") PRINTLN("Multiplayer has been selected for SWITCH! BUT IS_GTA_ONLINE_AVAILABLE() = FALSE ") PRINTLN("Multiplayer has been selected for SWITCH! BUT IS_PLAYER_ONLINE() = ", IS_PLAYER_ONLINE()) PRINTLN("Multiplayer has been selected for SWITCH! BUT NETWORK_IS_SIGNED_ONLINE() = ", NETWORK_IS_SIGNED_ONLINE()) PRINTLN("Multiplayer has been selected for SWITCH! BUT NETWORK_HAS_VALID_ROS_CREDENTIALS() = ", NETWORK_HAS_VALID_ROS_CREDENTIALS()) PRINTLN("Multiplayer has been selected for SWITCH! BUT NETWORK_CAN_ENTER_MULTIPLAYER() = ", NETWORK_CAN_ENTER_MULTIPLAYER()) PRINTLN("Multiplayer has been selected for SWITCH! BUT SCRIPT_NETWORK_CAN_ACCESS_MULTIPLAYER(nAccessCode) = ", SCRIPT_NETWORK_CAN_ACCESS_MULTIPLAYER(nAccessCode)) #if not USE_CLF_DLC #if not USE_NRM_DLC PRINTLN("Multiplayer has been selected for SWITCH! BUT g_savedGlobals.sFlow.missionSavedData[SP_MISSION_PROLOGUE].completed = ", g_savedGlobals.sFlow.missionSavedData[SP_MISSION_PROLOGUE].completed) #endif #endif PRINTLN("Multiplayer has been selected for SWITCH! BUT nAccessCode = ", nAccessCode) IF IS_PLAYSTATION_PLATFORM() PRINTLN("Multiplayer has been selected for SWITCH! BUT NETWORK_GET_NP_UNAVAILABLE_REASON = ",GET_UNAVAILABILITY_REASON_STRING(NETWORK_GET_NP_UNAVAILABLE_REASON())) ENDIF PRINTLN("***\n") #ENDIF IF nAccessCode = ACCESS_DENIED_TUNABLE_NOT_FOUND SET_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_GTAO_ACCESS_DENIED, TRUE) ELIF IS_PLAYSTATION_PLATFORM() AND NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_AGE SET_WARNING_SCREEN_BAIL(WARNINGSCREEN_TRANSITION_UNDERAGE_NEXTGEN, TRUE) ELIF IS_PLAYSTATION_PLATFORM() AND NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_GAME_UPDATE SET_WARNING_SCREEN_BAIL(WARNINGSCREEN_TRANSITION_GAME_UPDATE, TRUE) ELIF IS_PLAYSTATION_PLATFORM() AND NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_SYSTEM_UPDATE SET_WARNING_SCREEN_BAIL(WARNINGSCREEN_TRANSITION_SYSTEM_UPDATE, TRUE) ELIF (IS_PLAYER_ONLINE() AND NETWORK_IS_SIGNED_ONLINE()) = FALSE //Sign in SET_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_DROPINVITE_SIGNIN, TRUE) ELIF NETWORK_HAS_VALID_ROS_CREDENTIALS() = FALSE ELIF NETWORK_CAN_ENTER_MULTIPLAYER() = FALSE ELSE SET_WARNING_SCREEN_BAIL(WARNINGSCREEN_BAIL_GTAO_ACCESS_DENIED, TRUE) ENDIF ENDIF #ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC FUNC BOOL IS_PED_EXITING_ANY_AIRBORN_VEHICLE(PED_INDEX PedIndex) IF (IS_PED_IN_ANY_VEHICLE(PedIndex) AND NOT IS_PED_SITTING_IN_ANY_VEHICLE(PedIndex)) //#769971 VECTOR VecPedCoord = GET_ENTITY_COORDS(PedIndex) FLOAT fPedCoordGroundZ = 0.0 IF GET_GROUND_Z_FOR_3D_COORD(VecPedCoord, fPedCoordGroundZ) //#800237 IF (VecPedCoord.z > (fPedCoordGroundZ+1.5)) //player is at least 1.5m above the ground RETURN TRUE ENDIF //players vehicle on ground RETURN FALSE ELSE //no groundZ, must be mid-air RETURN TRUE ENDIF ENDIF //player not exiting vehicle RETURN FALSE ENDFUNC /// PURPOSE: Returns TRUE if the selector UI can be displayed FUNC BOOL IS_SELECTOR_UI_SAFE_TO_DISPLAY(BOOL bCheckActivationButton = TRUE) //////////////////////////////////////////////////////////////// /// Dead specific checks IF IS_PED_INJURED(PLAYER_PED_ID()) AND NOT (g_bInMultiplayer AND IS_A_SPECTATOR_CAM_ACTIVE()) #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player is dead") ENDIF #ENDIF RETURN FALSE ENDIF //////////////////////////////////////////////////////////////// /// Alive specific checks IF NOT IS_PED_INJURED(PLAYER_PED_ID()) // Do not allow if we are not in a suitable state IF (IS_PLAYER_BEING_ARRESTED(PLAYER_ID(), TRUE)) OR (IS_PED_RAGDOLL(PLAYER_PED_ID()) AND bCheckActivationButton AND NOT IS_PED_DRUNK(PLAYER_PED_ID())) OR (Is_Player_Timetable_Scene_In_Progress()) OR IS_PED_EXITING_ANY_AIRBORN_VEHICLE(PLAYER_PED_ID()) //OR (IS_PLAYER_FREE_AIMING(PLAYER_ID())) //OR (IS_PLAYER_TARGETTING_ANYTHING(PLAYER_ID())) OR NOT IS_SAFE_TO_START_PLAYER_SWITCH() OR (g_flowUnsaved.bFlowControllerBusy AND NOT NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_FRIENDS) AND NOT IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)) OR (g_bResultScreenDisplaying) OR (IS_PED_IN_ANY_TRAIN(PLAYER_PED_ID()) AND GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH( HASH( "franklin0" ) ) = 0 ) #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) IF (IS_PLAYER_BEING_ARRESTED(PLAYER_ID(), TRUE)) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player is being arreseted") ELIF (IS_PED_RAGDOLL(PLAYER_PED_ID()) AND bCheckActivationButton AND NOT IS_PED_DRUNK(PLAYER_PED_ID())) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player is ragdolling") ELIF (Is_Player_Timetable_Scene_In_Progress()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player timetable scene in progress") ELIF IS_PED_EXITING_ANY_AIRBORN_VEHICLE(PLAYER_PED_ID()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player exiting a vehice") /*ELIF IS_PLAYER_FREE_AIMING(PLAYER_ID()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player is free aiming") ELIF IS_PLAYER_TARGETTING_ANYTHING(PLAYER_ID()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player is targetting something")*/ ELIF NOT IS_SAFE_TO_START_PLAYER_SWITCH()IS_SAFE_TO_START_PLAYER_SWITCH() PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Not safe to start player switch") ELIF (g_flowUnsaved.bFlowControllerBusy AND NOT NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_FRIENDS) AND NOT IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Flow Controller is Busy") ELIF (g_bResultScreenDisplaying) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Result Screen Displaying") ELIF (IS_PED_IN_ANY_TRAIN(PLAYER_PED_ID()) AND GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH( HASH( "franklin0" ) ) = 0 ) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player is in a train") ELSE PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - some other reason???") ENDIF ENDIF #ENDIF RETURN FALSE ENDIF ENDIF //////////////////////////////////////////////////////////////// /// Multiplayer specific checks IF (g_bInMultiplayer) // KGM 3/10/11: Convert from old MP Comms routine to new MP Comms routine IF (Is_Any_MP_Comms_Device_Onscreen()) #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - MP Comms device on screen") ENDIF #ENDIF RETURN FALSE ENDIF INT iMyGBD = NATIVE_TO_INT(PLAYER_ID()) IF iMyGBD != -1 AND IS_BIT_SET(GlobalplayerBD_FM_2[iMyGBD].iBitSet, biIwantToVote) #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Voting") ENDIF #ENDIF RETURN FALSE ENDIF ENDIF //////////////////////////////////////////////////////////////// /// Singleplayer specific checks IF (NOT g_bInMultiplayer) enumCharacterList ePed = GET_CURRENT_PLAYER_PED_ENUM() IF IS_PLAYER_PED_PLAYABLE(ePed) IF (GET_PLAYER_CHAR_COMMUNICATION_PRIORITY_LEVEL(ePed) = CPR_VERY_HIGH) IF NOT IS_REPEAT_PLAY_ACTIVE() AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_FRIENDS) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_PREP) #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Communication with priority queued") ENDIF #ENDIF RETURN FALSE ENDIF ENDIF ELIF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Not a playable character and not in Director Mode.") ENDIF #ENDIF RETURN FALSE ENDIF IF NOT g_sSelectorUI.bMissionUpdate IF (IS_PED_IN_PARACHUTE_FREE_FALL(PLAYER_PED_ID()) AND bCheckActivationButton) OR (GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) != PPS_INVALID AND bCheckActivationButton) #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) IF (IS_PED_IN_PARACHUTE_FREE_FALL(PLAYER_PED_ID()) AND bCheckActivationButton) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player is in parachute free fall") ELIF (GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) != PPS_INVALID AND bCheckActivationButton) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player parachute is out") ENDIF ENDIF #ENDIF RETURN FALSE ENDIF IF g_sSelectorUI.bDisableForEndOfMission #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - End of mission delay") ENDIF #ENDIF RETURN FALSE ENDIF ENDIF ENDIF IF IS_PLAYER_SWITCH_IN_PROGRESS() #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - IS_PLAYER_SWITCH_IN_PROGRESS()") ENDIF #ENDIF RETURN FALSE ENDIF //////////////////////////////////////////////////////////////// /// Generic game checks IF (g_sSelectorUI.bSelection) OR (IS_SELECTOR_DISABLED()) //OR (IS_SELECTOR_CAM_ACTIVE()) OR (IS_PLAYER_SWITCH_IN_PROGRESS()) OR (IS_PLAYER_PED_SWITCH_IN_PROGRESS()) OR (IS_SCRIPT_HUD_DISPLAYING(HUDPART_TRANSITIONHUD)) OR (IS_CUTSCENE_PLAYING()) OR (IS_PHONE_ACTIVE_OR_OVERLAPPING_HUD_ITEMS()/* AND GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("appTrackify")) = 0*/) OR (IS_PAUSE_MENU_ACTIVE()) OR (IS_SYSTEM_UI_BEING_DISPLAYED()) OR (IS_STUNT_JUMP_IN_PROGRESS()) OR (IS_CUSTOM_MENU_ON_SCREEN()) OR (GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("appCamera")) > 0) //OR (g_bMissionOverStatTrigger) OR (g_bPlayerIsInTaxi) OR (g_bBrowserVisible) OR (g_bHeistEndscreenDisplaying) OR (IS_HUD_COMPONENT_ACTIVE(NEW_HUD_WEAPON_WHEEL) AND NOT g_sSelectorUI.bOnScreen) OR (IS_HUD_COMPONENT_ACTIVE(NEW_HUD_RADIO_STATIONS) AND NOT g_sSelectorUI.bOnScreen) OR IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP() OR IS_PLAYER_CHANGING_CLOTHES() OR g_bBrowserVisible OR g_eMissionTitleState = MTS_DISPLAY_CUTSCENE OR g_eMissionTitleState = MTS_DISPLAY_GAMEPLAY #IF USE_TU_CHANGES OR (IS_PAUSE_MENU_ACTIVE_EX()) OR (IS_STORE_PENDING_NETWORK_SHUTDOWN_TO_OPEN()) #ENDIF #IF IS_DEBUG_BUILD IF IS_SELECTOR_UI_BUTTON_JUST_PRESSED(FALSE) IF (g_sSelectorUI.bSelection) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Selection has been made, need to process") ELIF (IS_SELECTOR_DISABLED()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Switch has been disabled") ELIF (IS_SELECTOR_CAM_ACTIVE()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Selector cam is active") ELIF (IS_PLAYER_SWITCH_IN_PROGRESS()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Switch in progress") ELIF (IS_PLAYER_PED_SWITCH_IN_PROGRESS()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player ped switch in progress") ELIF (IS_SCRIPT_HUD_DISPLAYING(HUDPART_TRANSITIONHUD)) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Transition hud on screen") ELIF (IS_CUTSCENE_PLAYING()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Cutscene playing") ELIF (IS_PHONE_ACTIVE_OR_OVERLAPPING_HUD_ITEMS()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Cellphone is active or overlapping hud items") ELIF (IS_PAUSE_MENU_ACTIVE()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Pause menu is active") ELIF (IS_SYSTEM_UI_BEING_DISPLAYED()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - System UI is active") ELIF (IS_STUNT_JUMP_IN_PROGRESS()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Stunt jump in progress") ELIF (IS_CUSTOM_MENU_ON_SCREEN()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Custom menu is on screen") ELIF (IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE() AND NOT g_sSelectorUI.bMissionUpdate) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Mission launched and this is ambient switch") ELIF (GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("appCamera")) > 0) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Phone camera is active") ELIF (g_bPlayerIsInTaxi) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player in taxi") ELIF (g_bBrowserVisible) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Browser is visible") ELIF (g_eMissionTitleState = MTS_DISPLAY_CUTSCENE) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Mission title displaying during cutscene") ELIF (g_eMissionTitleState = MTS_DISPLAY_GAMEPLAY) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Mission title displaying during gameplay") ELIF (g_bHeistEndscreenDisplaying) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Heist end screen visible") ELIF (IS_HUD_COMPONENT_ACTIVE(NEW_HUD_WEAPON_WHEEL)) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Weapon wheel is on screen") ELIF (IS_HUD_COMPONENT_ACTIVE(NEW_HUD_RADIO_STATIONS)) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Radio station is on screen") ELIF (IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player borwsing items in shop") ELIF (IS_PLAYER_CHANGING_CLOTHES()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Player changing clothes") ELIF g_bBrowserVisible PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Web browser visible") #IF USE_TU_CHANGES ELIF (IS_PAUSE_MENU_ACTIVE_EX()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Pause menu is active EX") ELIF (IS_STORE_PENDING_NETWORK_SHUTDOWN_TO_OPEN()) PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Store is opening") #ENDIF ELSE PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Some general fail case!") ENDIF ENDIF #ENDIF RETURN FALSE ENDIF //////////////////////////////////////////////////////////////// /// Debug checks #IF IS_DEBUG_BUILD IF NOT NETWORK_IS_GAME_IN_PROGRESS() IF (GET_GAME_TIMER() - iSelectMissionStageDrawTime) < 100 PRINTLN("IS_SELECTOR_UI_SAFE_TO_DISPLAY() = FALSE - Z-Skip menu on screen") RETURN FALSE ENDIF ENDIF #ENDIF // No issues found RETURN TRUE ENDFUNC FUNC BOOL GET_MP_COUNTDOWN_STRING(TEXT_LABEL_31 &tlCountdownText, BOOL bCached) // Fix for bug 1596720 - remove text completely tlCountdownText = "" RETURN FALSE // Fix for bug 1450768 - remove countdown timer IF IS_SPECIAL_EDITION_GAME() OR IS_COLLECTORS_EDITION_GAME() OR NETWORK_IS_GAME_IN_PROGRESS() tlCountdownText = "GTA Online" RETURN FALSE ENDIF IF bCached tlCountdownText = g_sSelectorUI.tlStoredCountdown ELSE tlCountdownText = "GTA Online" IF IS_PLAYER_ONLINE() //INT iReleaseTime = 1379376000 INT iReleaseTime = g_sMPTunables.iMpCountDownTimer INT iCurrentTime = GET_CLOUD_TIME_AS_INT() INT iTimeDifference = (iReleaseTime-iCurrentTime) INT iDays, iHours, iMinutes IF iTimeDifference > 0 // DAYS IF (iTimeDifference/86400) > 0 iDays = (iTimeDifference/86400) iTimeDifference -= (iDays*86400) ENDIF // HOURS IF (iTimeDifference/3600) > 0 iHours = (iTimeDifference/3600) iTimeDifference -= (iHours*3600) ENDIF // MINUTES IF (iTimeDifference/60) > 0 iMinutes = (iTimeDifference/60) iTimeDifference -= (iMinutes*60) ENDIF // D H M /* tlCountdownText = "" tlCountdownText += iDays tlCountdownText += "d " tlCountdownText += iHours tlCountdownText += "h " tlCountdownText += iMinutes tlCountdownText += "m " //tlCountdownText += iTimeDifference //tlCountdownText += "s " //PRINTLN(tlCountdownText) */ // D tlCountdownText = "" tlCountdownText += iDays tlCountdownText += " days" //tlCountdownText += iHours //tlCountdownText += "h " //tlCountdownText += iMinutes //tlCountdownText += "m " //tlCountdownText += iTimeDifference //tlCountdownText += "s " //PRINTLN(tlCountdownText) ENDIF ENDIF g_sSelectorUI.tlStoredCountdown = tlCountdownText ENDIF RETURN (NOT ARE_STRINGS_EQUAL(tlCountdownText, "GTA Online")) ENDFUNC /// PURPOSE: Sets up the details of the character for the selector UI #if USE_CLF_DLC PROC GET_SELECTOR_PED_ENUM_FOR_UIclf(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, INT &iEnum) //CHAR_MICHAEL = 0 //CHAR_TREVOR = 1 //CHAR_FRANKLIN = 2 //CHAR_MULTIPLAYER = 3 //CHAR_CHOP_RIGHT = 4 //CHAR_CHOP_UP = 5 //CHAR_CHOP_LEFT = 6 //CHAR_MICHAEL_MASKED_PROLOGUE=7 //CHAR_MICHAEL_UNMASKED_PROLOGUE=8 //CHAR_TREVOR_MASKED_PROLOGUE=9 //CHAR_TREVOR_UNMASKED_PROLOGUE=10 // Default slot, enum, and state SWITCH ePed CASE SELECTOR_PED_MICHAEL iEnum = 0 // CHAR_MICHAEL = 0 BREAK CASE SELECTOR_PED_FRANKLIN iEnum = 7 // CHAR_JIMMY = 2 BREAK CASE SELECTOR_PED_TREVOR iEnum = 9 // CHAR_TRACEY = 1 BREAK CASE SELECTOR_PED_MULTIPLAYER iEnum = 3 // CHAR_MULTIPLAYER = 3 BREAK ENDSWITCH IF sSelectorPeds.eIcons[ePed] = SELECTOR_ICON_DEFAULT endif ENDPROC #endif #if USE_NRM_DLC PROC GET_SELECTOR_PED_ENUM_FOR_UINRM(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, INT &iEnum) //CHAR_MICHAEL = 0 //CHAR_TREVOR = 1 //CHAR_FRANKLIN = 2 //CHAR_MULTIPLAYER = 3 //CHAR_CHOP_RIGHT = 4 //CHAR_CHOP_UP = 5 //CHAR_CHOP_LEFT = 6 //CHAR_MICHAEL_MASKED_PROLOGUE=7 //CHAR_MICHAEL_UNMASKED_PROLOGUE=8 //CHAR_TREVOR_MASKED_PROLOGUE=9 //CHAR_TREVOR_UNMASKED_PROLOGUE=10 // Default slot, enum, and state SWITCH ePed CASE SELECTOR_PED_MICHAEL iEnum = 0 // CHAR_MICHAEL = 0 BREAK CASE SELECTOR_PED_FRANKLIN iEnum = 7 // CHAR_JIMMY = 2 BREAK CASE SELECTOR_PED_TREVOR iEnum = 9 // CHAR_TRACEY = 1 BREAK CASE SELECTOR_PED_MULTIPLAYER iEnum = 3 // CHAR_MULTIPLAYER = 3 BREAK ENDSWITCH IF sSelectorPeds.eIcons[ePed] = SELECTOR_ICON_DEFAULT endif ENDPROC #endif PROC GET_SELECTOR_PED_ENUM_FOR_UI(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, INT &iEnum) #if USE_CLF_DLC GET_SELECTOR_PED_ENUM_FOR_UIclf(sSelectorPeds, ePed, iEnum) #endif #if USE_NRM_DLC GET_SELECTOR_PED_ENUM_FOR_UINRM(sSelectorPeds, ePed, iEnum) #endif #if not USE_CLF_DLC #if not USE_NRM_DLC //CHAR_MICHAEL = 0 //CHAR_TREVOR = 1 //CHAR_FRANKLIN = 2 //CHAR_MULTIPLAYER = 3 //CHAR_CHOP_RIGHT = 4 //CHAR_CHOP_UP = 5 //CHAR_CHOP_LEFT = 6 //CHAR_MICHAEL_MASKED_PROLOGUE=7 //CHAR_MICHAEL_UNMASKED_PROLOGUE=8 //CHAR_TREVOR_MASKED_PROLOGUE=9 //CHAR_TREVOR_UNMASKED_PROLOGUE=10 // Default slot, enum, and state SWITCH ePed CASE SELECTOR_PED_MICHAEL iEnum = 0 // CHAR_MICHAEL = 0 BREAK CASE SELECTOR_PED_FRANKLIN iEnum = 2 // CHAR_FRANKLIN = 2 BREAK CASE SELECTOR_PED_TREVOR iEnum = 1 // CHAR_TREVOR = 1 BREAK CASE SELECTOR_PED_MULTIPLAYER iEnum = 3 // CHAR_MULTIPLAYER = 3 BREAK ENDSWITCH // Modify the enum? IF ePed <> NUMBER_OF_SELECTOR_PEDS IF sSelectorPeds.eIcons[ePed] = SELECTOR_ICON_DEFAULT // Auto set Prologue IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("prologue1")) > 0 IF ePed = SELECTOR_PED_MICHAEL IF Get_Mission_Flow_Flag_State(FLOWFLAG_MIC_PRO_MASK_REMOVED) iEnum = 8 //CHAR_MICHAEL_UNMASKED_PROLOGUE=8 ELSE iEnum = 7 //CHAR_MICHAEL_MASKED_PROLOGUE=7 ENDIF ELIF ePed = SELECTOR_PED_TREVOR IF Get_Mission_Flow_Flag_State(FLOWFLAG_TRV_PRO_MASK_REMOVED) iEnum = 10 //CHAR_TREVOR_UNMASKED_PROLOGUE=10 ELSE iEnum = 9 //CHAR_TREVOR_MASKED_PROLOGUE=9 ENDIF ENDIF ENDIF // Chop ELIF sSelectorPeds.eIcons[ePed] = SELECTOR_ICON_CHOP IF ePed = SELECTOR_PED_MICHAEL iEnum = 6 //CHAR_CHOP_LEFT = 6 (in the left position /michael) ELIF ePed = SELECTOR_PED_TREVOR iEnum = 4 //CHAR_CHOP_RIGHT = 4 (in the right position /trevor) ELIF ePed = SELECTOR_PED_FRANKLIN iEnum = 5 //CHAR_CHOP_UP = 5 (in the top position /franklin) ENDIF // Prologue ELIF sSelectorPeds.eIcons[ePed] = SELECTOR_ICON_PRO_MICHAEL_MASKED iEnum = 7 //CHAR_MICHAEL_MASKED_PROLOGUE=7 ELIF sSelectorPeds.eIcons[ePed] = SELECTOR_ICON_PRO_MICHAEL_UNMASKED iEnum = 8 //CHAR_MICHAEL_UNMASKED_PROLOGUE=8 ELIF sSelectorPeds.eIcons[ePed] = SELECTOR_ICON_PRO_TREVOR_MASKED iEnum = 9 //CHAR_TREVOR_MASKED_PROLOGUE=9 ELIF sSelectorPeds.eIcons[ePed] = SELECTOR_ICON_PRO_TREVOR_UNMASKED iEnum = 10 //CHAR_TREVOR_UNMASKED_PROLOGUE=10 ENDIF ENDIF #endif #endif ENDPROC /// PURPOSE: Sets up the details of the character for the selector UI PROC GET_SELECTOR_PED_DETAILS_FOR_UI(SELECTOR_PED_STRUCT &sSelectorPeds, SELECTOR_SLOTS_ENUM ePed, BOOL bGetEnum, INT &iState, INT &iSlot, INT &iEnum, INT &iCurrent) BOOL bIsPlayer = FALSE IF NETWORK_IS_GAME_IN_PROGRESS() IF ePed = SELECTOR_PED_MULTIPLAYER bIsPlayer = TRUE ENDIF ELSE IF (GET_LAST_KNOWN_PLAYER_PED_ENUM() = GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(ePed)) bIsPlayer = TRUE ENDIF ENDIF // Default slot, enum, and state SWITCH ePed CASE SELECTOR_PED_MICHAEL iSlot = 3 // Left iCurrent = 0 // No IF NOT IS_SELECTOR_PED_INTRODUCED_IN_FLOW(ePed) iState = 3 // NOTMET= 3 ELIF NOT IS_SELECTOR_PED_AVAILABLE_IN_FLOW(ePed) iState = 2 // UNAVAIL = 2 ELSE iState = 1 // AVAILABLE = 1 ENDIF // Unavailable for ambient HUD IF sSelectorPeds.bAmbient AND iState = 1 IF (NOT NETWORK_IS_GAME_IN_PROGRESS() AND GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0) OR (IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)) OR (IS_REPEAT_PLAY_ACTIVE()) OR (g_bCandidateSystemMidProcessing) // Candidate system processing mission trigger iState = 2 // UNAVAIL = 2 ENDIF ENDIF BREAK CASE SELECTOR_PED_FRANKLIN iSlot = 0 // Top iCurrent = 0 // No IF NOT IS_SELECTOR_PED_INTRODUCED_IN_FLOW(ePed) iState = 3 // NOTMET= 3 ELIF NOT IS_SELECTOR_PED_AVAILABLE_IN_FLOW(ePed) iState = 2 // UNAVAIL = 2 ELSE iState = 1 // AVAILABLE = 1 ENDIF // Unavailable for ambient HUD IF sSelectorPeds.bAmbient AND iState = 1 IF (NOT NETWORK_IS_GAME_IN_PROGRESS() AND GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0) OR (IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)) OR (IS_REPEAT_PLAY_ACTIVE()) OR (g_bCandidateSystemMidProcessing) // Candidate system processing mission trigger iState = 2 // UNAVAIL = 2 ENDIF ENDIF BREAK CASE SELECTOR_PED_TREVOR iSlot = 1 // Right iCurrent = 0 // No IF NOT IS_SELECTOR_PED_INTRODUCED_IN_FLOW(ePed) iState = 3 // NOTMET= 3 ELIF NOT IS_SELECTOR_PED_AVAILABLE_IN_FLOW(ePed) iState = 2 // UNAVAIL = 2 ELSE iState = 1 // AVAILABLE = 1 ENDIF // Unavailable for ambient HUD IF sSelectorPeds.bAmbient AND iState = 1 IF (NOT NETWORK_IS_GAME_IN_PROGRESS() AND GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0) OR (IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)) OR (IS_REPEAT_PLAY_ACTIVE()) OR (g_bCandidateSystemMidProcessing) // Candidate system processing mission trigger iState = 2 // UNAVAIL = 2 ENDIF ENDIF BREAK CASE SELECTOR_PED_MULTIPLAYER iSlot = 2 // Bottom iCurrent = 0 // No IF NOT sSelectorPeds.bAmbient OR g_bMagDemoActive OR (sSelectorPeds.bAmbient AND ((IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)))) OR (sSelectorPeds.bAmbient AND IS_REPEAT_PLAY_ACTIVE()) OR (sSelectorPeds.bAmbient AND (g_bCandidateSystemMidProcessing)) // Candidate system processing mission trigger OR NOT DOES_PLAYER_HAVE_PRIVILEGES() OR NOT IS_GTA_ONLINE_AVAILABLE() iState = 2 // UNAVAIL = 2 ELSE iState = 1 // AVAILABLE = 1 ENDIF // Unavailable for ambient HUD IF sSelectorPeds.bAmbient AND iState = 1 IF (IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)) OR (g_bCandidateSystemMidProcessing) // Candidate system processing mission trigger iState = 2 // UNAVAIL = 2 ENDIF ENDIF BREAK ENDSWITCH #IF USE_CLF_DLC // Modify the state? IF ePed <> SELECTOR_PED_MULTIPLAYER IF (bIsPlayer) OR (sSelectorPeds.eFakeState[ePed] = SELECTOR_STATE_AVAILABLE) iState = 1 // AVAILABLE = 1 ELIF (sSelectorPeds.eFakeState[ePed] = SELECTOR_STATE_UNAVAILABLE) OR (sSelectorPeds.bBlockSelectorPed[ePed]) OR (NOT sSelectorPeds.bAmbient AND IS_PED_INJURED(sSelectorPeds.pedID[ePed]) AND iState = 1) // AVAILABLE = 1 OR (sSelectorPeds.bAmbient AND IS_BIT_SET(g_sPlayerPedRequest.iBitsetPedInLeadIn, ENUM_TO_INT(ePed))) //Block switching to player's created in lead-ins. IF iState = 1 iState = 2 // UNAVAIL = 2 ENDIF ELIF (sSelectorPeds.eIcons[ePed] != SELECTOR_ICON_DEFAULT) iState = 1 // AVAILABLE = 1 ELIF (sSelectorPeds.bAmbient AND NOT IS_BIT_SET(g_savedGlobalsClifford.sFlow.strandSavedVars[STRAND_CLF].savedBitflags, SAVED_BITS_STRAND_ACTIVATED) AND NOT IS_REPEAT_PLAY_ACTIVE()) IF (IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)) // keep blocked on mission. ELSE iState = 1 // AVAILABLE = 1 ENDIF ENDIF ELSE // TEXT_LABEL_31 tlTemp // IF GET_MP_COUNTDOWN_STRING(tlTemp, TRUE) // iState = 2 // UNAVAIL = 2 // ENDIF // Fix for bug 1596720 - remove timer iState = 3 // NOTMET= 3 ENDIF #ENDIF #IF USE_NRM_DLC // Modify the state? IF ePed <> SELECTOR_PED_MULTIPLAYER IF (bIsPlayer) OR (sSelectorPeds.eFakeState[ePed] = SELECTOR_STATE_AVAILABLE) iState = 1 // AVAILABLE = 1 ELIF (sSelectorPeds.eFakeState[ePed] = SELECTOR_STATE_UNAVAILABLE) OR (sSelectorPeds.bBlockSelectorPed[ePed]) OR (NOT sSelectorPeds.bAmbient AND IS_PED_INJURED(sSelectorPeds.pedID[ePed]) AND iState = 1) // AVAILABLE = 1 OR (sSelectorPeds.bAmbient AND IS_BIT_SET(g_sPlayerPedRequest.iBitsetPedInLeadIn, ENUM_TO_INT(ePed))) //Block switching to player's created in lead-ins. IF iState = 1 iState = 2 // UNAVAIL = 2 ENDIF ELIF (sSelectorPeds.eIcons[ePed] != SELECTOR_ICON_DEFAULT) iState = 1 // AVAILABLE = 1 ELIF (sSelectorPeds.bAmbient AND NOT IS_BIT_SET(g_savedGlobalsnorman.sFlow.strandSavedVars[STRAND_NRM_SURVIVE].savedBitflags, SAVED_BITS_STRAND_ACTIVATED) AND NOT IS_REPEAT_PLAY_ACTIVE()) IF (IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)) // keep blocked on mission. ELSE iState = 1 // AVAILABLE = 1 ENDIF ENDIF ELSE // TEXT_LABEL_31 tlTemp // IF GET_MP_COUNTDOWN_STRING(tlTemp, TRUE) // iState = 2 // UNAVAIL = 2 // ENDIF // Fix for bug 1596720 - remove timer iState = 3 // NOTMET= 3 ENDIF #ENDIF #IF NOT USE_SP_DLC // Modify the state? IF ePed <> SELECTOR_PED_MULTIPLAYER IF (bIsPlayer) OR (sSelectorPeds.eFakeState[ePed] = SELECTOR_STATE_AVAILABLE) iState = 1 // AVAILABLE = 1 ELIF (sSelectorPeds.eFakeState[ePed] = SELECTOR_STATE_UNAVAILABLE) OR (sSelectorPeds.bBlockSelectorPed[ePed]) OR (NOT sSelectorPeds.bAmbient AND IS_PED_INJURED(sSelectorPeds.pedID[ePed]) AND iState = 1) // AVAILABLE = 1 OR (sSelectorPeds.bAmbient AND IS_BIT_SET(g_sPlayerPedRequest.iBitsetPedInLeadIn, ENUM_TO_INT(ePed))) //Block switching to player's created in lead-ins. IF iState = 1 iState = 2 // UNAVAIL = 2 ENDIF ELIF (sSelectorPeds.eIcons[ePed] != SELECTOR_ICON_DEFAULT) iState = 1 // AVAILABLE = 1 ELIF (sSelectorPeds.bAmbient AND NOT IS_BIT_SET(g_savedGlobals.sFlow.strandSavedVars[STRAND_PROLOGUE].savedBitflags, SAVED_BITS_STRAND_ACTIVATED) AND NOT g_bMagDemoActive AND NOT IS_REPEAT_PLAY_ACTIVE()) IF (IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) OR IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS)) // keep blocked on mission. ELSE iState = 1 // AVAILABLE = 1 ENDIF ENDIF ELSE // TEXT_LABEL_31 tlTemp // IF GET_MP_COUNTDOWN_STRING(tlTemp, TRUE) // iState = 2 // UNAVAIL = 2 // ENDIF // Fix for bug 1596720 - remove timer iState = 3 // NOTMET= 3 ENDIF #ENDIF #IF USE_CLF_DLC if g_bLoadedClifford AND (ePed = SELECTOR_PED_FRANKLIN OR ePed = SELECTOR_PED_MICHAEL) iState=2 endif #ENDIF // Modify the current? IF (bIsPlayer AND sSelectorPeds.eFakeState[ePed] = SELECTOR_STATE_DEFAULT) OR (sSelectorPeds.eFakeState[ePed] = SELECTOR_STATE_CURRENT) IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) iCurrent = 1 // Yes ENDIF ENDIF IF bGetEnum GET_SELECTOR_PED_ENUM_FOR_UI(sSelectorPeds, ePed, iEnum) ENDIF ENDPROC /// PURPOSE: Draws the ped selector HUD and handles keypresses /// /// NOTES: Updates the eNewSelectorPed and returns TRUE if the player has changed the current selection /// DPADUP = MICHAEL, DPADLEFT = FRANKLIN, DPADRIGHT = TREVOR, DPADDOWN = MULTIPLAYER FUNC BOOL UPDATE_SELECTOR_HUD(SELECTOR_PED_STRUCT &sSelectorPeds, BOOL bCheckPlayerIsInControl = TRUE, BOOL bCheckActivationButton = TRUE) #IF IS_DEBUG_BUILD // Update details for widget g_sSelectorUI.debug_pedID[0] = sSelectorPeds.pedID[0] g_sSelectorUI.debug_pedID[1] = sSelectorPeds.pedID[1] g_sSelectorUI.debug_pedID[2] = sSelectorPeds.pedID[2] g_sSelectorUI.debug_pedID[3] = sSelectorPeds.pedID[3] g_sSelectorUI.debug_bBlockState[0] = sSelectorPeds.bBlockSelectorPed[0] g_sSelectorUI.debug_bBlockState[1] = sSelectorPeds.bBlockSelectorPed[1] g_sSelectorUI.debug_bBlockState[2] = sSelectorPeds.bBlockSelectorPed[2] g_sSelectorUI.debug_bBlockState[3] = sSelectorPeds.bBlockSelectorPed[3] g_sSelectorUI.debug_bHintState[0] = sSelectorPeds.bDisplayHint[0] g_sSelectorUI.debug_bHintState[1] = sSelectorPeds.bDisplayHint[1] g_sSelectorUI.debug_bHintState[2] = sSelectorPeds.bDisplayHint[2] g_sSelectorUI.debug_bHintState[3] = sSelectorPeds.bDisplayHint[3] g_sSelectorUI.debug_bDamageState[0] = sSelectorPeds.bDisplayDamage[0] g_sSelectorUI.debug_bDamageState[1] = sSelectorPeds.bDisplayDamage[1] g_sSelectorUI.debug_bDamageState[2] = sSelectorPeds.bDisplayDamage[2] g_sSelectorUI.debug_bDamageState[3] = sSelectorPeds.bDisplayDamage[3] g_sSelectorUI.debug_iState[0] = -1 g_sSelectorUI.debug_iState[1] = -1 g_sSelectorUI.debug_iState[2] = -1 g_sSelectorUI.debug_iState[3] = -1 #ENDIF INT iPed, iState, iSlot, iEnum, iCurrent BOOL bFakeCurrent = FALSE BOOL bPlayerDead = IS_PED_INJURED(PLAYER_PED_ID()) BOOL bAllowWhenDead = (bPlayerDead AND g_bInMultiplayer AND IS_A_SPECTATOR_CAM_ACTIVE()) BOOL bUIButtonJustReleased = IS_SELECTOR_UI_BUTTON_JUST_RELEASED(bCheckPlayerIsInControl) // Set the current ped sSelectorPeds.eCurrentSelectorPed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_CURRENT_PLAYER_PED_ENUM()) // Set misc states g_sSelectorUI.bMissionUpdate = (NOT sSelectorPeds.bAmbient) g_sSelectorUI.bCheckPlayerControl = bCheckPlayerIsInControl g_sSelectorUI.bCheckActivationButton = bCheckActivationButton g_sSelectorUI.bAllowWhenDead = bAllowWhenDead g_sSelectorUI.bForceUpdate = g_sSelectorUI.bFakeStateUpdated g_sSelectorUI.bCharAvailable = FALSE BOOL bGetPedDetails = (g_sSelectorUI.eUIStateCurrent = SELECTOR_UI_FULL OR g_sSelectorUI.eUIStateCurrent = SELECTOR_UI_HIDDEN_TO_FULL OR g_sSelectorUI.eUIStateCurrent = SELECTOR_UI_HINT_TO_FULL) // Update the ped hints and stored data FOR iPed = 0 TO ENUM_TO_INT(NUMBER_OF_SELECTOR_PEDS)-1 //GET_SELECTOR_PED_ENUM_FOR_UI(sSelectorPeds, INT_TO_ENUM(SELECTOR_SLOTS_ENUM, iPed), iEnum) //GET_SELECTOR_PED_DETAILS_FOR_UI(sSelectorPeds, INT_TO_ENUM(SELECTOR_SLOTS_ENUM, iPed), FALSE, iState, iSlot, iEnum, iCurrent) GET_SELECTOR_PED_DETAILS_FOR_UI(sSelectorPeds, INT_TO_ENUM(SELECTOR_SLOTS_ENUM, iPed), TRUE, iState, iSlot, iEnum, iCurrent) g_sSelectorUI.iHealth[iPed] = -1 g_sSelectorUI.iArmour[iPed] = -1 g_sSelectorUI.iSpecial[iPed] = -1 g_sSelectorUI.iSpecialMax[iPed] = -1 g_sSelectorUI.bDamaged[iPed] = FALSE g_sSelectorUI.bFlashDamage[iPed] = FALSE g_sSelectorUI.vCoords[iPed] = <<0,0,0>> // [DIRECTOR_TODO] IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) SELECTOR_SLOTS_ENUM ePed = INT_TO_ENUM(SELECTOR_SLOTS_ENUM, iPed) //Casting trailer is always available. IF ePed = SELECTOR_PED_MULTIPLAYER g_sSelectorUI.bCharAvailable = TRUE ELIF IS_SELECTOR_PED_INTRODUCED_IN_FLOW(ePed) AND IS_SELECTOR_PED_AVAILABLE_IN_FLOW(ePed) #IF USE_CLF_DLC AND ePed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(g_savedGlobalsClifford.sPlayerData.sInfo.eLastKnownPed) #ENDIF #IF NOT USE_SP_DLC AND ePed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(g_savedGlobals.sPlayerData.sInfo.eLastKnownPed) #ENDIF g_sSelectorUI.bCharAvailable = TRUE ELSE g_sSelectorUI.bCharAvailable = FALSE ENDIF // Set g_sSelectorUI.bCharAvailable = TRUE if the character is unlocked in flow. // If we want to allow hints to be set (white flash on icon) then we do the following: //g_sSelectorUI.bHinted[iPed] = sSelectorPeds.bDisplayHint[iPed] //g_sSelectorUI.iHintEnum[iPed] = iEnum ELIF g_sSelectorUI.bMissionUpdate // See if we have an available character IF NOT g_sSelectorUI.bCharAvailable IF (NOT IS_PED_INJURED(sSelectorPeds.pedID[iPed]) AND NOT sSelectorPeds.bBlockSelectorPed[iPed] AND sSelectorPeds.pedID[iPed] != PLAYER_PED_ID()) OR (sSelectorPeds.eFakeState[iPed] = SELECTOR_STATE_AVAILABLE) OR (sSelectorPeds.eIcons[iPed] != SELECTOR_ICON_DEFAULT) g_sSelectorUI.bCharAvailable = TRUE #IF USE_CLF_DLC IF g_bLoadedClifford AND (iPed=ENUM_TO_INT(SELECTOR_PED_FRANKLIN) OR iPed=ENUM_TO_INT(SELECTOR_PED_MICHAEL)) g_sSelectorUI.bCharAvailable=FALSE ENDIF #ENDIF ENDIF ENDIF // Check for fake current ped IF (sSelectorPeds.eFakeState[iPed] = SELECTOR_STATE_CURRENT) bFakeCurrent = TRUE ELIF (sSelectorPeds.eCurrentSelectorPed = INT_TO_ENUM(SELECTOR_SLOTS_ENUM, iPed)) IF (sSelectorPeds.eFakeState[iPed] = SELECTOR_STATE_UNAVAILABLE) OR (sSelectorPeds.eFakeState[iPed] = SELECTOR_STATE_AVAILABLE) bFakeCurrent = TRUE ENDIF ENDIF // Update hints IF sSelectorPeds.bDisplayHint[iPed] // Remove hint if character selected IF sSelectorPeds.bInitialised AND (sSelectorPeds.eNewSelectorPed = INT_TO_ENUM(SELECTOR_SLOTS_ENUM, iPed)) sSelectorPeds.bDisplayHint[iPed] = FALSE // Remove hint if character current ELIF (sSelectorPeds.eCurrentSelectorPed = INT_TO_ENUM(SELECTOR_SLOTS_ENUM, iPed) AND NOT bFakeCurrent) OR (sSelectorPeds.eFakeState[iPed] = SELECTOR_STATE_CURRENT) sSelectorPeds.bDisplayHint[iPed] = FALSE // Remove hint if character dead ELIF (IS_PED_INJURED(sSelectorPeds.pedID[iPed]) AND NOT sSelectorPeds.bAmbient) AND NOT (sSelectorPeds.eFakeState[iPed] = SELECTOR_STATE_AVAILABLE) PRINTLN("set_selector_ped_hint clearing hint 2") sSelectorPeds.bDisplayHint[iPed] = FALSE ENDIF ENDIF g_sSelectorUI.bHinted[iPed] = sSelectorPeds.bDisplayHint[iPed] g_sSelectorUI.iHintEnum[iPed] = iEnum // Update damaged state IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[iPed]) AND NOT IS_PED_INJURED(sSelectorPeds.pedID[iPed]) AND sSelectorPeds.pedID[iPed] != PLAYER_PED_ID() g_sSelectorUI.iHealth[iPed] = FLOOR(((TO_FLOAT(GET_ENTITY_HEALTH(sSelectorPeds.pedID[iPed]))-100.0) / (TO_FLOAT(GET_PED_MAX_HEALTH(sSelectorPeds.pedID[iPed]))-100.0)) * 100.0) ENDIF IF (g_sSelectorUI.iHealth[iPed] != -1 AND g_sSelectorUI.iHealth[iPed] < 25.0) OR sSelectorPeds.bDisplayDamage[iPed] IF ENUM_TO_INT(sSelectorPeds.eCurrentSelectorPed) != iPed g_sSelectorUI.bDamaged[iPed] = TRUE g_sSelectorUI.bFlashDamage[iPed] = (sSelectorPeds.bDisplayDamage[iPed]) ENDIF ENDIF ELSE g_sSelectorUI.bHinted[iPed] = sSelectorPeds.bDisplayHint[iPed] g_sSelectorUI.iHintEnum[iPed] = iEnum ENDIF #IF IS_DEBUG_BUILD // Update details for widget g_sSelectorUI.debug_bHintState[iPed] = sSelectorPeds.bDisplayHint[iPed] g_sSelectorUI.debug_bDamageState[iPed] = sSelectorPeds.bDisplayDamage[iPed] g_sSelectorUI.debug_bBlockState[iPed] = sSelectorPeds.bBlockSelectorPed[iPed] #ENDIF // Update the stored data IF g_sSelectorUI.bDisplay g_sSelectorUI.iState[iSlot] = iState g_sSelectorUI.iEnum[iSlot] = iEnum g_sSelectorUI.iCurrent[iSlot] = iCurrent g_sSelectorUI.iMissions[iPed] = 0 g_sSelectorUI.iTxts[iPed] = 0 g_sSelectorUI.iCalls[iPed] = 0 #IF IS_DEBUG_BUILD // Update details for widget g_sSelectorUI.debug_iState[iPed] = iState #ENDIF IF bGetPedDetails // Ped location and health states IF g_sSelectorUI.bMissionUpdate IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[iPed]) AND NOT IS_PED_INJURED(sSelectorPeds.pedID[iPed]) //g_sSelectorUI.iHealth[iPed] = FLOOR(((TO_FLOAT(GET_ENTITY_HEALTH(sSelectorPeds.pedID[iPed]))-100.0) / (TO_FLOAT(GET_PED_MAX_HEALTH(sSelectorPeds.pedID[iPed]))-100.0)) * 100.0) g_sSelectorUI.iArmour[iPed] = GET_PED_ARMOUR(sSelectorPeds.pedID[iPed]) IF iPed = 0 // SELECTOR_PED_MICHAEL STAT_GET_INT(SP0_SPECIAL_ABILITY, g_sSelectorUI.iSpecial[iPed]) STAT_GET_INT(SP0_SPECIAL_ABILITY_UNLOCKED, g_sSelectorUI.iSpecialMax[iPed]) ELIF iPed = 1 // SELECTOR_PED_FRANKLIN STAT_GET_INT(SP1_SPECIAL_ABILITY, g_sSelectorUI.iSpecial[iPed]) STAT_GET_INT(SP1_SPECIAL_ABILITY_UNLOCKED, g_sSelectorUI.iSpecialMax[iPed]) ELIF iPed = 2 // SELECTOR_PED_TREVOR STAT_GET_INT(SP2_SPECIAL_ABILITY, g_sSelectorUI.iSpecial[iPed]) STAT_GET_INT(SP2_SPECIAL_ABILITY_UNLOCKED, g_sSelectorUI.iSpecialMax[iPed]) ENDIF g_sSelectorUI.vCoords[iPed] = GET_ENTITY_COORDS(sSelectorPeds.pedID[iPed]) ENDIF // Set the mission count for player characters when off mission ELIF (iPed < ENUM_TO_INT(SELECTOR_PED_MULTIPLAYER)) AND (iState != 3) // NOTMET= 3 AND (NOT IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE() OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)) g_sSelectorUI.iMissions[iPed] = g_iAvailablePlayerMissions[iPed] // Fix for bug #1001720 - just put the mission next to Trevor here rather than the sms sign even if he is waiting for the sms to trigger the mission g_sSelectorUI.iTxts[iPed] = 0 g_sSelectorUI.iMissions[iPed] += g_iQueuedTxts[iPed] // Fix for bug #975918 - dont put phone icon there - just have a 1 instead //g_sSelectorUI.iCalls[iSlot] = g_iQueuedCalls[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(INT_TO_ENUM(SELECTOR_SLOTS_ENUM, iPed))] g_sSelectorUI.iCalls[iPed] = 0 g_sSelectorUI.iMissions[iPed] += g_iQueuedCalls[iPed] ENDIF ENDIF ENDIF // Set the default character selection if the movie has not been set up yet IF (g_sSelectorUI.iSelectedSlot = -1 OR NOT g_sSelectorUI.bFirstSelectionMade) AND g_sSelectorUI.iSelectedSlot != iSlot AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) IF (sSelectorPeds.eCurrentSelectorPed = INT_TO_ENUM(SELECTOR_SLOTS_ENUM, iPed) AND NOT bFakeCurrent) OR (sSelectorPeds.eFakeState[iPed] = SELECTOR_STATE_CURRENT) g_sSelectorUI.iSelectedSlot = iSlot g_sSelectorUI.bFirstSelectionMade = TRUE PRINTLN("UPDATE_SELECTOR_HUD() - Setting default character selection to ", iSlot) ENDIF ENDIF ENDFOR // Check for final selection IF bUIButtonJustReleased IF (g_sSelectorUI.bDisplay) AND (NOT g_sSelectorUI.bHiddenThisFrame OR g_sSelectorUI.bAllowSelectionWhenHidden) AND (NOT IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY) OR g_sSelectorUI.bMissionUpdate OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)) AND (NOT IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_FRIENDS) OR g_sSelectorUI.bMissionUpdate OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)) AND (NOT IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_STORY_PREP) OR g_sSelectorUI.bMissionUpdate OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)) AND (NOT IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_MINIGAME) OR g_sSelectorUI.bMissionUpdate OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)) AND (NOT IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_MINIGAME_FRIENDS) OR g_sSelectorUI.bMissionUpdate OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)) // Manual selection IF g_sSelectorUI.eUIStateCurrent = SELECTOR_UI_FULL PRINTLN("UPDATE_SELECTOR_HUD() - Checking character selection") // [DIRECTOR_TODO] IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) // We should do a custom make_selector_ped_selection set up here // Check for character being unlocked in flow and available. // Make a global called g_bSwitchBackToTrailer for when we select the trailer, we can then pick this up in selector.sc to do trailer transition. IF (g_sSelectorUI.iSelectedSlot = 0) // Top g_sSelectorUI.bSelection = MAKE_DIRECTOR_MODE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_FRANKLIN) ELIF (g_sSelectorUI.iSelectedSlot = 1) // Right g_sSelectorUI.bSelection = MAKE_DIRECTOR_MODE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_TREVOR) ELIF (g_sSelectorUI.iSelectedSlot = 2) // Bottom g_sSelectorUI.bSelection = MAKE_DIRECTOR_MODE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_MULTIPLAYER) ELIF (g_sSelectorUI.iSelectedSlot = 3) // Left g_sSelectorUI.bSelection = MAKE_DIRECTOR_MODE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_MICHAEL) ENDIF // Casting Trailer selection. // IF g_sSelectorUI.iSelectedSlot = 2 // PRINTLN("UPDATE_SELECTOR_HUD() - Director Mode overriding MP switch to be the Casting Trailer.") // g_bSelectorChoseCastingTrailer = TRUE // ENDIF ELSE IF (g_sSelectorUI.iSelectedSlot = 0) // Top g_sSelectorUI.bSelection = MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_FRANKLIN) ELIF (g_sSelectorUI.iSelectedSlot = 1) // Right g_sSelectorUI.bSelection = MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_TREVOR) ELIF (g_sSelectorUI.iSelectedSlot = 2) // Bottom g_sSelectorUI.bSelection = MAKE_MULTIPLAYER_SELECTION(sSelectorPeds) ELIF (g_sSelectorUI.iSelectedSlot = 3) // Left g_sSelectorUI.bSelection = MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_MICHAEL) ENDIF ENDIF // Quick switch ELIF g_sSelectorUI.eUIStateCurrent = SELECTOR_UI_HINT_TO_FULL OR (g_sSelectorUI.bHiddenThisFrame AND g_sSelectorUI.bAllowSelectionWhenHidden) IF NOT g_sSelectorUI.bSelection AND g_sSelectorUI.bMissionUpdate AND (g_sSelectorUI.bCharAvailable) AND NOT NETWORK_IS_GAME_IN_PROGRESS() AND NOT (IS_AIMING_THROUGH_SNIPER_SCOPE(PLAYER_PED_ID()) AND (IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_AIM) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_AIM))) enumCharacterList eCurrentPed SELECTOR_SLOTS_ENUM ePed1, ePed2, ePed3 IF sSelectorPeds.eFakeState[SELECTOR_PED_MICHAEL] = SELECTOR_STATE_CURRENT eCurrentPed = CHAR_MICHAEL ELIF sSelectorPeds.eFakeState[SELECTOR_PED_FRANKLIN] = SELECTOR_STATE_CURRENT eCurrentPed = CHAR_FRANKLIN ELIF sSelectorPeds.eFakeState[SELECTOR_PED_TREVOR] = SELECTOR_STATE_CURRENT eCurrentPed = CHAR_TREVOR ELSE eCurrentPed = GET_CURRENT_PLAYER_PED_ENUM() ENDIF SWITCH eCurrentPed CASE CHAR_MICHAEL IF sSelectorPeds.bDisplayDamage[SELECTOR_PED_FRANKLIN] AND NOT g_sSelectorUI.bBlockQuickSwitchToDamagedPed ePed1 = SELECTOR_PED_FRANKLIN ELIF sSelectorPeds.bDisplayDamage[SELECTOR_PED_TREVOR] AND NOT g_sSelectorUI.bBlockQuickSwitchToDamagedPed ePed1 = SELECTOR_PED_TREVOR ELIF sSelectorPeds.bUseCustomAutoSelectOption ePed1 = sSelectorPeds.eAutoSelectOption1 ePed2 = sSelectorPeds.eAutoSelectOption2 ePed3 = sSelectorPeds.eAutoSelectOption3 ELSE ePed1 = SELECTOR_PED_FRANKLIN ePed2 = SELECTOR_PED_TREVOR ENDIF BREAK CASE CHAR_FRANKLIN IF sSelectorPeds.bDisplayDamage[SELECTOR_PED_TREVOR] AND NOT g_sSelectorUI.bBlockQuickSwitchToDamagedPed ePed1 = SELECTOR_PED_TREVOR ELIF sSelectorPeds.bDisplayDamage[SELECTOR_PED_MICHAEL] AND NOT g_sSelectorUI.bBlockQuickSwitchToDamagedPed ePed1 = SELECTOR_PED_MICHAEL ELIF sSelectorPeds.bUseCustomAutoSelectOption ePed1 = sSelectorPeds.eAutoSelectOption1 ePed2 = sSelectorPeds.eAutoSelectOption2 ePed3 = sSelectorPeds.eAutoSelectOption3 ELSE ePed1 = SELECTOR_PED_TREVOR ePed2 = SELECTOR_PED_MICHAEL ENDIF BREAK CASE CHAR_TREVOR IF sSelectorPeds.bDisplayDamage[SELECTOR_PED_MICHAEL] AND NOT g_sSelectorUI.bBlockQuickSwitchToDamagedPed ePed1 = SELECTOR_PED_MICHAEL ELIF sSelectorPeds.bDisplayDamage[SELECTOR_PED_FRANKLIN] AND NOT g_sSelectorUI.bBlockQuickSwitchToDamagedPed ePed1 = SELECTOR_PED_FRANKLIN ELIF sSelectorPeds.bUseCustomAutoSelectOption ePed1 = sSelectorPeds.eAutoSelectOption1 ePed2 = sSelectorPeds.eAutoSelectOption2 ePed3 = sSelectorPeds.eAutoSelectOption3 ELSE ePed1 = SELECTOR_PED_MICHAEL ePed2 = SELECTOR_PED_FRANKLIN ENDIF BREAK ENDSWITCH PRINTLN("...ped1 = ", GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(ePed1))) PRINTLN("...ped2 = ", GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(ePed2))) PRINTLN("...ped3 = ", GET_PLAYER_PED_STRING(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(ePed3))) // Normal quick switch cycling is disabled if one of the PC specific shortcut keys has been pressed. BOOL bNormalQuickSwitch = TRUE // Direct switching of selected character using keyboard controls. IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL) // Don't want to do this if the player is pressing the normal quick switch) IF NOT IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) IF IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_MICHAEL) bNormalQuickSwitch = FALSE IF eCurrentPed != CHAR_MICHAEL IF MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_MICHAEL) g_sSelectorUI.bSelection = TRUE ENDIF ENDIF ELIF IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_FRANKLIN) bNormalQuickSwitch = FALSE IF eCurrentPed != CHAR_FRANKLIN IF MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_FRANKLIN) g_sSelectorUI.bSelection = TRUE ENDIF ENDIF ELIF IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_SELECT_CHARACTER_TREVOR) bNormalQuickSwitch = FALSE IF eCurrentPed != CHAR_TREVOR IF MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_TREVOR) g_sSelectorUI.bSelection = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF IF bNormalQuickSwitch IF MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, ePed1) g_sSelectorUI.bSelection = TRUE ELIF MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, ePed2) g_sSelectorUI.bSelection = TRUE ELIF MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, ePed3) g_sSelectorUI.bSelection = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF IF (g_sSelectorUI.bSelection) g_sSelectorUI.bHideUiForSwitch = TRUE HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_VEHICLE_NAME) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_AREA_NAME) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_DISTRICT_NAME) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_STREET_NAME) ENDIF // Let scripts know if the player just made a selection RETURN (g_sSelectorUI.bSelection) ENDFUNC /// PURPOSE: Forces the player to be a specific character without scripts having to create a selector ped /// NOTE: This only works with SELECTOR_PED_MICHAEL, SELECTOR_PED_TREVOR, and SELECTOR_PED_FRANKLIN FUNC BOOL SET_CURRENT_SELECTOR_PED(SELECTOR_SLOTS_ENUM eSlot, BOOL bCleanupModel = TRUE) // We are forcing a switch with this command so clear manual selection flag g_sSelectorUI.bManualSelection = FALSE // Player is dead IF IS_PED_INJURED(PLAYER_PED_ID()) RETURN TRUE ENDIF // Grab the ped and model enums enumCharacterList ePed = GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(eSlot) MODEL_NAMES eModel = GET_PLAYER_PED_MODEL(ePed) // Character is not a playable character IF eModel = DUMMY_MODEL_FOR_SCRIPT #IF IS_DEBUG_BUILD SCRIPT_ASSERT("SET_CURRENT_SELECTOR_PED - Only works with SELECTOR_PED_MICHAEL, SELECTOR_PED_TREVOR, and SELECTOR_PED_FRANKLIN") PRINTSTRING("\nSET_CURRENT_SELECTOR_PED - Only works with SELECTOR_PED_MICHAEL, SELECTOR_PED_TREVOR, and SELECTOR_PED_FRANKLIN")PRINTNL() #ENDIF RETURN TRUE ENDIF // Player is already this character IF IS_PED_MODEL(PLAYER_PED_ID(), eModel) RETURN TRUE ENDIF // Reques the ped model REQUEST_MODEL(eModel) // Model not loaded yet IF NOT HAS_MODEL_LOADED(eModel) RETURN FALSE ENDIF // Check if the player is in a vehicle VEHICLE_INDEX veh VEHICLE_SEAT seat IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) IF PLAYER_PED_ID() = GET_PED_IN_VEHICLE_SEAT(veh, VS_DRIVER) seat = VS_DRIVER ELIF PLAYER_PED_ID() = GET_PED_IN_VEHICLE_SEAT(veh, VS_FRONT_RIGHT) seat = VS_FRONT_RIGHT ELIF PLAYER_PED_ID() = GET_PED_IN_VEHICLE_SEAT(veh, VS_BACK_LEFT) seat = VS_BACK_LEFT ELIF PLAYER_PED_ID() = GET_PED_IN_VEHICLE_SEAT(veh, VS_BACK_RIGHT) seat = VS_BACK_RIGHT ELSE seat = VS_DRIVER ENDIF ELSE veh = NULL ENDIF // Create the selector ped in the players place IF DOES_ENTITY_EXIST(veh) AND IS_VEHICLE_DRIVEABLE(veh) CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())// Gets them out of the vehicle seat CREATE_PLAYER_PED_INSIDE_VEHICLE(g_sTempSelectorData.pedID[eSlot], ePed, veh, seat, bCleanupModel) ELSE VECTOR vCoords = GET_ENTITY_COORDS(PLAYER_PED_ID()) GET_GROUND_Z_FOR_3D_COORD(vCoords, vCoords.z) CREATE_PLAYER_PED_ON_FOOT(g_sTempSelectorData.pedID[eSlot], ePed, vCoords, GET_ENTITY_HEADING(PLAYER_PED_ID()), bCleanupModel) ENDIF // Make the selection //MAKE_SELECTOR_PED_SELECTION(g_sTempSelectorData, eSlot) // Force the selection g_sTempSelectorData.eNewSelectorPed = eSlot g_sTempSelectorData.bInitialised = TRUE // Take control TAKE_CONTROL_OF_SELECTOR_PED(g_sTempSelectorData, FALSE) // Show this on the UI DISPLAY_SELECTOR_PED_AUTOSWITCH_UI(eSlot) // Complete RETURN TRUE ENDFUNC FUNC BOOL IS_CHARACTER_MODEL_CHECK_DONE() RETURN g_bCharacterModelCheckDone ENDFUNC PROC SET_CHARACTER_MODEL_CHECK_DONE(BOOL bSet) #IF IS_DEBUG_BUILD IF (bSet != g_bCharacterModelCheckDone) PRINTLN("g_bCharacterModelCheckDone changed to ", bSet) ELSE PRINTLN("g_bCharacterModelCheckDone already ", bSet) ENDIF DEBUG_PRINTCALLSTACK() #ENDIF g_bCharacterModelCheckDone = bSet ENDPROC PROC MAINTAIN_SP_CHARACTER_MODEL_CHECK() IF NOT g_bCharacterModelCheckDone CPRINTLN(DEBUG_INIT_SP, "Validating current player model as we start SP...") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Validating current player model as we start SP...") #ENDIF IF IS_PLAYER_PLAYING(PLAYER_ID()) // Run the check if we aren't transitioning, or we're transitioning out of SP. IF NOT IS_TRANSITION_ACTIVE() // No transition out of MP in progress. OR (GET_JOINING_GAMEMODE() != GAMEMODE_SP AND GET_JOINING_GAMEMODE() != GAMEMODE_EMPTY AND GET_CURRENT_GAMEMODE() != GAMEMODE_FM) // Current transition isn't in to SP. IF NOT IS_PLAYER_SWITCH_IN_PROGRESS() //Some form of switch scene being processed. AND GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("startup_positioning")) = 0 //Singleplayer character is being placed in the world. MODEL_NAMES ePlayerModel = GET_PLAYER_MODEL() CPRINTLN(DEBUG_INIT_SP, "The player model was set to hash ", ENUM_TO_INT(ePlayerModel)) #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> The player model was set to hash ", ENUM_TO_INT(ePlayerModel)) #ENDIF IF NOT IS_PLAYER_MODEL_PLAYABLE(ePlayerModel) CPRINTLN(DEBUG_INIT_SP, "Found the player model set to an invalid hash.") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Found the player model set to an invalid hash.") #ENDIF enumCharacterList eSwapChar IF IS_PLAYER_MODEL_PLAYABLE( GET_PLAYER_PED_MODEL(g_savedGlobals.sPlayerData.sInfo.eCurrentPed)) CPRINTLN(DEBUG_INIT_SP, "Swapping model back to current tracked player character.") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Swapping model back to current tracked player character.") #ENDIF eSwapChar = g_savedGlobals.sPlayerData.sInfo.eCurrentPed ELIF IS_PLAYER_MODEL_PLAYABLE( GET_PLAYER_PED_MODEL(g_savedGlobals.sPlayerData.sInfo.eLastKnownPed) ) CPRINTLN(DEBUG_INIT_SP, "Swapping model back to the last known player character.") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Swapping model back to the last known player character.") #ENDIF eSwapChar = g_savedGlobals.sPlayerData.sInfo.eLastKnownPed ELSE CPRINTLN(DEBUG_INIT_SP, "Swapping model back to Franklin as a default.") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Swapping model back to Franklin as a default.") #ENDIF eSwapChar = CHAR_FRANKLIN ENDIF CPRINTLN(DEBUG_INIT_SP, "Selected character swap is ", GET_PLAYER_PED_STRING(eSwapChar)) #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Selected character swap is ", ENUM_TO_INT(eSwapChar)) #ENDIF IF NOT SET_CURRENT_SELECTOR_PED(GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(eSwapChar)) CPRINTLN(DEBUG_INIT_SP, "Waiting for character swap to complete...") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Waiting for character swap to complete...") #ENDIF SET_CHARACTER_MODEL_CHECK_DONE(FALSE) EXIT ENDIF CPRINTLN(DEBUG_INIT_SP, "Model swapped back to a valid character. Check finished.") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Model swapped back to a valid character. Check finished.") #ENDIF ELSE SET_CHARACTER_MODEL_CHECK_DONE(TRUE) CPRINTLN(DEBUG_INIT_SP, "The player character model is valid. Check finished.") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> The player character model is valid. Check finished.") #ENDIF ENDIF ELSE SET_CHARACTER_MODEL_CHECK_DONE(FALSE) CPRINTLN(DEBUG_INIT_SP, "Waiting for startup scripts and switch scenes to finish running...") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Waiting for startup scripts and switch scenes to finish running...") #ENDIF ENDIF ELSE SET_CHARACTER_MODEL_CHECK_DONE(FALSE) CPRINTLN(DEBUG_INIT_SP, "Waiting for transition in to SP to finish...") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Waiting for transition in to SP to finish...") #ENDIF ENDIF ELSE SET_CHARACTER_MODEL_CHECK_DONE(FALSE) CPRINTLN(DEBUG_INIT_SP, "Waiting for player to be alive...") #IF USE_FINAL_PRINTS PRINTLN_FINAL("<2140379> Waiting for player to be alive...") #ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Obtains the RGB values for the ps4 contoller light effect for chop. PROC GET_CHOP_CONTROL_LIGHT_EFFECT_COLOUR(INT &R, INT &G, INT &B) r = 255 g = 0 b = 0 ENDPROC