Skip to content

Commit

Permalink
Backpack on Chest
Browse files Browse the repository at this point in the history
Mike-MF committed Jan 6, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 2c64797 commit 9930a88
Showing 50 changed files with 1,511 additions and 0 deletions.
1 change: 1 addition & 0 deletions addons/backpack_on_chest/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x\tac\addons\backpack_on_chest
27 changes: 27 additions & 0 deletions addons/backpack_on_chest/ACE_Arsenal_Actions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class ace_arsenal_actions {
class ADDON {
displayName = CSTRING(DisplayName);
condition = QUOTE((_this select 0) call FUNC(canMovePack) && {backpack (_this select 0) != '' || {(_this select 0) call FUNC(chestpack) != ''}});
scopeEditor = 0;
tabs[] = {5};
class GVAR(chestpack) {
condition = QUOTE((_this select 0) call FUNC(chestpack) != '');
textStatement = QUOTE(getText (configFile >> 'CfgVehicles' >> (_this select 0) call FUNC(chestpack) >> 'displayName'));
};
class GVAR(onChest) {
label = CSTRING(OnChest);
condition = QUOTE((_this select 0) call FUNC(canMovePack) && {backpack (_this select 0) != ''} && {(_this select 0) call FUNC(chestpack) == ''});
statement = QUOTE((_this select 0) call FUNC(actionOnChest));
};
class GVAR(onBack) {
label = CSTRING(OnBack);
condition = QUOTE((_this select 0) call FUNC(canMovePack) && {backpack (_this select 0) == ''} && {(_this select 0) call FUNC(chestpack) != ''});
statement = QUOTE((_this select 0) call FUNC(actionOnBack));
};
class GVAR(swap) {
label = CSTRING(Swap);
condition = QUOTE((_this select 0) call FUNC(canMovePack) && {backpack (_this select 0) != ''} && {(_this select 0) call FUNC(chestpack) != ''});
statement = QUOTE((_this select 0) call FUNC(actionSwap));
};
};
};
17 changes: 17 additions & 0 deletions addons/backpack_on_chest/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
};
};

class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
};
};

class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
};
};
40 changes: 40 additions & 0 deletions addons/backpack_on_chest/CfgVehicles.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class CfgVehicles {
class Man;
class CAManBase: Man {
class ACE_SelfActions {
class ACE_Equipment {
class GVAR(onChest) {
displayName = CSTRING(OnChest);
condition = QUOTE([_player] call FUNC(canMovePack) && {!(backpack _player isEqualTo '') && (([_player] call FUNC(chestpack)) isEqualTo '')});
exceptions[] = {"isNotInside"};
statement = QUOTE([_player] call FUNC(actionOnChest));
showDisabled = 0;
priority = 2.5;
icon = QPATHTOF(ui\onchest_ca.paa);
};
class GVAR(onBack) : GVAR(onChest) {
displayName = CSTRING(OnBack);
condition = QUOTE([_player] call FUNC(canMovePack) && {(backpack _player isEqualTo '') && !(([_player] call FUNC(chestpack)) isEqualTo '')});
statement = QUOTE([_player] call FUNC(actionOnBack));
icon = QPATHTOF(ui\onback_ca.paa);
};
class GVAR(swap) : GVAR(onChest) {
displayName = CSTRING(Swap);
condition = QUOTE([_player] call FUNC(canMovePack) && {!(backpack _player isEqualTo '') && !(([_player] call FUNC(chestpack)) isEqualTo '')});
statement = QUOTE([_player] call FUNC(actionSwap));
icon = QPATHTOF(ui\swap_ca.paa);
};
class GVAR(lower) : GVAR(onChest) {
displayName = CSTRING(lower);
condition = QUOTE([_player] call FUNC(canLower));
statement = QUOTE([_player] call FUNC(actionLower));
};
class GVAR(cutLoweringLine) : GVAR(onChest) {
displayName = CSTRING(cutLoweringLine);
condition = QUOTE([_player] call FUNC(canCutLoweringLine));
statement = QUOTE([_player] call FUNC(actionCutLoweringLine));
};
};
};
};
};
8 changes: 8 additions & 0 deletions addons/backpack_on_chest/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# About

Adds Backpack on Chest REDUX, with some minor reworks and optimisations

