Zone configuration (#62)

* wip

* updates on trigger zone labels, mgrs fix, mission briefings

---------

Co-authored-by: ex61wi <tim.rorije@ing.com>
Co-authored-by: dutchie032 <dutchie032>
This commit is contained in:
2025-09-03 11:58:48 +02:00
committed by GitHub
co-authored by ex61wi dutchie032 <dutchie032>
parent 1d4c0a8313
commit bd023b46ac
10 changed files with 195 additions and 184 deletions
+32 -28
View File
@@ -54,21 +54,20 @@
<h3 id="stage-zones">Stage Zones</h3>
<p>
<strong>Format:</strong> <span class="inline-lua"><span class="lua-variable">MISSIONSTAGE_[OrderNumber]_[FreeForm]</span></span>
<strong>Format:</strong> <code-inline>MISSIONSTAGE_[OrderNumber]_[FreeForm]</code-inline>
<br />
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">MISSIONSTAGE_1_EAST</span></span>
<strong>Example:</strong> <code-inline>MISSIONSTAGE_1_EAST</code-inline>
</p>
<p>
Stages are logical parts of a mission. They encapsulate multiple missions, airbases, and other
objects. <br />
Secondary stages can be defined using the format: <span
class="inline-lua"><span class="lua-variable">MISSIONSTAGE_x[OrderNumber]</span></span>.
Secondary stages can be defined using the format: <code-inline>MISSIONSTAGE_x[OrderNumber]</code-inline>.
</p>
<h3 id="waiting-stages">Waiting Stages</h3>
<p>
<strong>Format:</strong> <span class="inline-lua"><span class="lua-variable">WAITINGSTAGE_[Order]_[Seconds]</span></span> <br />
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">WAITINGSTAGE_2_180</span></span>
<strong>Format:</strong> <code-inline>WAITINGSTAGE_[Order]_[Seconds]</code-inline> <br />
<strong>Example:</strong> <code-inline>WAITINGSTAGE_2_180</code-inline>
</p>
<p>
Waiting stages introduce delays between stages. They activate only after the previous stage is
@@ -77,8 +76,8 @@
<h3 id="mission-zones">Mission Zones</h3>
<p>
<strong>Format:</strong> <span class="inline-lua"><span class="lua-variable">MISSION_[Type]_[Name]</span></span> <br />
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">MISSION_DEAD_BYRON</span></span>
<strong>Format:</strong> <code-inline>MISSION_[Type]_[Name]</code-inline> <br />
<strong>Example:</strong> <code-inline>MISSION_DEAD_BYRON</code-inline>
</p>
<p>
Missions are completable objectives with specific types, such as DEAD, BAI, STRIKE, or SAM. <br />
@@ -88,8 +87,8 @@
<h3 id="cap-routes">CAP Routes</h3>
<p>
<strong>Format:</strong> <span class="inline-lua"><span class="lua-variable">CAPROUTE_[routeID]_[Name]</span></span> <br />
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">CAPROUTE_103_ALPHA</span></span>
<strong>Format:</strong> <code-inline>CAPROUTE_[routeID]_[Name]</code-inline> <br />
<strong>Example:</strong> <code-inline>CAPROUTE_103_ALPHA</code-inline>
</p>
<p>
CAP routes define the patrol paths for CAP units. They are tied to specific stages and zones.
@@ -97,9 +96,9 @@
<h3 id="farp-zones">FARP Zones</h3>
<p>
<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">FARP_A_HOUSTON</span></span>
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">FARP_B_HOUSTON</span></span>
<strong>Format:</strong> <code-inline>FARP_A|B_[Name]</code-inline> <br />
<strong>Example:</strong> <code-inline>FARP_A_HOUSTON</code-inline>
<strong>Example:</strong> <code-inline>FARP_B_HOUSTON</code-inline>
</p>
<p>
FARP zones are spawned and activated based on the "activation parameter". <br/>
@@ -113,9 +112,9 @@
<h3 id="supply-hub">Supply Hub</h3>
<p>
<strong>Format:</strong> <span class="inline-lua"><span class="lua-variable">SUPPLYHUB_[Name]</span></span> <br />
<strong>Format:</strong> <span class="inline-lua"><span class="lua-variable">SUPPLYHUB_A_[Name]</span></span> <br />
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">SUPPLYHUB_HOUSTON</span></span> <br/> <br/>
<strong>Format:</strong> <code-inline>SUPPLYHUB_[Name]</code-inline> <br />
<strong>Format:</strong> <code-inline>SUPPLYHUB_A_[Name]</code-inline> <br />
<strong>Example:</strong> <code-inline>SUPPLYHUB_HOUSTON</code-inline> <br/> <br/>
Supply hubs are used as zones to pick up logistics for logistic missions. <br/>
They are activated when their parent is activated. <br/>
@@ -175,7 +174,7 @@
They are replaced with the corresponding values at the time a briefing is requested and can therefore show real time data. <br/>
<strong>Field:</strong> <span class="inline-lua"><span class="lua-variable">{{coords}}</span></span><br/>
<strong>Field:</strong> <code-inline>{{coords}}</code-inline><br/>
Coords are taken from the location of the trigger zone. Then converted to the aircrafts preferred format. <br/>
</p>
@@ -186,12 +185,12 @@
<h3 id="cap-group-naming">CAP Group Naming</h3>
<p>
<strong>Format:</strong> <span class="inline-lua"><span class="lua-variable">CAP_[A|B][Config]_[FreeForm]</span></span> <br />
<strong>Example:</strong> <span class="inline-lua"><span class="lua-variable">CAP_A[1-4]5_SomeName</span></span>
<strong>Format:</strong> <code-inline>CAP_[A|B][Config]_[FreeForm]</code-inline> <br />
<strong>Example:</strong> <code-inline>CAP_A[1-4]5_SomeName</code-inline>
</p>
<h3 id="cap-group-config">CAP Group Config</h3>
<pre>
<code-block>
<span class="lua-comment">1 at x:</span> <span class="lua-variable">[&lt;activeStage&gt;]&lt;CapRouteID&gt;</span>
<span class="lua-comment">n and n at x:</span> <span class="lua-variable">[&lt;activeStage&gt;,&lt;activeStage&gt;]&lt;CapRouteID&gt;</span>
<span class="lua-comment">n till n at x:</span> <span class="lua-variable">[&lt;activeStage&gt;-&lt;activeStage&gt;]&lt;CapRouteID&gt;</span>
@@ -202,7 +201,7 @@
<span class="lua-comment">Examples:</span>
<span class="lua-variable">CAP_A[1-4,6]7|[5,7]8_SomeName</span> <span class="lua-comment">=&gt; Will fly CAP at stage 7 when stages 1 through 4 and 6 are active and will fly CAP at 8 when 5 and 7 are active.</span>
<span class="lua-variable">CAP_A[2-5]5|[6]6_SomeName</span> <span class="lua-comment">=&gt; Will fly CAP at stage 5 when stages 2 through 5 are active and will fly CAP at CapRoute 6 when 6 is active.</span>
</pre>
</code-block>
<h3 id="active-and-backup-cap">Active and Backup CAP</h3>
<p>
@@ -221,7 +220,7 @@
<p>
If you want to have missions inside of a stage depends on each other you can. <br/>
Add a text drawing box inside of the mission trigger zone with the name:
<span class="inline-lua"><span class="lua-variable">dependson_[freeform]</span></span> <br/>
<code-inline>dependson_[freeform]</code-inline> <br/>
And in the text add the "Name" of the mission zone you want the mission to depend on. <br/>
The mission will be "pre-activated" (spawned) but won't have a f10 mission menu until the mission(s) it depends on is completed. <br/>
</p>
@@ -229,17 +228,22 @@
<h2 id="buildable">Buildables</h2>
<p>
Current buildables: <br/>
<span class="inline-lua"><span class="lua-variable">FARP_</span></span> <br/>
<span class="inline-lua"><span class="lua-variable">BLUESAM_</span></span> <br/>
<span class="inline-lua"><span class="lua-variable">Airbases</span></span> <br/>
<code-inline>FARP_</code-inline> <br/>
<code-inline>BLUESAM_</code-inline> <br/>
<code-inline>Airbases</code-inline> <br/>
<br/>
Buildables are zones or objects that first require logistics. <br/>
Eg. A forward SAM site or FARP requires logistic crates before it can be built. <br/>
To make an item buildable add a text box inside of the trigger zone and name it: <span class="inline-lua"><span class="lua-variable">buildable_[freeform]</span></span> <br/>
<br>
To make a zone buildable (farp, or bluesam): Select triggerzone -> below the property box hit "Add" -> Property Name should be <code-inline>buildable</code-inline> -> Value should be the kilos required eg. <code-inline>8000</code-inline>
<br>
To make an airbase buildable add a text box inside of the trigger zone and name it: <code-inline>buildable_[freeform]</code-inline> <br/>
Then in the text box type amount of kilo's you want to be transfered before the logistisc mission is complete. <br/>
The base will slowly build up with each crate giving both a nice view of it happening AND it's good for performance as there's not a big addition of objects at once. <br/>
<br>
The base or zone will slowly build up with each crate giving both a nice view of it happening AND it's good for performance as there's not a big addition of objects at once. <br/>
Right now a crate takes 15 seconds to unpack per 500kg. Meaning 2 crates of 1000kg will be faster than 1 crate of 2000kg. <br/>
All helicopters have a max limit set based on quick google searches and cannot be changed but the ME at this point: <br/>
Binary file not shown.
+1 -1
View File
@@ -939,7 +939,7 @@ do -- INIT DCS_UTIL
if coordType == "MGRS" then
local mgrs = coord.LLtoMGRS(lattitude, longitude)
return string.format("%s %s %s %s", mgrs.UTMZone, mgrs.MGRSDigraph, mgrs.Northing, mgrs.Easting)
return string.format("%s %s %s %s", mgrs.UTMZone, mgrs.MGRSDigraph, mgrs.Easting, mgrs.Northing)
end
-- Convert DD to DDM (Degrees Decimal Minutes)
+113 -134
View File
@@ -15,7 +15,6 @@
---@field CarrierRouteZones Array<string> All Carrier routes zones
---@field BlueSams Array<string> All blue sam zones
---@field SupplyHubZones Array<string> All supply hub zones
---@field MissionAnnotations table<string, MissionAnnotations> table<ZoneName, MissionAnnotations>
---@field AirbaseDataPerAirfield table<string, AirbaseData>
---@field BlueSamDataPerZone table<string, BlueSamData>
---@field MissionZoneData table<string, MissionZoneData>
@@ -27,13 +26,9 @@
---@field zones Array<SpearheadTriggerZone>
---@field current number
---@class MissionAnnotations
---@field description string?
---@field dependsOn Array<string>
---@field completeAt number?
---@class StageZoneData
---@field StageZoneName string
---@field StageBriefing string?
---@field AirbaseNames Array<string>
---@field FarpZones Array<string>
---@field MissionZones Array<string>
@@ -58,9 +53,13 @@
---@field buildingKilos number?
---@class MissionZoneData
---@field ZoneName string
---@field RedGroups Array<string>
---@field SceneryTargets Array<SpearheadSceneryObject>
---@field BlueGroups Array<string>
---@field description string?
---@field dependsOn Array<string>
---@field completeAt number?
---@class FarpZoneData
---@field groups Array<string>
@@ -99,7 +98,6 @@ function Database.New(Logger)
MissionZoneData = {},
FarpZoneData = {},
missionCodes = {},
MissionAnnotations = {},
SupplyHubZones = {}
}
@@ -209,47 +207,12 @@ function Database.New(Logger)
if string.lower(layer.name) == "author" then
for key, layer_object in pairs(layer.objects) do
if Spearhead.Util.startswith(string.lower(layer_object.name), "buildable", true) == true then
local blueSamData = self:getBlueSamDataForDrawLayer(layer_object)
if blueSamData then
local number = tonumber(layer_object.text)
blueSamData.buildingKilos = number
end
local farpData = self:getFarpDataForDrawLayer(layer_object)
if farpData then
local number = tonumber(layer_object.text)
farpData.buildingKilos = number
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
local annotationData = self:getMissionMetaDataForDrawLayer(layer_object)
if annotationData then
local number = tonumber(layer_object.text)
if number and number > 1 then
number = number / 100
end
annotationData.completeAt = number
end
elseif Spearhead.Util.startswith(string.lower(layer_object.name), "dependson", true) == true then
local annotationData = self:getMissionMetaDataForDrawLayer(layer_object)
if annotationData then
table.insert(annotationData.dependsOn, layer_object.text)
end
elseif Spearhead.Util.startswith(layer_object.name, "stagebriefing", true) == true then
--[[
TODO: Stage Briefings
]]
else
local annotationData = self:getMissionMetaDataForDrawLayer(layer_object)
if annotationData then
annotationData.description = layer_object.text
end
end
end
end
@@ -266,6 +229,27 @@ function Database.New(Logger)
for _, stageZoneName in pairs(self._tables.StageZoneNames) do
local stageData = self._tables.StageZones[stageZoneName]
if stageData then
-- Find and add Briefing
if env.mission.drawings and env.mission.drawings.layers then
for i, layer in pairs(env.mission.drawings.layers) do
if string.lower(layer.name) == "author" then
for key, layer_object in pairs(layer.objects) do
if Spearhead.Util.startswith(string.lower(layer_object.name), "stagebriefing_", true) == true then
local zone = Spearhead.DcsUtil.getZoneByName(stageZoneName)
local vec2 = { x = layer_object.mapX, y = layer_object.mapY }
if zone and Spearhead.Util.is2dPointInZone(vec2, zone) == true then
local description = layer_object.text
if description and description ~= "" then
stageData.StageBriefing = description
end
end
end
end
end
end
end
-- fill blue sams
for _, blueSamStageName in pairs(self._tables.BlueSams) do
if Spearhead.DcsUtil.isZoneInZone(blueSamStageName, stageZoneName) == true then
@@ -347,13 +331,13 @@ function Database.New(Logger)
end
for _, missionZone in pairs(self._tables.MissionZones) do
if self._tables.MissionAnnotations[missionZone] == nil or self._tables.MissionAnnotations[missionZone].description == nil then
if self._tables.MissionZoneData[missionZone] == nil or self._tables.MissionZoneData[missionZone].description == nil then
Spearhead.AddMissionEditorWarning("Mission with zonename: " .. missionZone .. " does not have a briefing")
end
end
for _, missionZone in pairs(self._tables.RandomMissionZones) do
if self._tables.MissionAnnotations[missionZone] == nil or self._tables.MissionAnnotations[missionZone].description == nil then
if self._tables.MissionZoneData[missionZone] == nil or self._tables.MissionZoneData[missionZone].description == nil then
Spearhead.AddMissionEditorWarning("Mission with zonename: " .. missionZone .. " does not have a briefing")
end
end
@@ -384,7 +368,7 @@ function Database.New(Logger)
self:loadBlueSamUnits()
self:loadMissionzoneUnits()
self:loadRandomMissionzoneUnits()
self:loadFarpGroups()
self:loadFarpData()
self:loadAirbaseGroups()
self:loadMiscGroupsInStages()
@@ -490,31 +474,6 @@ function Database:initAvailableUnits()
end
end
---comment
---@private
---@param layer_object table
---@return BlueSamData?
function Database:getBlueSamDataForDrawLayer(layer_object)
for _, zonename in pairs(self._tables.BlueSams) do
if Spearhead.DcsUtil.isPositionInZone(layer_object.mapX, layer_object.mapY, zonename) == true then
return self:getOrCreateBlueSamDataForZone(zonename)
end
end
return nil
end
---@private
---@param layer_object table
---@return FarpZoneData?
function Database:getFarpDataForDrawLayer(layer_object)
for _, zonename in pairs(self._tables.AllFarpZones) do
if Spearhead.DcsUtil.isPositionInZone(layer_object.mapX, layer_object.mapY, zonename) == true then
return self:getOrCreateFarpDataForZone(zonename)
end
end
return nil
end
---comment
---@param layer_object table
---@return AirbaseData?
@@ -536,7 +495,6 @@ function Database:getOrCreateBlueSamDataForZone(zoneName)
if blueSamData == nil then
blueSamData = {
groups = {},
buildingCrates = nil
}
self._tables.BlueSamDataPerZone[zoneName] = blueSamData
end
@@ -550,7 +508,6 @@ function Database:getOrCreateFarpDataForZone(zoneName)
farpData = {
padNames = {},
groups = {},
buildingCrates = nil,
supplyHubNames = {}
}
self._tables.FarpZoneData[zoneName] = farpData
@@ -577,38 +534,6 @@ function Database:getOrCreateAirbaseData(baseName)
return baseData
end
---@private
---@param layer_object table
---@return MissionAnnotations?
function Database:getMissionMetaDataForDrawLayer(layer_object)
for _, zonename in pairs(self._tables.MissionZones) do
if Spearhead.DcsUtil.isPositionInZone(layer_object.mapX, layer_object.mapY, zonename) == true then
if self._tables.MissionAnnotations[zonename] == nil then
self._tables.MissionAnnotations[zonename] = {
description = nil,
dependsOn = {}
}
end
return self._tables.MissionAnnotations[zonename]
end
end
for _, zonename in pairs(self._tables.RandomMissionZones) do
if Spearhead.DcsUtil.isPositionInZone(layer_object.mapX, layer_object.mapY, zonename) == true then
if self._tables.MissionAnnotations[zonename] == nil then
self._tables.MissionAnnotations[zonename] = {
description = nil,
dependsOn = {}
}
end
return self._tables.MissionAnnotations[zonename]
end
end
return nil
end
---@private
function Database:loadCapUnits()
local all_groups = getAvailableCAPGroups()
@@ -658,16 +583,31 @@ function Database:loadBlueSamUnits()
is_group_taken[groupName] = true
table.insert(samData.groups, groupName)
end
local triggerZone = Spearhead.DcsUtil.getZoneByName(blueSamZone)
if triggerZone then
for _, kvPair in pairs(triggerZone.properties) do
if kvPair.key and Spearhead.Util.startswith(kvPair.key, "buildable") then
local number = tonumber(kvPair.value)
if number and number > 0 then
samData.buildingKilos = number
end
end
end
end
end
end
---Loads all units, data and briefings
---@private
function Database:LoadZoneData(missionZoneName)
local all_groups = getAvailableGroups()
self._tables.MissionZoneData[missionZoneName] = {
RedGroups = {},
BlueGroups = {},
SceneryTargets = {}
SceneryTargets = {},
ZoneName = missionZoneName,
dependsOn = {}
}
local groups = Spearhead.DcsUtil.getGroupsInZone(all_groups, missionZoneName)
@@ -700,6 +640,47 @@ function Database:LoadZoneData(missionZoneName)
end
end
end
-- Check for properties and adds the settings to the mission data
local triggerZone = Spearhead.DcsUtil.getZoneByName(missionZoneName)
if triggerZone and triggerZone.properties then
for _, kvPair in pairs(triggerZone.properties) do
local key = kvPair.key
if Spearhead.Util.startswith(key, "dependson", true) == true then
table.insert(self._tables.MissionZoneData[missionZoneName].dependsOn, kvPair.value)
elseif Spearhead.Util.startswith(key, "completeat") == true then
local value = tonumber(kvPair.value)
if value then
if value > 1 and value <= 100 then
value = value / 100
elseif value > 100 then
Spearhead.AddMissionEditorWarning("Mission with zonename: " .. missionZoneName .. " has a complete at value of " .. value .. " which is higher than 100, this will not work as intended")
end
self._tables.MissionZoneData[missionZoneName].completeAt = value
end
end
end
end
---Adds Briefings
if env.mission.drawings and env.mission.drawings.layers then
for i, layer in pairs(env.mission.drawings.layers) do
if string.lower(layer.name) == "author" then
for key, layer_object in pairs(layer.objects) do
local vec2 = { x = layer_object.mapX, y = layer_object.mapY }
if triggerZone and Spearhead.Util.is2dPointInZone(vec2, triggerZone) then
if layer_object.name and Spearhead.Util.startswith(layer_object.name, "briefing_", true) then
local description = layer_object.text
if description and description ~= "" then
self._tables.MissionZoneData[missionZoneName].description = description
end
end
end
end
end
end
end
end
---@private
@@ -717,7 +698,7 @@ function Database:loadRandomMissionzoneUnits()
end
---@private
function Database:loadFarpGroups()
function Database:loadFarpData()
local all_groups = getAvailableGroups()
for _, farpZone in pairs(self._tables.AllFarpZones) do
local farpzoneData = self:getOrCreateFarpDataForZone(farpZone)
@@ -727,6 +708,18 @@ function Database:loadFarpGroups()
is_group_taken[groupName] = true
table.insert(farpzoneData.groups, groupName)
end
local triggerZone = Spearhead.DcsUtil.getZoneByName(farpZone)
if triggerZone then
for _, kvPair in pairs(triggerZone.properties) do
if kvPair.key and Spearhead.Util.startswith(kvPair.key, "buildable", true) == true then
local number = tonumber(kvPair.value)
if number and number > 0 then
farpzoneData.buildingKilos = number
end
end
end
end
end
end
@@ -810,34 +803,6 @@ function Database:loadMiscGroupsInStages()
end
end
---@return string?
function Database:getMissionBriefingForMissionZone(missionZoneName)
if not self._tables.MissionAnnotations[missionZoneName] then
return nil
end
return self._tables.MissionAnnotations[missionZoneName].description
end
---@param missionZoneName string
---@return Array<string>
function Database:getMissionDependencies(missionZoneName)
if not self._tables.MissionAnnotations[missionZoneName] then
return {}
end
return self._tables.MissionAnnotations[missionZoneName].dependsOn
end
---@return number?
function Database:getMissionCompleteAt(missionZoneName)
if not self._tables.MissionAnnotations[missionZoneName] then
return nil
end
return self._tables.MissionAnnotations[missionZoneName].completeAt
end
---comment
---@param missionZoneName any
---@return Vec2?
@@ -893,6 +858,14 @@ function Database:getCarrierRouteZones()
return self._tables.CarrierRouteZones
end
---@param stagename string
---@return string
function Database:getBriefingForStage(stagename)
local stageZone = self._tables.StageZones[stagename]
if not stageZone then return "" end
return stageZone.StageBriefing or ""
end
---@return Array<string>
function Database:getMissionsForStage(stagename)
local stageZone = self._tables.StageZones[stagename]
@@ -942,6 +915,12 @@ function Database:getAirbaseDataForZone(baseName)
return baseData
end
---@return string?
function Database:getStageBriefingForStage(stageName)
local stageData = self._tables.StageZones[stageName]
if not stageData then return nil end
return stageData.StageBriefing or nil
end
---@param stageName string
---@return Array<string>
@@ -54,7 +54,7 @@ function SpearheadGroup:Spawn(lateStart)
---@type SpawnOverrides
local overrides = {
uncontrolled = lateStart or false,
uncontrolled = lateStart,
}
local spawnedObject, isStatic = self._spawnManager:SpawnGroup(self._groupName, overrides, self._isPersistent)
@@ -59,6 +59,7 @@ function FarpZone.New(database, logger, zoneName, spawnManager)
local zone = Spearhead.DcsUtil.getZoneByName(zoneName)
if zone then
self._logger:debug("Creating Buildable zone: " .. zoneName .. " with " .. (farpData.buildingKilos or "nil") .. " kilos")
Spearhead.classes.stageClasses.SpecialZones.abstract.BuildableZone.New(self, zone, farpData.buildingKilos or 0, "FARP_CRATE", self._groups, logger, database)
end
end
@@ -28,6 +28,7 @@ function BuildableZone:New(targetZone, kilosRequired, crateType, buildableGroup
self._receivedBuildingKilos = 0
local persistedKilos = Spearhead.classes.persistence.Persistence.GetZoneDeliveredKilos(targetZone.name)
if persistedKilos and persistedKilos > 0 then
self._buildableLogger:debug("Zone " .. targetZone.name .. " already has " .. persistedKilos .. " kilos delivered")
self._receivedBuildingKilos = persistedKilos
---@param params UnpackCrateParam
@@ -5,6 +5,7 @@
---| "GRAY"
--- @class StageData
--- @field stageBriefing string?
--- @field missionsByCode table<string, Mission>
--- @field missionsByName table<string, Mission>
--- @field missions Array<ZoneMission>
@@ -29,6 +30,7 @@
--- @field zoneName string
--- @field stageName string?
--- @field stageNumber number
--- @field protected _missionCommandsHelper MissionCommandsHelper
--- @field protected _isActive boolean
--- @field protected _isComplete boolean
--- @field protected _missionPriority MissionPriority
@@ -83,6 +85,7 @@ function Stage:superNew(database, stageConfig, logger, initData, missionPriority
self._database = database
self._logger = logger
self._db = {
stageBriefing = nil,
missionsByCode = {},
missions = {},
sams ={},
@@ -98,6 +101,7 @@ function Stage:superNew(database, stageConfig, logger, initData, missionPriority
self._activeStage = -99
self._preActivated = false
self._stageConfig = stageConfig or {}
self._missionCommandsHelper = Spearhead.classes.stageClasses.helpers.MissionCommandsHelper.getOrCreate(logger.LogLevel)
local zone = Spearhead.DcsUtil.getZoneByName(self.zoneName)
if zone then
@@ -120,6 +124,7 @@ function Stage:superNew(database, stageConfig, logger, initData, missionPriority
table.insert(self._db.supplyHubs, supplyHub)
end
self._db.stageBriefing = database:getStageBriefingForStage(self.zoneName)
self._logger:info("Initiating new Stage with name: " .. self.zoneName)
---comment
@@ -238,7 +243,7 @@ function Stage:superNew(database, stageConfig, logger, initData, missionPriority
end
Spearhead.Events.AddStageNumberChangedListener(self)
return self
end
@@ -453,6 +458,10 @@ function Stage:OnStageNumberChanged(number)
if number == self.stageNumber then
self:ActivateStage()
if self._db and self._db.stageBriefing then
self._missionCommandsHelper:AddStageBriefing(self.zoneName, self._db.stageBriefing)
end
end
if previousActive <= self.stageNumber then
@@ -460,6 +469,10 @@ function Stage:OnStageNumberChanged(number)
self:ActivateBlueStage()
end
end
if number > self.stageNumber then
self._missionCommandsHelper:RemoveStageBriefing(self.zoneName)
end
end
function Stage:GetBriefing()
@@ -6,6 +6,7 @@
---@field lastUpdate number @last update time
---@field updateContinuous fun(self: MissionCommandsHelper, time: number): number @function to update commands continuously
---@field pinnedByGroup table<string, Mission> @table of pinned missions by group ID
---@field private _stageBriefings table<string, string> @table of stage briefings by stage name
---@field private _supplyHubGroups table<string, boolean> @table of supply hub groups by their ID
---@field private _logger Logger @logger instance for logging
---@field private _supplyUnitsTracker SupplyUnitsTracker @supply units tracker instance
@@ -32,6 +33,7 @@ function MissionCommandsHelper.getOrCreate(logLevel)
instance.pinnedByGroup = {}
instance.lastUpdate = 0
instance._supplyHubGroups = {}
instance._stageBriefings = {}
instance._supplyUnitsTracker = Spearhead.classes.stageClasses.helpers.SupplyUnitsTracker.getOrCreate(logLevel)
@@ -66,6 +68,14 @@ function MissionCommandsHelper.getOrCreate(logLevel)
return instance
end
function MissionCommandsHelper:AddStageBriefing(stageName, briefing)
self._stageBriefings[stageName] = briefing
end
function MissionCommandsHelper:RemoveStageBriefing(stageName)
self._stageBriefings[stageName] = nil
end
---@param mission Mission
function MissionCommandsHelper:AddMissionToCommands(mission)
self._logger:debug("Adding mission to commands: [" .. mission.code .. "]" .. mission.name)
@@ -174,6 +184,10 @@ function MissionCommandsHelper:AddOverviewCommand(groupID)
return string.format("[%s]\t%s \t%s \t%s %% \t%s nM\n", mission.code, mission.missionTypeDisplay, mission.name, mission:PercentageComplete(), distanceText)
end
for _, briefing in pairs(self._stageBriefings) do
text = text .. briefing .. "\n\n"
end
---Primary missions
text = text .. "Primary Missions\n"
for code, enabled in pairs(self.enabledByCode) do
+18 -19
View File
@@ -81,7 +81,10 @@ function ZoneMission.new(zoneName, priority, database, logger, parentStage, spaw
return nil
end
local missionBriefing = database:getMissionBriefingForMissionZone(zoneName) or "no briefing provided"
local missionData = database:getMissionDataForZone(zoneName)
if not missionData then return end
local missionBriefing = missionData.description or "No briefing available"
local success, error = Mission.newSuper(self, zoneName, parsed.missionName, parsed.type, missionBriefing, priority,
database, logger)
@@ -109,26 +112,22 @@ function ZoneMission.new(zoneName, priority, database, logger, parentStage, spaw
self._parentStage = parentStage
self._dependencies = {}
local dependencies = database:getMissionDependencies(zoneName)
for _, dependency in pairs(dependencies) do
self._dependencies[dependency] = false
end
local completeAtIndex = database:getMissionCompleteAt(zoneName)
if completeAtIndex == nil and self.missionType == "BAI" or self.missionType == "CAS" then
self._completeAtIndex = 0.8
elseif completeAtIndex == nil then
self._completeAtIndex = 1
else
self._completeAtIndex = completeAtIndex
end
self._logger:debug("Complete at index " .. self.zoneName .. ": " .. self._completeAtIndex)
local SpearheadGroup = Spearhead.classes.stageClasses.Groups.SpearheadGroup
local missionData = database:getMissionDataForZone(zoneName)
if not missionData then return end
if missionData.dependsOn then
for _, dependency in pairs(missionData.dependsOn) do
self._dependencies[dependency] = false
end
end
if missionData.completeAt == nil and (self.missionType == "BAI" or self.missionType == "CAS") then
self._completeAtIndex = 0.8
elseif missionData.completeAt == nil then
self._completeAtIndex = 1
else
self._completeAtIndex = missionData.completeAt
end
self._missionGroups.sceneryTargets = missionData.SceneryTargets or {}
if Spearhead.Util.tableLength(self._missionGroups.sceneryTargets) > 0 then
self._missionGroups.hasTargets = true