Added completeat functionality to indicate at which percentage of the… (#35)

* Added completeat functionality to indicate at which percentage of the TGT_ dead the mission should complete.

* added a pipeline to compile the script
This commit is contained in:
2025-05-10 14:05:11 +02:00
committed by GitHub
parent 6ff378455b
commit 8e107ca7c2
4 changed files with 107 additions and 53 deletions
+24
View File
@@ -0,0 +1,24 @@
name: Compile Artifact
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run SpearheadCompile
run: |
mkdir -p ./output
python3 SpearheadCompile.py . ./output/spearhead.lua
- name: Upload spearhead.lua artifact
uses: actions/upload-artifact@v4
with:
name: spearhead-lua
path: ./output/spearhead.lua
+30 -1
View File
@@ -29,6 +29,7 @@
---@class MissionAnnotations ---@class MissionAnnotations
---@field description string? ---@field description string?
---@field dependsOn Array<string> ---@field dependsOn Array<string>
---@field completeAt number?
---@class StageZoneData ---@class StageZoneData
---@field StageZoneName string ---@field StageZoneName string
@@ -169,7 +170,26 @@ function Database.New(Logger)
for i, layer in pairs(env.mission.drawings.layers) do for i, layer in pairs(env.mission.drawings.layers) do
if string.lower(layer.name) == "author" then if string.lower(layer.name) == "author" then
for key, layer_object in pairs(layer.objects) do for key, layer_object in pairs(layer.objects) do
if Spearhead.Util.startswith(string.lower(layer_object.name), "dependson", true) == true then if Spearhead.Util.startswith(string.lower(layer_object.name), "completeat", true) == true then
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
local missionAnnotation = self._tables.MissionAnnotations[zonename]
local number = tonumber(layer_object.text)
if number and number > 1 then
number = number / 100
end
missionAnnotation.completeAt = number
end
end
elseif Spearhead.Util.startswith(string.lower(layer_object.name), "dependson", true) == true then
for _, zonename in pairs(self._tables.MissionZones) do for _, zonename in pairs(self._tables.MissionZones) do
if Spearhead.DcsUtil.isPositionInZone(layer_object.mapX, layer_object.mapY, zonename) == true then if Spearhead.DcsUtil.isPositionInZone(layer_object.mapX, layer_object.mapY, zonename) == true then
@@ -621,6 +641,15 @@ function Database:getMissionDependencies(missionZoneName)
return self._tables.MissionAnnotations[missionZoneName].dependsOn return self._tables.MissionAnnotations[missionZoneName].dependsOn
end 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 ---comment
---@param missionZoneName any ---@param missionZoneName any
---@return Vec2? ---@return Vec2?
@@ -93,7 +93,12 @@ function SpearheadGroup:Destroy()
Spearhead.DcsUtil.DestroyGroup(self.groupName) Spearhead.DcsUtil.DestroyGroup(self.groupName)
end end
---comment ---@return boolean
function SpearheadGroup:IsStatic()
return self._isStatic
end
---@return integer ---@return integer
function SpearheadGroup:GetCoalition() function SpearheadGroup:GetCoalition()
if self._isStatic == true then if self._isStatic == true then
+44 -48
View File
@@ -1,10 +1,9 @@
--- ZoneMission is missions that are defined by zones in the ME --- ZoneMission is missions that are defined by zones in the ME
---@class ZoneMission : Mission, OnUnitLostListener ---@class ZoneMission : Mission, OnUnitLostListener
---@field private _state MissionState ---@field private _state MissionState
---@field private _missionGroups MissionGroups ---@field private _missionGroups MissionGroups
---@field private _dependencies table<string, boolean> ---@field private _dependencies table<string, boolean>
---@field private _completeAtIndex number
---@field private _parentStage Stage ---@field private _parentStage Stage
local ZoneMission = {} local ZoneMission = {}
@@ -43,7 +42,8 @@ local function ParseZoneName(input)
if inputType == "sam" then parsedType = "SAM" end if inputType == "sam" then parsedType = "SAM" end
if parsedType == "nil" then if parsedType == "nil" then
Spearhead.AddMissionEditorWarning("Mission with zonename '" .. input .. "' has an unsupported type '" .. (type or "nil" )) Spearhead.AddMissionEditorWarning("Mission with zonename '" ..
input .. "' has an unsupported type '" .. (type or "nil"))
return nil return nil
end end
local name = split_name[3] local name = split_name[3]
@@ -77,7 +77,8 @@ function ZoneMission.new(zoneName, priority, database, logger, parentStage)
local missionBriefing = database:getMissionBriefingForMissionZone(zoneName) or "no briefing provided" local missionBriefing = database:getMissionBriefingForMissionZone(zoneName) or "no briefing provided"
local success, error = Mission.newSuper(self, zoneName, parsed.missionName, parsed.type, missionBriefing, priority, database, logger) local success, error = Mission.newSuper(self, zoneName, parsed.missionName, parsed.type, missionBriefing, priority,
database, logger)
if not success then if not success then
logger:error("Failed to create ZoneMission " .. zoneName .. " => " .. error) logger:error("Failed to create ZoneMission " .. zoneName .. " => " .. error)
return nil return nil
@@ -105,6 +106,14 @@ function ZoneMission.new(zoneName, priority, database, logger, parentStage)
self._dependencies[dependency] = false self._dependencies[dependency] = false
end end
local completeAtIndex = database:getMissionCompleteAt(zoneName)
if completeAtIndex == nil and self.missionType == "BAI" then
self._completeAtIndex = 0.8
elseif completeAtIndex == nil then
self._completeAtIndex = 1
else
self._completeAtIndex = completeAtIndex
end
local SpearheadGroup = Spearhead.classes.stageClasses.Groups.SpearheadGroup local SpearheadGroup = Spearhead.classes.stageClasses.Groups.SpearheadGroup
local groupNames = database:getGroupsForMissionZone(zoneName) local groupNames = database:getGroupsForMissionZone(zoneName)
@@ -147,8 +156,6 @@ end
---@private ---@private
function ZoneMission:StartCheckingDependencies() function ZoneMission:StartCheckingDependencies()
self._state = "WAITING" self._state = "WAITING"
---comment ---comment
@@ -156,7 +163,6 @@ function ZoneMission:StartCheckingDependencies()
---@param time any ---@param time any
---@return unknown ---@return unknown
local function CheckDependencies(mission, time) local function CheckDependencies(mission, time)
if mission:AllDependenciesMet() == true then if mission:AllDependenciesMet() == true then
mission:SpawnActive() mission:SpawnActive()
return nil return nil
@@ -226,62 +232,57 @@ function ZoneMission:UpdateState(checkHealth, messageIfDone)
end end
end end
for groupName, unitNameDict in pairs(self._missionGroups.unitsAlive) do if self._missionGroups.hasTargets == true then
for unitName, isAlive in pairs(unitNameDict) do for groupName, unitNameDict in pairs(self._missionGroups.targetsAlive) do
if isAlive == true then for unitName, isAlive in pairs(unitNameDict) do
self._missionGroups.unitsAlive[groupName][unitName] = unitAliveState(unitName) if isAlive == true then
self._missionGroups.targetsAlive[groupName][unitName] = unitAliveState(unitName)
end
end end
end end
end else
for groupName, unitNameDict in pairs(self._missionGroups.unitsAlive) do
for groupName, unitNameDict in pairs(self._missionGroups.targetsAlive) do for unitName, isAlive in pairs(unitNameDict) do
for unitName, isAlive in pairs(unitNameDict) do if isAlive == true then
if isAlive == true then self._missionGroups.unitsAlive[groupName][unitName] = unitAliveState(unitName)
self._missionGroups.targetsAlive[groupName][unitName] = unitAliveState(unitName) end
end end
end end
end end
end end
if self._missionGroups.hasTargets == true then if self._missionGroups.hasTargets == true then
local anyTargetAlive = function() local total = 0
for _, units in pairs(self._missionGroups.targetsAlive) do local alive = 0
for _, isAlive in pairs(units) do
if isAlive == true then for _, units in pairs(self._missionGroups.targetsAlive) do
return true for _, isAlive in pairs(units) do
end total = total + 1
if isAlive == true then
alive = alive + 1
end end
end end
return false
end end
if anyTargetAlive() ~= true then local deadRatio = (total-alive) / total
if deadRatio >= self._completeAtIndex then
self._state = "COMPLETED" self._state = "COMPLETED"
end end
else else
local function CountAliveGroups() local total = 0
local aliveGroups = 0 local alive = 0
for _, group in pairs(self._missionGroups.unitsAlive) do for _, units in pairs(self._missionGroups.unitsAlive) do
local groupTotal = 0 for _, isAlive in pairs(units) do
local groupDeath = 0 total = total + 1
for _, isAlive in pairs(group) do if isAlive == true then
if isAlive ~= true then alive = alive + 1
groupDeath = groupDeath + 1
end
groupTotal = groupTotal + 1
end
local aliveRatio = (groupTotal - groupDeath) / groupTotal
if aliveRatio >= MINIMAL_UNITS_ALIVE_RATIO then
aliveGroups = aliveGroups + 1
end end
end end
return aliveGroups
end end
if CountAliveGroups() == 0 then local deadRatio = (total-alive) / total
if deadRatio >= self._completeAtIndex then
self._state = "COMPLETED" self._state = "COMPLETED"
end end
end end
@@ -303,7 +304,6 @@ function ZoneMission:SpawnInactive()
end end
function ZoneMission:SpawnActive() function ZoneMission:SpawnActive()
if self:AllDependenciesMet() == false then if self:AllDependenciesMet() == false then
self:SpawnInactive() self:SpawnInactive()
self:StartCheckingDependencies() self:StartCheckingDependencies()
@@ -327,10 +327,8 @@ function ZoneMission:SpawnActive()
self:StartCheckingContinuous() self:StartCheckingContinuous()
end end
---@private ---@private
function ZoneMission:StartCheckingContinuous() function ZoneMission:StartCheckingContinuous()
---comment ---comment
---@param mission Mission ---@param mission Mission
---@param time any ---@param time any
@@ -418,8 +416,6 @@ function ZoneMission:OnUnitLost(object)
self:UpdateState(false, true) self:UpdateState(false, true)
end end
if not Spearhead.classes then Spearhead.classes = {} end if not Spearhead.classes then Spearhead.classes = {} end
if not Spearhead.classes.stageClasses then Spearhead.classes.stageClasses = {} end if not Spearhead.classes.stageClasses then Spearhead.classes.stageClasses = {} end
if not Spearhead.classes.stageClasses.missions then Spearhead.classes.stageClasses.missions = {} end if not Spearhead.classes.stageClasses.missions then Spearhead.classes.stageClasses.missions = {} end