Files
gtav-src/script/dev_ng/singleplayer/scripts/Ambient/BailBonds/Maude_PostBailBond.sc
T
2025-09-29 00:52:08 +02:00

596 lines
25 KiB
Python
Executable File

// ******************************************************************************************************************
// ******************************************************************************************************************
//
// MISSION NAME : Maude_PostBailBond.sc
// AUTHOR : Ahron Mason
// DESCRIPTION : Handles Maude's cleanup post RC - Maude 1 / Bail Bond oddjobs
//
// ******************************************************************************************************************
// ******************************************************************************************************************
//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
USING "rage_builtins.sch"
USING "globals.sch"
USING "RC_Helper_Functions.sch"
USING "RC_Threat_Public.sch"
USING "bailbond_include.sch"
//-------------------------------------------------------------------------------------------------------------------------------------------------
// ENUMS
//-------------------------------------------------------------------------------------------------------------------------------------------------
ENUM MAUDE_AI_STATE_ENUM
MAUDE_AI_IDLE_STATE,
MAUDE_AI_EXIT_TO_FLEE_STATE,
MAUDE_AI_FLEE_STATE
ENDENUM
//-------------------------------------------------------------------------------------------------------------------------------------------------
// VARIABLES
//-------------------------------------------------------------------------------------------------------------------------------------------------
OBJECT_INDEX objMaudeChair
OBJECT_INDEX objMaudeTable
OBJECT_INDEX objMaudeLaptop
PED_INDEX pedMaude
INT iTimer_MaudeDialogue = 0
INT iCounterMaudeLines = 0
INT iMaxNumMaudeLines = -1
INT iFleeExit_SyncScene = -1
//INT iCount_MaudeDialogueLines = 0
MAUDE_AI_STATE_ENUM eMaudeAIState = MAUDE_AI_IDLE_STATE
SCENARIO_BLOCKING_INDEX ScenarioBlockArea_MaudesHouse
//-------------------------------------------------------------------------------------------------------------------------------------------------
// FUNCTIONS
//-------------------------------------------------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// unfreezes the table chair and Maude so she can flee
PROC UNFREEZE_ENTITIES_FOR_MAUDE_FLEEING()
/*IF DOES_ENTITY_EXIST(pedMaude)
FREEZE_ENTITY_POSITION(pedMaude, FALSE)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : UNFREEZE_ENTITIES_FOR_MAUDE_FLEEING - unfreese Maude")
ENDIF*/
IF DOES_ENTITY_EXIST(objMaudeLaptop)
FREEZE_ENTITY_POSITION(objMaudeLaptop, FALSE)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : UNFREEZE_ENTITIES_FOR_MAUDE_FLEEING - unfreese laptop")
ENDIF
IF DOES_ENTITY_EXIST(objMaudeTable)
FREEZE_ENTITY_POSITION(objMaudeTable, FALSE)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : UNFREEZE_ENTITIES_FOR_MAUDE_FLEEING - unfreese table")
ENDIF
/*IF DOES_ENTITY_EXIST(objMaudeChair)
IF IS_ENTITY_PLAYING_ANIM(objMaudeChair, "special_ped@maude@base", "base_chair")
STOP_ENTITY_ANIM(objMaudeChair, "base_chair", "special_ped@maude@base", INSTANT_BLEND_OUT)
STOP_SYNCHRONIZED_ENTITY_ANIM(objMaudeChair, INSTANT_BLEND_OUT, TRUE)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : UNFREEZE_ENTITIES_FOR_MAUDE_FLEEING() : stopped chair anim")
ENDIF
FREEZE_ENTITY_POSITION(objMaudeChair, FALSE)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : UNFREEZE_ENTITIES_FOR_MAUDE_FLEEING - unfreese chair")
ENDIF*/
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : UNFREEZE_ENTITIES_FOR_MAUDE_FLEEING() +++")
ENDPROC
/// PURPOSE:
/// Does any necessary cleanup and terminates the script
PROC SCRIPT_CLEANUP()
SETUP_MAUDES_FOR_DROPOFF(FALSE, ScenarioBlockArea_MaudesHouse)
IF IS_ENTITY_ALIVE(objMaudeLaptop)
FREEZE_ENTITY_POSITION(objMaudeLaptop, FALSE)
ENDIF
SAFE_RELEASE_OBJECT(objMaudeLaptop)
IF IS_ENTITY_ALIVE(objMaudeTable)
FREEZE_ENTITY_POSITION(objMaudeTable, FALSE)
ENDIF
SAFE_RELEASE_OBJECT(objMaudeTable)
IF IS_ENTITY_ALIVE(objMaudeChair)
FREEZE_ENTITY_POSITION(objMaudeChair, FALSE)
IF IS_ENTITY_PLAYING_ANIM(objMaudeChair, "special_ped@maude@base", "base_chair")
STOP_ENTITY_ANIM(objMaudeChair, "base_chair", "special_ped@maude@base", INSTANT_BLEND_OUT)
STOP_SYNCHRONIZED_ENTITY_ANIM(objMaudeChair, INSTANT_BLEND_OUT, TRUE)
ELIF IS_ENTITY_PLAYING_ANIM(objMaudeChair, GET_MAUDE_REACT_ANIM_DICT(), "Female_Flee_Table_Left_Maude_Chair")
STOP_ENTITY_ANIM(objMaudeChair, "Female_Flee_Table_Left_Maude_Chair", GET_MAUDE_REACT_ANIM_DICT(), INSTANT_BLEND_OUT)
STOP_SYNCHRONIZED_ENTITY_ANIM(objMaudeChair, INSTANT_BLEND_OUT, TRUE)
ENDIF
ENDIF
SAFE_RELEASE_OBJECT(objMaudeChair)
IF IS_PED_UNINJURED(pedMaude)
SET_PED_KEEP_TASK(pedMaude, TRUE) // Keep scripted task
SET_PED_CONFIG_FLAG(pedMaude, PCF_RunFromFiresAndExplosions, TRUE) // allow again
ENDIF
SAFE_RELEASE_PED(pedMaude, TRUE)
REMOVE_ANIM_DICT(GET_MAUDE_REACT_ANIM_DICT())
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : Terminate thread - Script Cleanup")
TERMINATE_THIS_THREAD()
ENDPROC
/// PURPOSE:
/// setup Maude for post mission script
PROC SETUP_MAUDE()
IF IS_PED_UNINJURED(pedMaude)
IF NOT IS_ENTITY_A_MISSION_ENTITY(pedMaude)
SET_ENTITY_AS_MISSION_ENTITY(pedMaude)
ENDIF
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedMaude, TRUE)
SET_PED_MONEY(pedMaude, 0)
SET_PED_CAN_BE_TARGETTED(pedMaude, FALSE)
SET_PED_RELATIONSHIP_GROUP_HASH(pedMaude, RELGROUPHASH_PLAYER)
SET_PED_PATH_CAN_USE_CLIMBOVERS(pedMaude, FALSE) // Maude has serious timber, not realistic for her to vault
SET_PED_PATH_CAN_DROP_FROM_HEIGHT(pedMaude, FALSE) // Maude has serious timber, not realistic for her to vault
SET_PED_CONFIG_FLAG(pedMaude, PCF_RunFromFiresAndExplosions, FALSE) // B*1560870 - stop pop during exit anim
#IF IS_DEBUG_BUILD SET_PED_NAME_DEBUG(pedMaude, "POSTMAUDE") #ENDIF
VECTOR vMaudeCoords = << 2728.33, 4145.60, 43.89 >> // pos taken from x:\gta5\script\dev\singleplayer\scripts\RandomChar\Maude\initial_scenes_Maude.sch
// get handle to Maude's table (done set as mission entity since created by map instead uses para on DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS)
IF DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS(vMaudeCoords, 10.0, prop_table_03b)
objMaudeTable = GET_CLOSEST_OBJECT_OF_TYPE(vMaudeCoords, 10.0, prop_table_03b, TRUE)
IF IS_ENTITY_ALIVE(objMaudeTable)
SET_ENTITY_COORDS(objMaudeTable, << 2727.40, 4145.56, 43.68 >>)
SET_ENTITY_HEADING(objMaudeTable, -92.17)
FREEZE_ENTITY_POSITION(objMaudeTable, TRUE)
ENDIF
ENDIF
// get handle to Maude's laptop (set as mission entity since created by script)
IF DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS(vMaudeCoords, 10.0, Prop_Laptop_01a)
objMaudeLaptop = GET_CLOSEST_OBJECT_OF_TYPE(vMaudeCoords, 10.0, Prop_Laptop_01a, FALSE)
IF IS_ENTITY_ALIVE(objMaudeLaptop)
IF NOT IS_ENTITY_A_MISSION_ENTITY(objMaudeLaptop)
SET_ENTITY_AS_MISSION_ENTITY(objMaudeLaptop)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SETUP_MAUDE() : grabbed handle for Maude's laptop")
ENDIF
SET_ENTITY_COORDS(objMaudeLaptop, <<2727.686035,4145.714844,44.080002>>)
SET_ENTITY_HEADING(objMaudeLaptop, 71.0)
FREEZE_ENTITY_POSITION(objMaudeLaptop, TRUE)
ENDIF
ENDIF
// get handle to Maude's chair (set as mission entity since created by script)
IF DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS(vMaudeCoords, 10.0, prop_table_03_chr)
objMaudeChair = GET_CLOSEST_OBJECT_OF_TYPE(vMaudeCoords, 10.0, prop_table_03_chr, FALSE)
IF IS_ENTITY_ALIVE(objMaudeChair)
IF NOT IS_ENTITY_A_MISSION_ENTITY(objMaudeChair)
SET_ENTITY_AS_MISSION_ENTITY(objMaudeChair)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SETUP_MAUDE() : grabbed handle for Maude's chair")
ENDIF
SET_ENTITY_COORDS(objMaudeChair, << 2728.35, 4145.59, 43.30 >>)
SET_ENTITY_HEADING(objMaudeChair, -91.28)
//FREEZE_ENTITY_POSITION(objMaudeChair, TRUE)
ENDIF
ENDIF
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SETUP_MAUDE() done *")
ENDIF
ENDPROC
/// PURPOSE:
/// grab handle to Maude
/// RETURNS:
/// TRUE if Maude was successfully grabbed
FUNC BOOL GET_MAUDE_PED()
INT cnt
INT i
PED_INDEX tmpArray[32]
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
cnt = GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), tmpArray)
REPEAT cnt i
IF IS_PED_UNINJURED(tmpArray[i])
IF (GET_ENTITY_MODEL(tmpArray[i]) = GET_NPC_PED_MODEL(CHAR_MAUDE))
pedMaude = tmpArray[i]
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : GET_MAUDE_PED() return TRUE")
RETURN TRUE
ENDIF
ENDIF
ENDREPEAT
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// get the specific dialogue block for the post mission
/// RETURNS:
/// STRING the specific dialogue block
FUNC STRING GET_MAUDE_DIALOGUE_BLOCK()
// bail bonds in reverse order
IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_HOBO))
RETURN "BB4AUD"
ELIF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_MOUNTAIN))
RETURN "BB3AUD"
ELIF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_FARM))
RETURN "BB2AUD"
ELIF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_QUARRY))
RETURN "BB1AUD"
ENDIF
// no bail bonds completed - must be post RC - Maude 1 setup
RETURN "MAUDEAU"
ENDFUNC
/// PURPOSE:
/// get the specific dialogue root for the post mission
/// RETURNS:
/// STRING the specific dialogue root
FUNC STRING GET_MAUDE_DIALOGUE_ROOT()
// bail bonds in reverse order
IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_HOBO))
// It's only goodbye for now, handsome. Don't you mope, you'll see me again.
// Leave me be now, Trevor. I'm gonna find myself a husband on this here internet if it kills me.
// Let me finish up this last bit of paperwork so I can move on with my dreams.
// I appreciate all your help, Trevor, but you gotta let this fledging spread her wings and fly.
RETURN "BB4_loiter"
ELIF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_MOUNTAIN))
// I do enjoy the chemistry between us, but I'm a busy woman.
// I got some trapped gas that's fit to burst; I'd clear the area if I was you.
// Don't be cluttering up the place. I got enough testosterone in my medication.
// Get goin', Trevor. This malefactor needs to be brought to justice.
RETURN "BB3_loiter"
ELIF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_FARM))
// Don't you be getting me all hot and bothered now.
// Much as I'm lacking a male presence in my life, I got work to do.
// I can't concentrate with you parading around the place.
// People gonna talk if you keep flirtin' with me like this.
RETURN "BB2_loiter"
ELIF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_QUARRY))
// I appreciate you catching that feller, but we got another sad degenerate needs bringing in.
// There's play time, then there's work time, and this here is the latter.
// Go on, Trevor. You know I'll cut you in on the money.
// I'd invite you into the trailer but the hording has got the better of me recently.
RETURN "BB1_loiter"
ENDIF
// no bail bonds completed - must be post RC - Maude 1 setup
// I'd really appreciate the help, and you know how grateful I can be.
// Don't let me hold you up, Trevor. I'll send you the file.
// Go on now, I'll give you a nice share of the proceeds.
// You best get goin'. I'm on the hook for that bond if he doesn't show.
RETURN "MAUDE_loiter"
ENDFUNC
/// PURPOSE:
/// get the max number of lines Maude has to say
/// RETURNS:
/// INT
FUNC INT GET_MAX_NUM_MAUDE_LINES()
// bail bonds in reverse order
IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_HOBO))
RETURN 4
ELIF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_MOUNTAIN))
RETURN 4
ELIF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_FARM))
RETURN 4
ELIF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(BBL_BIT_FLAG_COMPLETED_QUARRY))
RETURN 3
ENDIF
// no bail bonds completed - must be post RC - Maude 1 setup
RETURN 4
ENDFUNC
/// PURPOSE:
/// triggers Maude's ambient dialogue lines
/// PARAMS:
/// vMaudeCoords - Maude's position used in proximity check
/// vPlayerCoords - Player's position used in proximity check
/// RETURNS:
/// TRUE if Dialogue was added to the non critical standard buffer
FUNC BOOL TRIGGER_MAUDE_AMBIENT_MISSION_PASSED_DIALOGUE(VECTOR vMaudeCoords, VECTOR vPlayerCoords, INT iTimeDelay = 18000, FLOAT fTriggerRange = 20.0)
IF iCounterMaudeLines < iMaxNumMaudeLines
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF (VDIST2(vPlayerCoords, vMaudeCoords) < (fTriggerRange * fTriggerRange))
IF (GET_GAME_TIMER() - iTimer_MaudeDialogue) > (iTimeDelay + GET_RANDOM_INT_IN_RANGE(0, 2000))
structPedsForConversation sDialogue
ADD_PED_FOR_DIALOGUE(sDialogue, 3, pedMaude, "MAUDE")
STRING sDialogueBlock = GET_MAUDE_DIALOGUE_BLOCK()
STRING sDialogueRoot = GET_MAUDE_DIALOGUE_ROOT()
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(sDialogue, sDialogueBlock, sDialogueRoot, CONV_PRIORITY_MEDIUM)
iTimer_MaudeDialogue = GET_GAME_TIMER()
iCounterMaudeLines++
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : TRIGGER_MAUDE_AMBIENT_DIALOGUE - return TRUE : sDialogueBlock = ", sDialogueBlock, " sDialogueRoot = ", sDialogueRoot)
RETURN TRUE
ENDIF
ENDIF
ELSE
iTimer_MaudeDialogue = GET_GAME_TIMER()
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// triggers Maude's flee dialogue line
/// PARAMS:
/// vMaudeCoords - Maude's position used in proximity check
/// vPlayerCoords - Player's position used in proximity check
PROC TRIGGER_MAUDE_FLEE_DIALOGUE_LINE(VECTOR vMaudeCoords, VECTOR vPlayerCoords)
IF IS_PED_UNINJURED(pedMaude)
IF NOT IS_AMBIENT_SPEECH_PLAYING(pedMaude)
IF (VDIST2(vPlayerCoords, vMaudeCoords) < (35.0 * 35.0))
BB_PLAY_TRIGGER_AMBIENT_SPEECH(pedMaude, "GENERIC_FRIGHTENED_HIGH", "MAUDE", SPEECH_PARAMS_FORCE) // GENERIC_SHOCKED_HIGH
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : TRIGGER_MAUDE_FLEE_DIALOGUE_LINE - requested to trigger ambient speech line GENERIC_FRIGHTENED_HIGH")
ENDIF
ELSE
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : TRIGGER_MAUDE_FLEE_DIALOGUE_LINE - failed already ambient Maude speech playing")
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// stop any ongoing Maude mission passed ambient dialogue
/// PARAMS:
/// bFinishCurrentLine - if TRUE ongoing convo is allowed to finish current line, otherwise gets cut off
PROC KILL_ANY_ONGOING_MAUDE_MISSION_PASSED_DIALOGUE(BOOL bFinishCurrentLine = FALSE)
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
TEXT_LABEL_23 tlCurrentRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
STRING sMaudeDialogueRoot = GET_MAUDE_DIALOGUE_ROOT()
//if current root matches passed in string return true
IF ARE_STRINGS_EQUAL(tlCurrentRoot, sMaudeDialogueRoot)
IF bFinishCurrentLine
KILL_FACE_TO_FACE_CONVERSATION()
ELSE
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
ENDIF
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : KILL_ANY_ONGOING_MAUDE_MISSION_PASSED_DIALOGUE - convo killed : ", tlCurrentRoot, " bFinishCurrentLine = ", bFinishCurrentLine)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// gets which side vCoordsToCheck is to entityIndex
/// Used to decide which flee exit anim to play, based on which side of Maude the player is
/// NOTE: doesn't check entity is alive
/// PARAMS:
/// entityIndex - the entity to check against
/// vEntityCoords - the entities coords
/// vCoordsToCheck - the coords we want to check
/// RETURNS:
/// Int depicting the side of entityIndex the vCoordsToCheck is. 0 = Left side, 1 = Right side, -1 = directly in line
FUNC INT GET_SIDE_COORDS_IS_TO_ENTITY(ENTITY_INDEX entityIndex, VECTOR vEntityCoords, VECTOR vCoordsToCheck)
FLOAT fSide
VECTOR vPlaneNorm
vPlaneNorm = NORMALISE_VECTOR(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(entityIndex, << 3.0, 0.0, 0.0 >>) - vEntityCoords)
fSide = DOT_PRODUCT(vCoordsToCheck - vEntityCoords, vPlaneNorm)
CPRINTLN(DEBUG_BAIL_BOND, "GET_SIDE_COORDS_IS_TO_ENTITY : vEntityCoords = ", vEntityCoords, " vCoordsToCheck = ", vCoordsToCheck,
" vPlaneNorm = ", vPlaneNorm, " dot returning : ", fSide)
IF (fSide < 0)
RETURN 0 //left side
ELIF (fSide > 0)
RETURN 1 //right side
ENDIF
RETURN -1 // directly in line
ENDFUNC
/// PURPOSE:
/// task Maude to flee the player on foot
/// PARAMS:
/// pedMaudeIndex -
PROC SET_MAUDE_SMART_FLEE_PLAYER()
IF IS_PED_UNINJURED(pedMaude)
SET_MAUDE_FLEE_ATTRIBUTES(pedMaude)
TASK_SMART_FLEE_PED(pedMaude, PLAYER_PED_ID(), 10000, -1)
SET_PED_KEEP_TASK(pedMaude, TRUE) // Keep scripted task
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SET_MAUDE_SMART_FLEE_PLAYER() : done, FC = ", GET_FRAME_COUNT())
ENDIF
ENDPROC
/// PURPOSE:
/// checks to see if Maude should flee
/// PARAMS:
/// bCheckPlayerWanted - if TRUE checks the player's wanted level and returns TRUE if he has one
/// RETURNS:
/// TRUE if reason for Maude to flee
FUNC BOOL SHOULD_MAUDE_FLEE(PED_INDEX &pedMaudeIndex, BOOL bCheckPlayerWanted = FALSE)
IF IS_PED_UNINJURED(pedMaudeIndex)
// Check for Maude taking damage
IF HAS_ENTITY_BEEN_DAMAGED_BY_ANY_PED(pedMaudeIndex)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ANY_VEHICLE(pedMaudeIndex)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ANY_OBJECT(pedMaudeIndex)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude took damage : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
// Check for player pushing them with their car
IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID()) // Ignore player knocking them with car door (in vehicle, but not sitting= must be exiting)
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), pedMaudeIndex)
//OR HAS_ENTITY_COLLIDED_WITH_ANYTHING(objMaudeTable)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude pushed by player vehicle : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
IF DOES_ENTITY_EXIST(objMaudeChair)
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), objMaudeChair)
//OR HAS_ENTITY_COLLIDED_WITH_ANYTHING(objMaudeTable)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's chair pushed by player vehicle : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(objMaudeTable)
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), objMaudeTable)
//OR HAS_ENTITY_COLLIDED_WITH_ANYTHING(objMaudeTable)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's table pushed by player vehicle : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(objMaudeLaptop)
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), objMaudeLaptop)
//OR HAS_ENTITY_COLLIDED_WITH_ANYTHING(objMaudeLaptop)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's laptop pushed by player vehicle : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
ENDIF
ENDIF
// code event check for EVENT_POTENTIAL_GET_RUN_OVER
IF HAS_PED_RECEIVED_EVENT(pedMaudeIndex, EVENT_POTENTIAL_GET_RUN_OVER)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's received event EVENT_POTENTIAL_GET_RUN_OVER : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
// check for ragdoll
IF IS_PED_RAGDOLL(pedMaudeIndex)
IF IS_ENTITY_AT_ENTITY(pedMaudeIndex, PLAYER_PED_ID(), <<3.0, 3.0, 3.0>>) // Player close (so they bumped into them)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's ragdolled with player close by : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
ENDIF
// code event check for EVENT_PED_COLLISION_WITH_PLAYER
IF HAS_PED_RECEIVED_EVENT(pedMaudeIndex, EVENT_PED_COLLISION_WITH_PLAYER)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's received event EVENT_PED_COLLISION_WITH_PLAYER : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
// check for player aiming at RC character
IF IS_PLAYER_VISIBLY_TARGETTING_PED(pedMaudeIndex)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Player visibly targetting Maude : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
// Check for player shooting nearby
IF IS_PLAYER_SHOOTING_NEAR_PED(pedMaudeIndex)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Player shooting near Maude : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
// Check for explosions nearby
IF IS_EXPLOSION_IN_SPHERE(EXP_TAG_DONTCARE, GET_ENTITY_COORDS(pedMaudeIndex), 15)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Explosion near Maude : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
// code event check for EVENT_RESPONDED_TO_THREAT
IF HAS_PED_RECEIVED_EVENT(pedMaudeIndex, EVENT_RESPONDED_TO_THREAT)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude's received event EVENT_RESPONDED_TO_THREAT : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
// flee if player is wanted
IF bCheckPlayerWanted
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : player has wanted level : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
ENDIF
ELSE
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : SHOULD_MAUDE_FLEE() return TRUE : Maude injured : FC = ", GET_FRAME_COUNT())
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
SCRIPT
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : script launched")
// Default callbacks
IF HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : FORCE CLEANUP returned TRUE")
SCRIPT_CLEANUP()
ENDIF
IF NOT GET_MAUDE_PED()
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : cleanup Maude could not be located")
SCRIPT_CLEANUP()
ENDIF
IF NOT IS_PED_UNINJURED(pedMaude)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : maude already injured - heading to cleanup")
SCRIPT_CLEANUP()
ELSE
SETUP_MAUDE()
iTimer_MaudeDialogue = GET_GAME_TIMER() // allow time for mission passed graphic
iMaxNumMaudeLines = GET_MAX_NUM_MAUDE_LINES()
iCounterMaudeLines = 0
SETUP_MAUDES_FOR_DROPOFF(TRUE, ScenarioBlockArea_MaudesHouse)
ENDIF
VECTOR vPlayerPos
VECTOR vMaudePos
// Loop within here until Maude is safe to cleanup
WHILE (TRUE)
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
// check Maude is in good nick
IF NOT IS_PED_UNINJURED(pedMaude)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : Maude is injured - heading to cleanup")
SCRIPT_CLEANUP()
ENDIF
vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
vMaudePos = GET_ENTITY_COORDS(pedMaude)
// check for player leaving Maude
IF (VDIST2(vPlayerPos, vMaudePos) >= (100.0 * 100.0))
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : player left Maude - heading to cleanup")
SCRIPT_CLEANUP()
ENDIF
SWITCH eMaudeAIState
CASE MAUDE_AI_IDLE_STATE
TRIGGER_MAUDE_AMBIENT_MISSION_PASSED_DIALOGUE(vMaudePos, vPlayerPos)
IF SHOULD_MAUDE_FLEE(pedMaude)
UNFREEZE_ENTITIES_FOR_MAUDE_FLEEING()
KILL_ANY_ONGOING_MAUDE_MISSION_PASSED_DIALOGUE()
TRIGGER_MAUDE_FLEE_DIALOGUE_LINE(vMaudePos, vPlayerPos)
REQUEST_ANIM_DICT(GET_MAUDE_REACT_ANIM_DICT()) // begin request for flee anim
eMaudeAIState = MAUDE_AI_EXIT_TO_FLEE_STATE
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : eMaudeAIState = MAUDE_AI_EXIT_TO_FLEE_STATE")
ENDIF
BREAK
CASE MAUDE_AI_EXIT_TO_FLEE_STATE
IF SET_MAUDE_PLAY_FLEE_EXIT_ANIM(pedMaude, objMaudeChair, iFleeExit_SyncScene)
eMaudeAIState = MAUDE_AI_FLEE_STATE
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : eMaudeAIState = MAUDE_AI_FLEE_STATE")
ENDIF
BREAK
CASE MAUDE_AI_FLEE_STATE
IF NOT IsPedPerformingTask(pedMaude, SCRIPT_TASK_SMART_FLEE_PED)
AND NOT IS_PED_FLEEING(pedMaude)
IF NOT IS_ENTITY_PLAYING_ANIM(pedMaude, GET_MAUDE_REACT_ANIM_DICT(), GET_MAUDE_REACT_ANIM())
SET_MAUDE_SMART_FLEE_PLAYER()
ENDIF
ELSE
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : Maude fleeing - heading to cleanup")
SCRIPT_CLEANUP()
ENDIF
BREAK
ENDSWITCH
ENDIF
WAIT(0)
ENDWHILE
// Script should never reach here. Always terminate with cleanup function.
ENDSCRIPT