Binary file not shown.
@@ -487,29 +487,36 @@ do -- INIT DCS_UTIL
|
|||||||
DCS_UTIL.__airbaseNamesById[tostring(airbase:getID())] = name
|
DCS_UTIL.__airbaseNamesById[tostring(airbase:getID())] = name
|
||||||
|
|
||||||
if name then
|
if name then
|
||||||
|
---@type Array<Vec2>
|
||||||
local relevantPoints = {}
|
local relevantPoints = {}
|
||||||
for _, x in pairs(airbase:getRunways()) do
|
for _, x in pairs(airbase:getRunways()) do
|
||||||
if x.position and x.position.x and x.position.z then
|
if x.position and x.position.x and x.position.z then
|
||||||
table.insert(relevantPoints, { x = x.position.x, z = x.position.z, y = 0 })
|
table.insert(relevantPoints, { x = x.position.x, y = x.position.z })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, x in pairs(airbase:getParking()) do
|
for _, x in pairs(airbase:getParking()) do
|
||||||
if x.vTerminalPos and x.vTerminalPos.x and x.vTerminalPos.z then
|
if x.vTerminalPos and x.vTerminalPos.x and x.vTerminalPos.z then
|
||||||
table.insert(relevantPoints, { x = x.vTerminalPos.x, z = x.vTerminalPos.z, y = 0 })
|
table.insert(relevantPoints, { x = x.vTerminalPos.x, y = x.vTerminalPos.z })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local points = UTIL.getConvexHull(relevantPoints)
|
local points = UTIL.getConvexHull(relevantPoints)
|
||||||
local enlargedPoints = UTIL.enlargeConvexHull(points, 750)
|
local enlargedPoints = UTIL.enlargeConvexHull(points, 750)
|
||||||
|
|
||||||
DCS_UTIL.__airbaseZonesByName[name] = {
|
local triggerZone = {
|
||||||
name = name,
|
name = name,
|
||||||
location = { x = airbase:getPoint().x, y = airbase:getPoint().z },
|
location = { x = airbase:getPoint().x, y = airbase:getPoint().z },
|
||||||
zone_type = "Polygon",
|
zone_type = "Polygon",
|
||||||
radius = 0,
|
radius = 0,
|
||||||
verts = enlargedPoints
|
verts = enlargedPoints
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if SpearheadConfig and SpearheadConfig.debugEnabled == true then
|
||||||
|
DCS_UTIL.DrawZone(triggerZone, { r = 0, g = 1, b = 0, a = 1 }, { a = 0, r = 0, g = 1, b = 0 }, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
DCS_UTIL.__airbaseZonesByName[name] = triggerZone
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -732,10 +739,10 @@ do -- INIT DCS_UTIL
|
|||||||
|
|
||||||
---comment
|
---comment
|
||||||
---@param airbaseName string
|
---@param airbaseName string
|
||||||
---@return SpearheadTriggerZone? zone { name,b zone_type, x, z, radius, verts }
|
---@return SpearheadTriggerZone? zone
|
||||||
function DCS_UTIL.getAirbaseZoneByName(airbaseName)
|
function DCS_UTIL.getAirbaseZoneByName(airbaseName)
|
||||||
if string == nil then return nil end
|
if airbaseName == nil then return nil end
|
||||||
return DCS_UTIL.__airbaseZonesByName[string]
|
return DCS_UTIL.__airbaseZonesByName[airbaseName]
|
||||||
end
|
end
|
||||||
|
|
||||||
---maps the category name to the DCS group category
|
---maps the category name to the DCS group category
|
||||||
|
|||||||
+40
-16
@@ -49,6 +49,7 @@
|
|||||||
---@field RedGroups Array<string>
|
---@field RedGroups Array<string>
|
||||||
---@field BlueGroups Array<string>
|
---@field BlueGroups Array<string>
|
||||||
---@field supplyHubNames Array<string>
|
---@field supplyHubNames Array<string>
|
||||||
|
---@field buildingKilos number?
|
||||||
|
|
||||||
---@class BlueSamData
|
---@class BlueSamData
|
||||||
---@field groups Array<string>
|
---@field groups Array<string>
|
||||||
@@ -196,6 +197,13 @@ function Database.New(Logger)
|
|||||||
local number = tonumber(layer_object.text)
|
local number = tonumber(layer_object.text)
|
||||||
farpData.buildingKilos = number
|
farpData.buildingKilos = number
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local airbaseData = self:getAirbaseDataForDrawLayer(layer_object)
|
||||||
|
if airbaseData then
|
||||||
|
self._logger:debug("found airbase data for " .. layer_object.name)
|
||||||
|
local number = tonumber(layer_object.text)
|
||||||
|
airbaseData.buildingKilos = number
|
||||||
|
end
|
||||||
elseif Spearhead.Util.startswith(string.lower(layer_object.name), "completeat", true) == true then
|
elseif Spearhead.Util.startswith(string.lower(layer_object.name), "completeat", true) == true then
|
||||||
local annotationData = self:getMissionMetaDataForDrawLayer(layer_object)
|
local annotationData = self:getMissionMetaDataForDrawLayer(layer_object)
|
||||||
if annotationData then
|
if annotationData then
|
||||||
@@ -347,22 +355,6 @@ function Database.New(Logger)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@private
|
|
||||||
---@param baseName string
|
|
||||||
---@return AirbaseData
|
|
||||||
function Database:getOrCreateAirbaseData(baseName)
|
|
||||||
local baseData = self._tables.AirbaseDataPerAirfield[baseName]
|
|
||||||
if baseData == nil then
|
|
||||||
baseData = {
|
|
||||||
CapGroups = {},
|
|
||||||
RedGroups = {},
|
|
||||||
BlueGroups = {},
|
|
||||||
supplyHubNames = {}
|
|
||||||
}
|
|
||||||
self._tables.AirbaseDataPerAirfield[baseName] = baseData
|
|
||||||
end
|
|
||||||
return baseData
|
|
||||||
end
|
|
||||||
|
|
||||||
self:initAvailableUnits()
|
self:initAvailableUnits()
|
||||||
self:loadCapUnits()
|
self:loadCapUnits()
|
||||||
@@ -511,6 +503,21 @@ function Database:getFarpDataForDrawLayer(layer_object)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param layer_object table
|
||||||
|
---@return AirbaseData?
|
||||||
|
function Database:getAirbaseDataForDrawLayer(layer_object)
|
||||||
|
for _, airbase in pairs(world.getAirbases()) do
|
||||||
|
local zone = Spearhead.DcsUtil.getAirbaseZoneByName(airbase:getName())
|
||||||
|
|
||||||
|
if zone and Spearhead.Util.is2dPointInZone({ x = layer_object.mapX, y = layer_object.mapY }, zone) == true then
|
||||||
|
return self:getOrCreateAirbaseData(airbase:getName())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
function Database:getOrCreateBlueSamDataForZone(zoneName)
|
function Database:getOrCreateBlueSamDataForZone(zoneName)
|
||||||
local blueSamData = self._tables.BlueSamDataPerZone[zoneName]
|
local blueSamData = self._tables.BlueSamDataPerZone[zoneName]
|
||||||
@@ -539,6 +546,23 @@ function Database:getOrCreateFarpDataForZone(zoneName)
|
|||||||
return farpData
|
return farpData
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
---@param baseName string
|
||||||
|
---@return AirbaseData
|
||||||
|
function Database:getOrCreateAirbaseData(baseName)
|
||||||
|
local baseData = self._tables.AirbaseDataPerAirfield[baseName]
|
||||||
|
if baseData == nil then
|
||||||
|
baseData = {
|
||||||
|
CapGroups = {},
|
||||||
|
RedGroups = {},
|
||||||
|
BlueGroups = {},
|
||||||
|
supplyHubNames = {}
|
||||||
|
}
|
||||||
|
self._tables.AirbaseDataPerAirfield[baseName] = baseData
|
||||||
|
end
|
||||||
|
return baseData
|
||||||
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
---@param layer_object table
|
---@param layer_object table
|
||||||
---@return MissionAnnotations?
|
---@return MissionAnnotations?
|
||||||
|
|||||||
@@ -80,10 +80,13 @@ function BlueSam.New(database, logger, zoneName)
|
|||||||
self._logger:debug("Buildable mission creating for zone: " .. zoneName .. " with crates: " .. self._buildableCrateKilos)
|
self._logger:debug("Buildable mission creating for zone: " .. zoneName .. " with crates: " .. self._buildableCrateKilos)
|
||||||
|
|
||||||
local noLandingZone = self:GetNoLandingZone()
|
local noLandingZone = self:GetNoLandingZone()
|
||||||
|
local zone = Spearhead.DcsUtil.getZoneByName(zoneName)
|
||||||
self._buildableMission = Spearhead.classes.stageClasses.missions.BuildableMission.new(database, logger, zoneName, noLandingZone, self._buildableCrateKilos, "SAM_CRATE")
|
if zone then
|
||||||
self._buildableMission:AddOnCrateDroppedOfListener(self)
|
self._buildableMission = Spearhead.classes.stageClasses.missions.BuildableMission.new(database, logger, zone, noLandingZone, self._buildableCrateKilos, "SAM_CRATE")
|
||||||
self._buildableMission:AddMissionCompleteListener(self)
|
self._buildableMission:AddOnCrateDroppedOfListener(self)
|
||||||
|
self._buildableMission:AddMissionCompleteListener(self)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -66,14 +66,17 @@ function FarpZone.New(database, logger, zoneName)
|
|||||||
if self._requiredBuildingKilos ~= nil and self._requiredBuildingKilos > 0 then
|
if self._requiredBuildingKilos ~= nil and self._requiredBuildingKilos > 0 then
|
||||||
self._logger:debug("FARP zone " .. zoneName .. " requires " .. self._requiredBuildingKilos .. " crates to be dropped off")
|
self._logger:debug("FARP zone " .. zoneName .. " requires " .. self._requiredBuildingKilos .. " crates to be dropped off")
|
||||||
local noLandingZone = self:GetNoLandingZone()
|
local noLandingZone = self:GetNoLandingZone()
|
||||||
self._buildableMission = Spearhead.classes.stageClasses.missions.BuildableMission.new(database, logger, zoneName, noLandingZone, self._requiredBuildingKilos, "FARP_CRATE")
|
local zone = Spearhead.DcsUtil.getZoneByName(zoneName)
|
||||||
if self._buildableMission then
|
if zone then
|
||||||
self._buildableMission:AddOnCrateDroppedOfListener(self)
|
self._buildableMission = Spearhead.classes.stageClasses.missions.BuildableMission.new(database, logger, zone, noLandingZone, self._requiredBuildingKilos, "FARP_CRATE")
|
||||||
self._buildableMission:AddMissionCompleteListener(self)
|
if self._buildableMission then
|
||||||
end
|
self._buildableMission:AddOnCrateDroppedOfListener(self)
|
||||||
|
self._buildableMission:AddMissionCompleteListener(self)
|
||||||
|
end
|
||||||
|
|
||||||
local totalGroups = Spearhead.Util.tableLength(self._groups)
|
local totalGroups = Spearhead.Util.tableLength(self._groups)
|
||||||
self._groupsPerKilo = totalGroups / self._requiredBuildingKilos
|
self._groupsPerKilo = totalGroups / self._requiredBuildingKilos
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if self._buildableMission == nil then
|
if self._buildableMission == nil then
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
|
---@class StageBase : OnCrateDroppedListener, MissionCompleteListener
|
||||||
|
|
||||||
---@class StageBase
|
|
||||||
---@field private _database Database
|
---@field private _database Database
|
||||||
---@field private _logger Logger
|
---@field private _logger Logger
|
||||||
---@field private _red_groups Array<SpearheadGroup>
|
---@field private _red_groups Array<SpearheadGroup>
|
||||||
@@ -9,6 +7,10 @@
|
|||||||
---@field private _airbase Airbase?
|
---@field private _airbase Airbase?
|
||||||
---@field private _initialSide number?
|
---@field private _initialSide number?
|
||||||
---@field private _supplyHubs Array<SupplyHub>
|
---@field private _supplyHubs Array<SupplyHub>
|
||||||
|
---@field private _groupsPerKilo number
|
||||||
|
---@field private _requiredBuildingKilos number
|
||||||
|
---@field private _receivedBuildingKilos number
|
||||||
|
---@field private _buildableMission BuildableMission?
|
||||||
local StageBase = {}
|
local StageBase = {}
|
||||||
|
|
||||||
---comment
|
---comment
|
||||||
@@ -17,7 +19,6 @@ local StageBase = {}
|
|||||||
---@param airbaseName string
|
---@param airbaseName string
|
||||||
---@return StageBase?
|
---@return StageBase?
|
||||||
function StageBase.New(databaseManager, logger, airbaseName)
|
function StageBase.New(databaseManager, logger, airbaseName)
|
||||||
|
|
||||||
StageBase.__index = StageBase
|
StageBase.__index = StageBase
|
||||||
local self = setmetatable({}, StageBase)
|
local self = setmetatable({}, StageBase)
|
||||||
|
|
||||||
@@ -33,13 +34,12 @@ function StageBase.New(databaseManager, logger, airbaseName)
|
|||||||
self._initialSide = Spearhead.DcsUtil.getStartingCoalition(self._airbase)
|
self._initialSide = Spearhead.DcsUtil.getStartingCoalition(self._airbase)
|
||||||
|
|
||||||
do --init
|
do --init
|
||||||
|
|
||||||
local airbaseData = databaseManager:getAirbaseDataForZone(airbaseName)
|
local airbaseData = databaseManager:getAirbaseDataForZone(airbaseName)
|
||||||
if airbaseData == nil then
|
if airbaseData == nil then
|
||||||
logger:error("Airbase data not found for airbase: " .. airbaseName)
|
logger:error("Airbase data not found for airbase: " .. airbaseName)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type table<string, Vec3>
|
---@type table<string, Vec3>
|
||||||
local redUnitsPos = {}
|
local redUnitsPos = {}
|
||||||
|
|
||||||
@@ -69,16 +69,17 @@ function StageBase.New(databaseManager, logger, airbaseName)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for _, supplyHubName in pairs(airbaseData.supplyHubNames) do
|
for _, supplyHubName in pairs(airbaseData.supplyHubNames) do
|
||||||
local supplyHub = Spearhead.classes.stageClasses.SpecialZones.SupplyHub.new(databaseManager, logger, supplyHubName)
|
local supplyHub = Spearhead.classes.stageClasses.SpecialZones.SupplyHub.new(databaseManager, logger,
|
||||||
|
supplyHubName)
|
||||||
if supplyHub then
|
if supplyHub then
|
||||||
table.insert(self._supplyHubs, supplyHub)
|
table.insert(self._supplyHubs, supplyHub)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- check cleanup requirements
|
do -- check cleanup requirements
|
||||||
-- Checks is any of the units are withing range (5m) of another unit.
|
-- Checks is any of the units are withing range (5m) of another unit.
|
||||||
-- If so, make sure to add them to the cleanup list.
|
-- If so, make sure to add them to the cleanup list.
|
||||||
|
|
||||||
local cleanup_distance = 5
|
local cleanup_distance = 5
|
||||||
|
|
||||||
for blueUnitName, blueUnitPos in pairs(blueUnitsPos) do
|
for blueUnitName, blueUnitPos in pairs(blueUnitsPos) do
|
||||||
@@ -90,14 +91,31 @@ function StageBase.New(databaseManager, logger, airbaseName)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if airbaseData.buildingKilos ~= nil and airbaseData.buildingKilos > 0 then
|
||||||
|
self._logger:debug("Airbase " .. airbaseName .. " requires " .. tostring(airbaseData.buildingKilos) .. " kilos to be dropped off")
|
||||||
|
self._requiredBuildingKilos = airbaseData.buildingKilos
|
||||||
|
self._receivedBuildingKilos = 0
|
||||||
|
self._groupsPerKilo = Spearhead.Util.tableLength(self._blue_groups) / self._requiredBuildingKilos
|
||||||
|
local zone = Spearhead.DcsUtil.getAirbaseZoneByName(airbaseName)
|
||||||
|
if zone then
|
||||||
|
self._buildableMission = Spearhead.classes.stageClasses.missions.BuildableMission.new(databaseManager, logger, zone, self:GetNoLandingZone(), self._requiredBuildingKilos, "AIRBASE_CRATE")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if self._buildableMission then
|
||||||
|
self._buildableMission:AddOnCrateDroppedOfListener(self)
|
||||||
|
else
|
||||||
|
self._logger:error("Failed to create buildable mission for airbase: " .. airbaseName)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
function StageBase:SpawnRedUnits()
|
function StageBase:SpawnRedUnits()
|
||||||
|
|
||||||
---comment
|
---comment
|
||||||
---@param groups Array<SpearheadGroup>
|
---@param groups Array<SpearheadGroup>
|
||||||
local spawnAsync = function(groups)
|
local spawnAsync = function(groups)
|
||||||
@@ -122,14 +140,11 @@ function StageBase:CleanRedUnits()
|
|||||||
Spearhead.DcsUtil.DestroyUnit(unitName)
|
Spearhead.DcsUtil.DestroyUnit(unitName)
|
||||||
Spearhead.DcsUtil.CleanCorpse(unitName)
|
Spearhead.DcsUtil.CleanCorpse(unitName)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
function StageBase:SpawnBlueUnits()
|
function StageBase:SpawnBlueUnits()
|
||||||
|
|
||||||
---comment
|
---comment
|
||||||
---@param groups Array<SpearheadGroup>
|
---@param groups Array<SpearheadGroup>
|
||||||
local spawnAsync = function(groups)
|
local spawnAsync = function(groups)
|
||||||
@@ -152,25 +167,146 @@ function StageBase:ActivateRedStage()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function StageBase:ActivateBlueStage()
|
function StageBase:ActivateBlueStage()
|
||||||
|
self:CleanRedUnits()
|
||||||
|
|
||||||
|
if self._buildableMission and self._buildableMission:getState() ~= "COMPLETED" then
|
||||||
|
self._buildableMission:SpawnActive()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self:FinaliseBlueStage()
|
||||||
|
end
|
||||||
|
|
||||||
|
function StageBase:FinaliseBlueStage()
|
||||||
if self._initialSide == 2 and self._airbase then
|
if self._initialSide == 2 and self._airbase then
|
||||||
self._airbase:setCoalition(2)
|
self._airbase:setCoalition(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
self:CleanRedUnits()
|
|
||||||
self:SpawnBlueUnits()
|
self:SpawnBlueUnits()
|
||||||
|
|
||||||
for _, hub in pairs(self._supplyHubs) do
|
for _, hub in pairs(self._supplyHubs) do
|
||||||
hub:Activate()
|
hub:Activate()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do ---Building parts
|
||||||
|
---@class UnpackAirbaseCrateParam
|
||||||
|
---@field self StageBase
|
||||||
|
---@field kilos number
|
||||||
|
---@field groupsPerKilo number
|
||||||
|
---@field kilosPerSecond number
|
||||||
|
---@field unpackedItems number
|
||||||
|
---@field unpackedKilos number
|
||||||
|
|
||||||
|
---@param params UnpackAirbaseCrateParam
|
||||||
|
---@param time number
|
||||||
|
local startUnpackingCrate = function(params, time)
|
||||||
|
local unpacked = params.unpackedKilos + (params.kilosPerSecond * 2)
|
||||||
|
local alreadySpawned = params.unpackedItems / params.groupsPerKilo
|
||||||
|
local diff = unpacked - alreadySpawned
|
||||||
|
|
||||||
|
local amount = math.floor(diff * params.groupsPerKilo)
|
||||||
|
local spawned = params.self:SpawnAmount(amount)
|
||||||
|
|
||||||
|
params.unpackedItems = params.unpackedItems + amount
|
||||||
|
params.unpackedKilos = unpacked
|
||||||
|
if params.unpackedKilos >= params.kilos or spawned == false then
|
||||||
|
params.self:FinaliseCrate(params.kilos)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
return time + 2
|
||||||
|
end
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param amount number
|
||||||
|
---@return boolean
|
||||||
|
function StageBase:SpawnAmount(amount)
|
||||||
|
local function spawnOne()
|
||||||
|
for _, group in pairs(self._blue_groups) do
|
||||||
|
if group:IsSpawned() == false then
|
||||||
|
group:Spawn()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, amount do
|
||||||
|
local spawned = spawnOne()
|
||||||
|
if spawned ~= true then
|
||||||
|
self._logger:debug("No more groups to spawn at base: " .. self._airbase:getName())
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param buildableMission BuildableMission
|
||||||
|
function StageBase:OnCrateDroppedOff(buildableMission, kilos)
|
||||||
|
self._logger:debug("Crate dropped off at base: " .. self._airbase:getName())
|
||||||
|
|
||||||
|
local timeToUnpack = (kilos / 500) * 30
|
||||||
|
|
||||||
|
---@type UnpackAirbaseCrateParam
|
||||||
|
local params = {
|
||||||
|
self = self,
|
||||||
|
groupsPerKilo = self._groupsPerKilo,
|
||||||
|
unpackedItems = 0,
|
||||||
|
kilosPerSecond = kilos / timeToUnpack,
|
||||||
|
unpackedKilos = 0,
|
||||||
|
kilos = kilos
|
||||||
|
}
|
||||||
|
|
||||||
|
timer.scheduleFunction(startUnpackingCrate, params, timer.getTime() + 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
---@return SpearheadTriggerZone?
|
||||||
|
function StageBase:GetNoLandingZone()
|
||||||
|
---@type Array<Vec2>
|
||||||
|
local points = {}
|
||||||
|
|
||||||
|
for _, group in pairs(self._blue_groups) do
|
||||||
|
for _, unitPos in pairs(group:GetAllUnitPositions()) do
|
||||||
|
table.insert(points, { x = unitPos.x, y = unitPos.z })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local vecs = Spearhead.Util.getConvexHull(points)
|
||||||
|
|
||||||
|
local pos = self._airbase:getPoint()
|
||||||
|
local location = {
|
||||||
|
x = pos.x,
|
||||||
|
y = pos.z
|
||||||
|
}
|
||||||
|
|
||||||
|
---@type SpearheadTriggerZone
|
||||||
|
local spearheadZone = {
|
||||||
|
name = self._airbase:getName() .. "_noland",
|
||||||
|
location = location,
|
||||||
|
verts = vecs,
|
||||||
|
radius = 0,
|
||||||
|
zone_type = "Polygon"
|
||||||
|
}
|
||||||
|
|
||||||
|
return spearheadZone
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---@param kilos number
|
||||||
|
function StageBase:FinaliseCrate(kilos)
|
||||||
|
self._receivedBuildingKilos = self._receivedBuildingKilos + kilos
|
||||||
|
if self._receivedBuildingKilos >= self._requiredBuildingKilos then
|
||||||
|
self:FinaliseBlueStage()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if Spearhead == nil then Spearhead = {} end
|
if Spearhead == nil then Spearhead = {} end
|
||||||
if Spearhead.classes == nil then Spearhead.classes = {} end
|
if Spearhead.classes == nil then Spearhead.classes = {} end
|
||||||
if Spearhead.classes.stageClasses == nil then Spearhead.classes.stageClasses = {} end
|
if Spearhead.classes.stageClasses == nil then Spearhead.classes.stageClasses = {} end
|
||||||
if Spearhead.classes.stageClasses.SpecialZones == nil then Spearhead.classes.stageClasses.SpecialZones = {} end
|
if Spearhead.classes.stageClasses.SpecialZones == nil then Spearhead.classes.stageClasses.SpecialZones = {} end
|
||||||
Spearhead.classes.stageClasses.SpecialZones.StageBase = StageBase
|
Spearhead.classes.stageClasses.SpecialZones.StageBase = StageBase
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -358,12 +358,16 @@ function MissionCommandsHelper:AddSupplyHubCommandsIfApplicable(groupID)
|
|||||||
missionCommands.addCommandForGroup(groupID, "Load FARP Crate (2000)", path, loadCargoCommand, farpParams2000)
|
missionCommands.addCommandForGroup(groupID, "Load FARP Crate (2000)", path, loadCargoCommand, farpParams2000)
|
||||||
|
|
||||||
---@type LoadCargoCommandParams
|
---@type LoadCargoCommandParams
|
||||||
local samParms1000 = { unitID = unit:getID(), groupID = group:getID(), crateType = "FARP_CRATE_1000", supplyUnitsTracker = self._supplyUnitsTracker }
|
local samParms1000 = { unitID = unit:getID(), groupID = group:getID(), crateType = "SAM_CRATE_2000", supplyUnitsTracker = self._supplyUnitsTracker }
|
||||||
missionCommands.addCommandForGroup(groupID, "Load SAM Crate (1000)", path, loadCargoCommand, samParms1000)
|
missionCommands.addCommandForGroup(groupID, "Load SAM Crate (1000)", path, loadCargoCommand, samParms1000)
|
||||||
|
|
||||||
---@type LoadCargoCommandParams
|
---@type LoadCargoCommandParams
|
||||||
local samParms2000 = { unitID = unit:getID(), groupID = group:getID(), crateType = "FARP_CRATE_2000", supplyUnitsTracker = self._supplyUnitsTracker }
|
local samParms2000 = { unitID = unit:getID(), groupID = group:getID(), crateType = "SAM_CRATE_2000", supplyUnitsTracker = self._supplyUnitsTracker }
|
||||||
missionCommands.addCommandForGroup(groupID, "Load SAM Crate (2000)", path, loadCargoCommand, samParms2000)
|
missionCommands.addCommandForGroup(groupID, "Load SAM Crate (2000)", path, loadCargoCommand, samParms2000)
|
||||||
|
|
||||||
|
---@type LoadCargoCommandParams
|
||||||
|
local samParms2000 = { unitID = unit:getID(), groupID = group:getID(), crateType = "AIRBASE_CRATE_2000", supplyUnitsTracker = self._supplyUnitsTracker }
|
||||||
|
missionCommands.addCommandForGroup(groupID, "Airbase Crate (2000)", path, loadCargoCommand, samParms2000)
|
||||||
end
|
end
|
||||||
|
|
||||||
function MissionCommandsHelper:AddCargoCommands(groupID)
|
function MissionCommandsHelper:AddCargoCommands(groupID)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
---@alias SupplyType
|
---@alias SupplyType
|
||||||
---| "FARP_CRATE"
|
---| "FARP_CRATE"
|
||||||
---| "SAM_CRATE"
|
---| "SAM_CRATE"
|
||||||
|
---| "AIRBASE_CRATE"
|
||||||
|
|
||||||
---@alias CrateType
|
---@alias CrateType
|
||||||
---| "FARP_CRATE_500"
|
---| "FARP_CRATE_500"
|
||||||
@@ -10,6 +11,7 @@
|
|||||||
---| "SAM_CRATE_500"
|
---| "SAM_CRATE_500"
|
||||||
---| "SAM_CRATE_1000"
|
---| "SAM_CRATE_1000"
|
||||||
---| "SAM_CRATE_2000"
|
---| "SAM_CRATE_2000"
|
||||||
|
---| "AIRBASE_CRATE_2000"
|
||||||
|
|
||||||
---@class SupplyConfig
|
---@class SupplyConfig
|
||||||
---@field type SupplyType
|
---@field type SupplyType
|
||||||
@@ -55,6 +57,12 @@ local SupplyConfig = {
|
|||||||
displayName = "SAM Crate (2000)",
|
displayName = "SAM Crate (2000)",
|
||||||
staticType = "container_cargo",
|
staticType = "container_cargo",
|
||||||
},
|
},
|
||||||
|
["AIRBASE_CRATE_2000"] = {
|
||||||
|
type = "AIRBASE_CRATE",
|
||||||
|
weight = 2000,
|
||||||
|
displayName = "Airbase Crate (2000)",
|
||||||
|
staticType = "container_cargo",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
---@class MaxLoadConfig
|
---@class MaxLoadConfig
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
---@field private _requiredKilos number
|
---@field private _requiredKilos number
|
||||||
---@field private _droppedKilos number
|
---@field private _droppedKilos number
|
||||||
---@field private _crateType SupplyType
|
---@field private _crateType SupplyType
|
||||||
---@field private _targetZoneName string
|
---@field private _targetZone SpearheadTriggerZone
|
||||||
---@field private _database Database
|
---@field private _database Database
|
||||||
---@field private _onCrateDroppedOfListeners Array<OnCrateDroppedListener>
|
---@field private _onCrateDroppedOfListeners Array<OnCrateDroppedListener>
|
||||||
---@field private _markIDsPerGroup table<string, number>
|
---@field private _markIDsPerGroup table<string, number>
|
||||||
@@ -20,19 +20,19 @@ BuildableMission.__index = BuildableMission
|
|||||||
---@field OnCrateDroppedOff fun(self:OnCrateDroppedListener, mission:BuildableMission, kilos:number)
|
---@field OnCrateDroppedOff fun(self:OnCrateDroppedListener, mission:BuildableMission, kilos:number)
|
||||||
|
|
||||||
---@param database Database
|
---@param database Database
|
||||||
---@param targetZoneName string
|
---@param targetZone SpearheadTriggerZone
|
||||||
---@param requiredKilos number
|
---@param requiredKilos number
|
||||||
---@param requiredCrateType SupplyType
|
---@param requiredCrateType SupplyType
|
||||||
---@param noLandingZone SpearheadTriggerZone?
|
---@param noLandingZone SpearheadTriggerZone?
|
||||||
---@param logger Logger
|
---@param logger Logger
|
||||||
function BuildableMission.new(database, logger, targetZoneName, noLandingZone, requiredKilos, requiredCrateType)
|
function BuildableMission.new(database, logger, targetZone, noLandingZone, requiredKilos, requiredCrateType)
|
||||||
|
|
||||||
local Mission = Spearhead.classes.stageClasses.missions.baseMissions.Mission
|
local Mission = Spearhead.classes.stageClasses.missions.baseMissions.Mission
|
||||||
setmetatable(BuildableMission, Mission)
|
setmetatable(BuildableMission, Mission)
|
||||||
|
|
||||||
local self = setmetatable({}, { __index = BuildableMission })
|
local self = setmetatable({}, { __index = BuildableMission })
|
||||||
|
|
||||||
self._targetZoneName = targetZoneName
|
self._targetZone = targetZone
|
||||||
self._database = database
|
self._database = database
|
||||||
self._requiredKilos = requiredKilos
|
self._requiredKilos = requiredKilos
|
||||||
self._droppedKilos = 0
|
self._droppedKilos = 0
|
||||||
@@ -46,7 +46,7 @@ function BuildableMission.new(database, logger, targetZoneName, noLandingZone, r
|
|||||||
|
|
||||||
---@type SpearheadTriggerZone
|
---@type SpearheadTriggerZone
|
||||||
local dropOfZone = {
|
local dropOfZone = {
|
||||||
name = targetZoneName .. "_dropZone",
|
name = targetZone.name .. "_dropZone",
|
||||||
zone_type = "Polygon",
|
zone_type = "Polygon",
|
||||||
radius = 0,
|
radius = 0,
|
||||||
verts = enlarged,
|
verts = enlarged,
|
||||||
@@ -66,7 +66,7 @@ function BuildableMission.new(database, logger, targetZoneName, noLandingZone, r
|
|||||||
type = "FARP"
|
type = "FARP"
|
||||||
end
|
end
|
||||||
|
|
||||||
self.zoneName = targetZoneName .. "_supply"
|
self.zoneName = targetZone.name .. "_supply"
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
self._onCrateDroppedOfListeners = {}
|
self._onCrateDroppedOfListeners = {}
|
||||||
self._completeListeners = {}
|
self._completeListeners = {}
|
||||||
@@ -74,13 +74,8 @@ function BuildableMission.new(database, logger, targetZoneName, noLandingZone, r
|
|||||||
self._supplyUnitsTracker = Spearhead.classes.stageClasses.helpers.SupplyUnitsTracker.getOrCreate(logger.LogLevel)
|
self._supplyUnitsTracker = Spearhead.classes.stageClasses.helpers.SupplyUnitsTracker.getOrCreate(logger.LogLevel)
|
||||||
self._state = "NEW"
|
self._state = "NEW"
|
||||||
|
|
||||||
local spearheadZone = Spearhead.DcsUtil.getZoneByName(targetZoneName)
|
|
||||||
if spearheadZone == nil then
|
|
||||||
logger:error("Zone not found: " .. targetZoneName)
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
self.location = spearheadZone.location
|
self.location = targetZone.location
|
||||||
|
|
||||||
self.missionType = "LOGISTICS"
|
self.missionType = "LOGISTICS"
|
||||||
self.missionTypeDisplay = "LOGISTICS"
|
self.missionTypeDisplay = "LOGISTICS"
|
||||||
@@ -110,6 +105,8 @@ function BuildableMission:ShowBriefing(groupID)
|
|||||||
local siteType = "FARP"
|
local siteType = "FARP"
|
||||||
if self._crateType == "SAM_CRATE" then
|
if self._crateType == "SAM_CRATE" then
|
||||||
siteType = "SAM site"
|
siteType = "SAM site"
|
||||||
|
elseif self._crateType == "AIRBASE_CRATE" then
|
||||||
|
siteType = "airbase"
|
||||||
end
|
end
|
||||||
|
|
||||||
local briefing = "Mission [" .. self.code .. "] " .. self.name ..
|
local briefing = "Mission [" .. self.code .. "] " .. self.name ..
|
||||||
@@ -146,6 +143,11 @@ end
|
|||||||
|
|
||||||
function BuildableMission:SpawnActive()
|
function BuildableMission:SpawnActive()
|
||||||
|
|
||||||
|
if self._state ~= "NEW" then
|
||||||
|
self._logger:debug("Mission already spawned: " .. self.code)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
self._logger:debug("Spawning buildable mission: " .. self.code)
|
self._logger:debug("Spawning buildable mission: " .. self.code)
|
||||||
|
|
||||||
if self._noLandingZone == nil then
|
if self._noLandingZone == nil then
|
||||||
|
|||||||
Reference in New Issue
Block a user