------------------------------------------------------------------ -- VEAF groups and units database for DCS World -- By zip (2018) -- -- Features: -- --------- -- * Contains all the units aliases and groups definitions used by the other VEAF scripts -- -- See the documentation : https://veaf.github.io/documentation/ ------------------------------------------------------------------ veafUnits = {} ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Global settings. Stores the root VEAF constants ------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Identifier. All output in DCS.log will start with this. veafUnits.Id = "UNITS" --- Version. veafUnits.Version = "1.15.0" -- trace level, specific to this module --veafUnits.LogLevel = "trace" veaf.loggers.new(veafUnits.Id, veafUnits.LogLevel) --- If no unit is spawned in a cell, it will default to this width veafUnits.DefaultCellWidth = 10 --- If no unit is spawned in a cell, it will default to this height veafUnits.DefaultCellHeight = 10 --- Group format that will be spawned then destroyed from a convoy to fix the AI's dumb pathfinding as of 17/08/2022 veafUnits.DefaultPathfindingUnitType = "TZ-22_KrAZ" veafUnits.DefaultPathfindingGroup = {} veafUnits.DefaultPathfindingGroup = { disposition = {h=1, w=1}, units = { {veafUnits.DefaultPathfindingUnitType, random = true} }, groupName = "Pathfinder", description = "Plz Fix ED" } --- delay before the pathfinding fix unit is destroyed veafUnits.delayBeforePathfindingFix = 5 --- if true, the groups and units lists will be printed to the logs, so they can be saved to the documentation files veafUnits.OutputListsForDocumentation = false ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Do not change anything below unless you know what you are doing! ------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Utility methods ------------------------------------------------------------------------------------------------------------------------------------------------------------- function veafUnits.traceGroup(group, cells) if group and veafUnits.Trace then veaf.loggers.get(veafUnits.Id):trace("") veaf.loggers.get(veafUnits.Id):trace(" Group : " .. group.description) veaf.loggers.get(veafUnits.Id):trace("") local nCols = group.disposition.w local nRows = group.disposition.h local line1 = "| |" local line2 = "|----|" for nCol = 1, nCols do line1 = line1 .. " ".. string.format("%02d", nCol) .." |" line2 = line2 .. "--------------------------------|" end veaf.loggers.get(veafUnits.Id):trace(line1) veaf.loggers.get(veafUnits.Id):trace(line2) local unitCounter = 1 for nRow = 1, nRows do local line1 = "| |" local line2 = "| " .. string.format("%02d", nRow) .. " |" local line3 = "| |" local line4 = "|----|" for nCol = 1, nCols do local cellNum = (nRow - 1) * nCols + nCol local cell = cells[cellNum] local left = " " local top = " " local right = " " local bottom = " " local bottomleft = " " local center = " " if cell then local unit = cell.unit if unit then local unitName = unit.typeName if unitName:len() > 11 then unitName = unitName:sub(1,11) end unitName = string.format("%02d", unitCounter) .. "-" .. unitName local spaces = 14 - unitName:len() for i=1, math.floor(spaces/2) do unitName = " " .. unitName end for i=1, math.ceil(spaces/2) do unitName = unitName .. " " end center = " " .. unitName .. " " bottomleft = string.format(" %03d ", mist.utils.toDegree(unit.spawnPoint.hdg)) unitCounter = unitCounter + 1 end left = string.format("%08d",math.floor(cell.left)) top = string.format("%08d",math.floor(cell.top)) right = string.format("%08d",math.floor(cell.right)) bottom = string.format("%08d",math.floor(cell.bottom)) end line1 = line1 .. " " .. top .. " " .. "|" line2 = line2 .. "" .. left .. center .. right.. "|" line3 = line3 .. bottomleft .. bottom.. " |" line4 = line4 .. "--------------------------------|" end veaf.loggers.get(veafUnits.Id):trace(line1) veaf.loggers.get(veafUnits.Id):trace(line2) veaf.loggers.get(veafUnits.Id):trace(line3) veaf.loggers.get(veafUnits.Id):trace(line4) end end end ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Core methods ------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Browse all the units in a group and counts the infantry and vehicles remaining function veafUnits.countInfantryAndVehicles(groupname) local nbVehicles = 0 local nbInfantry = 0 local group = Group.getByName(groupname) if group and group:isExist() == true and #group:getUnits() > 0 then for _, u in pairs(group:getUnits()) do local typeName = u:getTypeName() if typeName then local unit = veafUnits.findUnit(typeName) if unit then if unit.vehicle then nbVehicles = nbVehicles + 1 elseif unit.infantry then nbInfantry = nbInfantry + 1 end end end end end return nbVehicles, nbInfantry end --- searches the DCS database for a unit having this type (case insensitive) function veafUnits.findDcsUnit(unitType) veaf.loggers.get(veafUnits.Id):trace("veafUnits.findDcsUnit(unitType=" .. unitType .. ")") -- find the desired unit in the DCS units database local unit = nil for _, u in pairs(dcsUnits.DcsUnitsDatabase) do if (u and u.type and unitType:lower() == u.type:lower()) or (u and u.name and unitType:lower() == u.name:lower()) then unit = u break end end return unit end --- process a group definition and return a usable group table function veafUnits.processGroup(group) local result = {} -- initialize result table and copy metadata result.disposition = {} result.disposition.h = group.disposition.h result.disposition.w = group.disposition.w result.description = group.description result.groupName = group.groupName result.units = {} veaf.loggers.get(veafUnits.Id):trace("group="..veaf.p(group)) local unitNumber = 1 -- replace all units with a simplified structure made from the DCS unit metadata structure for i = 1, #group.units do local unitType local cell = nil local number = nil local size = nil local hdg = nil local random = false local fitToUnit = false local u = group.units[i] veaf.loggers.get(veafUnits.Id):trace("u="..veaf.p(u)) if type(u) == "string" then -- information was skipped using simplified syntax unitType = u else unitType = u.typeName if not unitType then unitType = u[1] end veaf.loggers.get(veafUnits.Id):trace("unitType="..veaf.p(unitType)) cell = u.cell number = u.number size = u.size hdg = u.hdg if type(size) == "number" then size = {} size.width = u.size size.height = u.size end if u.random then random = true end if u.fitToUnit then fitToUnit = true end end if not(number) then number = 1 end if type(number) == "table" then -- create a random number of units local min = number.min local max = number.max if not(min) then min = 1 end if not(max) then max = 1 end number = math.random(min, max) end if not(hdg) then hdg = math.random(0, 359) -- default heading is random end veaf.loggers.get(veafUnits.Id):trace(string.format("hdg=%d",hdg)) for numUnit = 1, number do veaf.loggers.get(veafUnits.Id):trace("searching for unit [" .. unitType .. "] listed in group [" .. group.groupName .. "]") local unit = veafUnits.findUnit(unitType) if not(unit) then veaf.loggers.get(veafUnits.Id):info("cannot find unit [" .. unitType .. "] listed in group [" .. group.groupName .. "]") else unit.cell = cell unit.hdg = hdg unit.random = random unit.fitToUnit = fitToUnit unit.size = size result.units[unitNumber] = unit unitNumber = unitNumber + 1 end end end -- check group type (WARNING : unit types should not be mixed !) for _, unit in pairs(result.units) do if unit.naval then result.naval = true break end if unit.air then result.air = true break end end veaf.loggers.get(veafUnits.Id):trace("result="..veaf.p(result)) return result end --- searches the database for a group having this alias (case insensitive) function veafUnits.findGroup(groupAlias) veaf.loggers.get(veafUnits.Id):debug("veafUnits.findGroup(groupAlias=" .. groupAlias .. ")") -- find the desired group in the groups database local result = nil for _, g in pairs(veafUnits.GroupsDatabase) do for _, alias in pairs(g.aliases) do if alias:lower() == groupAlias:lower() then result = veafUnits.processGroup(g.group) break end end end return result end --- searches the database for a unit having this alias (case insensitive) function veafUnits.findUnit(unitAlias) veaf.loggers.get(veafUnits.Id):trace("veafUnits.findUnit(unitAlias=" .. unitAlias .. ")") -- find the desired unit in the units database local unit = nil for _, u in pairs(veafUnits.UnitsDatabase) do for _, alias in pairs(u.aliases) do if alias:lower() == unitAlias:lower() then unit = u break end end end if unit then unit = veafUnits.findDcsUnit(unit.unitType) else unit = veafUnits.findDcsUnit(unitAlias) end if not(unit) then veaf.loggers.get(veafUnits.Id):info("cannot find unit [" .. unitAlias .. "]") else unit = veafUnits.makeUnitFromDcsStructure(unit, 1) end return unit end --- Creates a simple structure from DCS complex metadata structure function veafUnits.makeUnitFromDcsStructure(dcsUnit, cell) local result = {} if not(dcsUnit) then return nil end --[[ [9] = { ["type"] = "Vulcan", ["name"] = "AAA Vulcan M163", ["category"] = "Air Defence", ["vehicle"] = true, ["description"] = "AAA Vulcan M163", ["aliases"] = { [1] = "M163 Vulcan", }, -- end of ["aliases"] }, -- end of [9] ]] result.category = dcsUnit.category result.typeName = dcsUnit.type result.displayName = dcsUnit.description result.naval = (dcsUnit.naval) result.air = (dcsUnit.air) if (not(dcsUnit.naval) and not(dcsUnit.air) and not(dcsUnit.infantry) and not(dcsUnit.vehicle) and (dcsUnit.attribute==nil or dcsUnit.attribute.Fortifications==nil)) then result.static = true end result.infantry = (dcsUnit.infantry) result.vehicle = (dcsUnit.vehicle) --[[ result.size = { x = veaf.round(dcsUnit.desc.box.max.x - dcsUnit.desc.box.min.x, 1), y = veaf.round(dcsUnit.desc.box.max.y - dcsUnit.desc.box.min.y, 1), z = veaf.round(dcsUnit.desc.box.max.z - dcsUnit.desc.box.min.z, 1)} result.width = result.size.z result.length= result.size.x -- invert if width > height if result.width > result.length then local width = result.width result.width = result.length result.length = width end ]] result.cell = cell return result end --- checks if position is correct for the unit type function veafUnits.checkPositionForUnit(spawnPosition, unit) veaf.loggers.get(veafUnits.Id):trace("checkPositionForUnit()") veaf.loggers.get(veafUnits.Id):trace("spawnPosition=%s", spawnPosition) local vec2 = { x = spawnPosition.x, y = spawnPosition.z } veaf.loggers.get(veafUnits.Id):trace("vec2=%s", vec2) veaf.loggers.get(veafUnits.Id):trace("unit=%s", unit) local landType = land.getSurfaceType(vec2) local IsNavalStatic = false --offshore static (list in dcsUnits.lua) flag if unit.static and veaf.findInTable(dcsUnits.NavalStatics, unit.typeName) then veaf.loggers.get(veafUnits.Id):trace("Is Naval Static") IsNavalStatic = true end if landType == land.SurfaceType.WATER then veaf.loggers.get(veafUnits.Id):trace("landType = WATER") else veaf.loggers.get(veafUnits.Id):trace("landType = GROUND") end if spawnPosition then if unit.air then -- if the unit is a plane or helicopter if spawnPosition.z <= 10 then -- if lower than 10m don't spawn unit return false end elseif unit.naval or IsNavalStatic then -- if the unit is a naval unit or an offshore static if landType ~= land.SurfaceType.WATER then -- don't spawn over anything but water return false end else if landType == land.SurfaceType.WATER then -- don't spawn over water return false end end end return true end --- Adds a placement point to every unit of the group, centering the whole group around the spawnPoint, and adding an optional spacing function veafUnits.placeGroup(group, spawnPoint, spacing, hdg, hasDest) veaf.loggers.get(veafUnits.Id):trace("group = %s",group) veaf.loggers.get(veafUnits.Id):trace("spawnPoint = %s", spawnPoint) veaf.loggers.get(veafUnits.Id):trace("spacing = %s", spacing) veaf.loggers.get(veafUnits.Id):trace("hdg = %s", hdg) veaf.loggers.get(veafUnits.Id):trace("hasDest = %s", hasDest) if not(hdg) then hdg = 0 -- default north end local hasDest = false or hasDest veaf.loggers.get(veafUnits.Id):trace(string.format("hasDest = %s", veaf.p(hasDest))) if not(group.disposition) then -- default disposition is a square local l = math.ceil(math.sqrt(#group.units)) group.disposition = { h = l, w = l} end local nRows = nil local nCols = nil if hasDest then local pathfindingFixer = veafUnits.processGroup(veafUnits.DefaultPathfindingGroup) --insert a unit (structured into a group) that will be destroyed just after the convoy is spawned, this is to fix the AI weird pathfinding table.insert(group.units, pathfindingFixer.units[1]) --insert the unit that has all of the necessary info into the group that's being placed nRows = #group.units nCols = 1 else nRows = group.disposition.h nCols = group.disposition.w end -- sort the units by occupied cell local fixedUnits = {} local freeUnits = {} for _, unit in pairs(group.units) do if unit.cell and not hasDest then --if the group has a destination, programmer defined patterns do not apply anymore as the convoy is spawned in a line table.insert(fixedUnits, unit) else table.insert(freeUnits, unit) end end local cells = {} local allCells = {} for cellNum = 1, nRows*nCols do allCells[cellNum] = cellNum end -- place fixed units in their designated cells for i = 1, #fixedUnits do local unit = fixedUnits[i] cells[unit.cell] = {} cells[unit.cell].unit = unit -- remove this cell from the list of available cells for cellNum = 1, #allCells do if allCells[cellNum] == unit.cell then table.remove(allCells, cellNum) break end end end -- randomly place non-fixed units in the remaining cells for i = 1, #freeUnits do local randomCellNum = allCells[math.random(1, #allCells)] local unit = freeUnits[i] unit.cell = randomCellNum cells[unit.cell] = {} cells[randomCellNum].unit = unit -- remove this cell from the list of available cells for cellNum = 1, #allCells do if allCells[cellNum] == unit.cell then table.remove(allCells, cellNum) break end end end if hasDest then local cellGreater = function(unit1, unit2) if unit1 and unit2 and unit1.cell < unit2.cell then return true else return false end end table.sort(group.units, cellGreater) end -- compute the size of the cells, rows and columns local cols = {} local rows = {} for nRow = 1, nRows do for nCol = 1, nCols do local cellNum = (nRow - 1) * nCols + nCol local cell = cells[cellNum] local colWidth = 0 local rowHeight = 0 if cols[nCol] then colWidth = cols[nCol].width end if rows[nRow] then rowHeight = rows[nRow].height end if cell then cell.width = veafUnits.DefaultCellWidth + (spacing * veafUnits.DefaultCellWidth) cell.height = veafUnits.DefaultCellHeight + (spacing * veafUnits.DefaultCellHeight) local unit = cell.unit if unit then unit.cell = cellNum if unit.width and unit.width > 0 then cell.width = unit.width + (spacing * unit.width) end if unit.length and unit.length > 0 then cell.height = unit.length + (spacing * unit.length) end if unit.size then cell.width = unit.size.width + (spacing * unit.size.width) cell.height = unit.size.height + (spacing * unit.size.height) end end if not unit.fitToUnit then -- make the cell square if cell.width > cell.height then cell.height = cell.width elseif cell.width < cell.height then cell.width = cell.height end end if cell.width > colWidth then colWidth = cell.width end if cell.height > rowHeight then rowHeight = cell.height end end cols[nCol] = {} cols[nCol].width = colWidth rows[nRow] = {} rows[nRow].height = rowHeight end end -- compute the size of the grid local totalWidth = 0 local totalHeight = 0 for nCol = 1, #cols do totalWidth = totalWidth + cols[nCol].width end for nRow = 1, #rows do -- bottom -> up totalHeight = totalHeight + rows[#rows-nRow+1].height end veaf.loggers.get(veafUnits.Id):trace(string.format("totalWidth = %d",totalWidth)) veaf.loggers.get(veafUnits.Id):trace(string.format("totalHeight = %d",totalHeight)) -- place the grid local currentColLeft = spawnPoint.z - totalWidth/2 local currentColTop = spawnPoint.x - totalHeight/2 for nCol = 1, #cols do veaf.loggers.get(veafUnits.Id):trace(string.format("currentColLeft = %d",currentColLeft)) cols[nCol].left = currentColLeft cols[nCol].right= currentColLeft + cols[nCol].width currentColLeft = cols[nCol].right end for nRow = 1, #rows do -- bottom -> up veaf.loggers.get(veafUnits.Id):trace(string.format("currentColTop = %d",currentColTop)) rows[#rows-nRow+1].bottom = currentColTop rows[#rows-nRow+1].top = currentColTop + rows[#rows-nRow+1].height currentColTop = rows[#rows-nRow+1].top end -- compute the centers and extents of the cells for nRow = 1, nRows do for nCol = 1, nCols do local cellNum = (nRow - 1) * nCols + nCol local cell = cells[cellNum] if cell then cell.top = rows[nRow].top cell.bottom = rows[nRow].bottom cell.left = cols[nCol].left cell.right = cols[nCol].right cell.center = {} cell.center.x = cell.left + math.random((cell.right - cell.left) / 10, (cell.right - cell.left) - ((cell.right - cell.left) / 10)) cell.center.y = cell.top + math.random((cell.bottom - cell.top) / 10, (cell.bottom - cell.top) - ((cell.bottom - cell.top) / 10)) end end end --find the heading offset relative to the group's heading to spawn the units perpendicular to the road -- local convoyHDGoffset = 90 -- if hasDest then -- local road_x, road_z = land.getClosestPointOnRoads('roads',spawnPoint.x, spawnPoint.z) -- local roadPoint = veaf.placePointOnLand({x = road_x, y = 0, z = road_z}) -- local nearestRoadHDG = mist.utils.getHeadingPoints(spawnPoint, roadPoint,false) * 180 / math.pi -- veaf.loggers.get(veafUnits.Id):trace(string.format("HDG to nearest road : %s", veaf.p(nearestRoadHDG))) -- veaf.loggers.get(veafUnits.Id):trace(string.format("Group HDG : %s", veaf.p(hdg))) -- if nearestRoadHDG then -- nearestRoadHDG = nearestRoadHDG - hdg -- if nearestRoadHDG < 0 then -- nearestRoadHDG = nearestRoadHDG + 360 -- end -- if nearestRoadHDG >= 180 then -- convoyHDGoffset = 270 -- end -- end -- end -- randomly place the units for _, cell in pairs(cells) do veaf.loggers.get(veafUnits.Id):trace(string.format("cell = %s",veaf.p(cell))) local unit = cell.unit if unit then unit.spawnPoint = {} if not cell.center then veaf.loggers.get(veafUnits.Id):error(string.format("Cannot find cell.center !")) veaf.loggers.get(veafUnits.Id):error(string.format("cell = %s",veaf.p(cell))) veaf.loggers.get(veafUnits.Id):error(string.format("group = %s",veaf.p(group))) end unit.spawnPoint.z = cell.center.x if unit.random and spacing > 0 then unit.spawnPoint.z = unit.spawnPoint.z + math.random(-((spacing-1) * (unit.width or veafUnits.DefaultCellWidth))/2, ((spacing-1) * (unit.width or veafUnits.DefaultCellWidth))/2) end unit.spawnPoint.x = cell.center.y if unit.random and spacing > 0 then unit.spawnPoint.x = unit.spawnPoint.x + math.random(-((spacing-1) * (unit.length or veafUnits.DefaultCellHeight))/2, ((spacing-1) * (unit.length or veafUnits.DefaultCellHeight))/2) end unit.spawnPoint.y = spawnPoint.y -- take into account group rotation, if needed if hdg > 0 then local angle = mist.utils.toRadian(hdg) local x = unit.spawnPoint.z - spawnPoint.z local y = unit.spawnPoint.x - spawnPoint.x local x_rotated = x * math.cos(angle) + y * math.sin(angle) local y_rotated = -x * math.sin(angle) + y * math.cos(angle) unit.spawnPoint.z = x_rotated + spawnPoint.z unit.spawnPoint.x = y_rotated + spawnPoint.x end -- unit heading if hasDest then --apply the offset when the group has a destination, 0 will make them spawn in line, 90 or 270 perpendicular to the group's hdg (the road if the group's hdg was set properly) etc. unit.hdg = 0 --convoyHDGoffset end if unit.hdg then local unitHeading = unit.hdg + hdg -- don't forget to add group heading if unitHeading > 360 then unitHeading = unitHeading - 360 end unit.spawnPoint.hdg = mist.utils.toRadian(unitHeading) else unit.spawnPoint.hdg = 0 -- due north end end end return group, cells end function veafUnits.removePathfindingFixUnit(groupName) local group = Group.getByName(groupName) if group then local units = group:getUnits() if units then for _,unit in pairs(units) do if unit then local unitType = unit:getTypeName() if unitType and unitType == veafUnits.DefaultPathfindingUnitType then unit:destroy() break end end end end end end function veafUnits.logGroupsListInMarkdown() local function _sortGroupNameCaseInsensitive(g1,g2) if g1 and g1.group and g1.group.groupName and g2 and g2.group and g2.group.groupName then return string.lower(g1.group.groupName) < string.lower(g2.group.groupName) else return string.lower(g1) < string.lower(g2) end end local text = [[ This goes in [documentation\content\Mission maker\references\group-list.md]: |Name|Description|Aliases| |--|--|--| ]] veaf.loggers.get(veafUnits.Id):info(text) -- make a copy of the table local groupsCopy = {} for _, g in pairs(veafUnits.GroupsDatabase) do if not g.hidden then table.insert(groupsCopy, g) end end -- sort the copy table.sort(groupsCopy, _sortGroupNameCaseInsensitive) -- use the keys to retrieve the values in the sorted order for _, g in pairs(groupsCopy) do text = "|" .. g.group.groupName .. "|" .. g.group.description .. "|" .. table.concat(g.aliases, ", ") .. "|\n" veaf.loggers.get(veafUnits.Id):info(text) end end function veafUnits.logUnitsListInMarkdown() local function _sortUnitNameCaseInsensitive(u1,u2) if u1 and u1.name and u2 and u2.name then return string.lower(u1.name) < string.lower(u2.name) else return string.lower(u1) < string.lower(u2) end end local text = [[ This goes in [documentation\content\Mission maker\references\units-list.md]: |Name|Description|Aliases| |--|--|--| ]] veaf.loggers.get(veafUnits.Id):info(text) -- make a copy of the table local units = {} for k, data in pairs(dcsUnits.DcsUnitsDatabase) do local u = { name = k } for _, aliasData in pairs(veafUnits.UnitsDatabase) do if aliasData and aliasData.unitType and string.lower(aliasData.unitType) == string.lower(k) then u.aliases = aliasData.aliases end end if data then u.description = data.description u.typeName = data.type end table.insert(units, u) end -- sort the copy table.sort(units, _sortUnitNameCaseInsensitive) -- use the keys to retrieve the values in the sorted order for _, u in pairs(units) do -- serialize its fields text = "|" .. u.name .. "|" if u.description then text = text .. u.description end text = text .. "|" if u.aliases then text = text .. table.concat(u.aliases, ", ") end text = text .. "|" veaf.loggers.get(veafUnits.Id):info(text) end end ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Units databases ------------------------------------------------------------------------------------------------------------------------------------------------------------- veafUnits.UnitsDatabase = { { aliases = {"hq7"}, unitType = "HQ-7_LN_SP", }, { aliases = {"hq7eo"}, unitType = "HQ-7_LN_EO", }, { aliases = {"sa8", "sa-8"}, unitType = "Osa 9A33 ln", }, { aliases = {"sa9", "sa-9"}, unitType = "Strela-1 9P31" }, { aliases = {"sa13", "sa-13"}, unitType = "Strela-10M3", }, { aliases = {"sa15", "sa-15"}, unitType = "Tor 9A331", }, { aliases = {"sa18", "sa-18", "manpad"}, unitType = "SA-18 Igla-S manpad", }, { aliases = {"dogear"}, unitType = "Dog Ear radar", }, { aliases = {"shilka"}, unitType = "ZSU-23-4 Shilka", }, { aliases = {"tarawa"}, unitType = "LHA_Tarawa", }, { aliases = {"blue-ewr"}, unitType = "FPS-117", }, { aliases = {"red-ewr"}, unitType = "1L13 EWR", }, { aliases = {"avenger"}, unitType = "M1097 Avenger", }, } ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Groups databases ------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Syntax : ------------ -- -- aliases : list of aliases which can be used to designate this group, case insensitive -- disposition : height and width (in cells) of the group layout template (see explanation of group layouts below) -- units : list of all the units composing the group. Each unit in the list is composed of : -- alias : alias of the unit in the VEAF units database, or actual DCS type name in the DCS units database -- cell : preferred layout cell ; the unit will be spawned in this cell, in the layout defined in the *layout* field. (see explanation of group layouts below) ; when nothing else is specified, a number after the unit alias is considered to be the *cell* parameter -- size : fixes the cell size (in meters), instead of relying on the contained unit size (modified with the *spacing* parameter) ; can be either a table with width and height, or a number for square cells -- number : either a number, which will be the quantity of this unit type spawned ; or a table, with *min* and *max* values that will be used to spawn a random quantity of this unit typ -- hdg : the unit heading will mean that, if the group is spawned facing north, this unit will be facing this heading (in degrees). If not set, units will face the group heading -- random : if set, the unit will be placed randomly in the cell, leaving a one unit size margin around. -- fitToUnit : if set, the cell around the unit will not be a square but a rectangle of the unit's exact size (plus the spacing, if set) -- description = human-friendly name for the group -- groupName = name used when spawning this group (will be flavored with a numerical suffix) -- -- empty cells measure 10m x 10m veafUnits.GroupsDatabase = { --China { aliases = {"hq7"}, group = { disposition = { h= 5, w= 5}, units = { --STR {"HQ-7_STR_SP", cell = 8}, --LN {"HQ-7_LN_SP", cell = 1, hdg = 300}, {"HQ-7_LN_SP", cell = 5, hdg = 60}, {"HQ-7_LN_SP", cell = 23, hdg = 180}, --supply truck {"Ural-375", random=true}, }, description = "HQ-7 SAM site", groupName = "HQ-7" }, }, { aliases = {"hq7_single"}, group = { disposition = { h= 3, w= 3}, units = { --LN {"HQ-7_LN_SP", cell = 1}, --supply truck {"Ural-375", random=true}, }, description = "HQ-7 SAM site", groupName = "HQ-7" }, }, { aliases = {"hq7-noew"}, group = { disposition = { h= 5, w= 5}, units = {{"HQ-7_LN_SP", cell = 1, hdg = 300}, {"HQ-7_LN_SP", cell = 5, hdg = 60}, {"HQ-7_LN_SP", cell = 23, hdg = 180}, {"Ural-375", random=true},}, description = "HQ-7 SAM site without STR", groupName = "HQ-7" }, }, { aliases = {"hq7eo"}, group = { disposition = { h= 5, w= 5}, units = { --STR {"HQ-7_STR_SP", cell = 8}, --LN {"HQ-7_LN_EO", cell = 1, hdg = 300}, {"HQ-7_LN_EO", cell = 5, hdg = 60}, {"HQ-7_LN_EO", cell = 23, hdg = 180}, --supply truck {"Ural-375", random=true}, }, description = "HQ-7EO SAM site", groupName = "HQ-7" }, }, { aliases = {"hq7eo_single"}, group = { disposition = { h= 3, w= 3}, units = { --LN {"HQ-7_LN_EO", cell = 1}, --supply truck {"Ural-375", random=true}, }, description = "HQ-7EO SAM site", groupName = "HQ-7" }, }, { aliases = {"hq7eo-noew"}, group = { disposition = { h= 5, w= 5}, units = {{"HQ-7_LN_EO", cell = 1, hdg = 300}, {"HQ-7_LN_EO", cell = 5, hdg = 60}, {"HQ-7_LN_EO", cell = 23, hdg = 180}, {"Ural-375", random=true},}, description = "HQ-7EO SAM site without STR", groupName = "HQ-7" }, }, --Warsaw Pact { aliases = {"sa2", "sa-2", "fs"}, group = { disposition = { h= 6, w= 8}, units = { {"SNR_75V", cell = 20}, {"p-19 s-125 sr", cell = 48}, {"S_75M_Volhov", cell = 2, hdg = 315}, {"S_75M_Volhov", cell = 6, hdg = 45}, {"S_75M_Volhov", cell = 17, hdg = 270}, {"S_75M_Volhov", cell = 24, hdg = 90}, {"S_75M_Volhov", cell = 34, hdg = 225}, {"S_75M_Volhov", cell = 38, hdg = 135}, {"ZSU_57_2", number = {min=1, max=2}, random=true}, {"S-60_Type59_Artillery", number = {min=1, max=2}, random=true}, {"ZIL-135", number = {min = 1, max = 2}, random=true}, }, description = "SA-2 SAM site", groupName = "SA2" }, }, { aliases = {"sa3", "sa-3", "lb"}, group = { disposition = { h= 7, w= 9}, units = { {"p-19 s-125 sr", cell = 1}, {"snr s-125 tr", cell = 33}, {"5p73 s-125 ln", cell = 18, hdg = 30}, {"5p73 s-125 ln", cell = 30, hdg = 270}, {"5p73 s-125 ln", cell = 61, hdg = 150}, {"ZSU_57_2", number = {min=1, max=2}, random=true}, {"S-60_Type59_Artillery", number = {min=1, max=2}, random=true}, {"ZIL-135", number = {min = 1, max = 2}, random=true}, }, description = "SA-3 SAM site", groupName = "SA3" }, }, { -- Sa-5 SAM site (2 launcher battery configuration, IRL 5 maximum could be seen deployed on one site). Note: doesn't come out exactly as planned when spawned, but close enough aliases = {"sa5", "sa-5", "S-200", "S200", "s200", "s-200"}, group = { disposition = {h= 155, w= 120}, units = { -- Search radar unit {"RLS_19J6", cell = 17614, size = 10}, -- Track radar unit {"RPC_5N62V", cell = 15118, size = 10}, --generator units {"generator_5i57", hdg = 80, cell = 15358, size = 10}, {"generator_5i57", hdg = 75, cell = 17854, size = 10}, --Track Radar, Search Radar generator -- launchers --battery 1 {"S-200_Launcher", hdg = 2, cell = 676, size = 10}, {"S-200_Launcher", hdg = 4, cell = 702, size = 10}, {"S-200_Launcher", hdg = 358, cell = 2749, size = 10}, {"S-200_Launcher", hdg = 358, cell = 3069, size = 10}, {"S-200_Launcher", hdg = 358, cell = 4786, size = 10}, {"S-200_Launcher", hdg = 355, cell = 5115, size = 10}, --battery 2 {"S-200_Launcher", hdg = 347, cell = 7231, size = 10}, {"S-200_Launcher", hdg = 343, cell = 8045, size = 10}, {"S-200_Launcher", hdg = 341, cell = 8935, size = 10}, {"S-200_Launcher", hdg = 355, cell = 9962, size = 10}, {"S-200_Launcher", hdg = 350, cell = 10734, size = 10}, {"S-200_Launcher", hdg = 340, cell = 11781, size = 10}, -- missile loading trucks (emulated, 1 per launcher for simplicity, 2 IRL) --battery 1 {"ZIL-135", hdg = 174, cell = 76, size = 10}, {"ZIL-135", hdg = 181, cell = 102, size = 10}, {"ZIL-135", hdg = 194, cell = 2149, size = 10}, {"ZIL-135", hdg = 179, cell = 2469, size = 10}, {"ZIL-135", hdg = 165, cell = 4186, size = 10}, {"ZIL-135", hdg = 183, cell = 4515, size = 10}, --battery 2 {"ZIL-135", hdg = 157, cell = 6631, size = 10}, {"ZIL-135", hdg = 175, cell = 7445, size = 10}, {"ZIL-135", hdg = 165, cell = 8335, size = 10}, {"ZIL-135", hdg = 175, cell = 9362, size = 10}, {"ZIL-135", hdg = 172, cell = 10134, size = 10}, {"ZIL-135", hdg = 179, cell = 11181, size = 10}, -- C2 units --battery 1 {"ZIL-131 KUNG", hdg = 192, cell = 2730, size = 10}, --battery 2 {"ZIL-131 KUNG", hdg = 170, cell = 9262, size = 10}, --site wide {"ZIL-131 KUNG", cell = 14616, size = 10} }, description = "S200 SAM site", groupName = "S200" }, }, { aliases = {"sa6", "sa-6", "06"}, group = { disposition = { h= 7, w= 7}, units = { {"Kub 1S91 str", cell = 25}, {"Kub 2P25 ln", cell = 4, hdg = 180}, {"Kub 2P25 ln", cell = 22, hdg = 90}, {"Kub 2P25 ln", cell = 28, hdg = 270}, {"Kub 2P25 ln", cell = 46, hdg = 0}, {"ZSU-23-4 Shilka", number = {min=1, max=2}, random=true}, {"ATZ-5", random=true}, {"ZIL-135", number = {min = 1, max = 2}, random=true}, {"Ural-375 PBU", random=true} }, description = "SA-6 SAM site", groupName = "SA6" }, }, { aliases = {"sa8_squad"}, group = { disposition = { h= 4, w= 4}, units = {{"Osa 9A33 ln", random = true}, {"GAZ-66", random=true}}, description = "Sa-8 SAM site", groupName = "SA8" }, }, { aliases = {"sa9_squad"}, group = { disposition = { h= 4, w= 4}, units = {{"Strela-1 9P31", random = true}, {"GAZ-66", random=true}}, description = "Sa-9 SAM site", groupName = "SA9" }, }, { aliases = {"sa10", "s300", "bb"}, group = { disposition = { h= 10, w= 13}, units = { {"S-300PS 40B6MD sr", cell = 130}, {"S-300PS 40B6M tr", cell = 7}, {"S-300PS 5P85C ln", cell = 29}, {"S-300PS 5P85D ln", cell = 37}, {"S-300PS 5P85D ln", cell = 43}, {"S-300PS 5P85C ln", cell = 49}, {"S-300PS 5P85C ln", cell = 57}, {"S-300PS 5P85D ln", cell = 61}, {"S-300PS 5P85D ln", cell = 71}, {"S-300PS 5P85C ln", cell = 73}, {"S-300PS 64H6E sr", cell = 98}, {"S-300PS 54K6 cp", cell = 118}, {"ZSU-23-4 Shilka", number = {min=1, max=2}, random=true}, {"2S6 Tunguska", random=true}, }, description = "S300 SAM site", groupName = "S300" }, }, { aliases = {"sa11", "sa-11", "sd"}, group = { disposition = { h= 9, w= 9}, units = { {"SA-11 Buk SR 9S18M1", cell = 42}, {"SA-11 Buk CC 9S470M1", cell = 39}, {"SA-11 Buk LN 9A310M1", cell = 1}, {"SA-11 Buk LN 9A310M1", cell = 5}, {"SA-11 Buk LN 9A310M1", cell = 9}, {"SA-11 Buk LN 9A310M1", cell = 72}, {"SA-11 Buk LN 9A310M1", cell = 76}, {"SA-11 Buk LN 9A310M1", cell = 81}, {"ZSU-23-4 Shilka", number = {min=1, max=2}, random=true}, {"ATZ-5", random=true}, {"Ural-375", number = {min = 1, max = 2}, random=true}, }, description = "SA-11 SAM site", groupName = "SA11" }, }, { aliases = {"sa13_squad"}, group = { disposition = { h= 4, w= 4}, units = {{"Strela-10M3", random = true}, {"GAZ-66", random=true}}, description = "Sa-13 SAM site", groupName = "SA13" }, }, { aliases = {"sa15_squad"}, group = { disposition = { h= 4, w= 4}, units = {{"Tor 9A331", random = true}, {"GAZ-66", random=true}}, description = "Sa-15 SAM site", groupName = "SA15" }, }, { aliases = {"sa15m2_squad"}, group = { disposition = { h= 4, w= 4}, units = {{"CHAP_TorM2", random = true}, {"GAZ-66", random=true}}, description = "Sa-15M2 SAM site", groupName = "SA15" }, }, { aliases = {"sa22_squad"}, group = { disposition = { h= 4, w= 4}, units = {{"CHAP_PantsirS1", random = true}, {"GAZ-66", random=true}}, description = "SA-22 SAM site", groupName = "SA22" }, }, { -- insurgent sa18 squad aliases = {"insurgent_manpad_squad", "ins_manpad"}, group = { disposition = {h= 3, w= 3}, units = { -- IglaS Command Unit {"MANPADS SA-18 Igla \"Grouse\" C2", random=true}, -- IglaS {"Igla manpad INS", random=true}, -- Troops {"Infantry AK Ins", number = {min=2, max=3}, random=true}, -- Transport {"HL_DSHK", random=true} }, description = "Insurgent Sa-18 Manpad Squad", groupName = "Insurgent Manpad Squad" }, }, { -- sa18 squad aliases = {"sa18_squad"}, group = { disposition = {h= 3, w= 3}, units = { -- IglaS Command Unit {"MANPADS SA-18 Igla \"Grouse\" C2", random=true}, -- IglaS {"SA-18 Igla manpad", number = {min=1, max=2}, random=true}, -- Troops {"Infantry AK", number = {min=2, max=4}, random=true}, --Transport {"UAZ-469", random=true} }, description = "Sa-18 Manpad Squad", groupName = "Red Manpad Squad" }, }, { -- sa18s squad aliases = {"sa18s_squad"}, group = { disposition = {h= 4, w= 4}, units = { -- IglaS Command Unit {"MANPADS SA-18 Igla-S \"Grouse\" C2", random=true}, -- IglaS {"SA-18 Igla-S manpad", number = {min=1, max=2}, random=true}, -- Troops {"Infantry AK ver2", number = {min=2, max=6}, random=true}, --Transport {"Tigr_233036", random=true} }, description = "Sa-18S Manpad Squad", groupName = "Red Modern Manpad Squad" }, }, { aliases = {"sa19_squad"}, group = { disposition = { h= 4, w= 4}, units = {{"2S6 Tunguska", random = true}, {"Ural-375", random=true}}, description = "Sa-19 SAM site", groupName = "SA19" }, }, { -- red ewr position aliases = {"red_ewr", "ewr"}, group = { disposition = {h= 7, w= 7}, units = { -- Radar unit {"55G6 EWR", cell = 25}, -- IglaS Command Unit {"MANPADS SA-18 Igla \"Grouse\" C2", random=true}, -- IglaS {"SA-18 Igla manpad", random=true}, -- C2 {"Ural-375 PBU", random=true} }, description = "Red EWR", groupName = "Red EWR" }, }, --NATO { aliases = {"rapier_optical", "rpo"}, group = { disposition = { h= 5, w= 5}, units = { {"rapier_fsa_optical_tracker_unit", cell = 9}, {"rapier_fsa_optical_tracker_unit", cell = 17}, {"rapier_fsa_launcher", cell = 1, hdg = 315}, {"rapier_fsa_launcher", cell = 5, hdg = 45}, {"rapier_fsa_launcher", cell = 21, hdg = 225}, {"rapier_fsa_launcher", cell = 25, hdg = 135}, --supply/crew truck {"Land_Rover_101_FC", number = {min=1, max = 2}, random = true}, }, description = "Rapier SAM site", groupName = "Rapier" }, }, { aliases = {"rapier_radar", "rpr"}, group = { disposition = { h= 5, w= 5}, units = { {"rapier_fsa_blindfire_radar", cell = 13}, {"rapier_fsa_optical_tracker_unit", cell = 9}, {"rapier_fsa_optical_tracker_unit", cell = 17}, {"rapier_fsa_launcher", cell = 1, hdg = 315}, {"rapier_fsa_launcher", cell = 5, hdg = 45}, {"rapier_fsa_launcher", cell = 21, hdg = 225}, {"rapier_fsa_launcher", cell = 25, hdg = 135}, --supply/crew truck {"Land_Rover_101_FC", number = {min=1, max = 2}, random = true}, }, description = "Rapier SAM site with radar", groupName = "Rapier-radar" }, }, { -- Stinger Squad aliases = {"stinger_squad"}, group = { disposition = {h= 4, w= 4}, units = { -- Stinger Command Unit {"MANPADS Stinger C2", random=true}, {"MANPADS Stinger C2", random=true}, -- Stinger {"Soldier stinger", random=true}, {"Soldier stinger", random=true}, -- Troops {"Soldier M4 GRG", number = {min=3, max=4}, random=true}, --Transport {"Hummer", random=true}, {"Hummer", random=true} }, description = "Stinger Manpad Squad", groupName = "Blue Manpad Squad" }, }, { aliases = {"avenger_squad"}, group = { disposition = { h= 4, w= 4}, units = {{"M1097 Avenger", random = true}, {"M 818", random=true}}, description = "Avenger SAM site", groupName = "Avenger" }, }, { aliases = {"roland"}, group = { disposition = { h= 5, w= 5}, units = {{"Roland Radar", cell = 8}, {"Roland ADS", cell = 1 , hdg = 300}, {"Roland ADS", cell = 5, hdg = 60}, {"Roland ADS", cell = 23, hdg = 180}, {"M 818", random=true}}, description = "Roland SAM site", groupName = "Roland" }, }, { aliases = {"roland-noew"}, group = { disposition = { h= 5, w= 5}, units = {{"Roland ADS", cell = 1 , hdg = 300}, {"Roland ADS", cell = 5, hdg = 60}, {"Roland ADS", cell = 23, hdg = 180}, {"M 818", random=true}}, description = "Roland SAM site", groupName = "Roland" }, }, { -- NASAMS SHORAD system with 120C aliases = {"nasams_c", "nasams", "NASAMS", "NASAMS_C"}, group = { disposition = { h= 7, w= 11}, units = { -- Search radar unit {"NASAMS_Radar_MPQ64F1", cell = 41}, -- launchers {"NASAMS_LN_C", hdg = 315, cell = 4}, {"NASAMS_LN_C", hdg = 45, cell = 11}, {"NASAMS_LN_C", hdg = 225, cell = 70}, {"NASAMS_LN_C", hdg = 135, cell = 77}, -- C2 {"NASAMS_Command_Post", cell = 34}, -- a supply truck or three {"M 818", number = {min=1, max=3}, random=true}, --IR defense {"M1097 Avenger", number = {min=1, max=2}, random=true} }, description = "NASAMS C battery", groupName = "NASAMS C battery" }, }, { -- NASAMS SHORAD system with 120B aliases = {"nasams_b", "NASAMS_B"}, group = { disposition = { h= 7, w= 11}, units = { -- Search radar unit {"NASAMS_Radar_MPQ64F1", cell = 41}, -- launchers {"NASAMS_LN_B", hdg = 315, cell = 4}, {"NASAMS_LN_B", hdg = 45, cell = 11}, {"NASAMS_LN_B", hdg = 225, cell = 70}, {"NASAMS_LN_B", hdg = 135, cell = 77}, -- C2 {"NASAMS_Command_Post", cell = 34}, -- a supply truck or three {"M 818", number = {min=1, max=3}, random=true}, --IR defense {"M1097 Avenger", number = {min=1, max=2}, random=true} }, description = "NASAMS B battery", groupName = "NASAMS B battery" }, }, { aliases = {"hawk", "ha", "mim-23"}, group = { disposition = { h= 40, w= 40}, units = { {"Hawk sr", cell = 816}, {"Hawk cwar", cell = 826}, {"Hawk cwar", cell = 1100}, {"Hawk tr", cell = 381, hdg = 0}, {"Hawk tr", cell = 1208, hdg = 240}, {"Hawk tr", cell = 1231, hdg = 120}, {"Hawk pcp", cell = 941}, {"Hawk ln", cell = 22, hdg = 0}, {"Hawk ln", cell = 297, hdg = 300 }, {"Hawk ln", cell = 306, hdg = 60}, {"Hawk ln", cell = 1042, hdg = 300}, {"Hawk ln", cell = 1401, hdg = 240 }, {"Hawk ln", cell = 1568, hdg = 180}, {"Hawk ln", cell = 1080, hdg = 60}, {"Hawk ln", cell = 1440, hdg = 120 }, {"Hawk ln", cell = 1588, hdg = 180}, -- a supply truck or three {"M 818", number = {min=4, max=6}, random=true}, --AAA defense {"Vulcan", number = {min=2, max=3}, random=true}, --IR defense {"M1097 Avenger", random=true}, }, description = "Hawk SAM site", groupName = "Hawk" }, }, { aliases = {"patriot", "pa", "mim-104"}, group = { disposition = { h= 7, w= 12}, units = { {"Patriot str", cell = 66, hdg = 0}, {"Patriot cp" , cell = 78}, {"Patriot AMG", cell = 79}, {"Patriot ECS", cell = 67}, {"Patriot EPP", cell = 68}, {"Patriot ln", cell = 1, hdg = 280}, {"Patriot ln", cell = 2, hdg = 300}, {"Patriot ln", cell = 28, hdg = 20}, {"Patriot ln", cell = 29, hdg = 40}, {"Patriot ln", cell = 32, hdg = 330}, {"Patriot ln", cell = 33, hdg = 310}, {"Patriot ln", cell = 11, hdg = 60}, {"Patriot ln", cell = 12, hdg = 80}, --supply trucks {"M 818", number = {min=2, max=5}, random=true}, --AAA defense {"Vulcan", number = {min=0, max=1}, cell = 60}, {"Vulcan", number = {min=0, max=1}, cell = 48}, {"Vulcan", cell = 54}, }, description = "Patriot SAM site", groupName = "Patriot" }, }, { -- blue ewr position aliases = {"blue_ewr"}, group = { disposition = {h= 7, w= 7}, units = { -- Radar unit {"FPS-117 Dome", cell = 25}, -- IR Defense {"M1097 Avenger", random=true} }, description = "Blue EWR", groupName = "Blue EWR" }, }, --infantry { aliases = {"infantry section", "infsec"}, group = { disposition = { h= 10, w= 4}, units = {{"IFV BTR-80", cell=38, random=true},{"IFV BTR-80", cell=39, random=true},{"INF Soldier AK", number = {min=12, max=30}, random=true}, {"SA-18 Igla manpad", number = {min=0, max=2}, random=true}}, description = "Mechanized infantry section with APCs", groupName = "Mechanized infantry section" }, }, { aliases = {"US infgroup"}, group = { disposition = { h = 5, w = 5}, units = {{"Hummer", number = {min=1, max=2}, random=true},{"Soldier M249", number = {min=1, max=2}, random=true},{"Soldier M4", number = {min=2, max=4}, random=true},{"Soldier M4 GRG", number = {min=6, max=15}, random=true}}, description = "US infantry group", groupName = "US infantry group", }, }, --artillery { aliases = {"insurgent_arty"}, group = { disposition = { h = 2, w = 4}, units = { {"tt_B8M1", number = {min=1, max=2}}, {"HL_B8M1", number = {min=1, max=2}} }, description = "Insurgent artillery battery", groupName = "Insurgent artillery battery", }, }, { aliases = {"mortar"}, group = { disposition = { h = 2, w = 4}, units = { {"2B11 mortar", number = 4} }, description = "2B11 Mortar team", groupName = "2B11 Mortar team", }, }, { aliases = {"M-109"}, group = { disposition = { h = 4, w = 4}, units = { {"M-109", number = 8}, {"MLRS FDDM", number = 1}, {"M 818", number = 1} }, description = "M-109 artillery battery", groupName = "M-109 artillery battery", }, }, { aliases = {"PLZ05"}, group = { disposition = { h = 2, w = 3}, units = { {"PLZ05", number = 3}, {"Grad_FDDM", number = 1}, {"Ural-375", number = 1} }, description = "PLZ05 artillery battery", groupName = "PLZ05 artillery battery", }, }, { aliases = {"Msta"}, group = { disposition = { h = 2, w = 3}, units = { {"SAU Msta", number = 3}, {"Grad_FDDM", number = 1}, {"Ural-375", number = 1} }, description = "Msta artillery battery", groupName = "Msta artillery battery", }, }, { aliases = {"MLRS"}, group = { disposition = { h = 2, w = 4}, units = { {"MLRS", number = 4}, {"MLRS FDDM", number = 1}, {"M 818", number = 1} }, description = "M270 MLRS artillery battery", groupName = "M270 MLRS artillery battery", }, }, { aliases = {"SmerchCM"}, group = { disposition = { h = 2, w = 4}, units = { {"Smerch", number = 4}, {"Grad_FDDM", number = 1}, {"ZIL-135", number = 2} }, description = "Smerch (CM) MLRS artillery battery", groupName = "Smerch (CM) MLRS artillery battery", }, }, { aliases = {"SmerchHE"}, group = { disposition = { h = 2, w = 4}, units = { {"Smerch_HE", number = 4}, {"Grad_FDDM", number = 1}, {"ZIL-135", number = 2} }, description = "Smerch (HE) MLRS artillery battery", groupName = "Smerch (HE) MLRS artillery battery", }, }, { aliases = {"Uragan"}, group = { disposition = { h = 2, w = 4}, units = { {"Uragan_BM-27", number = 4}, {"Grad_FDDM", number = 1}, {"ZIL-135", number = 2} }, description = "Uragan MLRS artillery battery", groupName = "Uragan MLRS artillery battery", }, }, { aliases = {"Grad"}, group = { disposition = { h = 2, w = 4}, units = { {"Grad-URAL", number = 4}, {"Grad_FDDM", number = 1}, {"Ural-375", number = 2} }, description = "Grad MLRS artillery battery", groupName = "Grad MLRS artillery battery", }, }, --convoys { aliases = {"US supply convoy","blueconvoy"}, group = { disposition = { h = 20, w = 20}, units = { {"Hummer", number = {min=2, max=4}, random=true}, {"Truck M 818", number = {min=3, max=6}, random=true}, {"Truck M978 HEMTT Tanker", number = {min=0, max=3}, random=true}, {"Truck Predator GCS", number = {min=0, max=2}, random=true}, {"Truck Predator TrojanSpirit", number = {min=0, max=2}, random=true} }, description = "US supply convoy", groupName = "US supply convoy", }, }, { aliases = {"RU supply convoy with defense","redconvoy-def"}, group = { disposition = { h = 20, w = 20}, units = { {"2S6 Tunguska", number = {min=0, max=1}, random=true}, {"Strela-10M3", number = {min=0, max=1}, random=true}, {"Strela-1 9P31", number = {min=0, max=1}, random=true}, {"ZSU-23-4 Shilka", number = {min=0, max=2}, random=true}, {"ZSU_57_2", number = {min=0, max=1}, random=true}, {"S-60_Type59_Artillery", number = {min=0, max=1}, random=true}, {"Ural-375 ZU-23", number = {min=0, max=2}, random=true}, {"UAZ-469", number = {min=2, max=4}, random=true}, {"Truck SKP-11", number = {min=1, max=3}, random=true}, {"Ural-375 PBU", number = {min=1, max=3}, random=true}, {"Truck Ural-375", number = {min=1, max=3}, random=true}, {"Truck Ural-4320 APA-5D", number = {min=1, max=3}, random=true}, {"Truck Ural-4320-31", number = {min=1, max=3}, random=true}, {"Truck Ural-4320T", number = {min=1, max=3}, random=true}, {"Truck ZiL-131 APA-80", number = {min=1, max=3}, random=true}, {"Truck ZIL-131 KUNG", number = {min=1, max=3}, random=true} }, description = "RU supply convoy with defense", groupName = "RU supply convoy with defense", }, }, { aliases = {"RU supply convoy with light defense","redconvoy-lightdef"}, group = { disposition = { h = 20, w = 20}, units = { {"ZSU-23-4 Shilka", number = {min=0, max=2}, random=true}, {"ZSU_57_2", number = {min=0, max=1}, random=true}, {"S-60_Type59_Artillery", number = {min=0, max=1}, random=true}, {"Ural-375 ZU-23", number = {min=0, max=2}, random=true}, {"UAZ-469", number = {min=2, max=4}, random=true}, {"Truck SKP-11", number = {min=1, max=3}, random=true}, {"Ural-375 PBU", number = {min=1, max=3}, random=true}, {"Truck Ural-375", number = {min=1, max=3}, random=true}, {"Truck Ural-4320 APA-5D", number = {min=1, max=3}, random=true}, {"Truck Ural-4320-31", number = {min=1, max=3}, random=true}, {"Truck Ural-4320T", number = {min=1, max=3}, random=true}, {"Truck ZiL-131 APA-80", number = {min=1, max=3}, random=true}, {"Truck ZIL-131 KUNG", number = {min=1, max=3}, random=true} }, description = "RU supply convoy with light defense", groupName = "RU supply convoy with light defense", }, }, { aliases = {"RU supply convoy with no defense","redconvoy-nodef"}, group = { disposition = { h = 20, w = 20}, units = { {"UAZ-469", number = {min=2, max=4}, random=true}, {"Truck SKP-11", number = {min=1, max=3}, random=true}, {"Ural-375 PBU", number = {min=1, max=3}, random=true}, {"Truck Ural-375", number = {min=1, max=3}, random=true}, {"Truck Ural-4320 APA-5D", number = {min=1, max=3}, random=true}, {"Truck Ural-4320-31", number = {min=1, max=3}, random=true}, {"Truck Ural-4320T", number = {min=1, max=3}, random=true}, {"Truck ZiL-131 APA-80", number = {min=1, max=3}, random=true}, {"Truck ZIL-131 KUNG", number = {min=1, max=3}, random=true} }, description = "RU supply convoy with no defense", groupName = "RU supply convoy with no defense", }, }, { aliases = {"RU small supply convoy with defense","redsmallconvoy-def"}, group = { disposition = { h = 20, w = 20}, units = { {"2S6 Tunguska", number = {min=0, max=1}, random=true}, {"Strela-10M3", number = {min=0, max=1}, random=true}, {"Strela-1 9P31", number = {min=0, max=1}, random=true}, {"ZSU-23-4 Shilka", number = {min=0, max=2}, random=true}, {"ZSU_57_2", number = {min=0, max=1}, random=true}, {"S-60_Type59_Artillery", number = {min=0, max=1}, random=true}, {"Ural-375 ZU-23", number = {min=0, max=2}, random=true}, {"UAZ-469", number = {min=1, max=2}, random=true}, {"Truck SKP-11", number = {min=1, max=2}, random=true}, {"Ural-375 PBU", number = {min=0, max=2}, random=true}, {"Truck Ural-375", number = {min=0, max=2}, random=true}, {"Truck Ural-4320 APA-5D", number = {min=0, max=2}, random=true}, {"Truck Ural-4320-31", number = {min=0, max=2}, random=true}, {"Truck Ural-4320T", number = {min=0, max=2}, random=true}, {"Truck ZiL-131 APA-80", number = {min=0, max=2}, random=true}, {"Truck ZIL-131 KUNG", number = {min=0, max=2}, random=true} }, description = "RU small supply convoy with defense", groupName = "RU small supply convoy with defense", }, }, { aliases = {"RU small supply convoy with light defense","redsmallconvoy-lightdef"}, group = { disposition = { h = 20, w = 20}, units = { {"ZSU-23-4 Shilka", number = {min=0, max=2}, random=true}, {"ZSU_57_2", number = {min=0, max=1}, random=true}, {"S-60_Type59_Artillery", number = {min=0, max=1}, random=true}, {"Ural-375 ZU-23", number = {min=0, max=2}, random=true}, {"UAZ-469", number = {min=1, max=2}, random=true}, {"Truck SKP-11", number = {min=1, max=2}, random=true}, {"Ural-375 PBU", number = {min=0, max=2}, random=true}, {"Truck Ural-375", number = {min=0, max=2}, random=true}, {"Truck Ural-4320 APA-5D", number = {min=0, max=2}, random=true}, {"Truck Ural-4320-31", number = {min=0, max=2}, random=true}, {"Truck Ural-4320T", number = {min=0, max=2}, random=true}, {"Truck ZiL-131 APA-80", number = {min=0, max=2}, random=true}, {"Truck ZIL-131 KUNG", number = {min=0, max=2}, random=true} }, description = "RU small supply convoy with light defense", groupName = "RU small supply convoy with light defense", }, }, { aliases = {"RU small supply convoy with no defense","redsmallconvoy-nodef","redconvoy","convoy"}, group = { disposition = { h = 20, w = 20}, units = { {"UAZ-469", number = {min=1, max=2}, random=true}, {"Truck SKP-11", number = {min=1, max=2}, random=true}, {"Ural-375 PBU", number = {min=0, max=2}, random=true}, {"Truck Ural-375", number = {min=0, max=2}, random=true}, {"Truck Ural-4320 APA-5D", number = {min=0, max=2}, random=true}, {"Truck Ural-4320-31", number = {min=0, max=2}, random=true}, {"Truck Ural-4320T", number = {min=0, max=2}, random=true}, {"Truck ZiL-131 APA-80", number = {min=0, max=2}, random=true}, {"Truck ZIL-131 KUNG", number = {min=0, max=2}, random=true} }, description = "RU small supply convoy with no defense", groupName = "RU small supply convoy with no defense", }, }, { -- High value offensive convoy potentially defended by Sa-15, Sa-19, Sa-13 and armor aliases = {"hv_convoy_red"}, group = { disposition = { h= 4, w= 4}, units = { --Radar defense {"Tor 9A331", number = {min=0, max=1}, random=true, hdg=0}, {"2S6 Tunguska", number = {min=0, max=1}, random=true, hdg=0}, -- scud units {"Scud_B", number = {min=0, max=2}, random=true, hdg=0}, -- armor {"T-72B3", random=true, hdg=0}, {"BTR-82A", random=true, hdg=0}, --supply truck and C2 {"ZIL-135", random=true, hdg=0}, {"Tigr_233036", random=true, hdg=0}, --IR defense {"Strela-10M3", number = {min=0, max=1}, random=true, hdg=0} }, description = "High Value Attack convoy red", groupName = "High Value Attack convoy red" }, }, { -- Offensive convoy potentially defended by Sa-15, Shilka, Sa-13 and armor aliases = {"attack_convoy_red"}, group = { disposition = { h= 4, w= 4}, units = { --Radar defense {"Tor 9A331", number = {min=0, max=1}, random=true}, {"ZSU-23-4 Shilka", random=true}, -- armor {"T-72B3", random=true}, {"BTR-82A", random=true}, --supply truck {"ZIL-135", random=true}, --IR defense {"Strela-10M3", random=true} }, description = "Attack convoy red", groupName = "Attack convoy red" }, }, { -- Quick reaction convoy potentially defended by Roland and armor aliases = {"QRC_red"}, group = { disposition = { h= 4, w= 4}, units = { --Radar defense {"Roland ADS", number = {min=0, max=1}, random=true}, -- armor {"BTR-82A", number = {min=0, max=1}, random=true}, {"BTR-82A", random=true}, --ATGM {"VAB_Mephisto", random=true}, {"VAB_Mephisto", random=true}, }, description = "Quick reaction convoy red", groupName = "Quick reaction convoy red" }, }, { -- Offensive convoy potentially defended by Sa-15, Sa-19, Sa-13 and armor aliases = {"civilian_convoy_red"}, group = { disposition = {h= 3, w= 3}, units = { -- buses {"LAZ Bus", number = {min=1,max=3}, random=true}, {"LiAZ Bus", number = {min=1,max=3}, random=true}, }, description = "Civilian convoy red", groupName = "Civilian convoy red" }, }, { -- Quick reaction convoy potentially defended by Roland and armor aliases = {"QRC_blue"}, group = { disposition = { h= 4, w= 4}, units = { --Radar defense {"Roland ADS", number = {min=0, max=1}, random=true}, -- armor {"M1128 Stryker MGS", number = {min=0, max=1}, random=true}, {"M1128 Stryker MGS", random=true}, --ATGM {"M1134 Stryker ATGM", random=true}, {"M1134 Stryker ATGM", random=true}, }, description = "Quick reaction convoy blue", groupName = "Quick reaction convoy blue" }, }, --ships { aliases = {"cargoships-nodef", "cargoships"}, group = { disposition = { h = 20, w = 20}, units = { {"Dry-cargo ship-1", number = {min=1, max=3}, random=true, size=150}, {"Dry-cargo ship-2", number = {min=1, max=3}, random=true, size=150}, {"ELNYA", number = {min=1, max=3}, random=true, size=150} }, description = "Cargo ships with no defense", groupName = "Cargo ships with no defense", }, }, { aliases = {"cargoships-escorted"}, group = { disposition = { h = 20, w = 20}, units = { {"Dry-cargo ship-1", number = {min=1, max=3}, random=true, size=150}, {"Dry-cargo ship-2", number = {min=1, max=3}, random=true, size=150}, {"ELNYA", number = {min=1, max=3}, random=true, size=150}, {"MOLNIYA", number = {min=1, max=2}, random=true, size=150}, {"ALBATROS", number = {min=1, max=2}, random=true, size=150}, {"NEUSTRASH", number = {min=0, max=1}, random=true, size=150} }, description = "Cargo ships with escort", groupName = "Cargo ships with escort", }, }, { aliases = {"combatships"}, group = { disposition = { h = 20, w = 20}, units = { {"MOLNIYA", number = {min=2, max=3}, random=true, size=150}, {"ALBATROS", number = {min=2, max=3}, random=true, size=150}, {"NEUSTRASH", number = {min=1, max=2}, random=true, size=150} }, description = "Combat ships with possible FFG defense", groupName = "Combat ships", }, }, --- --- groups made for dynamic group spawning (veafCasMission.generateAirDefenseGroup) --- { aliases = {"generateAirDefenseGroup-BLUE-5"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- hawk battery {"Hawk sr", cell = 8}, {"Hawk pcp", cell = 13}, {"Hawk tr", cell = 15}, {"Hawk ln", cell = 1, hdg = 225}, {"Hawk ln", cell = 3, hdg = 0 }, {"Hawk ln", cell = 21, hdg = 135}, -- Some M48 Chaparral {"M48 Chaparral", number = {min=2, max=4}, random=true}, -- Some Gepards {"Gepard", number = {min=2, max=4}, random=true}, -- a supply truck or three {"M 818", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-BLUE-5", groupName = "generateAirDefenseGroup-BLUE-5", }, }, { aliases = {"generateAirDefenseGroup-BLUE-4"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- Roland battery {"Roland Radar", random=true}, {"Roland ADS", random=true, hdg = 0}, {"Roland ADS", random=true, hdg = 225}, {"Roland ADS", random=true, hdg = 135}, -- Some M48 Chaparral {"M48 Chaparral", number = {min=2, max=4}, random=true}, -- Some Gepards {"Gepard", number = {min=2, max=4}, random=true}, -- a supply truck or three {"M 818", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-BLUE-4", groupName = "generateAirDefenseGroup-BLUE-4", }, }, { aliases = {"generateAirDefenseGroup-BLUE-3"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- Some Gepards {"Gepard", number = {min=2, max=4}, random=true}, -- M6 Linebacker battery {"M6 Linebacker", hdg = 0, random=true}, {"M6 Linebacker", hdg = 90, random=true}, {"M6 Linebacker", hdg = 180, random=true}, {"M6 Linebacker", hdg = 270, random=true}, -- Some M1097 Avenger {"M1097 Avenger", number = {min=2, max=4}, random=true}, -- a supply truck or three {"M 818", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-BLUE-3", groupName = "generateAirDefenseGroup-BLUE-3", }, }, { aliases = {"generateAirDefenseGroup-BLUE-2"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- Some Vulcans {"Vulcan", number = {min=2, max=4}, random=true}, -- Some M1097 Avenger {"M1097 Avenger", number = {min=2, max=4}, random=true}, -- a supply truck or three {"M 818", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-BLUE-2", groupName = "generateAirDefenseGroup-BLUE-2", }, }, { aliases = {"generateAirDefenseGroup-BLUE-1"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- Some Vulcans {"Vulcan", number = {min=1, max=3}, random=true}, -- Some M1097 Avenger {"M1097 Avenger", number = {min=0, max=1}, random=true}, -- a supply truck or three {"M 818", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-BLUE-1", groupName = "generateAirDefenseGroup-BLUE-1", }, }, { aliases = {"generateAirDefenseGroup-BLUE-0"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- Some AAV7 {"AAV7", number = {min=1, max=3}, random=true}, -- a supply truck or three {"M 818", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-BLUE-0", groupName = "generateAirDefenseGroup-BLUE-0", }, }, { aliases = {"generateAirDefenseGroup-RED-5"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- the search radar {"Dog Ear radar", random=true}, -- Tor battery {"Tor 9A331", hdg = 180, number = 1, random=true}, -- SA-8 battery {"Osa 9A33 ln", number = {min=1, max=2}, random=true}, -- Some SA13 {"Strela-10M3", number = {min=1, max=2}, random=true}, -- Some Tunguskas {"2S6 Tunguska", number = {min=1, max=2}, random=true}, -- Some ZU-57-2 {"ZSU_57_2", number = 1, random=true}, -- Some S-60 {"S-60_Type59_Artillery", number = 1, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-RED-5", groupName = "generateAirDefenseGroup-RED-5", }, }, { aliases = {"generateAirDefenseGroup-RED-4"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- the search radar {"Dog Ear radar", random=true}, -- SA-8 battery {"Osa 9A33 ln", number = {min=1, max=2}, random=true}, -- Some SA13 {"Strela-10M3", number = {min=1, max=2}, random=true}, -- Some Shilkas {"ZSU-23-4 Shilka", number = {min=1, max=2}, random=true}, -- Some ZU-57-2 {"ZSU_57_2", number = {min=1, max=1}, random=true}, -- Some S-60 {"S-60_Type59_Artillery", number = {min=0, max=1}, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-RED-4", groupName = "generateAirDefenseGroup-RED-4", }, }, { aliases = {"generateAirDefenseGroup-RED-3"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- the search radar {"Dog Ear radar", random=true}, -- SA13 battery {"Strela-10M3", number = {min=1, max=2}, random=true}, -- Some SA9 {"Strela-1 9P31", number = {min=1, max=2}, random=true}, -- Some Shilkas {"ZSU-23-4 Shilka", number = {min=1, max=2}, random=true}, -- Some ZU-57-2 {"ZSU_57_2", number = {min=0, max=1}, random=true}, -- Some S-60 {"S-60_Type59_Artillery", number = {min=0, max=1}, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-RED-3", groupName = "generateAirDefenseGroup-RED-3", }, }, { aliases = {"generateAirDefenseGroup-RED-2"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- the search radar {"Dog Ear radar", random=true}, -- SA9 battery {"Strela-1 9P31", number = {min=1, max=2}, random=true}, -- Some Shilkas {"ZSU-23-4 Shilka", number = {min=1, max=2}, random=true}, -- Some ZU-57-2 {"ZSU_57_2", number = {min=0, max=1}, random=true}, -- Some S-60 {"S-60_Type59_Artillery", number = {min=0, max=1}, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-RED-2", groupName = "generateAirDefenseGroup-RED-2", }, }, { aliases = {"generateAirDefenseGroup-RED-1"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- the search radar {"Dog Ear radar", random=true}, -- Some Shilkas {"ZSU-23-4 Shilka", number = {min=1, max=2}, random=true}, -- Some ZU-57-2 {"ZSU_57_2", number = {min=0, max=1}, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-RED-1", groupName = "generateAirDefenseGroup-RED-1", }, }, { aliases = {"generateAirDefenseGroup-RED-0"}, hidden = true, group = { disposition = { h= 7, w= 7}, units = { -- Some Ural-375 ZU-23 {"Ural-375 ZU-23", number = {min=0, max=1}, random=true}, -- Some S-60 {"S-60_Type59_Artillery", number = {min=0, max=1}, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true} }, description = "generateAirDefenseGroup-RED-0", groupName = "generateAirDefenseGroup-RED-0", }, }, --- --- Seemingly realistic russian air defense batteries --- { aliases = {"RU-SAM-Shilka-Battery", "shilka-battery"}, group = { disposition = { h= 5, w= 5}, units = { -- the search radar {"Dog Ear radar", cell = 13}, -- the actual air defense units {"ZSU-23-4 Shilka", hdg = 0, random=true}, {"ZSU-23-4 Shilka", hdg = 90, random=true}, {"ZSU-23-4 Shilka", hdg = 180, random=true}, {"ZSU-23-4 Shilka", hdg = 270, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true}, }, description = "ZSU-23-4 battery", groupName = "ZSU-23-4 battery" }, }, { aliases = {"RU-SAM-S60-Battery", "s60-battery"}, group = { disposition = { h= 5, w= 5}, units = { -- the search radar {"Dog Ear radar", cell = 13}, -- the actual air defense units {"S-60_Type59_Artillery", hdg = 0, random=true}, {"S-60_Type59_Artillery", hdg = 90, random=true}, {"S-60_Type59_Artillery", hdg = 180, random=true}, {"S-60_Type59_Artillery", hdg = 270, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true} }, description = "S-60 battery", groupName = "S-60 battery" }, }, { aliases = {"RU-SAM-SA9-Battery", "sa9-battery"}, group = { disposition = { h= 5, w= 5}, units = { -- the search radar {"Dog Ear radar", cell = 13}, -- the actual air defense units {"Strela-1 9P31", hdg = 0, random=true}, {"Strela-1 9P31", hdg = 90, random=true}, {"Strela-1 9P31", hdg = 180, random=true}, {"Strela-1 9P31", hdg = 270, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true} }, description = "SA-9 battery", groupName = "SA-9 battery" }, }, { aliases = {"RU-SAM-SA13-Battery", "sa13-battery"}, group = { disposition = { h= 5, w= 5}, units = { -- the search radar {"Dog Ear radar", cell = 13}, -- the actual air defense units {"Strela-10M3", hdg = 0, random=true}, {"Strela-10M3", hdg = 90, random=true}, {"Strela-10M3", hdg = 180, random=true}, {"Strela-10M3", hdg = 270, random=true}, -- a supply truck or three {"Ural-4320-31", number = {min=1, max=3}, random=true}, }, description = "SA-13 battery", groupName = "SA-13 battery" }, }, { aliases = {"US-refuel", "refuel-group"}, group = { disposition = { h= 1, w= 4}, units = { {"M978 HEMTT Tanker", cell = 1, fitToUnit = true}, {"M1043 HMMWV Armament", cell = 2, fitToUnit = true}, {"Truck M939 Heavy", cell = 3, fitToUnit = true}, {"Diesel Power Station 5I57A", cell = 4, fitToUnit = true}, }, description = "US refuel group", groupName = "US refuel group" }, }, } veaf.loggers.get(veafUnits.Id):info(string.format("Loading version %s", veafUnits.Version)) if veafUnits.OutputListsForDocumentation then veafUnits.logGroupsListInMarkdown() veafUnits.logUnitsListInMarkdown() end