### Authors
- [mjc4wilton](https://github.com/mjc4wilton)
- [DerZade](https://github.com/DerZade)
- [MikeMF](https://github.com/Mike-MF)
33 changes: 33 additions & 0 deletions addons/backpack_on_chest/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
PREP(actionCutLoweringLine);
PREP(actionLower);
PREP(actionOnBack);
PREP(actionSwap);
PREP(addChestpack);
PREP(addItemToChestpack);
PREP(addMagToChestpack);
PREP(arsenal_onButtonClick);
PREP(arsenal_opened);
PREP(arsenal_postInit);
PREP(arsenal_updateUI);
PREP(canAddItemToChestpack);
PREP(canCutLoweringLine);
PREP(canLower);
PREP(canMovePack);
PREP(chestpack);
PREP(chestpackContainer);
PREP(chestpackLoadout);
PREP(chestpackToHolder);
PREP(chestpackVariables);
PREP(clearAllCargo);
PREP(clearAllItemsFromChestpack);
PREP(clearCargoBackpacks);
PREP(EHAnimDone);
PREP(EHGetIn);
PREP(EHGetOut);
PREP(EHHandleDisconnect);
PREP(EHKilled);
PREP(itemMass);
PREP(removeChestpack);
PREP(removeItemFromChestpack);
PREP(removeMagFromChestpack);
PREP(setBackpackLoadout);
46 changes: 46 additions & 0 deletions addons/backpack_on_chest/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "script_component.hpp"

[] call FUNC(arsenal_postInit);

// Clear inventory of a container
[QGVAR(clearAllCargo), {call FUNC(clearAllCargo)}] call CBA_fnc_addEventHandler;
// Clear inventory of every backpack in a container
[QGVAR(clearCargoBackpacks), {call FUNC(clearCargoBackpacks)}] call CBA_fnc_addEventHandler;

// Backpack classnames which will be made invisible instead of being made a chestpack. Useful for items like the vanilla legstrap.
GVAR(exceptions) = [
"B_LegStrapBag_black_F",
"B_LegStrapBag_coyote_F",
"B_LegStrapBag_olive_F"
];

if (isServer) exitWith {};

[QGVAR(handleDisconnect), {
addMissionEventHandler ["HandleDisconnect", FUNC(EHHandleDisconnect)];
}] call CBA_fnc_addEventHandler;

// holding the backpack have landed
[QGVAR(checkLandedPFH), {
params ["_ropeTop", "_holder"];

// PFH to check when the helper object _ropeTop and the WeaponHolderSimulated
[{
params ["_ropeTop", "_handle"];

if (speed _ropeTop < 1 && {((getPos _ropeTop) select 2) < 1}) exitWith {
deleteVehicle _ropeTop;
[_handle] call CBA_fnc_removePerFrameHandler;
};
}, 0, _ropeTop] call CBA_fnc_addPerFrameHandler;

[{
params ["_holder", "_handle"];
if (speed _holder < 1 && {getPos _holder # 2 < 1}) exitWith {
private _pos = getPos _holder;
_pos set [2, 0];
_holder setPos _pos;
[_handle] call CBA_fnc_removePerFrameHandler;
};
}, 0, _holder] call CBA_fnc_addPerFrameHandler;
}] call CBA_fnc_addEventHandler;
8 changes: 8 additions & 0 deletions addons/backpack_on_chest/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "script_component.hpp"

ADDON = false;

#include "XEH_PREP.hpp"
#include "initSettings.inc.sqf"

ADDON = true;
3 changes: 3 additions & 0 deletions addons/backpack_on_chest/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

#include "XEH_PREP.hpp"
19 changes: 19 additions & 0 deletions addons/backpack_on_chest/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"tac_main"};
author = ECSTRING(main,Author);
authors[] = {"DerZade", "mjc4wilton", "MikeMF"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};

#include "ACE_Arsenal_Actions.hpp"
#include "CfgEventHandlers.hpp"
#include "CfgVehicles.hpp"
33 changes: 33 additions & 0 deletions addons/backpack_on_chest/functions/fnc_EHAnimDone.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Triggered by AnimDone-Eventhandler
*
* Arguments:
* 0: unit <OBJECT>
* 1: animtaion <STRING>
*
* Return Value:
* Nothing
*
* Example:
* _this call tac_backpack_on_chest_fnc_EHAnimDone;
*
* Public: No
*/
params ["_unit","_anim"];

if (isNil "_unit") exitWith {
ERROR("No proper argument(s) given.");
};

private _chestpack = [_unit] call FUNC(chestpackContainer);
private _chestpackClass = [_unit] call FUNC(chestpack);

// freefall
if ((animationState _unit) find "halofreefall_" isEqualTo 0) then {
if !(_chestpackClass in GVAR(exceptions)) then {
_chestpack attachTo [_unit,[0,-0.4,0.05],"pelvis"];
_chestpack setVectorDirAndUp [[0,0,1],[0,1,0]];
};
};
36 changes: 36 additions & 0 deletions addons/backpack_on_chest/functions/fnc_EHGetIn.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Triggered by GetInMan-Eventhandler
*
* Arguments:
* 0: unit <OBJECT>
* 1: position <STRING>
* 2: vehicle <OBJECT>
* 3: turret path <ARRAY>
*
* Return Value:
* Nothing
*
* Example:
* _this call tac_backpack_on_chest_fnc_EHGetIn;
*
* Public: No
*/
params ["_unit","_position","_veh"];

if (isNil "_unit" || isNil "_veh") exitWith {
ERROR("No proper argument(s) given.");
};

private _chestpack = [_unit] call FUNC(chestpackContainer);

if (_veh isKindOf "ParachuteBase") then {
_chestpack attachTo [_veh, [0, -0.03, -0.5]];
_chestpack setVectorDirAndUp [[-0.25, -1, 0], [0, 0, 1]];
_chestpack hideObjectGlobal false;
} else {
detach _chestpack;
hideObjectGlobal _chestpack;
_chestpack setPos [-10000, -10000, -100];
};
37 changes: 37 additions & 0 deletions addons/backpack_on_chest/functions/fnc_EHGetOut.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Triggered by GetOutMan-Eventhandler
*
* Arguments:
* 0: unit <OBJECT>
* 1: position <STRING>
* 2: vehicle <OBJECT>
* 3: turret path <ARRAY>
*
* Return Value:
* Nothing
*
* Example:
* _this call tac_backpack_on_chest_fnc_EHGetOut;
*
* Public: No
*/
params ["_unit","_position","_veh"];

if (isNil "_unit" || isNil "_veh") exitWith {
ERROR("No proper argument(s) given.");
};

private _chestpack = [_unit] call FUNC(chestpackContainer);
private _chestpackClass = [_unit] call FUNC(chestpack);

if !(_chestpackClass in GVAR(exceptions)) then {
_chestpack attachTo [_unit, [0,-0.03,-0.5], "pelvis"];
_chestpack setVectorDirAndUp [[-0.25,-1,0], [0,0,1]];
_chestpack hideObjectGlobal false;
};

if (GVAR(walk)) then {
[_unit, "forceWalk", "BackpackOnChest", true] call ACEFUNC(common,statusEffect_set);
};
28 changes: 28 additions & 0 deletions addons/backpack_on_chest/functions/fnc_EHHandleDisconnect.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton, MikeMF
* Triggered by HandleDisconnect-Eventhandler on Server.
* Handles deleting the chestpack of old units form disconnected players.
*
* Arguments:
* 0: unit <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* _this call tac_backpack_on_chest_fnc_EHHandleDisconnect;
*
* Public: Yes
*/
params ["_unit", "_id", "_uid", "_name"];

if ([_unit] call FUNC(chestpack) isEqualTo "") exitWith {};

[{
params ["_unit"];
private _container = _unit call FUNC(chestpackContainer);
if (!alive _unit) then {
deleteVehicle _container;
};
}, _unit, 1.5] call CBA_fnc_waitAndExecute;
38 changes: 38 additions & 0 deletions addons/backpack_on_chest/functions/fnc_EHKilled.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton, Ampersand
* Triggered by Killed-Eventhandler
*
* Arguments:
* 0: unit <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player] call tac_backpack_on_chest_fnc_EHKilled;
*
* Public: No
*/

params ["_unit"];

private _chestpack = [_unit] call FUNC(chestpack);
private _chestpackLoadout = [_unit] call FUNC(chestpackLoadout);
private _chestpackVariables = [_unit] call FUNC(chestpackVariables);

private _holder = createVehicle ["WeaponHolderSimulated", (getPos _unit), [], 0, "CAN_COLLIDE"];

// add pack
_holder addBackpackCargoGlobal [_chestpack, 1];
private _backpack = firstBackpack _holder;

[_backpack, _chestpackLoadout] call FUNC(setBackpackLoadout);

// add variables
{
_backpack setVariable [(_x select 0), (_x select 1), true];
} forEach _chestpackVariables;

// remove the backpack from the dead unit
[_unit] call FUNC(removeChestpack);
29 changes: 29 additions & 0 deletions addons/backpack_on_chest/functions/fnc_actionCutLoweringLine.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "..\script_component.hpp"
/*
* Author: Ampersand
* Triggered by the CutLoweringLine-action. Detaches the lowering line top
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player] call tac_backpack_on_chest_fnc_actionCutLoweringLine;
*
* Public: No
*/

params ["_unit"];
private _chute = vehicle _unit;
private _ropeTop = _chute getVariable [QGVAR(loweringLine), objNull];
if (!isNull _ropeTop) then {
private _rope = (ropes _ropeTop) select 0;
private _holder = (ropeAttachedObjects _ropeTop) select 0;
if !(isNull _holder) then {
_holder ropeDetach _rope;
ropeDestroy _rope;
};
_chute setVariable [QGVAR(loweringLine), nil, true];
};
45 changes: 45 additions & 0 deletions addons/backpack_on_chest/functions/fnc_actionLower.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "..\script_component.hpp"
/*
* Author: Ampersand
* Triggered by the lower-action. Attaches chestpack to a dummy and connects dummy to parachute by rope.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player] call tac_backpack_on_chest_fnc_actionLower;
*
* Public: No
*/

params ["_unit"];

private _chute = vehicle _unit;

// Rope top helper, workaround parachute rope visual bug, allow cut
private _ropeTop = createVehicle ["ace_fastroping_helper", getPos _chute, [], 0, "CAN_COLLIDE"];
_chute setVariable [QGVAR(loweringLine), _ropeTop, true];
_ropeTop allowDamage false;
_ropeTop disableCollisionWith _chute;

// Weapon holder with backpack
private _holder = [_unit] call FUNC(chestpackToHolder); // Chestpack to holder
_holder disableCollisionWith _chute;
_holder setPos (_chute modelToWorld [0, 1, -1]);
_holder setVelocity velocity _chute;

private _rope = ropeCreate [
_ropeTop, [0,0,0],
_holder, [0.1,-0.2,-0.55],
5
];

[{
params ["_chute", "_ropeTop"];
_ropeTop attachTo [_chute, [0,0,0]];
}, [_chute, _ropeTop]] call CBA_fnc_execNextFrame;

[QGVAR(checkLandedPFH), [_ropeTop, _holder]] call CBA_fnc_serverEvent;
44 changes: 44 additions & 0 deletions addons/backpack_on_chest/functions/fnc_actionOnBack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Triggered by the onBack-action. Handles all the stuff.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player] call tac_backpack_on_chest_fnc_actionOnBack;
*
* Public: No
*/
params ["_unit"];

private _chestpack = [_unit] call FUNC(chestpack);
private _chestpackLoadout = [_unit] call FUNC(chestpackLoadout);
private _chestpackVariables = [_unit] call FUNC(chestpackVariables);

// make sure the player has a chestpack and no backpack
if ((_chestpack isEqualTo "") || (backpack _unit isNotEqualTo "")) exitWith {};

// add items
private _loadout = getUnitLoadout _unit;
_loadout set [5, [_chestpack, _chestpackLoadout]];
_unit setUnitLoadout _loadout;

/*
* prefilled versions of backpacks (ammo bearer, engineer, explosives, medic, repair, etc), can be emptied and placed in unit's backpack.
* they must each be emptied when added safe since game inventory won't let players add non-empty backpacks into their backpack
*/

[QGVAR(clearCargoBackpacks), [backpackContainer _unit]] call CBA_fnc_globalEvent;

// add variables
private _backpack = backpackContainer _unit;
{
_backpack setVariable [(_x select 0), (_x select 1), true];
} forEach _chestpackVariables;

[_unit] call FUNC(removeChestpack);
32 changes: 32 additions & 0 deletions addons/backpack_on_chest/functions/fnc_actionOnChest.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Triggered by the onChest-action. Handles all the stuff.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player] call tac_backpack_on_chest_fnc_actionOnChest;
*
* Public: No
*/

