Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSW - Improved weapon attachments handling #9904

Merged
merged 10 commits into from
Jun 22, 2024
50 changes: 36 additions & 14 deletions addons/csw/functions/fnc_assemble_deployTripod.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,45 @@
params ["_player"];
TRACE_1("assemble_deployTripod",_player);

// Save magazines and attachments (handle loaded launchers which can become csw like CUP Metis)
private _secondaryWeaponInfo = (getUnitLoadout _player) select 1;
private _secondaryWeaponClassname = _secondaryWeaponInfo deleteAt 0;

// Remove empty entries
_secondaryWeaponInfo = _secondaryWeaponInfo select {_x isNotEqualTo "" && {_x isNotEqualTo []}};

// Remove the tripod from the launcher slot
private _secondaryWeaponClassname = secondaryWeapon _player;
// handle loaded launchers which can become csw like CUP Metis
private _secondaryWeaponMagazine = secondaryWeaponMagazine _player param [0, ""];
_player removeWeaponGlobal _secondaryWeaponClassname;

private _onFinish = {
params ["_args"];
_args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponMagazine"];
TRACE_3("deployTripod finish",_player,_secondaryWeaponClassname,_secondaryWeaponMagazine);
_args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponInfo"];
TRACE_3("deployTripod finish",_player,_secondaryWeaponClassname,_secondaryWeaponInfo);

private _tripodClassname = getText(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deploy");

// Create a tripod
private _cswTripod = createVehicle [_tripodClassname, [0, 0, 0], [], 0, "NONE"];
// Because the tripod can be a "full weapon" we disable any data that will allow it to be loaded
_cswTripod setVariable [QGVAR(assemblyMode), 2, true]; // Explicitly set enabled&unload assembly mode and broadcast
if (_secondaryWeaponMagazine isNotEqualTo "") then {
_cswTripod setVariable [QGVAR(secondaryWeaponMagazine), _secondaryWeaponMagazine];

private _secondaryWeaponMagazines = [];

{
// Magazines
if (_x isEqualType []) then {
_secondaryWeaponMagazines pushBack _x;
} else {
// Items
[_player, _x, true] call CBA_fnc_addItem;
};
} forEach _secondaryWeaponInfo;

// Only add magazines once the weapon is fully ready
if (_secondaryWeaponMagazines isNotEqualTo []) then {
_cswTripod setVariable [QGVAR(secondaryWeaponMagazines), _secondaryWeaponMagazines, true];
};

if (!GVAR(defaultAssemblyMode)) then {
[_cswTripod, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
};
Expand All @@ -65,15 +84,18 @@

private _onFailure = {
params ["_args"];
_args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponMagazine"];
TRACE_3("deployTripod failure",_player,_secondaryWeaponClassname,_secondaryWeaponMagazine);
_args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponInfo"];
TRACE_3("deployTripod failure",_player,_secondaryWeaponClassname,_secondaryWeaponInfo);

_player addWeaponGlobal _secondaryWeaponClassname;
if (_secondaryWeaponMagazine isNotEqualTo "") then {
_player addWeaponItem [_secondaryWeaponClassname, _secondaryWeaponMagazine, true];
};
// Add tripod back
[_player, _secondaryWeaponClassname] call CBA_fnc_addWeaponWithoutItems;

// Add all attachments back
{
_player addWeaponItem [_secondaryWeaponClassname, _x, true];
} forEach _secondaryWeaponInfo;
};

private _deployTime = getNumber(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deployTime");
[TIME_PROGRESSBAR(_deployTime), [_player, _secondaryWeaponClassname, _secondaryWeaponMagazine], _onFinish, _onFailure, LLSTRING(PlaceTripod_progressBar)] call EFUNC(common,progressBar);
[TIME_PROGRESSBAR(_deployTime), [_player, _secondaryWeaponClassname, _secondaryWeaponInfo], _onFinish, _onFailure, LLSTRING(PlaceTripod_progressBar)] call EFUNC(common,progressBar);
}, _this] call CBA_fnc_execNextFrame;
58 changes: 46 additions & 12 deletions addons/csw/functions/fnc_assemble_deployWeapon.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,78 @@
* Deploys the current CSW
*
* Arguments:
* 0: Unit <OBJECT>
* 0: Target <OBJECT>
* 1: Unit <OBJECT>
* 2: Args <ANY>
* 3: Action Data <ARRAY>
*
* Return Value:
* None
*
* Example:
* [player] call ace_csw_fnc_assemble_deployWeapon
* [cursorObject, player] call ace_csw_fnc_assemble_deployWeapon
*
* Public: No
*/

[{
params ["_tripod", "_player", "", "_carryWeaponClassname"];
if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapon _player };
params ["_tripod", "_player"];

// Save magazines and attachments (handle loaded launchers which can become csw like CUP Metis)
private _carryWeaponInfo = (getUnitLoadout _player) select 1;
private _carryWeaponClassname = _carryWeaponInfo deleteAt 0;

// Remove empty entries
_carryWeaponInfo = _carryWeaponInfo select {_x isNotEqualTo "" && {_x isNotEqualTo []}};

TRACE_3("assemble_deployWeapon_carryWeaponClassname",_tripod,_player,_carryWeaponClassname);

private _tripodClassname = typeOf _tripod;
_player removeWeaponGlobal _carryWeaponClassname;

private _weaponConfig = configfile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON);
private _assembledClassname = getText (_weaponConfig >> "assembleTo" >> _tripodClassname);

if (!isClass (configFile >> "CfgVehicles" >> _assembledClassname)) exitWith {ERROR_1("bad static classname [%1]",_assembledClassname);};

_player removeWeaponGlobal _carryWeaponClassname;

private _deployTime = getNumber (_weaponConfig >> "deployTime");

TRACE_4("",_carryWeaponClassname,_tripodClassname,_assembledClassname,_deployTime);

private _onFinish = {
params ["_args"];
_args params ["_tripod", "_player", "_assembledClassname"];
_args params ["_tripod", "_player", "_assembledClassname", "", "_carryWeaponInfo"];
TRACE_3("deployWeapon finish",_tripod,_player,_assembledClassname);

private _secondaryWeaponMagazines = _tripod getVariable [QGVAR(secondaryWeaponMagazines), []];

private _tripodPos = getPosATL _tripod;
private _tripodDir = getDir _tripod;
deleteVehicle _tripod;

_tripodPos set [2, (_tripodPos select 2) + 0.1];
// Delay a frame so tripod has a chance to be deleted
[{
params ["_assembledClassname", "_tripodDir", "_tripodPos"];
params ["_assembledClassname", "_tripodDir", "_tripodPos", "_player", "_carryWeaponInfo", "_secondaryWeaponMagazines"];
private _csw = createVehicle [_assembledClassname, [0, 0, 0], [], 0, "NONE"];
// Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default]
_csw setVariable [QGVAR(assemblyMode), 2, true]; // Explicitly set advanced assembly mode + unload, and broadcast

{
// Magazines
if (_x isEqualType []) then {
_secondaryWeaponMagazines pushBack _x;
} else {
// Items
[_player, _x, true] call CBA_fnc_addItem;
};
} forEach _carryWeaponInfo;

// Only add magazines once the weapon is fully ready
if (_secondaryWeaponMagazines isNotEqualTo []) then {
_csw setVariable [QGVAR(secondaryWeaponMagazines), _secondaryWeaponMagazines, true];
};

if (!GVAR(defaultAssemblyMode)) then {
[_csw, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
};
Expand All @@ -58,15 +86,21 @@
};
[QGVAR(deployWeaponSucceeded), [_csw]] call CBA_fnc_localEvent;
TRACE_2("csw placed",_csw,_assembledClassname);
}, [_assembledClassname, _tripodDir, _tripodPos]] call CBA_fnc_execNextFrame;
}, [_assembledClassname, _tripodDir, _tripodPos, _player, _carryWeaponInfo, _secondaryWeaponMagazines]] call CBA_fnc_execNextFrame;
};

private _onFailure = {
params ["_args"];
_args params ["", "_player", "", "_carryWeaponClassname"];
_args params ["", "_player", "", "_carryWeaponClassname", "_carryWeaponInfo"];
TRACE_2("deployWeapon failure",_player,_carryWeaponClassname);

_player addWeaponGlobal _carryWeaponClassname;
// Add weapon back
[_player, _carryWeaponClassname] call CBA_fnc_addWeaponWithoutItems;

// Add all attachments back
{
_player addWeaponItem [_carryWeaponClassname, _x, true];
} forEach _carryWeaponInfo;
};

private _codeCheck = {
Expand All @@ -76,5 +110,5 @@
alive _tripod
};

[TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _carryWeaponClassname], _onFinish, _onFailure, LLSTRING(AssembleCSW_progressBar), _codeCheck] call EFUNC(common,progressBar);
[TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _carryWeaponClassname, _carryWeaponInfo], _onFinish, _onFailure, LLSTRING(AssembleCSW_progressBar), _codeCheck] call EFUNC(common,progressBar);
}, _this] call CBA_fnc_execNextFrame;
40 changes: 32 additions & 8 deletions addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,38 @@ TRACE_1("Remove all loaded magazines",_magsToRemove);
};
} forEach _magsToRemove;

