Grenades - Add grenade rolling (#10005)

* Add grenade rolling

* Added some safeguards

* Use `setVectorDirAndUp` instead of rotation

* Don't allow players to roll grenades when in vehicles

* Grenades - Rolling only add PFEH when needed (#10015)

* Grenades - Rolling only add PFEH when needed

* Corrected minor typo, moved variable init in preInit, fixed bugs

---------

Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com>

* Don't switch modes if grenade can't be thrown

* Minor tweaks

---------

Co-authored-by: PabstMirror <pabstmirror@gmail.com>
This commit is contained in:
johnb432 2024-05-27 11:19:52 +02:00 committed by GitHub
parent be77ef233e
commit be9797d11d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 111 additions and 7 deletions

View File

@ -219,6 +219,10 @@ class CfgAmmo {
EGVAR(frag,force) = 0; EGVAR(frag,force) = 0;
}; };
class SmokeShell;
class rhs_ammo_rdg2_white: SmokeShell {
EGVAR(grenades,rollVectorDirAndUp)[] = {{0, 1, 0}, {0, 0, 1}};
};
class Sh_125mm_APFSDS; class Sh_125mm_APFSDS;
class Sh_125mm_HE; class Sh_125mm_HE;

View File

@ -4,6 +4,13 @@ class vn_molotov_grenade_ammo: vn_grenadehand {
EGVAR(frag,enabled) = 0; EGVAR(frag,enabled) = 0;
}; };
class vn_t67_grenade_ammo: vn_grenadehand {
EGVAR(grenades,rollVectorDirAndUp)[] = {{-1, 0, 0}, {0, 0, 1}};
};
class vn_chicom_grenade_ammo: vn_grenadehand {
EGVAR(grenades,rollVectorDirAndUp)[] = {{1, 0, 0}, {0, 0, 1}};
};
class SmokeShell; class SmokeShell;
class vn_m14_grenade_ammo: SmokeShell { class vn_m14_grenade_ammo: SmokeShell {
EGVAR(grenades,incendiary) = 1; EGVAR(grenades,incendiary) = 1;

View File

@ -32,3 +32,27 @@ GVAR(flashbangPPEffectCC) ppEffectForceInNVG true;
[] call FUNC(addChangeFuseItemContextMenuOptions); [] call FUNC(addChangeFuseItemContextMenuOptions);
}; };
}] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler;
["vehicle", {
private _currentThrowable = currentThrowable ACE_player;
// Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle)
if !(
GVAR(currentThrowMode) == 3 &&
{_currentThrowable isNotEqualTo []} &&
{
!isNull objectParent ACE_player ||
{getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL}
}
) exitWith {};
// If the player can't use throwables, don't change it
if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {};
// Force the user into the normal throw mode
// Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly...
[format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured);
GVAR(currentThrowMode) = 0;
GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler;
}, true] call CBA_fnc_addPlayerEventHandler;

View File

@ -6,6 +6,9 @@ PREP_RECOMPILE_START;
#include "XEH_PREP.hpp" #include "XEH_PREP.hpp"
PREP_RECOMPILE_END; PREP_RECOMPILE_END;
GVAR(currentThrowMode) = 0;
GVAR(throwModePFEH) = -1;
#include "initSettings.inc.sqf" #include "initSettings.inc.sqf"
ADDON = true; ADDON = true;

View File