params["_unit"];

private _backpack = backpack _unit;
private _backpackLoad = loadBackpack _unit;
private _backpackLoadout = ((getUnitLoadout _unit) select 5) select 1;
private _backpackVariables = [];

{
private _val = (backpackContainer _unit) getVariable _x;
_backpackVariables pushBack [_x, _val];
} forEach ((allVariables (backpackContainer _unit) - GVAR(VarBlacklist)));

[_unit, _backpack, _backpackLoadout, _backpackVariables, _backpackLoad] call FUNC(addChestpack);

removeBackpackGlobal _unit;
53 changes: 53 additions & 0 deletions addons/backpack_on_chest/functions/fnc_actionSwap.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Triggered by the swap-action. Handles all the stuff.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player] call tac_backpack_on_chest_fnc_actionSwap;
*
* Public: No
*/
params ["_unit"];

private _backpack = backpack _unit;
private _backpackLoad = loadBackpack _unit;
private _backpackLoadout = ((getUnitLoadout _unit) select 5) select 1;
private _backpackVariables = [];

private _chestpack = [_unit] call FUNC(chestpack);
private _chestpackLoadout = [_unit] call FUNC(chestpackLoadout);
private _chestpackVariables = [_unit] call FUNC(chestpackVariables);

// make sure the player has chest-pack and backpack
if ((_backpack isEqualTo "") || ([_unit] call FUNC(chestpack)) isEqualTo "") exitWith {};

