[Asking] Vanilla Pause Menu

Hello there,

I’m looking to customize my server!
I’ve lost my oldest backup that had THIS so I know this existed for a long time and searching since two completes hours using three differents methods including AI to FIND this but…welp.

CreateThread(function()
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'FE_THDR_GTAO', 'TITLE')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_MAP', 'MAP')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_GAM', 'GAME')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_PANE_LEAVE', 'DISCONNECT')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_PANE_QUIT', 'QUIT')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_INF', 'INFO')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_STA', 'STATS')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_SET', 'SETTINGS')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_GAL', 'GALERY')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_RPL', 'ROCKSTAR EDITOR')
    while true do
        BeginScaleformMovieMethodOnFrontendHeader('SET_HEADING_DETAILS')
        ScaleformMovieMethodAddParamTextureNameString('first line')
        ScaleformMovieMethodAddParamTextureNameString('second line')
        ScaleformMovieMethodAddParamTextureNameString('third line')
        ScaleformMovieMethodAddParamBool(false)
        EndScaleformMovieMethod()
        Citizen.Wait(0)
    end
end)

I KNOW there is a way to display a subtitle between Title and MAP or others tabs.
I am not willing to use NUI.
I do remember having one unique file for that thing over 3 differents servers. And then, nothing.
Can anyone help me please?

Thanks:

you need to call the frontend_header scaleform function
"SET_HEADER_TITLE" with params title, subtitle, shiftUpHeader

also this

    while true do
          BeginScaleformMovieMethodOnFrontendHeader('SET_HEADING_DETAILS')
          ScaleformMovieMethodAddParamTextureNameString('first line')
          ScaleformMovieMethodAddParamTextureNameString('second line')
          ScaleformMovieMethodAddParamTextureNameString('third line')
          ScaleformMovieMethodAddParamBool(false)
          EndScaleformMovieMethod()
        Citizen.Wait(0)
    end

you don’t need to call it every frame… you can simply call this everytime the game is paused checking the native
local bool = IsPauseMenuActive()

or for a more aggressive check: GetPauseMenuState() != 0

so you won’t need to call the scaleform function “on tick” but only once when the pause menu is opened or once every 1000ms if you want to make it looped.

CreateThread(function()
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'FE_THDR_GTAO', 'TITLE')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_MAP', 'MAP')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_GAM', 'GAME')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_PANE_LEAVE', 'DISCONNECT')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_PANE_QUIT', 'QUIT')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_INF', 'INFO')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_STA', 'STATS')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_SET', 'SETTINGS')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_GAL', 'GALERY')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_RPL', 'ROCKSTAR EDITOR')
   local timer = 500
    while true do
        Wait(timer)
        if IsPauseMenuActive() then
            BeginScaleformMovieMethodOnFrontendHeader('SET_HEADING_DETAILS')
            ScaleformMovieMethodAddParamTextureNameString('first line')
            ScaleformMovieMethodAddParamTextureNameString('second line')
            ScaleformMovieMethodAddParamTextureNameString('third line')
            ScaleformMovieMethodAddParamBool(false)
            EndScaleformMovieMethod()
            -- set the waiting timer to 1000 in pause menu
            if timer == 500 then timer = 1000 end
        end
        -- reset the timer to half second for outside pause menu for a bit more reactivity in checking.
        if timer == 1000 then timer = 500 end
    end
end)

if you want to make your own pause menus customizable and fully controllable :slight_smile: Check ScaleformUI it allows you to make your own Pause Menus and Lobbies.

Hello @manups4e, first of all thanks for your reply.

I obviously already tried to reduce the .Wait, however… It just flickers. Even at 15 or 10 ms. Or 5.
Its some details but yeah.
Preview:

I dare I knew a almost as short as possible snippet to just do this, even if called every frame. Optimized or not, thats not the guess especially if its 0.03ms loaded 0.02ms in background

I just don’t remind where is that cfx re thread :frowning:

You’re right the game updates the clock time every second resending the 3 lines :thinking:

1 Like

Hello,

Posting news, I did made various update to my pausemenu Script (see below)

Will find that subtitle one day, maybe I’m wrong and wasn’t one line. Will check tonight.

core/modules/pausemenu/client/main.lua
ESX = exports["es_extended"]:getSharedObject()

local name = GetPlayerName(PlayerId())
local id = GetPlayerServerId(PlayerId())
local money = 0

CreateThread(function()
    while not ESX.IsPlayerLoaded() do Wait(200) end

    local function refreshData()
        local data = ESX.GetPlayerData()
        local cash = data.money or 0
        local bank = 0

        name = (data.name and data.name ~= '' and data.name) or name
        
        for _, acc in ipairs(data.accounts or {}) do
            if acc.name == 'bank' then
                bank = acc.money or 0
                break
            end
        end

        money = cash + bank
    end

    RegisterNetEvent('esx:playerLoaded', refreshData)
    RegisterNetEvent('esx:setAccountMoney', refreshData)

    refreshData()
end)

local function formatMoney(n)
    n = tonumber(n) or 0
    local s = tostring(math.floor(n))
    local out, c = {}, 0

    for i = #s, 1, -1 do
        c = c + 1
        out[#out+1] = s:sub(i,i)
        if c % 3 == 0 and i > 1 then out[#out+1] = " " end
    end

    local r = table.concat(out):reverse()
    return r .. "$"
end


CreateThread(function()
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'FE_THDR_GTAO', '~o~Redacted~t~| ~o~redacted.tld ~t~| ~o~discord.gg/~d~Redacted')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_MAP', '~o~GPS')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_GAM', '~o~Partir')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_PANE_LEAVE', '~o~Disconnect')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_PANE_QUIT', '~r~Leave FiveM')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_INF', '~o~Informations')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_STA', '~o~Stats')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_SET', '~o~Settings')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_GAL', '~o~Gallery')
   Citizen.InvokeNative(GetHashKey("ADD_TEXT_ENTRY"),'PM_SCR_RPL', '~o~Rockstar Editor')
    while true do
        BeginScaleformMovieMethodOnFrontendHeader('SET_HEADING_DETAILS')
        ScaleformMovieMethodAddParamTextureNameString('~o~'..name)
        ScaleformMovieMethodAddParamTextureNameString('~t~ID '..id)
        ScaleformMovieMethodAddParamTextureNameString('~g~'..formatMoney(money))
        ScaleformMovieMethodAddParamBool(false)
        EndScaleformMovieMethod()
        Wait(6)
    end
end)

-- This is to implement RP opening GPS, idea from me and some code from @RowDog
-- https://forum.cfx.re/t/release-pause-menu-map-animation/177344
local wasMenuOpen = false
local startedTabletEmote = false

local function disarmOx(noAnim)
    TriggerEvent('ox_inventory:disarm', false)
end

local function startTablet()
    if startedTabletEmote then return end

    disarmOx(true)
    ExecuteCommand('e tablet2')
    ExecuteCommand('me open his tablet')
    startedTabletEmote = true
end

local function stopTablet()
    if not startedTabletEmote then return end
    ExecuteCommand('e c')
    startedTabletEmote = false
end

CreateThread(function()
    while true do
        Wait(0)

        if IsPauseMenuActive() and not wasMenuOpen then
            startTablet()
            wasMenuOpen = true
        end

        if not IsPauseMenuActive() and wasMenuOpen then
            Wait(2000)
            stopTablet()
            wasMenuOpen = false
        end
    end
end)