Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
446a98dc3b | ||
|
|
8cacad84a1 | ||
|
|
f3a38db5ca | ||
|
|
81d9aa7265 | ||
|
|
52f840c270 | ||
|
|
d14a0dc78e |
@@ -169,7 +169,7 @@ class Sidebar extends HTMLElement {
|
||||
|
||||
render() {
|
||||
var betaHtml = '';
|
||||
if (true || window.location.hostname.toLowerCase() == 'beta.spearhead.rocks') {
|
||||
if (window.location.hostname.toLowerCase() == 'beta.spearhead.rocks') {
|
||||
betaHtml = '<note-box type="warning" title="Beta Version">You are looking at docs that are released with the beta version.</note-box>';
|
||||
}
|
||||
|
||||
|
||||
@@ -26,14 +26,14 @@
|
||||
|
||||
<div class="content-wrapper">
|
||||
<h1>Advanced Tutorial: Missions</h1>
|
||||
<div id="strike-region">
|
||||
<h2 id="strike">Strike</h2>
|
||||
<p>
|
||||
Naming: <span class="inline-lua"><span class="lua-variable">MISSION_STRIKE_[Name]</span></span> <br>
|
||||
Naming: <code-inline>MISSION_STRIKE_[Name]</code-inline> <br>
|
||||
</p>
|
||||
<h3 id="specific_targets">Specific Targets</h3>
|
||||
<p>TBD</p>
|
||||
|
||||
|
||||
<h3 id="scenery_targets">Scenery Targets</h3>
|
||||
<p>
|
||||
Bridges, buildings or other type of targets that are baked into the map are awesome targets.<br>
|
||||
@@ -41,24 +41,100 @@
|
||||
</p>
|
||||
|
||||
<note-box type="info" title="Implementation details">
|
||||
Spearhead detects scenery targets by the trigger zone name. A zone named <strong>scenerytarget_[freeform]</strong> or
|
||||
<strong>scenerytargets</strong> (case-insensitive) will be scanned and any scenery objects that has the attribute "Buildings" inside the zone
|
||||
Spearhead detects scenery targets by the trigger zone name. A zone named
|
||||
<strong>scenerytarget_[freeform]</strong> or
|
||||
<strong>scenerytargets</strong> (case-insensitive) will be scanned and any scenery objects that
|
||||
has the attribute "Buildings" inside the zone
|
||||
will be added as mission scenery targets.
|
||||
</note-box>
|
||||
|
||||
<p>
|
||||
Scenery targets are treated like mission targets: they are included in the mission completion calculation
|
||||
(their `IsAlive()` state is checked) and their state is persisted/updated when missions spawn or resume.
|
||||
Scenery targets are treated like mission targets: they are included in the mission completion
|
||||
calculation
|
||||
(their `IsAlive()` state is checked) and their state is persisted/updated when missions spawn or
|
||||
resume.
|
||||
</p>
|
||||
|
||||
<note-box type="warning" title="Changing IDs">
|
||||
Due to Object IDs changing when maps are updated and edited the "Assign as..." functionality does not work for scenery targets.
|
||||
Due to Object IDs changing when maps are updated and edited the "Assign as..." functionality
|
||||
does not work for scenery targets.
|
||||
Hence the need to use trigger zones to define them.
|
||||
</note-box>
|
||||
|
||||
|
||||
<p>Here's two images showing how a bridge is added to a mission.</p>
|
||||
<img src="/img/bridge.png" style="max-height: 35remrem;"/>
|
||||
<img src="/img/bridge.png" style="max-height: 35remrem;" />
|
||||
</div>
|
||||
<div id="cas-region">
|
||||
<h2 id="cas">CAS</h2>
|
||||
<p>
|
||||
Naming: <code-inline>MISSION_CAS_[Name]</code-inline> <br>
|
||||
</p>
|
||||
|
||||
<h3 id="BattleManager">Battle Manager</h3>
|
||||
<p>TBD</p>
|
||||
</div>
|
||||
<div id="dead-region">
|
||||
<h2 id="dead">DEAD</h2>
|
||||
<p>
|
||||
Naming: <code-inline>MISSION_DEAD_[Name]</code-inline> <br>
|
||||
Naming: <code-inline>MISSION_SAM_[Name]</code-inline> <br>
|
||||
</p>
|
||||
|
||||
<h3 id="sam-vs-dead">SAM vs DEAD</h3>
|
||||
<p>TBD</p>
|
||||
</div>
|
||||
|
||||
<div id="bai-region">
|
||||
<h2 id="bai">BAI</h2>
|
||||
<p>
|
||||
Naming: <code-inline>MISSION_BAI_[Name]</code-inline> <br>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="deepstrike-region">
|
||||
<h2 id="deepstrike">DEEPSTRIKE</h2>
|
||||
<p>
|
||||
Naming: <code-inline>MISSION_DEEPSTRIKE_[Name]</code-inline> <br>
|
||||
<br>
|
||||
When you, as a mission editor, want to create a mission that's further away from the current front-line you can use the Deep Strike mission type. <br>
|
||||
This allows you to plan missions that require more strategic positioning and timing. <br>
|
||||
</p>
|
||||
|
||||
<h3 id="activation">Activation</h3>
|
||||
<p>
|
||||
Deep Strike missions are activated when the Stage in which they are located becomes "PreActive" or "Active". <br>
|
||||
"PreActive" is when either the current active StageNumber is a certain number of stages away OR the stage has "CAP" airbases active . <br>
|
||||
<code-inline>SpearheadConfig.StageConfig.preactivateStage</code-inline> changes the configuration. <br>
|
||||
<br>
|
||||
For example: <br>
|
||||
If the current active stage is <code-inline>MissionStage_2_[name]</code-inline> and preActivate config is set to 2. <br>
|
||||
Then both <code-inline>MissionStage_3_[name]</code-inline> and <code-inline>MissionStage_4_[name]</code-inline> would become "PreActive".
|
||||
</p>
|
||||
<h3 id="primary-vs-secondary">Make Primary</h3>
|
||||
<p>
|
||||
By default DEEPSTRIKE missions are "Secondary" missions when spawned as a pre-activated stage.<br>
|
||||
Then when the stage they are in is "Active", the mission becomes a "Primary" mission. <br>
|
||||
<br>
|
||||
If you want to make it a "Primary" mission from the start, you can overwrite it.<br>
|
||||
Click the mission's trigger zone. Add a property named <code-inline>primary</code-inline> and set it to <code-inline>true</code-inline>.
|
||||
This will make the mission "Primary" from the start. <br>
|
||||
<br>
|
||||
If you want it to "Secondary" even when its stage is the active stage, you can set "primary" to false. <br>
|
||||
<br>
|
||||
If you want to have it be "Secondary" when its stage is "Pre-Active" and "primary" when its stage is "Active" you don't have to do anything.
|
||||
</p>
|
||||
|
||||
<h3 id="future-additions">Future</h3>
|
||||
<p>
|
||||
In the future we're thinking it would be cool to make the Deep Strike missions
|
||||
be more integrated with the CAP airbases and/or logistics. <br>
|
||||
Eg. Completing a DEEPSTRIKE mission would disable CAP for X amount of minutes after completion. <br>
|
||||
This still needs to be refined, but we've already have ideas.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
--color-bg-hover: rgba(120, 140, 255, 0.12); /* More visible hover */
|
||||
--color-bg-note-dark: rgba(40, 35, 30, 0.85); /* Slightly darker note box */
|
||||
|
||||
--color-text-primary: #a5a5a5; /* Brighter text */
|
||||
--color-text-primary: #b4b3b3; /* Brighter text */
|
||||
--color-text-secondary: #bfc8d8; /* Lighter secondary text */
|
||||
--color-text-accent: #7ecbff; /* Brighter accent */
|
||||
--color-text-light: #ffffff;
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
Now enabled the mission editor to add a custom briefing to the "Buildable" missions.
|
||||
#44
|
||||
|
||||
- Issue: #42
|
||||
DEEPSTRIKE now added as a possible feature.
|
||||
This enables to have missions active in "Pre-Activated" Stages.
|
||||
#48
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
## [0.13.0] 2026-08
|
||||
|
||||
@@ -78,7 +78,7 @@ function FleetGroup.new(fleetGroupName, database, logger)
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
if Util.startswith(namePart, "%[") == true then
|
||||
if Util.startsWith(namePart, "%[") == true then
|
||||
namePart = Util.split_string(namePart, "[")[1]
|
||||
end
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ GlobalFleetManager.start = function(database)
|
||||
|
||||
local all_groups = MizGroupsManager.getAllGroupNames()
|
||||
for _, groupName in pairs(all_groups) do
|
||||
if Util.startswith(string.lower(groupName), "carriergroup" ) == true then
|
||||
if Util.startsWith(string.lower(groupName), "carriergroup" ) == true then
|
||||
logger:info("Registering " .. groupName .. " as a managed fleet")
|
||||
local carrierGroup = FleetGroup.new(groupName, database, logger)
|
||||
table.insert(fleetGroups, carrierGroup)
|
||||
|
||||
@@ -150,7 +150,7 @@ do
|
||||
for file in lfs.dir(dir) do
|
||||
|
||||
local split = Util.split_string(file, ".")
|
||||
local doesStartWith = Util.startswith(file, startsWith, true)
|
||||
local doesStartWith = Util.startsWith(file, startsWith, true)
|
||||
if split and #split > 0 and split[#split] == EXTENSION and doesStartWith == true then
|
||||
local numberString = split[#split-1]
|
||||
local number = tonumber(numberString)
|
||||
|
||||
@@ -69,6 +69,7 @@ local StageDrawing = require("classes.stageClasses.drawings.StageDrawing")
|
||||
---@field descriptionLocation Vec2?
|
||||
---@field dependsOn Array<string>
|
||||
---@field completeAt number?
|
||||
---@field primaryOverwrite boolean?
|
||||
|
||||
---@class FarpZoneData
|
||||
---@field groups Array<string>
|
||||
@@ -211,7 +212,7 @@ function Database.New(Logger)
|
||||
for _, layer in pairs(env.mission.drawings.layers) do
|
||||
if string.lower(layer.name) == "author" then
|
||||
for _, layer_object in pairs(layer.objects) do
|
||||
if Util.startswith(string.lower(layer_object.name), "buildable", true) == true then
|
||||
if Util.startsWith(string.lower(layer_object.name), "buildable", true) == true then
|
||||
local airbaseData = self:getAirbaseDataForDrawLayer(layer_object)
|
||||
if airbaseData then
|
||||
self._logger:debug("found airbase data for " .. layer_object.name)
|
||||
@@ -234,7 +235,7 @@ function Database.New(Logger)
|
||||
for _, layer in pairs(env.mission.drawings.layers) do
|
||||
if string.lower(layer.name) == "author" then
|
||||
for _, layer_object in pairs(layer.objects) do
|
||||
if Util.startswith(layer_object.name, "drawing_", true) then
|
||||
if Util.startsWith(layer_object.name, "drawing_", true) then
|
||||
local object = layer_object --[[@as DrawingObject]]
|
||||
local stageDrawing = StageDrawing.New(object)
|
||||
if stageDrawing then
|
||||
@@ -262,7 +263,7 @@ function Database.New(Logger)
|
||||
for _, layer in pairs(env.mission.drawings.layers) do
|
||||
if string.lower(layer.name) == "author" then
|
||||
for _, layer_object in pairs(layer.objects) do
|
||||
if Util.startswith(string.lower(layer_object.name), "stagebriefing_", true) == true then
|
||||
if Util.startsWith(string.lower(layer_object.name), "stagebriefing_", true) == true then
|
||||
local zone = DcsUtil.getZoneByName(stageZoneName)
|
||||
local vec2 = { x = layer_object.mapX, y = layer_object.mapY }
|
||||
if zone and Util.is2dPointInZone(vec2, zone) == true then
|
||||
@@ -491,7 +492,7 @@ end
|
||||
local getAvailableCAPGroups = function()
|
||||
local result = {}
|
||||
for name, value in pairs(is_group_taken) do
|
||||
if value == false and Util.startswith(name, "CAP") then
|
||||
if value == false and Util.startsWith(name, "CAP") then
|
||||
table.insert(result, name)
|
||||
end
|
||||
end
|
||||
@@ -594,11 +595,11 @@ function Database:loadCapUnits()
|
||||
for _, groupName in pairs(groups) do
|
||||
is_group_taken[groupName] = true
|
||||
|
||||
if Util.startswith(groupName, "CAP_A", true) or Util.startswith(groupName, "CAP_B", true) then
|
||||
if Util.startsWith(groupName, "CAP_A", true) or Util.startsWith(groupName, "CAP_B", true) then
|
||||
table.insert(baseData.CapGroups, groupName)
|
||||
elseif Util.startswith(groupName, "CAP_I", true) then
|
||||
elseif Util.startsWith(groupName, "CAP_I", true) then
|
||||
table.insert(baseData.InterceptGroups, groupName)
|
||||
elseif Util.startswith(groupName, "CAP_S", true) then
|
||||
elseif Util.startsWith(groupName, "CAP_S", true) then
|
||||
table.insert(baseData.SweepGroups, groupName)
|
||||
end
|
||||
end
|
||||
@@ -621,7 +622,7 @@ function Database:loadBlueSamUnits()
|
||||
local triggerZone = DcsUtil.getZoneByName(blueSamZone)
|
||||
if triggerZone then
|
||||
for _, kvPair in pairs(triggerZone.properties) do
|
||||
if kvPair.key and Util.startswith(kvPair.key, "buildable") then
|
||||
if kvPair.key and Util.startsWith(kvPair.key, "buildable") then
|
||||
local number = tonumber(kvPair.value)
|
||||
if number and number > 0 then
|
||||
samData.buildingKilos = number
|
||||
@@ -633,7 +634,7 @@ function Database:loadBlueSamUnits()
|
||||
|
||||
local vec2 = { x = layer_object.mapX, y = layer_object.mapY }
|
||||
if layer_object.primitiveType == "TextBox" and triggerZone and Util.is2dPointInZone(vec2, triggerZone) then
|
||||
if layer_object.name and Util.startswith(layer_object.name, "supplybriefing_", true) then
|
||||
if layer_object.name and Util.startsWith(layer_object.name, "supplybriefing_", true) then
|
||||
layer_object = layer_object --[[@as TextBox]]
|
||||
local description = layer_object.text
|
||||
if description and description ~= "" then
|
||||
@@ -710,9 +711,9 @@ function Database:LoadZoneData(missionZoneName)
|
||||
if triggerZone and triggerZone.properties then
|
||||
for _, kvPair in pairs(triggerZone.properties) do
|
||||
local key = kvPair.key
|
||||
if Util.startswith(key, "dependson", true) == true then
|
||||
if Util.startsWith(key, "dependson", true) == true then
|
||||
table.insert(self._tables.MissionZoneData[missionZoneName].dependsOn, kvPair.value)
|
||||
elseif Util.startswith(key, "completeat") == true then
|
||||
elseif Util.startsWith(key, "completeat") == true then
|
||||
local value = tonumber(kvPair.value)
|
||||
if value then
|
||||
if value > 1 and value <= 100 then
|
||||
@@ -722,6 +723,14 @@ function Database:LoadZoneData(missionZoneName)
|
||||
end
|
||||
self._tables.MissionZoneData[missionZoneName].completeAt = value
|
||||
end
|
||||
elseif Util.startsWith(key, "primary", true) == true then
|
||||
if type(kvPair.value) == "string" then
|
||||
if kvPair.value == "true" then
|
||||
self._tables.MissionZoneData[missionZoneName].primaryOverwrite = true
|
||||
elseif kvPair.value == "false" then
|
||||
self._tables.MissionZoneData[missionZoneName].primaryOverwrite = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -734,7 +743,7 @@ function Database:LoadZoneData(missionZoneName)
|
||||
|
||||
local vec2 = { x = layer_object.mapX, y = layer_object.mapY }
|
||||
if layer_object.primitiveType == "TextBox" and triggerZone and Util.is2dPointInZone(vec2, triggerZone) then
|
||||
if layer_object.name and Util.startswith(layer_object.name, "briefing_", true) then
|
||||
if layer_object.name and Util.startsWith(layer_object.name, "briefing_", true) then
|
||||
layer_object = layer_object --[[@as TextBox]]
|
||||
local description = layer_object.text
|
||||
if description and description ~= "" then
|
||||
@@ -778,7 +787,7 @@ function Database:loadFarpData()
|
||||
local triggerZone = DcsUtil.getZoneByName(farpZone)
|
||||
if triggerZone then
|
||||
for _, kvPair in pairs(triggerZone.properties) do
|
||||
if kvPair.key and Util.startswith(kvPair.key, "buildable", true) == true then
|
||||
if kvPair.key and Util.startsWith(kvPair.key, "buildable", true) == true then
|
||||
local number = tonumber(kvPair.value)
|
||||
if number and number > 0 then
|
||||
farpzoneData.buildingKilos = number
|
||||
@@ -792,7 +801,7 @@ function Database:loadFarpData()
|
||||
local vec2 = { x = layer_object.mapX, y = layer_object.mapY }
|
||||
if layer_object.primitiveType == "TextBox" and triggerZone and Util.is2dPointInZone(vec2, triggerZone) then
|
||||
layer_object = layer_object --[[@as TextBox]]
|
||||
if layer_object.name and Util.startswith(layer_object.name, "supplybriefing_", true) then
|
||||
if layer_object.name and Util.startsWith(layer_object.name, "supplybriefing_", true) then
|
||||
local description = layer_object.text
|
||||
if description and description ~= "" then
|
||||
farpzoneData.briefing = description
|
||||
|
||||
@@ -435,6 +435,12 @@ function Stage:PreActivate()
|
||||
end
|
||||
end
|
||||
|
||||
for _, mission in pairs(self._db.missions) do
|
||||
if mission and mission.missionType == "DEEPSTRIKE" then
|
||||
mission:SpawnInactive() --Not Really "inactive"
|
||||
end
|
||||
end
|
||||
|
||||
for _, airbase in pairs(self._db.airbases) do
|
||||
airbase:ActivateRedStage()
|
||||
end
|
||||
|
||||
@@ -210,7 +210,7 @@ function MissionCommandsHelper:OverviewToGroup(groupID)
|
||||
for code, enabled in pairs(self.enabledByCode) do
|
||||
if enabled == true then
|
||||
local mission = self.missionsByCode[code]
|
||||
if mission and mission:getState() == "ACTIVE" and mission.priority == "primary" then
|
||||
if mission and mission:getState() == "ACTIVE" and mission:GetPriority() == "primary" then
|
||||
table.insert(primaryMissions, mission)
|
||||
end
|
||||
end
|
||||
@@ -230,7 +230,7 @@ function MissionCommandsHelper:OverviewToGroup(groupID)
|
||||
for code, enabled in pairs(self.enabledByCode) do
|
||||
if enabled == true then
|
||||
local mission = self.missionsByCode[code]
|
||||
if mission and mission:getState() == "ACTIVE" and mission.priority == "secondary" then
|
||||
if mission and mission:getState() == "ACTIVE" and mission:GetPriority() == "secondary" then
|
||||
table.insert(secondaryMissions, mission)
|
||||
end
|
||||
end
|
||||
@@ -345,7 +345,7 @@ function MissionCommandsHelper:AddAllMissionCommandsToGroup(groupID)
|
||||
for code, enabled in pairs(self.enabledByCode) do
|
||||
if enabled == true then
|
||||
local mission = self.missionsByCode[code]
|
||||
if mission and mission.priority == "primary" then
|
||||
if mission and mission:GetPriority() == "primary" then
|
||||
table.insert(primaryMissions, mission)
|
||||
end
|
||||
end
|
||||
@@ -374,7 +374,7 @@ function MissionCommandsHelper:AddAllMissionCommandsToGroup(groupID)
|
||||
for code, enabled in pairs(self.enabledByCode) do
|
||||
if enabled == true then
|
||||
local mission = self.missionsByCode[code]
|
||||
if mission and mission.priority == "secondary" then
|
||||
if mission and mission:GetPriority() == "secondary" then
|
||||
table.insert(secondaryMissions, mission)
|
||||
end
|
||||
end
|
||||
@@ -416,7 +416,7 @@ function MissionCommandsHelper:addMissionCommands(groupId, path, mission)
|
||||
end
|
||||
|
||||
local missionFolderName = "[" ..
|
||||
mission.code .. "]" .. distance .. mission.name .. "( " .. mission.missionTypeDisplay .. " )"
|
||||
mission.code .. "]" .. distance .. mission.name .. "(" .. mission.missionTypeDisplay .. ")"
|
||||
missionCommands.addSubMenuForGroup(groupId, missionFolderName, path)
|
||||
table.insert(path, missionFolderName)
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ local SupplyConfigHelper = {}
|
||||
---@return SupplyConfig?
|
||||
function SupplyConfigHelper.fromObjectName(name)
|
||||
for configName, config in pairs(SupplyConfig) do
|
||||
if Util.startswith(name, configName, true) == true then
|
||||
if Util.startsWith(name, configName, true) == true then
|
||||
return config
|
||||
end
|
||||
end
|
||||
|
||||
@@ -259,7 +259,7 @@ function BuildableMission:CheckCratesInZone()
|
||||
|
||||
local crates = self._supplyUnitsTracker:GetCargoCratesDropped()
|
||||
for _, staticObject in pairs(crates) do
|
||||
if staticObject and staticObject:isExist() and Util.startswith(staticObject:getName(), self._crateType, true) then
|
||||
if staticObject and staticObject:isExist() and Util.startsWith(staticObject:getName(), self._crateType, true) then
|
||||
local pos = staticObject:getPoint()
|
||||
|
||||
if Util.is3dPointInZone(pos, self._dropOffZone) then
|
||||
|
||||
@@ -14,7 +14,7 @@ local DcsUtil = require("classes.util.DcsUtil")
|
||||
---@field private _completeAtIndex number
|
||||
---@field private _parentStage Stage
|
||||
---@field private _battleManager? BattleManager
|
||||
---@field private _lastContactMarkerID number;
|
||||
---@field private _lastContactMarkerID number
|
||||
local ZoneMission = {}
|
||||
|
||||
--- @class MissionGroups
|
||||
@@ -24,7 +24,7 @@ local ZoneMission = {}
|
||||
--- @field unitsAlive table<string, table<string, boolean>>
|
||||
--- @field targetsAlive table<string, table<string, boolean>>
|
||||
--- @field sceneryTargets Array<SpearheadSceneryObject>
|
||||
--- @field groupNamesPerunit table<string,string>
|
||||
--- @field groupNamesPerUnit table<string,string>
|
||||
|
||||
---@class ParsedMissionName
|
||||
---@field missionName string
|
||||
@@ -36,7 +36,7 @@ local ZoneMission = {}
|
||||
local function ParseZoneName(input)
|
||||
local split_name = Util.split_string(input, "_")
|
||||
local split_length = Util.tableLength(split_name)
|
||||
if Util.startswith(input, "RANDOMMISSION") == true and split_length < 4 then
|
||||
if Util.startsWith(input, "RANDOMMISSION") == true and split_length < 4 then
|
||||
MissionEditorWarnings.Add("Random Mission with zonename " .. input .. " not in right format")
|
||||
return nil
|
||||
elseif split_length < 3 then
|
||||
@@ -53,9 +53,10 @@ local function ParseZoneName(input)
|
||||
if inputType == "cas" then parsedType = "CAS" end
|
||||
if inputType == "bai" then parsedType = "BAI" end
|
||||
if inputType == "sam" then parsedType = "SAM" end
|
||||
if inputType == "deepstrike" then parsedType = "DEEPSTRIKE" end
|
||||
|
||||
if parsedType == "nil" then
|
||||
MissionEditorWarnings.Add("Mission with zonename '" ..
|
||||
MissionEditorWarnings.Add("Mission with zoneName '" ..
|
||||
input .. "' has an unsupported type '" .. (type or "nil"))
|
||||
return nil
|
||||
end
|
||||
@@ -110,7 +111,7 @@ function ZoneMission.new(zoneName, priority, database, logger, parentStage, spaw
|
||||
unitsAlive = {},
|
||||
targetsAlive = {},
|
||||
hasTargets = false,
|
||||
groupNamesPerunit = {},
|
||||
groupNamesPerUnit = {},
|
||||
sceneryTargets = {}
|
||||
}
|
||||
|
||||
@@ -148,17 +149,17 @@ function ZoneMission.new(zoneName, priority, database, logger, parentStage, spaw
|
||||
local spearheadGroup = SpearheadGroup.New(groupName, spawnManager, true)
|
||||
table.insert(self._missionGroups.redGroups, spearheadGroup)
|
||||
|
||||
local isGroupTarget = Util.startswith(string.lower(groupName), "tgt_")
|
||||
local isGroupTarget = Util.startsWith(string.lower(groupName), "tgt_")
|
||||
for _, unit in pairs(spearheadGroup:GetObjects()) do
|
||||
local unitName = unit:getName()
|
||||
local isUnitTarget = Util.startswith(string.lower(unitName), "tgt_")
|
||||
local isUnitTarget = Util.startsWith(string.lower(unitName), "tgt_")
|
||||
|
||||
if self._missionGroups.unitsAlive[groupName] == nil then
|
||||
self._missionGroups.unitsAlive[groupName] = {}
|
||||
end
|
||||
|
||||
self._missionGroups.unitsAlive[groupName][unitName] = true
|
||||
self._missionGroups.groupNamesPerunit[unitName] = groupName
|
||||
self._missionGroups.groupNamesPerUnit[unitName] = groupName
|
||||
|
||||
if isGroupTarget == true or isUnitTarget == true then
|
||||
self._missionGroups.hasTargets = true
|
||||
@@ -178,7 +179,6 @@ function ZoneMission.new(zoneName, priority, database, logger, parentStage, spaw
|
||||
|
||||
if self.missionType == "CAS" then
|
||||
self._battleManager = BattleManager.New(self._missionGroups.redGroups, self._missionGroups.blueGroups, self.zoneName, self._logger.LogLevel)
|
||||
|
||||
end
|
||||
|
||||
self._logger:debug("Mission " .. self.name .. " group count: " .. Util.tableLength(missionData.RedGroups))
|
||||
@@ -353,6 +353,19 @@ end
|
||||
function ZoneMission:SpawnInactive()
|
||||
self._logger:info("PreActivating " .. self.name)
|
||||
|
||||
if self.missionType == "DEEPSTRIKE" then
|
||||
local missionData = self._database:getMissionDataForZone(self.zoneName)
|
||||
---@type MissionPriority
|
||||
local priority = "secondary"
|
||||
if missionData and missionData.primaryOverwrite ~= nil then
|
||||
if missionData.primaryOverwrite == true then
|
||||
priority = "primary"
|
||||
end
|
||||
end
|
||||
self._priority = priority
|
||||
self._missionCommandsHelper:AddMissionToCommands(self)
|
||||
end
|
||||
|
||||
for _, group in pairs(self._missionGroups.redGroups) do
|
||||
group:Spawn()
|
||||
end
|
||||
@@ -389,6 +402,17 @@ function ZoneMission:SpawnActive()
|
||||
self._battleManager:Start()
|
||||
end
|
||||
|
||||
self._missionCommandsHelper:RemoveMissionToCommands(self) -- Remove first
|
||||
if self.missionType == "DEEPSTRIKE" then
|
||||
local missionData = self._database:getMissionDataForZone(self.zoneName)
|
||||
local priority = "primary"
|
||||
if missionData and missionData.primaryOverwrite ~= nil then
|
||||
if missionData.primaryOverwrite == false then
|
||||
priority = "secondary"
|
||||
end
|
||||
end
|
||||
self._priority = priority
|
||||
end
|
||||
self._missionCommandsHelper:AddMissionToCommands(self)
|
||||
|
||||
self:StartCheckingContinuous()
|
||||
@@ -480,7 +504,7 @@ function ZoneMission:OnUnitLost(object)
|
||||
local unitName = object:getName()
|
||||
self._logger:debug("UnitName:" .. unitName)
|
||||
|
||||
local groupName = self._missionGroups.groupNamesPerunit[unitName]
|
||||
local groupName = self._missionGroups.groupNamesPerUnit[unitName]
|
||||
self._missionGroups.unitsAlive[groupName][unitName] = false
|
||||
|
||||
if self._missionGroups.targetsAlive[groupName] and self._missionGroups.targetsAlive[groupName][unitName] then
|
||||
|
||||
@@ -9,7 +9,7 @@ local GlobalConfig = require("classes.configuration.GlobalConfig")
|
||||
---@field zoneName string
|
||||
---@field missionType MissionType
|
||||
---@field missionTypeDisplay string
|
||||
---@field priority MissionPriority
|
||||
---@field protected _priority MissionPriority
|
||||
---@field location Vec2?
|
||||
---@field code string
|
||||
---@field protected _state MissionState
|
||||
@@ -40,7 +40,7 @@ function Mission.newSuper(self, zoneName, missionName, missionType, missionBrief
|
||||
self.zoneName = zoneName
|
||||
self.name = missionName
|
||||
self.missionType = missionType
|
||||
self.priority = priority
|
||||
self._priority = priority
|
||||
self._state = "NEW"
|
||||
self._logger = logger
|
||||
self._database = database
|
||||
@@ -64,6 +64,11 @@ end
|
||||
|
||||
--region PUBLIC
|
||||
|
||||
---@return MissionPriority
|
||||
function Mission:GetPriority()
|
||||
return self._priority
|
||||
end
|
||||
|
||||
function Mission:SpawnPersistedState() end
|
||||
function Mission:SpawnActive() end
|
||||
|
||||
@@ -114,7 +119,7 @@ end
|
||||
function Mission:NotifyMissionComplete()
|
||||
self._missionCommandsHelper:RemoveMissionToCommands(self)
|
||||
self._logger:info("Mission Completed: " .. self.zoneName)
|
||||
trigger.action.outText("Mission " .. self.name .. " [" .. self.code .. "] was completed succesfully", 20)
|
||||
trigger.action.outText("Mission " .. self.name .. " [" .. self.code .. "] was completed successfully", 20)
|
||||
|
||||
for _, listener in pairs(self._completeListeners) do
|
||||
pcall(function()
|
||||
@@ -155,13 +160,14 @@ function Mission:ToStateString() return "status: in progress" end
|
||||
--- @alias MissionType
|
||||
--- | "nil"
|
||||
--- | "STRIKE"
|
||||
--- | "DEEPSTRIKE"
|
||||
--- | "CAS"
|
||||
--- | "BAI"
|
||||
--- | "DEAD"
|
||||
--- | "SAM"
|
||||
--- | "OCA"
|
||||
--- | "LOGISTICS"
|
||||
|
||||
---
|
||||
--- @alias MissionState
|
||||
--- | "NEW"
|
||||
--- | "WAITING"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---@class Util
|
||||
local UTIL = {}
|
||||
do -- INIT UTIL
|
||||
---splits a string in sub parts by seperator
|
||||
---splits a string in sub parts by separator
|
||||
---@param input string
|
||||
---@param seperator string
|
||||
---@param separator string
|
||||
---@return Array<string> result list of strings
|
||||
function UTIL.split_string(input, seperator)
|
||||
if seperator == nil then
|
||||
seperator = " "
|
||||
function UTIL.split_string(input, separator)
|
||||
if separator == nil then
|
||||
separator = " "
|
||||
end
|
||||
|
||||
local result = {}
|
||||
@@ -15,7 +15,7 @@ do -- INIT UTIL
|
||||
return result
|
||||
end
|
||||
|
||||
for str in string.gmatch(input, "[^" .. seperator .. "]+") do
|
||||
for str in string.gmatch(input, "[^" .. separator .. "]+") do
|
||||
table.insert(result, str)
|
||||
end
|
||||
return result
|
||||
@@ -134,7 +134,7 @@ do -- INIT UTIL
|
||||
---@param findable string
|
||||
---@param ignoreCase boolean?
|
||||
---@return boolean
|
||||
UTIL.startswith = function(str, findable, ignoreCase)
|
||||
UTIL.startsWith = function(str, findable, ignoreCase)
|
||||
if ignoreCase == true then
|
||||
return string.lower(str):find('^' .. string.lower(findable)) ~= nil
|
||||
end
|
||||
@@ -164,7 +164,7 @@ do -- INIT UTIL
|
||||
---@return boolean
|
||||
UTIL.startswithAny = function(str, findableTable)
|
||||
for _, value in pairs(findableTable) do
|
||||
if type(value) == "string" and UTIL.startswith(str, value) then return true end
|
||||
if type(value) == "string" and UTIL.startsWith(str, value) then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user