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

3634 lines
161 KiB
XML
Executable File

USING "commands_camera.sch"
#IF IS_DEBUG_BUILD
USING "shared_debug.sch"
USING "globals.sch"
USING "commands_debug.sch"
#ENDIF
CONST_INT MAX_NUM_SWITCH_NODES 20
CONST_INT NUM_SWITCH_ENTITIES 2
ENUM SWITCH_CAM_TYPE
SWITCH_CAM_OLD_SYSTEM = 0,
SWITCH_ENTITY_ATTACHED_CAM,
SWITCH_CAM_GAMEPLAY_CAM_COPY,
SWITCH_CAM_WORLD_POS,
SWITCH_CAM_WORLD_POS_W_LOOK_AT,
SWITCH_CAM_PATH_RELATIVE,
SWITCH_CAM_PATH_RELATIVE_ATTACHED,
SWITCH_CAM_PATH_RELATIVE_PED_TO_WORLD_COORD,
SWITCH_CAM_CLONE_NODE_WITH_OFFSET
// SWITCH_CAM_ENTITY_ATTACHED_W_WORLD_LOOK_AT
ENDENUM
ENUM SWITCH_CAM_POST_FX_TYPE
NO_EFFECT = 0,
SEPIA_EFFECT = 1,
SCANLINE_EFFECT = 2,
APFX_SWITCH_HUD_IN = 3
ENDENUM
ENUM SWITCH_CAM_FLASH_EFFECT
SCFE_CODE_FLASH,
SCFE_DefaultFlash,
SCFE_FocusOut,
SCFE_MinigameEndNeutral,
SCFE_MinigameTransitionOut,
SCFE_PauseMenuOut,
SCFE_SwitchShortNeutralIn,
SCFE_SwitchShortNeutralMid,
SCFE_SwitchShortMichaelMid,
SCFE_SwitchShortMichaelIn,
SCFE_SwitchSceneMichael,
SCFE_SwitchShortTrevorMid,
SCFE_SwitchShortFranklinIn,
SCFE_SwitchShortFranklinMid,
SCFE_SwitchShortTrevorIn,
SCFE_SwitchOpenFranklinOut,
SCFE_SwitchOpenMichaelIn,
SCFE_SwitchOpenMichaelOut,
SCFE_SwitchOpenTrevorIn,
SCFE_SwitchOpenTrevorOut,
SCFE_SwitchSceneFranklin,
SCFE_SwitchSceneTrevor
ENDENUM
ENUM SWITCH_CAM_SHAKE_TYPE
CAM_SHAKE_DEFAULT = 0,
CAM_SHAKE_LIGHT,
CAM_SHAKE_MEDIUM,
CAM_SHAKE_HEAVY
ENDENUM
STRUCT SWITCH_CAM_NODE_DOF
FLOAT fDOF_NearDOF
FLOAT fDOF_FarDOF
FLOAT fDOF_EffectStrength
ENDSTRUCT
CONST_INT MAX_NUM_CAM_VELOCITY_OVERRIDES 16
STRUCT CAM_VELOCITY_OVERRIDE
FLOAT fStartPoint
FLOAT fSpeed = -1.0
ENDSTRUCT
CONST_INT MAX_NUM_CAM_BLUR_OVERRIDES 16
STRUCT CAM_BLUR_OVERRIDE
FLOAT fBlurOverrideStartPoint = 0.0
FLOAT fBlurOverrideBlurLevel = -1.0
ENDSTRUCT
STRUCT SWITCH_CAM_NODE
INT iNodeActiveFlag //used to show that this node is active
CAMERA_INDEX ciSwitchNode
SWITCH_CAM_TYPE SwitchCamType
INT iForceCamPointAtEntityIndex = -1
#IF IS_DEBUG_BUILD
INT iSwitchCamTypeDebugSelect = 0
#ENDIF
BOOL bIsGameplayCamCopy
INT iNodeTime
VECTOR vNodePos
VECTOR vNodeDir
FLOAT fNodeOffsetDist
VECTOR vWorldPosLookAt
FLOAT fNodeVerticleOffset //[MF] To allow for height adjustment in SWITCH_CAM_PATH_RELATIVE_PED_TO_WORLD_COORD nodes
BOOL bAttachToOriginPed //[MF] Only used by SWITCH_CAM_PATH_RELATIVE_PED_TO_WORLD_COORD
BOOL bPointAtEntity
BOOL bPointAtOffsetIsRelative
BOOL bAttachOffsetIsRelative
FLOAT fNodeFOV
FLOAT fNodeMotionBlur
FLOAT fNodeCamShake
VECTOR vClonedNodeOffset //[MF] Offset to use in the SWITCH_CAM_CLONE_NODE_WITH_OFFSET type
INT iNodeToClone //[MF] Indicate which Node SWITCH_CAM_CLONE_NODE_WITH_OFFSET type is to clone from
INT iCamEaseType
FLOAT fCamEaseScaler
BOOL bCamEaseForceLinear
BOOL bCamEaseForceLevel
FLOAT fCamNodeVelocityScale
FLOAT fTimeScale = 1.0
INT iTimeScaleEaseType
FLOAT fTimeScaleEaseScaler
BOOL bFlashEnabled
SWITCH_CAM_FLASH_EFFECT SCFE_FlashEffectUsed
#IF IS_DEBUG_BUILD
INT iFlashEffectUsed_WidgetValue
#ENDIF
FLOAT fFlashNodePhaseOffset
FLOAT fMinExposure
FLOAT fMaxExposure
INT iRampUpDuration
INT iRampDownDuration
INT iHoldDuration
BOOL bHasFlashed
BOOL bIsLowDetailNode
BOOL bUseCustomDOF
SWITCH_CAM_NODE_DOF NodeDOF_Info
SWITCH_CAM_POST_FX_TYPE NodeTimePostFX_Type
#IF IS_DEBUG_BUILD
INT iNodeTimePostFX_WidgetValue
#ENDIF
FLOAT fNodeTimePostFXBlendTime
FLOAT fNodeTimePostFXTimeOffset
SWITCH_CAM_SHAKE_TYPE NodeCamShakeType
#IF IS_DEBUG_BUILD
INT iNodeCamShakeType_WidgetValue
#ENDIF
BOOL bIsCamCutNode
BOOL bHaveNodeSettingsBeenApplied
BOOL bHaveNodePostFX_BeenApplied
ENDSTRUCT
STRUCT SWITCH_CAM_STRUCT
BOOL bInitialized
CAMERA_INDEX ciSpline
BOOL bSplineNoSmoothing
BOOL bAddGameplayCamAsLastNode
VEHICLE_INDEX viVehicles[NUM_SWITCH_ENTITIES]
PED_INDEX piPeds[NUM_SWITCH_ENTITIES]
SWITCH_CAM_NODE nodes[MAX_NUM_SWITCH_NODES]
CAM_VELOCITY_OVERRIDE camVelocityOverrides[MAX_NUM_CAM_VELOCITY_OVERRIDES]
CAM_BLUR_OVERRIDE camBlurOverrides[MAX_NUM_CAM_BLUR_OVERRIDES]
INT iNumNodes
INT iCamSwitchFocusNode //Tell where the Cam is to switch Focus
INT iGameplayNodeBlendDuration
STRING strOutputFileName
STRING strOutputStructName
BOOL bSaveTextFile
BOOL bSaveXMLFile
BOOL bLoadXMLFile
STRING strXMLFileName
STRING strCamTarget1WidgetLabel
STRING strCamTarget2WidgetLabel
BOOL bForceDebugWidgetRecreate
BOOL bRecreateSpline
BOOL bGameplayCamDebug
BOOL bTimePostFXActive
BOOL bIsSplineCamFinishedPlaying
//Audio Variables
FLOAT fSwitchSoundAudioStartPhase = -1.0
FLOAT fSwitchSoundAudioEndPhase = -1.0
BOOL bSwitchSoundPlayOpeningPulse = TRUE
BOOL bSwitchSoundPlayMoveLoop = TRUE
BOOL bSwitchSoundPlayExitPulse = TRUE
INT iSwitchAudioCameraHitInID = -1
INT iSwitchAudioCameraMoveLoopID = -1
INT iSwitchAudioCameraHitOutID = -1
#IF IS_DEBUG_BUILD
WIDGET_GROUP_ID wgidParent
WIDGET_GROUP_ID wgidWidgets
BOOL bDEBUGSplineCam_DisableVelocityOverride
BOOL bIsApproved
BOOL bIsApprovedTextDisplayed
FLOAT fSplineCamPhase
#ENDIF
ENDSTRUCT
#IF IS_DEBUG_BUILD
SWITCH_CAM_NODE scnDefaultValues //[MF] This switch cam node instance is only used to compare outputed node values against a default. (WRITE_SPLINE_CAM_DATA_TO_FILE() )
#ENDIF
#IF IS_DEBUG_BUILD
PROC CREATE_SPLINE_CAM_VELOCITY_OVERRIDE_WIDGET(SWITCH_CAM_STRUCT &thisSwitchCam, INT i)
TEXT_LABEL_63 txtWidgetLabel
txtWidgetLabel = "Velocity Override - "
txtWidgetLabel += i
START_WIDGET_GROUP(txtWidgetLabel)
ADD_WIDGET_FLOAT_SLIDER("Vel Override Start", thisSwitchCam.camVelocityOverrides[i].fStartPoint, 0.0, TO_FLOAT(thisSwitchCam.iNumNodes), 0.2)
ADD_WIDGET_FLOAT_SLIDER("Speed", thisSwitchCam.camVelocityOverrides[i].fSpeed, -1.0, 100.0, 1.0)
STOP_WIDGET_GROUP()
ENDPROC
PROC CREATE_SPLINE_CAM_BLUR_OVERRIDE_WIDGET(SWITCH_CAM_STRUCT &thisSwitchCam, INT i)
TEXT_LABEL_63 txtWidgetLabel
txtWidgetLabel = "Blur Override - "
txtWidgetLabel += i
START_WIDGET_GROUP(txtWidgetLabel)
ADD_WIDGET_FLOAT_SLIDER("Blur Override Start", thisSwitchCam.camBlurOverrides[i].fBlurOverrideStartPoint, 0.0, TO_FLOAT(thisSwitchCam.iNumNodes), 0.2)
ADD_WIDGET_FLOAT_SLIDER("Blur Level", thisSwitchCam.camBlurOverrides[i].fBlurOverrideBlurLevel, -1.0, 1.0, 0.1)
STOP_WIDGET_GROUP()
ENDPROC
/// PURPOSE:
/// Create a widget combo box for the diffrent types of time scale interpolation
/// PARAMS:
/// i - int for widget combo selection
PROC CREATE_SPLINE_CAM_TIME_EASE_COMBO(INT &i)
//CDEBUG3LN(DEBUG_MISSION, "CREATE_SPLINE_CAM_TIME_EASE_COMBO")
START_NEW_WIDGET_COMBO()
ADD_TO_WIDGET_COMBO("Normal (Staight Interp) - 0")
ADD_TO_WIDGET_COMBO("Slow In - 1")
ADD_TO_WIDGET_COMBO("Slow Out - 2")
ADD_TO_WIDGET_COMBO("Slow In Out - 3")
STOP_WIDGET_COMBO("Time Ease Type", i)
ENDPROC
/// PURPOSE:
/// Create a widget combo box for the different types of Spline Camera Eases
/// PARAMS:
/// i - int for the widget combo selection
PROC CREATE_SPLINE_CAMERA_EASE_COMBO(INT &i)
//CDEBUG3LN(DEBUG_MISSION, "CREATE_SPLINE_CAMERA_EASE_COMBO")
START_NEW_WIDGET_COMBO()
ADD_TO_WIDGET_COMBO("Normal (Staight Interp) - 0")
ADD_TO_WIDGET_COMBO("Slow In - 1")
ADD_TO_WIDGET_COMBO("Slow Out - 2")
ADD_TO_WIDGET_COMBO("Slow In Out - 3")
STOP_WIDGET_COMBO("Camera Ease Type", i)
ENDPROC
/// PURPOSE:
/// Create a widget group to control camera node Depth Of Field
/// PARAMS:
/// thisSwitchCam - Switch cam struct that the depth of field widget will be created for
/// iNodeIndex - Spline node to create the depth of field widget for
PROC CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
START_WIDGET_GROUP("Camera DOF Settings")
ADD_WIDGET_BOOL("Use Custom DOF For this Cam", thisSwitchCam.nodes[iNodeIndex].bUseCustomDOF)
ADD_WIDGET_FLOAT_SLIDER("Near DOF (m)", thisSwitchCam.nodes[iNodeIndex].NodeDOF_Info.fDOF_NearDOF, 0.0, 10.0, 0.1)
ADD_WIDGET_FLOAT_SLIDER("Far DOF (m)", thisSwitchCam.nodes[iNodeIndex].NodeDOF_Info.fDOF_FarDOF, 0.0, 1000.0, 0.1)
ADD_WIDGET_FLOAT_SLIDER("DOF Effect Strength", thisSwitchCam.nodes[iNodeIndex].NodeDOF_Info.fDOF_EffectStrength, 0.0, 1.0, 0.01)
STOP_WIDGET_GROUP()
ENDPROC
/// PURPOSE:
/// Create a drop down-widget for selecting a camera POST-FX Type
/// PARAMS:
/// thisSwitchCam - Switch cam struct that the Post FX Drop Down Widget will be created for
/// iNodeIndex - Spline node to create the depth of field widget for
PROC CREATE_SPLINE_CAM_POST_FX_WIDGET(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
START_WIDGET_GROUP("Post FX Tuning")
START_NEW_WIDGET_COMBO()
ADD_TO_WIDGET_COMBO("None")
ADD_TO_WIDGET_COMBO("TOD Sepia")
ADD_TO_WIDGET_COMBO("TOD Scan Line")
ADD_TO_WIDGET_COMBO("APFX Switch HUD In")
STOP_WIDGET_COMBO("Post FX Type", thisSwitchCam.nodes[iNodeIndex].iNodeTimePostFX_WidgetValue)
ADD_WIDGET_FLOAT_SLIDER("Post FX Blend Time(secs)", thisSwitchCam.nodes[iNodeIndex].fNodeTimePostFXBlendTime, 0, 5.0, 0.1)
ADD_WIDGET_FLOAT_SLIDER("Post FX Node Time Offset(phase)", thisSwitchCam.nodes[iNodeIndex].fNodeTimePostFXTimeOffset, 0, 1.0, 0.1)
STOP_WIDGET_GROUP()
thisSwitchCam.nodes[iNodeIndex].iNodeTimePostFX_WidgetValue = ENUM_TO_INT(thisSwitchCam.nodes[iNodeIndex].NodeTimePostFX_Type)
ENDPROC
/// PURPOSE:
/// Create a widget to control camera shake
/// PARAMS:
/// thisSwitchCam - Switch Cam struct to control the node shake on
/// iNodeIndex - Node of switch cam struct to apply shake to
PROC CREATE_SPLINE_CAM_SHAKE_WIDGET(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
START_WIDGET_GROUP("Cam Shake")
START_NEW_WIDGET_COMBO()
ADD_TO_WIDGET_COMBO("Default Shake")
ADD_TO_WIDGET_COMBO("Light Animated Shake")
ADD_TO_WIDGET_COMBO("Medium Animated Shake")
ADD_TO_WIDGET_COMBO("Heavy Animated Shake")
STOP_WIDGET_COMBO("Cam Shake Type", thisSwitchCam.nodes[iNodeIndex].iNodeCamShakeType_WidgetValue)
ADD_WIDGET_FLOAT_SLIDER("Cam Shake", thisSwitchCam.nodes[iNodeIndex].fNodeCamShake, 0.0, 10.0, 0.01)
STOP_WIDGET_GROUP()
thisSwitchCam.nodes[iNodeIndex].iNodeCamShakeType_WidgetValue = ENUM_TO_INT(thisSwitchCam.nodes[iNodeIndex].NodeCamShakeType)
ENDPROC
PROC CREATE_SPLINE_CAM_FLASH_WIDGET(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
START_WIDGET_GROUP("Cam Flash")
ADD_WIDGET_BOOL("Enable Flash", thisSwitchCam.nodes[iNodeIndex].bFlashEnabled)
START_NEW_WIDGET_COMBO()
ADD_TO_WIDGET_COMBO("Standard Code Flash")
ADD_TO_WIDGET_COMBO("APFX Default Flash")
ADD_TO_WIDGET_COMBO("APFX Focus Out")
ADD_TO_WIDGET_COMBO("APFX Minigame End Neutral")
ADD_TO_WIDGET_COMBO("APFX Minigame Transition Out")
ADD_TO_WIDGET_COMBO("APFX Pause Menu Out")
ADD_TO_WIDGET_COMBO("APFX Switch Short Neutral In")
ADD_TO_WIDGET_COMBO("APFX Switch Short Neutral Mid")
ADD_TO_WIDGET_COMBO("APFX Switch Short Michael Mid")
ADD_TO_WIDGET_COMBO("APFX Switch Short Michael In")
ADD_TO_WIDGET_COMBO("APFX Switch Scene Michael")
ADD_TO_WIDGET_COMBO("APFX Switch Short Trevor Mid")
ADD_TO_WIDGET_COMBO("APFX Switch Short Franklin In")
ADD_TO_WIDGET_COMBO("APFX Switch Short Franklin Mid")
ADD_TO_WIDGET_COMBO("APFX Switch Short Trevor In")
ADD_TO_WIDGET_COMBO("APFX Switch Open Franklin Out")
ADD_TO_WIDGET_COMBO("APFX Switch Open Michael In")
ADD_TO_WIDGET_COMBO("APFX Switch Open Michael Out")
ADD_TO_WIDGET_COMBO("APFX Switch Open Trevor In")
ADD_TO_WIDGET_COMBO("APFX Switch Open Trevor Out")
ADD_TO_WIDGET_COMBO("APFX Switch Scene Franklin")
ADD_TO_WIDGET_COMBO("APFX Switch Scene Trevor")
STOP_WIDGET_COMBO("Flash Type", thisSwitchCam.nodes[iNodeIndex].iFlashEffectUsed_WidgetValue)
ADD_WIDGET_FLOAT_SLIDER("Start Time (Phase)", thisSwitchCam.nodes[iNodeIndex].fFlashNodePhaseOffset, 0, 1.0, 0.1)
START_WIDGET_GROUP("Code Flash Tuning Values")
ADD_WIDGET_FLOAT_SLIDER("Min Exposure", thisSwitchCam.nodes[iNodeIndex].fMinExposure, 0.0, 200.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("Max Exposure", thisSwitchCam.nodes[iNodeIndex].fMaxExposure, 0.0, 200.0, 1.0)
ADD_WIDGET_INT_SLIDER("Ramp Up Duration", thisSwitchCam.nodes[iNodeIndex].iRampUpDuration, 0, 20000, 1)
ADD_WIDGET_INT_SLIDER("Ramp Down Duration", thisSwitchCam.nodes[iNodeIndex].iRampDownDuration, 0, 20000, 1)
ADD_WIDGET_INT_SLIDER("Hold Duration", thisSwitchCam.nodes[iNodeIndex].iHoldDuration, 0, 20000, 1)
STOP_WIDGET_GROUP()
STOP_WIDGET_GROUP()
thisSwitchCam.nodes[iNodeIndex].iFlashEffectUsed_WidgetValue = ENUM_TO_INT(thisSwitchCam.nodes[iNodeIndex].SCFE_FlashEffectUsed)
ENDPROC
PROC CREATE_SPLINE_CAM_EASE_WIDGET(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
START_WIDGET_GROUP("Camera Ease")
CREATE_SPLINE_CAMERA_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iCamEaseType)
ADD_WIDGET_FLOAT_SLIDER("Camera Ease Scale", thisSwitchCam.nodes[iNodeIndex].fCamEaseScaler, -1.0, 1.0, 0.1)
ADD_WIDGET_FLOAT_SLIDER("Node Velocity Scale", thisSwitchCam.nodes[iNodeIndex].fCamNodeVelocityScale, -1.0, 1.0, 0.1)
ADD_WIDGET_BOOL("Force Linear", thisSwitchCam.nodes[iNodeIndex].bCamEaseForceLinear)
ADD_WIDGET_BOOL("Force Level", thisSwitchCam.nodes[iNodeIndex].bCamEaseForceLevel)
STOP_WIDGET_GROUP()
ENDPROC
#ENDIF
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Write a vector to a debug text file
/// PARAMS:
/// paramCoords - vector to write
/// sPath - directory path to the file to be saved
/// strFileName - the name of the debug file
PROC WRITE_VECTOR_TO_NAMED_FILE(VECTOR paramCoords, String sPath, String strFileName)
//CDEBUG3LN(DEBUG_MISSION, "WRITE_VECTOR_TO_NAMED_FILE")
SAVE_STRING_TO_NAMED_DEBUG_FILE("<<", sPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(paramCoords.x, sPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(", ", sPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(paramCoords.y, sPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(", ", sPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(paramCoords.z, sPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(">>", sPath, strFileName)
ENDPROC
/// PURPOSE:
/// write a bool to a debug text file. It will write out "TRUE" or "FALSE"
/// PARAMS:
/// bWrite - bool to write out
/// sPath - directory path to the file to be saved
/// strFileName - the name of the debug file
PROC WRITE_BOOL_TO_NAMED_FILE(BOOL bWrite, String sPath, String strFileName)
//CDEBUG3LN(DEBUG_MISSION, "WRITE_BOOL_TO_NAMED_FILE")
IF bWrite
SAVE_STRING_TO_NAMED_DEBUG_FILE("TRUE", sPath, strFileName)
ELSE
SAVE_STRING_TO_NAMED_DEBUG_FILE("FALSE", sPath, strFileName)
ENDIF
ENDPROC
#ENDIF
FUNC VECTOR CONVERT_EULER_TO_DIRECTION_VECTOR(VECTOR vEuler)
//CDEBUG3LN(DEBUG_MISSION, "CONVERT_EULER_TO_DIRECTION_VECTOR")
// Euler angles assumed to be in YXZ order
VECTOR vResult
//b.Set(-cx*sz, cx*cz, sx);
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:
/// Get the current entity the switch cam is focused on.
/// PARAMS:
/// iCamIndex -
/// thisSwitchCamStruct -
/// iDEBUGFocusEntitySwitchOverride -
/// RETURNS:
///
FUNC ENTITY_INDEX GET_SWITCH_CAM_FOCUS_ENTITY(SWITCH_CAM_STRUCT &thisSwitchCamStruct, INT iCamIndex, INT iDEBUGFocusEntitySwitchOverride = -1)
//CDEBUG3LN(DEBUG_MISSION, "GET_SWITCH_CAM_FOCUS_PED")
IF iDEBUGFocusEntitySwitchOverride != -1
iCamIndex = iDEBUGFocusEntitySwitchOverride
ENDIF
IF iCamIndex < thisSwitchCamStruct.iCamSwitchFocusNode
OR (thisSwitchCamStruct.iCamSwitchFocusNode = 0 and iDEBUGFocusEntitySwitchOverride = -1)
IF DOES_ENTITY_EXIST(thisSwitchCamStruct.piPeds[0])
RETURN GET_ENTITY_FROM_PED_OR_VEHICLE(thisSwitchCamStruct.piPeds[0])
ELIF DOES_ENTITY_EXIST(thisSwitchCamStruct.viVehicles[0])
RETURN GET_ENTITY_FROM_PED_OR_VEHICLE(thisSwitchCamStruct.viVehicles[0])
ENDIF
ELSE
IF DOES_ENTITY_EXIST(thisSwitchCamStruct.piPeds[1])
RETURN GET_ENTITY_FROM_PED_OR_VEHICLE(thisSwitchCamStruct.piPeds[1])
ELIF DOES_ENTITY_EXIST(thisSwitchCamStruct.viVehicles[1])
RETURN GET_ENTITY_FROM_PED_OR_VEHICLE(thisSwitchCamStruct.viVehicles[1])
ENDIF
ENDIF
RETURN NULL
ENDFUNC
#IF IS_DEBUG_BUILD
BOOL bStopOnNode = TRUE
INT iActiveNode = 0
VECTOR vNodeDirection
#ENDIF
/// PURPOSE:
/// Check if a node is flagged as a jump-cut node
/// PARAMS:
/// thisSwitchCam - Switch cam struct to check for the jump cut node
/// iNode - Node to check
/// RETURNS:
/// TRUE if the node is a jump-cut node. FALSE otherwise.
FUNC BOOL IS_NODE_JUMP_CUT(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNode)
//CDEBUG3LN(DEBUG_MISSION, "IS_NODE_JUMP_CUT")
IF iNode > 0
AND iNode < (thisSwitchCam.iNumNodes - 1)
IF thisSwitchCam.nodes[iNode].bIsCamCutNode
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Reduce the gameplay graphic detail and budget to improve streaming.
/// PARAMS:
/// bRenderHDOnly - Render only High Detail geo (eg, detail closest to camera)
/// iPedPopulationBudget - Set the available ped population (0 = none, 3 = full)
/// iVehiclePopulationBudget - Set available vehcile population (0 = none, 3 = full)
/// bReducePedModelBudget - Reduce the memory dedicated to ped model budget
/// bReduceVehicleModelBudget - Reduce the memory dedicated to vehicle model budget
PROC SET_TO_LOW_DETAIL_RENDERING(INT iPedPopulationBudget = 0, INT iVehiclePopulationBudget = 0, BOOL bReducePedModelBudget = TRUE, BOOL bReduceVehicleModelBudget = TRUE)
CDEBUG3LN(DEBUG_MISSION, "SET_TO_LOW_DETAIL_RENDERING")
SET_PED_POPULATION_BUDGET(iPedPopulationBudget)
SET_VEHICLE_POPULATION_BUDGET(iVehiclePopulationBudget)
SET_REDUCE_PED_MODEL_BUDGET(bReducePedModelBudget)
SET_REDUCE_VEHICLE_MODEL_BUDGET(bReduceVehicleModelBudget)
ENDPROC
/// PURPOSE:
/// Restore the graphic detail and budget to gameplay default.
/// PARAMS:
/// bRenderHDOnly - Render only High Detail geo (eg, detail closest to camera)
/// iPedPopulationBudget - Set the available ped population (0 = none, 3 = full)
/// iVehiclePopulationBudget - Set available vehcile population (0 = none, 3 = full)
/// bReducePedModelBudget - Reduce the memory dedicated to ped model budget
/// bReduceVehicleModelBudget - Reduce the memory dedicated to vehicle model budget
PROC SET_TO_DEFAULT_DETAIL_RENDERING(INT iPedPopulationBudget = 3, INT iVehiclePopulationBudget = 3, BOOL bReducePedModelBudget = FALSE, BOOL bReduceVehicleModelBudget = FALSE)
// CDEBUG3LN(DEBUG_MISSION, "SET_TO_DEFAULT_DETAIL_RENDERING")
SET_PED_POPULATION_BUDGET(iPedPopulationBudget)
SET_VEHICLE_POPULATION_BUDGET(iVehiclePopulationBudget)
SET_REDUCE_PED_MODEL_BUDGET(bReducePedModelBudget)
SET_REDUCE_VEHICLE_MODEL_BUDGET(bReduceVehicleModelBudget)
ENDPROC
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Save the data in a switch cam struct to a .txt file that will have the proper script formatting.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to save the data of.
PROC WRITE_SPLINE_CAM_DATA_TO_FILE(SWITCH_CAM_STRUCT &thisSwitchCam)
CDEBUG3LN(DEBUG_MISSION, "WRITE_SPLINE_CAM_DATA_TO_FILE")
STRING strFileName = thisSwitchCam.strOutputFileName
STRING strPath = ""
CLEAR_NAMED_DEBUG_FILE(strPath, strFileName)
OPEN_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("//--- Start of Cam Data ---", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
INT index
REPEAT thisSwitchCam.iNumNodes index
IF NOT IS_NODE_JUMP_CUT(thisSwitchCam, index)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
IF thisSwitchCam.nodes[index].SwitchCamType != scnDefaultValues.SwitchCamType
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].SwitchCamType = ", strPath, strFileName)
SWITCH thisSwitchCam.nodes[index].SwitchCamType
CASE SWITCH_CAM_OLD_SYSTEM
SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_CAM_OLD_SYSTEM", strPath, strFileName)
BREAK
CASE SWITCH_ENTITY_ATTACHED_CAM
SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_ENTITY_ATTACHED_CAM", strPath, strFileName)
BREAK
CASE SWITCH_CAM_GAMEPLAY_CAM_COPY
SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_CAM_GAMEPLAY_CAM_COPY", strPath, strFileName)
BREAK
CASE SWITCH_CAM_WORLD_POS
SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_CAM_WORLD_POS", strPath, strFileName)
BREAK
CASE SWITCH_CAM_WORLD_POS_W_LOOK_AT
SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_CAM_WORLD_POS_W_LOOK_AT", strPath, strFileName)
BREAK
CASE SWITCH_CAM_PATH_RELATIVE
SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_CAM_PATH_RELATIVE", strPath, strFileName)
BREAK
CASE SWITCH_CAM_PATH_RELATIVE_ATTACHED
SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_CAM_PATH_RELATIVE_ATTACHED", strPath, strFileName)
BREAK
CASE SWITCH_CAM_PATH_RELATIVE_PED_TO_WORLD_COORD
SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_CAM_PATH_RELATIVE_PED_TO_WORLD_COORD", strPath, strFileName)
BREAK
CASE SWITCH_CAM_CLONE_NODE_WITH_OFFSET
SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_CAM_CLONE_NODE_WITH_OFFSET", strPath, strFileName)
BREAK
// CASE SWITCH_CAM_ENTITY_ATTACHED_W_WORLD_LOOK_AT
// SAVE_STRING_TO_NAMED_DEBUG_FILE("SWITCH_CAM_ENTITY_ATTACHED_W_WORLD_LOOK_AT", strPath, strFileName)
// BREAK
ENDSWITCH
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].iForceCamPointAtEntityIndex != scnDefaultValues.iForceCamPointAtEntityIndex
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].iForceCamPointAtEntityIndex = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].iForceCamPointAtEntityIndex , strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bIsGameplayCamCopy != scnDefaultValues.bIsGameplayCamCopy
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bIsGameplayCamCopy = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].bIsGameplayCamCopy, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].iNodeTime != scnDefaultValues.iNodeTime
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].iNodeTime = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].iNodeTime, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF NOT ARE_VECTORS_EQUAL(thisSwitchCam.nodes[index].vNodePos, scnDefaultValues.vNodePos)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].vNodePos = ", strPath, strFileName)
WRITE_VECTOR_TO_NAMED_FILE(thisSwitchCam.nodes[index].vNodePos, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF NOT ARE_VECTORS_EQUAL(thisSwitchCam.nodes[index].vWorldPosLookAt, scnDefaultValues.vWorldPosLookAt)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].vWorldPosLookAt = ", strPath, strFileName)
WRITE_VECTOR_TO_NAMED_FILE(thisSwitchCam.nodes[index].vWorldPosLookAt, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fNodeOffsetDist != scnDefaultValues.fNodeOffsetDist
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fNodeOffsetDist = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fNodeOffsetDist, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fNodeVerticleOffset != scnDefaultValues.fNodeVerticleOffset
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fNodeVerticleOffset = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fNodeVerticleOffset, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bAttachToOriginPed != scnDefaultValues.bAttachToOriginPed
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bAttachToOriginPed = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].bAttachToOriginPed, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF NOT ARE_VECTORS_EQUAL(thisSwitchCam.nodes[index].vNodeDir, scnDefaultValues.vNodeDir)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].vNodeDir = ", strPath, strFileName)
WRITE_VECTOR_TO_NAMED_FILE(thisSwitchCam.nodes[index].vNodeDir, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bPointAtEntity != scnDefaultValues.bPointAtEntity
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bPointAtEntity = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].bPointAtEntity, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bPointAtOffsetIsRelative != scnDefaultValues.bPointAtOffsetIsRelative
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bPointAtOffsetIsRelative = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].bPointAtOffsetIsRelative, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bAttachOffsetIsRelative != scnDefaultValues.bAttachOffsetIsRelative
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bAttachOffsetIsRelative = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].bAttachOffsetIsRelative, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fNodeFOV != scnDefaultValues.fNodeFOV
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fNodeFOV = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fNodeFOV, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF NOT ARE_VECTORS_EQUAL(thisSwitchCam.nodes[index].vClonedNodeOffset, scnDefaultValues.vClonedNodeOffset)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].vClonedNodeOffset = ", strPath, strFileName)
WRITE_VECTOR_TO_NAMED_FILE(thisSwitchCam.nodes[index].vClonedNodeOffset, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].iNodeToClone != scnDefaultValues.iNodeToClone
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].iNodeToClone = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].iNodeToClone, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].NodeTimePostFX_Type != scnDefaultValues.NodeTimePostFX_Type
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].NodeTimePostFX_Type = ", strPath, strFileName)
SWITCH thisSwitchCam.nodes[index].NodeTimePostFX_Type
CASE NO_EFFECT
SAVE_STRING_TO_NAMED_DEBUG_FILE("NO_EFFECT", strPath, strFileName)
BREAK
CASE SEPIA_EFFECT
SAVE_STRING_TO_NAMED_DEBUG_FILE("SEPIA_EFFECT", strPath, strFileName)
BREAK
CASE SCANLINE_EFFECT
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCANLINE_EFFECT", strPath, strFileName)
BREAK
CASE APFX_SWITCH_HUD_IN
SAVE_STRING_TO_NAMED_DEBUG_FILE("APFX_SWITCH_HUD_IN", strPath, strFileName)
BREAK
ENDSWITCH
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fNodeTimePostFXBlendTime != scnDefaultValues.fNodeTimePostFXBlendTime
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fNodeTimePostFXBlendTime = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fNodeTimePostFXBlendTime, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fNodeTimePostFXTimeOffset != scnDefaultValues.fNodeTimePostFXTimeOffset
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fNodeTimePostFXTimeOffset = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fNodeTimePostFXTimeOffset, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fNodeMotionBlur != scnDefaultValues.fNodeMotionBlur
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fNodeMotionBlur = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fNodeMotionBlur, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].NodeCamShakeType != scnDefaultValues.NodeCamShakeType
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].NodeCamShakeType = ", strPath, strFileName)
SWITCH thisSwitchCam.nodes[index].NodeCamShakeType
CASE CAM_SHAKE_DEFAULT
SAVE_STRING_TO_NAMED_DEBUG_FILE("CAM_SHAKE_DEFAULT", strPath, strFileName)
BREAK
CASE CAM_SHAKE_LIGHT
SAVE_STRING_TO_NAMED_DEBUG_FILE("CAM_SHAKE_LIGHT", strPath, strFileName)
BREAK
CASE CAM_SHAKE_MEDIUM
SAVE_STRING_TO_NAMED_DEBUG_FILE("CAM_SHAKE_MEDIUM", strPath, strFileName)
BREAK
CASE CAM_SHAKE_HEAVY
SAVE_STRING_TO_NAMED_DEBUG_FILE("CAM_SHAKE_HEAVY", strPath, strFileName)
BREAK
ENDSWITCH
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fNodeCamShake != scnDefaultValues.fNodeCamShake
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fNodeCamShake = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fNodeCamShake, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].iCamEaseType != scnDefaultValues.iCamEaseType
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].iCamEaseType = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].iCamEaseType, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fCamEaseScaler != scnDefaultValues.fCamEaseScaler
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fCamEaseScaler = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fCamEaseScaler, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fCamNodeVelocityScale != scnDefaultValues.fCamNodeVelocityScale
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fCamNodeVelocityScale = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fCamNodeVelocityScale, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bCamEaseForceLinear != scnDefaultValues.bCamEaseForceLinear
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bCamEaseForceLinear = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].bCamEaseForceLinear, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bCamEaseForceLevel != scnDefaultValues.bCamEaseForceLevel
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bCamEaseForceLevel = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].bCamEaseForceLevel, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fTimeScale != scnDefaultValues.fTimeScale
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fTimeScale = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fTimeScale, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].iTimeScaleEaseType != scnDefaultValues.iTimeScaleEaseType
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].iTimeScaleEaseType = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].iTimeScaleEaseType, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fTimeScaleEaseScaler != scnDefaultValues.fTimeScaleEaseScaler
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fTimeScaleEaseScaler = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fTimeScaleEaseScaler, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bFlashEnabled != scnDefaultValues.bFlashEnabled
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bFlashEnabled = ", strPath, strFileName)
WRITE_BOOL_TO_NAMED_FILE(thisSwitchCam.nodes[index].bFlashEnabled, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].SCFE_FlashEffectUsed != scnDefaultValues.SCFE_FlashEffectUsed
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].SCFE_FlashEffectUsed = ", strPath, strFileName)
SWITCH thisSwitchCam.nodes[index].SCFE_FlashEffectUsed
CASE SCFE_CODE_FLASH
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_CODE_FLASH", strPath, strFileName)
BREAK
CASE SCFE_DefaultFlash
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_DefaultFlash", strPath, strFileName)
BREAK
CASE SCFE_FocusOut
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_FocusOut", strPath, strFileName)
BREAK
CASE SCFE_MinigameEndNeutral
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_MinigameEndNeutral", strPath, strFileName)
BREAK
CASE SCFE_MinigameTransitionOut
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_MinigameTransitionOut", strPath, strFileName)
BREAK
CASE SCFE_PauseMenuOut
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_PauseMenuOut", strPath, strFileName)
BREAK
CASE SCFE_SwitchShortNeutralIn
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchShortNeutralIn", strPath, strFileName)
BREAK
CASE SCFE_SwitchShortNeutralMid
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchShortNeutralMid", strPath, strFileName)
BREAK
CASE SCFE_SwitchShortMichaelMid
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchShortMichaelMid", strPath, strFileName)
BREAK
CASE SCFE_SwitchShortMichaelIn
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchShortMichaelIn", strPath, strFileName)
BREAK
CASE SCFE_SwitchSceneMichael
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchSceneMichael", strPath, strFileName)
BREAK
CASE SCFE_SwitchShortTrevorMid
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchShortTrevorMid", strPath, strFileName)
BREAK
CASE SCFE_SwitchShortFranklinIn
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchShortFranklinIn", strPath, strFileName)
BREAK
CASE SCFE_SwitchShortFranklinMid
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchShortFranklinMid", strPath, strFileName)
BREAK
CASE SCFE_SwitchShortTrevorIn
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchShortTrevorIn", strPath, strFileName)
BREAK
CASE SCFE_SwitchOpenFranklinOut
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchOpenFranklinOut", strPath, strFileName)
BREAK
CASE SCFE_SwitchOpenMichaelIn
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchOpenMichaelIn", strPath, strFileName)
BREAK
CASE SCFE_SwitchOpenMichaelOut
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchOpenMichaelOut", strPath, strFileName)
BREAK
CASE SCFE_SwitchOpenTrevorIn
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchOpenTrevorIn", strPath, strFileName)
BREAK
CASE SCFE_SwitchOpenTrevorOut
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchOpenTrevorOut", strPath, strFileName)
BREAK
CASE SCFE_SwitchSceneFranklin
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchSceneFranklin", strPath, strFileName)
BREAK
CASE SCFE_SwitchSceneTrevor
SAVE_STRING_TO_NAMED_DEBUG_FILE("SCFE_SwitchSceneTrevor", strPath, strFileName)
BREAK
ENDSWITCH
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fMinExposure != scnDefaultValues.fMinExposure
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fMinExposure = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fMinExposure, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fMaxExposure != scnDefaultValues.fMaxExposure
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fMaxExposure = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fMaxExposure, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].iRampUpDuration != scnDefaultValues.iRampUpDuration
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].iRampUpDuration = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].iRampUpDuration, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].iRampDownDuration != scnDefaultValues.iRampDownDuration
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].iRampDownDuration = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].iRampDownDuration, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].iHoldDuration != scnDefaultValues.iHoldDuration
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].iHoldDuration = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].iHoldDuration, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].fFlashNodePhaseOffset != scnDefaultValues.fFlashNodePhaseOffset
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fFlashNodePhaseOffset = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].fFlashNodePhaseOffset, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bIsLowDetailNode != scnDefaultValues.bIsLowDetailNode
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bIsLowDetailNode = ", strPath, strFileName)
WRITE_BOOL_TO_NAMED_FILE(thisSwitchCam.nodes[index].bIsLowDetailNode, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].bUseCustomDOF != scnDefaultValues.bUseCustomDOF
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bUseCustomDOF = ", strPath, strFileName)
WRITE_BOOL_TO_NAMED_FILE(thisSwitchCam.nodes[index].bUseCustomDOF, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].NodeDOF_Info.fDOF_NearDOF != scnDefaultValues.NodeDOF_Info.fDOF_NearDOF
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].NodeDOF_Info.fDOF_NearDOF = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].NodeDOF_Info.fDOF_NearDOF, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].NodeDOF_Info.fDOF_FarDOF != scnDefaultValues.NodeDOF_Info.fDOF_FarDOF
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].NodeDOF_Info.fDOF_FarDOF = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].NodeDOF_Info.fDOF_FarDOF, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
IF thisSwitchCam.nodes[index].NodeDOF_Info.fDOF_EffectStrength != scnDefaultValues.NodeDOF_Info.fDOF_EffectStrength
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].NodeDOF_Info.fDOF_EffectStrength = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].NodeDOF_Info.fDOF_EffectStrength, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
ELSE
// this allows the camera cut in between the nodes to be saved out
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".nodes[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].bIsCamCutNode = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.nodes[index].bIsCamCutNode, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
ENDREPEAT
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
REPEAT MAX_NUM_CAM_VELOCITY_OVERRIDES index
IF thisSwitchCam.camVelocityOverrides[index].fSpeed > -1
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".camVelocityOverrides[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fStartPoint = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.camVelocityOverrides[index].fStartPoint, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".camVelocityOverrides[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fSpeed = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.camVelocityOverrides[index].fSpeed, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
ENDREPEAT
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
REPEAT MAX_NUM_CAM_BLUR_OVERRIDES index
IF thisSwitchCam.camBlurOverrides[index].fBlurOverrideBlurLevel > -1
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".camBlurOverrides[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fBlurOverrideStartPoint = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.camBlurOverrides[index].fBlurOverrideStartPoint, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".camBlurOverrides[", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(index, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("].fBlurOverrideBlurLevel = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.camBlurOverrides[index].fBlurOverrideBlurLevel, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDIF
ENDREPEAT
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".iNumNodes = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.iNumNodes, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".iCamSwitchFocusNode = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.iCamSwitchFocusNode, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".fSwitchSoundAudioStartPhase = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.fSwitchSoundAudioStartPhase, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".fSwitchSoundAudioEndPhase = ", strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(thisSwitchCam.fSwitchSoundAudioEndPhase, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".bSwitchSoundPlayOpeningPulse = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.bSwitchSoundPlayOpeningPulse, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".bSwitchSoundPlayMoveLoop = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.bSwitchSoundPlayMoveLoop, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".bSwitchSoundPlayExitPulse = ", strPath, strFileName)
SAVE_BOOL_TO_NAMED_DEBUG_FILE(thisSwitchCam.bSwitchSoundPlayExitPulse, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".bSplineNoSmoothing = ", strPath, strFileName)
WRITE_BOOL_TO_NAMED_FILE(thisSwitchCam.bSplineNoSmoothing, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".bAddGameplayCamAsLastNode = ", strPath, strFileName)
WRITE_BOOL_TO_NAMED_FILE(thisSwitchCam.bAddGameplayCamAsLastNode, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(thisSwitchCam.strOutputStructName, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(".iGameplayNodeBlendDuration = ", strPath, strFileName)
SAVE_INT_TO_NAMED_DEBUG_FILE(thisSwitchCam.iGameplayNodeBlendDuration, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("//--- End of Cam Data ---", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
CLOSE_DEBUG_FILE()
ENDPROC
PROC SAVE_BOOL_VALUE_XML_TAG(STRING strTagName, BOOL bValue, INT iNumTabs, STRING strPath, STRING strFileName)
//CDEBUG3LN(DEBUG_MISSION, "BUILD_INT_VALUE_XML_TAG")
TEXT_LABEL_63 txtData
INT i
REPEAT iNumTabs i
txtData += " "
ENDREPEAT
txtData += "<"
txtData += strTagName
txtData += " value=\""
IF bValue
txtData += "true"
ELSE
txtData += "false"
ENDIF
txtData += "\" />"
SAVE_STRING_TO_NAMED_DEBUG_FILE(txtData, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDPROC
PROC SAVE_INT_VALUE_XML_TAG(STRING strTagName, INT iValue, INT iNumTabs, STRING strPath, STRING strFileName)
//CDEBUG3LN(DEBUG_MISSION, "BUILD_INT_VALUE_XML_TAG")
TEXT_LABEL_63 txtData
INT i
REPEAT iNumTabs i
txtData += " "
ENDREPEAT
txtData += "<"
txtData += strTagName
txtData += " value=\""
txtData += iValue
txtData += "\" />"
SAVE_STRING_TO_NAMED_DEBUG_FILE(txtData, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDPROC
PROC SAVE_FLOAT_VALUE_XML_TAG(STRING strTagName, FLOAT fValue, INT iNumTabs, STRING strPath, STRING strFileName)
TEXT_LABEL_63 txtData
INT i
REPEAT iNumTabs i
txtData += " "
ENDREPEAT
txtData += "<"
txtData += strTagName
txtData += " value=\""
SAVE_STRING_TO_NAMED_DEBUG_FILE(txtData, strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(fValue, strPath, strFileName)
txtData = "\" />"
SAVE_STRING_TO_NAMED_DEBUG_FILE(txtData, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDPROC
PROC SAVE_VECTOR_VALUE_XML_TAG(STRING strTagName, VECTOR vVector, INT iNumTabs, STRING strPath, STRING strFileName)
//CDEBUG3LN(DEBUG_MISSION, "BUILD_VECTOR_VALUE_XML_TAG")
TEXT_LABEL_63 txtData
INT i
REPEAT iNumTabs i
txtData += " "
ENDREPEAT
txtData += "<"
txtData += strTagName
txtData += " x=\""
SAVE_STRING_TO_NAMED_DEBUG_FILE(txtData, strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(vVector.x, strPath, strFileName)
txtData = "\" y=\""
SAVE_STRING_TO_NAMED_DEBUG_FILE(txtData, strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(vVector.y, strPath, strFileName)
txtData = "\" z=\""
SAVE_STRING_TO_NAMED_DEBUG_FILE(txtData, strPath, strFileName)
SAVE_FLOAT_TO_NAMED_DEBUG_FILE(vVector.z, strPath, strFileName)
txtData = "\" />"
SAVE_STRING_TO_NAMED_DEBUG_FILE(txtData, strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDPROC
/// PURPOSE:
/// Save the data in a switch cam struct to an .xml file
/// PARAMS:
/// thisSwitchCam - Switch cam struct to save the data of.
PROC OUTPUT_SPLINE_CAM_DATA_TO_XML(SWITCH_CAM_STRUCT &thisSwitchCam)
CDEBUG3LN(DEBUG_MISSION, "OUTPUT_SPLINE_CAM_DATA_TO_XML")
STRING strFileName = thisSwitchCam.strXMLFileName
STRING strPath = "common:/data/script/xml/"
CLEAR_NAMED_DEBUG_FILE(strPath, strFileName)
OPEN_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("<CustomCamData>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(" <SwitchNodes>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
INT i
REPEAT thisSwitchCam.iNumNodes i
SAVE_STRING_TO_NAMED_DEBUG_FILE(" <Node>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("Index", i, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("Time", thisSwitchCam.nodes[i].iNodeTime, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("IsGameplayCamCopy", thisSwitchCam.nodes[i].bIsGameplayCamCopy, 3, strPath, strFileName)
SAVE_VECTOR_VALUE_XML_TAG("Position", thisSwitchCam.nodes[i].vNodePos, 3, strPath, strFileName)
SAVE_VECTOR_VALUE_XML_TAG("Direction", thisSwitchCam.nodes[i].vNodeDir, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("PointAtEntity", thisSwitchCam.nodes[i].bPointAtEntity, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("PointAtOffsetIsRelative", thisSwitchCam.nodes[i].bPointAtOffsetIsRelative, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("AttachOffsetIsRelative", thisSwitchCam.nodes[i].bAttachOffsetIsRelative, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("SwitchCamType", ENUM_TO_INT(thisSwitchCam.nodes[i].SwitchCamType), 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("ForceCamPointAtEntityIndex", ENUM_TO_INT(thisSwitchCam.nodes[i].iForceCamPointAtEntityIndex), 3, strPath, strFileName)
SAVE_VECTOR_VALUE_XML_TAG("WorldCamLookAtCoord", thisSwitchCam.nodes[i].vWorldPosLookAt, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("WorldCamLookAtOffset", thisSwitchCam.nodes[i].fNodeOffsetDist, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("NodeVerticleOffset", thisSwitchCam.nodes[i].fNodeVerticleOffset, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("AttachToOriginPed", thisSwitchCam.nodes[i].bAttachToOriginPed, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("FOV", thisSwitchCam.nodes[i].fNodeFOV, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("TimePostFXType", ENUM_TO_INT(thisSwitchCam.nodes[i].NodeTimePostFX_Type), 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("PostFXBlendTime", thisSwitchCam.nodes[i].fNodeTimePostFXBlendTime, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("PostFXNodeStartOffset", thisSwitchCam.nodes[i].fNodeTimePostFXTimeOffset, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("CamShakeType", ENUM_TO_INT(thisSwitchCam.nodes[i].NodeCamShakeType), 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("MotionBlur", thisSwitchCam.nodes[i].fNodeMotionBlur, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("CamShake", thisSwitchCam.nodes[i].fNodeCamShake, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("CamEaseType", thisSwitchCam.nodes[i].iCamEaseType, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("CamEaseScaler", thisSwitchCam.nodes[i].fCamEaseScaler, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("CamNodeVelocityScale", thisSwitchCam.nodes[i].fCamNodeVelocityScale, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("CamEaseForceLinear", thisSwitchCam.nodes[i].bCamEaseForceLinear, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("CamEaseForceLevel", thisSwitchCam.nodes[i].bCamEaseForceLevel, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("TimeScale", thisSwitchCam.nodes[i].fTimeScale, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("TimeScaleEaseType", thisSwitchCam.nodes[i].iTimeScaleEaseType, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("TimeScaleEaseScaler", thisSwitchCam.nodes[i].fTimeScaleEaseScaler, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("FlashEnabled", thisSwitchCam.nodes[i].bFlashEnabled, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("FlashType", ENUM_TO_INT(thisSwitchCam.nodes[i].SCFE_FlashEffectUsed), 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("FlashNodePhaseOffset", thisSwitchCam.nodes[i].fFlashNodePhaseOffset, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("FlashMinExposure", thisSwitchCam.nodes[i].fMinExposure, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("FlashMaxExposure", thisSwitchCam.nodes[i].fMaxExposure, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("FlashRampUpDur", thisSwitchCam.nodes[i].iRampUpDuration, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("FlashRampDownDur", thisSwitchCam.nodes[i].iRampDownDuration, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("FlashHoldDur", thisSwitchCam.nodes[i].iHoldDuration, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("IsJumpCut", thisSwitchCam.nodes[i].bIsCamCutNode, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("IsLowDetailNode", thisSwitchCam.nodes[i].bIsLowDetailNode, 3, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("UseCustomDOF", thisSwitchCam.nodes[i].bUseCustomDOF, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("DOF_NearDOF", thisSwitchCam.nodes[i].NodeDOF_Info.fDOF_NearDOF, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("DOF_FarDOF", thisSwitchCam.nodes[i].NodeDOF_Info.fDOF_FarDOF, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("DOF_EffectStrength", thisSwitchCam.nodes[i].NodeDOF_Info.fDOF_EffectStrength, 3, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("NodeToClone", thisSwitchCam.nodes[i].iNodeToClone, 3, strPath, strFileName)
SAVE_VECTOR_VALUE_XML_TAG("ClonedNodeOffset", thisSwitchCam.nodes[i].vClonedNodeOffset, 3, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(" </Node>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDREPEAT
SAVE_STRING_TO_NAMED_DEBUG_FILE(" </SwitchNodes>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(" <VelocityOverride>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
REPEAT MAX_NUM_CAM_VELOCITY_OVERRIDES i
SAVE_STRING_TO_NAMED_DEBUG_FILE(" <VelNode>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("VelIndex", i, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("VelStartPoint", thisSwitchCam.camVelocityOverrides[i].fStartPoint, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("VelSpeed", thisSwitchCam.camVelocityOverrides[i].fSpeed, 3, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(" </VelNode>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDREPEAT
SAVE_STRING_TO_NAMED_DEBUG_FILE(" </VelocityOverride>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(" <BlurOverride>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
REPEAT MAX_NUM_CAM_VELOCITY_OVERRIDES i
SAVE_STRING_TO_NAMED_DEBUG_FILE(" <BlurNode>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("BlurIndex", i, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("BlurStartPoint", thisSwitchCam.camBlurOverrides[i].fBlurOverrideStartPoint, 3, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("BlurLevel", thisSwitchCam.camBlurOverrides[i].fBlurOverrideBlurLevel, 3, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE(" </BlurNode>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
ENDREPEAT
SAVE_STRING_TO_NAMED_DEBUG_FILE(" </BlurOverride>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("NumNodes", thisSwitchCam.iNumNodes, 1, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("SwitchFocusNode", thisSwitchCam.iCamSwitchFocusNode, 1, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("SwitchSoundAudioStartPhase", thisSwitchCam.fSwitchSoundAudioStartPhase, 1, strPath, strFileName)
SAVE_FLOAT_VALUE_XML_TAG("SwitchSoundAudioEndPhase", thisSwitchCam.fSwitchSoundAudioEndPhase, 1, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("SwitchSoundAudioPlayStartPulse", thisSwitchCam.bSwitchSoundPlayOpeningPulse, 1, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("SwitchSoundAudioPlayMoveLoop", thisSwitchCam.bSwitchSoundPlayMoveLoop, 1, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("SwitchSoundAudioPlayEndPulse", thisSwitchCam.bSwitchSoundPlayExitPulse, 1, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("SplineNoSmoothing", thisSwitchCam.bSplineNoSmoothing, 1, strPath, strFileName)
SAVE_BOOL_VALUE_XML_TAG("AddGameplayCamAsLastNode", thisSwitchCam.bAddGameplayCamAsLastNode, 1, strPath, strFileName)
SAVE_INT_VALUE_XML_TAG("GameplayNodeBlendDur", thisSwitchCam.iGameplayNodeBlendDuration, 1, strPath, strFileName)
SAVE_STRING_TO_NAMED_DEBUG_FILE("</CustomCamData>", strPath, strFileName)
SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(strPath, strFileName)
CLOSE_DEBUG_FILE()
ENDPROC
/// PURPOSE:
/// Load in the data from an .xml to the switch cam struct.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to populate with the .xml data.
PROC LOAD_SPLINE_CAM_DATA_FROM_XML(SWITCH_CAM_STRUCT &thisSwitchCam)
CDEBUG3LN(DEBUG_MISSION, "LOAD_SPLINE_CAM_DATA_FROM_XML")
//X:\gta5\build\dev\common\data\script\xml\...
//strFileName = "playerswitchestablishingshots.xml"
STRING strFileName = thisSwitchCam.strXMLFileName
IF IS_STRING_NULL_OR_EMPTY(strFileName)
TEXT_LABEL_63 txtAssert
txtAssert += strFileName
txtAssert += " file name is empty!!!"
SCRIPT_ASSERT(txtAssert)
EXIT
ENDIF
CDEBUG3LN(DEBUG_MISSION, "Loading XML file...")
IF LOAD_XML_FILE(strFileName)
INT iNumNodes
TEXT_LABEL_63 txtNodeName
iNumNodes = GET_NUMBER_OF_XML_NODES()
CDEBUG3LN(DEBUG_MISSION, "Number of Nodes: ", iNumNodes)
INT iIndex = 0
INT iVelIndex = 0
INT iBlurIndex = 0
INT i
REPEAT iNumNodes i
txtNodeName = GET_XML_NODE_NAME()
SWITCH GET_HASH_KEY(txtNodeName)
CASE HASH("Node")
iIndex = 0
BREAK
CASE HASH("Index")
iIndex = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("SwitchCamType")
thisSwitchCam.nodes[iIndex].iSwitchCamTypeDebugSelect = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
thisSwitchCam.nodes[iIndex].SwitchCamType = INT_TO_ENUM(SWITCH_CAM_TYPE, thisSwitchCam.nodes[iIndex].iSwitchCamTypeDebugSelect)
BREAK
CASE HASH("ForceCamPointAtEntityIndex")
thisSwitchCam.nodes[iIndex].iForceCamPointAtEntityIndex = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("Time")
thisSwitchCam.nodes[iIndex].iNodeTime = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("IsGameplayCamCopy")
thisSwitchCam.nodes[iIndex].bIsGameplayCamCopy = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("Position")
thisSwitchCam.nodes[iIndex].vNodePos.x = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
thisSwitchCam.nodes[iIndex].vNodePos.y = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(1)
thisSwitchCam.nodes[iIndex].vNodePos.z = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(2)
BREAK
CASE HASH("Direction")
thisSwitchCam.nodes[iIndex].vNodeDir.x = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
thisSwitchCam.nodes[iIndex].vNodeDir.y = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(1)
thisSwitchCam.nodes[iIndex].vNodeDir.z = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(2)
BREAK
CASE HASH("WorldCamLookAtCoord")
thisSwitchCam.nodes[iIndex].vWorldPosLookAt.x = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
thisSwitchCam.nodes[iIndex].vWorldPosLookAt.y = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(1)
thisSwitchCam.nodes[iIndex].vWorldPosLookAt.z = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(2)
BREAK
CASE HASH("WorldCamLookAtOffset")
thisSwitchCam.nodes[iIndex].fNodeOffsetDist = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("NodeVerticleOffset")
thisSwitchCam.nodes[iIndex].fNodeVerticleOffset = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("AttachToOriginPed")
thisSwitchCam.nodes[iIndex].bAttachToOriginPed = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("PointAtEntity")
thisSwitchCam.nodes[iIndex].bPointAtEntity = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("PointAtOffsetIsRelative")
thisSwitchCam.nodes[iIndex].bPointAtOffsetIsRelative = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("AttachOffsetIsRelative")
thisSwitchCam.nodes[iIndex].bAttachOffsetIsRelative = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("FOV")
thisSwitchCam.nodes[iIndex].fNodeFOV = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("TimePostFXType")
thisSwitchCam.nodes[iIndex].iNodeTimePostFX_WidgetValue = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
thisSwitchCam.nodes[iIndex].NodeTimePostFX_Type = INT_TO_ENUM(SWITCH_CAM_POST_FX_TYPE, thisSwitchCam.nodes[iIndex].iNodeTimePostFX_WidgetValue)
BREAK
CASE HASH("PostFXBlendTime")
thisSwitchCam.nodes[iIndex].fNodeTimePostFXBlendTime = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("PostFXNodeStartOffset")
thisSwitchCam.nodes[iIndex].fNodeTimePostFXTimeOffset = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("MotionBlur")
thisSwitchCam.nodes[iIndex].fNodeMotionBlur = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("CamShakeType")
thisSwitchCam.nodes[iIndex].iNodeCamShakeType_WidgetValue = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
thisSwitchCam.nodes[iIndex].NodeCamShakeType = INT_TO_ENUM(SWITCH_CAM_SHAKE_TYPE, thisSwitchCam.nodes[iIndex].iNodeCamShakeType_WidgetValue)
BREAK
CASE HASH("CamShake")
thisSwitchCam.nodes[iIndex].fNodeCamShake = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("CamEaseType")
thisSwitchCam.nodes[iIndex].iCamEaseType = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("CamEaseScaler")
thisSwitchCam.nodes[iIndex].fCamEaseScaler = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("CamNodeVelocityScale")
thisSwitchCam.nodes[iIndex].fCamNodeVelocityScale = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("CamEaseForceLinear")
thisSwitchCam.nodes[iIndex].bCamEaseForceLinear = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("CamEaseForceLevel")
thisSwitchCam.nodes[iIndex].bCamEaseForceLevel = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("TimeScale")
thisSwitchCam.nodes[iIndex].fTimeScale = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("TimeScaleEaseType")
thisSwitchCam.nodes[iIndex].iTimeScaleEaseType = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("TimeScaleEaseScaler")
thisSwitchCam.nodes[iIndex].fTimeScaleEaseScaler = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("FlashEnabled")
thisSwitchCam.nodes[iIndex].bFlashEnabled = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("FlashType")
thisSwitchCam.nodes[iIndex].iFlashEffectUsed_WidgetValue = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
thisSwitchCam.nodes[iIndex].SCFE_FlashEffectUsed = INT_TO_ENUM(SWITCH_CAM_FLASH_EFFECT, thisSwitchCam.nodes[iIndex].iFlashEffectUsed_WidgetValue)
BREAK
CASE HASH("FlashNodePhaseOffset")
thisSwitchCam.nodes[iIndex].fFlashNodePhaseOffset = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("FlashMinExposure")
thisSwitchCam.nodes[iIndex].fMinExposure = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("FlashMaxExposure")
thisSwitchCam.nodes[iIndex].fMaxExposure = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("FlashRampUpDur")
thisSwitchCam.nodes[iIndex].iRampUpDuration = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("FlashRampDownDur")
thisSwitchCam.nodes[iIndex].iRampDownDuration = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("FlashHoldDur")
thisSwitchCam.nodes[iIndex].iHoldDuration = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("IsJumpCut")
thisSwitchCam.nodes[iIndex].bIsCamCutNode = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("IsLowDetailNode")
thisSwitchCam.nodes[iIndex].bIsLowDetailNode = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("NumNodes")
thisSwitchCam.iNumNodes = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("SwitchFocusNode")
thisSwitchCam.iCamSwitchFocusNode = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("SplineNoSmoothing")
thisSwitchCam.bSplineNoSmoothing = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("AddGameplayCamAsLastNode")
CASE HASH("SplineLastFrameUseGamePlay")
thisSwitchCam.bAddGameplayCamAsLastNode = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("GameplayNodeBlendDur")
CASE HASH("LastNodeTime")
thisSwitchCam.iGameplayNodeBlendDuration = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("UseCustomDOF")
thisSwitchCam.nodes[iIndex].bUseCustomDOF = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("DOF_NearDOF")
thisSwitchCam.nodes[iIndex].NodeDOF_Info.fDOF_NearDOF = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("DOF_FarDOF")
thisSwitchCam.nodes[iIndex].NodeDOF_Info.fDOF_FarDOF = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("DOF_EffectStrength")
thisSwitchCam.nodes[iIndex].NodeDOF_Info.fDOF_EffectStrength = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("ClonedNodeOffset")
thisSwitchCam.nodes[iIndex].vClonedNodeOffset.x = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
thisSwitchCam.nodes[iIndex].vClonedNodeOffset.y = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(1)
thisSwitchCam.nodes[iIndex].vClonedNodeOffset.z = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(2)
BREAK
CASE HASH("NodeToClone")
thisSwitchCam.nodes[iIndex].iNodeToClone = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("VelNode")
iVelIndex = 0
BREAK
CASE HASH("VelIndex")
iVelIndex = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("VelStartPoint")
thisSwitchCam.camVelocityOverrides[iVelIndex].fStartPoint = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("VelSpeed")
thisSwitchCam.camVelocityOverrides[iVelIndex].fSpeed = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("BlurNode")
iBlurIndex = 0
BREAK
CASE HASH("BlurIndex")
iBlurIndex = GET_INT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("BlurStartPoint")
thisSwitchCam.camBlurOverrides[iBlurIndex].fBlurOverrideStartPoint = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("BlurLevel")
thisSwitchCam.camBlurOverrides[iBlurIndex].fBlurOverrideBlurLevel = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("SwitchSoundAudioEndPhase")
thisSwitchCam.fSwitchSoundAudioEndPhase = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("SwitchSoundAudioStartPhase")
thisSwitchCam.fSwitchSoundAudioStartPhase = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("SwitchSoundAudioPlayStartPulse")
thisSwitchCam.bSwitchSoundPlayOpeningPulse = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("SwitchSoundAudioPlayMoveLoop")
thisSwitchCam.bSwitchSoundPlayMoveLoop = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
CASE HASH("SwitchSoundAudioPlayEndPulse")
thisSwitchCam.bSwitchSoundPlayExitPulse = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(0)
BREAK
ENDSWITCH
GET_NEXT_XML_NODE()
ENDREPEAT
DELETE_XML_FILE()
ELSE
CDEBUG3LN(DEBUG_MISSION, strFileName, " Could not be found!")
ENDIF
ENDPROC
#ENDIF
/// PURPOSE:
/// Have this node copy the settings of the node after it and make it's time 0, thus causing the spline to appear to 'jump cut' to this node.
/// PARAMS:
/// thisSwitchCam - Camera spline to apply the cut node to
/// iNodeToMakeCutNode - Node on switch cam spline to set as cut node.
PROC SET_NODE_AS_CUT_NODE(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeToMakeCutNode)
IF iNodeToMakeCutNode < thisSwitchCam.iNumNodes - 1
thisSwitchCam.nodes[iNodeToMakeCutNode].iNodeTime = 0
thisSwitchCam.nodes[iNodeToMakeCutNode].vNodePos = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].vNodePos
thisSwitchCam.nodes[iNodeToMakeCutNode].vNodeDir = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].vNodeDir
thisSwitchCam.nodes[iNodeToMakeCutNode].bPointAtEntity = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].bPointAtEntity
thisSwitchCam.nodes[iNodeToMakeCutNode].fNodeFOV = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].fNodeFOV
thisSwitchCam.nodes[iNodeToMakeCutNode].fNodeMotionBlur = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].fNodeMotionBlur
thisSwitchCam.nodes[iNodeToMakeCutNode].fNodeCamShake = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].fNodeCamShake
thisSwitchCam.nodes[iNodeToMakeCutNode].iCamEaseType = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].iCamEaseType
thisSwitchCam.nodes[iNodeToMakeCutNode].fCamEaseScaler = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].fCamEaseScaler
thisSwitchCam.nodes[iNodeToMakeCutNode].bCamEaseForceLinear = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].bCamEaseForceLinear
thisSwitchCam.nodes[iNodeToMakeCutNode].bCamEaseForceLevel = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].bCamEaseForceLevel
thisSwitchCam.nodes[iNodeToMakeCutNode].fTimeScale = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].fTimeScale
thisSwitchCam.nodes[iNodeToMakeCutNode].iTimeScaleEaseType = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].iTimeScaleEaseType
thisSwitchCam.nodes[iNodeToMakeCutNode].fTimeScaleEaseScaler = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].fTimeScaleEaseScaler
thisSwitchCam.nodes[iNodeToMakeCutNode].bFlashEnabled = FALSE
thisSwitchCam.nodes[iNodeToMakeCutNode].fMinExposure = 0.0000
thisSwitchCam.nodes[iNodeToMakeCutNode].fMaxExposure = 0.0000
thisSwitchCam.nodes[iNodeToMakeCutNode].iRampUpDuration = 0
thisSwitchCam.nodes[iNodeToMakeCutNode].iRampDownDuration = 0
thisSwitchCam.nodes[iNodeToMakeCutNode].iHoldDuration = 0
thisSwitchCam.nodes[iNodeToMakeCutNode].bUseCustomDOF = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].bUseCustomDOF
thisSwitchCam.nodes[iNodeToMakeCutNode].bIsGameplayCamCopy = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].bIsGameplayCamCopy
thisSwitchCam.nodes[iNodeToMakeCutNode].fNodeOffsetDist = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].fNodeOffsetDist
thisSwitchCam.nodes[iNodeToMakeCutNode].vWorldPosLookAt = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].vWorldPosLookAt
thisSwitchCam.nodes[iNodeToMakeCutNode].bPointAtOffsetIsRelative = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].bPointAtOffsetIsRelative
thisSwitchCam.nodes[iNodeToMakeCutNode].bAttachOffsetIsRelative = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].bAttachOffsetIsRelative
thisSwitchCam.nodes[iNodeToMakeCutNode].NodeTimePostFX_Type = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].NodeTimePostFX_Type
thisSwitchCam.nodes[iNodeToMakeCutNode].bIsLowDetailNode = thisSwitchCam.nodes[iNodeToMakeCutNode + 1].bIsLowDetailNode
ENDIF
ENDPROC
func float magnitude_of_vector(vector &vec)
return sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z)
endfunc
FUNC VECTOR GET_VECTOR_FROM_DIRECTION_AND_MAGNITUDE(VECTOR v, FLOAT m)
VECTOR n = NORMALISE_VECTOR(v)
n.x = n.x * m
n.y = n.y * m
n.z = n.z * m
RETURN n
ENDFUNC
/// PURPOSE:
/// Returns the location of the switch cam look at target for the indicated target index
/// PARAMS:
/// thisSwitchCam - Switch cam to get the target entity coord ah
/// iTargetIndex - Target Index to get coords of (0 or 1)
/// RETURNS:
/// Vector position of the entity at the indicated target index
FUNC VECTOR GET_POSITION_OF_SWITCH_CAM_TARGET_ENTITY(SWITCH_CAM_STRUCT &thisSwitchCam, INT iTargetIndex)
IF iTargetIndex < NUM_SWITCH_ENTITIES
//[MF] Check if the target is a vehicle
IF DOES_ENTITY_EXIST(thisSwitchCam.viVehicles[iTargetIndex])
RETURN GET_ENTITY_COORDS(thisSwitchCam.viVehicles[iTargetIndex])
ENDIF
//[MF] Check if the target is ped
IF DOES_ENTITY_EXIST(thisSwitchCam.piPeds[iTargetIndex])
RETURN GET_ENTITY_COORDS(thisSwitchCam.piPeds[iTargetIndex])
ENDIF
ENDIF
SCRIPT_ASSERT("GET_POSITION_OF_WORLD_CAM_WITH_ENTITY_LOOK_AT_TARGET - Switch cam Struct Not Properly Initialized or iTargetIndex is invalid. No target ped has been designated to point cam at!")
RETURN <<0.0, 0.0, 0.0>>
ENDFUNC
/// PURPOSE:
/// Copy the current gameplay cam info to a Switch Cam Struct. This creates a switch cam spline node that is effectively a carbon copy of the gameplay cam, however is more stable on fast moving vehicles.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to create the gameplay cam clone in
/// index - Node of switch cam struct to copy info to
PROC CLONE_GAMEPLAY_CAM_TO_SWITCH_CAM_STRUCT_NODE(SWITCH_CAM_STRUCT &thisSwitchCam, INT index)
thisSwitchCam.nodes[index].vNodePos = GET_GAMEPLAY_CAM_COORD()
thisSwitchCam.nodes[index].vNodeDir = GET_GAMEPLAY_CAM_ROT()
thisSwitchCam.nodes[index].fNodeFov = GET_GAMEPLAY_CAM_FOV()
ENDPROC
/// PURPOSE:
/// Checks if we are in an instance where it is better to clone the gameplay cam instead of natively use it for the spline.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to process
/// index - Index of the spline cam node to check if we should clone it
/// RETURNS:
/// FALSE if it is better to use a native copy of the gameplay cam in the spline. TRUE if it's better for us to use a clone.
FUNC BOOL DO_WE_WANT_TO_CLONE_GAMEPLAY_CAM(SWITCH_CAM_STRUCT &thisSwitchCam, INT index)
//[SP] super hack for using the real gameplay cam as the first node... as seen in jewelryheist.sc
// This is done by making the first [0] and second [1] node of a spline cam to be type SWITCH_CAM_GAMEPLAY_CAM_COPY both with nodetime = 0
// Using just SWITCH_CAM_GAMEPLAY_CAM_COPY makes an actual copy (pos/dir) instead of using the dynamic values of a gameplay cam.
//[MF] We only want to clone the gameplay cam if the first node of the switch cam is a gameplay cam copy and it is NOT followed by another gameplay cam copy.
// Otherwise it's better to just use a native gameplay cam in the spline.
IF index = 0
IF (thisSwitchCam.nodes[index].SwitchCamType = SWITCH_CAM_GAMEPLAY_CAM_COPY OR thisSwitchCam.nodes[index].bIsGameplayCamCopy)
AND (thisSwitchCam.nodes[index + 1].SwitchCamType != SWITCH_CAM_GAMEPLAY_CAM_COPY AND thisSwitchCam.nodes[index + 1].bIsGameplayCamCopy = FALSE)
RETURN TRUE
ENDIF
ENDIF
IF index = 1
IF (thisSwitchCam.nodes[index].SwitchCamType = SWITCH_CAM_GAMEPLAY_CAM_COPY OR thisSwitchCam.nodes[index].bIsGameplayCamCopy)
AND (thisSwitchCam.nodes[index - 1].SwitchCamType != SWITCH_CAM_GAMEPLAY_CAM_COPY AND thisSwitchCam.nodes[index - 1].bIsGameplayCamCopy = FALSE)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Sets a spline cam node to copy the gameplay cam and then attaches that to the spline node's focus entity. This is useful for instances where a native gameplay cam clone can cause pops, usually occurs on fast moving vehicles.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to create the gameplay cam copy in
/// index - Index of the switch cam to set as a gameplay cam clone.
PROC ATTACH_GAMEPLAY_CAM_CLONE_TO_ENTITY(SWITCH_CAM_STRUCT &thisSwitchCam, INT index)
ATTACH_CAM_TO_ENTITY(thisSwitchCam.nodes[index].ciSwitchNode, GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, index), GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, index), GET_GAMEPLAY_CAM_COORD()))
ENDPROC
/// PURPOSE:
/// Check if we should attach the spline cam to it's a target entity based on the node properies
/// PARAMS:
/// thisSwitchCam - Switch cam struct to check
/// iNodeIndex - Node of Switch Cam Struct to check
/// RETURNS:
/// TRUE if the cam should be attached to an entity. FALSE otherwise (eg, gameplay cam copy, world pos cam, certain cut cams).
FUNC BOOL DO_WE_WANT_TO_ATTACH_CAM_TO_ENTITY(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
BOOL bWantToAttach = FALSE
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_OLD_SYSTEM
bWantToAttach = TRUE
ENDIF
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_ENTITY_ATTACHED_CAM
// OR thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_ENTITY_ATTACHED_W_WORLD_LOOK_AT
bWantToAttach = TRUE
ENDIF
IF thisSwitchCam.nodes[iNodeIndex].bIsGameplayCamCopy
OR thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_GAMEPLAY_CAM_COPY
bWantToAttach = FALSE
ENDIF
//[MF] Handle Cloned Node With Offset camera type
IF iNodeIndex > 0
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_CLONE_NODE_WITH_OFFSET
IF thisSwitchCam.nodes[thisSwitchCam.nodes[iNodeIndex].iNodeToClone].SwitchCamType = SWITCH_CAM_OLD_SYSTEM
bWantToAttach = TRUE
ENDIF
IF thisSwitchCam.nodes[thisSwitchCam.nodes[iNodeIndex].iNodeToClone].SwitchCamType = SWITCH_ENTITY_ATTACHED_CAM
// OR thisSwitchCam.nodes[thisSwitchCam.nodes[iNodeIndex].iNodeToClone].SwitchCamType = SWITCH_CAM_ENTITY_ATTACHED_W_WORLD_LOOK_AT
bWantToAttach = TRUE
ENDIF
IF thisSwitchCam.nodes[thisSwitchCam.nodes[iNodeIndex].iNodeToClone].bIsGameplayCamCopy
OR thisSwitchCam.nodes[thisSwitchCam.nodes[iNodeIndex].iNodeToClone].SwitchCamType = SWITCH_CAM_GAMEPLAY_CAM_COPY
bWantToAttach = FALSE
ENDIF
ENDIF
ENDIF
//[MF] TODO: Figure out how to go from a cut cam to a gameplay copy cam
//[MF]We don't want to attach the cam if we're going from a cut cam to a non-attached cam type.
IF iNodeIndex < (thisSwitchCam.iNumNodes - 1)
IF thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode
IF thisSwitchCam.nodes[iNodeIndex + 1].SwitchCamType = SWITCH_CAM_GAMEPLAY_CAM_COPY
OR thisSwitchCam.nodes[iNodeIndex + 1].bIsGameplayCamCopy
OR thisSwitchCam.nodes[iNodeIndex + 1].SwitchCamType = SWITCH_CAM_WORLD_POS
OR thisSwitchCam.nodes[iNodeIndex + 1].SwitchCamType = SWITCH_CAM_WORLD_POS_W_LOOK_AT
OR thisSwitchCam.nodes[iNodeIndex + 1].SwitchCamType = SWITCH_CAM_PATH_RELATIVE
OR thisSwitchCam.nodes[iNodeIndex + 1].SwitchCamType = SWITCH_CAM_PATH_RELATIVE_ATTACHED
bWantToAttach = FALSE
ENDIF
ENDIF
ENDIF
RETURN bWantToAttach
ENDFUNC
/// PURPOSE:
/// Set the Depth Of Field stats for a camera node
/// PARAMS:
/// thisSwitchCam - Switch cam Struct to get DOF settings from
/// index - Node index to apply the settings to
PROC P_UPDATE_NODE_DOF(SWITCH_CAM_STRUCT &thisSwitchCam, INT index)
SET_CAM_NEAR_DOF(thisSwitchCam.nodes[index].ciSwitchNode, thisSwitchCam.nodes[index].NodeDOF_Info.fDOF_NearDOF)
SET_CAM_FAR_DOF(thisSwitchCam.nodes[index].ciSwitchNode, thisSwitchCam.nodes[index].NodeDOF_Info.fDOF_FarDOF)
SET_CAM_DOF_STRENGTH(thisSwitchCam.nodes[index].ciSwitchNode, thisSwitchCam.nodes[index].NodeDOF_Info.fDOF_EffectStrength)
ENDPROC
/// PURPOSE:
/// Setup the position and rotation data for a CLONE_PREVIOUS_WITH_OFFSET switch cam node type
/// PARAMS:
/// thisSwitchCam -
/// iNodeIndex -
PROC SETUP_CAM_NODE_POSITION_TYPE_CLONE_NODE_WITH_OFFSET(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
IF iNodeIndex = 0
SCRIPT_ASSERT("Cannot use Node Type CLONE PREVIOUS WITH OFFSET on first node of spline cam! No previous node to copy data from.")
EXIT
ENDIF
INT iNodeToCloneFrom = thisSwitchCam.nodes[iNodeIndex].iNodeToClone
IF thisSwitchCam.nodes[iNodeToCloneFrom].bIsGameplayCamCopy
OR thisSwitchCam.nodes[iNodeToCloneFrom].SwitchCamType = SWITCH_CAM_GAMEPLAY_CAM_COPY
thisSwitchCam.nodes[iNodeIndex].vNodePos = GET_GAMEPLAY_CAM_COORD() + thisSwitchCam.nodes[iNodeIndex].vClonedNodeOffset
thisSwitchCam.nodes[iNodeIndex].vNodeDir = GET_GAMEPLAY_CAM_ROT()
ELSE
thisSwitchCam.nodes[iNodeIndex].vNodePos = thisSwitchCam.nodes[iNodeToCloneFrom].vNodePos + thisSwitchCam.nodes[iNodeIndex].vClonedNodeOffset
thisSwitchCam.nodes[iNodeIndex].vNodeDir = thisSwitchCam.nodes[iNodeToCloneFrom].vNodeDir
ENDIF
thisSwitchCam.nodes[iNodeIndex].fNodeFOV = thisSwitchCam.nodes[iNodeToCloneFrom].fNodeFOV
IF thisSwitchCam.nodes[iNodeIndex].fNodeFOV = 0.0
thisSwitchCam.nodes[iNodeIndex].fNodeFOV = GET_GAMEPLAY_CAM_FOV()
ENDIF
thisSwitchCam.nodes[iNodeIndex].bPointAtEntity = thisSwitchCam.nodes[iNodeToCloneFrom].bPointAtEntity
thisSwitchCam.nodes[iNodeIndex].fNodeOffsetDist = thisSwitchCam.nodes[iNodeToCloneFrom].fNodeOffsetDist
thisSwitchCam.nodes[iNodeIndex].vWorldPosLookAt = thisSwitchCam.nodes[iNodeToCloneFrom].vWorldPosLookAt
thisSwitchCam.nodes[iNodeIndex].bPointAtOffsetIsRelative = thisSwitchCam.nodes[iNodeToCloneFrom].bPointAtOffsetIsRelative
thisSwitchCam.nodes[iNodeIndex].bAttachOffsetIsRelative = thisSwitchCam.nodes[iNodeToCloneFrom].bAttachOffsetIsRelative
ENDPROC
/// PURPOSE:
/// Create a specific node for a switch cam spline.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to create the node from
/// iNodeIndex - Index of the node to create
PROC BUILD_SWITCH_CAM_NODE(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
CDEBUG3LN(DEBUG_MISSION, "BUILD_SWITCH_CAM_NODE - START - Index: ", iNodeIndex)
//[MF] if our first node is a gameplay copy node, create a copy of the gameplay cam that we'll render instead of using the actual gameplay cam.
//This resolves popping issues on small splines of < 3 nodes
IF DO_WE_WANT_TO_CLONE_GAMEPLAY_CAM(thisSwitchCam, iNodeIndex)
CLONE_GAMEPLAY_CAM_TO_SWITCH_CAM_STRUCT_NODE(thisSwitchCam, iNodeIndex)
ENDIF
FLOAT fFOV
IF thisSwitchCam.nodes[iNodeIndex].fNodeFOV = 0.0
fFOV = GET_GAMEPLAY_CAM_FOV()
ELSE
fFOV = thisSwitchCam.nodes[iNodeIndex].fNodeFOV
ENDIF
IF IS_NODE_JUMP_CUT(thisSwitchCam, iNodeIndex)
SET_NODE_AS_CUT_NODE(thisSwitchCam, iNodeIndex)
//[MF] Ensure that the last node can't be a jump cut node.
IF iNodeIndex = thisSwitchCam.iNumNodes - 1
thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode = FALSE
ENDIF
ENDIF
IF iNodeIndex = thisSwitchCam.iNumNodes - 1
thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode = FALSE
ENDIF
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_WORLD_POS_W_LOOK_AT
VECTOR vLookatCoords
IF thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex > -1
vLookatCoords = GET_POSITION_OF_SWITCH_CAM_TARGET_ENTITY(thisSwitchCam, thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex)
ELSE
vLookatCoords = thisSwitchCam.nodes[iNodeIndex].vWorldPosLookAt
ENDIF
VECTOR vStartingObserverLoc
IF iNodeIndex = 0
OR iNodeIndex >0 AND thisSwitchCam.nodes[iNodeIndex - 1].bIsGameplayCamCopy
OR iNodeIndex >0 AND thisSwitchCam.nodes[iNodeIndex - 1].SwitchCamType = SWITCH_CAM_GAMEPLAY_CAM_COPY
vStartingObserverLoc = GET_GAMEPLAY_CAM_COORD()
ELSE
vStartingObserverLoc = thisSwitchCam.nodes[iNodeIndex - 1].vNodePos
IF DO_WE_WANT_TO_ATTACH_CAM_TO_ENTITY(thisSwitchCam, iNodeIndex - 1)
VECTOR vEntityForward, vEntityRight, vEntityUp, vEntityPosition
GET_ENTITY_MATRIX(GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex - 1), vEntityForward, vEntityRight, vEntityUp, vEntityPosition)
IF thisSwitchCam.nodes[iNodeIndex].bAttachOffsetIsRelative
vStartingObserverLoc = vEntityPosition + (vEntityForward * thisSwitchCam.nodes[iNodeIndex - 1].vNodePos.y)
+ (vEntityRight * thisSwitchCam.nodes[iNodeIndex - 1].vNodePos.x)
+ (vEntityUp * thisSwitchCam.nodes[iNodeIndex - 1].vNodePos.z)
ELSE
vStartingObserverLoc = vEntityPosition + thisSwitchCam.nodes[iNodeIndex - 1].vNodePos
ENDIF
ENDIF
ENDIF
VECTOR vTargetDirection = vLookatCoords - vStartingObserverLoc
FLOAT fDistToTarget = (VMAG(vTargetDirection) - thisSwitchCam.nodes[iNodeIndex].fNodeOffsetDist)
vTargetDirection = NORMALISE_VECTOR(vTargetDirection)
vTargetDirection *= fDistToTarget
thisSwitchCam.nodes[iNodeIndex].vNodePos = vStartingObserverLoc + vTargetDirection
IF thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex > -1
thisSwitchCam.nodes[iNodeIndex].vWorldPosLookAt = vLookatCoords
ENDIF
ELIF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_PATH_RELATIVE
OR thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_PATH_RELATIVE_ATTACHED
VECTOR vTargetPosition = <<0.0, 0.0, 0.0>>
IF DOES_ENTITY_EXIST(GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, thisSwitchCam.iCamSwitchFocusNode))
IF thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex > -1
vTargetPosition = GET_POSITION_OF_SWITCH_CAM_TARGET_ENTITY(thisSwitchCam, thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex)
ELSE
vTargetPosition = GET_ENTITY_COORDS(GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, thisSwitchCam.iCamSwitchFocusNode))
ENDIF
ENDIF
VECTOR vGameCamRot = GET_GAMEPLAY_CAM_ROT()
VECTOR vGameCamPosition = GET_GAMEPLAY_CAM_COORD()
VECTOR vGameCamForward = vTargetPosition - vGameCamPosition
FLOAT fCameraOffset = 0.0
IF iNodeIndex < thisSwitchCam.iCamSwitchFocusNode
OR thisSwitchCam.iCamSwitchFocusNode = 0
fCameraOffset = thisSwitchCam.nodes[iNodeIndex].fNodeOffsetDist
ENDIF
FLOAT fDistanceToTarget = VMAG(vGameCamForward) - fCameraOffset
vGameCamForward = CONVERT_EULER_TO_DIRECTION_VECTOR(vGameCamRot)
vGameCamPosition = vGameCamPosition + (vGameCamForward * fCameraOffset) // offset forward by NodeOffsetDist
IF iNodeIndex < thisSwitchCam.iCamSwitchFocusNode
// For initial nodes, camera is game camera plus offset along game camera forward.
thisSwitchCam.nodes[iNodeIndex].vNodePos = vGameCamPosition
ELSE
// For ending nodes, camera is game camera + ((distance to target minus offset) along camera forward)
thisSwitchCam.nodes[iNodeIndex].vNodePos = vGameCamPosition
+ (vGameCamForward * (fDistanceToTarget - thisSwitchCam.nodes[iNodeIndex].fNodeOffsetDist))
ENDIF
thisSwitchCam.nodes[iNodeIndex].vNodeDir = vGameCamRot
ELIF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_PATH_RELATIVE_PED_TO_WORLD_COORD
VECTOR vTargetPosition = thisSwitchCam.nodes[iNodeIndex].vWorldPosLookAt
VECTOR vOriginPedPosition = GET_ENTITY_COORDS(GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex))
VECTOR vOriginPedForward = vTargetPosition - vOriginPedPosition
FLOAT fCameraOffset = 0.0
fCameraOffset = thisSwitchCam.nodes[iNodeIndex].fNodeOffsetDist
vOriginPedForward = NORMALISE_VECTOR(vOriginPedForward)
VECTOR vCamLocation
vCamLocation = vOriginPedPosition + (vOriginPedForward * fCameraOffset)
vCamLocation.z += thisSwitchCam.nodes[iNodeIndex].fNodeVerticleOffset
thisSwitchCam.nodes[iNodeIndex].vNodePos = vCamLocation
ENDIF
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_CLONE_NODE_WITH_OFFSET
SETUP_CAM_NODE_POSITION_TYPE_CLONE_NODE_WITH_OFFSET(thisSwitchCam, iNodeIndex)
fFOV = thisSwitchCam.nodes[iNodeIndex].fNodeFOV
ENDIF
//[MF] Create the node
thisSwitchCam.nodes[iNodeIndex].ciSwitchNode = CREATE_CAMERA_WITH_PARAMS(CAMTYPE_SCRIPTED, thisSwitchCam.nodes[iNodeIndex].vNodePos, thisSwitchCam.nodes[iNodeIndex].vNodeDir, fFOV, TRUE)
CAMERA_INDEX ciSwitchCamNodeIndex
ciSwitchCamNodeIndex = thisSwitchCam.nodes[iNodeIndex].ciSwitchNode
IF DOES_CAM_EXIST(thisSwitchCam.nodes[iNodeIndex].ciSwitchNode)
SET_CAM_MOTION_BLUR_STRENGTH(ciSwitchCamNodeIndex, thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur)
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_WORLD_POS_W_LOOK_AT
POINT_CAM_AT_COORD(ciSwitchCamNodeIndex, thisSwitchCam.nodes[iNodeIndex].vWorldPosLookAt)
ENDIF
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_WORLD_POS
AND thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex > -1
POINT_CAM_AT_ENTITY(ciSwitchCamNodeIndex, GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex, thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex), thisSwitchCam.nodes[iNodeIndex].vNodeDir, thisSwitchCam.nodes[iNodeIndex].bPointAtOffsetIsRelative)
ENDIF
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_PATH_RELATIVE_ATTACHED
IF thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex > -1
PRINTLN("Attaching Cam Path Relative Attached cam to forced look-at entity")
ATTACH_CAM_TO_ENTITY(ciSwitchCamNodeIndex, GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex, thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex), thisSwitchCam.nodes[iNodeIndex].vNodePos - GET_POSITION_OF_SWITCH_CAM_TARGET_ENTITY(thisSwitchCam, thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex) + thisSwitchCam.nodes[iNodeIndex].vClonedNodeOffset, FALSE)
ELSE
PRINTLN("Attaching Cam Path Relative Attached cam to default entity")
ATTACH_CAM_TO_ENTITY(ciSwitchCamNodeIndex, GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex), thisSwitchCam.nodes[iNodeIndex].vNodeDir, FALSE)
ENDIF
ENDIF
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_PATH_RELATIVE_PED_TO_WORLD_COORD
IF thisSwitchCam.nodes[iNodeIndex].bAttachToOriginPed
PRINTLN("Attaching Cam Path Relative Attached cam to default entity")
ATTACH_CAM_TO_ENTITY(ciSwitchCamNodeIndex, GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex), thisSwitchCam.nodes[iNodeIndex].vNodePos - GET_ENTITY_COORDS(GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex)), FALSE)
ENDIF
ENDIF
IF DO_WE_WANT_TO_ATTACH_CAM_TO_ENTITY(thisSwitchCam, iNodeIndex)
IF DOES_ENTITY_EXIST(GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex))
CDEBUG3LN(DEBUG_MISSION, "Attaching Cam Node " , iNodeIndex, " to Focus Entity: ", NATIVE_TO_INT(GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex)))
ATTACH_CAM_TO_ENTITY(ciSwitchCamNodeIndex, GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex), thisSwitchCam.nodes[iNodeIndex].vNodePos, thisSwitchCam.nodes[iNodeIndex].bAttachOffsetIsRelative)
IF thisSwitchCam.nodes[iNodeIndex].bPointAtEntity
// AND thisSwitchCam.nodes[iNodeIndex].SwitchCamType != SWITCH_CAM_ENTITY_ATTACHED_W_WORLD_LOOK_AT
IF thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex > -1
POINT_CAM_AT_ENTITY(ciSwitchCamNodeIndex, GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex, thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex), thisSwitchCam.nodes[iNodeIndex].vNodeDir, thisSwitchCam.nodes[iNodeIndex].bPointAtOffsetIsRelative)
ELSE
POINT_CAM_AT_ENTITY(ciSwitchCamNodeIndex, GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iNodeIndex), thisSwitchCam.nodes[iNodeIndex].vNodeDir, thisSwitchCam.nodes[iNodeIndex].bPointAtOffsetIsRelative)
ENDIF
ENDIF
ENDIF
ENDIF
// IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_ENTITY_ATTACHED_W_WORLD_LOOK_AT
IF thisSwitchCam.nodes[iNodeIndex].SwitchCamType = SWITCH_CAM_PATH_RELATIVE_PED_TO_WORLD_COORD
PRINTLN("Pointing cam at world coord ", iNodeIndex)
POINT_CAM_AT_COORD(ciSwitchCamNodeIndex, thisSwitchCam.nodes[iNodeIndex].vWorldPosLookAt)
ENDIF
IF thisSwitchCam.nodes[iNodeIndex].bUseCustomDOF
PRINTLN("Enabling custom DOF for Switch Cam Node: ", iNodeIndex)
P_UPDATE_NODE_DOF(thisSwitchCam, iNodeIndex)
ENDIF
ENDIF
thisSwitchCam.nodes[iNodeIndex].bHaveNodeSettingsBeenApplied = FALSE
thisSwitchCam.nodes[iNodeIndex].bHaveNodePostFX_BeenApplied = FALSE
CDEBUG3LN(DEBUG_MISSION, "BUILD_SWITCH_CAM_NODE - END")
ENDPROC
/// PURPOSE:
/// Check if the switch cam struct requires the animated cam shake libraries to be loaded.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to check if we need to load the animated cam shake anim library for
/// RETURNS:
/// TRUE the struct uses a cam shake that requires the animated cam shake library. FALSE otherwise
FUNC BOOL ARE_ANIM_CAM_SHAKE_LIBRARIES_NEEDED_FOR_STRUCT(SWITCH_CAM_STRUCT &thisSwitchCam)
BOOL bIsCamShakeLibraryNeeded = FALSE
INT i
REPEAT thisSwitchCam.iNumNodes i
IF thisSwitchCam.nodes[i].NodeCamShakeType != CAM_SHAKE_DEFAULT
bIsCamShakeLibraryNeeded = TRUE
ENDIF
ENDREPEAT
RETURN bIsCamShakeLibraryNeeded
ENDFUNC
/// PURPOSE:
/// Load in all the cam shake libraries needed for a switch cam struct
/// PARAMS:
/// thisSwitchCam - Switch cam struct to load the libraries for
/// RETURNS:
/// TRUE when all libraries needed by the switch cam have loaded. FALSE otherwise.
FUNC BOOL LOAD_CAM_SHAKE_LIBRARIES(SWITCH_CAM_STRUCT &thisSwitchCam)
thisSwitchCam.bInitialized = thisSwitchCam.bInitialized
IF ARE_ANIM_CAM_SHAKE_LIBRARIES_NEEDED_FOR_STRUCT(thisSwitchCam)
REQUEST_ANIM_DICT("shake_cam_all@")
IF HAS_ANIM_DICT_LOADED("shake_cam_all@")
RETURN TRUE
ENDIF
RETURN FALSE
ELSE
RETURN TRUE
ENDIF
ENDFUNC
/// PURPOSE:
/// Remove all animated camera libraried (light, medium, heavy) from memory
PROC UNLOAD_ALL_CAM_SHAKE_ANIM_LIBRARIES()
CDEBUG3LN(DEBUG_MISSION, "UNLOAD_ALL_CAM_SHAKE_ANIMS")
REMOVE_ANIM_DICT("shake_cam_all@")
ENDPROC
PROC PLAY_SWITCH_CAM_NODE_FLASH(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
STRING sFlashEffectName
SWITCH thisSwitchCam.nodes[iNodeIndex].SCFE_FlashEffectUsed
CASE SCFE_CODE_FLASH
CDEBUG3LN(DEBUG_MISSION, "Playing CODE Camera Flash...", iNodeIndex)
SET_FLASH(thisSwitchCam.nodes[iNodeIndex].fMinExposure, thisSwitchCam.nodes[iNodeIndex].fMaxExposure, thisSwitchCam.nodes[iNodeIndex].iRampUpDuration, thisSwitchCam.nodes[iNodeIndex].iRampDownDuration, thisSwitchCam.nodes[iNodeIndex].iHoldDuration)
BREAK
CASE SCFE_DefaultFlash
sFlashEffectName = "DefaultFlash"
BREAK
CASE SCFE_FocusOut
sFlashEffectName = "FocusOut"
BREAK
CASE SCFE_MinigameEndNeutral
sFlashEffectName = "MinigameEndNeutral"
BREAK
CASE SCFE_MinigameTransitionOut
sFlashEffectName = "MinigameTransitionOut"
BREAK
CASE SCFE_PauseMenuOut
sFlashEffectName = "PauseMenuOut"
BREAK
CASE SCFE_SwitchShortNeutralIn
sFlashEffectName = "SwitchShortNeutralIn"
BREAK
CASE SCFE_SwitchShortNeutralMid
sFlashEffectName = "SwitchShortNeutralMid"
BREAK
CASE SCFE_SwitchShortMichaelMid
sFlashEffectName = "SwitchShortMichaelMid"
BREAK
CASE SCFE_SwitchShortMichaelIn
sFlashEffectName = "SwitchShortMichaelIn"
BREAK
CASE SCFE_SwitchSceneMichael
sFlashEffectName = "SwitchSceneMichael"
BREAK
CASE SCFE_SwitchShortTrevorMid
sFlashEffectName = "SwitchShortTrevorMid"
BREAK
CASE SCFE_SwitchShortFranklinIn
sFlashEffectName = "SwitchShortFranklinIn"
BREAK
CASE SCFE_SwitchShortFranklinMid
sFlashEffectName = "SwitchShortFranklinMid"
BREAK
CASE SCFE_SwitchShortTrevorIn
sFlashEffectName = "SwitchShortTrevorIn"
BREAK
CASE SCFE_SwitchOpenFranklinOut
sFlashEffectName = "SwitchOpenFranklinOut"
BREAK
CASE SCFE_SwitchOpenMichaelIn
sFlashEffectName = "SwitchOpenMichaelIn"
BREAK
CASE SCFE_SwitchOpenMichaelOut
sFlashEffectName = "SwitchOpenMichaelOut"
BREAK
CASE SCFE_SwitchOpenTrevorIn
sFlashEffectName = "SwitchOpenTrevorIn"
BREAK
CASE SCFE_SwitchOpenTrevorOut
sFlashEffectName = "SwitchOpenTrevorOut"
BREAK
CASE SCFE_SwitchSceneFranklin
sFlashEffectName = "SwitchSceneFranklin"
BREAK
CASE SCFE_SwitchSceneTrevor
sFlashEffectName = "SwitchSceneTrevor"
BREAK
ENDSWITCH
IF thisSwitchCam.nodes[iNodeIndex].SCFE_FlashEffectUsed > SCFE_CODE_FLASH
CDEBUG3LN(DEBUG_MISSION, "Playing APFX Camera Flash: ", sFlashEffectName, " ", iNodeIndex)
ANIMPOSTFX_PLAY(sFlashEffectName, 0, false)
ENDIF
ENDPROC
/// PURPOSE:
/// Get the string name of the currently active ANIM POST FX
/// RETURNS:
/// String name of currently active ANIM POST FX. Return an empty string of "" if no ANIM POST FX is active.
FUNC STRING GET_NAME_OF_ACTIVE_ANIM_POST_FX()
STRING sNameOfActiveFX = ""
IF ANIMPOSTFX_IS_RUNNING("SwitchSceneMichael")
sNameOfActiveFX = "SwitchSceneMichael"
ELIF ANIMPOSTFX_IS_RUNNING("SwitchSceneFranklin")
sNameOfActiveFX = "SwitchSceneFranklin"
ELIF ANIMPOSTFX_IS_RUNNING("SwitchSceneTrevor")
sNameOfActiveFX = "SwitchSceneTrevor"
ELIF ANIMPOSTFX_IS_RUNNING("SwitchSceneNeutral")
sNameOfActiveFX = "SwitchSceneNeutral"
ELIF ANIMPOSTFX_IS_RUNNING("SwitchHUDIn")
sNameOfActiveFX = "SwitchHUDIn"
ENDIF
RETURN sNameOfActiveFX
ENDFUNC
/// PURPOSE:
/// Stop current Anim Post FX with the corresponding blend out if one exists.
/// PARAMS:
/// thisSwitchCam - Switch cam struct playing APFX
/// iNodeIndex - Node of Switch Cam blend out has been tagged in
PROC BLEND_OUT_FROM_SWITCH_CAM_APFX(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
//[MF] If we're playing the 'SwitchHUDIn', play it's exit effect 'SwitchHUDOut'
IF ARE_STRINGS_EQUAL(GET_NAME_OF_ACTIVE_ANIM_POST_FX(), "SwitchHUDIn")
AND thisSwitchCam.nodes[iNodeIndex].fNodeTimePostFXBlendTime > 0
ANIMPOSTFX_STOP(GET_NAME_OF_ACTIVE_ANIM_POST_FX())
ANIMPOSTFX_PLAY("SwitchHUDOut", FLOOR(thisSwitchCam.nodes[iNodeIndex].fNodeTimePostFXBlendTime) * 1000, FALSE)
NET_NL()NET_PRINT("BLEND_OUT_FROM_SWITCH_CAM_APFX SwitchHUDOut 4 ")
ELSE
ANIMPOSTFX_STOP(GET_NAME_OF_ACTIVE_ANIM_POST_FX())
ENDIF
ENDPROC
/// PURPOSE:
/// Handle the playback of the 'woosh' audio during switch cams.
/// PARAMS:
/// thisSwitchCam - Switch cam to play the audio of.
PROC HANDLE_CUSTOM_SWITCH_CAM_AUDIO(SWITCH_CAM_STRUCT &thisSwitchCam)
IF thisSwitchCam.fSwitchSoundAudioStartPhase >= 0
IF GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline) >= thisSwitchCam.fSwitchSoundAudioStartPhase
AND GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline) < thisSwitchCam.fSwitchSoundAudioEndPhase
IF thisSwitchCam.iSwitchAudioCameraHitInID = -1
IF thisSwitchCam.bSwitchSoundPlayOpeningPulse
thisSwitchCam.iSwitchAudioCameraHitInID = GET_SOUND_ID()
PLAY_SOUND_FRONTEND(thisSwitchCam.iSwitchAudioCameraHitInID, "Hit_In", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
ENDIF
ENDIF
IF thisSwitchCam.iSwitchAudioCameraMoveLoopID = -1
IF thisSwitchCam.bSwitchSoundPlayMoveLoop
thisSwitchCam.iSwitchAudioCameraMoveLoopID = GET_SOUND_ID()
PLAY_SOUND_FRONTEND(thisSwitchCam.iSwitchAudioCameraMoveLoopID, "Camera_Move_Loop", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
ENDIF
ENDIF
ENDIF
ENDIF
IF thisSwitchCam.fSwitchSoundAudioEndPhase >= 0
IF GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline) >= thisSwitchCam.fSwitchSoundAudioEndPhase
OR GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline) = 1.0
IF thisSwitchCam.iSwitchAudioCameraMoveLoopID != -1
IF thisSwitchCam.bSwitchSoundPlayMoveLoop
STOP_SOUND(thisSwitchCam.iSwitchAudioCameraMoveLoopID)
thisSwitchCam.iSwitchAudioCameraMoveLoopID = -1
ENDIF
ENDIF
IF thisSwitchCam.iSwitchAudioCameraHitOutID = -1
IF thisSwitchCam.bSwitchSoundPlayExitPulse
thisSwitchCam.iSwitchAudioCameraHitOutID = GET_SOUND_ID()
PLAY_SOUND_FRONTEND(thisSwitchCam.iSwitchAudioCameraHitOutID, "Hit_Out", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Stop all sounds associated with a spline and reset the audio IDs to 0
/// PARAMS:
/// thisSwitchCam -
PROC STOP_ALL_SWITCH_CAM_SOUNDS(SWITCH_CAM_STRUCT &thisSwitchCam)
PRINTLN("Stopping all switch cam sounds...")
STOP_SOUND(thisSwitchCam.iSwitchAudioCameraHitOutID)
STOP_SOUND(thisSwitchCam.iSwitchAudioCameraHitInID)
STOP_SOUND(thisSwitchCam.iSwitchAudioCameraMoveLoopID)
thisSwitchCam.iSwitchAudioCameraHitOutID = -1
thisSwitchCam.iSwitchAudioCameraHitInID = -1
thisSwitchCam.iSwitchAudioCameraMoveLoopID = -1
ENDPROC
/// PURPOSE:
/// This takes a CLONE_WITH_OFFSET node that copies a gameplay cam and ensures it is updated with the current gameplay cam data.
/// VERY useful when copying a gameplay cam that happens after a character switch in a spline.
/// PARAMS:
/// thisSwitchCam - Spline node struct to update the gameplay cam clone for
/// iNodeIndex - Node of the currently processced gameplay cam struct
PROC UPDATE_CLONE_NODE_GAMEPLAY_CAM_DATA(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex, BOOL bForceGameplayCamNodeCloneUpdate = FALSE)
CDEBUG3LN(DEBUG_MISSION, "UPDATE_CLONE_NODE_GAMEPLAY_CAM_DATA. NODE: ", iNodeIndex)
INT i
REPEAT COUNT_OF(thisSwitchCam.nodes) i
IF (iNodeIndex >= thisSwitchCam.iCamSwitchFocusNode AND i >= thisSwitchCam.iCamSwitchFocusNode)
OR bForceGameplayCamNodeCloneUpdate
IF thisSwitchCam.nodes[thisSwitchCam.nodes[i].iNodeToClone].bIsGameplayCamCopy
OR thisSwitchCam.nodes[thisSwitchCam.nodes[i].iNodeToClone].SwitchCamType = SWITCH_CAM_GAMEPLAY_CAM_COPY
PRINTLN("Updating Clone Cam Node To Copy Gameplay Cam")
SET_CAM_COORD(thisSwitchCam.nodes[i].ciSwitchNode, (GET_GAMEPLAY_CAM_COORD() + thisSwitchCam.nodes[i].vClonedNodeOffset))
SET_CAM_ROT(thisSwitchCam.nodes[i].ciSwitchNode, GET_GAMEPLAY_CAM_ROT())
ENDIF
ENDIF
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Create a script camera spline based on the data saved to the Switch Cam Struct
/// PARAMS:
/// thisSwitchCam - Switch Cam Struct to build the switch script cam spline from.
PROC CREATE_SPLINE_CAM(SWITCH_CAM_STRUCT &thisSwitchCam)
CDEBUG3LN(DEBUG_MISSION, "CREATE_SPLINE_CAM")
IF NOT LOAD_CAM_SHAKE_LIBRARIES(thisSwitchCam)
//SCRIPT_ASSERT("CAM SHAKE ANIM LIBRARIES NOT LOADED! Function F_LOAD_CAM_SHAKE_LIBRARIES must return true before playing this switch cam.")
ENDIF
CAM_SPLINE_NODE_FLAGS ease = CAM_SPLINE_NODE_NO_FLAGS
thisSwitchCam.bIsSplineCamFinishedPlaying = FALSE
STOP_ALL_SWITCH_CAM_SOUNDS(thisSwitchCam)
INT index
REPEAT MAX_NUM_SWITCH_NODES index
thisSwitchCam.nodes[index].bHasFlashed = FALSE
ENDREPEAT
thisSwitchCam.bTimePostFXActive = FALSE
IF DOES_CAM_EXIST(thisSwitchCam.ciSpline)
DESTROY_CAM(thisSwitchCam.ciSpline)
ENDIF
#IF IS_DEBUG_BUILD
thisSwitchCam.bIsApprovedTextDisplayed = FALSE
#ENDIF
thisSwitchCam.ciSpline = CREATE_CAMERA(CAMTYPE_SPLINE_TIMED_CUSTOM, FALSE)
IF DOES_CAM_EXIST(thisSwitchCam.ciSpline)
REPEAT thisSwitchCam.iNumNodes index
#IF IS_DEBUG_BUILD
IF NOT (thisSwitchCam.bRecreateSpline AND index = 0 AND DO_WE_WANT_TO_CLONE_GAMEPLAY_CAM(thisSwitchCam, index)) //[MF] If we're recreating the spline in debug mode, don't recreate an initial node gameplay cam clone.
#ENDIF
BUILD_SWITCH_CAM_NODE(thisSwitchCam, index)
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
//[MF] if we're creating a non 0 node gameplay cam copy, attach an actual gameplay cam to the spline. Otherwise we use a cloned gameplay cam.
IF (thisSwitchCam.nodes[index].bIsGameplayCamCopy OR thisSwitchCam.nodes[index].SwitchCamType = SWITCH_CAM_GAMEPLAY_CAM_COPY)
IF DO_WE_WANT_TO_CLONE_GAMEPLAY_CAM(thisSwitchCam, index)
ADD_CAM_SPLINE_NODE_USING_CAMERA(thisSwitchCam.ciSpline, thisSwitchCam.nodes[index].ciSwitchNode, thisSwitchCam.nodes[index].iNodeTime, CAM_SPLINE_NODE_SMOOTH_LENS_PARAMS)
ELSE
ADD_CAM_SPLINE_NODE_USING_GAMEPLAY_FRAME(thisSwitchCam.ciSpline, thisSwitchCam.nodes[index].iNodeTime, CAM_SPLINE_NODE_SMOOTH_LENS_PARAMS)
ENDIF
ELSE
ADD_CAM_SPLINE_NODE_USING_CAMERA(thisSwitchCam.ciSpline, thisSwitchCam.nodes[index].ciSwitchNode, thisSwitchCam.nodes[index].iNodeTime, CAM_SPLINE_NODE_SMOOTH_LENS_PARAMS)
ENDIF
#IF IS_DEBUG_BUILD
IF NOT (thisSwitchCam.bRecreateSpline AND index = 0 AND DO_WE_WANT_TO_CLONE_GAMEPLAY_CAM(thisSwitchCam, index)) //[MF] If we're recreating the spline in debug mode, don't recreate an initial node gameplay cam clone.
#ENDIF
IF DO_WE_WANT_TO_CLONE_GAMEPLAY_CAM(thisSwitchCam, index)
ATTACH_GAMEPLAY_CAM_CLONE_TO_ENTITY(thisSwitchCam, index)
ENDIF
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
IF thisSwitchCam.nodes[index].iCamEaseType > 0
AND thisSwitchCam.nodes[index].fCamEaseScaler > 0.0
SWITCH thisSwitchCam.nodes[index].iCamEaseType
CASE 1
ease = CAM_SPLINE_NODE_EASE_IN
BREAK
CASE 2
ease = CAM_SPLINE_NODE_EASE_OUT
BREAK
CASE 3
ease = CAM_SPLINE_NODE_EASE_INOUT
BREAK
ENDSWITCH
SET_CAM_SPLINE_NODE_EASE(thisSwitchCam.ciSpline, index, ease, thisSwitchCam.nodes[index].fCamEaseScaler)
ENDIF
INT iSplineNodeExtraValue = 0
IF thisSwitchCam.nodes[index].bCamEaseForceLinear
iSplineNodeExtraValue += (ENUM_TO_INT(CAM_SPLINE_NODE_FORCE_LINEAR))
ENDIF
IF thisSwitchCam.nodes[index].bCamEaseForceLevel
iSplineNodeExtraValue += (ENUM_TO_INT(CAM_SPLINE_NODE_FORCE_LEVEL))
ENDIF
SET_CAM_SPLINE_NODE_VELOCITY_SCALE(thisSwitchCam.ciSpline, index, thisSwitchCam.nodes[index].fCamNodeVelocityScale)
SET_CAM_SPLINE_NODE_EXTRA_FLAGS(thisSwitchCam.ciSpline, index, INT_TO_ENUM(CAM_SPLINE_NODE_FORCE_FLAGS, iSplineNodeExtraValue))
ENDREPEAT
IF thisSwitchCam.bAddGameplayCamAsLastNode
IF thisSwitchCam.iGameplayNodeBlendDuration >= 0
ADD_CAM_SPLINE_NODE_USING_GAMEPLAY_FRAME(thisSwitchCam.ciSpline, thisSwitchCam.iGameplayNodeBlendDuration, CAM_SPLINE_NODE_SMOOTH_LENS_PARAMS)
ENDIF
ENDIF
IF thisSwitchCam.bSplineNoSmoothing
SET_CAM_SPLINE_SMOOTHING_STYLE(thisSwitchCam.ciSpline, CAM_SPLINE_NO_SMOOTH)
ENDIF
#IF IS_DEBUG_BUILD
IF NOT thisSwitchCam.bDEBUGSplineCam_DisableVelocityOverride
#ENDIF
REPEAT MAX_NUM_CAM_VELOCITY_OVERRIDES index
IF thisSwitchCam.camVelocityOverrides[index].fSpeed > -1
PRINTLN("Applying Switch Cam Node velocity override...", index)
OVERRIDE_CAM_SPLINE_VELOCITY(thisSwitchCam.ciSpline, index, thisSwitchCam.camVelocityOverrides[index].fStartPoint, thisSwitchCam.camVelocityOverrides[index].fSpeed)
ENDIF
ENDREPEAT
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
REPEAT MAX_NUM_CAM_BLUR_OVERRIDES index
OVERRIDE_CAM_SPLINE_MOTION_BLUR(thisSwitchCam.ciSpline, index, thisSwitchCam.camBlurOverrides[index].fBlurOverrideStartPoint, thisSwitchCam.camBlurOverrides[index].fBlurOverrideBlurLevel)
ENDREPEAT
//[MF] Fix motion blur so it better matches what we need for the switch cams.
ALLOW_MOTION_BLUR_DECAY(thisSwitchCam.ciSpline, FALSE)
ENDIF
ENDPROC
FUNC FLOAT SLOW_IN_INTERP(FLOAT fVal1, FLOAT fVal2, FLOAT fAlpha)
FLOAT alpha2 = (1.0 - COS(RAD_TO_DEG(fAlpha * CONST_PI* 0.5)))
RETURN fVal1*(1.0 - alpha2) + fVal2*alpha2
ENDFUNC
FUNC FLOAT SLOW_OUT_INTERP(FLOAT fVal1, FLOAT fVal2, FLOAT fAlpha)
FLOAT alpha2 = (SIN(RAD_TO_DEG(fAlpha * CONST_PI* 0.5)))
RETURN fVal1*(1.0 - alpha2) + fVal2*alpha2
ENDFUNC
FUNC FLOAT SLOW_INOUT_INTERP(FLOAT fVal1, FLOAT fVal2, FLOAT fAlpha)
FLOAT alpha2 = 0.5*(1.0 - COS(RAD_TO_DEG(fAlpha * CONST_PI)))
RETURN fVal1*(1.0 - alpha2) + fVal2*alpha2
ENDFUNC
FLOAT fCurrentLerp = 1.0
/// PURPOSE:
/// Process logic to be played during the spline cam. This handles things like Post FX, DOF, Animated camera shake and other effects.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to process
/// RETURNS:
/// Index of currently active camera node in spline.
FUNC INT UPDATE_SPLINE_CAM(SWITCH_CAM_STRUCT &thisSwitchCam)
//CDEBUG3LN(DEBUG_MISSION, "UPDATE_SWITCH_CAM")
INT iIndex = GET_CAM_SPLINE_NODE_INDEX(thisSwitchCam.ciSpline)
//[MF] Have to grab the index of the next cam node as the widget layout makes that node effects appear to apply to the incorrect node.
//[MF] EG. If we're shown as being on node 2 in the debug widget, GET_CAM_SPLINE_NODE_INDEX still returns Node 1
INT iIndexOffset = GET_CAM_SPLINE_NODE_INDEX(thisSwitchCam.ciSpline) + 1
//[MF] Safety to ensure we don't get an array overrun error
IF iIndexOffset > thisSwitchCam.iNumNodes
iIndexOffset = thisSwitchCam.iNumNodes
ENDIF
//[MF] Matt P logic to handle camera time scaler ease types
IF iIndexOffset < thisSwitchCam.iNumNodes - 1
SWITCH thisSwitchCam.nodes[iIndexOffset].iTimeScaleEaseType
CASE 0
fCurrentLerp = LERP_FLOAT(thisSwitchCam.nodes[iIndexOffset].fTimeScale, thisSwitchCam.nodes[iIndexOffset + 1].fTimeScale, GET_CAM_SPLINE_NODE_PHASE(thisSwitchCam.ciSpline) )
BREAK
CASE 1
fCurrentLerp = SLOW_IN_INTERP(thisSwitchCam.nodes[iIndexOffset].fTimeScale, thisSwitchCam.nodes[iIndexOffset + 1].fTimeScale, CLAMP((GET_CAM_SPLINE_NODE_PHASE(thisSwitchCam.ciSpline) * (1 / thisSwitchCam.nodes[iIndexOffset].fTimeScaleEaseScaler)), 0.0, 1.0 ))
BREAK
CASE 2
fCurrentLerp = SLOW_OUT_INTERP(thisSwitchCam.nodes[iIndexOffset].fTimeScale, thisSwitchCam.nodes[iIndexOffset + 1].fTimeScale, CLAMP((GET_CAM_SPLINE_NODE_PHASE(thisSwitchCam.ciSpline) * (1 / thisSwitchCam.nodes[iIndexOffset].fTimeScaleEaseScaler)), 0.0, 1.0 ) )
BREAK
CASE 3
fCurrentLerp = SLOW_INOUT_INTERP(thisSwitchCam.nodes[iIndexOffset].fTimeScale, thisSwitchCam.nodes[iIndexOffset + 1].fTimeScale, CLAMP((GET_CAM_SPLINE_NODE_PHASE(thisSwitchCam.ciSpline) * (1 / thisSwitchCam.nodes[iIndexOffset].fTimeScaleEaseScaler)), 0.0, 1.0 ) )
BREAK
ENDSWITCH
SET_TIME_SCALE(fCurrentLerp)
ELSE
SET_TIME_SCALE(1.0)
ENDIF
//[MF] Make sure clone node is accurately representing gameplay cam data.
IF thisSwitchCam.nodes[iIndex].SwitchCamType = SWITCH_CAM_CLONE_NODE_WITH_OFFSET
UPDATE_CLONE_NODE_GAMEPLAY_CAM_DATA(thisSwitchCam, iIndex)
ENDIF
//[MF] Handle camera post FX types.
IF NOT thisSwitchCam.nodes[iIndexOffset].bHaveNodePostFX_BeenApplied
IF thisSwitchCam.nodes[iIndexOffset].NodeTimePostFX_Type != NO_EFFECT
IF NOT thisSwitchCam.bTimePostFXActive //[MF] If we're not yet playing a POST FX.
OR (iIndexOffset > 1 and (thisSwitchCam.nodes[iIndex].NodeTimePostFX_Type != thisSwitchCam.nodes[iIndexOffset].NodeTimePostFX_Type)) //[MF] Check if the previous effect doesn't match the current nodes effects (we've moved to a different effect)
IF GET_CAM_SPLINE_NODE_PHASE(thisSwitchCam.ciSpline) >= thisSwitchCam.nodes[iIndexOffset].fNodeTimePostFXTimeOffset
STRING sPostFX_Name
SWITCH thisSwitchCam.nodes[iIndexOffset].NodeTimePostFX_Type
CASE SEPIA_EFFECT
sPostFX_Name = "switch_cam_2"
BREAK
CASE SCANLINE_EFFECT
sPostFX_Name = "switch_cam_1"
BREAK
CASE APFX_SWITCH_HUD_IN
sPostFX_Name = "SwitchHUDIn"
BREAK
ENDSWITCH
SWITCH thisSwitchCam.nodes[iIndexOffset].NodeTimePostFX_Type
//[MF] Handle time Post FX
CASE SEPIA_EFFECT
CASE SCANLINE_EFFECT
BLEND_OUT_FROM_SWITCH_CAM_APFX(thisSwitchCam, iIndexOffset)
IF thisSwitchCam.nodes[iIndexOffset].fNodeTimePostFXBlendTime > 0
CDEBUG3LN(DEBUG_MISSION, "APPLYING TIME POSTFX. Index: ",iIndexOffset)
SET_TRANSITION_TIMECYCLE_MODIFIER(sPostFX_Name, thisSwitchCam.nodes[iIndexOffset].fNodeTimePostFXBlendTime)
ELSE
CDEBUG3LN(DEBUG_MISSION, "APPLYING TIME POSTFX. Index: ",iIndexOffset)
SET_TIMECYCLE_MODIFIER(sPostFX_Name)
ENDIF
BREAK
//[MF] Handle Anim Post FX
CASE APFX_SWITCH_HUD_IN
BLEND_OUT_FROM_SWITCH_CAM_APFX(thisSwitchCam, iIndexOffset)
CDEBUG3LN(DEBUG_MISSION, "APPLYING ANIM POSTFX. Index: ",iIndexOffset)
ANIMPOSTFX_PLAY(sPostFX_Name, FLOOR(1000* thisSwitchCam.nodes[iIndexOffset].fNodeTimePostFXBlendTime), FALSE)
BREAK
ENDSWITCH
thisSwitchCam.bTimePostFXActive = TRUE
thisSwitchCam.nodes[iIndexOffset].bHaveNodePostFX_BeenApplied = TRUE
ENDIF
ENDIF
ELSE
//[MF] Handle the cancelling of previously selected effects
IF thisSwitchCam.bTimePostFXActive
IF GET_CAM_SPLINE_NODE_PHASE(thisSwitchCam.ciSpline) >= thisSwitchCam.nodes[iIndexOffset].fNodeTimePostFXTimeOffset
IF GET_TIMECYCLE_MODIFIER_INDEX() != -1
CDEBUG3LN(DEBUG_MISSION, "TIME CYCLE OUTPUT TEST: REMOVING TIME POST FX. Index: ", iIndexOffset)
SET_TRANSITION_OUT_OF_TIMECYCLE_MODIFIER(thisSwitchCam.nodes[iIndexOffset].fNodeTimePostFXBlendTime)
thisSwitchCam.bTimePostFXActive = FALSE
thisSwitchCam.nodes[iIndexOffset].bHaveNodePostFX_BeenApplied = TRUE
ELIF NOT ARE_STRINGS_EQUAL(GET_NAME_OF_ACTIVE_ANIM_POST_FX(), "")
BLEND_OUT_FROM_SWITCH_CAM_APFX(thisSwitchCam, iIndexOffset)
thisSwitchCam.bTimePostFXActive = FALSE
thisSwitchCam.nodes[iIndexOffset].bHaveNodePostFX_BeenApplied = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//visual fx
IF thisSwitchCam.nodes[iIndexOffset].bFlashEnabled
IF NOT thisSwitchCam.nodes[iIndexOffset].bHasFlashed
IF GET_CAM_SPLINE_NODE_PHASE(thisSwitchCam.ciSpline) >= thisSwitchCam.nodes[iIndexOffset].fFlashNodePhaseOffset
PRINTLN("Playing Node Flash...")
PLAY_SWITCH_CAM_NODE_FLASH(thisSwitchCam, iIndexOffset)
thisSwitchCam.nodes[iIndexOffset].bHasFlashed = TRUE
ENDIF
ENDIF
ENDIF
//[MF] If we miss a flash due to a frame rate issue, play the skipped flash as soon as possible.
IF thisSwitchCam.nodes[iIndex].bFlashEnabled
IF NOT thisSwitchCam.nodes[iIndex].bHasFlashed
PRINTLN("Playing Skipped Node Flash...")
PLAY_SWITCH_CAM_NODE_FLASH(thisSwitchCam, iIndex)
thisSwitchCam.nodes[iIndex].bHasFlashed = TRUE
ENDIF
ENDIF
RESET_ADAPTATION()
//[MF] Handle Camera Node Effects
IF iIndexOffset < thisSwitchCam.iNumNodes - 1
//[MF] Camera shakes
IF NOT thisSwitchCam.nodes[iIndexOffset].bHaveNodeSettingsBeenApplied
STRING CamShake
STRING CamShakeLib
//[MF] So cam shakes won't persist through cut nodes
IF thisSwitchCam.nodes[iIndexOffset].bIsCamCutNode
STOP_CAM_SHAKING(thisSwitchCam.nodes[iIndexOffset].ciSwitchNode, TRUE)
ENDIF
IF thisSwitchCam.nodes[iIndexOffset].NodeCamShakeType != CAM_SHAKE_DEFAULT
CamShakeLib = "shake_cam_all@"
IF thisSwitchCam.nodes[iIndexOffset].NodeCamShakeType = CAM_SHAKE_LIGHT
CamShake = "light"
ELIF thisSwitchCam.nodes[iIndexOffset].NodeCamShakeType = CAM_SHAKE_MEDIUM
CamShake = "medium"
ELIF thisSwitchCam.nodes[iIndexOffset].NodeCamShakeType = CAM_SHAKE_HEAVY
CamShake = "heavy"
ENDIF
ANIMATED_SHAKE_CAM(thisSwitchCam.nodes[iIndexOffset].ciSwitchNode, CamShakeLib, CamShake, "", thisSwitchCam.nodes[iIndexOffset].fNodeCamShake)
ELSE
SHAKE_CAM(thisSwitchCam.ciSpline, "SKY_DIVING_SHAKE", thisSwitchCam.nodes[iIndexOffset].fNodeCamShake)
ENDIF
thisSwitchCam.nodes[iIndexOffset].bHaveNodeSettingsBeenApplied = TRUE
ENDIF
ENDIF
//[MF] Low/Regular detail nodes.
IF thisSwitchCam.nodes[iIndex].bIsLowDetailNode
SET_TO_LOW_DETAIL_RENDERING()
ELSE
SET_TO_DEFAULT_DETAIL_RENDERING()
ENDIF
BOOL bUseHighDOF
//[MF] Check if the next node uses custom DOF so we can start interpolating to that value
IF GET_CAM_SPLINE_NODE_INDEX(thisSwitchCam.ciSpline) < thisSwitchCam.iNumNodes
IF thisSwitchCam.nodes[GET_CAM_SPLINE_NODE_INDEX(thisSwitchCam.ciSpline) + 1].bUseCustomDOF
bUseHighDOF = TRUE
ENDIF
ENDIF
//[MF] check if current Node uses custom DOF
IF thisSwitchCam.nodes[GET_CAM_SPLINE_NODE_INDEX(thisSwitchCam.ciSpline)].bUseCustomDOF
bUseHighDOF = TRUE
ENDIF
//[MF] Set the cam to use High Quality DOF (must be set every frame)
IF bUseHighDOF
SET_USE_HI_DOF()
ENDIF
HANDLE_CUSTOM_SWITCH_CAM_AUDIO(thisSwitchCam)
#IF IS_DEBUG_BUILD
IF NOT thisSwitchCam.bIsApproved
IF NOT thisSwitchCam.bIsApprovedTextDisplayed
//DISPLAY_TEXT_WITH_LITERAL_STRING(0.77, 0.84, "STRING", "Unapproved")
ENDIF
ENDIF
#ENDIF
RETURN iIndex //[MF] Returning actual cam node we're on.
ENDFUNC
/// PURPOSE:
/// Check if the switch cam or any of it's nodes exist
/// PARAMS:
/// thisSwitchCam -
/// RETURNS:
/// TRUE if Switch cam exists or if ANY of it's nodes are still existing
FUNC BOOL DOES_SWITCH_CAM_EXIST(SWITCH_CAM_STRUCT &thisSwitchCam)
BOOL bDoesCamExist = FALSE
IF DOES_CAM_EXIST(thisSwitchCam.ciSpline)
bDoesCamExist = TRUE
ENDIF
INT i
REPEAT COUNT_OF(thisSwitchCam.nodes) i
DOES_CAM_EXIST(thisSwitchCam.nodes[i].ciSwitchNode)
bDoesCamExist = TRUE
ENDREPEAT
RETURN bDoesCamExist
ENDFUNC
/// PURPOSE:
/// Destroy all the cam indexes in the switch cam. The spline itself and each of it's nodes. NOTE: This does not reset the switch cam data.
/// PARAMS:
/// thisSwitchCam - Switch cam to destroy
PROC DESTROY_SWITCH_CAM(SWITCH_CAM_STRUCT &thisSwitchCam)
INT i
REPEAT COUNT_OF(thisSwitchCam.nodes) i
DESTROY_CAM(thisSwitchCam.nodes[i].ciSwitchNode)
ENDREPEAT
IF DOES_CAM_EXIST(thisSwitchCam.ciSpline)
DESTROY_CAM(thisSwitchCam.ciSpline)
ENDIF
ENDPROC
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Create a spline cam widget using our old style of widget. CAUTION: These contain several inputs that can contridict each other.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to build the widget from
/// iNodeIndex - Index of the camera
PROC CREATE_SPLINE_CAM_WIDGET_OLD_STYLE(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
ADD_WIDGET_INT_SLIDER("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime, 0, 20000, 25)
ADD_WIDGET_BOOL("Is Gameplay Cam Copy", thisSwitchCam.nodes[iNodeIndex].bIsGameplayCamCopy)
START_WIDGET_GROUP("Camera Position and Orientation")
ADD_WIDGET_VECTOR_SLIDER("Positon", thisSwitchCam.nodes[iNodeIndex].vNodePos, -100000.0, 100000.0, 1.0)
ADD_WIDGET_BOOL("Point at subject", thisSwitchCam.nodes[iNodeIndex].bPointAtEntity)
ADD_WIDGET_BOOL("Point At Offset Is Relative", thisSwitchCam.nodes[iNodeIndex].bPointAtOffsetIsRelative)
ADD_WIDGET_BOOL("Attach Offset Is Relative", thisSwitchCam.nodes[iNodeIndex].bAttachOffsetIsRelative)
ADD_WIDGET_VECTOR_SLIDER("Direction", thisSwitchCam.nodes[iNodeIndex].vNodeDir, -10000.0, 10000.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("FOV", thisSwitchCam.nodes[iNodeIndex].fNodeFOV, 0.0, 360.0, 1.0)
ADD_WIDGET_INT_SLIDER("Look At Entity Index Override", thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex, -1, (NUM_SWITCH_ENTITIES - 1), 1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_POST_FX_WIDGET(thisSwitchCam, iNodeIndex)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur, 0.0, 1.0, 0.01)
CREATE_SPLINE_CAM_SHAKE_WIDGET(thisSwitchCam, iNodeIndex)
IF iNodeIndex > 0 AND iNodeIndex < (thisSwitchCam.iNumNodes - 1) //[MF] Ensure that the first or last node of a cam can't be set as a jump-cut node.
ADD_WIDGET_BOOL("Is Jump-Cut Node", thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode)
ENDIF
CREATE_SPLINE_CAM_EASE_WIDGET(thisSwitchCam, iNodeIndex)
START_WIDGET_GROUP("Time Scale")
ADD_WIDGET_FLOAT_SLIDER("Time Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScale, 0.0, 12.0, 0.01)
CREATE_SPLINE_CAM_TIME_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iTimeScaleEaseType)
ADD_WIDGET_FLOAT_SLIDER("Time Ease Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScaleEaseScaler, 0.0, 2.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_FLASH_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(thisSwitchCam, iNodeIndex)
ADD_WIDGET_BOOL("Is Low Detail Node", thisSwitchCam.nodes[iNodeIndex].bIsLowDetailNode)
ENDPROC
/// PURPOSE:
/// Create a spline cam widget for an entity attached camera node
/// PARAMS:
/// thisSwitchCam - Switch cam struct to build the widget from
/// iNodeIndex - Index of the camera
PROC CREATE_SPLINE_CAM_WIDGET_ATTACHED_CAM(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
ADD_WIDGET_INT_SLIDER("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime, 0, 20000, 25)
START_WIDGET_GROUP("Camera Position and Orientation")
ADD_WIDGET_VECTOR_SLIDER("Positon", thisSwitchCam.nodes[iNodeIndex].vNodePos, -100000.0, 100000.0, 1.0)
ADD_WIDGET_BOOL("Point at subject", thisSwitchCam.nodes[iNodeIndex].bPointAtEntity)
ADD_WIDGET_BOOL("Point At Offset Is Relative", thisSwitchCam.nodes[iNodeIndex].bPointAtOffsetIsRelative)
ADD_WIDGET_BOOL("Attach Offset Is Relative", thisSwitchCam.nodes[iNodeIndex].bAttachOffsetIsRelative)
ADD_WIDGET_VECTOR_SLIDER("Direction", thisSwitchCam.nodes[iNodeIndex].vNodeDir, -10000.0, 10000.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("FOV", thisSwitchCam.nodes[iNodeIndex].fNodeFOV, 0.0, 360.0, 1.0)
ADD_WIDGET_INT_SLIDER("Look At Entity Index Override", thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex, -1, (NUM_SWITCH_ENTITIES - 1), 1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_POST_FX_WIDGET(thisSwitchCam, iNodeIndex)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur, 0.0, 1.0, 0.01)
CREATE_SPLINE_CAM_SHAKE_WIDGET(thisSwitchCam, iNodeIndex)
IF iNodeIndex > 0 AND iNodeIndex < (thisSwitchCam.iNumNodes - 1) //[MF] Ensure that the first or last node of a cam can't be set as a jump-cut node.
ADD_WIDGET_BOOL("Is Jump-Cut Node", thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode)
ENDIF
CREATE_SPLINE_CAM_EASE_WIDGET(thisSwitchCam, iNodeIndex)
START_WIDGET_GROUP("Time Scale")
ADD_WIDGET_FLOAT_SLIDER("Time Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScale, 0.0, 12.0, 0.01)
CREATE_SPLINE_CAM_TIME_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iTimeScaleEaseType)
ADD_WIDGET_FLOAT_SLIDER("Time Ease Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScaleEaseScaler, 0.0, 2.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_FLASH_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(thisSwitchCam, iNodeIndex)
ADD_WIDGET_BOOL("Is Low Detail Node", thisSwitchCam.nodes[iNodeIndex].bIsLowDetailNode)
ENDPROC
/// PURPOSE:
/// Create a spline cam widget for an entity attached camera node
/// PARAMS:
/// thisSwitchCam - Switch cam struct to build the widget from
/// iNodeIndex - Index of the camera
PROC CREATE_SPLINE_CAM_WIDGET_ATTACHED_CAM_W_WORLD_LOOK_AT(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
IF thisSwitchCam.nodes[iNodeIndex].bIsGameplayCamCopy
PRINTLN("Creating Entity Attached With World Look At Cam. Disabling Gameplay cam copy for node: ", iNodeIndex)
thisSwitchCam.nodes[iNodeIndex].bIsGameplayCamCopy = FALSE
ENDIF
ADD_WIDGET_INT_SLIDER("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime, 0, 20000, 25)
START_WIDGET_GROUP("Camera Position and Orientation")
ADD_WIDGET_VECTOR_SLIDER("Positon", thisSwitchCam.nodes[iNodeIndex].vNodePos, -100000.0, 100000.0, 1.0)
ADD_WIDGET_BOOL("Attach Offset Is Relative", thisSwitchCam.nodes[iNodeIndex].bAttachOffsetIsRelative)
ADD_WIDGET_VECTOR_SLIDER("World Look At Coord", thisSwitchCam.nodes[iNodeIndex].vWorldPosLookAt, -10000.0, 10000.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("FOV", thisSwitchCam.nodes[iNodeIndex].fNodeFOV, 0.0, 360.0, 1.0)
ADD_WIDGET_INT_SLIDER("Look At Entity Index Override", thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex, -1, (NUM_SWITCH_ENTITIES - 1), 1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_POST_FX_WIDGET(thisSwitchCam, iNodeIndex)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur, 0.0, 1.0, 0.01)
CREATE_SPLINE_CAM_SHAKE_WIDGET(thisSwitchCam, iNodeIndex)
IF iNodeIndex > 0 AND iNodeIndex < (thisSwitchCam.iNumNodes - 1) //[MF] Ensure that the first or last node of a cam can't be set as a jump-cut node.
ADD_WIDGET_BOOL("Is Jump-Cut Node", thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode)
ENDIF
CREATE_SPLINE_CAM_EASE_WIDGET(thisSwitchCam, iNodeIndex)
START_WIDGET_GROUP("Time Scale")
ADD_WIDGET_FLOAT_SLIDER("Time Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScale, 0.0, 12.0, 0.01)
CREATE_SPLINE_CAM_TIME_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iTimeScaleEaseType)
ADD_WIDGET_FLOAT_SLIDER("Time Ease Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScaleEaseScaler, 0.0, 2.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_FLASH_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(thisSwitchCam, iNodeIndex)
ADD_WIDGET_BOOL("Is Low Detail Node", thisSwitchCam.nodes[iNodeIndex].bIsLowDetailNode)
ENDPROC
/// PURPOSE:
/// Create a spline cam widget for a Gameplay cam copy node
/// PARAMS:
/// thisSwitchCam - Switch cam struct to build the widget from
/// iNodeIndex - Index of the camera
PROC CREATE_SPLINE_CAM_WIDGET_GAMEPLAY_CAM_COPY(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
ADD_WIDGET_INT_SLIDER("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime, 0, 20000, 25)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur, 0.0, 1.0, 0.01)
CREATE_SPLINE_CAM_SHAKE_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_POST_FX_WIDGET(thisSwitchCam, iNodeIndex)
IF iNodeIndex > 0 AND iNodeIndex < (thisSwitchCam.iNumNodes - 1) //[MF] Ensure that the first or last node of a cam can't be set as a jump-cut node.
ADD_WIDGET_BOOL("Is Jump-Cut Node", thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode)
ENDIF
CREATE_SPLINE_CAM_EASE_WIDGET(thisSwitchCam, iNodeIndex)
START_WIDGET_GROUP("Time Scale")
ADD_WIDGET_FLOAT_SLIDER("Time Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScale, 0.0, 12.0, 0.01)
CREATE_SPLINE_CAM_TIME_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iTimeScaleEaseType)
ADD_WIDGET_FLOAT_SLIDER("Time Ease Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScaleEaseScaler, 0.0, 2.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_FLASH_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(thisSwitchCam, iNodeIndex)
ADD_WIDGET_BOOL("Is Low Detail Node", thisSwitchCam.nodes[iNodeIndex].bIsLowDetailNode)
ENDPROC
/// PURPOSE:
/// Create a spline cam widget for a world position cam node
/// PARAMS:
/// thisSwitchCam - Switch cam struct to build the widget from
/// iNodeIndex - Index of the camera
PROC CREATE_SPLINE_CAM_WIDGET_WORLD_POS(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
ADD_WIDGET_INT_SLIDER("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime, 0, 20000, 25)
START_WIDGET_GROUP("Camera Position and Orientation")
ADD_WIDGET_VECTOR_SLIDER("Positon", thisSwitchCam.nodes[iNodeIndex].vNodePos, -10000.0, 10000.0, 1.0)
ADD_WIDGET_VECTOR_SLIDER("Direction", thisSwitchCam.nodes[iNodeIndex].vNodeDir, -10000.0, 10000.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("FOV", thisSwitchCam.nodes[iNodeIndex].fNodeFOV, 0.0, 360.0, 1.0)
ADD_WIDGET_BOOL("Point at subject", thisSwitchCam.nodes[iNodeIndex].bPointAtEntity)
ADD_WIDGET_BOOL("Point At Offset Is Relative", thisSwitchCam.nodes[iNodeIndex].bPointAtOffsetIsRelative)
ADD_WIDGET_INT_SLIDER("Look At Entity Index Override", thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex, -1, (NUM_SWITCH_ENTITIES - 1), 1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_POST_FX_WIDGET(thisSwitchCam, iNodeIndex)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur, 0.0, 1.0, 0.01)
CREATE_SPLINE_CAM_SHAKE_WIDGET(thisSwitchCam, iNodeIndex)
IF iNodeIndex > 0 AND iNodeIndex < (thisSwitchCam.iNumNodes - 1) //[MF] Ensure that the first or last node of a cam can't be set as a jump-cut node.
ADD_WIDGET_BOOL("Is Jump-Cut Node", thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode)
ENDIF
CREATE_SPLINE_CAM_EASE_WIDGET(thisSwitchCam, iNodeIndex)
START_WIDGET_GROUP("Time Scale")
ADD_WIDGET_FLOAT_SLIDER("Time Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScale, 0.0, 12.0, 0.01)
CREATE_SPLINE_CAM_TIME_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iTimeScaleEaseType)
ADD_WIDGET_FLOAT_SLIDER("Time Ease Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScaleEaseScaler, 0.0, 2.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_FLASH_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(thisSwitchCam, iNodeIndex)
ADD_WIDGET_BOOL("Is Low Detail Node", thisSwitchCam.nodes[iNodeIndex].bIsLowDetailNode)
ENDPROC
/// PURPOSE:
/// Create a spline cam widget for a world position cam node that tracks and looks at a world coord
/// PARAMS:
/// thisSwitchCam - Switch cam struct to build the widget from
/// iNodeIndex - Index of the camera
PROC CREATE_SPLINE_CAM_WIDGET_WORLD_POS_WITH_LOOK_AT(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
ADD_WIDGET_INT_SLIDER("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime, 0, 20000, 25)
START_WIDGET_GROUP("Camera Position and Orientation")
ADD_WIDGET_VECTOR_SLIDER("Look at Coord", thisSwitchCam.nodes[iNodeIndex].vWorldPosLookAt, -10000.0, 10000.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("Offset", thisSwitchCam.nodes[iNodeIndex].fNodeOffsetDist, 0.0, 100.0, 0.1)
ADD_WIDGET_FLOAT_SLIDER("FOV", thisSwitchCam.nodes[iNodeIndex].fNodeFOV, 0.0, 360.0, 1.0)
ADD_WIDGET_INT_SLIDER("Look At Entity Index Override", thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex, -1, (NUM_SWITCH_ENTITIES - 1), 1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_POST_FX_WIDGET(thisSwitchCam, iNodeIndex)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur, 0.0, 1.0, 0.01)
CREATE_SPLINE_CAM_SHAKE_WIDGET(thisSwitchCam, iNodeIndex)
IF iNodeIndex > 0 AND iNodeIndex < (thisSwitchCam.iNumNodes - 1) //[MF] Ensure that the first or last node of a cam can't be set as a jump-cut node.
ADD_WIDGET_BOOL("Is Jump-Cut Node", thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode)
ENDIF
CREATE_SPLINE_CAM_EASE_WIDGET(thisSwitchCam, iNodeIndex)
START_WIDGET_GROUP("Time Scale")
ADD_WIDGET_FLOAT_SLIDER("Time Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScale, 0.0, 12.0, 0.01)
CREATE_SPLINE_CAM_TIME_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iTimeScaleEaseType)
ADD_WIDGET_FLOAT_SLIDER("Time Ease Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScaleEaseScaler, 0.0, 2.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_FLASH_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(thisSwitchCam, iNodeIndex)
ADD_WIDGET_BOOL("Is Low Detail Node", thisSwitchCam.nodes[iNodeIndex].bIsLowDetailNode)
ENDPROC
/// PURPOSE:
/// Create a spline cam widget for a path relative cam node that sets a position along the gameplay camera forward from gameplay camera to target.
/// PARAMS:
/// thisSwitchCam - Switch cam struct to build the widget from
/// iNodeIndex - Index of the camera
PROC CREATE_SPLINE_CAM_WIDGET_PATH_RELATIVE(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
ADD_WIDGET_INT_SLIDER("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime, 0, 20000, 25)
START_WIDGET_GROUP("Camera Offset and FOV")
ADD_WIDGET_FLOAT_SLIDER("Distance Offset", thisSwitchCam.nodes[iNodeIndex].fNodeOffsetDist, 0.0, 100.0, 0.1)
ADD_WIDGET_FLOAT_SLIDER("FOV", thisSwitchCam.nodes[iNodeIndex].fNodeFOV, 0.0, 360.0, 1.0)
ADD_WIDGET_INT_SLIDER("Look At Entity Index Override", thisSwitchCam.nodes[iNodeIndex].iForceCamPointAtEntityIndex, -1, (NUM_SWITCH_ENTITIES - 1), 1)
ADD_WIDGET_VECTOR_SLIDER("Attach Position Offset", thisSwitchCam.nodes[iNodeIndex].vClonedNodeOffset, -10.0, 10.0, 0.1) //[MF] Bit of a hack to fix issue with cam being too high
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_POST_FX_WIDGET(thisSwitchCam, iNodeIndex)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur, 0.0, 1.0, 0.01)
CREATE_SPLINE_CAM_SHAKE_WIDGET(thisSwitchCam, iNodeIndex)
IF iNodeIndex > 0 AND iNodeIndex < (thisSwitchCam.iNumNodes - 1) //[MF] Ensure that the first or last node of a cam can't be set as a jump-cut node.
ADD_WIDGET_BOOL("Is Jump-Cut Node", thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode)
ENDIF
CREATE_SPLINE_CAM_EASE_WIDGET(thisSwitchCam, iNodeIndex)
START_WIDGET_GROUP("Time Scale")
ADD_WIDGET_FLOAT_SLIDER("Time Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScale, 0.0, 12.0, 0.01)
CREATE_SPLINE_CAM_TIME_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iTimeScaleEaseType)
ADD_WIDGET_FLOAT_SLIDER("Time Ease Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScaleEaseScaler, 0.0, 2.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_FLASH_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(thisSwitchCam, iNodeIndex)
ADD_WIDGET_BOOL("Is Low Detail Node", thisSwitchCam.nodes[iNodeIndex].bIsLowDetailNode)
ENDPROC
/// PURPOSE:
/// Create a widget for a Path Relative cam that is attached to a ped, but looking at a world coord
/// PARAMS:
/// thisSwitchCam - Switch cam struct to create the widget for
/// iNodeIndex - Node of the struct to contruct the widget from
PROC CREATE_SPLINE_CAM_WIDGET_PATH_RELATIVE_PED_TO_WORLD_COORD(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
ADD_WIDGET_INT_SLIDER("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime, 0, 20000, 25)
START_WIDGET_GROUP("Camera Offset and FOV")
ADD_WIDGET_VECTOR_SLIDER("Cam Look-At Coord", thisSwitchCam.nodes[iNodeIndex].vWorldPosLookAt, -10000.0, 10000.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("Cam Radius Offset From Origin Ped", thisSwitchCam.nodes[iNodeIndex].fNodeOffsetDist, -100.0, 100.0, 0.1)
ADD_WIDGET_FLOAT_SLIDER("Cam Height Offset From Origin Ped", thisSwitchCam.nodes[iNodeIndex].fNodeVerticleOffset, -100.0, 100.0, 0.5)
ADD_WIDGET_FLOAT_SLIDER("FOV", thisSwitchCam.nodes[iNodeIndex].fNodeFOV, 0.0, 360.0, 1.0)
ADD_WIDGET_BOOL("Attach to origin Ped", thisSwitchCam.nodes[iNodeIndex].bAttachToOriginPed)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_POST_FX_WIDGET(thisSwitchCam, iNodeIndex)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur, 0.0, 1.0, 0.01)
CREATE_SPLINE_CAM_SHAKE_WIDGET(thisSwitchCam, iNodeIndex)
IF iNodeIndex > 0 AND iNodeIndex < (thisSwitchCam.iNumNodes - 1) //[MF] Ensure that the first or last node of a cam can't be set as a jump-cut node.
ADD_WIDGET_BOOL("Is Jump-Cut Node", thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode)
ENDIF
CREATE_SPLINE_CAM_EASE_WIDGET(thisSwitchCam, iNodeIndex)
START_WIDGET_GROUP("Time Scale")
ADD_WIDGET_FLOAT_SLIDER("Time Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScale, 0.0, 12.0, 0.01)
CREATE_SPLINE_CAM_TIME_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iTimeScaleEaseType)
ADD_WIDGET_FLOAT_SLIDER("Time Ease Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScaleEaseScaler, 0.0, 2.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_FLASH_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(thisSwitchCam, iNodeIndex)
ADD_WIDGET_BOOL("Is Low Detail Node", thisSwitchCam.nodes[iNodeIndex].bIsLowDetailNode)
ENDPROC
/// PURPOSE:
/// Create a widget for a Path Relative cam that is attached to a ped, but looking at a world coord
/// PARAMS:
/// thisSwitchCam - Switch cam struct to create the widget for
/// iNodeIndex - Node of the struct to contruct the widget from
PROC CREATE_SPLINE_CAM_WIDGET_CLONE_NODE_WITH_OFFSET(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
ADD_WIDGET_INT_SLIDER("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime, 0, 20000, 25)
START_WIDGET_GROUP("Camera Position and Orientation")
ADD_WIDGET_INT_SLIDER("Node Index To Clone From", thisSwitchCam.nodes[iNodeIndex].iNodeToClone, 0, (thisSwitchCam.iNumNodes -1), 1)
ADD_WIDGET_VECTOR_SLIDER("Offset From Cloned Node", thisSwitchCam.nodes[iNodeIndex].vClonedNodeOffset, -1000.0, 1000.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_POST_FX_WIDGET(thisSwitchCam, iNodeIndex)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", thisSwitchCam.nodes[iNodeIndex].fNodeMotionBlur, 0.0, 1.0, 0.01)
CREATE_SPLINE_CAM_SHAKE_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_EASE_WIDGET(thisSwitchCam, iNodeIndex)
START_WIDGET_GROUP("Time Scale")
ADD_WIDGET_FLOAT_SLIDER("Time Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScale, 0.0, 12.0, 0.01)
CREATE_SPLINE_CAM_TIME_EASE_COMBO(thisSwitchCam.nodes[iNodeIndex].iTimeScaleEaseType)
ADD_WIDGET_FLOAT_SLIDER("Time Ease Scale", thisSwitchCam.nodes[iNodeIndex].fTimeScaleEaseScaler, 0.0, 2.0, 0.1)
STOP_WIDGET_GROUP()
CREATE_SPLINE_CAM_FLASH_WIDGET(thisSwitchCam, iNodeIndex)
CREATE_SPLINE_CAM_DOF_WIDGET_GROUP(thisSwitchCam, iNodeIndex)
ADD_WIDGET_BOOL("Is Low Detail Node", thisSwitchCam.nodes[iNodeIndex].bIsLowDetailNode)
ENDPROC
/// PURPOSE:
/// Create a widget for a character switch spline cut cam (used for jumping instatly from one cam to another)
/// PARAMS:
/// thisSwitchCam - Switch cam struct to get the cut cam info from
/// iNodeIndex - Index of the cut cam.
PROC CREATE_SPLINE_CAM_WIDGET_CUT_CAM(SWITCH_CAM_STRUCT &thisSwitchCam, INT iNodeIndex)
ADD_WIDGET_STRING("This Camera DOES NOT RENDER. It merely jumps to the next Camera Node")
ADD_WIDGET_STRING("To modify this camera you must edit the next Camera Node")
ADD_WIDGET_INT_READ_ONLY("Cam Time", thisSwitchCam.nodes[iNodeIndex].iNodeTime)
ADD_WIDGET_INT_READ_ONLY("", thisSwitchCam.nodes[iNodeIndex].iNodeActiveFlag)
ADD_WIDGET_BOOL("Is Jump-Cut Node", thisSwitchCam.nodes[iNodeIndex].bIsCamCutNode)
ENDPROC
/// PURPOSE:
/// Create the debug widgets for a custom character switch splin cam
/// PARAMS:
/// thisSwitchCam - Switch cam struct to create the widget for
/// strDebugEntity1Name - Display Name in the widget of the origin ped/vehicle EG. 'Franklin' or 'Car'
/// strDebugEntity2Name - Display Name in the widget of the destination ped/vehicle EG. 'Franklin' or 'Car'
/// wgidParent - ID of the widget group to parent the switch cam widget too
PROC CREATE_SPLINE_CAM_WIDGETS(SWITCH_CAM_STRUCT &thisSwitchCam, STRING strDebugEntity1Name, STRING strDebugEntity2Name, WIDGET_GROUP_ID wgidParent)
CDEBUG3LN(DEBUG_MISSION, "CREATE_SPLINE_CAM_WIDGETS")
thisSwitchCam.strCamTarget1WidgetLabel = strDebugEntity1Name
thisSwitchCam.strCamTarget2WidgetLabel = strDebugEntity2Name
TEXT_LABEL_63 txtGroupTitle = "Custom Switch Cameras - "
txtGroupTitle += thisSwitchCam.strCamTarget1WidgetLabel
IF NOT IS_STRING_NULL_OR_EMPTY(strDebugEntity2Name)
txtGroupTitle += " to "
txtGroupTitle += thisSwitchCam.strCamTarget2WidgetLabel
txtGroupTitle += " -"
ENDIF
IF DOES_WIDGET_GROUP_EXIST(thisSwitchCam.wgidWidgets)
DELETE_WIDGET_GROUP(thisSwitchCam.wgidWidgets)
ENDIF
thisSwitchCam.wgidParent = wgidParent
SET_CURRENT_WIDGET_GROUP(thisSwitchCam.wgidParent)
thisSwitchCam.wgidWidgets = START_WIDGET_GROUP(txtGroupTitle)
ADD_WIDGET_BOOL("Save Data to Text File", thisSwitchCam.bSaveTextFile)
ADD_WIDGET_BOOL("Save XML Data", thisSwitchCam.bSaveXMLFile)
ADD_WIDGET_BOOL("Load XML Data", thisSwitchCam.bLoadXMLFile)
ADD_WIDGET_BOOL("Recreate Camera Spline", thisSwitchCam.bRecreateSpline)
ADD_WIDGET_FLOAT_READ_ONLY("Spline Cam Phase", thisSwitchCam.fSplineCamPhase)
START_WIDGET_GROUP("Spline Cam Structure")
ADD_WIDGET_INT_SLIDER("Num Spline Cam Nodes", thisSwitchCam.iNumNodes, 0, MAX_NUM_SWITCH_NODES - 1, 1)
ADD_WIDGET_INT_SLIDER("Cam 'Switch Focus' Node", thisSwitchCam.iCamSwitchFocusNode, 0, MAX_NUM_SWITCH_NODES - 1, 1)
ADD_WIDGET_BOOL("Remove Spline Smoothing", thisSwitchCam.bSplineNoSmoothing)
ADD_WIDGET_BOOL("Recreate Widget", thisSwitchCam.bForceDebugWidgetRecreate)
STOP_WIDGET_GROUP()
INT i
START_WIDGET_GROUP("Cam Velocity Overrides")
ADD_WIDGET_BOOL("DEBUG: Disable Velocity Override", thisSwitchCam.bDEBUGSplineCam_DisableVelocityOverride)
REPEAT MAX_NUM_CAM_VELOCITY_OVERRIDES i
CREATE_SPLINE_CAM_VELOCITY_OVERRIDE_WIDGET(thisSwitchCam, i)
ENDREPEAT
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Cam Blur Overrides")
REPEAT MAX_NUM_CAM_BLUR_OVERRIDES i
CREATE_SPLINE_CAM_BLUR_OVERRIDE_WIDGET(thisSwitchCam, i)
ENDREPEAT
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Switch Cam Audio")
ADD_WIDGET_FLOAT_SLIDER("Start Switch Cam Audio", thisSwitchCam.fSwitchSoundAudioStartPhase, -1.0, 1.0, 0.1)
ADD_WIDGET_FLOAT_SLIDER("End Switch Cam Audio", thisSwitchCam.fSwitchSoundAudioEndPhase, -1.0, 1.0, 0.1)
ADD_WIDGET_BOOL("Play Start Pulse Audio", thisSwitchCam.bSwitchSoundPlayOpeningPulse)
ADD_WIDGET_BOOL("Play Movement Loop Audio", thisSwitchCam.bSwitchSoundPlayMoveLoop)
ADD_WIDGET_BOOL("Play End Pulse Audio", thisSwitchCam.bSwitchSoundPlayExitPulse)
STOP_WIDGET_GROUP()
TEXT_LABEL_63 txtLabel
REPEAT thisSwitchCam.iNumNodes i
txtLabel = "Cam "
txtLabel += i
txtLabel += " - "
IF thisSwitchCam.iCamSwitchFocusNode > 0
IF i < thisSwitchCam.iCamSwitchFocusNode
txtLabel += strDebugEntity1Name
ELIF i >= thisSwitchCam.iCamSwitchFocusNode
txtLabel += strDebugEntity2Name
ENDIF
ENDIF
IF i = (thisSwitchCam.iNumNodes - 1)
txtLabel += " End Cam"
ENDIF
IF IS_NODE_JUMP_CUT(thisSwitchCam, i)
txtLabel += " CUT NODE - IS READ ONLY"
ENDIF
START_WIDGET_GROUP(txtLabel)
IF NOT thisSwitchCam.nodes[i].bIsCamCutNode
thisSwitchCam.nodes[i].iSwitchCamTypeDebugSelect = ENUM_TO_INT(thisSwitchCam.nodes[i].SwitchCamType)
START_NEW_WIDGET_COMBO()
ADD_TO_WIDGET_COMBO("Old Switch Cam")
ADD_TO_WIDGET_COMBO("Entity Attached Cam")
ADD_TO_WIDGET_COMBO("Gameplay Cam Copy")
ADD_TO_WIDGET_COMBO("World Position Cam")
ADD_TO_WIDGET_COMBO("World Position Cam With Look At")
ADD_TO_WIDGET_COMBO("Path Relative")
ADD_TO_WIDGET_COMBO("Path Relative Attach")
ADD_TO_WIDGET_COMBO("Path Relative Ped to Coord")
ADD_TO_WIDGET_COMBO("Clone Node With Offset")
// ADD_TO_WIDGET_COMBO("Attached Cam With World Look At")
STOP_WIDGET_COMBO("Switch Cam Type", thisSwitchCam.nodes[i].iSwitchCamTypeDebugSelect)
ADD_WIDGET_INT_READ_ONLY("", thisSwitchCam.nodes[i].iNodeActiveFlag)
SWITCH thisSwitchCam.nodes[i].SwitchCamType
CASE SWITCH_CAM_OLD_SYSTEM
CREATE_SPLINE_CAM_WIDGET_OLD_STYLE(thisSwitchCam, i)
BREAK
CASE SWITCH_ENTITY_ATTACHED_CAM
CREATE_SPLINE_CAM_WIDGET_ATTACHED_CAM(thisSwitchCam, i)
BREAK
CASE SWITCH_CAM_GAMEPLAY_CAM_COPY
CREATE_SPLINE_CAM_WIDGET_GAMEPLAY_CAM_COPY(thisSwitchCam, i)
BREAK
CASE SWITCH_CAM_WORLD_POS
CREATE_SPLINE_CAM_WIDGET_WORLD_POS(thisSwitchCam, i)
BREAK
CASE SWITCH_CAM_WORLD_POS_W_LOOK_AT
CREATE_SPLINE_CAM_WIDGET_WORLD_POS_WITH_LOOK_AT(thisSwitchCam, i)
BREAK
CASE SWITCH_CAM_PATH_RELATIVE
CASE SWITCH_CAM_PATH_RELATIVE_ATTACHED
CREATE_SPLINE_CAM_WIDGET_PATH_RELATIVE(thisSwitchCam, i)
BREAK
CASE SWITCH_CAM_PATH_RELATIVE_PED_TO_WORLD_COORD
CREATE_SPLINE_CAM_WIDGET_PATH_RELATIVE_PED_TO_WORLD_COORD(thisSwitchCam, i)
BREAK
CASE SWITCH_CAM_CLONE_NODE_WITH_OFFSET
CREATE_SPLINE_CAM_WIDGET_CLONE_NODE_WITH_OFFSET(thisSwitchCam, i)
BREAK
// CASE SWITCH_CAM_ENTITY_ATTACHED_W_WORLD_LOOK_AT
// CREATE_SPLINE_CAM_WIDGET_ATTACHED_CAM_W_WORLD_LOOK_AT(thisSwitchCam, i)
// BREAK
ENDSWITCH
ELSE
CREATE_SPLINE_CAM_WIDGET_CUT_CAM(thisSwitchCam, i)
ENDIF
STOP_WIDGET_GROUP()
ENDREPEAT
START_WIDGET_GROUP("Spline Use Gameplay Cam")
ADD_WIDGET_BOOL("Add Gameplay Cam As Last Node", thisSwitchCam.bAddGameplayCamAsLastNode)
ADD_WIDGET_INT_SLIDER("Gameplay Node Length", thisSwitchCam.iGameplayNodeBlendDuration, -1, 20000, 25)
STOP_WIDGET_GROUP()
STOP_WIDGET_GROUP()
CLEAR_CURRENT_WIDGET_GROUP(thisSwitchCam.wgidParent)
ENDPROC
#ENDIF
FUNC VECTOR GET_NORMALISED_VERSION_OF_VECTOR(VECTOR vVector)
FLOAT magnitude = VMAG(vVector)
IF vVector.x <> 0
vVector.x = (vVector.x / magnitude)
ELSE
vVector.x = 0
ENDIF
IF vVector.y <> 0
vVector.y = (vVector.y / magnitude)
ELSE
vVector.y = 0
ENDIF
IF vVector.z <> 0
vVector.z = (vVector.z /magnitude)
ELSE
vVector.z = 0
ENDIF
RETURN vVector
ENDFUNC
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Update the widget displays and file saving of spline cam widgets. Must be called every frame.
/// PARAMS:
/// thisSwitchCam - Switch cam to update the widget from.
PROC UPDATE_SPLINE_CAM_WIDGETS(SWITCH_CAM_STRUCT &thisSwitchCam)
//CDEBUG3LN(DEBUG_MISSION, "UPDATE_SPLINE_CAM_WIDGETS")
IF thisSwitchCam.bSaveTextFile
WRITE_SPLINE_CAM_DATA_TO_FILE(thisSwitchCam)
thisSwitchCam.bSaveTextFile = FALSE
ENDIF
IF thisSwitchCam.bSaveXMLFile
OUTPUT_SPLINE_CAM_DATA_TO_XML(thisSwitchCam)
thisSwitchCam.bSaveXMLFile = FALSE
ENDIF
IF thisSwitchCam.bLoadXMLFile
LOAD_SPLINE_CAM_DATA_FROM_XML(thisSwitchCam)
thisSwitchCam.bLoadXMLFile = FALSE
ENDIF
IF thisSwitchCam.bForceDebugWidgetRecreate
thisSwitchCam.bForceDebugWidgetRecreate = FALSE
CREATE_SPLINE_CAM_WIDGETS(thisSwitchCam, thisSwitchCam.strCamTarget1WidgetLabel, thisSwitchCam.strCamTarget2WidgetLabel, thisSwitchCam.wgidParent)
ENDIF
IF thisSwitchCam.bRecreateSpline
thisSwitchCam.fSplineCamPhase = GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline)
IF DOES_CAM_EXIST(thisSwitchCam.ciSpline)
SET_CAM_ACTIVE(thisSwitchCam.ciSpline, FALSE)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
IF NOT DO_WE_WANT_TO_CLONE_GAMEPLAY_CAM(thisSwitchCam, 0)
DESTROY_ALL_CAMS()
PRINTLN("RECREATING SPLINE AND DELETING ALL NODES")
ELSE
INT i
REPEAT thisSwitchCam.iNumNodes i
IF i > 0
PRINTLN("RECREATING SPLINE AND DELETING NODE: ", i)
DESTROY_CAM(thisSwitchCam.nodes[i].ciSwitchNode)
ENDIF
ENDREPEAT
ENDIF
ENDIF
CREATE_SPLINE_CAM(thisSwitchCam)
WAIT(0)//[MF] Allow the cam to be created so we can properly activate it.
SET_CAM_ACTIVE(thisSwitchCam.ciSpline, TRUE)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
WAIT(0)//[MF] Allow the cam to be created so we can set the phase correctly
SET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline, thisSwitchCam.fSplineCamPhase)
thisSwitchCam.bRecreateSpline = FALSE
ENDIF
IF DOES_CAM_EXIST(thisSwitchCam.ciSpline)
thisSwitchCam.fSplineCamPhase = GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline)
ELSE
thisSwitchCam.fSplineCamPhase = -1.0
ENDIF
INT i
REPEAT thisSwitchCam.iNumNodes i
IF ENUM_TO_INT(thisSwitchCam.nodes[i].SwitchCamType) != thisSwitchCam.nodes[i].iSwitchCamTypeDebugSelect
thisSwitchCam.nodes[i].SwitchCamType = INT_TO_ENUM(SWITCH_CAM_TYPE, thisSwitchCam.nodes[i].iSwitchCamTypeDebugSelect)
ENDIF
IF ENUM_TO_INT(thisSwitchCam.nodes[i].NodeTimePostFX_Type) != thisSwitchCam.nodes[i].iNodeTimePostFX_WidgetValue
thisSwitchCam.nodes[i].NodeTimePostFX_Type = INT_TO_ENUM(SWITCH_CAM_POST_FX_TYPE, thisSwitchCam.nodes[i].iNodeTimePostFX_WidgetValue)
ENDIF
IF ENUM_TO_INT(thisSwitchCam.nodes[i].NodeCamShakeType) != thisSwitchCam.nodes[i].iNodeCamShakeType_WidgetValue
thisSwitchCam.nodes[i].NodeCamShakeType = INT_TO_ENUM(SWITCH_CAM_SHAKE_TYPE, thisSwitchCam.nodes[i].iNodeCamShakeType_WidgetValue)
ENDIF
IF ENUM_TO_INT(thisSwitchCam.nodes[i].SCFE_FlashEffectUsed) != thisSwitchCam.nodes[i].iFlashEffectUsed_WidgetValue
thisSwitchCam.nodes[i].SCFE_FlashEffectUsed = INT_TO_ENUM(SWITCH_CAM_FLASH_EFFECT, thisSwitchCam.nodes[i].iFlashEffectUsed_WidgetValue)
ENDIF
ENDREPEAT
IF bStopOnNode
IF DOES_CAM_EXIST(thisSwitchCam.ciSpline)
iActiveNode = GET_CAM_SPLINE_NODE_INDEX(thisSwitchCam.ciSpline)
//display what node is active
REPEAT MAX_NUM_SWITCH_NODES i
IF thisSwitchCam.nodes[i].iNodeActiveFlag <> -1
thisSwitchCam.nodes[i].iNodeActiveFlag = -1
ENDIF
ENDREPEAT
IF thisSwitchCam.nodes[iActiveNode].iNodeActiveFlag = -1
thisSwitchCam.nodes[iActiveNode].iNodeActiveFlag = 9999
ENDIF
IF IS_CAM_ACTIVE(GET_DEBUG_CAM())
AND (IS_BUTTON_JUST_PRESSED(PAD1, TRIANGLE)//copy camera info into the current node
OR IS_BUTTON_JUST_PRESSED(DEBUG_PAD, TRIANGLE))
ENTITY_INDEX eiCameraTargetEntity
IF DOES_ENTITY_EXIST(GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iActiveNode))
eiCameraTargetEntity = GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iActiveNode)
ENDIF
VECTOR entityForward, entityRight, entityUp, entityPosition
GET_ENTITY_MATRIX(eiCameraTargetEntity, entityForward, entityRight, entityUp, entityPosition)
vNodeDirection = GET_CAM_ROT(GET_DEBUG_CAM())
thisSwitchCam.nodes[iActiveNode].vNodePos = GET_CAM_COORD(GET_DEBUG_CAM()) - entityPosition
IF thisSwitchCam.nodes[iActiveNode].bAttachOffsetIsRelative
VECTOR cameraPosition = GET_CAM_COORD(GET_DEBUG_CAM())
VECTOR entityToCamera = cameraPosition - entityPosition
thisSwitchCam.nodes[iActiveNode].vNodePos.y = DOT_PRODUCT(entityToCamera, entityForward)
thisSwitchCam.nodes[iActiveNode].vNodePos.x = DOT_PRODUCT(entityToCamera, entityRight)
thisSwitchCam.nodes[iActiveNode].vNodePos.z = DOT_PRODUCT(entityToCamera, entityUp)
ENDIF
IF thisSwitchCam.nodes[iActiveNode].bPointAtEntity = FALSE
thisSwitchCam.nodes[iActiveNode].vNodeDir = vNodeDirection
ELSE
IF thisSwitchCam.nodes[iActiveNode].iForceCamPointAtEntityIndex > -1
eiCameraTargetEntity = GET_SWITCH_CAM_FOCUS_ENTITY(thisSwitchCam, iActiveNode, thisSwitchCam.nodes[iActiveNode].iForceCamPointAtEntityIndex)
entityPosition = GET_POSITION_OF_SWITCH_CAM_TARGET_ENTITY(thisSwitchCam, thisSwitchCam.nodes[iActiveNode].iForceCamPointAtEntityIndex)
ENDIF
VECTOR cameraPosition = GET_CAM_COORD(GET_DEBUG_CAM())
VECTOR cameraForward = CONVERT_EULER_TO_DIRECTION_VECTOR(vNodeDirection)
VECTOR cameraToEntity = entityPosition - cameraPosition
FLOAT dotProduct = DOT_PRODUCT(cameraToEntity, cameraForward)
VECTOR lookAtPoint = cameraForward * dotProduct
lookAtPoint = lookAtPoint + cameraPosition // add camera position to get look at point
IF thisSwitchCam.nodes[iActiveNode].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[iActiveNode].vNodeDir = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(eiCameraTargetEntity, lookAtPoint)
ELSE
VECTOR entityToLookat = lookAtPoint - entityPosition
thisSwitchCam.nodes[iActiveNode].vNodeDir.y = DOT_PRODUCT(entityToLookat, entityForward)
thisSwitchCam.nodes[iActiveNode].vNodeDir.x = DOT_PRODUCT(entityToLookat, entityRight)
thisSwitchCam.nodes[iActiveNode].vNodeDir.z = DOT_PRODUCT(entityToLookat, entityUp)
ENDIF
ENDIF
IF thisSwitchCam.nodes[iActiveNode].SwitchCamType = SWITCH_CAM_WORLD_POS
thisSwitchCam.nodes[iActiveNode].vNodePos = GET_CAM_COORD(GET_DEBUG_CAM())
thisSwitchCam.nodes[iActiveNode].fNodeFOV = GET_CAM_FOV(GET_DEBUG_CAM())
ENDIF
IF thisSwitchCam.nodes[iActiveNode].SwitchCamType = SWITCH_CAM_WORLD_POS_W_LOOK_AT
thisSwitchCam.nodes[iActiveNode].vWorldPosLookAt = GET_CAM_COORD(GET_DEBUG_CAM())
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
#ENDIF