// Backpack Variable Handling
{
private _val = (backpackContainer _unit) getVariable _x;
_backpackVariables pushBack [_x, _val];
} forEach ((allVariables (backpackContainer _unit) - GVAR(VarBlacklist)));

// remove packs
[_unit] call FUNC(removeChestpack);
removeBackpackGlobal _unit;

// add backpack loadout
private _loadout = getUnitLoadout _unit;
_loadout set [5, [_chestpack, _chestpackLoadout]];
_unit setUnitLoadout _loadout;

// add backpack variables
private _backpackNew = backpackContainer _unit;
{
_backpackNew setVariable [(_x select 0), (_x select 1), true];
} forEach _chestpackVariables;

// add chestpack
[_unit, _backpack, _backpackLoadout, _backpackVariables, _backpackLoad] call FUNC(addChestpack);
59 changes: 59 additions & 0 deletions addons/backpack_on_chest/functions/fnc_addChestpack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Adds a chestpack to a unit. If a unit already has one, the old chestpack will be ignored and will be deleted completely.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Backpack Classname <STRING>
* 2: Backpack Loadout <ARRAY>
* 3: Backpack Variables <ARRAY>
*
* Return Value:
* Nothing
*
* Example:
* [player, "B_Kitbag_rgr", ["FirstAidKit", 5], ["ace_gunbag_gunbagWeapon", "srifle_GM6_F"], []] call tac_backpack_on_chest_fnc_addChestpack;
*
* Public: No
*/
params ["_unit", "_chestpackClass", ["_backpackLoadout", []], ["_backpackVariables", []], ["_backpackLoad", -2]];

if (_backpackLoad isEqualTo -2) then {
_backpackLoad = loadBackpack _unit;
};

// add HandleDisconnect-EH on server if not done yet
if !(GETMVAR(GVAR(HDCEHadded),false)) then {
[QGVAR(handleDisconnect), []] call CBA_fnc_serverEvent;
GVAR(HDCEHadded) = true;
publicVariable QGVAR(HDCEHadded);
};

// delete existing chestpack, if there is one
if ([_unit] call FUNC(chestpack) != "") then {
[_unit] call FUNC(removeChestpack);
};

// add EHs
private _getInID = _unit addEventHandler ["GetInMan",FUNC(EHGetIn)];
private _getOutID = _unit addEventHandler ["GetOutMan",FUNC(EHGetOut)];
private _animID = _unit addEventHandler ["AnimDone",FUNC(EHAnimDone)];
private _killedID = _unit addEventHandler ["Killed",FUNC(EHKilled)];

// create chestpack itself
private _chestpack = createSimpleObject [_chestpackClass, getPos _unit];

if (GVAR(walk)) then {
[_unit, "forceWalk", "BackpackOnChest", true] call ACEFUNC(common,statusEffect_set);
};

// set variable
_unit setVariable [QGVAR(chestpack), [[_chestpackClass, _chestpack], [_getInID, _getOutID, _animID, _killedID], _backpackLoadout, _backpackVariables, _backpackLoad], true];

// handle vehicles
if (vehicle _unit isNotEqualTo _unit) then {
[_unit, "", vehicle _unit] call FUNC(EHGetIn);
} else {
[_unit, "", objNull] call FUNC(EHGetOut);
};
34 changes: 34 additions & 0 deletions addons/backpack_on_chest/functions/fnc_addItemToChestpack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Creates a new item and stores it in the soldier's chestpack.
* The item(s) won't be added, if adding them would cause an overflow of the backpack.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Item <ARRAY>
*
* Return Value:
* Nothing
*
* Example:
* [player,"FirstAidKit"] call tac_backpack_on_chest_fnc_addItemToChestpack;
*
* Public: No
*/
params ["_unit","_item"];

private _var = _unit getVariable [QGVAR(chestpack), nil];

// exit if there is not enough space left
if !([_unit, _item] call FUNC(canAddItemToChestpack)) exitWith {};

// add item
private _itemMass = [_item] call FUNC(itemMass);
private _maximumLoad = getNumber(configFile >> "CfgVehicles" >> ([_unit] call FUNC(chestpack)) >> "maximumLoad");
private _preLoadPercent = _var select 4;
(_var select 2) pushBack [_item, 1];
_var set [4, (_preLoadPercent + (_itemMass / _maximumLoad))];

// update public variable
_unit setVariable [QGVAR(chestpack), _var, true];
32 changes: 32 additions & 0 deletions addons/backpack_on_chest/functions/fnc_addMagToChestpack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Creates new magazine and stores it in the soldier's chestpack. Only magazines are supported.
* The purpose of this function is to ensure that magazines with a specified ammo count can be added.
* If you want to add a/multiple full magazine(s) you may want to use 'zade_boc_addItemToChestpack' instead.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Classname <STRING>
* 2: Ammo count <NUMBER>
* 3: Quanitity (Optional) <NUMBER>
*
* Return Value:
* Nothing
*
* Example:
* [player,"30Rnd_556x45_Stanag",25] call zade_boc_fnc_addMagToChestpack;
*
* Public: No
*/
params ["_unit","_item","_ammo", ["_quantity", 1]];

// exit if there is not enough space left
if !([_unit, _item, _quantity] call FUNC(canAddItemToChestpack)) exitWith {};

private _var = _unit getVariable [QGVAR(chestpack), nil];

(_var select 2) pushBack [_item, _quantity, _ammo];

// update variable
_unit setVariable [QGVAR(chestpack), _var, true];
42 changes: 42 additions & 0 deletions addons/backpack_on_chest/functions/fnc_arsenal_onButtonClick.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Triggered by the onButtonClick-EventHandler.
*
* Arguments:
* None
*
* Return Value:
* Nothing
*
* Example:
* [] call tac_backpack_on_chest_fnc_arsenal_onButtonClick;
*
* Public: No
*/
private _center = missionNamespace getVariable ["BIS_fnc_arsenal_center", player];

