Ability to link a belt of ammo to an AR's machinegun while he's firing. Non stop suppresion!

This commit is contained in:
Nicolás Badano 2015-02-20 02:45:17 -03:00
parent 2c05db3ffb
commit 96abddc31b
10 changed files with 267 additions and 0 deletions

View File

@ -110,6 +110,7 @@ PREP(removeCameraEventHandler);
PREP(removeCustomEventHandler);
PREP(removeMapMarkerCreatedEventHandler);
PREP(removeScrollWheelEventHandler);
PREP(removeSpecificMagazine);
PREP(restoreVariablesJIP);
PREP(revertKeyCodeLocalized);
PREP(sanitizeString);

View File

@ -0,0 +1,69 @@
/*
* Author: CAA-Picard
* Removes a magazine from the unit that has an specific ammo count
*
* Argument:
* 0: Player <OBJECT>
* 1: Magazine <STRING>
* 2: Ammo count <NUMBER>
*
* Return value:
* None
*/
#include "script_component.hpp"
EXPLODE_3_PVT(_this,_player,_magazineType,_ammoCount);
private ["_magazines","_index","_isRemoved"];
_isRemoved = false;
// Check uniform
_magazines = [magazinesAmmoCargo uniformContainer _player, {_this select 0 == _magazineType}] call FUNC(filter);
_index = _magazines find [_magazineType,_ammoCount];
if (_index > -1) exitWith {
{
_player removeItemFromUniform (_x select 0);
} forEach _magazines;
{
if (!_isRemoved && (_x isEqualTo [_magazineType,_ammoCount])) then {
_isRemoved = true;
} else {
(uniformContainer _player) addMagazineAmmoCargo [_x select 0, 1, _x select 1];
};
} forEach _magazines;
};
// Check vest
_magazines = [magazinesAmmoCargo vestContainer _player, {_this select 0 == _magazineType}] call FUNC(filter);
_index = _magazines find [_magazineType,_ammoCount];
if (_index > -1) exitWith {
{
_player removeItemFromVest (_x select 0);
} forEach _magazines;
{
if (!_isRemoved && (_x isEqualTo [_magazineType,_ammoCount])) then {
_isRemoved = true;
} else {
(vestContainer _player) addMagazineAmmoCargo [_x select 0, 1, _x select 1];
};
} forEach _magazines;
};
// Check backpack
_magazines = [magazinesAmmoCargo backpackContainer _player, {_this select 0 == _magazineType}] call FUNC(filter);
_index = _magazines find [_magazineType,_ammoCount];
if (_index > -1) exitWith {
{
_player removeItemFromBackpack (_x select 0);
} forEach _magazines;
{
if (!_isRemoved && (_x isEqualTo [_magazineType,_ammoCount])) then {
_isRemoved = true;
} else {
(backpackContainer _player) addMagazineAmmoCargo [_x select 0, 1, _x select 1];
};
} forEach _magazines;
};

View File

@ -0,0 +1,12 @@
class CfgMagazines {
class CA_Magazine;
class 150Rnd_762x51_Box : CA_Magazine {
ACE_isBelt = 1;
};
class 100Rnd_65x39_caseless_mag;
class 200Rnd_65x39_cased_Box : 100Rnd_65x39_caseless_mag {
ACE_isBelt = 1;
};
};

View File

@ -0,0 +1,19 @@
class CfgVehicles {
class Man;
class CAManBase: Man {
class ACE_Actions {
class ACE_WeaponsActions {
selection = "weapon";
displayName = "Weapon";
distance = 2;
condition = QUOTE([ARR_2(_player, _target)] call FUNC(canLinkBelt));
class ACE_LinkBelt {
displayName = "$STR_ACE_Reload_LinkBelt";
distance = 2;
condition = QUOTE([ARR_2(_player, _target)] call FUNC(canLinkBelt));
statement = QUOTE([ARR_2(_player, _target)] call FUNC(startLinkingBelt));
};
};
};
};
};

View File

@ -22,3 +22,48 @@ if !(hasInterface) exitWith {};
false,
"keydown"
] call cba_fnc_registerKeybind;
// Listen for attempts to link ammo
["linkedAmmo", {
EXPLODE_3_PVT(_this,_receiver,_giver,_magazine);
diag_log "linkedAmmo";
diag_log _this;
private ["_magazineCfg","_magazineType"];
_magazineType = currentMagazine _receiver;
_magazineCfg = configFile >> "CfgMagazines" >> _magazineType;
// Return the magazine if it's the wrong type
if (_magazineType != (_magazine select 0)) exitWith {
["returnedAmmo", [_giver], [_giver,_receiver,_magazine]] call EFUNC(common,targetEvent);
};
private ["_ammoCount","_ammoMissing","_ammoAdded","_ammoRemaining"];
_ammoCount = _receiver ammo currentWeapon _receiver;
_ammoMissing = getNumber (_magazineCfg >> "count") - _ammoCount;
// Return the magazine if the belt is full or empty
if ((_ammoCount == 0) || _ammoMissing == 0) exitWith {
["returnedAmmo", [_giver], [_giver,_receiver,_magazine]] call EFUNC(common,targetEvent);
};
// Add the ammo
_ammoAdded = _ammoMissing min (_magazine select 1);
_receiver setAmmo [currentWeapon _receiver, _ammoCount + _ammoAdded];
if ((_magazine select 1) - _ammoAdded > 0) then {
["returnedAmmo", [_giver], [_giver,_receiver,[_magazineType,(_magazine select 1) - _ammoAdded]]] call EFUNC(common,targetEvent);
};
}] call EFUNC(common,addEventhandler);
// Listen for returned magazines
["returnedAmmo", {
EXPLODE_3_PVT(_this,_receiver,_giver,_magazine);
diag_log "returnedAmmo";
diag_log _this;
_receiver addMagazine _magazine;
}] call EFUNC(common,addEventhandler);

