1352 lines
39 KiB
Python
Executable File
1352 lines
39 KiB
Python
Executable File
// NODE VIEWER - test script for placing and editing node paths
|
|
// Rob Bray 06/11/09
|
|
|
|
USING "rage_builtins.sch"
|
|
USING "globals.sch"
|
|
|
|
#IF IS_FINAL_BUILD
|
|
|
|
script
|
|
|
|
endscript
|
|
|
|
#endif
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
USING "brains.sch"
|
|
USING "script_player.sch"
|
|
USING "commands_script.sch"
|
|
USING "commands_pad.sch"
|
|
USING "commands_graphics.sch"
|
|
USING "commands_camera.sch"
|
|
USING "commands_streaming.sch"
|
|
USING "commands_interiors.sch"
|
|
USING "commands_object.sch"
|
|
USING "commands_audio.sch"
|
|
USING "script_drawing.sch"
|
|
|
|
|
|
// CONSTANTS
|
|
CONST_INT NUMBER_OF_NODES_PER_SET 12
|
|
CONST_INT NUMBER_OF_SETS 2
|
|
CONST_INT NUMBER_OF_SUB_MENU_ITEMS 4
|
|
|
|
CONST_INT SPHERE_ALPHA 170
|
|
CONST_INT BOX_ALPHA 115
|
|
CONST_FLOAT POINT_NODE_SIZE 1.65
|
|
CONST_FLOAT BOX_NODE_SIZE 1.4
|
|
CONST_FLOAT POINT_NODE_TEXT_OFFSET 1.95
|
|
CONST_FLOAT BOX_NODE_TEXT_OFFSET 1.65
|
|
|
|
|
|
// ENUMS
|
|
ENUM VIEWER_STATE_ENUM
|
|
STATE_MENU = 0,
|
|
STATE_FLYCAM
|
|
ENDENUM
|
|
VIEWER_STATE_ENUM current_viewer_state = STATE_MENU
|
|
|
|
ENUM SUB_MENU_ENUM
|
|
SUB_MENU_HIDDEN = 0,
|
|
SUB_MENU_EDIT,
|
|
SUB_MENU_COPY,
|
|
SUB_MENU_DELETE
|
|
ENDENUM
|
|
SUB_MENU_ENUM current_sub_menu_selection = SUB_MENU_HIDDEN
|
|
|
|
ENUM NODE_TYPE_ENUM
|
|
TYPE_FREE_NODE = 0,
|
|
TYPE_POINT_NODE,
|
|
TYPE_BOX_FIRST_NODE,
|
|
TYPE_BOX_SECOND_NODE
|
|
ENDENUM
|
|
|
|
ENUM AUDIO_CONFIRM_ENUM
|
|
AUDIO_CONFIRM_CHANGE = 0,
|
|
AUDIO_CONFIRM_EDIT
|
|
ENDENUM
|
|
|
|
// STRUCTURES
|
|
STRUCT NODE_STRUCT
|
|
NODE_TYPE_ENUM type
|
|
VECTOR v_coords
|
|
TEXT_LABEL_31 tl_label
|
|
INT i_creation_number
|
|
INT i_box_counterpart_index
|
|
ENDSTRUCT
|
|
|
|
STRUCT NODE_SET_STRUCT
|
|
NODE_STRUCT nodes[NUMBER_OF_NODES_PER_SET]
|
|
TEXT_LABEL_31 tl_name
|
|
BOOL b_open
|
|
//INT i_creation_number
|
|
INT i_node_creation_counter
|
|
ENDSTRUCT
|
|
|
|
|
|
// GLOBALS
|
|
NODE_SET_STRUCT node_sets[NUMBER_OF_SETS]
|
|
|
|
CAMERA_INDEX debug_cam
|
|
CAMERA_INDEX point_cam
|
|
CAMERA_INDEX menu_cam
|
|
|
|
INT i_current_set_index = -1
|
|
INT i_current_node_index = -1
|
|
INT i_set_creation_counter
|
|
|
|
INT i_white = INT_COLOUR(255, 255, 255, 255)
|
|
INT i_red = INT_COLOUR(255, 0, 0, 255)
|
|
|
|
BOOL b_do_update_widget
|
|
BOOL b_update_label
|
|
BOOL b_update_name
|
|
BOOL b_show_quit_confirm
|
|
BOOL b_set_menu_cam
|
|
BOOL b_equidistant_drop
|
|
BOOL b_draw_help = TRUE
|
|
BOOL b_quit_tool
|
|
|
|
VECTOR v_cam_coords
|
|
//VECTOR v_cam_rot
|
|
FLOAT f_distance_travelled
|
|
FLOAT f_distance_to_travel_for_next_drop = 50.0
|
|
|
|
VECTOR v_last_cam_coords
|
|
|
|
WIDGET_GROUP_ID w_nodes_group
|
|
TEXT_WIDGET_ID w_node_label
|
|
TEXT_WIDGET_ID w_set_name
|
|
|
|
|
|
// FUNCTIONS
|
|
// play audio confirmation of action
|
|
PROC DO_SOUND(AUDIO_CONFIRM_ENUM confirm_type)
|
|
IF confirm_type = AUDIO_CONFIRM_EDIT
|
|
PLAY_SOUND_FRONTEND(-1, "AK47_COCK_PULL")
|
|
ELIF confirm_type = AUDIO_CONFIRM_CHANGE
|
|
PLAY_SOUND_FRONTEND(-1, "GENERAL_WEAPONS_MP5_SLAM")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// create a new set
|
|
PROC CREATE_NEW_SET(INT i_index)
|
|
INT i
|
|
|
|
// fill set attributes
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
node_sets[i_index].nodes[i].type = TYPE_FREE_NODE
|
|
node_sets[i_index].nodes[i].v_coords = <<0,0,0>>
|
|
node_sets[i_index].nodes[i].tl_label = ""
|
|
//node_sets[i_index].nodes[i].i_creation_number = -1
|
|
node_sets[i_index].nodes[i].i_box_counterpart_index = -1
|
|
ENDREPEAT
|
|
|
|
node_sets[i_index].b_open = TRUE
|
|
node_sets[i_index].tl_name = "Set "
|
|
node_sets[i_index].tl_name += i_set_creation_counter
|
|
//node_sets[i_index].i_creation_number = i_set_creation_counter
|
|
node_sets[i_index].i_node_creation_counter = 0
|
|
|
|
i_set_creation_counter++
|
|
ENDPROC
|
|
|
|
// copy data from one set to another
|
|
FUNC BOOL COPY_SET_DATA_INTO_SLOT(INT i_from_index, INT i_to_index)
|
|
INT i
|
|
|
|
IF i_from_index >= 0
|
|
AND i_to_index >= 0
|
|
IF node_sets[i_from_index].b_open
|
|
IF NOT node_sets[i_to_index].b_open
|
|
// fill set attributes
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
node_sets[i_to_index].nodes[i].type = node_sets[i_from_index].nodes[i].type
|
|
node_sets[i_to_index].nodes[i].v_coords = node_sets[i_from_index].nodes[i].v_coords
|
|
node_sets[i_to_index].nodes[i].tl_label = node_sets[i_from_index].nodes[i].tl_label
|
|
node_sets[i_to_index].nodes[i].i_creation_number = node_sets[i_from_index].nodes[i].i_creation_number
|
|
node_sets[i_to_index].nodes[i].i_box_counterpart_index = node_sets[i_from_index].nodes[i].i_box_counterpart_index
|
|
ENDREPEAT
|
|
|
|
node_sets[i_to_index].b_open = TRUE
|
|
TEXT_LABEL_63 tl_name = "(Copy) "
|
|
tl_name += node_sets[i_from_index].tl_name
|
|
INT i_name_length = GET_LENGTH_OF_LITERAL_STRING(node_sets[i_to_index].tl_name)
|
|
IF i_name_length >= 15
|
|
tl_name = GET_FIRST_N_CHARACTERS_OF_STRING(tl_name, 15)
|
|
ENDIF
|
|
|
|
node_sets[i_to_index].tl_name = tl_name
|
|
//node_sets[i_to_index].i_creation_number = i_set_creation_counter
|
|
node_sets[i_to_index].i_node_creation_counter = node_sets[i_from_index].i_node_creation_counter
|
|
|
|
RETURN TRUE
|
|
ELSE
|
|
PRINTSTRING("Attempting to copy to an open set") PRINTNL()
|
|
ENDIF
|
|
ELSE
|
|
PRINTSTRING("Attempting to copy from a closed set") PRINTNL()
|
|
ENDIF
|
|
ELSE
|
|
PRINTSTRING("One or both copy slots do not exist") PRINTNL()
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
// delete a set
|
|
PROC DELETE_SET(INT i_index)
|
|
IF i_index >= 0
|
|
IF node_sets[i_index].b_open
|
|
node_sets[i_index].b_open = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// fill the data of initial sets (temp for testing)
|
|
PROC FILL_INITIAL_SETS()
|
|
INT i
|
|
|
|
REPEAT NUMBER_OF_SETS i
|
|
CREATE_NEW_SET(i)
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
// get the first available index of a free set
|
|
FUNC INT GET_FREE_SET_INDEX()
|
|
INT i
|
|
REPEAT NUMBER_OF_SETS i
|
|
IF NOT node_sets[i].b_open // only return sets that are not open
|
|
RETURN i
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN -1
|
|
ENDFUNC
|
|
|
|
// get next open set iterating through array
|
|
FUNC INT GET_NEXT_OPEN_SET(INT i_index)
|
|
INT i
|
|
|
|
IF i_index >= 0
|
|
FOR i = i_index TO (NUMBER_OF_SETS - 1)
|
|
IF node_sets[i].b_open // only return open sets
|
|
AND i <> i_index // don't return this index
|
|
RETURN i
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
// loop round if not found any
|
|
FOR i = 0 TO i_index
|
|
IF node_sets[i].b_open // only return open sets
|
|
AND i <> i_index // don't return this index
|
|
RETURN i
|
|
ENDIF
|
|
ENDFOR
|
|
ENDIF
|
|
|
|
RETURN -1
|
|
ENDFUNC
|
|
|
|
// get previous open set iterating through array
|
|
FUNC INT GET_PREVIOUS_OPEN_SET(INT i_index)
|
|
INT i
|
|
|
|
IF i_index >= 0
|
|
FOR i = i_index TO 0 STEP -1
|
|
IF node_sets[i].b_open // only return open sets
|
|
AND i <> i_index // don't return this index
|
|
RETURN i
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
// loop round if not found any
|
|
FOR i = (NUMBER_OF_SETS - 1) TO i_index STEP -1
|
|
IF node_sets[i].b_open // only return open sets
|
|
AND i <> i_index // don't return this index
|
|
RETURN i
|
|
ENDIF
|
|
ENDFOR
|
|
ENDIF
|
|
|
|
RETURN -1
|
|
ENDFUNC
|
|
|
|
// set the current set index
|
|
PROC SET_CURRENT_SET_INDEX(INT i_index)
|
|
i_current_set_index = i_index
|
|
b_do_update_widget = TRUE
|
|
ENDPROC
|
|
|
|
// set set name
|
|
PROC SET_SET_NAME(INT i_index, STRING s_name)
|
|
node_sets[i_index].tl_name = ""
|
|
node_sets[i_index].tl_name += s_name
|
|
ENDPROC
|
|
|
|
// set the current node index
|
|
PROC SET_CURRENT_NODE_INDEX(INT i_index)
|
|
i_current_node_index = i_index
|
|
b_do_update_widget = TRUE
|
|
ENDPROC
|
|
|
|
// get the node at a specific index
|
|
FUNC NODE_STRUCT GET_NODE_AT_INDEX(INT i_index)
|
|
//PRINTSTRING("GET_NODE_AT_INDEX - Index = ")
|
|
//PRINTINT(i_index)
|
|
//PRINTSTRING(" i_current_set_index = ")
|
|
//PRINTINT(i_current_set_index)
|
|
//PRINTNL()
|
|
RETURN node_sets[i_current_set_index].nodes[i_index]
|
|
ENDFUNC
|
|
|
|
// get the index of the closest node to the specified index
|
|
FUNC INT GET_CLOSEST_NODE_INDEX_TO_NODE(INT i_index)
|
|
INT i
|
|
NODE_STRUCT this_node = GET_NODE_AT_INDEX(i_index)
|
|
|
|
INT i_closest_index = -1
|
|
FLOAT f_closest_distance = -1
|
|
FLOAT f_distance
|
|
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
NODE_STRUCT check_node = GET_NODE_AT_INDEX(i)
|
|
IF check_node.type <> TYPE_FREE_NODE // only check active nodes
|
|
AND i <> i_index // don't check specified index
|
|
f_distance = GET_DISTANCE_BETWEEN_COORDS(this_node.v_coords, check_node.v_coords)
|
|
IF f_distance <= f_closest_distance
|
|
OR f_closest_distance = -1
|
|
// if closer than previous closest, set to return this index
|
|
i_closest_index = i
|
|
f_closest_distance = f_distance
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN i_closest_index
|
|
ENDFUNC
|
|
|
|
// get the node with the lowest creation number
|
|
FUNC INT GET_FIRST_NODE_INDEX()
|
|
INT i
|
|
INT i_closest_index = -1
|
|
INT i_closest_creation_number = -1
|
|
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
NODE_STRUCT check_node = GET_NODE_AT_INDEX(i)
|
|
IF check_node.type <> TYPE_FREE_NODE // only check active nodes
|
|
IF check_node.i_creation_number < i_closest_creation_number
|
|
OR i_closest_creation_number = -1
|
|
i_closest_index = i
|
|
i_closest_creation_number = check_node.i_creation_number
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN i_closest_index
|
|
ENDFUNC
|
|
|
|
// get next node in order of creation
|
|
FUNC INT GET_NEXT_NODE_INDEX_IN_ORDER(INT i_index, BOOL b_loop = FALSE)
|
|
INT i
|
|
NODE_STRUCT this_node = GET_NODE_AT_INDEX(i_index)
|
|
|
|
INT i_closest_index = -1
|
|
INT i_closest_creation_number = -1
|
|
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
NODE_STRUCT check_node = GET_NODE_AT_INDEX(i)
|
|
IF check_node.type <> TYPE_FREE_NODE // only check active nodes
|
|
AND i <> i_index // don't check specified index
|
|
IF check_node.i_creation_number > this_node.i_creation_number
|
|
AND (check_node.i_creation_number < i_closest_creation_number OR i_closest_creation_number = -1)
|
|
i_closest_index = i
|
|
i_closest_creation_number = check_node.i_creation_number
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
// if loop around, find lowest
|
|
IF b_loop
|
|
IF i_closest_index = -1
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
NODE_STRUCT check_node = GET_NODE_AT_INDEX(i)
|
|
IF check_node.type <> TYPE_FREE_NODE // only check active nodes
|
|
AND i <> i_index // don't check specified index
|
|
IF check_node.i_creation_number < this_node.i_creation_number
|
|
AND (check_node.i_creation_number < i_closest_creation_number OR i_closest_creation_number = -1)
|
|
i_closest_index = i
|
|
i_closest_creation_number = check_node.i_creation_number
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN i_closest_index
|
|
ENDFUNC
|
|
|
|
// get previous node in order of creation
|
|
FUNC INT GET_PREVIOUS_NODE_INDEX_IN_ORDER(INT i_index, BOOL b_loop = FALSE)
|
|
INT i
|
|
NODE_STRUCT this_node = GET_NODE_AT_INDEX(i_index)
|
|
|
|
INT i_closest_index = -1
|
|
INT i_closest_creation_number = -1
|
|
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
NODE_STRUCT check_node = GET_NODE_AT_INDEX(i)
|
|
IF check_node.type <> TYPE_FREE_NODE // only check active nodes
|
|
AND i <> i_index // don't check specified index
|
|
IF check_node.i_creation_number < this_node.i_creation_number
|
|
AND (check_node.i_creation_number > i_closest_creation_number OR i_closest_creation_number = -1)
|
|
i_closest_index = i
|
|
i_closest_creation_number = check_node.i_creation_number
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
// if loop around, find highest
|
|
IF b_loop
|
|
IF i_closest_index = -1
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
NODE_STRUCT check_node = GET_NODE_AT_INDEX(i)
|
|
IF check_node.type <> TYPE_FREE_NODE // only check active nodes
|
|
AND i <> i_index // don't check specified index
|
|
IF check_node.i_creation_number > this_node.i_creation_number
|
|
AND (check_node.i_creation_number > i_closest_creation_number OR i_closest_creation_number = -1)
|
|
i_closest_index = i
|
|
i_closest_creation_number = check_node.i_creation_number
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN i_closest_index
|
|
ENDFUNC
|
|
|
|
// get coords
|
|
FUNC VECTOR GET_NODE_COORDS_AT_INDEX(INT i_index)
|
|
RETURN node_sets[i_current_set_index].nodes[i_index].v_coords
|
|
ENDFUNC
|
|
|
|
// get label
|
|
FUNC TEXT_LABEL GET_NODE_LABEL_AT_INDEX(INT i_index)
|
|
RETURN node_sets[i_current_set_index].nodes[i_index].tl_label
|
|
ENDFUNC
|
|
|
|
// set node coords
|
|
PROC SET_NODE_COORDS_AT_INDEX(INT i_index, VECTOR v_coords)
|
|
node_sets[i_current_set_index].nodes[i_index].v_coords = v_coords
|
|
ENDPROC
|
|
|
|
// set node type
|
|
PROC SET_NODE_TYPE_AT_INDEX(INT i_index, NODE_TYPE_ENUM type)
|
|
node_sets[i_current_set_index].nodes[i_index].type = type
|
|
ENDPROC
|
|
|
|
// set node label
|
|
PROC SET_NODE_LABEL_AT_INDEX(INT i_index, STRING s_label)
|
|
node_sets[i_current_set_index].nodes[i_index].tl_label = ""
|
|
node_sets[i_current_set_index].nodes[i_index].tl_label += s_label
|
|
ENDPROC
|
|
|
|
// set node box counterpart
|
|
PROC SET_NODE_BOX_COUNTERPART_AT_INDEX(INT i_index, INT i_counterpart_index)
|
|
node_sets[i_current_set_index].nodes[i_index].i_box_counterpart_index = i_counterpart_index
|
|
ENDPROC
|
|
|
|
// delete node
|
|
PROC DELETE_NODE_AT_INDEX(INT i_index)
|
|
node_sets[i_current_set_index].nodes[i_index].type = TYPE_FREE_NODE
|
|
ENDPROC
|
|
|
|
// get the first available index of a free node in a set
|
|
FUNC INT GET_FREE_NODE_INDEX()
|
|
INT i
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
NODE_STRUCT check_node = GET_NODE_AT_INDEX(i)
|
|
IF check_node.type = TYPE_FREE_NODE
|
|
RETURN i
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN -1
|
|
ENDFUNC
|
|
|
|
// set camera to look down on the specified coords
|
|
PROC CAM_LOOK_DOWN_ON_COORDS(VECTOR v_coords)
|
|
SET_CAM_COORD(debug_cam, <<v_coords.x, v_coords.y, v_coords.z + 30>>)
|
|
SET_CAM_ROT(debug_cam, <<-89, 0, 0>>)
|
|
ENDPROC
|
|
|
|
// point cam at node if not on screen
|
|
PROC POINT_CAM_AT_NODE(INT i_index)
|
|
VECTOR v_node_coords = GET_NODE_COORDS_AT_INDEX(i_index)
|
|
IF NOT IS_SPHERE_VISIBLE(v_node_coords, POINT_NODE_SIZE)
|
|
IF GET_DISTANCE_BETWEEN_COORDS(v_node_coords, v_cam_coords) >= 120.0
|
|
// if further than 120m away, jump cam pos over there
|
|
CAM_LOOK_DOWN_ON_COORDS(v_node_coords)
|
|
ELSE
|
|
// otherwise just point at it
|
|
SET_CAM_COORD(point_cam, v_cam_coords)
|
|
POINT_CAM_AT_COORD(point_cam, v_node_coords)
|
|
WAIT(0)
|
|
SET_CAM_ROT(debug_cam, GET_CAM_ROT(point_cam))
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// create a node
|
|
PROC CREATE_NODE(NODE_STRUCT &node, NODE_SET_STRUCT &set)
|
|
// fill node attributes
|
|
node.type = TYPE_POINT_NODE
|
|
node.v_coords = v_cam_coords
|
|
node.tl_label = "Node "
|
|
node.tl_label += set.i_node_creation_counter
|
|
node.i_creation_number = set.i_node_creation_counter
|
|
node.i_box_counterpart_index = -1
|
|
|
|
// increment creation counter
|
|
set.i_node_creation_counter++
|
|
ENDPROC
|
|
|
|
// create a new node at the current debug cam coords
|
|
PROC PLACE_NEW_NODE(NODE_SET_STRUCT &set)
|
|
// find a free index
|
|
INT i_index = GET_FREE_NODE_INDEX()
|
|
|
|
IF i_index >= 0
|
|
// create the node
|
|
CREATE_NODE(node_sets[i_current_set_index].nodes[i_index], set)
|
|
|
|
// set this node as current
|
|
SET_CURRENT_NODE_INDEX(i_index)
|
|
|
|
DO_SOUND(AUDIO_CONFIRM_EDIT)
|
|
ELSE
|
|
SCRIPT_ASSERT("Maximum number of nodes for this set reached")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// move the currently selected node
|
|
PROC MOVE_CURRENT_NODE()
|
|
IF i_current_node_index >= 0
|
|
// set the node coords
|
|
SET_NODE_COORDS_AT_INDEX(i_current_node_index, v_cam_coords)
|
|
DO_SOUND(AUDIO_CONFIRM_EDIT)
|
|
ELSE
|
|
PRINTSTRING("Attempting to move a node which does not exist") PRINTNL()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// delete the currently selected node
|
|
PROC DELETE_CURRENT_NODE()
|
|
IF i_current_node_index >= 0
|
|
NODE_STRUCT current_node = GET_NODE_AT_INDEX(i_current_node_index)
|
|
IF current_node.type = TYPE_POINT_NODE
|
|
// if a point node, can just delete it
|
|
DELETE_NODE_AT_INDEX(i_current_node_index)
|
|
ELIF current_node.type = TYPE_BOX_FIRST_NODE
|
|
OR current_node.type = TYPE_BOX_SECOND_NODE
|
|
// if a box node, have to delete its counterpart too
|
|
IF current_node.i_box_counterpart_index >= 0
|
|
DELETE_NODE_AT_INDEX(current_node.i_box_counterpart_index)
|
|
ENDIF
|
|
DELETE_NODE_AT_INDEX(i_current_node_index)
|
|
ENDIF
|
|
|
|
// set currently selected node as the closest to the deleted one
|
|
INT i_closest_node = GET_CLOSEST_NODE_INDEX_TO_NODE(i_current_node_index)
|
|
SET_CURRENT_NODE_INDEX(i_closest_node)
|
|
IF i_current_node_index >= 0
|
|
POINT_CAM_AT_NODE(i_current_node_index)
|
|
ENDIF
|
|
|
|
DO_SOUND(AUDIO_CONFIRM_CHANGE)
|
|
ELSE
|
|
PRINTSTRING("Attempting to delete a node which does not exist") PRINTNL()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// place currently selected node on ground
|
|
PROC PLACE_CURRENT_NODE_ON_GROUND()
|
|
IF i_current_node_index >= 0
|
|
NODE_STRUCT current_node = GET_NODE_AT_INDEX(i_current_node_index)
|
|
VECTOR v_current_coords = current_node.v_coords
|
|
|
|
// get ground level
|
|
FLOAT f_ground_z
|
|
IF GET_GROUND_Z_FOR_3D_COORD(v_current_coords, f_ground_z)
|
|
// move the node
|
|
SET_NODE_COORDS_AT_INDEX(i_current_node_index, <<v_current_coords.x, v_current_coords.y, f_ground_z + (POINT_NODE_SIZE/2)>>)
|
|
|
|
DO_SOUND(AUDIO_CONFIRM_EDIT)
|
|
ENDIF
|
|
ELSE
|
|
PRINTSTRING("Attempting to move a node which does not exist") PRINTNL()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// change currently selected node and the one created before that into a box or vice versa
|
|
PROC CONVERT_CURRENT_AND_PRECEDING_NODES_TO_BOX()
|
|
IF i_current_node_index >= 0
|
|
NODE_STRUCT current_node = GET_NODE_AT_INDEX(i_current_node_index)
|
|
IF current_node.type = TYPE_POINT_NODE
|
|
// convert to box
|
|
INT i_preceding_node_index = GET_PREVIOUS_NODE_INDEX_IN_ORDER(i_current_node_index)
|
|
IF i_preceding_node_index >= 0
|
|
NODE_STRUCT preceding_node = GET_NODE_AT_INDEX(i_preceding_node_index)
|
|
IF preceding_node.type = TYPE_POINT_NODE
|
|
// setup preceding node as first box node
|
|
SET_NODE_TYPE_AT_INDEX(i_preceding_node_index, TYPE_BOX_FIRST_NODE)
|
|
SET_NODE_BOX_COUNTERPART_AT_INDEX(i_preceding_node_index, i_current_node_index)
|
|
|
|
// setup current node as second box node
|
|
SET_NODE_TYPE_AT_INDEX(i_current_node_index, TYPE_BOX_SECOND_NODE)
|
|
SET_NODE_BOX_COUNTERPART_AT_INDEX(i_current_node_index, i_preceding_node_index)
|
|
|
|
DO_SOUND(AUDIO_CONFIRM_EDIT)
|
|
ELSE
|
|
PRINTSTRING("Preceding node is already a box") PRINTNL()
|
|
ENDIF
|
|
ELSE
|
|
PRINTSTRING("Couldn't find preceding node") PRINTNL()
|
|
ENDIF
|
|
ELIF current_node.type = TYPE_BOX_FIRST_NODE
|
|
OR current_node.type = TYPE_BOX_SECOND_NODE
|
|
// change this node back to a point
|
|
SET_NODE_TYPE_AT_INDEX(i_current_node_index, TYPE_POINT_NODE)
|
|
|
|
// change the box's counterpart back to a point
|
|
IF current_node.i_box_counterpart_index >= 0
|
|
NODE_STRUCT counterpart_node = GET_NODE_AT_INDEX(current_node.i_box_counterpart_index)
|
|
IF counterpart_node.type = TYPE_BOX_FIRST_NODE
|
|
OR counterpart_node.type = TYPE_BOX_SECOND_NODE
|
|
SET_NODE_TYPE_AT_INDEX(current_node.i_box_counterpart_index, TYPE_POINT_NODE)
|
|
SET_NODE_BOX_COUNTERPART_AT_INDEX(current_node.i_box_counterpart_index, -1)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// reset this node's counterpart
|
|
SET_NODE_BOX_COUNTERPART_AT_INDEX(i_current_node_index, -1)
|
|
|
|
DO_SOUND(AUDIO_CONFIRM_EDIT)
|
|
ENDIF
|
|
ELSE
|
|
PRINTSTRING("Attempting to convert a node which does not exist") PRINTNL()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// set current node to next one along
|
|
PROC GO_TO_NEXT_NODE()
|
|
IF i_current_node_index >= 0
|
|
INT i_next_node = GET_NEXT_NODE_INDEX_IN_ORDER(i_current_node_index, TRUE)
|
|
IF i_next_node >= 0
|
|
SET_CURRENT_NODE_INDEX(i_next_node)
|
|
POINT_CAM_AT_NODE(i_current_node_index)
|
|
DO_SOUND(AUDIO_CONFIRM_CHANGE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// set current node to previous one along
|
|
PROC GO_TO_PREVIOUS_NODE()
|
|
IF i_current_node_index >= 0
|
|
INT i_previous_node = GET_PREVIOUS_NODE_INDEX_IN_ORDER(i_current_node_index, TRUE)
|
|
IF i_previous_node >= 0
|
|
SET_CURRENT_NODE_INDEX(i_previous_node)
|
|
POINT_CAM_AT_NODE(i_current_node_index)
|
|
DO_SOUND(AUDIO_CONFIRM_CHANGE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// debug cam coords and rot to menu cam
|
|
PROC COPY_DEBUG_CAM_TO_MENU_CAM()
|
|
SET_CAM_COORD(menu_cam, GET_CAM_COORD(debug_cam))
|
|
SET_CAM_ROT(menu_cam, GET_CAM_ROT(debug_cam))
|
|
SET_CAM_FOV(menu_cam, GET_CAM_FOV(debug_cam))
|
|
ENDPROC
|
|
|
|
// menu cam coords and rot to debug cam
|
|
PROC COPY_MENU_CAM_TO_DEBUG_CAM()
|
|
SET_CAM_COORD(debug_cam, GET_CAM_COORD(menu_cam))
|
|
SET_CAM_ROT(debug_cam, GET_CAM_ROT(menu_cam))
|
|
SET_CAM_FOV(debug_cam, GET_CAM_FOV(menu_cam))
|
|
ENDPROC
|
|
|
|
// jump the camera to the first node in the set
|
|
PROC JUMP_VIEW_TO_FIRST_NODE_IN_SET()
|
|
INT i_first_node_index = GET_FIRST_NODE_INDEX()
|
|
SET_CURRENT_NODE_INDEX(i_first_node_index)
|
|
IF i_first_node_index >= 0
|
|
VECTOR v_first_coords = GET_NODE_COORDS_AT_INDEX(i_first_node_index)
|
|
CAM_LOOK_DOWN_ON_COORDS(v_first_coords)
|
|
COPY_DEBUG_CAM_TO_MENU_CAM()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// select next set
|
|
PROC GO_TO_NEXT_SET()
|
|
IF i_current_set_index >= 0
|
|
INT i_next_set_index = GET_NEXT_OPEN_SET(i_current_set_index)
|
|
IF i_next_set_index >= 0
|
|
SET_CURRENT_SET_INDEX(i_next_set_index)
|
|
JUMP_VIEW_TO_FIRST_NODE_IN_SET()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// select previous set
|
|
PROC GO_TO_PREVIOUS_SET()
|
|
IF i_current_set_index >= 0
|
|
INT i_previous_set_index = GET_PREVIOUS_OPEN_SET(i_current_set_index)
|
|
IF i_previous_set_index >= 0
|
|
SET_CURRENT_SET_INDEX(i_previous_set_index)
|
|
JUMP_VIEW_TO_FIRST_NODE_IN_SET()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// go into set submenu
|
|
PROC DO_SUB_MENU()
|
|
IF i_current_set_index >= 0
|
|
current_sub_menu_selection = SUB_MENU_EDIT
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// select next submenu item
|
|
PROC GO_TO_NEXT_SUB_MENU_ITEM()
|
|
INT i_next_menu_pos
|
|
i_next_menu_pos = ENUM_TO_INT(current_sub_menu_selection) + 1
|
|
IF i_next_menu_pos > (NUMBER_OF_SUB_MENU_ITEMS -1)
|
|
i_next_menu_pos = 1
|
|
ENDIF
|
|
current_sub_menu_selection = INT_TO_ENUM(SUB_MENU_ENUM, i_next_menu_pos)
|
|
ENDPROC
|
|
|
|
// select previous submenu item
|
|
PROC GO_TO_PREVIOUS_SUB_MENU_ITEM()
|
|
INT i_next_menu_pos
|
|
i_next_menu_pos = ENUM_TO_INT(current_sub_menu_selection) - 1
|
|
IF i_next_menu_pos < 1
|
|
i_next_menu_pos = NUMBER_OF_SUB_MENU_ITEMS -1
|
|
ENDIF
|
|
current_sub_menu_selection = INT_TO_ENUM(SUB_MENU_ENUM, i_next_menu_pos)
|
|
ENDPROC
|
|
|
|
// create new set from menu
|
|
PROC DO_CREATE_SET()
|
|
INT i_slot = GET_FREE_SET_INDEX()
|
|
IF i_slot >= 0
|
|
CREATE_NEW_SET(i_slot)
|
|
SET_CURRENT_SET_INDEX(i_slot)
|
|
ELSE
|
|
PRINTSTRING("Could not find a free set index") PRINTNL()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// go into edit from menu
|
|
PROC DO_EDIT_SET()
|
|
IF i_current_set_index >= 0
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
IF i_current_node_index = -1
|
|
// set debug cam pos to game cam pos if no node selected
|
|
SET_CAM_COORD(debug_cam, GET_GAMEPLAY_CAM_COORD())
|
|
SET_CAM_ROT(debug_cam, GET_GAMEPLAY_CAM_ROT())
|
|
SET_CAM_FOV(debug_cam, GET_GAMEPLAY_CAM_FOV())
|
|
ENDIF
|
|
|
|
v_last_cam_coords = v_cam_coords
|
|
b_equidistant_drop = FALSE
|
|
SET_DEBUG_CAM_ACTIVE(TRUE, TRUE)
|
|
current_sub_menu_selection = SUB_MENU_HIDDEN
|
|
current_viewer_state = STATE_FLYCAM
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// delete set from menu
|
|
PROC DO_DELETE_SET()
|
|
IF i_current_set_index >= 0
|
|
DELETE_SET(i_current_set_index)
|
|
i_current_set_index = GET_PREVIOUS_OPEN_SET(i_current_set_index)
|
|
b_do_update_widget = TRUE
|
|
current_sub_menu_selection = SUB_MENU_HIDDEN
|
|
ELSE
|
|
PRINTSTRING("Attempting to delete a set which does not exist") PRINTNL()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// copy the current set into a free slot
|
|
PROC DO_COPY_SET()
|
|
IF i_current_set_index >= 0
|
|
INT i_slot = GET_FREE_SET_INDEX()
|
|
IF i_slot >= 0
|
|
IF COPY_SET_DATA_INTO_SLOT(i_current_set_index, i_slot)
|
|
SET_CURRENT_SET_INDEX(i_slot)
|
|
ELSE
|
|
PRINTSTRING("Copy failed") PRINTNL()
|
|
ENDIF
|
|
ELSE
|
|
PRINTSTRING("Could not find a free set index") PRINTNL()
|
|
ENDIF
|
|
current_sub_menu_selection = SUB_MENU_HIDDEN
|
|
ELSE
|
|
PRINTSTRING("Attempting to copy a set which does not exist") PRINTNL()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// toggle equidistant drop
|
|
PROC TOGGLE_EQUIDISTANT_DROP()
|
|
IF NOT b_equidistant_drop
|
|
b_equidistant_drop = TRUE
|
|
ELSE
|
|
b_equidistant_drop = FALSE
|
|
ENDIF
|
|
f_distance_travelled = 0.0
|
|
ENDPROC
|
|
|
|
// back into menu from fly cam
|
|
PROC GO_TO_MENU()
|
|
// save the set
|
|
NODEVIEWER_SAVE_SET(0, i_current_set_index, node_sets[i_current_set_index], SIZE_OF(NODE_SET_STRUCT))
|
|
|
|
RENDER_SCRIPT_CAMS(TRUE, FALSE)
|
|
//SET_CURRENT_NODE_INDEX(-1)
|
|
b_equidistant_drop = FALSE
|
|
f_distance_travelled = 0.0
|
|
SET_DEBUG_CAM_ACTIVE(FALSE, TRUE)
|
|
current_viewer_state = STATE_MENU
|
|
ENDPROC
|
|
|
|
// check the control pad and perform desired action
|
|
PROC HANDLE_USER_ACTIONS()
|
|
SWITCH current_viewer_state
|
|
CASE STATE_MENU
|
|
IF NOT b_show_quit_confirm
|
|
// if haven't selected a set yet
|
|
IF current_sub_menu_selection = SUB_MENU_HIDDEN
|
|
// dpad down - next set
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, DPADDOWN)
|
|
GO_TO_NEXT_SET()
|
|
ENDIF
|
|
|
|
// dpad up - previous set
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, DPADUP)
|
|
GO_TO_PREVIOUS_SET()
|
|
ENDIF
|
|
|
|
// square - create set
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, SQUARE)
|
|
DO_CREATE_SET()
|
|
ENDIF
|
|
|
|
// cross - select set, go to submenu
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, CROSS)
|
|
DO_SUB_MENU()
|
|
ENDIF
|
|
|
|
// triangle - quit
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, TRIANGLE)
|
|
b_show_quit_confirm = TRUE
|
|
ENDIF
|
|
ELSE
|
|
// dpad down - next submenu item
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, DPADDOWN)
|
|
GO_TO_NEXT_SUB_MENU_ITEM()
|
|
ENDIF
|
|
|
|
// dpad up - previous submenu item
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, DPADUP)
|
|
GO_TO_PREVIOUS_SUB_MENU_ITEM()
|
|
ENDIF
|
|
|
|
// if in sub menu, perform action based on what is selected in sub menu
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, CROSS)
|
|
SWITCH current_sub_menu_selection
|
|
CASE SUB_MENU_EDIT
|
|
// edit - go into fly cam
|
|
DO_EDIT_SET()
|
|
BREAK
|
|
|
|
CASE SUB_MENU_COPY
|
|
// copy
|
|
DO_COPY_SET()
|
|
BREAK
|
|
|
|
CASE SUB_MENU_DELETE
|
|
// delete - get rid of all data in current set
|
|
DO_DELETE_SET()
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
// triangle - back out of sub menu
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, TRIANGLE)
|
|
current_sub_menu_selection = SUB_MENU_HIDDEN
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
// controls for quit
|
|
// cross - confirm quit
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, CROSS)
|
|
b_quit_tool = TRUE
|
|
ENDIF
|
|
|
|
// triangle - cancel quit
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, TRIANGLE)
|
|
b_show_quit_confirm = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
// controls for dropping / editing in flycam
|
|
CASE STATE_FLYCAM
|
|
// edit functions
|
|
IF IS_BUTTON_PRESSED(DEBUG_PAD, LEFTSHOULDER1)
|
|
// cross - move node
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, RIGHTSHOULDER1)
|
|
MOVE_CURRENT_NODE()
|
|
ENDIF
|
|
|
|
// square - put node on ground
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, RIGHTSHOCK)
|
|
PLACE_CURRENT_NODE_ON_GROUND()
|
|
ENDIF
|
|
|
|
// rstick - convert last two nodes into a box
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, LEFTSHOCK)
|
|
CONVERT_CURRENT_AND_PRECEDING_NODES_TO_BOX()
|
|
ENDIF
|
|
|
|
// edit not held
|
|
ELSE
|
|
// r1 - create new node
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, RIGHTSHOULDER1)
|
|
PLACE_NEW_NODE(node_sets[i_current_set_index])
|
|
ENDIF
|
|
|
|
// triangle - delete node
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, TRIANGLE)
|
|
DELETE_CURRENT_NODE()
|
|
ENDIF
|
|
|
|
// dpad right - next node
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, DPADRIGHT)
|
|
GO_TO_NEXT_NODE()
|
|
ENDIF
|
|
|
|
// dpad left - previous node
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, DPADLEFT)
|
|
GO_TO_PREVIOUS_NODE()
|
|
ENDIF
|
|
|
|
// select - toggle equidistant drop
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, SELECT)
|
|
TOGGLE_EQUIDISTANT_DROP()
|
|
ENDIF
|
|
|
|
// start - go back into menu
|
|
IF IS_BUTTON_JUST_PRESSED(DEBUG_PAD, START)
|
|
GO_TO_MENU()
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
// update distance travelled for equidistant drop amd drop if gone over limit
|
|
PROC UPDATE_EQUIDISTANT_DROP()
|
|
IF b_equidistant_drop
|
|
f_distance_travelled += GET_DISTANCE_BETWEEN_COORDS(v_cam_coords, v_last_cam_coords)
|
|
IF f_distance_travelled >= f_distance_to_travel_for_next_drop
|
|
PLACE_NEW_NODE(node_sets[i_current_set_index])
|
|
f_distance_travelled = 0.0
|
|
ENDIF
|
|
ELSE
|
|
// reset distance to 0 if turned off
|
|
IF f_distance_travelled > 0.0
|
|
f_distance_travelled = 0.0
|
|
ENDIF
|
|
ENDIF
|
|
|
|
v_last_cam_coords = v_cam_coords
|
|
ENDPROC
|
|
|
|
// return the correct size to draw a debug sphere
|
|
FUNC FLOAT GET_SIZE_TO_DRAW_SPHERE(NODE_TYPE_ENUM type)
|
|
IF type = TYPE_POINT_NODE
|
|
RETURN POINT_NODE_SIZE
|
|
ELIF type = TYPE_BOX_FIRST_NODE
|
|
OR type = TYPE_BOX_SECOND_NODE
|
|
RETURN BOX_NODE_SIZE
|
|
ENDIF
|
|
|
|
RETURN POINT_NODE_SIZE
|
|
ENDFUNC
|
|
|
|
// return correct amount to offset text label
|
|
FUNC FLOAT GET_TEXT_OFFSET(NODE_TYPE_ENUM type)
|
|
IF type = TYPE_POINT_NODE
|
|
RETURN POINT_NODE_TEXT_OFFSET
|
|
ELIF type = TYPE_BOX_FIRST_NODE
|
|
OR type = TYPE_BOX_SECOND_NODE
|
|
RETURN BOX_NODE_TEXT_OFFSET
|
|
ENDIF
|
|
|
|
RETURN POINT_NODE_TEXT_OFFSET
|
|
ENDFUNC
|
|
|
|
// draw shadow under camera
|
|
PROC DRAW_SHADOW()
|
|
FLOAT f_ground_z
|
|
IF GET_GROUND_Z_FOR_3D_COORD(v_cam_coords, f_ground_z)
|
|
DRAW_DEBUG_SPHERE(<<v_cam_coords.x, v_cam_coords.y, f_ground_z - 0.85>>, 2.0, 0, 0, 0, 185)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// draw all the nodes in the current set
|
|
PROC DRAW_NODES_GROUP()
|
|
INT i
|
|
|
|
REPEAT NUMBER_OF_NODES_PER_SET i
|
|
NODE_STRUCT node = GET_NODE_AT_INDEX(i)
|
|
|
|
// draw sphere and text at each node coords
|
|
IF node.type <> TYPE_FREE_NODE
|
|
IF i = i_current_node_index
|
|
AND current_viewer_state = STATE_FLYCAM
|
|
// selected
|
|
DRAW_DEBUG_SPHERE(node.v_coords, GET_SIZE_TO_DRAW_SPHERE(node.type), 255, 0, 0, SPHERE_ALPHA)
|
|
DRAW_DEBUG_TEXT(node.tl_label, <<node.v_coords.x, node.v_coords.y, node.v_coords.z + GET_TEXT_OFFSET(node.type)>>, 255, 0, 0, SPHERE_ALPHA)
|
|
ELSE
|
|
// unselected
|
|
DRAW_DEBUG_SPHERE(node.v_coords, GET_SIZE_TO_DRAW_SPHERE(node.type), 0, 155, 255, SPHERE_ALPHA)
|
|
DRAW_DEBUG_TEXT(node.tl_label, <<node.v_coords.x, node.v_coords.y, node.v_coords.z + GET_TEXT_OFFSET(node.type)>>, 0, 155, 255, SPHERE_ALPHA)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// draw a box for any box nodes
|
|
IF node.type = TYPE_BOX_FIRST_NODE
|
|
IF node.i_box_counterpart_index >= 0
|
|
NODE_STRUCT second_node = GET_NODE_AT_INDEX(node.i_box_counterpart_index)
|
|
IF second_node.type = TYPE_BOX_SECOND_NODE
|
|
// setup the correct order to draw the points (for command to work first vector must be lowest, second highest)
|
|
VECTOR v_first_box_coords = <<0,0,0>>
|
|
VECTOR v_second_box_coords = <<0,0,0>>
|
|
|
|
IF node.v_coords.x < second_node.v_coords.x
|
|
v_first_box_coords.x = node.v_coords.x
|
|
v_second_box_coords.x = second_node.v_coords.x
|
|
ELSE
|
|
v_first_box_coords.x = second_node.v_coords.x
|
|
v_second_box_coords.x = node.v_coords.x
|
|
ENDIF
|
|
IF node.v_coords.y < second_node.v_coords.y
|
|
v_first_box_coords.y = node.v_coords.y
|
|
v_second_box_coords.y = second_node.v_coords.y
|
|
ELSE
|
|
v_first_box_coords.y = second_node.v_coords.y
|
|
v_second_box_coords.y = node.v_coords.y
|
|
ENDIF
|
|
IF node.v_coords.z < second_node.v_coords.z
|
|
v_first_box_coords.z = node.v_coords.z
|
|
v_second_box_coords.z = second_node.v_coords.z
|
|
ELSE
|
|
v_first_box_coords.z = second_node.v_coords.z
|
|
v_second_box_coords.z = node.v_coords.z
|
|
ENDIF
|
|
|
|
// do the box
|
|
IF (i = i_current_node_index
|
|
OR node.i_box_counterpart_index = i_current_node_index)
|
|
AND current_viewer_state = STATE_FLYCAM
|
|
// selected
|
|
DRAW_DEBUG_BOX(v_first_box_coords, v_second_box_coords, 255, 0, 0, BOX_ALPHA)
|
|
ELSE
|
|
// unselected
|
|
DRAW_DEBUG_BOX(v_first_box_coords, v_second_box_coords, 0, 155, 255, BOX_ALPHA)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
PROC DRAW_SUB_MENU_ITEM(SUB_MENU_ENUM item, FLOAT f_y_pos)
|
|
INT i_colour
|
|
IF current_sub_menu_selection = item
|
|
i_colour = i_red
|
|
ELSE
|
|
i_colour = i_white
|
|
ENDIF
|
|
|
|
STRING s_text
|
|
SWITCH item
|
|
CASE SUB_MENU_EDIT
|
|
s_text = "EDIT"
|
|
BREAK
|
|
CASE SUB_MENU_COPY
|
|
s_text = "COPY"
|
|
BREAK
|
|
CASE SUB_MENU_DELETE
|
|
s_text = "DELETE"
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
DEBUG_DISPLAY_LITERAL_TEXT(s_text, 0.25, f_y_pos, 0.3, 0.3, 0.0, 1.0, i_colour)
|
|
ENDPROC
|
|
|
|
// draw the sub menu popup
|
|
PROC DRAW_SUB_MENU(FLOAT f_y_pos)
|
|
DRAW_SUB_MENU_ITEM(SUB_MENU_EDIT, f_y_pos)
|
|
DRAW_SUB_MENU_ITEM(SUB_MENU_COPY, f_y_pos + 0.02)
|
|
DRAW_SUB_MENU_ITEM(SUB_MENU_DELETE, f_y_pos + 0.04)
|
|
ENDPROC
|
|
|
|
// draw the menu screen
|
|
PROC DRAW_MENU()
|
|
INT i
|
|
// draw the background
|
|
DRAW_RECT(0.25, 0.5, 0.5, 1.0, 0, 0, 0, 220)
|
|
|
|
// draw the title
|
|
DEBUG_DISPLAY_LITERAL_TEXT("NODE VIEWER", 0.06, 0.06, 0.75, 0.75, 0.0, 1.0, i_white)
|
|
|
|
IF NOT b_show_quit_confirm
|
|
// draw the list of node sets
|
|
REPEAT NUMBER_OF_SETS i
|
|
IF node_sets[i].b_open
|
|
// draw set name
|
|
IF i = i_current_set_index
|
|
DEBUG_DISPLAY_LITERAL_TEXT(node_sets[i].tl_name, 0.06, 0.135 + (i*0.05), 0.4, 0.4, 0.0, 1.0, i_red)
|
|
ELSE
|
|
DEBUG_DISPLAY_LITERAL_TEXT(node_sets[i].tl_name, 0.06, 0.135 + (i*0.05), 0.4, 0.4, 0.0, 1.0, i_white)
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
// draw the edit submenu
|
|
IF current_sub_menu_selection <> SUB_MENU_HIDDEN
|
|
DRAW_SUB_MENU(0.135 + (i_current_set_index*0.05))
|
|
ENDIF
|
|
ELSE
|
|
// show the message to confirm quit
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Press Cross to confirm quit or Triangle to return", 0.06, 0.5, 0.32, 0.32, 0.0, 0.5, i_white)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// draw control help
|
|
PROC DRAW_HELP()
|
|
SWITCH current_viewer_state
|
|
CASE STATE_FLYCAM
|
|
IF IS_BUTTON_PRESSED(DEBUG_PAD, LEFTSHOULDER1)
|
|
// edit menu
|
|
DEBUG_DISPLAY_LITERAL_TEXT("R1: move node", 0.06, 0.77, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("R3: set node on ground", 0.06, 0.80, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("L3: convert this and preceding nodes to box", 0.06, 0.83, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
ELSE
|
|
DEBUG_DISPLAY_LITERAL_TEXT("R1: create node", 0.06, 0.77, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Triangle: delete node", 0.06, 0.80, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Dpad left/right: change selected node", 0.06, 0.83, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
IF b_equidistant_drop
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Select: Disable equidistant drop", 0.06, 0.86, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
ELSE
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Select: Enable equidistant drop", 0.06, 0.86, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
ENDIF
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Hold L1: edit node functions", 0.06, 0.89, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Start: return to menu", 0.06, 0.92, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
ENDIF
|
|
|
|
// display state of equidistant drop
|
|
IF b_equidistant_drop
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Equidistant drop ON", 0.06, 0.06, 0.3, 0.3, 0.0, 1.0, i_red)
|
|
ELSE
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Equidistant drop OFF", 0.06, 0.06, 0.3, 0.3, 0.0, 1.0, i_red)
|
|
ENDIF
|
|
BREAK
|
|
CASE STATE_MENU
|
|
IF NOT b_show_quit_confirm
|
|
IF current_sub_menu_selection = SUB_MENU_HIDDEN
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Square: create new set", 0.06, 0.77, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Cross: select set", 0.06, 0.80, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Dpad up/down: navigate sets", 0.06, 0.83, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Triangle: quit tool", 0.06, 0.86, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
ELSE
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Cross: select option", 0.06, 0.77, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Dpad up/down: navigate menu", 0.06, 0.80, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
DEBUG_DISPLAY_LITERAL_TEXT("Triangle: go back", 0.06, 0.83, 0.3, 0.3, 0.0, 1.0, i_white)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
// create widget
|
|
PROC CREATE_NODES_WIDGET()
|
|
w_nodes_group = START_WIDGET_GROUP("Node Viewer")
|
|
ADD_WIDGET_STRING("Current Set")
|
|
w_set_name = ADD_TEXT_WIDGET("Name")
|
|
ADD_WIDGET_BOOL("Update Name", b_update_name)
|
|
ADD_WIDGET_STRING("Current Node")
|
|
w_node_label = ADD_TEXT_WIDGET("Label")
|
|
ADD_WIDGET_BOOL("Update Label", b_update_label)
|
|
ADD_WIDGET_STRING("Other Commands")
|
|
ADD_WIDGET_BOOL("Use equidistant drop", b_equidistant_drop)
|
|
ADD_WIDGET_FLOAT_SLIDER("Distance for eq. drop", f_distance_to_travel_for_next_drop, 20, 200, 1)
|
|
ADD_WIDGET_BOOL("Show Help", b_draw_help)
|
|
ADD_WIDGET_BOOL("Quit", b_quit_tool)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
b_do_update_widget = TRUE
|
|
ENDPROC
|
|
|
|
// update widget
|
|
PROC UPDATE_NODES_WIDGET()
|
|
// update with data of current node
|
|
IF b_do_update_widget
|
|
IF i_current_node_index >= 0
|
|
NODE_STRUCT current_node = GET_NODE_AT_INDEX(i_current_node_index)
|
|
SET_CONTENTS_OF_TEXT_WIDGET(w_node_label, current_node.tl_label)
|
|
ELSE
|
|
SET_CONTENTS_OF_TEXT_WIDGET(w_node_label, "<no node>")
|
|
ENDIF
|
|
|
|
IF i_current_set_index >= 0
|
|
SET_CONTENTS_OF_TEXT_WIDGET(w_set_name, node_sets[i_current_set_index].tl_name)
|
|
ELSE
|
|
SET_CONTENTS_OF_TEXT_WIDGET(w_set_name, "<no set>")
|
|
ENDIF
|
|
b_do_update_widget = FALSE
|
|
ENDIF
|
|
|
|
// change set name from text box
|
|
IF b_update_name
|
|
IF i_current_set_index >= 0
|
|
SET_SET_NAME(i_current_set_index, GET_CONTENTS_OF_TEXT_WIDGET(w_set_name))
|
|
ENDIF
|
|
b_update_name = FALSE
|
|
ENDIF
|
|
|
|
// change node label from text box
|
|
IF b_update_label
|
|
IF i_current_node_index >= 0
|
|
SET_NODE_LABEL_AT_INDEX(i_current_node_index, GET_CONTENTS_OF_TEXT_WIDGET(w_node_label))
|
|
ENDIF
|
|
b_update_label = FALSE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
SCRIPT
|
|
SET_SCRIPT_AS_NO_LONGER_NEEDED("nodeviewer")
|
|
|
|
CREATE_NODES_WIDGET()
|
|
REGISTER_SCRIPT_WITH_AUDIO()
|
|
NODEVIEWER_INIT()
|
|
|
|
INT i
|
|
REPEAT NUMBER_OF_SETS i
|
|
NODEVIEWER_LOAD_SET(0, i, node_sets[i], SIZE_OF(NODE_SET_STRUCT))
|
|
ENDREPEAT
|
|
|
|
i_current_node_index = -1
|
|
|
|
INT j
|
|
REPEAT COUNT_OF(node_sets) j
|
|
IF node_sets[j].b_open
|
|
i_current_set_index = j
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
// player control off
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_AMBIENT_SCRIPT)
|
|
DISPLAY_HUD(FALSE)
|
|
DISPLAY_RADAR(FALSE)
|
|
ENDIF
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
SET_ENTITY_PROOFS(PLAYER_PED_ID(), TRUE, TRUE, TRUE, TRUE, TRUE)
|
|
ENDIF
|
|
|
|
// get debug cam
|
|
debug_cam = GET_DEBUG_CAM()
|
|
|
|
// other cams
|
|
point_cam = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA")
|
|
SET_CAM_ACTIVE(point_cam, TRUE)
|
|
menu_cam = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA")
|
|
SET_CAM_ACTIVE(menu_cam, TRUE)
|
|
|
|
// debug drawing active
|
|
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
|
|
|
|
WHILE TRUE
|
|
|
|
// deal with input
|
|
HANDLE_USER_ACTIONS()
|
|
|
|
IF current_viewer_state = STATE_FLYCAM
|
|
// get current cam coords
|
|
v_cam_coords = GET_CAM_COORD(debug_cam)
|
|
//v_cam_rot = GET_CAM_ROT(debug_cam)
|
|
//f_cam_fov = GET_CAM_FOV(debug_cam)
|
|
|
|
// update menu cam
|
|
IF NOT b_set_menu_cam
|
|
b_set_menu_cam = TRUE
|
|
ELSE
|
|
COPY_DEBUG_CAM_TO_MENU_CAM()
|
|
ENDIF
|
|
|
|
// draw shadow under camera
|
|
DRAW_SHADOW()
|
|
|
|
// update distance travelled for equidistant dropped
|
|
UPDATE_EQUIDISTANT_DROP()
|
|
ENDIF
|
|
|
|
// draw all the nodes in the current set
|
|
IF i_current_set_index >= 0
|
|
DRAW_NODES_GROUP()
|
|
ENDIF
|
|
|
|
IF current_viewer_state = STATE_MENU
|
|
// draw menu
|
|
DRAW_MENU()
|
|
ENDIF
|
|
|
|
IF b_draw_help
|
|
DRAW_HELP()
|
|
ENDIF
|
|
|
|
// update the widget
|
|
UPDATE_NODES_WIDGET()
|
|
|
|
// quit
|
|
IF b_quit_tool
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE, SPC_AMBIENT_SCRIPT)
|
|
DISPLAY_HUD(TRUE)
|
|
DISPLAY_RADAR(TRUE)
|
|
ENDIF
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
SET_ENTITY_PROOFS(PLAYER_PED_ID(), FALSE, FALSE, FALSE, FALSE, FALSE)
|
|
ENDIF
|
|
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
SET_DEBUG_CAM_ACTIVE(FALSE, FALSE)
|
|
|
|
DELETE_WIDGET_GROUP(w_nodes_group)
|
|
UNREGISTER_SCRIPT_WITH_AUDIO()
|
|
TERMINATE_THIS_THREAD()
|
|
ENDIF
|
|
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ENDSCRIPT
|
|
|
|
#ENDIF
|