mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Add Fire component (#8245)
* merge fire * Change required addons. Change getPos to getPosASL. Remove include * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Kyle Mckay <kymckay.dev@gmail.com> * Update addons/fire/stringtable.xml Co-authored-by: jonpas <jonpas33@gmail.com> Co-authored-by: Kyle Mckay <kymckay.dev@gmail.com>
This commit is contained in:
parent
7009404d39
commit
caca92f71d
1
addons/fire/$PBOPREFIX$
Normal file
1
addons/fire/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\fire
|
20
addons/fire/ACE_Medical_Treatment_Actions.hpp
Normal file
20
addons/fire/ACE_Medical_Treatment_Actions.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
class EGVAR(medical_treatment,actions) {
|
||||
class BasicBandage;
|
||||
class PatDown: BasicBandage {
|
||||
displayName = CSTRING(Actions_PatDown);
|
||||
displayNameProgress = CSTRING(Actions_PerformingPatDown);
|
||||
icon = "";
|
||||
category = "advanced";
|
||||
treatmentLocations = 0;
|
||||
allowedSelections[] = {"All"};
|
||||
allowSelfTreatment = 1;
|
||||
medicRequired = 0;
|
||||
treatmentTime = 5;
|
||||
items[] = {};
|
||||
condition = QFUNC(medical_canPatDown);
|
||||
callbackSuccess = QFUNC(medical_success);
|
||||
callbackProgress = QFUNC(medical_progress);
|
||||
consumeItem = 0;
|
||||
litter[] = {};
|
||||
};
|
||||
};
|
17
addons/fire/CfgEventHandlers.hpp
Normal file
17
addons/fire/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
class Extended_PreStart_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PreInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preInit));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PostInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_postInit));
|
||||
};
|
||||
};
|
26
addons/fire/CfgSounds.hpp
Normal file
26
addons/fire/CfgSounds.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// weird ass concatenation syntax. PBO Project complains otherwise...
|
||||
#define CONCAT(a,b) a####b
|
||||
#define CREATE_SCREAM(no)\
|
||||
class GVAR(DOUBLES(scream,no)) { \
|
||||
name = QUOTE(GVAR(CONCAT(scream,no)));\
|
||||
sound[] = {QUOTE(PATHTOF(CONCAT(sounds\scream,no).ogg)), db + 8, 1};\
|
||||
titles[] = {}; \
|
||||
}
|
||||
|
||||
class CfgSounds {
|
||||
CREATE_SCREAM(1);
|
||||
CREATE_SCREAM(2);
|
||||
CREATE_SCREAM(3);
|
||||
CREATE_SCREAM(4);
|
||||
CREATE_SCREAM(5);
|
||||
CREATE_SCREAM(6);
|
||||
CREATE_SCREAM(7);
|
||||
CREATE_SCREAM(8);
|
||||
CREATE_SCREAM(9);
|
||||
CREATE_SCREAM(10);
|
||||
CREATE_SCREAM(11);
|
||||
CREATE_SCREAM(12);
|
||||
CREATE_SCREAM(13);
|
||||
CREATE_SCREAM(14);
|
||||
CREATE_SCREAM(15);
|
||||
};
|
41
addons/fire/RscTitles.hpp
Normal file
41
addons/fire/RscTitles.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
class RscTitles {
|
||||
class RscPicture;
|
||||
class GVAR(onFire1) {
|
||||
idd = -1;
|
||||
movingEnable = "true";
|
||||
duration = 0.1;
|
||||
fadein = 0.15;
|
||||
fadeout = 0.75;
|
||||
name = QGVAR(onFire1);
|
||||
onload = QUOTE(with uiNamespace do {GVAR(onFireIndicator1) = _this select 0});
|
||||
|
||||
class controls {
|
||||
class GVAR(indicator): RscPicture {
|
||||
idc = -1;
|
||||
type = 0;
|
||||
style = 48;
|
||||
colorBackground[] = {0, 0, 0, 0};
|
||||
colorText[] = {0.9, 0.9, 0.9, 0.6};
|
||||
font = "LucidaConsoleB";
|
||||
sizeEx = 0.023;
|
||||
x = "SafeZoneX";
|
||||
y = "SafeZoneY";
|
||||
w = "SafeZoneW + 0.05";
|
||||
h = "SafeZoneH + 0.05";
|
||||
text = PATHTOF(data\overlay_burn_1.paa);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class GVAR(onFire2): GVAR(onFire1) {
|
||||
idd = -1;
|
||||
name = QGVAR(onFire2);
|
||||
onload = QUOTE(with uiNamespace do {GVAR(onFireIndicator2) = _this select 0});
|
||||
|
||||
class controls: controls {
|
||||
class GVAR(indicator): GVAR(indicator) {
|
||||
text = PATHTOF(data\overlay_burn_2.paa);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
9
addons/fire/XEH_PREP.hpp
Normal file
9
addons/fire/XEH_PREP.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
PREP(burn);
|
||||
PREP(isBurning);
|
||||
PREP(isPlant);
|
||||
PREP(burnIndicator);
|
||||
PREP(fireManagerPFH);
|
||||
|
||||
PREP(medical_progress);
|
||||
PREP(medical_success);
|
||||
PREP(medical_canPatDown);
|
34
addons/fire/XEH_postInit.sqf
Normal file
34
addons/fire/XEH_postInit.sqf
Normal file
@ -0,0 +1,34 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
[QGVAR(burn), FUNC(burn)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(playScream), {
|
||||
params ["_scream", "_source"];
|
||||
_source say3D _scream;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
["ace_settingsInitialized", {
|
||||
TRACE_1("settingsInit", GVAR(enabled));
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
if (isServer) then {
|
||||
[QGVAR(addFireSource), {
|
||||
params ["_source", "_radius", "_intensity", "_key", ["_condition", { true }], ["_conditionArgs", []]];
|
||||
private _fireLogic = createVehicle ["ACE_LogicDummy", [0, 0, 0], [], 0, "NONE"];
|
||||
if (_source isEqualType objNull) then {
|
||||
_fireLogic attachTo [_source];
|
||||
} else {
|
||||
_fireLogic setPosASL _source;
|
||||
};
|
||||
|
||||
[GVAR(fireSources), _key, [_fireLogic, _radius, _intensity, _condition, _conditionArgs]] call CBA_fnc_hashSet;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
[QGVAR(removeFireSource), {
|
||||
params ["_key"];
|
||||
[GVAR(fireSources), _key] call CBA_fnc_hashRem;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
[{ _this call FUNC(fireManagerPFH) }, FIRE_MANAGER_PFH_DELAY, []] call CBA_fnc_addPerFrameHandler;
|
||||
GVAR(fireSources) = [[], nil] call CBA_fnc_hashCreate;
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
13
addons/fire/XEH_preInit.sqf
Normal file
13
addons/fire/XEH_preInit.sqf
Normal file
@ -0,0 +1,13 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
ADDON = false;
|
||||
|
||||
PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
#include "initSettings.sqf"
|
||||
|
||||
GVAR(burningPlants) = [];
|
||||
|
||||
ADDON = true;
|
3
addons/fire/XEH_preStart.sqf
Normal file
3
addons/fire/XEH_preStart.sqf
Normal file
@ -0,0 +1,3 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
#include "XEH_PREP.hpp"
|
20
addons/fire/config.cpp
Normal file
20
addons/fire/config.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
name = COMPONENT_NAME;
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ace_common", "ace_medical_engine"};
|
||||
author = ECSTRING(common,ACETeam);
|
||||
authors[] = {"commy2", "Brandon (TCVM)"};
|
||||
url = ECSTRING(main,URL);
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgSounds.hpp"
|
||||
#include "ACE_Medical_Treatment_Actions.hpp"
|
||||
#include "RscTitles.hpp"
|
BIN
addons/fire/data/overlay_burn_1.paa
Normal file
BIN
addons/fire/data/overlay_burn_1.paa
Normal file
Binary file not shown.
BIN
addons/fire/data/overlay_burn_2.paa
Normal file
BIN
addons/fire/data/overlay_burn_2.paa
Normal file
Binary file not shown.
348
addons/fire/functions/fnc_burn.sqf
Normal file
348
addons/fire/functions/fnc_burn.sqf
Normal file
@ -0,0 +1,348 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Makes object catch fire. Only call from events. Local effects only.
|
||||
* Arbitrary values to ignite people. Assumed maximum is "10".
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Vehicle <OBJECT>
|
||||
* 1: Intensity of fire <NUMBER>
|
||||
* 2: Instigator of fire <OBJECT> (default: objNull)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, 4] call ace_fire_fnc_burn
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
#define INTENSITY_LOSS 0.03
|
||||
#define INTENSITY_UPDATE 3
|
||||
#define BURN_PROPOGATE_UPDATE 1
|
||||
#define BURN_PROPOGATE_DISTANCE 2
|
||||
#define BURN_PROPOGATE_COUNTER_MAX 5
|
||||
#define MAX_INTENSITY 10
|
||||
#define MIN_INTENSITY 1
|
||||
|
||||
params ["_unit", "_intensity", ["_instigator", objNull]];
|
||||
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
private _isBurning = [_unit] call FUNC(isBurning);
|
||||
if (_isBurning) exitWith {};
|
||||
|
||||
[{
|
||||
// looped function
|
||||
(_this getVariable "params") params ["_unit", "", "_instigator"];
|
||||
private _unitPos = getPosASL _unit;
|
||||
|
||||
_intensity = _unit getVariable [QGVAR(intensity), 0];
|
||||
|
||||
if (surfaceIsWater _unitPos && {(_unitPos#2) < 1}) then {
|
||||
_intensity = 0;
|
||||
};
|
||||
|
||||
_fireParticle setDropInterval (0.01 max linearConversion [MAX_INTENSITY, 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 * _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]];
|
||||
_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);
|
||||
_lightFlare setLightBrightness (_intensity / 30);
|
||||
|
||||
private _distanceToUnit = (_unit distance ace_player);
|
||||
_fireLight setLightAttenuation [1, 10 max (5 min (10 - _intensity)), 0, 15];
|
||||
_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 isnt the player
|
||||
if !(_unit isEqualTo ace_player) then {
|
||||
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];
|
||||
};
|
||||
|
||||
if (!isGamePaused) then {
|
||||
// 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 isEqualTo ace_player) }) then {
|
||||
private _burnCounter = ace_player 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;
|
||||
};
|
||||
ace_player 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, but if its too high this wont do anything substantial
|
||||
_intensity = _intensity - (1 / _intensity);
|
||||
};
|
||||
};
|
||||
|
||||
if ((_unit isEqualTo vehicle _unit) && { !(currentWeapon _unit isEqualTo "") }) then {
|
||||
[_unit] call EFUNC(hitreactions,throwWeapon);
|
||||
};
|
||||
|
||||
private _soundID = floor (1 + random 15);
|
||||
private _sound = format [QGVAR(scream_%1), _soundID];
|
||||
[QGVAR(playScream), [_sound, _unit]] call CBA_fnc_globalEvent;
|
||||
};
|
||||
|
||||
// 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 / MAX_INTENSITY, _woundSelection, "burn", _instigator] call EFUNC(medical,addDamageToUnit);
|
||||
} else {
|
||||
[_unit, 0.15, _woundSelection, "unknown", _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 = [FUNC(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 isEqualTo 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], "destructionEffect1"];
|
||||
};
|
||||
|
||||
_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 = [FUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler;
|
||||
_unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH];
|
||||
};
|
||||
|
||||
private _soundID = floor (1 + random 15);
|
||||
private _sound = format [QGVAR(scream_%1), _soundID];
|
||||
[QGVAR(playScream), [_sound, _unit]] call CBA_fnc_globalEvent;
|
||||
};
|
||||
|
||||
_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];
|
||||
}, {
|
||||
// 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 <= MIN_INTENSITY } || { !([_unit] call FUNC(isBurning)) }
|
||||
}, ["_intensity", "_fireParticle", "_smokeParticle", "_fireLight", "_fireSound", "_lightFlare", "_lastIntensityUpdate", "_lastPropogateUpdate", "_isThisUnitAlive"]] call CBA_fnc_createPerFrameHandlerObject;
|
36
addons/fire/functions/fnc_burnIndicator.sqf
Normal file
36
addons/fire/functions/fnc_burnIndicator.sqf
Normal file
@ -0,0 +1,36 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Run once per second in a PFH. Update screen effects with burn indicator.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit on fire <OBJECT>
|
||||
* 1: PFH Handle <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, 4] call ace_fire_fnc_burnIndicator
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_unit", "_pfhHandle"];
|
||||
|
||||
if !(IS_UNCONSCIOUS(_unit)) then {
|
||||
private _iteration = _unit getVariable [QGVAR(indicatorIteration), 0];
|
||||
if (_iteration == 0) then {
|
||||
QGVAR(indicatorLayer) cutRsc [QGVAR(onFire1), "PLAIN"];
|
||||
_iteration = 1;
|
||||
} else {
|
||||
QGVAR(indicatorLayer) cutRsc [QGVAR(onFire2), "PLAIN"];
|
||||
_iteration = 0;
|
||||
};
|
||||
_unit setVariable [QGVAR(indicatorIteration), _iteration];
|
||||
};
|
||||
|
||||
if (!([_unit] call FUNC(isBurning)) || { !alive _unit }) then {
|
||||
[_pfhHandle] call CBA_fnc_removePerFrameHandler;
|
||||
_unit setVariable [QGVAR(burnUIPFH), -1];
|
||||
};
|
43
addons/fire/functions/fnc_fireManagerPFH.sqf
Normal file
43
addons/fire/functions/fnc_fireManagerPFH.sqf
Normal file
@ -0,0 +1,43 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Handles various fire objects and determines if local units deserves to get burned.
|
||||
* Used to handle external burning objects, not used internally because internal methods are more performant.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit on fire <OBJECT>
|
||||
* 1: PFH Handle <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [FUNC(fireManagerPFH), 0.25, [_unit]] call CBA_fnc_addPerFrameHandler
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_args", "_handle"];
|
||||
|
||||
[GVAR(fireSources), {
|
||||
_value params ["", "", "", "_condition", "_conditionArgs"];
|
||||
_conditionArgs call _condition;
|
||||
}] call CBA_fnc_hashFilter;
|
||||
|
||||
[GVAR(fireSources), {
|
||||
_value params ["_source", "_radius", "_intensity"];
|
||||
private _attachedObject = attachedTo _source;
|
||||
private _sourcePos = getPosATL _source;
|
||||
if !(_attachedObject isEqualTo objNull) then {
|
||||
_sourcePos = getPosATL _attachedObject;
|
||||
};
|
||||
|
||||
private _nearEntities = _sourcePos nearEntities ["Man", _radius];
|
||||
{
|
||||
private _burning = [_x] call FUNC(isBurning);
|
||||
if !(_burning) then {
|
||||
private _distancePercent = 1 - ((_sourcePos distance _x) / _radius);
|
||||
[QGVAR(burn), [_x, _intensity * _distancePercent]] call CBA_fnc_globalEvent;
|
||||
};
|
||||
} forEach _nearEntities;
|
||||
}] call CBA_fnc_hashEachPair;
|
23
addons/fire/functions/fnc_isBurning.sqf
Normal file
23
addons/fire/functions/fnc_isBurning.sqf
Normal file
@ -0,0 +1,23 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: commy2
|
||||
* Check if object is burning.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Vehicle <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* player call ace_fire_fnc_isBurning
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_unit", objNull, [objNull]]];
|
||||
|
||||
_unit getVariable [QGVAR(burning), false] || {
|
||||
GVAR(burningPlants) = GVAR(burningPlants) select {!isNull _x};
|
||||
_unit in GVAR(burningPlants)
|
||||
}
|
20
addons/fire/functions/fnc_isPlant.sqf
Normal file
20
addons/fire/functions/fnc_isPlant.sqf
Normal file
@ -0,0 +1,20 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: commy2
|
||||
* Check if object is a map placed bush or tree.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Object <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Is bush or tree? <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* cursorObject call ace_fire_fnc_isPlant
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params [["_object", objNull, [objNull]]];
|
||||
|
||||
_object in nearestTerrainObjects [_object, ["TREE", "SMALL TREE", "BUSH"], 0.1]
|
21
addons/fire/functions/fnc_medical_canPatDown.sqf
Normal file
21
addons/fire/functions/fnc_medical_canPatDown.sqf
Normal file
@ -0,0 +1,21 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Returns if unit can pat down fire or not.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Medic (not used) <OBJECT>
|
||||
* 1: Patient <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can Pat-Down <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [nil, player] call ace_fire_fnc_medical_canPatDown
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["", "_patient"];
|
||||
|
||||
[_patient] call FUNC(isBurning)
|
23
addons/fire/functions/fnc_medical_progress.sqf
Normal file
23
addons/fire/functions/fnc_medical_progress.sqf
Normal file
@ -0,0 +1,23 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Checks if patient is still burning for medical progress to continue.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Arguments <ARRAY>
|
||||
* 0: Medic <OBJECT>
|
||||
* 1: Patient <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Continue pat down <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [[player, cursorObject]] call ace_fire_fnc_medical_progress
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_args"];
|
||||
_args params ["_medic", "_patient"];
|
||||
|
||||
[_patient] call FUNC(isBurning)
|
23
addons/fire/functions/fnc_medical_success.sqf
Normal file
23
addons/fire/functions/fnc_medical_success.sqf
Normal file
@ -0,0 +1,23 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Decreases burning intensity on successful medical action.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Medic <OBJECT>
|
||||
* 1: Patient <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, cursorObject] call ace_fire_fnc_medical_success
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_medic", "_patient"];
|
||||
|
||||
private _intensity = _patient getVariable [QGVAR(intensity), 0];
|
||||
_intensity = _intensity * (4/5);
|
||||
_patient setVariable [QGVAR(intensity), _intensity, true];
|
1
addons/fire/functions/script_component.hpp
Normal file
1
addons/fire/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\fire\script_component.hpp"
|
19
addons/fire/initSettings.sqf
Normal file
19
addons/fire/initSettings.sqf
Normal file
@ -0,0 +1,19 @@
|
||||
[
|
||||
QGVAR(enabled), "CHECKBOX",
|
||||
["STR_A3_OPTIONS_ENABLED", LSTRING(setting_description)],
|
||||
LSTRING(category_displayName),
|
||||
true, // default value
|
||||
true, // isGlobal
|
||||
{[QGVAR(fireEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||
true // Needs mission restart
|
||||
] call CBA_settings_fnc_init;
|
||||
|
||||
[
|
||||
QGVAR(enableFlare), "CHECKBOX",
|
||||
[LSTRING(setting_flareEnable), LSTRING(setting_flareDescription)],
|
||||
LSTRING(category_displayName),
|
||||
false, // default value
|
||||
true, // isGlobal
|
||||
{[QGVAR(flareEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||
true // Needs mission restart
|
||||
] call CBA_settings_fnc_init;
|
32
addons/fire/script_component.hpp
Normal file
32
addons/fire/script_component.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#define COMPONENT fire
|
||||
#define COMPONENT_BEAUTIFIED Fire
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
// #define DEBUG_MODE_FULL
|
||||
// #define DISABLE_COMPILE_CACHE
|
||||
// #define CBA_DEBUG_SYNCHRONOUS
|
||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||
|
||||
#ifdef DEBUG_ENABLED_FIRE
|
||||
#define DEBUG_MODE_FULL
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SETTINGS_FIRE
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_FIRE
|
||||
#endif
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
|
||||
|
||||
#define FIRE_MANAGER_PFH_DELAY 0.25
|
||||
#define FLARE_SIZE_MODIFIER 5
|
||||
#define PRONE_ROLLING_ANIMS [\
|
||||
"amovppnemstpsnonwnondnon_amovppnemevasnonwnondl",\
|
||||
"amovppnemstpsnonwnondnon_amovppnemevasnonwnondr",\
|
||||
"amovppnemstpsraswrfldnon_amovppnemevaslowwrfldl",\
|
||||
"amovppnemstpsraswrfldnon_amovppnemevaslowwrfldr",\
|
||||
"amovppnemstpsraswpstdnon_amovppnemevaslowwpstdl",\
|
||||
"amovppnemstpsraswpstdnon_amovppnemevaslowwpstdr",\
|
||||
"amovppnemstpsoptwbindnon_amovppnemevasoptwbindl",\
|
||||
"amovppnemstpsoptwbindnon_amovppnemevasoptwbindr"\
|
||||
]
|
BIN
addons/fire/sounds/scream1.ogg
Normal file
BIN
addons/fire/sounds/scream1.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream10.ogg
Normal file
BIN
addons/fire/sounds/scream10.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream11.ogg
Normal file
BIN
addons/fire/sounds/scream11.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream12.ogg
Normal file
BIN
addons/fire/sounds/scream12.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream13.ogg
Normal file
BIN
addons/fire/sounds/scream13.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream14.ogg
Normal file
BIN
addons/fire/sounds/scream14.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream15.ogg
Normal file
BIN
addons/fire/sounds/scream15.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream2.ogg
Normal file
BIN
addons/fire/sounds/scream2.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream3.ogg
Normal file
BIN
addons/fire/sounds/scream3.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream4.ogg
Normal file
BIN
addons/fire/sounds/scream4.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream5.ogg
Normal file
BIN
addons/fire/sounds/scream5.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream6.ogg
Normal file
BIN
addons/fire/sounds/scream6.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream7.ogg
Normal file
BIN
addons/fire/sounds/scream7.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream8.ogg
Normal file
BIN
addons/fire/sounds/scream8.ogg
Normal file
Binary file not shown.
BIN
addons/fire/sounds/scream9.ogg
Normal file
BIN
addons/fire/sounds/scream9.ogg
Normal file
Binary file not shown.
23
addons/fire/stringtable.xml
Normal file
23
addons/fire/stringtable.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="ACE">
|
||||
<Package name="Fire">
|
||||
<Key ID="STR_ACE_Fire_category_displayName">
|
||||
<English>ACE Fire</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Fire_Actions_PatDown">
|
||||
<English>Pat Down Fire</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Fire_Actions_PerformingPatDown">
|
||||
<English>Patting Down Fire</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Fire_setting_description">
|
||||
<English>Allow units to catch fire</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Fire_setting_flareEnable">
|
||||
<English>Enable fire-flare at night</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Fire_setting_flareDescription">
|
||||
<English>Uses a flare effect to increase fire intensity at night</English>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user