Fixed possible nil errors.

This commit is contained in:
iTracerFacer 2025-12-01 10:30:19 -06:00
parent 6acad724c2
commit 552eff51e1
4 changed files with 32 additions and 13 deletions

View File

@ -19,6 +19,9 @@ REQUIRES:
]] ]]
---@diagnostic disable: undefined-global, lowercase-global
-- MOOSE framework globals are defined at runtime by DCS World
-- Single-run guard to prevent duplicate dispatcher loops if script is reloaded -- Single-run guard to prevent duplicate dispatcher loops if script is reloaded
if _G.__TDAC_DISPATCHER_RUNNING then if _G.__TDAC_DISPATCHER_RUNNING then

View File

@ -1,3 +1,4 @@
---@diagnostic disable: undefined-field
--[[ --[[
UNIVERSAL TADC UNIVERSAL TADC
@ -124,6 +125,8 @@ AUTHOR:
VERSION: 1.0 VERSION: 1.0
]] ]]
---@diagnostic disable: undefined-global, lowercase-global
-- MOOSE framework globals are defined at runtime by DCS World
--[[ --[[
@ -906,7 +909,7 @@ function cargoEventHandler:onEvent(event)
end end
end end
if closestAirbase then if closestAirbase and closestSquadron then
local abCoalition = closestAirbase:GetCoalition() local abCoalition = closestAirbase:GetCoalition()
local coalitionKey = (abCoalition == coalition.side.RED) and "red" or "blue" local coalitionKey = (abCoalition == coalition.side.RED) and "red" or "blue"
if closestDistance < ADVANCED_SETTINGS.cargoLandingEventRadius then if closestDistance < ADVANCED_SETTINGS.cargoLandingEventRadius then
@ -1009,7 +1012,7 @@ function cargoEventHandler:onEvent(event)
end end
end end
if closestAirbase then if closestAirbase and closestSquadron then
local abCoalition = closestAirbase:GetCoalition() local abCoalition = closestAirbase:GetCoalition()
local coalitionKey = (abCoalition == coalition.side.RED) and "red" or "blue" local coalitionKey = (abCoalition == coalition.side.RED) and "red" or "blue"
if closestDistance < ADVANCED_SETTINGS.cargoLandingEventRadius then if closestDistance < ADVANCED_SETTINGS.cargoLandingEventRadius then
@ -1157,7 +1160,7 @@ function cargoEventHandler:onEvent(event)
end end
end end
if closestAirbase and closestDistance < ADVANCED_SETTINGS.cargoLandingEventRadius then if closestAirbase and closestSquadron and closestDistance and closestDistance < ADVANCED_SETTINGS.cargoLandingEventRadius then
local abCoalition = closestAirbase:GetCoalition() local abCoalition = closestAirbase:GetCoalition()
local coalitionKey = (abCoalition == coalition.side.RED) and "red" or "blue" local coalitionKey = (abCoalition == coalition.side.RED) and "red" or "blue"
log("LANDING DELIVERY (raw-fallback): " .. rawNameUp .. " landed and delivered at " .. closestSquadron.airbaseName .. " (distance: " .. math.floor(closestDistance) .. "m)") log("LANDING DELIVERY (raw-fallback): " .. rawNameUp .. " landed and delivered at " .. closestSquadron.airbaseName .. " (distance: " .. math.floor(closestDistance) .. "m)")
@ -1254,7 +1257,7 @@ function cargoEventHandler:onEvent(event)
end end
end end
if closestAirbase and closestDistance < ADVANCED_SETTINGS.cargoLandingEventRadius then if closestAirbase and closestSquadron and closestDistance and closestDistance < ADVANCED_SETTINGS.cargoLandingEventRadius then
local abCoalition = closestAirbase:GetCoalition() local abCoalition = closestAirbase:GetCoalition()
local coalitionKey = (abCoalition == coalition.side.RED) and "red" or "blue" local coalitionKey = (abCoalition == coalition.side.RED) and "red" or "blue"
@ -1297,7 +1300,8 @@ function cargoEventHandler:onEvent(event)
end end
if ADVANCED_SETTINGS.verboseProxyLogging then if ADVANCED_SETTINGS.verboseProxyLogging then
log("LANDING DELIVERY (raw-proxy): " .. tostring(rawName) .. " landed and delivered at " .. closestSquadron.airbaseName .. " (distance: " .. math.floor(closestDistance) .. "m) - using proxy object", true) local distanceStr = closestDistance and math.floor(closestDistance) .. "m" or "unknown"
log("LANDING DELIVERY (raw-proxy): " .. tostring(rawName) .. " landed and delivered at " .. closestSquadron.airbaseName .. " (distance: " .. distanceStr .. ") - using proxy object", true)
end end
processCargoDelivery(cargoProxy, closestSquadron, abCoalition, coalitionKey) processCargoDelivery(cargoProxy, closestSquadron, abCoalition, coalitionKey)
end end
@ -1484,7 +1488,8 @@ local function sendInterceptorHome(interceptor, coalitionSide)
-- Schedule cleanup after they should have landed -- Schedule cleanup after they should have landed
local coalitionSettings = getCoalitionSettings(coalitionSide) local coalitionSettings = getCoalitionSettings(coalitionSide)
local flightTime = math.ceil(shortestDistance / (ADVANCED_SETTINGS.rtbSpeed * 0.5144)) + coalitionSettings.rtbFlightBuffer local rtbBuffer = (coalitionSettings and coalitionSettings.rtbFlightBuffer) or 300
local flightTime = math.ceil(shortestDistance / (ADVANCED_SETTINGS.rtbSpeed * 0.5144)) + rtbBuffer
SCHEDULER:New(nil, function() SCHEDULER:New(nil, function()
local coalitionKey = (coalitionSide == coalition.side.RED) and "red" or "blue" local coalitionKey = (coalitionSide == coalition.side.RED) and "red" or "blue"
@ -1734,11 +1739,12 @@ local function launchInterceptor(threatGroup, coalitionSide)
end end
-- Calculate how many interceptors to launch using zone-modified ratio -- Calculate how many interceptors to launch using zone-modified ratio
local finalInterceptRatio = coalitionSettings.interceptRatio * zoneResponseRatio local baseInterceptRatio = (coalitionSettings and coalitionSettings.interceptRatio) or 1.0
local finalInterceptRatio = baseInterceptRatio * zoneResponseRatio
local interceptorsNeeded = math.max(1, math.ceil(threatSize * finalInterceptRatio)) local interceptorsNeeded = math.max(1, math.ceil(threatSize * finalInterceptRatio))
-- Check if we have capacity -- Check if we have capacity
if countActiveFighters(coalitionSide) + interceptorsNeeded > coalitionSettings.maxActiveCAP then if coalitionSettings and countActiveFighters(coalitionSide) + interceptorsNeeded > coalitionSettings.maxActiveCAP then
interceptorsNeeded = coalitionSettings.maxActiveCAP - countActiveFighters(coalitionSide) interceptorsNeeded = coalitionSettings.maxActiveCAP - countActiveFighters(coalitionSide)
if interceptorsNeeded <= 0 then if interceptorsNeeded <= 0 then
log(coalitionName .. " max fighters airborne, skipping launch") log(coalitionName .. " max fighters airborne, skipping launch")
@ -1837,6 +1843,7 @@ local function launchInterceptor(threatGroup, coalitionSide)
end end
-- Emergency cleanup (safety net) -- Emergency cleanup (safety net)
local cleanupTime = (coalitionSettings and coalitionSettings.emergencyCleanupTime) or 7200
SCHEDULER:New(nil, function() SCHEDULER:New(nil, function()
local name = nil local name = nil
if interceptor and interceptor.GetName then if interceptor and interceptor.GetName then
@ -1847,7 +1854,7 @@ local function launchInterceptor(threatGroup, coalitionSide)
log("Emergency cleanup of " .. coalitionName .. " " .. name .. " (should have RTB'd)") log("Emergency cleanup of " .. coalitionName .. " " .. name .. " (should have RTB'd)")
destroyInterceptorGroup(interceptor, coalitionKey, 0) destroyInterceptorGroup(interceptor, coalitionKey, 0)
end end
end, {}, coalitionSettings.emergencyCleanupTime) end, {}, cleanupTime)
end end
end end
@ -1866,8 +1873,11 @@ local function launchInterceptor(threatGroup, coalitionSide)
-- Apply cooldown immediately when squadron launches -- Apply cooldown immediately when squadron launches
local currentTime = timer.getTime() local currentTime = timer.getTime()
squadronCooldowns[coalitionKey][squadron.templateName] = currentTime + coalitionSettings.squadronCooldown if coalitionSettings and coalitionSettings.squadronCooldown then
local cooldownMinutes = coalitionSettings.squadronCooldown / 60 squadronCooldowns[coalitionKey][squadron.templateName] = currentTime + coalitionSettings.squadronCooldown
local cooldownMinutes = coalitionSettings.squadronCooldown / 60
cooldownMinutes = coalitionSettings.squadronCooldown / 60
end
log(coalitionName .. " Squadron " .. squadron.displayName .. " LAUNCHED! Applying " .. cooldownMinutes .. " minute cooldown") log(coalitionName .. " Squadron " .. squadron.displayName .. " LAUNCHED! Applying " .. cooldownMinutes .. " minute cooldown")
end end
end end
@ -1891,7 +1901,8 @@ local function detectThreatsForCoalition(coalitionSide)
local enemyAircraft = cachedSets[cacheKey] local enemyAircraft = cachedSets[cacheKey]
local threatCount = 0 local threatCount = 0
enemyAircraft:ForEach(function(enemyGroup) if enemyAircraft then
enemyAircraft:ForEach(function(enemyGroup)
if enemyGroup and enemyGroup:IsAlive() then if enemyGroup and enemyGroup:IsAlive() then
threatCount = threatCount + 1 threatCount = threatCount + 1
currentThreats[enemyGroup:GetName()] = true currentThreats[enemyGroup:GetName()] = true
@ -1931,6 +1942,7 @@ local function detectThreatsForCoalition(coalitionSide)
log(coalitionName .. " scan complete: " .. threatCount .. " threats, " .. countActiveFighters(coalitionSide) .. " active fighters, " .. log(coalitionName .. " scan complete: " .. threatCount .. " threats, " .. countActiveFighters(coalitionSide) .. " active fighters, " ..
assignedCount .. " assigned") assignedCount .. " assigned")
end
end end
-- Main threat detection loop - calls both coalitions -- Main threat detection loop - calls both coalitions

View File

@ -76,7 +76,9 @@ RED_SQUADRON_CONFIG = {
} }
}, },
]] ]]
---@diagnostic disable: undefined-global, lowercase-global
-- MOOSE framework globals are defined at runtime by DCS World
-- ADD YOUR RED SQUADRONS HERE -- ADD YOUR RED SQUADRONS HERE
{ {
templateName = "Sukhumi CAP", -- Change to your RED template name templateName = "Sukhumi CAP", -- Change to your RED template name

View File

@ -6,6 +6,8 @@
-- for either coalition, with options for cold/hot/runway start. -- for either coalition, with options for cold/hot/runway start.
-- Includes cleanup and status commands. -- Includes cleanup and status commands.
-- ================================================================ -- ================================================================
---@diagnostic disable: undefined-global, lowercase-global
-- MOOSE framework globals are defined at runtime by DCS World
-- List of available airbases (Caucasus map, add/remove as needed) -- List of available airbases (Caucasus map, add/remove as needed)
local AIRBASES = { local AIRBASES = {