private _chestpack = [_center] call FUNC(chestpack);
private _backpack = backpack _center;

private _action = ["onback", "onchest"] select (_chestpack isEqualTo "");

if ((_backpack isNotEqualTo "") && (_chestpack isNotEqualTo "")) then {
_action = "swap";
};

// execute action
switch (_action) do {
case ("onback"): {
[_center] call FUNC(actionOnBack);
};
case ("onchest"): {
[_center] call FUNC(actionOnChest);
};
case ("swap"): {
[_center] call FUNC(actionSwap);
};
};

// update arsenal
["ListSelectCurrent"] call BIS_fnc_arsenal;
56 changes: 56 additions & 0 deletions addons/backpack_on_chest/functions/fnc_arsenal_opened.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Called by XEH_postInit. Creates button.
*
* Arguments:
* 0: Arsenal Display <DISPLAY>
*
* Return Value:
* Nothing
*
* Example:
* [_disp] call tac_backpack_on_chest_fnc_arsenal_opened;
*
* Public: No
*/
params ["_display"];

// exit if BOC is disabled
if (GVAR(disabled)) exitWith {};

// get lowest button that is hidden
private _notshown = 948;
for "_i" from 948 to 945 step -1 do {
if !(ctrlShown (_display displayCtrl _i)) then {
_notshown = _i;
};
};

// default offset of two buttons
private _offset = ((ctrlPosition (_display displayCtrl 932)) select 1) - ((ctrlPosition (_display displayCtrl 930)) select 1);

private _btn = _display ctrlCreate ["RscButtonArsenal", 9233];

// set pos
private _pos = ctrlPosition (_display displayCtrl (_notshown - 1));
_pos set [1, (_pos select 1) + _offset];
_btn ctrlSetPosition _pos;
_btn ctrlCommit 0;

// set color
_btn ctrlSetBackgroundColor [0,0,0,0.5];

// add EH to backpack list and to newly created button
(_display displayCtrl 965) ctrlAddEventHandler ["LBSelChanged",FUNC(arsenal_updateUI)];
_btn ctrlAddEventHandler ["ButtonClick",FUNC(arsenal_onButtonClick)];

// this is for hiding the button when the rest of the ui is hidden (e.g. by pressing BACKSPACE)
_display displayAddEventHandler ["KeyDown",
"0 = _this spawn {sleep 0.02; ((_this select 0) displayCtrl 9233) ctrlShow (ctrlShown ((_this select 0) displayCtrl 932));};"
];
_display displayAddEventHandler ["MouseButtonUp",
"0 = _this spawn {sleep 0.02; ((_this select 0) displayCtrl 9233) ctrlShow (ctrlShown ((_this select 0) displayCtrl 932));};"
];

[_display] call FUNC(arsenal_updateUI);
20 changes: 20 additions & 0 deletions addons/backpack_on_chest/functions/fnc_arsenal_postInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Called by postInit. Adds local "arsenalOpened" scriptedEventhandler.
*
* Arguments:
* None
*
* Return Value:
* Nothing
*
* Example:
* [] call tac_backpack_on_chest_fnc_arsenalPostInit;
*
* Public: No
*/

if !(hasInterface) exitWith {};

[missionNamespace, "arsenalOpened", FUNC(arsenal_opened)] call BIS_fnc_addScriptedEventHandler;
57 changes: 57 additions & 0 deletions addons/backpack_on_chest/functions/fnc_arsenal_updateUI.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Called when backpack of arsenal unit changes. Updates Button icon / tooltip.
*
* Arguments:
* 0: Arsenal Display <DISPLAY>
*
* Return Value:
* Nothing
*
* Example:
* [_display] call tac_backpack_on_chest_fnc_arsenal_updateUI;
*
* Public: No
*/

disableSerialization;
params ["_display"];

// the onSelChanged EH calls before the actual backpack changed so we have to wait a little bit
if (_display isEqualType controlNull) exitWith {
[ctrlParent _display] spawn {
sleep 0.05; _this call FUNC(arsenal_updateUI)
};
};

// the arsenal unit
private _center = missionNamespace getVariable ["BIS_fnc_arsenal_center", player];

private _chestpack = [_center] call FUNC(chestpack);
private _backpack = backpack _center;

private _action = ["onBack", "onChest"] select (_chestpack isEqualTo "");
if ((_backpack isNotEqualTo "") && (_chestpack isNotEqualTo "")) then {_action = "swap";};

switch (_action) do {
case ("onBack"): {
(_display displayCtrl 9233) ctrlSetText QPATHTOF(ui\onback_ca.paa);
(_display displayCtrl 9233) ctrlSetTooltip LLSTRING(onBack);
};
case ("onChest"): {
(_display displayCtrl 9233) ctrlSetText QPATHTOF(ui\onchest_ca.paa);
(_display displayCtrl 9233) ctrlSetTooltip LLSTRING(onChest);
};
case ("swap"): {
(_display displayCtrl 9233) ctrlSetText QPATHTOF(ui\swap_ca.paa);
(_display displayCtrl 9233) ctrlSetTooltip LLSTRING(swap);
};
};

if ((_backpack isEqualTo "") && (_chestpack isEqualTo "")) then {
(_display displayCtrl 9233) ctrlEnable false;
(_display displayCtrl 9233) ctrlSetTooltip "";
} else {
(_display displayCtrl 9233) ctrlEnable true;
};
29 changes: 29 additions & 0 deletions addons/backpack_on_chest/functions/fnc_canAddItemToChestpack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Checks if given item can be stored into soldier's chestpack.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Item/magazine/weapon classname <STRING>
* 2: Amount <NUMBER> (optional)
*
* Return Value:
* Can add item? <BOOL>
*
* Example:
* [player,"FirstAidKit",2] call tac_backpack_on_chest_fnc_canAddItemToChestpack;
*
* Public: No
*/
params ["_unit","_item",["_amount",1]];

private _var = _unit getVariable [QGVAR(chestpack), nil];
private _preLoadPercent = _var select 4;

//calculate space left in chestpack
private _maximumLoad = getNumber(configFile >> "CfgVehicles" >> ([_unit] call FUNC(chestpack)) >> "maximumLoad");
private _remainingLoad = (1 - _preLoadPercent) * _maximumLoad;
private _itemMass = [_item] call FUNC(itemMass);

