Files
2025-09-29 00:52:08 +02:00

200 lines
6.3 KiB
Python
Executable File

//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
// Includes
USING "rage_builtins.sch"
USING "globals.sch"
USING "player_ped_public.sch"
USING "dialogue_public.sch"
USING "flow_public_core.sch"
//////////////////////////////////////////////////////////////////////////////////////////
// //
// SCRIPT NAME : postRC_Nigel3.sc //
// AUTHOR : //
// DESCRIPTION : Handles Al DiNapoli reacting to player interference //
// after completing Nigel RCM. //
// //
//////////////////////////////////////////////////////////////////////////////////////////
ENUM CONV_STATE
CONV_WAITING,
CONV_SPEAKING
ENDENUM
ENUM MISSION_STAGE
MS_INIT,
MS_RUNNING
ENDENUM
MISSION_STAGE mStage = MS_INIT
CONV_STATE convState = CONV_WAITING
structPedsForConversation convStruct
INT iConvTimer
PED_INDEX pedDiNapoli
/// PURPOSE:
/// Checks array of nearby peds to see if one of them is using Al DiNapoli's model. Grab that ped as Al.
/// RETURNS:
/// TRUE if we grabbed Al successfully
FUNC BOOL GRAB_AL_DINAPOLI()
IF DOES_ENTITY_EXIST(PLAYER_PED_ID())
AND NOT IS_PED_INJURED(PLAYER_PED_ID())
PED_INDEX peds[16]
INT iNumPeds, iCount
iNumPeds = GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), peds)
FOR iCount = 0 TO iNumPeds-1
IF (peds[iCount] != NULL)
AND DOES_ENTITY_EXIST(peds[iCount])
IF GET_ENTITY_MODEL(peds[iCount]) = U_M_M_ALDINAPOLI
SET_ENTITY_AS_MISSION_ENTITY(peds[iCount], TRUE, TRUE)
pedDiNapoli = peds[iCount]
RETURN TRUE
ENDIF
ENDIF
ENDFOR
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks whether Al has been killed or is dying
/// RETURNS:
/// TRUE if Al is still alive
FUNC BOOL AL_STILL_ALIVE()
IF DOES_ENTITY_EXIST(pedDiNapoli)
IF NOT IS_PED_INJURED(pedDiNapoli)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks whether Al has got away enough that we consider him to have escaped
/// RETURNS:
/// TRUE if Al is still in range or visible to the player
FUNC BOOL AL_STILL_IN_RANGE()
FLOAT fRange = 200
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(pedDiNapoli)) >= fRange*fRange
AND NOT IS_ENTITY_ON_SCREEN(pedDiNapoli)
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// Initialises variables etc
PROC INIT()
iConvTimer = GET_GAME_TIMER()
ADD_PED_FOR_DIALOGUE(convStruct, 2, PLAYER_PED_ID(), "TREVOR")
ADD_PED_FOR_DIALOGUE(convStruct, 5, pedDiNapoli, "DINAPOLI")
mStage = MS_RUNNING
ENDPROC
/// PURPOSE:
/// Plays Franklin's annoyed lines randomly
PROC PLAY_ANNOYED_LINES()
SWITCH convState
CASE CONV_WAITING
IF (GET_GAME_TIMER() - iConvTimer) > 5000 // 5.0 sec delay between damage complaints
AND HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(pedDiNapoli, PLAYER_PED_ID())
IF CREATE_CONVERSATION(convStruct, "NIGE3AU", "NIGEL3_REACT", CONV_PRIORITY_MEDIUM)
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(pedDiNapoli)
convState = CONV_SPEAKING
ENDIF
ELIF (GET_GAME_TIMER() - iConvTimer) > 12000 // 12.0 sec delay between chasing complaints
AND VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(pedDiNapoli)) <= 900 // Trevor is still within 30m of Al
IF CREATE_CONVERSATION(convStruct, "NIGE3AU", "NIGEL3_REACT", CONV_PRIORITY_MEDIUM)
convState = CONV_SPEAKING
ENDIF
ENDIF
BREAK
CASE CONV_SPEAKING
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
iConvTimer = GET_GAME_TIMER()
convState = CONV_WAITING
ENDIF
BREAK
ENDSWITCH
ENDPROC
// -----------------------------------------------------------------------------------------------------------
// Script Cleanup
// -----------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// Terminates ambient script after performing cleanup functions
PROC SCRIPT_CLEANUP()
CPRINTLN(DEBUG_AMBIENT, "POSTRC_NIGEL3.SC - SCRIPT CLEANUP")
REMOVE_PED_FOR_DIALOGUE(convStruct, 1) // "FRANKLIN"
IF DOES_ENTITY_EXIST(pedDiNapoli)
SET_PED_AS_NO_LONGER_NEEDED(pedDiNapoli)
ENDIF
CPRINTLN(DEBUG_AMBIENT, "POSTRC_NIGEL3.SC - TERMINATING AMBIENT SCRIPT")
TERMINATE_THIS_THREAD()
ENDPROC
// ===========================================================================================================
// Script Loop
// ===========================================================================================================
SCRIPT
CPRINTLN(DEBUG_AMBIENT, "POSTRC_NIGEL3.SC - INIT AMBIENT SCRIPT")
// Default callbacks
IF HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU)
CPRINTLN(DEBUG_AMBIENT, "POSTRC_NIGEL3.SC - DEFAULT CLEANUP")
SCRIPT_CLEANUP()
ENDIF
// See if we can grab Al
IF NOT GRAB_AL_DINAPOLI()
CPRINTLN(DEBUG_AMBIENT, "POSTRC_NIGEL3.SC - COULD NOT GRAB AL, EXITING")
SCRIPT_CLEANUP()
ENDIF
// Main loop
WHILE (TRUE)
WAIT(0)
IF DOES_ENTITY_EXIST(PLAYER_PED_ID()) AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
// Terminate if we are not Trevor
IF NOT (GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR)
CPRINTLN(DEBUG_AMBIENT, "POSTRC_NIGEL3.SC - PLAYER IS NO LONGER TREVOR...")
SCRIPT_CLEANUP()
// Terminate if Al is dead
ELIF NOT AL_STILL_ALIVE()
CPRINTLN(DEBUG_AMBIENT, "POSTRC_NIGEL3.SC - AL DINAPOLI IS NOW DEAD...")
SET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_NIGEL3_AL_DI_NAPOLI_KILLED, TRUE)
STAT_SET_BOOL(SP_KILLED_AL, TRUE)
IF NOT IS_BIT_SET(g_savedGlobals.sRandomChars.g_iWebsiteQueryBit, ENUM_TO_INT(RC_NWS_NGL3_DINAPOLI_NOT_KILLED_BY_TRAIN))
SET_BIT(g_savedGlobals.sRandomChars.g_iWebsiteQueryBit, ENUM_TO_INT(RC_NWS_NGL3_DINAPOLI_NOT_KILLED_BY_TRAIN))
CPRINTLN(DEBUG_INTERNET, GET_THIS_SCRIPT_NAME(), " g_savedGlobals.sRandomChars.g_iWebsiteQueryBit, RC_NWS_NGL3_DINAPOLI_NOT_KILLED_BY_TRAIN) set")
ENDIF
SCRIPT_CLEANUP()
// Terminate if Al escaped
ELIF NOT AL_STILL_IN_RANGE()
CPRINTLN(DEBUG_AMBIENT, "POSTRC_NIGEL3.SC - AL DINAPOLI IS NO LONGER IN RANGE...")
SCRIPT_CLEANUP()
ELSE
SWITCH mStage
CASE MS_INIT
INIT()
BREAK
CASE MS_RUNNING
PLAY_ANNOYED_LINES()
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDWHILE
ENDSCRIPT