mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Fire - Mini-Rewrite (#9757)
Co-authored-by: Jouni Järvinen <rautamiekka@users.noreply.github.com> Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com>
This commit is contained in:
parent
f86e882b18
commit
f45dff8a09
@ -18,8 +18,6 @@
|
|||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BURN_THRESHOLD 1
|
|
||||||
|
|
||||||
params ["_unit", "_damages"];
|
params ["_unit", "_damages"];
|
||||||
TRACE_2("woundsHandlerIncendiary",_unit,_damages);
|
TRACE_2("woundsHandlerIncendiary",_unit,_damages);
|
||||||
|
|
||||||
@ -32,9 +30,7 @@ private _fireDamage = 0;
|
|||||||
private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true];
|
private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true];
|
||||||
TRACE_2("",_intensity,_fireDamage);
|
TRACE_2("",_intensity,_fireDamage);
|
||||||
|
|
||||||
if (_intensity > BURN_THRESHOLD) then {
|
// Let fire handle if unit is set ablaze or not
|
||||||
TRACE_2("Setting unit ablaze",_intensity,BURN_THRESHOLD);
|
[QEGVAR(fire,burn), [_unit, _intensity]] call CBA_fnc_localEvent;
|
||||||
["ace_fire_burn", [_unit, _intensity]] call CBA_fnc_globalEvent;
|
|
||||||
};
|
|
||||||
|
|
||||||
_this // return
|
_this // return
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BURN_THRESHOLD 1
|
|
||||||
|
|
||||||
params ["_unit", "_damages"];
|
params ["_unit", "_damages"];
|
||||||
TRACE_2("woundsHandlerIncendiary",_unit,_damages);
|
TRACE_2("woundsHandlerIncendiary",_unit,_damages);
|
||||||
|
|
||||||
@ -32,9 +30,7 @@ private _fireDamage = 0;
|
|||||||
private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true];
|
private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true];
|
||||||
TRACE_2("",_intensity,_fireDamage);
|
TRACE_2("",_intensity,_fireDamage);
|
||||||
|
|
||||||
if (_intensity > BURN_THRESHOLD) then {
|
// Let fire handle if unit is set ablaze or not
|
||||||
TRACE_2("Setting unit ablaze",_intensity,BURN_THRESHOLD);
|
[QEGVAR(fire,burn), [_unit, _intensity]] call CBA_fnc_localEvent;
|
||||||
["ace_fire_burn", [_unit, _intensity]] call CBA_fnc_globalEvent;
|
|
||||||
};
|
|
||||||
|
|
||||||
_this // return
|
_this // return
|
||||||
|
@ -175,7 +175,7 @@ if (_delayBetweenSmokeAndFire) then {
|
|||||||
if (["ace_fire"] call EFUNC(common,isModLoaded)) then {
|
if (["ace_fire"] call EFUNC(common,isModLoaded)) then {
|
||||||
// Use current intensity, in case GVAR(cookoffDuration) is very large and only 1 flameout stage happens
|
// Use current intensity, in case GVAR(cookoffDuration) is very large and only 1 flameout stage happens
|
||||||
{
|
{
|
||||||
[QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator]] call CBA_fnc_globalEvent;
|
[QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator], _x] call CBA_fnc_targetEvent;
|
||||||
} forEach (crew _vehicle);
|
} forEach (crew _vehicle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// weird ass concatenation syntax. PBO Project complains otherwise...
|
// weird ass concatenation syntax. PBO Project complains otherwise...
|
||||||
#define CONCAT(a,b) a####b
|
#define CONCAT(a,b) a####b
|
||||||
#define CREATE_SCREAM(no)\
|
#define CREATE_SCREAM(no)\
|
||||||
class GVAR(DOUBLES(scream,no)) { \
|
class GVAR(DOUBLES(scream,no)) {\
|
||||||
name = QUOTE(GVAR(CONCAT(scream,no)));\
|
name = QGVAR(CONCAT(scream,no));\
|
||||||
sound[] = {QUOTE(PATHTOF(CONCAT(sounds\scream,no).ogg)), QUOTE(db+8), 1};\
|
sound[] = {QPATHTOF(CONCAT(sounds\scream,no).ogg), QUOTE(db+8), 1};\
|
||||||
titles[] = {}; \
|
titles[] = {};\
|
||||||
}
|
}
|
||||||
|
|
||||||
class CfgSounds {
|
class CfgSounds {
|
||||||
|
7
addons/fire/CfgVehicles.hpp
Normal file
7
addons/fire/CfgVehicles.hpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class CfgVehicles {
|
||||||
|
class Static;
|
||||||
|
class GVAR(logic): Static {
|
||||||
|
scope = 1;
|
||||||
|
displayName = "";
|
||||||
|
};
|
||||||
|
};
|
@ -1,9 +1,10 @@
|
|||||||
PREP(burn);
|
PREP(burn);
|
||||||
PREP(isBurning);
|
PREP(burnEffects);
|
||||||
PREP(burnIndicator);
|
PREP(burnIndicator);
|
||||||
PREP(burnReaction);
|
PREP(burnReaction);
|
||||||
|
PREP(burnSimulation);
|
||||||
PREP(fireManagerPFH);
|
PREP(fireManagerPFH);
|
||||||
|
PREP(isBurning);
|
||||||
|
PREP(medical_canPatDown);
|
||||||
PREP(medical_progress);
|
PREP(medical_progress);
|
||||||
PREP(medical_success);
|
PREP(medical_success);
|
||||||
PREP(medical_canPatDown);
|
|
||||||
|
@ -1,37 +1,89 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
[QGVAR(burn), LINKFUNC(burn)] call CBA_fnc_addEventHandler;
|
[QGVAR(burn), LINKFUNC(burn)] call CBA_fnc_addEventHandler;
|
||||||
|
[QGVAR(burnEffects), LINKFUNC(burnEffects)] call CBA_fnc_addEventHandler;
|
||||||
|
[QGVAR(burnSimulation), LINKFUNC(burnSimulation)] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
[QGVAR(playScream), {
|
[QGVAR(playScream), {
|
||||||
params ["_scream", "_source"];
|
params ["_scream", "_source"];
|
||||||
// only play sound if enabled in settings and enabled for the unit
|
|
||||||
|
// Only play sound if enabled in settings and enabled for the unit
|
||||||
if (GVAR(enableScreams) && {_source getVariable [QGVAR(enableScreams), true]}) then {
|
if (GVAR(enableScreams) && {_source getVariable [QGVAR(enableScreams), true]}) then {
|
||||||
_source say3D _scream;
|
_source say3D _scream;
|
||||||
};
|
};
|
||||||
}] call CBA_fnc_addEventHandler;
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
["ace_settingsInitialized", {
|
if (!isServer) exitWith {};
|
||||||
|
|
||||||
|
["CBA_settingsInitialized", {
|
||||||
TRACE_1("settingsInit",GVAR(enabled));
|
TRACE_1("settingsInit",GVAR(enabled));
|
||||||
|
|
||||||
if (!GVAR(enabled)) exitWith {};
|
if (!GVAR(enabled)) exitWith {};
|
||||||
|
|
||||||
if (isServer) then {
|
GVAR(fireSources) = createHashMap;
|
||||||
|
|
||||||
[QGVAR(addFireSource), {
|
[QGVAR(addFireSource), {
|
||||||
params ["_source", "_radius", "_intensity", "_key", ["_condition", { true }], ["_conditionArgs", []]];
|
params [
|
||||||
private _fireLogic = createVehicle ["ACE_LogicDummy", [0, 0, 0], [], 0, "NONE"];
|
["_source", objNull, [objNull, []]],
|
||||||
if (_source isEqualType objNull) then {
|
["_radius", 0, [0]],
|
||||||
_fireLogic attachTo [_source];
|
["_intensity", 0, [0]],
|
||||||
} else {
|
["_key", ""],
|
||||||
_fireLogic setPosASL _source;
|
["_condition", {true}, [{}]],
|
||||||
|
["_conditionArgs", []]
|
||||||
|
];
|
||||||
|
|
||||||
|
private _isObject = _source isEqualType objNull;
|
||||||
|
|
||||||
|
// Check if the source is valid
|
||||||
|
if !(_isObject || {_source isEqualTypeParams [0, 0, 0]}) exitWith {};
|
||||||
|
|
||||||
|
if (_isObject && {isNull _source}) exitWith {};
|
||||||
|
if (_radius == 0 || _intensity == 0) exitWith {};
|
||||||
|
if (_key isEqualTo "") exitWith {}; // key can be many types
|
||||||
|
|
||||||
|
// hashValue supports more types than hashmaps do by default, but not all (e.g. locations)
|
||||||
|
private _hashedKey = hashValue _key;
|
||||||
|
|
||||||
|
if (isNil "_hashedKey") exitWith {
|
||||||
|
ERROR_2("Unsupported key type used: %1 - %2",_key,typeName _key);
|
||||||
};
|
};
|
||||||
|
|
||||||
[GVAR(fireSources), _key, [_fireLogic, _radius, _intensity, _condition, _conditionArgs]] call CBA_fnc_hashSet;
|
// If a position is passed, create a static object at said position
|
||||||
|
private _sourcePos = if (_isObject) then {
|
||||||
|
getPosATL _source
|
||||||
|
} else {
|
||||||
|
ASLToATL _source
|
||||||
|
};
|
||||||
|
|
||||||
|
private _fireLogic = createVehicle [QGVAR(logic), _sourcePos, [], 0, "CAN_COLLIDE"];
|
||||||
|
|
||||||
|
// If an object was passed, attach logic to the object
|
||||||
|
if (_isObject) then {
|
||||||
|
_fireLogic attachTo [_source];
|
||||||
|
};
|
||||||
|
|
||||||
|
// To avoid issues, remove existing entries first before overwriting
|
||||||
|
if (_hashedKey in GVAR(fireSources)) then {
|
||||||
|
[QGVAR(removeFireSource), _key] call CBA_fnc_localEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
GVAR(fireSources) set [_hashedKey, [_fireLogic, _radius, _intensity, _condition, _conditionArgs]];
|
||||||
}] call CBA_fnc_addEventHandler;
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
[QGVAR(removeFireSource), {
|
[QGVAR(removeFireSource), {
|
||||||
params ["_key"];
|
params ["_key"];
|
||||||
[GVAR(fireSources), _key] call CBA_fnc_hashRem;
|
|
||||||
|
private _hashedKey = hashValue _key;
|
||||||
|
|
||||||
|
if (isNil "_hashedKey") exitWith {
|
||||||
|
ERROR_2("Unsupported key type used: %1 - %2",_key,typeName _key);
|
||||||
|
};
|
||||||
|
|
||||||
|
(GVAR(fireSources) deleteAt _hashedKey) params [["_fireLogic", objNull]];
|
||||||
|
|
||||||
|
detach _fireLogic;
|
||||||
|
deleteVehicle _fireLogic;
|
||||||
}] call CBA_fnc_addEventHandler;
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
[LINKFUNC(fireManagerPFH), FIRE_MANAGER_PFH_DELAY, []] call CBA_fnc_addPerFrameHandler;
|
[LINKFUNC(fireManagerPFH), FIRE_MANAGER_PFH_DELAY, []] call CBA_fnc_addPerFrameHandler;
|
||||||
GVAR(fireSources) = [[], nil] call CBA_fnc_hashCreate;
|
|
||||||
};
|
|
||||||
}] call CBA_fnc_addEventHandler;
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
@ -24,6 +24,7 @@ class CfgPatches {
|
|||||||
|
|
||||||
#include "CfgEventHandlers.hpp"
|
#include "CfgEventHandlers.hpp"
|
||||||
#include "CfgSounds.hpp"
|
#include "CfgSounds.hpp"
|
||||||
|
#include "CfgVehicles.hpp"
|
||||||
#include "ACE_Medical_Treatment_Actions.hpp"
|
#include "ACE_Medical_Treatment_Actions.hpp"
|
||||||
#include "RscTitles.hpp"
|
#include "RscTitles.hpp"
|
||||||
|
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: tcvm
|
* Author: johnb43
|
||||||
* Makes object catch fire. Only call from events. Local effects only.
|
* Makes a unit catch fire. Only call from targeted events, is applied globally.
|
||||||
* Arbitrary values to ignite people. Assumed maximum is "10".
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Vehicle <OBJECT>
|
* 0: Unit <OBJECT>
|
||||||
* 1: Intensity of fire <NUMBER>
|
* 1: Fire intensity <NUMBER>
|
||||||
* 2: Instigator of fire <OBJECT> (default: objNull)
|
* 2: Fire instigator <OBJECT> (default: objNull)
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
@ -18,322 +17,62 @@
|
|||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INTENSITY_LOSS 0.03
|
if (!EGVAR(common,settingsInitFinished)) exitWith {
|
||||||
#define INTENSITY_UPDATE 3
|
EGVAR(common,runAtSettingsInitialized) pushBack [LINKFUNC(burn), _this];
|
||||||
#define BURN_PROPOGATE_UPDATE 1
|
};
|
||||||
#define BURN_PROPOGATE_DISTANCE 2
|
|
||||||
#define BURN_PROPOGATE_COUNTER_MAX 5
|
|
||||||
|
|
||||||
params ["_unit", "_intensity", ["_instigator", objNull]];
|
|
||||||
|
|
||||||
if (!GVAR(enabled)) exitWith {};
|
if (!GVAR(enabled)) exitWith {};
|
||||||
|
|
||||||
private _isBurning = [_unit] call FUNC(isBurning);
|
params ["_unit", "_intensity", ["_instigator", objNull]];
|
||||||
if (_isBurning) exitWith {};
|
TRACE_3("burn",_unit,_intensity,_instigator);
|
||||||
|
|
||||||
[{
|
if (BURN_MIN_INTENSITY > _intensity) exitWith {
|
||||||
// looped function
|
TRACE_3("intensity is too low",_unit,_intensity,BURN_MIN_INTENSITY);
|
||||||
(_this getVariable "params") params ["_unit", "", "_instigator"];
|
};
|
||||||
private _unitPos = getPosASL _unit;
|
|
||||||
|
|
||||||
_intensity = _unit getVariable [QGVAR(intensity), 0];
|
// Check if unit is remote (objNull is remote)
|
||||||
|
if (!local _unit) exitWith {
|
||||||
|
TRACE_1("unit is null or not local",_unit);
|
||||||
|
};
|
||||||
|
|
||||||
if (surfaceIsWater _unitPos && {(_unitPos#2) < 1}) then {
|
// Check if the unit can burn (takes care of spectators and curators)
|
||||||
_intensity = 0;
|
if (getNumber (configOf _unit >> "isPlayableLogic") == 1 || {!(_unit isKindOf "CAManBase")}) exitWith {
|
||||||
|
TRACE_1("unit is virtual or not a man",_unit);
|
||||||
|
};
|
||||||
|
|
||||||
|
// If unit is invulnerable, don't burn the unit
|
||||||
|
if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {
|
||||||
|
TRACE_1("unit is invulnerable",_unit);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _eyePos = eyePos _unit;
|
||||||
|
|
||||||
|
// Check if unit is mostly submerged in water
|
||||||
|
if (surfaceIsWater _eyePos && {(_eyePos select 2) < 0.1}) exitWith {
|
||||||
|
TRACE_1("unit is in water",_unit);
|
||||||
|
};
|
||||||
|
|
||||||
|
// If unit is already burning, update intensity, but don't add another PFH
|
||||||
|
if (_unit call FUNC(isBurning)) exitWith {
|
||||||
|
// Only allow intensity to be increased
|
||||||
|
if (_intensity <= (_unit getVariable [QGVAR(intensity), 0])) exitWith {
|
||||||
|
TRACE_2("unit already burning, no intensity update",_unit,_intensity);
|
||||||
};
|
};
|
||||||
|
|
||||||
_fireParticle setDropInterval (0.01 max linearConversion [BURN_MAX_INTENSITY, BURN_MIN_INTENSITY, _intensity, 0.03, 0.1, false]);
|
TRACE_2("unit already burning, updating intensity",_unit,_intensity);
|
||||||
_fireParticle setParticleParams [
|
|
||||||
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 10, 32], // sprite sheet values
|
|
||||||
"", // animation name
|
|
||||||
"Billboard", // particle type
|
|
||||||
1, // timer period
|
|
||||||
0.7, // lifetime
|
|
||||||
"destructionEffect2", // position
|
|
||||||
[0, 0, 1], // move velocity
|
|
||||||
0, // rotation velocity
|
|
||||||
10, // weight
|
|
||||||
7.9, // volume
|
|
||||||
1, // rubbing
|
|
||||||
[0.3, 0.3], // size
|
|
||||||
[
|
|
||||||
[1, 1, 1, -0],
|
|
||||||
[1, 1, 1, -1],
|
|
||||||
[1, 1, 1, -1],
|
|
||||||
[1, 1, 1, -1],
|
|
||||||
[1, 1, 1, -0]
|
|
||||||
], // colour
|
|
||||||
[0.5, 1], // animation speed
|
|
||||||
1, // random dir period
|
|
||||||
0, // random dir intensity
|
|
||||||
"", // on timer script
|
|
||||||
"", // before destroy script
|
|
||||||
_unit, // particle source
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
0,
|
|
||||||
[[0.8, 0.6, 0.2, 1]] // emissive color
|
|
||||||
];
|
|
||||||
_fireParticle setParticleRandom [
|
|
||||||
0.04 * _intensity, // life time
|
|
||||||
[0.05, 0.05, 2], // position
|
|
||||||
[0.05 * _intensity, 0.05 * _intensity, 0.05 * _intensity], // move velocity
|
|
||||||
0, // rotation velocity
|
|
||||||
0.06 * _intensity, // size
|
|
||||||
[0, 0, 0, 0], // color
|
|
||||||
0, // random direction period
|
|
||||||
0 // random direction intensity
|
|
||||||
];
|
|
||||||
|
|
||||||
_smokeParticle setParticleCircle [0, [0, 0, 0]];
|
_unit setVariable [QGVAR(intensity), _intensity, true];
|
||||||
_smokeParticle setParticleRandom [
|
};
|
||||||
0, // life time
|
|
||||||
[0.25, 0.25, 0], // position
|
|
||||||
[0.2, 0.2, 0], // move velocity
|
|
||||||
0, // rotation velocity
|
|
||||||
0.25, // size
|
|
||||||
[0, 0, 0, 0.1], // color
|
|
||||||
0, // random direction period
|
|
||||||
0 // random direction intensity
|
|
||||||
];
|
|
||||||
_smokeParticle setParticleParams [
|
|
||||||
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 7, 48], // sprite sheet values
|
|
||||||
"", // animation name
|
|
||||||
"Billboard", // particle type
|
|
||||||
1, // timer period
|
|
||||||
8, // lifetime
|
|
||||||
[0, 0, 1.1], // position
|
|
||||||
[0, 0, 1], // move velocity
|
|
||||||
0, // rotation velocity
|
|
||||||
10, // weight
|
|
||||||
7.9, // volume
|
|
||||||
0.066, // rubbing
|
|
||||||
[1, 3, 6], // size
|
|
||||||
[
|
|
||||||
[0.5, 0.5, 0.5, 0.15],
|
|
||||||
[0.75, 0.75, 0.75, 0.075],
|
|
||||||
[1, 1, 1, 0]
|
|
||||||
], // colour
|
|
||||||
[0.125], // animation speed
|
|
||||||
1, // random dir period
|
|
||||||
0, // random dir intensity
|
|
||||||
"", // on timer script
|
|
||||||
"", // before destroy script
|
|
||||||
_unit // particle source
|
|
||||||
];
|
|
||||||
_smokeParticle setDropInterval 0.15;
|
|
||||||
|
|
||||||
_fireLight setLightBrightness ((_intensity * 3) / 10);
|
TRACE_2("setting unit ablaze",_unit,_intensity);
|
||||||
_lightFlare setLightBrightness (_intensity / 30);
|
|
||||||
|
|
||||||
private _distanceToUnit = (_unit distance ace_player);
|
_unit setVariable [QGVAR(intensity), _intensity, true];
|
||||||
_fireLight setLightAttenuation [1, 10 max (5 min (10 - _intensity)), 0, 15];
|
|
||||||
_lightFlare setLightFlareSize (_intensity * (3 / 4)) * FLARE_SIZE_MODIFIER;
|
|
||||||
|
|
||||||
if (!GVAR(enableFlare)) then {
|
// Fire simulation (fire sources are handled differently)
|
||||||
_lightFlare setLightFlareSize 0;
|
[QGVAR(burnSimulation), [_unit, _instigator], _unit] call CBA_fnc_targetEvent;
|
||||||
};
|
|
||||||
|
|
||||||
// always keep flare visible to perceiving unit as long as it isnt the player
|
// Spawn effects for unit
|
||||||
if (_unit isNotEqualTo ace_player) then {
|
private _burnEffectsJipID = [QGVAR(burnEffects), _unit] call CBA_fnc_globalEventJIP;
|
||||||
private _relativeAttachPoint = [0, 0, 0.3];
|
[_burnEffectsJipID, _unit] call CBA_fnc_removeGlobalEventJIP;
|
||||||
if (_distanceToUnit > 1.5) then {
|
|
||||||
_relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ace_player))) vectorMultiply linearConversion [5, 30, _distanceToUnit, 0.5, 1.5];
|
|
||||||
_relativeAttachPoint set [2, 0.3 + ((_unit selectionPosition "pelvis") select 2)];
|
|
||||||
};
|
|
||||||
_lightFlare attachTo [_unit, _relativeAttachPoint];
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!isGamePaused) then {
|
_unit setVariable [QGVAR(jipID), _burnEffectsJipID, true];
|
||||||
// If the unit goes to spectator alive _unit == true and they will be on fire and still take damage
|
|
||||||
// Only workaround I could think of, kinda clunky
|
|
||||||
if (_isThisUnitAlive) then {
|
|
||||||
_isThisUnitAlive = (alive _unit) && { getNumber ((configOf _unit) >> "isPlayableLogic") != 1 };
|
|
||||||
};
|
|
||||||
|
|
||||||
// propagate fire
|
|
||||||
if ((CBA_missionTime - _lastPropogateUpdate) >= BURN_PROPOGATE_UPDATE) then {
|
|
||||||
_lastPropogateUpdate = CBA_missionTime;
|
|
||||||
if !([ace_player] call FUNC(isBurning)) then {
|
|
||||||
if ((vehicle _unit) isEqualTo (vehicle ace_player)) then {
|
|
||||||
if (0.5 > random 1) then {
|
|
||||||
[QGVAR(burn), [ace_player, _intensity * (7 / 8), _instigator]] call CBA_fnc_globalEvent;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
if ((ace_player isKindOf "Man") && {_unit isNotEqualTo ace_player} && {isDamageAllowed ace_player && {ace_player getVariable [QEGVAR(medical,allowDamage), true]}}) then {
|
|
||||||
private _burnCounter = _unit getVariable [QGVAR(burnCounter), 0];
|
|
||||||
if (_distanceToUnit < BURN_PROPOGATE_DISTANCE) then {
|
|
||||||
if (_burnCounter < BURN_PROPOGATE_COUNTER_MAX) then {
|
|
||||||
_burnCounter = _burnCounter + 1;
|
|
||||||
} else {
|
|
||||||
[QGVAR(burn), [ace_player, _intensity * (3 / 4), _instigator]] call CBA_fnc_globalEvent;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_burnCounter = 0;
|
|
||||||
};
|
|
||||||
_unit setVariable [QGVAR(burnCounter), _burnCounter];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// update intensity/fire reactions
|
|
||||||
if ((CBA_missionTime - _lastIntensityUpdate) >= INTENSITY_UPDATE) then {
|
|
||||||
_lastIntensityUpdate = CBA_missionTime;
|
|
||||||
_intensity = _intensity - INTENSITY_LOSS - (rain / 10);
|
|
||||||
if (local _unit) then {
|
|
||||||
if (_isThisUnitAlive) then {
|
|
||||||
if !(IS_UNCONSCIOUS(_unit)) then {
|
|
||||||
if !(isPlayer _unit) then {
|
|
||||||
private _sdr = _unit getVariable [QGVAR(stopDropRoll), false];
|
|
||||||
if ((_unit isEqualTo vehicle _unit) && (_sdr || ({ 0.05 > random 1 }))) then {
|
|
||||||
_unit setVariable [QGVAR(stopDropRoll), true];
|
|
||||||
if !(_sdr) then {
|
|
||||||
TRACE_1("stop,drop,roll!",_unit);
|
|
||||||
_unit setUnitPos "DOWN";
|
|
||||||
doStop _unit;
|
|
||||||
};
|
|
||||||
// queue up a bunch of animations
|
|
||||||
for "_i" from 0 to 2 do {
|
|
||||||
[_unit, selectRandom ["amovppnemstpsnonwnondnon_amovppnemevasnonwnondl", "amovppnemstpsnonwnondnon_amovppnemevasnonwnondr"], 0] call EFUNC(common,doAnimation);
|
|
||||||
};
|
|
||||||
_intensity = _intensity - (1 / _intensity);
|
|
||||||
} else {
|
|
||||||
private _group = (group _unit);
|
|
||||||
private _vehicle = vehicle _unit;
|
|
||||||
|
|
||||||
if (_vehicle != _unit) then {
|
|
||||||
TRACE_1("Ejecting",_unit);
|
|
||||||
_unit leaveVehicle _vehicle;
|
|
||||||
unassignVehicle _unit;
|
|
||||||
_unit action ["eject",_vehicle];
|
|
||||||
};
|
|
||||||
_unit disableAI "TARGET";
|
|
||||||
_unit disableAI "AUTOTARGET";
|
|
||||||
|
|
||||||
// Run away
|
|
||||||
if (leader _group != _unit) then {
|
|
||||||
[_unit] join grpNull;
|
|
||||||
};
|
|
||||||
_unit doMove ((getPosATL _unit) getPos [20 + random 35, floor (random 360)]);
|
|
||||||
_unit setSpeedMode "FULL";
|
|
||||||
_unit setSuppression 1;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
if ((animationState _unit) in PRONE_ROLLING_ANIMS) then {
|
|
||||||
// decrease intensity of burn
|
|
||||||
_intensity = _intensity * INTENSITY_DECREASE_MULT_ROLLING;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
[_unit] call FUNC(burnReaction);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/
|
|
||||||
private _woundSelection = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3];
|
|
||||||
if (GET_PAIN_PERCEIVED(_unit) < (PAIN_UNCONSCIOUS + random 0.2)) then {
|
|
||||||
// keep pain around unconciousness limit to allow for more fun interactions
|
|
||||||
[_unit, _intensity / BURN_MAX_INTENSITY, _woundSelection, "burn", _instigator] call EFUNC(medical,addDamageToUnit);
|
|
||||||
} else {
|
|
||||||
[_unit, 0.15, _woundSelection, "burn", _instigator] call EFUNC(medical,addDamageToUnit);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
_unit setVariable [QGVAR(intensity), _intensity, true]; // globally sync intensity across all clients to make sure simulation is deterministic
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
private _burnIndicatorPFH = _unit getVariable [QGVAR(burnUIPFH), -1];
|
|
||||||
if (_unit isEqualTo ace_player && { _isThisUnitAlive } && { _burnIndicatorPFH < 0 }) then {
|
|
||||||
_burnIndicatorPFH = [LINKFUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler;
|
|
||||||
_unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}, 0, [_unit, _intensity, _instigator], {
|
|
||||||
TRACE_1("burn init",GVAR(enableFlare));
|
|
||||||
// init function
|
|
||||||
private _params = _this getVariable "params";
|
|
||||||
_params params ["_unit", "_startingIntensity"];
|
|
||||||
|
|
||||||
_intensity = _startingIntensity;
|
|
||||||
private _unitPos = getPos _unit;
|
|
||||||
|
|
||||||
_fireParticle = "#particlesource" createVehicleLocal _unitPos;
|
|
||||||
_fireParticle attachTo [_unit, [0, 0, 0]];
|
|
||||||
_fireParticle setDropInterval 0.03;
|
|
||||||
|
|
||||||
_smokeParticle = "#particlesource" createVehicleLocal _unitPos;
|
|
||||||
|
|
||||||
_fireLight = "#lightpoint" createVehicleLocal _unitPos;
|
|
||||||
_fireLight setLightIntensity 0;
|
|
||||||
_fireLight setLightAmbient [0.8, 0.6, 0.2];
|
|
||||||
_fireLight setLightColor [1, 0.5, 0.4];
|
|
||||||
_fireLight attachTo [_unit, [0, 0, 0]];
|
|
||||||
_fireLight setLightDayLight false;
|
|
||||||
|
|
||||||
_lightFlare = "#lightpoint" createVehicleLocal _unitPos;
|
|
||||||
_lightFlare setLightIntensity 0;
|
|
||||||
_lightFlare setLightColor [1, 0.8, 0.8];
|
|
||||||
_lightFlare setLightUseFlare true;
|
|
||||||
_lightFlare setLightFlareMaxDistance 100;
|
|
||||||
_lightFlare setLightFlareSize 0;
|
|
||||||
|
|
||||||
if (_unit isNotEqualTo ace_player) then {
|
|
||||||
private _relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ace_player))) vectorMultiply 1;
|
|
||||||
_relativeAttachPoint set [2, 0.5];
|
|
||||||
_lightFlare attachTo [_unit, _relativeAttachPoint];
|
|
||||||
} else {
|
|
||||||
_lightFlare attachTo [_unit, [0, 0, 0.3]];
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isServer) then {
|
|
||||||
_fireSound = createSoundSource ["Sound_Fire", _unitPos, [], 0];
|
|
||||||
_fireSound attachTo [_unit, [0, 0, 0], "Head"];
|
|
||||||
};
|
|
||||||
|
|
||||||
_unit setVariable [QGVAR(burning), true];
|
|
||||||
_unit setVariable [QGVAR(intensity), _intensity];
|
|
||||||
_unit setVariable [QGVAR(burnUIPFH), -1];
|
|
||||||
|
|
||||||
if (local _unit) then {
|
|
||||||
if (_unit isEqualTo ace_player) then {
|
|
||||||
private _burnIndicatorPFH = [LINKFUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler;
|
|
||||||
_unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH];
|
|
||||||
};
|
|
||||||
|
|
||||||
[_unit, false] call FUNC(burnReaction);
|
|
||||||
};
|
|
||||||
|
|
||||||
_lastIntensityUpdate = 0;
|
|
||||||
_lastPropogateUpdate = 0;
|
|
||||||
|
|
||||||
_isThisUnitAlive = true;
|
|
||||||
}, {
|
|
||||||
(_this getVariable "params") params ["_unit"];
|
|
||||||
|
|
||||||
// deinit function
|
|
||||||
deleteVehicle _fireParticle;
|
|
||||||
deleteVehicle _smokeParticle;
|
|
||||||
deleteVehicle _fireLight;
|
|
||||||
deleteVehicle _lightFlare;
|
|
||||||
deleteVehicle _fireSound;
|
|
||||||
|
|
||||||
if (local _unit) then {
|
|
||||||
if (!isPlayer _unit) then {
|
|
||||||
_unit setUnitPos "AUTO";
|
|
||||||
_unit setVariable [QGVAR(stopDropRoll), false];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
_unit setVariable [QGVAR(burning), false];
|
|
||||||
_unit setVariable [QGVAR(burnCounter), 0];
|
|
||||||
}, {
|
|
||||||
// run condition
|
|
||||||
true
|
|
||||||
}, {
|
|
||||||
// exit condition
|
|
||||||
(_this getVariable "params") params ["_unit"];
|
|
||||||
|
|
||||||
private _unitAlive = (alive _unit) && { getNumber ((configOf _unit) >> "isPlayableLogic") != 1 };
|
|
||||||
private _unitIsUnit = { (_unit != vehicle _unit) && { isNull vehicle _unit } };
|
|
||||||
|
|
||||||
!_unitAlive || _unitIsUnit || { _intensity <= BURN_MIN_INTENSITY } || { !([_unit] call FUNC(isBurning)) }
|
|
||||||
}, ["_intensity", "_fireParticle", "_smokeParticle", "_fireLight", "_fireSound", "_lightFlare", "_lastIntensityUpdate", "_lastPropogateUpdate", "_isThisUnitAlive"]] call CBA_fnc_createPerFrameHandlerObject;
|
|
||||||
|
191
addons/fire/functions/fnc_burnEffects.sqf
Normal file
191
addons/fire/functions/fnc_burnEffects.sqf
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: tcvm, johnb43
|
||||||
|
* Spawns particle effects for a burning unit.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Unit <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* player call ace_fire_fnc_burnEffects
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
|
params ["_unit"];
|
||||||
|
|
||||||
|
// Spawn particles
|
||||||
|
private _unitPos = getPos _unit;
|
||||||
|
private _fireParticle = objNull;
|
||||||
|
private _smokeParticle = objNull;
|
||||||
|
private _fireLight = objNull;
|
||||||
|
private _lightFlare = objNull;
|
||||||
|
|
||||||
|
if (hasInterface) then {
|
||||||
|
_fireParticle = createVehicleLocal ["#particlesource", _unitPos, [], 0, "CAN_COLLIDE"];
|
||||||
|
_fireParticle attachTo [_unit];
|
||||||
|
_fireParticle setDropInterval 0.03;
|
||||||
|
|
||||||
|
_smokeParticle = createVehicleLocal ["#particlesource", _unitPos, [], 0, "CAN_COLLIDE"];
|
||||||
|
|
||||||
|
_fireLight = createVehicleLocal ["#lightpoint", _unitPos, [], 0, "CAN_COLLIDE"];
|
||||||
|
_fireLight setLightIntensity 0;
|
||||||
|
_fireLight setLightAmbient [0.8, 0.6, 0.2];
|
||||||
|
_fireLight setLightColor [1, 0.5, 0.4];
|
||||||
|
_fireLight attachTo [_unit];
|
||||||
|
_fireLight setLightDayLight false;
|
||||||
|
|
||||||
|
_lightFlare = createVehicleLocal ["#lightpoint", _unitPos, [], 0, "CAN_COLLIDE"];
|
||||||
|
_lightFlare setLightIntensity 0;
|
||||||
|
_lightFlare setLightColor [1, 0.8, 0.8];
|
||||||
|
_lightFlare setLightUseFlare true;
|
||||||
|
_lightFlare setLightFlareMaxDistance 100;
|
||||||
|
_lightFlare setLightFlareSize 0;
|
||||||
|
|
||||||
|
if (_unit != ACE_player) then {
|
||||||
|
private _relativeAttachPoint = vectorNormalized (_unit worldToModelVisual (getPos ACE_player));
|
||||||
|
_relativeAttachPoint set [2, 0.5];
|
||||||
|
_lightFlare attachTo [_unit, _relativeAttachPoint];
|
||||||
|
} else {
|
||||||
|
_lightFlare attachTo [_unit, [0, 0, 0.3]];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
private _fireSound = objNull;
|
||||||
|
|
||||||
|
if (isServer) then {
|
||||||
|
_fireSound = createSoundSource ["Sound_Fire", _unitPos, [], 0];
|
||||||
|
_fireSound attachTo [_unit, [0, 0, 0], "Head"];
|
||||||
|
};
|
||||||
|
|
||||||
|
[{
|
||||||
|
params ["_args", "_pfhID"];
|
||||||
|
_args params ["_unit", "_fireParticle", "_smokeParticle", "_fireLight", "_lightFlare", "_fireSound"];
|
||||||
|
|
||||||
|
if (isNull _unit || {!(_unit call FUNC(isBurning))}) exitWith {
|
||||||
|
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||||
|
|
||||||
|
deleteVehicle _fireParticle;
|
||||||
|
deleteVehicle _smokeParticle;
|
||||||
|
deleteVehicle _fireLight;
|
||||||
|
deleteVehicle _lightFlare;
|
||||||
|
deleteVehicle _fireSound;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Display burn indicators
|
||||||
|
if (_unit == ACE_player && {alive _unit} && {isNil {_unit getVariable QGVAR(burnUIPFH)}}) then { // This accounts for player remote controlled a new unit
|
||||||
|
private _burnIndicatorPFH = [LINKFUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler;
|
||||||
|
_unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH];
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!hasInterface) exitWith {};
|
||||||
|
|
||||||
|
private _intensity = _unit getVariable [QGVAR(intensity), 0];
|
||||||
|
|
||||||
|
_fireParticle setDropInterval (0.01 max linearConversion [BURN_MAX_INTENSITY, BURN_MIN_INTENSITY, _intensity, 0.03, 0.1, false]);
|
||||||
|
_fireParticle setParticleParams [
|
||||||
|
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 10, 32], // sprite sheet values
|
||||||
|
"", // animation name
|
||||||
|
"Billboard", // particle type
|
||||||
|
1, // timer period
|
||||||
|
0.7, // lifetime
|
||||||
|
"destructionEffect2", // position
|
||||||
|
[0, 0, 1], // move velocity
|
||||||
|
0, // rotation velocity
|
||||||
|
10, // weight
|
||||||
|
7.9, // volume
|
||||||
|
1, // rubbing
|
||||||
|
[0.3, 0.3], // size
|
||||||
|
[
|
||||||
|
[1, 1, 1, -0],
|
||||||
|
[1, 1, 1, -1],
|
||||||
|
[1, 1, 1, -1],
|
||||||
|
[1, 1, 1, -1],
|
||||||
|
[1, 1, 1, -0]
|
||||||
|
], // colour
|
||||||
|
[0.5, 1], // animation speed
|
||||||
|
1, // random dir period
|
||||||
|
0, // random dir intensity
|
||||||
|
"", // on timer script
|
||||||
|
"", // before destroy script
|
||||||
|
_unit, // particle source
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
[[0.8, 0.6, 0.2, 1]] // emissive color
|
||||||
|
];
|
||||||
|
_fireParticle setParticleRandom [
|
||||||
|
0.04 * _intensity, // life time
|
||||||
|
[0.05, 0.05, 2], // position
|
||||||
|
[0.05, 0.05, 0.05] vectorMultiply _intensity, // move velocity
|
||||||
|
0, // rotation velocity
|
||||||
|
0.06 * _intensity, // size
|
||||||
|
[0, 0, 0, 0], // color
|
||||||
|
0, // random direction period
|
||||||
|
0 // random direction intensity
|
||||||
|
];
|
||||||
|
|
||||||
|
_smokeParticle setDropInterval 0.15;
|
||||||
|
_smokeParticle setParticleCircle [0, [0, 0, 0]];
|
||||||
|
_smokeParticle setParticleParams [
|
||||||
|
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 7, 48], // sprite sheet values
|
||||||
|
"", // animation name
|
||||||
|
"Billboard", // particle type
|
||||||
|
1, // timer period
|
||||||
|
8, // lifetime
|
||||||
|
[0, 0, 1.1], // position
|
||||||
|
[0, 0, 1], // move velocity
|
||||||
|
0, // rotation velocity
|
||||||
|
10, // weight
|
||||||
|
7.9, // volume
|
||||||
|
0.066, // rubbing
|
||||||
|
[1, 3, 6], // size
|
||||||
|
[
|
||||||
|
[0.5, 0.5, 0.5, 0.15],
|
||||||
|
[0.75, 0.75, 0.75, 0.075],
|
||||||
|
[1, 1, 1, 0]
|
||||||
|
], // colour
|
||||||
|
[0.125], // animation speed
|
||||||
|
1, // random dir period
|
||||||
|
0, // random dir intensity
|
||||||
|
"", // on timer script
|
||||||
|
"", // before destroy script
|
||||||
|
_unit // particle source
|
||||||
|
];
|
||||||
|
_smokeParticle setParticleRandom [
|
||||||
|
0, // life time
|
||||||
|
[0.25, 0.25, 0], // position
|
||||||
|
[0.2, 0.2, 0], // move velocity
|
||||||
|
0, // rotation velocity
|
||||||
|
0.25, // size
|
||||||
|
[0, 0, 0, 0.1], // color
|
||||||
|
0, // random direction period
|
||||||
|
0 // random direction intensity
|
||||||
|
];
|
||||||
|
|
||||||
|
_fireLight setLightBrightness ((_intensity * 3) / 10);
|
||||||
|
_fireLight setLightAttenuation [1, 10 max (5 min (10 - _intensity)), 0, 15];
|
||||||
|
|
||||||
|
_lightFlare setLightBrightness (_intensity / 30);
|
||||||
|
_lightFlare setLightFlareSize (_intensity * (3 / 4)) * FLARE_SIZE_MODIFIER;
|
||||||
|
|
||||||
|
if (!GVAR(enableFlare)) then {
|
||||||
|
_lightFlare setLightFlareSize 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Always keep flare visible to perceiving unit as long as it isn't the player
|
||||||
|
if (_unit != ACE_player) then {
|
||||||
|
private _distanceToUnit = _unit distance ACE_player;
|
||||||
|
private _relativeAttachPoint = [0, 0, 0.3];
|
||||||
|
|
||||||
|
if (_distanceToUnit > 1.5) then {
|
||||||
|
_relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ACE_player))) vectorMultiply linearConversion [5, 30, _distanceToUnit, 0.5, 1.5];
|
||||||
|
_relativeAttachPoint set [2, 0.3 + ((_unit selectionPosition "pelvis") select 2)];
|
||||||
|
};
|
||||||
|
|
||||||
|
_lightFlare attachTo [_unit, _relativeAttachPoint];
|
||||||
|
};
|
||||||
|
}, 0, [_unit, _fireParticle, _smokeParticle, _fireLight, _lightFlare, _fireSound]] call CBA_fnc_addPerFrameHandler;
|
@ -11,26 +11,30 @@
|
|||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* [player, 4] call ace_fire_fnc_burnIndicator
|
* [player, _pfhID] call ace_fire_fnc_burnIndicator
|
||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params ["_unit", "_pfhHandle"];
|
params ["_unit", "_pfhID"];
|
||||||
|
|
||||||
if !(IS_UNCONSCIOUS(_unit)) then {
|
if (!alive _unit || {!(_unit call FUNC(isBurning))}) exitWith {
|
||||||
private _iteration = _unit getVariable [QGVAR(indicatorIteration), 0];
|
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||||
if (_iteration == 0) then {
|
|
||||||
|
_unit setVariable [QGVAR(burnUIPFH), nil];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't show burn overlay if unconscious or dead
|
||||||
|
if !(_unit call EFUNC(common,isAwake)) exitWith {};
|
||||||
|
|
||||||
|
private _iteration = _unit getVariable [QGVAR(indicatorIteration), 0];
|
||||||
|
|
||||||
|
if (_iteration == 0) then {
|
||||||
QGVAR(indicatorLayer) cutRsc [QGVAR(onFire1), "PLAIN"];
|
QGVAR(indicatorLayer) cutRsc [QGVAR(onFire1), "PLAIN"];
|
||||||
_iteration = 1;
|
_iteration = 1;
|
||||||
} else {
|
} else {
|
||||||
QGVAR(indicatorLayer) cutRsc [QGVAR(onFire2), "PLAIN"];
|
QGVAR(indicatorLayer) cutRsc [QGVAR(onFire2), "PLAIN"];
|
||||||
_iteration = 0;
|
_iteration = 0;
|
||||||
};
|
|
||||||
_unit setVariable [QGVAR(indicatorIteration), _iteration];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!([_unit] call FUNC(isBurning)) || {!alive _unit}) then {
|
_unit setVariable [QGVAR(indicatorIteration), _iteration];
|
||||||
[_pfhHandle] call CBA_fnc_removePerFrameHandler;
|
|
||||||
_unit setVariable [QGVAR(burnUIPFH), -1];
|
|
||||||
};
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Unit <OBJECT>
|
* 0: Unit <OBJECT>
|
||||||
* 1: Should unit throw its current weapon <BOOL>
|
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
@ -13,19 +12,15 @@
|
|||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params ["_unit", ["_throwWeapon", true]];
|
params ["_unit"];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
_throwWeapon
|
GVAR(dropWeapon) > 0 &&
|
||||||
&& {GVAR(dropWeapon) > 0}
|
{isNull objectParent _unit} &&
|
||||||
&& {_unit in _unit && {(currentWeapon _unit) isNotEqualTo ""}}
|
{(currentWeapon _unit) != ""} &&
|
||||||
&& {!isPlayer _unit || GVAR(dropWeapon) >= 2}
|
{!isPlayer _unit || GVAR(dropWeapon) == 2}
|
||||||
) then {
|
) then {
|
||||||
[_unit] call EFUNC(common,throwWeapon);
|
_unit call EFUNC(common,throwWeapon);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_unit isKindOf "CAManBase") then {
|
[QGVAR(playScream), [format [QGVAR(scream_%1), floor (1 + random 15)], _unit]] call CBA_fnc_globalEvent;
|
||||||
private _soundID = floor (1 + random 15);
|
|
||||||
private _sound = format [QGVAR(scream_%1), _soundID];
|
|
||||||
[QGVAR(playScream), [_sound, _unit]] call CBA_fnc_globalEvent;
|
|
||||||
};
|
|
||||||
|
167
addons/fire/functions/fnc_burnSimulation.sqf
Normal file
167
addons/fire/functions/fnc_burnSimulation.sqf
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: tcvm, johnb43
|
||||||
|
* Simulates fire intensity over time on burning units.
|
||||||
|
* Arbitrary values to ignite people. Assumed maximum is "10".
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Unit <OBJECT>
|
||||||
|
* 1: Instigator <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [player, player] call ace_fire_fnc_burnSimulation
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
|
||||||
|
params ["_unit", "_instigator"];
|
||||||
|
|
||||||
|
[{
|
||||||
|
params ["_args", "_pfhID"];
|
||||||
|
_args params ["_unit", "_instigator"];
|
||||||
|
|
||||||
|
if (isNull _unit) exitWith {
|
||||||
|
TRACE_1("unit is null",_unit);
|
||||||
|
|
||||||
|
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Locality has changed
|
||||||
|
if (!local _unit) exitWith {
|
||||||
|
TRACE_1("unit is no longer local",_unit);
|
||||||
|
|
||||||
|
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||||
|
|
||||||
|
[QGVAR(burnSimulation), [_unit, _instigator], _unit] call CBA_fnc_targetEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the unit is invulnerable, in water or if the fire has died out, stop burning the unit
|
||||||
|
if (
|
||||||
|
!(_unit call FUNC(isBurning)) ||
|
||||||
|
{!(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]})} ||
|
||||||
|
{private _eyePos = eyePos _unit; surfaceIsWater _eyePos && {(_eyePos select 2) < 0.1}}
|
||||||
|
) exitWith {
|
||||||
|
TRACE_3("unit is no longer burning, invulnerable or in water",_unit,_unit call FUNC(isBurning),isDamageAllowed _unit && {_unit getVariable [ARR_2(QEGVAR(medical,allowDamage),true)]});
|
||||||
|
|
||||||
|
// Remove global effects
|
||||||
|
(_unit getVariable [QGVAR(jipID), ""]) call CBA_fnc_removeGlobalEventJIP;
|
||||||
|
|
||||||
|
// Update globally that the unit isn't burning anymore
|
||||||
|
_unit setVariable [QGVAR(intensity), nil, true];
|
||||||
|
|
||||||
|
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||||
|
|
||||||
|
if (!isNil {_unit getVariable QGVAR(stopDropRoll)} && {!isPlayer _unit}) then {
|
||||||
|
_unit setUnitPos "AUTO";
|
||||||
|
|
||||||
|
_unit setVariable [QGVAR(stopDropRoll), nil, true];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isGamePaused) exitWith {};
|
||||||
|
|
||||||
|
private _intensity = _unit getVariable [QGVAR(intensity), 0];
|
||||||
|
|
||||||
|
// Propagate fire to other units (alive or dead) if it's intense
|
||||||
|
if (_intensity >= BURN_THRESHOLD_INTENSE) then {
|
||||||
|
TRACE_2("check for other units",_unit,_intensity);
|
||||||
|
|
||||||
|
{
|
||||||
|
private _distancePercent = 1 - ((_unit distance _x) / BURN_PROPAGATE_DISTANCE);
|
||||||
|
private _adjustedIntensity = _intensity * _distancePercent;
|
||||||
|
|
||||||
|
// Don't burn if intensity is too low or already burning with higher intensity
|
||||||
|
if (BURN_MIN_INTENSITY > _adjustedIntensity || {(_x getVariable [QGVAR(intensity), 0]) > _adjustedIntensity}) then {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
[QGVAR(burn), [_x, _adjustedIntensity, _instigator], _x] call CBA_fnc_targetEvent;
|
||||||
|
|
||||||
|
TRACE_3("propagate fire",_x,_intensity,_adjustedIntensity);
|
||||||
|
} forEach nearestObjects [_unit, ["CAManBase"], BURN_PROPAGATE_DISTANCE];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update intensity/fire reactions
|
||||||
|
if (CBA_missionTime >= _unit getVariable [QGVAR(intensityUpdate), 0]) then {
|
||||||
|
TRACE_2("update intensity",_unit,_intensity);
|
||||||
|
|
||||||
|
_unit setVariable [QGVAR(intensityUpdate), CBA_missionTime + INTENSITY_UPDATE];
|
||||||
|
|
||||||
|
_intensity = _intensity - INTENSITY_LOSS - (rain / 10);
|
||||||
|
|
||||||
|
if (_unit call EFUNC(common,isAwake)) then {
|
||||||
|
if (_unit call EFUNC(common,isPlayer)) then {
|
||||||
|
// Decrease intensity of burn if rolling around
|
||||||
|
if ((animationState _unit) in PRONE_ROLLING_ANIMS) then {
|
||||||
|
_intensity = _intensity * INTENSITY_DECREASE_MULT_ROLLING;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
private _sdr = _unit getVariable [QGVAR(stopDropRoll), false];
|
||||||
|
|
||||||
|
private _vehicle = objectParent _unit;
|
||||||
|
|
||||||
|
if (isNull _vehicle && {_sdr || {0.05 > random 1}}) then {
|
||||||
|
_unit setVariable [QGVAR(stopDropRoll), true, true];
|
||||||
|
|
||||||
|
if (!_sdr) then {
|
||||||
|
TRACE_1("stop, drop, roll!",_unit);
|
||||||
|
|
||||||
|
_unit setUnitPos "DOWN";
|
||||||
|
doStop _unit;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Queue up a bunch of animations
|
||||||
|
for "_i" from 0 to 2 do {
|
||||||
|
[_unit, selectRandom ["amovppnemstpsnonwnondnon_amovppnemevasnonwnondl", "amovppnemstpsnonwnondnon_amovppnemevasnonwnondr"], 0] call EFUNC(common,doAnimation);
|
||||||
|
};
|
||||||
|
|
||||||
|
_intensity = _intensity - (1 / _intensity);
|
||||||
|
} else {
|
||||||
|
// Make the unit leave the vehicle
|
||||||
|
if (_vehicle != _unit) then {
|
||||||
|
TRACE_1("Ejecting",_unit);
|
||||||
|
|
||||||
|
_unit leaveVehicle _vehicle;
|
||||||
|
unassignVehicle _unit;
|
||||||
|
|
||||||
|
_unit action ["Eject", _vehicle];
|
||||||
|
};
|
||||||
|
|
||||||
|
_unit disableAI "TARGET";
|
||||||
|
_unit disableAI "AUTOTARGET";
|
||||||
|
|
||||||
|
// Run away, erraticly
|
||||||
|
if (leader group _unit != _unit) then {
|
||||||
|
[_unit] join grpNull;
|
||||||
|
};
|
||||||
|
|
||||||
|
_unit doMove ((getPosATL _unit) getPos [20 + random 35, floor (random 360)]);
|
||||||
|
_unit setSpeedMode "FULL";
|
||||||
|
_unit setSuppression 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Play screams and throw weapon (if enabled)
|
||||||
|
_unit call FUNC(burnReaction);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isNull _instigator) then {
|
||||||
|
_unit setVariable [QEGVAR(medical,lastDamageSource), _instigator];
|
||||||
|
_unit setVariable [QEGVAR(medical,lastInstigator), _instigator];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/
|
||||||
|
private _bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3];
|
||||||
|
|
||||||
|
// Keep pain around unconciousness limit to allow for more fun interactions
|
||||||
|
private _damageToAdd = [0.15, _intensity / BURN_MAX_INTENSITY] select (!alive _unit || {GET_PAIN_PERCEIVED(_unit) < (PAIN_UNCONSCIOUS + random 0.2)});
|
||||||
|
|
||||||
|
// Use event directly, as ace_medical_fnc_addDamageToUnit requires unit to be alive
|
||||||
|
[QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, "burn"]] call CBA_fnc_localEvent;
|
||||||
|
|
||||||
|
_unit setVariable [QGVAR(intensity), _intensity, true]; // Globally sync intensity across all clients to make sure simulation is deterministic
|
||||||
|
};
|
||||||
|
}, BURN_PROPAGATE_UPDATE, [_unit, _instigator]] call CBA_fnc_addPerFrameHandler;
|
@ -1,43 +1,48 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: tcvm
|
* Author: tcvm, johnb43
|
||||||
* Handles various fire objects and determines if local units deserves to get burned.
|
* Handles various objects on fire and determines if units close to objects deserve to get burned.
|
||||||
* Used to handle external burning objects, not used internally because internal methods are more performant.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Unit on fire <OBJECT>
|
* None
|
||||||
* 1: PFH Handle <NUMBER>
|
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* [ace_fire_fnc_fireManagerPFH, 0.25, [_unit]] call CBA_fnc_addPerFrameHandler
|
* ace_fire_fnc_fireManagerPFH call CBA_fnc_addPerFrameHandler
|
||||||
*
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params ["_args", "_handle"];
|
{
|
||||||
|
_y params ["_fireLogic", "_radius", "_intensity", "_condition", "_conditionArgs"];
|
||||||
|
TRACE_2("fireManagerPFH loop",_x,_y);
|
||||||
|
|
||||||
[GVAR(fireSources), {
|
// Remove when condition is no longer valid
|
||||||
_value params ["", "", "", "_condition", "_conditionArgs"];
|
if !(_conditionArgs call _condition) then {
|
||||||
_conditionArgs call _condition;
|
TRACE_2("condition no longer valid, deleting",_x,_y);
|
||||||
}] call CBA_fnc_hashFilter;
|
|
||||||
|
|
||||||
[GVAR(fireSources), {
|
detach _fireLogic;
|
||||||
_value params ["_source", "_radius", "_intensity"];
|
deleteVehicle _fireLogic;
|
||||||
private _attachedObject = attachedTo _source;
|
|
||||||
private _sourcePos = getPosATL _source;
|
GVAR(fireSources) deleteAt _x;
|
||||||
if (_attachedObject isNotEqualTo objNull) then {
|
|
||||||
_sourcePos = getPosATL _attachedObject;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
private _nearEntities = _sourcePos nearEntities ["Man", _radius];
|
// Burn units (alive or dead) close to the fire
|
||||||
{
|
{
|
||||||
private _burning = [_x] call FUNC(isBurning);
|
private _distancePercent = 1 - ((_fireLogic distance _x) / _radius);
|
||||||
if !(_burning) then {
|
private _adjustedIntensity = _intensity * _distancePercent;
|
||||||
private _distancePercent = 1 - ((_sourcePos distance _x) / _radius);
|
|
||||||
[QGVAR(burn), [_x, _intensity * _distancePercent]] call CBA_fnc_globalEvent;
|
// Don't burn if intensity is too low or already burning with higher intensity
|
||||||
|
if (BURN_MIN_INTENSITY > _adjustedIntensity || {(_x getVariable [QGVAR(intensity), 0]) > _adjustedIntensity}) then {
|
||||||
|
continue;
|
||||||
};
|
};
|
||||||
} forEach _nearEntities;
|
|
||||||
}] call CBA_fnc_hashEachPair;
|
[QGVAR(burn), [_x, _adjustedIntensity], _x] call CBA_fnc_targetEvent;
|
||||||
|
|
||||||
|
TRACE_3("propagate fire",_x,_intensity,_adjustedIntensity);
|
||||||
|
} forEach nearestObjects [_fireLogic, ["CAManBase"], _radius];
|
||||||
|
} forEach GVAR(fireSources);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: commy2
|
* Author: commy2
|
||||||
* Check if object is burning.
|
* Check if an object is burning.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Vehicle <OBJECT>
|
* 0: Object <OBJECT>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
@ -15,6 +15,6 @@
|
|||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params [["_unit", objNull, [objNull]]];
|
params [["_object", objNull, [objNull]]];
|
||||||
|
|
||||||
_unit getVariable [QGVAR(burning), false]
|
(_object getVariable [QGVAR(intensity), 0]) > BURN_MIN_INTENSITY
|
||||||
|
@ -18,4 +18,4 @@
|
|||||||
|
|
||||||
params ["", "_patient"];
|
params ["", "_patient"];
|
||||||
|
|
||||||
[_patient] call FUNC(isBurning)
|
_patient call FUNC(isBurning)
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Arguments <ARRAY>
|
* 0: Arguments <ARRAY>
|
||||||
* 0: Medic <OBJECT>
|
* - 0: Medic (not used) <OBJECT>
|
||||||
* 1: Patient <OBJECT>
|
* - 1: Patient <OBJECT>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* Continue pat down <BOOL>
|
* Continue pat down <BOOL>
|
||||||
@ -18,6 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
params ["_args"];
|
params ["_args"];
|
||||||
_args params ["_medic", "_patient"];
|
_args params ["", "_patient"];
|
||||||
|
|
||||||
[_patient] call FUNC(isBurning)
|
_patient call FUNC(isBurning)
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
/*
|
/*
|
||||||
* Author: tcvm
|
* Author: tcvm
|
||||||
* Decreases burning intensity on successful medical action.
|
* Decreases burning intensity on successful medical action.
|
||||||
|
* The medical action is looped until the user stops the interaction or the unit is no longer burning.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Medic <OBJECT>
|
* 0: Medic <OBJECT>
|
||||||
* 1: Patient <OBJECT>
|
* 1: Patient <OBJECT>
|
||||||
|
* 2: Body Part <STRING>
|
||||||
|
* 3: Treatment <STRING>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
@ -20,17 +23,21 @@ params ["_medic", "_patient", "_bodyPart", "_classname"];
|
|||||||
|
|
||||||
private _intensity = _patient getVariable [QGVAR(intensity), 0];
|
private _intensity = _patient getVariable [QGVAR(intensity), 0];
|
||||||
_intensity = _intensity * INTENSITY_DECREASE_MULT_PAT_DOWN;
|
_intensity = _intensity * INTENSITY_DECREASE_MULT_PAT_DOWN;
|
||||||
|
|
||||||
_patient setVariable [QGVAR(intensity), _intensity, true];
|
_patient setVariable [QGVAR(intensity), _intensity, true];
|
||||||
|
|
||||||
if (_intensity > BURN_MIN_INTENSITY) then {
|
// If the unit is still burning, loop the medical action
|
||||||
TRACE_1("patient still burning, looping",_this);
|
if !(_patient call FUNC(isBurning)) exitWith {
|
||||||
|
TRACE_1("patient no longer burning, quitting",_this);
|
||||||
|
};
|
||||||
|
|
||||||
if (EGVAR(medical_gui,pendingReopen)) then {
|
TRACE_1("patient still burning, looping",_this);
|
||||||
LOG("temporarily blocking medical menu reopen");
|
|
||||||
|
if (EGVAR(medical_gui,pendingReopen)) then {
|
||||||
|
TRACE_1("temporarily blocking medical menu reopen",_this);
|
||||||
|
|
||||||
EGVAR(medical_gui,pendingReopen) = false;
|
EGVAR(medical_gui,pendingReopen) = false;
|
||||||
[{EGVAR(medical_gui,pendingReopen) = true}] call CBA_fnc_execNextFrame;
|
[{EGVAR(medical_gui,pendingReopen) = true}] call CBA_fnc_execNextFrame;
|
||||||
};
|
|
||||||
|
|
||||||
[_medic, _patient, _bodyPart, _classname] call EFUNC(medical_treatment,treatment);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[_medic, _patient, _bodyPart, _classname] call EFUNC(medical_treatment,treatment);
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
[
|
[
|
||||||
QGVAR(enabled), "CHECKBOX",
|
QGVAR(enabled),
|
||||||
|
"CHECKBOX",
|
||||||
[ELSTRING(common,Enabled), LSTRING(Setting_Description)],
|
[ELSTRING(common,Enabled), LSTRING(Setting_Description)],
|
||||||
LSTRING(Category_DisplayName),
|
LSTRING(Category_DisplayName),
|
||||||
true, // default value
|
true,
|
||||||
true, // isGlobal
|
1,
|
||||||
{[QGVAR(fireEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
{[QGVAR(fireEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||||
true // Needs mission restart
|
true // Needs mission restart
|
||||||
] call CBA_fnc_addSetting;
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
[
|
[
|
||||||
QGVAR(enableFlare), "CHECKBOX",
|
QGVAR(enableFlare),
|
||||||
|
"CHECKBOX",
|
||||||
[LSTRING(Setting_FlareEnable), LSTRING(Setting_FlareDescription)],
|
[LSTRING(Setting_FlareEnable), LSTRING(Setting_FlareDescription)],
|
||||||
LSTRING(Category_DisplayName),
|
LSTRING(Category_DisplayName),
|
||||||
false, // default value
|
false,
|
||||||
true, // isGlobal
|
1
|
||||||
{[QGVAR(flareEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
|
||||||
true // Needs mission restart
|
|
||||||
] call CBA_fnc_addSetting;
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
[
|
[
|
||||||
QGVAR(dropWeapon), "LIST",
|
QGVAR(dropWeapon),
|
||||||
|
"LIST",
|
||||||
[LSTRING(Setting_DropWeapon), LSTRING(Setting_DropWeapon_Description)],
|
[LSTRING(Setting_DropWeapon), LSTRING(Setting_DropWeapon_Description)],
|
||||||
LSTRING(Category_DisplayName),
|
LSTRING(Category_DisplayName),
|
||||||
[
|
[
|
||||||
[0,1,2],
|
[0, 1, 2],
|
||||||
[localize "STR_A3_OPTIONS_DISABLED", ELSTRING(common,aiOnly), ELSTRING(common,playersAndAI)],
|
["STR_A3_OPTIONS_DISABLED", ELSTRING(common,aiOnly), ELSTRING(common,playersAndAI)],
|
||||||
1
|
1
|
||||||
],
|
],
|
||||||
true // isGlobal
|
1
|
||||||
] call CBA_fnc_addSetting;
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
[
|
[
|
||||||
QGVAR(enableScreams), "CHECKBOX",
|
QGVAR(enableScreams),
|
||||||
|
"CHECKBOX",
|
||||||
[LSTRING(Setting_EnableScreams), LSTRING(Setting_EnableScreams_Description)],
|
[LSTRING(Setting_EnableScreams), LSTRING(Setting_EnableScreams_Description)],
|
||||||
LSTRING(Category_DisplayName),
|
LSTRING(Category_DisplayName),
|
||||||
true,
|
true
|
||||||
false // isGlobal
|
|
||||||
] call CBA_fnc_addSetting;
|
] call CBA_fnc_addSetting;
|
||||||
|
|
||||||
|
@ -31,9 +31,14 @@
|
|||||||
"amovppnemstpsoptwbindnon_amovppnemevasoptwbindr"\
|
"amovppnemstpsoptwbindnon_amovppnemevasoptwbindr"\
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
#define BURN_MAX_INTENSITY 10
|
#define BURN_MAX_INTENSITY 10
|
||||||
#define BURN_MIN_INTENSITY 1
|
#define BURN_MIN_INTENSITY 1
|
||||||
|
|
||||||
#define INTENSITY_DECREASE_MULT_PAT_DOWN 0.8
|
#define INTENSITY_DECREASE_MULT_PAT_DOWN 0.8
|
||||||
#define INTENSITY_DECREASE_MULT_ROLLING INTENSITY_DECREASE_MULT_PAT_DOWN
|
#define INTENSITY_DECREASE_MULT_ROLLING INTENSITY_DECREASE_MULT_PAT_DOWN
|
||||||
|
|
||||||
|
#define INTENSITY_LOSS 0.02
|
||||||
|
#define INTENSITY_UPDATE 2
|
||||||
|
#define BURN_PROPAGATE_UPDATE 1
|
||||||
|
#define BURN_PROPAGATE_DISTANCE 2
|
||||||
|
#define BURN_THRESHOLD_INTENSE 3
|
||||||
|
@ -17,26 +17,22 @@
|
|||||||
|
|
||||||
params ["_logic"];
|
params ["_logic"];
|
||||||
|
|
||||||
if !(local _logic) exitWith {};
|
if (!local _logic) exitWith {};
|
||||||
|
|
||||||
private _unit = attachedTo _logic;
|
private _unit = attachedTo _logic;
|
||||||
deleteVehicle _logic;
|
deleteVehicle _logic;
|
||||||
|
|
||||||
switch (false) do {
|
switch (false) do {
|
||||||
case !(isNull _unit): {
|
case (!isNull _unit): {
|
||||||
[LSTRING(NothingSelected)] call FUNC(showMessage);
|
[LSTRING(NothingSelected)] call FUNC(showMessage);
|
||||||
};
|
};
|
||||||
case (_unit isKindOf "CAManBase"): {
|
case (_unit isKindOf "CAManBase" && {getNumber (configOf _unit >> "isPlayableLogic") == 0}): {
|
||||||
[LSTRING(OnlyInfantry)] call FUNC(showMessage);
|
[LSTRING(OnlyInfantry)] call FUNC(showMessage);
|
||||||
};
|
};
|
||||||
case (alive _unit): {
|
|
||||||
[LSTRING(OnlyAlive)] call FUNC(showMessage);
|
|
||||||
};
|
|
||||||
case (["ace_fire"] call EFUNC(common,isModLoaded)): {
|
case (["ace_fire"] call EFUNC(common,isModLoaded)): {
|
||||||
[LSTRING(RequiresAddon)] call FUNC(showMessage);
|
[LSTRING(RequiresAddon)] call FUNC(showMessage);
|
||||||
};
|
};
|
||||||
default {
|
default {
|
||||||
[QEGVAR(fire,burn), [_unit, 5]] call CBA_fnc_globalEvent;
|
[QEGVAR(fire,burn), [_unit, 5], _unit] call CBA_fnc_targetEvent;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ Use `CBA_fnc_serverEvent` to use the following features. Events are defined only
|
|||||||
| 0 | Source of flame | Object/Position ASL | Required |
|
| 0 | Source of flame | Object/Position ASL | Required |
|
||||||
| 1 | Radius of fire | Number | Required |
|
| 1 | Radius of fire | Number | Required |
|
||||||
| 2 | Intensity of fire (1, 10] | Number | Required |
|
| 2 | Intensity of fire (1, 10] | Number | Required |
|
||||||
| 3 | Fire source ID | Any | Required |
|
| 3 | Fire source ID | Array/Boolean/Code/Config/Group/Namespace/NaN/Number/Object/Side/String | Required |
|
||||||
| 4 | Condition to stop fire | Code | Optional (default: `{ true }`) |
|
| 4 | Condition to stop fire | Code | Optional (default: `{true}`) |
|
||||||
| 5 | Arguments to pass to condition | Any | Optional (default: `[]`) |
|
| 5 | Arguments to pass to condition | Any | Optional (default: `[]`) |
|
||||||
|
|
||||||
### 1.2 Removing fire source
|
### 1.2 Removing fire source
|
||||||
@ -36,8 +36,7 @@ Use `CBA_fnc_serverEvent` to use the following features. Events are defined only
|
|||||||
|
|
||||||
| | Arguments | Type | Optional (default value) |
|
| | Arguments | Type | Optional (default value) |
|
||||||
|----| --------- | ---- | ------------------------ |
|
|----| --------- | ---- | ------------------------ |
|
||||||
| 0 | Fire source ID | Any | Required |
|
| 0 | Fire source ID | Array/Boolean/Code/Config/Group/Namespace/NaN/Number/Object/Side/String | Required |
|
||||||
|
|
||||||
|
|
||||||
## 2. Variables
|
## 2. Variables
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user