From de81fdf419d5e993fe40781b87ba6d09bc7a4397 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Tue, 8 Sep 2026 16:40:04 +0200 Subject: [PATCH 01/71] added lua check CI step --- .gitea/workflows/pr.yml | 37 +++++++++++++++++++++++++++++++++++++ .luacheckrc | 22 ++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 .gitea/workflows/pr.yml create mode 100644 .luacheckrc diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml new file mode 100644 index 0000000..d36f71c --- /dev/null +++ b/.gitea/workflows/pr.yml @@ -0,0 +1,37 @@ +name: PR Prerequisites + +on: + pull_request: + branches: + - main + - develop + +jobs: + bundles_without_error: + runs-on: ubuntu-latest + name: Bundles Without Errors + steps: + - uses: actions/checkout@v2 + - name: Set up Lua + uses: leafo/setup-lua@v1 + with: + lua-version: '5.1' + + - name: Compile Spearhead + uses: https://git.dutchie031.com/dutchie031/DcsMissionScriptingTools/github-action@action/v0 + with: + source-root: ./src + output-file: ./output/spearhead.lua + + - name: Verify Compiled Lua Syntax + run: lua -e "assert(loadfile('./output/spearhead.lua'))" + + - name: Set up Luarocks + uses: leafo/gh-actions-luarocks@v4 + + - name: Install luacheck + run: luarocks install luacheck + + - name: Lint Compiled Output + run: luacheck ./output/spearhead.lua + diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..cebce85 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,22 @@ +std = "lua51" + +max_line_length = false + +-- Compiled bundle is a single file; each source file's locals live inside +-- their own `do ... end` block, so cross-file shadowing isn't a real risk. +unused_args = false + +-- Cross-file globals set by Spearhead itself (no `require`/module system in the bundle) +globals = { + "SpearheadConfig", + "GlobalCapCallBacks", + "SpearheadAPI", +} + +-- DCS Mission Scripting Environment API +read_globals = { + "env", "timer", "trigger", "world", "coalition", "country", + "AI", "Group", "Unit", "StaticObject", "SceneryObject", + "Airbase", "Weapon", "land", "atmosphere", "missionCommands", + "net", +} -- 2.54.0 From 2cae676a101f7b964dcca6ccae1bcf63de7fa852 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Tue, 8 Sep 2026 16:41:35 +0200 Subject: [PATCH 02/71] changed checkout version --- .gitea/workflows/pr.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index d36f71c..7d54285 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -11,7 +11,8 @@ jobs: runs-on: ubuntu-latest name: Bundles Without Errors steps: - - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v4 - name: Set up Lua uses: leafo/setup-lua@v1 with: -- 2.54.0 From 233310209b66f7f73faf0de2c2d15f47fb1ff63a Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Tue, 8 Sep 2026 16:44:52 +0200 Subject: [PATCH 03/71] changed checkout version --- .gitea/workflows/pr.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 7d54285..d5c58d2 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -13,11 +13,12 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Set up Lua - uses: leafo/setup-lua@v1 + uses: leafo/gh-actions-lua@v13 with: - lua-version: '5.1' - + luaVersion: "5.1" + - name: Compile Spearhead uses: https://git.dutchie031.com/dutchie031/DcsMissionScriptingTools/github-action@action/v0 with: -- 2.54.0 From 341590e98197008c903c6f2521a41f7428857ccb Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Tue, 8 Sep 2026 16:54:00 +0200 Subject: [PATCH 04/71] fixed minor bug --- src/classes/stageClasses/Stages/ExtraStage.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/classes/stageClasses/Stages/ExtraStage.lua b/src/classes/stageClasses/Stages/ExtraStage.lua index 38b057c..48b56c8 100644 --- a/src/classes/stageClasses/Stages/ExtraStage.lua +++ b/src/classes/stageClasses/Stages/ExtraStage.lua @@ -1,7 +1,7 @@ local Stage = require("classes.stageClasses.Stages.BaseStage.Stage") local GlobalCapManager = require("classes.capClasses.GlobalCapManager") -local StageState = require("classes.stageClasses.Stages.StageState") +local StageState = require("classes.stageClasses.Stages.BaseStage.StageState") ---@class ExtraStage : Stage local ExtraStage = {} @@ -62,7 +62,7 @@ function ExtraStage:OnStageNumberChanged(number, stageLaneIdentifier) self:ActivateStage() end - if self._currentStageState == StageState.BLUE then + if self._currentStageState == StageState.Blue then self:ActivateBlueStage() end -- 2.54.0 From 70d18f4ac3256af7d71bbd7cb2b41c907d93940a Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Tue, 8 Sep 2026 17:07:41 +0200 Subject: [PATCH 05/71] updated luacheck rc --- .luacheckrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.luacheckrc b/.luacheckrc index cebce85..032c3df 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -18,5 +18,5 @@ read_globals = { "env", "timer", "trigger", "world", "coalition", "country", "AI", "Group", "Unit", "StaticObject", "SceneryObject", "Airbase", "Weapon", "land", "atmosphere", "missionCommands", - "net", + "net", "lfs", "Object", "coord", } -- 2.54.0 From 50f2a0eea03951a9d58a49ca26d013287c94e0a0 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Tue, 8 Sep 2026 17:35:21 +0200 Subject: [PATCH 06/71] added CI for all source files --- .gitea/workflows/pr.yml | 20 ++++++++++++++++++++ .luacheckrc | 4 ---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index d5c58d2..76e5218 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -37,3 +37,23 @@ jobs: - name: Lint Compiled Output run: luacheck ./output/spearhead.lua + lua_check: + runs-on: ubuntu-latest + name: Lua Check + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Lua + uses: leafo/gh-actions-lua@v13 + with: + luaVersion: "5.1" + + - name: Set up Luarocks + uses: leafo/gh-actions-luarocks@v4 + + - name: Install luacheck + run: luarocks install luacheck + + - name: Run Lua Check + run: luacheck ./src --config .luacheckrc \ No newline at end of file diff --git a/.luacheckrc b/.luacheckrc index 032c3df..4d4893b 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -2,10 +2,6 @@ std = "lua51" max_line_length = false --- Compiled bundle is a single file; each source file's locals live inside --- their own `do ... end` block, so cross-file shadowing isn't a real risk. -unused_args = false - -- Cross-file globals set by Spearhead itself (no `require`/module system in the bundle) globals = { "SpearheadConfig", -- 2.54.0 From ba240db31041f39802ccde295912a9fda28d5554 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Tue, 8 Sep 2026 21:04:40 +0200 Subject: [PATCH 07/71] fixing linting --- src/classes/capClasses/CapAirbase.lua | 21 +++++++------------ src/classes/capClasses/GlobalCapManager.lua | 10 +++------ src/classes/capClasses/airGroups/AirGroup.lua | 13 ++++++------ src/classes/capClasses/airGroups/CapGroup.lua | 2 +- .../capClasses/airGroups/InterceptGroup.lua | 2 +- .../capClasses/airGroups/SweepGroup.lua | 6 ++---- .../runwayBombing/RunwayBombingTracker.lua | 4 ++-- src/classes/capClasses/taskings/CAP.lua | 3 --- src/classes/configuration/GlobalConfig.lua | 4 ---- src/classes/debug/DebugMenu.lua | 1 - src/classes/fleetClasses/FleetGroup.lua | 2 +- src/classes/helpers/MizGroupsManager.lua | 7 +++---- src/classes/helpers/SpawnManager.lua | 8 +++---- src/classes/persistence/Persistence.lua | 4 ++-- src/classes/spearhead_db.lua | 12 +++++------ .../stageClasses/Groups/SpearheadGroup.lua | 2 +- .../stageClasses/drawings/CustomDrawing.lua | 2 -- .../drawings/helper/DrawingHelper.lua | 1 - .../stageClasses/helpers/BattleManager.lua | 5 ----- .../helpers/MissionCommandsHelper.lua | 11 ++++------ .../helpers/SupplyUnitsTracker.lua | 8 +++---- .../missions/baseMissions/Mission.lua | 5 ++++- src/main.lua | 3 +-- 23 files changed, 52 insertions(+), 84 deletions(-) diff --git a/src/classes/capClasses/CapAirbase.lua b/src/classes/capClasses/CapAirbase.lua index 80390a3..6d73e30 100644 --- a/src/classes/capClasses/CapAirbase.lua +++ b/src/classes/capClasses/CapAirbase.lua @@ -2,7 +2,6 @@ local Util = require("classes.util.Util") local CapGroup = require("classes.capClasses.airGroups.CapGroup") local SweepGroup = require("classes.capClasses.airGroups.SweepGroup") local InterceptGroup = require("classes.capClasses.airGroups.InterceptGroup") -local RunwayBombingTracker = require("classes.capClasses.runwayBombing.RunwayBombingTracker") local SpearheadEvents = require("classes.spearhead_events") local RunwayStrikeMission = require("classes.stageClasses.missions.RunwayStrikeMission") @@ -37,12 +36,11 @@ end ---@param database Database ---@param logger table ---@param capConfig table ----@param stageConfig table ---@param runwayBombingTracker RunwayBombingTracker ---@param detectionManager DetectionManager ---@param spawnManager SpawnManager ---@return CapBase -function CapBase.new(airbaseName, database, logger, capConfig, stageConfig, runwayBombingTracker, detectionManager, spawnManager) +function CapBase.new(airbaseName, database, logger, capConfig, runwayBombingTracker, detectionManager, spawnManager) CapBase.__index = CapBase local self = setmetatable({}, { __index = CapBase }) --[[@as CapBase]] @@ -61,7 +59,7 @@ function CapBase.new(airbaseName, database, logger, capConfig, stageConfig, runw local baseData = database:getAirbaseDataForZone(airbaseName) if baseData and baseData.CapGroups then - for key, name in pairs(baseData.CapGroups) do + for _, name in pairs(baseData.CapGroups) do local capGroup = CapGroup.New(name, capConfig, logger, spawnManager) if capGroup then self.capGroupsByName[name] = capGroup @@ -70,7 +68,7 @@ function CapBase.new(airbaseName, database, logger, capConfig, stageConfig, runw end if baseData and baseData.SweepGroups then - for key, name in pairs(baseData.SweepGroups) do + for _, name in pairs(baseData.SweepGroups) do local sweepGroup = SweepGroup.New(name, capConfig, logger, spawnManager) if sweepGroup then self.sweepGroupsByName[name] = sweepGroup @@ -79,7 +77,7 @@ function CapBase.new(airbaseName, database, logger, capConfig, stageConfig, runw end if baseData and baseData.InterceptGroups then - for key, name in pairs(baseData.InterceptGroups) do + for _, name in pairs(baseData.InterceptGroups) do local interceptGroup = InterceptGroup.New(name, capConfig, logger, detectionManager, spawnManager) if interceptGroup then self.interceptGroupsByName[name] = interceptGroup @@ -127,7 +125,7 @@ end function CapBase:SpawnIfApplicable() self.logger:debug("Check spawns for airbase " .. self.airbaseName) - for groupName, capGroup in pairs(self.capGroupsByName) do + for _, capGroup in pairs(self.capGroupsByName) do local targetStage = capGroup:GetZoneIDWhenStageID(tostring(self.activeStage)) if targetStage ~= nil and capGroup:GetState() == "UnSpawned" then @@ -135,7 +133,7 @@ function CapBase:SpawnIfApplicable() end end - for groupName, sweepGroup in pairs(self.sweepGroupsByName) do + for _, sweepGroup in pairs(self.sweepGroupsByName) do local targetStage = sweepGroup:GetZoneIDWhenStageID(tostring(self.activeStage)) if targetStage ~= nil and sweepGroup:GetState() == "UnSpawned" then @@ -143,7 +141,7 @@ function CapBase:SpawnIfApplicable() end end - for groupName, interceptGroup in pairs(self.interceptGroupsByName) do + for _, interceptGroup in pairs(self.interceptGroupsByName) do local targetStage = interceptGroup:GetZoneIDWhenStageID(tostring(self.activeStage)) if targetStage ~= nil and interceptGroup:GetState() == "UnSpawned" then @@ -314,14 +312,12 @@ function CapBase:CheckAndScheduleIntercept() local interceptZoneIDs = {} - local interceptZoneIDs = {} - local airbase = Airbase.getByName(self.airbaseName) if not airbase then return nil end - for name, group in pairs(self.interceptGroupsByName) do + for _, group in pairs(self.interceptGroupsByName) do local targetZoneID = group:GetZoneIDWhenStageID(tostring(self.activeStage)) if targetZoneID then interceptZoneIDs[targetZoneID] = true @@ -379,7 +375,6 @@ function CapBase:CheckAndScheduleIntercept() if total < required then for _, group in pairs(self.interceptGroupsByName) do if total < required then - local zoneID = group:GetZoneIDWhenStageID(tostring(self.activeStage)) if group:GetState() == "ReadyOnTheRamp" then group:SendToInterceptUnits(targets, name, airbase) total = total + 1 diff --git a/src/classes/capClasses/GlobalCapManager.lua b/src/classes/capClasses/GlobalCapManager.lua index 88f3edc..4e772d7 100644 --- a/src/classes/capClasses/GlobalCapManager.lua +++ b/src/classes/capClasses/GlobalCapManager.lua @@ -8,19 +8,15 @@ local GlobalCapManager = {} do local airbasesPerStage = {} local allAirbasesByName = {} - local activeAirbasesPerActiveStage = {} - local unitsPerzonePerStage = {} - local initiated = false ---comment ---@param database Database ---@param capConfig table - ---@param stageConfig StageConfig ---@param detectionManager DetectionManager ---@param logLevel LogLevel ---@param spawnManager SpawnManager - function GlobalCapManager.start(database, capConfig, detectionManager, stageConfig, logLevel, spawnManager) + function GlobalCapManager.start(database, capConfig, detectionManager, logLevel, spawnManager) if initiated == true then return end local logger = Logger.new("AirbaseManager", logLevel) @@ -29,7 +25,7 @@ do local zones = database:getStagezoneNames() if zones then - for key, stageName in pairs(zones) do + for _, stageName in pairs(zones) do if airbasesPerStage[stageName] == nil then airbasesPerStage[stageName] = {} end @@ -40,7 +36,7 @@ do if airbaseName then local airbaseSpecificLogger = Logger.new("CAP_" .. airbaseName, logLevel) - local airbase = CapAirbase.new(airbaseName, database, airbaseSpecificLogger, capConfig, stageConfig, runwayBombingTracker, detectionManager, spawnManager) + local airbase = CapAirbase.new(airbaseName, database, airbaseSpecificLogger, capConfig, runwayBombingTracker, detectionManager, spawnManager) if airbase then table.insert(airbasesPerStage[stageName], airbase) diff --git a/src/classes/capClasses/airGroups/AirGroup.lua b/src/classes/capClasses/airGroups/AirGroup.lua index 2e3456a..0b869bf 100644 --- a/src/classes/capClasses/airGroups/AirGroup.lua +++ b/src/classes/capClasses/airGroups/AirGroup.lua @@ -1,7 +1,6 @@ local SpearheadEvents = require("classes.spearhead_events") local RTBMission = require("classes.capClasses.taskings.RTB") local Util = require("classes.util.Util") -local DcsUtil = require("classes.util.DcsUtil") local GlobalConfig = require("classes.configuration.GlobalConfig") local CustomDrawing = require("classes.stageClasses.drawings.CustomDrawing") local DrawingHelper = require("classes.stageClasses.drawings.helper.DrawingHelper") @@ -81,7 +80,7 @@ function AirGroup:SetMission(mission) end end - local setMissionDelayed = function(data, time) + local setMissionDelayed = function(data, _) data.self:SetMissionPrivate(data.mission) end @@ -357,7 +356,7 @@ do --- RESPAWN FUNCTIONS self:SetState("Dead") ---@param selfA AirGroup - local respawnTask = function(selfA, time) + local respawnTask = function(selfA, _) selfA:StartRepair() end @@ -376,8 +375,7 @@ do --- RESPAWN FUNCTIONS end ---comment - ---@param selfA AirGroup - local rearmTask = function(selfA, time) + local rearmTask = function(_, _) self:StartRearm() end @@ -402,7 +400,7 @@ do --- RESPAWN FUNCTIONS end ---@param selfA AirGroup - local rearmTask = function(selfA, time) + local rearmTask = function(selfA, _) selfA:MarkRearmComplete() end @@ -415,6 +413,7 @@ end do --EVENT LISTENERS ---@param unit Unit function AirGroup:OnUnitLost(unit) + if unit == nil then return end self:CheckLiveness() end @@ -434,7 +433,7 @@ do --EVENT LISTENERS end end - function AirGroup:OnUnitLanded(unit, airbase) + function AirGroup:OnUnitLanded(_, _) local anyInAir = false local group = Group.getByName(self._groupName) if group then diff --git a/src/classes/capClasses/airGroups/CapGroup.lua b/src/classes/capClasses/airGroups/CapGroup.lua index 40319bb..a7ee26c 100644 --- a/src/classes/capClasses/airGroups/CapGroup.lua +++ b/src/classes/capClasses/airGroups/CapGroup.lua @@ -107,7 +107,7 @@ function CapGroup:InitWithName(groupName) local subsplit = Util.split_string(configPart, "|") if subsplit then - for key, value in pairs(subsplit) do + for _, value in pairs(subsplit) do local keySplit = Util.split_string(value, "]") local targetZone = keySplit[2] local allActives = string.sub(keySplit[1], 2, #keySplit[1]) diff --git a/src/classes/capClasses/airGroups/InterceptGroup.lua b/src/classes/capClasses/airGroups/InterceptGroup.lua index bfe98fa..c9afde3 100644 --- a/src/classes/capClasses/airGroups/InterceptGroup.lua +++ b/src/classes/capClasses/airGroups/InterceptGroup.lua @@ -323,7 +323,7 @@ function InterceptGroup:InitWithName(groupName) configPart = string.sub(configPart, 2, #configPart) local subsplit = Util.split_string(configPart, "|") if subsplit then - for key, value in pairs(subsplit) do + for _, value in pairs(subsplit) do local keySplit = Util.split_string(value, "]") local targetZone = keySplit[2] local allActives = string.sub(keySplit[1], 2, #keySplit[1]) diff --git a/src/classes/capClasses/airGroups/SweepGroup.lua b/src/classes/capClasses/airGroups/SweepGroup.lua index 4ad1812..05d25af 100644 --- a/src/classes/capClasses/airGroups/SweepGroup.lua +++ b/src/classes/capClasses/airGroups/SweepGroup.lua @@ -41,7 +41,7 @@ end ---@field self SweepGroup ---@param params SetTaskParams -local setMissionDelayedTask = function(params, time) +local setMissionDelayedTask = function(params, _) params.self:SetMissionPrivate(params.task) end @@ -50,8 +50,6 @@ function SweepGroup:SendToZone(zone, targetZoneID, airbase) self._currentTargetZoneID = targetZoneID - local group = Group.getByName(self._groupName) - local mission = SWEEP.getAsMissionFromAirbase(self._groupName, airbase, zone, self._config) if mission then ---@type SetTaskParams @@ -82,7 +80,7 @@ function SweepGroup:InitWithName(groupName) local subsplit = Util.split_string(configPart, "|") if subsplit then - for key, value in pairs(subsplit) do + for _, value in pairs(subsplit) do local keySplit = Util.split_string(value, "]") local targetZone = keySplit[2] local allActives = string.sub(keySplit[1], 2, #keySplit[1]) diff --git a/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua b/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua index a8366ae..725d556 100644 --- a/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua +++ b/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua @@ -21,7 +21,7 @@ end ---comment ---@param weapon Weapon -function RunwayBombingTracker:OnWeaponFired(unit, weapon, target) +function RunwayBombingTracker:OnWeaponFired(_, weapon, _) if weapon == nil then return @@ -109,7 +109,7 @@ function RunwayBombingTracker:OnWeaponImpact(weaponDesc, impactPoint) local warhead = weaponDesc.warhead local explosiveMass = warhead.explosiveMass or warhead.shapedExplosiveMass - for runway, strikeMission in pairs(self.trackedRunways) do + for _, strikeMission in pairs(self.trackedRunways) do local zone= strikeMission:GetRunwayZone() diff --git a/src/classes/capClasses/taskings/CAP.lua b/src/classes/capClasses/taskings/CAP.lua index cb53bd2..77c2a5f 100644 --- a/src/classes/capClasses/taskings/CAP.lua +++ b/src/classes/capClasses/taskings/CAP.lua @@ -33,9 +33,6 @@ local function GetCAPPointFromTriggerZone(airBase, capZone) local furthestA = nil local furthestB = nil - local furthestFromBase = nil - local furthestFromBaseDistance = 0 - local furthestDistance = 0 for indexA, pointA in ipairs(capZone.verts) do diff --git a/src/classes/configuration/GlobalConfig.lua b/src/classes/configuration/GlobalConfig.lua index d4c19d8..370baea 100644 --- a/src/classes/configuration/GlobalConfig.lua +++ b/src/classes/configuration/GlobalConfig.lua @@ -1,8 +1,4 @@ - - -local briefingMessageTime = nil - ---@class GlobalConfig ---@field private _briefingTime number ---@field private _debugEnabled boolean diff --git a/src/classes/debug/DebugMenu.lua b/src/classes/debug/DebugMenu.lua index 564679d..97539a2 100644 --- a/src/classes/debug/DebugMenu.lua +++ b/src/classes/debug/DebugMenu.lua @@ -1,5 +1,4 @@ local Logger = require("classes.util.Logger") -local Util = require("classes.util.Util") local StageRepository = require("classes.stageClasses.StageRepository") ---@class DebugMenu diff --git a/src/classes/fleetClasses/FleetGroup.lua b/src/classes/fleetClasses/FleetGroup.lua index 48d7671..97eab9d 100644 --- a/src/classes/fleetClasses/FleetGroup.lua +++ b/src/classes/fleetClasses/FleetGroup.lua @@ -114,7 +114,7 @@ function FleetGroup:new(fleetGroupName, database, logger) end end - local SetTaskAsync = function(input, time) + local SetTaskAsync = function(input, _) local targetZone = input.targetZone local task = input.task local groupName = input.groupName diff --git a/src/classes/helpers/MizGroupsManager.lua b/src/classes/helpers/MizGroupsManager.lua index 1e03b9a..f33a723 100644 --- a/src/classes/helpers/MizGroupsManager.lua +++ b/src/classes/helpers/MizGroupsManager.lua @@ -15,14 +15,13 @@ MizGroupsManager._groupNames = {} MizGroupsManager._spawnTemplateData = {} do --init - for coalition_name, coalition_data in pairs(env.mission.coalition) do - local coalition_nr = DcsUtil.stringToCoalition(coalition_name) + for _, coalition_data in pairs(env.mission.coalition) do if coalition_data.country then - for country_index, country_data in pairs(coalition_data.country) do + for _, country_data in pairs(coalition_data.country) do for category_name, categorydata in pairs(country_data) do local category_id = DcsUtil.stringToGroupCategory(category_name) if category_id ~= nil and type(categorydata) == "table" and categorydata.group ~= nil and type(categorydata.group) == "table" then - for group_index, group in pairs(categorydata.group) do + for _, group in pairs(categorydata.group) do local name = group.name local skippable = false local isStatic = false diff --git a/src/classes/helpers/SpawnManager.lua b/src/classes/helpers/SpawnManager.lua index 14f4686..a3ae9f3 100644 --- a/src/classes/helpers/SpawnManager.lua +++ b/src/classes/helpers/SpawnManager.lua @@ -44,7 +44,7 @@ function SpawnManager:SpawnGroup(groupName, overrides, isGroupPersistant) if spawnData.isStatic == true then return self:SpawnStaticInternal(groupName, spawnData, overrides, isGroupPersistant), true else - return self:SpawnGroupInternal(groupName, spawnData, overrides, isGroupPersistant), false + return self:SpawnGroupInternal(spawnData, overrides, isGroupPersistant), false end end @@ -103,20 +103,20 @@ function SpawnManager:OnUnitLost(object) end end +---@param groupName string function SpawnManager:SpawnCorpsesOnly(groupName) + if groupName == nil then return end end do --- privates ---@private - ---@param groupName string ---@param spawnData SpawnData ---@param override SpawnOverrides? ---@param isPersistent boolean? ---@return Group|nil - function SpawnManager:SpawnGroupInternal(groupName, spawnData, override, isPersistent) - + function SpawnManager:SpawnGroupInternal(spawnData, override, isPersistent) if not spawnData then return end local country = spawnData.country diff --git a/src/classes/persistence/Persistence.lua b/src/classes/persistence/Persistence.lua index d96f3cf..681151f 100644 --- a/src/classes/persistence/Persistence.lua +++ b/src/classes/persistence/Persistence.lua @@ -112,7 +112,7 @@ do logger:info("Wrote persistence data to file") end - local UpdateContinuous = function(null, time) + local UpdateContinuous = function(_, time) env.info("[Spearhead][Persistence] Checking up on persistence state...") if Persistence._updateRequired == true then local status, result = pcall(writeToFile) @@ -135,7 +135,7 @@ do end - local warnForNonPersistenceContinous = function(null, time) + local warnForNonPersistenceContinous = function(_, time) trigger.action.outText("Persistence was enabeld, however, io and lfs are not available and no persistence will be done. Make sure to either disable persistence or fix the issues before continuing.", 10) return time + 9 end diff --git a/src/classes/spearhead_db.lua b/src/classes/spearhead_db.lua index c60bc0b..5462572 100644 --- a/src/classes/spearhead_db.lua +++ b/src/classes/spearhead_db.lua @@ -121,7 +121,7 @@ function Database.New(Logger) self._logger:debug("Initiating tables") do -- INIT ZONE TABLES - for zone_ind, zone_data in pairs(DcsUtil.__trigger_zones) do + for _, zone_data in pairs(DcsUtil.__trigger_zones) do local zone_name = zone_data.name ---@type Vec2 @@ -208,9 +208,9 @@ function Database.New(Logger) self._logger:debug("initiated zone tables, continuing with descriptions") do --load markers if env.mission.drawings and env.mission.drawings.layers then - for i, layer in pairs(env.mission.drawings.layers) do + for _, layer in pairs(env.mission.drawings.layers) do if string.lower(layer.name) == "author" then - for key, layer_object in pairs(layer.objects) do + for _, layer_object in pairs(layer.objects) do if Util.startswith(string.lower(layer_object.name), "buildable", true) == true then local airbaseData = self:getAirbaseDataForDrawLayer(layer_object) if airbaseData then @@ -228,9 +228,9 @@ function Database.New(Logger) ---@type table do -- custom drawings if env.mission.drawings and env.mission.drawings.layers then - for i, layer in pairs(env.mission.drawings.layers) do + for _, layer in pairs(env.mission.drawings.layers) do if string.lower(layer.name) == "author" then - for key, layer_object in pairs(layer.objects) do + for _, layer_object in pairs(layer.objects) do if Util.startswith(layer_object.name, "drawing_", true) then local object = layer_object --[[@as DrawingObject]] local stageDrawing = StageDrawing.New(object) @@ -256,7 +256,7 @@ function Database.New(Logger) -- Find and add Briefing if env.mission.drawings and env.mission.drawings.layers then - for i, layer in pairs(env.mission.drawings.layers) do + for _, 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 Util.startswith(string.lower(layer_object.name), "stagebriefing_", true) == true then diff --git a/src/classes/stageClasses/Groups/SpearheadGroup.lua b/src/classes/stageClasses/Groups/SpearheadGroup.lua index efccb30..0a22e04 100644 --- a/src/classes/stageClasses/Groups/SpearheadGroup.lua +++ b/src/classes/stageClasses/Groups/SpearheadGroup.lua @@ -57,7 +57,7 @@ function SpearheadGroup:Spawn(lateStart) uncontrolled = lateStart, } - local spawnedObject, isStatic = self._spawnManager:SpawnGroup(self._groupName, overrides, self._isPersistent) + local _, isStatic = self._spawnManager:SpawnGroup(self._groupName, overrides, self._isPersistent) self._isStatic = isStatic self._isSpawned = true end diff --git a/src/classes/stageClasses/drawings/CustomDrawing.lua b/src/classes/stageClasses/drawings/CustomDrawing.lua index e902158..a768145 100644 --- a/src/classes/stageClasses/drawings/CustomDrawing.lua +++ b/src/classes/stageClasses/drawings/CustomDrawing.lua @@ -1,7 +1,5 @@ local DrawingHelper = require("classes.stageClasses.drawings.helper.DrawingHelper") -local Util = require("classes.util.Util") local Logger = require("classes.util.Logger") -local MissionEditorWarnings = require("classes.util.MissionEditorWarnings") local drawingLogger = Logger.new("CustomDrawing") diff --git a/src/classes/stageClasses/drawings/helper/DrawingHelper.lua b/src/classes/stageClasses/drawings/helper/DrawingHelper.lua index d356d59..3911546 100644 --- a/src/classes/stageClasses/drawings/helper/DrawingHelper.lua +++ b/src/classes/stageClasses/drawings/helper/DrawingHelper.lua @@ -1,4 +1,3 @@ -local Util = require("classes.util.Util") local DcsUtil = require("classes.util.DcsUtil") local Logger = require("classes.util.Logger") local GlobalConfig = require("classes.configuration.GlobalConfig") diff --git a/src/classes/stageClasses/helpers/BattleManager.lua b/src/classes/stageClasses/helpers/BattleManager.lua index dc855bb..03d22de 100644 --- a/src/classes/stageClasses/helpers/BattleManager.lua +++ b/src/classes/stageClasses/helpers/BattleManager.lua @@ -1,6 +1,5 @@ local Logger = require("classes.util.Logger") local Util = require("classes.util.Util") -local DcsUtil = require("classes.util.DcsUtil") ---@class BattleManager ---@field private _name string @@ -13,8 +12,6 @@ local DcsUtil = require("classes.util.DcsUtil") local BattleManager = {} BattleManager.__index = BattleManager -local debugDrawing = false - ---@param redGroups Array ---@param blueGroups Array ---@param name string @@ -90,8 +87,6 @@ function BattleManager:Update() self._logger:debug("BattleManager Update called for " .. self._name) - local shootChance = 1 -- Adjust this value to control the shooting probability (0.0 to 1.0) - self:LetUnitsShoot(self._redGroups, self._blueGroups) self:LetUnitsShoot(self._blueGroups, self._redGroups) diff --git a/src/classes/stageClasses/helpers/MissionCommandsHelper.lua b/src/classes/stageClasses/helpers/MissionCommandsHelper.lua index b9f33fb..9311bb6 100644 --- a/src/classes/stageClasses/helpers/MissionCommandsHelper.lua +++ b/src/classes/stageClasses/helpers/MissionCommandsHelper.lua @@ -31,8 +31,6 @@ local function sortMissions(list, groupPos) end) end -local id = 0 - local instance = nil ---@return MissionCommandsHelper @@ -57,16 +55,16 @@ function MissionCommandsHelper.getOrCreate() instance._supplyUnitsTracker:AddOnSupplyUnitEventListener( { - enteredSupplyHub = function(self, unit) + enteredSupplyHub = function(_, unit) if unit == nil then return end instance.updateNeeded = true instance:updateCommandsForGroup(unit:getGroup():getID()) end, - exitedSupplyHub = function(self, unit) + exitedSupplyHub = function(_, unit) instance.updateNeeded = true instance:updateCommandsForGroup(unit:getGroup():getID()) end, - supplyUnitSpawned = function(self, unit) + supplyUnitSpawned = function(_, unit) instance.updateNeeded = true instance:updateCommandsForGroup(unit:getGroup():getID()) end @@ -509,7 +507,6 @@ function MissionCommandsHelper:AddCargoCommands(groupID) local unloadCargoCommand = function(params) local unitID = params.unitID local crateType = params.crateType - local supplyUnitsTracker = params.supplyUnitsTracker params.supplyUnitsTracker:UnloadRequested(unitID, crateType, params.commandHelper) end @@ -518,7 +515,7 @@ function MissionCommandsHelper:AddCargoCommands(groupID) for cargoType, amount in pairs(cargo) do local cargoConfig = SupplyConfigHelper.getSupplyConfig(cargoType) if cargoConfig then - for i = 1, amount do + for _ = 1, amount do local path = { [1] = folderNames.cargo } ---@type UnloadCargoCommandParams local params = { unitID = unit:getID(), crateType = cargoType, supplyUnitsTracker = self diff --git a/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua b/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua index e83a582..eee35c8 100644 --- a/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua +++ b/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua @@ -185,7 +185,7 @@ function SupplyUnitsTracker:RemoveCargoFromUnit(unitID, crateType) self._cargoInUnits[unitIDStr][crateType] = self._cargoInUnits[unitIDStr][crateType] - 1 local hasCargo = false - for type, count in pairs(self._cargoInUnits[unitIDStr]) do + for _, count in pairs(self._cargoInUnits[unitIDStr]) do if count > 0 then hasCargo = true break @@ -216,13 +216,11 @@ end function SupplyUnitsTracker:CheckUnitsInZones() - for name, unit in pairs(self._supplyUnitsByName) do + for _, unit in pairs(self._supplyUnitsByName) do if unit ~= nil and unit:isExist() == true then self._logger:debug("Checking unit: " .. unit:getName()) local pos = unit:getPoint() - local group = unit:getGroup() - for hub, enabled in pairs(self._registeredHubs) do if enabled == true then local zone = hub:GetZone() @@ -614,7 +612,7 @@ function SupplyUnitsTracker:GetCargoPlacePosition(unit, crateTypeName) } local occupiedObjects = {} - local found = function(foundItem, val) + local found = function(foundItem, _) local bbox = self:GetBoundingBoxes(foundItem) if bbox then self._logger:debug("Found object: " .. foundItem:getTypeName() .. " at (" .. foundItem:getPoint().x .. ", " .. foundItem:getPoint().z .. ")") diff --git a/src/classes/stageClasses/missions/baseMissions/Mission.lua b/src/classes/stageClasses/missions/baseMissions/Mission.lua index f5272b7..2cb4c09 100644 --- a/src/classes/stageClasses/missions/baseMissions/Mission.lua +++ b/src/classes/stageClasses/missions/baseMissions/Mission.lua @@ -70,6 +70,7 @@ function Mission:SpawnActive() end ---comment ---@param checkHealth boolean ---@param messageIfDone boolean +---@diagnostic disable-next-line: unused-local function Mission:UpdateState(checkHealth, messageIfDone) end function Mission:StartCheckingContinuous() end @@ -120,7 +121,7 @@ function Mission:NotifyMissionComplete() end) end - local succ, err = pcall(function() + local _, _ = pcall(function() SpearheadAPI.Internal.notifyMissionComplete(self.zoneName) end) @@ -131,6 +132,8 @@ function Mission:ForceMissionComplete() self:NotifyMissionComplete() end +---@param groupId number +---@diagnostic disable-next-line: unused-local function Mission:MarkMissionAreaToGroup(groupId) end ---endregion diff --git a/src/main.lua b/src/main.lua index 56e3f69..fe6ab7c 100644 --- a/src/main.lua +++ b/src/main.lua @@ -1,7 +1,6 @@ --Single player purpose local Logger = require("classes.util.Logger") -local DcsUtil = require("classes.util.DcsUtil") local Database = require("classes.spearhead_db") local SpearheadEvents = require("classes.spearhead_events") local MissionCommandsHelper = require("classes.stageClasses.helpers.MissionCommandsHelper") @@ -47,7 +46,7 @@ local spawnManager = SpawnManager.new(spawnLogger) local detectionLogger = Logger.new("DetectionManager", defaultLogLevel) local detectionManager = DetectionManager.New(detectionLogger) -GlobalCapManager.start(databaseManager, capConfig, detectionManager, stageConfig, defaultLogLevel, spawnManager) +GlobalCapManager.start(databaseManager, capConfig, detectionManager, defaultLogLevel, spawnManager) local globalStageManager = GlobalStageManager.new(databaseManager, stageConfig, defaultLogLevel, spawnManager) GlobalFleetManager.start(databaseManager) -- 2.54.0 From 0346f8a7a84f7434dfadf89f2dbc85f55e26bbe8 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 11:12:58 +0200 Subject: [PATCH 08/71] linter fixes --- config.lua | 6 +- dev/dev_classes.lua | 73 ------- dev/dev_config.lua | 79 ------- src/classes/capClasses/CapAirbase.lua | 15 +- src/classes/capClasses/GlobalCapManager.lua | 3 +- src/classes/capClasses/airGroups/CapGroup.lua | 6 +- .../capClasses/airGroups/InterceptGroup.lua | 8 +- .../capClasses/airGroups/SweepGroup.lua | 6 +- .../capClasses/detection/DetectionManager.lua | 1 - .../runwayBombing/RunwayBombingTracker.lua | 8 +- src/classes/capClasses/taskings/INTERCEPT.lua | 10 +- src/classes/capClasses/taskings/RTB.lua | 6 +- src/classes/configuration/StageConfig.lua | 2 +- src/classes/fleetClasses/FleetGroup.lua | 90 ++++---- .../fleetClasses/GlobalFleetManager.lua | 2 +- src/classes/helpers/SpawnManager.lua | 5 +- src/classes/persistence/Persistence.lua | 10 +- src/classes/spearhead_db.lua | 26 ++- src/classes/spearhead_events.lua | 55 +++-- .../stageClasses/GlobalStageManager.lua | 202 +++++++++--------- .../stageClasses/Groups/SpearheadGroup.lua | 12 +- .../stageClasses/SpecialZones/BlueSam.lua | 14 +- .../stageClasses/SpecialZones/FarpZone.lua | 6 +- .../stageClasses/SpecialZones/StageBase.lua | 4 +- .../stageClasses/SpecialZones/SupplyHub.lua | 2 +- .../SpecialZones/abstract/BuildableZone.lua | 35 ++- src/classes/stageClasses/StageRepository.lua | 1 - .../stageClasses/Stages/BaseStage/Stage.lua | 48 ++--- .../stageClasses/Stages/ExtraStage.lua | 4 +- .../stageClasses/Stages/WaitingStage.lua | 8 +- .../drawings/helper/DrawingHelper.lua | 6 +- .../stageClasses/helpers/BattleManager.lua | 12 +- .../stageClasses/helpers/SupplyLoadConfig.lua | 2 +- .../helpers/SupplyUnitsTracker.lua | 50 ++--- .../missions/BuildableMission.lua | 23 +- .../missions/RunwayStrikeMission.lua | 8 +- .../stageClasses/missions/ZoneMission.lua | 6 +- .../missions/baseMissions/Mission.lua | 2 +- src/classes/util/DcsUtil.lua | 45 ++-- src/classes/util/Util.lua | 2 +- 40 files changed, 367 insertions(+), 536 deletions(-) delete mode 100644 dev/dev_classes.lua delete mode 100644 dev/dev_config.lua diff --git a/config.lua b/config.lua index 14af0b5..f463f95 100644 --- a/config.lua +++ b/config.lua @@ -15,7 +15,7 @@ SpearheadConfig = { --quickly enable of disable the entire CAP Logic --(you can also just rename all units to not be named "CAP_") enabled = true, -- default true - + --min ground speed for CAP aircraft during patrol -- unit: knots minSpeed = 400, -- default 400 @@ -62,7 +62,7 @@ SpearheadConfig = { deathDelay = 1800, -- default 1800 }, StageConfig = { - + -- management of stages and its missions. -- This is not related to CAP managers which will continue to work even if stage management is disabled enabled = true, -- default true @@ -98,7 +98,7 @@ SpearheadConfig = { }, Persistence = { --- io and lfs cannot be sanitized in the MissionScripting.lua - + --- enables or disables the persistence logic in spearhead enabled = false, diff --git a/dev/dev_classes.lua b/dev/dev_classes.lua deleted file mode 100644 index 8e2a55b..0000000 --- a/dev/dev_classes.lua +++ /dev/null @@ -1,73 +0,0 @@ - - - ---assert(loadfile("C:\\Repos\\DCS\\Spearhead\\dev\\dev_classes.lua"))() - -local basePath = "C:\\Repos\\DCS\\Spearhead\\" -local classPath = basePath .. "classes\\" - -assert(loadfile(classPath .. "_baseClasses\\Queue.lua"))() - -assert(loadfile(classPath .. "spearhead_base.lua"))() -assert(loadfile(classPath .. "spearhead_routeutil.lua"))() -assert(loadfile(classPath .. "spearhead_events.lua"))() -assert(loadfile(classPath .. "spearhead_db.lua"))() - -assert(loadfile(classPath .. "fleetClasses\\FleetGroup.lua"))() -assert(loadfile(classPath .. "fleetClasses\\GlobalFleetManager.lua"))() - -assert(loadfile(classPath .. "helpers\\MizGroupsManager.lua"))() -assert(loadfile(classPath .. "helpers\\SpawnManager.lua"))() - -assert(loadfile(classPath .. "configuration\\CapConfig.lua"))() -assert(loadfile(classPath .. "configuration\\StageConfig.lua"))() - -assert(loadfile(classPath .. "stageClasses\\GlobalStageManager.lua"))() -assert(loadfile(classPath .. "stageClasses\\missions\\baseMissions\\Mission.lua"))() -assert(loadfile(classPath .. "stageClasses\\missions\\ZoneMission.lua"))() -assert(loadfile(classPath .. "stageClasses\\missions\\RunwayStrikeMission.lua"))() -assert(loadfile(classPath .. "stageClasses\\missions\\BuildableMission.lua"))() - - -assert(loadfile(classPath .. "stageClasses\\Stages\\BaseStage\\Stage.lua"))() -assert(loadfile(classPath .. "stageClasses\\Stages\\PrimaryStage.lua"))() -assert(loadfile(classPath .. "stageClasses\\Stages\\ExtraStage.lua"))() -assert(loadfile(classPath .. "stageClasses\\Stages\\WaitingStage.lua"))() - - -assert(loadfile(classPath .. "stageClasses\\Groups\\SpearheadGroup.lua"))() -assert(loadfile(classPath .. "stageClasses\\Groups\\SpearheadSceneryObject.lua"))() - - -assert(loadfile(classPath .. "stageClasses\\helpers\\MissionCommandsHelper.lua"))() -assert(loadfile(classPath .. "stageClasses\\helpers\\SupplyConfig.lua"))() -assert(loadfile(classPath .. "stageClasses\\helpers\\SupplyUnitsTracker.lua"))() -assert(loadfile(classPath .. "stageClasses\\helpers\\BattleManager.lua"))() - -assert(loadfile(classPath .. "stageClasses\\SpecialZones\\abstract\\BuildableZone.lua"))() -assert(loadfile(classPath .. "stageClasses\\SpecialZones\\StageBase.lua"))() -assert(loadfile(classPath .. "stageClasses\\SpecialZones\\BlueSam.lua"))() -assert(loadfile(classPath .. "stageClasses\\SpecialZones\\FarpZone.lua"))() -assert(loadfile(classPath .. "stageClasses\\SpecialZones\\SupplyHub.lua"))() - -assert(loadfile(classPath .. "capClasses\\taskings\\RTB.lua"))() -assert(loadfile(classPath .. "capClasses\\taskings\\CAP.lua"))() -assert(loadfile(classPath .. "capClasses\\taskings\\SWEEP.lua"))() -assert(loadfile(classPath .. "capClasses\\taskings\\INTERCEPT.lua"))() -assert(loadfile(classPath .. "capClasses\\airGroups\\AirGroup.lua"))() -assert(loadfile(classPath .. "capClasses\\airGroups\\CapGroup.lua"))() -assert(loadfile(classPath .. "capClasses\\airGroups\\SweepGroup.lua"))() -assert(loadfile(classPath .. "capClasses\\airGroups\\InterceptGroup.lua"))() -assert(loadfile(classPath .. "capClasses\\detection\\DetectionManager.lua"))() -assert(loadfile(classPath .. "capClasses\\GlobalCapManager.lua"))() -assert(loadfile(classPath .. "capClasses\\CapAirbase.lua"))() -assert(loadfile(classPath .. "capClasses\\runwayBombing\\RunwayBombingTracker.lua"))() - -assert(loadfile(classPath .. "persistence\\Persistence.lua"))() - --- Startup: - - - -assert(loadfile(basePath .. "main.lua"))() - diff --git a/dev/dev_config.lua b/dev/dev_config.lua deleted file mode 100644 index cc1c608..0000000 --- a/dev/dev_config.lua +++ /dev/null @@ -1,79 +0,0 @@ - -SpearheadConfig = { - - debugEnabled = true, - CapConfig = { - --quickly enable of disable the entire CAP Logic - --(you can also just rename all units to not be named "CAP_") - enabled = true, -- default true - - --min ground speed for CAP aircraft during patrol - -- unit: knots - minSpeed = 400, -- default 400 - - --max speed for CAP aircraft during patrol - -- unit: knots - maxSpeed = 500, -- default 500 - - --minAlt for aircraft on patrol - -- unit: feet - minAlt = 18000, -- default 18000 - - --maxAlt for aircraft on patrol - -- unit: feet - maxAlt = 28000, -- default 28000 - - --Delay for aircraft from touchdown to off the chocks. - -- unit: seconds - rearmDelay = 180, -- default 600 - repairDelay = 600, -- default 600 - --Delay for aircraft from death to takeoff. - --When the seconds remaining is the same at the rearmDelay it will be spawned on the ramp and follow the rearm logic. - -- !! Can not be lower than rearmDelay - -- unit: seconds - deathDelay = 1800, -- default 1800 - }, - StageConfig = { - - -- management of stages and its missions. - -- This is not related to CAP managers which will continue to work even if stage management is disabled - enabled = true, -- default true - - --Will draw the active and the next stage - drawStages = true, -- default true - drawPreActivated = true, - markLastContact = 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. - --[[ - TODO: Add manual stage transition documentation - ]] - autoStages = true, --default true - - --Maximum missions per stage (includes all types of missions) - maxMissionStage = 100, - - --Stage starting number - startingStage = 1, - - ---DEBUG logging. Consider keeping this disabled - debugEnabled = true - }, - Persistence = { - --- io and lfs cannot be sanitized in the MissionScripting.lua - - --- enables or disables the persistence logic in spearhead - enabled = true, - - --- sets the directory where the persistence file is stored - --- if nil then lfs.writedir() will be used. - --- which will - directory = nil , - - --- the filename of the persistence file. Should end with .json for convention, but any text extension should do. - fileName = "Spearhead_Persistence_Dev" - - } -} - diff --git a/src/classes/capClasses/CapAirbase.lua b/src/classes/capClasses/CapAirbase.lua index 6d73e30..1a5c2d4 100644 --- a/src/classes/capClasses/CapAirbase.lua +++ b/src/classes/capClasses/CapAirbase.lua @@ -95,7 +95,6 @@ function CapBase.new(airbaseName, database, logger, capConfig, runwayBombingTrac SpearheadEvents.AddStageNumberChangedListener(self) timer.scheduleFunction(CheckStateContinuous, self, timer.getTime() + 15) - return self end @@ -152,8 +151,9 @@ end function CapBase:CheckAndScheduleCAP() self.logger:debug("Check taskings for airbase " .. self.airbaseName) - + ---@type table local countPerStage = {} + ---@type table local requiredPerStage = {} local airbase = Airbase.getByName(self.airbaseName) @@ -168,7 +168,7 @@ function CapBase:CheckAndScheduleCAP() if group:IsBackup() == true then local state = group:GetState() if state == "InTransit" or state == "OnStation" or state == "RtbInTen" then - + local supposedTargetZoneID = group:GetZoneIDWhenStageID(activeStageID) local currentTargetZone = group:GetCurrentTargetZoneID() @@ -190,7 +190,7 @@ function CapBase:CheckAndScheduleCAP() end end end - + if countPerStage[supposedTargetZoneID] == nil then countPerStage[supposedTargetZoneID] = 0 end @@ -229,7 +229,7 @@ function CapBase:CheckAndScheduleCAP() countPerStage[supposedZone] = countPerStage[supposedZone] + 1 end elseif state == "InTransit" or state == "OnStation" then - + if supposedZone ~= group:GetCurrentTargetZoneID() then if countPerStage[supposedZone] < requiredPerStage[supposedZone] then local triggerZone = self.database:GetCapZoneForZoneID(supposedZone) @@ -271,7 +271,7 @@ function CapBase:CheckAndScheduleCAP() if triggerZone then group:SendToZone(triggerZone, supposedZone, airbase) end - + countPerStage[supposedZone] = countPerStage[supposedZone] + 1 end end @@ -310,6 +310,7 @@ function CapBase:CheckAndScheduleIntercept() self.logger:debug("Check intercept taskings for airbase " .. self.airbaseName) + ---@type table local interceptZoneIDs = {} local airbase = Airbase.getByName(self.airbaseName) @@ -353,7 +354,7 @@ function CapBase:CheckAndScheduleIntercept() end end end - + ---RATIO. Amount of enemy fighters required per zone before another group gets added. local ratio = 4 -- Ratio of units to intercept per zone, can be adjusted diff --git a/src/classes/capClasses/GlobalCapManager.lua b/src/classes/capClasses/GlobalCapManager.lua index 4e772d7..94c9014 100644 --- a/src/classes/capClasses/GlobalCapManager.lua +++ b/src/classes/capClasses/GlobalCapManager.lua @@ -35,9 +35,8 @@ do for _, airbaseName in pairs(airbaseNames) do if airbaseName then local airbaseSpecificLogger = Logger.new("CAP_" .. airbaseName, logLevel) - + local airbase = CapAirbase.new(airbaseName, database, airbaseSpecificLogger, capConfig, runwayBombingTracker, detectionManager, spawnManager) - if airbase then table.insert(airbasesPerStage[stageName], airbase) allAirbasesByName[airbaseName] = airbase diff --git a/src/classes/capClasses/airGroups/CapGroup.lua b/src/classes/capClasses/airGroups/CapGroup.lua index a7ee26c..decd1d8 100644 --- a/src/classes/capClasses/airGroups/CapGroup.lua +++ b/src/classes/capClasses/airGroups/CapGroup.lua @@ -103,7 +103,7 @@ function CapGroup:InitWithName(groupName) return end - + local subsplit = Util.split_string(configPart, "|") if subsplit then @@ -112,8 +112,8 @@ function CapGroup:InitWithName(groupName) local targetZone = keySplit[2] local allActives = string.sub(keySplit[1], 2, #keySplit[1]) local commaSeperated = Util.split_string(allActives, ",") - for _, value in pairs(commaSeperated) do - local dashSeperated = Util.split_string(value, "-") + for _, childValue in pairs(commaSeperated) do + local dashSeperated = Util.split_string(childValue, "-") if Util.tableLength(dashSeperated) > 1 then local from = tonumber(dashSeperated[1]) local till = tonumber(dashSeperated[2]) diff --git a/src/classes/capClasses/airGroups/InterceptGroup.lua b/src/classes/capClasses/airGroups/InterceptGroup.lua index c9afde3..8bdac36 100644 --- a/src/classes/capClasses/airGroups/InterceptGroup.lua +++ b/src/classes/capClasses/airGroups/InterceptGroup.lua @@ -190,7 +190,7 @@ function InterceptGroup:UpdateTask() self:SendRTB(self._airbase) return nil -- Return to base if bingo fuel end - + if selfDetected and self:IsInAir() == true then if self._currentTargetName and self._currentTargetName == closestUnit:getName() then local distance = Util.VectorDistance3d(closestUnit:getPoint(), groupPoint) @@ -213,8 +213,6 @@ function InterceptGroup:UpdateTask() self._currentTargetName = nil end - - local speed = self._config:getMaxSpeed() local interceptPoint = self:GetInterceptPoint(groupPoint, speed, closestUnit) @@ -328,8 +326,8 @@ function InterceptGroup:InitWithName(groupName) local targetZone = keySplit[2] local allActives = string.sub(keySplit[1], 2, #keySplit[1]) local commaSeperated = Util.split_string(allActives, ",") - for _, value in pairs(commaSeperated) do - local dashSeperated = Util.split_string(value, "-") + for _, childValue in pairs(commaSeperated) do + local dashSeperated = Util.split_string(childValue, "-") if Util.tableLength(dashSeperated) > 1 then local from = tonumber(dashSeperated[1]) local till = tonumber(dashSeperated[2]) diff --git a/src/classes/capClasses/airGroups/SweepGroup.lua b/src/classes/capClasses/airGroups/SweepGroup.lua index 05d25af..ee5988a 100644 --- a/src/classes/capClasses/airGroups/SweepGroup.lua +++ b/src/classes/capClasses/airGroups/SweepGroup.lua @@ -77,7 +77,7 @@ function SweepGroup:InitWithName(groupName) local configPart = split_string[2] configPart = string.sub(configPart, 2, #configPart) - + local subsplit = Util.split_string(configPart, "|") if subsplit then for _, value in pairs(subsplit) do @@ -85,8 +85,8 @@ function SweepGroup:InitWithName(groupName) local targetZone = keySplit[2] local allActives = string.sub(keySplit[1], 2, #keySplit[1]) local commaSeperated = Util.split_string(allActives, ",") - for _, value in pairs(commaSeperated) do - local dashSeperated = Util.split_string(value, "-") + for _, childValue in pairs(commaSeperated) do + local dashSeperated = Util.split_string(childValue, "-") if Util.tableLength(dashSeperated) > 1 then local from = tonumber(dashSeperated[1]) local till = tonumber(dashSeperated[2]) diff --git a/src/classes/capClasses/detection/DetectionManager.lua b/src/classes/capClasses/detection/DetectionManager.lua index 50b16b4..5cef8bd 100644 --- a/src/classes/capClasses/detection/DetectionManager.lua +++ b/src/classes/capClasses/detection/DetectionManager.lua @@ -37,7 +37,6 @@ function DetectionManager.New(logger) return time + 10 end timer.scheduleFunction(updateDetected, self, timer.getTime() + 130) - return self end diff --git a/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua b/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua index 725d556..f77b958 100644 --- a/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua +++ b/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua @@ -30,7 +30,7 @@ function RunwayBombingTracker:OnWeaponFired(_, weapon, _) local desc = weapon:getDesc() local isTrackable = desc.category == Weapon.Category.BOMB or (desc.category == Weapon.Category.MISSILE and desc.missileCategory == Weapon.MissileCategory.CRUISE) if isTrackable == true then - + ---@type WeaponTrackingArgs local weaponTrackingArgs = { weapon = weapon, @@ -61,7 +61,7 @@ function RunwayBombingTracker.trackWeaponTask(weaponTrackingArgs, time) local weapon = weaponTrackingArgs.weapon local self = weaponTrackingArgs.self - + if not weapon or weapon:isExist() == false then return nil end local pos = weapon:getPoint() @@ -83,11 +83,7 @@ function RunwayBombingTracker.trackWeaponTask(weaponTrackingArgs, time) x = pos.x + velocity.x * nextInterval, y = pos.z + velocity.z * nextInterval } - - self:OnWeaponImpact(weapon:getDesc(), impactPoint) - - return nil end diff --git a/src/classes/capClasses/taskings/INTERCEPT.lua b/src/classes/capClasses/taskings/INTERCEPT.lua index e6cdc8d..6c90ec4 100644 --- a/src/classes/capClasses/taskings/INTERCEPT.lua +++ b/src/classes/capClasses/taskings/INTERCEPT.lua @@ -38,7 +38,7 @@ function INTERCEPT.getMissionFromAirbase(groupName, interceptPoint, airbase, con id = 'Mission', params = { airborne = true, - route = { + route = { points = points } } @@ -159,10 +159,10 @@ function INTERCEPT.getInterceptTaskPoint(groupName, currentPoint, targetPoint, a params = { tasks = { id = 'EngageTargetsInZone', - params = { + params = { point = targetPoint, zoneRadius = 10 * 1852, -- 10 NM, point will be updated, so target should be in this zone. - targetTypes = { + targetTypes = { [1] = "Planes", }, priority = 0 @@ -188,10 +188,10 @@ function INTERCEPT.getInterceptTaskPoint(groupName, currentPoint, targetPoint, a params = { tasks = { id = 'EngageTargetsInZone', - params = { + params = { point = targetPoint, zoneRadius = 10 * 1852, -- 10 NM, point will be updated, so target should be in this zone. - targetTypes = { + targetTypes = { [1] = "Planes", }, priority = 0 diff --git a/src/classes/capClasses/taskings/RTB.lua b/src/classes/capClasses/taskings/RTB.lua index 7ebfa5a..6484a91 100644 --- a/src/classes/capClasses/taskings/RTB.lua +++ b/src/classes/capClasses/taskings/RTB.lua @@ -47,7 +47,7 @@ local getRunwayIntoWindCourseRad = function(airbase) else rad = 0 - rad end - + local runwayVec = {x = math.cos(rad), z = math.sin(rad), y = 0} local alignment = Util.vectorAlignment(windVec, runwayVec) @@ -60,14 +60,14 @@ local getRunwayIntoWindCourseRad = function(airbase) do --inverse local degree = math.deg(runway.course) degree = (degree + 180) % 360 - + local rad = math.rad(degree) if rad < 0 then rad = math.abs(rad) else rad = 0 - rad end - + local runwayVec = {x = math.cos(rad), z = math.sin(rad), y = 0} local alignment = Util.vectorAlignment(windVec, runwayVec) diff --git a/src/classes/configuration/StageConfig.lua b/src/classes/configuration/StageConfig.lua index 94590db..54eb580 100644 --- a/src/classes/configuration/StageConfig.lua +++ b/src/classes/configuration/StageConfig.lua @@ -18,7 +18,7 @@ local _logger = Logger.new("StageConfig", Logger.LogLevel) ---@return StageConfig local function new() - if SpearheadConfig == nil then + if SpearheadConfig == nil then _logger:warn("SpearheadConfig is nil, creating default SpearheadConfig") SpearheadConfig = {} end diff --git a/src/classes/fleetClasses/FleetGroup.lua b/src/classes/fleetClasses/FleetGroup.lua index 97eab9d..12b63b3 100644 --- a/src/classes/fleetClasses/FleetGroup.lua +++ b/src/classes/fleetClasses/FleetGroup.lua @@ -4,37 +4,43 @@ local MissionEditorWarning = require("classes.util.MissionEditorWarnings") local RouteUtil = require("classes.spearhead_routeutil") local SpearheadEvents = require("classes.spearhead_events") ----@class FleetGroup +---@class FleetGroup : OnStageChangedListener +---@field private fleetGroupName string +---@field private logger Logger +---@field private fleetNameIdentifier string +---@field private targetZonePerStage table +---@field private currentTargetZone string +---@field private pointsPerZone table local FleetGroup = {} +FleetGroup.__index = FleetGroup ---comment ---@param fleetGroupName string ---@param database Database ---@param logger Logger ----@return nil -function FleetGroup:new(fleetGroupName, database, logger) - local o = {} +---@return FleetGroup? +function FleetGroup.new(fleetGroupName, database, logger) - setmetatable(o, { __index = self }) + local self = setmetatable({}, FleetGroup) - o.fleetGroupName = fleetGroupName - o.logger = logger + self.fleetGroupName = fleetGroupName + self.logger = logger local split_name = Util.split_string(fleetGroupName, "_") if Util.tableLength(split_name) < 2 then MissionEditorWarning.Add("CARRIERGROUP should have at least 2 parts. CARRIERGROUP_") return nil end - o.fleetNameIdentifier = split_name[2] + self.fleetNameIdentifier = split_name[2] - o.targetZonePerStage = {} - o.currentTargetZone = nil - o.pointsPerZone = {} + self.targetZonePerStage = {} + self.currentTargetZone = nil + self.pointsPerZone = {} do --INIT local carrierRouteZones = database:getCarrierRouteZones() for _, zoneName in pairs(carrierRouteZones) do - if Util.strContains(string.lower(zoneName), "_".. string.lower(o.fleetNameIdentifier) .. "_" ) == true then + if Util.strContains(string.lower(zoneName), "_".. string.lower(self.fleetNameIdentifier) .. "_" ) == true then local zone = DcsUtil.getZoneByName(zoneName) if zone and zone.zone_type == DcsUtil.ZoneType.Polygon then local split_string = Util.split_string(zoneName, "_") @@ -43,18 +49,18 @@ function FleetGroup:new(fleetGroupName, database, logger) "CARRIERROUTE should at least have 3 parts. Check the documentation for: " .. zoneName) else - ---@param zone SpearheadTriggerZone + ---@param zoneA SpearheadTriggerZone ---@return Vec2, Vec2 - local function GetTwoFurthestPoints(zone) + local function GetTwoFurthestPoints(zoneA) local biggest = nil - local biggestA = zone.verts[1] - local biggestB = zone.verts[2] + local biggestA = zoneA.verts[1] + local biggestB = zoneA.verts[2] for i = 1, 3 do for ii = i + 1, 4 do - local a = zone.verts[i] - local b = zone.verts[ii] + local a = zoneA.verts[i] + local b = zoneA.verts[ii] local dist = Util.VectorDistance2d(a, b) if biggest == nil or dist > biggest then @@ -100,9 +106,9 @@ function FleetGroup:new(fleetGroupName, database, logger) local first, second = getMinMaxStage(split_string[3]) if first ~= nil and second ~= nil then for i = first, second do - o.targetZonePerStage[tostring(i)] = zoneName + self.targetZonePerStage[tostring(i)] = zoneName end - o.pointsPerZone[zoneName] = { pointA = { x = pointA.x, z = pointA.y, y = 0 }, pointB = { x = pointB.x, z = pointB.y, y = 0} } + self.pointsPerZone[zoneName] = { pointA = { x = pointA.x, z = pointA.y, y = 0 }, pointB = { x = pointB.x, z = pointB.y, y = 0} } else MissionEditorWarning.Add("CARRIERROUTE zone stage numbers not in the format _[-]: " .. zoneName) end @@ -114,32 +120,32 @@ function FleetGroup:new(fleetGroupName, database, logger) end end - local SetTaskAsync = function(input, _) - local targetZone = input.targetZone - local task = input.task - local groupName = input.groupName - local logger = input.logger + SpearheadEvents.AddStageNumberChangedListener(self) + return self +end - local group = Group.getByName(groupName) - if group then - logger:info("Sending " .. groupName .. " to " .. targetZone) - group:getController():setTask(task) - end +local SetTaskAsync = function(input, _) + local targetZone = input.targetZone + local task = input.task + local groupName = input.groupName + local l_logger = input.logger + + local group = Group.getByName(groupName) + if group then + l_logger:info("Sending " .. groupName .. " to " .. targetZone) + group:getController():setTask(task) end +end - o.OnStageNumberChanged = function(self, number, laneIdentifier) - -- only react on "main" lane changes, ignore other lanes for now - if laneIdentifier ~= nil then return end - local targetZone = self.targetZonePerStage[tostring(number)] - if targetZone and targetZone ~= self.currentTargetZone then - local points = self.pointsPerZone[targetZone] - local task = RouteUtil.CreateCarrierRacetrack(points.pointA, points.pointB) - timer.scheduleFunction(SetTaskAsync, { task = task, targetZone = targetZone, groupName = self.fleetGroupName, logger = self.logger }, timer.getTime() + 5) - end +function FleetGroup:OnStageNumberChanged(number, laneIdentifier) + -- only react on "main" lane changes, ignore other lanes for now + if laneIdentifier ~= nil then return end + local targetZone = self.targetZonePerStage[tostring(number)] + if targetZone and targetZone ~= self.currentTargetZone then + local points = self.pointsPerZone[targetZone] + local task = RouteUtil.CreateCarrierRacetrack(points.pointA, points.pointB) + timer.scheduleFunction(SetTaskAsync, { task = task, targetZone = targetZone, groupName = self.fleetGroupName, logger = self.logger }, timer.getTime() + 5) end - - SpearheadEvents.AddStageNumberChangedListener(o) - return o end return FleetGroup diff --git a/src/classes/fleetClasses/GlobalFleetManager.lua b/src/classes/fleetClasses/GlobalFleetManager.lua index 11aa78c..b987dc8 100644 --- a/src/classes/fleetClasses/GlobalFleetManager.lua +++ b/src/classes/fleetClasses/GlobalFleetManager.lua @@ -17,7 +17,7 @@ GlobalFleetManager.start = function(database) for _, groupName in pairs(all_groups) do if Util.startswith(string.lower(groupName), "carriergroup" ) == true then logger:info("Registering " .. groupName .. " as a managed fleet") - local carrierGroup = FleetGroup:new(groupName, database, logger) + local carrierGroup = FleetGroup.new(groupName, database, logger) table.insert(fleetGroups, carrierGroup) end end diff --git a/src/classes/helpers/SpawnManager.lua b/src/classes/helpers/SpawnManager.lua index a3ae9f3..812faf4 100644 --- a/src/classes/helpers/SpawnManager.lua +++ b/src/classes/helpers/SpawnManager.lua @@ -33,7 +33,7 @@ end ---@return StaticObject|Group|nil spawned ---@return boolean isStatic function SpawnManager:SpawnGroup(groupName, overrides, isGroupPersistant) - + local spawnData = MizGroupsManager.getSpawnTemplateData(groupName) if spawnData == nil then @@ -50,7 +50,7 @@ end function SpawnManager:DestroyGroup(groupName) if groupName == nil then return end - + if self:IsGroupStatic(groupName) == true then local object = StaticObject.getByName(groupName) if object ~= nil then @@ -181,7 +181,6 @@ do --- privates return group end - return nil end diff --git a/src/classes/persistence/Persistence.lua b/src/classes/persistence/Persistence.lua index 681151f..9cb886c 100644 --- a/src/classes/persistence/Persistence.lua +++ b/src/classes/persistence/Persistence.lua @@ -89,7 +89,7 @@ do else logger:error("Could not load persistence file, using default tables") end - + if tables.version == nil then tables.version = version end end @@ -114,7 +114,7 @@ do local UpdateContinuous = function(_, time) env.info("[Spearhead][Persistence] Checking up on persistence state...") - if Persistence._updateRequired == true then + if Persistence._updateRequired == true then local status, result = pcall(writeToFile) if status == false then env.error("[Spearhead][Persistence] Could not write state to file: " .. result) @@ -194,7 +194,7 @@ do split[#split+1] = "0" split[#split+1] = "spearhead" end - + fileName = table.concat(split, ".") end @@ -218,12 +218,12 @@ do logger:info("No previous persistence file found, using default: " .. fileName) end - + logger:info("New Persistence file name: " .. tostring(fileName)) local lastPath = dir .. "\\" .. lastFile local path = dir .. "\\" .. fileName Persistence._path = path - + createFileIfNotExists(path) loadTablesFromFile(lastPath) timer.scheduleFunction(UpdateContinuous, nil, timer.getTime() + 120) diff --git a/src/classes/spearhead_db.lua b/src/classes/spearhead_db.lua index 5462572..2c1b1e9 100644 --- a/src/classes/spearhead_db.lua +++ b/src/classes/spearhead_db.lua @@ -258,7 +258,7 @@ function Database.New(Logger) if env.mission.drawings and env.mission.drawings.layers then for _, layer in pairs(env.mission.drawings.layers) do if string.lower(layer.name) == "author" then - for key, layer_object in pairs(layer.objects) do + for _, layer_object in pairs(layer.objects) do 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 } @@ -339,14 +339,14 @@ function Database.New(Logger) end -- fill missions - for key, missionZone in pairs(self._tables.MissionZones) do + for _, missionZone in pairs(self._tables.MissionZones) do if DcsUtil.isZoneInZone(missionZone, stageZoneName) == true then table.insert(stageData.MissionZones, missionZone) end end -- fill random missions - for key, missionZone in pairs(self._tables.RandomMissionZones) do + for _, missionZone in pairs(self._tables.RandomMissionZones) do if DcsUtil.isZoneInZone(missionZone, stageZoneName) == true then table.insert(stageData.RandomMissionZones, missionZone) end @@ -620,9 +620,9 @@ function Database:loadBlueSamUnits() samData.buildingKilos = number if env.mission.drawings and env.mission.drawings.layers then - for i, layer in pairs(env.mission.drawings.layers) do + for _, layer in pairs(env.mission.drawings.layers) do if string.lower(layer.name) == "author" then - for key, layer_object in pairs(layer.objects) do + for _, layer_object in pairs(layer.objects) do local vec2 = { x = layer_object.mapX, y = layer_object.mapY } if triggerZone and Util.is2dPointInZone(vec2, triggerZone) then @@ -637,7 +637,7 @@ function Database:loadBlueSamUnits() end end end - else + else MissionEditorWarnings.Add("Buildable number for " .. blueSamZone .. " is invalid") end end @@ -670,13 +670,13 @@ function Database:LoadZoneData(missionZoneName) for _, groupName in pairs(groups) do if MizGroupsManager.IsGroupStatic(groupName) == true then local object = StaticObject.getByName(groupName) - + if object and object:getCoalition() == coalition.side.RED then table.insert(self._tables.MissionZoneData[missionZoneName].RedGroups, groupName) elseif object then table.insert(self._tables.MissionZoneData[missionZoneName].BlueGroups, groupName) end - + else local group = Group.getByName(groupName) if group and group:getCoalition() == coalition.side.RED then @@ -720,9 +720,9 @@ function Database:LoadZoneData(missionZoneName) ---Adds Briefings if env.mission.drawings and env.mission.drawings.layers then - for i, layer in pairs(env.mission.drawings.layers) do + for _, layer in pairs(env.mission.drawings.layers) do if string.lower(layer.name) == "author" then - for key, layer_object in pairs(layer.objects) do + for _, layer_object in pairs(layer.objects) do local vec2 = { x = layer_object.mapX, y = layer_object.mapY } if triggerZone and Util.is2dPointInZone(vec2, triggerZone) then @@ -776,9 +776,9 @@ function Database:loadFarpData() -- check briefings if env.mission.drawings and env.mission.drawings.layers then - for i, layer in pairs(env.mission.drawings.layers) do + for _, layer in pairs(env.mission.drawings.layers) do if string.lower(layer.name) == "author" then - for key, layer_object in pairs(layer.objects) do + for _, layer_object in pairs(layer.objects) do local vec2 = { x = layer_object.mapX, y = layer_object.mapY } if triggerZone and Util.is2dPointInZone(vec2, triggerZone) then @@ -796,8 +796,6 @@ function Database:loadFarpData() else MissionEditorWarnings.Add("Buildable number for " .. farpZone .. " is invalid.") end - - end end end diff --git a/src/classes/spearhead_events.lua b/src/classes/spearhead_events.lua index 92ec417..ab7f495 100644 --- a/src/classes/spearhead_events.lua +++ b/src/classes/spearhead_events.lua @@ -46,7 +46,7 @@ do ---@class OnStageNumberChangeCompleteListener ---@field OnStageNumberChangeComplete fun(self:OnStageNumberChangeCompleteListener, number:integer, laneIdentifier:string?) - + local OnStageNumberChangeCompleteListeners = {} ---@param listener OnStageNumberChangeCompleteListener SpearheadEvents.AddStageNumberChangeCompleteListener = function(listener) @@ -65,7 +65,7 @@ do end) for _, callable in pairs(OnStageNumberChangedListeners) do - local succ, err = pcall(function() + local _, err = pcall(function() callable:OnStageNumberChanged(newStageNumber, laneIdentifier) end) if err then @@ -74,14 +74,14 @@ do end for _, callable in pairs(OnStageNumberChangedHandlers) do - local succ, err = pcall(callable, newStageNumber, laneIdentifier) + local _, err = pcall(callable, newStageNumber, laneIdentifier) if err then logError(err) end end for _, callable in pairs(OnStageNumberChangeCompleteListeners) do - local succ, err = pcall(function() + local _, err = pcall(function() callable:OnStageNumberChangeComplete(newStageNumber, laneIdentifier) end) if err then @@ -112,7 +112,7 @@ do local triggerWeaponFired = function(unit, weapon, target) for _, callable in pairs(onWeaponFiredListeners) do - local succ, err = pcall(function() + local _, err = pcall(function() callable:OnWeaponFired(unit, weapon, target) end) @@ -121,7 +121,7 @@ do end end end - + local onLandEventListeners = {} ---Add an event listener to a specific unit @@ -186,7 +186,7 @@ do if groupName ~= nil then if OnGroupRTBListeners[groupName] then for _, callable in pairs(OnGroupRTBListeners[groupName]) do - local succ, err = pcall(function() + local _, err = pcall(function() callable:OnGroupRTB(groupName) end) if err then @@ -221,7 +221,7 @@ do if groupName ~= nil then if OnGroupRTBInTenListeners[groupName] then for _, callable in pairs(OnGroupRTBInTenListeners[groupName]) do - local succ, err = pcall(function() + local _, err = pcall(function() callable:OnGroupRTBInTen(groupName) end) if err then @@ -257,7 +257,7 @@ do if groupName ~= nil then if OnGroupOnStationListeners[groupName] then for _, callable in pairs(OnGroupOnStationListeners[groupName]) do - local succ, err = pcall(function() + local _, err = pcall(function() callable:OnGroupOnStation(groupName) end) if err then @@ -286,7 +286,7 @@ do if unit ~= nil then if playerEnterUnitListeners then for _, callable in pairs(playerEnterUnitListeners) do - local succ, err = pcall(function() + local _, err = pcall(function() callable:OnPlayerEntersUnit(unit) end) if err then @@ -299,7 +299,7 @@ do end do -- Ejection events - + local unitEjectListeners = {} SpearheadEvents.AddOnUnitEjectedListener = function(listener) if type(listener) ~= "table" then @@ -321,7 +321,7 @@ do local name = unit:getName() if onLandEventListeners[name] then for _, callable in pairs(onLandEventListeners[name]) do - local succ, err = pcall(function() + local _, err = pcall(function() callable:OnUnitLanded(unit, airbase) end) if err then @@ -341,10 +341,10 @@ do if object and object.getName then logDebug("Receiving death event from: " .. object:getName()) end - + if object and object.getName and OnUnitLostListeners[object:getName()] then for _, callable in pairs(OnUnitLostListeners[object:getName()]) do - local succ, err = pcall(function() + local _, err = pcall(function() callable:OnUnitLost(object) end) @@ -356,11 +356,11 @@ do end if event.id == world.event.S_EVENT_EJECTION then - + end if event.id == world.event.S_EVENT_SHOT then - + local shooter = event.initiator local weapon = event.weapon local target = event.target @@ -374,26 +374,26 @@ do local AI_GROUPS = {} - local function CheckAndTriggerSpawnAsync(unit, time) - - local function isPlayer(unit) - if unit == nil then return false, "unit is nil" end - if unit.getGroup == nil then return false, 'no get group function in unit object, most likely static' end - if Object.getCategory(unit) ~= Object.Category.UNIT then + local function CheckAndTriggerSpawnAsync(unit, _) + + local function isPlayer(checkUnit) + if checkUnit == nil then return false, "unit is nil" end + if checkUnit.getGroup == nil then return false, 'no get group function in unit object, most likely static' end + if Object.getCategory(checkUnit) ~= Object.Category.UNIT then return false, "object is not a unit" end - if unit:isExist() ~= true then return false, "unit does not exist" end - local group = unit:getGroup() + if checkUnit:isExist() ~= true then return false, "unit does not exist" end + local group = checkUnit:getGroup() if group ~= nil then if AI_GROUPS[group:getName()] == true then return false end local players = DcsUtil.getAllPlayerUnits() - local unitName = unit:getName() - for i, unit in pairs(players) do - if unit:getName() == unitName then + local unitName = checkUnit:getName() + for _, playerUnit in pairs(players) do + if playerUnit:getName() == unitName then return true end end @@ -403,7 +403,6 @@ do end if isPlayer(unit) == true then - local groupId = unit:getGroup():getID() SpearheadEvents.TriggerPlayerEntersUnit(unit) end diff --git a/src/classes/stageClasses/GlobalStageManager.lua b/src/classes/stageClasses/GlobalStageManager.lua index 658c9f3..7b08a85 100644 --- a/src/classes/stageClasses/GlobalStageManager.lua +++ b/src/classes/stageClasses/GlobalStageManager.lua @@ -2,7 +2,6 @@ local Events = require("classes.spearhead_events") local Util = require("classes.util.Util") local DcsUtil = require("classes.util.DcsUtil") local Logger = require("classes.util.Logger") -local MissionEditorWarnings = require("classes.util.MissionEditorWarnings") local PersistenceConfig = require("classes.configuration.PersistenceConfig") local ExtraStage = require("classes.stageClasses.Stages.ExtraStage") local PrimaryStage = require("classes.stageClasses.Stages.PrimaryStage") @@ -35,7 +34,6 @@ local singletonInstance = nil ---@param spawnManager SpawnManager ---@return GlobalStageManager function GlobalStageManager.new(database, stageConfig, logLevel, spawnManager) - if singletonInstance ~= nil then return singletonInstance end @@ -44,7 +42,7 @@ function GlobalStageManager.new(database, stageConfig, logLevel, spawnManager) logger:info("Using Stage Log Level: " .. logLevel) local self = setmetatable({}, GlobalStageManager) singletonInstance = self - + self.database = database self.stageConfig = stageConfig self._missionCommandsHelper = MissionCommandsHelper.getOrCreate() @@ -52,14 +50,15 @@ function GlobalStageManager.new(database, stageConfig, logLevel, spawnManager) self.logger = logger if stageConfig.isAutoStages ~= true then - logger:warn("Spearhead will not automatically progress stages due to the given settings. If you manually have implemented this, please ignore this message") + logger:warn( + "Spearhead will not automatically progress stages due to the given settings. If you manually have implemented this, please ignore this message") end Events.AddStageNumberChangedListener(self) for _, stageName in pairs(database:getStagezoneNames()) do logger:debug("Found stage zone with name: " .. stageName) - + local parseResult = self:ParseStageName(stageName) if parseResult.isValid == false then logger:warn("Stage zone with name " .. stageName .. " is not valid: " .. parseResult.invalidReason) @@ -81,12 +80,12 @@ function GlobalStageManager.new(database, stageConfig, logLevel, spawnManager) stage:AddStageCompleteListener(self) self._stageRepository:AddStage(stage) elseif parseResult.stageType == "WaitingStage" then - local waitingStage = WaitingStage.New(database, stageConfig, logger, initData, parseResult.waitingStageSeconds, spawnManager) + local waitingStage = WaitingStage.New(database, stageConfig, logger, initData, + parseResult.waitingStageSeconds, spawnManager) waitingStage:AddStageCompleteListener(self) self._stageRepository:AddStage(waitingStage) end end - end singletonInstance = self @@ -103,11 +102,11 @@ function GlobalStageManager:Start() local stageLanes = self._stageRepository:getAllStageLanes() for _, stageLane in pairs(stageLanes) do - local stageLaneIdentifier = stageLane:GetStageLaneIdentifier() local persistedStage = Persistence.GetActiveStage(stageLaneIdentifier) if persistedStage then - self.logger:info("Loaded persisted stage " .. persistedStage .. " for lane " .. (stageLaneIdentifier or "default")) + self.logger:info("Loaded persisted stage " .. + persistedStage .. " for lane " .. (stageLaneIdentifier or "default")) stageLane:SetActiveStageIndex(persistedStage) Events.PublishStageNumberChanged(persistedStage, stageLaneIdentifier) else @@ -139,17 +138,16 @@ end ---@param stageName string ---@return StageNameParseResult function GlobalStageManager:ParseStageName(stageName) - local split = Util.split_string(stageName, "_") if Util.tableLength(split) < 3 then - return { isValid = false, invalidReason = "Stage zone with name " .. stageName .. " does not have a order number or valid format" } + return { isValid = false, invalidReason = "Stage zone with name " .. + stageName .. " does not have a order number or valid format" } end local typePart = string.lower(split[1]) if typePart == "missionstage" then - local orderNumberString = string.lower(split[2]) ---@type StageType local stageType = "PrimaryStage" @@ -161,15 +159,16 @@ function GlobalStageManager:ParseStageName(stageName) local first = orderNumberString:sub(1, 1) if tonumber(first) == nil then -- first character is the lane identifier only if it's not a number stageLaneIdentifier = string.lower(first) - + orderNumberString = orderNumberString:sub(2) end local orderNumber = tonumber(orderNumberString) if orderNumber == nil then - return { isValid = false, invalidReason = "Stage zone with name " .. stageName .. " does not have a valid order number : " .. orderNumberString } + return { isValid = false, invalidReason = "Stage zone with name " .. + stageName .. " does not have a valid order number : " .. orderNumberString } end - + local stageDisplayName = split[3] ---@type StageNameParseResult local result = { @@ -182,18 +181,19 @@ function GlobalStageManager:ParseStageName(stageName) } return result elseif typePart == "waitingstage" then - local stageType = "WaitingStage" local orderNumberString = split[2] local orderNumber = tonumber(orderNumberString) if orderNumber == nil then - return { isValid = false, invalidReason = "Waiting Stage zone with name " .. stageName .. " does not have a valid order number : " .. orderNumberString } + return { isValid = false, invalidReason = "Waiting Stage zone with name " .. + stageName .. " does not have a valid order number : " .. orderNumberString } end local waitingSecondsString = split[3] local waitingSeconds = tonumber(waitingSecondsString) if waitingSeconds == nil then - return { isValid = false, invalidReason = "Waiting Stage zone with name " .. stageName .. " does not have a valid amount of seconds parameter : " .. waitingSecondsString } + return { isValid = false, invalidReason = "Waiting Stage zone with name " .. + stageName .. " does not have a valid amount of seconds parameter : " .. waitingSecondsString } end local stageDisplayName = "Waiting Stage " .. orderNumber @@ -209,9 +209,9 @@ function GlobalStageManager:ParseStageName(stageName) waitingStageSeconds = waitingSeconds } return result - end - return { isValid = false, invalidReason = "Stage zone with name " .. stageName .. " has an unrecognized type: " .. typePart } + return { isValid = false, invalidReason = "Stage zone with name " .. + stageName .. " has an unrecognized type: " .. typePart } end ---@param stage Stage @@ -223,7 +223,8 @@ function GlobalStageManager:OnStageComplete(stage) local stageLane = self._stageRepository:getStageLane(laneIdentifier) if not stageLane or not stageLane:IsCurrentStageIndexComplete() then - self.logger:debug("Stage lane " .. (laneIdentifier or "default") .. " is not complete for stage index " .. stageIndex) + self.logger:debug("Stage lane " .. + (laneIdentifier or "default") .. " is not complete for stage index " .. stageIndex) return end @@ -234,7 +235,7 @@ function GlobalStageManager:OnStageComplete(stage) stageLane:SetActiveStageIndex(nextStageIndex) if stageLane:IsDefaultStageLane() then - -- COMPLETION IN THE DEFAULT LANE + -- COMPLETION IN THE DEFAULT LANE -- 1. Check if any lane is at status "BetweenChapters" and the next chapter start is "next stage index" local allLanes = self._stageRepository:getAllStageLanes() @@ -242,7 +243,9 @@ function GlobalStageManager:OnStageComplete(stage) if lane:GetStageLaneIdentifier() ~= StageLane.DefaultLaneKey and lane:GetStageLaneState() == "BetweenChapters" then local nextChapterStart = lane:GetNextChapterStart() if nextChapterStart == nextStageIndex then - self.logger:debug("Lane " .. (lane:GetStageLaneIdentifier() or "default") .. " is at chapter start for next stage index " .. nextStageIndex) + self.logger:debug("Lane " .. + (lane:GetStageLaneIdentifier() or "default") .. + " is at chapter start for next stage index " .. nextStageIndex) Events.PublishStageNumberChanged(nextStageIndex, lane:GetStageLaneIdentifier()) lane:SetActiveStageIndex(nextStageIndex) end @@ -256,7 +259,6 @@ function GlobalStageManager:OnStageComplete(stage) if defaultStageLane and defaultStageLane:GetStageLaneState() == "BetweenChapters" then local nextChapterStart = defaultStageLane:GetNextChapterStart() if nextChapterStart == nextStageIndex then - -- 2. Check if all side lanes are at or beyond the next chapter starts local allLanes = self._stageRepository:getAllStageLanes() local allSideLanesReady = true @@ -265,15 +267,19 @@ function GlobalStageManager:OnStageComplete(stage) -- Check if the lane is at or beyond the next chapter starts when "InChapter" eq "Active" if lane:GetStageLaneState() == "InChapter" and lane:GetActiveStageIndex() < nextStageIndex then allSideLanesReady = false - self.logger:debug("Lane " .. (lane:GetStageLaneIdentifier() or "default") .. " is not ready for next stage index " .. nextStageIndex) + self.logger:debug("Lane " .. + (lane:GetStageLaneIdentifier() or "default") .. + " is not ready for next stage index " .. nextStageIndex) break - -- When in between chapters, check if the next chapter start is less than the next stage index, meaning there is still stages to be completed before the main lane can be activated again + -- When in between chapters, check if the next chapter start is less than the next stage index, meaning there is still stages to be completed before the main lane can be activated again elseif lane:GetStageLaneState() == "BetweenChapters" then local nextChapter = lane:GetNextChapterStart() if nextChapter and nextChapter < nextStageIndex then allSideLanesReady = false - self.logger:debug("Lane " .. (lane:GetStageLaneIdentifier() or "default") .. " is not ready for next stage index " .. nextStageIndex) + self.logger:debug("Lane " .. + (lane:GetStageLaneIdentifier() or "default") .. + " is not ready for next stage index " .. nextStageIndex) break end end @@ -281,13 +287,14 @@ function GlobalStageManager:OnStageComplete(stage) end if allSideLanesReady then - self.logger:debug("All side lanes are ready for next stage index " .. nextStageIndex .. ", activating default lane") + self.logger:debug("All side lanes are ready for next stage index " .. + nextStageIndex .. ", activating default lane") Events.PublishStageNumberChanged(nextStageIndex, nil) defaultStageLane:SetActiveStageIndex(nextStageIndex) else - self.logger:debug("Not all side lanes are ready for next stage index " .. nextStageIndex .. ", default lane will not be activated") + self.logger:debug("Not all side lanes are ready for next stage index " .. + nextStageIndex .. ", default lane will not be activated") end - end end end @@ -308,7 +315,6 @@ end ---@public function GlobalStageManager:OnStageNumberChanged(stageNumber, stageLaneIdentifier) - -- only react on "main" lane changes, ignore other lanes for now if stageLaneIdentifier ~= nil then return end @@ -321,7 +327,6 @@ function GlobalStageManager:OnStageNumberChangeComplete(stageNumber, stageLaneId if stageLaneIdentifier ~= nil then return end self.logger:debug("Stage number change complete to: " .. tostring(stageNumber)) - local groups = {} for _, player in pairs(DcsUtil.getAllPlayerUnits()) do @@ -349,80 +354,81 @@ function GlobalStageManager:UpdateDrawings(stageNumber, stageLaneIdentifier) if laneIdentifier == stageLaneIdentifier then if stageNumber >= startStage and stageNumber < stopStage then - self.logger:debug("Drawing " .. drawing:GetName() .. " is active for stage number: " .. tostring(stageNumber)) + self.logger:debug("Drawing " .. + drawing:GetName() .. " is active for stage number: " .. tostring(stageNumber)) drawing:Draw() else - self.logger:debug("Drawing " .. drawing:GetName() .. " is not active for stage number: " .. tostring(stageNumber)) + self.logger:debug("Drawing " .. + drawing:GetName() .. " is not active for stage number: " .. tostring(stageNumber)) drawing:Remove() end end end end - function GlobalStageManager:PrintMermaidStage() local lanes = self._stageRepository:getAllStageLanes() - + local nodes = {} local edges = {} local stageIndicesByLane = {} -- Track all stage indices per lane local mainLaneId = "default" - + -- Color palette for lanes (26 vibrant colors optimized for dark mode) local laneColors = { - "#FF6B6B", -- 1: Red - "#4ECDC4", -- 2: Teal - "#45B7D1", -- 3: Blue - "#FFA502", -- 4: Orange - "#95E1D3", -- 5: Mint - "#F38181", -- 6: Coral - "#AA96DA", -- 7: Purple - "#FCBAD3", -- 8: Pink - "#A8E6CF", -- 9: Light green - "#FFD3B6", -- 10: Peach - "#FFAAA5", -- 11: Light red - "#FF8B94", -- 12: Rose - "#FFEAA7", -- 13: Butter - "#DFE6E9", -- 14: Gray - "#00B894", -- 15: Emerald - "#0984E3", -- 16: Cobalt - "#6C5CE7", -- 17: Indigo - "#A29BFE", -- 18: Lavender - "#FD79A8", -- 19: Magenta - "#FDCB6E", -- 20: Gold - "#6C757D", -- 21: Slate - "#20C997", -- 22: Seafoam - "#E74C3C", -- 23: Scarlet - "#3498DB", -- 24: Dodger blue - "#9B59B6", -- 25: Amethyst - "#1ABC9C", -- 26: Turquoise + "#FF6B6B", -- 1: Red + "#4ECDC4", -- 2: Teal + "#45B7D1", -- 3: Blue + "#FFA502", -- 4: Orange + "#95E1D3", -- 5: Mint + "#F38181", -- 6: Coral + "#AA96DA", -- 7: Purple + "#FCBAD3", -- 8: Pink + "#A8E6CF", -- 9: Light green + "#FFD3B6", -- 10: Peach + "#FFAAA5", -- 11: Light red + "#FF8B94", -- 12: Rose + "#FFEAA7", -- 13: Butter + "#DFE6E9", -- 14: Gray + "#00B894", -- 15: Emerald + "#0984E3", -- 16: Cobalt + "#6C5CE7", -- 17: Indigo + "#A29BFE", -- 18: Lavender + "#FD79A8", -- 19: Magenta + "#FDCB6E", -- 20: Gold + "#6C757D", -- 21: Slate + "#20C997", -- 22: Seafoam + "#E74C3C", -- 23: Scarlet + "#3498DB", -- 24: Dodger blue + "#9B59B6", -- 25: Amethyst + "#1ABC9C", -- 26: Turquoise } local laneColorMap = {} -- Map lane ID to color local colorIndex = 1 - + -- Build nodes and collect all stage indices per lane for _, lane in ipairs(lanes) do local laneId = lane:GetStageLaneIdentifier() or "default" local stageIndices = lane:GetAllStageIndices() stageIndicesByLane[laneId] = stageIndices - + -- Assign color to this lane laneColorMap[laneId] = laneColors[colorIndex] colorIndex = colorIndex + 1 if colorIndex > #laneColors then colorIndex = 1 end - + -- Create nodes for each stage index in this lane for _, stageIndex in ipairs(stageIndices) do local stages = lane:GetStagesAtIndex(stageIndex) - + if stages then for _, stage in ipairs(stages) do local nodeId = laneId .. "_" .. stageIndex local stageType = stage:GetStageType() local stageName = stage.stageName or stage.zoneName - + -- Generate bracket label: [1], [2] for default, [w1], [e2] for other lanes local bracketLabel if laneId == "default" then @@ -430,10 +436,10 @@ function GlobalStageManager:PrintMermaidStage() else bracketLabel = "[" .. laneId .. stageIndex .. "]" end - + -- Combined label: [bracket] Name local label = bracketLabel .. " " .. stageName - + -- Different node shapes for different stage types local nodeShape = "[" local nodeEnd = "]" @@ -444,14 +450,14 @@ function GlobalStageManager:PrintMermaidStage() nodeShape = "[[" nodeEnd = "]]" end - - nodes[nodeId] = string.format(' %s%s"%s"%s', + + nodes[nodeId] = string.format(' %s%s"%s"%s', nodeId, nodeShape, label, nodeEnd) end end end end - + -- Add edges for sequential stages within the same lane for laneId, stageIndices in pairs(stageIndicesByLane) do for i = 1, #stageIndices - 1 do @@ -459,7 +465,7 @@ function GlobalStageManager:PrintMermaidStage() local toIdx = stageIndices[i + 1] local fromNodeId = laneId .. "_" .. fromIdx local toNodeId = laneId .. "_" .. toIdx - + -- Check if this is a chapter boundary (gap) local isChapter = false for _, lane in ipairs(lanes) do @@ -469,12 +475,12 @@ function GlobalStageManager:PrintMermaidStage() break end end - + local label = isChapter and "|chapter|" or "" table.insert(edges, string.format(' %s -->%s %s', fromNodeId, label, toNodeId)) end end - + -- Get main lane reference local mainStageLane = nil for _, lane in ipairs(lanes) do @@ -483,7 +489,7 @@ function GlobalStageManager:PrintMermaidStage() break end end - + -- Add dependencies from DEFAULT lane to SIDE lanes at chapter starts -- Side lanes activate when main completes the stage BEFORE the chapter start if mainStageLane then @@ -491,7 +497,7 @@ function GlobalStageManager:PrintMermaidStage() if lane:IsDefaultStageLane() == false then local sideId = lane:GetStageLaneIdentifier() local sideIndices = stageIndicesByLane[sideId] - + -- For each stage in the side lane for _, stageIdx in ipairs(sideIndices) do -- Check if this is a chapter start in the side lane @@ -506,16 +512,16 @@ function GlobalStageManager:PrintMermaidStage() end end end - + -- Add dependencies from SIDE lanes gating the MAIN lane at chapter boundaries -- Main cannot advance to the next chapter until ALL side lanes are at or above that chapter index if mainStageLane then local mainIndices = stageIndicesByLane[mainLaneId] - + -- For each chapter start in main lane (skip first one) for i = 2, #mainIndices do local nextIdx = mainIndices[i] - + -- Check if nextIdx is a chapter start (there's a gap before it) if mainStageLane:IsChapterStart(nextIdx) then -- Before main can progress to nextIdx, all side lanes must be at >= nextIdx @@ -523,23 +529,23 @@ function GlobalStageManager:PrintMermaidStage() if lane:IsDefaultStageLane() == false then local sideId = lane:GetStageLaneIdentifier() local sideIndices = stageIndicesByLane[sideId] - + -- Find the appropriate gate node for this side lane -- Use first stage >= nextIdx if it exists, otherwise use the highest stage local gateStageIdx = nil - + for _, idx in ipairs(sideIndices) do if idx >= nextIdx then gateStageIdx = idx break end end - + -- If no stage >= nextIdx, use the highest stage in this lane if gateStageIdx == nil and #sideIndices > 0 then gateStageIdx = sideIndices[#sideIndices] end - + if gateStageIdx then local fromNodeId = sideId .. "_" .. gateStageIdx local toNodeId = mainLaneId .. "_" .. nextIdx @@ -550,25 +556,26 @@ function GlobalStageManager:PrintMermaidStage() end end end - + -- Build complete Mermaid diagram - local diagramLines = {"graph TD"} - + local diagramLines = { "graph TD" } + -- Add class definitions for each lane with colors and contrasting text for laneId, color in pairs(laneColorMap) do - table.insert(diagramLines, string.format(' classDef lane_%s fill:%s,stroke:#333,stroke-width:2px,color:#000', laneId, color)) + table.insert(diagramLines, + string.format(' classDef lane_%s fill:%s,stroke:#333,stroke-width:2px,color:#000', laneId, color)) end - + -- Add nodes for _, nodeStr in pairs(nodes) do table.insert(diagramLines, nodeStr) end - + -- Add edges for _, edgeStr in pairs(edges) do table.insert(diagramLines, edgeStr) end - + -- Apply classes to nodes for nodeId in pairs(nodes) do local laneId = nodeId:match("(.+)_[0-9]+$") @@ -576,9 +583,10 @@ function GlobalStageManager:PrintMermaidStage() table.insert(diagramLines, string.format(' class %s lane_%s', nodeId, laneId)) end end - + -- Print as single multi-line message - local diagram = "========== STAGE FLOW DIAGRAM ==========\n" .. table.concat(diagramLines, "\n") .. "\n========== END DIAGRAM ==========" + local diagram = "========== STAGE FLOW DIAGRAM ==========\n" .. + table.concat(diagramLines, "\n") .. "\n========== END DIAGRAM ==========" self.logger:info(diagram) end @@ -586,10 +594,10 @@ end ---@param stageNumber number ---@param stageLaneIdentifier string? nil for default lan ---@return boolean | nil -GlobalStageManager.isStageComplete = function (stageNumber, stageLaneIdentifier) - +GlobalStageManager.isStageComplete = function(stageNumber, stageLaneIdentifier) if singletonInstance == nil then - Logger.new("StageManager", "INFO"):warn("GlobalStageManager.isStageComplete called before GlobalStageManager was initialized. Returning nil") + Logger.new("StageManager", "INFO"):warn( + "GlobalStageManager.isStageComplete called before GlobalStageManager was initialized. Returning nil") return nil end diff --git a/src/classes/stageClasses/Groups/SpearheadGroup.lua b/src/classes/stageClasses/Groups/SpearheadGroup.lua index 0a22e04..c5f8d41 100644 --- a/src/classes/stageClasses/Groups/SpearheadGroup.lua +++ b/src/classes/stageClasses/Groups/SpearheadGroup.lua @@ -41,7 +41,7 @@ end function SpearheadGroup:SpawnCorpsesOnly() if self._isSpawned == true then return end - + self._spawnManager:SpawnCorpsesOnly(self._groupName) self._isSpawned = true @@ -97,7 +97,7 @@ function SpearheadGroup:GetObjects() local result = {} if self._isStatic == true then local staticObject = StaticObject.getByName(self._groupName) - if staticObject then + if staticObject then table.insert(result, staticObject) end else @@ -105,7 +105,7 @@ function SpearheadGroup:GetObjects() if not group then return {} end for _, unit in pairs(group:getUnits()) do table.insert(result, unit) - end + end end return result end @@ -123,7 +123,7 @@ function SpearheadGroup:GetAsUnits() if not group then return {} end for _, unit in pairs(group:getUnits()) do table.insert(result, unit) - end + end return result end @@ -133,7 +133,7 @@ function SpearheadGroup:GetAllUnitPositions() local result = {} if self._isStatic == true then local staticObject = StaticObject.getByName(self._groupName) - if staticObject then + if staticObject then table.insert(result, staticObject:getPoint()) end else @@ -141,7 +141,7 @@ function SpearheadGroup:GetAllUnitPositions() if not group then return {} end for _, unit in pairs(group:getUnits()) do table.insert(result, unit:getPoint()) - end + end end return result end diff --git a/src/classes/stageClasses/SpecialZones/BlueSam.lua b/src/classes/stageClasses/SpecialZones/BlueSam.lua index 1723fec..5e19b78 100644 --- a/src/classes/stageClasses/SpecialZones/BlueSam.lua +++ b/src/classes/stageClasses/SpecialZones/BlueSam.lua @@ -50,16 +50,10 @@ function BlueSam.New(database, logger, zoneName, spawnManager) ---@type table local redUnitsPos = {} - - local buildable = false - if self._buildableCrateKilos and self._buildableCrateKilos > 0 then - buildable = true - end - for _, groupName in pairs(blueSamData.groups) do local spearheadGroup = SpearheadGroup.New(groupName, spawnManager, true) if spearheadGroup then - + if spearheadGroup:GetCoalition() == 2 or spearheadGroup:GetCoalition() == 0 then table.insert(self._blueGroups, spearheadGroup) end @@ -78,7 +72,7 @@ function BlueSam.New(database, logger, zoneName, spawnManager) --Cleanup units local cleanup_distance = 5 - for blueUnitName, blueUnitPos in pairs(blueUnitsPos) do + for _, blueUnitPos in pairs(blueUnitsPos) do for redUnitName, redUnitPos in pairs(redUnitsPos) do local distance = Util.VectorDistance3d(blueUnitPos, redUnitPos) if distance <= cleanup_distance then @@ -140,7 +134,9 @@ end function BlueSam:SpawnGroups() for unitName, needsCleanup in pairs(self._cleanupUnits) do - DcsUtil.DestroyUnit(unitName) + if needsCleanup then + DcsUtil.DestroyUnit(unitName) + end end for _, group in pairs(self._blueGroups) do diff --git a/src/classes/stageClasses/SpecialZones/FarpZone.lua b/src/classes/stageClasses/SpecialZones/FarpZone.lua index 74b329d..b888fd5 100644 --- a/src/classes/stageClasses/SpecialZones/FarpZone.lua +++ b/src/classes/stageClasses/SpecialZones/FarpZone.lua @@ -42,11 +42,11 @@ function FarpZone.New(database, logger, zoneName, spawnManager) self._groups = {} self._padNames = {} self._supplyHubs = {} - + if farpData then self._padNames = farpData.padNames - + for _, supplyHubName in pairs(farpData.supplyHubNames) do local supplyHub = SupplyHub.new(database, logger, supplyHubName) if supplyHub then @@ -55,7 +55,7 @@ function FarpZone.New(database, logger, zoneName, spawnManager) end - for _, groupName in pairs(farpData.groups) do + for _, groupName in pairs(farpData.groups) do local group = SpearheadGroup.New(groupName, spawnManager, true) table.insert(self._groups, group) group:Destroy() diff --git a/src/classes/stageClasses/SpecialZones/StageBase.lua b/src/classes/stageClasses/SpecialZones/StageBase.lua index 552b98f..c738f43 100644 --- a/src/classes/stageClasses/SpecialZones/StageBase.lua +++ b/src/classes/stageClasses/SpecialZones/StageBase.lua @@ -90,7 +90,7 @@ function StageBase.New(databaseManager, logger, airbaseName, spawnManager) local cleanup_distance = 5 - for blueUnitName, blueUnitPos in pairs(blueUnitsPos) do + for _, blueUnitPos in pairs(blueUnitsPos) do for redUnitName, redUnitPos in pairs(redUnitsPos) do local distance = Util.VectorDistance3d(blueUnitPos, redUnitPos) if distance <= cleanup_distance then @@ -172,7 +172,7 @@ function StageBase:ActivateBlueStage() else self:FinaliseBlueStage() end - + end function StageBase:FinaliseBlueStage() diff --git a/src/classes/stageClasses/SpecialZones/SupplyHub.lua b/src/classes/stageClasses/SpecialZones/SupplyHub.lua index c05aba5..b9d49dd 100644 --- a/src/classes/stageClasses/SpecialZones/SupplyHub.lua +++ b/src/classes/stageClasses/SpecialZones/SupplyHub.lua @@ -42,7 +42,7 @@ function SupplyHub.new(database, logger, zoneName) end self._zone = DcsUtil.getZoneByName(zoneName) - + self._supplyUnitsTracker = SupplyUnitsTracker.getOrCreate() self._inZone = {} self._missionCommandsHelper = MissionCommandsHelper.getOrCreate() diff --git a/src/classes/stageClasses/SpecialZones/abstract/BuildableZone.lua b/src/classes/stageClasses/SpecialZones/abstract/BuildableZone.lua index 38fcada..fe1296f 100644 --- a/src/classes/stageClasses/SpecialZones/abstract/BuildableZone.lua +++ b/src/classes/stageClasses/SpecialZones/abstract/BuildableZone.lua @@ -50,7 +50,7 @@ function BuildableZone:New(targetZone, kilosRequired, crateType, buildableGroup if params.unpackedKilos >= params.kilos or spawned == false then return end - + return time + 0.5 end @@ -76,8 +76,6 @@ function BuildableZone:New(targetZone, kilosRequired, crateType, buildableGroup self._buildableMission = nil end - - if self._buildableMission == nil then self._buildableLogger:debug("No buildable mission for zone: " .. targetZone.name) end @@ -99,23 +97,11 @@ function BuildableZone:OnBuildingComplete() end ---@field unpackedItems number ---@field unpackedKilos number ----@param mission BuildableMission? +---@param _ BuildableMission? ---@param kilos number -function BuildableZone:OnCrateDroppedOff(mission, kilos) +function BuildableZone:OnCrateDroppedOff(_, kilos) self._buildableLogger:debug("Crate dropped off in zone: " .. self._targetZone.name) - local timeToUnpack = (kilos / 500) * 15 - - ---@type UnpackCrateParam - local params = { - self = self, - groupsPerKilo = self._groupsPerKilo, - unpackedItems = 0, - kilosPerSecond = kilos/timeToUnpack, - unpackedKilos = 0, - kilos = kilos - } - ---@param params UnpackCrateParam ---@param time number local startUnpackingCrate = function(params, time) @@ -132,10 +118,21 @@ function BuildableZone:OnCrateDroppedOff(mission, kilos) params.self:FinaliseCrate(params.kilos) return end - + return time + 2 end + local timeToUnpack = (kilos / 500) * 15 + ---@type UnpackCrateParam + local params = { + self = self, + groupsPerKilo = self._groupsPerKilo, + unpackedItems = 0, + kilosPerSecond = kilos/timeToUnpack, + unpackedKilos = 0, + kilos = kilos + } + timer.scheduleFunction(startUnpackingCrate, params, timer.getTime() + 2) end @@ -190,7 +187,7 @@ function BuildableZone:SpawnAmount(amount) return nil end - for i = 1, amount do + for _ = 1, amount do local spawned = spawnOne() if spawned ~= true then self._buildableLogger:debug("No more groups to spawn in zone: " .. self._targetZone.name) diff --git a/src/classes/stageClasses/StageRepository.lua b/src/classes/stageClasses/StageRepository.lua index 31f8840..a66ab5e 100644 --- a/src/classes/stageClasses/StageRepository.lua +++ b/src/classes/stageClasses/StageRepository.lua @@ -49,7 +49,6 @@ end function StageRepository:AddStage(stage) local stageLaneIdentifier = stage:GetStageLaneIdentifier() or StageLane.DefaultLaneKey - if self.StageLanes[tostring(stageLaneIdentifier)] == nil then self.StageLanes[tostring(stageLaneIdentifier)] = StageLane.New(stageLaneIdentifier) end diff --git a/src/classes/stageClasses/Stages/BaseStage/Stage.lua b/src/classes/stageClasses/Stages/BaseStage/Stage.lua index 69d2f4f..21bd59c 100644 --- a/src/classes/stageClasses/Stages/BaseStage/Stage.lua +++ b/src/classes/stageClasses/Stages/BaseStage/Stage.lua @@ -105,7 +105,7 @@ function Stage:superNew(database, stageConfig, logger, initData, stageType, miss end self.stageName = initData.stageDisplayName self._stageType = stageType - + self.OnPostStageComplete = nil self.OnPostBlueActivated = nil @@ -160,25 +160,25 @@ function Stage:superNew(database, stageConfig, logger, initData, stageType, miss self._logger:info("Initiating new Stage with name: " .. self.zoneName) ---comment - ---@param self Stage + ---@param selfA Stage ---@param time number? - self.CheckContinuousAsync = function (self, time) - - self:CheckAndUpdateSelf() - if self:IsComplete() == true then - self:NotifyComplete() + self.CheckContinuousAsync = function (selfA, time) + + selfA:CheckAndUpdateSelf() + if selfA:IsComplete() == true then + selfA:NotifyComplete() return nil end return time + 20 end - + do -- load tables local missionZones = database:getMissionsForStage(self.zoneName) self._logger:debug("Found " .. Util.tableLength(missionZones) .. " mission zones for stage: " .. self.zoneName) for _, missionZone in pairs(missionZones) do - + local mission = ZoneMission.new(missionZone, self._missionPriority, database, logger, self, spawnManager) if mission then self._db.missionsByCode[mission.code] = mission @@ -233,7 +233,7 @@ function Stage:superNew(database, stageConfig, logger, initData, stageType, miss table.insert(self._db.missions, mission) end end - else + else self._logger:info("Using persisted random mission with name: " .. missionName .. " and zone: " .. missionZonePicked) for _, mission in pairs(missions) do if string.lower(mission.zoneName) == string.lower(missionZonePicked) then @@ -284,14 +284,14 @@ end function Stage:IsComplete() if self._currentStageState >= StageState.Blue then return true end - for i, mission in pairs(self._db.sams) do + for _, mission in pairs(self._db.sams) do local state = mission:getState() if state == "ACTIVE" or state == "NEW" or state =="WAITING" then return false end end - for i, mission in pairs(self._db.missions) do + for _, mission in pairs(self._db.missions) do local state = mission:getState() if state == "ACTIVE" or state == "NEW" then return false @@ -370,9 +370,9 @@ function Stage:CheckAndUpdateSelf() local availableMissionsCount = Util.tableLength(getAvailableMissions()) local activeCount = getActiveMissionsCount() if activeCount < max and availableMissionsCount > 0 then - for i = activeCount+1, max do + for _ = activeCount+1, max do if availableMissionsCount == 0 then - i = max+1 --exits this loop + break else local mission = Util.randomFromList(getAvailableMissions()) --[[@as Mission]] if mission then @@ -426,7 +426,7 @@ function Stage:PreActivate() end self._currentStageState = StageState.PreActivated - for key, mission in pairs(self._db.sams) do + for _, mission in pairs(self._db.sams) do if mission then mission:SpawnInactive() end @@ -473,7 +473,7 @@ function Stage:MarkStage() drawing.colorString = DrawingHelper.ColorTableToColorString(Stage.StageColors.INVISIBLE) drawing.style = "no line" end - + return drawing end) self._customDrawing:Draw() @@ -585,12 +585,12 @@ function Stage:OnStageNumberChanged(number, stageLaneIdentifier) if needsBlueActivation() == true then self:ActivateBlueStage() end - + end ---@param self Stage ----@param mission Mission -Stage.OnMissionComplete = function(self, mission) +---@param _ Mission +Stage.OnMissionComplete = function(self, _) self:CheckAndUpdateSelf() end @@ -645,7 +645,7 @@ function Stage:GetStageStats() end end - for _, mission in pairs(self._db.sams) do + for _, _ in pairs(self._db.sams) do dead = dead + 1 end @@ -673,13 +673,13 @@ function Stage:ActivateBlueStage() miscGroup:Spawn() end - ---@param self Stage - local ActivateBlueAsync = function(self) + ---@param selfA Stage + local ActivateBlueAsync = function(selfA) pcall(function() - self:MarkStage() + selfA:MarkStage() end) - self:ActivateBlueGroups() + selfA:ActivateBlueGroups() return nil end diff --git a/src/classes/stageClasses/Stages/ExtraStage.lua b/src/classes/stageClasses/Stages/ExtraStage.lua index 48b56c8..d8dc033 100644 --- a/src/classes/stageClasses/Stages/ExtraStage.lua +++ b/src/classes/stageClasses/Stages/ExtraStage.lua @@ -23,10 +23,9 @@ function ExtraStage.New(database, stageConfig, logger, initData, spawnManager) self:superNew(database, stageConfig, logger, initData, "ExtraStage", "secondary", spawnManager) self.OnPostBlueActivated = function (selfStage) - selfStage:MarkStage() end - + self.OnPostStageComplete = function (selfStage) selfStage:ActivateBlueStage() end @@ -48,7 +47,6 @@ function ExtraStage:OnStageNumberChanged(number, stageLaneIdentifier) return end - local previousActive = self._activeStage self._activeStage = number if self.stageNumber - self._activeStage == self._stageConfig.AmountPreactivateStage then diff --git a/src/classes/stageClasses/Stages/WaitingStage.lua b/src/classes/stageClasses/Stages/WaitingStage.lua index a803a8a..4b722b6 100644 --- a/src/classes/stageClasses/Stages/WaitingStage.lua +++ b/src/classes/stageClasses/Stages/WaitingStage.lua @@ -25,7 +25,7 @@ function WaitingStage.New(database, stageConfig, logger, initData, waitingSecond self._startTime = nil self.CheckContinuousAsync = function (selfA, time) - + if selfA:IsComplete() == true then selfA:NotifyComplete() return nil @@ -47,7 +47,7 @@ function WaitingStage:ActivateStage() timer.scheduleFunction(self.CheckContinuousAsync, self, self._startTime + self._waitTimeSeconds) end -function WaitingStage:IsComplete() +function WaitingStage:IsComplete() if timer.getTime() > (self._startTime + self._waitTimeSeconds) then return true end return false end @@ -56,12 +56,12 @@ function WaitingStage:OnStageNumberChanged() self._logger:debug("Waiting Stage OnStageNumberChanged override") end -function WaitingStage:MarkStage(stageColor) +function WaitingStage:MarkStage(_) self._logger:debug("Waiting Stage MarkStage override") end function WaitingStage:GetExpectedTime() - return self._startTime + self._waitTimeSeconds + return self._startTime + self._waitTimeSeconds end return WaitingStage diff --git a/src/classes/stageClasses/drawings/helper/DrawingHelper.lua b/src/classes/stageClasses/drawings/helper/DrawingHelper.lua index 3911546..aa90234 100644 --- a/src/classes/stageClasses/drawings/helper/DrawingHelper.lua +++ b/src/classes/stageClasses/drawings/helper/DrawingHelper.lua @@ -77,7 +77,7 @@ local function MarkupToAll(shapeID, drawID, points, fillColor, lineColor, lineS end trigger.action.setMarkupColor(drawID, lineColor) trigger.action.setMarkupTypeLine(drawID, lineStyle) - + end ---@private @@ -200,7 +200,7 @@ function DrawingHelper.DrawLine(object) ---@type Array local points = {} - local ids = {} + local ids = {} for _, point in ipairs(object.points) do table.insert(points, { x = object.mapX + point.x, y = 0, z = object.mapY + point.y } ) @@ -264,7 +264,7 @@ function DrawingHelper.ColorTableToColorString(rgba) logger:warn("ColorTableToColorString called with invalid rgba table, returning default color string '0x00000000'") return "0x00000000" end - + local r = string.format("%02X", math.floor(rgba[1] * 255)) local g = string.format("%02X", math.floor(rgba[2] * 255)) local b = string.format("%02X", math.floor(rgba[3] * 255)) diff --git a/src/classes/stageClasses/helpers/BattleManager.lua b/src/classes/stageClasses/helpers/BattleManager.lua index 03d22de..951767a 100644 --- a/src/classes/stageClasses/helpers/BattleManager.lua +++ b/src/classes/stageClasses/helpers/BattleManager.lua @@ -27,8 +27,8 @@ function BattleManager.New(redGroups, blueGroups, name, logLevel) self._redGroups = redGroups self._blueGroups = blueGroups - self._logger:debug("BattleManager created with name: " .. self._name - .. ", red groups: " .. #self._redGroups + self._logger:debug("BattleManager created with name: " .. self._name + .. ", red groups: " .. #self._redGroups .. ", blue groups: " .. #self._blueGroups) return self @@ -131,7 +131,7 @@ function BattleManager:LetUnitsShoot(groups, targetGroups) expendQtyEnabled = true } } - + local controller = unit:getController() if controller then controller:setTask(shootTask) @@ -141,7 +141,7 @@ function BattleManager:LetUnitsShoot(groups, targetGroups) end end end -end +end ---@param unit Unit ---@return number @@ -191,7 +191,7 @@ function BattleManager:IsUnitApplicable(unit) end return true - + end ---@private @@ -231,7 +231,7 @@ end ---@param groupHulls Array> ---@return Vec2? function BattleManager:GetRandomPoint(origin, groupHulls) - + local hull = Util.randomFromList(groupHulls) --[[@as Array]] if not hull then return nil end local shootPoints = Util.GetTangentHullPointsFromOrigin(hull, origin) diff --git a/src/classes/stageClasses/helpers/SupplyLoadConfig.lua b/src/classes/stageClasses/helpers/SupplyLoadConfig.lua index 90b42db..dd0d528 100644 --- a/src/classes/stageClasses/helpers/SupplyLoadConfig.lua +++ b/src/classes/stageClasses/helpers/SupplyLoadConfig.lua @@ -29,7 +29,7 @@ local SupplyLoadConfig = { { centerAngle = 270, angleWidth = 60, minRadius = 15, maxRadius = 50, spacing = 5 }, { centerAngle = 90, angleWidth = 60, minRadius = 15, maxRadius = 50, spacing = 5 }, } - }, + }, ["UH-1H"] = { maxInternalLoad = 2000, dropZones = { diff --git a/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua b/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua index eee35c8..3256f8d 100644 --- a/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua +++ b/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua @@ -236,7 +236,7 @@ function SupplyUnitsTracker:CheckUnitsInZones() end) end end - + else if self._unitInSupplyHub[tostring(unit:getID())] == true then self._unitInSupplyHub[tostring(unit:getID())] = false @@ -290,11 +290,11 @@ local cargoCount = 0 ---@param crateType CrateType ---@param missionCommandsHelper MissionCommandsHelper function SupplyUnitsTracker:UnloadRequested(unitID, crateType, missionCommandsHelper) - + self._logger:debug("Unload requested for unit: " .. unitID .. " crateType: " .. crateType) local unit = DcsUtil.GetPlayerUnitByID(unitID) - if unit == nil or unit:isExist() == false then + if unit == nil or unit:isExist() == false then self._logger:warn("Unload requested for non-existent unit: " .. unitID) return end @@ -303,7 +303,7 @@ function SupplyUnitsTracker:UnloadRequested(unitID, crateType, missionCommandsHe self._logger:warn("Unload requested for unit with no group: " .. unit:getName()) return end - + local cargoConfig = SupplyConfigHelper.getSupplyConfig(crateType) if cargoConfig == nil then @@ -360,11 +360,11 @@ function SupplyUnitsTracker:UnitRequestCrateLoading(groupID, crateType, missionC end local unit = group:getUnit(1) - + if unit == nil then return end if unit:isExist() == false then return end - + if unit:inAir() == true then trigger.action.outTextForUnit(unit:getID(), "Land first before crates can be loaded", 10) return @@ -381,7 +381,7 @@ function SupplyUnitsTracker:UnitRequestCrateLoading(groupID, crateType, missionC ---@param params LoadCargoParams local LoadCrateTask = function(params) - + local loaded = params.self:TryLoadCrateInUnit(params.unit, params.crateType, params.commandHelper) if loaded ~= false then trigger.action.outTextForUnit(unit:getID(), "Loaded crate :" .. params.crateType, 10) @@ -408,7 +408,7 @@ end ---@param commandHelper MissionCommandsHelper ---@return boolean function SupplyUnitsTracker:TryLoadCrateInUnit(unit, crateType, commandHelper) - + local crateConfigA = SupplyConfigHelper.getSupplyConfig(crateType) if crateConfigA == nil then trigger.action.outTextForUnit(unit:getID(), "Invalid crate type: " .. crateType, 5) @@ -442,7 +442,7 @@ function SupplyUnitsTracker:TryLoadCrateInUnit(unit, crateType, commandHelper) if group == nil then return false end local groupID = group:getID() commandHelper:updateCommandsForGroup(groupID) - + return true end @@ -460,7 +460,7 @@ function SupplyUnitsTracker:UnitRequestCrateSpawn(groupID, crateType) return end - + end end @@ -482,11 +482,11 @@ function SupplyUnitsTracker:GetBoundingBoxes(foundObject) if desc == nil or desc.box == nil then return nil end - + local objPos = foundObject:getPoint() local box = desc.box local heading = 0 - + -- Try to get object heading from position vector's forward direction -- This works for units and other objects that support getPosition pcall(function() @@ -495,13 +495,13 @@ function SupplyUnitsTracker:GetBoundingBoxes(foundObject) heading = math.atan2(objPosition.x.z, objPosition.x.x) end end) - + -- For rotated objects, we need to rotate the bounding box local minX = box.min.x local maxX = box.max.x local minZ = box.min.z local maxZ = box.max.z - + -- If object has significant rotation, apply rotation to bbox corners if math.abs(heading) > 0.1 then -- Get all 4 corners of bbox in local space @@ -511,11 +511,11 @@ function SupplyUnitsTracker:GetBoundingBoxes(foundObject) {maxX, minZ}, {maxX, maxZ} } - + -- Rotate corners and find new min/max minX, maxX = math.huge, -math.huge minZ, maxZ = math.huge, -math.huge - + for _, corner in ipairs(corners) do local rotX = corner[1] * math.cos(heading) - corner[2] * math.sin(heading) local rotZ = corner[1] * math.sin(heading) + corner[2] * math.cos(heading) @@ -525,7 +525,7 @@ function SupplyUnitsTracker:GetBoundingBoxes(foundObject) maxZ = math.max(maxZ, rotZ) end end - + -- Convert relative bbox to world space by adding object position ---@type SupplyUnitsBoundingBox return { @@ -549,7 +549,7 @@ end ---@param safetyMargin number Safety margin around objects ---@return boolean True if collision detected function SupplyUnitsTracker:CheckBBoxCollision(crateBBox, objBBox, safetyMargin) - + -- Apply safety margin to object bbox local objMin = { x = objBBox.min.x - safetyMargin, @@ -561,7 +561,7 @@ function SupplyUnitsTracker:CheckBBoxCollision(crateBBox, objBBox, safetyMargin) y = objBBox.max.y + safetyMargin, z = objBBox.max.z + safetyMargin } - + -- AABB collision detection return crateBBox.min.x <= objMax.x and crateBBox.max.x >= objMin.x and crateBBox.min.y <= objMax.y and crateBBox.max.y >= objMin.y and @@ -575,7 +575,7 @@ end function SupplyUnitsTracker:GetCargoPlacePosition(unit, crateTypeName) local unitPos = unit:getPosition() - + -- Get unit's heading from the forward vector (x component) -- Heading is calculated as: atan2(forward.z, forward.x) local unitHeading = math.atan2(unitPos.x.z, unitPos.x.x) @@ -586,14 +586,14 @@ function SupplyUnitsTracker:GetCargoPlacePosition(unit, crateTypeName) self._logger:error("Could not get bbox for crate type: " .. crateTypeName) return nil end - + local crateRelativeBBox = crateDesc.box -- Get drop zone config for this unit local dropZones = { { centerAngle = 180, angleWidth = 60, minRadius = 15, maxRadius = 50, spacing = 5 } } - + if SupplyLoadConfig[unit:getTypeName()] ~= nil then dropZones = SupplyLoadConfig[unit:getTypeName()].dropZones end @@ -646,15 +646,15 @@ function SupplyUnitsTracker:GetCargoPlacePosition(unit, crateTypeName) for distance = zone.minRadius, zone.maxRadius, zone.spacing do -- Check multiple positions within the angular slice local angleStep = math.min(15, zone.angleWidth / 3) -- Divide slice into sections - + for angle = minAngle, maxAngle, angleStep do local radians = math.rad(angle) - + -- Calculate position at this angle and distance, relative to unit's heading -- Angle 0 = forward, 90 = right, 180 = rear, 270 = left -- Apply unit heading to make angles relative to unit orientation local worldAngle = radians + unitHeading - + local candidateX = unitPos.p.x + distance * math.sin(worldAngle) local candidateZ = unitPos.p.z + distance * math.cos(worldAngle) local candidateY = land.getHeight({ x = candidateX, y = candidateZ }) diff --git a/src/classes/stageClasses/missions/BuildableMission.lua b/src/classes/stageClasses/missions/BuildableMission.lua index cc0b5b7..e90202c 100644 --- a/src/classes/stageClasses/missions/BuildableMission.lua +++ b/src/classes/stageClasses/missions/BuildableMission.lua @@ -25,7 +25,7 @@ local DrawingHelper = require("classes.stageClasses.drawings.helper.DrawingHelpe local BuildableMission = {} BuildableMission.__index = BuildableMission - +---@return string local function getDefaultBriefing(siteType, coords) return "We've dispatched forward units to find a proper spot for a new " .. siteType .. "." .. "\nYou will need to drop off supplies so they can start building." .. @@ -48,7 +48,7 @@ function BuildableMission.new(database, logger, targetZone, noLandingZone, requi setmetatable(BuildableMission, Mission) local self = setmetatable({}, { __index = BuildableMission }) - + self._targetZone = targetZone self._database = database self._requiredKilos = requiredKilos @@ -75,7 +75,7 @@ function BuildableMission.new(database, logger, targetZone, noLandingZone, requi end self.code = tostring(database:GetNewMissionCode()) - + local splitTargetZoneName = Util.split_string(targetZone.name, "_") if splitTargetZoneName and splitTargetZoneName[3] and splitTargetZoneName[3] ~= "" then self.name = splitTargetZoneName[3] @@ -83,13 +83,6 @@ function BuildableMission.new(database, logger, targetZone, noLandingZone, requi self.name = "Resupply" end - local type = "site" - if requiredCrateType == "SAM_CRATE" then - type = "SAM site" - elseif requiredCrateType == "FARP_CRATE" then - type = "FARP" - end - self.zoneName = targetZone.name .. "_supply" self._logger = logger self._onCrateDroppedOfListeners = {} @@ -139,7 +132,7 @@ function BuildableMission:ShowBriefing(groupID) briefingPart = getDefaultBriefing(siteType, coords) end - local briefing = "Mission [" .. self.code .. "] " .. self.name .. + local briefing = "Mission [" .. self.code .. "] " .. self.name .. "\n \n" .. briefingPart .. "\n\n" .. @@ -201,7 +194,7 @@ function BuildableMission:SpawnActive() local fillColor2 = DrawingHelper.ColorTableToColorString({ 0, 0, 1, 0}) self._dropOffZoneDrawing = CustomDrawing.FromZone(self._dropOffZone, lineColor2, fillColor2, 2, 6) self._dropOffZoneDrawing:Draw() - + ---@param selfA BuildableMission ---@param time number local checkForCrateTasks = function (selfA, time) @@ -266,8 +259,8 @@ function BuildableMission:CheckCratesInZone() end end end - - for _, foundCrate in pairs(foundCrates) do + + for _, foundCrate in pairs(foundCrates) do local crateConfig = SupplyConfigHelper.fromObjectName(foundCrate:getName()) if crateConfig then self._droppedKilos = self._droppedKilos + crateConfig.weight @@ -282,7 +275,7 @@ function BuildableMission:CheckCratesInZone() self:NotifyMissionComplete() self._state = "COMPLETED" end - + if self._state == "COMPLETED" then for groupID, markID in pairs(self._markIDsPerGroup) do if markID then diff --git a/src/classes/stageClasses/missions/RunwayStrikeMission.lua b/src/classes/stageClasses/missions/RunwayStrikeMission.lua index e3119de..0d6e658 100644 --- a/src/classes/stageClasses/missions/RunwayStrikeMission.lua +++ b/src/classes/stageClasses/missions/RunwayStrikeMission.lua @@ -42,7 +42,7 @@ function RunwayStrikeMission.new(runway, airbaseName, database, logger, runwayBo self._runwayZone = self:RunwayToSpearheadZone(runway) self._repairInProgress = false self._minKilosForDamage = 100 - + local sections = self:ToSections(runway, 5) --[[ +-----------+-----------+-----------+-----------+-----------+ @@ -84,7 +84,6 @@ function RunwayStrikeMission:RunwayHit(impactPoint, explosiveMass) self._logger:debug("Runway hit: " .. self._airportName .. ":" .. self._runway.Name) for _, section in pairs(self._runwaySections) do - local zone = self:SectionToSpearheadZone(section) if Util.is3dPointInZone({ x = impactPoint.x, z = impactPoint.y, y = 0 }, zone) then if section.kilosHit == nil then @@ -96,7 +95,7 @@ function RunwayStrikeMission:RunwayHit(impactPoint, explosiveMass) end ---@param selfA RunwayStrikeMission - local updateState = function(selfA, time) + local updateState = function(selfA, _) selfA:UpdateState() end @@ -154,7 +153,7 @@ function RunwayStrikeMission:Draw() if runwaySection.drawID == nil then local zone = self:SectionToSpearheadZone(runwaySection) - + ---@type Free local drawObject = { primitiveType = "Polygon", @@ -213,7 +212,6 @@ function RunwayStrikeMission:StartRepair() if interval == nil then return nil end return time + interval end - timer.scheduleFunction(repairTask, self, timer.getTime() + 5) end diff --git a/src/classes/stageClasses/missions/ZoneMission.lua b/src/classes/stageClasses/missions/ZoneMission.lua index 8be5f72..c87ce14 100644 --- a/src/classes/stageClasses/missions/ZoneMission.lua +++ b/src/classes/stageClasses/missions/ZoneMission.lua @@ -211,7 +211,7 @@ end ---@return boolean function ZoneMission:AllDependenciesMet() local allDependenciesMet = true - for missionName, value in pairs(self._dependencies) do + for missionName, _ in pairs(self._dependencies) do if self._parentStage:IsMissionComplete(missionName) == false then allDependenciesMet = false self._dependencies[missionName] = false @@ -503,12 +503,12 @@ end ---@param unit Object function ZoneMission:MarkLastContact(unit) - if not unit then + if not unit then self._logger:error("MarkLastContact called with nil unit") return end - local point = unit:getPoint() + local point = unit:getPoint() if not point then self._logger:error("MarkLastContact called with unit without point") return diff --git a/src/classes/stageClasses/missions/baseMissions/Mission.lua b/src/classes/stageClasses/missions/baseMissions/Mission.lua index 2cb4c09..9fdabfb 100644 --- a/src/classes/stageClasses/missions/baseMissions/Mission.lua +++ b/src/classes/stageClasses/missions/baseMissions/Mission.lua @@ -51,7 +51,7 @@ function Mission.newSuper(self, zoneName, missionName, missionType, missionBrief self.location = database:GetLocationForMissionZone(zoneName) self.missionTypeDisplay = self.missionType - + self._missionCommandsHelper = MissionCommandsHelper.getOrCreate() return true, "success" diff --git a/src/classes/util/DcsUtil.lua b/src/classes/util/DcsUtil.lua index c314c0b..a59ffd9 100644 --- a/src/classes/util/DcsUtil.lua +++ b/src/classes/util/DcsUtil.lua @@ -77,7 +77,7 @@ do -- INIT DCS_UTIL do -- INITS ALL TABLES WITH DATA THAT's from the MIZ environment do --init trigger zones - for i, trigger_zone in pairs(env.mission.triggers.zones) do + for _, trigger_zone in pairs(env.mission.triggers.zones) do -- reorder verts as they are not ordered correctly in the ME local verts = {} if Util.tableLength(trigger_zone.verticies) >= 4 then @@ -192,7 +192,7 @@ do -- INIT DCS_UTIL BLUE = 2 } ]] -- - local input = string.lower(input) + input = string.lower(input) if input == 'neutrals' or input == "neutral" or input == "0" then return DCS_UTIL.Coalition.NEUTRAL end @@ -235,7 +235,7 @@ do -- INIT DCS_UTIL end end - for index, zone_name in pairs(zone_names) do + for _, zone_name in pairs(zone_names) do local zone = DCS_UTIL.__trigger_zones[zone_name] if zone then zones[#zones + 1] = zone @@ -247,7 +247,7 @@ do -- INIT DCS_UTIL local lUnit = units[units_ind] local unit_pos = lUnit:getPosition().p local lCat = Object.getCategory(lUnit) - for zone_name, zone in pairs(zones) do + for _, zone in pairs(zones) do if unit_pos and ((lCat == 1 and lUnit:isActive() == true) or lCat ~= 1) then -- it is a unit and is active or it is not a unit local isInZone = Util.is3dPointInZone(unit_pos, zone) if isInZone == true then @@ -313,7 +313,7 @@ do -- INIT DCS_UTIL function DCS_UTIL.isPositionInZones(x, z, zone_names) ---@type Array local zones = {} - for index, zone_name in pairs(zone_names) do + for _, zone_name in pairs(zone_names) do local zone = DCS_UTIL.__trigger_zones[zone_name] if zone then zones[#zones + 1] = zone @@ -321,7 +321,7 @@ do -- INIT DCS_UTIL end local result_zones = {} - for zone_name, zone in pairs(zones) do + for _, zone in pairs(zones) do if Util.is3dPointInZone({ x = x, z = z, y = 0 }, zone) == true then result_zones[#result_zones + 1] = zone.name end @@ -414,7 +414,7 @@ do -- INIT DCS_UTIL local height = land.getHeight(location) local vec3 = { x = location.x, y = height, z = location.y } - local unitType = string.lower(unitType or "") + unitType = string.lower(unitType or "") local conversionType = config[unitType] if not conversionType then conversionType = "DDM" end @@ -471,7 +471,7 @@ do -- INIT DCS_UTIL lon_hemisphere, math.abs(lon_deg), lon_min_display, lon_sec_display, altitude * 3,28084) end - + end ---@param zone SpearheadTriggerZone @@ -574,7 +574,7 @@ do -- INIT DCS_UTIL local units = {} for i = 0, 2 do local players = coalition.getPlayers(i) - for key, unit in pairs(players) do + for _, unit in pairs(players) do units[#units + 1] = unit end end @@ -617,8 +617,7 @@ do -- INIT DCS_UTIL end function DCS_UTIL.CleanCorpse(unitName) - local unitName = "dead_" .. unitName - + unitName = "dead_" .. unitName local object = StaticObject.getByName(unitName) if object then @@ -632,11 +631,11 @@ do -- INIT DCS_UTIL ---@field b number ---@field a number - local drawID = 4210 + local __drawID = 4210 function DCS_UTIL.GetNextDrawID() - drawID = drawID + 1 - return drawID + __drawID = __drawID + 1 + return __drawID end ---@param groupID number @@ -644,9 +643,9 @@ do -- INIT DCS_UTIL ---@param location Vec3 ---@return number markID function DCS_UTIL.AddMarkToGroup(groupID, text, location) - local drawID = DCS_UTIL.GetNextDrawID() - trigger.action.markToGroup(drawID, text, location, groupID, true, nil) - return drawID + local nextId = DCS_UTIL.GetNextDrawID() + trigger.action.markToGroup(nextId, text, location, groupID, true, nil) + return nextId end ---comment @@ -654,9 +653,9 @@ do -- INIT DCS_UTIL ---@param location Vec3 ---@return integer function DCS_UTIL.AddMarkToAll(text, location) - local drawID = DCS_UTIL.GetNextDrawID() - trigger.action.markToAll(drawID, text, location, true, nil) - return drawID + local nextId = DCS_UTIL.GetNextDrawID() + trigger.action.markToAll(nextId, text, location, true, nil) + return nextId end ---@param markId number @@ -705,7 +704,7 @@ do -- INIT DCS_UTIL ---@return number? id function DCS_UTIL.GetNeutralCountry() - for name, id in pairs(country.id) do + for _, id in pairs(country.id) do if coalition.getCountryCoalition(id) == DCS_UTIL.Coalition.NEUTRAL then return id end @@ -759,7 +758,7 @@ do -- INIT DCS_UTIL function DCS_UTIL.GetPlayerGroupByGroupID(groupId) for i = 0, 2 do local players = coalition.getPlayers(i) - for key, unit in pairs(players) do + for _, unit in pairs(players) do if unit and unit:isExist() == true then local group = unit:getGroup() if group and group:getID() == groupId then @@ -775,7 +774,7 @@ do -- INIT DCS_UTIL function DCS_UTIL.GetPlayerUnitByID(unitID) for i = 0, 2 do local players = coalition.getPlayers(i) - for key, unit in pairs(players) do + for _, unit in pairs(players) do if unit and unit:getID() == unitID then return unit end diff --git a/src/classes/util/Util.lua b/src/classes/util/Util.lua index f8366c4..09c8465 100644 --- a/src/classes/util/Util.lua +++ b/src/classes/util/Util.lua @@ -149,7 +149,7 @@ do -- INIT UTIL ---@param findableTable table ---@return boolean UTIL.startswithAny = function(str, findableTable) - for key, value in pairs(findableTable) do + for _, value in pairs(findableTable) do if type(value) == "string" and UTIL.startswith(str, value) then return true end end return false -- 2.54.0 From 96fab864c3cc13a79b02f68480bf1ca58c3018e3 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 11:22:21 +0200 Subject: [PATCH 09/71] non important trailing whitespace ignored --- .luacheckrc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.luacheckrc b/.luacheckrc index 4d4893b..480fb5c 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -9,6 +9,10 @@ globals = { "SpearheadAPI", } +ignore = { + "631" --Trailing whitespace +} + -- DCS Mission Scripting Environment API read_globals = { "env", "timer", "trigger", "world", "coalition", "country", -- 2.54.0 From 514a9a9c559b69e0decda3f74f0c65ee416ac8ba Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 11:24:09 +0200 Subject: [PATCH 10/71] non important trailing whitespace ignored --- .luacheckrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.luacheckrc b/.luacheckrc index 480fb5c..c89948b 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -10,7 +10,7 @@ globals = { } ignore = { - "631" --Trailing whitespace + "631", -- Trailing whitespace } -- DCS Mission Scripting Environment API -- 2.54.0 From 30c7124a8661e0c5ea1333d03809d177c820fb95 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 11:25:23 +0200 Subject: [PATCH 11/71] non important trailing whitespace ignored --- .luacheckrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.luacheckrc b/.luacheckrc index c89948b..a13ad00 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -9,8 +9,9 @@ globals = { "SpearheadAPI", } +-- Reference: https://luacheck.readthedocs.io/en/stable/warnings.html ignore = { - "631", -- Trailing whitespace + "614", -- Trailing whitespace in a comment } -- DCS Mission Scripting Environment API -- 2.54.0 From d16e25531a13028c74058e17bae37feb2343a31e Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 11:27:23 +0200 Subject: [PATCH 12/71] non important trailing whitespace ignored --- .luacheckrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.luacheckrc b/.luacheckrc index a13ad00..edea3fb 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -19,5 +19,5 @@ read_globals = { "env", "timer", "trigger", "world", "coalition", "country", "AI", "Group", "Unit", "StaticObject", "SceneryObject", "Airbase", "Weapon", "land", "atmosphere", "missionCommands", - "net", "lfs", "Object", "coord", + "net", "lfs", "Object", "coord", "Controller" } -- 2.54.0 From a55cd2bf2a15c667ab9a0eccf9555e2af92d42ee Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 12:36:29 +0200 Subject: [PATCH 13/71] trying other check --- .gitea/workflows/pr.yml | 7 +++++-- src/classes/util/Util.lua | 9 ++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 76e5218..c3243f2 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -55,5 +55,8 @@ jobs: - name: Install luacheck run: luarocks install luacheck - - name: Run Lua Check - run: luacheck ./src --config .luacheckrc \ No newline at end of file + # - name: Run Lua Check + # run: luacheck ./src --config .luacheckrc + + - name: Check Types + uses: mrcjkb/lua-typecheck-action@08d5ead5db7b1c8457aa7a0e566240b680b34588 \ No newline at end of file diff --git a/src/classes/util/Util.lua b/src/classes/util/Util.lua index 09c8465..697e7b6 100644 --- a/src/classes/util/Util.lua +++ b/src/classes/util/Util.lua @@ -237,8 +237,13 @@ do -- INIT UTIL return ((vec1Norm.x * vec2Norm.x) + (vec1Norm.y * vec2Norm.y) + (vec1Norm.z * vec2Norm.z)) end - + + ---@param polygon Array of pairs { x, y } + ---@param x number X location + ---@param y number Y location + ---@return boolean local function isInComplexPolygon(polygon, x, y) + ---@param poly Array of pairs { x, y } local function getEdges(poly) local result = {} for i = 1, #poly do @@ -399,7 +404,9 @@ do -- INIT UTIL if #points == 0 then return {} end -- Simple clustering: group points that are within minSeparation of each other + ---@type Array> local clusters = {} + ---@type table local assigned = {} for i, p in ipairs(points) do -- 2.54.0 From 2a76df1e21904700132681073fbc6c1acad4537f Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 15:36:02 +0200 Subject: [PATCH 14/71] updated --- .gitea/workflows/pr.yml | 27 +++++++++++++++++---------- .luacheckrc | 23 ----------------------- 2 files changed, 17 insertions(+), 33 deletions(-) delete mode 100644 .luacheckrc diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index c3243f2..6472901 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -6,6 +6,10 @@ on: - main - develop +env: + LUA_VERSION: "5.1" + LUA_LANGUAGE_SERVER_VERSION: ".19.1" + jobs: bundles_without_error: runs-on: ubuntu-latest @@ -17,7 +21,7 @@ jobs: - name: Set up Lua uses: leafo/gh-actions-lua@v13 with: - luaVersion: "5.1" + luaVersion: ${{ env.LUA_VERSION }} - name: Compile Spearhead uses: https://git.dutchie031.com/dutchie031/DcsMissionScriptingTools/github-action@action/v0 @@ -47,16 +51,19 @@ jobs: - name: Set up Lua uses: leafo/gh-actions-lua@v13 with: - luaVersion: "5.1" + luaVersion: ${{ env.LUA_VERSION }} - - name: Set up Luarocks - uses: leafo/gh-actions-luarocks@v4 + - name: Install lua-language-server + run: | + # For Ubuntu/Debian + wget https://github.com/LuaLS/lua-language-server/releases/download/${{ env.LUA_LANGUAGE_SERVER_VERSION }}/lua-language-server-${{ env.LUA_LANGUAGE_SERVER_VERSION }}-linux-x64.tar.gz + tar -xzf lua-language-server-*.tar.gz + rm lua-language-server-*.tar.gz - - name: Install luacheck - run: luarocks install luacheck + - name: Verify Lua Language Server Installation + run: ./lua-language-server-*/lua-language-server --version - # - name: Run Lua Check - # run: luacheck ./src --config .luacheckrc + - name: Run Lua Language Server + run: ./lua-language-server-*/lua-language-server --check ./src --checklevel=Information - - name: Check Types - uses: mrcjkb/lua-typecheck-action@08d5ead5db7b1c8457aa7a0e566240b680b34588 \ No newline at end of file + diff --git a/.luacheckrc b/.luacheckrc deleted file mode 100644 index edea3fb..0000000 --- a/.luacheckrc +++ /dev/null @@ -1,23 +0,0 @@ -std = "lua51" - -max_line_length = false - --- Cross-file globals set by Spearhead itself (no `require`/module system in the bundle) -globals = { - "SpearheadConfig", - "GlobalCapCallBacks", - "SpearheadAPI", -} - --- Reference: https://luacheck.readthedocs.io/en/stable/warnings.html -ignore = { - "614", -- Trailing whitespace in a comment -} - --- DCS Mission Scripting Environment API -read_globals = { - "env", "timer", "trigger", "world", "coalition", "country", - "AI", "Group", "Unit", "StaticObject", "SceneryObject", - "Airbase", "Weapon", "land", "atmosphere", "missionCommands", - "net", "lfs", "Object", "coord", "Controller" -} -- 2.54.0 From de1e6ffae9a09a4c9dc5a1a569c122ee75848046 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 15:37:39 +0200 Subject: [PATCH 15/71] updated luals version --- .gitea/workflows/pr.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 6472901..25afaca 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -8,7 +8,7 @@ on: env: LUA_VERSION: "5.1" - LUA_LANGUAGE_SERVER_VERSION: ".19.1" + LUA_LANGUAGE_SERVER_VERSION: "3.19.1" jobs: bundles_without_error: @@ -65,5 +65,6 @@ jobs: - name: Run Lua Language Server run: ./lua-language-server-*/lua-language-server --check ./src --checklevel=Information + -- 2.54.0 From ccd38078f3ddff4124a1e888e9f94782d2dc792c Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 15:47:50 +0200 Subject: [PATCH 16/71] updated luals version --- .gitea/workflows/pr.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 25afaca..173751f 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -57,14 +57,14 @@ jobs: run: | # For Ubuntu/Debian wget https://github.com/LuaLS/lua-language-server/releases/download/${{ env.LUA_LANGUAGE_SERVER_VERSION }}/lua-language-server-${{ env.LUA_LANGUAGE_SERVER_VERSION }}-linux-x64.tar.gz - tar -xzf lua-language-server-*.tar.gz + tar -xzf lua-language-server-*.tar.gz -C ./bin rm lua-language-server-*.tar.gz - name: Verify Lua Language Server Installation - run: ./lua-language-server-*/lua-language-server --version + run: ./bin/lua-language-server --version - - name: Run Lua Language Server - run: ./lua-language-server-*/lua-language-server --check ./src --checklevel=Information + # - name: Run Lua Language Server + # run: ./lua-language-server-*/lua-language-server --check ./src --checklevel=Information -- 2.54.0 From 68e8d1c9ac89d882cea4de324d4c1392949d1ed0 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 15:49:05 +0200 Subject: [PATCH 17/71] updated luals version --- .gitea/workflows/pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 173751f..333ee0b 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -55,6 +55,7 @@ jobs: - name: Install lua-language-server run: | + mkdir -p ./bin # For Ubuntu/Debian wget https://github.com/LuaLS/lua-language-server/releases/download/${{ env.LUA_LANGUAGE_SERVER_VERSION }}/lua-language-server-${{ env.LUA_LANGUAGE_SERVER_VERSION }}-linux-x64.tar.gz tar -xzf lua-language-server-*.tar.gz -C ./bin -- 2.54.0 From 1fde8ec3b16896d151104f48ddb741b618f86335 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 15:49:22 +0200 Subject: [PATCH 18/71] updated luals version --- .gitea/workflows/pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 333ee0b..76ca6b2 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -60,6 +60,7 @@ jobs: wget https://github.com/LuaLS/lua-language-server/releases/download/${{ env.LUA_LANGUAGE_SERVER_VERSION }}/lua-language-server-${{ env.LUA_LANGUAGE_SERVER_VERSION }}-linux-x64.tar.gz tar -xzf lua-language-server-*.tar.gz -C ./bin rm lua-language-server-*.tar.gz + ls -R ./bin - name: Verify Lua Language Server Installation run: ./bin/lua-language-server --version -- 2.54.0 From 4b3d87f589e4389e380cf8a846ba879eee649a66 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 15:49:32 +0200 Subject: [PATCH 19/71] updated luals version --- .gitea/workflows/pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 76ca6b2..45166b2 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -60,6 +60,7 @@ jobs: wget https://github.com/LuaLS/lua-language-server/releases/download/${{ env.LUA_LANGUAGE_SERVER_VERSION }}/lua-language-server-${{ env.LUA_LANGUAGE_SERVER_VERSION }}-linux-x64.tar.gz tar -xzf lua-language-server-*.tar.gz -C ./bin rm lua-language-server-*.tar.gz + echo "Contents of ./bin directory:" ls -R ./bin - name: Verify Lua Language Server Installation -- 2.54.0 From e081b8e44643d9c4fc89f0ac6d0f152c80a2c7af Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 15:55:11 +0200 Subject: [PATCH 20/71] updated luals version --- .gitea/workflows/pr.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 45166b2..90906a9 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -55,16 +55,14 @@ jobs: - name: Install lua-language-server run: | - mkdir -p ./bin + mkdir -p ./luals # For Ubuntu/Debian wget https://github.com/LuaLS/lua-language-server/releases/download/${{ env.LUA_LANGUAGE_SERVER_VERSION }}/lua-language-server-${{ env.LUA_LANGUAGE_SERVER_VERSION }}-linux-x64.tar.gz - tar -xzf lua-language-server-*.tar.gz -C ./bin + tar -xzf lua-language-server-*.tar.gz -C ./luals rm lua-language-server-*.tar.gz - echo "Contents of ./bin directory:" - ls -R ./bin - name: Verify Lua Language Server Installation - run: ./bin/lua-language-server --version + run: ./luals/bin/lua-language-server --version # - name: Run Lua Language Server # run: ./lua-language-server-*/lua-language-server --check ./src --checklevel=Information -- 2.54.0 From a351c45b73dd1454227da593bc78c66d886542fd Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Wed, 9 Sep 2026 22:04:15 +0200 Subject: [PATCH 21/71] wip --- .gitea/workflows/pr.yml | 4 ++-- .luarc.json | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 .luarc.json diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 90906a9..aeab382 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -64,8 +64,8 @@ jobs: - name: Verify Lua Language Server Installation run: ./luals/bin/lua-language-server --version - # - name: Run Lua Language Server - # run: ./lua-language-server-*/lua-language-server --check ./src --checklevel=Information + - name: Run Lua Language Server + run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning diff --git a/.luarc.json b/.luarc.json new file mode 100644 index 0000000..ce8a119 --- /dev/null +++ b/.luarc.json @@ -0,0 +1,30 @@ +{ + "Lua": { + "runtime": { + "version": "Lua 5.1" + }, + "workspace": { + "library": [ + "./src", + "./DcsTypes.lua" + ], + "checkThirdParty": false + }, + "diagnostics": { + "enable": true, + "globals": [ + "lfs" + ], + "severity": { + "undefined-field": "Warning", + "unused-local": "Warning" + } + }, + "hint": { + "enable": false + }, + "completion": { + "enable": true + } + } +} \ No newline at end of file -- 2.54.0 From c4683fb80cdbeae09f0b0982b548cd24a188314c Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 17:11:54 +0200 Subject: [PATCH 22/71] updated CI pipeline --- .gitea/workflows/pr.yml | 5 +++++ .gitignore | 1 + .luarc.json | 20 +++++++++++++++----- .vscode/extensions.json | 9 +++++---- src/classes/persistence/Persistence.lua | 4 +++- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index aeab382..8621770 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -53,6 +53,11 @@ jobs: with: luaVersion: ${{ env.LUA_VERSION }} + - name: Install Dcs Plugins + uses: https://git.dutchie031.com/dutchie031/DcsMissionScriptingTools/github-actions/install-lua-addon@install-lua-addon/v1 + with: + destination-path: "./.vscode/lua-addons" ##same as local so .luarc.json can be the same + - name: Install lua-language-server run: | mkdir -p ./luals diff --git a/.gitignore b/.gitignore index 5d688a1..1886557 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ /dist +.vscode/lua-addons .vscode/settings.json **\settings.json \ No newline at end of file diff --git a/.luarc.json b/.luarc.json index ce8a119..60edfc3 100644 --- a/.luarc.json +++ b/.luarc.json @@ -4,10 +4,6 @@ "version": "Lua 5.1" }, "workspace": { - "library": [ - "./src", - "./DcsTypes.lua" - ], "checkThirdParty": false }, "diagnostics": { @@ -17,7 +13,21 @@ ], "severity": { "undefined-field": "Warning", - "unused-local": "Warning" + "unused-local": "Warning", + "unused-function": "Warning" + + }, + "groupFileStatus": { + "ambiguity": "Any", + "await": "Any", + "duplicate": "Any", + "global": "Any", + "luadoc": "Any", + "redefined": "Any", + "strict": "Any", + "type-check": "Any", + "unbalanced": "Any", + "unused": "Any" } }, "hint": { diff --git a/.vscode/extensions.json b/.vscode/extensions.json index a12ed18..02af72a 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,6 @@ -{ - "recommendations": [ - "sumneko.lua" - ] +{ + "recommendations": [ + "dutchie031.dutchies-dcs-scripting-tools", + "sumneko.lua", + ] } \ No newline at end of file diff --git a/src/classes/persistence/Persistence.lua b/src/classes/persistence/Persistence.lua index 9cb886c..7919936 100644 --- a/src/classes/persistence/Persistence.lua +++ b/src/classes/persistence/Persistence.lua @@ -141,7 +141,9 @@ do end ---@param dir string @BaseDirectory - ---@return string + ---@param startsWith string + ---@param default string? + ---@return string? local getLastFileOrDefault = function(dir, startsWith, default) local latestFile, lastNumber = default, 0 -- 2.54.0 From 63ca8373e66159c9470e1e49eeee742c9c75fdd6 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 19:11:37 +0200 Subject: [PATCH 23/71] push --- .gitea/workflows/pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 8621770..2ad28f7 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -71,6 +71,7 @@ jobs: - name: Run Lua Language Server run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning + -- 2.54.0 From fd9a1fd0874b38e0e69621c10d510e04051abd8f Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 19:14:09 +0200 Subject: [PATCH 24/71] wip --- .gitea/workflows/pr.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 2ad28f7..39c72f2 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -58,6 +58,9 @@ jobs: with: destination-path: "./.vscode/lua-addons" ##same as local so .luarc.json can be the same + - name: Verify Dcs Plugins Installation + run: ls -la ./.vscode/lua-addons + - name: Install lua-language-server run: | mkdir -p ./luals -- 2.54.0 From 3e52e9ce7f407ec8c6a3fbd6ef5c444a24e85af3 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 19:16:55 +0200 Subject: [PATCH 25/71] wip --- .gitea/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 39c72f2..637025d 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -73,7 +73,7 @@ jobs: run: ./luals/bin/lua-language-server --version - name: Run Lua Language Server - run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning + run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning --configpath ./.luarc.json -- 2.54.0 From ba5c459eb5454a282a7b835598f2e3e21138dd23 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 19:27:39 +0200 Subject: [PATCH 26/71] wip --- .gitea/workflows/pr.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 637025d..5676b8d 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -72,6 +72,9 @@ jobs: - name: Verify Lua Language Server Installation run: ./luals/bin/lua-language-server --version + - name: Show Config + run: cat ./.luarc.json + - name: Run Lua Language Server run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning --configpath ./.luarc.json -- 2.54.0 From ce0c5f4a5857c1f1c2becf324c5c7a7fbfcb6fe8 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 19:32:24 +0200 Subject: [PATCH 27/71] updated luarc.json --- .luarc.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.luarc.json b/.luarc.json index 60edfc3..3c27934 100644 --- a/.luarc.json +++ b/.luarc.json @@ -4,7 +4,10 @@ "version": "Lua 5.1" }, "workspace": { - "checkThirdParty": false + "checkThirdParty": false, + "library": [ + ".vscode/lua-addons" + ] }, "diagnostics": { "enable": true, -- 2.54.0 From 6b5fd16a2f6664deaff23c5a78b4c1921adbecfc Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 19:56:06 +0200 Subject: [PATCH 28/71] updated luarc.json --- .gitea/workflows/pr.yml | 7 +++++++ .luarc.json | 6 +----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 5676b8d..da5e2ae 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -72,6 +72,13 @@ jobs: - name: Verify Lua Language Server Installation run: ./luals/bin/lua-language-server --version + - name: Update Json With Full Path + run: | + FULL_PATH=$(realpath ./.vscode/lua-addons) + echo "full-path: $FULL_PATH" + + jq --arg full_path "$FULL_PATH" '.Lua.workspace.library[0] = $full_path' ./.luarc.json > ./.luarc.json.tmp && mv ./.luarc.json.tmp ./.luarc.json + - name: Show Config run: cat ./.luarc.json diff --git a/.luarc.json b/.luarc.json index 3c27934..033a68b 100644 --- a/.luarc.json +++ b/.luarc.json @@ -4,10 +4,7 @@ "version": "Lua 5.1" }, "workspace": { - "checkThirdParty": false, - "library": [ - ".vscode/lua-addons" - ] + "checkThirdParty": false }, "diagnostics": { "enable": true, @@ -18,7 +15,6 @@ "undefined-field": "Warning", "unused-local": "Warning", "unused-function": "Warning" - }, "groupFileStatus": { "ambiguity": "Any", -- 2.54.0 From 4771387c1eb2e6252d987c2a39035df3111db323 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 20:28:27 +0200 Subject: [PATCH 29/71] removed obsolete weorkflow --- .gitea/workflows/pr.yml | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index da5e2ae..2ccfc92 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -72,16 +72,41 @@ jobs: - name: Verify Lua Language Server Installation run: ./luals/bin/lua-language-server --version - - name: Update Json With Full Path + - name: Resolve Addon Paths And Update Config run: | - FULL_PATH=$(realpath ./.vscode/lua-addons) - echo "full-path: $FULL_PATH" + ADDONS_PATH=$(realpath ./.vscode/lua-addons) + ADDON_ROOT=$(find "$ADDONS_PATH" -mindepth 1 -maxdepth 1 -type d | head -n 1) + LIBRARY_PATH="$ADDON_ROOT/library" - jq --arg full_path "$FULL_PATH" '.Lua.workspace.library[0] = $full_path' ./.luarc.json > ./.luarc.json.tmp && mv ./.luarc.json.tmp ./.luarc.json + echo "addons-path: $ADDONS_PATH" + echo "addon-root: $ADDON_ROOT" + echo "library-path: $LIBRARY_PATH" + + test -d "$ADDON_ROOT" + test -d "$LIBRARY_PATH" + test -f "$LIBRARY_PATH/DcsTypes.lua" + + jq \ + --arg addons_path "$ADDONS_PATH" \ + --arg addon_root "$ADDON_ROOT" \ + --arg library_path "$LIBRARY_PATH" \ + '.Lua.workspace.library = [$library_path, $addon_root] | .Lua.workspace.userThirdParty = [$addons_path]' \ + ./.luarc.json > ./.luarc.json.tmp && mv ./.luarc.json.tmp ./.luarc.json - name: Show Config run: cat ./.luarc.json + - name: LuaLS Smoke Test For Addon Globals + run: | + cat > ./_luals_smoke_test.lua << 'EOF' + local now = timer.getTime() + local base = Airbase.getByName("TEST") + local side = coalition.side.RED + return now, base, side + EOF + + ./luals/bin/lua-language-server --check ./_luals_smoke_test.lua --checklevel=Warning --configpath ./.luarc.json + - name: Run Lua Language Server run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning --configpath ./.luarc.json -- 2.54.0 From b9bfd4babf151a8b63894013238ea1f497006930 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 20:38:27 +0200 Subject: [PATCH 30/71] wip --- .gitea/workflows/pr.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 2ccfc92..0018e63 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -105,7 +105,32 @@ jobs: return now, base, side EOF - ./luals/bin/lua-language-server --check ./_luals_smoke_test.lua --checklevel=Warning --configpath ./.luarc.json + cat > ./src/_luals_smoke_test.lua << 'EOF' + local now = timer.getTime() + local base = Airbase.getByName("TEST") + local side = coalition.side.RED + return now, base, side + EOF + + set -o pipefail + + echo "=== smoke(root) ===" + ./luals/bin/lua-language-server --check ./_luals_smoke_test.lua --checklevel=Warning --configpath ./.luarc.json 2>&1 | tee ./_luals_smoke_root.log + if grep -q "undefined-global" ./_luals_smoke_root.log; then + echo "Root smoke test reported undefined-global" + exit 1 + fi + + echo "=== smoke(src) ===" + ./luals/bin/lua-language-server --check ./src/_luals_smoke_test.lua --checklevel=Warning --configpath ./.luarc.json 2>&1 | tee ./_luals_smoke_src.log + if grep -q "undefined-global" ./_luals_smoke_src.log; then + echo "Src smoke test reported undefined-global" + exit 1 + fi + + echo "=== check(failing-file) ===" + ./luals/bin/lua-language-server --check ./src/classes/capClasses/CapAirbase.lua --checklevel=Warning --configpath ./.luarc.json 2>&1 | tee ./_luals_capairbase.log || true + grep -n "undefined-global" ./_luals_capairbase.log || true - name: Run Lua Language Server run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning --configpath ./.luarc.json -- 2.54.0 From 8496ddc071251a2f3227609dde4df2a6c1887ded Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 20:43:42 +0200 Subject: [PATCH 31/71] wip --- .gitea/workflows/pr.yml | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 0018e63..93cfa58 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -105,13 +105,6 @@ jobs: return now, base, side EOF - cat > ./src/_luals_smoke_test.lua << 'EOF' - local now = timer.getTime() - local base = Airbase.getByName("TEST") - local side = coalition.side.RED - return now, base, side - EOF - set -o pipefail echo "=== smoke(root) ===" @@ -121,19 +114,16 @@ jobs: exit 1 fi - echo "=== smoke(src) ===" - ./luals/bin/lua-language-server --check ./src/_luals_smoke_test.lua --checklevel=Warning --configpath ./.luarc.json 2>&1 | tee ./_luals_smoke_src.log - if grep -q "undefined-global" ./_luals_smoke_src.log; then - echo "Src smoke test reported undefined-global" - exit 1 - fi - - echo "=== check(failing-file) ===" - ./luals/bin/lua-language-server --check ./src/classes/capClasses/CapAirbase.lua --checklevel=Warning --configpath ./.luarc.json 2>&1 | tee ./_luals_capairbase.log || true - grep -n "undefined-global" ./_luals_capairbase.log || true + rm -f ./_luals_smoke_test.lua - name: Run Lua Language Server - run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning --configpath ./.luarc.json + run: | + set -euo pipefail + echo "Checking Lua files one-by-one to keep addon globals resolution consistent" + while IFS= read -r -d '' file; do + echo "Checking $file" + ./luals/bin/lua-language-server --check "$file" --checklevel=Warning --configpath ./.luarc.json + done < <(find ./src -type f -name '*.lua' -print0) -- 2.54.0 From 5a9cf68dca8588c5ca29b3860d6644a800046418 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 21:01:27 +0200 Subject: [PATCH 32/71] wip --- .gitea/workflows/pr.yml | 51 +++++------------------------------------ 1 file changed, 6 insertions(+), 45 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 93cfa58..072ba6d 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -72,58 +72,19 @@ jobs: - name: Verify Lua Language Server Installation run: ./luals/bin/lua-language-server --version - - name: Resolve Addon Paths And Update Config + - name: Update Json run: | - ADDONS_PATH=$(realpath ./.vscode/lua-addons) - ADDON_ROOT=$(find "$ADDONS_PATH" -mindepth 1 -maxdepth 1 -type d | head -n 1) - LIBRARY_PATH="$ADDON_ROOT/library" + FULL_PATH=$(realpath ./.vscode/lua-addons) + echo "full-path: $FULL_PATH" - echo "addons-path: $ADDONS_PATH" - echo "addon-root: $ADDON_ROOT" - echo "library-path: $LIBRARY_PATH" - - test -d "$ADDON_ROOT" - test -d "$LIBRARY_PATH" - test -f "$LIBRARY_PATH/DcsTypes.lua" - - jq \ - --arg addons_path "$ADDONS_PATH" \ - --arg addon_root "$ADDON_ROOT" \ - --arg library_path "$LIBRARY_PATH" \ - '.Lua.workspace.library = [$library_path, $addon_root] | .Lua.workspace.userThirdParty = [$addons_path]' \ - ./.luarc.json > ./.luarc.json.tmp && mv ./.luarc.json.tmp ./.luarc.json + jq --arg full_path "$FULL_PATH" '.Lua.workspace.library[0] = $full_path' ./.luarc.json > ./.luarc.tmp.json + mv ./.luarc.tmp.json ./.luarc.json - name: Show Config run: cat ./.luarc.json - - name: LuaLS Smoke Test For Addon Globals - run: | - cat > ./_luals_smoke_test.lua << 'EOF' - local now = timer.getTime() - local base = Airbase.getByName("TEST") - local side = coalition.side.RED - return now, base, side - EOF - - set -o pipefail - - echo "=== smoke(root) ===" - ./luals/bin/lua-language-server --check ./_luals_smoke_test.lua --checklevel=Warning --configpath ./.luarc.json 2>&1 | tee ./_luals_smoke_root.log - if grep -q "undefined-global" ./_luals_smoke_root.log; then - echo "Root smoke test reported undefined-global" - exit 1 - fi - - rm -f ./_luals_smoke_test.lua - - name: Run Lua Language Server - run: | - set -euo pipefail - echo "Checking Lua files one-by-one to keep addon globals resolution consistent" - while IFS= read -r -d '' file; do - echo "Checking $file" - ./luals/bin/lua-language-server --check "$file" --checklevel=Warning --configpath ./.luarc.json - done < <(find ./src -type f -name '*.lua' -print0) + run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning --configpath ./.luarc.json -- 2.54.0 From 79dcdaa5dd996ad9ed004f4b57835d202b380367 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 21:15:08 +0200 Subject: [PATCH 33/71] wip --- .gitea/workflows/pr.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 072ba6d..62fc5ad 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -76,7 +76,9 @@ jobs: run: | FULL_PATH=$(realpath ./.vscode/lua-addons) echo "full-path: $FULL_PATH" + cat $FULL_PATH + echo "Updating .luarc.json with full path" jq --arg full_path "$FULL_PATH" '.Lua.workspace.library[0] = $full_path' ./.luarc.json > ./.luarc.tmp.json mv ./.luarc.tmp.json ./.luarc.json -- 2.54.0 From 28977026658e0b03b184e3443ccb2622eba55320 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 21:16:24 +0200 Subject: [PATCH 34/71] wip --- .gitea/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 62fc5ad..840b84e 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -76,7 +76,7 @@ jobs: run: | FULL_PATH=$(realpath ./.vscode/lua-addons) echo "full-path: $FULL_PATH" - cat $FULL_PATH + ls -la $FULL_PATH echo "Updating .luarc.json with full path" jq --arg full_path "$FULL_PATH" '.Lua.workspace.library[0] = $full_path' ./.luarc.json > ./.luarc.tmp.json -- 2.54.0 From 681f65ce932024961d66e0b8998809c9ceda24dc Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 21:28:54 +0200 Subject: [PATCH 35/71] updated workspace --- .luarc.json | 67 ++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/.luarc.json b/.luarc.json index 033a68b..b111901 100644 --- a/.luarc.json +++ b/.luarc.json @@ -1,39 +1,38 @@ { - "Lua": { - "runtime": { - "version": "Lua 5.1" + "$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json", + "runtime": { + "version": "Lua 5.1" + }, + "workspace": { + "checkThirdParty": false + }, + "diagnostics": { + "enable": true, + "globals": [ + "lfs" + ], + "severity": { + "undefined-field": "Warning", + "unused-local": "Warning", + "unused-function": "Warning" }, - "workspace": { - "checkThirdParty": false - }, - "diagnostics": { - "enable": true, - "globals": [ - "lfs" - ], - "severity": { - "undefined-field": "Warning", - "unused-local": "Warning", - "unused-function": "Warning" - }, - "groupFileStatus": { - "ambiguity": "Any", - "await": "Any", - "duplicate": "Any", - "global": "Any", - "luadoc": "Any", - "redefined": "Any", - "strict": "Any", - "type-check": "Any", - "unbalanced": "Any", - "unused": "Any" - } - }, - "hint": { - "enable": false - }, - "completion": { - "enable": true + "groupFileStatus": { + "ambiguity": "Any", + "await": "Any", + "duplicate": "Any", + "global": "Any", + "luadoc": "Any", + "redefined": "Any", + "strict": "Any", + "type-check": "Any", + "unbalanced": "Any", + "unused": "Any" } + }, + "hint": { + "enable": false + }, + "completion": { + "enable": true } } \ No newline at end of file -- 2.54.0 From 84f0b7c978c6eb26ed3bc7665c6832f6c9750a0f Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 21:35:36 +0200 Subject: [PATCH 36/71] updated workspace --- .gitea/workflows/pr.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 840b84e..bc2d649 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -86,7 +86,10 @@ jobs: run: cat ./.luarc.json - name: Run Lua Language Server - run: ./luals/bin/lua-language-server --check ./src --checklevel=Warning --configpath ./.luarc.json + run: ./luals/bin/lua-language-server \ + --check ./src \ + --checklevel=Warning \ + --configpath="./.luarc.json" -- 2.54.0 From 8f3eb63ffdf311647dbbc486f3d637738d59e019 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 21:49:08 +0200 Subject: [PATCH 37/71] updated workspace --- .gitea/workflows/pr.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index bc2d649..65c245c 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -86,7 +86,8 @@ jobs: run: cat ./.luarc.json - name: Run Lua Language Server - run: ./luals/bin/lua-language-server \ + run: | + ./luals/bin/lua-language-server \ --check ./src \ --checklevel=Warning \ --configpath="./.luarc.json" -- 2.54.0 From 489e78af9c7c664b64d42a2a8f9f04ec0871fd25 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:18:57 +0200 Subject: [PATCH 38/71] updated workspace --- .gitea/workflows/pr.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 65c245c..09c48f5 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -90,8 +90,10 @@ jobs: ./luals/bin/lua-language-server \ --check ./src \ --checklevel=Warning \ - --configpath="./.luarc.json" + --configpath="./.luarc.json" \ + --loglevel=trace \ + --logpath="./luals/logs" - - + - name: Show Log + run: cat ./luals/logs -- 2.54.0 From 86eed3bfdc13a1b6bea06733e4fb1762f17c8f9c Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:19:55 +0200 Subject: [PATCH 39/71] updated workspace --- .gitea/workflows/pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 09c48f5..846de84 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -95,5 +95,6 @@ jobs: --logpath="./luals/logs" - name: Show Log + if: failure() run: cat ./luals/logs -- 2.54.0 From fc5ab2f7cd56cd5410eb4c8f79ea10b5a8fb766d Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:23:36 +0200 Subject: [PATCH 40/71] updated workspace --- .gitea/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 846de84..cede6d3 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -90,7 +90,7 @@ jobs: ./luals/bin/lua-language-server \ --check ./src \ --checklevel=Warning \ - --configpath="./.luarc.json" \ + --configpath="./.luarc.json" \ --loglevel=trace \ --logpath="./luals/logs" -- 2.54.0 From 9c3c845bb0dd3cc4082b8ed04739caf689b7e900 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:24:20 +0200 Subject: [PATCH 41/71] wip --- .gitea/workflows/pr.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index cede6d3..fd7b581 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -92,7 +92,8 @@ jobs: --checklevel=Warning \ --configpath="./.luarc.json" \ --loglevel=trace \ - --logpath="./luals/logs" + --logpath="./luals/logs" \ + --develop - name: Show Log if: failure() -- 2.54.0 From 8dcb129fd3a3d52dbb3becc15dcbad7f654d06e0 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:26:19 +0200 Subject: [PATCH 42/71] wip --- .gitea/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index fd7b581..5e3ae2c 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -97,5 +97,5 @@ jobs: - name: Show Log if: failure() - run: cat ./luals/logs + run: ls -R . -- 2.54.0 From 196b42d5c1efe588557d3e5bd3c7ac5d55b00703 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:27:41 +0200 Subject: [PATCH 43/71] wip --- .gitea/workflows/pr.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 5e3ae2c..892c895 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -97,5 +97,6 @@ jobs: - name: Show Log if: failure() - run: ls -R . - + run: | + ls -R ./luals + cat ./luals/logs -- 2.54.0 From 03f11f6d67a1e4a41892ebce13589596f8803347 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:29:18 +0200 Subject: [PATCH 44/71] wip --- .gitea/workflows/pr.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 892c895..98ddec5 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -98,5 +98,6 @@ jobs: - name: Show Log if: failure() run: | - ls -R ./luals - cat ./luals/logs + ls -R ./luals/logs + + cat ./luals/logs/* || true -- 2.54.0 From 80011bdeacd1f03d670a59f5a9e115e9fcc03515 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:35:54 +0200 Subject: [PATCH 45/71] wip --- .gitea/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 98ddec5..b1724ce 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -79,7 +79,7 @@ jobs: ls -la $FULL_PATH echo "Updating .luarc.json with full path" - jq --arg full_path "$FULL_PATH" '.Lua.workspace.library[0] = $full_path' ./.luarc.json > ./.luarc.tmp.json + jq --arg full_path "$FULL_PATH" '.workspace.library[0] = $full_path' ./.luarc.json > ./.luarc.tmp.json mv ./.luarc.tmp.json ./.luarc.json - name: Show Config -- 2.54.0 From d14324c5436f8e6b7c901c45df6baa0eaa49586d Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:38:02 +0200 Subject: [PATCH 46/71] wip --- .gitea/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index b1724ce..dea0ab6 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -76,7 +76,7 @@ jobs: run: | FULL_PATH=$(realpath ./.vscode/lua-addons) echo "full-path: $FULL_PATH" - ls -la $FULL_PATH + ls -R $FULL_PATH echo "Updating .luarc.json with full path" jq --arg full_path "$FULL_PATH" '.workspace.library[0] = $full_path' ./.luarc.json > ./.luarc.tmp.json -- 2.54.0 From 48d055e16d0e9cc6dc716b08df09585ed5a8feea Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:53:31 +0200 Subject: [PATCH 47/71] wip --- .gitea/workflows/pr.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index dea0ab6..7a3afee 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -89,12 +89,12 @@ jobs: run: | ./luals/bin/lua-language-server \ --check ./src \ - --checklevel=Warning \ - --configpath="./.luarc.json" \ - --loglevel=trace \ - --logpath="./luals/logs" \ - --develop - + --checklevel=Warning + # --configpath="./.luarc.json" \ + # --loglevel=trace \ + # --logpath="./luals/logs" \ + # --develop + - name: Show Log if: failure() run: | -- 2.54.0 From 38f689c3a10e1b06c422ecad3d53cb5864ecec2e Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:56:23 +0200 Subject: [PATCH 48/71] wip --- .gitea/workflows/pr.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 7a3afee..9ee2246 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -89,10 +89,10 @@ jobs: run: | ./luals/bin/lua-language-server \ --check ./src \ - --checklevel=Warning + --checklevel=Warning \ + --loglevel=trace \ + --logpath="./luals/logs" # --configpath="./.luarc.json" \ - # --loglevel=trace \ - # --logpath="./luals/logs" \ # --develop - name: Show Log -- 2.54.0 From f53d0d5c83f3c850bebd717bb55cdc984f1d7014 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Thu, 10 Sep 2026 22:57:55 +0200 Subject: [PATCH 49/71] wip --- .gitea/workflows/pr.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 9ee2246..67878b7 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -87,12 +87,16 @@ jobs: - name: Run Lua Language Server run: | + CONFIG_FULL_PATH=$(realpath ./.luarc.json) + echo "Config full path: $CONFIG_FULL_PATH" + + ./luals/bin/lua-language-server \ --check ./src \ --checklevel=Warning \ --loglevel=trace \ - --logpath="./luals/logs" - # --configpath="./.luarc.json" \ + --logpath="./luals/logs" \ + --configpath="$CONFIG_FULL_PATH" \ # --develop - name: Show Log -- 2.54.0 From ff95845ae835457b0f2d59da0fc2f548f6095c63 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Fri, 11 Sep 2026 11:41:20 +0200 Subject: [PATCH 50/71] wip --- .luarc.json | 26 +++++++--- src/classes/_baseClasses/Queue.lua | 47 ------------------- src/classes/capClasses/airGroups/AirGroup.lua | 8 +++- src/classes/capClasses/airGroups/CapGroup.lua | 3 +- .../capClasses/airGroups/InterceptGroup.lua | 4 +- .../capClasses/airGroups/SweepGroup.lua | 3 +- .../capClasses/detection/DetectionManager.lua | 7 ++- .../runwayBombing/RunwayBombingTracker.lua | 2 + src/classes/capClasses/taskings/CAP.lua | 4 ++ src/classes/capClasses/taskings/INTERCEPT.lua | 1 + src/classes/capClasses/taskings/RTB.lua | 3 ++ src/classes/persistence/Persistence.lua | 4 ++ src/classes/util/Util.lua | 4 +- 13 files changed, 54 insertions(+), 62 deletions(-) delete mode 100644 src/classes/_baseClasses/Queue.lua diff --git a/.luarc.json b/.luarc.json index b111901..bbb66c5 100644 --- a/.luarc.json +++ b/.luarc.json @@ -4,17 +4,26 @@ "version": "Lua 5.1" }, "workspace": { - "checkThirdParty": false + "checkThirdParty": false, + "maxPreload": 1600, + "preloadFileSize": 1000 }, "diagnostics": { "enable": true, "globals": [ "lfs" ], - "severity": { - "undefined-field": "Warning", - "unused-local": "Warning", - "unused-function": "Warning" + "groupSeverity": { + "duplicate": "Warning", + "global":"Warning", + "luadoc": "Warning", + "redefined": "Warning", + "strong": "Warning", + "type-check": "Warning", + "unbalanced" : "Warning", + "ambiguity": "Warning", + "strict": "Warning", + "unused": "Warning" }, "groupFileStatus": { "ambiguity": "Any", @@ -26,8 +35,11 @@ "strict": "Any", "type-check": "Any", "unbalanced": "Any", - "unused": "Any" - } + "unused": "Any", + "strong": "Any" + }, + "ignoredFiles": "Opened", + "libraryFiles": "Opened" }, "hint": { "enable": false diff --git a/src/classes/_baseClasses/Queue.lua b/src/classes/_baseClasses/Queue.lua deleted file mode 100644 index 44b0a92..0000000 --- a/src/classes/_baseClasses/Queue.lua +++ /dev/null @@ -1,47 +0,0 @@ - ----@class Queue ----@field private _items Array ----@field private _first number ----@field private _last number -local Queue = {} -Queue.__index = Queue - ----@return Queue -function Queue.new() - - local self = setmetatable({}, Queue) - self._items = {} - self._first = 1 - self._last = 0 - return self -end - ----@return nil -function Queue:push(item) - self._last = self._last + 1 - self._items[self._last] = item -end - ----@return any? -function Queue:pop() - if self._first > self._last then - return nil - end - - local item = self._items[self._first] - self._items[self._first] = nil - self._first = self._first + 1 - return item -end - - ----@return Array -function Queue:toList() - local items = {} - for i = self._first, self._last do - items[#items + 1] = self._items[i] - end - return items -end - -return Queue \ No newline at end of file diff --git a/src/classes/capClasses/airGroups/AirGroup.lua b/src/classes/capClasses/airGroups/AirGroup.lua index 0b869bf..79b3d58 100644 --- a/src/classes/capClasses/airGroups/AirGroup.lua +++ b/src/classes/capClasses/airGroups/AirGroup.lua @@ -107,8 +107,9 @@ function AirGroup:SetMissionPrivate(mission) local points = {} if mission and mission.params and mission.params.route and mission.params.route.points then - for _, wp in pairs(mission.params.route.points) do - if wp.x and wp.y then + local routePoints = mission.params.route.points --[[@as Array ]] + for _, wp in pairs(routePoints) do + if wp and wp.x and wp.y then table.insert(points, { x = wp.x, y = wp.y }) end end @@ -198,6 +199,8 @@ function AirGroup:SpawnInternal(force, withoutLoadout) end ---@param selfA AirGroup + ---@param time number + ---@return number? local function CheckLivenessTask(selfA, time) local interval = selfA:CheckLiveness() if not interval then return end @@ -263,6 +266,7 @@ function AirGroup:OnLastUnitLanded() ---@param data CheckGroupForRestartData ---@param time number + ---@return number? local checkGroupForRestart = function(data, time) local group = Group.getByName(data.self:GetName()) if not group then diff --git a/src/classes/capClasses/airGroups/CapGroup.lua b/src/classes/capClasses/airGroups/CapGroup.lua index decd1d8..edefc93 100644 --- a/src/classes/capClasses/airGroups/CapGroup.lua +++ b/src/classes/capClasses/airGroups/CapGroup.lua @@ -34,9 +34,10 @@ function CapGroup:IsBackup() return self._isBackup end +---@param stageID string ---@return string? function CapGroup:GetZoneIDWhenStageID(stageID) - return self._targetZoneIdPerStage[stageID] + return self._targetZoneIdPerStage[tostring(stageID)] end ---@return string? diff --git a/src/classes/capClasses/airGroups/InterceptGroup.lua b/src/classes/capClasses/airGroups/InterceptGroup.lua index 8bdac36..bee6313 100644 --- a/src/classes/capClasses/airGroups/InterceptGroup.lua +++ b/src/classes/capClasses/airGroups/InterceptGroup.lua @@ -60,6 +60,7 @@ end ---comment ---@param units Array +---@param zoneName string ---@param homeAirbase Airbase function InterceptGroup:SendToInterceptUnits(units, zoneName, homeAirbase) @@ -68,9 +69,10 @@ function InterceptGroup:SendToInterceptUnits(units, zoneName, homeAirbase) self:SetTargetUnits(units) end +---@param stageID string ---@return string? function InterceptGroup:GetZoneIDWhenStageID(stageID) - return self._targetZoneIdPerStage[stageID] + return self._targetZoneIdPerStage[tostring(stageID)] end ---@return string? diff --git a/src/classes/capClasses/airGroups/SweepGroup.lua b/src/classes/capClasses/airGroups/SweepGroup.lua index ee5988a..9e18b69 100644 --- a/src/classes/capClasses/airGroups/SweepGroup.lua +++ b/src/classes/capClasses/airGroups/SweepGroup.lua @@ -26,9 +26,10 @@ function SweepGroup.New(groupName, config, logger, spawnManager) return self end +---@param stageID string ---@return string? function SweepGroup:GetZoneIDWhenStageID(stageID) - return self._targetZoneIdPerStage[stageID] + return self._targetZoneIdPerStage[tostring(stageID)] end ---@return string? diff --git a/src/classes/capClasses/detection/DetectionManager.lua b/src/classes/capClasses/detection/DetectionManager.lua index 5cef8bd..b9873e9 100644 --- a/src/classes/capClasses/detection/DetectionManager.lua +++ b/src/classes/capClasses/detection/DetectionManager.lua @@ -8,6 +8,7 @@ DetectionManager.__index = DetectionManager ---@param logger Logger +---@return DetectionManager function DetectionManager.New(logger) local self = setmetatable({}, DetectionManager) @@ -24,6 +25,7 @@ function DetectionManager.New(logger) ---@param selfA DetectionManager ---@param time number + ---@return number? local updateDetectingUnitsTask = function(selfA, time) selfA:UpdateDetectingUnits() return time + 120 @@ -32,6 +34,7 @@ function DetectionManager.New(logger) ---@param selfA DetectionManager ---@param time number + ---@return number? local updateDetected = function(selfA, time) selfA:UpdateDetectedUnits() return time + 10 @@ -43,6 +46,7 @@ end ---@param unitName string ---@param coalitionSide CoalitionSide +---@return boolean function DetectionManager:IsUnitDetectedBy(unitName, coalitionSide) local coalitionString = tostring(coalitionSide) if not self._detectedUnits[coalitionString] then @@ -56,7 +60,8 @@ function DetectionManager:IsUnitDetectedBy(unitName, coalitionSide) return timer.getTime() - self._detectedUnits[coalitionString][unitName] < 20 end ----@return Array +---@param coalitionSide CoalitionSide +---@return Array detectedUnits function DetectionManager:GetDetectedUnitsBy(coalitionSide) local coalitionString = tostring(coalitionSide) if not self._detectedUnits[coalitionString] then diff --git a/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua b/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua index f77b958..0d8e907 100644 --- a/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua +++ b/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua @@ -56,7 +56,9 @@ end ---@field self RunwayBombingTracker ---@private +---@param time number ---@param weaponTrackingArgs WeaponTrackingArgs +---@return number? function RunwayBombingTracker.trackWeaponTask(weaponTrackingArgs, time) local weapon = weaponTrackingArgs.weapon diff --git a/src/classes/capClasses/taskings/CAP.lua b/src/classes/capClasses/taskings/CAP.lua index 77c2a5f..16f2da2 100644 --- a/src/classes/capClasses/taskings/CAP.lua +++ b/src/classes/capClasses/taskings/CAP.lua @@ -84,6 +84,7 @@ end ---@param airbase Airbase ---@param capZone SpearheadTriggerZone ---@param capConfig CapConfig +---@return table local GetOutboundTask = function(airbase, capZone, capConfig) local airbaseVec3 = airbase:getPoint() local airbaseVec2 = { x = airbaseVec3.x, y = airbaseVec3.z } @@ -125,6 +126,7 @@ end ---@param airbase Airbase ---@param capZone SpearheadTriggerZone ---@param capConfig CapConfig +---@return table function CAP.getAsMissionFromAirbase(groupName, airbase, capZone, capConfig) local points = { [1] = GetOutboundTask(airbase, capZone, capConfig), @@ -152,6 +154,7 @@ end ---@param airbase Airbase ---@param capZone SpearheadTriggerZone ---@param capConfig CapConfig +---@return table function CAP.getAsMission(groupName, airbase, capZone, capConfig) local points = { [1] = CAP.getAsTasking(groupName, airbase, capZone, capConfig), @@ -178,6 +181,7 @@ end ---@param airbase Airbase ---@param capZone SpearheadTriggerZone ---@param capConfig CapConfig +---@return table function CAP.getAsTasking(groupName, airbase, capZone, capConfig) local duration = math.random(capConfig:getMinDurationOnStation(), capConfig:getMaxDurationOnStation()) or 1500 diff --git a/src/classes/capClasses/taskings/INTERCEPT.lua b/src/classes/capClasses/taskings/INTERCEPT.lua index 6c90ec4..b780f51 100644 --- a/src/classes/capClasses/taskings/INTERCEPT.lua +++ b/src/classes/capClasses/taskings/INTERCEPT.lua @@ -11,6 +11,7 @@ local INTERCEPT = {} ---@param speed number? ---@param alt number? ---@param config CapConfig +---@return table function INTERCEPT.getMissionFromAirbase(groupName, interceptPoint, airbase, config, speed, alt) local airbaseVec3 = airbase:getPoint() diff --git a/src/classes/capClasses/taskings/RTB.lua b/src/classes/capClasses/taskings/RTB.lua index 6484a91..859cd32 100644 --- a/src/classes/capClasses/taskings/RTB.lua +++ b/src/classes/capClasses/taskings/RTB.lua @@ -7,6 +7,7 @@ local RTB = {} ---@param airbase Airbase ---@param missionPoint Vec2 ---@param capConfig CapConfig +---@return table function RTB.getAsMission(airbase, missionPoint, capConfig) return { id = "Mission", @@ -113,6 +114,7 @@ end ---comment ---@param airbase Airbase ---@param missionPoint Vec2 +---@return table ---@param capConfig CapConfig function RTB.getApproachPoint(airbase, missionPoint, capConfig) @@ -147,6 +149,7 @@ function RTB.getApproachPoint(airbase, missionPoint, capConfig) end ---@param airbase Airbase +---@return table function RTB.getInitialPoint(airbase) local point = calcInitialPoint(airbase) return { diff --git a/src/classes/persistence/Persistence.lua b/src/classes/persistence/Persistence.lua index 7919936..a127e80 100644 --- a/src/classes/persistence/Persistence.lua +++ b/src/classes/persistence/Persistence.lua @@ -210,6 +210,10 @@ do local lastFile = getLastFileOrDefault(dir--[[@as string]], matchingPart, fileName) + if lastFile == nil then + lastFile = fileName + end + local fileSplit = Util.split_string(lastFile, ".") fileSplit[#fileSplit-1] = tostring(tonumber(fileSplit[#fileSplit-1]) + 1) fileName = table.concat(fileSplit, ".") diff --git a/src/classes/util/Util.lua b/src/classes/util/Util.lua index 697e7b6..d6a80d9 100644 --- a/src/classes/util/Util.lua +++ b/src/classes/util/Util.lua @@ -4,7 +4,7 @@ do -- INIT UTIL ---splits a string in sub parts by seperator ---@param input string ---@param seperator string - ---@return table result list of strings + ---@return Array result list of strings function UTIL.split_string(input, seperator) if seperator == nil then seperator = " " @@ -237,7 +237,7 @@ do -- INIT UTIL return ((vec1Norm.x * vec2Norm.x) + (vec1Norm.y * vec2Norm.y) + (vec1Norm.z * vec2Norm.z)) end - + ---@param polygon Array of pairs { x, y } ---@param x number X location ---@param y number Y location -- 2.54.0 From 5ec7d18fa860956b408fdcb7f501b320e1511a22 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Fri, 11 Sep 2026 11:44:32 +0200 Subject: [PATCH 51/71] wip --- .gitea/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 67878b7..92f2bf0 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -24,7 +24,7 @@ jobs: luaVersion: ${{ env.LUA_VERSION }} - name: Compile Spearhead - uses: https://git.dutchie031.com/dutchie031/DcsMissionScriptingTools/github-action@action/v0 + uses: https://git.dutchie031.com/dutchie031/DcsMissionScriptingTools/github-actions/bundle-script@bundle-script/v1 with: source-root: ./src output-file: ./output/spearhead.lua -- 2.54.0 From 05d47aa96927a97bedf4c74027f14ef75df8068c Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sat, 19 Sep 2026 22:27:57 +0200 Subject: [PATCH 52/71] All luals findings solved --- src/classes/capClasses/GlobalCapManager.lua | 2 + src/classes/capClasses/airGroups/AirGroup.lua | 2 +- .../capClasses/airGroups/InterceptGroup.lua | 4 ++ .../capClasses/airGroups/SweepGroup.lua | 2 +- .../runwayBombing/RunwayBombingTracker.lua | 5 +- src/classes/capClasses/taskings/CAP.lua | 4 ++ src/classes/capClasses/taskings/INTERCEPT.lua | 2 +- src/classes/capClasses/taskings/RTB.lua | 2 + src/classes/capClasses/taskings/SWEEP.lua | 5 ++ src/classes/debug/DebugMenu.lua | 2 +- src/classes/fleetClasses/FleetGroup.lua | 18 +++-- src/classes/helpers/MizGroupsManager.lua | 37 ++++++++-- src/classes/helpers/SpawnManager.lua | 22 +++--- src/classes/persistence/Persistence.lua | 3 +- src/classes/spearhead_db.lua | 33 ++++++--- src/classes/spearhead_events.lua | 60 +++++++++++----- src/classes/spearhead_routeutil.lua | 15 ++-- .../stageClasses/GlobalStageManager.lua | 13 +++- .../stageClasses/Groups/SpearheadGroup.lua | 4 +- .../stageClasses/SpecialZones/StageBase.lua | 2 + .../SpecialZones/abstract/BuildableZone.lua | 2 + src/classes/stageClasses/StageLane.lua | 21 +++--- .../stageClasses/Stages/BaseStage/Stage.lua | 4 ++ .../drawings/helper/DrawingHelper.lua | 7 +- .../stageClasses/helpers/BattleManager.lua | 8 ++- .../helpers/MissionCommandsHelper.lua | 4 +- .../helpers/SupplyConfigHelper.lua | 3 +- .../helpers/SupplyUnitsTracker.lua | 42 ++++++----- .../missions/BuildableMission.lua | 16 +++-- .../missions/RunwayStrikeMission.lua | 12 +++- .../stageClasses/missions/ZoneMission.lua | 10 ++- .../missions/baseMissions/Mission.lua | 1 + src/classes/util/DcsUtil.lua | 71 +++++++++++++------ src/classes/util/MissionEditorWarnings.lua | 10 ++- src/classes/util/Util.lua | 57 ++++++++++----- 35 files changed, 356 insertions(+), 149 deletions(-) diff --git a/src/classes/capClasses/GlobalCapManager.lua b/src/classes/capClasses/GlobalCapManager.lua index 94c9014..e5ed0f0 100644 --- a/src/classes/capClasses/GlobalCapManager.lua +++ b/src/classes/capClasses/GlobalCapManager.lua @@ -6,7 +6,9 @@ local CapAirbase = require("classes.capClasses.CapAirbase") ---@class GlobalCapManager local GlobalCapManager = {} do + ---@type table local airbasesPerStage = {} + ---@type table local allAirbasesByName = {} local initiated = false diff --git a/src/classes/capClasses/airGroups/AirGroup.lua b/src/classes/capClasses/airGroups/AirGroup.lua index 79b3d58..c0c272c 100644 --- a/src/classes/capClasses/airGroups/AirGroup.lua +++ b/src/classes/capClasses/airGroups/AirGroup.lua @@ -5,7 +5,7 @@ local GlobalConfig = require("classes.configuration.GlobalConfig") local CustomDrawing = require("classes.stageClasses.drawings.CustomDrawing") local DrawingHelper = require("classes.stageClasses.drawings.helper.DrawingHelper") ----@class AirGroup : OnUnitLostListener +---@class AirGroup : OnUnitLostListener, OnGroupRTBListener, OnGroupRTBInTenListener, OnLandEventListener, OnGroupOnStationListener ---@field protected _logger Logger ---@field protected _groupName string ---@field protected _groupType AirGroupType diff --git a/src/classes/capClasses/airGroups/InterceptGroup.lua b/src/classes/capClasses/airGroups/InterceptGroup.lua index bee6313..652ca5b 100644 --- a/src/classes/capClasses/airGroups/InterceptGroup.lua +++ b/src/classes/capClasses/airGroups/InterceptGroup.lua @@ -93,6 +93,9 @@ function InterceptGroup:SetTargetUnits(unitNames) end) end + ---@param selfA InterceptGroup + ---@param time number + ---@return number? local updateContinous = function(selfA, time) local next = selfA:UpdateTask() if next then @@ -104,6 +107,7 @@ function InterceptGroup:SetTargetUnits(unitNames) self._updateTaskID = timer.scheduleFunction(updateContinous, self, timer.getTime() + 30) end +---@param unit Unit function InterceptGroup:RemoveTargetUnit(unit) if not unit then return end diff --git a/src/classes/capClasses/airGroups/SweepGroup.lua b/src/classes/capClasses/airGroups/SweepGroup.lua index 9e18b69..bfc1d0b 100644 --- a/src/classes/capClasses/airGroups/SweepGroup.lua +++ b/src/classes/capClasses/airGroups/SweepGroup.lua @@ -4,7 +4,7 @@ local Util = require("classes.util.Util") local MissionEditorWarner = require("classes.util.MissionEditorWarnings") ---@class SweepGroup : AirGroup ----@field _targetZoneIdPerStage table +---@field _targetZoneIdPerStage table ---@field _currentTargetZoneID string? local SweepGroup = {} SweepGroup.__index = SweepGroup diff --git a/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua b/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua index 0d8e907..185f8d2 100644 --- a/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua +++ b/src/classes/capClasses/runwayBombing/RunwayBombingTracker.lua @@ -104,11 +104,10 @@ function RunwayBombingTracker:OnWeaponImpact(weaponDesc, impactPoint) self._logger:debug("RunwayBombingTracker:OnWeaponImpact") - local warhead = weaponDesc.warhead - local explosiveMass = warhead.explosiveMass or warhead.shapedExplosiveMass + local warhead = weaponDesc.warhead --[[@as table]] + local explosiveMass = (warhead.explosiveMass or warhead.shapedExplosiveMass) --[[@as number]] for _, strikeMission in pairs(self.trackedRunways) do - local zone= strikeMission:GetRunwayZone() if Util.is3dPointInZone({ x = impactPoint.x, z = impactPoint.y, y = 0 }, zone) then diff --git a/src/classes/capClasses/taskings/CAP.lua b/src/classes/capClasses/taskings/CAP.lua index 16f2da2..174b8d3 100644 --- a/src/classes/capClasses/taskings/CAP.lua +++ b/src/classes/capClasses/taskings/CAP.lua @@ -7,6 +7,7 @@ local CAP = {} ---@param attackHelos boolean ---@return table local function GetCAPTargetTypes(attackHelos) + ---@type Array local targetTypes = { [1] = "Planes", } @@ -53,7 +54,10 @@ local function GetCAPPointFromTriggerZone(airBase, capZone) ---@type Vec2 local baseVec2 = { x = baseVec3.x, y = baseVec3.z } + ---@type Vec2 local pointA = capZone.verts[furthestA] + + ---@type Vec2 local pointB = capZone.verts[furthestB] local furthest = pointA local closest = pointB diff --git a/src/classes/capClasses/taskings/INTERCEPT.lua b/src/classes/capClasses/taskings/INTERCEPT.lua index b780f51..d801f38 100644 --- a/src/classes/capClasses/taskings/INTERCEPT.lua +++ b/src/classes/capClasses/taskings/INTERCEPT.lua @@ -93,7 +93,7 @@ end ---@param currentPoint Vec2 ---@param targetPosition Vec2 ---@param targetUnit Unit ----@param airbase any +---@param airbase Airbase ---@param config any ---@param speed number? ---@param alt number? diff --git a/src/classes/capClasses/taskings/RTB.lua b/src/classes/capClasses/taskings/RTB.lua index 859cd32..dda92b7 100644 --- a/src/classes/capClasses/taskings/RTB.lua +++ b/src/classes/capClasses/taskings/RTB.lua @@ -173,6 +173,8 @@ function RTB.getInitialPoint(airbase) } end +---@param airbase Airbase +---@return table function RTB.getLandingPoint(airbase) local basePoint = airbase:getPoint() return { diff --git a/src/classes/capClasses/taskings/SWEEP.lua b/src/classes/capClasses/taskings/SWEEP.lua index 61e12aa..a77425a 100644 --- a/src/classes/capClasses/taskings/SWEEP.lua +++ b/src/classes/capClasses/taskings/SWEEP.lua @@ -7,6 +7,7 @@ local SWEEP = {} ---@param attackHelos boolean ---@return table local function GetCAPTargetTypes(attackHelos) + ---@type Array local targetTypes = { [1] = "Planes", } @@ -49,7 +50,9 @@ local function GetCAPPointFromTriggerZone(airBase, capZone) ---@type Vec2 local baseVec2 = { x = baseVec3.x, y = baseVec3.z } + ---@type Vec2 local pointA = capZone.verts[furthestA] + ---@type Vec2 local pointB = capZone.verts[furthestB] local furthest = pointA local closest = pointB @@ -80,6 +83,7 @@ end ---@param airbase Airbase ---@param capZone SpearheadTriggerZone ---@param capConfig CapConfig +---@return table local GetOutboundTask = function(airbase, capZone, capConfig) local airbaseVec3 = airbase:getPoint() local airbaseVec2 = { x = airbaseVec3.x, y = airbaseVec3.z } @@ -121,6 +125,7 @@ end ---@param airbase Airbase ---@param capZone SpearheadTriggerZone ---@param capConfig CapConfig +---@return table function SWEEP.getAsMissionFromAirbase(groupName, airbase, capZone, capConfig) local pointA, pointB, pointC = SWEEP.getAsTasking(groupName, airbase, capZone, capConfig) diff --git a/src/classes/debug/DebugMenu.lua b/src/classes/debug/DebugMenu.lua index 97539a2..b6002ad 100644 --- a/src/classes/debug/DebugMenu.lua +++ b/src/classes/debug/DebugMenu.lua @@ -21,7 +21,7 @@ function DebugMenu:RegisterMenus() missionCommands.addSubMenu(menuName, {}) local refresh = function(params) - local selfA = params.self + local selfA = params.self --[[@as DebugMenu]] selfA:RefreshMenu() end missionCommands.addCommand("Refresh Menu", debugMenuPath, refresh, { self = self }) diff --git a/src/classes/fleetClasses/FleetGroup.lua b/src/classes/fleetClasses/FleetGroup.lua index 12b63b3..28f124d 100644 --- a/src/classes/fleetClasses/FleetGroup.lua +++ b/src/classes/fleetClasses/FleetGroup.lua @@ -10,7 +10,7 @@ local SpearheadEvents = require("classes.spearhead_events") ---@field private fleetNameIdentifier string ---@field private targetZonePerStage table ---@field private currentTargetZone string ----@field private pointsPerZone table +---@field private pointsPerZone table local FleetGroup = {} FleetGroup.__index = FleetGroup @@ -108,7 +108,13 @@ function FleetGroup.new(fleetGroupName, database, logger) for i = first, second do self.targetZonePerStage[tostring(i)] = zoneName end - self.pointsPerZone[zoneName] = { pointA = { x = pointA.x, z = pointA.y, y = 0 }, pointB = { x = pointB.x, z = pointB.y, y = 0} } + ---@type {pointA: Vec3, pointB: Vec3} + local entry = { + pointA = {x = pointA.x, z = pointA.y, y = 0}, + pointB = {x = pointB.x, z = pointB.y, y = 0} + } + + self.pointsPerZone[zoneName] = entry else MissionEditorWarning.Add("CARRIERROUTE zone stage numbers not in the format _[-]: " .. zoneName) end @@ -125,10 +131,10 @@ function FleetGroup.new(fleetGroupName, database, logger) end local SetTaskAsync = function(input, _) - local targetZone = input.targetZone - local task = input.task - local groupName = input.groupName - local l_logger = input.logger + local targetZone = input.targetZone --[[@as string]] + local task = input.task --[[@as table]] + local groupName = input.groupName --[[@as string]] + local l_logger = input.logger --[[@as Logger]] local group = Group.getByName(groupName) if group then diff --git a/src/classes/helpers/MizGroupsManager.lua b/src/classes/helpers/MizGroupsManager.lua index f33a723..c5aef3a 100644 --- a/src/classes/helpers/MizGroupsManager.lua +++ b/src/classes/helpers/MizGroupsManager.lua @@ -15,23 +15,45 @@ MizGroupsManager._groupNames = {} MizGroupsManager._spawnTemplateData = {} do --init - for _, coalition_data in pairs(env.mission.coalition) do + + ---@param coalition_name string + ---@return Coalition + local getCoalitionData = function(coalition_name) + return env.mission.coalition[coalition_name] + end + + ---@param country Country + ---@param key string + ---@return Groups? + local getGroupsData = function(country, key) + if key == "planes" then return country.plane end + if key == "helicopters" then return country.helicopter end + if key == "ground" then return country.vehicle end + if key == "ships" then return country.ship end + if key == "statics" then return country.static end + return nil + end + + for _, coalition_name in ipairs({"neutral", "blue", "red"}) do + local coalition_data = getCoalitionData(coalition_name) if coalition_data.country then for _, country_data in pairs(coalition_data.country) do - for category_name, categorydata in pairs(country_data) do + for _, category_name in pairs(DcsUtil.getAllGroupCategoryNames()) do local category_id = DcsUtil.stringToGroupCategory(category_name) - if category_id ~= nil and type(categorydata) == "table" and categorydata.group ~= nil and type(categorydata.group) == "table" then - for _, group in pairs(categorydata.group) do - local name = group.name + local groups_data = getGroupsData(country_data, category_name) + + if category_id ~= nil and type(groups_data) == "table" and groups_data.group ~= nil and type(groups_data.group) == "table" then + for _, group in pairs(groups_data.group) do + local name = group.name --[[@as string]] local skippable = false local isStatic = false if category_id == DcsUtil.GroupCategory.STATIC then isStatic = true - local unit = group.units[1] + local unit = group.units[1] --[[@as table]] if unit and unit.category == "Heliports" then skippable = true elseif unit and unit.name then - name = unit.name + name = unit.name --[[@as string]] else env.error("Group " .. name .. " has no units, skipping it.") skippable = true @@ -71,6 +93,7 @@ function MizGroupsManager.IsGroupStatic(groupName) return nil end +---@param groupName string ---@return SpawnData? function MizGroupsManager.getSpawnTemplateData(groupName) return MizGroupsManager._spawnTemplateData[groupName] diff --git a/src/classes/helpers/SpawnManager.lua b/src/classes/helpers/SpawnManager.lua index 812faf4..1ac88c9 100644 --- a/src/classes/helpers/SpawnManager.lua +++ b/src/classes/helpers/SpawnManager.lua @@ -16,11 +16,11 @@ SpawnManager.__index = SpawnManager ---@field uncontrolled boolean? Sets the group to be uncontrolled on spawn ---@param logger Logger +---@return SpawnManager function SpawnManager.new(logger) local self = setmetatable({}, SpawnManager) self._logger = logger - self._persistedUnits = {} -- Stores units that should be persisted by name return self @@ -133,8 +133,9 @@ do --- privates ]] if spawnTemplate and spawnTemplate["units"] then - for _, unit in pairs(spawnTemplate["units"]) do - local name = unit["name"] + local units = spawnTemplate["units"] --[[@as Array]] + for _, unit in pairs(units) do + local name = unit["name"] --[[@as string]] SpearheadEvents.addOnUnitLostEventListener(name, self) local state = Persistence.UnitState(name) @@ -146,16 +147,17 @@ do --- privates if override and override.emptyLoadouts == true then if unit["payload"] and unit["payload"]["pylons"] then - unit["payload"]["pylons"] = {} + local payload = unit["payload"] --[[@as table]] + payload["pylons"] = {} --[[@as table]] end end if unit["parking"] then - unit["parking_landing"] = unit["parking"] + unit["parking_landing"] = unit["parking"] --[[@as number]] end if unit["parking_id"] then - unit["parking_landing_id"] = unit["parking_id"] + unit["parking_landing_id"] = unit["parking_id"] --[[@as number]] end end @@ -210,9 +212,11 @@ do --- privates spawnTemplate["x"] = persistentState.pos.x spawnTemplate["y"] = persistentState.pos.z if spawnTemplate["units"] and spawnTemplate["units"][1] then - spawnTemplate["units"][1]["x"] = persistentState.pos.x - spawnTemplate["units"][1]["y"] = persistentState.pos.z - spawnTemplate["units"][1]["heading"] = persistentState.heading or 0 + local units = spawnTemplate["units"] --[[@as Array
]] + local firstUnit = units[1] --[[@as table]] + firstUnit["x"] = persistentState.pos.x --[[@as number]] + firstUnit["y"] = persistentState.pos.z --[[@as number]] + firstUnit["heading"] = persistentState.heading or 0 --[[@as number]] end end end diff --git a/src/classes/persistence/Persistence.lua b/src/classes/persistence/Persistence.lua index a127e80..2684f90 100644 --- a/src/classes/persistence/Persistence.lua +++ b/src/classes/persistence/Persistence.lua @@ -187,7 +187,8 @@ do local userFileName = SpearheadConfig.Persistence.fileName local split = Util.split_string(userFileName, ".") - if not split and #split < 3 then + if not split or #split < 3 then + split = split or {} split[#split+1] = "0" split[#split+1] = "spearhead" end diff --git a/src/classes/spearhead_db.lua b/src/classes/spearhead_db.lua index 2c1b1e9..e62312a 100644 --- a/src/classes/spearhead_db.lua +++ b/src/classes/spearhead_db.lua @@ -215,8 +215,11 @@ function Database.New(Logger) 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 + if layer_object.primitiveType == "TextBox" then + layer_object = layer_object --[[@as TextBox]] + local number = tonumber(layer_object.text) + airbaseData.buildingKilos = number + end end end end @@ -263,9 +266,12 @@ function Database.New(Logger) local zone = DcsUtil.getZoneByName(stageZoneName) local vec2 = { x = layer_object.mapX, y = layer_object.mapY } if zone and Util.is2dPointInZone(vec2, zone) == true then - local description = layer_object.text - if description and description ~= "" then - stageData.StageBriefing = description + if layer_object.primitiveType == "TextBox" then + layer_object = layer_object --[[@as TextBox]] + local description = layer_object.text + if description and description ~= "" then + stageData.StageBriefing = description + end end end end @@ -468,6 +474,7 @@ function Database.New(Logger) return self end +---@type table local is_group_taken = {} local getAvailableGroups = function() @@ -625,8 +632,9 @@ function Database:loadBlueSamUnits() for _, layer_object in pairs(layer.objects) do local vec2 = { x = layer_object.mapX, y = layer_object.mapY } - if triggerZone and Util.is2dPointInZone(vec2, triggerZone) then + 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 + layer_object = layer_object --[[@as TextBox]] local description = layer_object.text if description and description ~= "" then samData.briefing = description @@ -725,8 +733,9 @@ function Database:LoadZoneData(missionZoneName) for _, layer_object in pairs(layer.objects) do local vec2 = { x = layer_object.mapX, y = layer_object.mapY } - if triggerZone and Util.is2dPointInZone(vec2, triggerZone) then + 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 + layer_object = layer_object --[[@as TextBox]] local description = layer_object.text if description and description ~= "" then self._tables.MissionZoneData[missionZoneName].description = description @@ -781,7 +790,8 @@ function Database:loadFarpData() for _, layer_object in pairs(layer.objects) do local vec2 = { x = layer_object.mapX, y = layer_object.mapY } - if triggerZone and Util.is2dPointInZone(vec2, triggerZone) then + 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 local description = layer_object.text if description and description ~= "" then @@ -950,6 +960,7 @@ function Database:getBriefingForStage(stagename) return stageZone.StageBriefing or "" end +---@param stagename string ---@return Array function Database:getMissionsForStage(stagename) local stageZone = self._tables.StageZones[stagename] @@ -957,6 +968,7 @@ function Database:getMissionsForStage(stagename) return stageZone.MissionZones end +---@param stagename string ---@return Array function Database:getRandomMissionsForStage(stagename) local stageZone = self._tables.StageZones[stagename] @@ -964,13 +976,14 @@ function Database:getRandomMissionsForStage(stagename) return stageZone.RandomMissionZones end +---@param missionZoneName string ---@return MissionZoneData? function Database:getMissionDataForZone(missionZoneName) return self._tables.MissionZoneData[missionZoneName] end ---@param stageName string ----@return table result airbase Names +---@return Array result airbase Names function Database:getAirbaseNamesInStage(stageName) local stageData = self._tables.StageZones[stageName] if not stageData then return {} end @@ -984,6 +997,7 @@ function Database:getFarpNamesInStage(stageName) return stageData.FarpZones or {} end +---@param farpZoneName string ---@return FarpZoneData? function Database:getFarpDataForZone(farpZoneName) local farpData = self._tables.FarpZoneData[farpZoneName] @@ -999,6 +1013,7 @@ function Database:getAirbaseDataForZone(baseName) return baseData end +---@param stageName string ---@return string? function Database:getStageBriefingForStage(stageName) local stageData = self._tables.StageZones[stageName] diff --git a/src/classes/spearhead_events.lua b/src/classes/spearhead_events.lua index ab7f495..83fb992 100644 --- a/src/classes/spearhead_events.lua +++ b/src/classes/spearhead_events.lua @@ -32,7 +32,9 @@ do ---@field OnStageNumberChanged fun(self:OnStageChangedListener, number:integer, laneIdentifier:string?) do -- STAGE NUMBER CHANGED + ---@type Array local OnStageNumberChangedListeners = {} + ---@type Array local OnStageNumberChangedHandlers = {} ---Add a stage zone number changed listener ---@param listener OnStageChangedListener object with function OnStageNumberChanged(self, number, stageLaneIdentifier) @@ -47,6 +49,7 @@ do ---@class OnStageNumberChangeCompleteListener ---@field OnStageNumberChangeComplete fun(self:OnStageNumberChangeCompleteListener, number:integer, laneIdentifier:string?) + ---@type Array local OnStageNumberChangeCompleteListeners = {} ---@param listener OnStageNumberChangeCompleteListener SpearheadEvents.AddStageNumberChangeCompleteListener = function(listener) @@ -110,6 +113,9 @@ do table.insert(onWeaponFiredListeners, weaponFiredListener) end + ---@param unit Unit + ---@param weapon Weapon + ---@param target Unit? local triggerWeaponFired = function(unit, weapon, target) for _, callable in pairs(onWeaponFiredListeners) do local _, err = pcall(function() @@ -122,11 +128,14 @@ do end end + ---@class OnLandEventListener + ---@field OnUnitLanded fun(self:OnLandEventListener, initiatorUnit:Unit, airbase:Airbase) + ---@type table> 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) + ---@param landListener OnLandEventListener table with function OnUnitLanded(self, initiatorUnit, airbase) SpearheadEvents.addOnUnitLandEventListener = function(unitName, landListener) if type(landListener) ~= "table" then warn("Event handler not of type table/object") @@ -162,6 +171,11 @@ do end do -- ON RTB + + ---@class OnGroupRTBListener + ---@field OnGroupRTB fun(self:OnGroupRTBListener, groupName:string) + + ---@type table> local OnGroupRTBListeners = {} ---Adds a function to the events listener that triggers when a group publishes themselves RTB. ---This is only available when a ROUTE is created via the Spearhead.RouteUtil @@ -197,11 +211,15 @@ do end end + ---@class OnGroupRTBInTenListener + ---@field OnGroupRTBInTen fun(self:OnGroupRTBInTenListener, groupName:string) + + ---@type table> local OnGroupRTBInTenListeners = {} ---Adds a function to the events listener that triggers when a group publishes themselves RTB. ---This is only available when a ROUTE is created via the Spearhead.RouteUtil ---@param groupName string the groupname to expect - ---@param handlingObject table object with OnGroupRTBInTen(self, groupName) + ---@param handlingObject OnGroupRTBInTenListener object with OnGroupRTBInTen(self, groupName) SpearheadEvents.addOnGroupRTBInTenListener = function(groupName, handlingObject) if type(handlingObject) ~= "table" then warn("Event handler not of type table/object") @@ -234,10 +252,17 @@ do end do -- ON Station + + ---@class OnGroupOnStationListener + ---@field OnGroupOnStation fun(self:OnGroupOnStationListener, groupName:string) + + ---@type table> local OnGroupOnStationListeners = {} + ---Adds a function to the events listener that triggers when a group publishes themselves RTB. ---This is only available when a ROUTE is created via the Spearhead.RouteUtil ---@param groupName string the groupname to expect + ---@param handlingObject OnGroupOnStationListener object with OnGroupOnStation(self, groupName) SpearheadEvents.addOnGroupOnStationListener = function(groupName, handlingObject) if type(handlingObject) ~= "table" then warn("Event handler not of type table/object") @@ -270,15 +295,18 @@ do end do -- PLAYER ENTER UNIT + ---@class OnPlayerEnterUnitListener + ---@field OnPlayerEntersUnit fun(self:OnPlayerEnterUnitListener, unit:Unit) + + ---@type Array local playerEnterUnitListeners = {} ---comment - ---@param listener table object with OnPlayerEntersUnit(self, unit) + ---@param listener OnPlayerEnterUnitListener object with OnPlayerEntersUnit(self, unit) SpearheadEvents.AddOnPlayerEnterUnitListener = function(listener) if type(listener) ~= "table" then warn("Unit lost Event listener not of type table/object") return end - table.insert(playerEnterUnitListeners, listener) end @@ -315,8 +343,8 @@ do local e = {} function e:onEvent(event) if event.id == world.event.S_EVENT_LAND or event.id == world.event.S_EVENT_RUNWAY_TOUCH then - local unit = event.initiator - local airbase = event.place + local unit = event.initiator --[[@as Unit]] + local airbase = event.place --[[@as Airbase]] if unit ~= nil then local name = unit:getName() if onLandEventListeners[name] then @@ -336,7 +364,7 @@ do event.id == world.event.S_EVENT_CRASH or event.id == world.event.S_EVENT_EJECTION or event.id == world.event.S_EVENT_UNIT_LOST then - local object = event.initiator + local object = event.initiator --[[@as Unit]] if object and object.getName then logDebug("Receiving death event from: " .. object:getName()) @@ -355,15 +383,11 @@ do end end - if event.id == world.event.S_EVENT_EJECTION then - - end - if event.id == world.event.S_EVENT_SHOT then - local shooter = event.initiator - local weapon = event.weapon - local target = event.target + local shooter = event.initiator --[[@as Unit]] + local weapon = event.weapon --[[@as Weapon]] + local target = event.target --[[@as Unit?]] triggerWeaponFired(shooter, weapon, target) end @@ -372,10 +396,14 @@ do Persistence.UpdateNow() end + ---@type table local AI_GROUPS = {} + ---@param unit Unit + ---@param _ any local function CheckAndTriggerSpawnAsync(unit, _) - + ---@param checkUnit Unit + ---@return boolean, string? local function isPlayer(checkUnit) if checkUnit == nil then return false, "unit is nil" end if checkUnit.getGroup == nil then return false, 'no get group function in unit object, most likely static' end @@ -405,8 +433,6 @@ do if isPlayer(unit) == true then SpearheadEvents.TriggerPlayerEntersUnit(unit) end - - return nil end if event.id == world.event.S_EVENT_BIRTH then diff --git a/src/classes/spearhead_routeutil.lua b/src/classes/spearhead_routeutil.lua index 717ee5b..82c7c47 100644 --- a/src/classes/spearhead_routeutil.lua +++ b/src/classes/spearhead_routeutil.lua @@ -8,6 +8,7 @@ do --setup route util ---@param attackHelos boolean ---@return table local function GetCAPTargetTypes(attackHelos) + ---@type table local targetTypes = { [1] = "Planes", } @@ -53,8 +54,9 @@ do --setup route util ---comment ---@param groupName string - ---@param position table { x, y} + ---@param position Vec3 ---@param altitude number + ---@param deviationdistance number ---@param speed number ---@param duration number ---@param engageHelos boolean @@ -181,7 +183,7 @@ do --setup route util end ---comment - ---@param position table { x, y} + ---@param position Vec3 ---@param altitude number ---@param speed number ---@param childTasks table @@ -210,7 +212,8 @@ do --setup route util ---comment ---@param groupName string groupName you're creating this route for ---@param airdromeId number airdromeId - ---@param capPoint table { x, z } + ---@param capPoint Vec3 + ---@param racetrackSecondPoint Vec3? ---@param altitude number ---@param speed number ---@param durationOnStation number @@ -304,6 +307,7 @@ do --setup route util end local group = Group.getByName(groupName) + ---@type Vec3? local pos; local i = 1 if group == nil then @@ -393,6 +397,9 @@ do --setup route util }, "" end + ---@param pointA Vec3 + ---@param pointB Vec3 + ---@return table, string? ROUTE_UTIL.CreateCarrierRacetrack = function(pointA, pointB) return { id = "Mission", @@ -461,7 +468,7 @@ do --setup route util } } } - }, "" + }, nil end end diff --git a/src/classes/stageClasses/GlobalStageManager.lua b/src/classes/stageClasses/GlobalStageManager.lua index 7b08a85..879ea93 100644 --- a/src/classes/stageClasses/GlobalStageManager.lua +++ b/src/classes/stageClasses/GlobalStageManager.lua @@ -327,12 +327,13 @@ function GlobalStageManager:OnStageNumberChangeComplete(stageNumber, stageLaneId if stageLaneIdentifier ~= nil then return end self.logger:debug("Stage number change complete to: " .. tostring(stageNumber)) + ---@type Array local groups = {} for _, player in pairs(DcsUtil.getAllPlayerUnits()) do local group = player:getGroup() if group then - groups[group:getID()] = group + table.insert(groups, group) end end @@ -369,8 +370,11 @@ end function GlobalStageManager:PrintMermaidStage() local lanes = self._stageRepository:getAllStageLanes() + ---@type table local nodes = {} + ---@type table local edges = {} + ---@type table> local stageIndicesByLane = {} -- Track all stage indices per lane local mainLaneId = "default" @@ -403,7 +407,9 @@ function GlobalStageManager:PrintMermaidStage() "#9B59B6", -- 25: Amethyst "#1ABC9C", -- 26: Turquoise } + ---@type table local laneColorMap = {} -- Map lane ID to color + ---@type number local colorIndex = 1 -- Build nodes and collect all stage indices per lane @@ -430,6 +436,7 @@ function GlobalStageManager:PrintMermaidStage() local stageName = stage.stageName or stage.zoneName -- Generate bracket label: [1], [2] for default, [w1], [e2] for other lanes + ---@type string local bracketLabel if laneId == "default" then bracketLabel = "[" .. stageIndex .. "]" @@ -496,7 +503,7 @@ function GlobalStageManager:PrintMermaidStage() for _, lane in ipairs(lanes) do if lane:IsDefaultStageLane() == false then local sideId = lane:GetStageLaneIdentifier() - local sideIndices = stageIndicesByLane[sideId] + local sideIndices = stageIndicesByLane[sideId] or {} --[[@as Array]] -- For each stage in the side lane for _, stageIdx in ipairs(sideIndices) do @@ -528,7 +535,7 @@ function GlobalStageManager:PrintMermaidStage() for _, lane in ipairs(lanes) do if lane:IsDefaultStageLane() == false then local sideId = lane:GetStageLaneIdentifier() - local sideIndices = stageIndicesByLane[sideId] + local sideIndices = stageIndicesByLane[sideId] or {} --[[@as Array]] -- Find the appropriate gate node for this side lane -- Use first stage >= nextIdx if it exists, otherwise use the highest stage diff --git a/src/classes/stageClasses/Groups/SpearheadGroup.lua b/src/classes/stageClasses/Groups/SpearheadGroup.lua index c5f8d41..a1e17d2 100644 --- a/src/classes/stageClasses/Groups/SpearheadGroup.lua +++ b/src/classes/stageClasses/Groups/SpearheadGroup.lua @@ -91,9 +91,9 @@ function SpearheadGroup:GetCoalition() end ---comment ----@return table result list of objects +---@return Array result list of objects function SpearheadGroup:GetObjects() - + ---@type Array local result = {} if self._isStatic == true then local staticObject = StaticObject.getByName(self._groupName) diff --git a/src/classes/stageClasses/SpecialZones/StageBase.lua b/src/classes/stageClasses/SpecialZones/StageBase.lua index c738f43..7e35f69 100644 --- a/src/classes/stageClasses/SpecialZones/StageBase.lua +++ b/src/classes/stageClasses/SpecialZones/StageBase.lua @@ -113,6 +113,7 @@ end function StageBase:SpawnRedUnits() ---comment ---@param groups Array + ---@return number|nil local spawnAsync = function(groups) for _, group in pairs(groups) do group:Spawn() @@ -142,6 +143,7 @@ end function StageBase:SpawnBlueUnits() ---comment ---@param groups Array + ---@return number|nil local spawnAsync = function(groups) for _, group in pairs(groups) do group:Spawn() diff --git a/src/classes/stageClasses/SpecialZones/abstract/BuildableZone.lua b/src/classes/stageClasses/SpecialZones/abstract/BuildableZone.lua index fe1296f..abff446 100644 --- a/src/classes/stageClasses/SpecialZones/abstract/BuildableZone.lua +++ b/src/classes/stageClasses/SpecialZones/abstract/BuildableZone.lua @@ -37,6 +37,7 @@ function BuildableZone:New(targetZone, kilosRequired, crateType, buildableGroup ---@param params UnpackCrateParam ---@param time number + ---@return number|nil local startUnpackingCrate = function(params, time) local unpacked = params.unpackedKilos + (params.kilosPerSecond * 2) local alreadySpawned = params.unpackedItems / params.groupsPerKilo @@ -104,6 +105,7 @@ function BuildableZone:OnCrateDroppedOff(_, kilos) ---@param params UnpackCrateParam ---@param time number + ---@return number|nil local startUnpackingCrate = function(params, time) local unpacked = params.unpackedKilos + (params.kilosPerSecond * 2) local alreadySpawned = params.unpackedItems / params.groupsPerKilo diff --git a/src/classes/stageClasses/StageLane.lua b/src/classes/stageClasses/StageLane.lua index c8a6441..74448ba 100644 --- a/src/classes/stageClasses/StageLane.lua +++ b/src/classes/stageClasses/StageLane.lua @@ -4,8 +4,8 @@ ---@field private _isDefaultStageLane boolean ---@field private _stageLaneIdentifier string ---@field private _activeStageIndex number ----@field private _stagesInLaneByIndex table> ----@field private _chapterStarts table? +---@field private _stagesInLaneByIndex table> +---@field private _chapterStarts table? ---@field private _stageLaneState StageLaneState ---@field private _maxStageIndex number local StageLane = {} @@ -16,6 +16,7 @@ StageLane.__index = StageLane ---| "BetweenChapters" ---| "Completed" +---@type string? StageLane.DefaultLaneKey = nil function StageLane.New(laneIdentifier) @@ -37,21 +38,21 @@ end ---@param stage Stage function StageLane:AddStage(stage) local stageIndex = stage:GetStageIndex() - if not self._stagesInLaneByIndex[stageIndex] then - self._stagesInLaneByIndex[stageIndex] = {} + if not self._stagesInLaneByIndex[tostring(stageIndex)] then + self._stagesInLaneByIndex[tostring(stageIndex)] = {} end if not self._maxStageIndex or stageIndex > self._maxStageIndex then self._maxStageIndex = stageIndex end - table.insert(self._stagesInLaneByIndex[stageIndex], stage) + table.insert(self._stagesInLaneByIndex[tostring(stageIndex)], stage) end ---@param stageNumber number ---@return boolean? function StageLane:IsStageIndexComplete(stageNumber) - local stages = self._stagesInLaneByIndex[stageNumber] + local stages = self._stagesInLaneByIndex[tostring(stageNumber)] if not stages then return nil end @@ -88,7 +89,7 @@ end ---@param stageNumber number function StageLane:SetActiveStageIndex(stageNumber) - if self._stagesInLaneByIndex[stageNumber] == nil then + if self._stagesInLaneByIndex[tostring(stageNumber)] == nil then self._stageLaneState = "BetweenChapters" -- stage number is not in this lane, so we are between chapters elseif stageNumber > self._maxStageIndex then self._stageLaneState = "Completed" -- stage number is beyond the max stage index @@ -108,6 +109,7 @@ end --- Chapter starts are the first StageIndex after a gap in stage numbers.
--- For example, if the stage numbers are 1, 2, 3, 5, 6, 7, then stage number 5 is a chapter start because there is a gap between 3 and 5.
---@param stageNumber number +---@return boolean function StageLane:IsChapterStart(stageNumber) if self._chapterStarts == nil then @@ -123,13 +125,14 @@ end function StageLane:FillChapterStarts() local previousIndex = nil + ---@type table local stageIndices = {} for stageIndex, _ in pairs(self._stagesInLaneByIndex) do table.insert(stageIndices, tonumber(stageIndex)) end table.sort(stageIndices) - self._chapterStarts = self._chapterStarts or {} + if self._chapterStarts == nil then self._chapterStarts = {} end for _, stageIndex in ipairs(stageIndices) do if previousIndex == nil then -- First stage is always a chapter start @@ -158,7 +161,7 @@ end ---@param stageIndex number ---@return Array? function StageLane:GetStagesAtIndex(stageIndex) - return self._stagesInLaneByIndex[stageIndex] + return self._stagesInLaneByIndex[tostring(stageIndex)] end ---@return number? diff --git a/src/classes/stageClasses/Stages/BaseStage/Stage.lua b/src/classes/stageClasses/Stages/BaseStage/Stage.lua index 21bd59c..2a14a3d 100644 --- a/src/classes/stageClasses/Stages/BaseStage/Stage.lua +++ b/src/classes/stageClasses/Stages/BaseStage/Stage.lua @@ -162,6 +162,7 @@ function Stage:superNew(database, stageConfig, logger, initData, stageType, miss ---comment ---@param selfA Stage ---@param time number? + ---@return number|nil self.CheckContinuousAsync = function (selfA, time) selfA:CheckAndUpdateSelf() @@ -325,7 +326,9 @@ function Stage:GetStageName() return self.stageName end +---@return Array function Stage:GetMissions() + ---@type Array local missions = {} for _, mission in pairs(self._db.missions) do table.insert(missions, mission) @@ -674,6 +677,7 @@ function Stage:ActivateBlueStage() end ---@param selfA Stage + ---@return number|nil local ActivateBlueAsync = function(selfA) pcall(function() selfA:MarkStage() diff --git a/src/classes/stageClasses/drawings/helper/DrawingHelper.lua b/src/classes/stageClasses/drawings/helper/DrawingHelper.lua index aa90234..8c7a59c 100644 --- a/src/classes/stageClasses/drawings/helper/DrawingHelper.lua +++ b/src/classes/stageClasses/drawings/helper/DrawingHelper.lua @@ -54,7 +54,7 @@ local function MarkupToAll(shapeID, drawID, points, fillColor, lineColor, lineS if lineThickness == nil or lineThickness <= 0 then lineStyle = 0 end - + ---@type string local functionString = "trigger.action.markupToAll(" .. shapeID .. ", -1, " .. drawID .. "," for _, point in pairs(points) do @@ -125,14 +125,14 @@ function DrawingHelper.DrawPolygon(object) local fillColor = DrawingHelper.ColorToColorTable(free.fillColorString) local color = DrawingHelper.ColorToColorTable(free.colorString) local lineStyle = DrawingHelper.ToLineStyleInteger(free.style) - + ---@type Array local keys = {} for k, _ in pairs(free.points) do table.insert(keys, k) end table.sort(keys, function(a, b) return a < b end) - + ---@type Array local points = {} for _, k in ipairs(keys) do local point = free.points[k] @@ -274,6 +274,7 @@ function DrawingHelper.ColorTableToColorString(rgba) end ---@param lineStyle string +---@return integer function DrawingHelper.ToLineStyleInteger(lineStyle) lineStyle = lineStyle:lower() if lineStyle == "no line" then diff --git a/src/classes/stageClasses/helpers/BattleManager.lua b/src/classes/stageClasses/helpers/BattleManager.lua index 951767a..1af72fd 100644 --- a/src/classes/stageClasses/helpers/BattleManager.lua +++ b/src/classes/stageClasses/helpers/BattleManager.lua @@ -36,6 +36,7 @@ end ---@param self BattleManager ---@param time number +---@return number? local function CheckTask(self, time) local interval = self:Update() if not interval then return end @@ -148,7 +149,7 @@ end ---@return number function BattleManager:getBestAmmo(unit) - local ammo = unit:getAmmo() + local ammo = unit:getAmmo() --[[@as table]] if not ammo then return 3221225470, 1 end -- Default ammo if no ammo is found @@ -162,9 +163,9 @@ function BattleManager:getBestAmmo(unit) end end - local entry = Util.randomFromList(shells) + local entry = Util.randomFromList(shells) --[[@as table]] if entry and entry.desc and entry.desc.warhead then - local caliber = entry.desc.warhead.caliber + local caliber = entry.desc.warhead.caliber --[[@as number]] if caliber > 50 then return 258503344128, 1 else @@ -209,6 +210,7 @@ function BattleManager:ToShootingHulls(groups) end local hulls = Util.getSeparatedConvexHulls(points, 50) + ---@type Array> local enlargedHulls = {} for _, hull in pairs(hulls) do local enlarged = Util.enlargeConvexHull(hull, 25) diff --git a/src/classes/stageClasses/helpers/MissionCommandsHelper.lua b/src/classes/stageClasses/helpers/MissionCommandsHelper.lua index 9311bb6..ff7798c 100644 --- a/src/classes/stageClasses/helpers/MissionCommandsHelper.lua +++ b/src/classes/stageClasses/helpers/MissionCommandsHelper.lua @@ -7,7 +7,7 @@ local SupplyConfigHelper = require("classes.stageClasses.helpers.SupplyConfigHel local StageConfig = require("classes.configuration.StageConfig") ----@class MissionCommandsHelper +---@class MissionCommandsHelper : OnPlayerEnterUnitListener ---@field missionsByCode table @table of missions by their code ---@field enabledByCode table @table of enabled missions by their code ---@field updateNeeded boolean @flag to indicate if an update is needed @@ -369,7 +369,7 @@ function MissionCommandsHelper:AddAllMissionCommandsToGroup(groupID) do --- secondary missions local count = 0 local path = { [1] = folderNames.secondary } - + ---@type Array local secondaryMissions = {} for code, enabled in pairs(self.enabledByCode) do if enabled == true then diff --git a/src/classes/stageClasses/helpers/SupplyConfigHelper.lua b/src/classes/stageClasses/helpers/SupplyConfigHelper.lua index 885bd87..379a795 100644 --- a/src/classes/stageClasses/helpers/SupplyConfigHelper.lua +++ b/src/classes/stageClasses/helpers/SupplyConfigHelper.lua @@ -83,7 +83,8 @@ function SupplyConfigHelper.fromObjectName(name) return nil end ----@param type CrateType +---@param type CrateType +---@return SupplyConfig? function SupplyConfigHelper.getSupplyConfig(type) return SupplyConfig[type] end diff --git a/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua b/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua index 3256f8d..092bbc0 100644 --- a/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua +++ b/src/classes/stageClasses/helpers/SupplyUnitsTracker.lua @@ -10,7 +10,7 @@ local SupplyLoadConfig = require("classes.stageClasses.helpers.SupplyLoadConfig" ---@field enteredSupplyHub fun(self:SupplyUnitEventListener, unit:Unit, hub:SupplyHub) | nil ---@field exitedSupplyHub fun(self:SupplyUnitEventListener, unit:Unit, hub:SupplyHub) | nil ----@class SupplyUnitsTracker +---@class SupplyUnitsTracker : OnPlayerEnterUnitListener ---@field private _supplyUnitsByName table ---@field private _cargoInUnits table> ---@field private _logger Logger @@ -43,6 +43,8 @@ function SupplyUnitsTracker.getOrCreate() SpearheadEvents.AddOnPlayerEnterUnitListener(singleton) ---@param selfA SupplyUnitsTracker + ---@param time number + ---@return number? local function updateTask(selfA, time) selfA:Update() @@ -134,6 +136,7 @@ end ---@private ---@param unit Unit +---@return boolean function SupplyUnitsTracker:IsSupplyUnit(unit) if unit == nil then return false end @@ -158,15 +161,17 @@ function SupplyUnitsTracker:AddCargoToUnit(unitID, crateType) local unit = DcsUtil.GetPlayerUnitByID(unitID) if unit == nil then return end - if self._cargoInUnits[unitID] == nil then - self._cargoInUnits[unitID] = {} + local unitIdStr = tostring(unitID) + + if self._cargoInUnits[unitIdStr] == nil then + self._cargoInUnits[unitIdStr] = {} end - if self._cargoInUnits[unitID][crateType] == nil then - self._cargoInUnits[unitID][crateType] = 0 + if self._cargoInUnits[unitIdStr][crateType] == nil then + self._cargoInUnits[unitIdStr][crateType] = 0 end - self._cargoInUnits[unitID][crateType] = self._cargoInUnits[unitID][crateType] + 1 + self._cargoInUnits[unitIdStr][crateType] = self._cargoInUnits[unitIdStr][crateType] + 1 end @@ -253,7 +258,7 @@ function SupplyUnitsTracker:CheckUnitsInZones() end end - self._unitPositions[unit:getID()] = pos + self._unitPositions[tostring(unit:getID())] = pos end end end @@ -323,6 +328,7 @@ function SupplyUnitsTracker:UnloadRequested(unitID, crateType, missionCommandsHe self:UpdateWeightForUnit(unit) cargoCount = cargoCount + 1 + ---@type {name: string, type: string, x: number, y: number} local cargoSpawnObject = { name = crateType .. "_" .. cargoCount, type = cargoConfig.staticType, @@ -484,7 +490,7 @@ function SupplyUnitsTracker:GetBoundingBoxes(foundObject) end local objPos = foundObject:getPoint() - local box = desc.box + local box = desc.box --[[@type table]] local heading = 0 -- Try to get object heading from position vector's forward direction @@ -497,10 +503,10 @@ function SupplyUnitsTracker:GetBoundingBoxes(foundObject) end) -- For rotated objects, we need to rotate the bounding box - local minX = box.min.x - local maxX = box.max.x - local minZ = box.min.z - local maxZ = box.max.z + local minX = box.min.x --[[@as number]] + local maxX = box.max.x --[[@as number]] + local minZ = box.min.z --[[@as number]] + local maxZ = box.max.z --[[@as number]] -- If object has significant rotation, apply rotation to bbox corners if math.abs(heading) > 0.1 then @@ -517,8 +523,8 @@ function SupplyUnitsTracker:GetBoundingBoxes(foundObject) minZ, maxZ = math.huge, -math.huge for _, corner in ipairs(corners) do - local rotX = corner[1] * math.cos(heading) - corner[2] * math.sin(heading) - local rotZ = corner[1] * math.sin(heading) + corner[2] * math.cos(heading) + local rotX = corner[1] * math.cos(heading) - corner[2] * math.sin(heading) --[[@as number]] + local rotZ = corner[1] * math.sin(heading) + corner[2] * math.cos(heading) --[[@as number]] minX = math.min(minX, rotX) maxX = math.max(maxX, rotX) minZ = math.min(minZ, rotZ) @@ -587,7 +593,7 @@ function SupplyUnitsTracker:GetCargoPlacePosition(unit, crateTypeName) return nil end - local crateRelativeBBox = crateDesc.box + local crateRelativeBBox = crateDesc.box --[[@as table]] -- Get drop zone config for this unit local dropZones = { @@ -610,8 +616,11 @@ function SupplyUnitsTracker:GetCargoPlacePosition(unit, crateTypeName) radius = 100 -- Search a large area } } - + ---@type Array<{ pos: { x: number, y: number, z: number }, bbox: { min: { x: number, y: number, z: number }, max: { x: number, y: number, z: number } } }> local occupiedObjects = {} + + ---@param foundItem Object + ---@param _ any local found = function(foundItem, _) local bbox = self:GetBoundingBoxes(foundItem) if bbox then @@ -660,6 +669,7 @@ function SupplyUnitsTracker:GetCargoPlacePosition(unit, crateTypeName) local candidateY = land.getHeight({ x = candidateX, y = candidateZ }) -- Convert crate's relative bbox to world space at this position + ---@type { min: { x: number, y: number, z: number }, max: { x: number, y: number, z: number } } local crateBBoxWorldSpace = { min = { x = candidateX + crateRelativeBBox.min.x, diff --git a/src/classes/stageClasses/missions/BuildableMission.lua b/src/classes/stageClasses/missions/BuildableMission.lua index e90202c..b8d0948 100644 --- a/src/classes/stageClasses/missions/BuildableMission.lua +++ b/src/classes/stageClasses/missions/BuildableMission.lua @@ -25,6 +25,8 @@ local DrawingHelper = require("classes.stageClasses.drawings.helper.DrawingHelpe local BuildableMission = {} BuildableMission.__index = BuildableMission +---@param siteType string +---@param coords string ---@return string local function getDefaultBriefing(siteType, coords) return "We've dispatched forward units to find a proper spot for a new " .. siteType .. "." .. @@ -43,6 +45,7 @@ end ---@param noLandingZone SpearheadTriggerZone? ---@param logger Logger ---@param briefing string? +---@return BuildableMission function BuildableMission.new(database, logger, targetZone, noLandingZone, requiredKilos, requiredCrateType, briefing) setmetatable(BuildableMission, Mission) @@ -117,6 +120,7 @@ function BuildableMission:ShowBriefing(groupID) local unitType = DcsUtil.getUnitTypeFromGroup(group) local coords = DcsUtil.convertVec2ToUnitUsableType(self.location, unitType) + if coords == nil then coords = "Could not make conversion" end local siteType = "FARP" if self._crateType == "SAM_CRATE" then @@ -143,17 +147,20 @@ function BuildableMission:ShowBriefing(groupID) trigger.action.outTextForGroup(groupID, briefing, GlobalConfig:getBriefingTime()) end +---@param groupID number function BuildableMission:MarkMissionAreaToGroup(groupID) - if self._markIDsPerGroup[groupID] then - DcsUtil.RemoveMark(self._markIDsPerGroup[groupID]) - end + local groupIdStr = tostring(groupID) + if self._markIDsPerGroup[groupIdStr] then + DcsUtil.RemoveMark(self._markIDsPerGroup[groupIdStr]) + end + ---@type string local text = "[" .. self.code .. "] " .. self.name .. " | " .. self._crateType local location = { x= self.location.x, y=land.getHeight(self.location), z=self.location.y } local markID = DcsUtil.AddMarkToGroup(groupID, text, location) - self._markIDsPerGroup[groupID] = markID + self._markIDsPerGroup[groupIdStr] = markID end ---@private @@ -197,6 +204,7 @@ function BuildableMission:SpawnActive() ---@param selfA BuildableMission ---@param time number + ---@return number? local checkForCrateTasks = function (selfA, time) selfA:CheckCratesInZone() diff --git a/src/classes/stageClasses/missions/RunwayStrikeMission.lua b/src/classes/stageClasses/missions/RunwayStrikeMission.lua index 0d6e658..4cbd019 100644 --- a/src/classes/stageClasses/missions/RunwayStrikeMission.lua +++ b/src/classes/stageClasses/missions/RunwayStrikeMission.lua @@ -24,6 +24,7 @@ local RunwayStrikeMission = {} ---@param runway Runway ---@param database Database ---@param logger Logger +---@param airbaseName string ---@param runwayBombingTracker RunwayBombingTracker ---@return RunwayStrikeMission? function RunwayStrikeMission.new(runway, airbaseName, database, logger, runwayBombingTracker) @@ -205,8 +206,9 @@ function RunwayStrikeMission:StartRepair() self._repairInProgress = true self._logger:debug("Starting repair of runway strike mission " .. self._airportName .. ":" .. self._runway.Name) ---comment - ---@param selfA any - ---@return unknown + ---@param selfA RunwayStrikeMission + ---@param time number + ---@return number? local repairTask = function (selfA, time) local interval = selfA:DoRepairCycle() if interval == nil then return nil end @@ -215,6 +217,7 @@ function RunwayStrikeMission:StartRepair() timer.scheduleFunction(repairTask, self, timer.getTime() + 5) end +---@return number? function RunwayStrikeMission:DoRepairCycle() local interval = 5 @@ -247,12 +250,14 @@ function RunwayStrikeMission:DoRepairCycle() end ----@class StaticSpawn +---@class StaticSpawn : table ---@field category string ---@field type string ---@field y number ---@field x number ---@field heading number +---@field name string? +---@field hidden boolean? local counter = 1 @@ -441,6 +446,7 @@ end ---@private ---@param runway Runway +---@param numSections number ---@return Array function RunwayStrikeMission:ToSections(runway, numSections) diff --git a/src/classes/stageClasses/missions/ZoneMission.lua b/src/classes/stageClasses/missions/ZoneMission.lua index c87ce14..5139a8b 100644 --- a/src/classes/stageClasses/missions/ZoneMission.lua +++ b/src/classes/stageClasses/missions/ZoneMission.lua @@ -240,7 +240,7 @@ function ZoneMission:UpdateState(checkHealth, messageIfDone) local staticObject = StaticObject.getByName(unitName) if staticObject then if staticObject:isExist() == true then - local life0 = staticObject:getDesc().life + local life0 = staticObject:getDesc().life --[[@as number]] if staticObject:getLife() / life0 < 0.3 then self._logger:debug("exploding unit") trigger.action.explosion(staticObject:getPoint(), 100) @@ -286,7 +286,9 @@ function ZoneMission:UpdateState(checkHealth, messageIfDone) end if self._missionGroups.hasTargets == true then + ---@type number local total = 0 + ---@type number local alive = 0 for _, units in pairs(self._missionGroups.targetsAlive) do @@ -299,13 +301,13 @@ function ZoneMission:UpdateState(checkHealth, messageIfDone) end for _, sceneryObject in pairs(self._missionGroups.sceneryTargets) do - total = total + 1 + total = total + 1 --[[@as number]] if sceneryObject:IsAlive() == true then alive = alive + 1 end end - local deadRatio = (total - alive) / total + local deadRatio = (total - alive) / total --[[@as number]] if deadRatio >= self._completeAtIndex then self._logger:debug("Dead ratio " .. self.zoneName .. deadRatio .. " >= " .. self._completeAtIndex) self._state = "COMPLETED" @@ -477,6 +479,7 @@ function ZoneMission:OnUnitLost(object) local category = Object.getCategory(object) if category == Object.Category.UNIT then + object = object --[[@as Unit]] local unitName = object:getName() self._logger:debug("UnitName:" .. unitName) @@ -487,6 +490,7 @@ function ZoneMission:OnUnitLost(object) self._missionGroups.targetsAlive[groupName][unitName] = false end elseif category == Object.Category.STATIC then + object = object --[[@as StaticObject]] local name = object:getName() self._missionGroups.unitsAlive[name][name] = false diff --git a/src/classes/stageClasses/missions/baseMissions/Mission.lua b/src/classes/stageClasses/missions/baseMissions/Mission.lua index 9fdabfb..8890a3a 100644 --- a/src/classes/stageClasses/missions/baseMissions/Mission.lua +++ b/src/classes/stageClasses/missions/baseMissions/Mission.lua @@ -86,6 +86,7 @@ function Mission:ShowBriefing(groupId) local unitType = DcsUtil.getUnitTypeFromGroup(group) local coords = DcsUtil.convertVec2ToUnitUsableType(self.location, unitType) + if coords == nil then coords = "Could not make conversion" end self._logger:debug("Coords converted: " .. coords) local stateString = self:ToStateString() diff --git a/src/classes/util/DcsUtil.lua b/src/classes/util/DcsUtil.lua index a59ffd9..434f585 100644 --- a/src/classes/util/DcsUtil.lua +++ b/src/classes/util/DcsUtil.lua @@ -40,7 +40,7 @@ do -- INIT DCS_UTIL ---@field zone_type SpearheadTriggerZoneType ---@field properties Array? - ---@type Array + ---@type table DCS_UTIL.__trigger_zones = {} end @@ -66,12 +66,15 @@ do -- INIT DCS_UTIL STATIC = 5 --CUSTOM CATEGORY } + ---@type table DCS_UTIL.__airbaseNamesById = {} ---@type table DCS_UTIL.__airbaseZonesByName = {} + ---@type table DCS_UTIL.__airportsStartingCoalition = {} + ---@type table DCS_UTIL.__warehouseStartingCoalition = {} function DCS_UTIL.__INIT() do -- INITS ALL TABLES WITH DATA THAT's from the MIZ environment @@ -104,8 +107,8 @@ do -- INIT DCS_UTIL if trigger_zone.properties then for _, kvPair in pairs(trigger_zone.properties) do - local key = kvPair["key"] - local value = kvPair["value"] + local key = kvPair.key + local value = kvPair.value zone.properties[#zone.properties + 1] = { key = key, value = value } end end @@ -116,6 +119,7 @@ do -- INIT DCS_UTIL do -- init airports and warehouses if env.warehouses.airports then + env.warehouses.airports = env.warehouses.airports --[[@as table]] for warehouse_id, value in pairs(env.warehouses.airports) do if warehouse_id ~= nil then warehouse_id = tostring(warehouse_id) or "nil" @@ -126,12 +130,12 @@ do -- INIT DCS_UTIL end if env.warehouses.warehouses then - DCS_UTIL.__warehouseStartingCoalition[-1] = "placeholder" + env.warehouses.warehouses = env.warehouses.warehouses --[[@as table]] for warehouse_id, value in pairs(env.warehouses.warehouses) do if warehouse_id ~= nil then - warehouse_id = tostring(warehouse_id) or "nil" + local warehouse_id_str = tostring(warehouse_id) or "nil" local coalitionNumber = DCS_UTIL.stringToCoalition(value.coalition) - DCS_UTIL.__warehouseStartingCoalition[warehouse_id] = coalitionNumber + DCS_UTIL.__warehouseStartingCoalition[warehouse_id_str] = coalitionNumber end end end @@ -218,11 +222,13 @@ do -- INIT DCS_UTIL end end + --- takes a list of units and returns all the units that are in any of the zones - ---@param unit_names table unit names - ---@param zone_names table zone names - ---@return table unit list of objects { unit = UNIT, zone_name = zoneName} + ---@param unit_names Array unit names + ---@param zone_names Array zone names + ---@return table function DCS_UTIL.getUnitsInZones(unit_names, zone_names) + ---@type Array local units = {} ---@type Array @@ -241,14 +247,19 @@ do -- INIT DCS_UTIL zones[#zones + 1] = zone end end - + ---@type table local in_zone_units = {} for units_ind = 1, #units do local lUnit = units[units_ind] - local unit_pos = lUnit:getPosition().p + local isActive = true local lCat = Object.getCategory(lUnit) - for _, zone in pairs(zones) do - if unit_pos and ((lCat == 1 and lUnit:isActive() == true) or lCat ~= 1) then -- it is a unit and is active or it is not a unit + if lCat == Object.Category.UNIT then + local unit = lUnit --[[@as Unit]] + isActive = unit:isActive() == true + end + local unit_pos = lUnit:getPosition().p + for _, zone in pairs(zones) do + if unit_pos and isActive == true then -- it is a unit and is active or it is not a unit local isInZone = Util.is3dPointInZone(unit_pos, zone) if isInZone == true then in_zone_units[#in_zone_units + 1] = { unit = lUnit, zone_name = zone.name } @@ -262,9 +273,9 @@ do -- INIT DCS_UTIL --- takes a list of groups and returns all the group leaders that are in any of the zones ---@param group_names table unit names ---@param zone_name string zone names - ---@return table groupnames list of group names + ---@return Array groupnames list of group names function DCS_UTIL.getGroupsInZone(group_names, zone_name) - local zone = DCS_UTIL.__trigger_zones[zone_name] + local zone = DCS_UTIL.__trigger_zones[zone_name] --[[@as SpearheadTriggerZone?]] if zone == nil then return {} end @@ -277,6 +288,7 @@ do -- INIT DCS_UTIL ---@param zone SpearheadTriggerZone ---@return Array groupnames list of groups that are in the zone function DCS_UTIL.areGroupsInCustomZone(group_names, zone) + ---@type Array<{ unit : Unit|StaticObject, groupname: string }> local units = {} if Util.tableLength(group_names) < 1 then return {} end @@ -308,8 +320,8 @@ do -- INIT DCS_UTIL --- takes a x, y poistion and checks if it is inside any of the zones ---@param x number North South position ---@param z number West East position - ---@param zone_names table zone names - ---@return table zones list of objects { zone_name = zoneName} + ---@param zone_names Array zone names + ---@return Array zones list of objects { zone_name = zoneName} function DCS_UTIL.isPositionInZones(x, z, zone_names) ---@type Array local zones = {} @@ -319,7 +331,7 @@ do -- INIT DCS_UTIL zones[#zones + 1] = zone end end - + ---@type Array local result_zones = {} for _, zone in pairs(zones) do if Util.is3dPointInZone({ x = x, z = z, y = 0 }, zone) == true then @@ -396,6 +408,18 @@ do -- INIT DCS_UTIL return nil; end + ---@return Array + function DCS_UTIL.getAllGroupCategoryNames() + return { + "airplane", + "helicopter", + "ground", + "ship", + "train", + "static" + } + end + ---@type table local config = { @@ -408,7 +432,8 @@ do -- INIT DCS_UTIL ---@param location Vec2 - ---@param unitType string + ---@param unitType string? + ---@return string? function DCS_UTIL.convertVec2ToUnitUsableType(location, unitType) local height = land.getHeight(location) @@ -429,6 +454,7 @@ do -- INIT DCS_UTIL ---@private ---@param location Vec3 ---@param coordType CoordType + ---@return string? function DCS_UTIL.convertToDisplayCoord(location, coordType) local lattitude, longitude, altitude = coord.LOtoLL(location) @@ -440,7 +466,7 @@ do -- INIT DCS_UTIL -- Convert DD to DDM (Degrees Decimal Minutes) local function dd_to_ddm(dd) local degrees = math.floor(math.abs(dd)) - local minutes = (math.abs(dd) - degrees) * 60 + local minutes = (math.abs(dd) - degrees) * 60 --[[@as number]] local sign = dd >= 0 and 1 or -1 return degrees * sign, minutes end @@ -559,6 +585,7 @@ do -- INIT DCS_UTIL end ---@param group Group + ---@return string? unit type name function DCS_UTIL.getUnitTypeFromGroup(group) for _, unit in pairs(group:getUnits()) do if unit and unit:isExist() then @@ -571,6 +598,7 @@ do -- INIT DCS_UTIL ---comment Get all units that are players ---@return Array units function DCS_UTIL.getAllPlayerUnits() + ---@type Array local units = {} for i = 0, 2 do local players = coalition.getPlayers(i) @@ -616,6 +644,7 @@ do -- INIT DCS_UTIL return result end + ---@param unitName string function DCS_UTIL.CleanCorpse(unitName) unitName = "dead_" .. unitName local object = StaticObject.getByName(unitName) @@ -734,6 +763,8 @@ do -- INIT DCS_UTIL return false end + ---@param groupName string + ---@param offset number? ---@return boolean function DCS_UTIL.IsBingoFuel(groupName, offset) if offset == nil then offset = 0 end diff --git a/src/classes/util/MissionEditorWarnings.lua b/src/classes/util/MissionEditorWarnings.lua index a5ff7ea..88b1fdd 100644 --- a/src/classes/util/MissionEditorWarnings.lua +++ b/src/classes/util/MissionEditorWarnings.lua @@ -1,8 +1,12 @@ ---@class MissionEditingWarnings local MissionEditingWarnings = {} + +---@type table +MissionEditingWarnings.warnings = {} + function MissionEditingWarnings.Add(warningMessage) - table.insert(MissionEditingWarnings, warningMessage or "skip") + table.insert(MissionEditingWarnings.warnings, warningMessage or "skip") end ---@param logger Logger @@ -12,12 +16,12 @@ function MissionEditingWarnings.WriteAll(logger) return end - if not MissionEditingWarnings or #MissionEditingWarnings == 0 then + if not MissionEditingWarnings.warnings or #MissionEditingWarnings.warnings == 0 then return end logger:warn("Mission Editor Warnings:") - for _, warning in ipairs(MissionEditingWarnings) do + for _, warning in ipairs(MissionEditingWarnings.warnings) do logger:warn("- " .. warning) end diff --git a/src/classes/util/Util.lua b/src/classes/util/Util.lua index d6a80d9..23688c3 100644 --- a/src/classes/util/Util.lua +++ b/src/classes/util/Util.lua @@ -22,7 +22,7 @@ do -- INIT UTIL end ---comment - ---@param table any + ---@param table table ---@return number function UTIL.tableLength(table) if table == nil then return 0 end @@ -35,23 +35,34 @@ do -- INIT UTIL ---@param orig table ---@return table copy function UTIL.deepCopyTable(orig) - local orig_type = type(orig) - local copy - if orig_type == 'table' then - copy = {} - for orig_key, orig_value in next, orig, nil do - copy[UTIL.deepCopyTable(orig_key)] = UTIL.deepCopyTable(orig_value) + + ---@param original any + ---@return any + local function deepCopy(original) + local orig_type = type(original) + ---@type any + local copy + if orig_type == 'table' then + original = original --[[@as table]] + copy = {} --[[@as table]] + for orig_key, orig_value in pairs(original) do + local copiedKey = deepCopy(orig_key) --[[@as any]] + copy[copiedKey] = deepCopy(orig_value) + end + setmetatable(copy, deepCopy(getmetatable(original))) + else -- number, string, boolean, etc + copy = original --[[@as any]] end - setmetatable(copy, UTIL.deepCopyTable(getmetatable(orig))) - else -- number, string, boolean, etc - copy = orig + return copy end - return copy + + return deepCopy(orig) end ---Gets a random from the list - ---@param list Array - ---@return any @random element from the list + ---@generic T + ---@param list Array + ---@return T @random element from the list function UTIL.randomFromList(list) local max = #list @@ -65,11 +76,13 @@ do -- INIT UTIL return list[random] end - ---@param list Array + ---@generic T + ---@param list Array ---@param start number start ---@param n number length - ---@return Array + ---@return Array function UTIL.sublist(list, start, n) + ---@type table local result = {} for i = start, n do result[#result + 1] = list[i] @@ -90,9 +103,10 @@ do -- INIT UTIL end local function table_print(tt, indent, done) - done = done or {} + done = done or {} --[[@as table]] indent = indent or 0 if type(tt) == "table" then + tt = tt --[[@as table]] local sb = {} for key, value in pairs(tt) do table.insert(sb, string.rep(" ", indent)) -- indent it @@ -146,7 +160,7 @@ do -- INIT UTIL ---comment ---@param str string - ---@param findableTable table + ---@param findableTable table ---@return boolean UTIL.startswithAny = function(str, findableTable) for _, value in pairs(findableTable) do @@ -244,6 +258,7 @@ do -- INIT UTIL ---@return boolean local function isInComplexPolygon(polygon, x, y) ---@param poly Array of pairs { x, y } + ---@return Array<{ x1: number, z1: number, x2: number, z2: number }> local function getEdges(poly) local result = {} for i = 1, #poly do @@ -280,6 +295,7 @@ do -- INIT UTIL ---@param point Vec3 ---@param zone SpearheadTriggerZone + ---@return boolean function UTIL.is3dPointInZone(point, zone) if zone.zone_type == "Polygon" and zone.verts then if UTIL.IsPointInPolygon(zone.verts, point.x, point.z) == true then @@ -296,6 +312,7 @@ do -- INIT UTIL ---@param point Vec2 ---@param zone SpearheadTriggerZone + ---@return boolean function UTIL.is2dPointInZone(point, zone) if zone.zone_type == "Polygon" and zone.verts then if UTIL.IsPointInPolygon(zone.verts, point.x, point.y) == true then @@ -447,6 +464,8 @@ do -- INIT UTIL end ---@param points Array + ---@param meters number + ---@return Array function UTIL.enlargeConvexHull(points, meters) if points == nil or #points == 0 then return {} @@ -524,6 +543,10 @@ function UTIL.GetTangentHullPointsFromOrigin(hull, origin) return {} end + ---@param a Vec2 + ---@param b Vec2 + ---@param c Vec2 + ---@return number local function orientation(a, b, c) -- Returns >0 if c is to the left of ab, <0 if to the right, 0 if colinear return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) -- 2.54.0 From 0e1650648fe6c6b69f473e3cf7bc8b11d35e6696 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sat, 19 Sep 2026 23:28:31 +0200 Subject: [PATCH 53/71] Added luacheck config --- .gitea/workflows/pr.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 92f2bf0..33acec8 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -38,6 +38,25 @@ jobs: - name: Install luacheck run: luarocks install luacheck + - name: Create LuaCheck Config + run: | + cat << EOF + std = { + globals = { + "SpearheadConfig" + }, + read_globals = { + "lfs", "env", "net", "trigger", "timer", "Object" + } + } + + max_line_length = false + EOF + > .luacheckrc + + - name: Show LuaCheck Config + run: cat .luacheckrc + - name: Lint Compiled Output run: luacheck ./output/spearhead.lua -- 2.54.0 From 1c2453e337844e53212af518e6f5766907bc67bc Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sat, 19 Sep 2026 23:33:15 +0200 Subject: [PATCH 54/71] Added luacheck config --- .gitea/workflows/pr.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 33acec8..9d9a20e 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -40,7 +40,7 @@ jobs: - name: Create LuaCheck Config run: | - cat << EOF + cat << EOF > .luacheckrc std = { globals = { "SpearheadConfig" @@ -52,7 +52,6 @@ jobs: max_line_length = false EOF - > .luacheckrc - name: Show LuaCheck Config run: cat .luacheckrc -- 2.54.0 From 51e480f8775b47e581da26e31d1fa8adf6fce0e2 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sat, 19 Sep 2026 23:40:28 +0200 Subject: [PATCH 55/71] Added luacheck config --- .gitea/workflows/pr.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 9d9a20e..8b30f78 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -43,11 +43,11 @@ jobs: cat << EOF > .luacheckrc std = { globals = { - "SpearheadConfig" + "SpearheadConfig", "lfs", "env", "net", "trigger", "timer", "Object", + "setmetatable", "table", "string", "math", "pairs", "ipairs", "tostring", + "require", + "Unit", "Group", "Airbase", "StaticObject" }, - read_globals = { - "lfs", "env", "net", "trigger", "timer", "Object" - } } max_line_length = false -- 2.54.0 From 8f6cccf4e0aad6c7fb01287d872ac9caf5ffe129 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 11:16:50 +0200 Subject: [PATCH 56/71] Added luacheck config --- .gitea/workflows/pr.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 8b30f78..188da75 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -43,10 +43,14 @@ jobs: cat << EOF > .luacheckrc std = { globals = { - "SpearheadConfig", "lfs", "env", "net", "trigger", "timer", "Object", - "setmetatable", "table", "string", "math", "pairs", "ipairs", "tostring", - "require", - "Unit", "Group", "Airbase", "StaticObject" + "lfs", + "setmetatable",getmetatable", "table", "string", "math", "pairs", "ipairs", + "require", "type", "tostring", "io", "error", "pcall", "tonumber", + + "SpearheadConfig", + "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition" + "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world", + }, } -- 2.54.0 From e12df3f805d420736b9cd2da713648d5989fe15e Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 11:19:03 +0200 Subject: [PATCH 57/71] Added luacheck config --- .gitea/workflows/pr.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 188da75..b993a6a 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -48,9 +48,8 @@ jobs: "require", "type", "tostring", "io", "error", "pcall", "tonumber", "SpearheadConfig", - "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition" + "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition", "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world", - }, } -- 2.54.0 From 4affe9405262399bac4b3bf105c3ec41e506cbf0 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 11:20:47 +0200 Subject: [PATCH 58/71] Added luacheck config --- .gitea/workflows/pr.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index b993a6a..292bd7f 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -46,10 +46,9 @@ jobs: "lfs", "setmetatable",getmetatable", "table", "string", "math", "pairs", "ipairs", "require", "type", "tostring", "io", "error", "pcall", "tonumber", - "SpearheadConfig", "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition", - "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world", + "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world" }, } -- 2.54.0 From a90e075e62b0b865a8b8e51aa8284f9d22d6fd02 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 11:24:58 +0200 Subject: [PATCH 59/71] Added luacheck config --- .gitea/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 292bd7f..f844de6 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -44,7 +44,7 @@ jobs: std = { globals = { "lfs", - "setmetatable",getmetatable", "table", "string", "math", "pairs", "ipairs", + "setmetatable", "getmetatable", "table", "string", "math", "pairs", "ipairs", "require", "type", "tostring", "io", "error", "pcall", "tonumber", "SpearheadConfig", "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition", -- 2.54.0 From f8641e607d9ea3e418628c85132aa7237ef973b3 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 11:27:31 +0200 Subject: [PATCH 60/71] Added luacheck config --- .gitea/workflows/pr.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index f844de6..29e982a 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -46,9 +46,12 @@ jobs: "lfs", "setmetatable", "getmetatable", "table", "string", "math", "pairs", "ipairs", "require", "type", "tostring", "io", "error", "pcall", "tonumber", - "SpearheadConfig", + "loadstring", + + "SpearheadConfig", "SpearheadAPI", "GlobalCapCallBacks" "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition", - "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world" + "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world", + "country", "missionCommands", "Controller", "Weapon", "atmosphere", "country" }, } -- 2.54.0 From 06e2a70fdb6b19594c8c3d2f2af90ff8103454af Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 11:28:50 +0200 Subject: [PATCH 61/71] Added luacheck config --- .gitea/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 29e982a..9d50311 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -48,7 +48,7 @@ jobs: "require", "type", "tostring", "io", "error", "pcall", "tonumber", "loadstring", - "SpearheadConfig", "SpearheadAPI", "GlobalCapCallBacks" + "SpearheadConfig", "SpearheadAPI", "GlobalCapCallBacks", "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition", "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world", "country", "missionCommands", "Controller", "Weapon", "atmosphere", "country" -- 2.54.0 From 88064824506eb8257b048c21369fd8598d9be709 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 11:35:49 +0200 Subject: [PATCH 62/71] Added luacheck config --- .gitea/workflows/pr.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 9d50311..368c8c1 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -38,16 +38,17 @@ jobs: - name: Install luacheck run: luarocks install luacheck + # "lfs", + # "setmetatable", "getmetatable", "table", "string", "math", "pairs", "ipairs", + # "require", "type", "tostring", "io", "error", "pcall", "tonumber", + # "loadstring", + - name: Create LuaCheck Config run: | cat << EOF > .luacheckrc std = { + "lua51c", globals = { - "lfs", - "setmetatable", "getmetatable", "table", "string", "math", "pairs", "ipairs", - "require", "type", "tostring", "io", "error", "pcall", "tonumber", - "loadstring", - "SpearheadConfig", "SpearheadAPI", "GlobalCapCallBacks", "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition", "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world", -- 2.54.0 From 9c6c72fc33cc85adbb5c41c3f832bba435574d2e Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 11:39:46 +0200 Subject: [PATCH 63/71] Added luacheck config --- .gitea/workflows/pr.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 368c8c1..26574d6 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -46,16 +46,21 @@ jobs: - name: Create LuaCheck Config run: | cat << EOF > .luacheckrc - std = { - "lua51c", + + stds.spearhead_lib = { + "SpearheadConfig", "SpearheadAPI", "GlobalCapCallBacks", + } + + stds.dcs_lib = { globals = { - "SpearheadConfig", "SpearheadAPI", "GlobalCapCallBacks", "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition", "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world", "country", "missionCommands", "Controller", "Weapon", "atmosphere", "country" - }, + } } + std = "lua51c+spearhead_lib+dcs_lib" + max_line_length = false EOF -- 2.54.0 From 0b012f59c62fc4a0f1e64410f05f88130cf8a32e Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 12:02:12 +0200 Subject: [PATCH 64/71] Added luacheck config --- .gitea/workflows/pr.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index 26574d6..a88e765 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -48,7 +48,9 @@ jobs: cat << EOF > .luacheckrc stds.spearhead_lib = { - "SpearheadConfig", "SpearheadAPI", "GlobalCapCallBacks", + globals = { + "SpearheadConfig", "SpearheadAPI", "GlobalCapCallBacks", + } } stds.dcs_lib = { -- 2.54.0 From 917266818dfaedbacd8c9e138e523bc2c19012ee Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 14:22:24 +0200 Subject: [PATCH 65/71] Added luacheck config --- .gitea/workflows/pr.yml | 4 +++- src/classes/helpers/SpawnManager.lua | 9 --------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index a88e765..a16d922 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -57,11 +57,13 @@ jobs: globals = { "env", "net", "trigger", "timer", "Object", "land", "coord", "coalition", "Unit", "Group", "Airbase", "StaticObject", "SceneryObject", "world", - "country", "missionCommands", "Controller", "Weapon", "atmosphere", "country" + "country", "missionCommands", "Controller", "Weapon", "atmosphere", "country", + "lfs", "AI" } } std = "lua51c+spearhead_lib+dcs_lib" + self = false max_line_length = false EOF diff --git a/src/classes/helpers/SpawnManager.lua b/src/classes/helpers/SpawnManager.lua index 1ac88c9..76b33de 100644 --- a/src/classes/helpers/SpawnManager.lua +++ b/src/classes/helpers/SpawnManager.lua @@ -125,8 +125,6 @@ do --- privates end local spawnTemplate = Util.deepCopyTable(spawnData.groupTemplate) - ---@type Array - local removeableUnitNames = {} --[[ TODO: Spawn units at "current"/LastKnown position with them going to the next waypoint. ONLY when perstable data is found. @@ -138,12 +136,6 @@ do --- privates local name = unit["name"] --[[@as string]] SpearheadEvents.addOnUnitLostEventListener(name, self) - local state = Persistence.UnitState(name) - if state then - if state.isDead == true then - removeableUnitNames[#removeableUnitNames+1] = name - end - end if override and override.emptyLoadouts == true then if unit["payload"] and unit["payload"]["pylons"] then @@ -171,7 +163,6 @@ do --- privates local group = coalition.addGroup(country, spawnData.category, spawnTemplate) - for _, unit in pairs(group:getUnits()) do self:CheckUnitAndReplaceIfPersistentDead(unit) if isPersistent == true then -- 2.54.0 From e9fd3921a6f05a91b882ad2e54b681375b10ab5f Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 15:49:41 +0200 Subject: [PATCH 66/71] updated for LuaLS findings --- .luarc.json | 3 ++- src/classes/configuration/CapConfig.lua | 4 ++++ src/classes/persistence/Persistence.lua | 9 +++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.luarc.json b/.luarc.json index bbb66c5..d7c6e39 100644 --- a/.luarc.json +++ b/.luarc.json @@ -6,7 +6,8 @@ "workspace": { "checkThirdParty": false, "maxPreload": 1600, - "preloadFileSize": 1000 + "preloadFileSize": 1000, + "ignoreDir": [ "config.lua" ] }, "diagnostics": { "enable": true, diff --git a/src/classes/configuration/CapConfig.lua b/src/classes/configuration/CapConfig.lua index cd81a3f..3984c0a 100644 --- a/src/classes/configuration/CapConfig.lua +++ b/src/classes/configuration/CapConfig.lua @@ -21,6 +21,10 @@ function CapConfig.new() if SpearheadConfig == nil then SpearheadConfig = {} end if SpearheadConfig.CapConfig == nil then SpearheadConfig.CapConfig = {} end + if type(SpearheadConfig.CapConfig.enabled) ~= "boolean" then + SpearheadConfig.CapConfig.enabled = true + end + local enabled = SpearheadConfig.CapConfig.enabled if enabled == nil then enabled = true end self._isEnabled = enabled diff --git a/src/classes/persistence/Persistence.lua b/src/classes/persistence/Persistence.lua index 2684f90..eea895c 100644 --- a/src/classes/persistence/Persistence.lua +++ b/src/classes/persistence/Persistence.lua @@ -183,7 +183,9 @@ do local fileName = "Spearhead_Persistence.0.spearhead" if SpearheadConfig and SpearheadConfig.Persistence then if SpearheadConfig.Persistence.fileName then - + if type(SpearheadConfig.Persistence.fileName) ~= "string" then + SpearheadConfig.Persistence.fileName = "Spearhead_Persistence.0.spearhead" + end local userFileName = SpearheadConfig.Persistence.fileName local split = Util.split_string(userFileName, ".") @@ -201,7 +203,10 @@ do fileName = table.concat(split, ".") end - if SpearheadConfig.Persistence.directory ~= nil then + if SpearheadConfig.Persistence.directory then + if type(SpearheadConfig.Persistence.directory) ~= "string" then + SpearheadConfig.Persistence.directory = lfs.writedir() .. "\\Data" + end dir = SpearheadConfig.Persistence.directory end end -- 2.54.0 From 205efbee8a66fc162562e087325cbcc152ba4e14 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 16:12:57 +0200 Subject: [PATCH 67/71] updated for LuaLS findings --- src/classes/capClasses/airGroups/InterceptGroup.lua | 3 ++- src/classes/stageClasses/missions/baseMissions/Mission.lua | 6 +++--- src/classes/util/DcsUtil.lua | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/classes/capClasses/airGroups/InterceptGroup.lua b/src/classes/capClasses/airGroups/InterceptGroup.lua index 652ca5b..aceff83 100644 --- a/src/classes/capClasses/airGroups/InterceptGroup.lua +++ b/src/classes/capClasses/airGroups/InterceptGroup.lua @@ -226,7 +226,8 @@ function InterceptGroup:UpdateTask() return 30 -- Return to base if no intercept point could be calculated end - local mission = nil + ---@type table + local mission if self:IsInAir() == true then -- If the group is in the air, create an intercept mission mission = INTERCEPT.getMissionFromInAir( diff --git a/src/classes/stageClasses/missions/baseMissions/Mission.lua b/src/classes/stageClasses/missions/baseMissions/Mission.lua index 8890a3a..9732880 100644 --- a/src/classes/stageClasses/missions/baseMissions/Mission.lua +++ b/src/classes/stageClasses/missions/baseMissions/Mission.lua @@ -68,10 +68,10 @@ function Mission:SpawnPersistedState() end function Mission:SpawnActive() end ---comment ----@param checkHealth boolean ----@param messageIfDone boolean +---@param _checkHealth boolean +---@param _messageIfDone boolean ---@diagnostic disable-next-line: unused-local -function Mission:UpdateState(checkHealth, messageIfDone) end +function Mission:UpdateState(_checkHealth, _messageIfDone) end function Mission:StartCheckingContinuous() end function Mission:PercentageComplete() diff --git a/src/classes/util/DcsUtil.lua b/src/classes/util/DcsUtil.lua index 434f585..d63f640 100644 --- a/src/classes/util/DcsUtil.lua +++ b/src/classes/util/DcsUtil.lua @@ -293,7 +293,8 @@ do -- INIT DCS_UTIL if Util.tableLength(group_names) < 1 then return {} end for k = 1, #group_names do - local entry = nil + ---@type { unit : Unit|StaticObject|nil, groupname: string }|nil + local entry local group = Group.getByName(group_names[k]) if group ~= nil then entry = { unit = group:getUnit(1), groupname = group_names[k] } @@ -302,7 +303,7 @@ do -- INIT DCS_UTIL end if entry and entry.unit and entry.unit:isExist() == true then - units[#units + 1] = entry + units[#units + 1] = { groupname = entry.groupname, unit = entry.unit } end end -- 2.54.0 From 18dcf6c0926fbe70ddbe2ac5612d0cfbe0302e5d Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 16:21:15 +0200 Subject: [PATCH 68/71] updated for LuaLS findings --- .../stageClasses/missions/ZoneMission.lua | 4 +- .../missions/baseMissions/Mission.lua | 43 +++++++++---------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/classes/stageClasses/missions/ZoneMission.lua b/src/classes/stageClasses/missions/ZoneMission.lua index 5139a8b..768ef74 100644 --- a/src/classes/stageClasses/missions/ZoneMission.lua +++ b/src/classes/stageClasses/missions/ZoneMission.lua @@ -66,8 +66,6 @@ local function ParseZoneName(input) } end -MINIMAL_UNITS_ALIVE_RATIO = 0.21 - ---comment ---@param zoneName string ---@param priority MissionPriority @@ -232,7 +230,7 @@ end ---@param messageIfDone boolean function ZoneMission:UpdateState(checkHealth, messageIfDone) if checkHealth == nil then checkHealth = false end - if messageIfDone == false then messageIfDone = true end + if messageIfDone == nil then messageIfDone = true end if checkHealth == true then diff --git a/src/classes/stageClasses/missions/baseMissions/Mission.lua b/src/classes/stageClasses/missions/baseMissions/Mission.lua index 9732880..1ef76d8 100644 --- a/src/classes/stageClasses/missions/baseMissions/Mission.lua +++ b/src/classes/stageClasses/missions/baseMissions/Mission.lua @@ -133,9 +133,9 @@ function Mission:ForceMissionComplete() self:NotifyMissionComplete() end ----@param groupId number +---@param _groupId number ---@diagnostic disable-next-line: unused-local -function Mission:MarkMissionAreaToGroup(groupId) end +function Mission:MarkMissionAreaToGroup(_groupId) end ---endregion @@ -147,29 +147,26 @@ function Mission:ToStateString() return "status: in progress" end --endregion -do --aliases +--- @alias MissionPriority +--- | "none" +--- | "primary" +--- | "secondary" - --- @alias MissionPriority - --- | "none" - --- | "primary" - --- | "secondary" +--- @alias MissionType +--- | "nil" +--- | "STRIKE" +--- | "CAS" +--- | "BAI" +--- | "DEAD" +--- | "SAM" +--- | "OCA" +--- | "LOGISTICS" - --- @alias MissionType - --- | "nil" - --- | "STRIKE" - --- | "CAS" - --- | "BAI" - --- | "DEAD" - --- | "SAM" - --- | "OCA" - --- | "LOGISTICS" +--- @alias MissionState +--- | "NEW" +--- | "WAITING" +--- | "ACTIVE" +--- | "COMPLETED" - --- @alias MissionState - --- | "NEW" - --- | "WAITING" - --- | "ACTIVE" - --- | "COMPLETED" - -end return Mission \ No newline at end of file -- 2.54.0 From 660f1091475bc684fe5065255efbcf263f96a8e5 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 18:01:26 +0200 Subject: [PATCH 69/71] cleaned up aliases --- src/classes/definitions/aliases.lua | 19 ------------------- src/classes/spearhead_routeutil.lua | 3 ++- .../stageClasses/missions/ZoneMission.lua | 6 +++--- src/classes/util/Logger.lua | 7 +++++++ 4 files changed, 12 insertions(+), 23 deletions(-) delete mode 100644 src/classes/definitions/aliases.lua diff --git a/src/classes/definitions/aliases.lua b/src/classes/definitions/aliases.lua deleted file mode 100644 index 1971941..0000000 --- a/src/classes/definitions/aliases.lua +++ /dev/null @@ -1,19 +0,0 @@ - - - -do -- mission aliases - - --- @alias LogLevel - --- | "DEBUG" - --- | "INFO" - --- | "WARN" - --- | "ERROR" - --- | "NONE" - - ---@class Array: { [integer]: T } - -end - ----@class KeyValuePair ----@field key string ----@field value any diff --git a/src/classes/spearhead_routeutil.lua b/src/classes/spearhead_routeutil.lua index 82c7c47..a345b55 100644 --- a/src/classes/spearhead_routeutil.lua +++ b/src/classes/spearhead_routeutil.lua @@ -261,7 +261,8 @@ do --setup route util if racetrackSecondPoint then orbitType = "Race-Track" end local basePoint = base:getPoint() - local points = {} + ---@type Array
+ local points if racetrackSecondPoint == nil then points = { [1] = FlyToPointTask(capPoint, altitude, speed, additionalFlyOverTasks), diff --git a/src/classes/stageClasses/missions/ZoneMission.lua b/src/classes/stageClasses/missions/ZoneMission.lua index 768ef74..48cd1e2 100644 --- a/src/classes/stageClasses/missions/ZoneMission.lua +++ b/src/classes/stageClasses/missions/ZoneMission.lua @@ -227,10 +227,10 @@ end ---@internal ---@param checkHealth boolean ----@param messageIfDone boolean -function ZoneMission:UpdateState(checkHealth, messageIfDone) +---@param _messageIfDone boolean +function ZoneMission:UpdateState(checkHealth, _messageIfDone) if checkHealth == nil then checkHealth = false end - if messageIfDone == nil then messageIfDone = true end + if _messageIfDone == nil then _messageIfDone = true end if checkHealth == true then diff --git a/src/classes/util/Logger.lua b/src/classes/util/Logger.lua index 5016cc7..6977d22 100644 --- a/src/classes/util/Logger.lua +++ b/src/classes/util/Logger.lua @@ -3,6 +3,13 @@ local Util = require("classes.util.Util") local SpearheadConfig = require("classes.configuration.GlobalConfig") +--- @alias LogLevel +--- | "DEBUG" +--- | "INFO" +--- | "WARN" +--- | "ERROR" +--- | "NONE" + ---@type LogLevel local defaultLogLevel = "INFO" -- 2.54.0 From d289f341664a77a2b20e844a0a9f9ea4f31e03d6 Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 18:03:39 +0200 Subject: [PATCH 70/71] cleaned up aliases --- src/classes/util/DcsUtil.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/classes/util/DcsUtil.lua b/src/classes/util/DcsUtil.lua index d63f640..2a1ef77 100644 --- a/src/classes/util/DcsUtil.lua +++ b/src/classes/util/DcsUtil.lua @@ -32,6 +32,10 @@ do -- INIT DCS_UTIL ---| "Cilinder" ---| "Polygon" + ---@class KeyValuePair + ---@field key string + ---@field value any + ---@class SpearheadTriggerZone ---@field name string ---@field location Vec2 -- 2.54.0 From 3a2dc644f8269592efb8de210eb95e5f1cc368fa Mon Sep 17 00:00:00 2001 From: dutchie031 Date: Sun, 20 Sep 2026 18:06:13 +0200 Subject: [PATCH 71/71] cleaned up aliases --- src/classes/stageClasses/missions/ZoneMission.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/classes/stageClasses/missions/ZoneMission.lua b/src/classes/stageClasses/missions/ZoneMission.lua index 48cd1e2..4acfaff 100644 --- a/src/classes/stageClasses/missions/ZoneMission.lua +++ b/src/classes/stageClasses/missions/ZoneMission.lua @@ -227,10 +227,9 @@ end ---@internal ---@param checkHealth boolean ----@param _messageIfDone boolean -function ZoneMission:UpdateState(checkHealth, _messageIfDone) +---@param _ boolean +function ZoneMission:UpdateState(checkHealth, _) if checkHealth == nil then checkHealth = false end - if _messageIfDone == nil then _messageIfDone = true end if checkHealth == true then -- 2.54.0