From 61ad4eddcb37df9b82c8029f8bd75d461d5c3de7 Mon Sep 17 00:00:00 2001 From: iTracerFacer <134304944+iTracerFacer@users.noreply.github.com> Date: Wed, 5 Nov 2025 21:05:05 -0600 Subject: [PATCH] =?UTF-8?q?Under=20=E2=80=9CAdmin/Help,=E2=80=9D=20the=20?= =?UTF-8?q?=E2=80=9CPlayer=20Guides=E2=80=9D=20(group-level)=20and=20?= =?UTF-8?q?=E2=80=9CPlayer=20Help=E2=80=9D=20(coalition-level)=20submenus?= =?UTF-8?q?=20now=20appear=20at=20the=20top=20of=20the=20Admin/Help=20root?= =?UTF-8?q?,=20before=20status,=20map=20drawings,=20and=20debug=20entries.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Moose_CTLD_Pure/Moose_CTLD.lua | 366 +++++++++++++++++---------------- 1 file changed, 185 insertions(+), 181 deletions(-) diff --git a/Moose_CTLD_Pure/Moose_CTLD.lua b/Moose_CTLD_Pure/Moose_CTLD.lua index 558bda5..0c5baa4 100644 --- a/Moose_CTLD_Pure/Moose_CTLD.lua +++ b/Moose_CTLD_Pure/Moose_CTLD.lua @@ -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