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

1973 lines
67 KiB
Scheme
Executable File

// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// SCRIPT NAME : TRI_Widget.sch
// AUTHOR : Nicholas Zippmann
// DESCRIPTION : Single Player Races - Widget main procs/functions file
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
#IF IS_DEBUG_BUILD
USING "TRI_Head.sch"
USING "TRI_Helpers.sch"
USING "TRI_Camera.sch"
USING "TRI_Gate.sch"
USING "TRI_Racer.sch"
USING "TRI_Race.sch"
USING "TRI_Master.sch"
USING "TRI_Widget_lib.sch"
INT iSelectedGateToDirty = -1
// -----------------------------------
// GATES HELPER PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_Gates_Sel_Set(TRI_WIDGET_GATES& Gates, INT iValue, BOOL bReset = TRUE)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Set")
TRI_Widget_Int_Set(Gates.Selection, iValue, bReset)
ENDPROC
PROC TRI_Widget_Gates_Sel_Set_Update(TRI_WIDGET_GATES& Gates, INT iValue)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Set_Update")
TRI_Widget_Int_Set(Gates.Selection, -1)
TRI_Widget_Int_Set(Gates.Selection, iValue, FALSE)
ENDPROC
FUNC INT TRI_Widget_Gates_Sel_Get(TRI_WIDGET_GATES& Gates)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Get")
RETURN TRI_Widget_Int_Get(Gates.Selection)
ENDFUNC
PROC TRI_Widget_Gates_Sel_Inc(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Inc")
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
IF (iGateSel < (Race.iGateCnt - 1))
++iGateSel
ELIF (iGateSel = (Race.iGateCnt - 1))
iGateSel = 0
ENDIF
TRI_Widget_Int_Set(Gates.Selection, iGateSel, FALSE)
ENDPROC
PROC TRI_Widget_Gates_Sel_Dec(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Dec")
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
IF (iGateSel > 0)
--iGateSel
ELIF (iGateSel = 0)
iGateSel = Race.iGateCnt - 1
ENDIF
TRI_Widget_Int_Set(Gates.Selection, iGateSel, FALSE)
ENDPROC
PROC TRI_Widget_Gates_Sel_Beg(TRI_WIDGET_GATES& Gates)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Beg")
TRI_Widget_Int_Set(Gates.Selection, 0, FALSE)
ENDPROC
PROC TRI_Widget_Gates_Sel_End(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_End")
TRI_Widget_Int_Set(Gates.Selection, Race.iGateCnt - 1, FALSE)
ENDPROC
// TODO: This gets used in probably too many places where I already have the index...
PROC TRI_Widget_Gates_Sel_Act(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Act")
TRI_Race_Gate_Activate(Race, TRI_Widget_Gates_Sel_Get(Gates), TRUE)
ENDPROC
// TODO: Add error checking and figure out a way to use race error textbox...
FUNC BOOL TRI_Widget_Gates_Sel_Create(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race, VECTOR vPos)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Create")
IF (Race.iGateCnt >= TRI_GATE_MAX)
RETURN FALSE
ENDIF
++Race.iGateCnt
INT iGate = Race.iGateCnt - 1
INT iGateNew = TRI_Widget_Gates_Sel_Get(Gates) + 1
WHILE (iGate > iGateNew)
Race.sGate[iGate] = Race.sGate[iGate - 1]
--iGate
ENDWHILE
TRI_Race_Gate_Init(Race, iGateNew)
Race.sGate[iGateNew].vPos = vPos
TRI_Widget_Gates_Sel_Set_Update(Gates, iGateNew)
RETURN TRUE
ENDFUNC
FUNC BOOL TRI_Widget_Gates_Sel_Delete(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Delete")
INT iGate = TRI_Widget_Gates_Sel_Get(Gates)
INT iGateNew = Race.iGateCnt - 1
TRI_Race_Gate_Init(Race, iGate)
WHILE (iGate < (Race.iGateCnt - 1))
Race.sGate[iGate] = Race.sGate[iGate + 1]
--iGateNew
++iGate
ENDWHILE
IF (Race.iGateCnt > 1)
--Race.iGateCnt
IF (iGateNew = Race.iGateCnt)
--iGateNew
ENDIF
ENDIF
TRI_Widget_Gates_Sel_Set_Update(Gates, iGateNew)
RETURN TRUE
ENDFUNC
PROC TRI_Widget_Gates_Sel_Update_Position(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Update_Position")
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
VECTOR vGatePos = Race.sGate[iGateSel].vPos
TRI_Widget_Vector_Set(Gates.Position, vGatePos)
ENDPROC
PROC TRI_Widget_Gates_Sel_Update_Radius(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Update_Radius")
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
FLOAT fGateRadius = Race.sGate[iGateSel].fRadius
TRI_Widget_Float_Set(Gates.Radius, fGateRadius)
ENDPROC
PROC TRI_Widget_Gates_Sel_Update_ChkpntType(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Update_ChkpntType")
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
TRI_RACE_CHECKPOINT_TYPE eChkpntType = Race.sGate[iGateSel].eChkpntType
INT iChkpntType = TRI_ChkpntType_GetIndex(eChkpntType)
TRI_Widget_Listbox_Set(Gates.ChkpntType, iChkpntType)
ENDPROC
PROC TRI_Widget_Gates_Sel_Update_All(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Sel_Update_All")
TRI_Widget_Gates_Sel_Update_Position(Gates, Race)
TRI_Widget_Gates_Sel_Update_Radius(Gates, Race)
TRI_Widget_Gates_Sel_Update_ChkpntType(Gates, Race)
//TRI_Widget_Gates_Sel_Update_StuntType(Gates, Race)
ENDPROC
// -----------------------------------
// GATES CONTROLS PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_Gates_Create_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera)
//DEBUG_MESSAGE("TRI_Widget_Gates_Create_Update")
// Check Create Gate (button).
IF TRI_Widget_Button_Check(Gates.Create)
// Reset Create Gate (button).
TRI_Widget_Button_Reset(Gates.Create)
// Create new gate at placement position, if possible.
VECTOR vGatePos = TRI_Camera_GetPlacementPos(Camera)
TRI_Widget_Gates_Sel_Create(Gates, Race, vGatePos)
ENDIF
ENDPROC
PROC TRI_Widget_Gates_Delete_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Delete_Update")
// Check Delete Gate (button).
IF TRI_Widget_Button_Check(Gates.Delete)
// Reset Delete Gate (button).
TRI_Widget_Button_Reset(Gates.Delete)
// Delete Selected Gate, if possible.
TRI_Widget_Gates_Sel_Delete(Gates, Race)
ENDIF
ENDPROC
PROC TRI_Widget_Gates_ShowAll_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_ShowAll_Update")
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
IF iSelectedGateToDirty != iGateSel
IF iSelectedGateToDirty != -1
TRI_Race_Gate_Deactivate(Race, iSelectedGateToDirty)
ENDIF
iSelectedGateToDirty = iGateSel
LOAD_SCENE(Race.sGate[iGateSel].vPos)
CPRINTLN(DEBUG_TRIATHLON, "LOAD_SCENE :: TRI_Widget_Gates_ShowAll_Update")
VECTOR vTelePlayer = Race.sGate[iGateSel].vPos
IF (Race.sGate[iGateSel].eChkpntType != TRI_CHKPT_STUNT_DEFAULT)
AND (Race.sGate[iGateSel].eChkpntType != TRI_CHKPT_STUNT_FINISH)
IF (Race.sGate[iGateSel].eChkpntType != TRI_CHKPT_TRI_SWIM)
IF GET_GROUND_Z_FOR_3D_COORD(vTelePlayer, vTelePlayer.z)
//FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), TRUE)
SET_ENTITY_COORDS(PLAYER_PED_ID(), vTelePlayer)
//WAIT(1000)
//SET_ENTITY_COORDS(PLAYER_PED_ID(), vTelePlayer)
//FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), Race.sGate[iGateSel].vPos)
ENDIF
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), Race.sGate[iGateSel].vPos)
ENDIF
ENDIF
TRI_Race_Gate_Activate(Race, TRI_Widget_Gates_Sel_Get(Gates), TRUE)
TRI_Race_Gate_Create_Custom_GPS_Route(Race)
ENDIF
// Check Show All Gates (toggle).
IF TRI_Widget_Toggle_Check(Gates.ShowAll)
// Reset Show All Gates (toggle).
TRI_Widget_Toggle_Reset(Gates.ShowAll)
// If Show All Gates is on, do just that.
// TODO: Think about making into a function.
IF TRI_Widget_Toggle_Get(Gates.ShowAll)
//TRI_Race_Gate_Activate_All(Race, TRUE)
//TRI_Race_Gate_Activate(Race, TRI_Widget_Gates_Sel_Get(Gates), TRUE)
// Otherwise, activate only Selected Gate.
ELSE
TRI_Race_Gate_Deactivate_All(Race)
TRI_Widget_Gates_Sel_Act(Gates, Race)
ENDIF
ENDIF
IF TRI_Widget_Toggle_Get(Gates.ShowAll)
TRI_Race_Gate_Draw_All_Inactive_Markers(Race, iGateSel)
ENDIF
ENDPROC
PROC TRI_Widget_Gates_Snap_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Delete_Update")
// Check Delete Gate (button).
IF TRI_Widget_Button_Check(Gates.SnapSelected)
// Reset Delete Gate (button).
TRI_Widget_Button_Reset(Gates.SnapSelected)
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
VECTOR vSnapPos = Race.sGate[iGateSel].vPos
IF GET_GROUND_Z_FOR_3D_COORD(vSnapPos, vSnapPos.z)
Race.sGate[iGateSel].vPos = vSnapPos
TRI_Widget_Gates_Sel_Act(Gates, Race)
ELSE
SCRIPT_ASSERT("GET_GROUND_Z_FOR_3D_COORD failed!")
ENDIF
ENDIF
ENDPROC
PROC TRI_Widget_Gates_Selection_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera)
//DEBUG_MESSAGE("TRI_Widget_Gates_Selection_Update")
// Check Selected Gate (int).
IF TRI_Widget_Int_Check(Gates.Selection)
// Reset Selected Gate (int).
TRI_Widget_Int_Reset(Gates.Selection)
// Clamp Selected Gate (int), if needed.
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
IF (iGateSel >= Race.iGateCnt)
iGateSel = Race.iGateCnt - 1
TRI_Widget_Gates_Sel_Set(Gates, iGateSel)
ENDIF
// Update Gates widgets from Selected Gate.
TRI_Widget_Gates_Sel_Update_All(Gates, Race)
// If Show All Gates is on, do just that.
// TODO: Think about making into a function.
IF TRI_Widget_Toggle_Get(Gates.ShowAll)
//TRI_Race_Gate_Activate_All(Race, TRUE)
// Otherwise, activate only Selected Gate.
ELSE
//TRI_Race_Gate_Deactivate_All(Race)
//TRI_Widget_Gates_Sel_Act(Gates, Race)
ENDIF
// Have camera interp to Selected Gate, if needed.
IF (Camera.eFocus = TRI_CAMERA_FOCUS_GATES)
VECTOR vGatePos = Race.sGate[iGateSel].vPos
TRI_Camera_Interp(Camera, vGatePos, FALSE)
ENDIF
ENDIF
ENDPROC
PROC TRI_Widget_Gates_Position_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera)
//DEBUG_MESSAGE("TRI_Widget_Gates_Position_Update")
// Check Gate Position XYZ (vector).
IF TRI_Widget_Vector_Check(Gates.Position)
// Reset Gate Position XYZ (vector).
TRI_Widget_Vector_Reset(Gates.Position)
// Set Selected Gate position from Gate Position XYZ.
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
VECTOR vGatePos = TRI_Widget_Vector_Get(Gates.Position)
Race.sGate[iGateSel].vPos = vGatePos
// Reactivate Selected Gate.
TRI_Widget_Gates_Sel_Act(Gates, Race)
// Have camera interp to Gate Position XYZ, if needed.
IF (Camera.eFocus = TRI_CAMERA_FOCUS_GATES)
TRI_Camera_Interp(Camera, vGatePos, FALSE)
ENDIF
ENDIF
ENDPROC
PROC TRI_Widget_Gates_Radius_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_Radius_Update")
// Check Gate Radius (float).
IF TRI_Widget_Float_Check(Gates.Radius)
// Reset Gate Radius (float).
TRI_Widget_Float_Reset(Gates.Radius)
// Set Selected Gate radius from Gate Radius.
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
FLOAT fGateRadius = TRI_Widget_Float_Get(Gates.Radius)
Race.sGate[iGateSel].fRadius = fGateRadius
ENDIF
ENDPROC
PROC TRI_Widget_Gates_ChkpntType_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Gates_ChkpntType_Update")
// Check Gate Checkpoint Type (listbox).
IF TRI_Widget_Listbox_Check(Gates.ChkpntType)
// Reset Gate Checkpoint Type (listbox).
TRI_Widget_Listbox_Reset(Gates.ChkpntType)
// Set Selected Gate checkpoint type from Gate Checkpoint Type.
INT iGateSel = TRI_Widget_Gates_Sel_Get(Gates)
INT iChkpntType = TRI_Widget_Listbox_Get(Gates.ChkpntType)
Race.sGate[iGateSel].eChkpntType = TRI_ChkpntType_GetEnum(iChkpntType)
// Reactivate Selected Gate.
//TRI_Widget_Gates_Sel_Act(Gates, Race)
ENDIF
ENDPROC
// TODO: Add error checking and figure out a way to use race error textbox...
PROC TRI_Widget_Gates_RelMove_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera, INT iRacerSel)
//DEBUG_MESSAGE("TRI_Widget_Gates_RelMove_Update")
// Check Relative Move XYZ (vector).
IF TRI_Widget_Vector_Check(Gates.RelMove)
// Calculate Relative Move XYZ according to mode.
INT iRelMode = TRI_Widget_Listbox_Get(Gates.RelMode)
BOOL bRelAbs = TRI_Widget_Toggle_Get(Gates.RelAbs)
VECTOR vRelMove = TRI_Widget_Vector_Get(Gates.RelMove)
VECTOR vGatePos = TRI_Widget_Vector_Get(Gates.Position)
SWITCH (INT_TO_ENUM(TRI_MOVE_MODE_ENUM, iRelMode))
// Camera Relative Move.
CASE TRI_MOVE_MODE_CAMERA
IF (vRelMove.x <> 0.0)
TRI_Camera_GetRelPos_Side(Camera, vGatePos, vRelMove.x, bRelAbs)
ELIF (vRelMove.y <> 0.0)
TRI_Camera_GetRelPos_Fwd(Camera, vGatePos, vRelMove.y, bRelAbs)
ELIF (vRelMove.z <> 0.0)
TRI_Camera_GetRelPos_Up(Camera, vGatePos, vRelMove.z, bRelAbs)
ENDIF
BREAK
// Ground Relative Move.
CASE TRI_MOVE_MODE_GROUND
IF (vRelMove.x <> 0.0)
TRI_GetRelPos_Ground_Side(vGatePos, vRelMove.x)
ELIF (vRelMove.y <> 0.0)
TRI_GetRelPos_Ground_Fwd(vGatePos, vRelMove.y)
ELIF (vRelMove.z <> 0.0)
TRI_GetRelPos_Ground_Up(vGatePos, vRelMove.z)
ENDIF
BREAK
// Gate Prev Relative Move.
CASE TRI_MOVE_MODE_PREV
IF (Race.iGateCnt > 1)
INT iGateSel
iGateSel = TRI_Widget_Int_Get(Gates.Selection) - 1
IF (iGateSel >= 0)
VECTOR vGate1Pos, vGate2Pos
vGate1Pos = Race.sGate[iGateSel].vPos
vGate2Pos = Race.sGate[iGateSel + 1].vPos
IF (vRelMove.x <> 0.0)
TRI_GetRelPos_Coord_Side(vGate1Pos, vGate2Pos, vGatePos, vRelMove.x, bRelAbs)
ELIF (vRelMove.y <> 0.0)
TRI_GetRelPos_Coord_Fwd(vGate1Pos, vGate2Pos, vGatePos, vRelMove.y, bRelAbs)
ELIF (vRelMove.z <> 0.0)
TRI_GetRelPos_Coord_Up(vGate1Pos, vGatePos, vRelMove.z, bRelAbs)
ENDIF
ENDIF
ENDIF
BREAK
// Gate Next Relative Move.
CASE TRI_MOVE_MODE_NEXT
IF (Race.iGateCnt > 1)
INT iGateSel
iGateSel = TRI_Widget_Int_Get(Gates.Selection) + 1
IF (iGateSel <= (Race.iGateCnt - 1))
VECTOR vGate1Pos, vGate2Pos
vGate1Pos = Race.sGate[iGateSel].vPos
vGate2Pos = Race.sGate[iGateSel - 1].vPos
IF (vRelMove.x <> 0.0)
TRI_GetRelPos_Coord_Side(vGate1Pos, vGate2Pos, vGatePos, vRelMove.x, bRelAbs)
ELIF (vRelMove.y <> 0.0)
TRI_GetRelPos_Coord_Fwd(vGate1Pos, vGate2Pos, vGatePos, vRelMove.y, bRelAbs)
ELIF (vRelMove.z <> 0.0)
TRI_GetRelPos_Coord_Up(vGate1Pos, vGatePos, vRelMove.z, bRelAbs)
ENDIF
ENDIF
ENDIF
BREAK
// Racer Selection Relative Move.
CASE TRI_MOVE_MODE_SELECT
PED_INDEX Driver
Driver = Race.Racer[iRacerSel].Driver
IF (vRelMove.x <> 0.0)
TRI_GetRelPos_Entity_Side(Driver, vGatePos, vRelMove.x, bRelAbs)
ELIF (vRelMove.y <> 0.0)
TRI_GetRelPos_Entity_Fwd(Driver, vGatePos, vRelMove.y, bRelAbs)
ELIF (vRelMove.z <> 0.0)
TRI_GetRelPos_Entity_Up(Driver, vGatePos, vRelMove.z, bRelAbs)
ENDIF
BREAK
ENDSWITCH
// Use Relative Move XYZ to set Gate Position XYZ.
TRI_Widget_Vector_Set(Gates.Position, vGatePos, FALSE)
// Set Relative Move XYZ (vector) back to zero.
TRI_Widget_Vector_Set(Gates.RelMove, <<0.0,0.0,0.0>>)
ENDIF
ENDPROC
// -----------------------------------
// GATES MAIN PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_Gates_Setup(TRI_WIDGET_GATES& Gates)
//DEBUG_MESSAGE("TRI_Widget_Gates_Setup")
// Create Gates widget group.
Gates.GroupID = START_WIDGET_GROUP("Gates")
// Setup Create Gate (button).
TRI_Widget_Button_Setup(Gates.Create, "Create Gate")
// Setup Delete Gate (button).
TRI_Widget_Button_Setup(Gates.Delete, "Delete Gate")
// Setup Show All Gates (toggle).
TRI_Widget_Toggle_Setup(Gates.ShowAll, "Show All Gates", TRUE)
// Setup Delete Gate (button).
TRI_Widget_Button_Setup(Gates.SnapSelected, "Snap Selected Gate To The Ground")
// Setup Selected Gate (int).
TRI_Widget_Int_Setup(Gates.Selection, "Selected Gate", 0, TRI_GATE_MAX - 1, 1)
// Setup Gate Position XYZ (vector).
TRI_Widget_Vector_Setup(Gates.Position, "Gate Position", -10000.0, 10000.0, 0.1)
// Setup Gate Radius (float).
TRI_Widget_Float_Setup(Gates.Radius, "Gate Radius", 0.0, 100.0, 1.0)
// Setup Gate Checkpoint Type (listbox).
TEXT_LABEL_31 szChkpntType[10]
TRI_ChkpntType_Populate(szChkpntType)
TRI_Widget_Listbox_Setup(Gates.ChkpntType, "Gate Checkpoint Type", szChkpntType)
// Setup Relative Move Mode (listbox).
TEXT_LABEL_31 szRelMode[5]
szRelMode[0] = "Camera Relative"
szRelMode[1] = "Ground Relative"
szRelMode[2] = "Gate Prev Relative"
szRelMode[3] = "Gate Next Relative"
szRelMode[4] = "Racer Selection Relative"
TRI_Widget_Listbox_Setup(Gates.RelMode, "Relative Move Mode", szRelMode)
// Setup Relative Move Absolute (toggle).
TRI_Widget_Toggle_Setup(Gates.RelAbs, "Relative Move Absolute")
// Setup Relative Move XYZ (vector).
TRI_Widget_Vector_Setup(Gates.RelMove, "Gate Relative Move", -100.0, 100.0, 0.1)
// Close Gates widget group.
STOP_WIDGET_GROUP()
ENDPROC
FUNC BOOL TRI_Widget_Gates_Update(TRI_WIDGET_GATES& Gates, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera, INT iRacerSel)
//DEBUG_MESSAGE("TRI_Widget_Gates_Update")
// Update all TRI_ Widget Gates controls.
TRI_Widget_Gates_Create_Update(Gates, Race, Camera)
TRI_Widget_Gates_Delete_Update(Gates, Race)
TRI_Widget_Gates_ShowAll_Update(Gates, Race)
TRI_Widget_Gates_Snap_Update(Gates, Race)
TRI_Widget_Gates_Selection_Update(Gates, Race, Camera)
TRI_Widget_Gates_Position_Update(Gates, Race, Camera)
TRI_Widget_Gates_Radius_Update(Gates, Race)
TRI_Widget_Gates_ChkpntType_Update(Gates, Race)
//TRI_Widget_Gates_StuntType_Update(Gates, Race)
TRI_Widget_Gates_RelMove_Update(Gates, Race, Camera, iRacerSel)
// Update TRI_ Widget Gates still running.
RETURN TRUE
ENDFUNC
PROC TRI_Widget_Gates_Cleanup(TRI_WIDGET_GATES& Gates)
//DEBUG_MESSAGE("TRI_Widget_Gates_Cleanup")
TRI_Widget_Delete_Widget_Group(Gates.GroupID)
ENDPROC
// -----------------------------------
// RACERS HELPER PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_Racers_Queue_Init(TRI_WIDGET_RACERS& Racers)
//DEBUG_MESSAGE("TRI_Widget_Racers_Queue_Init")
INT i
REPEAT TRI_RACER_MAX i
Racers.bRacerQueue[i] = FALSE
ENDREPEAT
ENDPROC
PROC TRI_Widget_Racers_Queue_Add(TRI_WIDGET_RACERS& Racers, INT iRacer)
//DEBUG_MESSAGE("TRI_Widget_Racers_Queue_Add")
Racers.bRacerQueue[iRacer] = TRUE
ENDPROC
PROC TRI_Widget_Racers_Queue_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Queue_Update")
INT i
REPEAT Race.iRacerCnt i
IF Racers.bRacerQueue[i]
IF TRI_Racer_Stream(Race.Racer[i])
IF TRI_Racer_Create(Race.Racer[i], FALSE)
TRI_Racer_Freeze(Race.Racer[i])
Racers.bRacerQueue[i] = FALSE
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDPROC
PROC TRI_Widget_Racers_Sel_Set(TRI_WIDGET_RACERS& Racers, INT iValue, BOOL bReset = TRUE)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Set")
TRI_Widget_Int_Set(Racers.Selection, iValue, bReset)
ENDPROC
PROC TRI_Widget_Racers_Sel_Set_Update(TRI_WIDGET_RACERS& Racers, INT iValue)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Set_Update")
TRI_Widget_Int_Set(Racers.Selection, -1)
TRI_Widget_Int_Set(Racers.Selection, iValue, FALSE)
ENDPROC
FUNC INT TRI_Widget_Racers_Sel_Get(TRI_WIDGET_RACERS& Racers)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Get")
RETURN TRI_Widget_Int_Get(Racers.Selection)
ENDFUNC
PROC TRI_Widget_Racers_Sel_Inc(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Inc")
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
IF (iRacerSel < (Race.iRacerCnt - 1))
++iRacerSel
ELIF (iRacerSel = (Race.iRacerCnt - 1))
iRacerSel = 0
ENDIF
TRI_Widget_Int_Set(Racers.Selection, iRacerSel, FALSE)
ENDPROC
PROC TRI_Widget_Racers_Sel_Dec(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Dec")
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
IF (iRacerSel > 0)
--iRacerSel
ELIF (iRacerSel = 0)
iRacerSel = Race.iRacerCnt - 1
ENDIF
TRI_Widget_Int_Set(Racers.Selection, iRacerSel, FALSE)
ENDPROC
PROC TRI_Widget_Racers_Sel_Beg(TRI_WIDGET_RACERS& Racers)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Beg")
TRI_Widget_Int_Set(Racers.Selection, 0, FALSE)
ENDPROC
PROC TRI_Widget_Racers_Sel_End(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_End")
TRI_Widget_Int_Set(Racers.Selection, Race.iRacerCnt - 1, FALSE)
ENDPROC
// TODO: These get used in probably too many places where I already have the indez...
PROC TRI_Widget_Racers_Sel_Drv_Act(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, BOOL bDestroyOld)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Drv_Act")
INT iRacer = TRI_Widget_Racers_Sel_Get(Racers)
IF bDestroyOld
TRI_Race_Racer_Driver_UnFreeze(Race, iRacer)
TRI_Race_Racer_Driver_Destroy(Race, iRacer)
ENDIF
TRI_Race_Racer_Driver_Request(Race, iRacer)
TRI_Widget_Racers_Queue_Add(Racers, iRacer)
ENDPROC
PROC TRI_Widget_Racers_Sel_Drv_DeAct(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, BOOL bDestroyOld)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Drv_DeAct")
INT iRacer = TRI_Widget_Racers_Sel_Get(Racers)
TRI_Race_Racer_Driver_Evict(Race, iRacer)
IF bDestroyOld
TRI_Race_Racer_Driver_UnFreeze(Race, iRacer)
TRI_Race_Racer_Driver_Destroy(Race, iRacer)
ENDIF
ENDPROC
PROC TRI_Widget_Racers_Sel_Veh_Act(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, BOOL bDestroyOld)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Veh_Act")
INT iRacer = TRI_Widget_Racers_Sel_Get(Racers)
IF bDestroyOld
TRI_Race_Racer_Vehicle_UnFreeze(Race, iRacer)
TRI_Race_Racer_Vehicle_Destroy(Race, iRacer)
ENDIF
TRI_Race_Racer_Vehicle_Request(Race, iRacer)
TRI_Widget_Racers_Queue_Add(Racers, iRacer)
ENDPROC
PROC TRI_Widget_Racers_Sel_Veh_DeAct(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, BOOL bDestroyOld)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Veh_DeAct")
INT iRacer = TRI_Widget_Racers_Sel_Get(Racers)
TRI_Race_Racer_Vehicle_Evict(Race, iRacer)
IF bDestroyOld
TRI_Race_Racer_Vehicle_UnFreeze(Race, iRacer)
TRI_Race_Racer_Vehicle_Destroy(Race, iRacer)
ENDIF
ENDPROC
PROC TRI_Widget_Racers_Sel_Act(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, BOOL bDestroyOld)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Act")
INT iRacer = TRI_Widget_Racers_Sel_Get(Racers)
IF bDestroyOld
TRI_Race_Racer_UnFreeze(Race, iRacer)
TRI_Race_Racer_Destroy(Race, iRacer)
ENDIF
TRI_Race_Racer_Request(Race, iRacer)
TRI_Widget_Racers_Queue_Add(Racers, iRacer)
ENDPROC
PROC TRI_Widget_Racers_Sel_DeAct(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, BOOL bDestroyOld)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_DeAct")
INT iRacer = TRI_Widget_Racers_Sel_Get(Racers)
TRI_Race_Racer_Evict(Race, iRacer)
IF bDestroyOld
TRI_Race_Racer_UnFreeze(Race, iRacer)
TRI_Race_Racer_Destroy(Race, iRacer)
ENDIF
ENDPROC
PROC TRI_Widget_Racers_All_Act(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, BOOL bDestroyOld)
//DEBUG_MESSAGE("TRI_Widget_Racers_All_Act")
TRI_Widget_Racers_Queue_Init(Racers)
INT i
REPEAT Race.iRacerCnt i
IF bDestroyOld
TRI_Race_Racer_UnFreeze(Race, i)
TRI_Race_Racer_Destroy(Race, i)
ENDIF
TRI_Race_Racer_Request(Race, i)
TRI_Widget_Racers_Queue_Add(Racers, i)
ENDREPEAT
ENDPROC
PROC TRI_Widget_Racers_All_DeAct(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, BOOL bDestroyOld)
//DEBUG_MESSAGE("TRI_Widget_Racers_All_DeAct")
UNUSED_PARAMETER(Racers)
INT i
REPEAT Race.iRacerCnt i
TRI_Race_Racer_Evict(Race, i)
IF bDestroyOld
TRI_Race_Racer_UnFreeze(Race, i)
TRI_Race_Racer_Destroy(Race, i)
ENDIF
ENDREPEAT
ENDPROC
// TODO: Add error checking and figure out a way to use race error textbox...
FUNC BOOL TRI_Widget_Racers_Sel_Create(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, VECTOR vStartPos)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Create")
IF (Race.iRacerCnt >= TRI_RACER_MAX)
RETURN FALSE
ENDIF
++Race.iRacerCnt
INT iRacer = Race.iRacerCnt - 1
INT iRacerNew = TRI_Widget_Racers_Sel_Get(Racers) + 1
WHILE (iRacer > iRacerNew)
Race.Racer[iRacer] = Race.Racer[iRacer - 1]
--iRacer
ENDWHILE
TRI_Race_Racer_Init(Race, iRacerNew)
Race.Racer[iRacerNew].vStartPos = vStartPos
TRI_Widget_Racers_Sel_Set_Update(Racers, iRacerNew)
RETURN TRUE
ENDFUNC
FUNC BOOL TRI_Widget_Racers_Sel_Delete(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Delete")
INT iRacer = TRI_Widget_Racers_Sel_Get(Racers)
INT iRacerNew = Race.iRacerCnt - 1
TRI_Race_Racer_Init(Race, iRacer)
WHILE (iRacer < (Race.iRacerCnt - 1))
Race.Racer[iRacer] = Race.Racer[iRacer + 1]
--iRacerNew
++iRacer
ENDWHILE
IF (Race.iRacerCnt > 1)
--Race.iRacerCnt
IF (iRacerNew = Race.iRacerCnt)
--iRacerNew
ENDIF
ENDIF
TRI_Widget_Racers_Sel_Set_Update(Racers, iRacerNew)
RETURN TRUE
ENDFUNC
PROC TRI_Widget_Racers_Sel_Update_Name(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Update_Position")
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
TEXT_LABEL_31 szName = Race.Racer[iRacerSel].szName
TRI_Widget_Textbox_Set(Racers.Name, szName)
ENDPROC
PROC TRI_Widget_Racers_Sel_Update_Position(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Update_Position")
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
VECTOR vStartPos = Race.Racer[iRacerSel].vStartPos
TRI_Widget_Vector_Set(Racers.Position, vStartPos)
ENDPROC
PROC TRI_Widget_Racers_Sel_Update_Heading(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Update_Heading")
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
FLOAT fStartHead = Race.Racer[iRacerSel].fStartHead
TRI_Widget_Float_Set(Racers.Heading, fStartHead)
ENDPROC
PROC TRI_Widget_Racers_Sel_Update_DriverType(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Update_DriverType")
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
PED_TYPE eDriverType = Race.Racer[iRacerSel].eDriverType
INT iDriverType = TRI_DriverType_GetIndex(eDriverType)
TRI_Widget_Listbox_Set(Racers.DriverType, iDriverType)
ENDPROC
PROC TRI_Widget_Racers_Sel_Update_DriverModel(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Update_DriverModel")
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
MODEL_NAMES eDriverModel = Race.Racer[iRacerSel].eDriverModel
INT iDriverModel = TRI_DriverModel_GetIndex(eDriverModel)
TRI_Widget_Listbox_Set(Racers.DriverModel, iDriverModel)
ENDPROC
PROC TRI_Widget_Racers_Sel_Update_VehicleModel(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Update_VehicleModel")
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
MODEL_NAMES eVehicleModel = Race.Racer[iRacerSel].eVehicleModel
INT iVehicleModel = TRI_VehicleModel_GetIndex(eVehicleModel)
TRI_Widget_Listbox_Set(Racers.VehicleModel, iVehicleModel)
ENDPROC
PROC TRI_Widget_Racers_Sel_Update_All(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Sel_Update_All")
TRI_Widget_Racers_Sel_Update_Name(Racers, Race)
TRI_Widget_Racers_Sel_Update_Position(Racers, Race)
TRI_Widget_Racers_Sel_Update_Heading(Racers, Race)
TRI_Widget_Racers_Sel_Update_DriverType(Racers, Race)
TRI_Widget_Racers_Sel_Update_DriverModel(Racers, Race)
TRI_Widget_Racers_Sel_Update_VehicleModel(Racers, Race)
ENDPROC
// -----------------------------------
// RACERS HELPER PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_Racers_Create_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera)
//DEBUG_MESSAGE("TRI_Widget_Racers_Create_Update")
// Check Create Racer (button).
IF TRI_Widget_Button_Check(Racers.Create)
// Reset Create Racer (button).
TRI_Widget_Button_Reset(Racers.Create)
// Create new racer at placement position, if possible.
VECTOR vStartPos = TRI_Camera_GetPlacementPos(Camera)
TRI_Widget_Racers_Sel_Create(Racers, Race, vStartPos)
ENDIF
ENDPROC
PROC TRI_Widget_Racers_Delete_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Delete_Update")
// Check Delete Racer (button).
IF TRI_Widget_Button_Check(Racers.Delete)
// Reset Delete Racer (button).
TRI_Widget_Button_Reset(Racers.Delete)
// Deactivate Selected Racer.
TRI_Widget_Racers_Sel_DeAct(Racers, Race, TRUE)
// Delete Selected Racer, if possible.
TRI_Widget_Racers_Sel_Delete(Racers, Race)
ENDIF
ENDPROC
PROC TRI_Widget_Racers_ShowAll_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_ShowAll_Update")
// Check Show All Racers (toggle).
IF TRI_Widget_Toggle_Check(Racers.ShowAll)
// Reset Show All Racers (toggle).
TRI_Widget_Toggle_Reset(Racers.ShowAll)
// If Show All Racers is on, do just that.
// TODO: Think about making into a function.
IF TRI_Widget_Toggle_Get(Racers.ShowAll)
TRI_Widget_Racers_All_Act(Racers, Race, FALSE)
// Otherwise, activate only Selected Racer.
ELSE
TRI_Widget_Racers_All_DeAct(Racers, Race, TRUE)
TRI_Widget_Racers_Sel_Act(Racers, Race, FALSE)
ENDIF
ENDIF
ENDPROC
PROC TRI_Widget_Racers_Selection_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera)
//DEBUG_MESSAGE("TRI_Widget_Racers_Selection_Update")
// Check Selected Racer (int).
IF TRI_Widget_Int_Check(Racers.Selection)
// Reset Selected Racer (int).
TRI_Widget_Int_Reset(Racers.Selection)
// Clamp Selected Racer (int), if needed.
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
IF (iRacerSel >= Race.iRacerCnt)
iRacerSel = Race.iRacerCnt - 1
TRI_Widget_Racers_Sel_Set(Racers, iRacerSel)
ENDIF
// Update Racers widgets from Selected Racer.
TRI_Widget_Racers_Sel_Update_All(Racers, Race)
// If Show All Racers is on, do just that.
// TODO: Think about making into a function.
IF TRI_Widget_Toggle_Get(Racers.ShowAll)
TRI_Widget_Racers_All_Act(Racers, Race, FALSE)
// Otherwise, activate only Selected Racer.
ELSE
TRI_Widget_Racers_All_DeAct(Racers, Race, TRUE)
TRI_Widget_Racers_Sel_Act(Racers, Race, FALSE)
ENDIF
// Have camera interp to Selected Racer, if needed.
IF (Camera.eFocus = TRI_CAMERA_FOCUS_RACERS)
VECTOR vStartPos = Race.Racer[iRacerSel].vStartPos
TRI_Camera_Interp(Camera, vStartPos, FALSE)
ENDIF
ENDIF
ENDPROC
PROC TRI_Widget_Racers_Name_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Name_Update")
// Check Racer Name (textbox).
IF TRI_Widget_Textbox_Check(Racers.Name)
// Reset Racer Name (textbox).
TRI_Widget_Textbox_Reset(Racers.Name)
// Set Selected Racer name from Racer Name.
INT iRacerSel = TRI_Widget_Int_Get(Racers.Selection)
TEXT_LABEL_31 szRacerName = TRI_Widget_Textbox_Get(Racers.Name)
Race.Racer[iRacerSel].szName = szRacerName
ENDIF
ENDPROC
PROC TRI_Widget_Racers_Position_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera)
//DEBUG_MESSAGE("TRI_Widget_Racers_Position_Update")
// Check Racer Start Position XYZ (vector).
IF TRI_Widget_Vector_Check(Racers.Position)
// Reset Racer Start Position XYZ (vector).
TRI_Widget_Vector_Reset(Racers.Position)
// Set Selected Racer start position from Racer Start Position XYZ.
INT iRacerSel = TRI_Widget_Int_Get(Racers.Selection)
VECTOR vStartPos = TRI_Widget_Vector_Get(Racers.Position)
Race.Racer[iRacerSel].vStartPos = vStartPos
// Reactivate Selected Racer.
TRI_Widget_Racers_Sel_Act(Racers, Race, FALSE)
// Have camera interp to Racer Start Position XYZ, if needed.
IF (Camera.eFocus = TRI_CAMERA_FOCUS_RACERS)
TRI_Camera_Interp(Camera, vStartPos, FALSE)
ENDIF
ENDIF
ENDPROC
PROC TRI_Widget_Racers_Heading_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_Heading_Update")
// Check Racer Start Heading (float).
IF TRI_Widget_Float_Check(Racers.Heading)
// Reset Racer Start Heading (float).
TRI_Widget_Float_Reset(Racers.Heading)
// Set Selected Racer start heading from Racer Start Heading.
INT iRacerSel = TRI_Widget_Int_Get(Racers.Selection)
FLOAT fStartHead = TRI_Widget_Float_Get(Racers.Heading)
Race.Racer[iRacerSel].fStartHead = fStartHead
// Reactivate Selected Racer.
TRI_Widget_Racers_Sel_Act(Racers, Race, FALSE)
ENDIF
ENDPROC
PROC TRI_Widget_Racers_DriverType_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_DriverType_Update")
// Check Racer Driver Type (listbox).
IF TRI_Widget_Listbox_Check(Racers.DriverType)
// Reset Racer Driver Type (listbox).
TRI_Widget_Listbox_Reset(Racers.DriverType)
// Deactivate Selected Racer driver.
TRI_Widget_Racers_Sel_Drv_DeAct(Racers, Race, TRUE)
// Set Selected Racer driver type from Racer Driver Type.
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
INT iDriverType = TRI_Widget_Listbox_Get(Racers.DriverType)
Race.Racer[iRacerSel].eDriverType = TRI_DriverType_GetEnum(iDriverType)
// Reactivate Selected Racer driver.
TRI_Widget_Racers_Sel_Drv_Act(Racers, Race, TRUE)
ENDIF
ENDPROC
PROC TRI_Widget_Racers_DriverModel_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_DriverModel_Update")
// Check Racer Driver Model (listbox).
IF TRI_Widget_Listbox_Check(Racers.DriverModel)
// Reset Racer Driver Model (listbox).
TRI_Widget_Listbox_Reset(Racers.DriverModel)
// Deactivate Selected Racer driver.
TRI_Widget_Racers_Sel_Drv_DeAct(Racers, Race, TRUE)
// Set Selected Racer driver model from Racer Driver Model.
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
INT iDriverModel = TRI_Widget_Listbox_Get(Racers.DriverModel)
Race.Racer[iRacerSel].eDriverModel = TRI_DriverModel_GetEnum(iDriverModel)
// Reactivate Selected Racer driver.
TRI_Widget_Racers_Sel_Drv_Act(Racers, Race, TRUE)
ENDIF
ENDPROC
PROC TRI_Widget_Racers_VehicleModel_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Widget_Racers_VehicleModel_Update")
// Check Racer Vehicle Model (listbox).
IF TRI_Widget_Listbox_Check(Racers.VehicleModel)
// Reset Racer Vehicle Model (listbox).
TRI_Widget_Listbox_Reset(Racers.VehicleModel)
// Deactivate Selected Racer vehicle.
TRI_Widget_Racers_Sel_Veh_DeAct(Racers, Race, TRUE)
// Set Selected Racer vehicle model from Racer Vehicle Model.
INT iRacerSel = TRI_Widget_Racers_Sel_Get(Racers)
INT iVehicleModel = TRI_Widget_Listbox_Get(Racers.VehicleModel)
Race.Racer[iRacerSel].eVehicleModel = TRI_VehicleModel_GetEnum(iVehicleModel)
// Reactivate Selected Racer vehicle.
TRI_Widget_Racers_Sel_Veh_Act(Racers, Race, TRUE)
ENDIF
ENDPROC
// TODO: Add error checking and figure out a way to use race error textbox...
PROC TRI_Widget_Racers_RelMove_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera, INT iGateSel)
//DEBUG_MESSAGE("TRI_Widget_Racers_RelMove_Update")
// Check Relative Move XYZ (vector).
IF TRI_Widget_Vector_Check(Racers.RelMove)
// Calculate Relative Move XYZ according to mode.
INT iRelMode = TRI_Widget_Listbox_Get(Racers.RelMode)
BOOL bRelAbs = TRI_Widget_Toggle_Get(Racers.RelAbs)
VECTOR vRelMove = TRI_Widget_Vector_Get(Racers.RelMove)
VECTOR vRacerPos = TRI_Widget_Vector_Get(Racers.Position)
FLOAT fRacerHead = TRI_Widget_Float_Get(Racers.Heading)
SWITCH (INT_TO_ENUM(TRI_MOVE_MODE_ENUM, iRelMode))
// Camera Relative Move.
CASE TRI_MOVE_MODE_CAMERA
IF (vRelMove.x <> 0.0)
TRI_Camera_GetRelPos_Side(Camera, vRacerPos, vRelMove.x, bRelAbs)
fRacerHead = TRI_Camera_GetHeading(Camera)
ELIF (vRelMove.y <> 0.0)
TRI_Camera_GetRelPos_Fwd(Camera, vRacerPos, vRelMove.y, bRelAbs)
fRacerHead = TRI_Camera_GetHeading(Camera)
ELIF (vRelMove.z <> 0.0)
TRI_Camera_GetRelPos_Up(Camera, vRacerPos, vRelMove.z, bRelAbs)
fRacerHead = TRI_Camera_GetHeading(Camera)
ENDIF
BREAK
// Ground Relative Move.
CASE TRI_MOVE_MODE_GROUND
IF (vRelMove.x <> 0.0)
TRI_GetRelPos_Ground_Side(vRacerPos, vRelMove.x)
fRacerHead = 0.0
ELIF (vRelMove.y <> 0.0)
TRI_GetRelPos_Ground_Fwd(vRacerPos, vRelMove.y)
fRacerHead = 0.0
ELIF (vRelMove.z <> 0.0)
TRI_GetRelPos_Ground_Up(vRacerPos, vRelMove.z)
fRacerHead = 0.0
ENDIF
BREAK
// Racer Prev Relative Move.
CASE TRI_MOVE_MODE_PREV
IF (Race.iRacerCnt > 1)
INT iRacerSel
iRacerSel = TRI_Widget_Int_Get(Racers.Selection) - 1
IF (iRacerSel >= 0)
PED_INDEX Driver
Driver = Race.Racer[iRacerSel].Driver
IF (vRelMove.x <> 0.0)
TRI_GetRelPos_Entity_Side(Driver, vRacerPos, vRelMove.x, bRelAbs)
fRacerHead = GET_ENTITY_HEADING(Driver)
ELIF (vRelMove.y <> 0.0)
TRI_GetRelPos_Entity_Fwd(Driver, vRacerPos, vRelMove.y, bRelAbs)
fRacerHead = GET_ENTITY_HEADING(Driver)
ELIF (vRelMove.z <> 0.0)
TRI_GetRelPos_Entity_Up(Driver, vRacerPos, vRelMove.z, bRelAbs)
fRacerHead = GET_ENTITY_HEADING(Driver)
ENDIF
ENDIF
ENDIF
BREAK
// Racer Next Relative Move.
CASE TRI_MOVE_MODE_NEXT
IF (Race.iRacerCnt > 1)
INT iRacerSel
iRacerSel = TRI_Widget_Int_Get(Racers.Selection) + 1
IF (iRacerSel <= (Race.iRacerCnt - 1))
PED_INDEX Driver
Driver = Race.Racer[iRacerSel].Driver
IF (vRelMove.x <> 0.0)
TRI_GetRelPos_Entity_Side(Driver, vRacerPos, vRelMove.x, bRelAbs)
fRacerHead = GET_ENTITY_HEADING(Driver)
ELIF (vRelMove.y <> 0.0)
TRI_GetRelPos_Entity_Fwd(Driver, vRacerPos, vRelMove.y, bRelAbs)
fRacerHead = GET_ENTITY_HEADING(Driver)
ELIF (vRelMove.z <> 0.0)
TRI_GetRelPos_Entity_Up(Driver, vRacerPos, vRelMove.z, bRelAbs)
fRacerHead = GET_ENTITY_HEADING(Driver)
ENDIF
ENDIF
ENDIF
BREAK
// Gate Selection Relative Move.
CASE TRI_MOVE_MODE_SELECT
VECTOR vGate1Pos, vGate2Pos, vGateFwd
IF (Race.iGateCnt = 1)
vGate1Pos = Race.sGate[iGateSel].vPos
vGate2Pos = TRI_Master.vDefRcrPos
ELIF (iGateSel = (Race.iGateCnt - 1))
vGate1Pos = Race.sGate[iGateSel].vPos
vGate2Pos = Race.sGate[iGateSel - 1].vPos
ELSE
vGate1Pos = Race.sGate[iGateSel].vPos
vGate2Pos = Race.sGate[iGateSel + 1].vPos
ENDIF
IF (vRelMove.x <> 0.0)
TRI_GetRelPos_Coord_Side(vGate1Pos, vGate2Pos, vRacerPos, vRelMove.x, bRelAbs)
vGateFwd = vGate2Pos - vGate1Pos
fRacerHead = GET_HEADING_FROM_VECTOR_2D(vGateFwd.x, vGateFwd.y)
ELIF (vRelMove.y <> 0.0)
TRI_GetRelPos_Coord_Fwd(vGate1Pos, vGate2Pos, vRacerPos, vRelMove.y, bRelAbs)
vGateFwd = vGate2Pos - vGate1Pos
fRacerHead = GET_HEADING_FROM_VECTOR_2D(vGateFwd.x, vGateFwd.y)
ELIF (vRelMove.z <> 0.0)
TRI_GetRelPos_Coord_Up(vGate1Pos, vRacerPos, vRelMove.z, bRelAbs)
vGateFwd = vGate2Pos - vGate1Pos
fRacerHead = GET_HEADING_FROM_VECTOR_2D(vGateFwd.x, vGateFwd.y)
ENDIF
BREAK
ENDSWITCH
// Use Relative Move XYZ to set Racer Start Position XYZ.
TRI_Widget_Vector_Set(Racers.Position, vRacerPos, FALSE)
// Use Relative Move Mode to set Racer Start Heading.
TRI_Widget_Float_Set(Racers.Heading, fRacerHead, FALSE)
// Set Relative Move XYZ (vector) back to zero.
TRI_Widget_Vector_Set(Racers.RelMove, <<0.0,0.0,0.0>>)
ENDIF
ENDPROC
// -----------------------------------
// RACERS MAIN PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_Racers_Setup(TRI_WIDGET_RACERS& Racers)
//DEBUG_MESSAGE("TRI_Widget_Racers_Setup")
// Create Racers widget group.
Racers.GroupID = START_WIDGET_GROUP("Racers")
// Setup Create Racer (button).
TRI_Widget_Button_Setup(Racers.Create, "Create Racer")
// Setup Delete Racer (button).
TRI_Widget_Button_Setup(Racers.Delete, "Delete Racer")
// Setup Show All Racers (toggle).
TRI_Widget_Toggle_Setup(Racers.ShowAll, "Show All Racers")
// Setup Selected Racer (int).
TRI_Widget_Int_Setup(Racers.Selection, "Selected Racer", 0, TRI_RACER_MAX - 1, 1)
// Setup Racer Name (textbox).
TRI_Widget_Textbox_Setup(Racers.Name, "Racer Name", "Put Racer Name Here!")
// Setup Racer Start Position XYZ (vector).
TRI_Widget_Vector_Setup(Racers.Position, "Racer Start Position", -10000.0, 10000.0, 0.1)
// Setup Racer Start Heading (float).
TRI_Widget_Float_Setup(Racers.Heading, "Racer Start Heading", 0.0, 359.9, 0.1)
// Setup Racer Driver Type (listbox).
TEXT_LABEL_31 szDriverType[4]
TRI_DriverType_Populate(szDriverType)
TRI_Widget_Listbox_Setup(Racers.DriverType, "Racer Driver Type", szDriverType)
// Setup Racer Driver Model (listbox).
TEXT_LABEL_31 szDriverModel[4]
TRI_DriverModel_Populate(szDriverModel)
TRI_Widget_Listbox_Setup(Racers.DriverModel, "Racer Driver Model", szDriverModel)
// Setup Racer Vehicle Model (listbox).
TEXT_LABEL_31 szVehicleModel[60]
TRI_VehicleModel_Populate(szVehicleModel)
TRI_Widget_Listbox_Setup(Racers.VehicleModel, "Racer Vehicle Model", szVehicleModel)
// Setup Relative Move Mode (listbox).
TEXT_LABEL_31 szRelMode[5]
szRelMode[0] = "Camera Relative"
szRelMode[1] = "Ground Relative"
szRelMode[2] = "Racer Prev Relative"
szRelMode[3] = "Racer Next Relative"
szRelMode[4] = "Gate Selection Relative"
TRI_Widget_Listbox_Setup(Racers.RelMode, "Relative Move Mode", szRelMode)
// Setup Relative Move Absolute (toggle).
TRI_Widget_Toggle_Setup(Racers.RelAbs, "Relative Move Absolute")
// Setup Relative Move XYZ (vector).
TRI_Widget_Vector_Setup(Racers.RelMove, "Racer Relative Move", -100.0, 100.0, 0.1)
// Init Racers Queue.
TRI_Widget_Racers_Queue_Init(Racers)
// Close Racers widget group.
STOP_WIDGET_GROUP()
ENDPROC
FUNC BOOL TRI_Widget_Racers_Update(TRI_WIDGET_RACERS& Racers, TRI_RACE_STRUCT& Race, TRI_CAMERA_STRUCT& Camera, INT iGateSel)
//DEBUG_MESSAGE("TRI_Widget_Racers_Update")
// Update all TRI_ Widget Racers controls.
TRI_Widget_Racers_Create_Update(Racers, Race, Camera)
TRI_Widget_Racers_Delete_Update(Racers, Race)
TRI_Widget_Racers_ShowAll_Update(Racers, Race)
TRI_Widget_Racers_Selection_Update(Racers, Race, Camera)
TRI_Widget_Racers_Name_Update(Racers, Race)
TRI_Widget_Racers_Position_Update(Racers, Race, Camera)
TRI_Widget_Racers_Heading_Update(Racers, Race)
TRI_Widget_Racers_DriverType_Update(Racers, Race)
TRI_Widget_Racers_DriverModel_Update(Racers, Race)
TRI_Widget_Racers_VehicleModel_Update(Racers, Race)
TRI_Widget_Racers_RelMove_Update(Racers, Race, Camera, iGateSel)
// Update Racers Queue.
TRI_Widget_Racers_Queue_Update(Racers, Race)
// Update TRI_ Widget Racers still running.
RETURN TRUE
ENDFUNC
PROC TRI_Widget_Racers_Cleanup(TRI_WIDGET_RACERS& Racers)
//DEBUG_MESSAGE("TRI_Widget_Racers_Cleanup")
TRI_Widget_Delete_Widget_Group(Racers.GroupID)
ENDPROC
// -----------------------------------
// RACE HELPER PROCS/FUNCTIONS
// -----------------------------------
FUNC BOOL TRI_Widget_Race_Name_Qualify(TRI_WIDGET_RACE& Race)
//DEBUG_MESSAGE("TRI_Widget_Race_Name_Qualify")
TEXT_LABEL_31 szName = TRI_Widget_Textbox_Get(Race.Name)
IF IS_STRING_EMPTY(szName)
TEXT_LABEL_31 szFileName = TRI_Widget_Textbox_Get(Race.FileName)
IF NOT IS_STRING_EMPTY(szFileName)
TRI_Widget_Textbox_Set(Race.Error, "Name Invalid! Used FileName!")
TRI_Widget_Textbox_Set(Race.Name, szFileName)
ELSE
DEBUG_MESSAGE("TRI_Widget_Race_Name_Qualify: Name invalid!")
TRI_Widget_Textbox_Set(Race.Error, "Name Invalid! Try Again!")
TRI_Widget_Textbox_Set(Race.Name, "")
RETURN FALSE
ENDIF
ENDIF
RETURN TRUE
ENDFUNC
#IF IS_DEBUG_BUILD
FUNC BOOL TRI_Widget_Race_FileName_Qualify(TRI_WIDGET_RACE& Race)
//DEBUG_MESSAGE("TRI_Widget_Race_FileName_Qualify")
TEXT_LABEL_31 szFileName = TRI_Widget_Textbox_Get(Race.FileName)
IF IS_STRING_EMPTY(szFileName)
TEXT_LABEL_31 szName = TRI_Widget_Textbox_Get(Race.Name)
IF NOT IS_STRING_EMPTY(szName)
TRI_Widget_Textbox_Set(Race.Error, "FileName Invalid! Used Name!")
TRI_Widget_Textbox_Set(Race.FileName, szName)
ELSE
DEBUG_MESSAGE("TRI_Widget_Race_FileName_Qualify: FileName invalid!")
TRI_Widget_Textbox_Set(Race.Error, "FileName Invalid! Try Again!")
TRI_Widget_Textbox_Set(Race.FileName, "")
RETURN FALSE
ENDIF
ENDIF
szFileName = TRI_FileName_MakeString(szFileName)
TRI_Widget_Textbox_Set(Race.FileName, szFileName)
RETURN TRUE
ENDFUNC
#ENDIF
// -----------------------------------
// RACE MAIN PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_Race_Setup(TRI_WIDGET_RACE& Race)
//DEBUG_MESSAGE("TRI_Widget_Race_Setup")
// Create Race widget group.
Race.GroupID = START_WIDGET_GROUP("Race")
// Setup Race Error (textbox).
TRI_Widget_Textbox_Setup(Race.Error, "Race Error", "Race Errors Show Up Here!")
// Setup Race Time (float) (set newest race).
// TODO: Not sure how to do a time widget. Hold off for now...
//TRI_Widget_Float_Setup(Race.Time, "Race Time", 0.0, 100.0, 0.01)
// Setup Race Name (textbox) (set newest race).
TRI_Widget_Textbox_Setup(Race.Name, "Race Name", TRI_Master.szRaceName[TRI_Master.iRaceCnt])
// Setup Race FileName (textbox) (set newest race).
TRI_Widget_Textbox_Setup(Race.FileName, "Race FileName", TRI_Master.szRaceFileName[TRI_Master.iRaceCnt])
// Setup Create Race (button).
TRI_Widget_Button_Setup(Race.Create, "Create Race")
// Setup Pick Race (listbox) (set newest race).
TRI_Widget_Listbox_Setup(Race.Pick, "Pick Race", TRI_Master.szRaceFileName, TRI_Master.iRaceCur) // TRI_Master.iRaceCnt - 1)
// Setup Load Race (button) (set to auto-load).
TRI_Widget_Button_Setup(Race.Load, "Load Race", TRUE)
// Setup Save Race (button).
TRI_Widget_Button_Setup(Race.Save, "Save Race")
// Setup Export Race (button).
TRI_Widget_Button_Setup(Race.Export, "Export Race")
// Setup Gates widget group.
TRI_Widget_Gates_Setup(Race.Gates)
// Setup Racers widget group.
TRI_Widget_Racers_Setup(Race.Racers)
// Close Race widget group.
STOP_WIDGET_GROUP()
ENDPROC
FUNC BOOL TRI_Widget_Race_Update(TRI_WIDGET_RACE& Race, TRI_CAMERA_STRUCT& Camera)
//DEBUG_MESSAGE("TRI_Widget_Race_Update")
// Update Race Name (textbox).
#IF IS_DEBUG_BUILD
IF TRI_Widget_Textbox_Check(Race.Name)
//DEBUG_MESSAGE("TRI_Widget_Race_Update: Name")
// Qualify Race Name (textbox).
TRI_Widget_Race_Name_Qualify(Race)
ENDIF
// Otherwise, update Race FileName (textbox).
IF TRI_Widget_Textbox_Check(Race.FileName)
//DEBUG_MESSAGE("TRI_Widget_Race_Update: FileName")
// Qualify Race FileName (textbox).
TRI_Widget_Race_FileName_Qualify(Race)
ENDIF
// Otherwise, update Create Race (button).
IF TRI_Widget_Button_Check(Race.Create)
//DEBUG_MESSAGE("TRI_Widget_Race_Update: Create")
// Reset Create Race (button).
TRI_Widget_Button_Reset(Race.Create)
// Qualify Race FileName (textbox).
IF NOT TRI_Widget_Race_FileName_Qualify(Race)
RETURN TRUE
ENDIF
// Add race filename/name to master list (check for errors).
TEXT_LABEL_31 szRaceFileName = TRI_Widget_Textbox_Get(Race.FileName)
// TEXT_LABEL_31 szRaceName = TRI_Widget_Textbox_Get(Race.Name)
INT iRaceIndex = ENUM_TO_INT(eCurrentTriRace) //TRI_Master_Add_Race(szRaceFileName, szRaceName)
IF (iRaceIndex = -2)
DEBUG_MESSAGE("TRI_Widget_Race_Update: Race FileName duplicate!")
TRI_Widget_Textbox_Set(Race.Error, "FileName Duplicate! Try Again!")
RETURN TRUE
ELIF (iRaceIndex = -1)
DEBUG_MESSAGE("TRI_Widget_Race_Update: Race limit reached!")
TRI_Widget_Textbox_Set(Race.Error, "Race Limit Reached! Up Limit!")
RETURN TRUE
ENDIF
// Create race (makes new XML/SCH files).
IF NOT TRI_Race_Create(Race.Race, szRaceFileName)
DEBUG_MESSAGE("TRI_Widget_Race_Update: Race create failed!")
TRI_Widget_Textbox_Set(Race.Error, "Race Create Failed! Try Again!")
RETURN TRUE
ENDIF
// Save master XML file and reset TRI_ Widget Race.
TRI_Master_Save()
RETURN FALSE
// Otherwise, update Pick Race (listbox).
ELIF TRI_Widget_Listbox_Check(Race.Pick)
//DEBUG_MESSAGE("TRI_Widget_Race_Update: Pick")
// Reset Pick Race (listbox).
TRI_Widget_Listbox_Reset(Race.Pick)
// Set Load Race (button) to auto-load.
TRI_Widget_Button_Set(Race.Load, TRUE)
// Otherwise, update Load Race (button).
ELIF TRI_Widget_Button_Check(Race.Load)
//DEBUG_MESSAGE("TRI_Widget_Race_Update: Load")
// Reset Load Race (button).
TRI_Widget_Button_Reset(Race.Load)
// Load selected race from XML file.
INT iRaceSel = TRI_Widget_Listbox_Get(Race.Pick)
IF NOT TRI_Race_Load(Race.Race, TRI_Master.szRaceFileName[iRaceSel])
DEBUG_MESSAGE("TRI_Widget_Race_Update: Race load failed!")
TRI_Widget_Textbox_Set(Race.Error, "Race Load Failed! Try Again!")
RETURN TRUE
ENDIF
// Set Race Time/Name/FileName using newly loaded race info.
// TODO: Not sure how to do a time widget. Hold off for now...
//TRI_Widget_Float_Set(Race.Time, TRI_Master.fRaceTime[iRaceSel])
TRI_Widget_Textbox_Set(Race.Name, TRI_Master.szRaceName[iRaceSel])
TRI_Widget_Textbox_Set(Race.FileName, TRI_Master.szRaceFileName[iRaceSel])
// Reset Selected Gate and update related widget fields.
iSelectedGateToDirty = -1 //will force gate selection to 0
//TRI_Widget_Int_Set(Race.Gates.Selection, 0)
TRI_Widget_Gates_Sel_Update_All(Race.Gates, Race.Race)
// If Show All Gates is on, do just that.
// TODO: Think about making into a function.
IF TRI_Widget_Toggle_Get(Race.Gates.ShowAll)
//TRI_Race_Gate_Activate_All(Race.Race, TRUE)
// Otherwise, activate only Selected Gate.
ELSE
TRI_Race_Gate_Deactivate_All(Race.Race)
//TRI_Widget_Gates_Sel_Act(Race.Gates, Race.Race)
ENDIF
// Reset Selected Racer and update related widget fields.
TRI_Widget_Int_Set(Race.Racers.Selection, 0)
TRI_Widget_Racers_Sel_Update_All(Race.Racers, Race.Race)
// If Show All Racers is on, do just that.
// TODO: Think about making into a function.
IF TRI_Widget_Toggle_Get(Race.Racers.ShowAll)
TRI_Widget_Racers_All_Act(Race.Racers, Race.Race, FALSE)
// Otherwise, activate only Selected Racer.
ELSE
TRI_Widget_Racers_All_DeAct(Race.Racers, Race.Race, TRUE)
TRI_Widget_Racers_Sel_Act(Race.Racers, Race.Race, FALSE)
ENDIF
// Have camera interp to Selected Gate/Racer, if needed.
VECTOR vFocusPos = <<0.0, 0.0, 0.0>>
IF (Camera.eFocus = TRI_CAMERA_FOCUS_GATES)
vFocusPos = Race.Race.sGate[0].vPos
ELIF (Camera.eFocus = TRI_CAMERA_FOCUS_RACERS)
vFocusPos = Race.Race.Racer[0].vStartPos
ENDIF
TRI_Camera_Interp(Camera, vFocusPos, FALSE)
// Otherwise, update Save Race (button).
ELIF TRI_Widget_Button_Check(Race.Save)
//DEBUG_MESSAGE("TRI_Widget_Race_Update: Save")
// Reset Save Race (button).
TRI_Widget_Button_Reset(Race.Save)
// Save selected race to XML file.
INT iRaceSel = TRI_Widget_Listbox_Get(Race.Pick)
TRI_Race_Save(Race.Race, TRI_Master.szRaceFileName[iRaceSel])
// Otherwise, update Export Race (button).
ELIF TRI_Widget_Button_Check(Race.Export)
//DEBUG_MESSAGE("TRI_Widget_Race_Update: Export")
// Reset Export Race (button).
TRI_Widget_Button_Reset(Race.Export)
// Export selected race to SCH file.
INT iRaceSel = TRI_Widget_Listbox_Get(Race.Pick)
TRI_Race_Export(Race.Race, TRI_Master.szRaceFileName[iRaceSel])
ENDIF
#ENDIF
// Update joystick selection controls.
// D-Pad Down - Set Selected Gate/Racer (begin).
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_DOWN)
IF (Camera.eFocus = TRI_CAMERA_FOCUS_GATES)
TRI_Widget_Gates_Sel_Beg(Race.Gates)
ELIF (Camera.eFocus = TRI_CAMERA_FOCUS_RACERS)
TRI_Widget_Racers_Sel_Beg(Race.Racers)
ENDIF
// D-Pad Up - Set Selected Gate/Racer (end).
ELIF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_UP)
IF (Camera.eFocus = TRI_CAMERA_FOCUS_GATES)
TRI_Widget_Gates_Sel_End(Race.Gates, Race.Race)
ELIF (Camera.eFocus = TRI_CAMERA_FOCUS_RACERS)
TRI_Widget_Racers_Sel_End(Race.Racers, Race.Race)
ENDIF
// D-Pad Left - Decrement Selected Gate/Racer (wrapping).
ELIF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_LEFT)
IF (Camera.eFocus = TRI_CAMERA_FOCUS_GATES)
TRI_Widget_Gates_Sel_Dec(Race.Gates, Race.Race)
ELIF (Camera.eFocus = TRI_CAMERA_FOCUS_RACERS)
TRI_Widget_Racers_Sel_Dec(Race.Racers, Race.Race)
ENDIF
// D-Pad Right - Increment Selected Gate/Racer (wrapping).
ELIF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_RIGHT)
IF (Camera.eFocus = TRI_CAMERA_FOCUS_GATES)
TRI_Widget_Gates_Sel_Inc(Race.Gates, Race.Race)
ELIF (Camera.eFocus = TRI_CAMERA_FOCUS_RACERS)
TRI_Widget_Racers_Sel_Inc(Race.Racers, Race.Race)
ENDIF
// LT + RT - Create new gate after Selected Gate/Racer.
ELIF (IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_LB)
AND IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_RB))
OR (IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_RB)
AND IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_LB))
IF (Camera.eFocus = TRI_CAMERA_FOCUS_GATES)
TRI_Widget_Button_Set(Race.Gates.Create, TRUE)
ELIF (Camera.eFocus = TRI_CAMERA_FOCUS_RACERS)
TRI_Widget_Button_Set(Race.Racers.Create, TRUE)
ENDIF
ENDIF
// Update Gates widget group.
INT iRacerSel = TRI_Widget_Int_Get(Race.Racers.Selection)
TRI_Widget_Gates_Update(Race.Gates, Race.Race, Camera, iRacerSel)
// Update Racers widget group.
INT iGateSel = TRI_Widget_Int_Get(Race.Gates.Selection)
TRI_Widget_Racers_Update(Race.Racers, Race.Race, Camera, iGateSel)
// Update TRI_ Widget Race still running.
RETURN TRUE
ENDFUNC
PROC TRI_Widget_Race_Cleanup(TRI_WIDGET_RACE& Race)
//DEBUG_MESSAGE("TRI_Widget_Race_Cleanup")
TRI_Race_Gate_Deactivate_All(Race.Race)
TRI_Widget_Racers_Cleanup(Race.Racers)
TRI_Widget_Gates_Cleanup(Race.Gates)
TRI_Widget_Delete_Widget_Group(Race.GroupID)
ENDPROC
// -----------------------------------
// RACEMODE PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_RaceMode_Setup(TRI_WIDGET_RACEMODE& RaceMode)
//DEBUG_MESSAGE("TRI_Widget_RaceMode_Setup")
// Create Race Mode widget group.
RaceMode.GroupID = START_WIDGET_GROUP("Race Mode")
// TODO: Setup Race Mode widgets here...
// Close Race Mode widget group.
STOP_WIDGET_GROUP()
ENDPROC
FUNC BOOL TRI_Widget_RaceMode_Update(TRI_WIDGET_RACEMODE& RaceMode)
//DEBUG_MESSAGE("TRI_Widget_RaceMode_Update")
UNUSED_PARAMETER(RaceMode)
// Update TRI_ Widget Race Mode still running.
RETURN TRUE
ENDFUNC
PROC TRI_Widget_RaceMode_Cleanup(TRI_WIDGET_RACEMODE& RaceMode)
//DEBUG_MESSAGE("TRI_Widget_RaceMode_Cleanup")
TRI_Widget_Delete_Widget_Group(RaceMode.GroupID)
ENDPROC
// -----------------------------------
// EDITMODE PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_EditMode_Setup(TRI_WIDGET_EDITMODE& EditMode)
//DEBUG_MESSAGE("TRI_Widget_EditMode_Setup")
// Create Edit Mode widget group.
EditMode.GroupID = START_WIDGET_GROUP("Edit Mode")
// Setup Camera Mode (listbox).
TEXT_LABEL_31 szCamMode[3]
szCamMode[0] = "Gameplay Mode"
szCamMode[1] = "Free Mode"
szCamMode[2] = "Fly-Through Mode"
TRI_Widget_Listbox_Setup(EditMode.CamMode, "Camera Mode", szCamMode)
// Setup Camera Focus (listbox).
TEXT_LABEL_31 szCamFocus[2]
szCamFocus[0] = "Gates Focus"
szCamFocus[1] = "Racers Focus"
TRI_Widget_Listbox_Setup(EditMode.CamFocus, "Camera Focus", szCamFocus)
// Close Edit Mode widget group.
STOP_WIDGET_GROUP()
// Setup Race widget group.
TRI_Widget_Race_Setup(EditMode.Race)
// Setup Edit Mode camera.
TRI_Camera_Setup(EditMode.Camera)
ENDPROC
FUNC BOOL TRI_Widget_EditMode_Update(TRI_WIDGET_EDITMODE& EditMode)
//DEBUG_MESSAGE("TRI_Widget_EditMode_Update")
// Get camera focus position for Selected Gate/Racer.
VECTOR vFocusPos = <<0.0, 0.0, 0.0>>
INT iCamFocus = TRI_Widget_Listbox_Get(EditMode.CamFocus)
TRI_CAMERA_FOCUS_ENUM eCamFocus = INT_TO_ENUM(TRI_CAMERA_FOCUS_ENUM, iCamFocus)
IF (eCamFocus = TRI_CAMERA_FOCUS_GATES)
INT iGateSel = TRI_Widget_Gates_Sel_Get(EditMode.Race.Gates)
vFocusPos = EditMode.Race.Race.sGate[iGateSel].vPos
ELIF (eCamFocus = TRI_CAMERA_FOCUS_RACERS)
INT iRacerSel = TRI_Widget_Racers_Sel_Get(EditMode.Race.Racers)
vFocusPos = EditMode.Race.Race.Racer[iRacerSel].vStartPos
ENDIF
// Update Camera Mode (listbox).
IF TRI_Widget_Listbox_Check(EditMode.CamMode)
//DEBUG_MESSAGE("TRI_Widget_EditMode_Update: CamMode")
// Reset Camera Mode (listbox).
TRI_Widget_Listbox_Reset(EditMode.CamMode)
// Set camera to new mode for Selected Gate/Racer.
INT iCamMode = TRI_Widget_Listbox_Get(EditMode.CamMode)
TRI_CAMERA_MODE_ENUM eCamMode = INT_TO_ENUM(TRI_CAMERA_MODE_ENUM, iCamMode)
TRI_Camera_Mode_Set(EditMode.Camera, eCamMode, vFocusPos)
// Otherwise, update Camera Focus (listbox).
ELIF TRI_Widget_Listbox_Check(EditMode.CamFocus)
//DEBUG_MESSAGE("TRI_Widget_EditMode_Update: CamFocus")
// Reset Camera Focus (listbox).
TRI_Widget_Listbox_Reset(EditMode.CamFocus)
// Set camera to new focus for Selected Gate/Racer.
iCamFocus = TRI_Widget_Listbox_Get(EditMode.CamFocus)
eCamFocus = INT_TO_ENUM(TRI_CAMERA_FOCUS_ENUM, iCamFocus)
IF (eCamFocus = TRI_CAMERA_FOCUS_GATES)
INT iGateSel = TRI_Widget_Gates_Sel_Get(EditMode.Race.Gates)
vFocusPos = EditMode.Race.Race.sGate[iGateSel].vPos
ELIF (eCamFocus = TRI_CAMERA_FOCUS_RACERS)
INT iRacerSel = TRI_Widget_Racers_Sel_Get(EditMode.Race.Racers)
vFocusPos = EditMode.Race.Race.Racer[iRacerSel].vStartPos
ENDIF
TRI_Camera_Focus_Set(EditMode.Camera, eCamFocus, vFocusPos)
ENDIF
// Update Race widget group, reset TRI_ Widget Edit Mode, if needed.
IF NOT TRI_Widget_Race_Update(EditMode.Race, EditMode.Camera)
RETURN FALSE
ENDIF
// Have camera update around Selected Gate.
TRI_Camera_Update(EditMode.Camera, EditMode.Input, vFocusPos)
// Update TRI_ Widget Edit Mode still running.
RETURN TRUE
ENDFUNC
PROC TRI_Widget_EditMode_Cleanup(TRI_WIDGET_EDITMODE& EditMode)
//DEBUG_MESSAGE("TRI_Widget_EditMode_Cleanup")
TRI_Camera_Cleanup(EditMode.Camera)
TRI_Widget_Race_Cleanup(EditMode.Race)
TRI_Widget_Delete_Widget_Group(EditMode.GroupID)
ENDPROC
// -----------------------------------
// MAIN PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Widget_Main_Setup(TRI_WIDGET_MAIN& Main)
//DEBUG_MESSAGE("TRI_Widget_Main_Setup")
// Create Main widget group.
Main.GroupID = START_WIDGET_GROUP("Single Player Races")
// Setup TRI_ Mode (listbox).
TEXT_LABEL_31 szTRIMode[2]
szTRIMode[0] = "Race Mode"
szTRIMode[1] = "Edit Mode"
TRI_Widget_Listbox_Setup(Main.TRIMode, "TRI_ Mode", szTRIMode)
// Close Main widget group.
STOP_WIDGET_GROUP()
ENDPROC
//PROC SETUP_TRI_INTESITY_WIDGETS()
// START_WIDGET_GROUP("Triathlon Intensity & Drain")
// ADD_WIDGET_FLOAT_SLIDER("BIKE_INTENSITY_INCREASE_RATE", BIKE_INTENSITY_INCREASE_RATE, 0, 1000, 0.1)
// ADD_WIDGET_FLOAT_SLIDER("BIKE_INTENSITY_DECREASE_RATE", BIKE_INTENSITY_DECREASE_RATE, 0, 1000, 0.1)
// ADD_WIDGET_FLOAT_SLIDER("BIKE_WAIT_BEFORE_COOLDOWN", BIKE_WAIT_BEFORE_COOLDOWN, 0, 5, 0.01)
// ADD_WIDGET_FLOAT_SLIDER("SWIM_INTENSITY_INCREASE_EMPTY", SWIM_INTENSITY_INCREASE_EMPTY, 0, 1000, 0.1)
// ADD_WIDGET_FLOAT_SLIDER("SWIM_INTENSITY_INCREASE_GREEN", SWIM_INTENSITY_INCREASE_GREEN, 0, 1000, 0.1)
// ADD_WIDGET_FLOAT_SLIDER("SWIM_INTENSITY_INCREASE_YRF", SWIM_INTENSITY_INCREASE_YRF, 0, 1000, 0.1)
// ADD_WIDGET_FLOAT_SLIDER("SWIM_INTENSITY_DECREASE_GREEN", SWIM_INTENSITY_DECREASE_GREEN, 0, 1000, 0.1)
// ADD_WIDGET_FLOAT_SLIDER("SWIM_INTENSITY_DECREASE_YRF", SWIM_INTENSITY_DECREASE_YRF, 0, 1000, 0.1)
// STOP_WIDGET_GROUP()
//ENDPROC
PROC SETUP_TRI_ENERGY_WIDGETS()
// START_WIDGET_GROUP("Triathlon Energy & Drain")
// ADD_WIDGET_FLOAT_SLIDER("GREEN_ENERGY_DRAIN", GREEN_ENERGY_DRAIN, 0, 1000, 0.01)
// ADD_WIDGET_FLOAT_SLIDER("YELLOW_ENERGY_DRAIN", YELLOW_ENERGY_DRAIN, 0, 1000, 0.01)
// ADD_WIDGET_FLOAT_SLIDER("RED_ENERGY_DRAIN", RED_ENERGY_DRAIN, 0, 1000, 0.01)
// ADD_WIDGET_FLOAT_SLIDER("MAX_ENERGY_DRAIN", MAX_ENERGY_DRAIN, 0, 1000, 0.01)
// ADD_WIDGET_FLOAT_SLIDER("GREEN_TO_YELLOW_SHIFT", GREEN_TO_YELLOW_SHIFT, 0, 1, 0.01)
// ADD_WIDGET_FLOAT_SLIDER("YELLOW_TO_RED_SHIFT", YELLOW_TO_RED_SHIFT, 0, 1, 0.01)
// ADD_WIDGET_FLOAT_SLIDER("ENERGY_EMPTY_REPLENISH_WAIT", ENERGY_EMPTY_REPLENISH_WAIT, 0, 10, 0.1)
// ADD_WIDGET_FLOAT_SLIDER("ENERGY_EMPTY_REPLENISH_BOOST", ENERGY_EMPTY_REPLENISH_BOOST, 0, 1, 0.01)
// ADD_WIDGET_FLOAT_SLIDER("ENERGY_EMPTY_REPLENISH_RATE", ENERGY_EMPTY_REPLENISH_RATE, 0, 1, 0.01)
// STOP_WIDGET_GROUP()
ENDPROC
PROC SETUP_TRI_SCAN_LINES_WIDGETS()
// START_WIDGET_GROUP("Triathlon News Heli Scan Lines")
// ADD_WIDGET_INT_SLIDER("TRI_NEWS_SCAN_LINES", TRI_NEWS_SCAN_LINES, 0, 200, 1)
// STOP_WIDGET_GROUP()
ENDPROC
PROC SETUP_TRI_CHEERING_WIDGETS()
START_WIDGET_GROUP("Triathlon Cheering")
/*
ADD_WIDGET_FLOAT_SLIDER("TRI_TIME_TO_CHEERING", TRI_TIME_TO_CHEERING, 0, 10, 0.1)
ADD_WIDGET_FLOAT_SLIDER("TRI_CHEERING_PROB", TRI_CHEERING_PROB, 0, 1.0, 0.01)
ADD_WIDGET_FLOAT_SLIDER("TRI_CHEERING_RANGE", TRI_CHEERING_RANGE, 0, 100, 1.0)
ADD_WIDGET_FLOAT_SLIDER("TRI_TIME_TO_INTRO_CHATTER", TRI_TIME_TO_INTRO_CHATTER, 0, 10, 0.1)
ADD_WIDGET_FLOAT_SLIDER("TRI_INTRO_CHATTER_PROB", TRI_INTRO_CHATTER_PROB, 0, 1.0, 0.01)
*/
STOP_WIDGET_GROUP()
ENDPROC
PROC SETUP_TRI_MENU_WIDGETS()
START_WIDGET_GROUP("Triathlon Menu Widgets")
/*
ADD_WIDGET_FLOAT_SLIDER("MENU_OFFSET_1", MENU_OFFSET_1, -3, 3, 0.01)
ADD_WIDGET_FLOAT_SLIDER("MENU_OFFSET_2", MENU_OFFSET_2, -3, 3, 0.01)
ADD_WIDGET_FLOAT_SLIDER("MENU_OFFSET_3", MENU_OFFSET_3, -3, 3, 0.01)
*/
STOP_WIDGET_GROUP()
ENDPROC
PROC SETUP_TRI_QUIT_MENU_WIDGETS()
START_WIDGET_GROUP( "Quit Delay" )
ADD_WIDGET_INT_SLIDER( "TRI_BLOCK_QUIT_INPUT_DURATION", TRI_BLOCK_QUIT_INPUT_DURATION, 0, 5000, 100 )
STOP_WIDGET_GROUP()
ENDPROC
// Only used when using the data driven method to adjust blocking area positions
//#IF IS_DEBUG_BUILD
//PROC SETUP_TRI_NAVMESH_WIDGETS()
// TEXT_LABEL_23 txtLabel
//
// INT idx2
// START_WIDGET_GROUP("Triathlon Blocking Areas")
// REPEAT COUNT_OF(TRI_Master.iNavBlockAreas) idx2
// txtLabel = "Nav block "
// txtLabel += idx2
// txtLabel += " pos"
// ADD_WIDGET_VECTOR_SLIDER(txtLabel, TRI_Master.vNavBlockPositions[idx2], -10000.0, 10000.0, 0.1)
// txtLabel = "Nav block "
// txtLabel += idx2
// txtLabel += " head"
// ADD_WIDGET_FLOAT_SLIDER(txtLabel, TRI_Master.fNavBlockHeadings[idx2], -360.0, 360.0, 0.0349)
// ADD_WIDGET_STRING("")
// ENDREPEAT
// STOP_WIDGET_GROUP()
//ENDPROC
//#ENDIF
#IF IS_DEBUG_BUILD
PROC SETUP_TRI_BANNER_WIDGETS()
START_WIDGET_GROUP("Triathlon Banners")
ADD_WIDGET_BOOL("Turn on to cheat and set banners", IS_CHEATING_ENABLED)
ADD_WIDGET_FLOAT_SLIDER("TEST_HEADING", TEST_HEADING, 0, 360, 1)
ADD_WIDGET_VECTOR_SLIDER("TEST_VECTOR_1", TEST_VECTOR_1, -10000, 10000, 0.01)
ADD_WIDGET_VECTOR_SLIDER("TEST_VECTOR_2", TEST_VECTOR_2, -10000, 10000, 0.01)
STOP_WIDGET_GROUP()
ENDPROC
PROC SETUP_TRI_AI_FINISH_HEADING_WIDGETS()
START_WIDGET_GROUP("Tri AI Finish Heading Widgets")
ADD_WIDGET_FLOAT_SLIDER("TRI_AI_FINISH_HEADING_ADJUST", TRI_AI_FINISH_HEADING_ADJUST, 0, 180, 1.0)
STOP_WIDGET_GROUP()
ENDPROC
#ENDIF
PROC SETUP_KITS_BAG_WIDGETS()
// START_WIDGET_GROUP("Triathlon Kits Bag")
// ADD_WIDGET_FLOAT_SLIDER("KITS_BAG_HEIGHT", KITS_BAG_HEIGHT, -1, 1, 0.01)
// STOP_WIDGET_GROUP()
ENDPROC
PROC TRI_Widget_Main_Setup_TRI(TRI_WIDGET_MAIN& Main)
//DEBUG_MESSAGE("TRI_Widget_Main_Setup")
// Create Main widget group.
Main.GroupID = START_WIDGET_GROUP("Single Player Races")
// Setup TRI_ Mode (listbox).
TEXT_LABEL_31 szTRIMode[2]
szTRIMode[0] = "Race Mode"
szTRIMode[1] = "Edit Mode"
TRI_Widget_Listbox_Setup(Main.TRIMode, "TRI_ Mode", szTRIMode)
// SETUP_TRI_INTESITY_WIDGETS()
SETUP_TRI_ENERGY_WIDGETS()
SETUP_TRI_BANNER_WIDGETS()
SETUP_TRI_AI_FINISH_HEADING_WIDGETS()
//SETUP_TRI_NAVMESH_WIDGETS()
SETUP_TRI_SCAN_LINES_WIDGETS()
SETUP_KITS_BAG_WIDGETS()
SETUP_TRI_CHEERING_WIDGETS()
SETUP_TRI_MENU_WIDGETS()
SETUP_TRI_QUIT_MENU_WIDGETS()
// Close Main widget group.
STOP_WIDGET_GROUP()
ENDPROC
FUNC BOOL TRI_Widget_Main_Update(TRI_WIDGET_MAIN& Main)
//DEBUG_MESSAGE("TRI_Widget_Main_Update")
// Update TRI_ Mode (listbox).
IF TRI_Widget_Listbox_Check(Main.TRIMode)
//DEBUG_MESSAGE("TRI_Widget_Main_Update: TRIMode")
// Reset TRI_ Mode (listbox).
TRI_Widget_Listbox_Reset(Main.TRIMode)
// If TRI_ Mode is Race, setup Race Mode.
SET_CURRENT_WIDGET_GROUP(Main.GroupID)
IF (TRI_Widget_Listbox_Get(Main.TRIMode) = 0)
TRI_Widget_EditMode_Cleanup(Main.EditMode)
TRI_Widget_RaceMode_Setup(Main.RaceMode)
// Otherwise, TRI_ Mode is Edit, setup Edit Mode.
ELSE
TRI_Widget_RaceMode_Cleanup(Main.RaceMode)
TRI_Widget_EditMode_Setup(Main.EditMode)
ENDIF
CLEAR_CURRENT_WIDGET_GROUP(Main.GroupID)
// Update TRI_ Widget Main finished.
RETURN FALSE
ENDIF
// If TRI_ Mode is Race, update Race Mode.
IF (TRI_Widget_Listbox_Get(Main.TRIMode) = 0)
TRI_Widget_RaceMode_Update(Main.RaceMode)
// Otherwise, TRI_ Mode is Edit, update Edit Mode.
ELIF NOT TRI_Widget_EditMode_Update(Main.EditMode)
SET_CURRENT_WIDGET_GROUP(Main.GroupID)
TRI_Widget_EditMode_Cleanup(Main.EditMode)
TRI_Widget_EditMode_Setup(Main.EditMode)
CLEAR_CURRENT_WIDGET_GROUP(Main.GroupID)
ENDIF
// Update TRI_ Widget Main still running.
RETURN TRUE
ENDFUNC
PROC TRI_Widget_Main_Cleanup(TRI_WIDGET_MAIN& Main)
//DEBUG_MESSAGE("TRI_Widget_Main_Cleanup")
SET_CURRENT_WIDGET_GROUP(Main.GroupID)
IF (TRI_Widget_Listbox_Get(Main.TRIMode) != 0)
TRI_Widget_EditMode_Cleanup(Main.EditMode)
ELSE
TRI_Widget_RaceMode_Cleanup(Main.RaceMode)
ENDIF
CLEAR_CURRENT_WIDGET_GROUP(Main.GroupID)
TRI_Widget_Delete_Widget_Group(Main.GroupID)
ENDPROC
#ENDIF // IS_DEBUG_BUILD
// END OF FILE! DO NOT ADD ANYTHING BELOW THIS LINE!