diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 11b0142..760529d 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -1,10 +1,11 @@
#start
-name: update newsletters
+name: Release
on:
push:
branches:
- main
+ - develop
jobs:
buildandpush:
@@ -61,8 +62,16 @@ jobs:
- run: npm i markdown-to-html-cli -g
- run: markdown-to-html --title 'Spearhead' --dark-mode auto --keywords "dcs,spearhead,tdcs,mission,campaign,tactical dcs,tactical" --no-dark-mode --markdown-style-theme dark --source ./spearhead/_docs/$sourcefileA.md --output ./$repo/Spearhead/$sourcefileA.html
- run: markdown-to-html --title 'Spearhead' --dark-mode auto --keywords "dcs,spearhead,tdcs,mission,campaign,tactical dcs,tactical" --no-dark-mode --markdown-style-theme dark --source ./spearhead/_docs/$sourcefileB.md --output ./$repo/Spearhead/$sourcefileB.html
+
- run: python3 ./spearhead/SpearheadCompile.py "./spearhead" "./$repo/Spearhead/spearhead.lua"
- - run: cp "./spearhead/config.lua" "./$repo/Spearhead/spearheadConfig.lua"
+ if: github.ref == 'refs/heads/master'
+
+ - run: mkdir -p ./$repo/Spearhead/beta
+ if: github.ref == 'refs/heads/develop'
+
+ - run: python3 ./spearhead/SpearheadCompile.py "./spearhead" "./$repo/Spearhead/beta/spearhead.lua"
+ if: github.ref == 'refs/heads/develop'
+
- run: cp -a ./spearhead/_docs/img/. ./$repo/Spearhead/img/
- name: ls
run: ls
diff --git a/_docs/GetStarted.md b/_docs/GetStarted.md
index 795632a..cf7b631 100644
--- a/_docs/GetStarted.md
+++ b/_docs/GetStarted.md
@@ -14,6 +14,8 @@ In the example we'll show how you can create a simple island hopping mission
Firstly include the script.
Download Script
+
Or if you want to use the latest beta version:
+Download Beta Script
Then run the script in the mission.
Please do exactly as it's done below.
diff --git a/_miz/SPEARHEADDEV.miz b/_miz/SPEARHEADDEV.miz
index b12706e..aad247d 100644
Binary files a/_miz/SPEARHEADDEV.miz and b/_miz/SPEARHEADDEV.miz differ
diff --git a/_miz/SPEARHEADEXAMPLE.miz b/_miz/SPEARHEADEXAMPLE.miz
index d69c3eb..2b3ba55 100644
Binary files a/_miz/SPEARHEADEXAMPLE.miz and b/_miz/SPEARHEADEXAMPLE.miz differ
diff --git a/classes/configuration/CapConfig.lua b/classes/configuration/CapConfig.lua
index 22488b7..bb277c6 100644
--- a/classes/configuration/CapConfig.lua
+++ b/classes/configuration/CapConfig.lua
@@ -8,7 +8,8 @@ function CapConfig:new()
if SpearheadConfig == nil then SpearheadConfig = {} end
if SpearheadConfig.CapConfig == nil then SpearheadConfig.CapConfig = {} end
- local enabled = SpearheadConfig.CapConfig.enabled or true
+ local enabled = SpearheadConfig.CapConfig.enabled
+ if enabled == nil then enabled = true end
---@return boolean
o.isEnabled = function(self) return enabled == true end
diff --git a/classes/configuration/StageConfig.lua b/classes/configuration/StageConfig.lua
index e86b0fc..07afd90 100644
--- a/classes/configuration/StageConfig.lua
+++ b/classes/configuration/StageConfig.lua
@@ -7,22 +7,35 @@ function StageConfig:new()
if SpearheadConfig == nil then SpearheadConfig = {} end
if SpearheadConfig.StageConfig == nil then SpearheadConfig.StageConfig = {} end
- local enabled = SpearheadConfig.StageConfig.enabled or true
+ local enabled = SpearheadConfig.StageConfig.enabled
+ if enabled == nil then enabled = true end
---@return boolean
o.isEnabled = function(self) return enabled == true end
- local drawStages = SpearheadConfig.StageConfig.drawStages or true
+ local drawStages = SpearheadConfig.StageConfig.drawStages
+ if drawStages == nil then drawStages = true end
---@return boolean
o.isDrawStagesEnabled = function(self) return drawStages == true end
local autoStages = SpearheadConfig.StageConfig.autoStages or true
+ if autoStages == nil then autoStages = true end
---@return boolean
o.isAutoStages = function(self) return autoStages end
local maxMissionsPerStage = SpearheadConfig.StageConfig.maxMissionStage
o.getMaxMissionsPerStage = function(self) return maxMissionsPerStage end
- o.logLevel = Spearhead.LoggerTemplate.LogLevelOptions.DEBUG
+ o.logLevel = Spearhead.LoggerTemplate.LogLevelOptions.INFO
+
+ o.toString = function()
+ return Spearhead.Util.toString({
+ maxMissionsPerStage = maxMissionsPerStage,
+ enabled = enabled,
+ drawStages = drawStages,
+ autoStages = autoStages
+ })
+ end
+
return o;
end
diff --git a/classes/fleetClasses/GlobalFleetManager.lua b/classes/fleetClasses/GlobalFleetManager.lua
index ec546a6..0a718f1 100644
--- a/classes/fleetClasses/GlobalFleetManager.lua
+++ b/classes/fleetClasses/GlobalFleetManager.lua
@@ -6,7 +6,7 @@ local fleetGroups = {}
GlobalFleetManager.start = function(database)
- local logger = Spearhead.LoggerTemplate:new("CARRIERFLEET", Spearhead.LoggerTemplate.LogLevelOptions.DEBUG)
+ local logger = Spearhead.LoggerTemplate:new("CARRIERFLEET", Spearhead.LoggerTemplate.LogLevelOptions.INFO)
local all_groups = Spearhead.DcsUtil.getAllGroupNames()
for _, groupName in pairs(all_groups) do
@@ -18,4 +18,5 @@ GlobalFleetManager.start = function(database)
end
end
+if not Spearhead.internal then Spearhead.internal = {} end
Spearhead.internal.GlobalFleetManager = GlobalFleetManager
\ No newline at end of file
diff --git a/classes/spearhead_base.lua b/classes/spearhead_base.lua
index 3d36cdb..afdd20d 100644
--- a/classes/spearhead_base.lua
+++ b/classes/spearhead_base.lua
@@ -445,7 +445,11 @@ do -- INIT DCS_UTIL
---checks if the groupname is a static group
---@param groupName any
function DCS_UTIL.IsGroupStatic(groupName)
- return DCS_UTIL.__miz_groups[groupName].category == 5;
+ if DCS_UTIL.__miz_groups[groupName] then
+ return DCS_UTIL.__miz_groups[groupName].category == 5;
+ end
+
+ return StaticObject.getByName(groupName) ~= nil
end
---comment
@@ -739,8 +743,8 @@ do -- INIT DCS_UTIL
---@return table units
function DCS_UTIL.getAllPlayerUnits()
local units = {}
- for key, value in pairs({ 1, 2, 3 }) do
- local players = coalition.getPlayers(value)
+ for i = 0,2 do
+ local players = coalition.getPlayers(i)
for key, unit in pairs(players) do
units[#units + 1] = unit
end
@@ -782,29 +786,6 @@ do -- INIT DCS_UTIL
return result
end
- ---Gets all groups that have players
- ---@return table groups
- function DCS_UTIL.getAllPlayerGroups()
- local groupNames = {}
- local result = {}
- for key, value in pairs({ 1, 2, 3 }) do
- local players = coalition.getPlayers(value)
- for key, unit in pairs(players) do
- local group = unit:getGroup()
- if group ~= nil then
- local name = group:getName()
- if name ~= nil then
- if groupNames[name] ~= nil then
- groupNames[name] = 1
- table.insert(result, group)
- end
- end
- end
- end
- end
- return result
- end
-
--- spawns the units as specified in the mission file itself
--- location and route can be nil and will then use default route
---@param groupName string
diff --git a/classes/spearhead_db.lua b/classes/spearhead_db.lua
index 0a59114..a2420b1 100644
--- a/classes/spearhead_db.lua
+++ b/classes/spearhead_db.lua
@@ -358,6 +358,7 @@ do -- DB
functionString = functionString .. "{0,1,0,1}, {0,1,0,1}, 1)"
env.info(functionString)
+---@diagnostic disable-next-line: deprecated
local f, err = loadstring(functionString)
if f then
f()
diff --git a/classes/spearhead_events.lua b/classes/spearhead_events.lua
index bebb601..3adda59 100644
--- a/classes/spearhead_events.lua
+++ b/classes/spearhead_events.lua
@@ -1,18 +1,24 @@
local SpearheadEvents = {}
do
- local SpearheadLogger = Spearhead.LoggerTemplate:new("Spearhead Events",
- Spearhead.LoggerTemplate.LogLevelOptions.INFO)
-
do -- STAGE NUMBER CHANGED
local OnStageNumberChangedListeners = {}
local OnStageNumberChangedHandlers = {}
+
+ local warn = function(text)
+ env.warn("[Spearhead][Events] " .. (text or "nil"))
+ end
+
+ local error = function(text)
+ env.error("[Spearhead][Events] " .. (text or "nil"))
+ end
+
---Add a stage zone number changed listener
---@param listener table object with function OnStageNumberChanged(self, number)
SpearheadEvents.AddStageNumberChangedListener = function(listener)
if type(listener) ~= "table" then
- SpearheadLogger:warn("Event listener not of type table, did you mean to use handler?")
+ warn("Event listener not of type table, did you mean to use handler?")
return
end
table.insert(OnStageNumberChangedListeners, listener)
@@ -22,7 +28,7 @@ do
---@param handler function function(number)
SpearheadEvents.AddStageNumberChangedHandler = function(handler)
if type(handler) ~= "function" then
- SpearheadLogger:warn("Event handler not of type function, did you mean to use listener?")
+ warn("Event handler not of type function, did you mean to use listener?")
return
end
table.insert(OnStageNumberChangedHandlers, handler)
@@ -35,31 +41,31 @@ do
callable:OnStageNumberChanged(newStageNumber)
end)
if err then
- SpearheadLogger:error(err)
+ error(err)
end
end
for _, callable in pairs(OnStageNumberChangedHandlers) do
local succ, err = pcall(callable, newStageNumber)
if err then
- SpearheadLogger:error(err)
+ error(err)
end
end
end
end
+
+
local onLandEventListeners = {}
---Add an event listener to a specific unit
---@param unitName string to call when the unit lands
---@param landListener table table with function OnUnitLanded(self, initiatorUnit, airbase)
SpearheadEvents.addOnUnitLandEventListener = function(unitName, landListener)
if type(landListener) ~= "table" then
- SpearheadLogger:warn("Event handler not of type table/object")
+ warn("Event handler not of type table/object")
return
end
- SpearheadLogger:debug("Added Land event handler for unit: " .. unitName)
-
if onLandEventListeners[unitName] == nil then
onLandEventListeners[unitName] = {}
end
@@ -73,7 +79,7 @@ do
---@param unitLostListener table Object with function: OnUnitLost(initiatorUnit)
SpearheadEvents.addOnUnitLostEventListener = function(unitName, unitLostListener)
if type(unitLostListener) ~= "table" then
- SpearheadLogger:warn("Unit lost Event listener not of type table/object")
+ warn("Unit lost Event listener not of type table/object")
return
end
@@ -92,7 +98,7 @@ do
---@param handlingObject table object with OnGroupRTB(self, groupName)
SpearheadEvents.addOnGroupRTBListener = function(groupName, handlingObject)
if type(handlingObject) ~= "table" then
- SpearheadLogger:warn("Event handler not of type table/object")
+ warn("Event handler not of type table/object")
return
end
@@ -106,7 +112,6 @@ do
---Publish the Group to RTB
---@param groupName string
SpearheadEvents.PublishRTB = function(groupName)
- SpearheadLogger:debug("Publishing RTB event for group " .. groupName)
if groupName ~= nil then
if OnGroupRTBListeners[groupName] then
for _, callable in pairs(OnGroupRTBListeners[groupName]) do
@@ -114,7 +119,7 @@ do
callable:OnGroupRTB(groupName)
end)
if err then
- SpearheadLogger:error(err)
+ error(err)
end
end
end
@@ -128,7 +133,7 @@ do
---@param handlingObject table object with OnGroupRTBInTen(self, groupName)
SpearheadEvents.addOnGroupRTBInTenListener = function(groupName, handlingObject)
if type(handlingObject) ~= "table" then
- SpearheadLogger:warn("Event handler not of type table/object")
+ warn("Event handler not of type table/object")
return
end
@@ -142,7 +147,6 @@ do
---Publish the Group is RTB
---@param groupName string
SpearheadEvents.PublishRTBInTen = function(groupName)
- SpearheadLogger:debug("Publishing RTB in TEN event for group " .. groupName)
if groupName ~= nil then
if OnGroupRTBInTenListeners[groupName] then
for _, callable in pairs(OnGroupRTBInTenListeners[groupName]) do
@@ -150,7 +154,7 @@ do
callable:OnGroupRTBInTen(groupName)
end)
if err then
- SpearheadLogger:error(err)
+ error(err)
end
end
end
@@ -165,7 +169,7 @@ do
---@param groupName string the groupname to expect
SpearheadEvents.addOnGroupOnStationListener = function(groupName, handlingObject)
if type(handlingObject) ~= "table" then
- SpearheadLogger:warn("Event handler not of type table/object")
+ warn("Event handler not of type table/object")
return
end
@@ -179,7 +183,6 @@ do
---Publish the Group to RTB
---@param groupName string
SpearheadEvents.PublishOnStation = function(groupName)
- SpearheadLogger:debug("Publishing onStation event for group " .. groupName)
if groupName ~= nil then
if OnGroupOnStationListeners[groupName] then
for _, callable in pairs(OnGroupOnStationListeners[groupName]) do
@@ -187,7 +190,7 @@ do
callable:OnGroupOnStation(groupName)
end)
if err then
- SpearheadLogger:error(err)
+ error(err)
end
end
end
@@ -202,7 +205,7 @@ do
---@param listener table object with OnStatusRequestReceived(self, groupId)
SpearheadEvents.AddOnStatusRequestReceivedListener = function(listener)
if type(listener) ~= "table" then
- SpearheadLogger:warn("Unit lost Event listener not of type table/object")
+ warn("Unit lost Event listener not of type table/object")
return
end
@@ -231,10 +234,10 @@ do
do -- PLAYER ENTER UNIT
local playerEnterUnitListeners = {}
---comment
- ---@param listener table object with OnPlayerEnterUnit(self, unit)
+ ---@param listener table object with OnPlayerEntersUnit(self, unit)
SpearheadEvents.AddOnPlayerEnterUnitListener = function(listener)
if type(listener) ~= "table" then
- SpearheadLogger:warn("Unit lost Event listener not of type table/object")
+ warn("Unit lost Event listener not of type table/object")
return
end
@@ -246,10 +249,10 @@ do
if playerEnterUnitListeners then
for _, callable in pairs(playerEnterUnitListeners) do
local succ, err = pcall(function()
- callable:OnPlayerEnterUnit(unit)
+ callable:OnPlayerEntersUnit(unit)
end)
if err then
- SpearheadLogger:error(err)
+ error(err)
end
end
end
@@ -270,7 +273,7 @@ do
callable:OnUnitLanded(unit, airbase)
end)
if err then
- SpearheadLogger:error(err)
+ error(err)
end
end
end
@@ -289,16 +292,51 @@ do
end)
if err then
- SpearheadLogger:error(err)
+ error(err)
end
end
end
end
- if event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT then
- env.info("blaat player entering unit")
- local groupId = event.initiator:getGroup():getID()
- SpearheadEvents.AddCommandsToGroup(groupId)
+ local AI_GROUPS = {}
+
+ local function CheckAndTriggerSpawnAsync(unit, time)
+ local function isPlayer(unit)
+ if unit == nil then return false, "unit is nil" end
+ if unit:isExist() ~= true then return false, "unit does not exist" end
+ local group = unit:getGroup()
+ if group ~= nil then
+ if Spearhead.DcsUtil.IsGroupStatic(group:getName()) == true then
+ return false
+ end
+
+ if AI_GROUPS[group:getName()] == true then
+ return false
+ end
+
+ local players = Spearhead.DcsUtil.getAllPlayerUnits()
+ local unitName = unit:getName()
+ for i, unit in pairs(players) do
+ if unit:getName() == unitName then
+ return true
+ end
+ end
+ AI_GROUPS[group:getName()] = true
+ end
+ return false, "unit is nil or does not exist"
+ end
+
+ if isPlayer(unit) == true then
+ local groupId = unit:getGroup():getID()
+ SpearheadEvents.AddCommandsToGroup(groupId)
+ SpearheadEvents.TriggerPlayerEntersUnit(unit)
+ end
+
+ return nil
+ end
+
+ if event.id == world.event.S_EVENT_BIRTH then
+ timer.scheduleFunction(CheckAndTriggerSpawnAsync, event.initiator, timer.getTime() + 3)
end
end
diff --git a/classes/stageClasses/GlobalStageManager.lua b/classes/stageClasses/GlobalStageManager.lua
index 767c8ff..30b41bd 100644
--- a/classes/stageClasses/GlobalStageManager.lua
+++ b/classes/stageClasses/GlobalStageManager.lua
@@ -6,12 +6,13 @@ local StagesByIndex = {}
GlobalStageManager = {}
function GlobalStageManager:NewAndStart(database, stageConfig)
-
+ local logger = Spearhead.LoggerTemplate:new("StageManager", stageConfig.logLevel)
local o = {}
setmetatable(o, { __index = self })
- o.onStageCompleted = function(stage)
+ o.logger = logger
+ o.onStageCompleted = function(self, stage)
local stageNumber = tostring(stage.stageNumber)
local anyActive = false
for _, stage in pairs(StagesByIndex[stageNumber] or {}) do
@@ -24,8 +25,6 @@ function GlobalStageManager:NewAndStart(database, stageConfig)
end
- local logger = Spearhead.LoggerTemplate:new("StageManager", stageConfig.logLevel)
-
for _, stageName in pairs(database:getStagezoneNames()) do
local stagelogger = Spearhead.LoggerTemplate:new(stageName, stageConfig.logLevel)
diff --git a/classes/stageClasses/Mission.lua b/classes/stageClasses/Mission.lua
index 9409d5b..aadc136 100644
--- a/classes/stageClasses/Mission.lua
+++ b/classes/stageClasses/Mission.lua
@@ -183,17 +183,35 @@ do -- INIT Mission Class
timer.scheduleFunction(CheckAndUpdate, self, timer.getTime() + 300)
end
- local CleanupDelayedAsync = function (self, time)
- self:Cleanup()
- return nil
- end
-
---comment
---@param self table
---@param checkUnitHealth boolean?
o.CheckAndUpdateSelf = function(self, checkUnitHealth)
if not checkUnitHealth then checkUnitHealth = false end
+ if checkUnitHealth == true then
+ local function unitAliveState(unitName)
+ local unit = Unit.getByName(unitName)
+ return unit ~= nil and unit:isExist() == true and unit:getLife() > 0.1
+ end
+
+ for groupName, unitNameDict in pairs(self.groupUnitAliveDict) do
+ for unitName, isAlive in pairs(unitNameDict) do
+ if isAlive == true then
+ self.groupUnitAliveDict[groupName][unitName] = unitAliveState(unitName)
+ end
+ end
+ end
+
+ for groupName, unitNameDict in pairs(self.targetAliveStates) do
+ for unitName, isAlive in pairs(unitNameDict) do
+ if isAlive == true then
+ self.targetAliveStates[groupName][unitName] = unitAliveState(unitName)
+ end
+ end
+ end
+ end
+
if self.missionState == Mission.MissionState.COMPLETED then
return
end
diff --git a/classes/stageClasses/Stage.lua b/classes/stageClasses/Stage.lua
index 84b0e17..ae05045 100644
--- a/classes/stageClasses/Stage.lua
+++ b/classes/stageClasses/Stage.lua
@@ -41,7 +41,7 @@ do --init STAGE DIRECTOR
o.db.blueSamGroups = {}
o.db.airbaseIds = {}
o.db.farps = {}
- o.activeStage = 0
+ o.activeStage = -99
o.preActivated = false
o.stageConfig = stageConfig or {}
o.stageDrawingId = stageDrawingId + 1
@@ -146,7 +146,6 @@ do --init STAGE DIRECTOR
end
end
-
o.IsComplete = function(self)
for i, mission in pairs(self.db.missions) do
local state = mission:GetState()
@@ -157,6 +156,19 @@ do --init STAGE DIRECTOR
return true
end
+ local CheckContinuousAsync = function(self, time)
+ self.logger:info("Checking stage completion for stage: " .. self.zoneName)
+ if self.activeStage == self.stageNumber then
+ return nil -- stop looping if this stage is not even active
+ end
+
+ if self:IsComplete() == true then
+ triggerStageCompleteListeners(self)
+ return nil
+ end
+ return time + 60
+ end
+
---Activates all SAMS, Airbase units etc all at once.
---@param self table
o.PreActivate = function(self)
@@ -230,6 +242,8 @@ do --init STAGE DIRECTOR
end
end
timer.scheduleFunction(activateMissionsIfApplicableAsync, self, timer.getTime() + 5)
+
+ timer.scheduleFunction(CheckContinuousAsync, self, timer.getTime() + 60)
end
o.ActivateMissionsIfApplicable = function (self)
@@ -267,6 +281,7 @@ do --init STAGE DIRECTOR
end
end
end
+
end
---Cleans up all missions
@@ -471,6 +486,7 @@ do --init STAGE DIRECTOR
mission:AddMissionCompleteListener(o)
end
+ Spearhead.Events.AddOnPlayerEnterUnitListener(o)
Spearhead.Events.AddOnStatusRequestReceivedListener(o)
Spearhead.Events.AddStageNumberChangedListener(o)
return o
diff --git a/config.lua b/config.lua
index a63cec5..d4dde35 100644
--- a/config.lua
+++ b/config.lua
@@ -40,7 +40,7 @@ SpearheadConfig = {
enabled = true, -- default true
--Will draw the active and the next stage
- drawStages = true, -- default true
+ drawStages = false, -- default true
--AutoStages will continue to the next stage automatically on completion of the missions within the stage.
-- If you want to make it so the next stage triggers only when you want to disable it here and manually implement the actions needed.
diff --git a/main.lua b/main.lua
index c9e671d..0b928dd 100644
--- a/main.lua
+++ b/main.lua
@@ -8,11 +8,15 @@ if id == 0 then
end
local dbLogger = Spearhead.LoggerTemplate:new("database", Spearhead.LoggerTemplate.LogLevelOptions.INFO)
+local standardLogger = Spearhead.LoggerTemplate:new("", Spearhead.LoggerTemplate.LogLevelOptions.INFO)
local databaseManager = Spearhead.DB:new(dbLogger, debug)
local capConfig = Spearhead.internal.configuration.CapConfig:new();
local stageConfig = Spearhead.internal.configuration.StageConfig:new();
+standardLogger:info("Using StageConfig: ".. stageConfig:toString())
+
+
Spearhead.internal.GlobalCapManager.start(databaseManager, capConfig, stageConfig)
Spearhead.internal.GlobalStageManager:NewAndStart(databaseManager, stageConfig)
Spearhead.internal.GlobalFleetManager.start(databaseManager)
@@ -29,9 +33,6 @@ Spearhead.LoadingDone()
-- Get-ChildItem . -Include *.lua -Recurse | foreach {""+(Get-Content $_).Count + " => " + $_.name }; && GCI . -Include *.lua* -Recurse | foreach{(GC $_).Count} | measure-object -sum | % Sum
-- find . -name '*.lua' | xargs wc -l
-
-
-
--- ==================== DEBUG ORDER OR ZONE VEC ===========================
-- local zone = Spearhead.DcsUtil.getZoneByName("MISSIONSTAGE_99")