diff --git a/Moose_CTLD_Pure/Moose_CTLD.lua b/Moose_CTLD_Pure/Moose_CTLD.lua index c639436..e27b24e 100644 --- a/Moose_CTLD_Pure/Moose_CTLD.lua +++ b/Moose_CTLD_Pure/Moose_CTLD.lua @@ -1503,6 +1503,157 @@ function CTLD:BuildGroupMenus(group) MESSAGE:New('CTLD map drawings cleared.', 8):ToGroup(group) end) + -- Player Help submenu (group-level) + local help = MENU_GROUP:New(group, 'Player Help', admin) + -- Removed standalone "Repair - How To" in favor of consolidated SAM Sites help + 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) + return root end @@ -2052,6 +2203,158 @@ function CTLD:InitCoalitionAdminMenu() self:ClearMapDrawings() _msgCoalition(self.Side, 'CTLD map drawings cleared.', 8) end) + -- Player Help submenu + 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() + 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, '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) + end) + MENU_COALITION_COMMAND:New(self.Side, 'Inventory - How It Works', helpMenu, 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.') + _msgCoalition(self.Side, table.concat(lines, '\n'), 40) + end) + MENU_COALITION_COMMAND:New(self.Side, 'CTLD Basics (2-minute tour)', helpMenu, function() + local isMetric = true + 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.') + _msgCoalition(self.Side, table.concat(lines, '\n'), 35) + end) + MENU_COALITION_COMMAND:New(self.Side, 'Troop Transport & JTAC Use', helpMenu, 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.') + _msgCoalition(self.Side, table.concat(lines, '\n'), 35) + end) + MENU_COALITION_COMMAND:New(self.Side, 'Crates 101: Requesting and Handling', helpMenu, 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.') + _msgCoalition(self.Side, table.concat(lines, '\n'), 35) + end) + MENU_COALITION_COMMAND:New(self.Side, 'Hover Pickup & Slingloading', helpMenu, 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.') + _msgCoalition(self.Side, table.concat(lines, '\n'), 35) + end) + MENU_COALITION_COMMAND:New(self.Side, 'Build System: Build Here and Advanced', helpMenu, 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.') + _msgCoalition(self.Side, table.concat(lines, '\n'), 40) + end) + MENU_COALITION_COMMAND:New(self.Side, 'FOBs: Forward Supply & Why They Matter', helpMenu, 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.') + _msgCoalition(self.Side, table.concat(lines, '\n'), 35) + end) + MENU_COALITION_COMMAND:New(self.Side, 'SAM Sites: Building, Repairing, and Augmenting', helpMenu, 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.') + _msgCoalition(self.Side, table.concat(lines, '\n'), 45) + end) self.AdminMenu = root end -- #endregion Menus diff --git a/Moose_CTLD_Pure/Moose_CTLD_Pure.miz b/Moose_CTLD_Pure/Moose_CTLD_Pure.miz index 9f12386..0f139ab 100644 Binary files a/Moose_CTLD_Pure/Moose_CTLD_Pure.miz and b/Moose_CTLD_Pure/Moose_CTLD_Pure.miz differ