Files
gtav-src/script/dev_ng/singleplayer/include/private/Ambient/Ambient_Approach.sch
T
2025-09-29 00:52:08 +02:00

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