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

857 lines
35 KiB
Scheme
Executable File

//
// Author: Adam Westwood Date: 12/07/14
//
//
// Drill Minigame
//
// Controls the drill minigame
//|
//
//
USING "timer_public.sch"
USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_audio.sch"
USING "commands_camera.sch"
USING "commands_clock.sch"
USING "commands_debug.sch"
USING "commands_fire.sch"
USING "commands_graphics.sch"
USING "commands_hud.sch"
USING "commands_misc.sch"
USING "commands_object.sch"
USING "commands_pad.sch"
USING "commands_ped.sch"
USING "commands_player.sch"
USING "commands_script.sch"
USING "commands_streaming.sch"
USING "commands_task.sch"
USING "commands_vehicle.sch"
USING "commands_interiors.sch"
USING "net_include.sch"
USING "model_enums.sch"
USING "script_player.sch"
USING "script_misc.sch"
USING "selector_public.sch"
USING "timer_public.sch"
USING "LineActivation.sch"
#IF IS_DEBUG_BUILD
USING "shared_debug.sch"
USING "script_debug.sch"
#ENDIF
CONST_INT DRILL_MINIGAME_STATE_INITIALISE 0
CONST_INT DRILL_MINIGAME_STATE_DRILLING 1
CONST_INT DRILL_MINIGAME_STATE_CLEANUP 2
CONST_INT DRILL_BITSET_IS_IN_SWEET_SPOT 0
CONST_INT DRILL_BITSET_IS_MINIGAME_COMPLETE 1
CONST_INT DRILL_BITSET_DID_PLAYER_MESS_UP 2
CONST_INT DRILL_BITSET_DID_PLAYER_MESS_UP_ON_LEFT_SIDE 4
CONST_INT DRILL_BITSET_DID_PLAYER_BACK_OUT 5
CONST_INT DRILL_BITSET_SKIP_WALK_TO_POSITION 6
CONST_INT DRILL_BITSET_HAS_BROADCAST_ASSET_REQUEST 7
CONST_FLOAT DRILL_MAX_SWEET_SPOT_SIZE 0.25 //0.2 - Rob - 2167673 - make drilling game twice as long (compensate a little for decreased speed)
CONST_FLOAT DRILL_MIN_SWEET_SPOT_SIZE 0.15
CONST_FLOAT DRILL_MAX_PROGRESS_SPEED 0.025 //0.07 - Rob - 2167673 - make drilling game twice as long
CONST_FLOAT DRILL_MIN_PROGRESS_SPEED 0.0
CONST_FLOAT DRILL_COOLDOWN_SPEED 0.08
CONST_FLOAT DRILL_OVERHEAT_SPEED 0.35 //0.4 - Rob - 2167673 - make drilling game twice as long (compensate a little for decreased speed)
CONST_FLOAT DRILL_LEAN_INTERP_SPEED 0.2
CONST_FLOAT DRILL_POS_SCALE_MODIFIER 0.82
CONST_FLOAT DRILL_PASS_POINT 0.775
CONST_FLOAT DRILL_START_POINT 0.08
CONST_FLOAT DRILL_PIN_BREAK_POWER_MODIFER_MAX 0.5
CONST_FLOAT DRILL_PIN_BREAK_POWER_MODIFIER_DECEL 0.4
STRUCT S_DRILL_DATA
INT iBitset
INT iHUDFlashTimer
INT iCurrentState
INT iDrillSoundID = -1
INT iSyncScene
INT iPassTimer
INT iAudioEvent
//INT iMoveNetworkSignalState
FLOAT fCurrentDrillPosY
FLOAT fCurrentDrillBasePosX
FLOAT fCurrentDrillPower
FLOAT fPinBreakPowerModifier
FLOAT fCurrentProgress
FLOAT fCurrentSweetSpotHeight
FLOAT fCurrentSweetSpotMin
FLOAT fCurrentSweetSpotMax
FLOAT fCurrentHeatLevel
FLOAT fCurrentProgressIncreaseSpeed
FLOAT fCurrentLeanPos
FLOAT fCurrentForwardLeanPos
FLOAT fForwardLeanExtraAmountForPins
FLOAT fCurrentDrillAnimPower
FLOAT fCurrentDrillBitPos
FLOAT fDrillBitShakeOffset
FLOAT fDesiredDrillBitShakeOffset
FLOAT fCurrentCamShake
FLOAT fCamRotOffset
FLOAT fDesiredCamRotOffset
FLOAT fCamHeightOffset
FLOAT fDesiredCamHeightOffset
FLOAT fDrillBitAnimSpeed
FLOAT fHudPosX = 0.82
FLOAT fHudPosY = 0.83
CAMERA_INDEX cam
SCALEFORM_INDEX sfDrillHud
VECTOR vCamPointPos
VECTOR vCamStartPos
#IF IS_DEBUG_BUILD
BOOL bDisplayDebug
INT iDebugNumPrintsThisFrame
#ENDIF
ENDSTRUCT
// PC CONTROL FOR DRILLING MINIGAME
BOOL bPCCOntrolsSetup = FALSE
PROC SETUP_PC_DRILLING_CONTROLS()
IF IS_PC_VERSION()
IF bPCCOntrolsSetup = FALSE
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME]- Setup PC controls" )
INIT_PC_SCRIPTED_CONTROLS("MP DRILL MINIGAME")
bPCCOntrolsSetup = TRUE
ENDIF
ENDIF
ENDPROC
PROC CLEANUP_PC_DRILLING_CONTROLS()
IF IS_PC_VERSION()
IF bPCCOntrolsSetup = TRUE
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME]- Cleanup PC controls" )
SHUTDOWN_PC_SCRIPTED_CONTROLS()
bPCCOntrolsSetup = FALSE
ENDIF
ENDIF
ENDPROC
/// REQUEST_DRILL_MINIGAME_ASSETS()
/// NOTES:
/// PURPOSE:
/// checking assets are loaded
/// PARAMS:
/// RETURNS:
PROC REQUEST_DRILL_MINIGAME_ASSETS(S_DRILL_DATA &sDrillData)
REQUEST_ANIM_DICT("anim@heists@fleeca_bank@drilling")
REQUEST_MODEL(HEI_PROP_HEIST_DEPOSIT_BOX)
REQUEST_MODEL(hei_prop_heist_drill)
REQUEST_MODEL(HEI_P_M_BAG_VAR22_ARM_S)
REQUEST_MODEL(HEI_PROP_HEI_DRILL_HOLE)
REQUEST_SCRIPT_AUDIO_BANK("DLC_MPHEIST\\HEIST_FLEECA_DRILL")
REQUEST_SCRIPT_AUDIO_BANK("DLC_MPHEIST\\HEIST_FLEECA_DRILL_2")
REQUEST_NAMED_PTFX_ASSET("fm_mission_controler")
IF sDrillData.sfDrillHud = NULL
sDrillData.sfDrillHud = REQUEST_SCALEFORM_MOVIE("DRILLING")
ENDIF
ENDPROC
/// HAVE_DRILL_ASSETS_LOADED()
/// NOTES:
/// PURPOSE:
/// checking assets are loaded
/// PARAMS:
/// RETURNS:
FUNC BOOL HAVE_DRILL_ASSETS_LOADED(S_DRILL_DATA &sDrillData)
REQUEST_ANIM_DICT("anim@heists@fleeca_bank@drilling")
REQUEST_MODEL(HEI_PROP_HEIST_DEPOSIT_BOX)
REQUEST_MODEL(hei_prop_heist_drill)
REQUEST_MODEL(HEI_P_M_BAG_VAR22_ARM_S)
IF HAS_ANIM_DICT_LOADED("anim@heists@fleeca_bank@drilling")
AND HAS_MODEL_LOADED(HEI_PROP_HEIST_DEPOSIT_BOX)
AND HAS_MODEL_LOADED(hei_prop_heist_drill)
AND HAS_MODEL_LOADED(HEI_P_M_BAG_VAR22_ARM_S)
AND HAS_MODEL_LOADED(HEI_PROP_HEI_DRILL_HOLE)
AND HAS_NAMED_PTFX_ASSET_LOADED("fm_mission_controler")
AND HAS_SCALEFORM_MOVIE_LOADED(sDrillData.sfDrillHud)
AND REQUEST_SCRIPT_AUDIO_BANK("DLC_MPHEIST\\HEIST_FLEECA_DRILL")
AND REQUEST_SCRIPT_AUDIO_BANK("DLC_MPHEIST\\HEIST_FLEECA_DRILL_2")
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC RESET_DRILL_MINIGAME_DATA(S_DRILL_DATA &sDrillData)
sDrillData.iBitset = 0
sDrillData.iHUDFlashTimer = 0
sDrillData.iCurrentState = 0
sDrillData.iAudioEvent = 0
sDrillData.fCurrentDrillPosY = 0.0
sDrillData.fCurrentDrillBitPos = 0.0
sDrillData.fDrillBitShakeOffset = 0.0
sDrillData.fCurrentDrillBasePosX = 0.0
sDrillData.fCurrentDrillPower = 0.0
sDrillData.fCurrentProgress = 0.0
sDrillData.fCurrentSweetSpotHeight = DRILL_MAX_SWEET_SPOT_SIZE
sDrillData.fCurrentSweetSpotMin = 0.0
sDrillData.fCurrentSweetSpotMax = 0.0
sDrillData.fCurrentHeatLevel = 0.0
sDrillData.fCurrentProgressIncreaseSpeed = 0.0
sDrillData.fForwardLeanExtraAmountForPins = 0.0
sDrillData.fPinBreakPowerModifier = 0.0
ENDPROC
/// PURPOSE:
/// Checks if it's okay to run the drilling minigame.
FUNC BOOL IS_SAFE_TO_PLAY_DRILL_MINIGAME()
//Currently just one check: may be expanded in the future.
IF NOT IS_CUTSCENE_PLAYING()
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL MANAGE_DRILL_TIMER(INT &iStartTime, INT iTimeToWait)
RETURN (GET_GAME_TIMER() - iStartTime > iTimeToWait)
ENDFUNC
PROC FORCE_QUIT_FAIL_DRILL_MINIGAME_KEEP_DATA(S_DRILL_DATA &drill_data, BOOL bResetData = TRUE)
IF IS_MINIGAME_IN_PROGRESS()
SET_MINIGAME_IN_PROGRESS(FALSE)
ENDIF
CLEAR_HELP()
NET_SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
DISABLE_CELLPHONE(FALSE)
DISABLE_SCRIPT_HUD_THIS_FRAME_RESET()
IF bResetData
RESET_DRILL_MINIGAME_DATA(drill_data)
ENDIF
ENDPROC
PROC FORCE_QUIT_PASS_DRILL_MINIGAME_KEEP_DATA(S_DRILL_DATA &drill_data, BOOL bResetData = TRUE, BOOL bClearTasks = TRUE, BOOL bRestoreControl = TRUE)
IF IS_MINIGAME_IN_PROGRESS()
SET_MINIGAME_IN_PROGRESS(FALSE)
ENDIF
IF bClearTasks
CLEAR_PED_TASKS(PLAYER_PED_ID())
ENDIF
CLEAR_HELP()
IF bRestoreControl
NET_SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
ENDIF
DISABLE_CELLPHONE(FALSE)
DISABLE_SCRIPT_HUD_THIS_FRAME_RESET()
CLEANUP_PC_DRILLING_CONTROLS()
IF bResetData
RESET_DRILL_MINIGAME_DATA(drill_data)
ENDIF
ENDPROC
FUNC BOOL HAS_PLAYER_BEAT_DRILL_MINIGAME(S_DRILL_DATA &sDrillData, BOOL bForceQuit = FALSE)
IF IS_BIT_SET(sDrillData.iBitset, DRILL_BITSET_IS_MINIGAME_COMPLETE)
IF bForceQuit
FORCE_QUIT_PASS_DRILL_MINIGAME_KEEP_DATA(sDrillData)
ENDIF
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC INITIALISE_MINIGAME_VALUES(S_DRILL_DATA &sDrillData)
IF NOT IS_BIT_SET(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_MESS_UP)
IF NOT IS_BIT_SET(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_BACK_OUT)
sDrillData.fCurrentProgress = DRILL_START_POINT
sDrillData.iAudioEvent = 0
ENDIF
sDrillData.fCurrentHeatLevel = 0.0
ENDIF
sDrillData.iHUDFlashTimer = 0
sDrillData.iCurrentState = 0
sDrillData.fCurrentDrillPosY = 0.0
sDrillData.fCurrentDrillBitPos = 0.0
sDrillData.fDrillBitShakeOffset = 0.0
sDrillData.fCurrentDrillBasePosX = 0.0
sDrillData.fCurrentDrillPower = 0.0
sDrillData.fCurrentProgressIncreaseSpeed = 0.0
sDrillData.fCurrentForwardLeanPos = 0.0
sDrillData.fForwardLeanExtraAmountForPins = 0.0
sDrillData.fPinBreakPowerModifier = 0.0
sDrillData.fCurrentSweetSpotHeight = DRILL_MAX_SWEET_SPOT_SIZE
sDrillData.fCurrentSweetSpotMax = sDrillData.fCurrentProgress
sDrillData.fCurrentSweetSpotMin = sDrillData.fCurrentSweetSpotMax - DRILL_MAX_SWEET_SPOT_SIZE
IF sDrillData.fCurrentSweetSpotMin < 0.0
sDrillData.fCurrentSweetSpotMin = 0.0
ENDIF
CLEAR_BIT(sDrillData.iBitset, DRILL_BITSET_IS_MINIGAME_COMPLETE)
CLEAR_BIT(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_MESS_UP)
ENDPROC
/*FUNC BOOL IS_DRILL_IN_SWEET_SPOT(S_DRILL_DATA &sDrillData)
IF sDrillData.fCurrentDrillPosY >= sDrillData.fCurrentSweetSpotMin
AND sDrillData.fCurrentDrillPosY <= sDrillData.fCurrentSweetSpotMax
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC*/
PROC SET_PLAYER_BACKED_OUT_OF_DRILLING(S_DRILL_DATA &sDrillData)
SET_BIT(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_BACK_OUT)
ENDPROC
FUNC BOOL HAS_PLAYER_BACKED_OUT_OF_DRILLING(S_DRILL_DATA &sDrillData)
RETURN IS_BIT_SET(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_BACK_OUT)
ENDFUNC
PROC PLAYER_MESSED_UP_DRILLING(S_DRILL_DATA &sDrillData)
SET_CONTROL_SHAKE(PLAYER_CONTROL, 2000, 220)
SET_BIT(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_MESS_UP)
IF sDrillData.fCurrentDrillBasePosX <= 0.0
SET_BIT(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_MESS_UP_ON_LEFT_SIDE)
ELSE
CLEAR_BIT(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_MESS_UP_ON_LEFT_SIDE)
ENDIF
ENDPROC
FUNC BOOL HAS_PLAYER_MESSED_UP_DRILLING(S_DRILL_DATA &sDrillData)
RETURN IS_BIT_SET(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_MESS_UP)
ENDFUNC
/// PURPOSE:
/// Returns whether the player was leaning on the left side when they messed up the drilling minigame. Useful for
/// working out which transition anim to play.
FUNC BOOL DID_PLAYER_MESS_UP_DRILLING_ON_LEFT_SIDE(S_DRILL_DATA &sDrillData)
RETURN IS_BIT_SET(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_MESS_UP_ON_LEFT_SIDE)
ENDFUNC
/// PURPOSE:
/// Calculates a skew value for the drill's sideways movement: the skew forces the player to compensate their own movement to avoid hitting the edges.
/// The skew changes with the current progress of the drill.
/*FUNC FLOAT GET_CURRENT_DRILL_POSITION_SKEW(S_DRILL_DATA &sDrillData)
FLOAT fSkew = 0.0
IF sDrillData.fCurrentProgress > 0.3
fSkew = 1.15 * SIN(600.0 * (sDrillData.fCurrentProgress - 0.3))
ENDIF
RETURN fSkew
ENDFUNC*/
PROC SHAKE_DRILL_BIT(S_DRILL_DATA &sDrillData)
IF sDrillData.fCurrentDrillPosY > sDrillData.fCurrentSweetSpotMax
IF ABSF(sDrillData.fDesiredDrillBitShakeOffset - sDrillData.fDrillBitShakeOffset) < 0.002
sDrillData.fDesiredDrillBitShakeOffset = GET_RANDOM_FLOAT_IN_RANGE(-0.04, 0.0)
ENDIF
ELSE
sDrillData.fDesiredDrillBitShakeOffset = 0.0
ENDIF
sDrillData.fDrillBitShakeOffset = LERP_FLOAT(sDrillData.fDrillBitShakeOffset, sDrillData.fDesiredDrillBitShakeOffset, 1.0)
ENDPROC
//Old HUD, due to be replaced by Scaleform.
/*PROC DRAW_DRILL_MINIGAME_HUD(S_DRILL_DATA &sDrillData)
IF CAN_INGAME_HUD_ELEMENTS_DISPLAY()
CONST_FLOAT DRILL_HUD_CENTRE_X 0.85
CONST_FLOAT DRILL_HUD_CENTRE_Y 0.8
CONST_FLOAT DRILL_HUD_HEIGHT 0.2
CONST_FLOAT DRILL_HUD_WIDTH 0.03
CONST_FLOAT DRILL_HUD_PROGRESS_HEIGHT 0.18
CONST_FLOAT DRILL_HUD_PROGRESS_WIDTH 0.025
CONST_FLOAT DRILL_HUD_INDICATOR_SIZE 0.003
BOOL bFlashHUD = FALSE
INT iR, iG, iB
INT iScreenSizeX
INT iScreenSizeY
GET_SCREEN_RESOLUTION(iScreenSizeX, iScreenSizeY)
FLOAT fAspectRatio = TO_FLOAT(iScreenSizeX) / TO_FLOAT(iScreenSizeY)
//Work out the colour for the progress bar: colour is based on heat level. Try to get the colour to gradually turn from green to red.
//Roughly the colours should be:
// heat = 0.0 colour = green
// heat - 0.25 colour = yellow
// heat = 0.5 colour = orange
// heat = 0.75 colour = red
// heat = 1.0 colour = dark red
IF sDrillData.fCurrentHeatLevel >= 0.75
//Increase red value where heat 1.0 = 128 and heat 0.75 = 255
iR = 128 + ROUND(((0.25 - (sDrillData.fCurrentHeatLevel - 0.75)) / 0.25) * 127.0)
ELIF sDrillData.fCurrentHeatLevel < 0.25
iR = ROUND((sDrillData.fCurrentHeatLevel / 0.25) * 255.0)
ELSE
iR = 255
ENDIF
IF sDrillData.fCurrentHeatLevel >= 0.75
iG = 0
ELIF sDrillData.fCurrentHeatLevel >= 0.25
//Increase green value where heat 0.75 = 0 and heat 0.25 = 255
iG = ROUND(((0.5 - (sDrillData.fCurrentHeatLevel - 0.25)) / 0.5) * 255.0)
ELSE
iG = 255
ENDIF
iB = 0
//If the player is outside the sweet spot then flash the whole bar.
IF NOT IS_BIT_SET(sDrillData.iBitset, DRILL_BITSET_IS_IN_SWEET_SPOT)
AND sDrillData.fCurrentDrillPower > 0.0
IF sDrillData.iHUDFlashTimer = 0
OR GET_GAME_TIMER() - sDrillData.iHUDFlashTimer > 300
sDrillData.iHUDFlashTimer = GET_GAME_TIMER()
ELSE
IF GET_GAME_TIMER() - sDrillData.iHUDFlashTimer < 100
bFlashHUD = TRUE
ENDIF
ENDIF
ENDIF
//Draw the background (black background plus a progress background).
DRAW_RECT(DRILL_HUD_CENTRE_X, DRILL_HUD_CENTRE_Y, DRILL_HUD_WIDTH, DRILL_HUD_HEIGHT, 0, 0, 0, 128)
IF bFlashHUD
DRAW_RECT(DRILL_HUD_CENTRE_X, DRILL_HUD_CENTRE_Y, DRILL_HUD_PROGRESS_WIDTH, DRILL_HUD_PROGRESS_HEIGHT, 255, 255, 255, 255)
ELSE
DRAW_RECT(DRILL_HUD_CENTRE_X, DRILL_HUD_CENTRE_Y, DRILL_HUD_PROGRESS_WIDTH, DRILL_HUD_PROGRESS_HEIGHT, ROUND(TO_FLOAT(iR) * 0.25), ROUND(TO_FLOAT(iG) * 0.25), ROUND(TO_FLOAT(iB) * 0.25), 255)
ENDIF
//Draw the progress bar.
FLOAT fProgressBarHeight = sDrillData.fCurrentProgress * DRILL_HUD_PROGRESS_HEIGHT
FLOAT fProgressBarCentreY = DRILL_HUD_CENTRE_Y + (DRILL_HUD_PROGRESS_HEIGHT * 0.5) - (fProgressBarHeight * 0.5)
IF bFlashHUD
DRAW_RECT(DRILL_HUD_CENTRE_X, fProgressBarCentreY, DRILL_HUD_PROGRESS_WIDTH, fProgressBarHeight, 255, 255, 255, 255)
ELSE
DRAW_RECT(DRILL_HUD_CENTRE_X, fProgressBarCentreY, DRILL_HUD_PROGRESS_WIDTH, fProgressBarHeight, iR, iG, iB, 255)
ENDIF
//Draw the sweet spot.
FLOAT fSweetSpotHeight = (sDrillData.fCurrentSweetSpotMax - sDrillData.fCurrentSweetSpotMin) * DRILL_HUD_PROGRESS_HEIGHT
FLOAT fSweetSpotCentreY = DRILL_HUD_CENTRE_Y + (DRILL_HUD_PROGRESS_HEIGHT * 0.5) - fProgressBarHeight + (fSweetSpotHeight * 0.5)
IF bFlashHUD
DRAW_RECT(DRILL_HUD_CENTRE_X, fSweetSpotCentreY, DRILL_HUD_PROGRESS_WIDTH, fSweetSpotHeight, 255, 255, 255, 255)
ELSE
DRAW_RECT(DRILL_HUD_CENTRE_X, fSweetSpotCentreY, DRILL_HUD_PROGRESS_WIDTH, fSweetSpotHeight, 0, 96, 255, 255)
ENDIF
//Draw the drill indicator.
FLOAT fIndicatorPosX = DRILL_HUD_CENTRE_X + (sDrillData.fCurrentDrillSkewedPosX * DRILL_HUD_PROGRESS_WIDTH * 0.5)
FLOAT fIndicatorPosY = DRILL_HUD_CENTRE_Y + (DRILL_HUD_PROGRESS_HEIGHT * 0.5) - (sDrillData.fCurrentDrillPosY * DRILL_HUD_PROGRESS_HEIGHT)
DRAW_RECT(fIndicatorPosX, fIndicatorPosY, DRILL_HUD_INDICATOR_SIZE, DRILL_HUD_INDICATOR_SIZE * fAspectRatio, 255, 255, 255, 255)
ENDIF
ENDPROC*/
//New version of HUD using scaleform movie.
PROC DRAW_DRILL_MINIGAME_SCALEFORM_HUD(S_DRILL_DATA &sDrillData)
IF CAN_INGAME_HUD_ELEMENTS_DISPLAY()
AND IS_SAFE_TO_PLAY_DRILL_MINIGAME()
HIDE_HUD_AND_RADAR_THIS_FRAME()
THEFEED_HIDE_THIS_FRAME()
//NOTE: with the current UI the drill starts to strobe at max power, so adjust the input value slightly. This also lets us boost the speed when we hit a pin (2207563)
CALL_SCALEFORM_MOVIE_METHOD_WITH_NUMBER(sDrillData.sfDrillHud, "SET_SPEED", (sDrillData.fCurrentDrillPower * 0.79) + (sDrillData.fPinBreakPowerModifier * 0.08))
CALL_SCALEFORM_MOVIE_METHOD_WITH_NUMBER(sDrillData.sfDrillHud, "SET_HOLE_DEPTH", sDrillData.fCurrentProgress)
CALL_SCALEFORM_MOVIE_METHOD_WITH_NUMBER(sDrillData.sfDrillHud, "SET_DRILL_POSITION", sDrillData.fCurrentDrillBitPos + sDrillData.fDrillBitShakeOffset)
CALL_SCALEFORM_MOVIE_METHOD_WITH_NUMBER(sDrillData.sfDrillHud, "SET_TEMPERATURE", sDrillData.fCurrentHeatLevel)
DRAW_SCALEFORM_MOVIE_FULLSCREEN(sDrillData.sfDrillHUD, 255, 255, 255, 255)
//DRAW_SCALEFORM_MOVIE(sDrillData.sfDrillHUD, sDrillData.fHudPosX, sDrillData.fHudPosY, 0.6, 0.8, 255, 255, 255, 255)
ENDIF
ENDPROC
#IF IS_DEBUG_BUILD
PROC DRAW_STRING_TO_DRILL_DEBUG(S_DRILL_DATA &sDrillData, STRING strDebug)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
DRAW_DEBUG_TEXT_2D(strDebug, <<0.05, 0.04 + (0.04 * sDrillData.iDebugNumPrintsThisFrame), 0.0>>, 0, 0, 255, 255)
sDrillData.iDebugNumPrintsThisFrame++
ENDPROC
PROC DRAW_INT_TO_DRILL_DEBUG(S_DRILL_DATA &sDrillData, INT iDebug, STRING strLabel)
TEXT_LABEL_63 strConcat = strLabel
strConcat += iDebug
DRAW_STRING_TO_DRILL_DEBUG(sDrillData, strConcat)
ENDPROC
PROC DRAW_FLOAT_TO_DRILL_DEBUG(S_DRILL_DATA &sDrillData, FLOAT fDebug, STRING strLabel)
TEXT_LABEL_63 strConcat = strLabel
strConcat += " "
strConcat += GET_STRING_FROM_FLOAT(fDebug)
DRAW_STRING_TO_DRILL_DEBUG(sDrillData, strConcat)
ENDPROC
PROC DUMP_DRILL_MINIGAME_STATE_TO_CONSOLE(S_DRILL_DATA &sDrillData)
INT iCurrentTime = GET_GAME_TIMER()
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] Dumping script state, current game time = ", iCurrentTime)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] iCurrentState = ", sDrillData.iCurrentState)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] iBitset = ", sDrillData.iBitSet)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] iHUDFlashTimer = ", sDrillData.iHUDFlashTimer)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentDrillPosY = ", sDrillData.fCurrentDrillPosY)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentDrillBasePosX = ", sDrillData.fCurrentDrillBasePosX)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentDrillBitPos = ", sDrillData.fCurrentDrillBitPos)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fDrillBitShakeOffset = ", sDrillData.fDrillBitShakeOffset)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentLeanPos = ", sDrillData.fCurrentLeanPos)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentForwardLeanPos = ", sDrillData.fCurrentForwardLeanPos)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentDrillPower = ", sDrillData.fCurrentDrillPower)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentProgress = ", sDrillData.fCurrentProgress)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentSweetSpotHeight = ", sDrillData.fCurrentSweetSpotHeight)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentSweetSpotMin = ", sDrillData.fCurrentSweetSpotMin)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentSweetSpotMax = ", sDrillData.fCurrentSweetSpotMax)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentHeatLevel = ", sDrillData.fCurrentHeatLevel)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fCurrentProgressIncreaseSpeed = ", sDrillData.fCurrentProgressIncreaseSpeed)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fHudPosX = ", sDrillData.fHudPosX)
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] fHudPosY = ", sDrillData.fHudPosY)
ENDPROC
PROC UPDATE_DRILL_MINIGAME_DEBUG(S_DRILL_DATA &sDrillData)
//Dump the state of all variables if someone enters a bug.
IF IS_KEYBOARD_KEY_PRESSED(KEY_SPACE)
OR IS_KEYBOARD_KEY_PRESSED(KEY_RBRACKET)
DUMP_DRILL_MINIGAME_STATE_TO_CONSOLE(sDrillData)
ENDIF
//Instant pass.
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD1)
sDrillData.fCurrentProgress = 1.0
ENDIF
//Incremental increase
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD9)
sDrillData.fCurrentProgress += 0.005
ENDIF
//Incremental decrease
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD3)
sDrillData.fCurrentProgress -= 0.005
ENDIF
//Display some debug
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD5)
sDrillData.bDisplayDebug = NOT sDrillData.bDisplayDebug
ENDIF
//Move the HUD around
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD4)
sDrillData.fHudPosX -= 0.01
ENDIF
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD6)
sDrillData.fHudPosX += 0.01
ENDIF
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD8)
sDrillData.fHudPosY -= 0.01
ENDIF
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD2)
sDrillData.fHudPosY += 0.01
ENDIF
IF sDrillData.bDisplayDebug
sDrillData.iDebugNumPrintsThisFrame = 0
DRAW_INT_TO_DRILL_DEBUG(sDrillData, sDrillData.iCurrentState, "iCurrentState")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentDrillBasePosX, "fCurrentDrillBasePosX")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentLeanPos, "fCurrentLeanPos")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentForwardLeanPos, "fCurrentForwardLeanPos")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentDrillPosY, "fCurrentDrillPosY")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentDrillBitPos, "fCurrentDrillBitPos")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fDrillBitShakeOffset, "fDrillBitShakeOffset")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentDrillPower, "fCurrentDrillPower")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fPinBreakPowerModifier, "fPinBreakPowerModifier")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentDrillAnimPower, "fCurrentDrillAnimPower")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentProgress, "fCurrentProgress")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentSweetSpotHeight, "fCurrentSweetSpotHeight")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentSweetSpotMin, "fCurrentSweetSpotMin")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentSweetSpotMax, "fCurrentSweetSpotMax")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentHeatLevel, "fCurrentHeatLevel")
DRAW_FLOAT_TO_DRILL_DEBUG(sDrillData, sDrillData.fCurrentProgressIncreaseSpeed, "fCurrentProgressIncreaseSpeed")
DRAW_RECT(0.8, 0.5, 0.05, sDrillData.fCurrentSweetSpotHeight * 0.5, 255, 0, 0, 255)
ENDIF
ENDPROC
#ENDIF
PROC RUN_DRILL_MINIGAME(S_DRILL_DATA &sDrillData)
#IF IS_DEBUG_BUILD
UPDATE_DRILL_MINIGAME_DEBUG(sDrillData)
#ENDIF
SWITCH sDrillData.iCurrentState
CASE DRILL_MINIGAME_STATE_INITIALISE
INITIALISE_MINIGAME_VALUES(sDrillData)
//If this is a second attempt at the game then reset the backing out flag.
CLEAR_BIT(sDrillData.iBitset, DRILL_BITSET_DID_PLAYER_BACK_OUT)
sDrillData.iCurrentState = DRILL_MINIGAME_STATE_DRILLING
SETUP_PC_DRILLING_CONTROLS()
BREAK
CASE DRILL_MINIGAME_STATE_DRILLING
CLEAR_BIT(sDrillData.iBitset, DRILL_BITSET_IS_IN_SWEET_SPOT)
//Grab the inputs
IF HAS_PLAYER_MESSED_UP_DRILLING(sDrillData)
OR NOT IS_SAFE_TO_PLAY_DRILL_MINIGAME()
sDrillData.fCurrentDrillBasePosX = 0.0
sDrillData.fCurrentDrillPosY = 0.0
sDrillData.fCurrentDrillPower = 0.0
ELSE
sDrillData.fCurrentDrillBasePosX = GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_X)
IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
IF IS_MOUSE_LOOK_INVERTED()
sDrillData.fCurrentDrillPosY += ( GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_Y) * 0.25 )
ELSE
sDrillData.fCurrentDrillPosY -= ( GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_Y) * 0.25 )
ENDIF
ELSE
sDrillData.fCurrentDrillPosY = -GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_FRONTEND_AXIS_Y)
ENDIF
sDrillData.fCurrentDrillPower = GET_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_RT)
ENDIF
//Floor negative values of the Y position as they're not relevant.
IF sDrillData.fCurrentDrillPosY < 0.0
sDrillData.fCurrentDrillPosY = 0.0
ENDIF
//2081557 - Allow some room in the Y-position so the game doesn't get stuck due to a dodgy analog stick.
IF NOT IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
sDrillData.fCurrentDrillPosY = sDrillData.fCurrentDrillPosY / DRILL_POS_SCALE_MODIFIER
ENDIF
IF sDrillData.fCurrentDrillPosY > 1.0
sDrillData.fCurrentDrillPosY = 1.0
ENDIF
// No need to dead-zone on mouse
IF NOT IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
//If the power is a really small value then floor it (to protect against dodgy pad triggers).
IF sDrillData.fCurrentDrillPower < 0.03
sDrillData.fCurrentDrillPower = 0.0
ENDIF
ENDIF
//2207563 - Have a power modifier value that kicks in when a pin breaks and gradually dies down. If the player stops drilling it dies down more quickly.
sDrillData.fPinBreakPowerModifier = sDrillData.fPinBreakPowerModifier -@ (DRILL_PIN_BREAK_POWER_MODIFIER_DECEL + (0.2 * (1.0 - sDrillData.fCurrentDrillPower)))
IF sDrillData.fPinBreakPowerModifier < 0.0
sDrillData.fPinBreakPowerModifier = 0.0
ENDIF
sDrillData.fCurrentDrillPower *= (1.0 + (sDrillData.fPinBreakPowerModifier * DRILL_PIN_BREAK_POWER_MODIFER_MAX))
IF sDrillData.fCurrentDrillPower > 1.0
sDrillData.fCurrentDrillPower = 1.0
ENDIF
//Determine the current sweet spot height and progress speed we should progress (both are based on drill power).
//Extra request: Make the sweet spot bigger at the start to make it easier.
FLOAT fSweetSpotExtraHeight
sDrillData.fCurrentSweetSpotHeight = DRILL_MAX_SWEET_SPOT_SIZE - ((DRILL_MAX_SWEET_SPOT_SIZE - DRILL_MIN_SWEET_SPOT_SIZE) * sDrillData.fCurrentDrillPower)
fSweetSpotExtraHeight = (1.0 - sDrillData.fCurrentProgress) * DRILL_MAX_SWEET_SPOT_SIZE
sDrillData.fCurrentSweetSpotHeight += fSweetSpotExtraHeight
sDrillData.fCurrentProgressIncreaseSpeed = DRILL_MIN_PROGRESS_SPEED + ((DRILL_MAX_PROGRESS_SPEED - DRILL_MIN_PROGRESS_SPEED) * sDrillData.fCurrentDrillPower)
//2207563 - Make the sweet spot smaller if we just broke a pin.
sDrillData.fCurrentSweetSpotHeight /= (1.0 + (sDrillData.fPinBreakPowerModifier * 6.0))
//Determine the current sweet spot: the sweet spot goes from the top of the progress bar down to a position depending on the current height.
sDrillData.fCurrentSweetSpotMin = sDrillData.fCurrentProgress
sDrillData.fCurrentSweetSpotMax = sDrillData.fCurrentSweetSpotMin + sDrillData.fCurrentSweetSpotHeight
IF sDrillData.fCurrentSweetSpotMin < 0.0
sDrillData.fCurrentSweetSpotMin = 0.0
ENDIF
IF sDrillData.fCurrentSweetSpotMax > 1.0
sDrillData.fCurrentSweetSpotMax = 1.0
ENDIF
//Handle progress and overheat updates (don't update if the player currently messed up and is still recovering).
IF NOT HAS_PLAYER_MESSED_UP_DRILLING(sDrillData)
IF sDrillData.fCurrentDrillPower > 0.0
IF sDrillData.fCurrentDrillPosY < sDrillData.fCurrentSweetSpotMin
//Drill is too far back: nothing happens.
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 200, 15 + ROUND(sDrillData.fCurrentDrillPower * 45.0) + ROUND(sDrillData.fPinBreakPowerModifier * 45.0))
ELIF sDrillData.fCurrentDrillPosY > sDrillData.fCurrentSweetSpotMax
//Drill is too far forward: overheat it. Increase the rate of overheating based on drill power.
sDrillData.fCurrentHeatLevel = sDrillData.fCurrentHeatLevel +@ (DRILL_OVERHEAT_SPEED + (sDrillData.fCurrentDrillPower * 0.2))
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 200, 200)
ELSE
//Drill is in the sweet spot.
sDrillData.fCurrentProgress = sDrillData.fCurrentProgress +@ sDrillData.fCurrentProgressIncreaseSpeed
IF sDrillData.fCurrentProgress >= 1.0
sDrillData.fCurrentProgress = 1.0
ENDIF
SET_BIT(sDrillData.iBitset, DRILL_BITSET_IS_IN_SWEET_SPOT)
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 200, 30 + ROUND(sDrillData.fCurrentDrillPower * 60.0) + ROUND(sDrillData.fPinBreakPowerModifier * 60.0))
ENDIF
ELSE
//Shake slightly if the player is pushing the drill too hard.
IF sDrillData.fCurrentDrillPosY > sDrillData.fCurrentSweetSpotMax
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 200, 30)
ENDIF
ENDIF
ELSE
sDrillData.fCurrentForwardLeanPos = 0.0
ENDIF
//Decrease the overheat meter over time, if the player has let go of the power then cool down quicker (or if they overheated completely).
IF HAS_PLAYER_MESSED_UP_DRILLING(sDrillData)
sDrillData.fCurrentHeatLevel = sDrillData.fCurrentHeatLevel -@ (DRILL_COOLDOWN_SPEED * 2.0)
ELIF sDrillData.fCurrentDrillPower > 0.0
sDrillData.fCurrentHeatLevel = sDrillData.fCurrentHeatLevel -@ DRILL_COOLDOWN_SPEED
ELSE
sDrillData.fCurrentHeatLevel = sDrillData.fCurrentHeatLevel -@ (DRILL_COOLDOWN_SPEED * 1.25)
ENDIF
//Cap the heat value.
IF sDrillData.fCurrentHeatLevel > 1.0
sDrillData.fCurrentHeatLevel = 1.0
ELIF sDrillData.fCurrentHeatLevel < 0.0
sDrillData.fCurrentHeatLevel = 0.0
ENDIF
//Set the visible drill bit position: the drill can't go further than the current progress. If the player is trying to do this then shake the drill bit.
sDrillData.fCurrentDrillBitPos = sDrillData.fCurrentDrillBitPos + ((sDrillData.fCurrentDrillPosY - sDrillData.fCurrentDrillBitPos) * 0.5)
IF sDrillData.fCurrentDrillBitPos > sDrillData.fCurrentProgress
sDrillData.fCurrentDrillBitPos = sDrillData.fCurrentProgress
ENDIF
SHAKE_DRILL_BIT(sDrillData)
//Work out the anim values: these are just interpolations of the progress and sideways movement values, and are used for smoothing out the anims.
sDrillData.fCurrentLeanPos = COSINE_INTERP_FLOAT(sDrillData.fCurrentLeanPos, sDrillData.fCurrentDrillBasePosX, DRILL_LEAN_INTERP_SPEED)
sDrillData.fCurrentForwardLeanPos = COSINE_INTERP_FLOAT(sDrillData.fCurrentForwardLeanPos, sDrillData.fCurrentDrillBitPos, DRILL_LEAN_INTERP_SPEED * 0.5)
sDrillData.fCurrentDrillAnimPower = COSINE_INTERP_FLOAT(sDrillData.fCurrentDrillAnimPower, sDrillData.fCurrentDrillPower, 0.4)
//If the progress reaches max then go to the next stage.
//NOTE: the new drill scaleform cracks before progress reaches 1.0.
//2136848 - Have some delay so it doesn't cut to the cutscene too quickly after passing.
IF sDrillData.fCurrentProgress >= DRILL_PASS_POINT
AND IS_SAFE_TO_PLAY_DRILL_MINIGAME()
//Guarantee that we;ve gone past the point where the drill HUD cracks.
IF DRILL_PASS_POINT < 0.99
AND sDrillData.fCurrentProgress - DRILL_PASS_POINT < 0.01
sDrillData.fCurrentProgress = DRILL_PASS_POINT + 0.01
ENDIF
IF GET_GAME_TIMER() - sDrillData.iPassTimer > 500
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] Progress complete, passing minigame.")
sDrillData.iCurrentState = DRILL_MINIGAME_STATE_CLEANUP
ENDIF
ELSE
sDrillData.iPassTimer = GET_GAME_TIMER()
ENDIF
//If the heat level reaches max then put us in the overheat state.
IF sDrillData.fCurrentHeatLevel >= 1.0
AND sDrillData.iCurrentState != DRILL_MINIGAME_STATE_CLEANUP
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] Player messed up.")
PLAYER_MESSED_UP_DRILLING(sDrillData)
ENDIF
//Handle audio for pins breaking, also make sure the progress is forced to a value that guarantees the sound and UI sync up.
IF sDrillData.iAudioEvent = 0
IF sDrillData.fCurrentProgress > 0.325
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] Playing drill pin break sound ", sDrillData.iAudioEvent)
PLAY_SOUND_FRONTEND( -1, "Drill_Pin_Break", "DLC_HEIST_FLEECA_SOUNDSET")
IF sDrillData.fCurrentProgress < 0.33
sDrillData.fCurrentProgress = 0.33
ENDIF
sDrillData.fCurrentProgress += 0.01 //2207563 - This gives the effect of the drill lurching forward after breaking a pin.
sDrillData.fPinBreakPowerModifier = 1.0
sDrillData.iAudioEvent++
ENDIF
ELIF sDrillData.iAudioEvent = 1
//2207563 - This will be added to the lean animation phase, giving the effect of the player lurching forward after each pin breaking.
sDrillData.fForwardLeanExtraAmountForPins += (0.06 - sDrillData.fForwardLeanExtraAmountForPins) * 0.5
IF sDrillData.fCurrentProgress > 0.475
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] Playing drill pin break sound ", sDrillData.iAudioEvent)
PLAY_SOUND_FRONTEND( -1, "Drill_Pin_Break", "DLC_HEIST_FLEECA_SOUNDSET")
IF sDrillData.fCurrentProgress < 0.48
sDrillData.fCurrentProgress = 0.48
ENDIF
sDrillData.fCurrentProgress += 0.01
sDrillData.fPinBreakPowerModifier = 1.0
sDrillData.iAudioEvent++
ENDIF
ELIF sDrillData.iAudioEvent = 2
sDrillData.fForwardLeanExtraAmountForPins += (0.12 - sDrillData.fForwardLeanExtraAmountForPins) * 0.5
IF sDrillData.fCurrentProgress > 0.625
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] Playing drill pin break sound ", sDrillData.iAudioEvent)
PLAY_SOUND_FRONTEND( -1, "Drill_Pin_Break", "DLC_HEIST_FLEECA_SOUNDSET")
IF sDrillData.fCurrentProgress < 0.63
sDrillData.fCurrentProgress = 0.63
ENDIF
sDrillData.fCurrentProgress += 0.01
sDrillData.fPinBreakPowerModifier = 1.0
sDrillData.iAudioEvent++
ENDIF
ELIF sDrillData.iAudioEvent = 3
sDrillData.fForwardLeanExtraAmountForPins += (0.18 - sDrillData.fForwardLeanExtraAmountForPins) * 0.5
IF sDrillData.fCurrentProgress >= DRILL_PASS_POINT
CDEBUG1LN(DEBUG_MISSION, "[RUN_DRILL_MINIGAME] Playing drill pin break sound ", sDrillData.iAudioEvent)
PLAY_SOUND_FRONTEND( -1, "Drill_Pin_Break", "DLC_HEIST_FLEECA_SOUNDSET")
sDrillData.fCurrentProgress += 0.01
sDrillData.fPinBreakPowerModifier = 1.0
sDrillData.iAudioEvent++
ENDIF
ENDIF
BREAK
CASE DRILL_MINIGAME_STATE_CLEANUP
SET_BIT(sDrillData.iBitset, DRILL_BITSET_IS_MINIGAME_COMPLETE)
sDrillData.iCurrentState++
CLEANUP_PC_DRILLING_CONTROLS()
BREAK
ENDSWITCH
//Update HUD
//DRAW_DRILL_MINIGAME_HUD(sDrillData)
DRAW_DRILL_MINIGAME_SCALEFORM_HUD(sDrillData)
ENDPROC