if (_staticWeapon getVariable [QGVAR(secondaryWeaponMagazine), ""] isNotEqualTo "") then {
private _secondaryWeaponMagazine = _staticWeapon getVariable QGVAR(secondaryWeaponMagazine);
private _turret = allTurrets _staticWeapon param [0, []];
private _vehicleMag = [_staticWeapon, _turret, _secondaryWeaponMagazine] call FUNC(reload_getVehicleMagazine);
TRACE_3("Re-add previous mag",_secondaryWeaponMagazine,_turret,_vehicleMag);
if (!isClass (configFile >> "CfgMagazines" >> _vehicleMag)) exitWith {};
_staticWeapon addMagazineTurret [_vehicleMag, _turret, 1];
_staticWeapon setVariable [QGVAR(secondaryWeaponMagazine), nil];
private _secondaryWeaponMagazines = _staticWeapon getVariable [QGVAR(secondaryWeaponMagazines), []];

if (_secondaryWeaponMagazines isNotEqualTo []) then {
// Check if the static weapon can take magazines
private _turret = (allTurrets _staticWeapon) param [0, []];
private _compatibleMagazinesTurret = flatten ((_staticWeapon weaponsTurret _turret) apply {compatibleMagazines _x});
private _container = objNull;

{
private _vehicleMag = [_staticWeapon, _turret, _x select 0] call FUNC(reload_getVehicleMagazine);
TRACE_3("Re-add previous mag",_x select 0,_turret,_vehicleMag);

// If the magazine can be added to the static weapon, do it now
if (_vehicleMag in _compatibleMagazinesTurret) then {
_staticWeapon addMagazineTurret [_vehicleMag, _turret, _x select 1];
} else {
// Find a suitable container to place items in if necessary
if (isNull _container) then {
_container = (nearestObjects [_staticWeapon, ["GroundWeaponHolder"], 10]) param [0, objNull];

// Create ammo storage container
if (isNull _container) then {
_container = createVehicle ["GroundWeaponHolder", getPosATL _staticWeapon, [], 0, "NONE"];
};
};

// If the mag can't be added to the static weapon, add it to the ground holder
_container addMagazineAmmoCargo [_x select 0, 1, _x select 1];
};
} forEach _secondaryWeaponMagazines;

_staticWeapon setVariable [QGVAR(secondaryWeaponMagazines), nil, true];
};

if (_storeExtraMagazines) then {
Expand Down
Loading