mirror of
https://github.com/iTracerFacer/DCS_MissionDev.git
synced 2025-12-03 04:14:46 +00:00
Fixed timing issues at mission start that was causing Kilpyavr to go into a captured state. Cleaned up logging functions. Fixed capture zone unit counting error. Other cool stuff. :)
This commit is contained in:
parent
4b18037c32
commit
37b7e34c8d
155
DCS_Kola/Operation_Polar_Shield/DUAL_COALITION_CHANGES.md
Normal file
155
DCS_Kola/Operation_Polar_Shield/DUAL_COALITION_CHANGES.md
Normal file
@ -0,0 +1,155 @@
|
||||
# Dual Coalition Zone Capture - Full Analysis & Changes
|
||||
|
||||
## Summary
|
||||
The script has been refactored to provide **complete parity between RED and BLUE coalitions**. Both sides now have equal access to all features, information, and victory conditions.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Changes Made for Full Dual-Coalition Support
|
||||
|
||||
### 1. **Tactical Markers** (Lines ~390-440)
|
||||
**BEFORE:** Only BLUE coalition received tactical markers
|
||||
**AFTER:** Both RED and BLUE receive separate tactical markers
|
||||
- Each coalition sees enemy unit positions (when ≤10 units)
|
||||
- Markers are coalition-specific and read-only
|
||||
- Uses `TacticalMarkerID_BLUE` and `TacticalMarkerID_RED` for tracking
|
||||
|
||||
### 2. **Victory Conditions** (Lines ~490-600)
|
||||
**BEFORE:** Only checked for BLUE victory
|
||||
**AFTER:** Both coalitions can win
|
||||
- BLUE Victory: All zones captured → "BLUE_VICTORY" flag set
|
||||
- RED Victory: All zones captured → "RED_VICTORY" flag set
|
||||
- Each side gets appropriate celebration effects (smoke colors, flares)
|
||||
- Proper victory/defeat messages for both sides
|
||||
|
||||
### 3. **Zone Status Reports** (Lines ~710-740)
|
||||
**BEFORE:** Only BLUE received status broadcasts
|
||||
**AFTER:** Both coalitions receive status reports
|
||||
- Each coalition sees their specific victory progress percentage
|
||||
- Same zone ownership data, customized messaging per coalition
|
||||
|
||||
### 4. **Victory Progress Monitoring** (Lines ~745-780)
|
||||
**BEFORE:** Only warned BLUE when approaching victory
|
||||
**AFTER:** Both sides get symmetric warnings
|
||||
- BLUE approaching victory (80%+) → BLUE gets encouragement, RED gets warning
|
||||
- RED approaching victory (80%+) → RED gets encouragement, BLUE gets warning
|
||||
|
||||
### 5. **F10 Radio Menu Commands** (Lines ~840-900)
|
||||
**BEFORE:** Only BLUE had F10 menu access
|
||||
**AFTER:** Both coalitions have identical F10 menus
|
||||
- "Get Zone Status Report" - Shows current zone ownership
|
||||
- "Check Victory Progress" - Shows their specific progress percentage
|
||||
- "Refresh Zone Colors" - Forces zone border redraw
|
||||
|
||||
### 6. **Zone Color Refresh Messages** (Line ~835)
|
||||
**BEFORE:** Only BLUE notified when colors refreshed
|
||||
**AFTER:** Both coalitions receive confirmation message
|
||||
|
||||
### 7. **Mission Definitions** (Lines 52-88)
|
||||
**BEFORE:** Only BLUE mission defined
|
||||
**AFTER:** Both coalitions have missions
|
||||
- BLUE: "Capture the Airfields" (offensive mission)
|
||||
- RED: "Defend the Motherland" (defensive mission)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Features Now Available to BOTH Coalitions
|
||||
|
||||
| Feature | BLUE | RED |
|
||||
|---------|------|-----|
|
||||
| Mission Objectives | ✅ | ✅ |
|
||||
| Tactical Markers (enemy positions) | ✅ | ✅ |
|
||||
| Zone Status Reports | ✅ | ✅ |
|
||||
| Victory Progress Tracking | ✅ | ✅ |
|
||||
| Victory Conditions | ✅ | ✅ |
|
||||
| F10 Menu Commands | ✅ | ✅ |
|
||||
| Zone Color Indicators | ✅ | ✅ |
|
||||
| Capture/Attack/Guard Messages | ✅ | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration
|
||||
|
||||
Mission makers can now set up asymmetric scenarios by configuring the `ZONE_CONFIG` table:
|
||||
|
||||
```lua
|
||||
local ZONE_CONFIG = {
|
||||
RED = {
|
||||
"Kilpyavr",
|
||||
"Severomorsk-1",
|
||||
-- ... more zones
|
||||
},
|
||||
|
||||
BLUE = {
|
||||
"Banak", -- Example: BLUE starting zone
|
||||
"Kirkenes"
|
||||
},
|
||||
|
||||
NEUTRAL = {
|
||||
"Contested Valley" -- Starts empty
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎮 Gameplay Impact
|
||||
|
||||
### Balanced Competition
|
||||
- Both sides can now win by capturing all zones
|
||||
- Victory celebrations are coalition-specific (blue/red smoke & flares)
|
||||
- Mission end triggers coalition-specific flags
|
||||
|
||||
### Equal Information Access
|
||||
- Both coalitions see enemy positions in contested zones
|
||||
- Both receive periodic status updates
|
||||
- Both have access to F10 menu commands
|
||||
|
||||
### Symmetric Design
|
||||
- All event handlers work equally for both sides
|
||||
- Messages are dynamically generated based on zone ownership
|
||||
- No hardcoded coalition bias anywhere in the code
|
||||
|
||||
---
|
||||
|
||||
## 📝 Technical Notes
|
||||
|
||||
### Global Variables Used
|
||||
- `US_CC` - BLUE coalition command center
|
||||
- `RU_CC` - RED coalition command center
|
||||
- Both must be defined before loading this script
|
||||
|
||||
### User Flags Set on Victory
|
||||
- `BLUE_VICTORY` = 1 when BLUE wins
|
||||
- `RED_VICTORY` = 1 when RED wins
|
||||
|
||||
### Storage Structure
|
||||
- `zoneCaptureObjects[]` - Array of zone capture objects
|
||||
- `zoneNames[]` - Array of zone names
|
||||
- `zoneMetadata{}` - Dictionary with coalition info
|
||||
- All zones accessible via table iteration (no global zone variables)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Migration from Old Script
|
||||
|
||||
If migrating from `Moose_CaptureZones.lua`:
|
||||
|
||||
1. **Update zone configuration** - Move zone names to `ZONE_CONFIG` table
|
||||
2. **Remove manual zone creation** - The loop handles it now
|
||||
3. **No code changes needed** for existing trigger zones in mission editor
|
||||
4. **F10 menus now available** to RED players automatically
|
||||
|
||||
---
|
||||
|
||||
## ✨ Benefits of Refactoring
|
||||
|
||||
1. **Easy to configure** - Simple table instead of repetitive code
|
||||
2. **Coalition agnostic** - Works equally for RED/BLUE/NEUTRAL
|
||||
3. **Maintainable** - Zone logic centralized in loops
|
||||
4. **Extensible** - Easy to add new features for both sides
|
||||
5. **Balanced** - True dual-coalition gameplay
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: Analysis completed with full dual-coalition parity*
|
||||
Binary file not shown.
@ -25,7 +25,7 @@ end
|
||||
-- Logging configuration: toggle logging behavior for this module
|
||||
-- Set `CAPTURE_ZONE_LOGGING.enabled = false` to silence module logs
|
||||
if not CAPTURE_ZONE_LOGGING then
|
||||
CAPTURE_ZONE_LOGGING = { enabled = false, prefix = "[CAPTURE Module]" }
|
||||
CAPTURE_ZONE_LOGGING = { enabled = true, prefix = "[CAPTURE Module]" }
|
||||
end
|
||||
|
||||
local function log(message, detailed)
|
||||
@ -155,14 +155,13 @@ local function GetZoneForceStrengths(ZoneCapture)
|
||||
local blueCount = 0
|
||||
local neutralCount = 0
|
||||
|
||||
-- Use MOOSE's optimized zone scanning instead of manual distance checks
|
||||
local success, scannedUnits = pcall(function()
|
||||
return zone:GetScannedUnits()
|
||||
end)
|
||||
-- Get all units in the zone using MOOSE's zone scanning
|
||||
local unitsInZone = SET_UNIT:New()
|
||||
:FilterZones({zone})
|
||||
:FilterOnce()
|
||||
|
||||
if success and scannedUnits then
|
||||
-- Use MOOSE's built-in scanned units (much faster)
|
||||
for _, unit in pairs(scannedUnits) do
|
||||
if unitsInZone then
|
||||
unitsInZone:ForEachUnit(function(unit)
|
||||
if unit and unit:IsAlive() then
|
||||
local unitCoalition = unit:GetCoalition()
|
||||
if unitCoalition == coalition.side.RED then
|
||||
@ -173,32 +172,7 @@ local function GetZoneForceStrengths(ZoneCapture)
|
||||
neutralCount = neutralCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Fallback: Use zone's built-in scanning with the cached set
|
||||
InitializeCachedUnitSet()
|
||||
|
||||
-- Use zone radius to limit search area
|
||||
local coord = zone:GetCoordinate()
|
||||
local radius = zone:GetRadius() or 1000
|
||||
|
||||
-- Only scan units within a reasonable distance of the zone
|
||||
local nearbyUnits = coord:ScanUnits(radius)
|
||||
if nearbyUnits then
|
||||
for _, unitData in pairs(nearbyUnits) do
|
||||
local unit = unitData -- ScanUnits returns unit objects
|
||||
if unit and type(unit.IsAlive) == "function" and unit:IsAlive() then
|
||||
local unitCoalition = unit:GetCoalition()
|
||||
if unitCoalition == coalition.side.RED then
|
||||
redCount = redCount + 1
|
||||
elseif unitCoalition == coalition.side.BLUE then
|
||||
blueCount = blueCount + 1
|
||||
elseif unitCoalition == coalition.side.NEUTRAL then
|
||||
neutralCount = neutralCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
log(string.format("[TACTICAL] Zone %s scan result: R:%d B:%d N:%d",
|
||||
@ -216,69 +190,81 @@ local function GetRedUnitMGRSCoords(ZoneCapture)
|
||||
if not zone then return {} end
|
||||
|
||||
local coords = {}
|
||||
local units = nil
|
||||
|
||||
-- Optimized: Try MOOSE's built-in zone scanning first (fastest method)
|
||||
local success1 = pcall(function()
|
||||
units = zone:GetScannedUnits()
|
||||
end)
|
||||
-- Get all units in the zone using MOOSE's zone scanning
|
||||
local unitsInZone = SET_UNIT:New()
|
||||
:FilterZones({zone})
|
||||
:FilterOnce()
|
||||
|
||||
-- Fallback: Use coordinate-based scanning (much faster than SET_UNIT filtering)
|
||||
if not success1 or not units then
|
||||
local coord = zone:GetCoordinate()
|
||||
local radius = zone:GetRadius() or 1000
|
||||
|
||||
local success2 = pcall(function()
|
||||
units = coord:ScanUnits(radius)
|
||||
end)
|
||||
|
||||
-- Last resort: Manual zone check with cached unit set
|
||||
if not success2 or not units then
|
||||
InitializeCachedUnitSet()
|
||||
units = {}
|
||||
if CachedUnitSet then
|
||||
CachedUnitSet:ForEachUnit(function(unit)
|
||||
if unit and unit:IsAlive() and unit:IsInZone(zone) then
|
||||
units[unit:GetName()] = unit
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
local totalUnits = 0
|
||||
local redUnits = 0
|
||||
local unitsWithCoords = 0
|
||||
|
||||
-- Extract RED unit coordinates with optimized error handling
|
||||
if units then
|
||||
for unitName, unit in pairs(units) do
|
||||
-- Streamlined nil checking
|
||||
if unit and type(unit) == "table" then
|
||||
local success, isAlive = pcall(function() return unit:IsAlive() end)
|
||||
if unitsInZone then
|
||||
unitsInZone:ForEachUnit(function(unit)
|
||||
totalUnits = totalUnits + 1
|
||||
if unit and unit:IsAlive() then
|
||||
local unitCoalition = unit:GetCoalition()
|
||||
|
||||
if success and isAlive then
|
||||
local success_coalition, coalition_side = pcall(function() return unit:GetCoalition() end)
|
||||
-- Only process RED units
|
||||
if unitCoalition == coalition.side.RED then
|
||||
redUnits = redUnits + 1
|
||||
local coord = unit:GetCoordinate()
|
||||
|
||||
if success_coalition and coalition_side == coalition.side.RED then
|
||||
local success_coord, coord = pcall(function() return unit:GetCoordinate() end)
|
||||
if coord then
|
||||
-- Try multiple methods to get coordinates
|
||||
local mgrs = nil
|
||||
local success_mgrs = false
|
||||
|
||||
if success_coord and coord then
|
||||
local success_mgrs, mgrs = pcall(function()
|
||||
return coord:ToStringMGRS(5) -- 5-digit precision
|
||||
-- Method 1: Try ToStringMGRS
|
||||
success_mgrs, mgrs = pcall(function()
|
||||
return coord:ToStringMGRS(5)
|
||||
end)
|
||||
|
||||
-- Method 2: Try ToStringMGRS without precision parameter
|
||||
if not success_mgrs or not mgrs then
|
||||
success_mgrs, mgrs = pcall(function()
|
||||
return coord:ToStringMGRS()
|
||||
end)
|
||||
|
||||
if success_mgrs and mgrs then
|
||||
local success_type, unitType = pcall(function() return unit:GetTypeName() end)
|
||||
table.insert(coords, {
|
||||
name = unit:GetName(),
|
||||
type = success_type and unitType or "Unknown",
|
||||
mgrs = mgrs
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Method 3: Try ToMGRS
|
||||
if not success_mgrs or not mgrs then
|
||||
success_mgrs, mgrs = pcall(function()
|
||||
return coord:ToMGRS()
|
||||
end)
|
||||
end
|
||||
|
||||
-- Method 4: Fallback to Lat/Long
|
||||
if not success_mgrs or not mgrs then
|
||||
success_mgrs, mgrs = pcall(function()
|
||||
local lat, lon = coord:GetLLDDM()
|
||||
return string.format("N%s E%s", lat, lon)
|
||||
end)
|
||||
end
|
||||
|
||||
if success_mgrs and mgrs then
|
||||
unitsWithCoords = unitsWithCoords + 1
|
||||
local unitType = unit:GetTypeName() or "Unknown"
|
||||
table.insert(coords, {
|
||||
name = unit:GetName(),
|
||||
type = unitType,
|
||||
mgrs = mgrs
|
||||
})
|
||||
else
|
||||
log(string.format("[TACTICAL DEBUG] All coordinate methods failed for unit %s", unit:GetName() or "unknown"))
|
||||
end
|
||||
else
|
||||
log(string.format("[TACTICAL DEBUG] No coordinate for unit %s", unit:GetName() or "unknown"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
log(string.format("[TACTICAL DEBUG] %s - Total units scanned: %d, RED units: %d, units with MGRS: %d",
|
||||
ZoneCapture:GetZoneName(), totalUnits, redUnits, unitsWithCoords))
|
||||
|
||||
log(string.format("[TACTICAL] Found %d RED units with coordinates in %s",
|
||||
#coords, ZoneCapture:GetZoneName()))
|
||||
|
||||
@ -303,21 +289,34 @@ local function CreateTacticalInfoMarker(ZoneCapture)
|
||||
-- Add MGRS coordinates if RED forces <= 10
|
||||
if forces.red > 0 and forces.red <= 10 then
|
||||
local redCoords = GetRedUnitMGRSCoords(ZoneCapture)
|
||||
log(string.format("[TACTICAL DEBUG] Building marker text for %d RED units", #redCoords))
|
||||
if #redCoords > 0 then
|
||||
tacticalText = tacticalText .. "\n\nRED UNITS:"
|
||||
tacticalText = tacticalText .. "\nTGTS:"
|
||||
for i, unit in ipairs(redCoords) do
|
||||
if i <= 6 then -- Limit to 6 entries to avoid text overflow
|
||||
if i <= 10 then -- Show up to 10 units (the threshold)
|
||||
-- Shorten unit type names to fit better
|
||||
local shortType = unit.type:gsub("^%w+%-", ""):gsub("%s.*", "")
|
||||
tacticalText = tacticalText .. string.format("\n%s: %s", shortType, unit.mgrs)
|
||||
-- Clean up MGRS string - remove "MGRS " prefix and compress spacing
|
||||
local cleanMgrs = unit.mgrs:gsub("^MGRS%s+", ""):gsub("%s+", " ")
|
||||
-- Ultra-compact: comma-separated on same line
|
||||
if i == 1 then
|
||||
tacticalText = tacticalText .. string.format(" %s@%s", shortType, cleanMgrs)
|
||||
else
|
||||
tacticalText = tacticalText .. string.format(", %s@%s", shortType, cleanMgrs)
|
||||
end
|
||||
log(string.format("[TACTICAL DEBUG] Added unit %d: %s at %s", i, shortType, cleanMgrs))
|
||||
end
|
||||
end
|
||||
if #redCoords > 6 then
|
||||
tacticalText = tacticalText .. string.format("\n+%d more", #redCoords - 6)
|
||||
if #redCoords > 10 then
|
||||
tacticalText = tacticalText .. string.format(" (+%d)", #redCoords - 10)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Debug: Log the complete marker text that will be displayed
|
||||
log(string.format("[TACTICAL DEBUG] Complete marker text for %s:\n%s", zoneName, tacticalText))
|
||||
log(string.format("[TACTICAL DEBUG] Marker text length: %d characters", string.len(tacticalText)))
|
||||
|
||||
-- Create tactical marker offset from zone center
|
||||
local coord = zone:GetCoordinate()
|
||||
if coord then
|
||||
|
||||
1009
DCS_Kola/Operation_Polar_Shield/Moose_DualCoalitionZoneCapture.lua
Normal file
1009
DCS_Kola/Operation_Polar_Shield/Moose_DualCoalitionZoneCapture.lua
Normal file
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,8 @@ MAX_RU_IFV_Technicals = 45
|
||||
MAX_RU_SA08 = 15
|
||||
MAX_RU_SA19 = 15
|
||||
MAX_RU_SA15 = 30 -- This is a group of 3 . Sa15 + Shilka + Ammo truck.
|
||||
MAX_RU_SA2 = 120 -- Each group has 15 units, so 120 = 8 groups of 15.
|
||||
MAX_RU_SA6 = 88 -- Each group has 11 units, so 88 = 8 groups of 11.
|
||||
|
||||
MIN_RU_INTERCEPTORS = 1 -- Each group has 2 units, so 2 = 1 group of 2. This is the minimum number of interceptors that will always be present.
|
||||
MAX_RU_INTERCEPTORS = 500 -- This the total number of interceptors that can be spawned. The script will maintain at least the minimum number above.
|
||||
@ -286,6 +288,18 @@ RandomSpawns_RU_SA15 = SPAWN:New( "RU_SA-15" )
|
||||
:InitRandomizeZones( RandomSpawnZoneTable )
|
||||
:SpawnScheduled( .1, .5 )
|
||||
|
||||
env.info("Spawning SA-02 SAMs...")
|
||||
RandomSpawns_RU_SA02 = SPAWN:New( "RU_SA2" )
|
||||
:InitLimit( MAX_RU_SA2, MAX_RU_SA2 )
|
||||
:InitRandomizeZones( RandomSpawnZoneTable )
|
||||
:SpawnScheduled( .1, .5 )
|
||||
|
||||
env.info("Spawning SA6 SAMs...")
|
||||
RandomSpawns_RU_SA6 = SPAWN:New( "RU_SA6" )
|
||||
:InitLimit( MAX_RU_SA6, MAX_RU_SA6 )
|
||||
:InitRandomizeZones( RandomSpawnZoneTable )
|
||||
:SpawnScheduled( .1, .5 )
|
||||
|
||||
--[[
|
||||
RU_INTERCEPTOR_SPAWN = SPAWN:New("RU_INTERCEPT-1")
|
||||
:InitLimit( MIN_RU_INTERCEPTORS, MAX_RU_INTERCEPTORS )
|
||||
|
||||
@ -314,8 +314,6 @@ for _, squadron in pairs(BLUE_SQUADRON_CONFIG) do
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Squadron resource summary generator
|
||||
|
||||
local function getSquadronResourceSummary(coalitionSide)
|
||||
@ -1883,7 +1881,7 @@ local function checkAirbaseStatus()
|
||||
redUsableCount = redUsableCount + 1
|
||||
end
|
||||
|
||||
log(statusPrefix .. " " .. squadron.airbaseName .. " - " .. fullStatus)
|
||||
log(statusPrefix .. " " .. squadron.displayName .. " (" .. squadron.airbaseName .. ") - " .. fullStatus)
|
||||
end
|
||||
log("RED Status: " .. redUsableCount .. "/" .. #RED_SQUADRON_CONFIG .. " airbases operational")
|
||||
end
|
||||
@ -1949,8 +1947,7 @@ local function checkAirbaseStatus()
|
||||
blueUsableCount = blueUsableCount + 1
|
||||
end
|
||||
|
||||
log(statusPrefix .. " " .. squadron.airbaseName .. " - " .. fullStatus)
|
||||
end
|
||||
log(statusPrefix .. " " .. squadron.displayName .. " (" .. squadron.airbaseName .. ") - " .. fullStatus)
|
||||
end
|
||||
log("BLUE Status: " .. blueUsableCount .. "/" .. #BLUE_SQUADRON_CONFIG .. " airbases operational")
|
||||
end
|
||||
@ -2168,7 +2165,7 @@ local function initializeSystem()
|
||||
SCHEDULER:New(nil, detectThreats, {}, 5, TADC_SETTINGS.checkInterval)
|
||||
SCHEDULER:New(nil, monitorInterceptors, {}, 10, TADC_SETTINGS.monitorInterval)
|
||||
SCHEDULER:New(nil, checkAirbaseStatus, {}, 30, TADC_SETTINGS.statusReportInterval)
|
||||
SCHEDULER:New(nil, updateSquadronStates, {}, 15, 30) -- Update squadron states every 30 seconds
|
||||
SCHEDULER:New(nil, updateSquadronStates, {}, 60, 30) -- Update squadron states every 30 seconds (60 sec initial delay to allow DCS airbase coalition to stabilize)
|
||||
SCHEDULER:New(nil, cleanupOldDeliveries, {}, 60, 3600) -- Cleanup old delivery records every hour
|
||||
|
||||
-- Start periodic squadron summary broadcast
|
||||
|
||||
@ -79,8 +79,36 @@ RED_SQUADRON_CONFIG = {
|
||||
|
||||
-- ADD YOUR RED SQUADRONS HERE
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Kilpyavr", -- Change to your RED template name
|
||||
displayName = "Kilpyavr CAP", -- Change to your preferred name
|
||||
templateName = "FIGHTER_SWEEP_RED_Kilpyavr-MiG29A", -- Change to your RED template name
|
||||
displayName = "Kilpyavr CAP MiG-29A", -- Change to your preferred name
|
||||
airbaseName = "Kilpyavr", -- Change to your RED airbase
|
||||
aircraft = 12, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
altitude = 15400, -- Patrol altitude (feet)
|
||||
speed = 312, -- Patrol speed (knots)
|
||||
patrolTime = 32, -- Time on station (minutes)
|
||||
type = "FIGHTER",
|
||||
|
||||
-- Zone-based Areas of Responsibility (optional - leave nil for global response)
|
||||
primaryZone = "RED BORDER", -- Main responsibility area (zone name from mission editor)
|
||||
secondaryZone = nil, -- Secondary coverage area (zone name)
|
||||
tertiaryZone = nil, -- Emergency/fallback zone (zone name)
|
||||
|
||||
-- Zone behavior settings (optional - uses defaults if not specified)
|
||||
zoneConfig = {
|
||||
primaryResponse = 1.0, -- Intercept ratio multiplier in primary zone
|
||||
secondaryResponse = 0.6, -- Intercept ratio multiplier in secondary zone
|
||||
tertiaryResponse = 1.4, -- Intercept ratio multiplier in tertiary zone
|
||||
maxRange = 200, -- Maximum engagement range from airbase (nm)
|
||||
enableFallback = false, -- Auto-switch to tertiary when base threatened
|
||||
priorityThreshold = 4, -- Min aircraft count for "major threat"
|
||||
ignoreLowPriority = false, -- Ignore threats below threshold in secondary zones
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Kilpyavr-MiG29S", -- Change to your RED template name
|
||||
displayName = "Kilpyavr CAP MiG-29S", -- Change to your preferred name
|
||||
airbaseName = "Kilpyavr", -- Change to your RED airbase
|
||||
aircraft = 12, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
@ -107,8 +135,36 @@ RED_SQUADRON_CONFIG = {
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Severomorsk-1", -- Change to your RED template name
|
||||
displayName = "Severomorsk-1 CAP", -- Change to your preferred name
|
||||
templateName = "FIGHTER_SWEEP_RED_Severomorsk-1-MiG23", -- Change to your RED template name
|
||||
displayName = "Severomorsk-1 CAP MiG-23", -- Change to your preferred name
|
||||
airbaseName = "Severomorsk-1", -- Change to your RED airbase
|
||||
aircraft = 10, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
altitude = 18800, -- Patrol altitude (feet)
|
||||
speed = 420, -- Patrol speed (knots)
|
||||
patrolTime = 23, -- Time on station (minutes)
|
||||
type = "FIGHTER",
|
||||
|
||||
-- Zone-based Areas of Responsibility (optional - leave nil for global response)
|
||||
primaryZone = "RED BORDER", -- Main responsibility area (zone name from mission editor)
|
||||
secondaryZone = nil, -- Secondary coverage area (zone name)
|
||||
tertiaryZone = nil, -- Emergency/fallback zone (zone name)
|
||||
|
||||
-- Zone behavior settings (optional - uses defaults if not specified)
|
||||
zoneConfig = {
|
||||
primaryResponse = 1.0, -- Intercept ratio multiplier in primary zone
|
||||
secondaryResponse = 0.6, -- Intercept ratio multiplier in secondary zone
|
||||
tertiaryResponse = 1.4, -- Intercept ratio multiplier in tertiary zone
|
||||
maxRange = 200, -- Maximum engagement range from airbase (nm)
|
||||
enableFallback = false, -- Auto-switch to tertiary when base threatened
|
||||
priorityThreshold = 4, -- Min aircraft count for "major threat"
|
||||
ignoreLowPriority = false, -- Ignore threats below threshold in secondary zones
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Severomorsk-1-MiG25", -- Change to your RED template name
|
||||
displayName = "Severomorsk-1 CAP MiG-25", -- Change to your preferred name
|
||||
airbaseName = "Severomorsk-1", -- Change to your RED airbase
|
||||
aircraft = 10, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
@ -135,8 +191,36 @@ RED_SQUADRON_CONFIG = {
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Severomorsk-3", -- Change to your RED template name
|
||||
displayName = "Severomorsk-3 CAP", -- Change to your preferred name
|
||||
templateName = "FIGHTER_SWEEP_RED_Severomorsk-3-SU27", -- Change to your RED template name
|
||||
displayName = "Severomorsk-3 CAP SU-27", -- Change to your preferred name
|
||||
airbaseName = "Severomorsk-3", -- Change to your RED airbase
|
||||
aircraft = 15, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
altitude = 26700, -- Patrol altitude (feet)
|
||||
speed = 335, -- Patrol speed (knots)
|
||||
patrolTime = 28, -- Time on station (minutes)
|
||||
type = "FIGHTER",
|
||||
|
||||
-- Zone-based Areas of Responsibility (optional - leave nil for global response)
|
||||
primaryZone = "RED BORDER", -- Main responsibility area (zone name from mission editor)
|
||||
secondaryZone = nil, -- Secondary coverage area (zone name)
|
||||
tertiaryZone = nil, -- Emergency/fallback zone (zone name)
|
||||
|
||||
-- Zone behavior settings (optional - uses defaults if not specified)
|
||||
zoneConfig = {
|
||||
primaryResponse = 1.0, -- Intercept ratio multiplier in primary zone
|
||||
secondaryResponse = 0.6, -- Intercept ratio multiplier in secondary zone
|
||||
tertiaryResponse = 1.4, -- Intercept ratio multiplier in tertiary zone
|
||||
maxRange = 200, -- Maximum engagement range from airbase (nm)
|
||||
enableFallback = false, -- Auto-switch to tertiary when base threatened
|
||||
priorityThreshold = 4, -- Min aircraft count for "major threat"
|
||||
ignoreLowPriority = false, -- Ignore threats below threshold in secondary zones
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Severomorsk-3-MiG-21", -- Change to your RED template name
|
||||
displayName = "Severomorsk-3 CAP MiG-21", -- Change to your preferred name
|
||||
airbaseName = "Severomorsk-3", -- Change to your RED airbase
|
||||
aircraft = 15, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
@ -163,8 +247,36 @@ RED_SQUADRON_CONFIG = {
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Murmansk", -- Change to your RED template name
|
||||
displayName = "Murmansk CAP", -- Change to your preferred name
|
||||
templateName = "FIGHTER_SWEEP_RED_Murmansk-JF17", -- Change to your RED template name
|
||||
displayName = "Murmansk CAP JF-17", -- Change to your preferred name
|
||||
airbaseName = "Murmansk International", -- Change to your RED airbase
|
||||
aircraft = 8, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
altitude = 22100, -- Patrol altitude (feet)
|
||||
speed = 390, -- Patrol speed (knots)
|
||||
patrolTime = 20, -- Time on station (minutes)
|
||||
type = "FIGHTER",
|
||||
|
||||
-- Zone-based Areas of Responsibility (optional - leave nil for global response)
|
||||
primaryZone = "RED BORDER", -- Main responsibility area (zone name from mission editor)
|
||||
secondaryZone = nil, -- Secondary coverage area (zone name)
|
||||
tertiaryZone = nil, -- Emergency/fallback zone (zone name)
|
||||
|
||||
-- Zone behavior settings (optional - uses defaults if not specified)
|
||||
zoneConfig = {
|
||||
primaryResponse = 1.0, -- Intercept ratio multiplier in primary zone
|
||||
secondaryResponse = 0.6, -- Intercept ratio multiplier in secondary zone
|
||||
tertiaryResponse = 1.4, -- Intercept ratio multiplier in tertiary zone
|
||||
maxRange = 200, -- Maximum engagement range from airbase (nm)
|
||||
enableFallback = false, -- Auto-switch to tertiary when base threatened
|
||||
priorityThreshold = 4, -- Min aircraft count for "major threat"
|
||||
ignoreLowPriority = false, -- Ignore threats below threshold in secondary zones
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Murmansk-MiG29A", -- Change to your RED template name
|
||||
displayName = "Murmansk CAP MiG-29A", -- Change to your preferred name
|
||||
airbaseName = "Murmansk International", -- Change to your RED airbase
|
||||
aircraft = 8, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
@ -191,12 +303,12 @@ RED_SQUADRON_CONFIG = {
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Monchegorsk", -- Change to your RED template name
|
||||
displayName = "Monchegorsk CAP", -- Change to your preferred name
|
||||
templateName = "FIGHTER_SWEEP_RED_Monchegorsk-F4", -- Change to your RED template name
|
||||
displayName = "Monchegorsk CAP F-4", -- Change to your preferred name
|
||||
airbaseName = "Monchegorsk", -- Change to your RED airbase
|
||||
aircraft = 16, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
altitude = 30000, -- Patrol altitude (feet)
|
||||
altitude = 12000, -- Patrol altitude (feet)
|
||||
speed = 305, -- Patrol speed (knots)
|
||||
patrolTime = 35, -- Time on station (minutes)
|
||||
type = "FIGHTER",
|
||||
@ -216,11 +328,67 @@ RED_SQUADRON_CONFIG = {
|
||||
priorityThreshold = 4, -- Min aircraft count for "major threat"
|
||||
ignoreLowPriority = false, -- Ignore threats below threshold in secondary zones
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Monchegorsk-F5", -- Change to your RED template name
|
||||
displayName = "Monchegorsk CAP F-5", -- Change to your preferred name
|
||||
airbaseName = "Monchegorsk", -- Change to your RED airbase
|
||||
aircraft = 16, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
altitude = 15000, -- Patrol altitude (feet)
|
||||
speed = 305, -- Patrol speed (knots)
|
||||
patrolTime = 35, -- Time on station (minutes)
|
||||
type = "FIGHTER",
|
||||
|
||||
-- Zone-based Areas of Responsibility (optional - leave nil for global response)
|
||||
primaryZone = "RED BORDER", -- Main responsibility area (zone name from mission editor)
|
||||
secondaryZone = nil, -- Secondary coverage area (zone name)
|
||||
tertiaryZone = nil, -- Emergency/fallback zone (zone name)
|
||||
|
||||
-- Zone behavior settings (optional - uses defaults if not specified)
|
||||
zoneConfig = {
|
||||
primaryResponse = 1.0, -- Intercept ratio multiplier in primary zone
|
||||
secondaryResponse = 0.6, -- Intercept ratio multiplier in secondary zone
|
||||
tertiaryResponse = 1.4, -- Intercept ratio multiplier in tertiary zone
|
||||
maxRange = 200, -- Maximum engagement range from airbase (nm)
|
||||
enableFallback = false, -- Auto-switch to tertiary when base threatened
|
||||
priorityThreshold = 4, -- Min aircraft count for "major threat"
|
||||
ignoreLowPriority = false, -- Ignore threats below threshold in secondary zones
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Olenya", -- Change to your RED template name
|
||||
displayName = "Olenya CAP", -- Change to your preferred name
|
||||
templateName = "FIGHTER_SWEEP_RED_Olenya-MiG21", -- Change to your RED template name
|
||||
displayName = "Olenya CAP MiG-21", -- Change to your preferred name
|
||||
airbaseName = "Olenya", -- Change to your RED airbase
|
||||
aircraft = 12, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
altitude = 17800, -- Patrol altitude (feet)
|
||||
speed = 445, -- Patrol speed (knots)
|
||||
patrolTime = 27, -- Time on station (minutes)
|
||||
type = "FIGHTER",
|
||||
|
||||
-- Zone-based Areas of Responsibility (optional - leave nil for global response)
|
||||
primaryZone = "RED BORDER", -- Main responsibility area (zone name from mission editor)
|
||||
secondaryZone = nil, -- Secondary coverage area (zone name)
|
||||
tertiaryZone = nil, -- Emergency/fallback zone (zone name)
|
||||
|
||||
-- Zone behavior settings (optional - uses defaults if not specified)
|
||||
zoneConfig = {
|
||||
primaryResponse = 1.0, -- Intercept ratio multiplier in primary zone
|
||||
secondaryResponse = 0.6, -- Intercept ratio multiplier in secondary zone
|
||||
tertiaryResponse = 1.4, -- Intercept ratio multiplier in tertiary zone
|
||||
maxRange = 200, -- Maximum engagement range from airbase (nm)
|
||||
enableFallback = false, -- Auto-switch to tertiary when base threatened
|
||||
priorityThreshold = 4, -- Min aircraft count for "major threat"
|
||||
ignoreLowPriority = false, -- Ignore threats below threshold in secondary zones
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
templateName = "FIGHTER_SWEEP_RED_Olenya-MiG31", -- Change to your RED template name
|
||||
displayName = "Olenya CAP MiG-31", -- Change to your preferred name
|
||||
airbaseName = "Olenya", -- Change to your RED airbase
|
||||
aircraft = 12, -- Adjust aircraft count
|
||||
skill = AI.Skill.ACE, -- AVERAGE, GOOD, HIGH, EXCELLENT, ACE
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user