[true, false] select ((_itemMass * _amount) > _remainingLoad);
25 changes: 25 additions & 0 deletions addons/backpack_on_chest/functions/fnc_canCutLoweringLine.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "..\script_component.hpp"
/*
* Author: Ampersand
* Checks if given unit can cut its lowering line
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Success <BOOLEAN>
*
* Example:
* [_unit] call tac_backpack_on_chest_fnc_canCutLoweringLine;
*
* Public: No
*/

params ["_unit"];

if (GVAR(disabled)) exitWith {false};

private _chute = vehicle _unit;

_chute isKindOf "ParachuteBase"
&& {!isNull (_chute getVariable [QGVAR(loweringLine), objNull])}
22 changes: 22 additions & 0 deletions addons/backpack_on_chest/functions/fnc_canLower.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "..\script_component.hpp"
/*
* Author: Ampersand
* Checks if given unit can lower its chestpack
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Success <BOOLEAN>
*
* Example:
* [_unit] call tac_backpack_on_chest_fnc_canLower;
*
* Public: No
*/

params ["_unit"];

if (GVAR(disabled)) exitWith {false};

vehicle _unit isKindOf "ParachuteBase" && {[_player] call FUNC(chestpack) != ''}
22 changes: 22 additions & 0 deletions addons/backpack_on_chest/functions/fnc_canMovePack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "..\script_component.hpp"
/*
* Author: Ampersand
* Checks if given unit can move its pack(s)
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Success <BOOL>
*
* Example:
* [_unit] call tac_backpack_on_chest_fnc_canMovePack;
*
* Public: No
*/

params ["_unit"];

if (GVAR(disabled)) exitWith {false};

!(vehicle _unit isKindOf "ParachuteBase") // Can't move pack while in a parachute
25 changes: 25 additions & 0 deletions addons/backpack_on_chest/functions/fnc_chestpack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Returns the classname of a unit's chestpack.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Classname <STRING>
*
* Example:
* [player] call tac_backpack_on_chest_fnc_chestpack;
*
* Public: No
*/
params ["_unit"];

private _var = _unit getVariable [QGVAR(chestpack), nil];

if (isNil "_var") exitWith {""};
private _chestpackClass = (_var select 0) select 0;

// return classname
_chestpackClass
29 changes: 29 additions & 0 deletions addons/backpack_on_chest/functions/fnc_chestpackContainer.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Returns the cargo container of a unit's chestpack. Note that this is only a prop and does not contain any items. Items which
* were added with vanilla commands like 'addWeaponCargo' etc. will be ignored. You have to use the provided functions instead.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Cargo container or objNull <OBJECT>
*
* Example:
* [player] call tac_backpack_on_chest_fnc_chestpackContainer;
*
* Public: No
*/
params ["_unit"];

if (isNil "_unit") exitWith {
ERROR("No proper argument(s) given.");
};

private _var = _unit getVariable [QGVAR(chestpack), nil];
private _chestpack = (_var select 0) select 1;

if (isNil "_var" || isNil "_chestpack") exitWith {objNull};

_chestpack
26 changes: 26 additions & 0 deletions addons/backpack_on_chest/functions/fnc_chestpackLoadout.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Returns Unit Loadout Array of chestpack of the given unit.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Items <ARRAY>
*
* Example:
* [player] call tac_backpack_on_chest_fnc_chestpackLoadout;
*
* Public: No
*/
params ["_unit"];

private _var = _unit getVariable [QGVAR(chestpack), nil];
private _loadout = + (_var select 2);

// return objNull
if (isNil "_var" || isNil "_loadout") exitWith {[]};

// return items
_loadout
41 changes: 41 additions & 0 deletions addons/backpack_on_chest/functions/fnc_chestpackToHolder.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "..\script_component.hpp"
/*
* Author: Ampersand
* Returns WeaponHolderSimulated with copy of chestpack
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* 0: WeaponHolderSimulated <OBJECT>
*
* Example:
* [player] call tac_backpack_on_chest_fnc_chestpackToHolder;
*
* Public: No
*/

params ["_unit"];

private _chestpack = [_unit] call FUNC(chestpack);
if (_chestpack isEqualTo "") exitWith {objNull};
private _chestpackLoadout = [_unit] call FUNC(chestpackLoadout);
private _chestpackVariables = [_unit] call FUNC(chestpackVariables);

private _holder = createVehicle ["WeaponHolderSimulated", (getPos _unit), [], 0, "CAN_COLLIDE"];

// add pack
_holder addBackpackCargoGlobal [_chestpack, 1];
private _backpack = firstBackpack _holder;

[_backpack, _chestpackLoadout] call FUNC(setBackpackLoadout);

// add variables
{
_backpack setVariable [(_x select 0), (_x select 1), true];
} forEach _chestpackVariables;

// remove the backpack from the dead unit
[_unit] call FUNC(removeChestpack);

_holder
26 changes: 26 additions & 0 deletions addons/backpack_on_chest/functions/fnc_chestpackVariables.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Returns array with all variables in chestpack of the given unit.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* variables <ARRAY>
*
* Example:
* [player] call tac_backpack_on_chest_fnc_chestpackVariables;
*
* Public: No
*/
params ["_unit"];

private _var = _unit getVariable [QGVAR(chestpack), nil];
private _variables = + (_var select 3);


if (isNil "_var" || isNil "_variables") exitWith {[]};

// return items
_variables
23 changes: 23 additions & 0 deletions addons/backpack_on_chest/functions/fnc_clearAllCargo.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "..\script_component.hpp"
/*
* Author: Ampersand
* Called locally by event. Clears all the cargo of given container.
*
* Arguments:
* 0: Container <OBJECT>
*
* Return Value:
* NONE
*
* Example:
* [_container] call tac_backpack_on_chest_fnc_clearAllCargo;
*
* Public: No
*/

params ["_container"];

