Farps (#27)
* added FARP zones logic A and B farps (Active and Blue zone farps). Read more about the specifics in the reference docs
This commit is contained in:
@@ -215,13 +215,20 @@
|
|||||||
CAP routes define the patrol paths for CAP units. They are tied to specific stages and zones.
|
CAP routes define the patrol paths for CAP units. They are tied to specific stages and zones.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="cap-zones">CAP Zones</h3>
|
<h3 id="farp-zones">FARP Zones</h3>
|
||||||
<p>
|
<p>
|
||||||
<strong>Format:</strong> <span class="inline-lua"><span class="lua-variable">CAPZONE_[Name]</span></span> <br />
|
<strong>Format:</strong> <span class="inline-lua"><span class="lua-variable">FARP_A|B_[Name]</span></span> <br />
|
||||||
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">CAPZONE_BRAVO</span></span>
|
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">FARP_A_HOUSTON</span></span>
|
||||||
|
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">FARP_B_HOUSTON</span></span>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
CAP zones are areas where CAP units operate. They are linked to CAP routes and stages.
|
FARP zones are spawned and activated based on the "activation parameter". <br/>
|
||||||
|
A: Activates when the parent stage zone activates. <br/>
|
||||||
|
B: Activates when the parent stage is "Blue". <br/>
|
||||||
|
<br/>
|
||||||
|
Future: FARP zones will be "buildable" once logistics are implemented.
|
||||||
|
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 id="mission-types">Mission Types</h2>
|
<h2 id="mission-types">Mission Types</h2>
|
||||||
|
|||||||
Binary file not shown.
@@ -346,8 +346,16 @@ do -- INIT DCS_UTIL
|
|||||||
if category_id ~= nil and type(categorydata) == "table" and categorydata.group ~= nil and type(categorydata.group) == "table" then
|
if category_id ~= nil and type(categorydata) == "table" and categorydata.group ~= nil and type(categorydata.group) == "table" then
|
||||||
for group_index, group in pairs(categorydata.group) do
|
for group_index, group in pairs(categorydata.group) do
|
||||||
local name = group.name
|
local name = group.name
|
||||||
|
|
||||||
|
local skippable = false
|
||||||
|
|
||||||
if category_id == DCS_UTIL.GroupCategory.STATIC then
|
if category_id == DCS_UTIL.GroupCategory.STATIC then
|
||||||
local unit = group.units[1]
|
local unit = group.units[1]
|
||||||
|
|
||||||
|
if unit.category == "Heliports" then
|
||||||
|
skippable = true
|
||||||
|
end
|
||||||
|
|
||||||
name = unit.name
|
name = unit.name
|
||||||
local staticObj = {
|
local staticObj = {
|
||||||
heading = unit.heading,
|
heading = unit.heading,
|
||||||
@@ -365,6 +373,7 @@ do -- INIT DCS_UTIL
|
|||||||
group = staticObj
|
group = staticObj
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if skippable == false then
|
||||||
table.insert(DCS_UTIL.__groupNames, name)
|
table.insert(DCS_UTIL.__groupNames, name)
|
||||||
DCS_UTIL.__miz_groups[name] =
|
DCS_UTIL.__miz_groups[name] =
|
||||||
{
|
{
|
||||||
@@ -385,6 +394,7 @@ do -- INIT DCS_UTIL
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
do --init trigger zones
|
do --init trigger zones
|
||||||
for i, trigger_zone in pairs(env.mission.triggers.zones) do
|
for i, trigger_zone in pairs(env.mission.triggers.zones) do
|
||||||
|
|||||||
+49
-17
@@ -8,7 +8,6 @@
|
|||||||
---@field MissionZonesLocations table<string, Vec2> All Mission Zone Locations
|
---@field MissionZonesLocations table<string, Vec2> All Mission Zone Locations
|
||||||
---@field StageZonesByNumber table<string, Array<string>> Stage zones grouped by index number
|
---@field StageZonesByNumber table<string, Array<string>> Stage zones grouped by index number
|
||||||
---@field AllFarpZones Array<string>
|
---@field AllFarpZones Array<string>
|
||||||
---@field FarpIdsInFarpZones table<string, Array<integer>> farp pad Id's in farp zones.
|
|
||||||
---@field CapRoutes Array<string> All Cap route zone names
|
---@field CapRoutes Array<string> All Cap route zone names
|
||||||
---@field CapDataPerStageNumber table<integer, CapData> table<StageNumber, table>
|
---@field CapDataPerStageNumber table<integer, CapData> table<StageNumber, table>
|
||||||
---@field CarrierRouteZones Array<string> All Carrier routes zones
|
---@field CarrierRouteZones Array<string> All Carrier routes zones
|
||||||
@@ -53,7 +52,8 @@
|
|||||||
---@field Groups Array<string>
|
---@field Groups Array<string>
|
||||||
|
|
||||||
---@class FarpZoneData
|
---@class FarpZoneData
|
||||||
---@field Groups Array<string>
|
---@field groups Array<string>
|
||||||
|
---@field padNames Array<string>
|
||||||
|
|
||||||
---@class Database
|
---@class Database
|
||||||
---@field private _tables DatabaseTables
|
---@field private _tables DatabaseTables
|
||||||
@@ -73,7 +73,6 @@ function Database.New(Logger)
|
|||||||
CapDataPerStageNumber = {},
|
CapDataPerStageNumber = {},
|
||||||
CarrierRouteZones = {},
|
CarrierRouteZones = {},
|
||||||
DescriptionsByMission = {},
|
DescriptionsByMission = {},
|
||||||
FarpIdsInFarpZones = {},
|
|
||||||
MissionZones = {},
|
MissionZones = {},
|
||||||
MissionZonesLocations = {},
|
MissionZonesLocations = {},
|
||||||
StageZoneNames = {},
|
StageZoneNames = {},
|
||||||
@@ -224,6 +223,13 @@ function Database.New(Logger)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- fill farp zones
|
||||||
|
for _, farpZoneName in pairs(self._tables.AllFarpZones) do
|
||||||
|
if Spearhead.DcsUtil.isZoneInZone(farpZoneName, stageZoneName) then
|
||||||
|
table.insert(stageData.FarpZones, farpZoneName)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- fill airbases
|
-- fill airbases
|
||||||
for _, airbase in pairs(world.getAirbases()) do
|
for _, airbase in pairs(world.getAirbases()) do
|
||||||
local point = airbase:getPoint()
|
local point = airbase:getPoint()
|
||||||
@@ -231,22 +237,10 @@ function Database.New(Logger)
|
|||||||
if Spearhead.DcsUtil.isPositionInZone(point.x, point.z, stageZoneName) == true then
|
if Spearhead.DcsUtil.isPositionInZone(point.x, point.z, stageZoneName) == true then
|
||||||
if airbase:getDesc().category == 0 then
|
if airbase:getDesc().category == 0 then
|
||||||
table.insert(stageData.AirbaseNames, airbase:getName())
|
table.insert(stageData.AirbaseNames, airbase:getName())
|
||||||
elseif airbase:getDesc().category == 1 then
|
|
||||||
-- farp
|
|
||||||
--[[
|
|
||||||
TODO: FARP ZONES FILL
|
|
||||||
]]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- fill farp zones
|
|
||||||
for _, farpZoneName in pairs(self._tables.AllFarpZones) do
|
|
||||||
if Spearhead.DcsUtil.isZoneInZone(farpZoneName, stageZoneName) then
|
|
||||||
table.insert(stageData.FarpZones, farpZoneName)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, missionZone in pairs(self._tables.MissionZones) do
|
for _, missionZone in pairs(self._tables.MissionZones) do
|
||||||
if self._tables.DescriptionsByMission[missionZone] == nil then
|
if self._tables.DescriptionsByMission[missionZone] == nil then
|
||||||
Spearhead.AddMissionEditorWarning("Mission with zonename: " .. missionZone .. " does not have a briefing")
|
Spearhead.AddMissionEditorWarning("Mission with zonename: " .. missionZone .. " does not have a briefing")
|
||||||
@@ -262,6 +256,26 @@ function Database.New(Logger)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for _, farpZoneName in pairs(self._tables.AllFarpZones) do
|
||||||
|
|
||||||
|
for _, airbase in pairs(world.getAirbases()) do
|
||||||
|
|
||||||
|
if airbase:getDesc().category == Airbase.Category.HELIPAD then
|
||||||
|
local name = airbase:getName()
|
||||||
|
|
||||||
|
if self._tables.FarpZoneData[farpZoneName] == nil then
|
||||||
|
self._tables.FarpZoneData[farpZoneName] = {
|
||||||
|
groups = {},
|
||||||
|
padNames = {}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
local position = airbase:getPoint()
|
||||||
|
if Spearhead.DcsUtil.isPositionInZone(position.x, position.z, farpZoneName) == true then
|
||||||
|
table.insert(self._tables.FarpZoneData[farpZoneName].padNames, name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
---@param baseName string
|
---@param baseName string
|
||||||
@@ -489,14 +503,18 @@ end
|
|||||||
function Database:loadFarpGroups()
|
function Database:loadFarpGroups()
|
||||||
local all_groups = getAvailableGroups()
|
local all_groups = getAvailableGroups()
|
||||||
for _, farpZone in pairs(self._tables.AllFarpZones) do
|
for _, farpZone in pairs(self._tables.AllFarpZones) do
|
||||||
|
|
||||||
|
if self._tables.FarpZoneData[farpZone] == nil then
|
||||||
self._tables.FarpZoneData[farpZone] = {
|
self._tables.FarpZoneData[farpZone] = {
|
||||||
Groups = {}
|
groups = {},
|
||||||
|
padNames = {}
|
||||||
}
|
}
|
||||||
|
end
|
||||||
|
|
||||||
local groups = Spearhead.DcsUtil.getGroupsInZone(all_groups, farpZone)
|
local groups = Spearhead.DcsUtil.getGroupsInZone(all_groups, farpZone)
|
||||||
for _, groupName in pairs(groups) do
|
for _, groupName in pairs(groups) do
|
||||||
is_group_taken[groupName] = true
|
is_group_taken[groupName] = true
|
||||||
table.insert(self._tables.FarpZoneData[farpZone].Groups, groupName)
|
table.insert(self._tables.FarpZoneData[farpZone].groups, groupName)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -704,6 +722,20 @@ function Database:getAirbaseNamesInStage(stageName)
|
|||||||
return stageData.AirbaseNames or {}
|
return stageData.AirbaseNames or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Database:getFarpNamesInStage(stageName)
|
||||||
|
local stageData = self._tables.StageZones[stageName]
|
||||||
|
if not stageData then return {} end
|
||||||
|
return stageData.FarpZones or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return FarpZoneData?
|
||||||
|
function Database:getFarpDataForZone(farpZoneName)
|
||||||
|
local farpData = self._tables.FarpZoneData[farpZoneName]
|
||||||
|
if not farpData then return nil end
|
||||||
|
return farpData
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---@param airbaseName string
|
---@param airbaseName string
|
||||||
---@return Array<string>
|
---@return Array<string>
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
|
||||||
|
|
||||||
|
---@class FarpZone
|
||||||
|
---@field private _startingFarp boolean
|
||||||
|
---@field private _groups Array<SpearheadGroup>
|
||||||
|
---@field private _padNames Array<string>
|
||||||
|
---@field private _database Database
|
||||||
|
---@field private _logger Logger
|
||||||
|
---@field private _zoneName string
|
||||||
|
local FarpZone = {}
|
||||||
|
FarpZone.__index = FarpZone
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param database Database
|
||||||
|
---@param logger Logger
|
||||||
|
---@param zoneName string
|
||||||
|
---@return FarpZone
|
||||||
|
function FarpZone.New(database, logger, zoneName)
|
||||||
|
|
||||||
|
FarpZone.__index = FarpZone
|
||||||
|
local self = setmetatable({}, FarpZone)
|
||||||
|
|
||||||
|
self._database = database
|
||||||
|
self._logger = logger
|
||||||
|
self._zoneName = zoneName
|
||||||
|
|
||||||
|
local split = Spearhead.Util.split_string(zoneName, "_")
|
||||||
|
if string.lower(split[2]) == "a" then
|
||||||
|
self._startingFarp = true
|
||||||
|
else
|
||||||
|
self._startingFarp = false
|
||||||
|
end
|
||||||
|
|
||||||
|
logger:debug("FARP zone name: " .. zoneName .. " startingFarp" .. tostring(self._startingFarp))
|
||||||
|
|
||||||
|
local farpData = database:getFarpDataForZone(zoneName)
|
||||||
|
self._groups = {}
|
||||||
|
self._padNames = {}
|
||||||
|
|
||||||
|
if farpData then
|
||||||
|
self._padNames = farpData.padNames
|
||||||
|
|
||||||
|
for _, groupName in pairs(farpData.groups) do
|
||||||
|
local group = Spearhead.classes.stageClasses.Groups.SpearheadGroup.New(groupName)
|
||||||
|
table.insert(self._groups, group)
|
||||||
|
group:Destroy()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:Deactivate()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return boolean
|
||||||
|
function FarpZone:IsStartingFarp()
|
||||||
|
return self._startingFarp
|
||||||
|
end
|
||||||
|
|
||||||
|
function FarpZone:Activate()
|
||||||
|
self._logger:info("Activating FARP zone: " .. self._zoneName)
|
||||||
|
self:BuildUp()
|
||||||
|
self:SetPadsBlue()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function FarpZone:Deactivate()
|
||||||
|
|
||||||
|
self:NeutralisePads()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function FarpZone:BuildUp()
|
||||||
|
for _, group in pairs(self._groups) do
|
||||||
|
group:Spawn()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
function FarpZone:NeutralisePads()
|
||||||
|
for _, name in pairs(self._padNames) do
|
||||||
|
local base = Airbase.getByName(name)
|
||||||
|
if base then
|
||||||
|
base:autoCapture(false) -- Disable auto capture
|
||||||
|
base:setCoalition(1) -- 1 = Red (Can't neutralise)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
function FarpZone:SetPadsBlue()
|
||||||
|
for _, name in pairs(self._padNames) do
|
||||||
|
local base = Airbase.getByName(name)
|
||||||
|
if base then
|
||||||
|
base:autoCapture(false) -- Disable auto capture
|
||||||
|
base:setCoalition(2) -- 2 = Blue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if Spearhead == nil then Spearhead = {} end
|
||||||
|
if Spearhead.classes == nil then Spearhead.classes = {} end
|
||||||
|
if Spearhead.classes.stageClasses == nil then Spearhead.classes.stageClasses = {} end
|
||||||
|
if Spearhead.classes.stageClasses.SpecialZones == nil then Spearhead.classes.stageClasses.SpecialZones = {} end
|
||||||
|
Spearhead.classes.stageClasses.SpecialZones.FarpZone = FarpZone
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
--- @field airbases Array<StageBase>
|
--- @field airbases Array<StageBase>
|
||||||
--- @field miscGroups Array<SpearheadGroup>
|
--- @field miscGroups Array<SpearheadGroup>
|
||||||
--- @field maxMissions integer
|
--- @field maxMissions integer
|
||||||
|
--- @field farps Array<FarpZone>
|
||||||
|
|
||||||
--- @class StageInitData
|
--- @class StageInitData
|
||||||
--- @field stageZoneName string
|
--- @field stageZoneName string
|
||||||
@@ -45,7 +46,6 @@ local Stage = {}
|
|||||||
|
|
||||||
Stage.__index = Stage
|
Stage.__index = Stage
|
||||||
|
|
||||||
local stageDrawingId = 100
|
|
||||||
|
|
||||||
Stage.StageColors = {
|
Stage.StageColors = {
|
||||||
INVISIBLE = { r=0, g=0, b=0, a=0 },
|
INVISIBLE = { r=0, g=0, b=0, a=0 },
|
||||||
@@ -86,7 +86,8 @@ function Stage:superNew(database, stageConfig, logger, initData, missionPriority
|
|||||||
blueSams = {},
|
blueSams = {},
|
||||||
airbases ={},
|
airbases ={},
|
||||||
miscGroups = {},
|
miscGroups = {},
|
||||||
maxMissions = stageConfig.maxMissionsPerStage
|
maxMissions = stageConfig.maxMissionsPerStage,
|
||||||
|
farps = {},
|
||||||
}
|
}
|
||||||
self._activeStage = -99
|
self._activeStage = -99
|
||||||
self._preActivated = false
|
self._preActivated = false
|
||||||
@@ -101,7 +102,12 @@ function Stage:superNew(database, stageConfig, logger, initData, missionPriority
|
|||||||
self._missionPriority = missionPriority
|
self._missionPriority = missionPriority
|
||||||
self._stageCompleteListeners = {}
|
self._stageCompleteListeners = {}
|
||||||
|
|
||||||
stageDrawingId = stageDrawingId + 1
|
local farpNames = database:getFarpNamesInStage(self.zoneName)
|
||||||
|
for _, farpName in pairs(farpNames) do
|
||||||
|
local farp = Spearhead.classes.stageClasses.SpecialZones.FarpZone.New(database, logger, farpName)
|
||||||
|
table.insert(self._db.farps, farp)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
self._logger:info("Initiating new Stage with name: " .. self.zoneName)
|
self._logger:info("Initiating new Stage with name: " .. self.zoneName)
|
||||||
|
|
||||||
@@ -364,6 +370,12 @@ function Stage:ActivateStage()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for _, farp in pairs(self._db.farps) do
|
||||||
|
if farp:IsStartingFarp() == true then
|
||||||
|
farp:Activate()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
timer.scheduleFunction(self.CheckContinuousAsync, self, timer.getTime() + 3)
|
timer.scheduleFunction(self.CheckContinuousAsync, self, timer.getTime() + 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -430,6 +442,12 @@ function Stage:ActivateBlueGroups()
|
|||||||
self:OnPostBlueActivated()
|
self:OnPostBlueActivated()
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for _, farp in pairs(self._db.farps) do
|
||||||
|
if farp:IsStartingFarp() == true then
|
||||||
|
farp:Activate()
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Stage:ActivateBlueStage()
|
function Stage:ActivateBlueStage()
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ assert(loadfile(classPath .. "stageClasses\\helpers\\MissionCommandsHelper.lua")
|
|||||||
|
|
||||||
assert(loadfile(classPath .. "stageClasses\\SpecialZones\\StageBase.lua"))()
|
assert(loadfile(classPath .. "stageClasses\\SpecialZones\\StageBase.lua"))()
|
||||||
assert(loadfile(classPath .. "stageClasses\\SpecialZones\\BlueSam.lua"))()
|
assert(loadfile(classPath .. "stageClasses\\SpecialZones\\BlueSam.lua"))()
|
||||||
|
assert(loadfile(classPath .. "stageClasses\\SpecialZones\\FarpZone.lua"))()
|
||||||
|
|
||||||
assert(loadfile(classPath .. "capClasses\\CapGroup.lua"))()
|
assert(loadfile(classPath .. "capClasses\\CapGroup.lua"))()
|
||||||
assert(loadfile(classPath .. "capClasses\\GlobalCapManager.lua"))()
|
assert(loadfile(classPath .. "capClasses\\GlobalCapManager.lua"))()
|
||||||
|
|||||||
Reference in New Issue
Block a user