- Refactored all CAP classes. - Improved timing - Zones are now not tied to MissionStages - CAPROUTE_<routeID>_<free> - routeID is now what is used in the naming convention. - Units taxi back to their spawn parking space and rearm there. (Units destroyed while in the Rearming or Repairing state are not taken into account)
328 lines
11 KiB
Lua
328 lines
11 KiB
Lua
---@class CAPTasking
|
|
local CAP = {}
|
|
|
|
---@param attackHelos boolean
|
|
---@return table
|
|
local function GetCAPTargetTypes(attackHelos)
|
|
local targetTypes = {
|
|
[1] = "Planes",
|
|
}
|
|
|
|
if attackHelos then
|
|
targetTypes[2] = "Helicopters"
|
|
end
|
|
|
|
return targetTypes
|
|
end
|
|
|
|
---@class CapTaskingOptions
|
|
---@field furthest Vec2
|
|
---@field closest Vec2
|
|
---@field legLength number
|
|
---@field width number
|
|
---@field hotLegDir number
|
|
|
|
|
|
---@param capZone SpearheadTriggerZone
|
|
---@param airBase Airbase
|
|
---@return CapTaskingOptions
|
|
local function GetCAPPointFromTriggerZone(airBase, capZone)
|
|
local furthestA = nil
|
|
local furthestB = nil
|
|
|
|
local furthestFromBase = nil
|
|
local furthestFromBaseDistance = 0
|
|
|
|
local furthestDistance = 0
|
|
|
|
for indexA, pointA in ipairs(capZone.verts) do
|
|
for indexB, pointB in ipairs(capZone.verts) do
|
|
if pointA ~= pointB then
|
|
local distance = Spearhead.Util.VectorDistance2d(pointA, pointB)
|
|
if distance > furthestDistance then
|
|
furthestDistance = distance
|
|
furthestA = indexA
|
|
furthestB = indexB
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local baseVec3 = airBase:getPoint()
|
|
|
|
---@type Vec2
|
|
local baseVec2 = { x = baseVec3.x, y = baseVec3.z }
|
|
|
|
local pointA = capZone.verts[furthestA]
|
|
local pointB = capZone.verts[furthestB]
|
|
local furthest = pointA
|
|
local closest = pointB
|
|
|
|
local heading = Spearhead.Util.vectorHeadingFromTo(pointA, pointB)
|
|
|
|
if Spearhead.Util.VectorDistance2d(baseVec2, pointB) > Spearhead.Util.VectorDistance2d(baseVec2, pointA) then
|
|
furthest = pointB
|
|
closest = pointA
|
|
heading = Spearhead.Util.vectorHeadingFromTo(pointB, pointA)
|
|
end
|
|
|
|
local distance = furthestDistance
|
|
if distance > 15000 then
|
|
distance = distance - 10000
|
|
end
|
|
|
|
return {
|
|
width = 10000,
|
|
furthest = furthest,
|
|
closest = closest,
|
|
legLength = distance,
|
|
hotLegDir = math.rad(heading),
|
|
orbitOriginPoint = closest
|
|
}
|
|
end
|
|
|
|
---@param airbase Airbase
|
|
---@param capZone SpearheadTriggerZone
|
|
---@param capConfig CapConfig
|
|
local GetOutboundTask = function(airbase, capZone, capConfig)
|
|
local airbaseVec3 = airbase:getPoint()
|
|
local airbaseVec2 = { x = airbaseVec3.x, y = airbaseVec3.z }
|
|
local heading = Spearhead.Util.vectorHeadingFromTo(airbaseVec2, capZone.location)
|
|
local point = Spearhead.Util.vectorMove(airbaseVec2, heading, 18520)
|
|
|
|
return {
|
|
alt = 2000,
|
|
action = "Fly Over Point",
|
|
type = "Turning Point",
|
|
alt_type = "BARO",
|
|
speed = capConfig:getMinSpeed(),
|
|
ETA = 0,
|
|
ETA_locked = false,
|
|
x = point.x,
|
|
y = point.y,
|
|
speed_locked = false,
|
|
formation_template = "",
|
|
task = {
|
|
id = "ComboTask",
|
|
params = {
|
|
tasks = {
|
|
[1] = {
|
|
id = 'EngageTargets',
|
|
params = {
|
|
maxDist = capConfig:getMaxDeviationRange() + 10 * 1852,
|
|
maxDistEnabled = capConfig:getMaxDeviationRange() > 0, -- required to check maxDist
|
|
targetTypes = GetCAPTargetTypes(false),
|
|
priority = 0
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
end
|
|
|
|
---@param groupName string
|
|
---@param airbase Airbase
|
|
---@param capZone SpearheadTriggerZone
|
|
---@param capConfig CapConfig
|
|
function CAP.getAsMissionFromAirbase(groupName, airbase, capZone, capConfig)
|
|
local points = {
|
|
[1] = GetOutboundTask(airbase, capZone, capConfig),
|
|
[2] = GetOutboundTask(airbase, capZone, capConfig),
|
|
[3] = CAP.getAsTasking(groupName, airbase, capZone, capConfig),
|
|
[4] = Spearhead.classes.capClasses.taskings.RTB.getApproachPoint(airbase, capZone.location, capConfig),
|
|
[5] = Spearhead.classes.capClasses.taskings.RTB.getInitialPoint(airbase),
|
|
[6] = Spearhead.classes.capClasses.taskings.RTB.getLandingPoint(airbase)
|
|
}
|
|
|
|
local mission = {
|
|
id = 'Mission',
|
|
params = {
|
|
airborne = true,
|
|
route = {
|
|
points = points
|
|
}
|
|
}
|
|
}
|
|
|
|
return mission
|
|
end
|
|
|
|
---@param groupName string
|
|
---@param airbase Airbase
|
|
---@param capZone SpearheadTriggerZone
|
|
---@param capConfig CapConfig
|
|
function CAP.getAsMission(groupName, airbase, capZone, capConfig)
|
|
local points = {
|
|
[1] = CAP.getAsTasking(groupName, airbase, capZone, capConfig),
|
|
[2] = Spearhead.classes.capClasses.taskings.RTB.getApproachPoint(airbase, capZone.location, capConfig),
|
|
[3] = Spearhead.classes.capClasses.taskings.RTB.getInitialPoint(airbase),
|
|
[4] = Spearhead.classes.capClasses.taskings.RTB.getLandingPoint(airbase)
|
|
}
|
|
|
|
local mission = {
|
|
id = 'Mission',
|
|
params = {
|
|
airborne = true,
|
|
route = {
|
|
points = points
|
|
}
|
|
}
|
|
}
|
|
|
|
return mission
|
|
end
|
|
|
|
---@private
|
|
---@param groupName string
|
|
---@param airbase Airbase
|
|
---@param capZone SpearheadTriggerZone
|
|
---@param capConfig CapConfig
|
|
function CAP.getAsTasking(groupName, airbase, capZone, capConfig)
|
|
local duration = math.random(capConfig:getMinDurationOnStation(), capConfig:getMaxDurationOnStation()) or 1500
|
|
|
|
local capTaskingOptions = GetCAPPointFromTriggerZone(airbase, capZone)
|
|
|
|
local durationBefore10 = duration - 600
|
|
if durationBefore10 < 0 then durationBefore10 = 0 end
|
|
local durationAfter10 = 600
|
|
if duration < 600 then
|
|
durationAfter10 = duration
|
|
end
|
|
|
|
local alt = math.random(capConfig:getMinAlt(), capConfig:getMaxAlt())
|
|
local speed = math.random(capConfig:getMinSpeed(), capConfig:getMaxSpeed())
|
|
|
|
return {
|
|
alt = alt,
|
|
action = "Turning Point",
|
|
alt_type = "BARO",
|
|
speed = speed,
|
|
ETA = 0,
|
|
ETA_locked = false,
|
|
x = capTaskingOptions.closest.x,
|
|
y = capTaskingOptions.closest.y,
|
|
speed_locked = true,
|
|
formation_template = "",
|
|
task = {
|
|
id = "ComboTask",
|
|
params = {
|
|
tasks = {
|
|
[1] = {
|
|
number = 1,
|
|
auto = false,
|
|
id = "WrappedAction",
|
|
enabled = "true",
|
|
params = {
|
|
action = {
|
|
id = "Script",
|
|
params = {
|
|
command = "pcall(Spearhead.Events.PublishOnStation, \"" .. groupName .. "\")"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
[2] = {
|
|
id = 'EngageTargets',
|
|
params = {
|
|
maxDist = capConfig:getMaxDeviationRange(),
|
|
maxDistEnabled = capConfig:getMaxDeviationRange() >= 0, -- required to check maxDist
|
|
targetTypes = GetCAPTargetTypes(false),
|
|
priority = 0
|
|
}
|
|
},
|
|
[3] = {
|
|
number = 3,
|
|
auto = false,
|
|
id = "ControlledTask",
|
|
enabled = true,
|
|
params = {
|
|
task = {
|
|
id = "Orbit",
|
|
params = {
|
|
altitude = alt,
|
|
pattern = "Anchored",
|
|
speed = speed,
|
|
point = {
|
|
x = capTaskingOptions.closest.x,
|
|
y = capTaskingOptions.closest.y
|
|
},
|
|
speedEdited = true,
|
|
clockWise = false,
|
|
hotLegDir = capTaskingOptions.hotLegDir,
|
|
legLength = capTaskingOptions.legLength,
|
|
width = capTaskingOptions.width,
|
|
}
|
|
},
|
|
stopCondition = {
|
|
duration = durationBefore10,
|
|
condition = "return Spearhead.DcsUtil.NeedsRTBInTen(\"" .. groupName .. "\", 0.10)",
|
|
}
|
|
}
|
|
},
|
|
[4] = {
|
|
number = 4,
|
|
auto = false,
|
|
id = "WrappedAction",
|
|
enabled = "true",
|
|
params = {
|
|
action = {
|
|
id = "Script",
|
|
params = {
|
|
command = "pcall(Spearhead.Events.PublishRTBInTen, \"" .. groupName .. "\")"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
[5] = {
|
|
number = 5,
|
|
auto = false,
|
|
id = "ControlledTask",
|
|
enabled = true,
|
|
params = {
|
|
task = {
|
|
id = "Orbit",
|
|
params = {
|
|
altitude = alt,
|
|
pattern = "Circle",
|
|
speed = speed,
|
|
-- speedEdited = true,
|
|
-- clockWise = false,
|
|
-- hotLegDir = capTaskingOptions.hotLegDir,
|
|
-- legLength = capTaskingOptions.legLength,
|
|
-- width = capTaskingOptions.width,
|
|
}
|
|
},
|
|
stopCondition = {
|
|
duration = durationAfter10,
|
|
condition = "return Spearhead.DcsUtil.IsBingoFuel(\"" .. groupName .. "\")",
|
|
}
|
|
}
|
|
},
|
|
[6] = {
|
|
number = 6,
|
|
auto = false,
|
|
id = "WrappedAction",
|
|
enabled = "true",
|
|
params = {
|
|
action = {
|
|
id = "Script",
|
|
params = {
|
|
command = "pcall(Spearhead.Events.PublishRTB, \"" .. groupName .. "\")"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
end
|
|
|
|
if not Spearhead then Spearhead = {} end
|
|
if not Spearhead.classes then Spearhead.classes = {} end
|
|
if not Spearhead.classes.capClasses then Spearhead.classes.capClasses = {} end
|
|
if not Spearhead.classes.capClasses.taskings then Spearhead.classes.capClasses.taskings = {} end
|
|
Spearhead.classes.capClasses.taskings.CAP = CAP
|