From 16b2ee66b7a6060ab13dd50084a6c09d9bbadf59 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 5 Jun 2024 21:59:16 +0200 Subject: [PATCH] Merge conflict caused issues --- .../fnc_detonateAmmunitionServer.sqf | 223 ++---------------- 1 file changed, 21 insertions(+), 202 deletions(-) diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf index e2fe44ce86..9f9fecaab2 100644 --- a/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf @@ -1,230 +1,49 @@ #include "..\script_component.hpp" /* - * Author: Glowbal, johnb43 - * Detonates ammunition from an object (e.g. vehicle or crate) until no ammo is left. + * Author: johnb43 + * Starts detonating ammunition from an object (e.g. vehicle or crate). * * Arguments: * 0: Object - * 1: Destroy when finished - * 2: Source - * 3: Instigator + * 1: Destroy when finished (default: false) + * 2: Source (default: objNull) + * 3: Instigator (default: objNull) + * 4: Initial delay (default: 0) * * Return Value: * None * * Example: - * [cursorObject, true, player, player] call ace_cookoff_fnc_detonateAmmunitionServer + * [cursorObject] call ace_cookoff_fnc_detonateAmmunitionServer * * Public: No */ if (!isServer) exitWith {}; -params ["_object", "_destroyWhenFinished", "_source", "_instigator"]; +params ["_object", ["_destroyWhenFinished", false], ["_source", objNull], ["_instigator", objNull], ["_initialDelay", 0]]; if (isNull _object) exitWith {}; -// If the variable is set, it won't remove magazines -private _objectAmmo = _object getVariable QGVAR(cookoffMagazines); -private _removeAmmoDuringCookoff = isNil "_objectAmmo"; - -if (_removeAmmoDuringCookoff) then { - _objectAmmo = _object call FUNC(getVehicleAmmo) -}; - -_objectAmmo params ["_magazines", "_totalAmmo"]; - -private _hasFinished = _totalAmmo <= 0 || {_magazines isEqualTo []}; - -// If the cook-off has finished or been interrupted, clean up the effects for boxes (no vehicle effects) +// Check if the object can cook its ammo off if ( - _hasFinished || - {underwater _object} || - {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // underwater is not very reliable, so use model center instead + underwater _object || + {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead {GVAR(ammoCookoffDuration) == 0} || {!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} || {!(_object getVariable [QGVAR(enableAmmoCookoff), true])} -) exitWith { - // Box cook-off fire ends after the ammo has detonated (vehicle cook-off fire does not depend on the ammo detonation) - if (_object isKindOf "ReammoBox_F") then { - [QGVAR(cleanupEffects), _object] call CBA_fnc_globalEvent; +) exitWith {}; - // Reset variable, so the box can cook-off again - _object setVariable [QGVAR(isCookingOff), nil, true]; - }; +// Don't have an object detonate its ammo twice +if (_object getVariable [QGVAR(isAmmoDetonating), false]) exitWith {}; - // Reset variables, so the object can detonate its ammo again - _object setVariable [QGVAR(cookoffMagazines), nil]; - _object setVariable [QGVAR(virtualMagazines), nil]; - _object setVariable [QGVAR(isAmmoDetonating), nil, true]; +_object setVariable [QGVAR(isAmmoDetonating), true, true]; - // If done, destroy the object if necessary - if (_hasFinished && _destroyWhenFinished) then { - _object setDamage [1, true, _source, _instigator]; - }; +_object setVariable [QGVAR(cookoffMagazines), _object call FUNC(getVehicleAmmo)]; + +// Save the vehicle's ammo, so it won't be removed during cook-off +if (!GVAR(removeAmmoDuringCookoff)) then { + _object setVariable [QGVAR(cookoffMagazines), _object call FUNC(getVehicleAmmo)]; }; -private _magazineIndex = floor random (count _magazines); -private _magazine = _magazines select _magazineIndex; -_magazine params ["_magazineClassname", "_ammoCount", "_spawnProjectile", "_magazineInfo"]; - -// To use setMagazineTurretAmmo properly, we need to get the ammo with magazineTurretAmmo -if (_removeAmmoDuringCookoff && {_magazineInfo isEqualType []}) then { - _ammoCount = _object magazineTurretAmmo [_magazineClassname, _magazineInfo]; -}; - -// Make sure ammo is at least 0 -_ammoCount = _ammoCount max 0; - -// Remove some ammo, which will be detonated -private _removed = _ammoCount min floor (1 + random (6 / GVAR(ammoCookoffDuration))); -private _newAmmoCount = _ammoCount - _removed; - -// Remove ammo from magazines if enabled -if (_removeAmmoDuringCookoff) then { - switch (true) do { - // Turret magazines - case (_magazineInfo isEqualType []): { - // Remove loaded magazine - if (_newAmmoCount <= 0) then { - [QEGVAR(common,removeMagazineTurret), [_object, _magazineClassname, _magazineInfo], _object, _magazineInfo] call CBA_fnc_turretEvent; - } else { - [QEGVAR(common,setMagazineTurretAmmo), [_object, _magazineClassname, _newAmmoCount, _magazineInfo], _object, _magazineInfo] call CBA_fnc_turretEvent; - }; - }; - // Inventory magazines - case (_magazineInfo isEqualTo false): { - // Remove selected magazine - _object addMagazineAmmoCargo [_magazineClassname, -1, _ammoCount]; - - // Add a new one with reduced ammo back - if (_newAmmoCount > 0) then { - _object addMagazineAmmoCargo [_magazineClassname, 1, _newAmmoCount]; - }; - }; - // Virtual magazines - case (_magazineInfo isEqualTo true): { - // Find the virtual magazines and update its count - private _virtualAmmo = _object getVariable QGVAR(virtualMagazines); - _magazineIndex = _virtualAmmo findIf {(_x select 0) == _magazineClassname}; - - if (_magazineIndex == -1) exitWith { - TRACE_1("no virtual magazine",_magazineClass); - }; - - if (_newAmmoCount <= 0) then { - _virtualAmmo deleteAt _magazineIndex; - } else { - (_virtualAmmo select _magazineIndex) set [1, _newAmmoCount]; // remove ammo that was detonated - }; - }; - }; -} else { - if (_newAmmoCount <= 0) then { - _magazines deleteAt _magazineIndex; - } else { - _magazine set [1, _newAmmoCount]; // remove ammo that was detonated - }; -}; - -private _timeBetweenAmmoDetonation = ((random 10 / sqrt _totalAmmo) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; -TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); - -// Update total ammo value if mags aren't being removed (if they are, an updated total will be gotten upon the next ammo detonation iteration) -if (!_removeAmmoDuringCookoff) then { - _objectAmmo set [1, _totalAmmo - _removed]; -}; - -// Get magazine info, which is used to spawn projectiles -private _configMagazine = configFile >> "CfgMagazines" >> _magazineClassname; -private _ammo = getText (_configMagazine >> "ammo"); -private _configAmmo = configFile >> "CfgAmmo" >> _ammo; - -private _simType = toLower getText (_configAmmo >> "simulation"); -private _speed = linearConversion [0, 1, random 1, 1, 20, true]; -private _effect2pos = _object selectionPosition "destructionEffect2"; - -// Spawns the projectiles, making them either fly in random directions or explode -private _fnc_spawnProjectile = { - // If the magazines are inside of the cargo (inventory), don't let their projectiles escape the interior of the vehicle - if (!_spawnProjectile) exitWith {}; - - params ["_object", "_ammo", "_speed", "_flyAway"]; - - private _spawnPos = _object 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 = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; - - if (_flyAway) then { - private _vectorAmmo = [-1 + random 2, -1 + random 2, -0.2 + random 1]; - private _vectorVelocity = _vectorAmmo vectorMultiply _speed; - - _projectile setVectorDir _vectorVelocity; - _projectile setVelocity _vectorVelocity; - } else { - _projectile setDamage 1; - }; -}; - -switch (_simType) do { - case "shotbullet": { - [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; - - if (random 1 < 0.6) then { - [_object, _ammo, _speed, true] call _fnc_spawnProjectile; - }; - }; - case "shotshell": { - [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; - - if (random 1 < 0.15) then { - [_object, _ammo, _speed, true] call _fnc_spawnProjectile; - }; - }; - case "shotgrenade": { - if (random 1 < 0.9) then { - _speed = 0; - }; - - [_object, _ammo, _speed, random 1 < 0.5] call _fnc_spawnProjectile; - }; - case "shotrocket"; - case "shotmissile"; - case "shotsubmunitions": { - if (random 1 < 0.1) then { - [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; - - [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; - } else { - createVehicle ["ACE_ammoExplosionLarge", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; - }; - }; - case "shotdirectionalbomb"; - case "shotmine": { - if (random 1 < 0.5) then { - // Not all explosives detonate on destruction, some have scripted alternatives - if (getNumber (_configAmmo >> "triggerWhenDestroyed") != 1) then { - _ammo = getText (_configAmmo >> QEGVAR(explosives,explosive)); - }; - - // If a scripted alternative doesn't exist use generic explosion - if (_ammo != "") then { - [_object, _ammo, 0, false] call _fnc_spawnProjectile; - } else { - createVehicle ["SmallSecondary", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; - }; - }; - }; - case "shotilluminating": { - if (random 1 < 0.15) then { - [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; - }; - }; -}; - -// Detonate the remaining ammo after a delay -[FUNC(detonateAmmunitionServer), [_object, _destroyWhenFinished, _source, _instigator], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; +[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _initialDelay] call CBA_fnc_waitAndExecute;