mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
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
This commit is contained in:
parent
dfa09d3161
commit
059980b1a5
@ -6,4 +6,16 @@ class ACE_Settings {
|
|||||||
value = 1;
|
value = 1;
|
||||||
typeName = "BOOL";
|
typeName = "BOOL";
|
||||||
};
|
};
|
||||||
|
class GVAR(enableAmmobox) {
|
||||||
|
displayName = CSTRING(enableBoxCookoff_name);
|
||||||
|
description = CSTRING(enableBoxCookoff_tooltip);
|
||||||
|
value = 1;
|
||||||
|
typeName = "BOOL";
|
||||||
|
};
|
||||||
|
class GVAR(enableAmmoCookoff) {
|
||||||
|
displayName = CSTRING(enableAmmoCookoff_name);
|
||||||
|
description = CSTRING(enableAmmoCookoff_tooltip);
|
||||||
|
value = 1;
|
||||||
|
typeName = "BOOL";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
33
addons/cookoff/CfgAmmo.hpp
Normal file
33
addons/cookoff/CfgAmmo.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
class CfgAmmo {
|
||||||
|
class ShellBase;
|
||||||
|
class ace_ammoExplosion: ShellBase {
|
||||||
|
hit = 10;
|
||||||
|
indirectHit = 0.5;
|
||||||
|
indirectHitRange = 1;
|
||||||
|
soundHit[] = {"", 1, 1, 0};
|
||||||
|
typicalSpeed = 100;
|
||||||
|
explosive = 0;
|
||||||
|
cost = 300;
|
||||||
|
model = "\A3\Weapons_F\empty.p3d";
|
||||||
|
airFriction = 0;
|
||||||
|
timeToLive = 1;
|
||||||
|
explosionTime = 0.001;
|
||||||
|
soundFly[] = {"",1,1};
|
||||||
|
soundEngine[] = {"",1,4};
|
||||||
|
explosionEffects = "ExploAmmoExplosion";
|
||||||
|
};
|
||||||
|
|
||||||
|
class SmallSecondary;
|
||||||
|
class ACE_ammoExplosionLarge: SmallSecondary {
|
||||||
|
soundHit[] = {"", 1, 1, 0};
|
||||||
|
model = "\A3\Weapons_F\empty.p3d";
|
||||||
|
soundFly[] = {"",1,1};
|
||||||
|
soundEngine[] = {"",1,4};
|
||||||
|
soundHit1[] = {"",1,1,1};
|
||||||
|
soundHit2[] = {"",1,1,1};
|
||||||
|
soundHit3[] = {"",1,1,1};
|
||||||
|
supersonicCrackFar[] = {"",1,1,1};
|
||||||
|
supersonicCrackNear[] = {"",1,1,1};
|
||||||
|
craterEffects = "ImpactEffectsMedium";
|
||||||
|
};
|
||||||
|
};
|
@ -52,3 +52,30 @@ class CfgCloudlets {
|
|||||||
destroyOnWaterSurfaceOffset = 0;
|
destroyOnWaterSurfaceOffset = 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GVAR(ExploAmmoExplosion) {
|
||||||
|
class ExploAmmoFlash {
|
||||||
|
position[] = {0,0,0};
|
||||||
|
simulation = "particles";
|
||||||
|
type = "ExploAmmoFlash";
|
||||||
|
intensity = 1;
|
||||||
|
interval = 1;
|
||||||
|
lifeTime = 1;
|
||||||
|
};
|
||||||
|
class LightExplosion {
|
||||||
|
simulation = "light";
|
||||||
|
type = "SparksLight";
|
||||||
|
position[] = {0,0,0};
|
||||||
|
intensity = 1;
|
||||||
|
interval = 1;
|
||||||
|
lifeTime = 0.15;
|
||||||
|
};
|
||||||
|
class ExploAmmoSmoke {
|
||||||
|
position[] = {0,0,0};
|
||||||
|
simulation = "particles";
|
||||||
|
type = "AutoCannonFired";
|
||||||
|
intensity = 1.5;
|
||||||
|
interval = 1.5;
|
||||||
|
lifeTime = 1.5;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -2,5 +2,7 @@
|
|||||||
PREP(handleDamage);
|
PREP(handleDamage);
|
||||||
PREP(engineFire);
|
PREP(engineFire);
|
||||||
PREP(cookOff);
|
PREP(cookOff);
|
||||||
|
PREP(cookOffBox);
|
||||||
PREP(blowOffTurret);
|
PREP(blowOffTurret);
|
||||||
PREP(secondaryExplosions);
|
PREP(secondaryExplosions);
|
||||||
|
PREP(detonateAmmunition);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
[QGVAR(engineFire), FUNC(engineFire)] call CBA_fnc_addEventHandler;
|
[QGVAR(engineFire), FUNC(engineFire)] call CBA_fnc_addEventHandler;
|
||||||
[QGVAR(cookOff), FUNC(cookOff)] call CBA_fnc_addEventHandler;
|
[QGVAR(cookOff), FUNC(cookOff)] call CBA_fnc_addEventHandler;
|
||||||
|
[QGVAR(cookOffBox), FUNC(cookOffBox)] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
GVAR(cacheTankDuplicates) = call CBA_fnc_createNamespace;
|
GVAR(cacheTankDuplicates) = call CBA_fnc_createNamespace;
|
||||||
|
|
||||||
@ -52,21 +53,31 @@ GVAR(cacheTankDuplicates) = call CBA_fnc_createNamespace;
|
|||||||
}];
|
}];
|
||||||
}, nil, ["Wheeled_APC_F"], true] call CBA_fnc_addClassEventHandler;
|
}, nil, ["Wheeled_APC_F"], true] call CBA_fnc_addClassEventHandler;
|
||||||
|
|
||||||
|
["ReammoBox_F", "init", {
|
||||||
|
(_this select 0) addEventHandler ["HandleDamage", {
|
||||||
|
if (GVAR(enableAmmobox)) then {
|
||||||
|
["box", _this] call FUNC(handleDamage);
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
}, nil, nil, true] call CBA_fnc_addClassEventHandler;
|
||||||
|
|
||||||
// secondary explosions
|
// secondary explosions
|
||||||
["AllVehicles", "killed", {
|
["AllVehicles", "killed", {
|
||||||
params ["_vehicle"];
|
params ["_vehicle"];
|
||||||
|
if (_vehicle getVariable [QGVAR(enable),GVAR(enable)]) then {
|
||||||
if (_vehicle getVariable [QGVAR(enable), GVAR(enable)]) then {
|
|
||||||
_vehicle call FUNC(secondaryExplosions);
|
_vehicle call FUNC(secondaryExplosions);
|
||||||
|
if (_vehicle getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)]) then {
|
||||||
|
[_vehicle, magazinesAmmo _vehicle] call FUNC(detonateAmmunition);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}, nil, ["Man"]] call CBA_fnc_addClassEventHandler;
|
}, nil, ["Man","StaticWeapon"]] call CBA_fnc_addClassEventHandler;
|
||||||
|
|
||||||
// blow off turret effect
|
// blow off turret effect
|
||||||
["Tank", "killed", {
|
["Tank", "killed", {
|
||||||
params ["_vehicle"];
|
if ((_this select 0) getVariable [QGVAR(enable),GVAR(enable)]) then {
|
||||||
|
if (random 1 < 0.15) then {
|
||||||
if (_vehicle getVariable [QGVAR(enable), GVAR(enable)]) then {
|
(_this select 0) call FUNC(blowOffTurret);
|
||||||
_vehicle call FUNC(blowOffTurret);
|
};
|
||||||
};
|
};
|
||||||
}] call CBA_fnc_addClassEventHandler;
|
}] call CBA_fnc_addClassEventHandler;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ class CfgPatches {
|
|||||||
requiredVersion = REQUIRED_VERSION;
|
requiredVersion = REQUIRED_VERSION;
|
||||||
requiredAddons[] = {"ace_common"};
|
requiredAddons[] = {"ace_common"};
|
||||||
author = ECSTRING(common,ACETeam);
|
author = ECSTRING(common,ACETeam);
|
||||||
authors[] = {"commy2"};
|
authors[] = {"commy2", "Glowbal"};
|
||||||
url = ECSTRING(main,URL);
|
url = ECSTRING(main,URL);
|
||||||
VERSION_CONFIG;
|
VERSION_CONFIG;
|
||||||
};
|
};
|
||||||
@ -18,6 +18,7 @@ class CfgPatches {
|
|||||||
#include "CfgEden.hpp"
|
#include "CfgEden.hpp"
|
||||||
#include "CfgEventHandlers.hpp"
|
#include "CfgEventHandlers.hpp"
|
||||||
|
|
||||||
|
#include "CfgAmmo.hpp"
|
||||||
#include "CfgCloudlets.hpp"
|
#include "CfgCloudlets.hpp"
|
||||||
#include "CfgSFX.hpp"
|
#include "CfgSFX.hpp"
|
||||||
#include "CfgVehicles.hpp"
|
#include "CfgVehicles.hpp"
|
||||||
|
@ -129,6 +129,6 @@ if (local _vehicle) then {
|
|||||||
if (local _vehicle) then {
|
if (local _vehicle) then {
|
||||||
_vehicle setDamage 1;
|
_vehicle setDamage 1;
|
||||||
};
|
};
|
||||||
}, [_vehicle, _effects], 4 + random 1] call CBA_fnc_waitAndExecute;
|
}, [_vehicle, _effects], 4 + random 20] call CBA_fnc_waitAndExecute;
|
||||||
}, [_vehicle, _effects, _positions], 3 + random 2] call CBA_fnc_waitAndExecute;
|
}, [_vehicle, _effects, _positions], 3 + random 15] call CBA_fnc_waitAndExecute;
|
||||||
}, _vehicle, 0.5 + random 0.3] call CBA_fnc_waitAndExecute;
|
}, _vehicle, 0.5 + random 5] call CBA_fnc_waitAndExecute;
|
||||||
|
75
addons/cookoff/functions/fnc_cookOffBox.sqf
Normal file
75
addons/cookoff/functions/fnc_cookOffBox.sqf
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Author: KoffeinFlummi, commy2, SilentSpike
|
||||||
|
* Start a cook-off in the given ammo box.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Ammo box <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [_box] call ace_cookoff_fnc_cookOffBox
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
params ["_box"];
|
||||||
|
|
||||||
|
if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {};
|
||||||
|
_box setVariable [QGVAR(isCookingOff), true];
|
||||||
|
|
||||||
|
if (local _vehicle) then {
|
||||||
|
[QGVAR(cookOffBox), _box] call CBA_fnc_remoteEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
[{
|
||||||
|
params ["_box"];
|
||||||
|
|
||||||
|
// Box will start smoking
|
||||||
|
private _smoke = "#particlesource" createVehicleLocal [0,0,0];
|
||||||
|
_smoke setParticleClass "AmmoSmokeParticles2";
|
||||||
|
_smoke attachTo [_box, [0,0,0]];
|
||||||
|
|
||||||
|
private _effects = [_smoke];
|
||||||
|
|
||||||
|
if (isServer) then {
|
||||||
|
private _sound = createSoundSource ["Sound_Fire", position _box, [], 0];
|
||||||
|
_effects pushBack _sound;
|
||||||
|
};
|
||||||
|
|
||||||
|
[{
|
||||||
|
params ["_box", "_effects"];
|
||||||
|
|
||||||
|
// These functions are smart and do all the cooking off work
|
||||||
|
if (local _box) then {
|
||||||
|
_box call FUNC(secondaryExplosions);
|
||||||
|
if (_box getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)]) then {
|
||||||
|
[_box, magazinesAmmo _box] call FUNC(detonateAmmunition);
|
||||||
|
};
|
||||||
|
|
||||||
|
// This shit is busy being on fire, magazines aren't accessible/usable
|
||||||
|
clearMagazineCargoGlobal _box;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Light the fire (also handles lighting)
|
||||||
|
private _fire = "#particlesource" createVehicleLocal [0,0,0];
|
||||||
|
_fire setParticleClass "AmmoBulletCore";
|
||||||
|
_fire attachTo [_box, [0,0,0]];
|
||||||
|
|
||||||
|
_effects pushBack _fire;
|
||||||
|
|
||||||
|
[{
|
||||||
|
params ["_box", "_effects"];
|
||||||
|
|
||||||
|
{
|
||||||
|
deleteVehicle _x;
|
||||||
|
} forEach _effects;
|
||||||
|
|
||||||
|
if (local _box) then {
|
||||||
|
_box setDamage 1;
|
||||||
|
};
|
||||||
|
}, [_box, _effects], 45 + random 75] call CBA_fnc_waitAndExecute; // Give signifcant time for ammo cookoff to occur (perhaps keep the box alive until all cooked off?)
|
||||||
|
}, [_box, _effects], 3 + random 15] call CBA_fnc_waitAndExecute;
|
||||||
|
}, _box, 0.5 + random 5] call CBA_fnc_waitAndExecute;
|
112
addons/cookoff/functions/fnc_detonateAmmunition.sqf
Normal file
112
addons/cookoff/functions/fnc_detonateAmmunition.sqf
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Author: Glowbal
|
||||||
|
* Detonates ammunition from a vehicle until no ammo left
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: vehicle <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [_vehicle, magazinesAmmo _vehicle] call ace_cookoff_fnc_detonateAmmunition
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
#define MAX_TIME_BETWEEN_AMMO_DET 25
|
||||||
|
|
||||||
|
params ["_vehicle", "_magazines"];
|
||||||
|
|
||||||
|
if (isNull _vehicle) exitWith {}; // vehicle got deleted
|
||||||
|
if (_magazines isEqualTo []) exitWith {}; // nothing to detonate anymore
|
||||||
|
if (underwater _vehicle) exitWith {};
|
||||||
|
|
||||||
|
private _magazineIndex = floor random(count _magazines);
|
||||||
|
private _magazine = _magazines select _magazineIndex;
|
||||||
|
_magazine params ["_magazineClassname", "_amountOfMagazines"];
|
||||||
|
|
||||||
|
if (_amountOfMagazines > 0) exitWith {
|
||||||
|
private _newMagCount = _amountOfMagazines - floor(1 + random(6));
|
||||||
|
if (_newMagCount <= 0) then {
|
||||||
|
_magazines deleteAt _magazineIndex;
|
||||||
|
} else {
|
||||||
|
_magazine set [1, _newMagCount]; // clear out the magazine
|
||||||
|
};
|
||||||
|
private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClassname >> "ammo");
|
||||||
|
|
||||||
|
private _timeBetweenAmmoDetonation = (random 7) * (1 / random (_amountOfMagazines)) min MAX_TIME_BETWEEN_AMMO_DET;
|
||||||
|
_timeBetweenAmmoDetonation = _timeBetweenAmmoDetonation max 0.1;
|
||||||
|
|
||||||
|
private _speedOfAmmo = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "initSpeed");
|
||||||
|
private _simulationTime = getNumber (configFile >> "CfgAmmo" >> _ammo >> "simulation");
|
||||||
|
private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber");
|
||||||
|
private _simType = getText (configFile >> "CfgAmmo" >> _ammo >> "simulation");
|
||||||
|
|
||||||
|
private _effect2pos = _vehicle selectionPosition "destructionEffect2";
|
||||||
|
|
||||||
|
private _spawnProjectile = {
|
||||||
|
params ["_vehicle", "_ammo", "_speed", "_flyAway"];
|
||||||
|
|
||||||
|
private _spawnPos = _vehicle modelToWorld [-0.2 + (random 0.4), -0.2 + (random 0.4), random 3];
|
||||||
|
if (_spawnPos select 2 < 0) then {
|
||||||
|
_spawnPos set [2, 0];
|
||||||
|
};
|
||||||
|
private _projectile = _ammo createVehicle [0,0,0];
|
||||||
|
_projectile setPos _spawnPos;
|
||||||
|
if (_flyAway) then {
|
||||||
|
private _vectorAmmo = [(-1 + (random 2)), (-1 + (random 2)), -0.2 + (random 1)];
|
||||||
|
private _velVec = _vectorAmmo vectorMultiply _speed;
|
||||||
|
_projectile setVectorDir _velVec;
|
||||||
|
_projectile setVelocity _velVec;
|
||||||
|
[ACE_player, _projectile, [1,0,0,1]] call EFUNC(frag,addTrack);
|
||||||
|
} else {
|
||||||
|
_projectile setDamage 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
_projectile;
|
||||||
|
};
|
||||||
|
|
||||||
|
private _speed = random (_speedOfAmmo / 10) max 1;
|
||||||
|
|
||||||
|
if (toLower _simType == "shotbullet") then {
|
||||||
|
private _sound = selectRandom [QUOTE(PATHTO_R(sounds\light_crack_close.wss)), QUOTE(PATHTO_R(sounds\light_crack_close_filtered.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close_filtered.wss))];
|
||||||
|
playSound3D [_sound, objNull, false, (getPosASL _vehicle), 2, 1, 1250];
|
||||||
|
|
||||||
|
if (random 1 < 0.6) then {
|
||||||
|
[_vehicle, _ammo, _speed, true] call _spawnProjectile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (toLower _simType == "shotshell") then {
|
||||||
|
private _sound = selectRandom [QUOTE(PATHTO_R(sounds\heavy_crack_close.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close_filtered.wss))];
|
||||||
|
playSound3D [_sound, objNull, false, (getPosASL _vehicle), 2, 1, 1300];
|
||||||
|
|
||||||
|
if (random 1 < 0.15) then {
|
||||||
|
[_vehicle, _ammo, _speed, random 1 < 0.15] call _spawnProjectile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (toLower _simType == "shotgrenade") then {
|
||||||
|
if (random 1 < 0.9) then {
|
||||||
|
_speed = 0;
|
||||||
|
};
|
||||||
|
[_vehicle, _ammo, _speed, random 1 < 0.5] call _spawnProjectile;
|
||||||
|
};
|
||||||
|
if (toLower _simType == "shotrocket" || {toLower _simType == "shotmissile"}) then {
|
||||||
|
if (random 1 < 0.1) then {
|
||||||
|
private _sound = selectRandom [QUOTE(PATHTO_R(sounds\cannon_crack_close.wss)), QUOTE(PATHTO_R(sounds\cannon_crack_close_filtered.wss))];
|
||||||
|
playSound3D [_sound, objNull, false, (getPosASL _vehicle), 3, 1, 1600];
|
||||||
|
|
||||||
|
[_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile;
|
||||||
|
} else {
|
||||||
|
"ACE_ammoExplosionLarge" createvehicle (_vehicle modelToWorld _effect2pos);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (toLower _simType in ["shotdirectionalbomb", "shotilluminating", "shotmine"]) then {
|
||||||
|
if (random 1 < 0.5) then {
|
||||||
|
[_vehicle, _ammo, 0, false] call _spawnProjectile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
[FUNC(detonateAmmunition), [_vehicle, _magazines], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute;
|
||||||
|
};
|
||||||
|
[FUNC(detonateAmmunition), [_vehicle, _magazines], random 3] call CBA_fnc_waitAndExecute;
|
@ -16,7 +16,7 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
params ["_simulationType", "_thisHandleDamage"];
|
params ["_simulationType", "_thisHandleDamage"];
|
||||||
_thisHandleDamage params ["_vehicle", "", "_damage", "", "_ammo", "_hitIndex"];
|
_thisHandleDamage params ["_vehicle", "", "_damage", "_source", "_ammo", "_hitIndex", "_shooter"];
|
||||||
|
|
||||||
// it's already dead, who cares?
|
// it's already dead, who cares?
|
||||||
if (damage _vehicle >= 1) exitWith {};
|
if (damage _vehicle >= 1) exitWith {};
|
||||||
@ -58,12 +58,12 @@ if (_simulationType == "car") exitWith {
|
|||||||
|
|
||||||
if (_simulationType == "tank") exitWith {
|
if (_simulationType == "tank") exitWith {
|
||||||
// determine ammo storage location
|
// determine ammo storage location
|
||||||
private _ammoLocationHitpoint = getText (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(ammoLocation));
|
private _ammoLocationHitpoint = getText (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(ammoLocation));
|
||||||
|
|
||||||
if (_hitIndex in (GVAR(cacheTankDuplicates) getVariable (typeOf _vehicle))) then {
|
if (_hitIndex in (GVAR(cacheTankDuplicates) getVariable (typeOf _vehicle))) then {
|
||||||
_hitpoint = "#subturret";
|
_hitpoint = "#subturret";
|
||||||
};
|
};
|
||||||
|
|
||||||
// ammo was hit, high chance for cook-off
|
// ammo was hit, high chance for cook-off
|
||||||
if (_hitpoint == _ammoLocationHitpoint) then {
|
if (_hitpoint == _ammoLocationHitpoint) then {
|
||||||
if (_damage > 0.5 && {random 1 < 0.7}) then {
|
if (_damage > 0.5 && {random 1 < 0.7}) then {
|
||||||
@ -82,3 +82,37 @@ if (_simulationType == "tank") exitWith {
|
|||||||
_damage
|
_damage
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (_simulationType == "box") exitWith {
|
||||||
|
if (_hitpoint == "#structural" && _damage > 0.5) then {
|
||||||
|
// Almost always catch fire when hit by an explosive
|
||||||
|
if (IS_EXPLOSIVE_AMMO(_ammo)) then {
|
||||||
|
_vehicle call FUNC(cookOffBox);
|
||||||
|
} else {
|
||||||
|
// Need magazine to check for tracers
|
||||||
|
private _mag = "";
|
||||||
|
if (_source == _shooter) then {
|
||||||
|
_mag = currentMagazine _source;
|
||||||
|
} else {
|
||||||
|
_mag = _source currentMagazineTurret ([_shooter] call CBA_fnc_turretPath);
|
||||||
|
};
|
||||||
|
private _magCfg = configFile >> "CfgMagazines" >> _mag;
|
||||||
|
|
||||||
|
// Magazine could have changed during flight time (just ignore if so)
|
||||||
|
if (getText (_magCfg >> "ammo") == _ammo) then {
|
||||||
|
// If magazine's tracer density is high enough then low chance for cook off
|
||||||
|
private _tracers = getNumber (_magCfg >> "tracersEvery");
|
||||||
|
if (_tracers >= 1 && {_tracers <= 4}) then {
|
||||||
|
if (random 1 < _oldDamage*0.05) then {
|
||||||
|
_vehicle call FUNC(cookOffBox);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// prevent destruction, let cook-off handle it if necessary
|
||||||
|
_damage min 0.89
|
||||||
|
} else {
|
||||||
|
_damage
|
||||||
|
};
|
||||||
|
};
|
||||||
|
BIN
addons/cookoff/sounds/cannon_crack_close.wss
Normal file
BIN
addons/cookoff/sounds/cannon_crack_close.wss
Normal file
Binary file not shown.
BIN
addons/cookoff/sounds/cannon_crack_close_filtered.wss
Normal file
BIN
addons/cookoff/sounds/cannon_crack_close_filtered.wss
Normal file
Binary file not shown.
BIN
addons/cookoff/sounds/heavy_crack_close.wss
Normal file
BIN
addons/cookoff/sounds/heavy_crack_close.wss
Normal file
Binary file not shown.
BIN
addons/cookoff/sounds/heavy_crack_close_filtered.wss
Normal file
BIN
addons/cookoff/sounds/heavy_crack_close_filtered.wss
Normal file
Binary file not shown.
BIN
addons/cookoff/sounds/light_crack_close.wss
Normal file
BIN
addons/cookoff/sounds/light_crack_close.wss
Normal file
Binary file not shown.
BIN
addons/cookoff/sounds/light_crack_close_filtered.wss
Normal file
BIN
addons/cookoff/sounds/light_crack_close_filtered.wss
Normal file
Binary file not shown.
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project name="ACE">
|
<Project name="ACE">
|
||||||
<Package name="CookOff">
|
<Package name="CookOff">
|
||||||
<Key ID="STR_ACE_CookOff_enable_name">
|
<Key ID="STR_ACE_CookOff_enable_name">
|
||||||
@ -31,5 +31,17 @@
|
|||||||
<Korean>잔해(포탑)</Korean>
|
<Korean>잔해(포탑)</Korean>
|
||||||
<Japanese>残骸(タレット)</Japanese>
|
<Japanese>残骸(タレット)</Japanese>
|
||||||
</Key>
|
</Key>
|
||||||
|
<Key ID="STR_ACE_CookOff_enable_name">
|
||||||
|
<English>Enable ammo box cook off</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_CookOff_enable_tooltip">
|
||||||
|
<English>Enables cooking off of ammo boxes.</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_CookOff_enableAmmoCookoff_name">
|
||||||
|
<English>Enable Ammunition cook off</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_CookOff_enableAmmoCookoff_tooltip">
|
||||||
|
<English>Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition.</English>
|
||||||
|
</Key>
|
||||||
</Package>
|
</Package>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -146,9 +146,16 @@ if (isServer) then {
|
|||||||
//systemChat format ["burn: %1", _x];
|
//systemChat format ["burn: %1", _x];
|
||||||
|
|
||||||
// --- destroy nearby static weapons and ammo boxes
|
// --- destroy nearby static weapons and ammo boxes
|
||||||
if (_x isKindOf "StaticWeapon" || {_x isKindOf "ReammoBox_F"} || {_x isKindOf "ACE_RepairItem_Base"}) then {
|
if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then {
|
||||||
_x setDamage 1;
|
_x setDamage 1;
|
||||||
};
|
};
|
||||||
|
if (_x isKindOf "ReammoBox_F") then {
|
||||||
|
if ("ace_cookoff" call EFUNC(common,isModLoaded) && {EGVAR(cookoff,enable)}) then {
|
||||||
|
_x call EFUNC(cookoff,cookOffBox);
|
||||||
|
} else {
|
||||||
|
_x setDamage 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// --- delete nearby ground weapon holders
|
// --- delete nearby ground weapon holders
|
||||||
if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then {
|
if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then {
|
||||||
|
Loading…
Reference in New Issue
Block a user