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:
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user