From ed4cea6c4a11fde0f53e4fc619ff1108c8669aab Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:31:27 +0100 Subject: [PATCH] Various improvements --- addons/cookoff/XEH_postInit.sqf | 30 ++----- addons/cookoff/functions/fnc_cookOff.sqf | 38 +++++---- addons/cookoff/functions/fnc_cookOffBox.sqf | 9 +- .../cookoff/functions/fnc_cookOffBoxLocal.sqf | 85 +++++++------------ .../cookoff/functions/fnc_cookOffEffect.sqf | 19 +++-- .../cookoff/functions/fnc_engineFireLocal.sqf | 14 ++- addons/cookoff/script_component.hpp | 8 +- addons/grenades/functions/fnc_incendiary.sqf | 2 +- .../functions/fnc_handleCookoff.sqf | 3 +- 9 files changed, 90 insertions(+), 118 deletions(-) diff --git a/addons/cookoff/XEH_postInit.sqf b/addons/cookoff/XEH_postInit.sqf index 811dd295a9..b8a9523496 100644 --- a/addons/cookoff/XEH_postInit.sqf +++ b/addons/cookoff/XEH_postInit.sqf @@ -1,12 +1,12 @@ #include "script_component.hpp" -[QGVAR(cookOff), LINKFUNC(cookOff)] call CBA_fnc_addEventHandler; [QGVAR(cookOffBoxLocal), LINKFUNC(cookOffBoxLocal)] call CBA_fnc_addEventHandler; [QGVAR(cookOffEffect), LINKFUNC(cookOffEffect)] call CBA_fnc_addEventHandler; [QGVAR(engineFireLocal), LINKFUNC(engineFireLocal)] call CBA_fnc_addEventHandler; [QGVAR(smoke), LINKFUNC(smoke)] call CBA_fnc_addEventHandler; if (isServer) then { + [QGVAR(cookOff), LINKFUNC(cookOff)] call CBA_fnc_addEventHandler; [QGVAR(cookOffBox), LINKFUNC(cookOffBox)] call CBA_fnc_addEventHandler; [QGVAR(engineFire), LINKFUNC(engineFire)] call CBA_fnc_addEventHandler; [QGVAR(detonateAmmunition), LINKFUNC(detonateAmmunition)] call CBA_fnc_addEventHandler; @@ -14,9 +14,6 @@ if (isServer) then { // Handle cleaning up effects when vehicle is deleted mid cook-off [QGVAR(addCleanupHandlers), { - // No effects on machines without interfaces - if (!hasInterface) exitWith {}; - params ["_object"]; // Don't add a new EH if cook-off is run multiple times @@ -30,33 +27,24 @@ if (isServer) then { }] call CBA_fnc_addEventHandler; [QGVAR(cleanupEffects), { - params ["_object", ["_effects", []]]; + params ["_object"]; if (isServer) then { - // Reset, so that object can cook-off again + // Reset, so that the object can cook-off again _object setVariable [QGVAR(isCookingOff), nil, true]; // Remove effects from JIP - private _jipID = _object getVariable QGVAR(jipID); + { + _x call CBA_fnc_removeGlobalEventJIP; + } forEach (_object getVariable [QGVAR(jipIDs), []]); - if (isNil "_jipID") exitWith {}; - - _jipID call CBA_fnc_removeGlobalEventJIP; - - _object setVariable [QGVAR(jipID), nil]; + _object setVariable [QGVAR(jipIDs), nil]; }; - // No effects on machines without interfaces - if (!hasInterface) exitWith {}; - - // All effects are local - _effects append (_object getVariable [QGVAR(effects), []]); - - if (_effects isEqualTo []) exitWith {}; - + // All effects are local (apart from sound, which is global, but is handled by server) { deleteVehicle _x; - } forEach _effects; + } forEach (_object getVariable [QGVAR(effects), []]); _object setVariable [QGVAR(effects), nil]; }] call CBA_fnc_addEventHandler; diff --git a/addons/cookoff/functions/fnc_cookOff.sqf b/addons/cookoff/functions/fnc_cookOff.sqf index 46fe4f9a3d..f278cb51ce 100644 --- a/addons/cookoff/functions/fnc_cookOff.sqf +++ b/addons/cookoff/functions/fnc_cookOff.sqf @@ -13,8 +13,8 @@ * 5: Detonate after cook-off (default: false) * 6: Selection for fire source (default: "") * 7: Can spawn fire ring (default: true) - * 8: Maximum intensity (default: MAX_COOKOFF_INTENSITY) - * 9: Can spawn fire jet (default: true) + * 8: Can spawn fire jet (default: true) + * 9: Maximum intensity (default: MAX_COOKOFF_INTENSITY) * * Return Value: * None @@ -37,8 +37,8 @@ params [ ["_detonateAfterCookoff", false], ["_fireSource", ""], ["_canRing", true], - ["_maxIntensity", MAX_COOKOFF_INTENSITY, [0]], - ["_canJet", true, [true]] + ["_canJet", true], + ["_maxIntensity", MAX_COOKOFF_INTENSITY] ]; // Check if cook-off is disabled on vehicle specifically @@ -54,6 +54,9 @@ if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; _vehicle setVariable [QGVAR(isCookingOff), true, true]; +// Only required on the server, as the only effect to clean up is to remove the effects from the JIP queue +[QGVAR(addCleanupHandlers), _vehicle] call CBA_fnc_localEvent; + // Limit maximum value of intensity to prevent very long cook-off times _intensity = _intensity min _maxIntensity; @@ -73,9 +76,12 @@ if (_positions isEqualTo []) then { }; }; +// Not guaranteed to be active/used, but reserve it nonetheless +private _fireJipID = format [QGVAR(cookOffEffect_%1), hashValue _vehicle]; + // Spawn smoke -private _jipID = [QGVAR(smoke), [_vehicle, _positions]] call CBA_fnc_globalEventJIP; -_vehicle setVariable [QGVAR(jipID), _jipID]; +private _smokeJipID = [QGVAR(smoke), [_vehicle, _positions]] call CBA_fnc_globalEventJIP; +_vehicle setVariable [QGVAR(jipIDs), [_smokeJipID, _fireJipID]]; // Save intensity for looping purposes _vehicle setVariable [QGVAR(intensity), _intensity]; @@ -83,23 +89,23 @@ _vehicle setVariable [QGVAR(intensity), _intensity]; private _delay = 0; if (_delayBetweenSmokeAndFire) then { - _delay = SMOKE_TIME + random SMOKE_TIME; + _delay = random [SMOKE_DELAY, 1.5 * SMOKE_DELAY, 2 * SMOKE_DELAY]; }; [{ [{ - (_this select 0) params ["_vehicle", "_positions", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet"]; + (_this select 0) params ["_vehicle", "_positions", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet", "_fireJipID"]; private _intensity = _vehicle getVariable [QGVAR(intensity), 0]; if (isNull _vehicle || {_intensity <= 1} || {GVAR(enable) == 0} || {GVAR(cookoffDuration) == 0}) exitWith { - [_this select 1] call CBA_fnc_removePerFrameHandler; + (_this select 1) call CBA_fnc_removePerFrameHandler; // Effects are deleted when vehicle is deleted if (isNull _vehicle) exitWith {}; - // Remove effects globally - [QGVAR(cleanupEffects), _vehicle] call CBA_fnc_globalEvent; + // Remove effects on server + [QGVAR(cleanupEffects), _vehicle] call CBA_fnc_localEvent; if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then { _vehicle setDamage [1, true, _instigator, _instigator]; // because it's running on the server, killer and instigator can be set @@ -118,19 +124,19 @@ if (_delayBetweenSmokeAndFire) then { }; }; - private _time = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; + private _duration = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; if (_fireSource isEqualTo "") then { _fireSource = selectRandom _positions; }; - // As the cook-off effect is max 20s, this is not synced with JIP players - [QGVAR(cookOffEffect), [_vehicle, _canJet, _ring, _time, _fireSource, _intensity]] call CBA_fnc_globalEvent; + // Sync for JIP players + [QGVAR(cookOffEffect), [_vehicle, _canJet, _ring, _fireSource, _intensity, CBA_missionTime, _duration], _fireJipID] call CBA_fnc_globalEventJIP; _intensity = _intensity - (0.5 max random 1) / GVAR(cookoffDuration); _vehicle setVariable [QGVAR(intensity), _intensity]; - _vehicle setVariable [QGVAR(nextFlame), CBA_missionTime + _time + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; + _vehicle setVariable [QGVAR(nextFlame), CBA_missionTime + _duration + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; // If there are any crew, burn them if (["ace_fire"] call EFUNC(common,isModLoaded)) then { @@ -150,4 +156,4 @@ if (_delayBetweenSmokeAndFire) then { _vehicle setVariable [QGVAR(nextExplosiveDetonation), CBA_missionTime + random 60]; }; }, 0.25, _this] call CBA_fnc_addPerFrameHandler; -}, [_vehicle, _positions, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet], _delay] call CBA_fnc_waitAndExecute; +}, [_vehicle, _positions, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet, _fireJipID], _delay] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBox.sqf b/addons/cookoff/functions/fnc_cookOffBox.sqf index 0a1d92944f..cfea21dd3e 100644 --- a/addons/cookoff/functions/fnc_cookOffBox.sqf +++ b/addons/cookoff/functions/fnc_cookOffBox.sqf @@ -5,6 +5,8 @@ * * Arguments: * 0: Ammo box + * 1: Killer (default: objNull) + * 2: Instigator (default: objNull) * * Return Value: * None @@ -17,7 +19,7 @@ if (!isServer) exitWith {}; -params ["_box", "_killer", "_instigator"]; +params ["_box", ["_killer", objNull], ["_instigator", objNull]]; if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; @@ -29,10 +31,9 @@ private _jipID = [QGVAR(cookOffBoxLocal), [ _killer, _instigator, CBA_missionTime, - random [IGNITE_TIME / 2, IGNITE_TIME, IGNITE_TIME / 2 * 3], // generate random timers that are global - random [SMOKE_TIME / 2, SMOKE_TIME, SMOKE_TIME / 2 * 3] + random [SMOKE_DELAY / 2, SMOKE_DELAY, SMOKE_DELAY / 2 * 3] // generate random timer that is global synced ]] call CBA_fnc_globalEventJIP; [_jipID, _box] call CBA_fnc_removeGlobalEventJIP; -_box setVariable [QGVAR(jipID), _jipID]; +_box setVariable [QGVAR(jipIDs), [_jipID]]; diff --git a/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf index 499e5f2a70..e0510905c2 100644 --- a/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf +++ b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf @@ -1,78 +1,53 @@ #include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2, kymckay, johnb43 - * Start a cook-off in the given ammo box. + * Spawns local cook-off effects for ammo boxes. * * Arguments: - * 0: Ammo box + * 0: Box + * 1: Killer + * 2: Instigator + * 3: Start time of the cook-off + * 4: Smoke delay * * Return Value: * None * * Example: - * cursorObject call ace_cookoff_fnc_cookOffBox + * [cursorObject, player, player, CBA_missionTime, 10, 60] call ace_cookoff_fnc_cookOffBoxLocal * * Public: No */ -params ["_box", "_killer", "_instigator", "_startTime", "_igniteTime", "_smokeTime"]; +params ["", "", "", "_startTime", "_smokeDelay"]; -// Make sure effects are cleaned up if box is deleted -[QGVAR(addCleanupHandlers), _box] call CBA_fnc_localEvent; +[{ + params ["_box", "_killer", "_instigator"]; -// These time checks are for JIP players -private _delay = _startTime - CBA_missionTime + _igniteTime; + // Make sure effects are cleaned up if box is deleted + [QGVAR(addCleanupHandlers), _box] call CBA_fnc_localEvent; -if (_delay >= 0) then { - [{ - params ["_box"]; + private _boxPos = ASLToAGL getPosASL _box; + private _effects = []; - private _effects = []; + // Box will start smoking + if (hasInterface) then { + private _smoke = createVehicleLocal ["#particlesource", _boxPos, [], 0, "CAN_COLLIDE"]; + _smoke setParticleClass "AmmoSmokeParticles2"; + _smoke attachTo [_box]; - // Box will start smoking - if (hasInterface) then { - private _smoke = "#particlesource" createVehicleLocal [0, 0, 0]; - _smoke setParticleClass "AmmoSmokeParticles2"; - _smoke attachTo [_box, [0, 0, 0]]; + _effects pushBack _smoke; + }; - _effects pushBack _smoke; - }; + if (isServer) then { + private _sound = createSoundSource ["Sound_Fire", _boxPos, [], 0]; + _sound attachTo [_box]; - if (isServer) then { - private _sound = createSoundSource ["Sound_Fire", ASLToAGL getPosASL _box, [], 0]; - _smoke attachTo [_sound]; - - _effects pushBack _sound; - }; - - _box setVariable [QGVAR(effects), _effects]; - }, _box, _delay] call CBA_fnc_waitAndExecute; -}; - -// Smoke happens later -_delay = _delay + _smokeTime; - -if (_delay >= 0) then { - // Light the fire (also handles lighting) - [{ - params ["_box", "_killer", "_instigator"]; - - if (hasInterface) then { - private _fire = "#particlesource" createVehicleLocal [0, 0, 0]; - - _fire setParticleClass "AmmoBulletCore"; - _fire attachTo [_box, [0, 0, 0]]; - - private _effects = _box getVariable [QGVAR(effects), []]; - - _effects pushBack _fire; - - _box setVariable [QGVAR(effects), _effects]; - }; + _effects pushBack _sound; // Detonate the ammunition - if (isServer) then { - [QGVAR(detonateAmmunition), [_box, true, _killer, _instigator]] call CBA_fnc_localEvent; - }; - }, _this, _delay] call CBA_fnc_waitAndExecute; -}; + [QGVAR(detonateAmmunition), [_box, true, _killer, _instigator, random [DETONATION_DELAY / 2, DETONATION_DELAY, DETONATION_DELAY / 2 * 3]]] call CBA_fnc_localEvent; + }; + + _box setVariable [QGVAR(effects), _effects]; +}, _this, (_startTime - CBA_missionTime + _smokeDelay) max 0] call CBA_fnc_waitAndExecute; // this delay allows for synchronisation for JIP players diff --git a/addons/cookoff/functions/fnc_cookOffEffect.sqf b/addons/cookoff/functions/fnc_cookOffEffect.sqf index 0447959a59..6f8bd84e04 100644 --- a/addons/cookoff/functions/fnc_cookOffEffect.sqf +++ b/addons/cookoff/functions/fnc_cookOffEffect.sqf @@ -7,15 +7,16 @@ * 0: Vehicle * 1: Spawn fire jet * 2: Spawn fire ring - * 3: Duration of effect (max 20 seconds) - * 4: What selection will fire originate from - * 5: Cookoff intensity value + * 3: What selection fire will originate from + * 4: Cookoff intensity value + * 5: Start time + * 6: Duration of effect (max 20 seconds) * * Return Value: * None * * Example: - * [vehicle player, true, false, 15, "commander_turret"] call ace_cookoff_fnc_cookOffEffect + * [vehicle player, true, false, "commander_turret", 6, CBA_missionTime, 15] call ace_cookoff_fnc_cookOffEffect * * Public: No */ @@ -23,7 +24,7 @@ #define FLAME_SIZE 1.5 #define FIRE_INTENSITY 6 -params ["_vehicle", "_jet", "_ring", "_duration", "_fireSelection", "_intensity"]; +params ["_vehicle", "_jet", "_ring", "_fireSelection", "_intensity", "_startTime", "_duration"]; // Spawn light private _light = objNull; @@ -51,20 +52,20 @@ if (isServer) then { // Make the ring a source of fire if (_ring && {["ace_fire"] call EFUNC(common,isModLoaded)}) then { - _fireKey = format [QGVAR(%1), hashValue _vehicle]; + _fireKey = format [QGVAR(cookoffFire_%1), hashValue _vehicle]; [QEGVAR(fire,addFireSource), [_vehicle, FLAME_SIZE * ((boundingBoxReal _vehicle) select 2), FIRE_INTENSITY, _fireKey]] call CBA_fnc_localEvent; }; }; [{ - (_this select 0) params ["_vehicle", "_jet", "_ring", "_duration", "_startTime", "_light", "_fireSelection", "_sound", "_intensity", "_fireKey"]; + (_this select 0) params ["_vehicle", "_jet", "_ring", "_startTime", "_duration", "_light", "_fireSelection", "_sound", "_intensity", "_fireKey"]; private _elapsedTime = CBA_missionTime - _startTime; // Clean up effects once effects have finished or vehicle has been deleted if (isNull _vehicle || {_elapsedTime >= _duration}) exitWith { - [_this select 1] call CBA_fnc_removePerFrameHandler; + (_this select 1) call CBA_fnc_removePerFrameHandler; deleteVehicle _light; @@ -222,4 +223,4 @@ if (isServer) then { (_tiWheels + _intensity * 0.004) / 1.002, // wheels//tracks are further away from burning parts (_tiWeapon + _intensity * 0.01) / 1.005 ]; -}, 0, [_vehicle, _jet, _ring, _duration, CBA_missionTime, _light, _fireSelection, _sound, _intensity, _fireKey]] call CBA_fnc_addPerFrameHandler; +}, 0, [_vehicle, _jet, _ring, _startTime, _duration, _light, _fireSelection, _sound, _intensity, _fireKey]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireLocal.sqf b/addons/cookoff/functions/fnc_engineFireLocal.sqf index 625a6d3fe9..65d1670ed2 100644 --- a/addons/cookoff/functions/fnc_engineFireLocal.sqf +++ b/addons/cookoff/functions/fnc_engineFireLocal.sqf @@ -51,7 +51,7 @@ if (hasInterface) then { }; // Spawn smoke - _smoke = "#particlesource" createVehicleLocal [0, 0, 0]; + _smoke = createVehicleLocal ["#particlesource", ASLToAGL getPosASL _vehicle, [], 0, "CAN_COLLIDE"];; _smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; _smoke attachTo [_vehicle, _position]; }; @@ -60,14 +60,20 @@ if (hasInterface) then { (_this select 0) params ["_vehicle", "_smoke", "_endTime"]; if (!alive _vehicle || {_vehicle getHitPointDamage "HitEngine" < 0.9} || {CBA_missionTime >= _endTime}) exitWith { - [_this select 1] call CBA_fnc_removePerFrameHandler; + (_this select 1) call CBA_fnc_removePerFrameHandler; deleteVehicle _smoke; if (isNull _vehicle || !isServer) exitWith {}; - (_vehicle getVariable [QGVAR(engineFireJipID), ""]) call CBA_fnc_removeGlobalEventJIP; + _vehicle setVariable [QGVAR(isEngineSmoking), nil]; - _vehicle setVariable [QGVAR(isEngineSmoking), false]; + private _jipID = _vehicle getVariable QGVAR(engineFireJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _vehicle setVariable [QGVAR(engineFireJipID), nil]; }; }, 5, [_vehicle, _smoke, _endTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/script_component.hpp b/addons/cookoff/script_component.hpp index 3e81984515..7c812cd84b 100644 --- a/addons/cookoff/script_component.hpp +++ b/addons/cookoff/script_component.hpp @@ -20,10 +20,9 @@ // Stages of cookoff in order (in seconds) // Should be no un-synced randomness in these as the effects must be ran on each client -#define IGNITE_TIME 3 -#define SMOKE_TIME 10.5 +#define SMOKE_DELAY 10.5 +#define DETONATION_DELAY 3 #define COOKOFF_TIME 14 // Cook off time should be 20s at most due to length of sound files -#define COOKOFF_TIME_BOX 82.5 // Cook off time for boxes should be significant to allow time for ammo to burn #define ENGINE_FIRE_TIME 240 #define MIN_TIME_BETWEEN_FLAMES 5 #define MAX_TIME_BETWEEN_FLAMES 15 @@ -33,9 +32,6 @@ #define MIN_AMMO_DETONATION_START_DELAY 1 // Min time to wait before a vehicle's ammo starts to cookoff #define MAX_AMMO_DETONATION_START_DELAY 6 // Max time to wait before a vehicle's ammo starts to cookoff -// Delay between flame effect for players in a cooking off vehicle -#define FLAME_EFFECT_DELAY 0.4 - // Common commander hatch defines for default vehicles #define DEFAULT_COMMANDER_HATCHES ["osa_poklop_commander", "hatch_commander_axis"] diff --git a/addons/grenades/functions/fnc_incendiary.sqf b/addons/grenades/functions/fnc_incendiary.sqf index e1e2732576..77cf8153a4 100644 --- a/addons/grenades/functions/fnc_incendiary.sqf +++ b/addons/grenades/functions/fnc_incendiary.sqf @@ -180,7 +180,7 @@ if (isServer) then { {EGVAR(cookoff,ammoCookoffDuration) != 0} && {_x getVariable [QEGVAR(cookoff,enableAmmoCookoff), true]} ) then { - [QEGVAR(cookOff,cookOffBox), [_box, objNull, objNull]] call CBA_fnc_serverEvent; + [QEGVAR(cookOff,cookOffBox), _box] call CBA_fnc_serverEvent; } else { _x setDamage 1; }; diff --git a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf index 26823f2493..5ff4d0e8f2 100644 --- a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf +++ b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf @@ -47,8 +47,7 @@ if (_chanceOfFire >= random 1) exitWith { _source = ["hit_engine_point", "HitPoints"]; }; - // sending nil for _maxIntensity (9th param) to use default value in ace_cookoff_fnc_cookOff - [QEGVAR(cookOff,cookOff), [_vehicle, _intensity, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, nil, _canJet]] call CBA_fnc_serverEvent; + [QEGVAR(cookOff,cookOff), [_vehicle, _intensity, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, _canJet]] call CBA_fnc_serverEvent; LOG_4("Cooking-off [%1] with a chance-of-fire [%2] - Delayed Smoke | Detonate after cookoff [%3 | %4]",_vehicle,_chanceOfFire,_delayWithSmoke,_detonateAfterCookoff); [_vehicle] spawn FUNC(abandon); LOG_1("[%1] is on fire is bailing",_vehicle);