mirror of
https://github.com/jimathy/jim_bridge.git
synced 2026-08-16 21:46:03 +01:00
283 lines
9.5 KiB
Lua
283 lines
9.5 KiB
Lua
--[[
|
|
Instructional Buttons & Debug Text Module
|
|
-------------------------------------------
|
|
This module provides functions for:
|
|
• Displaying instructional buttons on-screen via a scaleform movie.
|
|
• Drawing debug text with a background rectangle when debugMode is enabled.
|
|
• Rendering 3D text in the world.
|
|
• Displaying help messages and spinners.
|
|
]]
|
|
|
|
-------------------------------------------------------------
|
|
-- Instructional Buttons Functionality
|
|
-------------------------------------------------------------
|
|
|
|
--- Loads and draws instructional buttons on-screen using a scaleform movie.
|
|
---
|
|
--- Requests the "instructional_buttons" scaleform, clears previous data, sets clear space,
|
|
--- creates data slots for each button option provided in `info`, and then draws the scaleform fullscreen.
|
|
---
|
|
--- @param info table An array of tables, where each table represents a button option:
|
|
--- - keys (table): An array of key codes (e.g., {38, 29}) to display.
|
|
--- - text (string): The label for the button.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
---CreateThread(function()
|
|
--- while true do
|
|
--- makeInstructionalButtons({
|
|
--- { keys = {38, 29}, text = "Open Menu" },
|
|
--- { keys = {45}, text = "Close Menu" }
|
|
--- })
|
|
--- Wait(0)
|
|
--- end
|
|
---end)
|
|
--- ```
|
|
function makeInstructionalButtons(info)
|
|
local build = RequestScaleformMovie("instructional_buttons")
|
|
while not HasScaleformMovieLoaded(build) do Wait(0) end
|
|
|
|
-- Draw the scaleform fullscreen (initial draw).
|
|
DrawScaleformMovieFullscreen(build, 255, 255, 255, 0, 0)
|
|
|
|
-- Clear previous instructions.
|
|
BeginScaleformMovieMethod(build, "CLEAR_ALL")
|
|
EndScaleformMovieMethod()
|
|
|
|
-- Set clear spacing between buttons.
|
|
BeginScaleformMovieMethod(build, "SET_CLEAR_SPACE")
|
|
ScaleformMovieMethodAddParamInt(200)
|
|
EndScaleformMovieMethod()
|
|
|
|
-- Add each button option to the scaleform.
|
|
for i = 1, #info do
|
|
BeginScaleformMovieMethod(build, "SET_DATA_SLOT")
|
|
ScaleformMovieMethodAddParamInt(i - 1)
|
|
for k = 1, #info[i].keys do
|
|
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(2, info[i].keys[k], true))
|
|
end
|
|
BeginTextCommandScaleformString("STRING")
|
|
AddTextComponentSubstringKeyboardDisplay(info[i].text)
|
|
EndTextCommandScaleformString()
|
|
EndScaleformMovieMethod()
|
|
end
|
|
|
|
-- Draw the instructional buttons.
|
|
BeginScaleformMovieMethod(build, "DRAW_INSTRUCTIONAL_BUTTONS")
|
|
EndScaleformMovieMethod()
|
|
|
|
-- Set a translucent black background.
|
|
BeginScaleformMovieMethod(build, "SET_BACKGROUND_COLOUR")
|
|
ScaleformMovieMethodAddParamInt(0)
|
|
ScaleformMovieMethodAddParamInt(0)
|
|
ScaleformMovieMethodAddParamInt(0)
|
|
ScaleformMovieMethodAddParamInt(80)
|
|
EndScaleformMovieMethod()
|
|
|
|
-- Final full-screen draw with full opacity.
|
|
DrawScaleformMovieFullscreen(build, 255, 255, 255, 255, 0)
|
|
end
|
|
|
|
-- EXPERIMENTAL --
|
|
-- RedM Button Prompts --
|
|
-- Creates the promot, then shows it, this needs to be run in a loop
|
|
local promptGroups = {}
|
|
|
|
function makeRedInstructionalButtons(info, title)
|
|
if not promptGroups[title] then -- Create group if not exists
|
|
promptGroups[title] = {
|
|
title = CreateVarString(10, 'LITERAL_STRING', title),
|
|
id = GetRandomIntInRange(0, 0xffffff),
|
|
prompts = {},
|
|
}
|
|
for i = 1, #info do
|
|
promptGroups[title].prompts[i] = {
|
|
keys = info[i].keys,
|
|
text = info[i].text,
|
|
}
|
|
local keyTitle = CreateVarString(10, 'LITERAL_STRING', info[i].text)
|
|
-- Create one prompt per entry
|
|
local promptSet = UiPromptRegisterBegin()
|
|
-- Register all keys for this prompt
|
|
for k = 1, #info[i].keys do
|
|
PromptSetControlAction(promptSet, info[i].keys[k])
|
|
end
|
|
PromptSetText(promptSet, keyTitle)
|
|
PromptSetEnabled(promptSet, true)
|
|
PromptSetVisible(promptSet, true)
|
|
PromptSetGroup(promptSet, promptGroups[title].id)
|
|
PromptRegisterEnd(promptSet)
|
|
end
|
|
end
|
|
PromptSetActiveGroupThisFrame(promptGroups[title].id, promptGroups[title].title)
|
|
end
|
|
|
|
onResourceStop(function()
|
|
for k, v in pairs(promptGroups) do
|
|
print("^5GTAUI^7: ^2Removing Prompt Group^7: ^3" .. k .. "^7")
|
|
PromptDelete(promptGroups[k].id, 1)
|
|
end
|
|
end, true)
|
|
|
|
-------------------------------------------------------------
|
|
-- Debug Text Display Functionality
|
|
-------------------------------------------------------------
|
|
|
|
--- Draws debug text on the screen if debugMode is enabled.
|
|
---
|
|
--- Calculates a background rectangle based on the number of text lines and renders each line on-screen.
|
|
---
|
|
--- @param textTable table An array of strings to display.
|
|
--- @param loc vector2 (Optional) Top-left coordinate for the text box (default: vec2(0.05, 0.65)).
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
---CreateThread(function()
|
|
--- while true do
|
|
--- debugScaleForm(
|
|
--- {
|
|
--- "Line 1: Debug info",
|
|
--- "Line 2: More info"
|
|
--- }
|
|
--- )
|
|
--- Wait(0)
|
|
--- end
|
|
---end)
|
|
--- ```
|
|
function debugScaleForm(textTable, loc)
|
|
if debugMode then
|
|
loc = loc or vec2(0.05, 0.65)
|
|
|
|
local lineHeight = 0.025 -- Height per line.
|
|
local totalHeight = #textTable * lineHeight
|
|
local boxPadding = 0.01 -- Padding around the text.
|
|
local size = vec2(0.18, totalHeight + boxPadding * 2)
|
|
|
|
-- Draw background rectangle.
|
|
DrawRect(loc.x + size.x / 2, loc.y + size.y / 2, size.x, size.y, 0, 0, 0, 255)
|
|
|
|
-- Render each line of text.
|
|
for i = 1, #textTable do
|
|
SetTextScale(0.30, 0.30)
|
|
BeginTextCommandDisplayText("STRING")
|
|
AddTextComponentSubstringKeyboardDisplay(textTable[i])
|
|
EndTextCommandDisplayText(loc.x + 0.005, loc.y + (i - 1) * lineHeight + 0.01)
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------
|
|
-- 3D Text Rendering
|
|
-------------------------------------------------------------
|
|
|
|
--- Draws 3D text at specified world coordinates.
|
|
---
|
|
--- Configures text properties, draws the text, and displays a background rectangle behind it.
|
|
---
|
|
--- @param coord table A vector3 with x, y, and z coordinates.
|
|
--- @param text string The text to display.
|
|
--- @param highlight boolean (Optional) If true, highlights parts of the text.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
--- CreateThread(function()
|
|
--- while true do
|
|
--- DrawText3D(vector3(100, 200, 300), "Hello World", true)
|
|
--- Wait(0)
|
|
--- end
|
|
--- end)
|
|
--- ```
|
|
function DrawText3D(coord, text, highlight)
|
|
SetTextScale(0.30, 0.30)
|
|
SetTextFont(0)
|
|
SetTextProportional(1)
|
|
SetTextColour(255, 255, 255, 215)
|
|
SetTextEntry("STRING")
|
|
SetTextCentre(true)
|
|
|
|
local totalLength = string.len(text)
|
|
local textMaxLength = 99 -- max 99
|
|
local text = totalLength > textMaxLength and text:sub(1, totalLength - (totalLength - textMaxLength)) or text
|
|
AddTextComponentString(highlight and text:gsub("%~w~", "~y~") or text)
|
|
SetDrawOrigin(coord.x, coord.y, coord.z, 0)
|
|
DrawText(0.0, 0.0)
|
|
local count, length = GetLineCountAndMaxLength(text)
|
|
|
|
local padding = 0.005
|
|
local heightFactor = (count / 43) + padding
|
|
local weightFactor = (length / 150) + padding
|
|
|
|
local height = (heightFactor / 2) - padding / 1
|
|
local width = (weightFactor / 2) - padding / 1
|
|
|
|
DrawRect(0.0, height, width, heightFactor, 0, 0, 0, 150)
|
|
ClearDrawOrigin()
|
|
end
|
|
|
|
--- Calculates the number of lines and the maximum line length from the given text.
|
|
---
|
|
--- @param text string The text to analyze.
|
|
--- @return number, number The line count and maximum line length.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
--- local count, maxLen = GetLineCountAndMaxLength("Hello World")
|
|
--- ```
|
|
function GetLineCountAndMaxLength(text)
|
|
local lineCount, maxLength = 0, 0
|
|
for line in text:gmatch("[^\n]+") do
|
|
lineCount += 1
|
|
local lineLength = string.len(line)
|
|
if lineLength > maxLength then
|
|
maxLength = lineLength
|
|
end
|
|
end
|
|
if lineCount == 0 then lineCount = 1 end
|
|
return lineCount, maxLength
|
|
end
|
|
|
|
-------------------------------------------------------------
|
|
-- Additional UI Helpers
|
|
-------------------------------------------------------------
|
|
|
|
--- Displays a help message on the screen.
|
|
---
|
|
--- @param text string The message to display.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
--- DisplayHelpMsg("Press E to interact")
|
|
--- ```
|
|
function DisplayHelpMsg(text)
|
|
BeginTextCommandDisplayHelp("STRING")
|
|
AddTextComponentScaleform(text)
|
|
EndTextCommandDisplayHelp(0, true, false, -1)
|
|
end
|
|
|
|
--- Displays a "Saving/Loading" spinner with a custom message.
|
|
---
|
|
--- @param text string The message to display alongside the spinner.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
--- displaySpinner("Saving data...")
|
|
--- ```
|
|
function displaySpinner(text)
|
|
BeginTextCommandBusyspinnerOn('STRING')
|
|
AddTextComponentSubstringPlayerName(text)
|
|
EndTextCommandBusyspinnerOn(4)
|
|
end
|
|
|
|
--- Stops the "Saving/Loading" spinner.
|
|
---
|
|
--- This function should only be called client-side.
|
|
---
|
|
--- @usage
|
|
--- ```lua
|
|
--- stopSpinner()
|
|
--- ```
|
|
function stopSpinner()
|
|
if not isServer() then
|
|
BusyspinnerOff()
|
|
end
|
|
end |