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

1254 lines
42 KiB
Scheme
Executable File

#IF IS_DEBUG_BUILD
//
USING "rage_builtins.sch"
USING "stack_sizes.sch"
// game commands
USING "commands_debug.sch"
USING "commands_graphics.sch"
USING "commands_hud.sch"
USING "commands_misc.sch"
USING "commands_pad.sch"
USING "commands_xml.sch"
// global files
USING "globals.sch"
USING "script_DRAWING.sch"
//CONST_INT JIMMY_TESTBED_ACTIVE 1
// ******************************************************************
//
// SCRIPT XML
//
// XML commands for dealing with xml in the game
//
// dont call any of the commands in lowercase inside your scripts,
// these are private functions called by the other commands inside
// this file.
//
// ******************************************************************
// ********************************************************
// SHARED HASH KEYS - Simon Lashley
// ********************************************************
// "x","y" and "z"
CONST_INT XML_HASH_X -1828477467
CONST_INT XML_HASH_Y -2137718520
CONST_INT XML_HASH_Z -1235194722
// "h" used for headings
CONST_INT XML_HASH_H 1879302122
// ********************************************************
// XML MENUS - Simon Lashley
// ********************************************************
// SCROLL SPEED FOR MENUS WHEN BEING HELD DOWN
CONST_INT XML_MENU_SCROLL_SPEED 6000
// HASH KEYS
// "menuItem"
CONST_INT XML_HASH_MENUITEM -802149892
// "name"
CONST_INT XML_HASH_NAME -421429484
// "script"
CONST_INT XML_HASH_SCRIPT -408367631
// "value"
CONST_INT XML_HASH_VALUE 510789971
// "info"
CONST_INT XML_HASH_INFO 1745727664
// "title"
CONST_INT XML_HASH_TITLE 1923799069
// "mpSafe"
CONST_INT XML_HASH_MP_SAFE -264210844
//#NO_WIKI
//PURPOSE: reset menu item data
PROC resetXmlMenuItemData()
INT i
// RESET MENU ITEMS
FOR i = 0 TO (TOTAL_XML_ITEMS_ON_SCREEN-1)
xmlMenuData.items[i].type = XML_MENU_OPTION_NULL
xmlMenuData.items[i].name = ""
xmlMenuData.items[i].warp = <<0.0,0.0,0.0>>
xmlMenuData.items[i].heading = 0.0
xmlMenuData.items[i].scriptName = ""
xmlMenuData.items[i].value = -1
ENDFOR
// RESET NAVIGATION DATA
// current item
xmlMenuData.current = 0
// total items on the menu
xmlMenuData.total = 0
// item at the top of the screen used for scrolling
xmlMenuData.top = 0
// key press used for item jump
xmlMenuData.key = KEY_ESCAPE
// value passed back to mission menus
xmlMenuData.missionValue = -1
// menu scroll speed
xmlMenuData.menuScrollSpeed = 0
//
xmlMenuData.menuTitle = "XML Menu"
ENDPROC
// PURPOSE: resets the global xml menu structure
PROC resetAllXmlMenuData()
// INT i
// SET COLOURS AND ALPHA
// background rectangle colour
xmlMenuData.colourBackground = INT_COLOUR(40, 40, 40, 200)
// active text colour
xmlMenuData.colourActiveText = INT_COLOUR(230, 230, 230, 230)
// active text backshadow colour
xmlMenuData.colourActiveTextBackshadow = INT_COLOUR(0, 0, 0, 230)
// deactive text colour
xmlMenuData.colourDeactiveText = INT_COLOUR(130, 130, 130, 220)
// info text colour
xmlMenuData.colourInfoText = INT_COLOUR(255, 255, 255, 255)
xmlMenuData.menuIsBeingDrawn = FALSE
// reset choosen menu
xmlMenuData.choosenMenu = XML_MENU_LIST_NULL
// RESET MENU ITEMS
resetXmlMenuItemData()
ENDPROC
//#END_NO_WIKI
FUNC INT GET_CURRENT_XML_MENU_ARRAY_POS()
RETURN (xmlMenuData.current - xmlMenuData.top)
ENDFUNC
//PURPOSE: checks if menu is being drawn
FUNC BOOL IS_XML_MENU_ON_SCREEN()
RETURN xmlMenuData.menuIsBeingDrawn
ENDFUNC
//PURPOSE: removes the xml menu from the screen
PROC REMOVE_XML_MENU()
IF IS_XML_MENU_ON_SCREEN()
xmlMenuData.menuIsBeingDrawn = FALSE
ENDIF
ENDPROC
//#NO_WIKI
// PURPOSE: loads the passed xml file into the global data
FUNC BOOL loadXmlIntoGlobalStruct(STRING xml, XML_MENU_LIST choosenMenu)
// stores info just incase attributes done in wrong order
TEXT_LABEL_63 infoAttribute
// load in xml file
IF LOAD_XML_FILE(xml)
// Keep track of the current menu type and item so we can restore later
INT iCurrentItem = xmlMenuData.current
INT iTopItem = xmlMenuData.top
XML_MENU_LIST eCurrentMenu = xmlMenuData.choosenMenu
// reset the data
resetXmlMenuItemData()
xmlMenuData.menuTitle = xml
INT iNewItem
INT eachNode, eachAttribute
BOOL addItemInMP
INT iNodeCount = GET_NUMBER_OF_XML_NODES()
IF iNodeCount <> 0
FOR eachNode = 0 TO (iNodeCount-1)
SWITCH GET_HASH_KEY(GET_XML_NODE_NAME())
CASE XML_HASH_MENUITEM
IF GET_NUMBER_OF_XML_NODE_ATTRIBUTES() <> 0
infoAttribute = ""
addItemInMP = FALSE
FOR eachAttribute = 0 TO (GET_NUMBER_OF_XML_NODE_ATTRIBUTES()-1)
SWITCH GET_HASH_KEY(GET_XML_NODE_ATTRIBUTE_NAME(eachAttribute))
CASE XML_HASH_MP_SAFE
addItemInMP = GET_BOOL_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_NAME
xmlMenuData.items[iNewItem].name = GET_STRING_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
IF (choosenMenu = XML_MENU_LIST_VEHICLES) OR (choosenMenu = XML_MENU_LIST_PEDS)
xmlMenuData.items[iNewItem].type = XML_MENU_OPTION_VALUE
ENDIF
BREAK
CASE XML_HASH_X
xmlMenuData.items[iNewItem].warp.x = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
xmlMenuData.items[iNewItem].type = XML_MENU_OPTION_WARP
BREAK
CASE XML_HASH_Y
xmlMenuData.items[iNewItem].warp.y = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_Z
xmlMenuData.items[iNewItem].warp.z = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_H
xmlMenuData.items[iNewItem].heading = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_SCRIPT
xmlMenuData.items[iNewItem].scriptName = GET_STRING_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
xmlMenuData.items[iNewItem].type = XML_MENU_OPTION_SCRIPT
BREAK
CASE XML_HASH_VALUE
xmlMenuData.items[iNewItem].value = GET_INT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
xmlMenuData.items[iNewItem].type = XML_MENU_OPTION_VALUE
BREAK
CASE XML_HASH_INFO
infoAttribute = GET_STRING_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
ENDSWITCH
ENDFOR
// if vehicle or ped menu generate enum from name and add info to name
IF (choosenMenu = XML_MENU_LIST_VEHICLES) OR (choosenMenu = XML_MENU_LIST_PEDS)
xmlMenuData.items[iNewItem].value = GET_HASH_KEY(xmlMenuData.items[iNewItem].name)
IF NOT ARE_STRINGS_EQUAL(infoAttribute, "")
xmlMenuData.items[iNewItem].name += " - "
xmlMenuData.items[iNewItem].name += infoAttribute
ENDIF
IF GET_LENGTH_OF_LITERAL_STRING(xmlMenuData.items[iNewItem].name) <= 15
xmlMenuData.items[iNewItem].modelName = xmlMenuData.items[iNewItem].name
ELSE
xmlMenuData.items[iNewItem].modelName = GET_STRING_FROM_STRING(xmlMenuData.items[iNewItem].name, 0, 14)
ENDIF
ENDIF
IF (g_bInMultiplayer AND addItemInMP)
OR NOT (g_bInMultiplayer)
// Only start adding once we are back in the range
IF xmlMenuData.total >= iTopItem
// Only add up to max items on screen
IF iNewItem < TOTAL_XML_ITEMS_ON_SCREEN
iNewItem++
ELSE
xmlMenuData.items[iNewItem].name = ""
ENDIF
ENDIF
xmlMenuData.total++
ENDIF
ENDIF
BREAK
DEFAULT
IF GET_NUMBER_OF_XML_NODE_ATTRIBUTES() <> 0
FOR eachAttribute = 0 TO (GET_NUMBER_OF_XML_NODE_ATTRIBUTES()-1)
SWITCH GET_HASH_KEY(GET_XML_NODE_ATTRIBUTE_NAME(eachAttribute))
CASE XML_HASH_TITLE
xmlMenuData.menuTitle = GET_STRING_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
xmlMenuData.menuTitle += " - "
xmlMenuData.menuTitle += xml
BREAK
ENDSWITCH
ENDFOR
ENDIF
BREAK
ENDSWITCH
GET_NEXT_XML_NODE()
ENDFOR
ENDIF
// delete xml file
DELETE_XML_FILE()
// Restore the last selection
IF eCurrentMenu = xmlMenuData.choosenMenu
//IF iCurrentItem <= xmlMenuData.total
//AND iTopItem <= xmlMenuData.total
xmlMenuData.current = iCurrentItem
xmlMenuData.top = iTopItem
//ENDIF
ENDIF
ELSE
PRINTSTRING("\n UNABLE TO LOAD THE FOLLOWING XML FILE - ")
PRINTSTRING(xml)
PRINTSTRING("\n")
resetAllXmlMenuData()
RETURN FALSE
ENDIF
RETURN (xmlMenuData.total > 0)
ENDFUNC
FUNC KEY_NUMBER getDebugKeyForChar(STRING sChar)
// Invalid string
IF ARE_STRINGS_EQUAL(sChar, "")
OR IS_STRING_NULL(sChar)
RETURN KEY_ESCAPE
ENDIF
// We only want the first character
IF GET_LENGTH_OF_LITERAL_STRING(sChar) > 1
sChar = (GET_STRING_FROM_STRING(sChar, 0, 1))
ENDIF
INT iKey = GET_HASH_KEY(sChar)
IF iKey = GET_HASH_KEY("A") RETURN KEY_A
ELIF iKey = GET_HASH_KEY("B") RETURN KEY_B
ELIF iKey = GET_HASH_KEY("C") RETURN KEY_C
ELIF iKey = GET_HASH_KEY("D") RETURN KEY_D
ELIF iKey = GET_HASH_KEY("E") RETURN KEY_E
ELIF iKey = GET_HASH_KEY("F") RETURN KEY_F
ELIF iKey = GET_HASH_KEY("G") RETURN KEY_G
ELIF iKey = GET_HASH_KEY("H") RETURN KEY_H
ELIF iKey = GET_HASH_KEY("I") RETURN KEY_I
ELIF iKey = GET_HASH_KEY("J") RETURN KEY_J
ELIF iKey = GET_HASH_KEY("K") RETURN KEY_K
ELIF iKey = GET_HASH_KEY("L") RETURN KEY_L
ELIF iKey = GET_HASH_KEY("M") RETURN KEY_M
ELIF iKey = GET_HASH_KEY("N") RETURN KEY_N
ELIF iKey = GET_HASH_KEY("O") RETURN KEY_O
ELIF iKey = GET_HASH_KEY("P") RETURN KEY_P
ELIF iKey = GET_HASH_KEY("Q") RETURN KEY_Q
ELIF iKey = GET_HASH_KEY("R") RETURN KEY_R
ELIF iKey = GET_HASH_KEY("S") RETURN KEY_S
ELIF iKey = GET_HASH_KEY("T") RETURN KEY_T
ELIF iKey = GET_HASH_KEY("U") RETURN KEY_U
ELIF iKey = GET_HASH_KEY("V") RETURN KEY_V
ELIF iKey = GET_HASH_KEY("W") RETURN KEY_W
ELIF iKey = GET_HASH_KEY("X") RETURN KEY_X
ELIF iKey = GET_HASH_KEY("Y") RETURN KEY_Y
ELIF iKey = GET_HASH_KEY("Z") RETURN KEY_Z
ENDIF
RETURN KEY_ESCAPE
ENDFUNC
FUNC BOOL getMenuKeyJustPressed(KEY_NUMBER &eKey)
// Reset the key
eKey = KEY_ESCAPE
INT i
KEY_NUMBER eTempKey
TEXT_LABEL_31 sAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
FOR i = 0 TO 25
eTempKey = getDebugKeyForChar(GET_STRING_FROM_STRING(sAlpha, i, i+1))
IF IS_KEYBOARD_KEY_JUST_PRESSED(eTempKey)
eKey = eTempKey
RETURN TRUE
ENDIF
ENDFOR
RETURN FALSE
ENDFUNC
FUNC XML_MENU_INPUT_TYPE getXmlMenuInput()
INT i
// stick pos
INT stickPosY, stickPosDump
stickPosY = -1
// check for a button or return on the keyboard
IF IS_BUTTON_JUST_PRESSED(PAD1, CROSS) OR IS_KEYBOARD_KEY_JUST_PRESSED(KEY_RETURN)
RETURN XML_MENU_INPUT_ACCEPT
// check for b button
ELIF IS_BUTTON_JUST_PRESSED(PAD1, CIRCLE)
RETURN XML_MENU_INPUT_ACCEPT2
// check for x button
ELIF IS_BUTTON_JUST_PRESSED(PAD1, SQUARE)
RETURN XML_MENU_INPUT_ACCEPT3
// check for pressing same key that loaded the menu
ELIF (xmlMenuInfo[xmlMenuData.choosenMenu].button != 0 AND IS_KEYBOARD_KEY_JUST_PRESSED(INT_TO_ENUM(KEY_NUMBER, xmlMenuInfo[xmlMenuData.choosenMenu].button))) OR IS_KEYBOARD_KEY_JUST_PRESSED(KEY_ESCAPE)
RETURN XML_MENU_INPUT_CANCEL
// check dpad up and cursor up
ELIF IS_BUTTON_JUST_PRESSED(PAD1, DPADUP) OR IS_KEYBOARD_KEY_JUST_PRESSED(KEY_UP)
xmlMenuData.menuScrollSpeed = 0
RETURN XML_MENU_INPUT_UP
// check dpad down and cursor down
ELIF IS_BUTTON_JUST_PRESSED(PAD1, DPADDOWN) OR IS_KEYBOARD_KEY_JUST_PRESSED(KEY_DOWN)
xmlMenuData.menuScrollSpeed = 0
RETURN XML_MENU_INPUT_DOWN
// check dpad left and cursor left
ELIF IS_BUTTON_JUST_PRESSED(PAD1, DPADLEFT) OR IS_KEYBOARD_KEY_JUST_PRESSED(KEY_LEFT)
xmlMenuData.menuScrollSpeed = 0
RETURN XML_MENU_INPUT_LEFT
// check dpad right and cursor right
ELIF IS_BUTTON_JUST_PRESSED(PAD1, DPADRIGHT) OR IS_KEYBOARD_KEY_JUST_PRESSED(KEY_RIGHT)
xmlMenuData.menuScrollSpeed = 0
RETURN XML_MENU_INPUT_RIGHT
// check lb for previous menu
ELIF IS_BUTTON_JUST_PRESSED(PAD1, LEFTSHOULDER1)
RETURN XML_MENU_INPUT_PREVIOUS_MENU
// check lb for previous menu
ELIF IS_BUTTON_JUST_PRESSED(PAD1, RIGHTSHOULDER1)
RETURN XML_MENU_INPUT_NEXT_MENU
// check keypress for item jump
ELIF getMenuKeyJustPressed(xmlMenuData.key)
RETURN XML_MENU_INPUT_KEYPRESS
// check keypress for item filter
ELIF IS_BUTTON_JUST_PRESSED(PAD1, SELECT)
RETURN XML_MENU_INPUT_SEARCH
// check to see if trying to load another menu
ELSE
FOR i = 0 TO (ENUM_TO_INT(TOTAL_XML_MENUS)-1)
// dont load if its this menu
IF i <> ENUM_TO_INT(xmlMenuData.choosenMenu)
IF xmlMenuInfo[i].button != 0
AND IS_KEYBOARD_KEY_JUST_PRESSED(INT_TO_ENUM(KEY_NUMBER, xmlMenuInfo[i].button))
xmlMenuData.choosenMenu = INT_TO_ENUM(XML_MENU_LIST, i)
RETURN XML_MENU_INPUT_NEW_MENU
ENDIF
ENDIF
ENDFOR
ENDIF
// check left stick if none of the other buttons are pressed
IF IS_BUTTON_PRESSED(PAD1, LEFTSTICKY)
// get position of stick
GET_POSITION_OF_ANALOGUE_STICKS(PAD1, stickPosDump, stickPosY, stickPosDump, stickPosDump)
stickPosY *= 10
ELIF IS_BUTTON_PRESSED(PAD1, DPADUP) OR IS_KEYBOARD_KEY_PRESSED(KEY_UP)
stickPosY = -800
ELIF IS_BUTTON_PRESSED(PAD1, DPADDOWN) OR IS_KEYBOARD_KEY_PRESSED(KEY_DOWN)
stickPosY = 800
ENDIF
IF stickPosY <> -1
// speed up if right trigger pressed or shift is pressed
IF IS_BUTTON_PRESSED(PAD1, RIGHTSHOULDER2)
stickPosY *= 5
ENDIF
// depending on the direction of the stick go up or down the menu
IF stickPosY < 0
xmlMenuData.menuScrollSpeed += (stickPosY * -1)
IF xmlMenuData.menuScrollSpeed >= XML_MENU_SCROLL_SPEED
xmlMenuData.menuScrollSpeed = 0
RETURN XML_MENU_INPUT_UP
ENDIF
ELSE
xmlMenuData.menuScrollSpeed += stickPosY
IF xmlMenuData.menuScrollSpeed >= XML_MENU_SCROLL_SPEED
xmlMenuData.menuScrollSpeed = 0
RETURN XML_MENU_INPUT_DOWN
ENDIF
ENDIF
ELSE
xmlMenuData.menuScrollSpeed = XML_MENU_SCROLL_SPEED
ENDIF
RETURN XML_MENU_INPUT_NULL
ENDFUNC
// PURPOSE: moves the selection up the menu
PROC moveUpXmlMenu(BOOL bWrap = TRUE)
IF xmlMenuData.current > 0
IF xmlMenuData.current = xmlMenuData.top
xmlMenuData.top -= TOTAL_XML_ITEMS_ON_SCREEN
IF xmlMenuData.top < 0
xmlMenuData.top = 0
ENDIF
xmlMenuData.current--
loadXmlIntoGlobalStruct(xmlMenuInfo[xmlMenuData.choosenMenu].xml, xmlMenuData.choosenMenu)
ELSE
xmlMenuData.current--
ENDIF
ELIF bWrap
IF xmlMenuData.total > TOTAL_XML_ITEMS_ON_SCREEN
xmlMenuData.top = (xmlMenuData.total - TOTAL_XML_ITEMS_ON_SCREEN)
loadXmlIntoGlobalStruct(xmlMenuInfo[xmlMenuData.choosenMenu].xml, xmlMenuData.choosenMenu)
ELSE
xmlMenuData.top = 0
ENDIF
xmlMenuData.current = (xmlMenuData.total-1)
ENDIF
ENDPROC
// PURPOSE: moves the selection up the menu
PROC moveDownXmlMenu(BOOL bWrap = TRUE)
IF xmlMenuData.current < (xmlMenuData.total-1)
IF xmlMenuData.current = (xmlMenuData.top + (TOTAL_XML_ITEMS_ON_SCREEN-1))
xmlMenuData.current++
xmlMenuData.top = xmlMenuData.current
loadXmlIntoGlobalStruct(xmlMenuInfo[xmlMenuData.choosenMenu].xml, xmlMenuData.choosenMenu)
ELSE
xmlMenuData.current++
ENDIF
ELIF bWrap
xmlMenuData.top = 0
xmlMenuData.current = 0
loadXmlIntoGlobalStruct(xmlMenuInfo[xmlMenuData.choosenMenu].xml, xmlMenuData.choosenMenu)
ENDIF
ENDPROC
// PURPOSE: moves the selection up the menu
PROC jumpToXMLMenuKey(BOOL bWrap = TRUE)
// Invalid key
IF xmlMenuData.key = KEY_ESCAPE
EXIT
ENDIF
BOOL bPassedKey
BOOL bNewKeyFound
KEY_NUMBER eNextKey
INT iCurrentTop = xmlMenuData.top
INT iCurrentItem = xmlMenuData.current
// Next item
xmlMenuData.current++
// Cycle through the list of items to see if we can find a match
WHILE (NOT bNewKeyFound AND NOT bPassedKey)
IF xmlMenuData.current < xmlMenuData.total-1
AND GET_CURRENT_XML_MENU_ARRAY_POS() < TOTAL_XML_ITEMS_ON_SCREEN
eNextKey = getDebugKeyForChar(xmlMenuData.items[GET_CURRENT_XML_MENU_ARRAY_POS()].name)
// Found a match
IF (eNextKey = xmlMenuData.key)
bNewKeyFound = TRUE
// Grab the next item
ELSE
// Next item
xmlMenuData.current++
ENDIF
ELSE
bPassedKey = TRUE
ENDIF
ENDWHILE
// continue to end of list, reloading etc.
// Start from the beginning if no key was found and wrap is true
IF (NOT bNewKeyFound AND bWrap)
xmlMenuData.current = 0
bPassedKey = FALSE
// Cycle through the list of items to see if we can find a match
WHILE (NOT bNewKeyFound AND NOT bPassedKey)
IF xmlMenuData.current < xmlMenuData.total-1
AND GET_CURRENT_XML_MENU_ARRAY_POS() < TOTAL_XML_ITEMS_ON_SCREEN
eNextKey = getDebugKeyForChar(xmlMenuData.items[GET_CURRENT_XML_MENU_ARRAY_POS()].name)
// Found a match
IF (eNextKey = xmlMenuData.key)
bNewKeyFound = TRUE
// Grab the next item
ELSE
// Next item
xmlMenuData.current++
ENDIF
ELSE
bPassedKey = TRUE
ENDIF
ENDWHILE
ENDIF
IF (NOT bNewKeyFound)
xmlMenuData.top = iCurrentTop
xmlMenuData.current = iCurrentItem
ELSE
BOOL bLastPage
BOOL bLessThanTop = (xmlMenuData.current < xmlMenuData.top)
BOOL bGreaterBottom = (xmlMenuData.current > xmlMenuData.top+(TOTAL_XML_ITEMS_ON_SCREEN-1))
IF (bLessThanTop OR bGreaterBottom)
xmlMenuData.top = 0
bLessThanTop = (xmlMenuData.current < xmlMenuData.top)
bGreaterBottom = (xmlMenuData.current > xmlMenuData.top+(TOTAL_XML_ITEMS_ON_SCREEN-1))
bLastPage = (xmlMenuData.top > xmlMenuData.total-(TOTAL_XML_ITEMS_ON_SCREEN))
WHILE (bLessThanTop OR bGreaterBottom)
AND (NOT bLastPage)
xmlMenuData.top++
bLessThanTop = (xmlMenuData.current < xmlMenuData.top)
bGreaterBottom = (xmlMenuData.current > xmlMenuData.top+(TOTAL_XML_ITEMS_ON_SCREEN-1))
bLastPage = (xmlMenuData.top > xmlMenuData.total-(TOTAL_XML_ITEMS_ON_SCREEN))
ENDWHILE
ENDIF
ENDIF
ENDPROC
// PURPOSE: draws the xml menu
PROC drawXmlMenu()
INT i
FLOAT pos = (0.16*xmlMenuData.size)
TEXT_LABEL_63 tlItem, tlTemp
// TEXT_LABEL_15 acceptLabel
IF IS_XML_MENU_ON_SCREEN()
// hide hud
HIDE_HUD_AND_RADAR_THIS_FRAME()
// draw background to show text
DRAW_RECT((0.35*xmlMenuData.size), (0.485*xmlMenuData.size), (0.605*xmlMenuData.size), (0.860*xmlMenuData.size), INT_RED(xmlMenuData.colourBackground), INT_GREEN(xmlMenuData.colourBackground), INT_BLUE(xmlMenuData.colourBackground), INT_ALPHA(xmlMenuData.colourBackground))
// title text
DEBUG_DISPLAY_LITERAL_TEXT(xmlMenuData.menuTitle, (0.055*xmlMenuData.size), (0.0635*xmlMenuData.size), (0.475*xmlMenuData.size), (0.475*xmlMenuData.size), (0.055*xmlMenuData.size), (0.65*xmlMenuData.size), xmlMenuData.colourActiveText, 1, xmlMenuData.colourActiveTextBackshadow)
// outline
DRAW_RECT((0.048*xmlMenuData.size), (0.485*xmlMenuData.size), (0.003*xmlMenuData.size), (0.860*xmlMenuData.size), INT_RED(xmlMenuData.colourDeactiveText), INT_GREEN(xmlMenuData.colourDeactiveText), INT_BLUE(xmlMenuData.colourDeactiveText), INT_ALPHA(xmlMenuData.colourDeactiveText))
DRAW_RECT((0.652*xmlMenuData.size), (0.485*xmlMenuData.size), (0.003*xmlMenuData.size), (0.860*xmlMenuData.size), INT_RED(xmlMenuData.colourDeactiveText), INT_GREEN(xmlMenuData.colourDeactiveText), INT_BLUE(xmlMenuData.colourDeactiveText), INT_ALPHA(xmlMenuData.colourDeactiveText))
DRAW_RECT((0.35*xmlMenuData.size), (0.055*xmlMenuData.size), (0.607*xmlMenuData.size), (0.006*xmlMenuData.size), INT_RED(xmlMenuData.colourDeactiveText), INT_GREEN(xmlMenuData.colourDeactiveText), INT_BLUE(xmlMenuData.colourDeactiveText), INT_ALPHA(xmlMenuData.colourDeactiveText))
DRAW_RECT((0.35*xmlMenuData.size), (0.105*xmlMenuData.size), (0.607*xmlMenuData.size), (0.006*xmlMenuData.size), INT_RED(xmlMenuData.colourDeactiveText), INT_GREEN(xmlMenuData.colourDeactiveText), INT_BLUE(xmlMenuData.colourDeactiveText), INT_ALPHA(xmlMenuData.colourDeactiveText))
DRAW_RECT((0.35*xmlMenuData.size), (0.915*xmlMenuData.size), (0.607*xmlMenuData.size), (0.006*xmlMenuData.size), INT_RED(xmlMenuData.colourDeactiveText), INT_GREEN(xmlMenuData.colourDeactiveText), INT_BLUE(xmlMenuData.colourDeactiveText), INT_ALPHA(xmlMenuData.colourDeactiveText))
//scroll bar
IF xmlMenuData.total > TOTAL_XML_ITEMS_ON_SCREEN
// edge
DRAW_RECT((0.640*xmlMenuData.size), (0.510*xmlMenuData.size), (0.003*xmlMenuData.size), (0.805*xmlMenuData.size), INT_RED(xmlMenuData.colourDeactiveText), INT_GREEN(xmlMenuData.colourDeactiveText), INT_BLUE(xmlMenuData.colourDeactiveText), INT_ALPHA(xmlMenuData.colourDeactiveText))
// bar
FLOAT topOfBar = (0.510 - (0.805 * 0.5))
FLOAT amountPerItem = 0.805 / xmlMenuData.total
DRAW_RECT((0.646*xmlMenuData.size), (((topOfBar + (xmlMenuData.top*amountPerItem)) + ((amountPerItem*TOTAL_XML_ITEMS_ON_SCREEN) * 0.5))*xmlMenuData.size), (0.005*xmlMenuData.size), ((amountPerItem*TOTAL_XML_ITEMS_ON_SCREEN)*xmlMenuData.size), INT_RED(xmlMenuData.colourDeactiveText), INT_GREEN(xmlMenuData.colourDeactiveText), INT_BLUE(xmlMenuData.colourDeactiveText), INT_ALPHA(xmlMenuData.colourDeactiveText))
ENDIF
// add viewable options
FOR i = 0 TO (TOTAL_XML_ITEMS_ON_SCREEN-1)
IF NOT ARE_STRINGS_EQUAL(xmlMenuData.items[i].name, "")
tlItem = xmlMenuData.items[i].name
IF xmlMenuData.choosenMenu = XML_MENU_LIST_VEHICLES
tlTemp = tlItem
tlTemp += "_D"
IF DOES_TEXT_LABEL_EXIST(tlTemp)
tlTemp = GET_STRING_FROM_TEXT_FILE(tlTemp)
ELSE
tlTemp = "-"
ENDIF
IF (xmlMenuData.top + i) = xmlMenuData.current
DEBUG_DISPLAY_LITERAL_TEXT(tlTemp, (0.055*xmlMenuData.size)+0.1, (pos*xmlMenuData.size), (0.55*xmlMenuData.size), (0.55*xmlMenuData.size), (0.055*xmlMenuData.size), (0.95*xmlMenuData.size), xmlMenuData.colourActiveText, 1, xmlMenuData.colourActiveTextBackshadow)
ELSE
DEBUG_DISPLAY_LITERAL_TEXT(tlTemp, (0.055*xmlMenuData.size)+0.1, (pos*xmlMenuData.size), (0.55*xmlMenuData.size), (0.55*xmlMenuData.size), (0.055*xmlMenuData.size), (0.95*xmlMenuData.size), xmlMenuData.colourDeactiveText)
ENDIF
ENDIF
IF (xmlMenuData.top + i) = xmlMenuData.current
DEBUG_DISPLAY_LITERAL_TEXT(tlItem, (0.055*xmlMenuData.size), (pos*xmlMenuData.size), (0.55*xmlMenuData.size), (0.55*xmlMenuData.size), (0.055*xmlMenuData.size), (0.95*xmlMenuData.size), xmlMenuData.colourActiveText, 1, xmlMenuData.colourActiveTextBackshadow)
ELSE
DEBUG_DISPLAY_LITERAL_TEXT(tlItem, (0.055*xmlMenuData.size), (pos*xmlMenuData.size), (0.55*xmlMenuData.size), (0.55*xmlMenuData.size), (0.055*xmlMenuData.size), (0.95*xmlMenuData.size), xmlMenuData.colourDeactiveText)
ENDIF
pos += (0.0475*xmlMenuData.size)
ENDIF
ENDFOR
// option text
IF xmlMenuData.choosenMenu = XML_MENU_LIST_VEHICLES
DISPLAY_TEXT_LABEL("XML_NAV_VEH", (0.055*xmlMenuData.size), (0.87*xmlMenuData.size)-0.020, (0.475*xmlMenuData.size), (0.475*xmlMenuData.size), (0.0*xmlMenuData.size), (1.0*xmlMenuData.size), xmlMenuData.colourInfoText)
ELSE
DISPLAY_TEXT_LABEL("XML_NAV", (0.055*xmlMenuData.size), (0.87*xmlMenuData.size), (0.475*xmlMenuData.size), (0.475*xmlMenuData.size), (0.0*xmlMenuData.size), (1.0*xmlMenuData.size), xmlMenuData.colourInfoText)
ENDIF
ENDIF
ENDPROC
//#END_NO_WIKI
//PURPOSE: sets up the active mission xml menu
PROC SETUP_MISSION_XML_MENU(STRING xml, KEY_NUMBER key = KEY_R)
xmlMenuInfo[XML_MENU_LIST_MISSION].xml = xml
xmlMenuInfo[XML_MENU_LIST_MISSION].active = TRUE
xmlMenuInfo[XML_MENU_LIST_MISSION].button = ENUM_TO_INT(key)
ENDPROC
//PURPOSE: cleans up the active mission xml menu
PROC CLEANUP_MISSION_XML_MENU()
xmlMenuInfo[XML_MENU_LIST_MISSION].xml = ""
xmlMenuInfo[XML_MENU_LIST_MISSION].active = FALSE
xmlMenuInfo[XML_MENU_LIST_MISSION].button = ENUM_TO_INT(KEY_R)
ENDPROC
//PURPOSE: returns an int if pressed on the mission menu
FUNC INT GET_MISSION_XML_VALUE()
INT value = xmlMenuData.missionValue
IF xmlMenuData.missionValue <> -1
xmlMenuData.missionValue = -1
ENDIF
RETURN value
ENDFUNC
PROC GRAB_PREVIOUS_XML_MENU()
INT menuInt = ENUM_TO_INT(xmlMenuData.choosenMenu)
IF menuInt > ENUM_TO_INT(XML_MENU_LIST_SHARED_WARPS)
menuInt --
ELSE
menuInt = (ENUM_TO_INT(XML_MENU_LIST_MISSION)-1)
ENDIF
xmlMenuData.choosenMenu = INT_TO_ENUM(XML_MENU_LIST, menuInt)
IF NOT xmlMenuInfo[xmlMenuData.choosenMenu].active
GRAB_PREVIOUS_XML_MENU()
ENDIF
ENDPROC
PROC GRAB_NEXT_XML_MENU()
INT menuInt = ENUM_TO_INT(xmlMenuData.choosenMenu)
IF menuInt < (ENUM_TO_INT(XML_MENU_LIST_MISSION)-1)
menuInt ++
ELSE
menuInt = ENUM_TO_INT(XML_MENU_LIST_SHARED_WARPS)
ENDIF
xmlMenuData.choosenMenu = INT_TO_ENUM(XML_MENU_LIST, menuInt)
IF NOT xmlMenuInfo[xmlMenuData.choosenMenu].active
GRAB_NEXT_XML_MENU()
ENDIF
ENDPROC
PROC RESET_AND_RELOAD_XML_MENU()
resetXmlMenuItemData()
IF loadXmlIntoGlobalStruct(xmlMenuInfo[xmlMenuData.choosenMenu].xml, xmlMenuData.choosenMenu)
xmlMenuData.menuIsBeingDrawn = TRUE
ELSE
xmlMenuData.menuIsBeingDrawn = FALSE
ENDIF
ENDPROC
// ********************************************************
// ********************************************************
// ********************************************************
// END OF XML MENUS
// ********************************************************
// ********************************************************
// ********************************************************
// ********************************************************
// XML COORDS - Simon Lashley
// ********************************************************
//
// The following are commands for placing coordinates in
// xml files and grabbing them back
//
// HASH KEYS
// "coord"
CONST_INT XML_HASH_COORD -1036347508
// "all" - passed into commands
CONST_INT XML_HASH_ALL 1166234150
// This structure holds the info taken from each line of the xml
// this is mainly used to avoid having a big array of vectors
STRUCT XML_COORDS_STRUCT
// vector for x,y and z
VECTOR vec
// float for heading
FLOAT heading
// bool storing if struct in the right section of the xml
BOOL active
// int counter for total nodes
INT totalNodes
// int counter for current node
INT currentNode
// bool saying if xml was loaded ok
BOOL loaded
ENDSTRUCT
//#NO_WIKI
//
FUNC BOOL getValuesFromCoordXml(XML_COORDS_STRUCT &coordStruct, STRING node)
INT eachNode
INT eachAttribute
// make active incase all is set
IF GET_HASH_KEY(node) = XML_HASH_ALL
coordStruct.active = TRUE
ENDIF
coordStruct.vec = <<0.0, 0.0, 0.0>>
coordStruct.heading = 0
// carry on through the nodes where it left off
FOR eachNode = coordStruct.currentNode TO (coordStruct.totalNodes-1)
SWITCH GET_HASH_KEY(GET_XML_NODE_NAME())
// hit a coord
CASE XML_HASH_COORD
IF coordStruct.active
IF GET_NUMBER_OF_XML_NODE_ATTRIBUTES() <> 0
FOR eachAttribute = 0 TO (GET_NUMBER_OF_XML_NODE_ATTRIBUTES()-1)
SWITCH GET_HASH_KEY(GET_XML_NODE_ATTRIBUTE_NAME(eachAttribute))
CASE XML_HASH_X
coordStruct.vec.x = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_Y
coordStruct.vec.y = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_Z
coordStruct.vec.z = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_H
coordStruct.heading = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
ENDSWITCH
ENDFOR
coordStruct.currentNode++
GET_NEXT_XML_NODE()
RETURN TRUE
ENDIF
ENDIF
BREAK
// check to see if this is the node the user wants to load
DEFAULT
coordStruct.active = (GET_HASH_KEY(GET_XML_NODE_NAME()) = GET_HASH_KEY(node)) OR (GET_HASH_KEY(node) = XML_HASH_ALL)
BREAK
ENDSWITCH
coordStruct.currentNode++
GET_NEXT_XML_NODE()
ENDFOR
RETURN FALSE
ENDFUNC
//#END_NO_WIKI
// resets the structure and gets ready for the xml grab loop
FUNC BOOL LOAD_COORD_XML(XML_COORDS_STRUCT &coordStruct, STRING xml)
// see if the xml file can be loaded, return false if not
coordStruct.loaded = LOAD_XML_FILE(xml)
IF NOT coordStruct.loaded
// PRINTSTRING("GET_COORDS_FROM_XML failed cannot load ")
// PRINTSTRING(xml)
// PRINTNL()
RETURN FALSE
ENDIF
// see if the xml file contains any nodes, return false if not
coordStruct.totalNodes = GET_NUMBER_OF_XML_NODES()
IF coordStruct.totalNodes = 0
// PRINTSTRING("GET_COORDS_FROM_XML failed file contains no nodes ")
// PRINTSTRING(xml)
// PRINTNL()
RETURN FALSE
ENDIF
// reset the current node and active flag
coordStruct.currentNode = 0
coordStruct.active = FALSE
RETURN TRUE
ENDFUNC
PROC UNLOAD_COORD_XML(XML_COORDS_STRUCT &coordStruct)
coordStruct.active = FALSE
coordStruct.loaded = FALSE
DELETE_XML_FILE()
ENDPROC
//
FUNC BOOL GET_NEXT_COORD_FROM_XML(XML_COORDS_STRUCT &coordStruct, STRING node)
RETURN getValuesFromCoordXml(coordStruct, node)
ENDFUNC
//
FUNC BOOL GET_COORDS_AND_HEADINGS_FROM_XML(STRING xml, STRING node, VECTOR &coords[], FLOAT &headings[])
INT counter = 0
INT vecArraySize = COUNT_OF(coords)
INT headingArraySize = COUNT_OF(headings)
XML_COORDS_STRUCT coordStruct
IF LOAD_COORD_XML(coordStruct, xml)
// if the xml file has no nodes return FALSE and display a pring in the console window
IF coordStruct.totalNodes = 0
// PRINTSTRING("GET_COORDS_FROM_XML failed file contains no nodes ")
// PRINTSTRING(xml)
// PRINTNL()
RETURN FALSE
ENDIF
// keep grabbing coords while they exist
WHILE getValuesFromCoordXml(coordStruct, node) AND (counter < vecArraySize)
// grab the vector
coords[counter] = coordStruct.vec
// grab the heading if there is one
IF counter < headingArraySize
headings[counter] = coordStruct.heading
ENDIF
// increment array counter
counter++
ENDWHILE
// delete the xml file
DELETE_XML_FILE()
// all valid data was passed into the arrays return TRUE
RETURN TRUE
ENDIF
// PRINTSTRING("GET_COORDS_FROM_XML failed cannot load ")
// PRINTSTRING(xml)
// PRINTNL()
RETURN FALSE
ENDFUNC
//
FUNC BOOL GET_COORDS_FROM_XML(STRING xml, STRING node, VECTOR &coords[])
FLOAT headings[2]
RETURN GET_COORDS_AND_HEADINGS_FROM_XML(xml, node, coords, headings)
ENDFUNC
// ********************************************************
// ********************************************************
// ********************************************************
// END OF XML COORDINATES
// ********************************************************
// ********************************************************
// ********************************************************
// ********************************************************
// XML SPLINE CAM - Alwyn Roberts
// ********************************************************
//
// The following are commands for placing spline cam values in
// xml files and grabbing them back
//
// HASH KEYS
// "SplineNode"
CONST_INT XML_HASH_SPLINENODE -1282907452
// "posx", "posy" and "posz" positions
CONST_INT XML_HASH_POSX 1999642847
CONST_INT XML_HASH_POSY 1227506900
CONST_INT XML_HASH_POSZ -1686836888
// "rotx", "roty" and "rotz" rotations
CONST_INT XML_HASH_ROTX 769268202
CONST_INT XML_HASH_ROTY 989803572
CONST_INT XML_HASH_ROTZ 1228787889
// "dur" duration
CONST_INT XML_HASH_DUR 533369123
// This structure holds the info taken from each line of the xml
// this is mainly used to avoid having a big array of vectors
STRUCT XML_SPLINE_CAM_STRUCT
VECTOR pos // vector for x,y and z
VECTOR rot // vector for x,y and z
INT dur // int for duration
BOOL active // bool storing if struct in the right section of the xml
INT totalNodes // int counter for total nodes
INT currentNode // int counter for current node
BOOL loaded // bool saying if xml was loaded ok
ENDSTRUCT
//#NO_WIKI
//
FUNC BOOL getValuesFromSplineCamXml(XML_SPLINE_CAM_STRUCT &splineCamStruct, STRING node)
INT eachNode
INT eachAttribute
// make active incase all is set
IF GET_HASH_KEY(node) = XML_HASH_ALL
splineCamStruct.active = TRUE
ENDIF
splineCamStruct.pos = <<0.0, 0.0, 0.0>>
splineCamStruct.rot = <<0.0, 0.0, 0.0>>
splineCamStruct.dur = 0
// carry on through the nodes where it left off
FOR eachNode = splineCamStruct.currentNode TO (splineCamStruct.totalNodes-1)
SWITCH GET_HASH_KEY(GET_XML_NODE_NAME())
// hit a SPLINE_CAM
CASE XML_HASH_SPLINENODE
IF splineCamStruct.active
IF GET_NUMBER_OF_XML_NODE_ATTRIBUTES() <> 0
FOR eachAttribute = 0 TO (GET_NUMBER_OF_XML_NODE_ATTRIBUTES()-1)
SWITCH GET_HASH_KEY(GET_XML_NODE_ATTRIBUTE_NAME(eachAttribute))
CASE XML_HASH_POSX
splineCamStruct.pos.x = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_POSY
splineCamStruct.pos.y = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_POSZ
splineCamStruct.pos.z = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_ROTX
splineCamStruct.rot.x = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_ROTY
splineCamStruct.rot.y = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_ROTZ
splineCamStruct.rot.z = GET_FLOAT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
CASE XML_HASH_DUR
splineCamStruct.dur = GET_INT_FROM_XML_NODE_ATTRIBUTE(eachAttribute)
BREAK
ENDSWITCH
ENDFOR
splineCamStruct.currentNode++
GET_NEXT_XML_NODE()
RETURN TRUE
ENDIF
ENDIF
BREAK
// check to see if this is the node the user wants to load
DEFAULT
splineCamStruct.active = (GET_HASH_KEY(GET_XML_NODE_NAME()) = GET_HASH_KEY(node)) OR (GET_HASH_KEY(node) = XML_HASH_ALL)
BREAK
ENDSWITCH
splineCamStruct.currentNode++
GET_NEXT_XML_NODE()
ENDFOR
RETURN FALSE
ENDFUNC
//#END_NO_WIKI
// resets the structure and gets ready for the xml grab loop
FUNC BOOL LOAD_SPLINE_CAM_XML(XML_SPLINE_CAM_STRUCT &splineCamStruct, STRING xml)
// see if the xml file can be loaded, return false if not
splineCamStruct.loaded = LOAD_XML_FILE(xml)
IF NOT splineCamStruct.loaded
// PRINTSTRING("GET_SPLINE_CAMS_FROM_XML failed cannot load ")
// PRINTSTRING(xml)
// PRINTNL()
RETURN FALSE
ENDIF
// see if the xml file contains any nodes, return false if not
splineCamStruct.totalNodes = GET_NUMBER_OF_XML_NODES()
IF splineCamStruct.totalNodes = 0
// PRINTSTRING("GET_SPLINE_CAMS_FROM_XML failed file contains no nodes ")
// PRINTSTRING(xml)
// PRINTNL()
RETURN FALSE
ENDIF
// reset the current node and active flag
splineCamStruct.currentNode = 0
splineCamStruct.active = FALSE
RETURN TRUE
ENDFUNC
PROC UNLOAD_SPLINE_CAM_XML(XML_SPLINE_CAM_STRUCT &splineCamStruct)
splineCamStruct.active = FALSE
splineCamStruct.loaded = FALSE
DELETE_XML_FILE()
ENDPROC
//
FUNC BOOL GET_NEXT_SPLINE_CAM_FROM_XML(XML_SPLINE_CAM_STRUCT &splineCamStruct, STRING node)
RETURN getValuesFromSplineCamXml(splineCamStruct, node)
ENDFUNC
//
FUNC BOOL GET_SPLINE_CAM_COORDS_FROM_XML(STRING xml, STRING node,
VECTOR &vSplineCam_pos[], VECTOR &vSplineCam_rot[], INT &iSplineCam_dur[])
INT counter = 0
INT iCount_of_splinecam_pos = COUNT_OF(vSplineCam_pos)
XML_SPLINE_CAM_STRUCT splineCamStruct
IF LOAD_SPLINE_CAM_XML(splineCamStruct, xml)
// if the xml file has no nodes return FALSE and display a pring in the console window
IF splineCamStruct.totalNodes = 0
PRINTSTRING("GET_SPLINE_CAMS_FROM_XML failed file contains no nodes ")PRINTSTRING(xml)PRINTNL()
RETURN FALSE
ENDIF
// keep grabbing SPLINE_CAMs while they exist
WHILE getValuesFromSplineCamXml(splineCamStruct, node) AND (counter < iCount_of_splinecam_pos)
// grab the vector
vSplineCam_pos[counter] = splineCamStruct.pos
vSplineCam_rot[counter] = splineCamStruct.rot
iSplineCam_dur[counter] = splineCamStruct.dur
// increment array counter
counter++
ENDWHILE
// delete the xml file
DELETE_XML_FILE()
// all valid data was passed into the arrays return TRUE
RETURN TRUE
ENDIF
// PRINTSTRING("GET_SPLINE_CAMS_FROM_XML failed cannot load ")
// PRINTSTRING(xml)
// PRINTNL()
RETURN FALSE
ENDFUNC
// ********************************************************
// ********************************************************
// ********************************************************
// END OF XML SPLINE CAM
// ********************************************************
// ********************************************************
// ********************************************************
#ENDIF // IS_DEBUG_BUILD