Airbases — DM.Airbase¶
Class defined in sources/DynamicMission.lua:1282-2076.
Coalition tracking¶
Each instance locally tracks coalition/coalitionPrevious, refreshed on demand by
updateCoalition(). The isNeutral()/isRed()/isBlue()/isAlly() methods, on the other
hand, always read the live DCS coalition, not the cached value — so they're reliable even
between two explicit updateCoalition() calls.
The Jerrycan mechanic (neutral anchoring)¶
spawnJerrycan() only applies to neutral bases. A "Jerrycan" static object (Fortifications
category) is placed on one of two pre-computed slots (perpendicular to the runway, 50m offset by
default), picked at random with a fallback to the other slot if the first is obstructed.
Spawning the static object itself flips the base's DCS coalition — confirmed by the immediate
updateCoalition() call that follows. Only called once, at mission start, for bases linked to a
region and neutral.
Automatic defense spawn: three triggers¶
Landing — _handleLanding() on S_EVENT_LAND. If the landing player's coalition differs
from the base's and no defense is placed yet, spawns 1 to 3 groups (random) for the landing
player's coalition — protects the intruder after a capture/landing on a previously
hostile-or-neutral airfield.
Proximity — checkEnemiesProximityForDefenses(), a 30s scheduler. For any allied base — or
neutral one still carrying its Jerrycan — with no defense placed, scans for enemy air+ground
units within a 20km radius. On detection, spawns defenses for the base's owning coalition —
a defensive reinforcement. The enemy unit list (enemyUnits) is rebuilt once per tick,
before the region/base loop, rather than once per base — an O(units) complexity optimization
instead of O(units × bases).
Capture — _handleBaseCaptured() on S_EVENT_BASE_CAPTURED. This handler calls no spawn
function at all. It only calls setCoalition() plus a re-check of the parent region's CLEARED
status. The capture changes the coalition without ever placing defenses in the same stroke —
they only appear afterward, through either of the two paths above reacting to the new state.
One-shot mechanic, per base and per mission run
The Jerrycan-to-defense replacement (Proximity trigger) only ever happens once per base:
checkEnemiesProximityForDefenses() requires airbase.jerrycanStatic to be present and
not airbase.defenseSpawned. spawnDefensesByProximity() destroys the Jerrycan the moment
it places defenses — once consumed, the Jerrycan never comes back short of a full mission
reload (DM.Manager:start() only re-anchors Jerrycans on load).
spawnAirbaseDefenses() resets AD_ template usage counters on every call; picks templates at
random with a per-template cap (maxLocalSpawn, taken from the AD_[description]_[maxLocalSpawn]
nomenclature), with 10 attempts before a forced spawn; assigns each group to a free runway slot
(6 available); rotates each group by a random 0–360° heading before translation, to vary the
visual presentation.
Spawn slots¶
6 fixed positions around the runway, computed from position/heading/length/width: 4 corner slots
(diagonal, at distance × √2 from the edge) + 2 lateral slots (perpendicular, at plain distance),
distance = 100m by default. In DEBUG_MODE, red debug circles are drawn on F10 for each slot
(filterable to a single region).