827 lines
30 KiB
Scheme
Executable File
827 lines
30 KiB
Scheme
Executable File
|
|
|
|
|
|
USING "globals.sch"
|
|
USING "rage_builtins.sch"
|
|
USING "commands_player.sch"
|
|
USING "commands_brains.sch"
|
|
USING "commands_script.sch"
|
|
USING "commands_streaming.sch"
|
|
USING "ambience_run_checks.sch"
|
|
USING "commands_misc.sch"
|
|
USING "brains.sch"
|
|
USING "script_player.sch"
|
|
USING "commands_pad.sch"
|
|
USING "commands_object.sch"
|
|
USING "commands_path.sch"
|
|
USING "Minigame_private.sch"
|
|
USING "dialogue_public.sch"
|
|
USING "Ambient_Speech.sch"
|
|
USING "script_buttons.sch"
|
|
USING "commands_entity.sch"
|
|
|
|
ENUM EApproach
|
|
EApproach_Start = 0,
|
|
EApproach_Follow
|
|
ENDENUM
|
|
|
|
ENUM EThanks
|
|
EThanks_Start = 0,
|
|
EThanks_Follow,
|
|
eThanks_GetInPosition,
|
|
EThanks_ResetAnimSet,
|
|
EThanks_PlayAnim,
|
|
EThanks_Face,
|
|
EThanks_CameraCut,
|
|
EThanks_YoureWelcome,
|
|
EThanks_WaitForOffScreen,
|
|
EThanks_SceneSkip,
|
|
EThanks_WrapUp
|
|
ENDENUM
|
|
|
|
|
|
//
|
|
//Name: IS_ACTOR_USEABLE
|
|
//Purpose: Check to see if an actor is valid and isn't dead. There is a delay where an actor may be valid but still dead this is a check for that case
|
|
//
|
|
FUNC BOOL IS_PED_USEABLE(PED_INDEX actorA)
|
|
|
|
|
|
|
|
IF NOT IS_ENTITY_DEAD(actorA)
|
|
IF GET_SCRIPT_TASK_STATUS(actorA, SCRIPT_TASK_SMART_FLEE_PED) = PERFORMING_TASK OR GET_SCRIPT_TASK_STATUS(actorA, SCRIPT_TASK_SMART_FLEE_PED) = WAITING_TO_START_TASK
|
|
OR GET_SCRIPT_TASK_STATUS(actorA, SCRIPT_TASK_SMART_FLEE_POINT) = PERFORMING_TASK OR GET_SCRIPT_TASK_STATUS(actorA, SCRIPT_TASK_SMART_FLEE_POINT) = WAITING_TO_START_TASK
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Actor is Fleeing")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ELIF NOT IS_PED_INJURED(actorA)
|
|
RETURN TRUE
|
|
ELSE
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Actor is Injured")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ENDIF
|
|
ELSE
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Actor is Dead")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ENDIF
|
|
// RETURN FALSE
|
|
ENDFUNC
|
|
|
|
STRUCT PRIVATE
|
|
eApproach ApproachState //Empty variable
|
|
EThanks ThankState //Empty Variable
|
|
INT iDialogueTimer //Empty Variable
|
|
INT mWaitTime //Empty variable
|
|
INTERPCAMS CameraSet //Empty variable
|
|
FLOAT vStartDistance
|
|
BOOL SkippedCutscene
|
|
ENDSTRUCT
|
|
|
|
STRUCT APPROACHPLAYER
|
|
PED_INDEX aApproachPed = NULL //Ped to approach the player
|
|
|
|
//Anim to play on the thank you ped
|
|
STRING AnimName = NULL //Anim name for the animation to play
|
|
STRING AnimDict = NULL //The dictionary that anim lives
|
|
|
|
//Speech said by the Thank you ped
|
|
structPedsForConversation SpeechBlock //The speech block you've already loaded into the script for the speech (if no speech then an empty variable)
|
|
STRING SubtitleBlock = NULL //The subtitle string used for the speech
|
|
STRING ThanksSpeech = NULL //The actual line of conversation used
|
|
|
|
//where you want the ped to walk to if they are walking off in the scene
|
|
VECTOR vWalkToPosition
|
|
|
|
//Values returned if needed
|
|
BOOL bFirstDialoguePlayed = FALSE //Returns true when the ped starts speaking
|
|
BOOL bSuccess = FALSE //Returns true if the thanking was successful and ended well
|
|
|
|
//Variables to change if you want it behaving differently
|
|
FLOAT fApproachDistance = 10.5 //Distance the approachped should try to get in front of the player
|
|
FLOAT fGiveupDist = 80.0 //The distance you want the guy to give up trying to approach the player
|
|
FLOAT MoveSpeed = PEDMOVEBLENDRATIO_RUN //What speed should the ped approach the player
|
|
FLOAT fFirstAudioDist = 11.5 //What distance do you want the ped to start speaking
|
|
BOOL bDoNotRemovePed = FALSE //The ped will remain after the scene. If set to false they will be deleted on the camera cut.
|
|
BOOL bWalkOff = TRUE //The ped will walk off after saying thank you
|
|
BOOL bFleeAtEnd = TRUE //The ped will flee after saying thank you, set this to default true but walk off will take precidence
|
|
|
|
BOOL bFacePlayer = TRUE //Will the ped attempt to face the player before interactin
|
|
BOOL bApproachPlayer= TRUE //Are you wanting him to run up to the player or do you need it quick
|
|
|
|
|
|
INT ThankYouEnthusiasm = 0 //// 0 ignore, 1 slightly enthused, 2 medium enthused, 3 very enthused if using default thank you anims.
|
|
INT HandoverSceneId = 0 //Synched Scene ID, if needed
|
|
|
|
PRIVATE DoNotTouch
|
|
ENDSTRUCT
|
|
|
|
|
|
///// PURPOSE:
|
|
/// Gives the ped the instructions to approach the player, used at the start of a beat.
|
|
/// PARAMS:
|
|
/// ApproachStruct -
|
|
/// - ApproachStruct.aApproachPed = Ped to use
|
|
/// - ApproachStruct.SpeechBlock = structPedsForConversation for the script
|
|
/// - ApproachStruct.SubtitleBlock = Subtitles used for the block (from dialoguestar)
|
|
/// - ApproachStruct.ThanksSpeech = Line to play when approaching the player
|
|
/// RETURNS:
|
|
/// returns false if this cannot be completed
|
|
/// returns ApproachStruct.bSuccess = TRUE when completed successfully.
|
|
FUNC BOOL UPDATE_APPROACH_PLAYER(APPROACHPLAYER& ApproachStruct)
|
|
|
|
FLOAT StopDistance
|
|
|
|
IF IS_ENTITY_DEAD(ApproachStruct.aApproachPed)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
|
|
VECTOR ApproachCoord = GET_ENTITY_COORDS(ApproachStruct.aApproachPed)
|
|
VECTOR TargetCoord = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
|
|
IF NOT IS_STRING_NULL(ApproachStruct.SubtitleBlock)
|
|
IF NOT IS_STRING_NULL(ApproachStruct.ThanksSpeech)
|
|
IF ApproachStruct.fFirstAudioDist <> 0 AND NOT ApproachStruct.bFirstDialoguePlayed
|
|
IF ApproachStruct.fFirstAudioDist < ApproachStruct.fApproachDistance
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("firstAudioDist is too low to ever work")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
ELIF VDIST(ApproachCoord, TargetCoord) < ApproachStruct.fFirstAudioDist
|
|
ApproachStruct.bFirstDialoguePlayed = TRUE
|
|
PLAY_AMBIENT_DIALOGUE_LINE(ApproachStruct.SpeechBlock, ApproachStruct.aApproachPed,ApproachStruct.SubtitleBlock, ApproachStruct.ThanksSpeech)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH ApproachStruct.DoNotTouch.ApproachState
|
|
CASE EApproach_Start
|
|
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ApproachStruct.aApproachPed, TRUE)
|
|
|
|
//AI_SET_NAV_ACTOR_AVOIDANCE_MODE(aApproach, AIAVOID_PASSIVE)
|
|
// SET_ACTOR_ALLOW_BUMP_REACTIONS(aApproach, FALSE)
|
|
|
|
ApproachStruct.DoNotTouch.vStartDistance = VDIST(ApproachCoord, TargetCoord)
|
|
TASK_LOOK_AT_ENTITY(ApproachStruct.aApproachPed, PLAYER_PED_ID(), -1)
|
|
TASK_FOLLOW_TO_OFFSET_OF_ENTITY(ApproachStruct.aApproachPed, PLAYER_PED_ID(), <<0, 0.5, 0>>, ApproachStruct.MoveSpeed, -1, 1)
|
|
ApproachStruct.DoNotTouch.ApproachState = EApproach_Follow
|
|
BREAK
|
|
CASE EApproach_Follow
|
|
|
|
IF IS_PED_ON_FOOT(PLAYER_PED_ID())
|
|
StopDistance = ApproachStruct.fApproachDistance-3
|
|
ELSE
|
|
StopDistance = ApproachStruct.fApproachDistance
|
|
ENDIF
|
|
IF (VDIST(ApproachCoord, TargetCoord) - ApproachStruct.DoNotTouch.vStartDistance) > ApproachStruct.fGiveupDist
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Approach actor out of give up distance")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ELIF (IS_ENTITY_VISIBLE(ApproachStruct.aApproachPed) AND IS_ENTITY_AT_ENTITY(ApproachStruct.aApproachPed, PLAYER_PED_ID(), <<StopDistance,StopDistance,StopDistance>>))
|
|
// IF ApproachStruct.bFacePlayer
|
|
CLEAR_PED_TASKS(ApproachStruct.aApproachPed)
|
|
TASK_LOOK_AT_ENTITY(ApproachStruct.aApproachPed, PLAYER_PED_ID(), -1)
|
|
// ELSE
|
|
// TASK_CLEAR_LOOK_AT(ApproachStruct.aApproachPed)
|
|
// ENDIF
|
|
ApproachStruct.bSuccess = TRUE
|
|
RETURN TRUE
|
|
ELIF NOT IS_PED_USEABLE(ApproachStruct.aApproachPed)
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Approach actor isn't useable ending")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
FUNC STRING GiveThankYouAnims(INT enthusiastic)
|
|
|
|
STRING CurrentLevel = "Thanks_Male_01"
|
|
|
|
IF enthusiastic = 0
|
|
INT RandomInt = GET_RANDOM_INT_IN_RANGE(1, 8)
|
|
|
|
IF RandomInt = 1
|
|
CurrentLevel = "Thanks_Male_01"
|
|
ELIF RandomInt = 2
|
|
CurrentLevel = "Thanks_Male_02"
|
|
ELIF RandomInt = 3
|
|
CurrentLevel = "Thanks_Male_03"
|
|
ELIF RandomInt = 4
|
|
CurrentLevel = "Thanks_Male_04"
|
|
ELIF RandomInt = 5
|
|
CurrentLevel = "Thanks_Male_05"
|
|
ELIF RandomInt = 6
|
|
CurrentLevel = "Thanks_Male_06"
|
|
ELSE
|
|
CurrentLevel = "Thanks_Male_07"
|
|
ENDIF
|
|
ELIF enthusiastic = 1
|
|
INT RandomInt = GET_RANDOM_INT_IN_RANGE(1, 3)
|
|
|
|
IF RandomInt = 1
|
|
CurrentLevel = "Thanks_Male_01"
|
|
ELSE
|
|
CurrentLevel = "Thanks_Male_02"
|
|
ENDIF
|
|
|
|
ELIF enthusiastic = 2
|
|
INT RandomInt = GET_RANDOM_INT_IN_RANGE(1, 4)
|
|
|
|
IF RandomInt = 1
|
|
CurrentLevel = "Thanks_Male_03"
|
|
ELIF RandomInt = 2
|
|
CurrentLevel = "Thanks_Male_04"
|
|
ELSE
|
|
CurrentLevel = "Thanks_Male_05"
|
|
ENDIF
|
|
ELIF enthusiastic = 3
|
|
INT RandomInt = GET_RANDOM_INT_IN_RANGE(1, 3)
|
|
|
|
IF RandomInt = 1
|
|
CurrentLevel = "Thanks_Male_06"
|
|
ELSE
|
|
CurrentLevel = "Thanks_Male_07"
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN CurrentLevel
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// a basic approach the player and thank him, no cutscene.
|
|
/// PARAMS:
|
|
/// ThankYouStruct -
|
|
/// - ThankYouStruct.aApproachPed = Ped to use
|
|
/// - ThankYouStruct.SpeechBlock = structPedsForConversation for the script
|
|
/// - ThankYouStruct.SubtitleBlock = Subtitles used for the block (from dialoguestar)
|
|
/// - ThankYouStruct.ThanksSpeech = Line to play when thanking the player
|
|
/// - ThankYouStruct.ThankYouEnthusiasm = 0 ignore, 1 slightly enthused, 2 medium enthused, 3 very enthused.
|
|
/// - ThankYouStruct.AnimName = Anim name to play while thanking the player
|
|
/// - ThankYouStruct.AnimDict = Dictionary the anim belongs.
|
|
///
|
|
/// RETURNS:
|
|
/// returns false if this cannot be completed
|
|
/// returns ThankYouStruct.bSuccess = TRUE when completed successfully.
|
|
FUNC BOOL UPDATE_RUN_THANKYOU(APPROACHPLAYER& ThankYouStruct)
|
|
|
|
SEQUENCE_INDEX SeqNPC
|
|
FLOAT StopDistance
|
|
IF IS_ENTITY_DEAD(ThankYouStruct.aApproachPed)
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Approach actor is dead aborting thank you")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
VECTOR ApproachCoord = GET_ENTITY_COORDS(ThankYouStruct.aApproachPed)
|
|
VECTOR TargetCoord = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
|
|
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID())
|
|
TASK_SMART_FLEE_PED(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), 150, -1)
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Approach actor was attacked by player abort thank you")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
VEHICLE_INDEX aVeh
|
|
|
|
SWITCH ThankYouStruct.DoNotTouch.ThankState
|
|
CASE EThanks_Start
|
|
IF IS_STRING_NULL(ThankYouStruct.AnimDict)
|
|
IF IS_STRING_NULL(ThankYouStruct.AnimName)
|
|
ThankYouStruct.AnimDict = "AMB@THANKS"
|
|
ThankYouStruct.AnimName = GiveThankYouAnims(ThankYouStruct.ThankYouEnthusiasm)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
REQUEST_ANIM_DICT(ThankYouStruct.AnimDict)
|
|
|
|
IF ThankYouStruct.bApproachPlayer = FALSE
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_PlayAnim
|
|
ELSE
|
|
|
|
CLEAR_PED_TASKS(ThankYouStruct.aApproachPed)
|
|
SET_CURRENT_PED_WEAPON(ThankYouStruct.aApproachPed, WEAPONTYPE_UNARMED)
|
|
ThankYouStruct.DoNotTouch.vStartDistance = VDIST(ApproachCoord, TargetCoord)
|
|
TASK_LOOK_AT_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), -1)
|
|
IF NOT IS_ENTITY_AT_COORD(ThankYouStruct.aApproachPed, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PLAYER_PED_ID(), <<0, -0.5, 0>>), <<1,1,1>>)
|
|
IF IS_PED_IN_ANY_VEHICLE(ThankYouStruct.aApproachPed)
|
|
aVeh = GET_VEHICLE_PED_IS_IN(ThankYouStruct.aApproachPed)
|
|
IF IS_VEHICLE_DRIVEABLE(aVeh)
|
|
TASK_VEHICLE_MISSION_PED_TARGET(ThankYouStruct.aApproachPed, aVeh, PLAYER_PED_ID(), MISSION_FOLLOW, 10.0, DRIVINGMODE_AVOIDCARS, 5, 20)
|
|
ELSE
|
|
TASK_FOLLOW_TO_OFFSET_OF_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), <<0, -0.5, 0>>, ThankYouStruct.MoveSpeed)
|
|
ENDIF
|
|
ELSE
|
|
TASK_FOLLOW_TO_OFFSET_OF_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), <<0, -0.5, 0>>, ThankYouStruct.MoveSpeed)
|
|
ENDIF
|
|
ENDIF
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_Follow
|
|
ENDIF
|
|
BREAK
|
|
CASE EThanks_Follow
|
|
PRINTNL()
|
|
PRINTSTRING("EThanks_Follow")
|
|
IF IS_PED_ON_FOOT(PLAYER_PED_ID())
|
|
StopDistance = ThankYouStruct.fApproachDistance-3
|
|
ELSE
|
|
StopDistance = ThankYouStruct.fApproachDistance
|
|
ENDIF
|
|
|
|
IF (VDIST(ApproachCoord,TargetCoord) - ThankYouStruct.DoNotTouch.vStartDistance) > ThankYouStruct.fGiveupDist
|
|
TASK_SMART_FLEE_PED(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), 200, -1)
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Thank you: Peds are too far away")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ELIF (IS_ENTITY_VISIBLE(ThankYouStruct.aApproachPed) AND IS_ENTITY_AT_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), <<StopDistance,StopDistance,StopDistance>>))
|
|
IF ThankYouStruct.bFacePlayer = TRUE
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(ThankYouStruct.aApproachPed )
|
|
TASK_TURN_PED_TO_FACE_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID())
|
|
ENDIF
|
|
TASK_LOOK_AT_ENTITY(ThankYouStruct.aApproachPed , PLAYER_PED_ID(), 10000)
|
|
ThankYouStruct.DoNotTouch.mWaitTime = 0
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_PlayAnim
|
|
ELSE
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_PlayAnim
|
|
ENDIF
|
|
ELIF NOT IS_PED_USEABLE(ThankYouStruct.aApproachPed)
|
|
IF NOT IS_PED_INJURED(ThankYouStruct.aApproachPed)
|
|
TASK_SMART_FLEE_PED(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), 200, -1)
|
|
ENDIF
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Thank you: Ped isn't useable ending in Thank_follow")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
CASE EThanks_PlayAnim
|
|
REQUEST_ANIM_DICT(ThankYouStruct.AnimDict)
|
|
IF HAS_ANIM_DICT_LOADED(ThankYouStruct.AnimDict)
|
|
IF IS_PED_FACING_PED(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), 60)
|
|
OR ThankYouStruct.bApproachPlayer = FALSE
|
|
OR ThankYouStruct.bFacePlayer = FALSE
|
|
|
|
CLEAR_PED_TASKS(ThankYouStruct.aApproachPed)
|
|
TASK_PLAY_ANIM(ThankYouStruct.aApproachPed, ThankYouStruct.AnimDict, ThankYouStruct.AnimName, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY)
|
|
TASK_LOOK_AT_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), -1)
|
|
|
|
IF IS_STRING_NULL(ThankYouStruct.ThanksSpeech)
|
|
//Context speech!
|
|
|
|
ELSE
|
|
PLAY_AMBIENT_DIALOGUE_LINE(ThankYouStruct.SpeechBlock, ThankYouStruct.aApproachPed, ThankYouStruct.SubtitleBlock, ThankYouStruct.ThanksSpeech)
|
|
ENDIF
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ThankYouStruct.aApproachPed, TRUE)
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_Face
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE EThanks_Face
|
|
|
|
ThankYouStruct.DoNotTouch.mWaitTime = 0
|
|
|
|
IF NOT IS_PED_INJURED(ThankYouStruct.aApproachPed)
|
|
IF GET_SCRIPT_TASK_STATUS(ThankYouStruct.aApproachPed, SCRIPT_TASK_PLAY_ANIM) = FINISHED_TASK
|
|
|
|
IF ThankYouStruct.bWalkOff = TRUE
|
|
|
|
OPEN_SEQUENCE_TASK(SeqNPC)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
IF IS_VECTOR_ZERO(ThankYouStruct.vWalkToPosition)
|
|
TASK_WANDER_STANDARD(NULL)
|
|
ELSE
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, ThankYouStruct.vWalkToPosition, PEDMOVE_WALK)
|
|
ENDIF
|
|
CLOSE_SEQUENCE_TASK(SeqNPC)
|
|
TASK_PERFORM_SEQUENCE(ThankYouStruct.aApproachPed, SeqNPC)
|
|
CLEAR_SEQUENCE_TASK(SeqNPC)
|
|
SeqNPC = NULL
|
|
SET_PED_KEEP_TASK(ThankYouStruct.aApproachPed, TRUE)
|
|
ELSE
|
|
IF ThankYouStruct.bFleeAtEnd = TRUE
|
|
OPEN_SEQUENCE_TASK(SeqNPC)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 200, -1)
|
|
CLOSE_SEQUENCE_TASK(SeqNPC)
|
|
TASK_PERFORM_SEQUENCE(ThankYouStruct.aApproachPed, SeqNPC)
|
|
CLEAR_SEQUENCE_TASK(SeqNPC)
|
|
SeqNPC = NULL
|
|
SET_PED_KEEP_TASK(ThankYouStruct.aApproachPed, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_WaitForOffScreen
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
BREAK
|
|
|
|
CASE EThanks_WaitForOffScreen
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_WrapUp
|
|
|
|
BREAK
|
|
|
|
CASE EThanks_WrapUp
|
|
ThankYouStruct.bSuccess = TRUE
|
|
RETURN TRUE
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
|
|
|
|
/// PURPOSE:
|
|
/// a Cutscene thank you that makes a ped run towards the player and plays a little cutscene of thanks.
|
|
/// PARAMS:
|
|
/// ThankYouStruct -
|
|
/// - ThankYouStruct.aApproachPed = Ped to use
|
|
/// - ThankYouStruct.SpeechBlock = structPedsForConversation for the script
|
|
/// - ThankYouStruct.SubtitleBlock = Subtitles used for the block (from dialoguestar)
|
|
/// - ThankYouStruct.ThanksSpeech = Line to play when thanking the player
|
|
/// - ThankYouStruct.ThankYouEnthusiasm = 0 ignore, 1 slightly enthused, 2 medium enthused, 3 very enthused.
|
|
/// - ThankYouStruct.AnimName = Anim name to play while thanking the player
|
|
/// - ThankYouStruct.AnimDict = Dictionary the anim belongs.
|
|
///
|
|
/// RETURNS:
|
|
/// returns false if this cannot be completed
|
|
/// returns ThankYouStruct.bSuccess = TRUE when completed successfully.
|
|
FUNC BOOL UPDATE_RUN_ONFOOT_THANKYOU(APPROACHPLAYER& ThankYouStruct)
|
|
|
|
// VECTOR CameraRotation
|
|
VECTOR WarpPos
|
|
FLOAT StopDistance
|
|
SEQUENCE_INDEX SeqNPC
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_KEYBOARD_KEY_PRESSED(KEY_B)
|
|
IF NOT IS_ENTITY_DEAD(ThankYouStruct.aApproachPed)
|
|
OUTPUT_DEBUG_CAM_RELATIVE_TO_ENTITY(ThankYouStruct.aApproachPed)
|
|
ENDIF
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
IF IS_ENTITY_DEAD(ThankYouStruct.aApproachPed)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
VECTOR ApproachCoord = GET_ENTITY_COORDS(ThankYouStruct.aApproachPed)
|
|
VECTOR TargetCoord = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
|
|
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID())
|
|
TASK_SMART_FLEE_PED(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), 200, -1)
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Approach actor was attacked by player abort thank you")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
|
|
ThankYouStruct.DoNotTouch.SkippedCutscene = TRUE
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_SceneSkip
|
|
ENDIF
|
|
|
|
SWITCH ThankYouStruct.DoNotTouch.ThankState
|
|
|
|
|
|
CASE EThanks_Start
|
|
|
|
IF IS_STRING_NULL(ThankYouStruct.AnimDict)
|
|
IF IS_STRING_NULL(ThankYouStruct.AnimName)
|
|
ThankYouStruct.AnimDict = "AMB@THANKS"
|
|
ThankYouStruct.AnimName = GiveThankYouAnims(ThankYouStruct.ThankYouEnthusiasm)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
REQUEST_ANIM_DICT(ThankYouStruct.AnimDict)
|
|
|
|
CLEAR_PED_TASKS(ThankYouStruct.aApproachPed)
|
|
SET_CURRENT_PED_WEAPON(ThankYouStruct.aApproachPed, WEAPONTYPE_UNARMED)
|
|
ThankYouStruct.DoNotTouch.vStartDistance = VDIST(ApproachCoord, TargetCoord)
|
|
TASK_LOOK_AT_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), -1)
|
|
IF ThankYouStruct.bApproachPlayer = TRUE
|
|
TASK_FOLLOW_TO_OFFSET_OF_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), <<0, -0.5, 0>>, ThankYouStruct.MoveSpeed)
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_Follow
|
|
ELSE
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_PlayAnim
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
|
|
CASE EThanks_Follow
|
|
ThankYouStruct.DoNotTouch.mWaitTime = 0
|
|
IF IS_PED_ON_FOOT(PLAYER_PED_ID())
|
|
StopDistance = ThankYouStruct.fApproachDistance-3
|
|
ELSE
|
|
StopDistance = ThankYouStruct.fApproachDistance
|
|
ENDIF
|
|
|
|
IF (VDIST(ApproachCoord,TargetCoord) - ThankYouStruct.DoNotTouch.vStartDistance) > ThankYouStruct.fGiveupDist
|
|
TASK_SMART_FLEE_PED(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), 200, -1)
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Thank you: Peds are too far away")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ELIF (IS_ENTITY_VISIBLE(ThankYouStruct.aApproachPed) AND IS_ENTITY_AT_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), <<StopDistance,StopDistance,StopDistance>>))
|
|
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_PlayAnim
|
|
|
|
ELIF NOT IS_PED_USEABLE(ThankYouStruct.aApproachPed)
|
|
IF NOT IS_PED_INJURED(ThankYouStruct.aApproachPed)
|
|
TASK_SMART_FLEE_PED(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), 200, -1)
|
|
ENDIF
|
|
PRINTSTRING("***********************************")
|
|
PRINTNL()
|
|
PRINTSTRING("Thank you: Ped isn't useable ending in Thank_follow")
|
|
PRINTNL()
|
|
PRINTSTRING("***********************************")
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
|
|
|
|
CASE EThanks_PlayAnim
|
|
|
|
// ATTACH_CAM_TO_ENTITY(cam, entity, <<0.8999, 2.2000, 0.7409>>)
|
|
// POINT_CAM_AT_ENTITY(cam, entity, <<-0.8002, -0.2271, 0.2741>>)
|
|
// SET_CAM_FOV(cam, 33.0000)
|
|
// Camera world coords: <<-135.0128, -1499.1949, 34.6461>> Camera rotation: <<-8.9280, 0.0000, 19.4382>>
|
|
// Entity world coords: <<-136.2800, -1497.1833, 33.9068>> Entity rotation: <<-0.0558, -0.0399, -125.5618>>
|
|
//
|
|
//
|
|
//
|
|
|
|
ThankYouStruct.DoNotTouch.CameraSet.CamFov = 33
|
|
ThankYouStruct.DoNotTouch.CameraSet.ShotTime = 20000
|
|
|
|
// CameraRotation.z = GET_ENTITY_HEADING(PLAYER_PED_ID())
|
|
// CameraRotation.z += 325
|
|
|
|
// ThankYouStruct.DoNotTouch.CameraSet.StartCamPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PLAYER_PED_ID(), <<-0.9,-0.7,0.7>>)
|
|
// ThankYouStruct.DoNotTouch.CameraSet.StartCamRot = CameraRotation
|
|
|
|
ThankYouStruct.DoNotTouch.CameraSet.StartCamPos = <<0.8999, 2.2000, 0.7409>>
|
|
ThankYouStruct.DoNotTouch.CameraSet.StartCamRot = <<-0.8002, -0.2271, 0.2741>>
|
|
|
|
ThankYouStruct.DoNotTouch.CameraSet.AttachToEntity = FALSE
|
|
|
|
WarpPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PLAYER_PED_ID(), <<0,1.5,10>>)
|
|
GET_GROUND_Z_FOR_3D_COORD(WarpPos, WarpPos.z)
|
|
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS_IMMEDIATELY(ThankYouStruct.aApproachPed)
|
|
|
|
SET_ENTITY_COORDS(ThankYouStruct.aApproachPed, WarpPos)
|
|
SET_ENTITY_HEADING(ThankYouStruct.aApproachPed, GET_ENTITY_HEADING(PLAYER_PED_ID())-180)
|
|
|
|
SET_CURRENT_PED_WEAPON(ThankYouStruct.aApproachPed, WEAPONTYPE_UNARMED, TRUE)
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE)
|
|
|
|
// Run_camera_static(ThankYouStruct.DoNotTouch.CameraSet)
|
|
|
|
Run_camera_Attach_Entity_Static(ThankYouStruct.DoNotTouch.CameraSet, ThankYouStruct.aApproachPed, FALSE)
|
|
|
|
SET_CUTSCENE_RUNNING(TRUE)
|
|
|
|
IF NOT IS_PED_INJURED(ThankYouStruct.aApproachPed)
|
|
CLEAR_PED_TASKS(ThankYouStruct.aApproachPed)
|
|
IF GET_SCRIPT_TASK_STATUS(ThankYouStruct.aApproachPed, SCRIPT_TASK_PERFORM_SEQUENCE) <> PERFORMING_TASK
|
|
OR GET_SCRIPT_TASK_STATUS(ThankYouStruct.aApproachPed, SCRIPT_TASK_PERFORM_SEQUENCE) <> WAITING_TO_START_TASK
|
|
IF NOT IS_PED_INJURED(ThankYouStruct.aApproachPed)
|
|
OPEN_SEQUENCE_TASK(SeqNPC)
|
|
TASK_STAND_STILL(NULL, 4000)
|
|
CLOSE_SEQUENCE_TASK(SeqNPC)
|
|
TASK_PERFORM_SEQUENCE(ThankYouStruct.aApproachPed, SeqNPC)
|
|
CLEAR_SEQUENCE_TASK(SeqNPC)
|
|
SeqNPC = NULL
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ThankYouStruct.aApproachPed, TRUE)
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_Face
|
|
|
|
BREAK
|
|
|
|
CASE EThanks_Face
|
|
|
|
IF NOT IS_PED_INJURED(ThankYouStruct.aApproachPed)
|
|
REQUEST_ANIM_DICT(ThankYouStruct.AnimDict)
|
|
IF HAS_ANIM_DICT_LOADED(ThankYouStruct.AnimDict)
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), ThankYouStruct.aApproachPed, 4000)
|
|
IF IS_STRING_NULL(ThankYouStruct.ThanksSpeech)
|
|
//Context speech!
|
|
|
|
ELSE
|
|
PLAY_AMBIENT_DIALOGUE_LINE(ThankYouStruct.SpeechBlock, ThankYouStruct.aApproachPed, ThankYouStruct.SubtitleBlock, ThankYouStruct.ThanksSpeech)
|
|
ENDIF
|
|
OPEN_SEQUENCE_TASK(SeqNPC)
|
|
TASK_STAND_STILL(NULL, 1000)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID())
|
|
TASK_PLAY_ANIM(NULL, ThankYouStruct.AnimDict, ThankYouStruct.AnimName, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY)
|
|
CLOSE_SEQUENCE_TASK(SeqNPC)
|
|
TASK_PERFORM_SEQUENCE(ThankYouStruct.aApproachPed, SeqNPC)
|
|
CLEAR_SEQUENCE_TASK(SeqNPC)
|
|
SeqNPC = NULL
|
|
TASK_LOOK_AT_ENTITY(ThankYouStruct.aApproachPed, PLAYER_PED_ID(), 4000)
|
|
SET_PED_KEEP_TASK(ThankYouStruct.aApproachPed, TRUE)
|
|
ThankYouStruct.DoNotTouch.iDialogueTimer = GET_GAME_TIMER()
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_CameraCut
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE EThanks_CameraCut
|
|
IF DO_TIMER(ThankYouStruct.DoNotTouch.iDialogueTimer, 1500)
|
|
|
|
ThankYouStruct.DoNotTouch.CameraSet.StartCamPos = <<-0.9000, -0.8000, 0.7000>>
|
|
ThankYouStruct.DoNotTouch.CameraSet.StartCamRot = <<0.8723, 1.5782, 0.2491>>
|
|
ThankYouStruct.DoNotTouch.CameraSet.AttachToEntity = FALSE
|
|
Run_camera_Attach_Entity_Static(ThankYouStruct.DoNotTouch.CameraSet, ThankYouStruct.aApproachPed, FALSE)
|
|
|
|
|
|
// ATTACH_CAM_TO_ENTITY(cam, entity, <<-0.9000, -0.8000, 0.7000>>)
|
|
// POINT_CAM_AT_ENTITY(cam, entity, <<0.8723, 1.5782, 0.2491>>)
|
|
// SET_CAM_FOV(cam, 33.0000)
|
|
// Camera world coords: <<-136.4065, -1495.9860, 34.6069>> Camera rotation: <<-8.6656, 0.0000, -162.2667>>
|
|
// Entity world coords: <<-136.2800, -1497.1833, 33.9068>> Entity rotation: <<-0.0558, -0.0399, -125.5618>>
|
|
|
|
|
|
|
|
ThankYouStruct.DoNotTouch.iDialogueTimer = GET_GAME_TIMER()
|
|
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_ResetAnimSet
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EThanks_ResetAnimSet
|
|
IF DO_TIMER(ThankYouStruct.DoNotTouch.iDialogueTimer, 2000)
|
|
IF NOT IS_PED_INJURED(ThankYouStruct.aApproachPed)
|
|
IF GET_SCRIPT_TASK_STATUS(ThankYouStruct.aApproachPed, SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK
|
|
|
|
IF ThankYouStruct.bWalkOff = TRUE
|
|
OPEN_SEQUENCE_TASK(SeqNPC)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
IF IS_VECTOR_ZERO(ThankYouStruct.vWalkToPosition)
|
|
TASK_WANDER_STANDARD(NULL)
|
|
ELSE
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, ThankYouStruct.vWalkToPosition, PEDMOVE_WALK)
|
|
ENDIF
|
|
CLOSE_SEQUENCE_TASK(SeqNPC)
|
|
TASK_PERFORM_SEQUENCE(ThankYouStruct.aApproachPed, SeqNPC)
|
|
CLEAR_SEQUENCE_TASK(SeqNPC)
|
|
SeqNPC = NULL
|
|
SET_PED_KEEP_TASK(ThankYouStruct.aApproachPed, TRUE)
|
|
|
|
ELSE
|
|
IF ThankYouStruct.bFleeAtEnd = TRUE
|
|
OPEN_SEQUENCE_TASK(SeqNPC)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 200, -1)
|
|
CLOSE_SEQUENCE_TASK(SeqNPC)
|
|
TASK_PERFORM_SEQUENCE(ThankYouStruct.aApproachPed, SeqNPC)
|
|
CLEAR_SEQUENCE_TASK(SeqNPC)
|
|
SeqNPC = NULL
|
|
SET_PED_KEEP_TASK(ThankYouStruct.aApproachPed, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
ThankYouStruct.DoNotTouch.iDialogueTimer = GET_GAME_TIMER()
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_WaitForOffScreen
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE EThanks_WaitForOffScreen
|
|
|
|
IF NOT IS_PED_INJURED(ThankYouStruct.aApproachPed)
|
|
|
|
IF ThankYouStruct.bWalkOff = TRUE
|
|
IF NOT IS_ENTITY_ON_SCREEN(ThankYouStruct.aApproachPed) OR DO_TIMER(ThankYouStruct.DoNotTouch.iDialogueTimer, 5000)
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_SceneSkip
|
|
ENDIF
|
|
ELSE
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_SceneSkip
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE EThanks_SceneSkip
|
|
|
|
|
|
IF ThankYouStruct.bDoNotRemovePed = FALSE
|
|
IF DOES_ENTITY_EXIST(ThankYouStruct.aApproachPed)
|
|
DELETE_PED(ThankYouStruct.aApproachPed)
|
|
ENDIF
|
|
ELSE
|
|
IF ThankYouStruct.DoNotTouch.SkippedCutscene = TRUE
|
|
IF NOT IS_PED_INJURED(ThankYouStruct.aApproachPed)
|
|
IF ThankYouStruct.bWalkOff = TRUE
|
|
OPEN_SEQUENCE_TASK(SeqNPC)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
IF IS_VECTOR_ZERO(ThankYouStruct.vWalkToPosition)
|
|
TASK_WANDER_STANDARD(NULL)
|
|
ELSE
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, ThankYouStruct.vWalkToPosition, PEDMOVE_WALK)
|
|
ENDIF
|
|
CLOSE_SEQUENCE_TASK(SeqNPC)
|
|
TASK_PERFORM_SEQUENCE(ThankYouStruct.aApproachPed, SeqNPC)
|
|
CLEAR_SEQUENCE_TASK(SeqNPC)
|
|
SeqNPC = NULL
|
|
SET_PED_KEEP_TASK(ThankYouStruct.aApproachPed, TRUE)
|
|
|
|
ELSE
|
|
IF ThankYouStruct.bFleeAtEnd = TRUE
|
|
OPEN_SEQUENCE_TASK(SeqNPC)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 200, -1)
|
|
CLOSE_SEQUENCE_TASK(SeqNPC)
|
|
TASK_PERFORM_SEQUENCE(ThankYouStruct.aApproachPed, SeqNPC)
|
|
CLEAR_SEQUENCE_TASK(SeqNPC)
|
|
SeqNPC = NULL
|
|
SET_PED_KEEP_TASK(ThankYouStruct.aApproachPed, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_CUTSCENE_RUNNING(FALSE)
|
|
CLEAR_PRINTS()
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
|
|
|
|
ThankYouStruct.DoNotTouch.ThankState = EThanks_WrapUp
|
|
|
|
BREAK
|
|
|
|
CASE EThanks_WrapUp
|
|
ThankYouStruct.bSuccess = TRUE
|
|
RETURN TRUE
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|