Files
2025-09-29 00:52:08 +02:00

518 lines
17 KiB
Scheme
Executable File

USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_Streaming.sch"
USING "drunk_public.sch"
USING "script_debug.sch"
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// MISSION NAME : drunk_debug.sch
// AUTHOR : Keith / Alwyn
// DESCRIPTION : Widgets and debug routines to aid 'drunk' testing.
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
FUNC BOOL DrawLiteralDrunkString(STRING sLiteral, INT iColumn, HUD_COLOURS eColour = HUD_COLOUR_PURE_WHITE)
IF g_bDrawDebugDrunkInfo
INT iColumnOffset = 6
INT red, green, blue, iAlpha
GET_HUD_COLOUR(eColour, red, green, blue, iAlpha)
SET_TEXT_SCALE(0.45, 0.45)
SET_TEXT_COLOUR(red, green, blue, iAlpha)
DISPLAY_TEXT_WITH_LITERAL_STRING(0.7795, 0.0305*TO_FLOAT(iColumn+iColumnOffset), "STRING", sLiteral)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL DrawLiteralDrunkStringInt(STRING sLiteral, INT sInt, INT iColumn, HUD_COLOURS eColour = HUD_COLOUR_PURE_WHITE)
TEXT_LABEL_63 sNewLiteral = sLiteral
sNewLiteral += sInt
RETURN DrawLiteralDrunkString(sNewLiteral, iColumn, eColour)
ENDFUNC
FUNC BOOL DrawLiteralDrunkStringFloat(STRING sLiteral, FLOAT sFloat, INT iColumn, HUD_COLOURS eColour = HUD_COLOUR_PURE_WHITE)
TEXT_LABEL_63 sNewLiteral = sLiteral
sNewLiteral += GET_STRING_FROM_FLOAT(sFloat)
RETURN DrawLiteralDrunkString(sNewLiteral, iColumn, eColour)
ENDFUNC
FUNC BOOL DrawDebugDrunkTextWithOffset(STRING text, VECTOR VecCoors, int Offset_x, int Offset_y,int Red = 0, int Green = 0, int Blue = 255, int iAlpha = 255)
IF g_bDrawDebugDrunkInfo
DRAW_DEBUG_TEXT_WITH_OFFSET (text, VecCoors, Offset_x, Offset_y, Red, Green, Blue, iAlpha)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC STRING Get_String_From_DrunkStatus(g_eDrunkStatus thisDrunkStatus)
SWITCH thisDrunkStatus
// Script Control
CASE DS_REQUEST_SCRIPT
RETURN "DS_REQUEST_SCRIPT"
BREAK
// Long-Term Target
CASE DSLT_PLAYER_CONTROLLED
RETURN "DSLT_PLAYER_CONTROLLED"
BREAK
CASE DSLT_GET_INTO_VEHICLE
RETURN "DSLT_GET_INTO_VEHICLE"
BREAK
// Short-Term Task
CASE DSST_SWITCH_ON_RAGDOLL
RETURN "DSST_SWITCH_ON_RAGDOLL"
BREAK
CASE DSST_WALK
RETURN "DSST_WALK"
BREAK
// CASE DSST_FALLING
// RETURN "DSST_FALLING"
// BREAK
// CASE DSST_ON_GROUND
// RETURN "DSST_ON_GROUND"
// BREAK
// CASE DSST_STANDING_UP
// RETURN "DSST_STANDING_UP"
// BREAK
CASE DSST_ENTER_VEHICLE
RETURN "DSST_ENTER_VEHICLE"
BREAK
CASE DSST_ENTERING_VEHICLE
RETURN "DSST_ENTERING_VEHICLE"
BREAK
CASE DSST_WARP_INTO_TAXI
RETURN "DSST_WARP_INTO_TAXI"
BREAK
CASE DSST_SHUFFLE_CARSEATS
RETURN "DSST_SHUFFLE_CARSEATS"
BREAK
CASE DSST_IN_VEHICLE
RETURN "DSST_IN_VEHICLE"
BREAK
CASE DSST_LEAVE_VEHICLE
RETURN "DSST_LEAVE_VEHICLE"
BREAK
// Generic
CASE DS_IDLE
RETURN "DS_IDLE"
BREAK
// Leave this at the bottom
CASE DS_NO_STATUS
RETURN "DS_NO_STATUS"
BREAK
ENDSWITCH
RETURN "invalid thisDrunkStatus"
ENDFUNC
FUNC STRING Get_String_From_DrunkLevel(g_eDrunkLevel thisDrunkLevel)
SWITCH thisDrunkLevel
// Script Control
CASE DL_verydrunk
RETURN "DL_verydrunk"
BREAK
CASE DL_slightlydrunk
RETURN "DL_slightlydrunk"
BREAK
CASE DL_moderatedrunk
RETURN "DL_moderatedrunk"
BREAK
// Leave this at the bottom
CASE DL_NO_LEVEL
RETURN "DL_NO_LEVEL"
BREAK
ENDSWITCH
RETURN "invalid thisDrunkLevel"
ENDFUNC
// PURPOSE: Some drunk variables are ENUMs - for the widgets we need these translated into INTs
PROC Update_Drunk_Widget_Variables()
INT tempLoop = 0
// Convert Drunk Request Status Enums into Ints
REPEAT MAX_NUMBER_OF_DRUNK_REQUESTS tempLoop
g_widgetDrunkRequestStatusAsInt[tempLoop] = ENUM_TO_INT(g_drunkRequests[tempLoop].status)
ENDREPEAT
// Store Drunk Ped Unique IDs
REPEAT MAX_NUMBER_OF_DRUNK_PEDS tempLoop
g_widgetUniqueID[tempLoop] = ENUM_TO_INT(g_drunkPeds[tempLoop].uniqueID)
ENDREPEAT
g_isDrunkCameraActive = g_drunkCameraActive
g_isPlayerDrunk = g_playerIsDrunk
IF (g_widgetMakePlayerDrunk_60s)
IF NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()))
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Making Player Drunk (60s)")
Make_Ped_Drunk(PLAYER_PED_ID(), 60000)
ENDIF
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
g_bDrawDebugDrunkInfo = TRUE
g_widgetMakePlayerDrunk_60s = FALSE
ENDIF
IF (g_widgetMakePlayerDrunk_constant)
IF NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()))
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Making Player Drunk (constant)")
Make_Ped_Drunk_Constant(PLAYER_PED_ID())
ENDIF
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
g_bDrawDebugDrunkInfo = TRUE
g_widgetMakePlayerDrunk_constant = FALSE
ENDIF
IF (g_widgetExtendPlayerDrunkTime_30s)
IF NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()))
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Extending Player Drunk Time (30s)")
Extend_Overall_Drunk_Time(PLAYER_PED_ID(), 30000)
ENDIF
g_bDrawDebugDrunkInfo = TRUE
g_widgetExtendPlayerDrunkTime_30s = FALSE
ENDIF
IF (g_widgetMakePlayerSober)
IF NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()))
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Making Player Sober ")
Make_Ped_Sober(PLAYER_PED_ID())
ENDIF
g_bDrawDebugDrunkInfo = TRUE
g_widgetMakePlayerSober = FALSE
ENDIF
IF (g_widgetPlayerTakesAlcoholHit)
IF NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()))
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Player Takes Alcohol Hit ")
Player_Takes_Alcohol_Hit(PLAYER_PED_ID())
ENDIF
g_bDrawDebugDrunkInfo = TRUE
g_widgetPlayerTakesAlcoholHit = FALSE
ENDIF
IF (g_widgetPlayerTakesWeedHit)
IF NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()))
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Player Takes Alcohol Hit ")
Player_Takes_Weed_Hit(PLAYER_PED_ID())
ENDIF
g_bDrawDebugDrunkInfo = TRUE
g_widgetPlayerTakesWeedHit = FALSE
ENDIF
IF (g_widgetPlayerHangoverWakeup)
IF NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()))
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Player Hangover Wakeup ")
Make_Ped_Sober(PLAYER_PED_ID())
ENDIF
g_bDrawDebugDrunkInfo = TRUE
g_widgetPlayerHangoverWakeup = FALSE
ENDIF
IF (g_widgetCreateDrunkPedOne)
IF NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()))
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Create Blitzed First Ped")
VECTOR xyzP = GET_ENTITY_COORDS(PLAYER_PED_ID())
xyzP.x += 2.0
REQUEST_MODEL(S_F_Y_SCRUBS_01)
WHILE NOT HAS_MODEL_LOADED(S_F_Y_SCRUBS_01)
WAIT(0)
REQUEST_MODEL(S_F_Y_SCRUBS_01)
ENDWHILE
g_widgetDrunkPedOne = CREATE_PED(PEDTYPE_MISSION, S_F_Y_SCRUBS_01, xyzP, 0.0)
Make_Ped_Drunk(g_widgetDrunkPedOne, 140000)
ENDIF
g_bDrawDebugDrunkInfo = TRUE
g_widgetCreateDrunkPedOne = FALSE
ENDIF
IF (g_widgetCreateDrunkPedTwo)
IF NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()))
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Create Blitzed PedTwo")
VECTOR xyzP = GET_ENTITY_COORDS(PLAYER_PED_ID())
xyzP.y += 2.0
REQUEST_MODEL(S_F_Y_AirHostess_01)
WHILE NOT HAS_MODEL_LOADED(S_F_Y_AirHostess_01)
WAIT(0)
REQUEST_MODEL(S_F_Y_AirHostess_01)
ENDWHILE
g_widgetDrunkPedTwo = CREATE_PED(PEDTYPE_MISSION, S_F_Y_AirHostess_01, xyzP, 0.0)
Make_Ped_Drunk(g_widgetDrunkPedTwo, 140000)
ENDIF
g_bDrawDebugDrunkInfo = TRUE
g_widgetCreateDrunkPedTwo = FALSE
ENDIF
IF (g_widgetActivateDrunkCamera_60s)
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Activate Drunk Camera")
Activate_Drunk_Camera(60000)
g_bDrawDebugDrunkInfo = TRUE
g_widgetActivateDrunkCamera_60s = FALSE
ENDIF
IF (g_widgetActivateDrunkCameraConstant)
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Activate Drunk Camera Constant")
Activate_Drunk_Camera_Constant()
g_bDrawDebugDrunkInfo = TRUE
g_widgetActivateDrunkCameraConstant = FALSE
ENDIF
IF (g_widgetQuitDrunkCameraNow)
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Quit Drunk Camera Immediately")
Quit_Drunk_Camera_Immediately()
g_bDrawDebugDrunkInfo = TRUE
g_widgetQuitDrunkCameraNow = FALSE
ENDIF
IF (g_widgetQuitDrunkCameraGradual)
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> Quit Drunk Camera Gradually")
Quit_Drunk_Camera_Gradually()
g_bDrawDebugDrunkInfo = TRUE
g_widgetQuitDrunkCameraGradual = FALSE
ENDIF
IF g_bIncrementDrunkModifier[0]
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> ////BAWSAQ_INCREMENT_MODIFIER(BSMF_PUBCLUBVISIT)")
BawsaqIncrementDrunkModifier_PUBCLUBVISIT()
g_bIncrementDrunkModifier[0] = FALSE
ENDIF
IF g_bIncrementDrunkModifier[1]
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> ////BAWSAQ_INCREMENT_MODIFIER(BSMF_TIMESDRUNK)")
BawsaqIncrementDrunkModifier_TIMESDRUNK()
g_bIncrementDrunkModifier[1] = FALSE
ENDIF
IF g_bIncrementDrunkModifier[2]
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> ////BAWSAQ_INCREMENT_MODIFIER(BSMF_FRNDTOPUB)")
BawsaqIncrementDrunkModifier_FRNDTOPUB()
g_bIncrementDrunkModifier[2] = FALSE
ENDIF
IF g_bIncrementDrunkModifier[3]
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> ////BAWSAQ_INCREMENT_MODIFIER(BSMF_DRNKCRIME)")
BawsaqIncrementDrunkModifier_DRNKCRIME()
g_bIncrementDrunkModifier[3] = FALSE
ENDIF
IF g_bIncrementDrunkModifier[4]
CPRINTLN(DEBUG_DRUNK, "<DRUNK DEBUG> ////BAWSAQ_INCREMENT_MODIFIER(BSMF_HANGOVERS)")
BawsaqIncrementDrunkModifier_HANGOVERS()
g_bIncrementDrunkModifier[4] = FALSE
ENDIF
ENDPROC
// PURPOSE: Initialise any drunk widget variables that need it
PROC Initialise_Drunk_Widget_Variables()
Update_Drunk_Widget_Variables()
// 'drunk' variables
INT tempLoop = 0
REPEAT MAX_NUMBER_OF_DRUNK_PEDS tempLoop
g_widgetLongTermStatusAsInt[tempLoop] = ENUM_TO_INT(DS_NO_STATUS)
g_widgetShortTermStatusAsInt[tempLoop] = ENUM_TO_INT(DS_NO_STATUS)
g_widgetTimerA[tempLoop] = 0
g_widgetRagdolling[tempLoop] = 0
g_widgetOverall[tempLoop] = 0
g_widgetActivity[tempLoop] = 0
g_widgetFailsafe[tempLoop] = 0
g_widgetSteering[tempLoop] = 0
g_widgetAlcoholHitCount[tempLoop] = 0
g_widgetWeedHitCount[tempLoop] = 0
ENDREPEAT
g_widgetMakePlayerDrunk_60s = FALSE
g_widgetMakePlayerDrunk_constant = FALSE
g_widgetExtendPlayerDrunkTime_30s = FALSE
g_widgetMakePlayerSober = FALSE
g_widgetPlayerTakesAlcoholHit = FALSE
g_widgetPlayerTakesWeedHit = FALSE
g_widgetPlayerHangoverWakeup = FALSE
g_widgetCreateDrunkPedOne = FALSE
g_widgetCreateDrunkPedTwo = FALSE
g_widgetActivateDrunkCamera_60s = FALSE
g_widgetActivateDrunkCameraConstant = FALSE
g_widgetQuitDrunkCameraNow = FALSE
g_widgetQuitDrunkCameraGradual = FALSE
ENDPROC
// PURPOSE: Setup One Drunk Request Widget Set
//
// INPUT PARAMS: paramArrayIndex Drunk Request array element being set up
PROC Drunk_Debug_Setup_Drunk_Request_Widget(INT paramArrayIndex)
g_eDrunkStatus eDrunkStatus
START_NEW_WIDGET_COMBO()
REPEAT COUNT_OF(g_eDrunkStatus) eDrunkStatus
ADD_TO_WIDGET_COMBO(Get_String_From_DrunkStatus(eDrunkStatus))
ENDREPEAT
STOP_WIDGET_COMBO("Request Status", g_widgetDrunkRequestStatusAsInt[paramArrayIndex])
ENDPROC
// PURPOSE: Setup One Drunk Ped Widget Set
//
// INPUT PARAMS: paramArrayIndex Drunk Ped array element being set up
PROC Drunk_Debug_Setup_Drunk_Ped_Widget(INT paramArrayIndex)
g_eDrunkStatus eDrunkStatus
TEXT_LABEL str = "Ped "
str += paramArrayIndex
START_WIDGET_GROUP(str)
ADD_WIDGET_INT_READ_ONLY("Unique ID", g_widgetUniqueID[paramArrayIndex])
START_NEW_WIDGET_COMBO()
REPEAT COUNT_OF(g_eDrunkStatus) eDrunkStatus
ADD_TO_WIDGET_COMBO(Get_String_From_DrunkStatus(eDrunkStatus))
ENDREPEAT
STOP_WIDGET_COMBO("Long-Term Status", g_widgetLongTermStatusAsInt[paramArrayIndex])
START_NEW_WIDGET_COMBO()
REPEAT COUNT_OF(g_eDrunkStatus) eDrunkStatus
ADD_TO_WIDGET_COMBO(Get_String_From_DrunkStatus(eDrunkStatus))
ENDREPEAT
STOP_WIDGET_COMBO("Short-Term Status", g_widgetShortTermStatusAsInt[paramArrayIndex])
START_WIDGET_GROUP("Timings")
ADD_WIDGET_INT_READ_ONLY("TimerA (secs)", g_widgetTimerA[paramArrayIndex])
ADD_WIDGET_INT_READ_ONLY("Ragdolling (secs)", g_widgetRagdolling[paramArrayIndex])
ADD_WIDGET_INT_READ_ONLY("Overall (sec)", g_widgetOverall[paramArrayIndex])
ADD_WIDGET_INT_READ_ONLY("Activity (msec)", g_widgetActivity[paramArrayIndex])
ADD_WIDGET_INT_READ_ONLY("Failsafe (msec)", g_widgetFailsafe[ParamArrayIndex])
ADD_WIDGET_INT_READ_ONLY("Steering (msec)", g_widgetSteering[paramArrayIndex])
ADD_WIDGET_INT_READ_ONLY("Beer Hit Count", g_widgetAlcoholHitCount[paramArrayIndex])
ADD_WIDGET_INT_READ_ONLY("Weed Hit Count", g_widgetWeedHitCount[paramArrayIndex])
STOP_WIDGET_GROUP()
STOP_WIDGET_GROUP()
ENDPROC
// PURPOSE: Setup any other drunk control widgets that may be useful
PROC Drunk_Debug_Setup_Other_Widgets()
ADD_WIDGET_STRING("drunk player")
ADD_WIDGET_INT_SLIDER("g_iPlayerDrunkCount", g_iPlayerDrunkCount, 0, 9999, 1)
ADD_WIDGET_BOOL("Make Player Drunk (60s)", g_widgetMakePlayerDrunk_60s)
ADD_WIDGET_BOOL("Make Player Drunk (constant)", g_widgetMakePlayerDrunk_constant)
ADD_WIDGET_BOOL("Extend Player Drunk Time (30s)", g_widgetExtendPlayerDrunkTime_30s)
ADD_WIDGET_BOOL("Make Player Sober", g_widgetMakePlayerSober)
ADD_WIDGET_STRING("create drunk peds")
ADD_WIDGET_BOOL("Player Takes Alcohol Hit", g_widgetPlayerTakesAlcoholHit)
ADD_WIDGET_BOOL("Player Takes Weed Hit", g_widgetPlayerTakesWeedHit)
ADD_WIDGET_BOOL("Player Hangover Wakeup", g_widgetPlayerHangoverWakeup)
ADD_WIDGET_STRING("create drunk peds")
ADD_WIDGET_BOOL("Create Drunk PedOne", g_widgetCreateDrunkPedOne)
ADD_WIDGET_BOOL("Create Drunk PedTwo", g_widgetCreateDrunkPedTwo)
ADD_WIDGET_STRING("control drunk camera")
ADD_WIDGET_BOOL("Activate Drunk Camera (60s)", g_widgetActivateDrunkCamera_60s)
ADD_WIDGET_BOOL("Activate Drunk Camera (constant)", g_widgetActivateDrunkCameraConstant)
ADD_WIDGET_BOOL("Quit Drunk Camera Now", g_widgetQuitDrunkCameraNow)
ADD_WIDGET_BOOL("Quit Drunk Camera Gradual (30s)", g_widgetQuitDrunkCameraGradual)
ADD_WIDGET_STRING("increment drunk modifier")
ADD_WIDGET_BOOL("BSMF_PUBCLUBVISIT", g_bIncrementDrunkModifier[0])
ADD_WIDGET_BOOL("BSMF_TIMESDRUNK", g_bIncrementDrunkModifier[1])
ADD_WIDGET_BOOL("BSMF_FRNDTOPUB", g_bIncrementDrunkModifier[2])
ADD_WIDGET_BOOL("BSMF_DRNKCRIME", g_bIncrementDrunkModifier[3])
ADD_WIDGET_BOOL("BSMF_HANGOVERS", g_bIncrementDrunkModifier[4])
ENDPROC
// PURPOSE: Initialise any widgets and controls that enable debug options for the drunk routines
PROC Drunk_Debug_Initialise()
Initialise_Drunk_Widget_Variables()
INT tempLoop = 0
g_wDrawDebugDrunkInfo = START_WIDGET_GROUP("Drunk Controller")
ADD_WIDGET_BOOL("g_bDrawDebugDrunkInfo", g_bDrawDebugDrunkInfo)
// Drunk Requests
START_WIDGET_GROUP("Requests")
REPEAT MAX_NUMBER_OF_DRUNK_REQUESTS tempLoop
Drunk_Debug_Setup_Drunk_Request_Widget(tempLoop)
ENDREPEAT
STOP_WIDGET_GROUP()
// Drunk Peds
START_WIDGET_GROUP("Peds")
REPEAT MAX_NUMBER_OF_DRUNK_PEDS tempLoop
Drunk_Debug_Setup_Drunk_Ped_Widget(tempLoop)
ENDREPEAT
STOP_WIDGET_GROUP()
// Drunk Camera
START_WIDGET_GROUP("Drunk Camera")
ADD_WIDGET_BOOL("Active?", g_isDrunkCameraActive)
ADD_WIDGET_INT_SLIDER("Timeout (msec)", g_drunkCameraTimeout, DRUNK_LEVEL_CONSTANT, GET_GAME_TIMER() + (5*60*1000), 1000)
ADD_WIDGET_INT_SLIDER("Timeout Duration (msec)", g_drunkCameraTimeoutDuration, DRUNK_LEVEL_CONSTANT, GET_GAME_TIMER() + (5*60*1000), 1000)
ADD_WIDGET_FLOAT_SLIDER("Motion Blur", g_drunkCameraMotionBlur, 0.0, MAX_DRUNK_CAMERA_STRENGTH, 0.01)
ADD_WIDGET_FLOAT_SLIDER("Desired Amplitude Scalar", g_drunkCameraDesiredAmplitudeScalar, 0.0, 10.0, 0.01)
ADD_WIDGET_FLOAT_SLIDER("Actual Amplitude Scalar", g_drunkCameraActualAmplitudeScalar, 0.0, 10.0, 0.01)
ADD_WIDGET_FLOAT_SLIDER("g_drunkCameraTimeCycleModifier", g_drunkCameraTimeCycleModifier, 0.0, 10.0, 0.01)
STOP_WIDGET_GROUP()
// Other Stuff
START_WIDGET_GROUP("Other Variables")
ADD_WIDGET_BOOL("Is Player Drunk?", g_isPlayerDrunk)
ADD_WIDGET_BOOL("Has Player Requested To Be Drunk?", g_playerRequestedToBeDrunk)
STOP_WIDGET_GROUP()
Drunk_Debug_Setup_Other_Widgets()
STOP_WIDGET_GROUP()
ENDPROC