Fixed tanks spawning with troops (again)

This commit is contained in:
iTracerFacer 2025-11-09 19:50:39 -06:00
parent 24ffbaf378
commit 4be360880a
11 changed files with 3472 additions and 409 deletions

72
.github/copilot-instructions.md vendored Normal file
View File

@ -0,0 +1,72 @@
# Copilot instructions for DCS_MissionDev
These notes teach AI coding agents how to be productive in this DCS World mission-scripting workspace. Keep responses concrete, reference the files below, and prefer making small targeted edits over broad rewrites.
## Big picture
- This repo is a DCS mission lab focused on Lua scripting for the MOOSE, MIST, CTLD, and CSAR ecosystems.
- Structure:
- Root hosts shared framework scripts and utilities: `Moose_.lua`, `Moose.lua`, `mist.lua`, multiple pinned `mist_*` versions, `CTLD.lua`, `CSAR.lua`, plus helper and mission glue scripts (e.g., `NukeBlockerScriptv1_2_1.lua`, `OnBirthMessage.lua`).
- Mission families live under `DCS_<Theater>/...` with individual `.miz` files and scenario folders.
- Purpose-built modules live under `Moose_*/*` with a main Lua, demo `.miz`, and a README describing setup.
- Loading order matters in DCS: framework(s) first, then modules, then mission glue. Typical trigger order: `Moose_.lua` → framework/middleware → module script(s) → custom mission logic.
## Core modules and patterns (examples in repo)
- Zone Capture (dual coalition): `Moose_DualCoalitionZoneCapture/Moose_DualCoalitionZoneCapture.lua`
- Edit-only config tables: `ZONE_CONFIG` (BLUE/RED/NEUTRAL lists) and `ZONE_SETTINGS` (scan/capture/guard).
- Uses MOOSE classes like `ZONE`, `ZONE_CAPTURE_COALITION`, `COMMANDCENTER`, `MISSION`; logs via `env.info` with `[CAPTURE Module]` prefix.
- Visuals driven by `ZONE_COLORS`; contested/attacked overrides ownership color.
- Dynamic Ground Battle: `Moose_DynamicGroundBattle/Moose_DynamicGroundBattle.lua`
- User-edit section defines red/blue `ZONE:New(...)`, warehouse `STATIC:FindByName(...)`, and template arrays. After the “DO NOT EDIT BELOW THIS LINE” banner core logic runs.
- Spawn rates scale with warehouse survival; periodic tasking (`ASSIGN_TASKS_SCHED`) retasks idle groups; optional infantry movement via `MOVING_INFANTRY_PATROLS`.
- CTLD: `CTLD.lua`
- Large, configurable logistics/troop script; user config at top: smoke, hover pickup, crate rules, pickup/drop/wp zones, vehicle weights, JTAC settings, and transport pilot names.
- Important distances: `ctld.maximumDistanceLogistic`, `ctld.minimumDeployDistance`, etc. Keep names matching ME zones strictly.
- CSAR: `CSAR.lua`
- Note: the current file contains an HTML GitHub page artifact. When updating, replace with the raw Lua from ciribob/DCS-CSAR (use the Raw file, not the HTML page).
## Developer workflows (what to run and how)
- Script load in missions (Mission Editor → Triggers):
1) DO SCRIPT FILE `Moose_.lua`
2) DO SCRIPT FILE your module(s) (e.g., DualCoalitionZoneCapture or DynamicGroundBattle)
3) DO SCRIPT FILE mission glue (CTLD/CSAR/others), respecting their config requirements
- Fast mission patching without opening the editor: `Patch-MooseMissions/`
- Use `Patch-MooseMissions.ps1` to inject or replace a Lua inside a `.miz` and auto-bump version numbers.
- See `Patch-MooseMissions/README.md` for examples (pipeline-friendly; default script location inside miz: `l10n/DEFAULT/*.lua`).
- Versioning conventions for missions: filenames embed the version (`F99th-Operation Ronin 1.4.miz` → next `1.5`); the patcher respects X, X.Y, X.Y.Z.
- Debugging:
- Prefer `env.info("[Tag] message")`; check `Saved Games\DCS\Logs\DCS.log`. Modules log with distinct prefixes (e.g., `[CAPTURE Module]`).
- Common issues: wrong zone/group/static names; framework not loaded first; CTLD/CSAR configs mismatched with ME. Fix by aligning names and load order.
## Conventions and gotchas (repo-specific)
- Name matching is strict across modules. Examples to copy:
- Zones: `"Capture Zone-1"`, `"FrontLine7"`, etc.
- HQ groups: `BLUEHQ`, `REDHQ` for MOOSE `COMMANDCENTER`/`MISSION` creation.
- Warehouses: use Static object Unit Name: `RedWarehouse1-1`, `BlueWarehouse3-1`.
- Module layout: top “user config” section, followed by `-- DO NOT EDIT BELOW THIS LINE` guard. Keep PRs to config when possible; avoid editing engine logic unless necessary.
- Framework pinning: multiple `mist_*` versions live alongside `mist.lua`. Mission scripts may expect a specific version; dont silently swap them—load the version matching the mission.
- CTLD settings commonly used here: `ctld.enableCrates`, `ctld.slingLoad`, `ctld.pickupZones`, `ctld.dropOffZones`, `ctld.wpZones`, `ctld.transportPilotNames`. Follow the existing style when extending.
- CSAR file hygiene: replace HTML artifacts with raw Lua. Verify by ensuring the file starts with Lua, not `<!DOCTYPE html>`.
## Integration points
- MOOSE: all advanced orchestration depends on `Moose_.lua`/`Moose.lua` APIs (`ZONE`, `GROUP`, `STATIC`, `ZONE_CAPTURE_COALITION`, `COMMANDCENTER`, `MISSION`, `SCORING`). Load it first.
- CTLD/CSAR interop: DynamicGroundBattle notes CTLD troops integrate automatically; ensure CTLD is active if you expect troop drops to influence zones.
- VoiceAttack: profiles under `Moose_CTLD_Pure/Voice Attack/` are player tooling, not runtime dependencies. Dont reference them from mission scripts.
## Making changes safely
- When adding new zones/templates/warehouses, update the corresponding arrays in the modules user config and mirror the names in the Mission Editor.
- When changing visuals or scan cadence, update `ZONE_COLORS` and `ZONE_SETTINGS` in Zone Capture, or scheduler values in Dynamic Ground Battle.
- For patching `.miz` with new `Moose_.lua`/scripts, prefer the PowerShell patcher; it preserves originals and bumps the version.
## Pointers to examples in this repo
- Dual coalition capture: `Moose_DualCoalitionZoneCapture/README.md` and example `.miz` in same folder.
- Dynamic ground battle: `Moose_DynamicGroundBattle/README.md`.
- Mission patching: `Patch-MooseMissions/README.md`.
If anything above is ambiguous (e.g., CSAR expected version, CTLD defaults for a specific mission family), ask for the target mission and well codify the exact load order and script set.

