// Includes USING "rage_builtins.sch" USING "globals.sch" USING "commands_camera.sch" USING "commands_pad.sch" USING "commands_misc.sch" USING "commands_script.sch" USING "commands_streaming.sch" USING "script_player.sch" // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // MISSION NAME : charAnimTest.sc // AUTHOR : // DESCRIPTION : Script tool to test character anims at specific phases. // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** #IF IS_DEBUG_BUILD // ----------------------------------------------------------------------------------------------------------- // Variable declaration // ----------------------------------------------------------------------------------------------------------- // Includes USING "charAnimTest.sch" // Constants CONST_INT MODEL_TIMEOUT 3000 // Anim widgets WIDGET_GROUP_ID widgetGroup BOOL bUseIdleAnims = TRUE FLOAT fIdleTime = 5.0 FLOAT fIdleShot = 2.5 INT iIdleTimer = 0 TEXT_WIDGET_ID widgetAnimDict TEXT_WIDGET_ID widgetAnimName STRING sAnimDict = "" STRING sAnimName = "" FLOAT fAnimPhase = 0.0 FLOAT fPhaseMin = 0.0 FLOAT fPhaseMax = 1.0 // Prop widgets OBJECT_INDEX propIndex INT iPropModel INT iLastModel INT iPropAttachBone VECTOR vPropOffset = <<0,0,0>> VECTOR vPropRot = <<0,0,0>> BOOL bUseProp = FALSE BOOL bLiveUpdate = FALSE // Screenshot widgets TEXT_WIDGET_ID widgetFolderName TEXT_WIDGET_ID widgetShotName STRING sFolderName = "X:/GTA5/" STRING sShotName = "testShot" INT iScreenShot = 0 BOOL bScreenShot = FALSE BOOL bUseScreenCount = TRUE BOOL bUseModelName = TRUE // Ped widgets BOOL bToggleAllPeds = FALSE BOOL bToggleAmbient = FALSE BOOL bToggleGang = FALSE BOOL bToggleUnique = FALSE BOOL bToggledOn[4] BOOL bShowAFM = FALSE BOOL bShowAFO = FALSE BOOL bShowAFY = FALSE BOOL bShowAMM = FALSE BOOL bShowAMO = FALSE BOOL bShowAMY = FALSE BOOL bShowGFY = FALSE BOOL bShowGMM = FALSE BOOL bShowGMY = FALSE BOOL bShowUFM = FALSE BOOL bShowUFO = FALSE BOOL bShowUFY = FALSE BOOL bShowUMM = FALSE BOOL bShowUMO = FALSE BOOL bShowUMY = FALSE // Camera widgets CAMERA_INDEX ciTestCamera VECTOR vCameraPos = <<2013.4475, 2851.7219, 50.9609>> VECTOR vCameraRot = <<-13.1265, -0.0000, 173.5950>> FLOAT fCameraFOV = 50.0000 BOOL bGetCurrentCam = FALSE // Control variables BOOL bTestSceneOn = FALSE BOOL bFullTestOn = FALSE BOOL bTestActive = FALSE // Character index PED_INDEX piCharacter // ----------------------------------------------------------------------------------------------------------- // Script Cleanup // ----------------------------------------------------------------------------------------------------------- /// PURPOSE: Removes anim dictionary PROC UNLOAD_ANIM_DICT() IF NOT IS_STRING_NULL_OR_EMPTY(sAnimDict) PRINTLN("charAnimTest: Unloaded animation dictionary...") REMOVE_ANIM_DICT(sAnimDict) ENDIF ENDPROC /// PURPOSE: Toggle specific camera for test PROC TOGGLE_TEST_CAMERA(BOOL bOn, BOOL bResetCam=TRUE) IF bOn IF NOT DOES_CAM_EXIST(ciTestCamera) PRINTLN("charAnimTest: Creating and setting camera...") ciTestCamera = CREATE_CAMERA_WITH_PARAMS(CAMTYPE_SCRIPTED, vCameraPos, vCameraRot, fCameraFOV) SET_CAM_ACTIVE(ciTestCamera, TRUE) RENDER_SCRIPT_CAMS(TRUE, FALSE, 0) ENDIF ELSE IF DOES_CAM_EXIST(ciTestCamera) IF IS_CAM_ACTIVE(ciTestCamera) SET_CAM_ACTIVE(ciTestCamera, FALSE) ENDIF DESTROY_CAM(ciTestCamera) ENDIF // Set camera behind player IF bResetCam PRINTLN("charAnimTest: Restoring normal camera...") RENDER_SCRIPT_CAMS(FALSE, FALSE) SET_GAMEPLAY_CAM_RELATIVE_HEADING() ENDIF ENDIF ENDPROC /// PURPOSE: Deletes widget box PROC CLEANUP_TEST() // Remove animation dictionary UNLOAD_ANIM_DICT() // Reset camera TOGGLE_TEST_CAMERA(FALSE) // Remove prop IF DOES_ENTITY_EXIST(propIndex) DELETE_OBJECT(propIndex) ENDIF // Remove ped IF DOES_ENTITY_EXIST(piCharacter) DELETE_PED(piCharacter) ENDIF // Cleanup widgets IF DOES_WIDGET_GROUP_EXIST(widgetGroup) DELETE_WIDGET_GROUP(widgetGroup) ENDIF ENDPROC #ENDIF /// PURPOSE: Removes any active models, anims and resets camera PROC SCRIPT_CLEANUP() #IF IS_DEBUG_BUILD PRINTLN("charAnimTest: Cleanup") #ENDIF #IF IS_DEBUG_BUILD CLEANUP_TEST() #ENDIF TERMINATE_THIS_THREAD() ENDPROC #IF IS_DEBUG_BUILD /// PURPOSE: Checks for player pressing debug key to cancel script PROC CHECK_DEBUG_CLEANUP() IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)) OR (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)) OR (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)) SCRIPT_CLEANUP() ENDIF ENDPROC // ----------------------------------------------------------------------------------------------------------- // Initialisation // ----------------------------------------------------------------------------------------------------------- /// PURPOSE: Initialise widgets with initial values PROC SETUP_WIDGETS() // Setup widget widgetGroup = START_WIDGET_GROUP("Character Anim Test") // Animation related widget START_WIDGET_GROUP("Animation Settings") // Idle animations ADD_WIDGET_BOOL("Use Idle Animations", bUseIdleAnims) ADD_WIDGET_FLOAT_SLIDER("Idle Time", fIdleTime, 0, 10, 0.1) ADD_WIDGET_FLOAT_SLIDER("Screenshot Time", fIdleShot, 0, 10, 0.1) // Specified animations widgetAnimDict = ADD_TEXT_WIDGET("Animation Dictionary") widgetAnimName = ADD_TEXT_WIDGET("Animation Name") ADD_WIDGET_FLOAT_SLIDER("Start Phase", fPhaseMin, 0, 1, 0.01) ADD_WIDGET_FLOAT_SLIDER("Screenshot Phase", fAnimPhase, 0, 1, 0.01) ADD_WIDGET_FLOAT_SLIDER("End Phase", fPhaseMax, 0, 1, 0.01) SET_CONTENTS_OF_TEXT_WIDGET(widgetAnimDict, sAnimDict) SET_CONTENTS_OF_TEXT_WIDGET(widgetAnimName, sAnimName) STOP_WIDGET_GROUP() // Prop widget START_WIDGET_GROUP("Prop Settings") ADD_WIDGET_BOOL("Use Prop", bUseProp) ADD_WIDGET_BOOL("Test Scene Update", bLiveUpdate) // Prop list START_NEW_WIDGET_COMBO() ADD_TO_WIDGET_COMBO("P_AMB_COFFEECUP_01") ADD_TO_WIDGET_COMBO("P_CS_JOINT_01") ADD_TO_WIDGET_COMBO("PROP_CS_BEER_BOT_01") ADD_TO_WIDGET_COMBO("PROP_CS_BEER_BOT_40OZ") ADD_TO_WIDGET_COMBO("PROP_CS_CIGGY_01") ADD_TO_WIDGET_COMBO("PROP_PHONE_ING") ADD_TO_WIDGET_COMBO("PROP_PLASTIC_CUP_02") STOP_WIDGET_COMBO("Prop Model", iPropModel) // Ped bone attachment START_NEW_WIDGET_COMBO() ADD_TO_WIDGET_COMBO("Left Hand") ADD_TO_WIDGET_COMBO("Right Hand") STOP_WIDGET_COMBO("Prop Attachment", iPropAttachBone) // Offset and Rotation ADD_WIDGET_FLOAT_SLIDER("Offset X", vPropOffset.x, -1, 1, 0.01) ADD_WIDGET_FLOAT_SLIDER("Offset Y", vPropOffset.y, -1, 1, 0.01) ADD_WIDGET_FLOAT_SLIDER("Offset Z", vPropOffset.z, -1, 1, 0.01) ADD_WIDGET_FLOAT_SLIDER("Rot X", vPropRot.x, -360, 360, 1) ADD_WIDGET_FLOAT_SLIDER("Rot Y", vPropRot.y, -360, 360, 1) ADD_WIDGET_FLOAT_SLIDER("Rot Z", vPropRot.z, -360, 360, 1) STOP_WIDGET_GROUP() // Screenshot settings START_WIDGET_GROUP("Screenshot Settings") widgetFolderName = ADD_TEXT_WIDGET("Folder Name") widgetShotName = ADD_TEXT_WIDGET("Screenshot Name") SET_CONTENTS_OF_TEXT_WIDGET(widgetFolderName, sFolderName) SET_CONTENTS_OF_TEXT_WIDGET(widgetShotName, sShotName) // Removed on request to simplify as this behaviour is wanted by default // ADD_WIDGET_BOOL("Use Screenshot Numbering", bUseScreenCount) // ADD_WIDGET_BOOL("Include Model Name", bUseModelName) STOP_WIDGET_GROUP() // Ped settings START_WIDGET_GROUP("Ped Models") ADD_WIDGET_BOOL("Toggle All Peds (On/Off)", bToggleAllPeds) ADD_WIDGET_STRING("Ambient Peds") ADD_WIDGET_BOOL("Toggle Ambient (On/Off)", bToggleAmbient) ADD_WIDGET_BOOL("A_F_M", bShowAFM) ADD_WIDGET_BOOL("A_F_O", bShowAFO) ADD_WIDGET_BOOL("A_F_Y", bShowAFY) ADD_WIDGET_BOOL("A_M_M", bShowAMM) ADD_WIDGET_BOOL("A_M_O", bShowAMO) ADD_WIDGET_BOOL("A_M_Y", bShowAMY) ADD_WIDGET_STRING("Gang Peds") ADD_WIDGET_BOOL("Toggle Gang (On/Off)", bToggleGang) ADD_WIDGET_BOOL("G_F_Y", bShowGFY) ADD_WIDGET_BOOL("G_M_M", bShowGMM) ADD_WIDGET_BOOL("G_M_O", bShowGMY) ADD_WIDGET_STRING("Unique Peds") ADD_WIDGET_BOOL("Toggle Unique (On/Off)", bToggleUnique) ADD_WIDGET_BOOL("U_F_M", bShowUFM) ADD_WIDGET_BOOL("U_F_O", bShowUFO) ADD_WIDGET_BOOL("U_F_Y", bShowUFY) ADD_WIDGET_BOOL("U_M_M", bShowUMM) ADD_WIDGET_BOOL("U_M_O", bShowUMO) ADD_WIDGET_BOOL("U_M_Y", bShowUMY) STOP_WIDGET_GROUP() // Camera related settings START_WIDGET_GROUP("Camera Settings") ADD_WIDGET_FLOAT_SLIDER("Cam X", vCameraPos.x, -5000, 5000, 1) ADD_WIDGET_FLOAT_SLIDER("Cam Y", vCameraPos.y, -5000, 5000, 1) ADD_WIDGET_FLOAT_SLIDER("Cam Z", vCameraPos.z, -5000, 5000, 1) ADD_WIDGET_FLOAT_SLIDER("Rot X", vCameraRot.x, -5000, 5000, 1) ADD_WIDGET_FLOAT_SLIDER("Rot Y", vCameraRot.y, -5000, 5000, 1) ADD_WIDGET_FLOAT_SLIDER("Rot Z", vCameraRot.z, -5000, 5000, 1) ADD_WIDGET_FLOAT_SLIDER("F.O.V", fCameraFOV, -360, 360, 1) ADD_WIDGET_BOOL("Update with Current Debug Cam", bGetCurrentCam) STOP_WIDGET_GROUP() // START!!! ADD_WIDGET_STRING("CHARACTER ANIMATION TEST") ADD_WIDGET_BOOL("Start Test Scene", bTestSceneOn) ADD_WIDGET_BOOL("Start Full Run", bFullTestOn) STOP_WIDGET_GROUP() // Initialise ped toggles INT i FOR i = 0 TO 3 bToggledOn[i] = FALSE ENDFOR // Load model enums into array INIT_MODEL_ENUMS() INIT_PROP_ENUMS() ENDPROC /// PURPOSE: Loads animation dictionary into memory PROC LOAD_ANIM_DICT() IF NOT bUseIdleAnims IF NOT IS_STRING_NULL_OR_EMPTY(sAnimDict) AND NOT IS_STRING_NULL_OR_EMPTY(sAnimName) PRINTLN("charAnimTest: Requesting animation dictionary: ", sAnimDict) REQUEST_ANIM_DICT(sAnimDict) WHILE NOT HAS_ANIM_DICT_LOADED(sAnimDict) WAIT(0) ENDWHILE PRINTLN("charAnimTest: Loaded animation dictionary...") ELSE PRINTLN("charAnimTest: No dictionary or anim name specified...") ENDIF ELSE PRINTLN("charAnimTest: No need to load animations...") ENDIF ENDPROC // ----------------------------------------------------------------------------------------------------------- // Character functions // ----------------------------------------------------------------------------------------------------------- /// PURPOSE: Has this ped model been selected in the RAG widget? FUNC BOOL HAS_CHARACTER_MODEL_BEEN_SELECTED(INT iIndex) // Ambient peds IF bShowAFM IF (iIndex >= A_F_M_START AND iIndex <= A_F_M_END) RETURN TRUE ENDIF ENDIF IF bShowAFO IF (iIndex >= A_F_O_START AND iIndex <= A_F_O_END) RETURN TRUE ENDIF ENDIF IF bShowAFY IF (iIndex >= A_F_Y_START AND iIndex <= A_F_Y_END) RETURN TRUE ENDIF ENDIF IF bShowAMM IF (iIndex >= A_M_M_START AND iIndex <= A_M_M_END) RETURN TRUE ENDIF ENDIF IF bShowAMO IF (iIndex >= A_M_O_START AND iIndex <= A_M_O_END) RETURN TRUE ENDIF ENDIF IF bShowAMY IF (iIndex >= A_M_Y_START AND iIndex <= A_M_Y_END) RETURN TRUE ENDIF ENDIF // Gang peds IF bShowGFY IF (iIndex >= G_F_Y_START AND iIndex <= G_F_Y_END) RETURN TRUE ENDIF ENDIF IF bShowGMM IF (iIndex >= G_M_M_START AND iIndex <= G_M_M_END) RETURN TRUE ENDIF ENDIF IF bShowGMY IF (iIndex >= G_M_Y_START AND iIndex <= G_M_Y_END) RETURN TRUE ENDIF ENDIF // Unique peds IF bShowUFM IF (iIndex >= U_F_M_START AND iIndex <= U_F_M_END) RETURN TRUE ENDIF ENDIF IF bShowUFO IF (iIndex >= U_F_O_START AND iIndex <= U_F_O_END) RETURN TRUE ENDIF ENDIF IF bShowUFY IF (iIndex >= U_F_Y_START AND iIndex <= U_F_Y_END) RETURN TRUE ENDIF ENDIF IF bShowUMM IF (iIndex >= U_M_M_START AND iIndex <= U_M_M_END) RETURN TRUE ENDIF ENDIF IF bShowUMO IF (iIndex >= U_M_O_START AND iIndex <= U_M_O_END) RETURN TRUE ENDIF ENDIF IF bShowUMY IF (iIndex >= U_M_Y_START AND iIndex <= U_M_Y_END) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Create character for anim test FUNC BOOL CREATE_CHARACTER(INT iIndex, BOOL bOn) IF bOn // Locals MODEL_NAMES thisModel = DUMMY_MODEL_FOR_SCRIPT INT iTimeOut = GET_GAME_TIMER() + MODEL_TIMEOUT // Set model based on index or test scene model IF bTestSceneOn = TRUE AND bFullTestOn = FALSE thisModel = A_M_Y_BEACH_01 ELSE thisModel = eModelName[iIndex] ENDIF PRINTLN("charAnimTest: Requesting ped model...") REQUEST_MODEL(thisModel) WHILE NOT HAS_MODEL_LOADED(thisModel) // Have we taken too long to load model (e.g. missing from datafile) IF GET_GAME_TIMER() > iTimeOut PRINTLN("charAnimTest: Timeout on model load for ", GET_MODEL_NAME_FOR_DEBUG(thisModel)) RETURN FALSE ENDIF WAIT(0) ENDWHILE IF bUseProp PRINTLN("charAnimTest: Requesting prop model...") REQUEST_MODEL(ePropName[iPropModel]) WHILE NOT HAS_MODEL_LOADED(ePropName[iPropModel]) // Have we taken too long to load prop... IF GET_GAME_TIMER() > iTimeOut PRINTLN("charAnimTest: Timeout on model load for ", GET_MODEL_NAME_FOR_DEBUG(ePropName[iPropModel])) RETURN FALSE ENDIF WAIT(0) ENDWHILE // Store this so we know if it has been altered for Live Update... iLastModel = iPropModel ENDIF // Get ground coords FLOAT fZ GET_GROUND_Z_FOR_3D_COORD(<<2013.12, 2848.46, 50.25>>, fZ) PRINTLN("charAnimTest: Creating ped model: ", GET_MODEL_NAME_FOR_DEBUG(thisModel)) WHILE NOT DOES_ENTITY_EXIST(piCharacter) piCharacter = CREATE_PED(PEDTYPE_MISSION, thisModel, <<2013.12, 2848.46, fZ>>, -23.49, FALSE, FALSE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(piCharacter, TRUE) ENDWHILE IF bUseProp PRINTLN("charAnimTest: Creating prop model: ", GET_MODEL_NAME_FOR_DEBUG(ePropName[iPropModel])) IF DOES_ENTITY_EXIST(piCharacter) propIndex = CREATE_OBJECT(ePropName[iPropModel], GET_ENTITY_COORDS(piCharacter)) IF (iPropAttachBone = 0) ATTACH_ENTITY_TO_ENTITY(propIndex, piCharacter, GET_PED_BONE_INDEX(piCharacter, BONETAG_PH_L_HAND), vPropOffset, vPropRot) ELSE ATTACH_ENTITY_TO_ENTITY(propIndex, piCharacter, GET_PED_BONE_INDEX(piCharacter, BONETAG_PH_R_HAND), vPropOffset, vPropRot) ENDIF ELSE PRINTLN("charAnimTest: Character didn't exist - unable to create and attach prop... ") ENDIF PRINTLN("charAnimTest: Prop created... ") SET_MODEL_AS_NO_LONGER_NEEDED(ePropName[iPropModel]) ENDIF PRINTLN("charAnimTest: Ped created...") SET_MODEL_AS_NO_LONGER_NEEDED(thisModel) RETURN TRUE ELSE PRINTLN("charAnimTest: Cleaning up ped...") IF DOES_ENTITY_EXIST(propIndex) DELETE_OBJECT(propIndex) ENDIF IF DOES_ENTITY_EXIST(piCharacter) DELETE_PED(piCharacter) ENDIF RETURN TRUE ENDIF ENDFUNC /// PURPOSE: Play animation on a specified ped PROC PLAY_ANIM_ON_CHARACTER() IF DOES_ENTITY_EXIST(piCharacter) AND NOT IS_ENTITY_DEAD(piCharacter) IF bUseIdleAnims PRINTLN("charAnimTest: Playing idle animation on ped...") bScreenShot = FALSE ELSE IF NOT IS_STRING_NULL_OR_EMPTY(sAnimDict) AND NOT IS_STRING_NULL_OR_EMPTY(sAnimName) IF HAS_ANIM_DICT_LOADED(sAnimDict) PRINTLN("charAnimTest: Playing animation on ped...") IF bFullTestOn TASK_PLAY_ANIM(piCharacter, sAnimDict, sAnimName, INSTANT_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_DEFAULT, fPhaseMin) ELSE TASK_PLAY_ANIM(piCharacter, sAnimDict, sAnimName, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING) ENDIF bScreenShot = FALSE ELSE PRINTLN("charAnimTest: Specified animation dictionary isn't loaded...") ENDIF ELSE PRINTLN("charAnimTest: Animation and/or dictionary haven't been defined...") ENDIF ENDIF ELSE PRINTLN("charAnimTest: Ped isn't valid or dead when attempting to play animation...") ENDIF ENDPROC /// PURPOSE: Waits for animation to play on specified ped FUNC BOOL HAS_ANIM_STARTED_ON_CHARACTER() IF DOES_ENTITY_EXIST(piCharacter) AND NOT IS_ENTITY_DEAD(piCharacter) IF bUseIdleAnims PRINTLN("charAnimTest: Ped started idle animation...") iIdleTimer = GET_GAME_TIMER() RETURN TRUE ENDIF IF ((GET_SCRIPT_TASK_STATUS(piCharacter, SCRIPT_TASK_PLAY_ANIM) = PERFORMING_TASK) OR (GET_SCRIPT_TASK_STATUS(piCharacter, SCRIPT_TASK_PLAY_ANIM) = WAITING_TO_START_TASK)) PRINTLN("charAnimTest: Ped started animation...") RETURN TRUE ELSE RETURN FALSE ENDIF ELSE PRINTLN("charAnimTest: Ped no longer valid or dead...") RETURN FALSE ENDIF ENDFUNC // ----------------------------------------------------------------------------------------------------------- // Screenshot functions // ----------------------------------------------------------------------------------------------------------- /// PURPOSE: Build screenshot name from model name and save to file PROC TAKE_SCREENSHOT(INT iIndex) // Check widget for screenshot name sFolderName = GET_CONTENTS_OF_TEXT_WIDGET(widgetFolderName) sShotName = GET_CONTENTS_OF_TEXT_WIDGET(widgetShotName) // Build screenshot name and directory TEXT_LABEL_63 sTemp = sFolderName sTemp += sShotName IF bUseScreenCount IF iScreenShot < 10 sTemp += "_0" ELSE sTemp += "_" ENDIF sTemp += iScreenShot ENDIF IF bUseModelName sTemp += "_" sTemp += GET_MODEL_NAME_FOR_DEBUG(eModelName[iIndex]) ENDIF // Take screenshot SAVE_SCREENSHOT(sTemp) bScreenShot = TRUE ENDPROC /// PURPOSE: Take screenshot at specified time during idle animation FUNC BOOL TAKE_SCREENSHOT_AT_TIME(INT iIndex) IF DOES_ENTITY_EXIST(piCharacter) AND NOT IS_ENTITY_DEAD(piCharacter) INT iCurrentAnimTime = GET_GAME_TIMER() - iIdleTimer // Check for screenshot IF NOT bScreenShot IF (iCurrentAnimTime > fIdleShot*1000) TAKE_SCREENSHOT(iIndex) ENDIF ENDIF // Finished idle duration IF (iCurrentAnimTime > fIdleTime*1000) PRINTLN("charAnimTest: Ped finished idle animation after specified duration.") RETURN TRUE ENDIF ELSE PRINTLN("charAnimTest: Ped died during idle animation...") RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Take screenshot at specified phase FUNC BOOL TAKE_SCREENSHOT_AT_PHASE(INT iIndex) IF DOES_ENTITY_EXIST(piCharacter) AND NOT IS_ENTITY_DEAD(piCharacter) // Ped is either playing or getting ready to play anim IF ((GET_SCRIPT_TASK_STATUS(piCharacter, SCRIPT_TASK_PLAY_ANIM) = PERFORMING_TASK) OR (GET_SCRIPT_TASK_STATUS(piCharacter, SCRIPT_TASK_PLAY_ANIM) = WAITING_TO_START_TASK)) // Ped is definitely playing animation IF GET_SCRIPT_TASK_STATUS(piCharacter, SCRIPT_TASK_PLAY_ANIM) = PERFORMING_TASK // Get current animation phase FLOAT fCurrentPhase = GET_ENTITY_ANIM_CURRENT_TIME(piCharacter, sAnimDict, sAnimName) // Check for screenshot IF NOT bScreenShot IF (fCurrentPhase >= fAnimPhase) TAKE_SCREENSHOT(iIndex) ENDIF ENDIF // Need to exit before animation has finished? IF fPhaseMax < 1.0 IF (fCurrentPhase >= fPhaseMax) PRINTLN("charAnimTest: Ped finished animation early at specified phase ", fPhaseMax) RETURN TRUE ENDIF ENDIF ENDIF ELSE PRINTLN("charAnimTest: Ped finished animation...") RETURN TRUE ENDIF ELSE PRINTLN("charAnimTest: Ped died during animation...") RETURN TRUE ENDIF RETURN FALSE ENDFUNC // ----------------------------------------------------------------------------------------------------------- // Widget functions // ----------------------------------------------------------------------------------------------------------- /// PURPOSE: Caps the idle time if min or max values are updated PROC CHECK_IDLE_TIME_VALUES IF (fIdleTime < fIdleShot) fIdleShot = fIdleTime ENDIF IF (fIdleShot > fIdleTime) fIdleShot = fIdleTime ENDIF ENDPROC /// PURPOSE: Caps the animation phase if min or max values are updated PROC CHECK_ANIM_PHASE_VALUES IF (fPhaseMin > fPhaseMax) fPhaseMax = fPhaseMin ENDIF IF (fPhaseMin > fAnimPhase) fAnimPhase = fPhaseMin ENDIF IF (fPhaseMax < fAnimPhase) fAnimPhase = fPhaseMax ENDIF ENDPROC /// PURPOSE: Toggles ped models either on or off PROC TOGGLE_PEDS(BOOL bOn, BOOL bAmbient, BOOL bGang, BOOL bUnique) // Ambient peds IF bAmbient bShowAFM = bOn bShowAFO = bOn bShowAFY = bOn bShowAMM = bOn bShowAMO = bOn bShowAMY = bOn ENDIF // Gang peds IF bGang bShowGFY = bOn bShowGMM = bOn bShowGMY = bOn ENDIF // Unique peds IF bUnique bShowUFM = bOn bShowUFO = bOn bShowUFY = bOn bShowUMM = bOn bShowUMO = bOn bShowUMY = bOn ENDIF ENDPROC /// PURPOSE: Checks for prop settings being updated PROC CHECK_FOR_PROP_UPDATE() IF bUseProp IF bLiveUpdate IF DOES_ENTITY_EXIST(piCharacter) AND DOES_ENTITY_EXIST(propIndex) IF NOT IS_ENTITY_DEAD(piCharacter) // Model has been updated IF iPropModel != iLastModel // Request new model REQUEST_MODEL(ePropName[iPropModel]) WHILE NOT HAS_MODEL_LOADED(ePropName[iPropModel]) WAIT(0) ENDWHILE // Delete old prop... IF DOES_ENTITY_EXIST(propIndex) DELETE_OBJECT(propIndex) ENDIF // And create new prop... propIndex = CREATE_OBJECT(ePropName[iPropModel], GET_ENTITY_COORDS(piCharacter)) // Update reference to last model iLastModel = iPropModel ELSE // Need to reattach current prop to new position IF IS_ENTITY_ATTACHED_TO_ENTITY(propIndex, piCharacter) DETACH_ENTITY(propIndex) ENDIF ENDIF // Attach to relevant hand IF (iPropAttachBone = 0) ATTACH_ENTITY_TO_ENTITY(propIndex, piCharacter, GET_PED_BONE_INDEX(piCharacter, BONETAG_PH_L_HAND), vPropOffset, vPropRot) ELSE ATTACH_ENTITY_TO_ENTITY(propIndex, piCharacter, GET_PED_BONE_INDEX(piCharacter, BONETAG_PH_R_HAND), vPropOffset, vPropRot) ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: Checks the widget that handles the ped toggle PROC CHECK_FOR_PED_TOGGLE() // Ambient toggle is switched on IF bToggledOn[1] // Check for player unticking all ambient peds IF NOT bShowAFM AND NOT bShowAFO AND NOT bShowAFY AND NOT bShowAMM AND NOT bShowAMO AND NOT bShowAMY bToggleAmbient = FALSE bToggledOn[1] = FALSE ENDIF ELSE // Check for player ticking all ambient peds IF bShowAFM AND bShowAFO AND bShowAFY AND bShowAMM AND bShowAMO AND bShowAMY bToggleAmbient = TRUE bToggledOn[1] = TRUE ENDIF ENDIF // Gang toggle is switched on IF bToggledOn[2] // Check for player unticking all gang peds IF NOT bShowGFY AND NOT bShowGMM AND NOT bShowGMY bToggleGang = FALSE bToggledOn[2] = FALSE ENDIF ELSE // Check for player ticking all gang peds IF bShowGFY AND bShowGMM AND bShowGMY bToggleGang = TRUE bToggledOn[2] = TRUE ENDIF ENDIF // Unique toggle is switched on IF bToggledOn[3] // Check for player unticking all gang peds IF NOT bShowUFM AND NOT bShowUFO AND NOT bShowUFY AND NOT bShowUMM AND NOT bShowUMO AND NOT bShowUMY bToggleUnique = FALSE bToggledOn[3] = FALSE ENDIF ELSE // Check for player ticking all gang peds IF bShowUFM AND bShowUFO AND bShowUFY AND bShowUMM AND bShowUMO AND bShowUMY bToggleUnique = TRUE bToggledOn[3] = TRUE ENDIF ENDIF // Check whether we need to update the ALL toggle IF bToggledOn[0] IF NOT bToggleAmbient AND NOT bToggleGang AND NOT bToggleUnique bToggleAllPeds = FALSE bToggledOn[0] = FALSE ENDIF ELSE IF bToggleAmbient AND bToggleGang AND bToggleUnique bToggleAllPeds = TRUE bToggledOn[0] = TRUE ENDIF ENDIF // Toggle all ped models IF bToggleAllPeds IF NOT bToggledOn[0] PRINTLN("charAnimTest: Toggling all peds on...") TOGGLE_PEDS(TRUE, TRUE, TRUE, TRUE) bToggleAmbient = TRUE bToggleGang = TRUE bToggleUnique = TRUE INT i FOR i = 0 TO 3 bToggledOn[i] = TRUE ENDFOR EXIT ENDIF ELSE IF bToggledOn[0] PRINTLN("charAnimTest: Toggling all peds off...") TOGGLE_PEDS(FALSE, TRUE, TRUE, TRUE) bToggleAmbient = FALSE bToggleGang = FALSE bToggleUnique = FALSE INT i FOR i = 0 TO 3 bToggledOn[i] = FALSE ENDFOR ENDIF ENDIF // Toggle all ambient models IF bToggleAmbient IF NOT bToggledOn[1] PRINTLN("charAnimTest: Toggling all ambient peds on...") TOGGLE_PEDS(TRUE, TRUE, FALSE, FALSE) bToggledOn[1] = TRUE EXIT ENDIF ELSE IF bToggledOn[1] PRINTLN("charAnimTest: Toggling all ambient peds off...") TOGGLE_PEDS(FALSE, TRUE, FALSE, FALSE) bToggledOn[1] = FALSE EXIT ENDIF ENDIF // Toggle all gang models IF bToggleGang IF NOT bToggledOn[2] PRINTLN("charAnimTest: Toggling all gang peds on...") TOGGLE_PEDS(TRUE, FALSE, TRUE, FALSE) bToggledOn[2] = TRUE EXIT ENDIF ELSE IF bToggledOn[2] PRINTLN("charAnimTest: Toggling all gang peds off...") TOGGLE_PEDS(FALSE, FALSE, TRUE, FALSE) bToggledOn[2] = FALSE EXIT ENDIF ENDIF // Toggle all unique models IF bToggleUnique IF NOT bToggledOn[3] PRINTLN("charAnimTest: Toggling all unique peds on...") TOGGLE_PEDS(TRUE, FALSE, FALSE, TRUE) bToggledOn[3] = TRUE EXIT ENDIF ELSE IF bToggledOn[3] PRINTLN("charAnimTest: Toggling all unique peds off...") TOGGLE_PEDS(FALSE, FALSE, FALSE, TRUE) bToggledOn[3] = FALSE EXIT ENDIF ENDIF ENDPROC /// PURPOSE: Checks to see whether camera settings has been updated via widget PROC CHECK_FOR_CAMERA_UPDATE() // Update camera with current view settings IF bGetCurrentCam // Check for debug camera being active IF DOES_CAM_EXIST(GET_RENDERING_CAM()) // Get current settings PRINTLN("charAnimTest: Grabbing current camera info...") VECTOR vCurrentCamPos = GET_CAM_COORD(GET_RENDERING_CAM()) VECTOR vCurrentCamRot = GET_CAM_ROT(GET_RENDERING_CAM()) FLOAT fCurrentCamFOV = GET_CAM_FOV(GET_RENDERING_CAM()) // Position vCameraPos.x = vCurrentCamPos.x vCameraPos.y = vCurrentCamPos.y vCameraPos.z = vCurrentCamPos.z // Rotation vCameraRot.x = vCurrentCamRot.x vCameraRot.y = vCurrentCamRot.y vCameraRot.z = vCurrentCamRot.z // Field of view fCameraFOV = fCurrentCamFOV // Apply camera settings during "Test Scene" IF bTestSceneOn TOGGLE_TEST_CAMERA(FALSE) TOGGLE_TEST_CAMERA(TRUE) ENDIF ELSE PRINTLN("charAnimTest: Debug Cam is not active...") ENDIF // Done! bGetCurrentCam = FALSE ENDIF ENDPROC // ----------------------------------------------------------------------------------------------------------- // Test Functions/States // ----------------------------------------------------------------------------------------------------------- /// PURPOSE: Handles the test scene when active PROC PROCESS_TEST_SCENE() // Start test scene IF bTestSceneOn // Don't run if the full test is running IF NOT bFullTestOn IF NOT bTestActive PRINTLN("charAnimTest: Starting Test Scene...") bTestActive = TRUE // Get anims from widgets sAnimDict = GET_CONTENTS_OF_TEXT_WIDGET(widgetAnimDict) sAnimName = GET_CONTENTS_OF_TEXT_WIDGET(widgetAnimName) // Setup camera position TOGGLE_TEST_CAMERA(TRUE) // Load anim dictionary LOAD_ANIM_DICT() // Attempt to create character - will timeout if failed to create within 5 seconds... IF CREATE_CHARACTER(0, TRUE) PRINTLN("charAnimTest: Waiting for ped to be visible...") WAIT(1000) // Play looping animation PLAY_ANIM_ON_CHARACTER() // Play animation WHILE bTestSceneOn // "Full Test" cannot be selected whilst "Test Scene" runs... IF bFullTestOn bFullTestOn = FALSE ENDIF // Allow prop to be updated whilst test is running... CHECK_FOR_PROP_UPDATE() // Allow toggles and updates (doesn't affect test) CHECK_FOR_PED_TOGGLE() CHECK_FOR_CAMERA_UPDATE() // Check debug exit CHECK_DEBUG_CLEANUP() WAIT(0) ENDWHILE // Remove character CREATE_CHARACTER(0, FALSE) ENDIF // Unload animations UNLOAD_ANIM_DICT() // Restore normal game camera TOGGLE_TEST_CAMERA(FALSE) // Reset variables bTestActive = FALSE PRINTLN("charAnimTest: Ending Test Scene") ENDIF ELSE // Reset widget box bTestSceneOn = FALSE ENDIF ENDIF ENDPROC // PURPOSE: Common checks whilst processing the test - returns FALSE if the test should abort FUNC BOOL DO_TEST_WAIT(INT i) // Ensure test scene tickbox cannot be enabled IF bTestSceneOn bTestSceneOn = FALSE ENDIF // Check for debug quit/pass CHECK_DEBUG_CLEANUP() // Check for cancelling the test IF NOT bFullTestOn WAIT(0) RETURN FALSE ELSE WAIT(i) RETURN TRUE ENDIF ENDFUNC // PURPOSE: Handles the full test when active PROC PROCESS_FULL_TEST() // Start Full Anim Test IF bFullTestOn IF NOT bTestActive PRINTLN("charAnimTest: Starting Full Test...") bTestActive = TRUE // Get anims from widgets sAnimDict = GET_CONTENTS_OF_TEXT_WIDGET(widgetAnimDict) sAnimName = GET_CONTENTS_OF_TEXT_WIDGET(widgetAnimName) // Check animations IF IS_STRING_NULL_OR_EMPTY(sAnimDict) AND IS_STRING_NULL_OR_EMPTY(sAnimName) AND bUseIdleAnims = FALSE // Cancel test if no animations have been defined PRINTLN("charAnimTest: Animations not defined - Test Aborted...") bFullTestOn = FALSE bTestActive = FALSE ELSE // Specify whether using idles or defined animations IF bUseIdleAnims PRINTLN("charAnimTest: Starting Full Test - Using Idle Anims...") ELSE PRINTLN("charAnimTest: Starting Full Test - Using Specified Anims...") ENDIF // Setup camera position TOGGLE_TEST_CAMERA(TRUE) // Load anim dictionary LOAD_ANIM_DICT() // Cycle through character list INT iIndex = 0 FOR iIndex = 0 TO MAX_NUM_CHARACTERS // Check to see whether we want to create this ped model IF HAS_CHARACTER_MODEL_BEEN_SELECTED(iIndex) // Attempt to create character - will timeout if failed to create within 3 seconds... IF CREATE_CHARACTER(iIndex, TRUE) PRINTLN("charAnimTest: Waiting for ped to be visible...") IF NOT DO_TEST_WAIT(1000) PRINTLN("charAnimTest: Aborting test whilst waiting for ped to be visible...") EXIT ENDIF // Play animation PLAY_ANIM_ON_CHARACTER() WHILE NOT HAS_ANIM_STARTED_ON_CHARACTER() IF NOT DO_TEST_WAIT(0) PRINTLN("charAnimTest: Aborting test whilst waiting for anim to start on character...") EXIT ENDIF ENDWHILE // Wait for screenshot IF bUseIdleAnims WHILE NOT TAKE_SCREENSHOT_AT_TIME(iIndex) IF NOT DO_TEST_WAIT(0) PRINTLN("charAnimTest: Aborting test whilst waiting for idle screenshot...") EXIT ENDIF ENDWHILE ELSE WHILE NOT TAKE_SCREENSHOT_AT_PHASE(iIndex) IF NOT DO_TEST_WAIT(0) PRINTLN("charAnimTest: Aborting test whilst waiting for specified anim screenshot...") EXIT ENDIF ENDWHILE ENDIF // Remove character CREATE_CHARACTER(iIndex, FALSE) ENDIF ENDIF ENDFOR // Unload animations UNLOAD_ANIM_DICT() // Restore normal game camera TOGGLE_TEST_CAMERA(FALSE) // Increment screenshot counter iScreenShot++ // Reset variables bFullTestOn = FALSE bTestActive = FALSE PRINTLN("charAnimTest: Complete") ENDIF ENDIF ELSE // Stop animation test IF bTestActive // Remove character and restore camera CREATE_CHARACTER(0, FALSE) TOGGLE_TEST_CAMERA(FALSE) bTestActive = FALSE iScreenShot++ PRINTLN("charAnimTest: Cancelled") ENDIF ENDIF ENDPROC /// PURPOSE: Updates widgets and tests PROC UPDATE_TEST_SCRIPT() // Update idle times if min/max change CHECK_IDLE_TIME_VALUES() // Update anim phase if min/max change CHECK_ANIM_PHASE_VALUES() // Have all ped models been toggled on/off CHECK_FOR_PED_TOGGLE() // Check to see whether camera values are updated CHECK_FOR_CAMERA_UPDATE() // Check and update test scene when active PROCESS_TEST_SCENE() // Check and update full test when active PROCESS_FULL_TEST() ENDPROC #ENDIF /// Main script loop SCRIPT // Fade in screen if necessary #IF IS_DEBUG_BUILD PRINTLN("charAnimTest: Launched") #ENDIF IF IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_IN(500) ENDIF // Check for force cleanup of script IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_DEBUG_MENU|FORCE_CLEANUP_FLAG_SP_TO_MP) #IF IS_DEBUG_BUILD PRINTLN("charAnimTest: Force Cleanup") #ENDIF SCRIPT_CLEANUP() ENDIF // Create anim widgets #IF IS_DEBUG_BUILD SETUP_WIDGETS() #ENDIF // Main loop WHILE (TRUE) #IF IS_DEBUG_BUILD // Only display instruction text when tests aren't running IF NOT bTestActive // Display 'Placeholder Mission' SET_TEXT_COLOUR(255, 255, 255, 255) SET_TEXT_SCALE(0.75, 0.9) SET_TEXT_WRAP(0.0, 1.0) DISPLAY_TEXT(0.05, 0.63, "PLCHLD_MISS") // Display Pass and Fail instructions SET_TEXT_COLOUR(255, 255, 255, 255) SET_TEXT_SCALE(0.4, 0.45) SET_TEXT_WRAP(0.0, 1.0) DISPLAY_TEXT(0.05, 0.7, "PLCHLD_PASS") ENDIF // Update anim test UPDATE_TEST_SCRIPT() // Check for player debug quitting the script CHECK_DEBUG_CLEANUP() #ENDIF WAIT(0) ENDWHILE // Script should never reach here. Always terminate with cleanup function. ENDSCRIPT