-
Notifications
You must be signed in to change notification settings - Fork 4
Mod Tools
WIP, not in release builds yet
Mod tools are similar to scripts except they can create GUIs.
-- These 4 functions return a table that represent the GUI element.
gui.create_dockpanel(lastChildFill : boolean) -> table
gui.create_stackpanel(isVertical : boolean) -> table
gui.create_gridpanel() -> table
gui.create_button(text : string) -> table
gui.create_text(text : string) -> table
-- Sets the GUI's root panel to draw
gui.set_root_panel(panel : table)
-- Blocks until there's pending messages queued on the lua thread, then processes them, and returns.
-- For example, when the user presses a button, it dispatches a click event to the lua thread,
-- then this method will process that press event (which starts an internal loop until the click
-- release event is sent, and this inner loop calls the equivalent of pump.try_run_messages())
pump.run_messages()
-- Processes any pending messages queued on the lua thread, or returns if the queue is empty.
-- This is the same as `pump.run_messages()` except doesn't block if the queue is empty.
-- Note, this may block anyway (e.g. pressing a button which has a holding function set)
pump.try_run_messages()-- Horizontally aligns this element relative to the parent. Can be "stretch", "left", "center" or "right"
set_align_h(align : string)
-- Vertically aligns this element relative to the parent. Can be "stretch", "top", "center" or "bottom"
set_align_v(align : string)All column/row parameters pass column first and row next, so that it behaves like X and Y coordinates
-- Note: Row and column indices are zero-based and cannot be negative
-- RowSpan and ColumnSpan must be >= 1
add(column : number, row : number, element : table)
add(column : number, row : number, columnSpan : number, rowSpan : number, element : table)-- Adds a row with the given format for the pixel height. E.g. "25", "3*", "Auto"
add_row(layout: string)
-- Adds a column with the given format for the pixel width. E.g. "25", "3*", "Auto"
add_column(layout: string)-- Adds an element docked to either "left", "top", "right" or "bottom"
add(dock : string, element : table)
-- Adds an element docked to the left. Ideally only use for the last child when lastChildFill is true
add(element : table)-- Adds an element
add(element : table)-- Sets the function that runs when the user clicks then releases their mouse on the button
set_press_function(callback : function)
-- Sets the function that is called in a loop while the user has left-click pressed.
-- The 'delta' parameter is the amount of time since the callback was last called, in seconds.
set_holding_function(callback : function(delta : number) -> boolean)
-- Sets the button's text
set_text(text : string)The holding function is provided the delta time between each callback invocation. On the first run, it will be very very small.
You should use this if you need to, for example, increase a float on the console at a fixed rate (e.g. 25.0 per second).
Example: engine.writenumber(addr, "float", 25.0 * delta)
In the demo script at the bottom of the page, the text increments by 3000 per second on a modern PC. This is because setting the text requires posting a message to the UI dispatcher to set the text, because the caller is the lua thread. If you only used lua code and no network operations, it would run as fast as the lua virtual machine can execute, which is significantly faster than 3000 times per second.
Warning
Do not create your own loop inside of this, because the outer loop will pump any queued messages automatically. If you need a loop, call pump.try_run_messages() often
-- Sets the text of the text block
set_text(text : string)This is a demo of UI layout
press_btn_counter = 0
holding_btn_counter = 0
function CreateTestDock(side)
-- create a dock panel that won't fill the last child control,
-- since we want a left and right dock
local dock = gui.create_dockpanel(false)
-- create a horizontal stack panel
local bottom_spL = gui.create_stackpanel(true)
bottom_spL.add(bottom_spL, gui.create_button(side .. " left btn 1"))
bottom_spL.add(bottom_spL, gui.create_button(side .. " left btn 2"))
bottom_spL.add(bottom_spL, gui.create_button(side .. " left btn 3"))
-- create a horizontal stack panel
local bottom_spR = gui.create_stackpanel(true)
bottom_spR.add(bottom_spR, gui.create_button(side .. " right btn 1"))
bottom_spR.add(bottom_spR, gui.create_button(side .. " right btn 2"))
bottom_spR.add(bottom_spR, gui.create_button(side .. " right btn 3"))
-- add panels to the dock
dock.add(dock, "left", bottom_spL)
dock.add(dock, "right", bottom_spR)
return dock
end
-- create our root panel, which will fill the last child (tmpstack)
-- to the window contents (inbetween the top and bottom docks ofc)
local root = gui.create_dockpanel(true)
root.add(root, "top", CreateTestDock("Top "))
root.add(root, "bottom", CreateTestDock("Bottom "))
-- create a vertical stack panel
local tmpstack = gui.create_stackpanel(true)
tmpstack.add(tmpstack, gui.create_text("Hello!"))
local tmpbutton1 = gui.create_button("Click to incr per press")
tmpbutton1.set_press_function(tmpbutton1, function ()
press_btn_counter = press_btn_counter + 1
tmpbutton1.set_text(tmpbutton1, press_btn_counter)
end)
tmpstack.add(tmpstack, tmpbutton1)
local tmpbutton2 = gui.create_button("Click to incr while holding")
tmpbutton2.set_holding_function(tmpbutton2, function (delta)
holding_btn_counter = holding_btn_counter + 1
tmpbutton2.set_text(tmpbutton2, holding_btn_counter)
end)
tmpstack.add(tmpstack, tmpbutton2)
root.add(root, tmpstack)
-- assign root panel to the GUI
gui.set_root_panel(root)
-- the important part. In order for button clicks to work,
-- pump.run_messages() must be called often
while true do
pump.run_messages()
end
Here is a small script to move the player around using 4 buttons:
local tb_x = gui.create_text("Pos X: ???");
local tb_y = gui.create_text("Pos Y: ???");
local grid = gui.create_gridpanel()
grid:add_row("40")
grid:add_row("40")
grid:add_row("40")
grid:add_column("40")
grid:add_column("40")
grid:add_column("40")
local btn_fwd = gui.create_button("+Y");
local btn_lft = gui.create_button("-X");
local btn_rht = gui.create_button("+X");
local btn_bck = gui.create_button("-Y");
btn_fwd:set_holding_function(function (delta)
local num = engine.readnumber(0x830CBFA0, "float") + (100 * delta)
engine.writenumber(0x830CBFA0, "float", num)
tb_y:set_text("Pos Y: " .. tostring(num))
end)
btn_lft:set_holding_function(function (delta)
local num = engine.readnumber(0x830CBF9C, "float") - (100 * delta)
engine.writenumber(0x830CBF9C, "float", num)
tb_x:set_text("Pos X: " .. tostring(num))
end)
btn_rht:set_holding_function(function (delta)
local num = engine.readnumber(0x830CBF9C, "float") + (100 * delta)
engine.writenumber(0x830CBF9C, "float", num)
tb_x:set_text("Pos X: " .. tostring(num))
end)
btn_bck:set_holding_function(function (delta)
local num = engine.readnumber(0x830CBFA0, "float") - (100 * delta)
engine.writenumber(0x830CBFA0, "float", num)
tb_y:set_text("Pos Y: " .. tostring(num))
end)
grid:add(1, 0, btn_fwd)
grid:add(0, 1, btn_lft)
grid:add(2, 1, btn_rht)
grid:add(1, 2, btn_bck)
local stack = gui.create_stackpanel(true)
stack:add(grid)
stack:add(tb_x)
stack:add(tb_y)
-- assign root panel to the GUI
gui.set_root_panel(stack)
-- the important part. In order for button clicks to work,
-- pump.run_messages() must be called often
while true do
pump.run_messages()
end
-
Home
- Connect to a console
- Scanning Options
- Scan results & Saved Address Table
- Remote Commands
- Memory Dump
- Tools
- Preferences/App Settings
-
API
- Making a custom connection
- Busy Tokens
- Models, ViewStates, MVP & Binding
- Plugins
- Config Pages
- Brushes and Icons
- Data Manager, Context Data and Data Keys
- Commands and Shortcuts
- Context Menus
- Windows and Dialogs