Under “Admin/Help,” the “Player Guides” (group-level) and “Player Help” (coalition-level) submenus now appear at the top of the Admin/Help root, before status, map drawings, and debug entries.

This commit is contained in:
iTracerFacer 2025-11-05 21:05:05 -06:00
parent 54ce683c05
commit 61ad4eddcb

View File

@ -1277,6 +1277,157 @@ function CTLD:BuildGroupMenus(group)
local navRoot = MENU_GROUP:New(group, 'Navigation', root)
local adminRoot = MENU_GROUP:New(group, 'Admin/Help', root)
-- Admin/Help -> Player Guides (moved to top of Admin/Help)
local help = MENU_GROUP:New(group, 'Player Guides', adminRoot)
MENU_GROUP_COMMAND:New(group, 'CTLD Basics (2-minute tour)', help, function()
local lines = {}
table.insert(lines, 'CTLD Basics - 2 minute tour')
table.insert(lines, '')
table.insert(lines, 'Loop: Request -> Deliver -> Build -> Fight')
table.insert(lines, '- Request crates at an ACTIVE Supply Zone (Pickup).')
table.insert(lines, '- Deliver crates to the build point (within Build Radius).')
table.insert(lines, '- Build units or sites with "Build Here" (confirm + cooldown).')
table.insert(lines, '- Optional: set Attack or Defend behavior when building.')
table.insert(lines, '')
table.insert(lines, 'Key concepts:')
table.insert(lines, '- Zones: Pickup (supply), Drop (mission targets), FOB (forward supply).')
table.insert(lines, '- Inventory: stock is tracked per zone; requests consume stock there.')
table.insert(lines, '- FOBs: building one creates a local supply point with seeded stock.')
table.insert(lines, '- Advanced: SAM site repair crates, AI attack orders, EWR/JTAC support.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Zones - Guide', help, function()
local lines = {}
table.insert(lines, 'CTLD Zones - Guide')
table.insert(lines, '')
table.insert(lines, 'Zone types:')
table.insert(lines, '- Pickup (Supply): Request crates and load troops here. Crate requests require proximity to an ACTIVE pickup zone (default within 10 km).')
table.insert(lines, '- Drop: Mission-defined delivery or rally areas. Some missions may require delivery or deployment at these zones (see briefing).')
table.insert(lines, '- FOB: Forward Operating Base areas. Some recipes (FOB Site) can be built here; if FOB restriction is enabled, FOB-only builds must be inside an FOB zone.')
table.insert(lines, '')
table.insert(lines, 'Colors and map marks:')
table.insert(lines, '- Pickup zone crate spawns are marked with smoke in the configured color. Admin/Help -> Draw CTLD Zones on Map draws zone circles and labels on F10.')
table.insert(lines, '- Use Admin/Help -> Clear CTLD Map Drawings to remove the drawings. Drawings are read-only if configured.')
table.insert(lines, '')
table.insert(lines, 'How to use zones:')
table.insert(lines, '- To request crates: move within the pickup zone distance and use CTLD -> Request Crate.')
table.insert(lines, '- To load troops: must be inside a Pickup zone if troop loading restriction is enabled.')
table.insert(lines, '- Navigation: CTLD -> Coach & Nav -> Vectors to Nearest Pickup Zone gives bearing and range.')
table.insert(lines, '- Activation: Zones can be active/inactive per mission logic; inactive pickup zones block crate requests.')
table.insert(lines, '')
table.insert(lines, string.format('Build Radius: about %d m to collect nearby crates when building.', self.Config.BuildRadius or 60))
table.insert(lines, string.format('Pickup Zone Max Distance: about %d m to request crates.', self.Config.PickupZoneMaxDistance or 10000))
MESSAGE:New(table.concat(lines, '\n'), 40):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Inventory - How It Works', help, function()
local inv = self.Config.Inventory or {}
local enabled = inv.Enabled ~= false
local showHint = inv.ShowStockInMenu == true
local fobPct = math.floor(((inv.FOBStockFactor or 0.25) * 100) + 0.5)
local lines = {}
table.insert(lines, 'CTLD Inventory - How It Works')
table.insert(lines, '')
table.insert(lines, 'Overview:')
table.insert(lines, '- Inventory is tracked per Supply (Pickup) Zone and per FOB. Requests consume stock at that location.')
table.insert(lines, string.format('- Inventory is %s.', enabled and 'ENABLED' or 'DISABLED'))
table.insert(lines, '')
table.insert(lines, 'Starting stock:')
table.insert(lines, '- Each configured Supply Zone is seeded from the catalog initialStock for every crate type at mission start.')
table.insert(lines, string.format('- When you build a FOB, it creates a small Supply Zone with stock seeded at ~%d%% of initialStock.', fobPct))
table.insert(lines, '')
table.insert(lines, 'Requesting crates:')
table.insert(lines, '- You must be within range of an ACTIVE Supply Zone to request crates; stock is decremented on spawn.')
table.insert(lines, '- If out of stock for a type at that zone, requests are denied for that type until resupplied (mission logic).')
table.insert(lines, '')
table.insert(lines, 'UI hints:')
table.insert(lines, string.format('- Show stock in menu labels: %s.', showHint and 'ON' or 'OFF'))
table.insert(lines, '- Some missions may include an "In Stock Here" list showing only items available at the nearest zone.')
MESSAGE:New(table.concat(lines, '\n'), 40):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Troop Transport & JTAC Use', help, function()
local lines = {}
table.insert(lines, 'Troop Transport & JTAC Use')
table.insert(lines, '')
table.insert(lines, 'Troops:')
table.insert(lines, '- Load inside an ACTIVE Supply Zone (if mission enforces it).')
table.insert(lines, '- Deploy with Defend (hold) or Attack (advance to targets/bases).')
table.insert(lines, '- Attack uses a search radius and moves at configured speed.')
table.insert(lines, '')
table.insert(lines, 'JTAC:')
table.insert(lines, '- Build JTAC units (MRAP/Tigr or drones) to support target marking.')
table.insert(lines, '- JTAC helps with target designation/SA; details depend on mission setup.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Crates 101: Requesting and Handling', help, function()
local lines = {}
table.insert(lines, 'Crates 101 - Requesting and Handling')
table.insert(lines, '')
table.insert(lines, '- Request crates near an ACTIVE Supply Zone; max distance is configurable.')
table.insert(lines, '- Menu labels show the total crates required for a recipe.')
table.insert(lines, '- Drop crates close together but avoid overlap; smoke marks spawns.')
table.insert(lines, '- Use Coach & Nav tools: vectors to nearest pickup zone, re-mark crate with smoke.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Hover Pickup & Slingloading', help, function()
local hp = self.Config.HoverPickup or {}
local height = hp.Height or 5
local spd = hp.MaxSpeedMPS or 5
local dur = hp.Duration or 3
local lines = {}
table.insert(lines, 'Hover Pickup & Slingloading')
table.insert(lines, '')
table.insert(lines, string.format('- Hover pickup: hold AGL ~%d m, speed < %d m/s, for ~%d s to auto-load.', height, spd, dur))
table.insert(lines, '- Keep steady within ~15 m of the crate; Hover Coach gives cues if enabled.')
table.insert(lines, '- Slingloading tips: avoid rotor wash over stacks; approach from upwind; re-mark crate with smoke if needed.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Build System: Build Here and Advanced', help, function()
local br = self.Config.BuildRadius or 60
local win = self.Config.BuildConfirmWindowSeconds or 10
local cd = self.Config.BuildCooldownSeconds or 60
local lines = {}
table.insert(lines, 'Build System - Build Here and Advanced')
table.insert(lines, '')
table.insert(lines, string.format('- Build Here collects crates within ~%d m. Double-press within %d s to confirm.', br, win))
table.insert(lines, string.format('- Cooldown: about %d s per group after a successful build.', cd))
table.insert(lines, '- Advanced Build lets you choose Defend (hold) or Attack (move).')
table.insert(lines, '- Static or unsuitable units will hold even if Attack is chosen.')
table.insert(lines, '- FOB-only recipes must be inside an FOB zone when restriction is enabled.')
MESSAGE:New(table.concat(lines, '\n'), 40):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'FOBs: Forward Supply & Why They Matter', help, function()
local fobPct = math.floor(((self.Config.Inventory and self.Config.Inventory.FOBStockFactor or 0.25) * 100) + 0.5)
local lines = {}
table.insert(lines, 'FOBs - Forward Supply and Why They Matter')
table.insert(lines, '')
table.insert(lines, '- Build a FOB by assembling its crate recipe (see Recipe Info).')
table.insert(lines, string.format('- A new local Supply Zone is created and seeded at ~%d%% of initial stock.', fobPct))
table.insert(lines, '- FOBs shorten logistics legs and increase throughput toward the front.')
table.insert(lines, '- If enabled, FOB-only builds must occur inside FOB zones.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'SAM Sites: Building, Repairing, and Augmenting', help, function()
local br = self.Config.BuildRadius or 60
local lines = {}
table.insert(lines, 'SAM Sites - Building, Repairing, and Augmenting')
table.insert(lines, '')
table.insert(lines, 'Build:')
table.insert(lines, '- Assemble site recipes using the required component crates (see menu labels). Build Here will place the full site.')
table.insert(lines, '')
table.insert(lines, 'Repair/Augment (merged):')
table.insert(lines, '- Request the matching "Repair/Launcher +1" crate for your site type (HAWK, Patriot, KUB, BUK).')
table.insert(lines, string.format('- Drop repair crate(s) within ~%d m of the site, then use Build Here (confirm window applies).', br))
table.insert(lines, '- The nearest matching site (within a local search) is respawned fully repaired; +1 launcher per crate, up to caps.')
table.insert(lines, '- Caps: HAWK 6, Patriot 6, KUB 3, BUK 6. Extra crates beyond the cap are not consumed.')
table.insert(lines, '- Must match coalition and site type; otherwise no changes are applied.')
table.insert(lines, '- Respawn is required to apply repairs/augmentation due to DCS limitations.')
table.insert(lines, '')
table.insert(lines, 'Placement tips:')
table.insert(lines, '- Space launchers to avoid masking; keep radars with good line-of-sight; avoid fratricide arcs.')
MESSAGE:New(table.concat(lines, '\n'), 45):ToGroup(group)
end)
-- Operations -> Troop Transport
local troopsRoot = MENU_GROUP:New(group, 'Troop Transport', opsRoot)
CMD('Load Troops', troopsRoot, function() self:LoadTroops(group) end)
@ -1583,155 +1734,7 @@ function CTLD:BuildGroupMenus(group)
MESSAGE:New('CTLD Debug logging DISABLED', 8):ToGroup(group)
end)
-- Admin/Help -> Player Guides (all the guides)
local help = MENU_GROUP:New(group, 'Player Guides', adminRoot)
MENU_GROUP_COMMAND:New(group, 'Zones - Guide', help, function()
local lines = {}
table.insert(lines, 'CTLD Zones - Guide')
table.insert(lines, '')
table.insert(lines, 'Zone types:')
table.insert(lines, '- Pickup (Supply): Request crates and load troops here. Crate requests require proximity to an ACTIVE pickup zone (default within 10 km).')
table.insert(lines, '- Drop: Mission-defined delivery or rally areas. Some missions may require delivery or deployment at these zones (see briefing).')
table.insert(lines, '- FOB: Forward Operating Base areas. Some recipes (FOB Site) can be built here; if FOB restriction is enabled, FOB-only builds must be inside an FOB zone.')
table.insert(lines, '')
table.insert(lines, 'Colors and map marks:')
table.insert(lines, '- Pickup zone crate spawns are marked with smoke in the configured color. Admin/Help -> Draw CTLD Zones on Map draws zone circles and labels on F10.')
table.insert(lines, '- Use Admin/Help -> Clear CTLD Map Drawings to remove the drawings. Drawings are read-only if configured.')
table.insert(lines, '')
table.insert(lines, 'How to use zones:')
table.insert(lines, '- To request crates: move within the pickup zone distance and use CTLD -> Request Crate.')
table.insert(lines, '- To load troops: must be inside a Pickup zone if troop loading restriction is enabled.')
table.insert(lines, '- Navigation: CTLD -> Coach & Nav -> Vectors to Nearest Pickup Zone gives bearing and range.')
table.insert(lines, '- Activation: Zones can be active/inactive per mission logic; inactive pickup zones block crate requests.')
table.insert(lines, '')
table.insert(lines, string.format('Build Radius: about %d m to collect nearby crates when building.', self.Config.BuildRadius or 60))
table.insert(lines, string.format('Pickup Zone Max Distance: about %d m to request crates (configurable).', self.Config.PickupZoneMaxDistance or 10000))
MESSAGE:New(table.concat(lines, '\n'), 40):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Inventory - How It Works', help, function()
local inv = self.Config.Inventory or {}
local enabled = inv.Enabled ~= false
local showHint = inv.ShowStockInMenu == true
local fobPct = math.floor(((inv.FOBStockFactor or 0.25) * 100) + 0.5)
local lines = {}
table.insert(lines, 'CTLD Inventory - How It Works')
table.insert(lines, '')
table.insert(lines, 'Overview:')
table.insert(lines, '- Inventory is tracked per Supply (Pickup) Zone and per FOB. Requests consume stock at that location.')
table.insert(lines, string.format('- Inventory is %s.', enabled and 'ENABLED' or 'DISABLED'))
table.insert(lines, '')
table.insert(lines, 'Starting stock:')
table.insert(lines, '- Each configured Supply Zone is seeded from the catalog initialStock for every crate type at mission start.')
table.insert(lines, string.format('- When you build a FOB, it creates a small Supply Zone with stock seeded at ~%d%% of initialStock.', fobPct))
table.insert(lines, '')
table.insert(lines, 'Requesting crates:')
table.insert(lines, '- You must be within range of an ACTIVE Supply Zone to request crates; stock is decremented on spawn.')
table.insert(lines, '- If out of stock for a type at that zone, requests are denied for that type until resupplied (mission logic).')
table.insert(lines, '')
table.insert(lines, 'UI hints:')
table.insert(lines, string.format('- Show stock in menu labels: %s.', showHint and 'ON' or 'OFF'))
table.insert(lines, '- Some missions may include an "In Stock Here" list showing only items available at the nearest zone.')
MESSAGE:New(table.concat(lines, '\n'), 40):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'CTLD Basics (2-minute tour)', help, function()
local lines = {}
table.insert(lines, 'CTLD Basics - 2 minute tour')
table.insert(lines, '')
table.insert(lines, 'Loop: Request -> Deliver -> Build -> Fight')
table.insert(lines, '- Request crates at an ACTIVE Supply Zone (Pickup).')
table.insert(lines, '- Deliver crates to the build point (within Build Radius).')
table.insert(lines, '- Build units or sites with "Build Here" (confirm + cooldown).')
table.insert(lines, '- Optional: set Attack or Defend behavior when building.')
table.insert(lines, '')
table.insert(lines, 'Key concepts:')
table.insert(lines, '- Zones: Pickup (supply), Drop (mission targets), FOB (forward supply).')
table.insert(lines, '- Inventory: stock is tracked per zone; requests consume stock there.')
table.insert(lines, '- FOBs: building one creates a local supply point with seeded stock.')
table.insert(lines, '- Advanced: SAM site repair crates, AI attack orders, EWR/JTAC support.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Troop Transport & JTAC Use', help, function()
local lines = {}
table.insert(lines, 'Troop Transport & JTAC Use')
table.insert(lines, '')
table.insert(lines, 'Troops:')
table.insert(lines, '- Load inside an ACTIVE Supply Zone (if mission enforces it).')
table.insert(lines, '- Deploy with Defend (hold) or Attack (advance to targets/bases).')
table.insert(lines, '- Attack uses a search radius and moves at configured speed.')
table.insert(lines, '')
table.insert(lines, 'JTAC:')
table.insert(lines, '- Build JTAC units (MRAP/Tigr or drones) to support target marking.')
table.insert(lines, '- JTAC helps with target designation/SA; details depend on mission setup.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Crates 101: Requesting and Handling', help, function()
local lines = {}
table.insert(lines, 'Crates 101 - Requesting and Handling')
table.insert(lines, '')
table.insert(lines, '- Request crates near an ACTIVE Supply Zone; max distance is configurable.')
table.insert(lines, '- Menu labels show the total crates required for a recipe.')
table.insert(lines, '- Drop crates close together but avoid overlap; smoke marks spawns.')
table.insert(lines, '- Use Coach & Nav tools: vectors to nearest pickup zone, re-mark crate with smoke.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Hover Pickup & Slingloading', help, function()
local hp = self.Config.HoverPickup or {}
local height = hp.Height or 5
local spd = hp.MaxSpeedMPS or 5
local dur = hp.Duration or 3
local lines = {}
table.insert(lines, 'Hover Pickup & Slingloading')
table.insert(lines, '')
table.insert(lines, string.format('- Hover pickup: hold AGL ~%d m, speed < %d m/s, for ~%d s to auto-load.', height, spd, dur))
table.insert(lines, '- Keep steady within ~15 m of the crate; Hover Coach gives cues if enabled.')
table.insert(lines, '- Slingloading tips: avoid rotor wash over stacks; approach from upwind; re-mark crate with smoke if needed.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'Build System: Build Here and Advanced', help, function()
local br = self.Config.BuildRadius or 60
local win = self.Config.BuildConfirmWindowSeconds or 10
local cd = self.Config.BuildCooldownSeconds or 60
local lines = {}
table.insert(lines, 'Build System - Build Here and Advanced')
table.insert(lines, '')
table.insert(lines, string.format('- Build Here collects crates within ~%d m. Double-press within %d s to confirm.', br, win))
table.insert(lines, string.format('- Cooldown: about %d s per group after a successful build.', cd))
table.insert(lines, '- Advanced Build lets you choose Defend (hold) or Attack (move).')
table.insert(lines, '- Static or unsuitable units will hold even if Attack is chosen.')
table.insert(lines, '- FOB-only recipes must be inside an FOB zone when restriction is enabled.')
MESSAGE:New(table.concat(lines, '\n'), 40):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'FOBs: Forward Supply & Why They Matter', help, function()
local fobPct = math.floor(((self.Config.Inventory and self.Config.Inventory.FOBStockFactor or 0.25) * 100) + 0.5)
local lines = {}
table.insert(lines, 'FOBs - Forward Supply and Why They Matter')
table.insert(lines, '')
table.insert(lines, '- Build a FOB by assembling its crate recipe (see Recipe Info).')
table.insert(lines, string.format('- A new local Supply Zone is created and seeded at ~%d%% of initial stock.', fobPct))
table.insert(lines, '- FOBs shorten logistics legs and increase throughput toward the front.')
table.insert(lines, '- If enabled, FOB-only builds must occur inside FOB zones.')
MESSAGE:New(table.concat(lines, '\n'), 35):ToGroup(group)
end)
MENU_GROUP_COMMAND:New(group, 'SAM Sites: Building, Repairing, and Augmenting', help, function()
local br = self.Config.BuildRadius or 60
local lines = {}
table.insert(lines, 'SAM Sites - Building, Repairing, and Augmenting')
table.insert(lines, '')
table.insert(lines, 'Build:')
table.insert(lines, '- Assemble site recipes using the required component crates (see menu labels). Build Here will place the full site.')
table.insert(lines, '')
table.insert(lines, 'Repair/Augment (merged):')
table.insert(lines, '- Request the matching "Repair/Launcher +1" crate for your site type (HAWK, Patriot, KUB, BUK).')
table.insert(lines, string.format('- Drop repair crate(s) within ~%d m of the site, then use Build Here (confirm window applies).', br))
table.insert(lines, '- The nearest matching site (within a local search) is respawned fully repaired; +1 launcher per crate, up to caps.')
table.insert(lines, '- Caps: HAWK 6, Patriot 6, KUB 3, BUK 6. Extra crates beyond the cap are not consumed.')
table.insert(lines, '- Must match coalition and site type; otherwise no changes are applied.')
table.insert(lines, '- Respawn is required to apply repairs/augmentation due to DCS limitations.')
table.insert(lines, '')
table.insert(lines, 'Placement tips:')
table.insert(lines, '- Space launchers to avoid masking; keep radars with good line-of-sight; avoid fratricide arcs.')
MESSAGE:New(table.concat(lines, '\n'), 45):ToGroup(group)
end)
-- Admin/Help -> Player Guides (moved earlier)
return root
end
@ -2252,37 +2255,7 @@ function CTLD:InitCoalitionAdminMenu()
local rootCaption = (self.Config and self.Config.UseGroupMenus) and 'CTLD Admin' or 'CTLD'
self.MenuRoot = self.MenuRoot or MENU_COALITION:New(self.Side, rootCaption)
local root = MENU_COALITION:New(self.Side, 'Admin/Help', self.MenuRoot)
MENU_COALITION_COMMAND:New(self.Side, 'Enable CTLD Debug Logging', root, function()
self.Config.Debug = true
env.info(string.format('[Moose_CTLD][%s] Debug ENABLED via Admin menu', tostring(self.Side)))
_msgCoalition(self.Side, 'CTLD Debug logging ENABLED', 8)
end)
MENU_COALITION_COMMAND:New(self.Side, 'Disable CTLD Debug Logging', root, function()
self.Config.Debug = false
env.info(string.format('[Moose_CTLD][%s] Debug DISABLED via Admin menu', tostring(self.Side)))
_msgCoalition(self.Side, 'CTLD Debug logging DISABLED', 8)
end)
MENU_COALITION_COMMAND:New(self.Side, 'Show CTLD Status (crates/zones)', root, function()
local crates = 0
for _ in pairs(CTLD._crates) do crates = crates + 1 end
local msg = string.format('CTLD Status:\nActive crates: %d\nPickup zones: %d\nDrop zones: %d\nFOB zones: %d\nBuild Confirm: %s (%ds window)\nBuild Cooldown: %s (%ds)'
, crates, #(self.PickupZones or {}), #(self.DropZones or {}), #(self.FOBZones or {})
, self.Config.BuildConfirmEnabled and 'ON' or 'OFF', self.Config.BuildConfirmWindowSeconds or 0
, self.Config.BuildCooldownEnabled and 'ON' or 'OFF', self.Config.BuildCooldownSeconds or 0)
_msgCoalition(self.Side, msg, 20)
end)
MENU_COALITION_COMMAND:New(self.Side, 'Show Coalition Summary', root, function()
self:ShowCoalitionSummary()
end)
MENU_COALITION_COMMAND:New(self.Side, 'Draw CTLD Zones on Map', root, function()
self:DrawZonesOnMap()
_msgCoalition(self.Side, 'CTLD zones drawn on F10 map.', 8)
end)
MENU_COALITION_COMMAND:New(self.Side, 'Clear CTLD Map Drawings', root, function()
self:ClearMapDrawings()
_msgCoalition(self.Side, 'CTLD map drawings cleared.', 8)
end)
-- Player Help submenu
-- Player Help submenu (moved to top of Admin/Help)
local helpMenu = MENU_COALITION:New(self.Side, 'Player Help', root)
-- Removed standalone "Repair - How To" in favor of consolidated SAM Sites help
MENU_COALITION_COMMAND:New(self.Side, 'Zones - Guide', helpMenu, function()
@ -2304,7 +2277,6 @@ function CTLD:InitCoalitionAdminMenu()
table.insert(lines, '- Navigation: CTLD -> Coach & Nav -> Vectors to Nearest Pickup Zone gives bearing and range.')
table.insert(lines, '- Activation: Zones can be active/inactive per mission logic; inactive pickup zones block crate requests.')
table.insert(lines, '')
table.insert(lines, 'Handy numbers:')
table.insert(lines, string.format('- Build Radius: about %d m to collect nearby crates when building.', self.Config.BuildRadius or 60))
table.insert(lines, string.format('- Pickup Zone Max Distance: about %d m to request crates (configurable).', self.Config.PickupZoneMaxDistance or 10000))
_msgCoalition(self.Side, table.concat(lines, '\n'), 40)
@ -2434,6 +2406,38 @@ function CTLD:InitCoalitionAdminMenu()
table.insert(lines, '- Space launchers to avoid masking; keep radars with good line-of-sight; avoid fratricide arcs.')
_msgCoalition(self.Side, table.concat(lines, '\n'), 45)
end)
MENU_COALITION_COMMAND:New(self.Side, 'Enable CTLD Debug Logging', root, function()
self.Config.Debug = true
env.info(string.format('[Moose_CTLD][%s] Debug ENABLED via Admin menu', tostring(self.Side)))
_msgCoalition(self.Side, 'CTLD Debug logging ENABLED', 8)
end)
MENU_COALITION_COMMAND:New(self.Side, 'Disable CTLD Debug Logging', root, function()
self.Config.Debug = false
env.info(string.format('[Moose_CTLD][%s] Debug DISABLED via Admin menu', tostring(self.Side)))
_msgCoalition(self.Side, 'CTLD Debug logging DISABLED', 8)
end)
MENU_COALITION_COMMAND:New(self.Side, 'Show CTLD Status (crates/zones)', root, function()
local crates = 0
for _ in pairs(CTLD._crates) do crates = crates + 1 end
local msg = string.format('CTLD Status:\nActive crates: %d\nPickup zones: %d\nDrop zones: %d\nFOB zones: %d\nBuild Confirm: %s (%ds window)\nBuild Cooldown: %s (%ds)'
, crates, #(self.PickupZones or {}), #(self.DropZones or {}), #(self.FOBZones or {})
, self.Config.BuildConfirmEnabled and 'ON' or 'OFF', self.Config.BuildConfirmWindowSeconds or 0
, self.Config.BuildCooldownEnabled and 'ON' or 'OFF', self.Config.BuildCooldownSeconds or 0)
_msgCoalition(self.Side, msg, 20)
end)
MENU_COALITION_COMMAND:New(self.Side, 'Show Coalition Summary', root, function()
self:ShowCoalitionSummary()
end)
MENU_COALITION_COMMAND:New(self.Side, 'Draw CTLD Zones on Map', root, function()
self:DrawZonesOnMap()
_msgCoalition(self.Side, 'CTLD zones drawn on F10 map.', 8)
end)
MENU_COALITION_COMMAND:New(self.Side, 'Clear CTLD Map Drawings', root, function()
self:ClearMapDrawings()
_msgCoalition(self.Side, 'CTLD map drawings cleared.', 8)
end)
-- Player Help submenu (was below; removed there and added above)
self.AdminMenu = root
end
-- #endregion Menus