View File

@ -2,6 +2,8 @@
ADDON = false;
PREP(canLinkBelt);
PREP(checkAmmo);
PREP(startLinkingBelt);
ADDON = true;

View File

@ -12,6 +12,10 @@ class CfgPatches {
};
};
#include "CfgVehicles.hpp"
#include "CfgMagazines.hpp"
#include "CfgEventHandlers.hpp"
#include "CfgActions.hpp"

View File

@ -0,0 +1,41 @@
/*
* Author: CAA-Picard
* Check if the target has an MG equiped with belt system that the player can link
*
* Argument:
* 0: Player <OBJECT>
* 1: Target <OBJECT>
*
* Return value:
* Can link belt<BOOL>
*/
#include "script_component.hpp"
EXPLODE_2_PVT(_this,_player,_target);
if (vehicle _target != _target) exitWith {false};
private ["_magazineCfg","_magazineType"];
_magazineType = currentMagazine _target;
_magazineCfg = configFile >> "CfgMagazines" >> _magazineType;
if (getNumber (_magazineCfg >> "ACE_isBelt") == 0) exitWith {false};
// Check if the ammo is not empty or full
private "_ammoCount";
_ammoCount = _target ammo currentWeapon _target;
// Exit if the belt is full or empty
if ((_ammoCount == 0) || (getNumber (_magazineCfg >> "count") - _ammoCount) == 0) exitWith {false};
// Check if the player has any of the same same magazines
// Calculate max ammo
private "_maxAmmo";
_maxAmmo = 0;
{
diag_log "filtered:";
diag_log _x;
_maxAmmo = _maxAmmo max (_x select 1);
} forEach ([magazinesAmmo _player, {_this select 0 == _magazineType}] call EFUNC(common,filter));
_maxAmmo > 0

View File

@ -0,0 +1,68 @@
/*
* Author: CAA-Picard
* Start linking the belt
*
* Argument:
* 0: Player <OBJECT>
* 1: Target <OBJECT>
*
* Return value:
* None
*/
#include "script_component.hpp"
EXPLODE_2_PVT(_this,_player,_target);
if (vehicle _target != _target) exitWith {false};
private ["_magazineCfg","_magazineType"];
_magazineType = currentMagazine _target;
_magazineCfg = configFile >> "CfgMagazines" >> _magazineType;
if (getNumber (_magazineCfg >> "ACE_isBelt") == 0) exitWith {false};
// Check if the ammo is not empty or full
private "_ammoCount";
_ammoCount = _target ammo currentWeapon _target;
// Exit if the belt is full or empty
if ((_ammoCount == 0) || (getNumber (_magazineCfg >> "count") - _ammoCount) == 0) exitWith {false};
// Check if the player has any of the same same magazines
// Calculate max ammo it can link
private "_maxAmmo";
_maxAmmo = 0;
{
_maxAmmo = _maxAmmo max (_x select 1);
} forEach ([magazinesAmmo _player, {_this select 0 == _magazineType}] call EFUNC(common,filter));
if (_maxAmmo == 0) exitWith {};
// Condition to call each frame
_condition = {
EXPLODE_2_PVT((_this select 0),_player,_target);
([_player, _target] call EFUNC(common,canInteract)) && ((_player distance _target) < 3) && ((speed _target) < 1)
};
_onFinish = {
EXPLODE_3_PVT((_this select 0),_player,_target,_magazine);
// Raise event on remote unit
["linkedAmmo", [_target], [_target, _player, _magazine]] call EFUNC(common,targetEvent);
};
_onFailure = {
EXPLODE_3_PVT((_this select 0),_player,_target,_magazine);
[_caller, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation);
// Add back the magazine with the former ammo count
_player addMagazine _magazine;
};
[_player, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation);
// Remove the magazine with maximum remaining ammo
[_player, _magazineType, _maxAmmo] call EFUNC(common,removeSpecificMagazine);
// Call progress bar
[4, [_player, _target, [_magazineType, _maxAmmo]], _onFinish, _onFailure, (localize "STR_ACE_Reload_LinkingBelt"), _condition] call EFUNC(common,progressBar);

View File

@ -26,5 +26,11 @@
<Portuguese>Munições</Portuguese>
<Russian>Боеприпасы</Russian>
</Key>
<Key ID="STR_ACE_Reload_LinkBelt">
<English>Link belt</English>
</Key>
<Key ID="STR_ACE_Reload_LinkingBelt">
<English>Linking belt...</English>
</Key>
</Package>
</Project>