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

164 lines
5.1 KiB
Scheme
Executable File

USING "rage_builtins.sch"
USING "commands_clock.sch"
USING "globals.sch"
USING "player_ped_public.sch"
USING "commands_script.sch"
using "commands_pad.sch"
using "commands_misc.sch"
using "commands_player.sch"
USING "Commands_streaming.sch"
USING "script_player.sch"
USING "commands_camera.sch"
USING "script_MISC.sch"
USING "commands_object.sch"
USING "script_ped.sch"
USING "commands_cutscene.sch"
USING "script_maths.sch"
USING "cutscene_public.sch"
STRUCT KILL_CAM_DATA
INT iOverallTimer
INT iShootTimer
INT iEvent
FLOAT fCurrentTimeScale
CAMERA_INDEX camMain
ENDSTRUCT
/// PURPOSE:
/// Gets the ped that's alive and closest to the rendering camera. This is intended for use by RUN_KILL_CAM but it's safe to use
/// elsewhere if needed.
/// PARAMS:
/// peds - The array of peds
/// bIgnoreNonEnemyPeds - If TRUE only peds that hate the player or cops are considered.
/// RETURNS:
/// The ped that's closest to the camera, or NULL if no valid peds were found.
FUNC PED_INDEX GET_CLOSEST_PED_TO_CAM_IN_ARRAY(PED_INDEX &peds[], BOOL bIgnoreNonEnemyPeds = TRUE)
INT i = 0
PED_INDEX pedClosest
FLOAT fClosestDist = -1.0
VECTOR vCamPos = GET_FINAL_RENDERED_CAM_COORD()
REPEAT COUNT_OF(peds) i
IF NOT IS_ENTITY_DEAD(peds[i])
RELATIONSHIP_TYPE relType = GET_RELATIONSHIP_BETWEEN_PEDS(PLAYER_PED_ID(), peds[i])
IF relType = ACQUAINTANCE_TYPE_PED_HATE
OR relType = ACQUAINTANCE_TYPE_PED_WANTED
OR NOT bIgnoreNonEnemyPeds
FLOAT fDist = VDIST2(vCamPos, GET_ENTITY_COORDS(peds[i]))
IF fClosestDist = -1.0
OR fDist < fClosestDist
fClosestDist = fDist
pedClosest = peds[i]
ENDIF
ENDIF
ENDIF
ENDREPEAT
RETURN pedClosest
ENDFUNC
/// PURPOSE:
/// Runs Michael's kill cam: a slow motion shot where all enemy peds in the vicinity are killed by the player.
/// Call every frame until the command returns TRUE, then don't call again until you want to activate another kill cam.
/// PARAMS:
/// sKillCamData - The kill cam data struct: stores any variables required by the kill cam.
/// vStartCamPos - The start coords for the camera.
/// vStartCamRot - The start rotation for the camera.
/// fStartCamFOV - The start FOV for the camera.
/// vEndCamPos - The end coords for the camera.
/// vEndCamRot - The end rotation for the camera.
/// fEndCamFOV - The end FOV for the camera.
/// RETURNS:
/// TRUE once the kill cam has finished.
FUNC BOOL RUN_KILL_CAM(KILL_CAM_DATA &sKillCamData, VECTOR vStartCamPos, VECTOR vStartCamRot, FLOAT fStartCamFOV,
VECTOR vEndCamPos, VECTOR vEndCamRot, FLOAT fEndCamFOV)
PED_INDEX pedEnemies[10]
PED_INDEX pedToShoot
GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), pedEnemies)
IF NOT DOES_CAM_EXIST(sKillCamData.camMain)
sKillCamData.camMain = CREATE_CAMERA_WITH_PARAMS(CAMTYPE_SCRIPTED, vStartCamPos, vStartCamRot, fStartCamFOV, TRUE)
SET_CAM_PARAMS(sKillCamData.camMain, vEndCamPos, vEndCamRot, fEndCamFOV, 9000, GRAPH_TYPE_LINEAR, GRAPH_TYPE_LINEAR)
SHAKE_CAM(sKillCamData.camMain, "HAND_SHAKE", 0.1)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
CLEAR_HELP(TRUE)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
DISPLAY_HUD(FALSE)
DISPLAY_RADAR(FALSE)
SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE)
sKillCamData.fCurrentTimeScale = 1.0
sKillCamData.iEvent = 0
sKillCamData.iOverallTimer = GET_GAME_TIMER()
sKillCamData.iShootTimer = 0
ELSE
//Grab the closest peds to the camera and kill them
pedToShoot = GET_CLOSEST_PED_TO_CAM_IN_ARRAY(pedEnemies)
IF GET_GAME_TIMER() - sKillCamData.iShootTimer > 100
IF NOT IS_ENTITY_DEAD(pedToShoot)
SET_PED_SHOOTS_AT_COORD(PLAYER_PED_ID(), GET_ENTITY_COORDS(pedToShoot))
TASK_SHOOT_AT_ENTITY(PLAYER_PED_ID(), pedToShoot, 2000, FIRING_TYPE_CONTINUOUS)
APPLY_DAMAGE_TO_PED(pedToShoot, 200, TRUE)
sKillCamData.iShootTimer = GET_GAME_TIMER()
ENDIF
ENDIF
//Handle the camera sequence
SWITCH sKillCamData.iEvent
CASE 0
IF sKillCamData.fCurrentTimeScale > 0.15
sKillCamData.fCurrentTimeScale = sKillCamData.fCurrentTimeScale -@ 1.5
ENDIF
SET_TIME_SCALE(sKillCamData.fCurrentTimeScale)
IF GET_GAME_TIMER() - sKillCamData.iOverallTimer > 1500
sKillCamData.iOverallTimer = GET_GAME_TIMER()
sKillCamData.iEvent++
ENDIF
BREAK
CASE 1
IF sKillCamData.fCurrentTimeScale < 1.0
sKillCamData.fCurrentTimeScale = sKillCamData.fCurrentTimeScale +@ 1.5
IF sKillCamData.fCurrentTimeScale > 1.0
sKillCamData.fCurrentTimeScale = 1.0
ENDIF
ENDIF
SET_TIME_SCALE(sKillCamData.fCurrentTimeScale)
IF GET_GAME_TIMER() - sKillCamData.iOverallTimer > 1500
sKillCamData.iEvent++
ENDIF
BREAK
CASE 2 //Cleanup
SET_TIME_SCALE(1.0)
DESTROY_CAM(sKillCamData.camMain)
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
DISPLAY_HUD(TRUE)
DISPLAY_RADAR(TRUE)
SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE)
RETURN TRUE
BREAK
ENDSWITCH
ENDIF
RETURN FALSE
ENDFUNC