Skip to content

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.

ProximitycheckEnemiesProximityForDefenses(), 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).