596 lines
25 KiB
Python
Executable File
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
|