ACE3/addons/cookoff/functions/fnc_cookOff.sqf
Glowbal 059980b1a5 Add ammo cookoff (#4376)
* Add Ammo cookoff

* Remove tabs

* Add initial ammo box cook-off

Does not include a fire effect, mostly just a proof of concept.

Should probably also add further potential cook-off conditons (if hit by tracer for example).

* Add burning effects to ammo box cook off

- Add burning effect while ammo box is cooking off
- Add setting to enable/disable ammo boxes cooking off
- Clear magazine cargo while box is burning

Currently the box will burn for 60 seconds hardcoded, this is to allow time for the ammunition to cook off (since boxes sink into the ground and dissapear when destroyed). Perhaps we can implement a way to burn until all ammo is expended.

* Improve ammo cookoff

* Integrate ammo cookoff with the incendiary grenade

* Disable ammo cook off underwater

* Optimize fnc_detonateAmmunition

I say optimize, the only real performance optimization is using `vectorMultiply`. The rest is readability optimization though!

* Improve ammo box cook off

- Remove unnecessary light source (fire particles provide lighting)
- Add randomness to cook off time
- Cook off begins with fire effect rather than smoke

* Add tracer induced ammo box cook off

Due to limitations in the way arma handles tracer rounds (there's no way to check if an individual projectile is a tracer), only magazines with a high enough tracer density (at least 1 in 4) can cause cook off this way. However this is deemed an acceptable approximation since the chance of this happening should be quite low anyway.

* Decrease amount of explosions from ammo cookoff

* Add is local check for remote event
2016-10-06 22:37:38 +02:00

135 lines
3.9 KiB
Plaintext

/*
* Author: KoffeinFlummi, commy2
* Start a cook-off in the given vehicle.
*
* Arguments:
* 0: Vehicle <Object>
*
* Return Value:
* None
*
* Example:
* (vehicle player) call ace_cookoff_fnc_cookOff
*
* Public: No
*/
#include "script_component.hpp"
params ["_vehicle"];
if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {};
_vehicle setVariable [QGVAR(isCookingOff), true];
if (local _vehicle) then {
[QGVAR(cookOff), _vehicle] call CBA_fnc_remoteEvent;
};
[{
params ["_vehicle"];
private _config = _vehicle call CBA_fnc_getObjectConfig;
private _positions = getArray (_config >> QGVAR(cookoffSelections)) select {!((_vehicle selectionPosition _x) isEqualTo [0,0,0])};
if (_positions isEqualTo []) then {
WARNING_1("no valid selection for cookoff found. %1", typeOf _vehicle);
_positions pushBack "#noselection";
};
private _turretConfig = [_vehicle, [0]] call CBA_fnc_getTurret;
private _positionBarrelEnd = getText (_turretConfig >> "gunBeg");
// smoke out of cannon and hatches
private _smokeBarrel = "#particlesource" createVehicleLocal [0,0,0];
_smokeBarrel setParticleClass "MediumDestructionSmoke";
_smokeBarrel attachTo [_vehicle, [0,0,0], _positionBarrelEnd];
private _effects = [_smokeBarrel];
{
private _position = [0,-2,0];
if !(_x isEqualTo "#noselection") then {
_position = _vehicle selectionPosition _x;
};
private _smoke = "#particlesource" createVehicleLocal [0,0,0];
_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx";
_smoke attachTo [_vehicle, _position];
_effects pushBack _smoke;
} forEach _positions;
[{
params ["_vehicle", "_effects", "_positions"];
// this shit is busy being on fire, can't go driving around all over the place
if (local _vehicle) then {
_vehicle setFuel 0;
};
private _light = "#lightpoint" createVehicleLocal [0,0,0];
_light setLightBrightness 0.7;
_light setLightAmbient [1,0.4,0.15];
_light setLightColor [1,0.4,0.15];
_light lightAttachObject [_vehicle, [0,0,4]];
_effects pushBack _light;
// cookoffs
{
private _position = [0,-2,0];
if !(_x isEqualTo "#noselection") then {
_position = _vehicle selectionPosition _x;
};
private _fire = "#particlesource" createVehicleLocal [0,0,0];
_fire setParticleClass QGVAR(CookOff);
_fire attachTo [_vehicle, _position];
_effects pushBack _fire;
} forEach _positions;
if (isServer) then {
private _sound = createSoundSource [QGVAR(Sound), position _vehicle, [], 0];
_effects pushBack _sound;
};
// indicator for the crew - yo, your shit's on fire
private _fnc_FlameEffect = {
params ["_vehicle", "_fnc_FlameEffect", "_counter"];
if (_vehicle == cameraOn) then {
[] call BIS_fnc_flamesEffect;
};
DEC(_counter);
if (_counter > 0) then {
[_fnc_FlameEffect, [_vehicle, _fnc_FlameEffect, _counter], 0.4] call CBA_fnc_waitAndExecute
};
};
[_vehicle, _fnc_FlameEffect, 12] call _fnc_FlameEffect; // recursive function
{
if (local _x && {!(_x call EFUNC(common,isPlayer))}) then {
_x action ["Eject", _vehicle];
};
} forEach crew _vehicle;
[{
params ["_vehicle", "_effects"];
{
deleteVehicle _x;
} forEach _effects;
if (local _vehicle) then {
_vehicle setDamage 1;
};
}, [_vehicle, _effects], 4 + random 20] call CBA_fnc_waitAndExecute;
}, [_vehicle, _effects, _positions], 3 + random 15] call CBA_fnc_waitAndExecute;
}, _vehicle, 0.5 + random 5] call CBA_fnc_waitAndExecute;