I'm new to programming with Lua so please forgive me my stupidity. I'm trying to create a dynamic array using Lua for QBcore (FiveM), but I keep ending up with index (?) when I create the array.
This makes the menu within the game not working (I think..).
The code I have is:
local mdtMenu = nil
RegisterNetEvent('qb-radialmenu:client:onRadialmenuOpen', function()
if mdtMenu ~= nil then
exports['qb-radialmenu']:RemoveOption(mdtMenu)
mdtMenu = nil
end
local myData = QBCore.Functions.GetPlayerData()
local myJob = myData.job
local menuItems = createRadialJobExtrasMenu(myJob.onduty)
if myJob.name == "ems" or myJob.name == "police" then
mdtMenu = exports['qb-radialmenu']:AddOption({
menuItems
}, mdtMenu)
end
print(QBCore.Debug(mdtMenu))
--print(mdtMenu)
end)
The function used in above code:
function createRadialJobExtrasMenu(onduty)
local extra_menuItems = {}
local mdtMenu = {
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
open_mdt = {
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
my_data = {
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
mdt_signonoff = {},
}
}
if onduty then
mdt_signonoff = {
title = 'Sign Off (Duty)',
icon = "circle-xmark",
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
}
else
mdt_signonoff = {
title = 'Sign On (Duty)',
icon = "check-to-slot",
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
}
end
table.insert(mdtMenu.items.mdt_signonoff, mdt_signonoff)
return mdtMenu
end
The menu I expect when on-duty (note the third entry in items:
):
local mdtMenu = nil
RegisterNetEvent('qb-radialmenu:client:onRadialmenuOpen', function()
if mdtMenu ~= nil then
exports['qb-radialmenu']:RemoveOption(mdtMenu)
mdtMenu = nil
end
local myData = QBCore.Functions.GetPlayerData()
local myJob = myData.job
if myJob.name == "ems" or myJob.name == "police" then
mdtMenu = exports['qb-radialmenu']:AddOption({
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
{
id = 'open_mdt',
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
{
id = 'my_data',
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
{
id = 'mdt_signoff',
title = 'Sign Off (Duty)',
icon = "circle-xmark",
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
},
}
}, mdtMenu)
end
end)
And when off-duty (note the third entry in items:
):
local mdtMenu = nil
RegisterNetEvent('qb-radialmenu:client:onRadialmenuOpen', function()
if mdtMenu ~= nil then
exports['qb-radialmenu']:RemoveOption(mdtMenu)
mdtMenu = nil
end
local myData = QBCore.Functions.GetPlayerData()
local myJob = myData.job
if myJob.name == "ems" or myJob.name == "police" then
mdtMenu = exports['qb-radialmenu']:AddOption({
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
{
id = 'open_mdt',
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
{
id = 'my_data',
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
{
id = 'mdt_signon',
title = 'Sign On (Duty)',
icon = "check-to-slot",
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
},
}
}, mdtMenu)
end
end)
I hope my question makes any sence.
Edit: Changed the code as I assume that @Vlad means, but this still leaves me with 1 index (?) number.
Edit2: The only correct structure is like the code below:
local mdtMenu = nil
RegisterNetEvent('qb-radialmenu:client:onRadialmenuOpen', function()
if mdtMenu ~= nil then
exports['qb-radialmenu']:RemoveOption(mdtMenu)
mdtMenu = nil
end
local myData = QBCore.Functions.GetPlayerData()
local myJob = myData.job
if myJob.name == "ems" or myJob.name == "police" then
mdtMenu = exports['qb-radialmenu']:AddOption({
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
{
id = 'open_mdt',
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
{
id = 'my_data',
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
}
}, mdtMenu)
end
end)
But when I dynamically try to add a menu item with code below, I get an error.
if myJob.onduty then
table.insert(mdtMenu.items, {id = 'mdt_signoff', title = 'Sign Off (Duty)', icon = "circle-xmark", type = 'command', event = 'myaddons-toggleduty', shouldClose = true})
else
table.insert(mdtMenu.items, {id = 'mdt_signon', title = 'Sign On (Duty)', icon = "check-to-slot", type = 'command', event = 'myaddons-toggleduty', shouldClose = true})
end
The complete codeblock:
local mdtMenu = nil
RegisterNetEvent('qb-radialmenu:client:onRadialmenuOpen', function()
if mdtMenu ~= nil then
exports['qb-radialmenu']:RemoveOption(mdtMenu)
mdtMenu = nil
end
local myData = QBCore.Functions.GetPlayerData()
local myJob = myData.job
if myJob.name == "ems" or myJob.name == "police" then
mdtMenu = exports['qb-radialmenu']:AddOption({
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
{
id = 'open_mdt',
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
{
id = 'my_data',
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
}
}, mdtMenu)
end
if myJob.onduty then
table.insert(mdtMenu.items, {id = 'mdt_signoff', title = 'Sign Off (Duty)', icon = "circle-xmark", type = 'command', event = 'myaddons-toggleduty', shouldClose = true})
else
table.insert(mdtMenu.items, {id = 'mdt_signon', title = 'Sign On (Duty)', icon = "check-to-slot", type = 'command', event = 'myaddons-toggleduty', shouldClose = true})
end
end)
The error I'm getting:
It IS working with below code, but that means that I have to re-create the complete menu for each dynamic menu item, making the menu not-so-dynamic:
local mdtMenu = nil
RegisterNetEvent('qb-radialmenu:client:onRadialmenuOpen', function()
if mdtMenu ~= nil then
exports['qb-radialmenu']:RemoveOption(mdtMenu)
mdtMenu = nil
end
local myData = QBCore.Functions.GetPlayerData()
local myJob = myData.job
if myJob.name == "ems" or myJob.name == "police" then
if myJob.onduty then
mdtMenu = exports['qb-radialmenu']:AddOption({
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
{
id = 'open_mdt',
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
{
id = 'my_data',
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
{
id = 'mdt_signoff',
title = 'Sign Off (Duty)',
icon = "circle-xmark",
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
},
}
}, mdtMenu)
else
mdtMenu = exports['qb-radialmenu']:AddOption({
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
{
id = 'open_mdt',
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
{
id = 'my_data',
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
{
id = 'mdt_signon',
title = 'Sign On (Duty)',
icon = "check-to-slot",
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
},
}
}, mdtMenu)
end
end
end)
Edit3: Below code seems to be working (thanks @dt192!!):
local mdtMenu = nil
RegisterNetEvent('qb-radialmenu:client:onRadialmenuOpen', function()
if mdtMenu ~= nil then
exports['qb-radialmenu']:RemoveOption(mdtMenu)
mdtMenu = nil
end
local myData = QBCore.Functions.GetPlayerData()
local myJob = myData.job
if myJob.name == "ems" or myJob.name == "police" then
local myTable = createRadialJobExtrasMenu(myJob.onduty)
mdtMenu = exports['qb-radialmenu']:AddOption(myTable, mdtMenu)
end
end)
AddEventHandler('onResourceStop', function(resource)
if mdtMenu ~= nil then
exports['qb-radialmenu']:RemoveOption(mdtMenu)
mdtMenu = nil
end
end)
With the function:
function createRadialJobExtrasMenu(onduty)
local tbl = {
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
{
id = 'open_mdt',
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
{
id = 'my_data',
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
{
id = 'mdt_signon',
title = 'Sign On (Duty)',
icon = "check-to-slot",
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
},
}
}
if onduty then
tbl.items[3].id = 'mdt_signoff'
tbl.items[3].title = 'Sign Off (Duty)'
tbl.items[3].icon = 'circle-xmark'
end
return tbl
end
You could probably do something like this
local tbl = {
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
{
id = 'open_mdt',
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
{
id = 'my_data',
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
{
id = 'mdt_signon',
title = 'Sign On (Duty)',
icon = "check-to-slot",
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
},
}
}
if myJob.onduty then
tbl.items[3].id = 'mdt_signoff'
tbl.items[3].title = 'Sign Off (Duty)'
tbl.items[3].icon = 'circle-xmark'
end
mdtMenu = exports['qb-radialmenu']:AddOption(tbl, mdtMenu)
You could also just inline the checks like
mdtMenu = exports['qb-radialmenu']:AddOption({
id = 'job_extras',
title = 'Job Extras',
icon = "square-plus",
items = {
{
id = 'open_mdt',
title = 'Open MDT menu',
icon = "tablet-screen-button",
type = 'command',
event = "mdt",
shouldClose = true
},
{
id = 'my_data',
title = 'My Data',
icon = "person",
type = 'command',
event = "myaddons-myinfo",
shouldClose = true
},
{
id = myJob.onduty and 'mdt_signoff' or 'mdt_signon',
title = myJob.onduty and 'Sign Off (Duty)' or 'Sign On (Duty)',
icon = myJob.onduty and 'circle-xmark' or 'check-to-slot',
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
},
}
}, mdtMenu)
or (not sure which version you are using at this point)
mdtMenu.item.mdt_signonoff = {
title = myJob.onduty and 'Sign Off (Duty)' or 'Sign On (Duty)',
icon = myJob.onduty and 'circle-xmark' or 'check-to-slot',
type = 'command',
event = 'myaddons-toggleduty',
shouldClose = true
}