clearItemCargo _container;
clearWeaponCargo _container;
clearMagazineCargo _container;
clearBackpackCargo _container;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "..\script_component.hpp"
/*
* Author: DerZade
* Removes all items (includes weapons and magazines) from a unit's chestpack.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Clear Variables (Optional) <BOOLEAN>
*
* Return Value:
* Nothing
*
* Example:
* [player] call zade_boc_fnc_clearAllItemsFromChestpack;
*
* Public: No
*/
params ["_unit", ["_variables", true]];

private _var = _unit getVariable [QGVAR(chestpack),nil];
_var set [2,[]];

if (_variables) then {
_var set [3, []];
};

_var set [4, 0];

_unit setVariable [QGVAR(chestpack),_var, true];
22 changes: 22 additions & 0 deletions addons/backpack_on_chest/functions/fnc_clearCargoBackpacks.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "..\script_component.hpp"
/*
* Author: Ampersand
* Called locally by event. Clear inventory of every backpack in given container.
*
* Arguments:
* 0: Container <OBJECT>
*
* Return Value:
* NONE
*
* Example:
* [_container] call tac_backpack_on_chest_fnc_clearCargoBackpacks;
*
* Public: No
*/

params ["_container"];

{
[_x] call FUNC(clearAllCargo);
} forEach everyBackpack _container;
49 changes: 49 additions & 0 deletions addons/backpack_on_chest/functions/fnc_itemMass.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton, MikeMF
* Finds mass of given item.
*
* Arguments:
* 0: Item <STRING>
*
* Return Value:
* Item mass <NUMBER>
*
* Example:
* ["FirstAidKit"] call tac_backpack_on_chest_fnc_itemMass;
*
* Public: No
*/

params ["_item"];

private _weaponConfig = configFile >> "CfgWeapons" >> _item;
private _weaponConfigItemInfo = _weaponConfig >> "ItemInfo";

if (isClass (_weaponConfigItemInfo)) exitWith {
getNumber (_weaponConfig >> "ItemInfo" >> "Mass");
};

private _weaponConfigSlots = _weaponConfig >> "WeaponSlotsInfo";

if (isClass (_weaponConfigSlots)) exitWith {
getNumber (_weaponConfigSlots >> "Mass");
};

private _magazineConfigMass = configFile >> "CfgMagazines" >> _item;

if (isClass _magazineConfigMass) exitWith {
getNumber (_magazineConfigMass >> "Mass");
};

private _vehiclesConfigMass = configFile >>"CfgVehicles">> _item;

if (isClass _vehiclesConfigMass) exitWith {
getNumber (_vehiclesConfigMass >> "Mass");
};

private _glassesConfigMass = configFile >> "CfgGlasses" >> _item;

if (isClass _glassesConfigMass) exitWith {
getNumber (_glassesConfigMass >> "Mass");
};
35 changes: 35 additions & 0 deletions addons/backpack_on_chest/functions/fnc_removeChestpack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Removes unit's chestpack.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player] call tac_backpack_on_chest_fnc_removeChestpack;
*
* Public: No
*/
params ["_unit"];

private _var = _unit getVariable [QGVAR(chestpack), nil];

// delete chestpackContainer
deleteVehicle ([_unit] call FUNC(chestpackContainer));

// remove all EHs
_unit removeEventHandler ["GetInMan",(_var select 1) select 0];
_unit removeEventHandler ["GetOutMan",(_var select 1) select 1];
_unit removeEventHandler ["AnimDone",(_var select 1) select 2];
_unit removeEventHandler ["Killed",(_var select 1) select 3];

if (GVAR(walk)) then {
[_unit, "forceWalk", "BackpackOnChest", false] call ACEFUNC(common,statusEffect_set);
};

// reset variable
_unit setVariable [QGVAR(chestpack), nil, true];
46 changes: 46 additions & 0 deletions addons/backpack_on_chest/functions/fnc_removeItemFromChestpack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Removes item from unit's chestpack.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Item/magazine/weapon classname <STRING>
* 2: Quantity (Optional) <NUMBER>
*
* Return Value:
* Nothing
*
* Example:
* [player,"FirstAidKit"] call tac_backpack_on_chest_fnc_removeItemFromChestpack;
*
* Public: No
*/
params ["_unit","_item", ["_quantity", 1]];

private _loadout = _unit call FUNC(chestpackLoadout);
private _itemFound = {
if (_x find _item isNotEqualTo -1) exitWith {
[_x, _forEachIndex, true]
};
} forEach _loadout;

// exit if no item found
if (_itemFound select 2 isNotEqualTo true) exitWith {};

private _var = _unit getVariable [QGVAR(chestpack), nil];
private _currentItem = (_var select 2) select (_itemFound select 1);
private _newQuantity = (_currentItem select 1) - _quantity;

if (_newQuantity <= 0) then {
(_var select 2) deleteAt (_itemFound select 1);
} else {
private _newItem = +(_currentItem);
_newItem set [1, _newQuantity];
(_var select 2) set [(_itemFound select 1), _newItem];
};

_unit setVariable [QGVAR(chestpack), _var, true];

// return deleted item
(_itemFound select 0)
49 changes: 49 additions & 0 deletions addons/backpack_on_chest/functions/fnc_removeMagFromChestpack.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "..\script_component.hpp"
/*
* Author: DerZade, mjc4wilton
* Removes magazine from unit's chestpack. The purpose of this function is to ensure that magazines with a specified ammo count can be removed.
* If you want to remove a magazine with just any amount of ammo you may want to use 'zade_boc_fnc_removeItemFromChestpack' instead.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Classname <STRING>
* 2: Ammo count <NUMBER>
* 3: Quantity (Optional) <NUMBER>
*
* Return Value:
* [MagazineClassname, Qty, Rounds] <ARRAY>
*
* Example:
* [player,"30Rnd_556x45_Stanag",25] call tac_backpack_on_chest_fnc_removeMagFromChestpack;
*
* Public: No
*/
params ["_unit","_item","_ammo", ["_quantity", 1]];

private _loadout = [_unit] call FUNC(chestpackLoadout);

private _mag = {
if ((_x select 0 isEqualTo _item) && (_x select 2 isEqualTo _ammo)) exitWith {
[_x, _forEachIndex, true];
};
} forEach _loadout;

