diff --git a/DCS_Kola/Operation_Polar_Shield/AFAC_Test.lua b/DCS_Kola/Operation_Polar_Shield/AFAC_Test.lua deleted file mode 100644 index c055194..0000000 --- a/DCS_Kola/Operation_Polar_Shield/AFAC_Test.lua +++ /dev/null @@ -1,126 +0,0 @@ --- Simple AFAC Test Script --- This is a minimal version to test if scripts load at all - --- Test if script loads -trigger.action.outText("TEST SCRIPT: Loading AFAC test...", 15) -env.info("AFAC TEST: Script is loading") - --- Basic data structure -AFAC = { - pilots = {}, - debug = true -} - --- Simple logging -function AFAC.log(message) - env.info("AFAC TEST: " .. tostring(message)) - trigger.action.outText("AFAC: " .. tostring(message), 5) -end - -AFAC.log("Test script initialized") - --- Simple aircraft check -AFAC.afacTypes = { - "UH-1H" -} - -function AFAC.isAFAC(unit) - if not unit then return false end - local unitType = unit:getTypeName() - AFAC.log("Checking aircraft type: " .. unitType) - - for _, afacType in ipairs(AFAC.afacTypes) do - if unitType == afacType then - AFAC.log("MATCH FOUND: " .. unitType .. " is AFAC!") - return true - end - end - return false -end - -function AFAC.addPilot(unit) - local unitName = unit:getName() - AFAC.log("Adding AFAC pilot: " .. unitName) - - local groupId = unit:getGroup():getID() - trigger.action.outTextForGroup(groupId, "AFAC ACTIVE: " .. unit:getTypeName(), 20) - - -- Add simple F10 menu - local mainMenu = missionCommands.addSubMenuForGroup(groupId, "AFAC TEST") - missionCommands.addCommandForGroup(groupId, "Test Command", mainMenu, function() - trigger.action.outTextForGroup(groupId, "AFAC Test Menu Works!", 10) - end) - - AFAC.pilots[unitName] = unit -end - --- Event handler -AFAC.EventHandler = {} - -function AFAC.EventHandler:onEvent(event) - AFAC.log("Event received: " .. tostring(event.id)) - - if event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT then - AFAC.log("Player entered unit event") - local unit = event.initiator - - if unit then - AFAC.log("Unit type: " .. unit:getTypeName()) - if AFAC.isAFAC(unit) then - AFAC.log("AFAC detected, adding pilot") - AFAC.addPilot(unit) - end - end - end - - if event.id == world.event.S_EVENT_BIRTH then - AFAC.log("Birth event") - local unit = event.initiator - - if unit and Object.getCategory(unit) == Object.Category.UNIT then - local objDesc = unit:getDesc() - if objDesc.category == Unit.Category.AIRPLANE or objDesc.category == Unit.Category.HELICOPTER then - AFAC.log("Aircraft born: " .. unit:getTypeName()) - if AFAC.isAFAC(unit) then - timer.scheduleFunction(function(args) - if args[1]:isActive() then - AFAC.addPilot(args[1]) - end - end, {unit}, timer.getTime() + 2) - end - end - end - end -end - --- Add event handler -world.addEventHandler(AFAC.EventHandler) -AFAC.log("Event handler added") - --- Check existing units -timer.scheduleFunction(function() - AFAC.log("Checking existing units...") - - for coalitionId = 1, 2 do - local heliGroups = coalition.getGroups(coalitionId, Group.Category.HELICOPTER) - AFAC.log("Found " .. #heliGroups .. " helicopter groups for coalition " .. coalitionId) - - for _, group in ipairs(heliGroups) do - local units = group:getUnits() - if units then - for _, unit in ipairs(units) do - if unit and unit:isActive() then - AFAC.log("Found helicopter: " .. unit:getTypeName()) - if AFAC.isAFAC(unit) and unit:getPlayerName() then - AFAC.log("Found player AFAC: " .. unit:getName()) - AFAC.addPilot(unit) - end - end - end - end - end - end -end, nil, timer.getTime() + 3) - -AFAC.log("AFAC Test Script loaded successfully!") -trigger.action.outText("AFAC Test Script loaded!", 10) \ No newline at end of file diff --git a/DCS_Kola/Operation_Polar_Shield/Moose_CTLD_TypeBased.lua b/DCS_Kola/Operation_Polar_Shield/Moose_CTLD_TypeBased.lua deleted file mode 100644 index 0ed8e35..0000000 --- a/DCS_Kola/Operation_Polar_Shield/Moose_CTLD_TypeBased.lua +++ /dev/null @@ -1,1126 +0,0 @@ --- Enhanced CTLD System with Aircraft Type Detection (like AFAC) --- Automatically detects and adds aircraft based on their type rather than specific names - --- Switch the tracing On ---BASE:TraceOnOff( true ) - -local msgTime = 15 - --- ===================================================== --- CTLD CONFIGURATION --- ===================================================== - -CTLD_CONFIG = { - -- Aircraft types that can perform CTLD operations - transportAircraft = { - -- Helicopters - "UH-1H", "UH-60L", "UH-60A", "Mi-8MT", "Mi-24P", "Ka-50", "Ka-50_3", - "SA342L", "SA342M", "SA342Mistral", "SA342Minigun", - "CH-47F", "CH-53E", "AH-64D_BLK_II", "Mi-26", - -- Fixed Wing - "C-130", "An-26B", "Yak-40", "C-47" - }, - - debug = true -} - --- ===================================================== --- CTLD DATA STORAGE --- ===================================================== - -CTLD_DATA = { - pilots = {}, -- Store pilot information - blueInstance = nil, -- Blue CTLD instance - redInstance = nil -- Red CTLD instance -} - --- ===================================================== --- UTILITY FUNCTIONS --- ===================================================== - -function CTLD_LOG(message) - if CTLD_CONFIG.debug then - env.info("CTLD_AUTO: " .. tostring(message)) - end -end - -function CTLD_CONTAINS(table, value) - for i = 1, #table do - if table[i] == value then return true end - end - return false -end - -function CTLD_GET_GROUP_ID(unit) - local group = unit:getGroup() - if group then return group:getID() end - return nil -end - --- ===================================================== --- AIRCRAFT DETECTION --- ===================================================== - -function CTLD_IS_TRANSPORT(unit) - if not unit then return false end - local unitType = unit:getTypeName() - CTLD_LOG("Checking aircraft type: " .. unitType) - local result = CTLD_CONTAINS(CTLD_CONFIG.transportAircraft, unitType) - CTLD_LOG("isTransport result for " .. unitType .. ": " .. tostring(result)) - return result -end - --- ===================================================== --- CTLD INSTANCES SETUP --- ===================================================== - --- Initialize CTLD instances without specific group names (empty arrays) -local ctld_blue = CTLD:New(coalition.side.BLUE, {}, "Transport Aircraft") -local ctld_red = CTLD:New(coalition.side.RED, {}, "Transport Aircraft") - --- Store instances globally -CTLD_DATA.blueInstance = ctld_blue -CTLD_DATA.redInstance = ctld_red - --- Scores Awarded for Dropping, Building and Repairing logistics -local pointsAwardedTroopsDeployed = 1 -local pointsAwardedTroopsExtracted = 1 -local pointsAwardedTroopsPickedup = 1 -local pointsAwardedTroopsRTB = 2 -local pointsAwardedCrateDropped = 5 -local pointsAwardedCrateBuilt = 2 -local pointsAwardedCrateRepair = 5 - --- ===================================================== --- SUPPLY ZONES SETUP --- ===================================================== - --- Blue Coalition Supply Zones -ctld_blue:AddCTLDZone("Luostari Supply", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Blue, true, true) -ctld_blue:AddCTLDZone("Ivalo Supply", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Blue, true, true) -ctld_blue:AddCTLDZone("FARP-1 Supply", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Blue, true, true) -ctld_blue:AddCTLDZone("Dallas FARP Supply", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Blue, true, true) -ctld_blue:AddCTLDZone("Paris FARP Supply", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Blue, true, true) ---ctld_blue:AddCTLDZone("Tromso Airbase", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Blue, true, true) - --- Red Coalition Supply Zones ---ctld_red:AddCTLDZone("Murmansk Airbase", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Red, true, true) ---ctld_red:AddCTLDZone("Severomorsk Airbase", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Red, true, true) ---ctld_red:AddCTLDZone("Pechenga Airbase", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Red, true, true) ---ctld_red:AddCTLDZone("Alakurtti Airbase", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Red, true, true) - --- Neutral/Contested Zones (can be used by both sides) --- Uncomment and modify as needed for your mission --- ctld_blue:AddCTLDZone("Contested Zone 1", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Green, true, true) --- ctld_red:AddCTLDZone("Contested Zone 1", CTLD.CargoZoneType.LOAD, SMOKECOLOR.Green, true, true) - --- Set CTLD Options for Blue Side -ctld_blue.useprefix = false -- Set to false to allow all transport aircraft -ctld_blue.CrateDistance = 100 -ctld_blue.dropcratesanywhere = true -ctld_blue.maximumHoverHeight = 15 -ctld_blue.minimumHoverHeight = 4 -ctld_blue.forcehoverload = false -ctld_blue.hoverautoloading = true -ctld_blue.smokedistance = 10000 -ctld_blue.movetroopstowpzone = true -ctld_blue.movetroopsdistance = 2000 -ctld_blue.suppressmessages = false -ctld_blue.repairtime = 300 -ctld_blue.buildtime = 20 -ctld_blue.cratecountry = country.id.USA -ctld_blue.allowcratepickupagain = true -ctld_blue.enableslingload = false -ctld_blue.pilotmustopendoors = false -ctld_blue.SmokeColor = SMOKECOLOR.Blue -ctld_blue.FlareColor = FLARECOLOR.Green -ctld_blue.basetype = "container_cargo" -ctld_blue.droppedbeacontimeout = 600 -ctld_blue.usesubcats = true -ctld_blue.placeCratesAhead = true -ctld_blue.nobuildinloadzones = true -ctld_blue.movecratesbeforebuild = false -ctld_blue.surfacetypes = {land.SurfaceType.LAND, land.SurfaceType.ROAD, land.SurfaceType.RUNWAY, land.SurfaceType.SHALLOW_WATER} - --- Set CTLD Options for Red Side (similar to Blue) -ctld_red.useprefix = false -- Set to false to allow all transport aircraft -ctld_red.CrateDistance = 100 -ctld_red.dropcratesanywhere = true -ctld_red.maximumHoverHeight = 15 -ctld_red.minimumHoverHeight = 4 -ctld_red.forcehoverload = false -ctld_red.hoverautoloading = true -ctld_red.smokedistance = 10000 -ctld_red.movetroopstowpzone = true -ctld_red.movetroopsdistance = 2000 -ctld_red.suppressmessages = false -ctld_red.repairtime = 300 -ctld_red.buildtime = 20 -ctld_red.cratecountry = country.id.RUSSIA -ctld_red.allowcratepickupagain = true -ctld_red.enableslingload = false -ctld_red.pilotmustopendoors = false -ctld_red.SmokeColor = SMOKECOLOR.Red -ctld_red.FlareColor = FLARECOLOR.Red -ctld_red.basetype = "container_cargo" -ctld_red.droppedbeacontimeout = 600 -ctld_red.usesubcats = true -ctld_red.placeCratesAhead = true -ctld_red.nobuildinloadzones = true -ctld_red.movecratesbeforebuild = false -ctld_red.surfacetypes = {land.SurfaceType.LAND, land.SurfaceType.ROAD, land.SurfaceType.RUNWAY, land.SurfaceType.SHALLOW_WATER} - --- ===================================================== --- DYNAMIC UNIT DEFINITIONS --- ===================================================== - --- Unit definitions for dynamic spawning (no templates needed!) -CTLD_UNIT_DEFINITIONS = { - BLUE = { - -- Infantry/Troops - ["2 Recon"] = { - units = { - {type = "Soldier M4", name = "Recon-1", x = 0, y = 0}, - {type = "Soldier M4", name = "Recon-2", x = 5, y = 0} - }, - category = "TROOPS", - seats = 2, - stock = 10 - }, - ["4 Anti-Air"] = { - units = { - {type = "Soldier stinger", name = "AA-1", x = 0, y = 0}, - {type = "Soldier stinger", name = "AA-2", x = 5, y = 0}, - {type = "Soldier stinger", name = "AA-3", x = -5, y = 0}, - {type = "Soldier stinger", name = "AA-4", x = 0, y = 5} - }, - category = "TROOPS", - seats = 4, - stock = 10 - }, - ["6 Anti-Tank"] = { - units = { - {type = "Soldier M4", name = "AT-1", x = 0, y = 0}, - {type = "Soldier M4", name = "AT-2", x = 5, y = 0}, - {type = "Soldier M4", name = "AT-3", x = -5, y = 0}, - {type = "Soldier M4", name = "AT-4", x = 0, y = 5}, - {type = "Soldier M4", name = "AT-5", x = 0, y = -5}, - {type = "Soldier M4", name = "AT-6", x = 10, y = 0} - }, - category = "TROOPS", - seats = 6, - stock = 12 - }, - - -- Vehicles - ["ATGM HMMWV"] = { - units = { - {type = "M1045 HMMWV TOW", name = "ATGM-HMMWV", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 1, - stock = 10, - subcategory = "Anti-Tank" - }, - ["IFV M2A2 Bradley"] = { - units = { - {type = "M-2 Bradley", name = "Bradley-IFV", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 1, - stock = 10, - subcategory = "Anti-Tank" - }, - ["MBT M1A2 Abrams"] = { - units = { - {type = "M-1 Abrams", name = "Abrams-MBT", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 2, - stock = 10, - subcategory = "Anti-Tank" - }, - - -- SAM Systems - ["SAM Avenger"] = { - units = { - {type = "M1097 Avenger", name = "Avenger-1", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 2, - stock = 8, - subcategory = "Anti-Air" - }, - ["SAM Hawk Site"] = { - units = { - {type = "Hawk pcp", name = "Hawk-PCP", x = 0, y = 0}, - {type = "Hawk tr", name = "Hawk-TR", x = 20, y = 0}, - {type = "Hawk ln", name = "Hawk-LN-1", x = -15, y = 15}, - {type = "Hawk ln", name = "Hawk-LN-2", x = -15, y = -15}, - {type = "Hawk ln", name = "Hawk-LN-3", x = -30, y = 0} - }, - category = "VEHICLE", - crates = 4, - stock = 3, - subcategory = "Anti-Air" - }, - ["SAM Patriot Site"] = { - units = { - {type = "Patriot ECS", name = "Patriot-ECS", x = 0, y = 0}, - {type = "Patriot AMG", name = "Patriot-AMG", x = 15, y = 0}, - {type = "Patriot ICC", name = "Patriot-ICC", x = -15, y = 0}, - {type = "Patriot ln", name = "Patriot-LN-1", x = 25, y = 25}, - {type = "Patriot ln", name = "Patriot-LN-2", x = 25, y = -25}, - {type = "Patriot ln", name = "Patriot-LN-3", x = -25, y = 25}, - {type = "Patriot ln", name = "Patriot-LN-4", x = -25, y = -25} - }, - category = "VEHICLE", - crates = 8, - stock = 2, - subcategory = "Anti-Air" - }, - ["EWR Roland"] = { - units = { - {type = "Roland ADS", name = "Roland-ADS", x = 0, y = 0}, - {type = "Roland Radar", name = "Roland-Radar", x = 15, y = 0} - }, - category = "VEHICLE", - crates = 1, - stock = 5, - subcategory = "Anti-Air" - }, - - -- Support Vehicles - ["Recon HMMWV"] = { - units = { - {type = "M1025 HMMWV", name = "Recon-HMMWV", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 1, - stock = 10, - subcategory = "Ground Ops" - }, - ["Supply Truck"] = { - units = { - {type = "M 818", name = "Supply-Truck", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 1, - stock = 10, - subcategory = "Ground Ops" - }, - ["FARP Equipment"] = { - units = { - {type = "FARP Fuel Truck", name = "FARP-Fuel", x = 0, y = 0}, - {type = "FARP Ammo Dump Coating", name = "FARP-Ammo", x = 15, y = 0}, - {type = "FARP CP Blindage", name = "FARP-CP", x = -15, y = 0}, - {type = "FARP Tent", name = "FARP-Tent", x = 0, y = 15} - }, - category = "VEHICLE", - crates = 4, - stock = 4, - subcategory = "Ground Ops" - } - }, - - RED = { - -- Infantry/Troops - ["2 Saboteurs"] = { - units = { - {type = "Soldier AK", name = "Saboteur-1", x = 0, y = 0}, - {type = "Soldier AK", name = "Saboteur-2", x = 5, y = 0} - }, - category = "TROOPS", - seats = 2, - stock = 50 - }, - ["4 Anti-Air"] = { - units = { - {type = "Soldier AK", name = "AA-1", x = 0, y = 0}, - {type = "Soldier AK", name = "AA-2", x = 5, y = 0}, - {type = "Soldier AK", name = "AA-3", x = -5, y = 0}, - {type = "Soldier AK", name = "AA-4", x = 0, y = 5} - }, - category = "TROOPS", - seats = 4, - stock = 50 - }, - ["6 Anti-Tank"] = { - units = { - {type = "Soldier AK", name = "AT-1", x = 0, y = 0}, - {type = "Soldier AK", name = "AT-2", x = 5, y = 0}, - {type = "Soldier AK", name = "AT-3", x = -5, y = 0}, - {type = "Soldier AK", name = "AT-4", x = 0, y = 5}, - {type = "Soldier AK", name = "AT-5", x = 0, y = -5}, - {type = "Soldier AK", name = "AT-6", x = 10, y = 0} - }, - category = "TROOPS", - seats = 6, - stock = 50 - }, - - -- Vehicles - ["ATGM BTR-RD"] = { - units = { - {type = "BTR-RD", name = "BTR-RD", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 1, - stock = 50, - subcategory = "Anti-Tank" - }, - ["APC IFV BMP"] = { - units = { - {type = "BMP-2", name = "BMP-IFV", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 1, - stock = 50, - subcategory = "Anti-Tank" - }, - ["MBT T-90"] = { - units = { - {type = "T-90", name = "T90-MBT", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 2, - stock = 50, - subcategory = "Anti-Tank" - }, - - -- SAM Systems - ["SA-8"] = { - units = { - {type = "Osa 9A33 ln", name = "SA8-LN", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 2, - stock = 10, - subcategory = "Anti-Air" - }, - ["SA-11"] = { - units = { - {type = "SA-11 Buk CC 9S470M1", name = "SA11-CC", x = 0, y = 0}, - {type = "SA-11 Buk SR 9S18M1", name = "SA11-SR", x = 20, y = 0}, - {type = "SA-11 Buk LN 9A310M1", name = "SA11-LN-1", x = -15, y = 15}, - {type = "SA-11 Buk LN 9A310M1", name = "SA11-LN-2", x = -15, y = -15} - }, - category = "VEHICLE", - crates = 4, - stock = 10, - subcategory = "Anti-Air" - }, - ["SA-10 Site"] = { - units = { - {type = "S-300PS 40B6M tr", name = "SA10-TR", x = 0, y = 0}, - {type = "S-300PS 40B6MD sr", name = "SA10-SR", x = 25, y = 0}, - {type = "S-300PS 5P85C ln", name = "SA10-LN-1", x = -20, y = 20}, - {type = "S-300PS 5P85C ln", name = "SA10-LN-2", x = -20, y = -20}, - {type = "S-300PS 5P85D ln", name = "SA10-LN-3", x = -35, y = 0}, - {type = "S-300PS 5P85D ln", name = "SA10-LN-4", x = -50, y = 20} - }, - category = "VEHICLE", - crates = 8, - stock = 5, - subcategory = "Anti-Air" - }, - - -- Support - ["Supply Truck"] = { - units = { - {type = "ZiL-131 APA-80", name = "Supply-Truck", x = 0, y = 0} - }, - category = "VEHICLE", - crates = 1, - stock = 50, - subcategory = "Ground Ops" - } - } -} - --- ===================================================== --- DYNAMIC UNIT SPAWNING FUNCTIONS --- ===================================================== - --- Generate unique group name -function CTLD_GENERATE_GROUP_NAME(basename, coalition) - local timestamp = os.time() - local coalitionName = coalition == coalition.side.BLUE and "BLUE" or "RED" - return string.format("%s-%s-%d-%d", coalitionName, basename, timestamp, math.random(1000, 9999)) -end - --- Calculate rotated position based on helicopter heading -function CTLD_CALCULATE_ROTATED_POSITION(baseX, baseY, heading) - local headingRad = math.rad(heading) - local cos_h = math.cos(headingRad) - local sin_h = math.sin(headingRad) - - return { - x = baseX * cos_h - baseY * sin_h, - y = baseX * sin_h + baseY * cos_h - } -end - --- Create dynamic group from definition -function CTLD_CREATE_DYNAMIC_GROUP(unitDef, spawnPoint, heading, coalition) - local groupName = CTLD_GENERATE_GROUP_NAME(unitDef.units[1].name, coalition) - local countryId = coalition == coalition.side.BLUE and country.id.USA or country.id.RUSSIA - - local groupData = { - ["name"] = groupName, - ["task"] = "Ground Nothing", - ["units"] = {} - } - - -- Create each unit in the group with proper positioning and heading - for i, unitInfo in ipairs(unitDef.units) do - local rotatedPos = CTLD_CALCULATE_ROTATED_POSITION(unitInfo.x, unitInfo.y, heading) - - local unitData = { - ["name"] = string.format("%s-%d", groupName, i), - ["type"] = unitInfo.type, - ["x"] = spawnPoint.x + rotatedPos.x, - ["y"] = spawnPoint.z + rotatedPos.y, - ["heading"] = math.rad(heading), - ["skill"] = "Average", - ["playerCanDrive"] = false - } - - table.insert(groupData.units, unitData) - end - - -- Spawn the group - local success, spawnedGroup = pcall(function() - return coalition.addGroup(countryId, Group.Category.GROUND, groupData) - end) - - if success and spawnedGroup then - CTLD_LOG("Successfully spawned dynamic group: " .. groupName) - return spawnedGroup - else - CTLD_LOG("Failed to spawn dynamic group: " .. groupName) - return nil - end -end - --- Setup dynamic cargo using the definitions (bypassing template checks) -function CTLD_SETUP_DYNAMIC_CARGO() - CTLD_LOG("Starting TEMPLATE-FREE dynamic cargo setup...") - - -- Multiple approaches to disable template checking - ctld_blue.checkTemplatePrefixes = false - ctld_red.checkTemplatePrefixes = false - - -- Force disable template validation entirely - local originalCheckTemplates = ctld_blue._CheckTemplates - ctld_blue._CheckTemplates = function(self, templates) - CTLD_LOG("Bypassing template check for: " .. tostring(templates)) - return true -- Always return success - end - - local originalCheckTemplatesRed = ctld_red._CheckTemplates - ctld_red._CheckTemplates = function(self, templates) - CTLD_LOG("Bypassing RED template check for: " .. tostring(templates)) - return true -- Always return success - end - - local blueCargoCount = 0 - local redCargoCount = 0 - - -- Setup Blue cargo with bypassed template checking - for cargoName, unitDef in pairs(CTLD_UNIT_DEFINITIONS.BLUE) do - CTLD_LOG("Setting up Blue cargo: " .. cargoName .. " (Category: " .. unitDef.category .. ")") - - -- Create dummy template entries to satisfy CTLD's internal checks - if unitDef.category == "TROOPS" then - -- Add to troops cargo without template validation - if not ctld_blue.TroopsCargo then ctld_blue.TroopsCargo = {} end - ctld_blue.TroopsCargo[cargoName] = { - name = cargoName, - templates = {cargoName}, -- Dummy template name - cargoType = CTLD_CARGO.Enum.TROOPS, - seats = unitDef.seats, - stock = unitDef.stock, - template_found = true -- Force template found to true - } - blueCargoCount = blueCargoCount + 1 - - elseif unitDef.category == "VEHICLE" then - -- Add to crates cargo without template validation - if not ctld_blue.CratesCargo then ctld_blue.CratesCargo = {} end - ctld_blue.CratesCargo[cargoName] = { - name = cargoName, - templates = {cargoName}, -- Dummy template name - cargoType = CTLD_CARGO.Enum.VEHICLE, - cratesRequired = unitDef.crates, - stock = unitDef.stock, - subcategory = unitDef.subcategory, - template_found = true -- Force template found to true - } - blueCargoCount = blueCargoCount + 1 - end - end - - -- Setup Red cargo with bypassed template checking - for cargoName, unitDef in pairs(CTLD_UNIT_DEFINITIONS.RED) do - CTLD_LOG("Setting up Red cargo: " .. cargoName .. " (Category: " .. unitDef.category .. ")") - - if unitDef.category == "TROOPS" then - if not ctld_red.TroopsCargo then ctld_red.TroopsCargo = {} end - ctld_red.TroopsCargo[cargoName] = { - name = cargoName, - templates = {cargoName}, - cargoType = CTLD_CARGO.Enum.TROOPS, - seats = unitDef.seats, - stock = unitDef.stock, - template_found = true - } - redCargoCount = redCargoCount + 1 - - elseif unitDef.category == "VEHICLE" then - if not ctld_red.CratesCargo then ctld_red.CratesCargo = {} end - ctld_red.CratesCargo[cargoName] = { - name = cargoName, - templates = {cargoName}, - cargoType = CTLD_CARGO.Enum.VEHICLE, - cratesRequired = unitDef.crates, - stock = unitDef.stock, - subcategory = unitDef.subcategory, - template_found = true - } - redCargoCount = redCargoCount + 1 - end - end - - -- Set engineer search range - ctld_blue.EngineerSearch = 2000 - ctld_red.EngineerSearch = 2000 - - CTLD_LOG("TEMPLATE-FREE dynamic cargo setup complete - Blue: " .. blueCargoCount .. " items, Red: " .. redCargoCount .. " items") - - -- Alternative approach: Try using standard CTLD functions with overridden template checking - CTLD_LOG("Attempting fallback cargo registration...") - - -- Try the standard approach but with template checking disabled - pcall(function() - for cargoName, unitDef in pairs(CTLD_UNIT_DEFINITIONS.BLUE) do - if unitDef.category == "TROOPS" then - ctld_blue:AddTroopsCargo(cargoName, {cargoName}, CTLD_CARGO.Enum.TROOPS, unitDef.seats, nil, unitDef.stock) - elseif unitDef.category == "VEHICLE" then - ctld_blue:AddCratesCargo(cargoName, {cargoName}, CTLD_CARGO.Enum.VEHICLE, unitDef.crates, nil, unitDef.stock, unitDef.subcategory) - end - end - - for cargoName, unitDef in pairs(CTLD_UNIT_DEFINITIONS.RED) do - if unitDef.category == "TROOPS" then - ctld_red:AddTroopsCargo(cargoName, {cargoName}, CTLD_CARGO.Enum.TROOPS, unitDef.seats, nil, unitDef.stock) - elseif unitDef.category == "VEHICLE" then - ctld_red:AddCratesCargo(cargoName, {cargoName}, CTLD_CARGO.Enum.VEHICLE, unitDef.crates, nil, unitDef.stock, unitDef.subcategory) - end - end - - CTLD_LOG("Fallback cargo registration completed successfully") - end) - - -- Force rebuild F10 menus with the new cargo - if ctld_blue._buildF10Menu then - ctld_blue:_buildF10Menu() - CTLD_LOG("Rebuilt Blue F10 menu") - end - - if ctld_red._buildF10Menu then - ctld_red:_buildF10Menu() - CTLD_LOG("Rebuilt Red F10 menu") - end -end - --- ===================================================== --- AIRCRAFT MANAGEMENT FUNCTIONS --- ===================================================== - -function CTLD_ADD_TRANSPORT_PILOT(unit) - if not unit then - CTLD_LOG("CTLD_ADD_TRANSPORT_PILOT: unit is nil") - return - end - - local unitName = unit:getName() - local unitType = unit:getTypeName() - local unitCoalition = unit:getCoalition() -- Renamed to avoid conflict - local groupId = CTLD_GET_GROUP_ID(unit) - local playerName = unit:getPlayerName() - - CTLD_LOG("Attempting to add transport pilot: " .. unitName .. " (Type: " .. unitType .. ", Coalition: " .. unitCoalition .. ", Player: " .. tostring(playerName) .. ")") - - if not groupId then - CTLD_LOG("No group ID found for unit: " .. unitName) - return - end - - -- Check if pilot is already registered - if CTLD_DATA.pilots[unitName] then - CTLD_LOG("Transport pilot " .. unitName .. " already registered, skipping") - return - end - - -- Store pilot data - CTLD_DATA.pilots[unitName] = { - name = unitName, - unit = unit, - coalition = unitCoalition, -- Use renamed variable - groupId = groupId, - playerName = playerName - } - - -- Get the appropriate CTLD instance - local ctldInstance = nil - if unitCoalition == coalition.side.BLUE then -- Now coalition.side works properly - ctldInstance = CTLD_DATA.blueInstance - elseif unitCoalition == coalition.side.RED then - ctldInstance = CTLD_DATA.redInstance - end - - if ctldInstance then - -- Force add the group to CTLD if it's not already there - local groupName = unit:getGroup():getName() - CTLD_LOG("Adding group to CTLD: " .. groupName) - - -- Add the group name to the CTLD instance - if not ctldInstance.TransportGroups then - ctldInstance.TransportGroups = {} - end - - -- Check if group is already in the list - local groupExists = false - for _, existingGroup in ipairs(ctldInstance.TransportGroups) do - if existingGroup == groupName then - groupExists = true - break - end - end - - if not groupExists then - table.insert(ctldInstance.TransportGroups, groupName) - CTLD_LOG("Added group " .. groupName .. " to CTLD TransportGroups") - end - - -- Send welcome message with more detail - local message = string.format("CTLD System Active\nAircraft: %s\nType: %s\nUse F10 Radio Menu → CTLD\n\nAvailable cargo types loaded!", - unitName, unitType) - trigger.action.outTextForGroup(groupId, message, 20) - - -- Also send to coalition - trigger.action.outTextForCoalition(unitCoalition, "CTLD Transport " .. unitName .. " (" .. unitType .. ") is now active!", 10) - - CTLD_LOG("Transport pilot " .. unitName .. " added successfully to CTLD system with group: " .. groupName) - else - CTLD_LOG("ERROR: Could not find CTLD instance for coalition: " .. unitCoalition) - end -end - -function CTLD_REMOVE_TRANSPORT_PILOT(unitName) - if not CTLD_DATA.pilots[unitName] then return end - - CTLD_DATA.pilots[unitName] = nil - CTLD_LOG("Removed transport pilot: " .. unitName) -end - --- ===================================================== --- EVENT HANDLER (similar to AFAC) --- ===================================================== - -CTLD_EventHandler = {} - -function CTLD_EventHandler:onEvent(event) - if event.id == world.event.S_EVENT_BIRTH then - local unit = event.initiator - - if unit and Object.getCategory(unit) == Object.Category.UNIT then - local objDesc = unit:getDesc() - if objDesc.category == Unit.Category.AIRPLANE or objDesc.category == Unit.Category.HELICOPTER then - if CTLD_IS_TRANSPORT(unit) then - timer.scheduleFunction(function(args) - local u = args[1] - if u and u:isActive() then - CTLD_ADD_TRANSPORT_PILOT(u) - end - end, {unit}, timer.getTime() + 2) - end - end - end - end - - if event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT then - local unit = event.initiator - - if unit and Object.getCategory(unit) == Object.Category.UNIT then - local objDesc = unit:getDesc() - if objDesc.category == Unit.Category.AIRPLANE or objDesc.category == Unit.Category.HELICOPTER then - if CTLD_IS_TRANSPORT(unit) then - local unitName = unit:getName() - - if not CTLD_DATA.pilots[unitName] then - timer.scheduleFunction(function(args) - local u = args[1] - if u and u:isActive() then - CTLD_ADD_TRANSPORT_PILOT(u) - end - end, {unit}, timer.getTime() + 1) - end - end - end - end - end - - if event.id == world.event.S_EVENT_UNIT_LOST or event.id == world.event.S_EVENT_CRASH then - local unit = event.initiator - if unit then - local unitName = unit:getName() - CTLD_REMOVE_TRANSPORT_PILOT(unitName) - end - end -end - --- ===================================================== --- SCORING AND EVENT FUNCTIONS (from original CTLD) --- ===================================================== - --- Blue CTLD Event Functions -function ctld_blue:OnAfterTroopsDeployed(From, Event, To, Group, Unit, Troops) - if Unit then - local PlayerName = Unit:GetPlayerName() - local vname = Troops:GetName() - local points = pointsAwardedTroopsDeployed - MESSAGE:New("Pilot " .. PlayerName .. " has deployed " .. vname .. " to the field!", msgTime, "[ Mission Info ]", false):ToBlue() - -- Add scoring if you have a scoring system - CTLD_LOG("Troops deployed by " .. PlayerName) - end -end - -function ctld_blue:OnAfterTroopsExtracted(From, Event, To, Group, Unit, Cargo) - if Unit then - local PlayerName = Unit:GetPlayerName() - local vname = Cargo:GetName() - local points = pointsAwardedTroopsExtracted - MESSAGE:New("Pilot " .. PlayerName .. " has extracted " .. vname .. " from the field!", msgTime, "[ Mission Info ]", false):ToBlue() - CTLD_LOG("Troops extracted by " .. PlayerName) - end -end - -function ctld_blue:OnBeforeCratesBuild(From, Event, To, Group, Unit, CargoName) - if Unit and CargoName then - local PlayerName = Unit:GetPlayerName() - local unitCoalition = Unit:GetCoalition() - local helicopterPos = Unit:GetCoordinate() - local helicopterHeading = Unit:GetHeading() - - CTLD_LOG("OnBeforeCratesBuild called for: " .. CargoName .. " by " .. PlayerName) - - -- Find the unit definition in our custom definitions - local unitDef = nil - local coalitionDefs = unitCoalition == coalition.side.BLUE and CTLD_UNIT_DEFINITIONS.BLUE or CTLD_UNIT_DEFINITIONS.RED - - for cargoName, definition in pairs(coalitionDefs) do - if cargoName == CargoName then - unitDef = definition - CTLD_LOG("Found unit definition for: " .. CargoName) - break - end - end - - if unitDef and unitDef.category == "VEHICLE" then - -- Create spawn point slightly ahead of helicopter - local spawnPoint = helicopterPos:Translate(20, helicopterHeading) - - -- Spawn the dynamic group with helicopter's heading - local spawnedGroup = CTLD_CREATE_DYNAMIC_GROUP(unitDef, spawnPoint, math.deg(helicopterHeading), unitCoalition) - - if spawnedGroup then - CTLD_LOG("Dynamic spawn successful: " .. CargoName .. " by " .. PlayerName .. " facing " .. math.deg(helicopterHeading) .. " degrees") - - -- Create visual effects - trigger.action.smoke(spawnPoint:GetVec3(), 4) -- Blue smoke - - local message = string.format("Dynamic %s deployed by %s and oriented %d degrees!", - CargoName, PlayerName, math.deg(helicopterHeading)) - MESSAGE:New(message, msgTime, "[ Dynamic Spawn ]", false):ToCoalition(unitCoalition) - - -- Prevent CTLD from trying to spawn its own template - return false -- Cancel the normal CTLD build process - else - CTLD_LOG("Dynamic spawn failed for: " .. CargoName) - end - else - CTLD_LOG("No unit definition found for: " .. CargoName .. " or not a vehicle type") - end - end -end - --- Handle troop deployment dynamically -function ctld_blue:OnBeforeTroopsDeployed(From, Event, To, Group, Unit, TroopName) - if Unit and TroopName then - local PlayerName = Unit:GetPlayerName() - local unitCoalition = Unit:GetCoalition() - local helicopterPos = Unit:GetCoordinate() - local helicopterHeading = Unit:GetHeading() - - CTLD_LOG("OnBeforeTroopsDeployed called for: " .. TroopName .. " by " .. PlayerName) - - -- Find the unit definition - local unitDef = nil - local coalitionDefs = unitCoalition == coalition.side.BLUE and CTLD_UNIT_DEFINITIONS.BLUE or CTLD_UNIT_DEFINITIONS.RED - - for cargoName, definition in pairs(coalitionDefs) do - if cargoName == TroopName then - unitDef = definition - break - end - end - - if unitDef and unitDef.category == "TROOPS" then - -- Create spawn point slightly ahead of helicopter - local spawnPoint = helicopterPos:Translate(10, helicopterHeading) - - -- Spawn the dynamic troop group - local spawnedGroup = CTLD_CREATE_DYNAMIC_GROUP(unitDef, spawnPoint, math.deg(helicopterHeading), unitCoalition) - - if spawnedGroup then - CTLD_LOG("Dynamic troop spawn successful: " .. TroopName .. " by " .. PlayerName) - - local message = string.format("Dynamic %s deployed by %s!", TroopName, PlayerName) - MESSAGE:New(message, msgTime, "[ Dynamic Troop Spawn ]", false):ToCoalition(unitCoalition) - - return false -- Cancel normal CTLD troop deployment - end - end - end -end - -function ctld_blue:OnAfterCratesBuild(From, Event, To, Group, Unit, Vehicle) - if Unit then - local points = pointsAwardedCrateBuilt - local PlayerName = Unit:GetPlayerName() - local vname = Vehicle:GetName() - - MESSAGE:New("Pilot " .. PlayerName .. " has deployed " .. vname .. " to the field!", msgTime, "[ Mission Info ]", false):ToBlue() - - -- FOB creation logic - if string.match(vname, "FARP", 1, true) then - local Coord = Vehicle:GetCoordinate():GetVec2() - local mCoord = Vehicle:GetCoordinate() - local zonename = "FARP-" .. math.random(1, 10000) - local farpzone = ZONE_RADIUS:New(zonename, Coord, 500) - local farpmarker = MARKER:New(mCoord, "FORWARD ARMING & REFUELING POINT:\nBUILT BY: " .. PlayerName .. "\n\nTransport aircraft may pick up troops and equipment from this location."):ReadOnly():ToCoalition(coalition.side.BLUE) - farpzone:DrawZone(2, {.25, .63, .79}, 1, {0, 0, 0}, 0.25, 2, true) - ctld_blue:AddCTLDZone(zonename, CTLD.CargoZoneType.LOAD, SMOKECOLOR.Blue, true, true) - MESSAGE:New("Pilot " .. PlayerName .. " has created a new FARP loading zone! See your F10 Map for marker!", msgTime, "[ Mission Info ]", false):ToBlue() - end - - CTLD_LOG("Built: " .. vname .. " by " .. PlayerName) - end -end - --- Red CTLD Event Functions (similar structure) -function ctld_red:OnAfterTroopsDeployed(From, Event, To, Group, Unit, Troops) - if Unit then - local PlayerName = Unit:GetPlayerName() - local vname = Troops:GetName() - MESSAGE:New("Pilot " .. PlayerName .. " has deployed " .. vname .. " to the field!", msgTime, "[ Mission Info ]", false):ToRed() - CTLD_LOG("Troops deployed by " .. PlayerName) - end -end - -function ctld_red:OnAfterTroopsExtracted(From, Event, To, Group, Unit, Cargo) - if Unit then - local PlayerName = Unit:GetPlayerName() - local vname = Cargo:GetName() - MESSAGE:New("Pilot " .. PlayerName .. " has extracted " .. vname .. " from the field!", msgTime, "[ Mission Info ]", false):ToRed() - CTLD_LOG("Troops extracted by " .. PlayerName) - end -end - -function ctld_red:OnBeforeCratesBuild(From, Event, To, Group, Unit, CargoName) - if Unit and CargoName then - local PlayerName = Unit:GetPlayerName() - local unitCoalition = Unit:GetCoalition() - local helicopterPos = Unit:GetCoordinate() - local helicopterHeading = Unit:GetHeading() - - CTLD_LOG("Red OnBeforeCratesBuild called for: " .. CargoName .. " by " .. PlayerName) - - -- Find the unit definition - local unitDef = nil - local coalitionDefs = unitCoalition == coalition.side.BLUE and CTLD_UNIT_DEFINITIONS.BLUE or CTLD_UNIT_DEFINITIONS.RED - - for cargoName, definition in pairs(coalitionDefs) do - if cargoName == CargoName then - unitDef = definition - break - end - end - - if unitDef and unitDef.category == "VEHICLE" then - -- Create spawn point slightly ahead of helicopter - local spawnPoint = helicopterPos:Translate(20, helicopterHeading) - - -- Spawn the dynamic group with helicopter's heading - local spawnedGroup = CTLD_CREATE_DYNAMIC_GROUP(unitDef, spawnPoint, math.deg(helicopterHeading), unitCoalition) - - if spawnedGroup then - CTLD_LOG("Red dynamic spawn successful: " .. CargoName .. " by " .. PlayerName .. " facing " .. math.deg(helicopterHeading) .. " degrees") - - -- Create visual effects - trigger.action.smoke(spawnPoint:GetVec3(), 1) -- Red smoke - - local message = string.format("Dynamic %s deployed by %s and oriented %d degrees!", - CargoName, PlayerName, math.deg(helicopterHeading)) - MESSAGE:New(message, msgTime, "[ Dynamic Spawn ]", false):ToCoalition(unitCoalition) - - return false -- Cancel normal CTLD build - else - CTLD_LOG("Red dynamic spawn failed for: " .. CargoName) - end - end - end -end - --- Handle Red troop deployment dynamically -function ctld_red:OnBeforeTroopsDeployed(From, Event, To, Group, Unit, TroopName) - if Unit and TroopName then - local PlayerName = Unit:GetPlayerName() - local unitCoalition = Unit:GetCoalition() - local helicopterPos = Unit:GetCoordinate() - local helicopterHeading = Unit:GetHeading() - - CTLD_LOG("Red OnBeforeTroopsDeployed called for: " .. TroopName .. " by " .. PlayerName) - - -- Find the unit definition - local unitDef = nil - local coalitionDefs = unitCoalition == coalition.side.BLUE and CTLD_UNIT_DEFINITIONS.BLUE or CTLD_UNIT_DEFINITIONS.RED - - for cargoName, definition in pairs(coalitionDefs) do - if cargoName == TroopName then - unitDef = definition - break - end - end - - if unitDef and unitDef.category == "TROOPS" then - -- Create spawn point slightly ahead of helicopter - local spawnPoint = helicopterPos:Translate(10, helicopterHeading) - - -- Spawn the dynamic troop group - local spawnedGroup = CTLD_CREATE_DYNAMIC_GROUP(unitDef, spawnPoint, math.deg(helicopterHeading), unitCoalition) - - if spawnedGroup then - CTLD_LOG("Red dynamic troop spawn successful: " .. TroopName .. " by " .. PlayerName) - - local message = string.format("Dynamic %s deployed by %s!", TroopName, PlayerName) - MESSAGE:New(message, msgTime, "[ Dynamic Troop Spawn ]", false):ToCoalition(unitCoalition) - - return false -- Cancel normal CTLD troop deployment - end - end - end -end - --- ===================================================== --- INITIALIZATION --- ===================================================== - -function CTLD_CHECK_EXISTING_TRANSPORTS() - for coalitionId = 1, 2 do - local airGroups = coalition.getGroups(coalitionId, Group.Category.AIRPLANE) - local heliGroups = coalition.getGroups(coalitionId, Group.Category.HELICOPTER) - - local allGroups = {} - for _, group in ipairs(airGroups) do table.insert(allGroups, group) end - for _, group in ipairs(heliGroups) do table.insert(allGroups, group) end - - for _, group in ipairs(allGroups) do - local units = group:getUnits() - if units then - for _, unit in ipairs(units) do - if unit and unit:isActive() and CTLD_IS_TRANSPORT(unit) then - local unitName = unit:getName() - if unit:getPlayerName() and not CTLD_DATA.pilots[unitName] then - CTLD_ADD_TRANSPORT_PILOT(unit) - end - end - end - end - end - end -end - --- Register event handler -world.addEventHandler(CTLD_EventHandler) - --- Initialize CTLD instances first -CTLD_LOG("Starting CTLD instances...") -ctld_blue:__Start(2) -ctld_red:__Start(2) - --- Setup dynamic cargo definitions after CTLD starts -timer.scheduleFunction(function() - CTLD_SETUP_DYNAMIC_CARGO() - CTLD_LOG("CTLD instances started and cargo configured") - trigger.action.outText("Enhanced CTLD System ready - Transport aircraft can now use CTLD!", 15) -end, nil, timer.getTime() + 3) - --- Check for existing pilots after everything is set up -timer.scheduleFunction(CTLD_CHECK_EXISTING_TRANSPORTS, nil, timer.getTime() + 5) - --- Periodic check for new pilots -function CTLD_PERIODIC_CHECK() - CTLD_CHECK_EXISTING_TRANSPORTS() - timer.scheduleFunction(CTLD_PERIODIC_CHECK, nil, timer.getTime() + 10) -end - -timer.scheduleFunction(CTLD_PERIODIC_CHECK, nil, timer.getTime() + 15) - --- Add debug status function -function CTLD_DEBUG_STATUS() - local message = "=== CTLD DEBUG STATUS ===\n\n" - - local pilotCount = 0 - for _ in pairs(CTLD_DATA.pilots) do pilotCount = pilotCount + 1 end - message = message .. "Registered Pilots: " .. pilotCount .. "\n" - - for unitName, pilotData in pairs(CTLD_DATA.pilots) do - message = message .. "- " .. unitName .. " (Coalition: " .. pilotData.coalition .. ")\n" - end - - message = message .. "\nBlue CTLD Groups: " - if ctld_blue.TransportGroups then - local blueCount = 0 - for _ in pairs(ctld_blue.TransportGroups) do blueCount = blueCount + 1 end - message = message .. blueCount .. "\n" - for _, groupName in ipairs(ctld_blue.TransportGroups) do - message = message .. "- " .. groupName .. "\n" - end - else - message = message .. "0 (TransportGroups not initialized)\n" - end - - message = message .. "\nRed CTLD Groups: " - if ctld_red.TransportGroups then - local redCount = 0 - for _ in pairs(ctld_red.TransportGroups) do redCount = redCount + 1 end - message = message .. redCount .. "\n" - for _, groupName in ipairs(ctld_red.TransportGroups) do - message = message .. "- " .. groupName .. "\n" - end - else - message = message .. "0 (TransportGroups not initialized)\n" - end - - trigger.action.outText(message, 30) - CTLD_LOG(message) -end - --- Schedule debug status after initialization -timer.scheduleFunction(CTLD_DEBUG_STATUS, nil, timer.getTime() + 10) - -CTLD_LOG("Enhanced CTLD System with Aircraft Type Detection initialized successfully") -trigger.action.outText("Enhanced CTLD System loading - Transport aircraft will be automatically detected!", 10) \ No newline at end of file diff --git a/DCS_Kola/Operation_Polar_Shield/TADC_Diagnostic.lua b/DCS_Kola/Operation_Polar_Shield/TADC_Diagnostic.lua deleted file mode 100644 index cc3f644..0000000 --- a/DCS_Kola/Operation_Polar_Shield/TADC_Diagnostic.lua +++ /dev/null @@ -1,304 +0,0 @@ --- TADC Diagnostic Script --- This script will run diagnostics on the TADC system to identify why no aircraft are launching - -env.info("=== TADC DIAGNOSTIC SCRIPT STARTING ===") - --- Test 1: Check if zones exist and are properly defined -local function testZones() - env.info("=== ZONE DIAGNOSTIC ===") - - local redBorderGroup = GROUP:FindByName("RED BORDER") - local heloBorderGroup = GROUP:FindByName("HELO BORDER") - - if redBorderGroup then - env.info("✓ RED BORDER group found") - local redZone = ZONE_POLYGON:New("RED BORDER TEST", redBorderGroup) - if redZone then - env.info("✓ RED BORDER zone created successfully") - local coord = redZone:GetCoordinate() - if coord then - env.info("✓ RED BORDER zone coordinate: " .. coord:ToStringLLDMS()) - else - env.info("✗ RED BORDER zone has no coordinate") - end - else - env.info("✗ Failed to create RED BORDER zone") - end - else - env.info("✗ RED BORDER group NOT found - this is likely the problem!") - end - - if heloBorderGroup then - env.info("✓ HELO BORDER group found") - local heloZone = ZONE_POLYGON:New("HELO BORDER TEST", heloBorderGroup) - if heloZone then - env.info("✓ HELO BORDER zone created successfully") - local coord = heloZone:GetCoordinate() - if coord then - env.info("✓ HELO BORDER zone coordinate: " .. coord:ToStringLLDMS()) - else - env.info("✗ HELO BORDER zone has no coordinate") - end - else - env.info("✗ Failed to create HELO BORDER zone") - end - else - env.info("✗ HELO BORDER group NOT found - this may be the problem!") - end -end - --- Test 2: Check if Blue aircraft exist on the map -local function testBlueAircraft() - env.info("=== BLUE AIRCRAFT DIAGNOSTIC ===") - - local BlueAircraft = SET_GROUP:New():FilterCoalitions("blue"):FilterCategoryAirplane():FilterStart() - local blueCount = BlueAircraft:Count() - - env.info("Total Blue aircraft on map: " .. blueCount) - - if blueCount > 0 then - env.info("Blue aircraft found:") - BlueAircraft:ForEach(function(blueGroup) - if blueGroup and blueGroup:IsAlive() then - local coord = blueGroup:GetCoordinate() - local name = blueGroup:GetName() - if coord then - env.info(" - " .. name .. " at " .. coord:ToStringLLDMS()) - else - env.info(" - " .. name .. " (no coordinate)") - end - end - end) - else - env.info("✗ NO BLUE AIRCRAFT FOUND - this is likely why no intercepts are launching!") - env.info("SOLUTION: Add Blue coalition aircraft to the mission or spawn some for testing") - end -end - --- Test 3: Check if Blue aircraft are in the detection zones -local function testBlueInZones() - env.info("=== BLUE AIRCRAFT IN ZONES DIAGNOSTIC ===") - - local redBorderGroup = GROUP:FindByName("RED BORDER") - local heloBorderGroup = GROUP:FindByName("HELO BORDER") - - if not redBorderGroup or not heloBorderGroup then - env.info("✗ Cannot test zones - border groups missing") - return - end - - local redZone = ZONE_POLYGON:New("RED BORDER TEST", redBorderGroup) - local heloZone = ZONE_POLYGON:New("HELO BORDER TEST", heloBorderGroup) - - local BlueAircraft = SET_GROUP:New():FilterCoalitions("blue"):FilterCategoryAirplane():FilterStart() - local blueCount = BlueAircraft:Count() - - if blueCount == 0 then - env.info("✗ No Blue aircraft to test zone containment") - return - end - - local inRedZone = 0 - local inHeloZone = 0 - - BlueAircraft:ForEach(function(blueGroup) - if blueGroup and blueGroup:IsAlive() then - local coord = blueGroup:GetCoordinate() - local name = blueGroup:GetName() - - if coord then - local inRed = redZone and redZone:IsCoordinateInZone(coord) - local inHelo = heloZone and heloZone:IsCoordinateInZone(coord) - - if inRed then - inRedZone = inRedZone + 1 - env.info(" ✓ " .. name .. " is in RED BORDER zone") - elseif inHelo then - inHeloZone = inHeloZone + 1 - env.info(" ✓ " .. name .. " is in HELO BORDER zone") - else - env.info(" - " .. name .. " is NOT in any border zone") - end - end - end - end) - - env.info("Summary: " .. inRedZone .. " in RED zone, " .. inHeloZone .. " in HELO zone") - - if inRedZone == 0 and inHeloZone == 0 then - env.info("✗ NO BLUE AIRCRAFT IN DETECTION ZONES - this is why no intercepts are launching!") - env.info("SOLUTION: Move Blue aircraft into the border zones or expand the zone definitions") - end -end - --- Test 4: Check squadron templates -local function testSquadronTemplates() - env.info("=== SQUADRON TEMPLATE DIAGNOSTIC ===") - - local squadronTemplates = { - "FIGHTER_SWEEP_RED_Kilpyavr", - "FIGHTER_SWEEP_RED_Severomorsk-1", - "FIGHTER_SWEEP_RED_Severomorsk-3", - "FIGHTER_SWEEP_RED_Murmansk", - "FIGHTER_SWEEP_RED_Monchegorsk", - "FIGHTER_SWEEP_RED_Olenya", - "HELO_SWEEP_RED_Afrikanda" - } - - local found = 0 - local total = #squadronTemplates - - for _, templateName in pairs(squadronTemplates) do - local template = GROUP:FindByName(templateName) - if template then - env.info("✓ Found template: " .. templateName) - - -- Check if template is alive (should NOT be for Late Activation) - local isAlive = template:IsAlive() - if isAlive then - env.info(" ⚠ WARNING: Template is ALIVE - should be set to Late Activation") - else - env.info(" ✓ Template correctly set to Late Activation") - end - - -- Check coalition - local coalition = template:GetCoalition() - if coalition == 1 then - env.info(" ✓ Template is Red coalition") - else - env.info(" ✗ Template is NOT Red coalition (coalition=" .. coalition .. ")") - end - - found = found + 1 - else - env.info("✗ Missing template: " .. templateName) - end - end - - env.info("Squadron templates found: " .. found .. "/" .. total) - - if found == 0 then - env.info("✗ NO SQUADRON TEMPLATES FOUND - this is why no aircraft can launch!") - env.info("SOLUTION: Create squadron groups in Mission Editor with the correct names and set to Late Activation") - end -end - --- Test 5: Check airbases -local function testAirbases() - env.info("=== AIRBASE DIAGNOSTIC ===") - - local airbases = { - "Kilpyavr", "Severomorsk-1", "Severomorsk-3", - "Murmansk International", "Monchegorsk", "Olenya", "Afrikanda" - } - - local found = 0 - local redBases = 0 - - for _, airbaseName in pairs(airbases) do - local airbase = AIRBASE:FindByName(airbaseName) - if airbase then - env.info("✓ Found airbase: " .. airbaseName) - - local coalition = airbase:GetCoalition() - local coalitionName = coalition == 1 and "Red" or (coalition == 2 and "Blue" or "Neutral") - env.info(" Coalition: " .. coalitionName) - - if coalition == 1 then - redBases = redBases + 1 - end - - found = found + 1 - else - env.info("✗ Airbase not found: " .. airbaseName) - end - end - - env.info("Airbases found: " .. found .. "/" .. #airbases .. " (Red: " .. redBases .. ")") -end - --- Test 6: Manual threat detection test -local function testThreatDetection() - env.info("=== THREAT DETECTION TEST ===") - - -- Try to manually detect threats - local BlueAircraft = SET_GROUP:New():FilterCoalitions("blue"):FilterCategoryAirplane():FilterStart() - local blueCount = BlueAircraft:Count() - - env.info("Manual threat scan - found " .. blueCount .. " blue aircraft") - - if blueCount > 0 then - local redBorderGroup = GROUP:FindByName("RED BORDER") - local heloBorderGroup = GROUP:FindByName("HELO BORDER") - - if redBorderGroup and heloBorderGroup then - local redZone = ZONE_POLYGON:New("RED BORDER TEST", redBorderGroup) - local heloZone = ZONE_POLYGON:New("HELO BORDER TEST", heloBorderGroup) - - local threatsInZones = 0 - - BlueAircraft:ForEach(function(blueGroup) - if blueGroup and blueGroup:IsAlive() then - local coord = blueGroup:GetCoordinate() - local name = blueGroup:GetName() - - if coord then - local inRed = redZone:IsCoordinateInZone(coord) - local inHelo = heloZone:IsCoordinateInZone(coord) - - if inRed or inHelo then - threatsInZones = threatsInZones + 1 - local classification = "UNKNOWN" - local category = blueGroup:GetCategory() - local typeName = blueGroup:GetTypeName() or "Unknown" - - if category == Group.Category.AIRPLANE then - if string.find(typeName:upper(), "B-") or string.find(typeName:upper(), "BOMBER") then - classification = "BOMBER" - elseif string.find(typeName:upper(), "A-") or string.find(typeName:upper(), "ATTACK") then - classification = "ATTACK" - else - classification = "FIGHTER" - end - elseif category == Group.Category.HELICOPTER then - classification = "HELICOPTER" - end - - env.info(" THREAT DETECTED: " .. name .. " (" .. classification .. ") in " .. (inRed and "RED BORDER" or "HELO BORDER")) - end - end - end - end) - - if threatsInZones == 0 then - env.info("✗ No threats detected in border zones") - else - env.info("✓ " .. threatsInZones .. " threats detected in border zones") - end - end - end -end - --- Run all diagnostic tests -local function runAllDiagnostics() - env.info("Starting comprehensive TADC diagnostic...") - - testZones() - testBlueAircraft() - testBlueInZones() - testSquadronTemplates() - testAirbases() - testThreatDetection() - - env.info("=== DIAGNOSTIC COMPLETE ===") - env.info("Check the log above for any ✗ (failed) items - these are likely the cause of the problem") -end - --- Schedule the diagnostic to run after a delay -SCHEDULER:New(nil, runAllDiagnostics, {}, 3) - --- Also create a repeating diagnostic every 60 seconds for ongoing monitoring -SCHEDULER:New(nil, function() - env.info("=== PERIODIC THREAT CHECK ===") - testBlueInZones() -end, {}, 10, 60) -- Start after 10 seconds, repeat every 60 seconds \ No newline at end of file diff --git a/DCS_Kola/Operation_Polar_Shield/TADC_ManualTest.lua b/DCS_Kola/Operation_Polar_Shield/TADC_ManualTest.lua deleted file mode 100644 index 748ce03..0000000 --- a/DCS_Kola/Operation_Polar_Shield/TADC_ManualTest.lua +++ /dev/null @@ -1,164 +0,0 @@ --- TADC Manual Launch Test --- This script will attempt to manually launch one aircraft to test if the spawn system works - -env.info("=== TADC MANUAL LAUNCH TEST ===") - --- Wait a few seconds for MOOSE to initialize, then try a manual launch -SCHEDULER:New(nil, function() - - env.info("Attempting manual aircraft launch...") - - -- Test configuration - using the first squadron - local testConfig = { - templateName = "FIGHTER_SWEEP_RED_Severomorsk-1", - displayName = "Severomorsk-1 TEST", - airbaseName = "Severomorsk-1", - aircraft = 1, - skill = AI.Skill.GOOD, - altitude = 20000, - speed = 350, - patrolTime = 25, - type = "FIGHTER" - } - - -- Manual launch function (simplified version) - local function manualLaunch(config) - env.info("=== MANUAL LAUNCH ATTEMPT ===") - env.info("Template: " .. config.templateName) - env.info("Airbase: " .. config.airbaseName) - - local success, errorMsg = pcall(function() - -- Check if template exists - local templateGroup = GROUP:FindByName(config.templateName) - if not templateGroup then - env.info("✗ CRITICAL: Template group not found: " .. config.templateName) - env.info("DIAGNOSIS: This template does not exist in the mission!") - env.info("SOLUTION: Create a group named '" .. config.templateName .. "' in Mission Editor") - return - end - - env.info("✓ Template group found: " .. config.templateName) - - -- Check template properties - local coalition = templateGroup:GetCoalition() - local isAlive = templateGroup:IsAlive() - - env.info("Template coalition: " .. (coalition == 1 and "Red" or (coalition == 2 and "Blue" or "Neutral"))) - env.info("Template alive: " .. tostring(isAlive)) - - if coalition ~= 1 then - env.info("✗ CRITICAL: Template is not Red coalition!") - env.info("SOLUTION: Set '" .. config.templateName .. "' to Red coalition in Mission Editor") - return - end - - if isAlive then - env.info("⚠ WARNING: Template is alive - Late Activation may not be set") - env.info("RECOMMENDATION: Set '" .. config.templateName .. "' to Late Activation in Mission Editor") - end - - -- Check airbase - local airbaseObj = AIRBASE:FindByName(config.airbaseName) - if not airbaseObj then - env.info("✗ CRITICAL: Airbase not found: " .. config.airbaseName) - env.info("SOLUTION: Check airbase name spelling or use a different airbase") - return - end - - env.info("✓ Airbase found: " .. config.airbaseName) - - local airbaseCoalition = airbaseObj:GetCoalition() - env.info("Airbase coalition: " .. (airbaseCoalition == 1 and "Red" or (airbaseCoalition == 2 and "Blue" or "Neutral"))) - - -- Create SPAWN object - env.info("Creating SPAWN object...") - local spawner = SPAWN:New(config.templateName) - - -- Try to spawn - env.info("Attempting to spawn aircraft...") - local spawnedGroup = nil - - -- Method 1: Air spawn - local airbaseCoord = airbaseObj:GetCoordinate() - local spawnCoord = airbaseCoord:Translate(2000, math.random(0, 360)):SetAltitude(config.altitude * 0.3048) - - env.info("Trying air spawn at " .. config.altitude .. "ft...") - spawnedGroup = spawner:SpawnFromCoordinate(spawnCoord, nil, SPAWN.Takeoff.Air) - - if not spawnedGroup then - env.info("Air spawn failed, trying hot start at airbase...") - spawnedGroup = spawner:SpawnAtAirbase(airbaseObj, SPAWN.Takeoff.Hot) - end - - if not spawnedGroup then - env.info("Hot start failed, trying cold start at airbase...") - spawnedGroup = spawner:SpawnAtAirbase(airbaseObj, SPAWN.Takeoff.Cold) - end - - if spawnedGroup then - env.info("✓ SUCCESS: Aircraft spawned successfully!") - env.info("Spawned group: " .. spawnedGroup:GetName()) - - -- Set basic CAP task after a delay - SCHEDULER:New(nil, function() - if spawnedGroup and spawnedGroup:IsAlive() then - env.info("Setting up basic CAP task...") - - local currentCoord = spawnedGroup:GetCoordinate() - if currentCoord then - env.info("Aircraft position: " .. currentCoord:ToStringLLDMS()) - - -- Clear tasks and set basic patrol - spawnedGroup:ClearTasks() - spawnedGroup:OptionROEOpenFire() - - -- Simple patrol task - local patrolCoord = currentCoord:Translate(10000, math.random(0, 360)):SetAltitude(config.altitude * 0.3048) - - local patrolTask = { - id = 'Orbit', - params = { - pattern = 'Circle', - point = {x = patrolCoord.x, y = patrolCoord.z}, - radius = 5000, - altitude = config.altitude * 0.3048, - speed = config.speed * 0.514444, - } - } - spawnedGroup:PushTask(patrolTask, 1) - - env.info("✓ Basic CAP task assigned") - - -- Clean up after 10 minutes - SCHEDULER:New(nil, function() - if spawnedGroup and spawnedGroup:IsAlive() then - env.info("Test complete - cleaning up spawned aircraft") - spawnedGroup:Destroy() - end - end, {}, 600) -- 10 minutes - - else - env.info("⚠ Could not get aircraft coordinate") - end - else - env.info("⚠ Aircraft not alive for task assignment") - end - end, {}, 5) -- 5 second delay - - else - env.info("✗ CRITICAL: All spawn methods failed!") - env.info("DIAGNOSIS: There may be an issue with the template or MOOSE setup") - end - end) - - if not success then - env.info("✗ CRITICAL ERROR in manual launch: " .. tostring(errorMsg)) - end - end - - -- Attempt the manual launch - manualLaunch(testConfig) - -end, {}, 5) -- Wait 5 seconds for MOOSE initialization - -env.info("Manual launch test scheduled - check log in 5 seconds") \ No newline at end of file diff --git a/DCS_Kola/Operation_Polar_Shield/TADC_Verification.lua b/DCS_Kola/Operation_Polar_Shield/TADC_Verification.lua deleted file mode 100644 index bc19c16..0000000 --- a/DCS_Kola/Operation_Polar_Shield/TADC_Verification.lua +++ /dev/null @@ -1,100 +0,0 @@ --- TADC Verification Script --- This script provides a simple way to verify that all TADC components are properly configured --- Run this in DCS to check for missing functions, configuration errors, etc. - --- Verification function to check if all required elements exist -local function verifyTADC() - local errors = {} - local warnings = {} - - -- Check if GCI_Config exists and has required values - if not GCI_Config then - table.insert(errors, "GCI_Config not found") - else - local requiredConfig = { - "threatRatio", "maxSimultaneousCAP", "useEWRDetection", "ewrDetectionRadius", - "mainLoopInterval", "mainLoopDelay", "squadronCooldown", "supplyMode", - "defaultSquadronSize", "reservePercent", "responseDelay", "capSetupDelay", - "capOrbitRadius", "capEngagementRange", "capZoneConstraint", - "statusReportInterval", "engagementUpdateInterval", "fighterVsFighter", - "fighterVsBomber", "fighterVsHelicopter", "threatTimeout", "debugLevel" - } - - for _, configKey in pairs(requiredConfig) do - if GCI_Config[configKey] == nil then - table.insert(errors, "Missing config: GCI_Config." .. configKey) - end - end - end - - -- Check if TADC data structure exists - if not TADC then - table.insert(errors, "TADC data structure not found") - else - local requiredTADC = {"squadrons", "activeCAPs", "threats", "missions"} - for _, key in pairs(requiredTADC) do - if TADC[key] == nil then - table.insert(errors, "Missing TADC." .. key) - end - end - end - - -- Check if zones exist - if not CCCPBorderZone then - table.insert(errors, "CCCPBorderZone not found") - end - if not HeloBorderZone then - table.insert(errors, "HeloBorderZone not found") - end - - -- Check if main functions exist - local requiredFunctions = { - "TADC_Log", "validateConfiguration", "mainTADCLoop", "simpleDetectThreats", - "launchCAP", "launchInterceptMission", "maintainPersistentCAP" - } - - for _, funcName in pairs(requiredFunctions) do - if not _G[funcName] then - table.insert(errors, "Missing function: " .. funcName) - end - end - - -- Count squadrons - local squadronCount = 0 - if TADC and TADC.squadrons then - for _ in pairs(TADC.squadrons) do - squadronCount = squadronCount + 1 - end - end - - -- Print results - env.info("=== TADC VERIFICATION RESULTS ===") - - if #errors > 0 then - env.error("VERIFICATION FAILED - " .. #errors .. " errors found:") - for _, error in pairs(errors) do - env.error(" ❌ " .. error) - end - else - env.info("✅ All critical components verified successfully!") - end - - if #warnings > 0 then - env.warning("Warnings found:") - for _, warning in pairs(warnings) do - env.warning(" ⚠️ " .. warning) - end - end - - env.info("📊 Squadron count: " .. squadronCount) - env.info("📊 Config debug level: " .. (GCI_Config and GCI_Config.debugLevel or "N/A")) - env.info("=== VERIFICATION COMPLETE ===") - - return #errors == 0 -end - --- Run verification after a short delay to ensure everything is loaded -SCHEDULER:New(nil, function() - env.info("Starting TADC verification...") - verifyTADC() -end, {}, 10) \ No newline at end of file diff --git a/DCS_Kola/Operation_Polar_Shield/test.lua b/DCS_Kola/Operation_Polar_Shield/test.lua deleted file mode 100644 index 98fb7f3..0000000 --- a/DCS_Kola/Operation_Polar_Shield/test.lua +++ /dev/null @@ -1,69 +0,0 @@ --- Add this at the very beginning after MOOSE loads -env.info("=== MOOSE DEBUG INFO ===") -env.info("MOOSE loaded: " .. tostring(MOOSE ~= nil)) -env.info("OPS available: " .. tostring(OPS ~= nil)) -env.info("_G.OPS available: " .. tostring(_G.OPS ~= nil)) - --- Check what's in the global namespace -for k,v in pairs(_G) do - if string.find(k, "OPS") then - env.info("Found OPS-related: " .. k .. " = " .. tostring(v)) - end -end - - --- Debug airbase availability -env.info("=== AIRBASE DEBUG ===") -env.info("AIRBASE table exists: " .. tostring(AIRBASE ~= nil)) - -if AIRBASE then - env.info("AIRBASE.Kola exists: " .. tostring(AIRBASE.Kola ~= nil)) - - -- List all airbases found on the map - env.info("=== ALL AIRBASES ON MAP ===") - - -- Method 1: Try using SET_AIRBASE to get all airbases - if SET_AIRBASE then - env.info("Using SET_AIRBASE method...") - local airbaseSet = SET_AIRBASE:New():FilterOnce() - if airbaseSet then - local count = airbaseSet:Count() - env.info("Total airbases found: " .. count) - airbaseSet:ForEach(function(airbase) - if airbase then - local name = airbase:GetName() - local coalition = airbase:GetCoalition() - local coalitionName = "Unknown" - if coalition == 0 then coalitionName = "Neutral" - elseif coalition == 1 then coalitionName = "Red" - elseif coalition == 2 then coalitionName = "Blue" - end - env.info("Airbase: '" .. name .. "' (" .. coalitionName .. ")") - end - end) - end - end - - -- Method 2: Try specific airbase names we expect - env.info("=== TESTING SPECIFIC AIRBASES ===") - local testNames = { - "Severomorsk-1", "Severomorsk-3", "Kilpyavr", "Murmansk", - "Monchegorsk", "Olenya", "Afrikanda" - } - - for _, name in pairs(testNames) do - local airbase = AIRBASE:FindByName(name) - env.info(name .. ": " .. tostring(airbase ~= nil)) - if airbase then - env.info(" - Coalition: " .. airbase:GetCoalition()) - end - end - - -- Alternative method - check AIRBASE.Kola if it exists - if AIRBASE.Kola then - env.info("=== AIRBASE.Kola CONSTANTS ===") - for k,v in pairs(AIRBASE.Kola) do - env.info("AIRBASE.Kola." .. k .. " = " .. tostring(v)) - end - end -end \ No newline at end of file