@ -15,7 +15,7 @@
* Public: No * Public: No
*/ */
private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; private _mode = GVAR(currentThrowMode);
if (_mode == 4) then { if (_mode == 4) then {
_mode = 0; _mode = 0;
@ -23,9 +23,18 @@ if (_mode == 4) then {
_mode = _mode + 1; _mode = _mode + 1;
}; };
// ROLL GRENADE DOESN'T WORK RIGHT NOW private _currentThrowable = currentThrowable ACE_player;
if (_mode == 3) then {
_mode = 4; // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle)
if (
_mode == 3 &&
{_currentThrowable isNotEqualTo []} &&
{
!isNull objectParent ACE_player ||
{getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL}
}
) then {
_mode = _mode + 1;
}; };
private _hint = localize ([ private _hint = localize ([
@ -38,6 +47,37 @@ private _hint = localize ([
[_hint] call EFUNC(common,displayTextStructured); [_hint] call EFUNC(common,displayTextStructured);
GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler;
GVAR(currentThrowMode) = _mode; GVAR(currentThrowMode) = _mode;
// If in rolling mode, check every frame if current throwable is rollable
if (GVAR(currentThrowMode) == 3) then {
GVAR(currentThrowable) = _currentThrowable;
GVAR(throwModePFEH) = {
private _currentThrowable = currentThrowable ACE_player;
if (GVAR(currentThrowable) isEqualTo _currentThrowable) exitWith {};
GVAR(currentThrowable) = _currentThrowable;
// Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle)
if !(
GVAR(currentThrowMode) == 3 &&
{_currentThrowable isNotEqualTo []} &&
{
!isNull objectParent ACE_player ||
{getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL}
}
) exitWith {};
// Force the user into the normal throw mode
// Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly...
[format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured);
GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler;
GVAR(currentThrowMode) = 0;
} call CBA_fnc_addPerFrameHandler;
};
true true

View File

@ -85,7 +85,7 @@ if (getNumber (_config >> QGVAR(incendiary)) == 1) then {
if (_unit != ACE_player) exitWith {}; if (_unit != ACE_player) exitWith {};
if (_unit getVariable [QEGVAR(advanced_throwing,primed), false]) exitWith {LOG("advanced_throwing throw");}; if (_unit getVariable [QEGVAR(advanced_throwing,primed), false]) exitWith {LOG("advanced_throwing throw");};
private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; private _mode = GVAR(currentThrowMode);
if (_mode != 0) then { if (_mode != 0) then {
private _velocity = velocity _projectile; private _velocity = velocity _projectile;
@ -103,9 +103,22 @@ if (_mode != 0) then {
case 2 : { case 2 : {
_velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity);
}; };
//roll grande //roll grenade
case 3 : { case 3 : {
//@todo private _posASL = getPosASL _projectile;
// 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 //drop grenade
case 4 : { case 4 : {

View File

@ -20,3 +20,5 @@
#define EFFECT_STAGE_DELETELIGHT 1 #define EFFECT_STAGE_DELETELIGHT 1
#define EFFECT_STAGE_PARTIALRECOVERY 2 #define EFFECT_STAGE_PARTIALRECOVERY 2
#define EFFECT_STAGE_FULLRECOVERY 3 #define EFFECT_STAGE_FULLRECOVERY 3
#define MIN_EXPLOSION_TIME_FOR_ROLL 1

View File

@ -103,6 +103,9 @@
<Chinese>下丟投擲</Chinese> <Chinese>下丟投擲</Chinese>
<Turkish>Bombayı Yere Bırak</Turkish> <Turkish>Bombayı Yere Bırak</Turkish>
</Key> </Key>
<Key ID="STR_ACE_Grenades_RollGrenadeDisabled">
<English>Can't roll this grenade, switched to %1</English>
</Key>
<Key ID="STR_ACE_Grenades_M84_Name"> <Key ID="STR_ACE_Grenades_M84_Name">
<English>M84 Stun Grenade</English> <English>M84 Stun Grenade</English>
<German>M84 Blendgranate</German> <German>M84 Blendgranate</German>

View File

@ -23,6 +23,8 @@ version:
### 1.1 Throw modes ### 1.1 Throw modes
Provides different modes for throwing grenades (high throw, precision throw and drop mode). Provides different modes for throwing grenades (high throw, precision throw and drop mode).
A grenade is only rollable if the fuse time (`explosionTime`) is >= 1 second and the player isn't in a vehicle.
### 1.2 Hand flares ### 1.2 Hand flares
Adds throwable hand flares in the colors white, red, green and yellow. Additionally buffs existing flares by making them brighter and last longer. Adds throwable hand flares in the colors white, red, green and yellow. Additionally buffs existing flares by making them brighter and last longer.

View File

@ -112,6 +112,12 @@ If set to zero or left undefined, the grenade is not treated as a flare. If it i
Sets the color of the emitted light. The first 3 values of the array of the color, the last is the light intensity. Sets the color of the emitted light. The first 3 values of the array of the color, the last is the light intensity.
### 2.4 Grenade Rolling
#### 2.4.1 ace_grenades_rollVectorDirAndUp
Sets the `setVectorDirAndUp` of the grenade when the grenade is rolled.
## 3. Events ## 3. Events
### 3.1 Listenable ### 3.1 Listenable