// exit if there is no such item in chestpack
if (_mag select 2 isNotEqualTo true) exitWith {};

private _var = _unit getVariable [QGVAR(chestpack),nil];
private _currentMag = (_var select 2) select (_mag select 1);
private _newQuantity = (_currentMag select 1) - (_quantity);

if (_newQuantity <= 0) then {
(_var select 2) deleteAt (_mag select 1);
} else {
private _newMag = [(_currentMag select 0), _newQuantity, (_currentMag select 2)];
(_var select 2) set [(_mag select 1), _newMag];
};

// update variable
_unit setVariable [QGVAR(chestpack),_var,true];

// return item.
(_mag select 0);
64 changes: 64 additions & 0 deletions addons/backpack_on_chest/functions/fnc_setBackpackLoadout.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "..\script_component.hpp"
/*
* Author: Ampersand
* Returns WeaponHolderSimulated with copy of chestpack
*
* Arguments:
* 0: Backpack <OBJECT>
* 1: Loadout <ARRAY>
*
* Return Value:
* 0: Success <BOOLEAN>
*
* Example:
* [_backpack, (getUnitLoadout _unit) select 5 select 1] call tac_backpack_on_chest_fnc_setBackpackLoadout;
*
* Public: No
*/

params ["_backpack", "_loadout"];
if (isNull _backpack) exitWith {false};

[QGVAR(clearAllCargo), [_backpack]] call CBA_fnc_globalEvent;

// add items
private _cfgMagazines = configFile >> "CfgMagazines";
private _cfgVehicles = configFile >> "CfgVehicles";
{
if (typeName (_x select 0) == "Array") then {
// weapon with attachments
for "_i" from 1 to (_x select 1) do {
_backpack addWeaponWithAttachmentsCargoGlobal _x;
};
} else {
private _cargoClass = (_x select 0);
if (isClass (_cfgMagazines >> _cargoClass)) then {

_backpack addMagazineAmmoCargo _x;
// Above command sometimes fails on its own, like with PCML Missile in NATO Ammo Bearer's backpack
[{
params ["_backpack", "_mag", "_count", "_rounds"];
private _countInBackpack = {_x isEqualTo [_mag, _rounds]} count magazinesAmmoCargo _backpack;
if (_countInBackpack < _count) then {
_backpack addMagazineAmmoCargo [_mag, 1, _rounds];
};
_countInBackpack == _count
}, {}, [_backpack] + _x, 1, {
WARNING("chestpackToHolder timed out adding magazines");
TRACE_1("Container: ",_this);
}] call CBA_fnc_waitUntilAndExecute;

} else {
// backpacks
private _cfgCargoBackpack = _cfgVehicles >> _cargoClass;
if (isClass _cfgCargoBackpack) then {
_backpack addBackpackCargoGlobal [_cargoClass, 1];
[QGVAR(clearCargoBackpacks), [_backpack]] call CBA_fnc_globalEvent;
} else {
_backpack addItemCargoGlobal _x;
};
};
};
} forEach _loadout;

true
20 changes: 20 additions & 0 deletions addons/backpack_on_chest/initSettings.inc.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
private _category = format ["TAC %1", QUOTE(COMPONENT_BEAUTIFIED)];
[
QGVAR(disabled),
"CHECKBOX",
[LSTRING(Disable), LSTRING(Disable_Description)],
_category,
true,
true
] call CBA_fnc_addSetting;

[
QGVAR(walk), "CHECKBOX",
[LSTRING(forceWalk), LSTRING(forceWalk_Description)],
category,
true,
true
] call CBA_fnc_addSetting;

// Blacklisted variables for mods that don't want variables to be transferred. Useful for very particular cases.
GVAR(VarBlacklist) = [];
17 changes: 17 additions & 0 deletions addons/backpack_on_chest/script_component.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#define COMPONENT backpack_on_chest
#define COMPONENT_BEAUTIFIED Backpack On Chest
#include "\x\tac\addons\main\script_mod.hpp"

// #define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE
// #define ENABLE_PERFORMANCE_COUNTERS

#ifdef DEBUG_ENABLED_BACKPACK_ON_CHEST
#define DEBUG_MODE_FULL
#endif

#ifdef DEBUG_SETTINGS_BACKPACK_ON_CHEST
#define DEBUG_SETTINGS BACKPACK_ON_CHEST
#endif

#include "\x\tac\addons\main\script_macros.hpp"
35 changes: 35 additions & 0 deletions addons/backpack_on_chest/stringtable.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="TAC">
<Package name="Backpack_On_Chest">
<Key ID="STR_TAC_Backpack_On_Chest_Disable">
<English>Disable Backpack On Chest</English>
</Key>
<Key ID="STR_TAC_Backpack_On_Chest_Disable_Description">
<English>Prevent usage of Backpack on Chest features</English>
</Key>
<Key ID="STR_TAC_Backpack_On_Chest_DisplayName">
<English>Backpack on Chest</English>
</Key>
<Key ID="STR_TAC_Backpack_On_Chest_Lower">
<English>Lower chestpack</English>
</Key>
<Key ID="STR_TAC_Backpack_On_Chest_OnBack">
<English>Put backpack on back</English>
</Key>
<Key ID="STR_TAC_Backpack_On_Chest_OnChest">
<English>Put backpack on chest</English>
</Key>
<Key ID="STR_TAC_Backpack_On_Chest_Swap">
<English>Swap rucksacks</English>
</Key>
<Key ID="STR_TAC_Backpack_On_Chest_cutLoweringLine">
<English>Cut lowering line</English>
</Key>
<Key ID="STR_TAC_Backpack_On_Chest_forceWalk">
<English>Force Walking</English>
</Key>
<Key ID="STR_TAC_Backpack_On_Chest_forceWalk_Description">
<English>Force the unit to walk with backpack on chest</English>
</Key>
</Package>
</Project>
Binary file added addons/backpack_on_chest/ui/onback_ca.paa
Binary file not shown.
Binary file added addons/backpack_on_chest/ui/onchest_ca.paa
Binary file not shown.
Binary file added addons/backpack_on_chest/ui/swap_ca.paa
Binary file not shown.

0 comments on commit 9930a88

Please sign in to comment.