366 lines
13 KiB
Scheme
Executable File
366 lines
13 KiB
Scheme
Executable File
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Description: A bunch of methods common to many scripted weapon implementations //
|
|
// //
|
|
// Written by: Online Technical Team: Orlando C-H //
|
|
// Date: 12/09/2018 //
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///
|
|
USING "globals.sch"
|
|
USING "script_blip.sch"
|
|
USING "net_hud_displays.sch"
|
|
USING "rc_helper_functions.sch"
|
|
USING "script_maths.sch"
|
|
USING "turret_cam_public_def.sch"
|
|
|
|
/// PURPOSE:
|
|
/// Returns the screen space distance of "entity" from the
|
|
/// screen centre.
|
|
FUNC FLOAT GET_ENT_DIST2_TO_SCREEN_CENTRE(ENTITY_INDEX entity)
|
|
VECTOR vPos = GET_ENTITY_COORDS(entity)
|
|
IF NOT GET_SCREEN_COORD_FROM_WORLD_COORD(vPos, vPos.x, vPos.y)
|
|
RETURN 1.0
|
|
ENDIF
|
|
|
|
vPos -= <<0.5,0.5,0>> //We want dist from centre of screen
|
|
vPos.z = 0
|
|
RETURN VMAG2(vPos)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Set whether zoom bar is visibale or not on an "ARENA_GUN_CAM_[X]" HUD.
|
|
PROC ARENA_HUD_SET_ZOOM_IS_VISIBLE(SCALEFORM_INDEX scaleformId, BOOL bZoomVisible)
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformId, "SET_ZOOM_VISIBLE")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_BOOL(bZoomVisible)
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set weapon icons on an "ARENA_GUN_CAM_[X]" HUD.
|
|
PROC ARENA_HUD_SET_WEAPON_ICONS(SCALEFORM_INDEX scaleformId, ARENA_HUD_WEAPON_ICON eIconMg, ARENA_HUD_WEAPON_ICON eIconHm, ARENA_HUD_WEAPON_ICON eIconPm)
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformId, "SET_WEAPON_VALUES")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(eIconMg))
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(eIconHm))
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(eIconPm))
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update a "turret_cam" scaleform hud.
|
|
PROC UPDATE_HUD_TURRET_CAM(SCALEFORM_INDEX scaleformId, FLOAT fCurAltitude, FLOAT fFov, FLOAT fMinFov, FLOAT fMaxFov, FLOAT fHeading)
|
|
fFov = (fFov - fMinFov) / (fMaxFov - fMinFov)
|
|
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformId, "SET_ALT_FOV_HEADING")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(fCurAltitude)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(fFov)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(fHeading)
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Convert Euler rotation to a direction vector.
|
|
///
|
|
FUNC VECTOR EULER_TO_DIRECTION_VECTOR(VECTOR vEuler)
|
|
VECTOR vResult
|
|
vResult.x = COS(vEuler.x)
|
|
vResult.y = COS(vEuler.z)
|
|
vResult.z = SIN(vEuler.x)
|
|
vResult.y *= vResult.x
|
|
vResult.x *= -SIN(vEuler.z)
|
|
RETURN vResult
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// This function returns an endpoint vector to pass into SHOOT_SINGLE_BULLET_BETWEEN_COORDS_IGNORE_ENTITY_NEW.
|
|
/// However it is simple and only uses rotation of the camera to determine the endpoint irrespective of camera distance
|
|
/// from vStartCoord (If the camera is far away from vStartCoord then the projectile will not end up where you're pointing).
|
|
/// PARAMS:
|
|
/// vStartCoord - Where the projectile is to be fired from.
|
|
/// fEndPointDistance - How far away from vStartCoord to set the endpoint.
|
|
/// RETURNS:
|
|
///
|
|
FUNC VECTOR GET_TURRET_PROJECTILE_ENDPOINT(VECTOR vStartCoord, FLOAT fEndPointDistance = 1.0)
|
|
VECTOR vRot = GET_FINAL_RENDERED_CAM_ROT()
|
|
VECTOR vDir = EULER_TO_DIRECTION_VECTOR(vRot)
|
|
RETURN vStartCoord + (fEndPointDistance * vDir)
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Creates and updates a vehicle weapon blip.
|
|
/// Caller is responsible for cleaning up the blips.
|
|
PROC MAINTAIN_TURRET_WEAPON_BLIP(BLIP_INDEX& ref_blipFront, BLIP_INDEX& ref_blipBack)
|
|
HIDE_PLAYER_ARROW_THIS_FRAME()
|
|
|
|
VECTOR vCamCoord = GET_FINAL_RENDERED_CAM_COORD()
|
|
IF IS_PAUSE_MENU_ACTIVE()
|
|
OR IS_PAUSE_MENU_ACTIVE_EX()
|
|
OR IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_PAUSE)
|
|
OR IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_PAUSE)
|
|
OR IS_CONTROL_JUST_RELEASED(FRONTEND_CONTROL, INPUT_FRONTEND_PAUSE)
|
|
SET_FAKE_PAUSEMAP_PLAYER_POSITION_THIS_FRAME(vCamCoord.x,vCamCoord.y)
|
|
SET_FAKE_GPS_PLAYER_POSITION_THIS_FRAME(vCamCoord.x, vCamCoord.y)
|
|
IF IS_PAUSE_MENU_ACTIVE()
|
|
OR IS_PAUSE_MENU_ACTIVE_EX()
|
|
IF DOES_BLIP_EXIST(GET_MAIN_PLAYER_BLIP_ID())
|
|
SET_BLIP_ALPHA(GET_MAIN_PLAYER_BLIP_ID(), 255)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF DOES_BLIP_EXIST(GET_MAIN_PLAYER_BLIP_ID())
|
|
SET_BLIP_ALPHA(GET_MAIN_PLAYER_BLIP_ID(), 0)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
LOCK_MINIMAP_POSITION(vCamCoord.x,vCamCoord.y)
|
|
CAMERA_INDEX cam = GET_RENDERING_CAM()
|
|
IF DOES_CAM_EXIST(cam)
|
|
SET_CAM_CONTROLS_MINI_MAP_HEADING(cam, TRUE)
|
|
ENDIF
|
|
|
|
VECTOR vRot
|
|
vRot = GET_FINAL_RENDERED_CAM_ROT(EULER_XYZ)
|
|
vRot = EULER_TO_DIRECTION_VECTOR(vRot)
|
|
|
|
IF NOT DOES_BLIP_EXIST(ref_blipFront)
|
|
ref_blipBack = CREATE_BLIP_FOR_COORD(vCamCoord)
|
|
SET_BLIP_SPRITE(ref_blipBack, RADAR_TRACE_CENTRE_STROKE)
|
|
SHOW_HEIGHT_ON_BLIP(ref_blipBack, FALSE)
|
|
SET_BLIP_DISPLAY(ref_blipBack, DISPLAY_BOTH)
|
|
SET_BLIP_COLOUR(ref_blipBack,GET_BLIP_COLOUR_FROM_HUD_COLOUR(HUD_COLOUR_BLACK))
|
|
SET_BLIP_SHOW_CONE(ref_blipBack, TRUE)
|
|
SET_BLIP_SCALE(ref_blipBack, 0.54)
|
|
SET_BLIP_PRIORITY(ref_blipBack, INT_TO_ENUM(BLIP_PRIORITY, (ENUM_TO_INT(BLIPPRIORITY_OVER_CENTRE_BLIP)+1)))
|
|
ref_blipFront = CREATE_BLIP_FOR_COORD(vCamCoord)
|
|
SET_BLIP_SPRITE(ref_blipFront, RADAR_TRACE_CENTRE_STROKE)
|
|
SHOW_HEIGHT_ON_BLIP(ref_blipFront, FALSE)
|
|
SET_BLIP_DISPLAY(ref_blipFront, DISPLAY_BOTH)
|
|
SET_BLIP_COLOUR(ref_blipFront,GET_BLIP_COLOUR_FROM_HUD_COLOUR(HUD_COLOUR_GREEN))
|
|
SET_BLIP_SHOW_CONE(ref_blipFront, TRUE)
|
|
SET_BLIP_SCALE(ref_blipFront, 0.44)
|
|
SET_BLIP_PRIORITY(ref_blipFront, INT_TO_ENUM(BLIP_PRIORITY, (ENUM_TO_INT(BLIPPRIORITY_OVER_CENTRE_BLIP)+1)))
|
|
SET_BLIP_HIDDEN_ON_LEGEND(ref_blipFront, TRUE)
|
|
SET_BLIP_ROTATION(ref_blipFront, ROUND(GET_HEADING_FROM_VECTOR_2D(vRot.x, vRot.y)))
|
|
|
|
SET_BLIP_HIDDEN_ON_LEGEND(ref_blipBack, TRUE)
|
|
SET_BLIP_ROTATION(ref_blipBack, ROUND(GET_HEADING_FROM_VECTOR_2D(vRot.x, vRot.y)))
|
|
ELSE
|
|
SET_BLIP_COORDS(ref_blipFront, vCamCoord)
|
|
SET_BLIP_ROTATION(ref_blipFront, ROUND(GET_HEADING_FROM_VECTOR_2D(vRot.x, vRot.y)))
|
|
SET_BLIP_DISPLAY(ref_blipFront, DISPLAY_RADAR_ONLY)
|
|
SET_BLIP_COORDS(ref_blipBack, vCamCoord)
|
|
SET_BLIP_ROTATION(ref_blipBack, ROUND(GET_HEADING_FROM_VECTOR_2D(vRot.x, vRot.y)))
|
|
SET_BLIP_DISPLAY(ref_blipBack, DISPLAY_RADAR_ONLY)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC REMOVE_BLIP_IF_EXIST(BLIP_INDEX blip)
|
|
IF DOES_BLIP_EXIST(blip)
|
|
REMOVE_BLIP(blip)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
STRUCT CAM_OUTPUT
|
|
FLOAT fFovChange
|
|
VECTOR vRotChange
|
|
ENDSTRUCT
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Use default camera controls to calculate ref_vCamRotation.
|
|
/// The CAM_OUTPUT struct describes (current - prev) states.
|
|
/// Unlike rotation, fov changes are applied in this function.
|
|
///
|
|
/// If limits.fMinHeading > limits.fMaxHeading the cam will loop 360* instead of clamping.
|
|
FUNC CAM_OUTPUT UPDATE_TURRET_TRANSFORM(CAMERA_INDEX cam, VECTOR& ref_vCamRotation, CAM_CONTROL_LIMITS limits, FLOAT fRotSpeed = 0.6, FLOAT fZoomSpeed = 20.0)
|
|
|
|
FLOAT fCurrentFov = GET_CAM_FOV(cam)
|
|
|
|
// Set up outputs
|
|
//
|
|
CAM_OUTPUT output
|
|
output.fFovChange = -fCurrentFov
|
|
output.vRotChange = -ref_vCamRotation
|
|
|
|
// Cam controls
|
|
//
|
|
FLOAT fZoom = GET_DISABLED_CONTROL_NORMAL(PLAYER_CONTROL, INPUT_SNIPER_ZOOM)
|
|
VECTOR vRStick = -<<GET_DISABLED_CONTROL_UNBOUND_NORMAL(PLAYER_CONTROL, INPUT_SCALED_LOOK_UD), 0, GET_DISABLED_CONTROL_UNBOUND_NORMAL(PLAYER_CONTROL, INPUT_SCALED_LOOK_LR)>>
|
|
|
|
// No need to dead-zone on mouse
|
|
IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
|
|
fRotSpeed *= 8
|
|
ELSE
|
|
CONST_FLOAT cfDEADZONE_MAG 0.06
|
|
// Deadzone zoom
|
|
IF ABSF(fZoom) < cfDEADZONE_MAG
|
|
fZoom = 0
|
|
ENDIF
|
|
|
|
// Deadzone camera movement
|
|
IF VMAG(vRStick) < cfDEADZONE_MAG
|
|
vRStick = <<0,0,0>>
|
|
ENDIF
|
|
ENDIF
|
|
|
|
FLOAT fFrameTime = GET_FRAME_TIME()
|
|
FLOAT fFov = CLAMP(fCurrentFov + (fZoom * fZoomSpeed * fFrameTime), limits.fMinFov, limits.fMaxFov)
|
|
SET_CAM_FOV(cam, fFov)
|
|
SET_CAM_NEAR_CLIP(cam, 0.01)
|
|
|
|
FLOAT fBlurOverride = (fFov - 5.0) /42.0
|
|
SET_GAMEPLAY_CAM_MOTION_BLUR_SCALING_THIS_UPDATE(1.0)
|
|
SET_DISTANCE_BLUR_STRENGTH_OVERRIDE(fBlurOverride)
|
|
|
|
VECTOR vMin, vMax
|
|
vMin.x = limits.fMinPitch
|
|
vMin.y = 0 // no roll
|
|
vMin.z = limits.fMinHeading
|
|
vMax.x = limits.fMaxPitch
|
|
vMax.y = 0 // no roll
|
|
vMax.z = limits.fMaxHeading
|
|
|
|
FLOAT fCamRotSpeed = fFrameTime * fFov * fRotSpeed * (1 + (fFov - limits.fMinFov) / (limits.fMaxFov - limits.fMinFov))
|
|
VECTOR vPan = vRStick
|
|
vPan.z *= fCamRotSpeed
|
|
vPan.x *= fCamRotSpeed
|
|
|
|
ref_vCamRotation += vPan
|
|
|
|
BOOL bLoopHeading = vMin.z > vMax.z
|
|
IF bLoopHeading
|
|
ref_vCamRotation.x = CLAMP(ref_vCamRotation.x, vMin.x, vMax.x)
|
|
ref_vCamRotation.y = CLAMP(ref_vCamRotation.y, vMin.y, vMax.y)
|
|
ref_vCamRotation.z = NORMALIZE_ANGLE(ref_vCamRotation.z)
|
|
ELSE
|
|
ref_vCamRotation = CLAMP_VECTOR_COMPONENTS(ref_vCamRotation, vMin, vMax)
|
|
ENDIF
|
|
|
|
output.fFovChange += fFov
|
|
output.vRotChange += ref_vCamRotation
|
|
RETURN output
|
|
ENDFUNC
|
|
|
|
PROC APPLY_TURRET_TRANSFORM_UPDATE_STATIC(CAMERA_INDEX cam, VECTOR vPos, VECTOR vRot)
|
|
SET_CAM_COORD(cam, vPos)
|
|
SET_CAM_ROT(cam, vRot)
|
|
ENDPROC
|
|
|
|
PROC APPLY_TURRET_TRANSFORM_UPDATE_VEH(CAMERA_INDEX cam, VECTOR vOffsetPos, VECTOR vOffsetRot, VEHICLE_INDEX vehParent, INT iBoneIndex)
|
|
ATTACH_CAM_TO_VEHICLE_BONE(cam, vehParent, iBoneIndex, TRUE, vOffsetRot, vOffsetPos, TRUE)
|
|
ENDPROC
|
|
|
|
PROC APPLY_TURRET_TRANSFORM_UPDATE_ENT_HEADING(CAMERA_INDEX cam, VECTOR vOffsetPos, VECTOR vOffsetRot, ENTITY_INDEX entity)
|
|
ATTACH_CAM_TO_ENTITY(cam, entity, vOffsetPos)
|
|
SET_CAM_ROT(cam, vOffsetRot + GET_ENTITY_ROTATION(entity))
|
|
ENDPROC
|
|
|
|
PROC INIT_CAM_AUDIO_POLICE_CHOPPER(INT& ref_iPanSoundId, INT& ref_iZoomSoundId, INT& ref_iBackgroundSoundId)
|
|
HINT_SCRIPT_AUDIO_BANK("SCRIPT\\POLICE_CHOPPER_CAM")
|
|
ref_iPanSoundId = GET_SOUND_ID()
|
|
ref_iZoomSoundId = GET_SOUND_ID()
|
|
ref_iBackgroundSoundId = GET_SOUND_ID()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Plays HUD sounds. Assumes that the "Zoom" sound has "Ctrl" and "Dir" variables,
|
|
/// and the "Pan" sound has a "Ctrl" variable.
|
|
/// Any soundId that is -1 will be ignored.
|
|
/// PARAMS:
|
|
/// sBank - Ambient bank e.g. SCRIPT\\POLICE_CHOPPER_CAM
|
|
/// sSoundSet - Soundset for these sounds
|
|
/// iDamageTaken - damage suffered this frame
|
|
/// bHeadshot - suffered a headshot this frame?
|
|
PROC MAINTAIN_CAM_HUD_AUDIO(STRING sBank, STRING sSoundSet,
|
|
INT iPanSoundId, STRING sPanSound,
|
|
INT iZoomSoundId, STRING sZoomSound,
|
|
INT iBackgroundSoundId, STRING sBackgroundSound,
|
|
INT iTakeDamageId, STRING sTakeDamageSound,
|
|
INT iLowHealthLoop, STRING sLowHealthLoopSound,
|
|
FLOAT fZoomChange, VECTOR vRotChange,
|
|
INT iDamageTaken, BOOL bSufferedHeadshot)
|
|
|
|
IF IS_STRING_NULL_OR_EMPTY(sBank)
|
|
OR REQUEST_SCRIPT_AUDIO_BANK(sBank)
|
|
IF fZoomChange <> 0
|
|
IF iZoomSoundId != -1
|
|
IF HAS_SOUND_FINISHED(iZoomSoundId)
|
|
PLAY_SOUND_FRONTEND(iZoomSoundId, sZoomSound, sSoundSet)
|
|
ENDIF
|
|
|
|
SET_VARIABLE_ON_SOUND(iZoomSoundId, "Ctrl", fZoomChange)
|
|
IF fZoomChange < 0
|
|
SET_VARIABLE_ON_SOUND(iZoomSoundId,"Dir",-1)
|
|
ELSE
|
|
SET_VARIABLE_ON_SOUND(iZoomSoundId,"Dir", 1)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF iZoomSoundId != -1
|
|
IF NOT HAS_SOUND_FINISHED(iZoomSoundId)
|
|
STOP_SOUND(iZoomSoundId)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
FLOAT fLookMag = VMAG(vRotChange)
|
|
IF fLookMag > 0
|
|
IF iPanSoundId != -1
|
|
IF HAS_SOUND_FINISHED(iPanSoundId)
|
|
PLAY_SOUND_FRONTEND(iPanSoundId, sPanSound, sSoundSet)
|
|
ENDIF
|
|
SET_VARIABLE_ON_SOUND(iPanSoundId, "Ctrl", fLookMag)
|
|
ENDIF
|
|
ELSE
|
|
IF iPanSoundId != -1
|
|
IF NOT HAS_SOUND_FINISHED(iPanSoundId)
|
|
STOP_SOUND(iPanSoundId)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF iBackgroundSoundId != -1
|
|
IF HAS_SOUND_FINISHED(iBackgroundSoundId)
|
|
PLAY_SOUND_FRONTEND(iBackgroundSoundId, sBackgroundSound, sSoundSet)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Damage sounds...
|
|
PED_INDEX pedLocal = PLAYER_PED_ID()
|
|
ENTITY_INDEX playerEntity
|
|
IF IS_PED_IN_ANY_VEHICLE(pedLocal)
|
|
playerEntity = GET_VEHICLE_PED_IS_IN(pedLocal)
|
|
ELSE
|
|
playerEntity = pedLocal
|
|
ENDIF
|
|
|
|
IF iTakeDamageId != -1
|
|
BOOL bPlaySound = bSufferedHeadshot
|
|
|
|
IF NOT bPlaySound
|
|
FLOAT fMaxHealth = TO_FLOAT(GET_ENTITY_MAX_HEALTH(playerEntity))
|
|
bPlaySound = iDamageTaken / fMaxHealth > 0.10 // 10 % Damage in one frame?
|
|
ENDIF
|
|
|
|
IF bPlaySound
|
|
IF HAS_SOUND_FINISHED(iTakeDamageId)
|
|
PLAY_SOUND_FRONTEND(iTakeDamageId, sTakeDamageSound, sTakeDamageSound)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF iLowHealthLoop != -1
|
|
// Check ped and vehicle...
|
|
IF GET_ENTITY_HEALTH(pedLocal) / TO_FLOAT(GET_ENTITY_MAX_HEALTH(pedLocal)) < 0.15 // 15% health is low
|
|
OR GET_ENTITY_HEALTH(playerEntity) / TO_FLOAT(GET_ENTITY_MAX_HEALTH(playerEntity)) < 0.15 // Check vehicle
|
|
IF HAS_SOUND_FINISHED(iLowHealthLoop)
|
|
PLAY_SOUND_FRONTEND(iLowHealthLoop, sLowHealthLoopSound, sSoundSet)
|
|
ENDIF
|
|
ELSE
|
|
IF NOT HAS_SOUND_FINISHED(iLowHealthLoop)
|
|
STOP_SOUND(iLowHealthLoop)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|