View File

@ -186,6 +186,7 @@ CTLD.Messages = {
CTLD.Config = { CTLD.Config = {
CoalitionSide = coalition.side.BLUE, -- default coalition this instance serves (menus created for this side) CoalitionSide = coalition.side.BLUE, -- default coalition this instance serves (menus created for this side)
CountryId = nil, -- optional explicit country id for spawned groups; falls back per coalition
AllowedAircraft = { -- transport-capable unit type names (case-sensitive as in DCS DB) AllowedAircraft = { -- transport-capable unit type names (case-sensitive as in DCS DB)
'UH-1H','Mi-8MTV2','Mi-24P','SA342M','SA342L','SA342Minigun','Ka-50','Ka-50_3','AH-64D_BLK_II','UH-60L','CH-47Fbl1','CH-47F','Mi-17','GazelleAI' 'UH-1H','Mi-8MTV2','Mi-24P','SA342M','SA342L','SA342Minigun','Ka-50','Ka-50_3','AH-64D_BLK_II','UH-60L','CH-47Fbl1','CH-47F','Mi-17','GazelleAI'
}, },
@ -196,7 +197,7 @@ CTLD.Config = {
-- 2 = INFO - Important state changes, initialization, cleanup (default for production) -- 2 = INFO - Important state changes, initialization, cleanup (default for production)
-- 3 = VERBOSE - Detailed operational info (zone validation, menus, builds, MEDEVAC events) -- 3 = VERBOSE - Detailed operational info (zone validation, menus, builds, MEDEVAC events)
-- 4 = DEBUG - Everything including hover checks, crate pickups, detailed troop spawns -- 4 = DEBUG - Everything including hover checks, crate pickups, detailed troop spawns
LogLevel = 1, LogLevel = 4,
-- Per-aircraft capacity limits (realistic cargo/troop capacities) -- Per-aircraft capacity limits (realistic cargo/troop capacities)
-- Set maxCrates = 0 and maxTroops = 0 for attack helicopters with no cargo capability -- Set maxCrates = 0 and maxTroops = 0 for attack helicopters with no cargo capability
@ -254,9 +255,9 @@ CTLD.Config = {
-- Air-spawn settings for CTLD-built drones (AIRPLANE category entries in the catalog like MQ-9 / WingLoong) -- Air-spawn settings for CTLD-built drones (AIRPLANE category entries in the catalog like MQ-9 / WingLoong)
DroneAirSpawn = { DroneAirSpawn = {
Enabled = true, -- when true, AIRPLANE catalog items that opt-in can spawn in the air at a set altitude Enabled = true, -- when true, AIRPLANE catalog items that opt-in can spawn in the air at a set altitude
AltitudeMeters = 3048, -- default spawn altitude ASL (meters) - 10,000 feet AltitudeMeters = 3048, -- default spawn altitude ASL (meters) - 10,000 feet
SpeedMps = 120 -- default initial speed in m/s SpeedMps = 120 -- default initial speed in m/s
}, },
DropCrateForwardOffset = 35, -- meters: drop loaded crates this far in front of the aircraft (instead of directly under) DropCrateForwardOffset = 35, -- meters: drop loaded crates this far in front of the aircraft (instead of directly under)
RestrictFOBToZones = false, -- if true, recipes marked isFOB only build inside configured FOBZones RestrictFOBToZones = false, -- if true, recipes marked isFOB only build inside configured FOBZones
@ -1198,28 +1199,29 @@ local LOG_INFO = 2
local LOG_VERBOSE = 3 local LOG_VERBOSE = 3
local LOG_DEBUG = 4 local LOG_DEBUG = 4
local _logLevelLabels = {
[LOG_ERROR] = 'ERROR',
[LOG_INFO] = 'INFO',
[LOG_VERBOSE] = 'VERBOSE',
[LOG_DEBUG] = 'DEBUG',
}
local function _log(level, msg) local function _log(level, msg)
local logLevel = CTLD.Config and CTLD.Config.LogLevel or LOG_INFO local logLevel = CTLD.Config and CTLD.Config.LogLevel or LOG_INFO
if level <= logLevel then if level > logLevel or level == LOG_NONE then return end
_logVerbose('' .. msg) local label = _logLevelLabels[level] or tostring(level)
local text = string.format('[Moose_CTLD][%s] %s', label, tostring(msg))
if env and env.info then
env.info(text)
else
print(text)
end end
end end
local function _logError(msg) local function _logError(msg) _log(LOG_ERROR, msg) end
_log(LOG_ERROR, msg) local function _logInfo(msg) _log(LOG_INFO, msg) end
end local function _logVerbose(msg) _log(LOG_VERBOSE, msg) end
local function _logDebug(msg) _log(LOG_DEBUG, msg) end
local function _logInfo(msg)
_log(LOG_INFO, msg)
end
local function _logVerbose(msg)
_log(LOG_VERBOSE, msg)
end
local function _logDebug(msg)
_log(LOG_DEBUG, msg)
end
-- ========================= -- =========================
-- Zone and Unit Utilities -- Zone and Unit Utilities
@ -1402,9 +1404,29 @@ function CTLD:_nearestActivePickupZone(unit)
return _nearestZonePoint(unit, self:_collectActivePickupDefs()) return _nearestZonePoint(unit, self:_collectActivePickupDefs())
end end
local function _defaultCountryForSide(side)
if not (country and country.id) then return nil end
if side == coalition.side.BLUE then
return country.id.USA or country.id.CJTF_BLUE
elseif side == coalition.side.RED then
return country.id.RUSSIA or country.id.CJTF_RED
elseif side == coalition.side.NEUTRAL then
return country.id.UN or country.id.CJTF_NEUTRAL or country.id.USA
end
return nil
end
local function _coalitionAddGroup(side, category, groupData, ctldConfig) local function _coalitionAddGroup(side, category, groupData, ctldConfig)
-- Enforce side/category in groupData just to be safe -- Enforce side/category in groupData just to be safe
groupData.category = category groupData.category = category
local countryId = ctldConfig and ctldConfig.CountryId
if not countryId then
countryId = _defaultCountryForSide(side)
if ctldConfig then ctldConfig.CountryId = countryId end
end
if countryId then
groupData.country = countryId
end
-- Apply air-spawn altitude adjustment for AIRPLANE category if DroneAirSpawn is enabled -- Apply air-spawn altitude adjustment for AIRPLANE category if DroneAirSpawn is enabled
if category == Group.Category.AIRPLANE and ctldConfig and ctldConfig.DroneAirSpawn and ctldConfig.DroneAirSpawn.Enabled then if category == Group.Category.AIRPLANE and ctldConfig and ctldConfig.DroneAirSpawn and ctldConfig.DroneAirSpawn.Enabled then
@ -1424,7 +1446,8 @@ local function _coalitionAddGroup(side, category, groupData, ctldConfig)
end end
end end
return coalition.addGroup(side, category, groupData) local addCountry = countryId or side
return coalition.addGroup(addCountry, category, groupData)
end end
local function _spawnStaticCargo(side, point, cargoType, name) local function _spawnStaticCargo(side, point, cargoType, name)
@ -2264,6 +2287,8 @@ function CTLD:New(cfg)
end end
o.Side = o.Config.CoalitionSide o.Side = o.Config.CoalitionSide
o.CountryId = o.Config.CountryId or _defaultCountryForSide(o.Side)
o.Config.CountryId = o.CountryId
o.MenuRoots = {} o.MenuRoots = {}
o.MenusByGroup = {} o.MenusByGroup = {}
@ -7736,6 +7761,28 @@ function CTLD:_CreateMobileMASH(group, position, catalogDef)
if not cfg or not cfg.Enabled then return end if not cfg or not cfg.Enabled then return end
if not cfg.MobileMASH or not cfg.MobileMASH.Enabled then return end if not cfg.MobileMASH or not cfg.MobileMASH.Enabled then return end
-- Ensure we have a MOOSE GROUP instance (coalition.addGroup returns a raw DCS group)
local mashGroup = group
if mashGroup and not (mashGroup.IsAlive and mashGroup.GetCoordinate) then
local rawName = (mashGroup.GetName and mashGroup:GetName()) or (mashGroup.getName and mashGroup:getName())
if rawName and GROUP and GROUP.FindByName then
local found = GROUP:FindByName(rawName)
if found then
mashGroup = found
else
_logError(string.format('[MobileMASH] Could not resolve MOOSE group for %s; aborting Mobile MASH setup', rawName))
return
end
else
_logError('[MobileMASH] Missing group reference for Mobile MASH deployment; aborting')
return
end
end
if not mashGroup then
_logError('[MobileMASH] Mobile MASH group resolution failed; aborting')
return
end
local side = catalogDef.side or self.Side local side = catalogDef.side or self.Side
if not CTLD._mobileMASHCounter then CTLD._mobileMASHCounter = {} end if not CTLD._mobileMASHCounter then CTLD._mobileMASHCounter = {} end
if not CTLD._mobileMASHCounter[side] then CTLD._mobileMASHCounter[side] = 0 end if not CTLD._mobileMASHCounter[side] then CTLD._mobileMASHCounter[side] = 0 end
@ -7750,7 +7797,7 @@ function CTLD:_CreateMobileMASH(group, position, catalogDef)
position = {x = position.x, z = position.z}, position = {x = position.x, z = position.z},
radius = radius, radius = radius,
side = side, side = side,
group = group, group = mashGroup,
isMobile = true, isMobile = true,
catalogKey = catalogDef.description or 'Mobile MASH' catalogKey = catalogDef.description or 'Mobile MASH'
} }
@ -7760,8 +7807,8 @@ function CTLD:_CreateMobileMASH(group, position, catalogDef)
CTLD._mashZones[mashId] = mashData CTLD._mashZones[mashId] = mashData
-- Draw on F10 map -- Draw on F10 map
local circleId = mashId .. '_circle' local circleId = _nextMarkupId()
local textId = mashId .. '_text' local textId = _nextMarkupId()
local p = {x = position.x, y = 0, z = position.z} local p = {x = position.x, y = 0, z = position.z}
local borderColor = cfg.MASHZoneColors.border or {1, 1, 0, 0.85} local borderColor = cfg.MASHZoneColors.border or {1, 1, 0, 0.85}
@ -7791,15 +7838,16 @@ function CTLD:_CreateMobileMASH(group, position, catalogDef)
local ctldInstance = self local ctldInstance = self
local scheduler = SCHEDULER:New(nil, function() local scheduler = SCHEDULER:New(nil, function()
-- Check if group still exists -- Check if group still exists
if not group or not group:IsAlive() then if not mashGroup or not mashGroup:IsAlive() then
ctldInstance:_RemoveMobileMASH(mashId) ctldInstance:_RemoveMobileMASH(mashId)
return return
end end
-- Send periodic announcement -- Send periodic announcement
local currentPos = group:GetCoordinate() local coord = mashGroup:GetCoordinate()
if currentPos then if coord then
local currentGrid = ctldInstance:_GetMGRSString({x = currentPos.x, z = currentPos.z}) local vec3 = coord:GetVec3()
local currentGrid = ctldInstance:_GetMGRSString({x = vec3.x, z = vec3.z})
local announceMsg = _fmtTemplate(CTLD.Messages.medevac_mash_announcement, { local announceMsg = _fmtTemplate(CTLD.Messages.medevac_mash_announcement, {
mash_id = CTLD._mobileMASHCounter[side], mash_id = CTLD._mobileMASHCounter[side],
grid = currentGrid, grid = currentGrid,
@ -7814,7 +7862,7 @@ function CTLD:_CreateMobileMASH(group, position, catalogDef)
-- Set up death event handler for this specific MASH -- Set up death event handler for this specific MASH
local ctldInstance = self local ctldInstance = self
local mashGroupName = group:GetName() local mashGroupName = mashGroup:GetName()
local eventHandler = EVENTHANDLER:New() local eventHandler = EVENTHANDLER:New()
eventHandler:HandleEvent(EVENTS.Dead) eventHandler:HandleEvent(EVENTS.Dead)

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-16"?>
<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>DCS CTLD Menu Navigation</Name>
<Id>a8f7c9d2-4e6b-4c1a-9f3e-2a8d7c6b5e4f</Id>
<Commands>
<Command>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c0d</Id>
<CommandString>load troops</CommandString>
<ActionSequence>
<PressKey>
<KeyCodes>{RALT}\{F2}{F1}{F1}</KeyCodes>
</PressKey>
</ActionSequence>
</Command>
<Command>
<Id>4b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e</Id>
<CommandString>show status;ctld status;check status</CommandString>
<ActionSequence>
<PressKey>
<KeyCodes>{RALT}\{F5}{F2}</KeyCodes>
</PressKey>
</ActionSequence>
</Command>
</Commands>
</Profile>

File diff suppressed because it is too large Load Diff

View File

@ -1,378 +0,0 @@
<?xml version="1.0" encoding="utf-16"?>
<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Name="DCS CTLD Menu Navigation" Id="a8f7c9d2-4e6b-4c1a-9f3e-2a8d7c6b5e4f" EnableMouseClicks="true" Dock="1" v="2.8.10" TrimExecuteCommandLines="true">
<Commands>
<!-- F10 MENU KEY: RAlt+\ (works on ground and in air) -->
<!-- On ground: \ alone works, but RAlt+\ is compatible -->
<!-- In air: RAlt+\ required (\ alone is disabled) -->
<!-- OPERATIONS: TROOP TRANSPORT -->
<Command Id="cmd_load_troops">
<CommandString>load troops</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F1}{F1}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_deploy_hold">
<CommandString>deploy troops;deploy hold;deploy defend</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F1}{F3}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_deploy_attack">
<CommandString>deploy attack;troops attack</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F1}{F4}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<!-- OPERATIONS: BUILD -->
<Command Id="cmd_build_here">
<CommandString>build here;build at position</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F2}{F1}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_refresh_buildable">
<CommandString>refresh buildable list;refresh build list</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F2}{F4}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<!-- OPERATIONS: MEDEVAC -->
<Command Id="cmd_medevac_list">
<CommandString>list medevac;active medevac requests</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F1}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_medevac_nearest">
<CommandString>nearest medevac location;medevac location</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F2}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_salvage_points">
<CommandString>salvage points;check salvage</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F3}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_vectors_medevac">
<CommandString>vectors to medevac;medevac vectors</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F4}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_mash_locations">
<CommandString>mash locations;show mash</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F5}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_smoke_crews">
<CommandString>smoke crew locations;mark crews</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F6}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_smoke_mash">
<CommandString>smoke mash zones;mark mash</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F7}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<!-- LOGISTICS: CRATE MANAGEMENT -->
<Command Id="cmd_drop_one_crate">
<CommandString>drop one crate;drop crate</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F1}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_drop_all_crates">
<CommandString>drop all crates;drop cargo</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F2}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_remark_crate">
<CommandString>mark nearest crate;smoke crate;remark crate</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F3}{F3}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_show_inventory">
<CommandString>show inventory;check inventory;zone inventory</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F4}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<!-- FIELD TOOLS -->
<Command Id="cmd_create_dropzone">
<CommandString>create drop zone;mark drop zone</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F3}{F1}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_smoke_green">
<CommandString>smoke green;green smoke</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F3}{F2}{F1}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_smoke_red">
<CommandString>smoke red;red smoke</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F3}{F2}{F2}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_smoke_white">
<CommandString>smoke white;white smoke</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F3}{F2}{F3}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_smoke_orange">
<CommandString>smoke orange;orange smoke</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F3}{F2}{F4}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_smoke_blue">
<CommandString>smoke blue;blue smoke</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F3}{F2}{F5}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<!-- NAVIGATION -->
<Command Id="cmd_vectors_crate">
<CommandString>vectors to crate;find crate;nearest crate</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F4}{F1}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_vectors_pickup">
<CommandString>vectors to pickup;find pickup zone;nearest pickup</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F4}{F2}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_smoke_nearest_zone">
<CommandString>smoke nearest zone;mark nearest zone</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F4}{F3}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_smoke_all_zones">
<CommandString>smoke all zones;mark all zones;smoke nearby zones</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F4}{F4}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_vectors_mash">
<CommandString>vectors to mash;find mash;nearest mash</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F4}{F6}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_hover_coach_enable">
<CommandString>enable hover coach;hover coach on</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F4}{F7}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_hover_coach_disable">
<CommandString>disable hover coach;hover coach off</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F4}{F8}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<!-- STATUS & ADMIN -->
<Command Id="cmd_show_status">
<CommandString>show status;ctld status;check status</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F5}{F2}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_draw_zones">
<CommandString>draw zones on map;show zones;mark zones on map</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F5}{F3}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_clear_map">
<CommandString>clear map drawings;clear map marks;remove zone marks</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F5}{F4}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_medevac_stats">
<CommandString>medevac statistics;medevac stats;show medevac stats</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F5}{F5}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<!-- QUICK ACCESS COMBOS -->
<Command Id="cmd_quick_pickup">
<CommandString>quick pickup;pickup mode</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F1}{F1}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_quick_deploy">
<CommandString>quick deploy;fast deploy</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F1}{F3}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
<Command Id="cmd_quick_build">
<CommandString>quick build;fast build</CommandString>
<ActionSequence>
<CommandAction>
<Context>Send keys to active window</Context>
<KeyCodes>{RALT}\\{F2}{F2}{F1}</KeyCodes>
</CommandAction>
</ActionSequence>
</Command>
</Commands>
</Profile>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,587 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>CTLD VoiceAttack Profile &mdash; Command Reference</title>
<style>
:root {
color-scheme: light dark;
--bg: #0f141a;
--bg-alt: #162029;
--fg: #f0f3f6;
--fg-muted: #c8d2dd;
--accent: #2f8dda;
--accent-soft: rgba(47, 141, 218, 0.14);
--border: rgba(240, 243, 246, 0.14);
--border-strong: rgba(240, 243, 246, 0.28);
}
body {
margin: 0;
font-family: "Segoe UI", "Roboto", sans-serif;
font-size: 15px;
line-height: 1.6;
background: var(--bg);
color: var(--fg);
}
main {
margin: 0 auto;
padding: 48px 32px 64px;
max-width: 1180px;
}
header {
position: sticky;
top: 0;
margin: -48px -32px 36px;
padding: 36px 32px 24px;
background: linear-gradient(160deg, rgba(47, 141, 218, 0.35), rgba(15, 20, 26, 0.0));
border-bottom: 1px solid var(--border);
backdrop-filter: blur(10px);
}
h1 {
margin: 0 0 4px;
font-size: 30px;
letter-spacing: 0.02em;
}
h2 {
margin-top: 44px;
margin-bottom: 12px;
font-size: 22px;
color: var(--accent);
}
p.lead {
margin: 8px 0 16px;
color: var(--fg-muted);
max-width: 880px;
}
.callout {
background: var(--bg-alt);
border: 1px solid var(--border);
border-radius: 12px;
padding: 18px 22px;
margin-bottom: 28px;
box-shadow: 0 16px 32px rgba(0, 0, 0, 0.22);
}
.callout strong {
color: var(--accent);
}
table {
width: 100%;
border-collapse: collapse;
background: var(--bg-alt);
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.18);
}
thead {
background: rgba(47, 141, 218, 0.18);
color: var(--fg);
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 12px;
}
th, td {
padding: 14px 18px;
vertical-align: top;
border-bottom: 1px solid var(--border);
}
tbody tr:last-child td {
border-bottom: none;
}
tbody tr:nth-child(odd) {
background: rgba(255, 255, 255, 0.02);
}
code {
font-family: "Cascadia Code", "Fira Code", monospace;
font-size: 13px;
background: rgba(255, 255, 255, 0.04);
padding: 2px 6px;
border-radius: 6px;
border: 1px solid var(--border);
}
ul {
padding-left: 22px;
margin: 0;
}
.phrases span {
display: inline-block;
background: var(--accent-soft);
color: var(--accent);
border: 1px solid rgba(47, 141, 218, 0.35);
border-radius: 999px;
padding: 4px 12px;
margin: 2px 6px 2px 0;
font-size: 13px;
}
footer {
margin-top: 64px;
font-size: 13px;
color: var(--fg-muted);
border-top: 1px solid var(--border);
padding-top: 18px;
}
@media (max-width: 900px) {
main {
padding: 36px 18px 48px;
}
header {
margin: -36px -18px 24px;
padding: 28px 18px 18px;
}
table, thead, tbody, th, td, tr {
display: block;
}
thead {
display: none;
}
tbody tr {
margin-bottom: 18px;
border: 1px solid var(--border);
border-radius: 10px;
overflow: hidden;
}
td {
border: none;
border-bottom: 1px solid var(--border);
}
td::before {
content: attr(data-label);
display: block;
font-weight: 600;
margin-bottom: 6px;
color: var(--accent);
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 11px;
}
tbody tr:last-child td {
border-bottom: none;
}
}
</style>
</head>
<body>
<main>
<header>
<h1>CTLD VoiceAttack Command Reference</h1>
<p class="lead">All phrases below assume the VoiceAttack profile sends <code>Right&nbsp;Alt&nbsp;+&nbsp;Backslash</code> to open the radio menu, then <code>F10 &gt; F2</code> to enter the CTLD root. Speak any phrase shown to run the navigation sequence automatically.</p>
</header>
<section class="callout">
<strong>Pro Tip:</strong> Fine-tune the pause durations inside VoiceAttack if your DCS instance needs more/less time for menus to populate. You can also add your own synonyms by editing the command string list for any entry.
</section>
<h2>Operations &mdash; Troop Transport</h2>
<table>
<thead>
<tr>
<th scope="col">Phrases</th>
<th scope="col">Action</th>
<th scope="col">Menu Path</th>
</tr>
</thead>
<tbody>
<tr>
<td class="phrases" data-label="Phrases">
<span>load troops</span>
<span>load infantry</span>
</td>
<td data-label="Action">Load default troop package.</td>
<td data-label="Menu Path">Operations → Troop Transport → Load Troops</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>load assault squad</span>
<span>load assault team</span>
</td>
<td data-label="Action">Load Assault Squad preset (AS).</td>
<td data-label="Menu Path">Operations → Troop Transport → Load Troops (Type) → Assault Squad</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>load manpads team</span>
<span>load aa squad</span>
</td>
<td data-label="Action">Load MANPADS Team preset (AA).</td>
<td data-label="Menu Path">Operations → Troop Transport → Load Troops (Type) → MANPADS Team</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>load anti tank team</span>
<span>load at squad</span>
</td>
<td data-label="Action">Load Anti-Tank Team preset (AT).</td>
<td data-label="Menu Path">Operations → Troop Transport → Load Troops (Type) → AT Team</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>load mortar team</span>
<span>load mortar squad</span>
</td>
<td data-label="Action">Load Mortar Team preset (AR).</td>
<td data-label="Menu Path">Operations → Troop Transport → Load Troops (Type) → Mortar Team</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>deploy troops hold</span>
<span>deploy hold</span>
</td>
<td data-label="Action">Unload troops with Hold/Defend behavior.</td>
<td data-label="Menu Path">Operations → Troop Transport → Deploy [Hold Position]</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>deploy troops attack</span>
<span>deploy attack</span>
</td>
<td data-label="Action">Unload troops with Attack/Advance behavior.</td>
<td data-label="Menu Path">Operations → Troop Transport → Deploy [Attack]</td>
</tr>
</tbody>
</table>
<h2>Operations &mdash; Build</h2>
<table>
<thead>
<tr>
<th scope="col">Phrases</th>
<th scope="col">Action</th>
<th scope="col">Menu Path</th>
</tr>
</thead>
<tbody>
<tr>
<td class="phrases" data-label="Phrases">
<span>build here</span>
<span>build at position</span>
</td>
<td data-label="Action">Build using nearby crates (with confirm/cooldown rules).</td>
<td data-label="Menu Path">Operations → Build → Build Here</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>open build advanced</span>
<span>build advanced menu</span>
</td>
<td data-label="Action">Open the dynamic build menu.</td>
<td data-label="Menu Path">Operations → Build → Build (Advanced)</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>open buildable near you</span>
<span>show buildable list</span>
</td>
<td data-label="Action">Focus the “Buildable Near You” submenu.</td>
<td data-label="Menu Path">Operations → Build → Build (Advanced) → Buildable Near You</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>refresh build list</span>
<span>refresh buildable list</span>
</td>
<td data-label="Action">Rescan crate availability for builds.</td>
<td data-label="Menu Path">Operations → Build → Refresh Buildable List</td>
</tr>
</tbody>
</table>
<h2>Operations &mdash; MEDEVAC</h2>
<table>
<thead>
<tr>
<th scope="col">Phrases</th>
<th scope="col">Action</th>
<th scope="col">Menu Path</th>
</tr>
</thead>
<tbody>
<tr>
<td class="phrases" data-label="Phrases">
<span>list medevac requests</span>
<span>active medevac</span>
</td>
<td data-label="Action">Show all active MEDEVAC crews.</td>
<td data-label="Menu Path">Operations → MEDEVAC → List Active MEDEVAC Requests</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>nearest medevac location</span>
<span>medevac location</span>
</td>
<td data-label="Action">Display nearest crew position.</td>
<td data-label="Menu Path">Operations → MEDEVAC → Nearest MEDEVAC Location</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>check salvage points</span>
<span>show salvage</span>
</td>
<td data-label="Action">Report coalition salvage totals.</td>
<td data-label="Menu Path">Operations → MEDEVAC → Coalition Salvage Points</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>vectors to medevac</span>
<span>medevac vectors</span>
</td>
<td data-label="Action">Provide bearing/range to nearest crew.</td>
<td data-label="Menu Path">Operations → MEDEVAC → Vectors to Nearest MEDEVAC</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>show mash locations</span>
<span>list mash</span>
</td>
<td data-label="Action">List all MASH delivery zones.</td>
<td data-label="Menu Path">Operations → MEDEVAC → MASH Locations</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>smoke crew locations</span>
<span>mark crews</span>
</td>
<td data-label="Action">Drop smoke on every active crew.</td>
<td data-label="Menu Path">Operations → MEDEVAC → Pop Smoke at Crew Locations</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>smoke mash zones</span>
<span>mark mash</span>
</td>
<td data-label="Action">Drop smoke on all MASH zones.</td>
<td data-label="Menu Path">Operations → MEDEVAC → Pop Smoke at MASH Zones</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>medevac guide</span>
<span>salvage guide</span>
</td>
<td data-label="Action">Show in-game MEDEVAC/salvage quick reference.</td>
<td data-label="Menu Path">Operations → MEDEVAC → MASH &amp; Salvage System Guide</td>
</tr>
</tbody>
</table>
<h2>Logistics</h2>
<table>
<thead>
<tr>
<th scope="col">Phrases</th>
<th scope="col">Action</th>
<th scope="col">Menu Path</th>
</tr>
</thead>
<tbody>
<tr>
<td class="phrases" data-label="Phrases">
<span>open request crate</span>
<span>request crate menu</span>
</td>
<td data-label="Action">Open the crate request submenu (choose item manually).</td>
<td data-label="Menu Path">Logistics → Request Crate</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>open recipe info</span>
<span>recipe info menu</span>
</td>
<td data-label="Action">Open recipe info submenu.</td>
<td data-label="Menu Path">Logistics → Recipe Info</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>drop one crate</span>
<span>drop crate</span>
</td>
<td data-label="Action">Drop a single loaded crate.</td>
<td data-label="Menu Path">Logistics → Crate Management → Drop One Loaded Crate</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>drop all crates</span>
<span>drop cargo</span>
</td>
<td data-label="Action">Drop every loaded crate.</td>
<td data-label="Menu Path">Logistics → Crate Management → Drop All Loaded Crates</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>remark nearest crate</span>
<span>smoke crate</span>
</td>
<td data-label="Action">Smoke the nearest friendly crate.</td>
<td data-label="Menu Path">Logistics → Crate Management → Re-mark Nearest Crate (Smoke)</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>show zone inventory</span>
<span>check inventory</span>
</td>
<td data-label="Action">Show stock at nearest supply/FOB zone.</td>
<td data-label="Menu Path">Logistics → Show Inventory at Nearest Zone</td>
</tr>
</tbody>
</table>
<h2>Field Tools</h2>
<table>
<thead>
<tr>
<th scope="col">Phrases</th>
<th scope="col">Action</th>
<th scope="col">Menu Path</th>
</tr>
</thead>
<tbody>
<tr>
<td class="phrases" data-label="Phrases">
<span>create drop zone</span>
<span>mark drop zone</span>
</td>
<td data-label="Action">Create a player drop zone (AO).</td>
<td data-label="Menu Path">Field Tools → Create Drop Zone (AO)</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>smoke green</span>
<span>green smoke</span>
</td>
<td data-label="Action">Drop green smoke at your position.</td>
<td data-label="Menu Path">Field Tools → Smoke My Location → Green</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>smoke red</span>
<span>red smoke</span>
</td>
<td data-label="Action">Drop red smoke at your position.</td>
<td data-label="Menu Path">Field Tools → Smoke My Location → Red</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>smoke white</span>
<span>white smoke</span>
</td>
<td data-label="Action">Drop white smoke at your position.</td>
<td data-label="Menu Path">Field Tools → Smoke My Location → White</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>smoke orange</span>
<span>orange smoke</span>
</td>
<td data-label="Action">Drop orange smoke at your position.</td>
<td data-label="Menu Path">Field Tools → Smoke My Location → Orange</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>smoke blue</span>
<span>blue smoke</span>
</td>
<td data-label="Action">Drop blue smoke at your position.</td>
<td data-label="Menu Path">Field Tools → Smoke My Location → Blue</td>
</tr>
</tbody>
</table>
<h2>Navigation &amp; Hover Coach</h2>
<table>
<thead>
<tr>
<th scope="col">Phrases</th>
<th scope="col">Action</th>
<th scope="col">Menu Path</th>
</tr>
</thead>
<tbody>
<tr>
<td class="phrases" data-label="Phrases">
<span>vectors to crate</span>
<span>find crate</span>
</td>
<td data-label="Action">Show bearing/range to nearest friendly crate.</td>
<td data-label="Menu Path">Navigation → Request Vectors to Nearest Crate</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>vectors to pickup zone</span>
<span>find pickup zone</span>
</td>
<td data-label="Action">Show bearing/range to nearest supply zone.</td>
<td data-label="Menu Path">Navigation → Vectors to Nearest Pickup Zone</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>smoke nearest zone</span>
<span>mark nearest zone</span>
</td>
<td data-label="Action">Smoke the closest zone (pickup/drop/FOB/MASH).</td>
<td data-label="Menu Path">Navigation → Smoke Nearest Zone (Pickup/Drop/FOB/MASH)</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>smoke all zones</span>
<span>mark all zones</span>
</td>
<td data-label="Action">Smoke every zone within 5&nbsp;km.</td>
<td data-label="Menu Path">Navigation → Smoke All Nearby Zones (5km)</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>vectors to medevac crew</span>
<span>find medevac crew</span>
</td>
<td data-label="Action">Show bearing/range to the nearest crew (shortcut).</td>
<td data-label="Menu Path">Navigation → Vectors to Nearest MEDEVAC Crew</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>vectors to mash</span>
<span>find mash</span>
</td>
<td data-label="Action">Show bearing/range to nearest MASH.</td>
<td data-label="Menu Path">Navigation → Vectors to Nearest MASH</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>enable hover coach</span>
<span>hover coach on</span>
</td>
<td data-label="Action">Enable hover coach prompts for this group.</td>
<td data-label="Menu Path">Navigation → Hover Coach: Enable</td>
</tr>
<tr>
<td class="phrases" data-label="Phrases">
<span>disable hover coach</span>
<span>hover coach off</span>
</td>
<td data-label="Action">Disable hover coach prompts for this group.</td>
<td data-label="Menu Path">Navigation → Hover Coach: Disable</td>
</tr>
</tbody>
</table>
<footer>
Generated for <code>CTLD_VoiceAttack_Profile_F10.vap</code> (Right Alt + Backslash → F10 → F2). Tweak phrases or delays directly inside VoiceAttack to match your mission&apos;s pace.
</footer>
</main>
</body>
</html>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-16"?>
<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>DCS CTLD Menu Navigation</Name>
<Id>a8f7c9d2-4e6b-4c1a-9f3e-2a8d7c6b5e4f</Id>
<Commands>
<!-- OPERATIONS: TROOP TRANSPORT -->
<Command>
<CommandString>load troops</CommandString>
<ActionSequence>
<CommandAction>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c0d</Id>
<ActionType>PressKey</ActionType>
<Delay>0</Delay>
<KeyCodes>
<unsignedShort>165</unsignedShort>
</KeyCodes>
</CommandAction>
<CommandAction>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c0e</Id>
<ActionType>Pause</ActionType>
<Delay>200</Delay>
</CommandAction>
<CommandAction>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c0f</Id>
<ActionType>PressKey</ActionType>
<Delay>0</Delay>
<KeyCodes>
<unsignedShort>220</unsignedShort>
</KeyCodes>
</CommandAction>
<CommandAction>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c10</Id>
<ActionType>Pause</ActionType>
<Delay>300</Delay>
</CommandAction>
<CommandAction>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c11</Id>
<ActionType>PressKey</ActionType>
<Delay>0</Delay>
<KeyCodes>
<unsignedShort>113</unsignedShort>
</KeyCodes>
</CommandAction>
<CommandAction>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c12</Id>
<ActionType>Pause</ActionType>
<Delay>300</Delay>
</CommandAction>
<CommandAction>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c13</Id>
<ActionType>PressKey</ActionType>
<Delay>0</Delay>
<KeyCodes>
<unsignedShort>112</unsignedShort>
</KeyCodes>
</CommandAction>
<CommandAction>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c14</Id>
<ActionType>Pause</ActionType>
<Delay>300</Delay>
</CommandAction>
<CommandAction>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c15</Id>
<ActionType>PressKey</ActionType>
<Delay>0</Delay>
<KeyCodes>
<unsignedShort>112</unsignedShort>
</KeyCodes>
</CommandAction>
</ActionSequence>
<Id>3a7f2b1e-8c4d-4f9a-b2e1-5d6c7a8b9c0d</Id>
</Command>
</Commands>
</Profile>

View File

@ -263,7 +263,7 @@ local troops = {}
troops['AS'] = { troops['AS'] = {
label = 'Assault Squad', label = 'Assault Squad',
size = 8, size = 8,
unitsBlue = { 'Soldier M4', 'Infantry M249' }, unitsBlue = { 'Soldier M4', 'Soldier M249' },
unitsRed = { 'Infantry AK', 'Infantry AK' }, unitsRed = { 'Infantry AK', 'Infantry AK' },
units = { 'Infantry AK' }, units = { 'Infantry AK' },
} }