Skip to content

GUER VBIED Detonate Action

rayswaynl edited this page Jul 6, 2026 · 5 revisions

GUER VBIED Detonate Action

Source-verified 2026-07-06 against branch claude/cmdcon44-wddm @ 1ac5a3f (Build 89 line). Paths relative to Missions/[55-2hc]warfarev2_073v48co.chernarus/ unless noted. Arma 2 OA 1.64.

The GUER "Insurgents" playable faction (Feature B, added by Ray 2026-06-16) gives the resistance player a driver-detonated car bomb. A buyable covered civilian pickup — or, once the side has racked up enough kills, an M113 APC — carries a red Detonate VBIED player action that, on a single scroll-wheel click, immediately asks the server to blow up the vehicle and pay the detonator personally (cash by UID + score) — there is no confirm window and no arm countdown (instant detonation, Ray 2026-06-18). The old team-funds payout was disabled on 2026-06-27: the suicide driver's pre-blast group never reaches the respawned detonator, so the wallet/UID channel is now the single payout path. The whole feature is gated behind WFBE_C_GUER_PLAYERSIDE > 0; that gate defaults ON since B66, so on a stock server the action is added for GUER VBIED drivers (with the gate off, no action is added and the server case is never reached). This page traces the action wiring, the one-shot client guard, the detonation mechanic (the server blast that mirrors AI wildcard W21), the payout pipeline, and the two M113-specific extras (kill gate + speed-boost loop).

Where the action is attached

The action is a local addAction attached on the buyer's client only, inside the per-vehicle local-init block of Client_BuildUnit.sqf, via an idempotent helper.

Item Detail Source
Gate WFBE_C_GUER_PLAYERSIDE > 0 and vehicle typeOf equals WFBE_C_GUER_VBIED_TYPE (truck) or WFBE_C_GUER_VBIED_M113_TYPE (M113) Client/Functions/Client_BuildUnit.sqf:496
Attach helper WFBE_CL_FNC_AddGuerVbiedAction — idempotent via a wfbe_vbied_action getVariable check, so re-entry never stacks duplicate actions Client/Functions/Client_BuildUnit.sqf:511-520
addAction <t color='#ff3333'>Detonate VBIED</t> (HTML red) → Client\Action\Action_GuerVbiedDetonate.sqf, priority 6, showWindow false, hideOnUse true, condition driver _target == _this && {side _this == resistance} (driver-only, resistance-only) Client/Functions/Client_BuildUnit.sqf:518
Re-arm a GetIn event handler re-attaches for a local resistance player entering the driver seat Client/Functions/Client_BuildUnit.sqf:559-578
M113 tag the M113 chassis is tagged wfbe_vbied_m113 at build time (feeds the speed-boost loop below) Client/Functions/Client_BuildUnit.sqf:503

Because addAction is local, only the client that built (bought) the vehicle — or a driver caught by the GetIn re-arm — attaches the action. On the gate-off / non-VBIED path the if at line 496 is false and no action is added.

The VBIED truck chassis is a tier-0 "always available" entry in the GUER buy pool: hilux1_civil_2_covered on Chernarus (Common/Config/Core_Root/Root_GUE_PlayerOverlay.sqf:77) and datsun1_civil_2_covered on Takistan, where the overlay also repoints WFBE_C_GUER_VBIED_TYPE so the client gate and the server guard both match the TK truck (Common/Config/Core_Root/Root_GUE_PlayerOverlay.sqf:86-93).

The M113 second chassis (B75): kill-gated, speed-boosted

Mechanic Detail Source
Kill gate the M113 (WFBE_C_GUER_VBIED_M113_TYPE, default M113_UN_EP1) joins the depot pool only once WFBE_GUER_PLAYER_KILLS >= WFBE_C_GUER_VBIED_M113_KILLS (50 since the 2x bump; was 25) Common/Config/Core_Root/Root_GUE_PlayerOverlay.sqf:63-64,104; Common/Init/Init_CommonConstants.sqf:114
Pool rebuild the overlay's polling loop (10 s cadence) rebuilds WFBE_GUERDEPOTUNITS whenever the [_tier,_m113On,_fobAvail,_civDepotOn] signature changes Common/Config/Core_Root/Root_GUE_PlayerOverlay.sqf:56-115
Speed boost WFBE_CL_FNC_GuerVbiedM113Boost: a driver-local 0.1 s loop that nudges setVelocity +7% of the forward component per tick while isEngineOn && speed > 3 && speed < _target, where _target = (config maxSpeed) * WFBE_C_GUER_VBIED_M113_SPEEDCOEF (2.0 → ~2x stock M113). A2-OA has no setMaxSpeed, hence the velocity-nudge idiom Client/Functions/Client_BuildUnit.sqf:522-555
Boost lifecycle started from the GetIn EH (driver, local player, resistance, wfbe_vbied_m113 tag); exits when the hull dies, the local player stops driving, or canMove fails; an idempotency guard (wfbe_m113_boost_running) prevents duplicate loops Client/Functions/Client_BuildUnit.sqf:529-530,538,553,559-578

