mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Fire deals more damage
This commit is contained in:
parent
ccb09e60d7
commit
41bd5bf5c3
@ -38,7 +38,7 @@ if (isServer) then {
|
||||
};
|
||||
|
||||
if (_ring) then {
|
||||
private _intensity = 6;
|
||||
private _intensity = 20;
|
||||
private _radius = 1.5 * ((boundingBoxReal _obj) select 2);
|
||||
[QEGVAR(fire,addFireSource), [_obj, _radius, _intensity, format [QGVAR(%1), hashValue _obj]]] call CBA_fnc_localEvent;
|
||||
};
|
||||
|
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 = "";
|
||||
};
|
||||
};
|
@ -2,6 +2,7 @@
|
||||
|
||||
[QGVAR(burn), LINKFUNC(burn)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(burnEffects), LINKFUNC(burnEffects)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(burnObjectEffects), LINKFUNC(burnObjectEffects)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(burnSimulation), LINKFUNC(burnSimulation)] call CBA_fnc_addEventHandler;
|
||||
|
||||
// Only play sound if enabled in settings
|
||||
@ -22,23 +23,67 @@ if (isServer) then {
|
||||
GVAR(fireSources) = createHashMap;
|
||||
|
||||
[QGVAR(addFireSource), {
|
||||
params ["_source", "_radius", "_intensity", "_key", ["_condition", {true}], ["_conditionArgs", []]];
|
||||
params [
|
||||
["_source", objNull, [objNull, []]],
|
||||
["_radius", 0, [0]],
|
||||
["_intensity", 0, [0]],
|
||||
["_key", ""],
|
||||
["_condition", {true}],
|
||||
["_conditionArgs", []]
|
||||
];
|
||||
|
||||
private _fireLogic = createVehicle ["ACE_LogicDummy", [0, 0, 0], [], 0, "NONE"];
|
||||
private _isObject = _source isEqualType objNull;
|
||||
|
||||
if (_source isEqualType objNull) then {
|
||||
_fireLogic attachTo [_source];
|
||||
// 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
|
||||
|
||||
// If a position is passed, create a static object at said position
|
||||
private _sourcePos = if (_isObject) then {
|
||||
getPosATL _source
|
||||
} else {
|
||||
_fireLogic setPosASL _source;
|
||||
ASLToATL _source
|
||||
};
|
||||
|
||||
GVAR(fireSources) set [_key, [_fireLogic, _radius, _intensity, _condition, _conditionArgs]];
|
||||
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];
|
||||
};
|
||||
|
||||
// hashValue supports more types than hashmaps do by default, but not all (e.g. locations)
|
||||
private _hashedKey = hashValue _key;
|
||||
|
||||
if (isNil "_hashedKey") exitWith {
|
||||
ERROR_1("Unsupported key type used: %1",_key)
|
||||
};
|
||||
|
||||
// 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;
|
||||
|
||||
[QGVAR(removeFireSource), {
|
||||
params ["_key"];
|
||||
|
||||
GVAR(fireSources) deleteAt _key;
|
||||
private _hashedKey = hashValue _key;
|
||||
|
||||
if (isNil "_hashedKey") exitWith {
|
||||
ERROR_1("Unsupported key type used: %1",_key)
|
||||
};
|
||||
|
||||
(GVAR(fireSources) deleteAt _hashedKey) params [["_fireLogic", objNull]];
|
||||
|
||||
// Deleting the object will automatically remove any particles (if there are any)
|
||||
detach _fireLogic;
|
||||
deleteVehicle _fireLogic;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
[LINKFUNC(fireManagerPFH), FIRE_MANAGER_PFH_DELAY, []] call CBA_fnc_addPerFrameHandler;
|
||||
|
@ -24,6 +24,7 @@ class CfgPatches {
|
||||
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgSounds.hpp"
|
||||
#include "CfgVehicles.hpp"
|
||||
#include "ACE_Medical_Treatment_Actions.hpp"
|
||||
#include "RscTitles.hpp"
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: tcvm, johnb43
|
||||
* Makes object catch fire. Only call from targeted events, is applied globally.
|
||||
* Author: johnb43
|
||||
* Makes a unit catch fire. Only call from targeted events, is applied globally.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Vehicle <OBJECT>
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Intensity of fire <NUMBER>
|
||||
* 2: Instigator of fire <OBJECT> (default: objNull)
|
||||
*
|
||||
@ -25,31 +25,35 @@ if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
params ["_unit", "_intensity", ["_instigator", objNull]];
|
||||
|
||||
if (BURN_MIN_INTENSITY > _intensity) exitWith {};
|
||||
|
||||
// Check if unit is remote (objNull is remote)
|
||||
if (!local _unit) exitWith {};
|
||||
|
||||
// Check if the unit can burn (takes care of spectators and curators)
|
||||
if (getNumber (configOf _unit >> "isPlayableLogic") == 1) exitWith {};
|
||||
if (getNumber (configOf _unit >> "isPlayableLogic") == 1 || {!(_unit isKindOf "CAManBase")}) exitWith {};
|
||||
|
||||
// If unit is invulnerable, don't burn unit
|
||||
// If unit is invulnerable, don't burn the unit
|
||||
if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {};
|
||||
|
||||
// If unit is already burning, don't burn more
|
||||
if (_unit call FUNC(isBurning)) exitWith {};
|
||||
private _unitPos = getPosASL _unit;
|
||||
|
||||
// Check if unit is in water
|
||||
if (surfaceIsWater _unitPos && {(_unitPos select 2) < 1}) exitWith {};
|
||||
|
||||
// If unit is already burning, update intensity, but don't add another PFH
|
||||
if (_unit call FUNC(isBurning)) exitWith {
|
||||
_unit setVariable [QGVAR(intensity), _intensity, true];
|
||||
};
|
||||
|
||||
_unit setVariable [QGVAR(intensity), _intensity, true];
|
||||
|
||||
// Fire simulation
|
||||
private _burnSimulationJipID = [QGVAR(burnSimulation), [_unit, _instigator], format [QGVAR(burnSimulation_%1), hashValue _unit]] call CBA_fnc_globalEventJIP;
|
||||
// Fire simulation (objects are handled differently)
|
||||
private _burnSimulationJipID = [QGVAR(burnSimulation), [_unit, _instigator]] call CBA_fnc_globalEventJIP;
|
||||
[_burnSimulationJipID, _unit] call CBA_fnc_removeGlobalEventJIP;
|
||||
|
||||
// Spawn effects for unit
|
||||
private _burnEffectsJipID = [QGVAR(burnEffects), _unit, format [QGVAR(burnEffects_%1), hashValue _unit]] call CBA_fnc_globalEventJIP;
|
||||
private _burnEffectsJipID = [QGVAR(burnEffects), _unit] call CBA_fnc_globalEventJIP;
|
||||
[_burnEffectsJipID, _unit] call CBA_fnc_removeGlobalEventJIP;
|
||||
|
||||
_unit setVariable [QGVAR(jipIDs), [_burnSimulationJipID, _burnEffectsJipID], true];
|
||||
|
||||
// Play screams and optional weapon dropping
|
||||
if (_unit call EFUNC(common,isAwake)) then {
|
||||
[_unit, false] call FUNC(burnReaction);
|
||||
};
|
||||
|
@ -26,7 +26,7 @@ private _lightFlare = objNull;
|
||||
|
||||
if (hasInterface) then {
|
||||
_fireParticle = "#particlesource" createVehicleLocal _unitPos;
|
||||
_fireParticle attachTo [_unit, [0, 0, 0]];
|
||||
_fireParticle attachTo [_unit];
|
||||
_fireParticle setDropInterval 0.03;
|
||||
|
||||
_smokeParticle = "#particlesource" createVehicleLocal _unitPos;
|
||||
@ -35,7 +35,7 @@ if (hasInterface) then {
|
||||
_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 attachTo [_unit];
|
||||
_fireLight setLightDayLight false;
|
||||
|
||||
_lightFlare = "#lightpoint" createVehicleLocal _unitPos;
|
||||
@ -128,17 +128,8 @@ if (isServer) then {
|
||||
0 // random direction intensity
|
||||
];
|
||||
|
||||
_smokeParticle setDropInterval 0.15;
|
||||
_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
|
||||
@ -164,13 +155,21 @@ if (isServer) then {
|
||||
"", // before destroy script
|
||||
_unit // particle source
|
||||
];
|
||||
_smokeParticle setDropInterval 0.15;
|
||||
_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);
|
||||
_lightFlare setLightBrightness (_intensity / 30);
|
||||
|
||||
private _distanceToUnit = _unit distance ACE_player;
|
||||
_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 {
|
||||
@ -179,6 +178,7 @@ if (isServer) then {
|
||||
|
||||
// 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 {
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: tcvm, johnb43
|
||||
* Makes object catch fire. Simulates fire intensity over time.
|
||||
* Simulates fire intensity over time on burning units.
|
||||
* Arbitrary values to ignite people. Assumed maximum is "10".
|
||||
*
|
||||
* Arguments:
|
||||
@ -29,20 +29,18 @@ _unit setVariable [QGVAR(burnCounter), nil];
|
||||
|
||||
private _remote = !local _unit;
|
||||
|
||||
// If unit is local and the fire has died now, the effects need to be cleaned up -> do not stop PFH here
|
||||
// If unit is local and the fire has died out, the effects need to be cleaned up -> do not stop PFH here
|
||||
if (isNull _unit || {_remote && {!(_unit call FUNC(isBurning))}}) exitWith {
|
||||
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
if (_remote) exitWith {};
|
||||
|
||||
private _unitPos = getPosASL _unit;
|
||||
|
||||
// If unit is invulnerable or in water or if the fire has died out, stop burning unit
|
||||
if (
|
||||
!(_unit call FUNC(isBurning)) ||
|
||||
{surfaceIsWater _unitPos && {(_unitPos select 2) < 1}} ||
|
||||
{!(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]})}
|
||||
{!(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]})} ||
|
||||
{private _unitPos = getPosASL _unit; surfaceIsWater _unitPos && {(_unitPos select 2) < 1}}
|
||||
) exitWith {
|
||||
// Remove global effects and simulation
|
||||
{
|
||||
@ -66,17 +64,21 @@ _unit setVariable [QGVAR(burnCounter), nil];
|
||||
|
||||
private _intensity = _unit getVariable [QGVAR(intensity), 0];
|
||||
|
||||
// Propagate fire to other units if it's intense
|
||||
// Propagate fire to other units (alive or dead) if it's intense
|
||||
if (_intensity >= BURN_THRESHOLD_INTENSE) then {
|
||||
_unitPos = ASLToAGL _unitPos;
|
||||
private _adjustedIntensity = 0;
|
||||
|
||||
{
|
||||
if !(_x call FUNC(isBurning)) then {
|
||||
_distancePercent = 1 - ((_unitPos distance _x) / BURN_PROPAGATE_DISTANCE);
|
||||
_distancePercent = 1 - ((_unit distance _x) / BURN_PROPAGATE_DISTANCE);
|
||||
_adjustedIntensity = _intensity * _distancePercent;
|
||||
|
||||
[QGVAR(burn), [_x, _intensity * _distancePercent, _instigator], _x] call CBA_fnc_targetEvent;
|
||||
// Don't burn if intensity is too low
|
||||
if (BURN_MIN_INTENSITY > _adjustedIntensity) then {
|
||||
continue;
|
||||
};
|
||||
} forEach (_unitPos nearEntities ["CAManBase", BURN_PROPAGATE_DISTANCE]);
|
||||
|
||||
[QGVAR(burn), [_x, _adjustedIntensity, _instigator], _x] call CBA_fnc_targetEvent;
|
||||
} forEach nearestObjects [_unit, ["CAManBase"], BURN_PROPAGATE_DISTANCE];
|
||||
};
|
||||
|
||||
// Update intensity/fire reactions
|
||||
|
@ -1,8 +1,7 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: 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.
|
||||
* Handles various objects on fire and determines if units close to objects deserve to get burned.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Args (not used) <ARRAY>
|
||||
@ -12,34 +11,37 @@
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [ace_fire_fnc_fireManagerPFH, 0.25] call CBA_fnc_addPerFrameHandler
|
||||
* [[], -1] call CBA_fnc_addPerFrameHandler
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
private _attachedObject = objNull;
|
||||
private _sourcePos = [];
|
||||
private _distancePercent = 0;
|
||||
private _adjustedIntensity = 0;
|
||||
|
||||
{
|
||||
_y params ["_source", "_radius", "_intensity", "_condition", "_conditionArgs"];
|
||||
_y params ["_fireLogic", "_radius", "_intensity", "_condition", "_conditionArgs"];
|
||||
|
||||
// Remove when condition is no longer valid
|
||||
if !(_conditionArgs call _condition) then {
|
||||
GVAR(fireSources) deleteAt _x;
|
||||
(GVAR(fireSources) deleteAt _x) params [["_fireLogic", objNull]];
|
||||
|
||||
detach _fireLogic;
|
||||
deleteVehicle _fireLogic;
|
||||
|
||||
continue;
|
||||
};
|
||||
|
||||
_attachedObject = attachedTo _source;
|
||||
_sourcePos = ASLtoAGL getPosASL ([_source, _attachedObject] select (!isNull _attachedObject));
|
||||
|
||||
// Burn units close to the fire
|
||||
// Burn units (alive or dead) close to the fire
|
||||
{
|
||||
if !(_x call FUNC(isBurning)) then {
|
||||
_distancePercent = 1 - ((_sourcePos distance _x) / _radius);
|
||||
_distancePercent = 1 - ((_fireLogic distance _x) / _radius);
|
||||
_adjustedIntensity = _intensity * _distancePercent;
|
||||
|
||||
[QGVAR(burn), [_x, _intensity * _distancePercent], _x] call CBA_fnc_targetEvent;
|
||||
// Don't burn if intensity is too low
|
||||
if (BURN_MIN_INTENSITY > _adjustedIntensity) then {
|
||||
continue;
|
||||
};
|
||||
} forEach (_sourcePos nearEntities ["CAManBase", _radius]);
|
||||
|
||||
[QGVAR(burn), [_x, _adjustedIntensity], _x] call CBA_fnc_targetEvent;
|
||||
} forEach nearestObjects [_fireLogic, ["CAManBase"], _radius];
|
||||
} forEach GVAR(fireSources);
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: commy2
|
||||
* Check if unit is burning.
|
||||
* Check if an object is burning.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 0: Object <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -15,6 +15,6 @@
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_unit", objNull, [objNull]]];
|
||||
params [["_object", objNull, [objNull]]];
|
||||
|
||||
(_unit getVariable [QGVAR(intensity), 0]) > BURN_MIN_INTENSITY
|
||||
(_object getVariable [QGVAR(intensity), 0]) > BURN_MIN_INTENSITY
|
||||
|
@ -37,8 +37,8 @@
|
||||
#define INTENSITY_DECREASE_MULT_PAT_DOWN 0.8
|
||||
#define INTENSITY_DECREASE_MULT_ROLLING INTENSITY_DECREASE_MULT_PAT_DOWN
|
||||
|
||||
#define INTENSITY_LOSS 0.03
|
||||
#define INTENSITY_UPDATE 3
|
||||
#define INTENSITY_LOSS 0.02
|
||||
#define INTENSITY_UPDATE 2
|
||||
#define BURN_PROPAGATE_UPDATE 1
|
||||
#define BURN_PROPAGATE_DISTANCE 2
|
||||
#define BURN_THRESHOLD_INTENSE 3
|
||||
|
@ -153,7 +153,7 @@ class CfgAmmo {
|
||||
class ACE_G_M14: SmokeShell {
|
||||
GVAR(incendiary) = 1;
|
||||
model = QPATHTOF(models\ace_anm14th3_armed.p3d);
|
||||
hit = 5;
|
||||
hit = 10;
|
||||
indirectHit = 4;
|
||||
indirectHitRange = 1.1;
|
||||
dangerRadiusHit = 50;
|
||||
|
@ -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
|
||||
1 | Radius of fire | Number | Required
|
||||
2 | Intensity of fire (1, 10] | Number | Required
|
||||
3 | Fire source ID | Any | Required
|
||||
4 | Condition to stop fire | Code | Optional (default: `{ true }`)
|
||||
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}`)
|
||||
5 | Arguments to pass to condition | Any | Optional (default: `[]`)
|
||||
|
||||
### 1.2 Removing fire source
|
||||
@ -36,4 +36,4 @@ Use `CBA_fnc_serverEvent` to use the following features. Events are defined only
|
||||
|
||||
| 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
|
||||
|
Loading…
Reference in New Issue
Block a user