mirror of
https://github.com/weyne85/DML.git
synced 2025-10-29 16:57:49 +00:00
Version 1.1.4
sequencer messenger radioMenu
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
radioMenu = {}
|
||||
radioMenu.version = "1.1.0"
|
||||
radioMenu.version = "2.0.0"
|
||||
radioMenu.verbose = false
|
||||
radioMenu.ups = 1
|
||||
radioMenu.requiredLibs = {
|
||||
@@ -15,8 +15,18 @@ radioMenu.menus = {}
|
||||
1.1.0 removeMenu
|
||||
addMenu
|
||||
menuVisible
|
||||
2.0.0 redesign: handles multiple receivers
|
||||
optional MX module
|
||||
group option
|
||||
type option
|
||||
multiple group names
|
||||
multiple types
|
||||
gereric helo type
|
||||
generic plane type
|
||||
type works with coalition
|
||||
|
||||
--]]--
|
||||
|
||||
function radioMenu.addRadioMenu(theZone)
|
||||
table.insert(radioMenu.menus, theZone)
|
||||
end
|
||||
@@ -35,44 +45,192 @@ end
|
||||
--
|
||||
-- read zone
|
||||
--
|
||||
function radioMenu.installMenu(theZone)
|
||||
if theZone.coalition == 0 then
|
||||
theZone.rootMenu = missionCommands.addSubMenu(theZone.rootName, nil)
|
||||
function radioMenu.filterPlayerIDForType(theZone)
|
||||
-- note: we currently ignore coalition
|
||||
local theIDs = {}
|
||||
local allTypes = {}
|
||||
if dcsCommon.containsString(theZone.menuTypes, ",") then
|
||||
allTypes = dcsCommon.splitString(theZone.menuTypes, ",")
|
||||
else
|
||||
theZone.rootMenu = missionCommands.addSubMenuForCoalition(theZone.coalition, theZone.rootName, nil)
|
||||
table.insert(allTypes, theZone.menuTypes)
|
||||
end
|
||||
|
||||
local menuA = cfxZones.getStringFromZoneProperty(theZone, "itemA", "<no A submenu>")
|
||||
if theZone.coalition == 0 then
|
||||
theZone.menuA = missionCommands.addCommand(menuA, theZone.rootMenu, radioMenu.redirectMenuX, {theZone, "A"})
|
||||
-- now iterate all types, and include any player that matches
|
||||
-- note that a player may match twice, so we use a dict instead of an
|
||||
-- array. Since we later iterate ID by idx, that's not an issue
|
||||
|
||||
for idx, aType in pairs(allTypes) do
|
||||
local theType = dcsCommon.trim(aType)
|
||||
local lowerType = string.lower(theType)
|
||||
|
||||
for gName, gData in pairs(cfxMX.playerGroupByName) do
|
||||
-- get coalition of group
|
||||
local coa = cfxMX.groupCoalitionByName[gName]
|
||||
if (theZone.coalition == 0 or theZone.coalition == coa) then
|
||||
-- do special types first
|
||||
if dcsCommon.stringStartsWith(lowerType, "helo") or dcsCommon.stringStartsWith(lowerType, "heli") then
|
||||
-- we look for all helicoperts
|
||||
if cfxMX.groupTypeByName[gName] == "helicopter" then
|
||||
theIDs[gName] = gData.groupId
|
||||
if theZone.verbose or radioMenu.verbose then
|
||||
trigger.action.outText("+++menu: Player Group <" .. gName .. "> matches gen-type helicopter", 30)
|
||||
end
|
||||
end
|
||||
elseif lowerType == "plane" or lowerType == "planes" then
|
||||
-- we look for all planes
|
||||
if cfxMX.groupTypeByName[gName] == "plane" then
|
||||
theIDs[gName] = gData.groupId
|
||||
if theZone.verbose or radioMenu.verbose then
|
||||
trigger.action.outText("+++menu: Player Group <" .. gName .. "> matches gen-type plane", 30)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- we are looking for a particular type, e.g. A-10A
|
||||
-- since groups do not carry the type, but all player
|
||||
-- groups are of the same type, we access the first
|
||||
-- unit. Note that this may later break if ED implement
|
||||
-- player groups of mixed type
|
||||
if gData.units and gData.units[1] and gData.units[1].type == theType then
|
||||
theIDs[gName] = gData.groupId
|
||||
if theZone.verbose or radioMenu.verbose then
|
||||
trigger.action.outText("+++menu: Player Group <" .. gName .. "> matches type <" .. theType .. ">", 30)
|
||||
end
|
||||
else
|
||||
|
||||
end
|
||||
end
|
||||
else
|
||||
if theZone.verbose or radioMenu.verbose then
|
||||
trigger.action.outText("+++menu: type check failed coalition for <" .. gName .. ">", 30)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return theIDs
|
||||
end
|
||||
|
||||
function radioMenu.filterPlayerIDForGroup(theZone)
|
||||
-- create an iterable list of groups, separated by commas
|
||||
-- note that we could introduce wildcards for groups later
|
||||
local theIDs = {}
|
||||
local allGroups = {}
|
||||
if dcsCommon.containsString(theZone.menuGroup, ",") then
|
||||
allGroups = dcsCommon.splitString(theZone.menuGroup, ",")
|
||||
else
|
||||
theZone.menuA = missionCommands.addCommandForCoalition(theZone.coalition, menuA, theZone.rootMenu, radioMenu.redirectMenuX, {theZone, "A"})
|
||||
table.insert(allGroups, theZone.menuGroup)
|
||||
end
|
||||
|
||||
for idx, gName in pairs(allGroups) do
|
||||
gName = dcsCommon.trim(gName)
|
||||
local theGroup = cfxMX.playerGroupByName[gName]
|
||||
if theGroup then
|
||||
local gID = theGroup.groupId
|
||||
table.insert(theIDs, gID)
|
||||
if theZone.verbose or radioMenu.verbose then
|
||||
trigger.action.outText("+++menu: Player Group <" .. gName .. "> found: <" .. gID .. ">", 30)
|
||||
end
|
||||
else
|
||||
trigger.action.outText("+++menu: Player Group <" .. gName .. "> does not exist", 30)
|
||||
end
|
||||
end
|
||||
|
||||
return theIDs
|
||||
end
|
||||
|
||||
function radioMenu.installMenu(theZone)
|
||||
-- local theGroup = 0 -- was: nil
|
||||
local gID = nil
|
||||
if theZone.menuGroup then
|
||||
if not cfxMX then
|
||||
trigger.action.outText("WARNING: radioMenu's group attribute requires the 'cfxMX' module", 30)
|
||||
return
|
||||
end
|
||||
-- access cfxMX player info for group ID
|
||||
gID = radioMenu.filterPlayerIDForGroup(theZone)
|
||||
elseif theZone.menuTypes then
|
||||
if not cfxMX then
|
||||
trigger.action.outText("WARNING: radioMenu's type attribute requires the 'cfxMX' module", 30)
|
||||
return
|
||||
end
|
||||
-- access cxfMX player infor with type match for ID
|
||||
gID = radioMenu.filterPlayerIDForType(theZone)
|
||||
end
|
||||
|
||||
theZone.rootMenu = {}
|
||||
theZone.mcdA = {}
|
||||
theZone.mcdB = {}
|
||||
theZone.mcdC = {}
|
||||
theZone.mcdD = {}
|
||||
theZone.mcdA[0] = 0
|
||||
theZone.mcdB[0] = 0
|
||||
theZone.mcdC[0] = 0
|
||||
theZone.mcdD[0] = 0
|
||||
|
||||
if theZone.menuGroup or theZone.menuTypes then
|
||||
for idx, grp in pairs(gID) do
|
||||
local aRoot = missionCommands.addSubMenuForGroup(grp, theZone.rootName, nil)
|
||||
theZone.rootMenu[grp] = aRoot
|
||||
theZone.mcdA[grp] = 0
|
||||
theZone.mcdB[grp] = 0
|
||||
theZone.mcdC[grp] = 0
|
||||
theZone.mcdD[grp] = 0
|
||||
end
|
||||
elseif theZone.coalition == 0 then
|
||||
theZone.rootMenu[0] = missionCommands.addSubMenu(theZone.rootName, nil)
|
||||
else
|
||||
theZone.rootMenu[0] = missionCommands.addSubMenuForCoalition(theZone.coalition, theZone.rootName, nil)
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(theZone, "itemA") then
|
||||
local menuA = cfxZones.getStringFromZoneProperty(theZone, "itemA", "<no A submenu>")
|
||||
if theZone.menuGroup or theZone.menuTypes then
|
||||
theZone.menuA = {}
|
||||
for idx, grp in pairs(gID) do
|
||||
theZone.menuA[grp] = missionCommands.addCommandForGroup(grp, menuA, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "A", grp})
|
||||
end
|
||||
elseif theZone.coalition == 0 then
|
||||
theZone.menuA = missionCommands.addCommand(menuA, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "A"})
|
||||
else
|
||||
theZone.menuA = missionCommands.addCommandForCoalition(theZone.coalition, menuA, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "A"})
|
||||
end
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(theZone, "itemB") then
|
||||
local menuB = cfxZones.getStringFromZoneProperty(theZone, "itemB", "<no B submenu>")
|
||||
if theZone.coalition == 0 then
|
||||
theZone.menuB = missionCommands.addCommand(menuB, theZone.rootMenu, radioMenu.redirectMenuX, {theZone, "B"})
|
||||
if theZone.menuGroup or theZone.menuTypes then
|
||||
for idx, grp in pairs(gID) do
|
||||
theZone.menuB[grp] = missionCommands.addCommandForGroup(grp, menuB, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "B"})
|
||||
end
|
||||
elseif theZone.coalition == 0 then
|
||||
theZone.menuB = missionCommands.addCommand(menuB, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "B"})
|
||||
else
|
||||
theZone.menuB = missionCommands.addCommandForCoalition(theZone.coalition, menuB, theZone.rootMenu, radioMenu.redirectMenuX, {theZone, "B"})
|
||||
theZone.menuB = missionCommands.addCommandForCoalition(theZone.coalition, menuB, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "B"})
|
||||
end
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(theZone, "itemC") then
|
||||
local menuC = cfxZones.getStringFromZoneProperty(theZone, "itemC", "<no C submenu>")
|
||||
if theZone.coalition == 0 then
|
||||
theZone.menuC = missionCommands.addCommand(menuC, theZone.rootMenu, radioMenu.redirectMenuX, {theZone, "C"})
|
||||
if theZone.menuGroup or theZone.menuTypes then
|
||||
for idx, grp in pairs(gID) do
|
||||
theZone.menuC[grp] = missionCommands.addCommandForGroup(grp, menuC, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "C"})
|
||||
end
|
||||
elseif theZone.coalition == 0 then
|
||||
theZone.menuC = missionCommands.addCommand(menuC, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "C"})
|
||||
else
|
||||
theZone.menuC = missionCommands.addCommandForCoalition(theZone.coalition, menuC, theZone.rootMenu, radioMenu.redirectMenuX, {theZone, "C"})
|
||||
theZone.menuC = missionCommands.addCommandForCoalition(theZone.coalition, menuC, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "C"})
|
||||
end
|
||||
end
|
||||
|
||||
if cfxZones.hasProperty(theZone, "itemD") then
|
||||
local menuD = cfxZones.getStringFromZoneProperty(theZone, "itemD", "<no D submenu>")
|
||||
if theZone.coalition == 0 then
|
||||
theZone.menuD = missionCommands.addCommand(menuD, theZone.rootMenu, radioMenu.redirectMenuX, {theZone, "D"})
|
||||
if theZone.menuGroup or theZone.menuTypes then
|
||||
for idx, grp in pairs(gID) do
|
||||
theZone.menuD[grp] = missionCommands.addCommandForGroup(grp, menuD, theZone.rootMenu[grp], radioMenu.redirectMenuX, {theZone, "D"})
|
||||
end
|
||||
elseif theZone.coalition == 0 then
|
||||
theZone.menuD = missionCommands.addCommand(menuD, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "D"})
|
||||
else
|
||||
theZone.menuD = missionCommands.addCommandForCoalition(theZone.coalition, menuD, theZone.rootMenu, radioMenu.redirectMenuX, {theZone, "D"})
|
||||
theZone.menuD = missionCommands.addCommandForCoalition(theZone.coalition, menuD, theZone.rootMenu[0], radioMenu.redirectMenuX, {theZone, "D"})
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -81,6 +239,18 @@ function radioMenu.createRadioMenuWithZone(theZone)
|
||||
theZone.rootName = cfxZones.getStringFromZoneProperty(theZone, "radioMenu", "<No Name>")
|
||||
|
||||
theZone.coalition = cfxZones.getCoalitionFromZoneProperty(theZone, "coalition", 0)
|
||||
-- groups / types
|
||||
if cfxZones.hasProperty(theZone, "group") then
|
||||
theZone.menuGroup = cfxZones.getStringFromZoneProperty(theZone, "group", "<none>")
|
||||
theZone.menuGroup = dcsCommon.trim(theZone.menuGroup)
|
||||
elseif cfxZones.hasProperty(theZone, "groups") then
|
||||
theZone.menuGroup = cfxZones.getStringFromZoneProperty(theZone, "groups", "<none>")
|
||||
theZone.menuGroup = dcsCommon.trim(theZone.menuGroup)
|
||||
elseif cfxZones.hasProperty(theZone, "type") then
|
||||
theZone.menuTypes = cfxZones.getStringFromZoneProperty(theZone, "type", "none")
|
||||
elseif cfxZones.hasProperty(theZone, "types") then
|
||||
theZone.menuTypes = cfxZones.getStringFromZoneProperty(theZone, "types", "none")
|
||||
end
|
||||
|
||||
theZone.menuVisible = cfxZones.getBoolFromZoneProperty(theZone, "menuVisible", true)
|
||||
|
||||
@@ -99,22 +269,22 @@ function radioMenu.createRadioMenuWithZone(theZone)
|
||||
|
||||
theZone.itemAChosen = cfxZones.getStringFromZoneProperty(theZone, "A!", "*<none>")
|
||||
theZone.cooldownA = cfxZones.getNumberFromZoneProperty(theZone, "cooldownA", 0)
|
||||
theZone.mcdA = 0
|
||||
--theZone.mcdA = 0
|
||||
theZone.busyA = cfxZones.getStringFromZoneProperty(theZone, "busyA", "Please stand by (<s> seconds)")
|
||||
|
||||
theZone.itemBChosen = cfxZones.getStringFromZoneProperty(theZone, "B!", "*<none>")
|
||||
theZone.cooldownB = cfxZones.getNumberFromZoneProperty(theZone, "cooldownB", 0)
|
||||
theZone.mcdB = 0
|
||||
--theZone.mcdB = 0
|
||||
theZone.busyB = cfxZones.getStringFromZoneProperty(theZone, "busyB", "Please stand by (<s> seconds)")
|
||||
|
||||
theZone.itemCChosen = cfxZones.getStringFromZoneProperty(theZone, "C!", "*<none>")
|
||||
theZone.cooldownC = cfxZones.getNumberFromZoneProperty(theZone, "cooldownC", 0)
|
||||
theZone.mcdC = 0
|
||||
--theZone.mcdC = 0
|
||||
theZone.busyC = cfxZones.getStringFromZoneProperty(theZone, "busyC", "Please stand by (<s> seconds)")
|
||||
|
||||
theZone.itemDChosen = cfxZones.getStringFromZoneProperty(theZone, "D!", "*<none>")
|
||||
theZone.cooldownD = cfxZones.getNumberFromZoneProperty(theZone, "cooldownD", 0)
|
||||
theZone.mcdD = 0
|
||||
--theZone.mcdD = 0
|
||||
theZone.busyD = cfxZones.getStringFromZoneProperty(theZone, "busyD", "Please stand by (<s> seconds)")
|
||||
|
||||
if cfxZones.hasProperty(theZone, "removeMenu?") then
|
||||
@@ -160,24 +330,43 @@ function radioMenu.redirectMenuX(args)
|
||||
timer.scheduleFunction(radioMenu.doMenuX, args, timer.getTime() + 0.1)
|
||||
end
|
||||
|
||||
function radioMenu.cdByGID(cd, theZone, gID)
|
||||
if not gID then gID = 0 end
|
||||
--if not gID then return cd[0] end
|
||||
return cd[gID]
|
||||
end
|
||||
|
||||
function radioMenu.setCDByGID(cd, theZone, gID, newVal)
|
||||
if not gID then gID = 0 end
|
||||
--theZone[cd] = newVal
|
||||
--
|
||||
--end
|
||||
local allCD = theZone[cd]
|
||||
allCD[gID] = newVal
|
||||
theZone[cd] = allCD
|
||||
end
|
||||
|
||||
function radioMenu.doMenuX(args)
|
||||
theZone = args[1]
|
||||
theItemIndex = args[2] -- A, B , C .. ?
|
||||
local cd = theZone.mcdA
|
||||
theGroup = args[3] -- can be nil or groupID
|
||||
if not theGroup then theGroup = 0 end
|
||||
|
||||
local cd = radioMenu.cdByGID(theZone.mcdA, theZone, theGroup) --theZone.mcdA
|
||||
local busy = theZone.busyA
|
||||
local theFlag = theZone.itemAChosen
|
||||
|
||||
-- decode A..X
|
||||
if theItemIndex == "B"then
|
||||
cd = theZone.mcdB
|
||||
cd = radioMenu.cdByGID(theZone.mcdB, theZone, theGroup) -- theZone.mcdB
|
||||
busy = theZone.busyB
|
||||
theFlag = theZone.itemBChosen
|
||||
elseif theItemIndex == "C" then
|
||||
cd = theZone.mcdC
|
||||
cd = radioMenu.cdByGID(theZone.mcdC, theZone, theGroup) -- theZone.mcdC
|
||||
busy = theZone.busyC
|
||||
theFlag = theZone.itemCChosen
|
||||
elseif theItemIndex == "D" then
|
||||
cd = theZone.mcdD
|
||||
cd = radioMenu.cdByGID(theZone.mcdD, theZone, theGroup) -- theZone.mcdD
|
||||
busy = theZone.busyD
|
||||
theFlag = theZone.itemDChosen
|
||||
end
|
||||
@@ -193,13 +382,13 @@ function radioMenu.doMenuX(args)
|
||||
|
||||
-- set new cooldown -- needs own decoder A..X
|
||||
if theItemIndex == "A" then
|
||||
theZone.mcdA = now + theZone.cooldownA
|
||||
radioMenu.setCDByGID("mcdA", theZone, theGroup, now + theZone.cooldownA)
|
||||
elseif theItemIndex == "B" then
|
||||
theZone.mcdB = now + theZone.cooldownB
|
||||
radioMenu.setCDByGID("mcdB", theZone, theGroup, now + theZone.cooldownB)
|
||||
elseif theItemIndex == "C" then
|
||||
theZone.mcdC = now + theZone.cooldownC
|
||||
radioMenu.setCDByGID("mcdC", theZone, theGroup, now + theZone.cooldownC)
|
||||
else
|
||||
theZone.mcdD = now + theZone.cooldownD
|
||||
radioMenu.setCDByGID("mcdC", theZone, theGroup, now + theZone.cooldownC)
|
||||
end
|
||||
|
||||
cfxZones.pollFlag(theFlag, theZone.radioMethod, theZone)
|
||||
@@ -208,10 +397,10 @@ function radioMenu.doMenuX(args)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- Update -- required when we can enable/disable a zone's menu
|
||||
--
|
||||
|
||||
function radioMenu.update()
|
||||
-- call me in a second to poll triggers
|
||||
timer.scheduleFunction(radioMenu.update, {}, timer.getTime() + 1/radioMenu.ups)
|
||||
@@ -221,15 +410,15 @@ function radioMenu.update()
|
||||
if theZone.removeMenu
|
||||
and cfxZones.testZoneFlag(theZone, theZone.removeMenu, theZone.radioTriggerMethod, "lastRemoveMenu")
|
||||
and theZone.menuVisible
|
||||
then
|
||||
if theZone.verbose or radioMenu.verbose then
|
||||
trigger.action.outText("+++menu: removing <" .. dcsCommon.menu2text(theZone.rootMenu) .. "> for <" .. theZone.name .. ">", 30)
|
||||
end
|
||||
|
||||
if theZone.coalition == 0 then
|
||||
missionCommands.removeItem(theZone.rootMenu)
|
||||
then
|
||||
if theZone.menuGroup or theZone.menuTypes then
|
||||
for gID, aRoot in pairs(theZone.rootMenu) do
|
||||
missionCommands.removeItemForGroup(gID, aRoot)
|
||||
end
|
||||
elseif theZone.coalition == 0 then
|
||||
missionCommands.removeItem(theZone.rootMenu[0])
|
||||
else
|
||||
missionCommands.removeItemForCoalition(theZone.coalition, theZone.rootMenu)
|
||||
missionCommands.removeItemForCoalition(theZone.coalition, theZone.rootMenu[0])
|
||||
end
|
||||
|
||||
theZone.menuVisible = false
|
||||
@@ -304,5 +493,6 @@ if not radioMenu.start() then
|
||||
end
|
||||
|
||||
--[[--
|
||||
callbacks for the menus
|
||||
callbacks for the menus
|
||||
check CD/standby code for multiple groups
|
||||
--]]--
|
||||
Reference in New Issue
Block a user