Note the stale-looking 25 in Root_GUE_PlayerOverlay.sqf:64 and Server/PVFunctions/RequestOnUnitKilled.sqf:118 is only the getVariable fallback literal (used if the constant were nil); the live isNil-seeded constant is 50.

The instant client action

Action_GuerVbiedDetonate.sqf receives _this = [target(vehicle), caller(player), actionId, args] and runs entirely on the activating client. Its header records the design intent verbatim: INSTANT DETONATION (Ray 2026-06-18) — no confirm window, no arm countdown, no dialog. A single selection sets a one-shot guard and immediately asks the server to detonate.

Stage Logic Source
Sanity guard `isNull _veh
Driver guard driver _veh != _player -> exit (belt-and-braces vs the action condition) Client/Action/Action_GuerVbiedDetonate.sqf:21
One-shot guard _veh getVariable ["wfbe_vbied_fired", false] -> exit (already sent; blocks a same-frame double-select) Client/Action/Action_GuerVbiedDetonate.sqf:22
Detonate set wfbe_vbied_fired = true, then immediately ["RequestSpecial", ["guer-vbied-detonate", _veh, _player]] Call WFBE_CO_FNC_SendToServer Client/Action/Action_GuerVbiedDetonate.sqf:25-26

There is no wfbe_vbied_confirm / wfbe_vbied_arming state and no countdown thread — the only client-side state is the boolean wfbe_vbied_fired. (An earlier build had a two-step confirm + arm countdown; it was removed on 2026-06-18 in favour of the single instant click. The WFBE_C_GUER_VBIED_ARM_DELAY constant at Common/Init/Init_CommonConstants.sqf:77 is a leftover of that design — nothing references it anymore.) The request convention is the standard one used across the codebase: WFBE_CO_FNC_SendToServer hands ["guer-vbied-detonate", _veh, _player] to the server's Server_HandleSpecial.sqf, which switches on the tag (_args select 0).

The server detonation mechanic

The server re-validates everything (it cannot trust the client) and only then runs the blast, in the guer-vbied-detonate case of Server_HandleSpecial.sqf (case starts at Server/Functions/Server_HandleSpecial.sqf:1155; the body runs in a spawn-ed thread from :1160).

Step Logic Source
Unpack _veh = _args select 1, _driver = _args select 2 Server/Functions/Server_HandleSpecial.sqf:1156-1158
Re-validate vehicle non-null + alive, gate ON, driver _veh == _driver, side _driver == resistance, and typeOf _veh is either WFBE_C_GUER_VBIED_TYPE (truck) or WFBE_C_GUER_VBIED_M113_TYPE (B75) Server/Functions/Server_HandleSpecial.sqf:1159
Capture identity _drvGrp = group _driver and _drvUID = getPlayerUID _driver, snapped before the blast — the suicide driver is dead/unreliable by settle time Server/Functions/Server_HandleSpecial.sqf:1164-1168
Victim snapshot living east/west Man units, plus crewed LandVehicle/Air (alive crew > 0, so empty wrecks never pay — B74.1/C5 over-pay bound), within WFBE_C_GUER_VBIED_BLAST_RADIUS of the vehicle Server/Functions/Server_HandleSpecial.sqf:1176-1190
Structure snapshot living enemy base structures within the radius, read from each enemy side logic's authoritative wfbe_structures list (B75) Server/Functions/Server_HandleSpecial.sqf:1191-1205
Blast _veh setDamage 1, then "Bo_FAB_250" createVehicle _p three times at the vehicle position (B74.1: was 3x Sh_122_HE; the FAB-250 aerial bomb gives a far bigger crater) Server/Functions/Server_HandleSpecial.sqf:1206-1212
Settle sleep 4, then resolve payouts from the snapshots (below) Server/Functions/Server_HandleSpecial.sqf:1214

The re-validation makes the request safe to receive: it re-checks the gate, that _driver still drives _veh, that the driver is resistance, and that the vehicle is a configured VBIED type — so a forged request for a non-VBIED vehicle or a non-resistance caller is a no-op.

The blast mirrors the AI wildcard W21 idiom: pop the vehicle with setDamage 1 (so the engine's Killed event handler still fires for kill credit) then stack three aerial bombs at its position for a large lethal crater. As of B74.1 (Ray 2026-06-23) the VBIED uses Bo_FAB_250 — the FAB-250 the EASA plane loadouts already carry, so it is loaded on both maps — rather than the older 122mm Sh_122_HE shell.

The payout pipeline — wallet/UID is the single live channel

Team-funds path: computed, logged, disabled

The original cash-for-kills credit to the driver's team is still computed per dead snapshot victim (_payout += round(price * WFBE_C_GUER_KILL_BOUNTY_COEF), Server/Functions/Server_HandleSpecial.sqf:1222-1226) — but the actual ChangeTeamFunds call was disabled by Ray on 2026-06-27 (Server/Functions/Server_HandleSpecial.sqf:1239-1242): the statement is a no-op false; with the old call preserved in a trailing //was: comment. Rationale (from the comment): the paid group _drvGrp was captured pre-suicide, so the credit never reached the respawned, base-less GUER detonator. Beware when reading the RPT: the adjacent INFORMATION log line still fires and claims a team payout that no longer happens (:1241).

Personal bounty + score: the live path

For each snapshot victim that is dead after the 4 s settle — Man units and crewed vehicles alike (Ray 2026-06-27: was Man-only; VBIEDing a convoy previously paid the wallet nothing) — the detonator accumulates (Server/Functions/Server_HandleSpecial.sqf:1227-1236):

  • _persBounty += round(price * 0.7 * WFBE_C_UNITS_BOUNTY_COEF) — the same formula as the AwardBounty.sqf personal-kill path (price is the unit's QUERYUNITPRICE config-price, index 2, Common/Init/Init_CommonConstants.sqf:8);
  • _persScore += ceil(_b / 100).

Every enemy base structure from the structure snapshot that is dead after settle adds the same per-type bounty a normal building kill grants (mirrors Server_BuildingKilled.sqf): Barracks 3000, Light Factory 4500, Heavy Factory 7000, Aircraft Factory 8000, UAV Terminal 5000, Vehicle Service Point 3000, AA Radar 8000, default 3000 (Server/Functions/Server_HandleSpecial.sqf:1248-1264), plus score _facBounty * WFBE_C_UNITS_BOUNTY_COEF / 100 * 3. Factory/Barracks kills also record a leaderboard WFBE_STAT_KILLS_FACTORY stat against the detonator UID (:1266-1268). Proximity capture is required here because the createVehicle FAB-250s carry no instigator — the structure's own killed EH fires with a null killer and would pay nothing (:1191-1196). That same null-instigator property is why the normal killed-event pipeline never double-pays the blast kills.

FOB tokens (B75, guer-tech): a VBIED-levelled enemy Barracks / Light Factory / Heavy Factory additionally grants GUER a FOB build token of that type — index 0/1/2 of the WFBE_GUER_FOB_AVAIL array ([barracks, light, heavy], seeded [0,0,0] at Common/Init/Init_CommonConstants.sqf:129), incremented and publicVariable'd at Server/Functions/Server_HandleSpecial.sqf:1274-1284. The other structure types pay bounty + score but no token. This is the only place a VBIED factory kill feeds FOB availability (the null-instigator blast never reaches Server_BuildingKilled's resistance gate — no double count).

Delivery: GuerVbiedBounty by UID + a score request

After the always-on GUERVBIED|v1 diag trace (Server/Functions/Server_HandleSpecial.sqf:1289):

Channel Mechanics Source
Cash [_drvUID, "GuerVbiedBounty", _persBounty] Call WFBE_CO_FNC_SendToClients — a UID-targeted client PVF, sent only if the UID was captured and the bounty is positive Server/Functions/Server_HandleSpecial.sqf:1290-1293
Score RequestChangeScore sets score _driver to score + _persScore (server-local WFBE_SE_FNC_HandlePVF spawn, or SendToServer on a hosted client) Server/Functions/Server_HandleSpecial.sqf:1294-1300

The client side of GuerVbiedBounty: registered in Common/Init/Init_Common.sqf:320-322 (compiled to CLTFNCGuerVbiedBounty, added to WFBE_CL_PVF_ALLOWED, wired to WFBE_CL_FNC_HandlePVF); the receiver Client/PVFunctions/GuerVbiedBounty.sqf exits on headless clients / null player / non-scalar / non-positive amounts, then credits (_bounty) Call ChangePlayerFunds (:20). Precision on the "wallet" naming: ChangePlayerFunds is [clientTeam, _amount] Call ChangeTeamFunds (Client/Functions/Client_ChangePlayerFunds.sqf:1), and clientTeam is group player on the receiving client — so mechanically the credit lands in the detonator's own group's wfbe_funds store. It is "personal" in the sense that the PVF is delivered to that one player's client by UID (not broadcast to the whole team), and it is applied to whatever group the detonator is in at receipt time — which is exactly what fixed the dead pre-suicide-group credit.

For contrast: the general GUER kill-bounty in Server/PVFunctions/RequestOnUnitKilled.sqf:131-152 (any resistance player kill of a west/east unit, with the WFBE_C_GUER_IED_KILL_COEF anti-farm override for IED kills) is a separate, still-live team-funds path — it pays _killer_group via WFBE_CO_FNC_ChangeTeamFunds and is unrelated to the VBIED case's disabled statement.

Configuration variables

All VBIED constants are isNil-guarded defaults in Init_CommonConstants.sqf, so MP mission parameters can override them without being clobbered.

Variable Default Role Source
WFBE_C_GUER_PLAYERSIDE 1 master gate — ON by default since B66 (0 = off) Common/Init/Init_CommonConstants.sqf:76
WFBE_C_GUER_VBIED_ARM_DELAY 3 orphaned — leftover of the removed arm-countdown design; zero references anywhere in the repo Common/Init/Init_CommonConstants.sqf:77
WFBE_C_GUER_VBIED_BLAST_RADIUS 60 server victim/structure-snapshot radius, in metres (B74.1: 30->60 for the FAB-250 blast; the in-case getVariable fallback literal is still 30 but the seeded constant governs) Common/Init/Init_CommonConstants.sqf:78
WFBE_C_GUER_VBIED_TYPE "hilux1_civil_2_covered" primary suicide-truck classname (runtime-repointed to "datsun1_civil_2_covered" on Takistan) Common/Init/Init_CommonConstants.sqf:79, Common/Config/Core_Root/Root_GUE_PlayerOverlay.sqf:86-93
WFBE_C_GUER_KILL_BOUNTY_COEF 0.5 coefficient of the (now-disabled) team-funds computation; still live in the general RequestOnUnitKilled GUER bounty Common/Init/Init_CommonConstants.sqf:80
WFBE_C_GUER_IED_KILL_COEF 0.30 reduced fraction for IED-tagged kills (anti-farm; RequestOnUnitKilled path) Common/Init/Init_CommonConstants.sqf:81
WFBE_C_GUER_VBIED_M113_TYPE "M113_UN_EP1" second, kill-gated VBIED chassis the server guard also accepts (B75) Common/Init/Init_CommonConstants.sqf:113
WFBE_C_GUER_VBIED_M113_KILLS 50 GUER player kills needed before the M113 VBIED appears in the depot (2x-ed; was 25) Common/Init/Init_CommonConstants.sqf:114
WFBE_C_GUER_VBIED_M113_SPEEDCOEF 2.0 target top-speed multiplier of the driver-local M113 boost loop Common/Init/Init_CommonConstants.sqf:115
WFBE_GUER_FOB_AVAIL [0,0,0] state var (not a tunable): available GUER FOB tokens [barracks, light, heavy] Common/Init/Init_CommonConstants.sqf:129

A2-OA coding notes

The handler's header (Action_GuerVbiedDetonate.sqf) records the A2 OA-safe constraints it follows: array-form private [...] only (no inline typed private _x =), _arr + [x] rather than pushBack, no params / select-with-code / isEqualType, titleText instead of A3 hint structures, and lazy && {} short-circuit. The server case follows the same rules — note the capitalized Private [...] declarations (Server_HandleSpecial.sqf:1156,1161), the _victims = _victims + [_x] accumulation (Server_HandleSpecial.sqf:1185-1187), and nearestObjects rather than any A3-only collection call (Server_HandleSpecial.sqf:1190). The M113 boost loop's comment likewise documents why it nudges setVelocity instead of the (A3-only) setMaxSpeed (Client_BuildUnit.sqf:522-524).

Continue Reading

Sidebar

Clone this wiki locally