mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Grenades - Code cleanup (#9979)
* Improved various aspects of grenades * Update addons/grenades/functions/fnc_flashbangExplosionEH.sqf Co-authored-by: Jouni Järvinen <rautamiekka@users.noreply.github.com> * Update addons/grenades/functions/fnc_incendiary.sqf Co-authored-by: Jouni Järvinen <rautamiekka@users.noreply.github.com> * Update addons/grenades/functions/fnc_incendiary.sqf Co-authored-by: Jouni Järvinen <rautamiekka@users.noreply.github.com> * Update fnc_flashbangExplosionEH.sqf * More cleanup * Update fnc_incendiary.sqf * Update fnc_incendiary.sqf * Update fnc_flashbangThrownFuze.sqf * Update fnc_flashbangThrownFuze.sqf * Update addons/grenades/functions/fnc_nextMode.sqf Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> * Update addons/grenades/functions/fnc_flashbangExplosionEH.sqf * Update addons/grenades/functions/fnc_incendiary.sqf * Removed fix that is included in another PR * Update fnc_incendiary.sqf * Messed up merge conflict resolution --------- 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
95b7951919
commit
8fc093de8f
@ -1,4 +1,3 @@
|
||||
|
||||
class CfgAmmo {
|
||||
class Default;
|
||||
class Grenade: Default {
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
class Extended_PreStart_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
class CfgMagazines {
|
||||
class HandGrenade;
|
||||
class ACE_HandFlare_Base: HandGrenade {
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
class CfgVehicles {
|
||||
class NATO_Box_Base;
|
||||
class Box_NATO_Grenades_F: NATO_Box_Base {
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
class CfgWeapons {
|
||||
class GrenadeLauncher;
|
||||
class Throw: GrenadeLauncher {
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
class ACE_M84FlashbangEffect {
|
||||
// empty
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
PREP(addChangeFuseItemContextMenuOptions);
|
||||
PREP(damageEngineAndWheels);
|
||||
PREP(flare);
|
||||
PREP(flashbangExplosionEH);
|
||||
@ -5,4 +6,3 @@ PREP(flashbangThrownFuze);
|
||||
PREP(incendiary);
|
||||
PREP(nextMode);
|
||||
PREP(throwGrenade);
|
||||
PREP(addChangeFuseItemContextMenuOptions);
|
||||
|
@ -1,6 +1,7 @@
|
||||
// by commy2
|
||||
|
||||
#include "script_component.hpp"
|
||||
#include "\a3\ui_f\hpp\defineDIKCodes.inc"
|
||||
|
||||
["ace_flashbangExploded", LINKFUNC(flashbangExplosionEH)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(damageEngineAndWheels), LINKFUNC(damageEngineAndWheels)] call CBA_fnc_addEventHandler;
|
||||
@ -16,21 +17,21 @@ GVAR(flashbangPPEffectCC) = ppEffectCreate ["ColorCorrections", 4265];
|
||||
GVAR(flashbangPPEffectCC) ppEffectForceInNVG true;
|
||||
|
||||
// Add keybinds
|
||||
["ACE3 Weapons", QGVAR(switchGrenadeMode), localize LSTRING(SwitchGrenadeMode), {
|
||||
["ACE3 Weapons", QGVAR(switchGrenadeMode), LLSTRING(SwitchGrenadeMode), {
|
||||
// Conditions: canInteract
|
||||
if !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false};
|
||||
// Conditions: specific
|
||||
if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false};
|
||||
if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {false};
|
||||
// Don't change mode or show hint if advanced throwing is active
|
||||
if (ACE_player getVariable [QEGVAR(advanced_throwing,inHand), false]) exitWith {false};
|
||||
|
||||
// Statement
|
||||
[] call FUNC(nextMode);
|
||||
}, {false}, [9, [false, false, false]], false] call CBA_fnc_addKeybind; //8 Key
|
||||
call FUNC(nextMode) // return
|
||||
}, {}, [DIK_8, [false, false, false]], false] call CBA_fnc_addKeybind; // 8 Key
|
||||
|
||||
["CBA_settingsInitialized", {
|
||||
if (GVAR(convertExplosives)) then {
|
||||
[] call FUNC(addChangeFuseItemContextMenuOptions);
|
||||
call FUNC(addChangeFuseItemContextMenuOptions);
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Cyruz
|
||||
* Allows conversion of explosive charges in to throwable versions
|
||||
* Allows conversion of explosive charges into throwable versions.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
@ -14,7 +14,8 @@
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
TRACE_1("addChangeFuseItemContextMenuOptions",_this);
|
||||
|
||||
LOG("addChangeFuseItemContextMenuOptions");
|
||||
|
||||
{
|
||||
_x params ["_mag", "_throwableMag"];
|
||||
@ -29,21 +30,25 @@
|
||||
{true},
|
||||
{
|
||||
params ["", "", "_item", "", "_magArr"];
|
||||
_item isEqualTo (_magArr select 0);
|
||||
|
||||
_item == (_magArr select 0)
|
||||
}
|
||||
],
|
||||
{
|
||||
params ["_unit", "", "", "_slot", "_magArr"];
|
||||
private _container = "";
|
||||
switch _slot do {
|
||||
|
||||
private _container = switch (_slot) do {
|
||||
case "UNIFORM_CONTAINER": {
|
||||
_container = "uniform";
|
||||
"uniform"
|
||||
};
|
||||
case "VEST_CONTAINER": {
|
||||
_container = "vest";
|
||||
"vest"
|
||||
};
|
||||
case "BACKPACK_CONTAINER": {
|
||||
_container = "backpack";
|
||||
"backpack"
|
||||
};
|
||||
default {
|
||||
""
|
||||
};
|
||||
};
|
||||
|
||||
@ -54,7 +59,7 @@
|
||||
false
|
||||
},
|
||||
true,
|
||||
[_mag,_throwableMag]
|
||||
[_mag, _throwableMag]
|
||||
] call CBA_fnc_addItemContextMenuOption;
|
||||
|
||||
[
|
||||
@ -67,21 +72,25 @@
|
||||
{true},
|
||||
{
|
||||
params ["", "", "_item", "", "_magArr"];
|
||||
_item isEqualTo (_magArr select 1);
|
||||
|
||||
_item == (_magArr select 1)
|
||||
}
|
||||
],
|
||||
{
|
||||
params ["_unit", "", "", "_slot", "_magArr"];
|
||||
private _container = "";
|
||||
switch _slot do {
|
||||
|
||||
private _container = switch (_slot) do {
|
||||
case "UNIFORM_CONTAINER": {
|
||||
_container = "uniform";
|
||||
"uniform"
|
||||
};
|
||||
case "VEST_CONTAINER": {
|
||||
_container = "vest";
|
||||
"vest"
|
||||
};
|
||||
case "BACKPACK_CONTAINER": {
|
||||
_container = "backpack";
|
||||
"backpack"
|
||||
};
|
||||
default {
|
||||
""
|
||||
};
|
||||
};
|
||||
|
||||
@ -92,7 +101,7 @@
|
||||
false
|
||||
},
|
||||
true,
|
||||
[_mag,_throwableMag]
|
||||
[_mag, _throwableMag]
|
||||
] call CBA_fnc_addItemContextMenuOption;
|
||||
} forEach [
|
||||
["SatchelCharge_Remote_Mag", "ACE_SatchelCharge_Remote_Mag_Throwable"],
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Makes flare shine.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The flare <OBJECT>
|
||||
* 0: Flare <OBJECT>
|
||||
* 1: Color of flare <ARRAY>
|
||||
* 2: Intensity of flare <NUMBER>
|
||||
* 3: Flare lifetime <OBJECT>
|
||||
@ -34,6 +34,5 @@ _light setLightFlareMaxDistance 1000;
|
||||
_light setLightDayLight true;
|
||||
|
||||
_light lightAttachObject [_projectile, [0,0,0]];
|
||||
//_light attachTo [_projectile, [0,0,0]];
|
||||
|
||||
[{deleteVehicle _this}, _light, _timeToLive] call CBA_fnc_waitAndExecute;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Creates the flashbang effect and knock out AI units.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The flashBang position ASL <ARRAY>
|
||||
* 0: Flashbang position ASL <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -18,152 +18,148 @@
|
||||
params ["_grenadePosASL"];
|
||||
TRACE_1("params",_grenadePosASL);
|
||||
|
||||
// Create flash to illuminate environment
|
||||
if (hasInterface) then {
|
||||
private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL;
|
||||
_light setPosASL _grenadePosASL;
|
||||
|
||||
_light setLightBrightness 20;
|
||||
_light setLightAmbient [1,1,1];
|
||||
_light setLightColor [1,1,1];
|
||||
_light setLightDayLight true;
|
||||
_light setLightAttenuation [0, 1, 5, 1000, 0, 20];
|
||||
|
||||
// Reduce the light after 0.1 seconds
|
||||
[{
|
||||
params ["_light"];
|
||||
_light setLightBrightness 5;
|
||||
// Delete the light after 0.2 more seconds
|
||||
[{
|
||||
params ["_light"];
|
||||
deleteVehicle _light;
|
||||
}, [_light], 0.2] call CBA_fnc_waitAndExecute;
|
||||
}, [_light], 0.1] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
|
||||
// Affect local AI (players are not local, except for ACE_player)
|
||||
// @todo: Affect units in static weapons, turned out, etc
|
||||
private _affected = (ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20];
|
||||
_affected = _affected - [ACE_player];
|
||||
private _affected = ((ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]) - [ACE_player];
|
||||
|
||||
{
|
||||
if (local _x && {_x call EFUNC(common,isAwake)}) then {
|
||||
private _unit = _x;
|
||||
private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20;
|
||||
private _unit = _x;
|
||||
private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20;
|
||||
|
||||
TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength);
|
||||
TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength);
|
||||
|
||||
[_unit, true] call EFUNC(common,disableAI);
|
||||
[_unit, true] call EFUNC(common,disableAI);
|
||||
|
||||
// Make AI try to look away
|
||||
private _dirToFlash = _unit getDir _grenadePosASL;
|
||||
_unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]);
|
||||
// Make AI try to look away
|
||||
private _dirToFlash = _unit getDir _grenadePosASL;
|
||||
_unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]);
|
||||
|
||||
private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0];
|
||||
_unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))];
|
||||
|
||||
if (_flashReactionDebounce < CBA_missionTime) then {
|
||||
// Not used internally but could be useful for other mods
|
||||
_unit setVariable [QGVAR(flashStrength), _strength, true];
|
||||
|
||||
[QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent;
|
||||
|
||||
{
|
||||
_unit setSkill [_x, (_unit skill _x) / 50];
|
||||
} forEach SUBSKILLS;
|
||||
|
||||
[{
|
||||
CBA_missiontime >= _this getVariable [QGVAR(flashReactionDebounce), 0]
|
||||
}, {
|
||||
params ["_unit"];
|
||||
|
||||
_unit setVariable [QGVAR(flashStrength), 0, true];
|
||||
|
||||
// Make sure we don't enable AI for unconscious units
|
||||
if (_unit call EFUNC(common,isAwake)) then {
|
||||
[_unit, false] call EFUNC(common,disableAI);
|
||||
};
|
||||
|
||||
private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0];
|
||||
_unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))];
|
||||
if (_flashReactionDebounce < CBA_missionTime) then {
|
||||
// Not used interally but could be useful for other mods
|
||||
_unit setVariable [QGVAR(flashStrength), _strength, true];
|
||||
[QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent;
|
||||
{
|
||||
_unit setSkill [_x, (_unit skill _x) / 50];
|
||||
_unit setSkill [_x, (_unit skill _x) * 50];
|
||||
} forEach SUBSKILLS;
|
||||
[{
|
||||
params ["_unit"];
|
||||
CBA_missiontime >= _unit getVariable [QGVAR(flashReactionDebounce), 0]
|
||||
},{
|
||||
params ["_unit"];
|
||||
|
||||
_unit setVariable [QGVAR(flashStrength), 0, true];
|
||||
|
||||
// Make sure we don't enable AI for unconscious units
|
||||
if !(_unit getVariable ["ace_isUnconscious", false]) then {
|
||||
[_unit, false] call EFUNC(common,disableAI);
|
||||
};
|
||||
{
|
||||
_unit setSkill [_x, (_unit skill _x) * 50];
|
||||
} forEach SUBSKILLS;
|
||||
}, [_unit]] call CBA_fnc_waitUntilAndExecute;
|
||||
};
|
||||
}, _unit] call CBA_fnc_waitUntilAndExecute;
|
||||
};
|
||||
} forEach _affected;
|
||||
} forEach (_affected select {local _x && {_x call EFUNC(common,isAwake)}});
|
||||
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
// Create flash to illuminate environment
|
||||
private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL;
|
||||
_light setPosASL _grenadePosASL;
|
||||
|
||||
_light setLightBrightness 20;
|
||||
_light setLightAmbient [1,1,1];
|
||||
_light setLightColor [1,1,1];
|
||||
_light setLightDayLight true;
|
||||
_light setLightAttenuation [0, 1, 5, 1000, 0, 20];
|
||||
|
||||
// Reduce the light after 0.1 seconds
|
||||
[{
|
||||
_this setLightBrightness 5;
|
||||
|
||||
// Delete the light after 0.2 more seconds
|
||||
[{deleteVehicle _this}, _this, 0.2] call CBA_fnc_waitAndExecute;
|
||||
}, _light, 0.1] call CBA_fnc_waitAndExecute;
|
||||
|
||||
// Ignore dead and placeable logic (zeus / spectator)
|
||||
if (!alive ACE_player || {(getNumber (configOf ACE_player >> "isPlayableLogic")) == 1}) exitWith {};
|
||||
|
||||
// Affect local player, independently of distance
|
||||
if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then {
|
||||
if ((getNumber (configOf ACE_player >> "isPlayableLogic")) == 1) exitWith {
|
||||
TRACE_1("skipping playable logic",typeOf ACE_player); // VirtualMan_F (placeable logic zeus / spectator)
|
||||
};
|
||||
// Do effects for player
|
||||
// is there line of sight to the grenade?
|
||||
private _eyePos = eyePos ACE_player; //PositionASL
|
||||
_grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground
|
||||
// Check for line of sight to the grenade
|
||||
private _eyePos = eyePos ACE_player; // PositionASL
|
||||
_grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground
|
||||
|
||||
private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20;
|
||||
private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20;
|
||||
|
||||
// Check for line of sight (check 4 points in case grenade is stuck in an object or underground)
|
||||
private _losCoefficient = 1;
|
||||
private _losCount = {
|
||||
!lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player]
|
||||
} count [[0,0,0], [0,0,0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]];
|
||||
TRACE_1("Line of sight count (out of 4)",_losCount);
|
||||
if (_losCount <= 1) then {
|
||||
_losCoefficient = 0.1;
|
||||
};
|
||||
_strength = _strength * _losCoefficient;
|
||||
// Check for line of sight (check 4 points in case grenade is stuck in an object or underground)
|
||||
private _losCount = {
|
||||
!lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player]
|
||||
} count [[0, 0, 0], [0, 0, 0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]];
|
||||
TRACE_1("Line of sight count (out of 4)",_losCount);
|
||||
|
||||
// Add ace_hearing ear ringing sound effect
|
||||
if (["ace_hearing"] call EFUNC(common,isModLoaded) && {_strength > 0 && {EGVAR(hearing,damageCoefficent) > 0.25}}) then {
|
||||
private _earringingStrength = 40 * _strength;
|
||||
[_earringingStrength] call EFUNC(hearing,earRinging);
|
||||
TRACE_1("Earringing Strength",_earringingStrength);
|
||||
};
|
||||
private _losCoefficient = [1, 0.1] select (_losCount <= 1);
|
||||
_strength = _strength * _losCoefficient;
|
||||
|
||||
// add ace_medical pain effect:
|
||||
if (GETEGVAR(medical,enabled,false) && {_strength > 0.1} && {isDamageAllowed _unit} && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) then {
|
||||
[ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel);
|
||||
};
|
||||
|
||||
// Effect on vision has a wider range, with a higher falloff
|
||||
_strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4;
|
||||
_strength = _strength * _losCoefficient;
|
||||
// Account for people looking away by slightly reducing the effect for visual effects.
|
||||
private _eyeDir = ((AGLtoASL positionCameraToWorld [0,0,1]) vectorDiff (AGLtoASL positionCameraToWorld [0,0,0]));
|
||||
private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL;
|
||||
private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector);
|
||||
TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0));
|
||||
// from 0-45deg, full effect
|
||||
if (_angleDiff > 45) then {
|
||||
_strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0);
|
||||
};
|
||||
|
||||
// Blind player
|
||||
if (_strength > 0.1) then {
|
||||
private _blend = [[1,1,1,0], [0.3,0.3,0.3,1]] select EGVAR(common,epilepsyFriendlyMode);
|
||||
|
||||
GVAR(flashbangPPEffectCC) ppEffectEnable true;
|
||||
GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, (0.8 + _strength) min 1, _blend, [0,0,0,1], [0,0,0,0]];
|
||||
GVAR(flashbangPPEffectCC) ppEffectCommit 0.01;
|
||||
|
||||
//PARTIALRECOVERY - start decreasing effect over time
|
||||
[{
|
||||
params ["_strength", "_blend"];
|
||||
|
||||
GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, 0, _blend, [0,0,0,1], [0,0,0,0]];
|
||||
GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength);
|
||||
}, [_strength, _blend], 7 * _strength] call CBA_fnc_waitAndExecute;
|
||||
|
||||
//FULLRECOVERY - end effect
|
||||
[{
|
||||
GVAR(flashbangPPEffectCC) ppEffectEnable false;
|
||||
}, [], 17 * _strength] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
|
||||
// Make player flinch
|
||||
if (_strength <= 0.2) exitWith {};
|
||||
private _minFlinch = linearConversion [0.2, 1, _strength, 0, 60, true];
|
||||
private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true];
|
||||
private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1];
|
||||
ACE_player setDir (getDir ACE_player + _flinch);
|
||||
|
||||
[QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent;
|
||||
// Add ace_hearing ear ringing sound effect
|
||||
if (["ace_hearing"] call EFUNC(common,isModLoaded) && {_strength > 0} && {EGVAR(hearing,damageCoefficent) > 0.25}) then {
|
||||
private _earringingStrength = 40 * _strength;
|
||||
[_earringingStrength] call EFUNC(hearing,earRinging);
|
||||
TRACE_1("Earringing Strength",_earringingStrength);
|
||||
};
|
||||
true
|
||||
|
||||
// Add ace_medical pain effect
|
||||
if (GETEGVAR(medical,enabled,false) && {_strength > 0.1} && {isDamageAllowed _unit} && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) then {
|
||||
[ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel);
|
||||
};
|
||||
|
||||
// Effect on vision has a wider range, with a higher falloff
|
||||
_strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4;
|
||||
_strength = _strength * _losCoefficient;
|
||||
|
||||
// Account for people looking away by slightly reducing the effect for visual effects.
|
||||
private _eyeDir = ((AGLtoASL positionCameraToWorld [0, 0, 1]) vectorDiff (AGLtoASL positionCameraToWorld [0, 0, 0]));
|
||||
private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL;
|
||||
private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector);
|
||||
TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0));
|
||||
|
||||
// From 0-45deg, full effect
|
||||
if (_angleDiff > 45) then {
|
||||
_strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0);
|
||||
};
|
||||
|
||||
// Blind player
|
||||
if (_strength > 0.1) then {
|
||||
private _blend = [[1, 1, 1, 0], [0.3, 0.3, 0.3, 1]] select EGVAR(common,epilepsyFriendlyMode);
|
||||
|
||||
GVAR(flashbangPPEffectCC) ppEffectEnable true;
|
||||
GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, (0.8 + _strength) min 1, _blend, [0, 0, 0, 1], [0, 0, 0, 0]];
|
||||
GVAR(flashbangPPEffectCC) ppEffectCommit 0.01;
|
||||
|
||||
// PARTIALRECOVERY - start decreasing effect over time
|
||||
[{
|
||||
params ["_strength", "_blend"];
|
||||
|
||||
GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, 0, _blend, [0, 0, 0, 1], [0, 0, 0, 0]];
|
||||
GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength);
|
||||
}, [_strength, _blend], 7 * _strength] call CBA_fnc_waitAndExecute;
|
||||
|
||||
// FULLRECOVERY - end effect
|
||||
[{
|
||||
GVAR(flashbangPPEffectCC) ppEffectEnable false;
|
||||
}, [], 17 * _strength] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
|
||||
// Make player flinch
|
||||
if (_strength <= 0.2) exitWith {};
|
||||
|
||||
private _minFlinch = linearConversion [0.2, 1, _strength, 0, 60, true];
|
||||
private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true];
|
||||
private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1];
|
||||
ACE_player setDir (getDir ACE_player + _flinch);
|
||||
|
||||
[QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Waits for the flashbang grenade fuze to trigger and 'explode'
|
||||
*
|
||||
* Arguments:
|
||||
* 0: projectile - Flashbang Grenade <OBJECT>
|
||||
* 0: Flashbang grenade <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -18,16 +18,17 @@
|
||||
params ["_projectile"];
|
||||
TRACE_1("params",_projectile);
|
||||
|
||||
if (alive _projectile) then {
|
||||
private _sounds = getArray (_projectile call CBA_fnc_getObjectConfig >> QGVAR(flashbangExplodeSound));
|
||||
if (!alive _projectile) exitWith {};
|
||||
|
||||
(if (_sounds isEqualTo []) then {
|
||||
[format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400]
|
||||
} else {
|
||||
selectRandom _sounds
|
||||
}) params ["_file", "_volume", "_pitch", "_distance"];
|
||||
private _posASL = getPosASL _projectile;
|
||||
private _sounds = getArray (_projectile call CBA_fnc_getObjectConfig >> QGVAR(flashbangExplodeSound));
|
||||
|
||||
playSound3D [_file, _projectile, false, getPosASL _projectile, _volume, _pitch, _distance];
|
||||
(if (_sounds isEqualTo []) then {
|
||||
[format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400]
|
||||
} else {
|
||||
selectRandom _sounds
|
||||
}) params ["_file", "_volume", "_pitch", "_distance"];
|
||||
|
||||
["ace_flashbangExploded", [getPosASL _projectile]] call CBA_fnc_globalEvent;
|
||||
};
|
||||
playSound3D [_file, _projectile, false, _posASL, _volume, _pitch, _distance];
|
||||
|
||||
["ace_flashbangExploded", [_posASL]] call CBA_fnc_globalEvent;
|
||||
|
@ -1,11 +1,12 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: commy2
|
||||
* Makes incendiary burn.
|
||||
* Makes an incendiary grenade burn.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The grenade <OBJECT>
|
||||
* 0: Incendiary grenade <OBJECT>
|
||||
* 1: Incendiary lifetime <OBJECT>
|
||||
* 2: Instigator's side <SIDE>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -42,16 +43,16 @@ if (isNull _projectile) exitWith {TRACE_1("null",_projectile);};
|
||||
|
||||
private _position = position _projectile;
|
||||
|
||||
// --- AI
|
||||
// Alert nearby hostile AI
|
||||
private _nearLocalEnemies = [];
|
||||
|
||||
{
|
||||
{
|
||||
if (local _x && {[_center, side _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECTS SIDE HERE!
|
||||
if (local _x && {[_center, side group _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECT'S SIDE HERE!
|
||||
_nearLocalEnemies pushBackUnique _x;
|
||||
};
|
||||
} forEach crew _x;
|
||||
} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE);
|
||||
} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); //@todo replace with nearEntities in 2.18
|
||||
|
||||
{
|
||||
if (behaviour _x in ["SAFE", "AWARE"]) then {
|
||||
@ -59,7 +60,7 @@ private _nearLocalEnemies = [];
|
||||
};
|
||||
} forEach _nearLocalEnemies;
|
||||
|
||||
// --- fire
|
||||
// Fire particles
|
||||
private _fire = "#particlesource" createVehicleLocal _position;
|
||||
|
||||
_fire setParticleParams [
|
||||
@ -99,7 +100,7 @@ _fire setParticleRandom [PARTICLE_LIFE_TIME / 4, [0.15 * EFFECT_SIZE, 0.15 * EFF
|
||||
_fire setParticleFire [1.2,1.0,0.1];
|
||||
_fire setDropInterval (1 / PARTICLE_DENSITY);
|
||||
|
||||
// --- smoke
|
||||
// Smoke particles
|
||||
private _smoke = "#particlesource" createVehicleLocal _position;
|
||||
|
||||
_smoke setParticleParams [
|
||||
@ -137,7 +138,7 @@ _smoke setParticleParams [
|
||||
_smoke setParticleRandom [PARTICLE_SMOKE_LIFE_TIME / 2, [0.5 * EFFECT_SIZE, 0.5 * EFFECT_SIZE, 0.2 * EFFECT_SIZE], [0.3,0.3,0.5], 1, 0, [0,0,0,0.06], 0, 0];
|
||||
_smoke setDropInterval (1 / PARTICLE_SMOKE_DENSITY);
|
||||
|
||||
// --- light
|
||||
// Light
|
||||
private _light = "#lightpoint" createVehicleLocal (_position vectorAdd [0,0,0.5]);
|
||||
|
||||
_light setLightBrightness 1.0;
|
||||
@ -150,19 +151,20 @@ _light setLightDayLight false;
|
||||
|
||||
_light lightAttachObject [_projectile, [0,0,0]];
|
||||
|
||||
// --- sound
|
||||
// Sound
|
||||
private _sound = objNull;
|
||||
|
||||
if (isServer) then {
|
||||
_sound = createSoundSource ["Sound_Fire", _position, [], 0];
|
||||
private _radius = 1.5 * getNumber (configOf _projectile >> "indirectHitRange");
|
||||
private _intensity = getNumber (configOf _projectile >> "hit");
|
||||
|
||||
[QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, {
|
||||
params ["_endTime", "_projectile"];
|
||||
|
||||
// If incendiary no longer exists, exit
|
||||
if (isNull _projectile) exitWith {
|
||||
false
|
||||
false // return
|
||||
};
|
||||
|
||||
// Need to get the position every time, as grenade might have been moved
|
||||
@ -181,37 +183,38 @@ if (isServer) then {
|
||||
{deleteVehicle _x} forEach _this;
|
||||
}, [_fire, _smoke, _light, _sound], _timeToLive] call CBA_fnc_waitAndExecute;
|
||||
|
||||
// --- damage
|
||||
// Damage
|
||||
{
|
||||
if (local _x && {isDamageAllowed _x}) then {
|
||||
//systemChat format ["burn: %1", _x];
|
||||
// Inflame fireplace, barrels etc.
|
||||
_x inflame true;
|
||||
|
||||
// --- destroy nearby static weapons and ammo boxes
|
||||
if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then {
|
||||
// Destroy nearby static weapons and ammo boxes
|
||||
if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then {
|
||||
_x setDamage 1;
|
||||
|
||||
continue;
|
||||
};
|
||||
|
||||
if (_x isKindOf "ReammoBox_F") then {
|
||||
if (
|
||||
(["ace_cookoff"] call EFUNC(common,isModLoaded)) &&
|
||||
{EGVAR(cookoff,enableAmmobox)} &&
|
||||
{EGVAR(cookoff,ammoCookoffDuration) != 0} &&
|
||||
{_x getVariable [QEGVAR(cookoff,enableAmmoCookoff), true]}
|
||||
) then {
|
||||
[QEGVAR(cookOff,cookOffBoxServer), _box] call CBA_fnc_serverEvent;
|
||||
} else {
|
||||
_x setDamage 1;
|
||||
};
|
||||
if (_x isKindOf "ReammoBox_F") then {
|
||||
if (
|
||||
(["ace_cookoff"] call EFUNC(common,isModLoaded)) &&
|
||||
{EGVAR(cookoff,enableAmmobox)} &&
|
||||
{EGVAR(cookoff,ammoCookoffDuration) != 0} &&
|
||||
{_x getVariable [QEGVAR(cookoff,enableAmmoCookoff), true]}
|
||||
) then {
|
||||
[QEGVAR(cookOff,cookOffBoxServer), _box] call CBA_fnc_serverEvent;
|
||||
} else {
|
||||
_x setDamage 1;
|
||||
};
|
||||
};
|
||||
|
||||
// --- delete nearby ground weapon holders
|
||||
if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then {
|
||||
deleteVehicle _x;
|
||||
};
|
||||
|
||||
// --- inflame fireplace, barrels etc.
|
||||
_x inflame true;
|
||||
continue;
|
||||
};
|
||||
} forEach (_position nearObjects DESTRUCTION_RADIUS);
|
||||
|
||||
// Delete nearby ground weapon holders
|
||||
if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then {
|
||||
deleteVehicle _x;
|
||||
};
|
||||
} forEach ((_position nearObjects DESTRUCTION_RADIUS) select {local _x && {isDamageAllowed _x}});
|
||||
|
||||
{
|
||||
// Damage vehicles (locality is checked in FUNC(damageEngineAndWheels))
|
||||
|
@ -7,21 +7,16 @@
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* Handeled <BOOL>
|
||||
* Handled <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_grenades_fnc_nextMode
|
||||
* call ace_grenades_fnc_nextMode
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
private _mode = GVAR(currentThrowMode);
|
||||
|
||||
if (_mode == 4) then {
|
||||
_mode = 0;
|
||||
} else {
|
||||
_mode = _mode + 1;
|
||||
};
|
||||
// _mode is 0-4, don't overflow
|
||||
private _mode = (GVAR(currentThrowMode) + 1) % 5;
|
||||
|
||||
private _currentThrowable = currentThrowable ACE_player;
|
||||
|
||||
|
@ -27,40 +27,26 @@ if (isNull _projectile) then {
|
||||
|
||||
private _config = configFile >> "CfgAmmo" >> _ammo;
|
||||
|
||||
// handle special grenades and sounds
|
||||
// Handle special grenades and sounds
|
||||
if (local _unit) then {
|
||||
// handle priming sound, if present
|
||||
private _soundConfig = getArray (configFile >> "CfgAmmo" >> _ammo >> QGVAR(pullPinSound));
|
||||
// Handle priming sound, if present
|
||||
private _soundConfig = getArray (_config >> QGVAR(pullPinSound));
|
||||
|
||||
if (_soundConfig isNotEqualTo []) then {
|
||||
_soundConfig params ["_file", "_volume", "_pitch", "_distance"];
|
||||
playSound3D [_file, objNull, false, getPosASL _projectile, _volume, _pitch, _distance];
|
||||
playSound3D [_file, objNull, insideBuilding _unit >= 0.5, getPosASL _projectile, _volume, _pitch, _distance];
|
||||
};
|
||||
|
||||
if (getNumber (_config >> QGVAR(flashbang)) == 1) then {
|
||||
private _bangs = 1;
|
||||
private _entry = _config >> QGVAR(flashbangBangs);
|
||||
if (isNumber _entry || isText _entry) then {
|
||||
_bangs = getNumber _entry;
|
||||
};
|
||||
|
||||
private _fuzeTimeBase = getNumber (_config >> "explosionTime");
|
||||
|
||||
private _interval = 0.5;
|
||||
_entry = _config >> QGVAR(flashbangInterval);
|
||||
if (isNumber _entry || isText _entry) then {
|
||||
_interval = getNumber _entry;
|
||||
};
|
||||
|
||||
private _maxDeviation = 0.1;
|
||||
_entry = _config >> QGVAR(flashbangIntervalMaxDeviation);
|
||||
if (isNumber _entry || isText _entry) then {
|
||||
_maxDeviation = getNumber _entry;
|
||||
};
|
||||
private _bangs = [_config >> QGVAR(flashbangBangs), "NUMBER", 1] call CBA_fnc_getConfigEntry;
|
||||
private _interval = [_config >> QGVAR(flashbangInterval), "NUMBER", 0.5] call CBA_fnc_getConfigEntry;
|
||||
private _maxDeviation = [_config >> QGVAR(flashbangIntervalMaxDeviation), "NUMBER", 0.1] call CBA_fnc_getConfigEntry;
|
||||
|
||||
for "_i" from 0 to (_bangs - 1) do {
|
||||
private _fuzeTime = _fuzeTimeBase + _i*_interval + random [- _maxDeviation, 0, _maxDeviation];
|
||||
private _fuzeTime = _fuzeTimeBase + _i * _interval + random [-_maxDeviation, 0, _maxDeviation];
|
||||
|
||||
[FUNC(flashbangThrownFuze), [_projectile], _fuzeTime] call CBA_fnc_waitAndExecute;
|
||||
[LINKFUNC(flashbangThrownFuze), _projectile, _fuzeTime] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -71,60 +57,56 @@ if (getNumber (_config >> QGVAR(flare)) == 1) then {
|
||||
private _color = getArray (_config >> QGVAR(color));
|
||||
private _intensity = _color deleteAt 3;
|
||||
|
||||
[FUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute;
|
||||
[LINKFUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
|
||||
if (getNumber (_config >> QGVAR(incendiary)) == 1) then {
|
||||
private _fuzeTime = getNumber (_config >> "explosionTime");
|
||||
private _timeToLive = getNumber (_config >> "timeToLive");
|
||||
|
||||
[FUNC(incendiary), [_projectile, _timeToLive, side _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // WE WANT THE OBJECTS SIDE HERE!
|
||||
[LINKFUNC(incendiary), [_projectile, _timeToLive, side group _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // Get the unit's real side (will return civilian if unconscious)
|
||||
};
|
||||
|
||||
// handle throw modes
|
||||
// Handle throw modes
|
||||
if (_unit != ACE_player) exitWith {};
|
||||
if (_unit getVariable [QEGVAR(advanced_throwing,primed), false]) exitWith {LOG("advanced_throwing throw");};
|
||||
|
||||
private _mode = GVAR(currentThrowMode);
|
||||
if (GVAR(currentThrowMode) == 0) exitWith {};
|
||||
|
||||
if (_mode != 0) then {
|
||||
private _velocity = velocity _projectile;
|
||||
private _velocity = velocity _projectile;
|
||||
|
||||
switch (_mode) do {
|
||||
//high throw
|
||||
case 1 : {
|
||||
_velocity = [
|
||||
0.5 * (_velocity select 0),
|
||||
0.5 * (_velocity select 1),
|
||||
[0, 0, 0] distance (_velocity vectorMultiply 0.5)
|
||||
];
|
||||
};
|
||||
//precise throw
|
||||
case 2 : {
|
||||
_velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity);
|
||||
};
|
||||
//roll grenade
|
||||
case 3 : {
|
||||
private _posASL = getPosASL _projectile;
|
||||
switch (GVAR(currentThrowMode)) do {
|
||||
// High throw
|
||||
case 1: {
|
||||
_velocity = _velocity vectorMultiply 0.5;
|
||||
|
||||
// getPos is unreliable, as surfaces in some ruins are not recognised as surfaces
|
||||
private _lisPos = (lineIntersectsSurfaces [_posASL, _posASL vectorAdd [0, 0, -1e11], ACE_player, objNull, true, 1, "ROADWAY", "FIRE"]) select 0;
|
||||
_projectile setPosASL ((_lisPos select 0) vectorAdd [0, 0, 0.2]);
|
||||
|
||||
// Rotate throwables by 90° to the side by default, so cylindrical throwables can be rolled
|
||||
private _vectorDirAndUp = getArray (_config >> QGVAR(rollVectorDirAndUp));
|
||||
_vectorDirAndUp params [["_vectorDir", [0, 1, 0], [[]], 3], ["_vectorUp", [1, 0, 0], [[]], 3]];
|
||||
|
||||
// Do as if object were facing north
|
||||
_projectile setVectorDirAndUp ([[_vectorDir, _vectorUp], -(direction _projectile), 0, 0] call BIS_fnc_transformVectorDirAndUp);
|
||||
|
||||
_velocity = (vectorDir _unit) vectorMultiply 10;
|
||||
};
|
||||
//drop grenade
|
||||
case 4 : {
|
||||
_velocity = [0, 0, 0];
|
||||
};
|
||||
_velocity set [2, vectorMagnitude _velocity];
|
||||
};
|
||||
// Precise throw
|
||||
case 2: {
|
||||
_velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity);
|
||||
};
|
||||
// Roll grenade
|
||||
case 3: {
|
||||
private _posASL = getPosASL _projectile;
|
||||
|
||||
_projectile setVelocity _velocity;
|
||||
// getPos is unreliable, as surfaces in some ruins are not recognised as surfaces
|
||||
private _lisPos = (lineIntersectsSurfaces [_posASL, _posASL vectorAdd [0, 0, -1e11], ACE_player, objNull, true, 1, "ROADWAY", "FIRE"]) select 0;
|
||||
_projectile setPosASL ((_lisPos select 0) vectorAdd [0, 0, 0.2]);
|
||||
|
||||
// Rotate throwables by 90° to the side by default, so cylindrical throwables can be rolled
|
||||
private _vectorDirAndUp = getArray (_config >> QGVAR(rollVectorDirAndUp));
|
||||
_vectorDirAndUp params [["_vectorDir", [0, 1, 0], [[]], 3], ["_vectorUp", [1, 0, 0], [[]], 3]];
|
||||
|
||||
// Do as if object were facing north
|
||||
_projectile setVectorDirAndUp ([[_vectorDir, _vectorUp], -(direction _projectile), 0, 0] call BIS_fnc_transformVectorDirAndUp);
|
||||
|
||||
_velocity = (vectorDir _unit) vectorMultiply 10;
|
||||
};
|
||||
// Drop grenade
|
||||
case 4: {
|
||||
_velocity = [0, 0, 0];
|
||||
};
|
||||
};
|
||||
|
||||
_projectile setVelocity _velocity;
|
||||
|
@ -1,9 +1,10 @@
|
||||
[
|
||||
QGVAR(convertExplosives), "CHECKBOX",
|
||||
QGVAR(convertExplosives),
|
||||
"CHECKBOX",
|
||||
[LSTRING(convertExplosives_DisplayName), LSTRING(convertExplosives_Description)],
|
||||
LSTRING(Settings_DisplayName),
|
||||
true,
|
||||
true,
|
||||
{},
|
||||
true
|
||||
1,
|
||||
{[QGVAR(convertExplosives), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||
true // Needs mission restart
|
||||
] call CBA_fnc_addSetting;
|
||||
|
@ -16,11 +16,6 @@
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define EFFECT_STAGE_RESETAI 0
|
||||
#define EFFECT_STAGE_DELETELIGHT 1
|
||||
#define EFFECT_STAGE_PARTIALRECOVERY 2
|
||||
#define EFFECT_STAGE_FULLRECOVERY 3
|
||||
|
||||
#define EFFECT_SIZE 1
|
||||
|
||||
#define MIN_EXPLOSION_TIME_FOR_ROLL 1
|
||||
|
Loading…
Reference in New Issue
Block a user