From 39f200b9418f2819d215e63dff5f17c16478cf66 Mon Sep 17 00:00:00 2001 From: Salluci Date: Fri, 30 Jun 2023 03:43:09 +0300 Subject: [PATCH 01/37] fix belt linking issues --- .../fnc_reload_handleAddTurretMag.sqf | 5 +++-- .../functions/fnc_reload_handleReturnAmmo.sqf | 22 ++++++++++--------- .../csw/functions/fnc_reload_loadMagazine.sqf | 15 +++++++++++-- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index 8cdd9d29fee..dbdf3c6d8b1 100644 --- a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -10,7 +10,7 @@ * 2: Source of magazine * 3: Vehicle Magazine * 4: Ammo in magazine - * 5: Unit or object to return ammo to + * 5: Unit or object to return ammo to (default: Source of magazine) * * Return Value: * None @@ -21,7 +21,8 @@ * Public: No */ -params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived", ["_returnTo", _magSource]]; +params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived"]; +private _returnTo = param [5, _magSource]; TRACE_6("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_returnTo); TRACE_2("",local _vehicle, _vehicle turretLocal _turret); diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index 52a14903201..7de01717c9b 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -18,13 +18,13 @@ */ params ["_unloadTo", "_carryMag", "_ammo"]; -TRACE_3("reload_handleReturnAmmo",_unloadTo,_carryMag,_ammo); +TRACE_4("reload_handleReturnAmmo",_unloadTo,typeOf _unloadTo,_carryMag,_ammo); private _carryMaxAmmo = getNumber (configFile >> "CfgMagazines" >> _carryMag >> "count"); private _fullMagazines = floor (_ammo / _carryMaxAmmo); private _bulletsRemaining = _ammo % _carryMaxAmmo; -if (_unloadTo isKindOf "CaManBase") then { +if (_unloadTo isKindOf "CAManBase") then { while {(_fullMagazines > 0) && {[_unloadTo, _carryMag] call CBA_fnc_canAddItem}} do { _unloadTo addMagazine [_carryMag, _carryMaxAmmo]; _fullMagazines = _fullMagazines - 1; @@ -37,19 +37,21 @@ if (_unloadTo isKindOf "CaManBase") then { if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {}; -// Try to use existing container -private _container = _unloadTo getVariable [QGVAR(container), objNull]; -if ((_container distance _unloadTo) > 10) then { _container = objNull; }; -if (isNull _container) then { - _container = (nearestObjects [_unloadTo, [QGVAR(ammo_holder), "GroundWeaponHolder"], 10]) param [0, objNull]; +// Try to use object inventory or existing container +private _container = _unloadTo; +if ((maxLoad _container) isEqualTo 0) then { + _container = _unloadTo getVariable [QGVAR(container), objNull]; + if ((_container distance _unloadTo) > 10) then { _container = objNull; }; + if (isNull _container) then { + _container = (nearestObjects [_unloadTo, [QGVAR(ammo_holder), "GroundWeaponHolder"], 10]) param [0, objNull]; + }; }; - if (isNull _container) then { // Create ammo storage container private _weaponRelPos = _unloadTo getRelPos RELATIVE_DIRECTION(270); _weaponRelPos set [2, ((getPosATL _unloadTo) select 2) + 0.05]; - _container = createVehicle [["GroundWeaponHolder", QGVAR(ammo_holder)] select GVAR(handleExtraMagazinesType), [0, 0, 0], [], 0, "NONE"]; + _container = createVehicle [["GroundWeaponHolder", QGVAR(ammo_holder)] select GVAR(handleExtraMagazinesType), [0, 0, 0], [], 0, "CAN_COLLIDE"]; _unloadTo setVariable [QGVAR(container), _container, true]; _container setDir random [0, 180, 360]; _container setPosATL _weaponRelPos; @@ -59,7 +61,7 @@ if (isNull _container) then { TRACE_2("Creating NEW Container",_container,_weaponRelPos); }; -TRACE_3("adding to container",_container,_fullMagazines,_bulletsRemaining); +TRACE_4("adding to container",_container,typeOf _container,_fullMagazines,_bulletsRemaining); if (_fullMagazines > 0) then { _container addMagazineAmmoCargo [_carryMag, _fullMagazines, _carryMaxAmmo]; diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf index 5cceb55113e..1444a985dca 100644 --- a/addons/csw/functions/fnc_reload_loadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -51,8 +51,19 @@ private _onFinish = { [_magSource, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); if (_bestAmmoToSend == 0) exitWith {}; - TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend, _unit); - [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend, _unit]] call CBA_fnc_globalEvent; + // workaround for removeSpecificMagazine and WeaponHolders being deleted when empty, get the closest object of same type on the next frame + private _magSourcePos = getPosATL _magSource; + private _magSourceType = typeOf _magSource; + private _eventParams = [_vehicle, _turret, objNull, _carryMag, _bestAmmoToSend]; + [{ + params ["_args", "_magSourcePos", "_magSourceType"]; + _args params ["_vehicle", "_turret", "_magSource", "_carryMag", "_bestAmmoToSend"]; + _magSource = _magSourcePos nearestObject _magSourceType; + + TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend, _unit); + [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend, _unit]] call CBA_fnc_globalEvent; + + }, [_eventParams, _magSourcePos, _magSourceType]] call CBA_fnc_execNextFrame; }; From 78800be9abfac30c035782bb18e8284bf8f8e5b4 Mon Sep 17 00:00:00 2001 From: Salluci Date: Fri, 30 Jun 2023 03:57:20 +0300 Subject: [PATCH 02/37] fix unloading to units with full inventory --- addons/csw/functions/fnc_reload_handleReturnAmmo.sqf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index 7de01717c9b..136e70e0f46 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -24,7 +24,9 @@ private _carryMaxAmmo = getNumber (configFile >> "CfgMagazines" >> _carryMag >> private _fullMagazines = floor (_ammo / _carryMaxAmmo); private _bulletsRemaining = _ammo % _carryMaxAmmo; -if (_unloadTo isKindOf "CAManBase") then { +private _unloadToUnit = _unloadTo isKindOf "CAManBase"; + +if (_unloadToUnit) then { while {(_fullMagazines > 0) && {[_unloadTo, _carryMag] call CBA_fnc_canAddItem}} do { _unloadTo addMagazine [_carryMag, _carryMaxAmmo]; _fullMagazines = _fullMagazines - 1; @@ -38,7 +40,7 @@ if (_unloadTo isKindOf "CAManBase") then { if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {}; // Try to use object inventory or existing container -private _container = _unloadTo; +private _container = [_unloadTo, objNull] select _unloadToUnit; if ((maxLoad _container) isEqualTo 0) then { _container = _unloadTo getVariable [QGVAR(container), objNull]; if ((_container distance _unloadTo) > 10) then { _container = objNull; }; From 01dffca9c1a71055aae574b6c85a25b3cb5fc97c Mon Sep 17 00:00:00 2001 From: Salluci Date: Fri, 30 Jun 2023 04:06:50 +0300 Subject: [PATCH 03/37] progress bar text changes --- addons/csw/functions/fnc_reload_actionsLoad.sqf | 2 +- addons/csw/functions/fnc_reload_actionsUnload.sqf | 2 +- addons/csw/stringtable.xml | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/addons/csw/functions/fnc_reload_actionsLoad.sqf b/addons/csw/functions/fnc_reload_actionsLoad.sqf index d141da3d93b..6a410c77462 100644 --- a/addons/csw/functions/fnc_reload_actionsLoad.sqf +++ b/addons/csw/functions/fnc_reload_actionsLoad.sqf @@ -46,7 +46,7 @@ private _cfgMagazines = configFile >> "CfgMagazines"; // micro-optimization private _text = if (_isBeltLinking) then { format [localize LSTRING(actionLink), _displayName]; } else { - format [localize LSTRING(loadX), _displayName]; + format [localize LSTRING(actionLoad), _displayName]; }; private _action = [format ["load_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, _x] call EFUNC(interact_menu,createAction); diff --git a/addons/csw/functions/fnc_reload_actionsUnload.sqf b/addons/csw/functions/fnc_reload_actionsUnload.sqf index 0f4e9cb7ded..22dd6507e1e 100644 --- a/addons/csw/functions/fnc_reload_actionsUnload.sqf +++ b/addons/csw/functions/fnc_reload_actionsUnload.sqf @@ -64,7 +64,7 @@ private _cfgMagazines = configFile >> "CfgMagazines"; if (_carryMag == "") exitWith {}; private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName"); - private _text = format [LLSTRING(unloadX), _displayName]; + private _text = format [LLSTRING(actionUnload), _displayName]; private _picture = getText (_cfgMagazines >> _carryMag >> "picture"); private _action = [format ["unload_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, [_xMag, _xTurret, _carryMag]] call EFUNC(interact_menu,createAction); _actions pushBack [_action, [], _vehicle]; diff --git a/addons/csw/stringtable.xml b/addons/csw/stringtable.xml index 2782bad8500..dcb74d349ae 100644 --- a/addons/csw/stringtable.xml +++ b/addons/csw/stringtable.xml @@ -64,7 +64,7 @@ Bin 탑승하기 - + Load %1 Lade %1 Cargar %1 @@ -81,7 +81,7 @@ Yükle %1 %1 싣는중 - + Unload %1 Entlade %1 Descargar %1 @@ -113,6 +113,12 @@ Соединить %1 %1 연결 + + Loading %1... + + + Unloading %1... + Advanced Assembly Erweiterter Zusammenbau From aca90fb1879fa5435709af4335498777deb11efb Mon Sep 17 00:00:00 2001 From: Salluci Date: Sat, 1 Jul 2023 18:39:42 +0300 Subject: [PATCH 04/37] this took way too long --- addons/csw/functions/fnc_ai_handleFired.sqf | 2 +- addons/csw/functions/fnc_ai_handleGetIn.sqf | 7 ++- addons/csw/functions/fnc_ai_reload.sqf | 46 +++++++++++-------- .../functions/fnc_reload_canLoadMagazine.sqf | 22 ++++----- .../fnc_reload_getLoadableMagazines.sqf | 45 ++++++++++-------- .../fnc_reload_handleAddTurretMag.sqf | 9 ++-- .../functions/fnc_reload_handleReturnAmmo.sqf | 4 +- .../csw/functions/fnc_reload_loadMagazine.sqf | 22 ++++----- .../fnc_staticWeaponInit_unloadExtraMags.sqf | 2 +- 9 files changed, 87 insertions(+), 72 deletions(-) diff --git a/addons/csw/functions/fnc_ai_handleFired.sqf b/addons/csw/functions/fnc_ai_handleFired.sqf index 668a425b50f..da7258e76cd 100644 --- a/addons/csw/functions/fnc_ai_handleFired.sqf +++ b/addons/csw/functions/fnc_ai_handleFired.sqf @@ -20,4 +20,4 @@ if (someAmmo _staticWeapon) exitWith {}; TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); -[_staticWeapon, _gunner, _weapon, _magazine] call FUNC(ai_reload); +[_staticWeapon, _gunner, _weapon] call FUNC(ai_reload); diff --git a/addons/csw/functions/fnc_ai_handleGetIn.sqf b/addons/csw/functions/fnc_ai_handleGetIn.sqf index 2906a01d1e8..c45fff5364f 100644 --- a/addons/csw/functions/fnc_ai_handleGetIn.sqf +++ b/addons/csw/functions/fnc_ai_handleGetIn.sqf @@ -11,7 +11,7 @@ * * Public: No */ -params ["_staticWeapon", "_role", "_gunner"]; +params ["_staticWeapon", "_role", "_gunner", "_turret"]; TRACE_3("getInEH:",_staticWeapon,_role,_gunner); if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; @@ -19,4 +19,7 @@ if (someAmmo _staticWeapon) exitWith {}; TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); -[_staticWeapon, _gunner, currentWeapon _staticWeapon] call FUNC(ai_reload); +// this doesn't handle multi-weapon turrets, need a "turretWeapon" event or a PFH to do that +private _weapon = (_staticWeapon weaponsTurret _turret) select 0; + +[_staticWeapon, _gunner, weapon] call FUNC(ai_reload); diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index 47e5d1ee6fe..7b7dec6e461 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -7,14 +7,14 @@ * 0: Static Weapon * 1: Gunner * 2: Weapon - * 3: Magazine (default: "") * * Return Value: * None * * Public: No */ -params ["_staticWeapon", "_gunner", "_weapon", ["_magazine", ""]]; +params ["_staticWeapon", "_gunner", "_weapon"]; +TRACE_4("AI reload",_staticWeapon,_gunner,_weapon); private _turretPath = [_gunner] call EFUNC(common,getTurretIndex); private _reloadSource = objNull; @@ -23,27 +23,29 @@ private _reloadNeededAmmo = -1; private _cfgMagGroups = configFile >> QGVAR(groups); -private _nearSupplies = [_gunner] + ((_staticWeapon nearSupplies 10) select { +// see fnc_reload_getLoadableMagazines, but AI doesn't get filtered out +private _nearSupplies = (_staticWeapon nearSupplies 5) select { isNull (group _x) || {!([_x] call EFUNC(common,isPlayer)) && {[side group _gunner, side group _x] call BIS_fnc_sideIsFriendly}} -}); +}; + +// add gunner since it won't show up in nearSupplies +_nearSupplies pushBack _gunner; // Find if there is anything we can reload with +// see fnc_reload_getLoadableMagazines, though we don't care about AI pulling from the best ammo possible { scopeName "findSource"; + if (_x isKindOf "CAManBase") then { + // unit inventory needs to be added manually + _nearSupplies append [uniformContainer _x, vestContainer _x, backpackContainer _x]; + continue + }; private _xSource = _x; - private _cswMagazines = []; - { - _cswMagazines pushBackUnique _x; - } forEach ((magazineCargo _xSource) select {isClass (_cfgMagGroups >> _x)}); + private _cswMagazines = (magazineCargo _xSource) select {isClass (_cfgMagGroups >> _x)}; TRACE_2("",_xSource,_cswMagazines); - private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines; - if (_magazine != "") then { - _compatibleMags insert [0, [_magazine]]; - }; - { private _xWeaponMag = _x; { @@ -58,7 +60,7 @@ private _nearSupplies = [_gunner] + ((_staticWeapon nearSupplies 10) select { }; }; } forEach _cswMagazines; - } forEach _compatibleMags; + } forEach (compatibleMagazines _weapon); } forEach _nearSupplies; if (_reloadMag == "") exitWith {TRACE_1("could not find mag",_reloadMag);}; @@ -79,17 +81,21 @@ if (_bestAmmoToSend == -1) exitWith {ERROR("No ammo");}; // Remove the mag from the source [_reloadSource, _reloadMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); +// see fnc_reload_loadMagazine #L54 +// AI never returns ammo and removes the magazine before reloading, so we can skip distance and weaponHolder checks +private _eventParams = [_staticWeapon, _turretPath, objNull, _reloadMag, _bestAmmoToSend, _gunner]; + private _timeToLoad = 1; -if (!isNull(configOf _staticWeapon >> QUOTE(ADDON) >> "ammoLoadTime")) then { - _timeToLoad = getNumber(configOf _staticWeapon >> QUOTE(ADDON) >> "ammoLoadTime"); +if !(isNull (configOf _staticWeapon >> QUOTE(ADDON) >> "ammoLoadTime")) then { + _timeToLoad = getNumber (configOf _staticWeapon >> QUOTE(ADDON) >> "ammoLoadTime"); }; TRACE_1("Reloading in progress",_timeToLoad); [{ - params ["_staticWeapon", "_turretPath", "_gunner", "_reloadMag", "_bestAmmoToSend"]; - if ((!alive _staticWeapon) || {!alive _gunner} || {(_staticWeapon distance _gunner) > 10}) exitWith {TRACE_1("invalid state",_this);}; + params ["_staticWeapon", "", "", "", "", "_gunner"]; + if !(alive _staticWeapon && {alive _gunner}) exitWith {TRACE_2("invalid state",alive _staticWeapon,alive _gunner);}; // Reload the static weapon - TRACE_5("calling addTurretMag event",_staticWeapon,_turretPath,_gunner,_reloadMag,_bestAmmoToSend); + TRACE_5("calling addTurretMag event: AI reload",_staticWeapon,_turretPath,_gunner,_reloadMag,_bestAmmoToSend); [QGVAR(addTurretMag), _this] call CBA_fnc_globalEvent; -}, [_staticWeapon, _turretPath, _gunner, _reloadMag, _bestAmmoToSend], _timeToLoad] call CBA_fnc_waitAndExecute; +}, _eventParams, _timeToLoad] call CBA_fnc_waitAndExecute; diff --git a/addons/csw/functions/fnc_reload_canLoadMagazine.sqf b/addons/csw/functions/fnc_reload_canLoadMagazine.sqf index 1fbd2e47080..4a189e5e98b 100644 --- a/addons/csw/functions/fnc_reload_canLoadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_canLoadMagazine.sqf @@ -7,7 +7,7 @@ * 0: Static Weapon * 1: Turret Path * 2: Carryable Magazine - * 3: Supplier + * 3: Supplier (default: objNull) * * Return Value: * [CanLoad, LoadedMag, AmmoNeeded, IsBeltLinking] @@ -24,16 +24,16 @@ params ["_vehicle", "_turret", "_carryMag", ["_magSource", objNull]]; private _return = [false, "", -2, false]; // Handle disassembled or deleted -if (!alive _vehicle) exitWith { _return }; -// Verify holder has carry magazine -if ( - (!isNull _magSource) && - {!((_magSource isKindOf "Bag_Base") || {_magSource isKindOf "ContainerSupply"})} && // hacky workaround for magazines within dropped backpacks - { - ((_vehicle distance _magSource) > 10) || - {((magazineCargo _magSource) findIf {_x == _carryMag}) == -1} - } -) exitWith { _return }; +if !(alive _vehicle) exitWith {TRACE_1("not alive",_vehicle);_return}; + +// objNull as mag source means we can skip these checks: used to just get magazine info to load in turret +if !(isNull _magSource) then { + // Verify holder has carry magazine + if !(_carryMag in (magazineCargo _magSource)) exitWith {TRACE_3("no carry mag",_magSource,_carryMag,magazineCargo _magSource);_return}; + + // Verify holder has not moved away from vehicle, with workaround for containers within containers + if ((_vehicle distance _magSource) > 5 && {(_vehicle distance (objectParent _magSource)) > 5}) exitWith {TRACE_1("too far","");_return}; +}; // solve config lookups private _cfgMagazines = configFile >> "CfgMagazines"; diff --git a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf index 1419e7b16e6..2906c33b799 100644 --- a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf +++ b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* - * Author: PabstMirror - * Gets magazines that the player is carrying that can be loaded into the static weapon + * Author: PabstMirror, LinkIsGrim + * Gets nearby magazines that can be loaded in the static weapon * * Arguments: * 0: Vehicle @@ -23,30 +23,39 @@ private _magGroupsConfig = configFile >> QGVAR(groups); // so we don't solve in private _availableMagazines = createHashMap; // slower than array, still needed for setting source of magazine // filter enemy & player units while allowing pulling from friendly AI, crates, etc -private _nearSupplies = ((_vehicle nearSupplies 10) select { +private _nearSupplies = (_vehicle nearSupplies 5) select { isNull (group _x) || {!([_x] call EFUNC(common,isPlayer)) && {[side group _player, side group _x] call BIS_fnc_sideIsFriendly}} -}); +}; + +// add caller to nearSupplies since players will get filtered out +_nearSupplies pushBack _player; + +// send the mag source with the highest ammo +private _bestMagAmmo = createHashMap; -// backpacks/uniforms/etc need to be added manually. -// array can't be modified while iterating, use copy { + if (_x isKindOf "CAManBase") then { + // unit inventory needs to be added manually + _nearSupplies append [uniformContainer _x, vestContainer _x, backpackContainer _x]; + continue; + }; + private _xSource = _x; + private _cswMags = (magazinesAmmoCargo _xSource) select {isClass (_magGroupsConfig >> _x select 0)}; + + // add containers inside containers { _x params ["_classname", "_container"]; _nearSupplies pushBack _container; } forEach (everyContainer _x); -} forEach ((+_nearSupplies) select {(everyContainer _x) isNotEqualTo []}); - -// add caller to list of sources -_nearSupplies = [_player] + _nearSupplies; - -{ - private _xSource = _x; - private _mags = magazineCargo _xSource; { - _availableMagazines set [_x, _xSource]; - } forEach (_mags select {isClass (_magGroupsConfig >> _x)}); + _x params ["_classname", "_ammo"]; + if (_ammo > (_bestMagAmmo getOrDefault [_classname, 0])) then { + _bestMagAmmo set [_classname, _ammo]; + _availableMagazines set [_classname, _xSource]; + }; + } forEach _cswMags; } forEach _nearSupplies; if (_availableMagazines isEqualTo createHashMap) exitWith { [] }; // fast exit if no available mags @@ -68,9 +77,9 @@ private _return = []; ((getNumber (_carryGroup >> _x)) == 1) && {_loadInfo = [_vehicle, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine); _loadInfo select 0} ) exitWith { - _return pushBack [_carryMag, _turretPath, _loadInfo, _magSource]; + _return pushBack [_carryMag, _turretPath, _loadInfo, _magSource, _player]; }; - } forEach ([_weapon] call CBA_fnc_compatibleMagazines); + } forEach (compatibleMagazines _weapon); } forEach _availableMagazines; } forEach (_vehicle weaponsTurret _turretPath); } forEach (allTurrets _vehicle); diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index dbdf3c6d8b1..781d4d1c520 100644 --- a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -10,7 +10,8 @@ * 2: Source of magazine * 3: Vehicle Magazine * 4: Ammo in magazine - * 5: Unit or object to return ammo to (default: Source of magazine) + * 5: Unit that added the magazine + * 6: Object to return extra ammo (default: Unit that added the magazine) * * Return Value: * None @@ -21,9 +22,9 @@ * Public: No */ -params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived"]; -private _returnTo = param [5, _magSource]; -TRACE_6("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_returnTo); +params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived", "_unit"]; +private _returnTo = param [6, _unit]; +TRACE_7("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_unit,_returnTo); TRACE_2("",local _vehicle, _vehicle turretLocal _turret); if (!(_vehicle turretLocal _turret)) exitWith {}; diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index 136e70e0f46..46b0000fdcb 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -43,9 +43,9 @@ if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {}; private _container = [_unloadTo, objNull] select _unloadToUnit; if ((maxLoad _container) isEqualTo 0) then { _container = _unloadTo getVariable [QGVAR(container), objNull]; - if ((_container distance _unloadTo) > 10) then { _container = objNull; }; + if ((_container distance _unloadTo) > 5) then { _container = objNull; }; if (isNull _container) then { - _container = (nearestObjects [_unloadTo, [QGVAR(ammo_holder), "GroundWeaponHolder"], 10]) param [0, objNull]; + _container = (nearestObjects [_unloadTo, [QGVAR(ammo_holder), "GroundWeaponHolder"], 5]) param [0, objNull]; }; }; diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf index 1444a985dca..411c8717b4f 100644 --- a/addons/csw/functions/fnc_reload_loadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -51,25 +51,21 @@ private _onFinish = { [_magSource, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); if (_bestAmmoToSend == 0) exitWith {}; - // workaround for removeSpecificMagazine and WeaponHolders being deleted when empty, get the closest object of same type on the next frame - private _magSourcePos = getPosATL _magSource; - private _magSourceType = typeOf _magSource; - private _eventParams = [_vehicle, _turret, objNull, _carryMag, _bestAmmoToSend]; - [{ - params ["_args", "_magSourcePos", "_magSourceType"]; - _args params ["_vehicle", "_turret", "_magSource", "_carryMag", "_bestAmmoToSend"]; - _magSource = _magSourcePos nearestObject _magSourceType; + private _returnTo = _magSource; + // if we're pulling from a weaponHolder, return the ammo to the unit doing the action + // workaround for weaponHolders being recreated with removeSpecificMagazine, magazines will still get dropped if inventory is full + if (_magSource isKindOf "WeaponHolder") then { + _returnTo = _unit; + }; - TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend, _unit); - [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend, _unit]] call CBA_fnc_globalEvent; - - }, [_eventParams, _magSourcePos, _magSourceType]] call CBA_fnc_execNextFrame; + TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend, _unit); + [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend, _unit, _returnTo]] call CBA_fnc_globalEvent; }; [ TIME_PROGRESSBAR(_timeToLoad), - [_vehicle, _turret, _carryMag, _magSource], + [_vehicle, _turret, _carryMag, _magSource, _unit], _onFinish, {TRACE_1("load progressBar fail",_this);}, _displayName, diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 41845c0eb3c..78f06e72fce 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -35,6 +35,7 @@ private _containerMagazineCount = []; { _x params ["_xMag", "_xTurret", "_xAmmo"]; + _magsToRemove pushBackUnique [_xMag, _xTurret]; private _carryMag = _xMag call FUNC(getCarryMagazine); if (_carryMag != "") then { @@ -45,7 +46,6 @@ private _containerMagazineCount = []; TRACE_1("",_loadedMagAmmo); }; if (_xAmmo > 0) then { - _magsToRemove pushBackUnique [_xMag, _xTurret]; private _index = _containerMagazineClassnames find _carryMag; if (_index < 0) then { _index = _containerMagazineClassnames pushBack _carryMag; From f3c393f50c02359d4265f4a5b9ea08915c570bad Mon Sep 17 00:00:00 2001 From: Salluci Date: Sat, 1 Jul 2023 18:52:29 +0300 Subject: [PATCH 05/37] fix TRACE --- addons/csw/functions/fnc_ai_reload.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index 7b7dec6e461..4861fb5ead6 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -14,7 +14,7 @@ * Public: No */ params ["_staticWeapon", "_gunner", "_weapon"]; -TRACE_4("AI reload",_staticWeapon,_gunner,_weapon); +TRACE_3("AI reload",_staticWeapon,_gunner,_weapon); private _turretPath = [_gunner] call EFUNC(common,getTurretIndex); private _reloadSource = objNull; From 76a20760f538b3972a9593c5b63a35e206531801 Mon Sep 17 00:00:00 2001 From: Salluci Date: Sat, 1 Jul 2023 20:33:42 +0300 Subject: [PATCH 06/37] cache nearby ammo sources --- addons/csw/XEH_PREP.hpp | 1 + addons/csw/functions/fnc_ai_handleGetIn.sqf | 8 +++- addons/csw/functions/fnc_ai_reload.sqf | 16 +------- addons/csw/functions/fnc_getNearbySources.sqf | 40 +++++++++++++++++++ .../fnc_reload_getLoadableMagazines.sqf | 21 +--------- .../functions/fnc_reload_handleReturnAmmo.sqf | 9 ++++- .../csw/functions/fnc_reload_loadMagazine.sqf | 4 ++ addons/csw/script_component.hpp | 2 + 8 files changed, 65 insertions(+), 36 deletions(-) create mode 100644 addons/csw/functions/fnc_getNearbySources.sqf diff --git a/addons/csw/XEH_PREP.hpp b/addons/csw/XEH_PREP.hpp index 5966578aca5..5d461ae415d 100644 --- a/addons/csw/XEH_PREP.hpp +++ b/addons/csw/XEH_PREP.hpp @@ -20,6 +20,7 @@ PREP(canGetIn); PREP(getIn); PREP(getCarryMagazine); +PREP(getNearbySources); PREP(proxyWeapon); PREP(reload_actionsLoad); diff --git a/addons/csw/functions/fnc_ai_handleGetIn.sqf b/addons/csw/functions/fnc_ai_handleGetIn.sqf index c45fff5364f..90c071eddb9 100644 --- a/addons/csw/functions/fnc_ai_handleGetIn.sqf +++ b/addons/csw/functions/fnc_ai_handleGetIn.sqf @@ -17,9 +17,13 @@ TRACE_3("getInEH:",_staticWeapon,_role,_gunner); if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; if (someAmmo _staticWeapon) exitWith {}; -TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); +// turret can be empty when AI is forcefully moved to the vehicle +if (_turret isEqualTo []) then { + _turret = (assignedVehicleRole _gunner) select 1; +}; // this doesn't handle multi-weapon turrets, need a "turretWeapon" event or a PFH to do that private _weapon = (_staticWeapon weaponsTurret _turret) select 0; +TRACE_4("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon,_turret,_weapon); -[_staticWeapon, _gunner, weapon] call FUNC(ai_reload); +[_staticWeapon, _gunner, _weapon] call FUNC(ai_reload); diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index 4861fb5ead6..fcf4bb904bb 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -23,24 +23,12 @@ private _reloadNeededAmmo = -1; private _cfgMagGroups = configFile >> QGVAR(groups); -// see fnc_reload_getLoadableMagazines, but AI doesn't get filtered out -private _nearSupplies = (_staticWeapon nearSupplies 5) select { - isNull (group _x) || - {!([_x] call EFUNC(common,isPlayer)) && {[side group _gunner, side group _x] call BIS_fnc_sideIsFriendly}} -}; - -// add gunner since it won't show up in nearSupplies -_nearSupplies pushBack _gunner; +private _sources = [_gunner] call FUNC(getNearbySources); // Find if there is anything we can reload with // see fnc_reload_getLoadableMagazines, though we don't care about AI pulling from the best ammo possible { scopeName "findSource"; - if (_x isKindOf "CAManBase") then { - // unit inventory needs to be added manually - _nearSupplies append [uniformContainer _x, vestContainer _x, backpackContainer _x]; - continue - }; private _xSource = _x; private _cswMagazines = (magazineCargo _xSource) select {isClass (_cfgMagGroups >> _x)}; @@ -61,7 +49,7 @@ _nearSupplies pushBack _gunner; }; } forEach _cswMagazines; } forEach (compatibleMagazines _weapon); -} forEach _nearSupplies; +} forEach _sources; if (_reloadMag == "") exitWith {TRACE_1("could not find mag",_reloadMag);}; // Figure out what we can add from the magazines we have diff --git a/addons/csw/functions/fnc_getNearbySources.sqf b/addons/csw/functions/fnc_getNearbySources.sqf new file mode 100644 index 00000000000..7c9e3e96ba1 --- /dev/null +++ b/addons/csw/functions/fnc_getNearbySources.sqf @@ -0,0 +1,40 @@ +#include "script_component.hpp" +/* + * Author: LinkIsGrim + * Gets available ammo sources for loading a static weapon + * + * Arguments: + * 0: Unit attempting to load + * + * Return Value: + * Ammo sources + * + * Example: + * [player] call ace_csw_fnc_getNearbySources + * + * Public: No + */ +params ["_unit"]; + +[_unit, { + params ["_unit"]; + private _nearSupplies = (_unit nearSupplies 5) select { + isNull (group _x) || + {!([_x] call EFUNC(common,isPlayer)) && {[side group _player, side group _x] call BIS_fnc_sideIsFriendly}} + }; + + _nearSupplies pushBack _unit; + { + if (_x isKindOf "CAManBase") then { + _nearSupplies append [uniformContainer _x, vestContainer _x, backpackContainer _x]; + continue; + }; + + { + _x params ["", "_container"]; + _nearSupplies pushBack _container; + } forEach (everyContainer _x); + } forEach _nearSupplies; + + _nearSupplies select {!(_x isKindOf "CAManBase")} // return +}, _unit, QGVAR(nearbySourcesCache), NEARBY_SOURCES_CACHE_EXPIRY, QGVAR(clearNearbySourcesCache)] call EFUNC(common,cachedCall); diff --git a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf index 2906c33b799..58d8a6b9c9d 100644 --- a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf +++ b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf @@ -23,32 +23,15 @@ private _magGroupsConfig = configFile >> QGVAR(groups); // so we don't solve in private _availableMagazines = createHashMap; // slower than array, still needed for setting source of magazine // filter enemy & player units while allowing pulling from friendly AI, crates, etc -private _nearSupplies = (_vehicle nearSupplies 5) select { - isNull (group _x) || - {!([_x] call EFUNC(common,isPlayer)) && {[side group _player, side group _x] call BIS_fnc_sideIsFriendly}} -}; - -// add caller to nearSupplies since players will get filtered out -_nearSupplies pushBack _player; +private _sources = [_player] call FUNC(getNearbySources); // send the mag source with the highest ammo private _bestMagAmmo = createHashMap; { - if (_x isKindOf "CAManBase") then { - // unit inventory needs to be added manually - _nearSupplies append [uniformContainer _x, vestContainer _x, backpackContainer _x]; - continue; - }; private _xSource = _x; private _cswMags = (magazinesAmmoCargo _xSource) select {isClass (_magGroupsConfig >> _x select 0)}; - // add containers inside containers - { - _x params ["_classname", "_container"]; - _nearSupplies pushBack _container; - } forEach (everyContainer _x); - { _x params ["_classname", "_ammo"]; if (_ammo > (_bestMagAmmo getOrDefault [_classname, 0])) then { @@ -56,7 +39,7 @@ private _bestMagAmmo = createHashMap; _availableMagazines set [_classname, _xSource]; }; } forEach _cswMags; -} forEach _nearSupplies; +} forEach _sources; if (_availableMagazines isEqualTo createHashMap) exitWith { [] }; // fast exit if no available mags diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index 46b0000fdcb..f2f07c17614 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -24,6 +24,9 @@ private _carryMaxAmmo = getNumber (configFile >> "CfgMagazines" >> _carryMag >> private _fullMagazines = floor (_ammo / _carryMaxAmmo); private _bulletsRemaining = _ammo % _carryMaxAmmo; +// get nearby units to clear cache +private _nearUnits = _unloadTo nearEntities ["CAManBase", 5]; + private _unloadToUnit = _unloadTo isKindOf "CAManBase"; if (_unloadToUnit) then { @@ -37,7 +40,9 @@ if (_unloadToUnit) then { }; }; -if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {}; +if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith { + [QGVAR(clearNearbySourcesCache), [], _nearUnits] call CBA_fnc_targetEvent; +}; // Try to use object inventory or existing container private _container = [_unloadTo, objNull] select _unloadToUnit; @@ -71,3 +76,5 @@ if (_fullMagazines > 0) then { if (_bulletsRemaining > 0) then { _container addMagazineAmmoCargo [_carryMag, 1, _bulletsRemaining]; }; + +[QGVAR(clearNearbySourcesCache), [], _nearUnits] call CBA_fnc_targetEvent; diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf index 411c8717b4f..cdc0dff751c 100644 --- a/addons/csw/functions/fnc_reload_loadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -49,6 +49,10 @@ private _onFinish = { if (_bestAmmoToSend == -1) exitWith {ERROR_2("No ammo [%1 - %2]?",_xMag,_bestAmmoToSend);}; [_magSource, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); + + private _nearUnits = _vehicle nearEntities ["CAManBase", 5]; + [QGVAR(clearNearbySourcesCache), [], _nearUnits] call CBA_fnc_targetEvent; + if (_bestAmmoToSend == 0) exitWith {}; private _returnTo = _magSource; diff --git a/addons/csw/script_component.hpp b/addons/csw/script_component.hpp index 29521039f24..3917dad9011 100644 --- a/addons/csw/script_component.hpp +++ b/addons/csw/script_component.hpp @@ -21,6 +21,8 @@ #define DISTANCE_FROM_GUN 1.5 #define RELATIVE_DIRECTION(direction) [DISTANCE_FROM_GUN, direction] +#define NEARBY_SOURCES_CACHE_EXPIRY 5 + #ifdef FAST_PROGRESSBARS #define TIME_PROGRESSBAR(X) ((X) * 0.075) #else From 5d62ab4125886ee3b44749d24d13a76cf25208dc Mon Sep 17 00:00:00 2001 From: Salluci Date: Sun, 2 Jul 2023 19:48:01 +0300 Subject: [PATCH 07/37] fix undefined variable --- addons/csw/functions/fnc_getNearbySources.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/csw/functions/fnc_getNearbySources.sqf b/addons/csw/functions/fnc_getNearbySources.sqf index 7c9e3e96ba1..fec7b4c9b5d 100644 --- a/addons/csw/functions/fnc_getNearbySources.sqf +++ b/addons/csw/functions/fnc_getNearbySources.sqf @@ -20,7 +20,7 @@ params ["_unit"]; params ["_unit"]; private _nearSupplies = (_unit nearSupplies 5) select { isNull (group _x) || - {!([_x] call EFUNC(common,isPlayer)) && {[side group _player, side group _x] call BIS_fnc_sideIsFriendly}} + {!([_x] call EFUNC(common,isPlayer)) && {[side group _unit, side group _x] call BIS_fnc_sideIsFriendly}} }; _nearSupplies pushBack _unit; From b4a0771730ac2ea6829902d1eb714a525f4956e8 Mon Sep 17 00:00:00 2001 From: Salluci Date: Sun, 2 Jul 2023 22:10:22 +0300 Subject: [PATCH 08/37] add csw override --- addons/csw/functions/fnc_ai_handleFired.sqf | 1 + addons/csw/functions/fnc_ai_handleGetIn.sqf | 1 + .../csw/functions/fnc_reload_actionsLoad.sqf | 3 ++- .../functions/fnc_reload_actionsUnload.sqf | 3 ++- .../fnc_staticWeaponInit_unloadExtraMags.sqf | 1 + addons/mk6mortar/XEH_preInit.sqf | 13 +++++++++++ .../functions/fnc_csw_getProxyWeapon.sqf | 22 +++++-------------- addons/mk6mortar/stringtable.xml | 16 ++------------ .../crew-served-weapons-framework.md | 19 ++++++++++++---- 9 files changed, 43 insertions(+), 36 deletions(-) diff --git a/addons/csw/functions/fnc_ai_handleFired.sqf b/addons/csw/functions/fnc_ai_handleFired.sqf index 668a425b50f..bc34e1e6319 100644 --- a/addons/csw/functions/fnc_ai_handleFired.sqf +++ b/addons/csw/functions/fnc_ai_handleFired.sqf @@ -16,6 +16,7 @@ params ["_staticWeapon", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_ TRACE_8("firedEH:",_staticWeapon,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner); if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; +if (_staticWeapon getVariable [QGVAR(disabled), false]) exitWith {}; if (someAmmo _staticWeapon) exitWith {}; TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); diff --git a/addons/csw/functions/fnc_ai_handleGetIn.sqf b/addons/csw/functions/fnc_ai_handleGetIn.sqf index 2906a01d1e8..654a32e5557 100644 --- a/addons/csw/functions/fnc_ai_handleGetIn.sqf +++ b/addons/csw/functions/fnc_ai_handleGetIn.sqf @@ -15,6 +15,7 @@ params ["_staticWeapon", "_role", "_gunner"]; TRACE_3("getInEH:",_staticWeapon,_role,_gunner); if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; +if (_staticWeapon getVariable [QGVAR(disabled), false]) exitWith {}; if (someAmmo _staticWeapon) exitWith {}; TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); diff --git a/addons/csw/functions/fnc_reload_actionsLoad.sqf b/addons/csw/functions/fnc_reload_actionsLoad.sqf index d141da3d93b..843f34019bf 100644 --- a/addons/csw/functions/fnc_reload_actionsLoad.sqf +++ b/addons/csw/functions/fnc_reload_actionsLoad.sqf @@ -32,7 +32,8 @@ private _condition = { params ["_target", "_player", "_params"]; _params params ["_carryMag", "_turretPath", "", "_magSource"]; - ([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0 + !(_target getVariable [QGVAR(disabled), false]) && + {([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0} }; private _cfgMagazines = configFile >> "CfgMagazines"; // micro-optimization diff --git a/addons/csw/functions/fnc_reload_actionsUnload.sqf b/addons/csw/functions/fnc_reload_actionsUnload.sqf index 0f4e9cb7ded..908c6b25b47 100644 --- a/addons/csw/functions/fnc_reload_actionsUnload.sqf +++ b/addons/csw/functions/fnc_reload_actionsUnload.sqf @@ -46,7 +46,8 @@ private _statement = { private _condition = { params ["_target", "_player", "_params"]; _params params ["_vehMag", "_turretPath", "_carryMag"]; - [_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine) + !(_target getVariable [QGVAR(disabled), false]) && + {[_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine)} }; private _actions = []; diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 41845c0eb3c..374fe7873d9 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -19,6 +19,7 @@ params ["_staticWeapon", "_assemblyMode", "_emptyWeapon"]; TRACE_3("staticWeaponInit_unloadExtraMags",_staticWeapon,_assemblyMode,_emptyWeapon); if (!_assemblyMode) exitWith {}; +if (_staticWeapon getVariable [QGVAR(disabled), false]) exitWith {}; private _desiredAmmo = getNumber (configOf _staticWeapon >> QUOTE(ADDON) >> "desiredAmmo"); private _storeExtraMagazines = GVAR(handleExtraMagazines); diff --git a/addons/mk6mortar/XEH_preInit.sqf b/addons/mk6mortar/XEH_preInit.sqf index 9361d05015e..100217ffe4e 100644 --- a/addons/mk6mortar/XEH_preInit.sqf +++ b/addons/mk6mortar/XEH_preInit.sqf @@ -8,4 +8,17 @@ PREP_RECOMPILE_END; #include "initSettings.sqf" +["Mortar_01_base_F", "Init", { // override CSW's ammo handling with Mk6 setting + params ["_mortar"]; + _mortar setVariable [QEGVAR(csw,disabled), !GVAR(useAmmoHandling)]; +}] call CBA_fnc_addClassEventHandler; + +GVAR(ammoHandlingMagazineReplacement) = createHashMapFromArray [ + ["8Rnd_82mm_Mo_shells", "ACE_1Rnd_82mm_Mo_HE"], + ["8Rnd_82mm_Mo_Smoke_white", "ACE_1Rnd_82mm_Mo_Smoke"], + ["8Rnd_82mm_Mo_Flare_white", "ACE_1Rnd_82mm_Mo_Illum"], + ["8Rnd_82mm_Mo_guided", "ACE_1Rnd_82mm_Mo_HE_Guided"], + ["8Rnd_82mm_Mo_LG", "ACE_1Rnd_82mm_Mo_HE_LaserGuided"] +]; + ADDON = true; diff --git a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf index fd4804b98f6..bf4ed48f643 100644 --- a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf +++ b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf @@ -22,9 +22,9 @@ params ["_mortar", "_turret", "_currentWeapon", "_proxyWeaponNeeded"]; TRACE_4("csw_getProxyWeapon",_mortar,_turret,_currentWeapon,_proxyWeaponNeeded); -private _newWeapon = ""; +private _newWeapon = _currentWeapon; -if (_proxyWeaponNeeded || GVAR(useAmmoHandling)) then { +if (GVAR(useAmmoHandling)) then { if (_currentWeapon != "mortar_82mm") exitWith { ERROR_2("unknown weapon [%1 - %2]",typeOf _mortar,_currentWeapon); }; // Replace weapon with fast reloading version @@ -36,23 +36,13 @@ if (_proxyWeaponNeeded || GVAR(useAmmoHandling)) then { private _convertedMags = []; { _x params ["_xMag", "_xTurret", "_xAmmo"]; - if (_xTurret isEqualTo _turret) then { - private _replaceMag = switch (true) do { - case (_xMag == "8Rnd_82mm_Mo_shells"): {"ACE_1Rnd_82mm_Mo_HE"}; - case (_xMag == "8Rnd_82mm_Mo_Smoke_white"): {"ACE_1Rnd_82mm_Mo_Smoke"}; - case (_xMag == "8Rnd_82mm_Mo_Flare_white"): {"ACE_1Rnd_82mm_Mo_Illum"}; - case (_xMag == "8Rnd_82mm_Mo_guided"): {"ACE_1Rnd_82mm_Mo_HE_Guided"}; - case (_xMag == "8Rnd_82mm_Mo_LG"): {"ACE_1Rnd_82mm_Mo_HE_LaserGuided"}; - default {""}; - }; + private _replaceMag = GVAR(ammoHandlingMagazineReplacement) getOrDefault [_xMag, ""]; if (_replaceMag != "") then { _magsToRemove pushBackUnique [_xMag, _xTurret]; - if (!GVAR(useAmmoHandling)) then { - TRACE_3("replacing",_xMag,_replaceMag,_xAmmo); - for "_i" from 1 to _xAmmo do { - _convertedMags pushBack [_replaceMag, _xTurret, 1]; - }; + TRACE_3("replacing",_xMag,_replaceMag,_xAmmo); + for "_i" from 1 to _xAmmo do { + _convertedMags pushBack [_replaceMag, _xTurret, 1]; }; } else { WARNING_1("unknown mag %1", _xMag); diff --git a/addons/mk6mortar/stringtable.xml b/addons/mk6mortar/stringtable.xml index 464d6543462..26ef489f5e9 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -218,7 +218,7 @@ 這個模塊允許你設定MK6迫擊砲的相關功能 - Use Ammunition handling + Use Ammunition Handling Aktiviere Munitionshandhabung Usar manejo de munición. Aktywuj obsługę amunicji @@ -233,19 +233,7 @@ Používat ruční manipulaci s municí - Removes mortar magazines, requiring individual rounds to be loaded by the gunner or loader. Does not affect AI mortars. - Enfernt das Magzin des Mörsers. Es ist nun erforderlich, die einzelnen Patronen manuell zu laden. Dies beeinflusst nicht die KI-Truppen. - Elimina los cargadores del mortero, requiriendo al artillero o cargador la carga manual de cada rondas. No afecta morteros controlados por IA. - Usuwa magazynki moździerza, wymagając ładowania pojedynczych pocisków przez strzelca lub ładowniczego. Nie dotyczy moździerzy AI. - Enlève les chargeurs de mortier, ce qui oblige le tireur ou le servant à charger les obus manuellement. N'affecte pas les mortiers IA. - Toglie i proiettili dal mortaio. I colpi singoli devono essere caricati dall'operatore. Non cambia quado l'IA spara. - Elimina os carregadores do morteiro, requerendo que o atirador ou carregador utilize de forma individual a munição. Não afeta os morteiros controlados pela IA. - Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжающим. Не влияет на артиллерию ИИ. - 迫撃砲から弾薬を除去します。射手か装填手により予め装填されている必要があります。AI 迫撃砲へ影響を与えません。 - 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야 합니다. 인공지능은 영향을 받지 않습니다. - 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填。此功能并不影响由 AI 射击的迫击炮 - 開啟此功能時。迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填。此功能並不影響由AI射擊的迫擊砲 - Odstraní z minometu zásobník a vynucuje nabíjení po každém výstřelu buď mířičem nebo nabíječem. Tato možnost neovlivňuje AI posádky. + Converts mortar magazines into their single round versions, requiring individual rounds to be loaded by the crew.\nOverrides Crew Served Weapon's Ammo Handling. Remove Round diff --git a/docs/wiki/framework/crew-served-weapons-framework.md b/docs/wiki/framework/crew-served-weapons-framework.md index 9b3ef28d4fb..bc140286b45 100644 --- a/docs/wiki/framework/crew-served-weapons-framework.md +++ b/docs/wiki/framework/crew-served-weapons-framework.md @@ -102,12 +102,12 @@ class ACE_CSW_Groups { class prefix_100rnd_hmg_csw_mag { // Same name as the carryable magazine prefix_100rnd_hmg_mag = 1; // Vehicle magazine that will be loaded when loading this magazine }; - + // Using an existing CSW magazine class ace_csw_100Rnd_127x99_mag { banana_dummy_ammo = 1; }; - + /* Carryable magazines already defined by ACE: - ace_csw_100Rnd_127x99_mag @@ -134,12 +134,12 @@ class CfgVehicles { class StaticMGWeapon; class prefix_hmg: StaticMGWeapon { class ACE_CSW { - enabled = 1; // Enables ACE CSW for this weapon + enabled = 1; // Enables ACE CSW for this weapon proxyWeapon = "prefix_hmg_weapon_proxy"; // The proxy weapon created above magazineLocation = "_target selectionPosition 'magazine'"; // Ammo handling interaction point location disassembleWeapon = "prefix_hmg_carry"; // Carryable weapon created above disassembleTurret = "ace_csw_m3Tripod"; // Which static tripod will appear when weapon is disassembled - ammoLoadTime = 7; // How long it takes in seconds to load ammo into the weapon + ammoLoadTime = 7; // How long it takes in seconds to load ammo into the weapon ammoUnloadTime = 5; // How long it takes in seconds to unload ammo from the weapon desiredAmmo = 100; // When the weapon is reloaded it will try and reload to this ammo capacity // Optional callback function for when the CSW gets disassembled, called with [tripod, staticWeapon] @@ -149,6 +149,17 @@ class CfgVehicles { }; ``` +### 1.5 Custom Ammo Handling + +ACE's ammo handling (including AI reloading, and initial unloading and conversion of the weapon's magazines) can be blocked by setting the `ace_csw_disabled` variable on init. +This will also block reloading and unloading the weapon manually through ACE. +This variable needs to be set where the weapon is local. + +```sqf +myCustomStaticWeapon = createVehicle ["B_Mortar_01_F", [0, 0, 0]]; +myCustomStaticWeapon setVariable ["ace_csw_disabled", true, true]; // blocks ammo handling +``` + ## 2. Making a new Tripod If none of the existing ACE tripods fit your weapon, you can create your own. Creating a tripod is similar to creating a crew served weapon and consists of two parts: From 9fe3f8432f1b349d1e798dbcd7202e1c462fc3b2 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Mon, 3 Jul 2023 04:26:03 +0300 Subject: [PATCH 09/37] Update docs/wiki/framework/crew-served-weapons-framework.md --- docs/wiki/framework/crew-served-weapons-framework.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/wiki/framework/crew-served-weapons-framework.md b/docs/wiki/framework/crew-served-weapons-framework.md index bc140286b45..6c5222fd4c2 100644 --- a/docs/wiki/framework/crew-served-weapons-framework.md +++ b/docs/wiki/framework/crew-served-weapons-framework.md @@ -153,7 +153,7 @@ class CfgVehicles { ACE's ammo handling (including AI reloading, and initial unloading and conversion of the weapon's magazines) can be blocked by setting the `ace_csw_disabled` variable on init. This will also block reloading and unloading the weapon manually through ACE. -This variable needs to be set where the weapon is local. +This variable needs to be set globally. ```sqf myCustomStaticWeapon = createVehicle ["B_Mortar_01_F", [0, 0, 0]]; From d00c9ca2a0fd8f84e5bd72016ee98e1d0c8d9f80 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 10:42:30 +0300 Subject: [PATCH 10/37] all the things --- addons/csw/XEH_PREP.hpp | 2 + addons/csw/XEH_postInit.sqf | 2 - addons/csw/XEH_preInit.sqf | 4 +- addons/csw/functions/fnc_ai_reload.sqf | 68 ++++--------------- .../csw/functions/fnc_compatibleMagazines.sqf | 39 +++++++++++ addons/csw/functions/fnc_getCarryMagazine.sqf | 4 +- .../fnc_getSourceCompatibleMagazines.sqf | 35 ++++++++++ addons/csw/functions/fnc_proxyWeapon.sqf | 9 +++ .../csw/functions/fnc_reload_actionsLoad.sqf | 4 +- .../fnc_reload_getLoadableMagazines.sqf | 58 +++++++--------- .../fnc_reload_handleAddTurretMag.sqf | 3 + .../csw/functions/fnc_reload_loadMagazine.sqf | 38 +++-------- addons/csw/script_component.hpp | 1 + 13 files changed, 148 insertions(+), 119 deletions(-) create mode 100644 addons/csw/functions/fnc_compatibleMagazines.sqf create mode 100644 addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf diff --git a/addons/csw/XEH_PREP.hpp b/addons/csw/XEH_PREP.hpp index 5d461ae415d..36e898913a7 100644 --- a/addons/csw/XEH_PREP.hpp +++ b/addons/csw/XEH_PREP.hpp @@ -19,8 +19,10 @@ PREP(assemble_pickupWeapon); PREP(canGetIn); PREP(getIn); +PREP(compatibleMagazines); PREP(getCarryMagazine); PREP(getNearbySources); +PREP(getSourceCompatibleMagazines); PREP(proxyWeapon); PREP(reload_actionsLoad); diff --git a/addons/csw/XEH_postInit.sqf b/addons/csw/XEH_postInit.sqf index fddac693858..3d6809b0ca2 100644 --- a/addons/csw/XEH_postInit.sqf +++ b/addons/csw/XEH_postInit.sqf @@ -1,7 +1,5 @@ #include "script_component.hpp" -GVAR(vehicleMagCache) = createHashMap; - ["CBA_settingsInitialized", { TRACE_3("settingsInit",GVAR(defaultAssemblyMode),GVAR(handleExtraMagazines),GVAR(ammoHandling)); ["StaticWeapon", "init", LINKFUNC(staticWeaponInit), true, [], true] call CBA_fnc_addClassEventHandler; diff --git a/addons/csw/XEH_preInit.sqf b/addons/csw/XEH_preInit.sqf index 6ecb2a0c2fb..a95f9746217 100644 --- a/addons/csw/XEH_preInit.sqf +++ b/addons/csw/XEH_preInit.sqf @@ -9,6 +9,8 @@ PREP_RECOMPILE_END; #include "initSettings.sqf" GVAR(initializedStaticTypes) = []; +GVAR(vehicleMagCache) = createHashMap; +GVAR(compatibleMagsCache) = createHashMap; +GVAR(compatibleVehicleMagsCache) = createHashMap; ADDON = true; - diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index fcf4bb904bb..e61a7b76fd9 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -16,67 +16,29 @@ params ["_staticWeapon", "_gunner", "_weapon"]; TRACE_3("AI reload",_staticWeapon,_gunner,_weapon); -private _turretPath = [_gunner] call EFUNC(common,getTurretIndex); -private _reloadSource = objNull; -private _reloadMag = ""; -private _reloadNeededAmmo = -1; +private _loadableMagazines = [_staticWeapon, _gunner, true] call FUNC(reload_getLoadableMagazines); +if (_loadableMagazines isEqualTo []) exitWith {TRACE_1("could not find reloadable mag",_staticWeapon)}; -private _cfgMagGroups = configFile >> QGVAR(groups); - -private _sources = [_gunner] call FUNC(getNearbySources); - -// Find if there is anything we can reload with -// see fnc_reload_getLoadableMagazines, though we don't care about AI pulling from the best ammo possible +private _bestAmmo = 0; +private _magazineInfo = []; { - scopeName "findSource"; - private _xSource = _x; - - private _cswMagazines = (magazineCargo _xSource) select {isClass (_cfgMagGroups >> _x)}; - TRACE_2("",_xSource,_cswMagazines); - - { - private _xWeaponMag = _x; - { - if ((getNumber (_cfgMagGroups >> _x >> _xWeaponMag)) == 1) then { - private _loadInfo = [_staticWeapon, _turretPath, _x, _xSource] call FUNC(reload_canLoadMagazine); - if (_loadInfo select 0) then { - _reloadMag = _x; - _reloadSource = _xSource; - _reloadNeededAmmo = _loadInfo select 2; - TRACE_3("found mag",_reloadMag,_reloadSource,_x); - breakOut "findSource"; - }; - }; - } forEach _cswMagazines; - } forEach (compatibleMagazines _weapon); -} forEach _sources; -if (_reloadMag == "") exitWith {TRACE_1("could not find mag",_reloadMag);}; - -// Figure out what we can add from the magazines we have -private _bestAmmoToSend = -1; -{ - _x params ["_xMag", "_xAmmo"]; - TRACE_2("",_xMag,_xAmmo); - if (_xMag == _reloadMag) then { - if ((_bestAmmoToSend == -1) || {(_xAmmo > _bestAmmoToSend) && {_xAmmo <= _reloadNeededAmmo}}) then { - _bestAmmoToSend = _xAmmo; - }; + _x params ["", "", "", "", "", "_ammo"]; + if (_ammo > _bestAmmo) then { + _bestAmmo = _ammo; + _magazineInfo = _x; }; -} forEach (if (_reloadSource isKindOf "CAManBase") then {magazinesAmmo _reloadSource} else {magazinesAmmoCargo _reloadSource}); -TRACE_4("",_reloadSource,_reloadMag,_reloadNeededAmmo,_bestAmmoToSend); -if (_bestAmmoToSend == -1) exitWith {ERROR("No ammo");}; +} forEach _loadableMagazines; + +_magazineInfo params ["_carryMag", "_turretPath", "_loadInfo", "_magSource", "", "_ammo"]; // Remove the mag from the source -[_reloadSource, _reloadMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); +[_magSource, _carryMag, _ammo] call EFUNC(common,removeSpecificMagazine); // see fnc_reload_loadMagazine #L54 // AI never returns ammo and removes the magazine before reloading, so we can skip distance and weaponHolder checks -private _eventParams = [_staticWeapon, _turretPath, objNull, _reloadMag, _bestAmmoToSend, _gunner]; +private _eventParams = [_staticWeapon, _turretPath, objNull, _carryMag, _ammo, _gunner]; -private _timeToLoad = 1; -if !(isNull (configOf _staticWeapon >> QUOTE(ADDON) >> "ammoLoadTime")) then { - _timeToLoad = getNumber (configOf _staticWeapon >> QUOTE(ADDON) >> "ammoLoadTime"); -}; +private _timeToLoad = GET_NUMBER(configOf _staticWeapon >> QUOTE(ADDON) >> "ammoLoadTime", 1); TRACE_1("Reloading in progress",_timeToLoad); [{ @@ -84,6 +46,6 @@ TRACE_1("Reloading in progress",_timeToLoad); if !(alive _staticWeapon && {alive _gunner}) exitWith {TRACE_2("invalid state",alive _staticWeapon,alive _gunner);}; // Reload the static weapon - TRACE_5("calling addTurretMag event: AI reload",_staticWeapon,_turretPath,_gunner,_reloadMag,_bestAmmoToSend); + TRACE_1("calling addTurretMag event: AI reload",_this); [QGVAR(addTurretMag), _this] call CBA_fnc_globalEvent; }, _eventParams, _timeToLoad] call CBA_fnc_waitAndExecute; diff --git a/addons/csw/functions/fnc_compatibleMagazines.sqf b/addons/csw/functions/fnc_compatibleMagazines.sqf new file mode 100644 index 00000000000..c3fc52f32df --- /dev/null +++ b/addons/csw/functions/fnc_compatibleMagazines.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" +/* + * Author: LinkIsGrim + * Gets all carry magazines that can be loaded into a CSW, includes weapons added by script + * + * Arguments: + * 0: CSW + * + * Return Value: + * Compatible Magazines + * Magazine classname + * Nothing + * + * Example: + * [cursorObject] call ace_csw_fnc_compatibleMagazines + * + * Public: Yes + */ +params [["_csw", objNull, [objNull]]]; + +private _weapons = []; + +{ + private _turret = _x; + { + _weapons pushBackUnique _x; + } forEach (_csw weaponsTurret _turret); +} forEach (allTurrets _csw); + +if (_weapons isEqualTo []) exitWith {[]}; + +private _carryMagazines = createHashMap; // hashmap for constant lookup +{ + private _weapon = _x; + if !(_weapon in GVAR(compatibleVehicleMagsCache)) then {continue}; + _carryMagazines merge [GVAR(compatibleMagsCache) get _weapon, true]; +} forEach _weapons; + +_carryMagazines // return diff --git a/addons/csw/functions/fnc_getCarryMagazine.sqf b/addons/csw/functions/fnc_getCarryMagazine.sqf index 4535512e2db..402cf866a8f 100644 --- a/addons/csw/functions/fnc_getCarryMagazine.sqf +++ b/addons/csw/functions/fnc_getCarryMagazine.sqf @@ -12,10 +12,10 @@ * Example: * "1Rnd_GAT_missiles" call ace_csw_fnc_getCarryMagazine * - * Public: No + * Public: Yes */ -params ["_vehicleMag"]; +params [["_vehicleMag", "", [""]]]; private _carryMag = GVAR(vehicleMagCache) get _vehicleMag; if (isNil "_carryMag") then { diff --git a/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf b/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf new file mode 100644 index 00000000000..27e42688ea6 --- /dev/null +++ b/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * Author: LinkIsGrim + * Gets compatible magazines to load a CSW from a magazine source + * + * Arguments: + * 0: Magazine Source + * 1: CSW (default: objNull) + * + * Return Value: + * Magazines + * Magazine classname + * Magazine ammo + * + * Example: + * [player, cursorObject] call ace_csw_fnc_getSourceCompatibleMagazines + * + * Public: Yes + */ +params [["_source", objNull, [objNull]], ["_csw", objNull, [objNull]]]; + +if (isNull _source || {isNull _csw}) exitWith {[]}; + +private _magazines = magazinesAmmoCargo _source; + +if (_magazines isEqualTo []) exitWith {[]}; + +private _compatibleMagazines = [_csw] call FUNC(compatibleMagazines); + +private _return = _magazines select {(_x select 0) in _compatibleMagazines}; + +// sort by ammo count, highest to lowest +_return sort false; + +_return diff --git a/addons/csw/functions/fnc_proxyWeapon.sqf b/addons/csw/functions/fnc_proxyWeapon.sqf index e4449bbbce4..dfce44c3ddc 100644 --- a/addons/csw/functions/fnc_proxyWeapon.sqf +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -37,6 +37,15 @@ if ((missionNamespace getVariable [_proxyWeapon, objNull]) isEqualType {}) then }; if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); }; +// Cache compatible magazines +if !(_proxyWeapon in GVAR(compatibleVehicleMagsCache)) then { + private _compatibleMagazines = compatibleMagazines _proxyWeapon; + GVAR(compatibleVehicleMagsCache) set [_proxyWeapon, _compatibleMagazines]; + GVAR(compatibleCarryMagsCache) set [_proxyWeapon, + _compatibleMagazines apply {_x call FUNC(getCarryMagazine)} createHashMapFromArray [] + ]; +}; + TRACE_2("swapping to proxy weapon",_currentWeapon,_proxyWeapon); _staticWeapon removeWeaponTurret [_currentWeapon, _turret]; _staticWeapon addWeaponTurret [_proxyWeapon, _turret]; diff --git a/addons/csw/functions/fnc_reload_actionsLoad.sqf b/addons/csw/functions/fnc_reload_actionsLoad.sqf index 6a410c77462..1632edd2ca1 100644 --- a/addons/csw/functions/fnc_reload_actionsLoad.sqf +++ b/addons/csw/functions/fnc_reload_actionsLoad.sqf @@ -23,9 +23,9 @@ private _loadableMagazines = [_vehicle, _player] call FUNC(reload_getLoadableMag private _statement = { params ["_target", "_player", "_params"]; - _params params ["_carryMag", "_turretPath", "", "_magSource"]; + _params params ["_carryMag", "_turretPath", "", "_magSource", "", "_ammo"]; - [_target, _turretPath, _carryMag, _magSource, _player] call FUNC(reload_loadMagazine); + [_target, _turretPath, _carryMag, _magSource, _player, _ammo] call FUNC(reload_loadMagazine); }; private _condition = { diff --git a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf index 58d8a6b9c9d..287aa56b597 100644 --- a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf +++ b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf @@ -5,7 +5,8 @@ * * Arguments: * 0: Vehicle - * 1: Player + * 1: Unit + * 2: AI reloading, skip turret checks (default: false) * * Return Value: * Mags @@ -17,55 +18,48 @@ * Public: No */ -params ["_vehicle", "_player"]; +params ["_vehicle", "_unit", ["_aiReload", false]]; -private _magGroupsConfig = configFile >> QGVAR(groups); // so we don't solve in loop every time private _availableMagazines = createHashMap; // slower than array, still needed for setting source of magazine // filter enemy & player units while allowing pulling from friendly AI, crates, etc -private _sources = [_player] call FUNC(getNearbySources); - -// send the mag source with the highest ammo -private _bestMagAmmo = createHashMap; +private _sources = [_unit] call FUNC(getNearbySources); { + // minor optimization: since mags are sorted by ammo count in FUNC(getSourceCompatibleMagazines), we only need to check the first mag of this type in this source + private _handledSourceMags = []; private _xSource = _x; - private _cswMags = (magazinesAmmoCargo _xSource) select {isClass (_magGroupsConfig >> _x select 0)}; - { _x params ["_classname", "_ammo"]; - if (_ammo > (_bestMagAmmo getOrDefault [_classname, 0])) then { - _bestMagAmmo set [_classname, _ammo]; - _availableMagazines set [_classname, _xSource]; + if (_classname in _handledSourceMags) then {continue}; + _handledSourceMags pushBack _classname; + + // select mag source with the highest ammo + if (_ammo > (_availableMagazines getOrDefault [_classname, [objNull, 0]]) select 1) then { + _availableMagazines set [_classname, [_xSource, _ammo]]; }; - } forEach _cswMags; + } forEach ([_x, _vehicle] call FUNC(getSourceCompatibleMagazines)); } forEach _sources; -if (_availableMagazines isEqualTo createHashMap) exitWith { [] }; // fast exit if no available mags +if (_availableMagazines isEqualTo createHashMap) exitWith {[]}; // fast exit if no available mags private _loadInfo = []; private _return = []; +private _turretPath = [_unit] call EFUNC(common,getTurretIndex); + // Go through turrets and find weapons that we could reload +// We can skip checking all turrets if we're doing AI reloading { private _turretPath = _x; { - private _weapon = _x; - { - //IGNORE_PRIVATE_WARNING ["_x", "_y"]; - private _carryMag = _x; - private _magSource = _y; - private _carryGroup = _magGroupsConfig >> _carryMag; - { - if ( - ((getNumber (_carryGroup >> _x)) == 1) && - {_loadInfo = [_vehicle, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine); _loadInfo select 0} - ) exitWith { - _return pushBack [_carryMag, _turretPath, _loadInfo, _magSource, _player]; - }; - } forEach (compatibleMagazines _weapon); - } forEach _availableMagazines; - } forEach (_vehicle weaponsTurret _turretPath); -} forEach (allTurrets _vehicle); -// Note: these nested forEach's looks terrible, but most only have one element + //IGNORE_PRIVATE_WARNING ["_x", "_y"]; + private _carryMag = _x; + _y params ["_magSource", "_ammo"]; + _loadInfo = [_vehicle, _turretPath, _carryMag] call FUNC(reload_canLoadMagazine); + if (_loadInfo select 0) then { + _return pushBack [_carryMag, _turretPath, _loadInfo, _magSource, _unit, _ammo]; + }; + } forEach _availableMagazines; +} forEach ([(allTurrets _vehicle), [_turretPath]] select _aiReload); _return diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index 781d4d1c520..556a7a9541f 100644 --- a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -24,6 +24,9 @@ params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived", "_unit"]; private _returnTo = param [6, _unit]; +if (isNull _returnTo) then { + _returnTo = _vehicle; +}; TRACE_7("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_unit,_returnTo); TRACE_2("",local _vehicle, _vehicle turretLocal _turret); diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf index cdc0dff751c..77909f429d3 100644 --- a/addons/csw/functions/fnc_reload_loadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -19,57 +19,41 @@ * Public: No */ -params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"]; -TRACE_5("loadMagazine",_vehicle,_turret,_carryMag,_magSource,_unit); +params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit", "_ammo"]; +TRACE_6("loadMagazine",_vehicle,_turret,_carryMag,_magSource,_unit,_ammo); -private _timeToLoad = 1; -if (!isNull(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime")) then { - _timeToLoad = getNumber(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime"); -}; +private _timeToLoad = GET_NUMBER(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime", 1); private _displayName = format [localize LSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")]; private _onFinish = { - (_this select 0) params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"]; - TRACE_5("load progressBar finish",_vehicle,_turret,_carryMag,_magSource,_unit); + (_this select 0) params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit", "_ammo"]; + TRACE_6("load progressBar finish",_vehicle,_turret,_carryMag,_magSource,_unit,_ammo); ([_vehicle, _turret, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) params ["", "", "_neededAmmo", ""]; if (_neededAmmo <= 0) exitWith { ERROR_1("Can't load ammo - %1",_this); }; - // Figure out what we can add from the magazines we have - private _bestAmmoToSend = -1; - { - _x params ["_xMag", "_xAmmo"]; - if (_xMag == _carryMag) then { - if ((_bestAmmoToSend == -1) || {(_xAmmo > _bestAmmoToSend) && {_xAmmo <= _neededAmmo}}) then { - _bestAmmoToSend = _xAmmo; - }; - }; - } forEach (if (_magSource isKindOf "CAManBase") then {magazinesAmmo _magSource} else {magazinesAmmoCargo _magSource}); - - if (_bestAmmoToSend == -1) exitWith {ERROR_2("No ammo [%1 - %2]?",_xMag,_bestAmmoToSend);}; - [_magSource, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); + [_magSource, _carryMag, _ammo] call EFUNC(common,removeSpecificMagazine); private _nearUnits = _vehicle nearEntities ["CAManBase", 5]; [QGVAR(clearNearbySourcesCache), [], _nearUnits] call CBA_fnc_targetEvent; - if (_bestAmmoToSend == 0) exitWith {}; - private _returnTo = _magSource; + // if we're pulling from a weaponHolder, return the ammo to the unit doing the action // workaround for weaponHolders being recreated with removeSpecificMagazine, magazines will still get dropped if inventory is full + // TODO: remove after 2.14 if (_magSource isKindOf "WeaponHolder") then { _returnTo = _unit; }; - TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend, _unit); - [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend, _unit, _returnTo]] call CBA_fnc_globalEvent; + TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_ammo, _unit); + [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _ammo, _unit, _returnTo]] call CBA_fnc_globalEvent; }; - [ TIME_PROGRESSBAR(_timeToLoad), - [_vehicle, _turret, _carryMag, _magSource, _unit], + [_vehicle, _turret, _carryMag, _magSource, _unit, _ammo], _onFinish, {TRACE_1("load progressBar fail",_this);}, _displayName, diff --git a/addons/csw/script_component.hpp b/addons/csw/script_component.hpp index 3917dad9011..42b292c17ef 100644 --- a/addons/csw/script_component.hpp +++ b/addons/csw/script_component.hpp @@ -17,6 +17,7 @@ #include "\z\ace\addons\main\script_macros.hpp" +#define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) #define DISTANCE_FROM_GUN 1.5 #define RELATIVE_DIRECTION(direction) [DISTANCE_FROM_GUN, direction] From c96a9daf7bbc68c27a56a9f50b3e204a7243313d Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 10:50:06 +0300 Subject: [PATCH 11/37] remove unnecessary change --- addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 78f06e72fce..41845c0eb3c 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -35,7 +35,6 @@ private _containerMagazineCount = []; { _x params ["_xMag", "_xTurret", "_xAmmo"]; - _magsToRemove pushBackUnique [_xMag, _xTurret]; private _carryMag = _xMag call FUNC(getCarryMagazine); if (_carryMag != "") then { @@ -46,6 +45,7 @@ private _containerMagazineCount = []; TRACE_1("",_loadedMagAmmo); }; if (_xAmmo > 0) then { + _magsToRemove pushBackUnique [_xMag, _xTurret]; private _index = _containerMagazineClassnames find _carryMag; if (_index < 0) then { _index = _containerMagazineClassnames pushBack _carryMag; From c46dc339c5a493a0b5ef046907bc1e424190a59c Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 13:01:28 +0300 Subject: [PATCH 12/37] _staticWeapon > _vehicle, StaticWeapon > CSW --- addons/csw/functions/fnc_ai_handleFired.sqf | 10 ++-- addons/csw/functions/fnc_ai_handleGetIn.sqf | 2 +- addons/csw/functions/fnc_ai_reload.sqf | 2 +- .../fnc_assemble_canPickupWeapon.sqf | 11 ++--- .../functions/fnc_assemble_pickupWeapon.sqf | 34 ++++++------- addons/csw/functions/fnc_canGetIn.sqf | 14 +++--- .../csw/functions/fnc_compatibleMagazines.sqf | 9 +++- addons/csw/functions/fnc_getNearbySources.sqf | 2 +- .../fnc_getSourceCompatibleMagazines.sqf | 2 + addons/csw/functions/fnc_proxyWeapon.sqf | 24 +++++----- .../csw/functions/fnc_reload_actionsLoad.sqf | 4 +- .../functions/fnc_reload_actionsUnload.sqf | 2 +- .../functions/fnc_reload_canLoadMagazine.sqf | 4 +- .../fnc_reload_canUnloadMagazine.sqf | 4 +- .../fnc_reload_getLoadableMagazines.sqf | 4 +- .../fnc_reload_handleAddTurretMag.sqf | 2 +- .../fnc_reload_handleRemoveTurretMag.sqf | 2 +- .../csw/functions/fnc_reload_loadMagazine.sqf | 2 +- addons/csw/functions/fnc_staticWeaponInit.sqf | 48 +++++++++---------- .../fnc_staticWeaponInit_unloadExtraMags.sqf | 28 +++++------ 20 files changed, 108 insertions(+), 102 deletions(-) diff --git a/addons/csw/functions/fnc_ai_handleFired.sqf b/addons/csw/functions/fnc_ai_handleFired.sqf index da7258e76cd..64edc11f76e 100644 --- a/addons/csw/functions/fnc_ai_handleFired.sqf +++ b/addons/csw/functions/fnc_ai_handleFired.sqf @@ -12,12 +12,12 @@ * Public: No */ -params ["_staticWeapon", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; -TRACE_8("firedEH:",_staticWeapon,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner); +params ["_vehicle", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; +TRACE_8("firedEH:",_vehicle,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner); if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; -if (someAmmo _staticWeapon) exitWith {}; +if (someAmmo _vehicle) exitWith {}; -TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); +TRACE_2("need ammo",someAmmo _vehicle,magazinesAllTurrets _vehicle); -[_staticWeapon, _gunner, _weapon] call FUNC(ai_reload); +[_vehicle, _gunner, _weapon] call FUNC(ai_reload); diff --git a/addons/csw/functions/fnc_ai_handleGetIn.sqf b/addons/csw/functions/fnc_ai_handleGetIn.sqf index 90c071eddb9..94d43e4691b 100644 --- a/addons/csw/functions/fnc_ai_handleGetIn.sqf +++ b/addons/csw/functions/fnc_ai_handleGetIn.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Grim + * Author: LinkIsGrim * Handles AI GetIn on an empty weapon * * Arguments: diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index e61a7b76fd9..2c45c9b650a 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: PabstMirror, modified by Grim + * Author: PabstMirror, LinkIsGrim * Handles AI reloading * * Arguments: diff --git a/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf b/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf index 9736fb97dde..139d1106bc8 100644 --- a/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf @@ -4,7 +4,7 @@ * If the CSW is mounted or in use this will not allow you to dismount the weapon * * Arguments: - * 0: Static Weapon + * 0: CSW * * Return Value: * Can Dismount @@ -15,12 +15,11 @@ * Public: No */ -params ["_staticWeapon"]; +params ["_vehicle"]; // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] -private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 3]); -private _notCrewed = (crew _staticWeapon) isEqualTo []; -private _deadCrew = !(alive (gunner _staticWeapon)); // need to eject body??? +private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_vehicle getVariable [QGVAR(assemblyMode), 3]); +private _notCrewed = (crew _vehicle) isEqualTo []; +private _deadCrew = !(alive (gunner _vehicle)); // need to eject body??? _assemblyMode && {_notCrewed || _deadCrew} - diff --git a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf index 9b17fcaf732..f5ce64d3062 100644 --- a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf @@ -4,7 +4,7 @@ * Dismounts the weapon from the tripod and drops its backpack beside * * Arguments: - * 0: Static Weapon + * 0: CSW * * Return Value: * None @@ -16,26 +16,26 @@ */ [{ - params ["_staticWeapon", "_player"]; - TRACE_2("assemble_pickupWeapon",_staticWeapon,_player); + params ["_vehicle", "_player"]; + TRACE_2("assemble_pickupWeapon",_vehicle,_player); - private _onDisassembleFunc = getText(configOf _staticWeapon >> QUOTE(ADDON) >> "disassembleFunc"); - private _carryWeaponClassname = getText(configOf _staticWeapon >> QUOTE(ADDON) >> "disassembleWeapon"); - private _turretClassname = getText(configOf _staticWeapon >> QUOTE(ADDON) >> "disassembleTurret"); + private _onDisassembleFunc = getText(configOf _vehicle >> QUOTE(ADDON) >> "disassembleFunc"); + private _carryWeaponClassname = getText(configOf _vehicle >> QUOTE(ADDON) >> "disassembleWeapon"); + private _turretClassname = getText(configOf _vehicle >> QUOTE(ADDON) >> "disassembleTurret"); private _pickupTime = getNumber(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "pickupTime"); - TRACE_4("",typeOf _staticWeapon,_carryWeaponClassname,_turretClassname,_pickupTime); + TRACE_4("",typeOf _vehicle,_carryWeaponClassname,_turretClassname,_pickupTime); if (!isClass (configFile >> "CfgWeapons" >> _carryWeaponClassname)) exitWith {ERROR_1("bad weapon classname [%1]",_carryWeaponClassname);}; // Turret classname can equal nothing if the deploy bag is the "whole" weapon. e.g Kornet, Metis, other ATGMs if ((_turretClassname isNotEqualTo "") && {!isClass (configFile >> "CfgVehicles" >> _turretClassname)}) exitWith {ERROR_1("bad turret classname [%1]",_turretClassname);}; private _onFinish = { params ["_args"]; - _args params ["_staticWeapon", "_player", "_carryWeaponClassname", "_turretClassname", "_onDisassembleFunc"]; - TRACE_4("disassemble finish",_staticWeapon,_player,_carryWeaponClassname,_turretClassname); + _args params ["_vehicle", "_player", "_carryWeaponClassname", "_turretClassname", "_onDisassembleFunc"]; + TRACE_4("disassemble finish",_vehicle,_player,_carryWeaponClassname,_turretClassname); - private _weaponPos = getPosATL _staticWeapon; + private _weaponPos = getPosATL _vehicle; _weaponPos set [2, (_weaponPos select 2) + 0.1]; - private _weaponDir = getDir _staticWeapon; + private _weaponDir = getDir _vehicle; private _carryWeaponMag = ""; private _carryWeaponMags = getArray (configFile >> "CfgWeapons" >> _carryWeaponClassname >> "magazines") apply {toLower _x}; @@ -54,7 +54,7 @@ TRACE_2("Removing ammo",_xMag,_carryMag); [_player, _carryMag, _xAmmo] call FUNC(reload_handleReturnAmmo); }; - } forEach (magazinesAllTurrets _staticWeapon); + } forEach (magazinesAllTurrets _vehicle); if (_turretClassname isNotEqualTo "") then { private _cswTripod = createVehicle [_turretClassname, [0, 0, 0], [], 0, "NONE"]; @@ -66,7 +66,7 @@ _cswTripod setVelocity [0, 0, -0.05]; _cswTripod setVectorUp (surfaceNormal _weaponPos); }, [_cswTripod, _weaponDir, _weaponPos]] call CBA_fnc_execNextFrame; - [_cswTripod, _staticWeapon] call (missionNamespace getVariable _onDisassembleFunc); + [_cswTripod, _vehicle] call (missionNamespace getVariable _onDisassembleFunc); }; [{ @@ -89,16 +89,16 @@ }, [_player, _weaponPos, _carryWeaponClassname, _carryWeaponMag]] call CBA_fnc_execNextFrame; LOG("delete weapon"); - deleteVehicle _staticWeapon; + deleteVehicle _vehicle; LOG("end"); }; private _condition = { params ["_args"]; - _args params ["_staticWeapon"]; - ((crew _staticWeapon) isEqualTo []) && (alive _staticWeapon) + _args params ["_vehicle"]; + ((crew _vehicle) isEqualTo []) && (alive _vehicle) }; - [TIME_PROGRESSBAR(_pickupTime), [_staticWeapon, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, localize LSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_pickupTime), [_vehicle, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, localize LSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/csw/functions/fnc_canGetIn.sqf b/addons/csw/functions/fnc_canGetIn.sqf index 052f48f8b0d..73a170ab8ee 100644 --- a/addons/csw/functions/fnc_canGetIn.sqf +++ b/addons/csw/functions/fnc_canGetIn.sqf @@ -1,10 +1,10 @@ #include "script_component.hpp" /* * Author:Dani (TCVM) - * Checks if the player can get in the weapon + * Checks if the player can get in the CSW * * Arguments: - * 0: Static Weapon + * 0: CSW * * Return Value: * None @@ -20,9 +20,9 @@ if ((missionNamespace getVariable [QEGVAR(quickmount,enabled), false]) && {(miss false }; -params ["_staticWeapon"]; +params ["_vehicle"]; -alive _staticWeapon -&& {!(alive (gunner _staticWeapon))} -&& {(locked _staticWeapon) < 2} -&& {0.3 < ((vectorUp _staticWeapon) select 2)} +alive _vehicle +&& {!(alive (gunner _vehicle))} +&& {(locked _vehicle) < 2} +&& {0.3 < ((vectorUp _vehicle) select 2)} diff --git a/addons/csw/functions/fnc_compatibleMagazines.sqf b/addons/csw/functions/fnc_compatibleMagazines.sqf index c3fc52f32df..d4cfbf7382f 100644 --- a/addons/csw/functions/fnc_compatibleMagazines.sqf +++ b/addons/csw/functions/fnc_compatibleMagazines.sqf @@ -18,6 +18,13 @@ */ params [["_csw", objNull, [objNull]]]; +if !(typeOf _csw in GVAR(initializedStaticTypes)) exitWith {createHashMap}; + +// fast exit for csw with single weapon, most common scenario +if (count allTurrets _csw isEqualTo 1 && {count weapons _csw isEqualTo 1}) exitWith { + GVAR(compatibleMagsCache) get ((weapons _csw) select 0) // return +}; + private _weapons = []; { @@ -32,7 +39,7 @@ if (_weapons isEqualTo []) exitWith {[]}; private _carryMagazines = createHashMap; // hashmap for constant lookup { private _weapon = _x; - if !(_weapon in GVAR(compatibleVehicleMagsCache)) then {continue}; + if !(_weapon in GVAR(compatibleMagsCache)) then {continue}; _carryMagazines merge [GVAR(compatibleMagsCache) get _weapon, true]; } forEach _weapons; diff --git a/addons/csw/functions/fnc_getNearbySources.sqf b/addons/csw/functions/fnc_getNearbySources.sqf index fec7b4c9b5d..22fd19f045f 100644 --- a/addons/csw/functions/fnc_getNearbySources.sqf +++ b/addons/csw/functions/fnc_getNearbySources.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: LinkIsGrim - * Gets available ammo sources for loading a static weapon + * Gets available ammo sources for loading a CSW * * Arguments: * 0: Unit attempting to load diff --git a/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf b/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf index 27e42688ea6..38e0bde4462 100644 --- a/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf +++ b/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf @@ -21,6 +21,8 @@ params [["_source", objNull, [objNull]], ["_csw", objNull, [objNull]]]; if (isNull _source || {isNull _csw}) exitWith {[]}; +if !(typeOf _csw in GVAR(initializedStaticTypes)) exitWith {[]}; + private _magazines = magazinesAmmoCargo _source; if (_magazines isEqualTo []) exitWith {[]}; diff --git a/addons/csw/functions/fnc_proxyWeapon.sqf b/addons/csw/functions/fnc_proxyWeapon.sqf index dfce44c3ddc..2ad18406cf6 100644 --- a/addons/csw/functions/fnc_proxyWeapon.sqf +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -18,21 +18,21 @@ * Public: No */ -params ["_staticWeapon", "_turret", "_needed", "_emptyWeapon"]; -TRACE_4("proxyWeapon",_staticWeapon,_turret,_needed,_emptyWeapon); +params ["_vehicle", "_turret", "_needed", "_emptyWeapon"]; +TRACE_4("proxyWeapon",_vehicle,_turret,_needed,_emptyWeapon); -if (_staticWeapon getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _staticWeapon); }; +if (_vehicle getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _vehicle); }; -private _proxyWeapon = getText (configOf _staticWeapon >> "ace_csw" >> "proxyWeapon"); +private _proxyWeapon = getText (configOf _vehicle >> "ace_csw" >> "proxyWeapon"); -TRACE_2("",typeOf _staticWeapon,_proxyWeapon); +TRACE_2("",typeOf _vehicle,_proxyWeapon); if (_proxyWeapon == "") exitWith {}; -private _currentWeapon = (_staticWeapon weaponsTurret [0]) param [0, "#none"]; +private _currentWeapon = (_vehicle weaponsTurret [0]) param [0, "#none"]; if ((missionNamespace getVariable [_proxyWeapon, objNull]) isEqualType {}) then { // check if string is a function TRACE_1("Calling proxyWeapon function",_proxyWeapon); // This function may replace magazines or do other things to the static weapon - _proxyWeapon = [_staticWeapon, _turret, _currentWeapon, _needed, _emptyWeapon] call (missionNamespace getVariable _proxyWeapon); + _proxyWeapon = [_vehicle, _turret, _currentWeapon, _needed, _emptyWeapon] call (missionNamespace getVariable _proxyWeapon); _needed = _proxyWeapon != ""; }; if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); }; @@ -41,12 +41,10 @@ if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); }; if !(_proxyWeapon in GVAR(compatibleVehicleMagsCache)) then { private _compatibleMagazines = compatibleMagazines _proxyWeapon; GVAR(compatibleVehicleMagsCache) set [_proxyWeapon, _compatibleMagazines]; - GVAR(compatibleCarryMagsCache) set [_proxyWeapon, - _compatibleMagazines apply {_x call FUNC(getCarryMagazine)} createHashMapFromArray [] - ]; + GVAR(compatibleCarryMagsCache) set [_proxyWeapon, (_compatibleMagazines apply {_x call FUNC(getCarryMagazine)}) createHashMapFromArray []]; }; TRACE_2("swapping to proxy weapon",_currentWeapon,_proxyWeapon); -_staticWeapon removeWeaponTurret [_currentWeapon, _turret]; -_staticWeapon addWeaponTurret [_proxyWeapon, _turret]; -_staticWeapon setVariable [format [QGVAR(proxyHandled_%1), _turret], true, true]; +_vehicle removeWeaponTurret [_currentWeapon, _turret]; +_vehicle addWeaponTurret [_proxyWeapon, _turret]; +_vehicle setVariable [format [QGVAR(proxyHandled_%1), _turret], true, true]; diff --git a/addons/csw/functions/fnc_reload_actionsLoad.sqf b/addons/csw/functions/fnc_reload_actionsLoad.sqf index 1632edd2ca1..a5387813cee 100644 --- a/addons/csw/functions/fnc_reload_actionsLoad.sqf +++ b/addons/csw/functions/fnc_reload_actionsLoad.sqf @@ -1,10 +1,10 @@ #include "script_component.hpp" /* * Author: PabstMirror - * Gets sub actions for what the player can load into the static weapon + * Gets sub actions for what the player can load into the CSW * * Arguments: - * 0: Static Weapon + * 0: Target * 1: Player * * Return Value: diff --git a/addons/csw/functions/fnc_reload_actionsUnload.sqf b/addons/csw/functions/fnc_reload_actionsUnload.sqf index 22dd6507e1e..043683e37f5 100644 --- a/addons/csw/functions/fnc_reload_actionsUnload.sqf +++ b/addons/csw/functions/fnc_reload_actionsUnload.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: PabstMirror - * Gets sub actions for what the player can unload from the static weapon + * Gets sub actions for what the player can unload from the CSW * * Arguments: * 0: Target diff --git a/addons/csw/functions/fnc_reload_canLoadMagazine.sqf b/addons/csw/functions/fnc_reload_canLoadMagazine.sqf index 4a189e5e98b..851147ef772 100644 --- a/addons/csw/functions/fnc_reload_canLoadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_canLoadMagazine.sqf @@ -1,10 +1,10 @@ #include "script_component.hpp" /* * Author: PabstMirror &Dani (TCVM) - * Tests if unit can load a magazine into a static weapon. + * Tests if unit can load a magazine into a CSW. * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Turret Path * 2: Carryable Magazine * 3: Supplier (default: objNull) diff --git a/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf b/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf index 2ce6b6e591c..634eff0968e 100644 --- a/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_canUnloadMagazine.sqf @@ -1,10 +1,10 @@ #include "script_component.hpp" /* * Author: PabstMirror - * Tests if unit can unload a magazine from a static weapon. + * Tests if unit can unload a magazine from a CSW. * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Turret Path * 2: Player * 3: Carryable Magazine diff --git a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf index 287aa56b597..6af3ee8b8e2 100644 --- a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf +++ b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf @@ -1,10 +1,10 @@ #include "script_component.hpp" /* * Author: PabstMirror, LinkIsGrim - * Gets nearby magazines that can be loaded in the static weapon + * Gets nearby magazines that can be loaded into the CSW * * Arguments: - * 0: Vehicle + * 0: CSW * 1: Unit * 2: AI reloading, skip turret checks (default: false) * diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index 556a7a9541f..0dee4ac31b9 100644 --- a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -5,7 +5,7 @@ * Called from a global event but only runs where turret is local * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Turret Path * 2: Source of magazine * 3: Vehicle Magazine diff --git a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf index c78c1414499..5eb32479b3d 100644 --- a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf @@ -5,7 +5,7 @@ * Called from a global event but only runs where turret is local * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Turret Path * 2: Magainze Unit Can Carry * 3: Magazine To Remove From Static diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf index 77909f429d3..26df08d1ac2 100644 --- a/addons/csw/functions/fnc_reload_loadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -30,7 +30,7 @@ private _onFinish = { (_this select 0) params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit", "_ammo"]; TRACE_6("load progressBar finish",_vehicle,_turret,_carryMag,_magSource,_unit,_ammo); - ([_vehicle, _turret, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) params ["", "", "_neededAmmo", ""]; + ([_vehicle, _turret, _carryMag] call FUNC(reload_canLoadMagazine)) params ["", "", "_neededAmmo", ""]; if (_neededAmmo <= 0) exitWith { ERROR_1("Can't load ammo - %1",_this); }; [_magSource, _carryMag, _ammo] call EFUNC(common,removeSpecificMagazine); diff --git a/addons/csw/functions/fnc_staticWeaponInit.sqf b/addons/csw/functions/fnc_staticWeaponInit.sqf index 6ddaa9d36a5..9b216d68670 100644 --- a/addons/csw/functions/fnc_staticWeaponInit.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit.sqf @@ -1,10 +1,10 @@ #include "script_component.hpp" /* * Author: Dani (TCVM) - * Initializes weapon to disable weapon disassembling + * Initializes CSW to disable weapon disassembling * * Arguments: - * 0: Weapon + * 0: CSW * * Return Value: * None @@ -15,44 +15,44 @@ * Public: No */ -params ["_staticWeapon"]; -private _typeOf = typeOf _staticWeapon; -private _configOf = configOf _staticWeapon; +params ["_vehicle"]; +private _typeOf = typeOf _vehicle; +private _configOf = configOf _vehicle; private _configEnabled = (getNumber (_configOf >> "ace_csw" >> "enabled")) == 1; private _assemblyConfig = _configEnabled && {(getText (_configOf >> "ace_csw" >> "disassembleWeapon")) != ""}; -TRACE_4("staticWeaponInit",_staticWeapon,_typeOf,_configEnabled,_assemblyConfig); +TRACE_4("staticWeaponInit",_vehicle,_typeOf,_configEnabled,_assemblyConfig); if (_configEnabled && {GVAR(ammoHandling) == 2}) then { - TRACE_1("adding AI fired handler",_staticWeapon); - _staticWeapon addEventHandler ["Fired", LINKFUNC(ai_handleFired)]; - _staticWeapon addEventHandler ["GetIn", LINKFUNC(ai_handleGetIn)]; // handle AI getting inside weapon with no ammo + TRACE_1("adding AI fired handler",_vehicle); + _vehicle addEventHandler ["Fired", LINKFUNC(ai_handleFired)]; + _vehicle addEventHandler ["GetIn", LINKFUNC(ai_handleGetIn)]; // handle AI getting inside weapon with no ammo }; -TRACE_2("",local _staticWeapon,_staticWeapon turretLocal [0]); -if (_configEnabled && {_staticWeapon turretLocal [0]}) then { // if turret is local to us, then handle mags/weapon +TRACE_2("",local _vehicle,_vehicle turretLocal [0]); +if (_configEnabled && {_vehicle turretLocal [0]}) then { // if turret is local to us, then handle mags/weapon [{ - params ["_staticWeapon"]; - if (!alive _staticWeapon) exitWith { TRACE_1("dead/deleted",_staticWeapon); }; + params ["_vehicle"]; + if (!alive _vehicle) exitWith { TRACE_1("dead/deleted",_vehicle); }; // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] - private _assemblyModeIndex = _staticWeapon getVariable [QGVAR(assemblyMode), 3]; + private _assemblyModeIndex = _vehicle getVariable [QGVAR(assemblyMode), 3]; private _emptyWeapon = _assemblyModeIndex isEqualTo 2; private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select _assemblyModeIndex; - TRACE_2("turretLocal",_staticWeapon,_assemblyMode); - [_staticWeapon, [0], _assemblyMode, _emptyWeapon] call FUNC(proxyWeapon); - [_staticWeapon, _assemblyMode, _emptyWeapon] call FUNC(staticWeaponInit_unloadExtraMags); - }, [_staticWeapon]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly + TRACE_2("turretLocal",_vehicle,_assemblyMode); + [_vehicle, [0], _assemblyMode, _emptyWeapon] call FUNC(proxyWeapon); + [_vehicle, _assemblyMode, _emptyWeapon] call FUNC(staticWeaponInit_unloadExtraMags); + }, [_vehicle]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly }; if (_assemblyConfig) then { [{ - params ["_staticWeapon"]; - if (!alive _staticWeapon) exitWith { TRACE_1("dead/deleted",_staticWeapon); }; - private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 3]); - TRACE_2("assemblyConfig present",_staticWeapon,_assemblyMode); + params ["_vehicle"]; + if (!alive _vehicle) exitWith { TRACE_1("dead/deleted",_vehicle); }; + private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_vehicle getVariable [QGVAR(assemblyMode), 3]); + TRACE_2("assemblyConfig present",_vehicle,_assemblyMode); if (_assemblyMode) then { // Disable vanilla assembly if assemblyMode eanbled - [QGVAR(disableVanillaAssembly), [_staticWeapon]] call CBA_fnc_localEvent; + [QGVAR(disableVanillaAssembly), [_vehicle]] call CBA_fnc_localEvent; }; - }, [_staticWeapon]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly + }, [_vehicle]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly }; // Add interactions for players diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 41845c0eb3c..6796dd18fa4 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -4,7 +4,7 @@ * Dumps ammo to container * * Arguments: - * 0: Weapon + * 0: CSW * 1: Using advanced assembly * * Return Value: @@ -16,11 +16,11 @@ * Public: No */ -params ["_staticWeapon", "_assemblyMode", "_emptyWeapon"]; -TRACE_3("staticWeaponInit_unloadExtraMags",_staticWeapon,_assemblyMode,_emptyWeapon); +params ["_vehicle", "_assemblyMode", "_emptyWeapon"]; +TRACE_3("staticWeaponInit_unloadExtraMags",_vehicle,_assemblyMode,_emptyWeapon); if (!_assemblyMode) exitWith {}; -private _desiredAmmo = getNumber (configOf _staticWeapon >> QUOTE(ADDON) >> "desiredAmmo"); +private _desiredAmmo = getNumber (configOf _vehicle >> QUOTE(ADDON) >> "desiredAmmo"); private _storeExtraMagazines = GVAR(handleExtraMagazines); if (_emptyWeapon) then { _desiredAmmo = 0; @@ -56,31 +56,31 @@ private _containerMagazineCount = []; } else { if ((_xMag select [0,4]) != "fake") then { WARNING_1("Unable to unload [%1] - No matching carry mag",_xMag); }; }; -} forEach (magazinesAllTurrets _staticWeapon); +} forEach (magazinesAllTurrets _vehicle); TRACE_1("Remove all loaded magazines",_magsToRemove); { - _staticWeapon removeMagazinesTurret _x; + _vehicle removeMagazinesTurret _x; if ((_loadedMagazineInfo select [0,2]) isEqualTo _x) then { TRACE_1("Re-add the starting mag",_loadedMagazineInfo); - _staticWeapon addMagazineTurret _loadedMagazineInfo; + _vehicle addMagazineTurret _loadedMagazineInfo; }; } 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); +if (_vehicle getVariable [QGVAR(secondaryWeaponMagazine), ""] isNotEqualTo "") then { + private _secondaryWeaponMagazine = _vehicle getVariable QGVAR(secondaryWeaponMagazine); + private _turret = allTurrets _vehicle param [0, []]; + private _vehicleMag = [_vehicle, _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]; + _vehicle addMagazineTurret [_vehicleMag, _turret, 1]; + _vehicle setVariable [QGVAR(secondaryWeaponMagazine), nil]; }; if (_storeExtraMagazines) then { TRACE_1("saving extra mags to container",_containerMagazineCount); { - [_staticWeapon, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); + [_vehicle, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); } forEach _containerMagazineClassnames; }; From 6c2a8a2117a1a7d4ac5a6614de3c50014d24d5e7 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 13:16:15 +0300 Subject: [PATCH 13/37] add container property --- .../functions/fnc_reload_handleReturnAmmo.sqf | 3 +-- .../fnc_staticWeaponInit_unloadExtraMags.sqf | 25 ++++++++++++++++++- addons/mk6mortar/CfgVehicles.hpp | 1 + .../crew-served-weapons-framework.md | 10 +++++--- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index f2f07c17614..a661b81710f 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -56,8 +56,7 @@ if ((maxLoad _container) isEqualTo 0) then { if (isNull _container) then { // Create ammo storage container - private _weaponRelPos = _unloadTo getRelPos RELATIVE_DIRECTION(270); - _weaponRelPos set [2, ((getPosATL _unloadTo) select 2) + 0.05]; + private _weaponRelPos = (_unloadTo getRelPos RELATIVE_DIRECTION(270)) vectorAdd [0, 0, 0.05]; _container = createVehicle [["GroundWeaponHolder", QGVAR(ammo_holder)] select GVAR(handleExtraMagazinesType), [0, 0, 0], [], 0, "CAN_COLLIDE"]; _unloadTo setVariable [QGVAR(container), _container, true]; _container setDir random [0, 180, 360]; diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 6796dd18fa4..75a45dcd764 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -80,7 +80,30 @@ if (_vehicle getVariable [QGVAR(secondaryWeaponMagazine), ""] isNotEqualTo "") t if (_storeExtraMagazines) then { TRACE_1("saving extra mags to container",_containerMagazineCount); + + // Create container from config if available, use setting if not + private _containerType = getText (configOf _vehicle >> QUOTE(ADDON) >> "container"); + if (_containerType isNotEqualTo "") then { + private _relPos = (_vehicle getRelPos RELATIVE_DIRECTION(270)) vectorAdd [0, 0, 0.05]; + _container = createVehicle [_containerType, [0, 0, 0], [], 0, "CAN_COLLIDE"]; + _vehicle setVariable [QGVAR(container), _container, true]; + _container setDir random [0, 180, 360]; + _container setPosATL _relPos; + if ((_relPos select 2) < 0.5) then { + _container setVectorUp (surfaceNormal _relPos); + }; + + // empty container inventory + // TODO: make a function in common? + clearItemCargoGlobal _container; + clearWeaponCargoGlobal _container; + clearMagazineCargoGlobal _container; + clearBackpackCargoGlobal _container; + } else { + _container = _vehicle; + }; + { - [_vehicle, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); + [_container, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); } forEach _containerMagazineClassnames; }; diff --git a/addons/mk6mortar/CfgVehicles.hpp b/addons/mk6mortar/CfgVehicles.hpp index 41e45abf351..8ffcde64f4b 100644 --- a/addons/mk6mortar/CfgVehicles.hpp +++ b/addons/mk6mortar/CfgVehicles.hpp @@ -29,6 +29,7 @@ class CfgVehicles { class ace_csw { proxyWeapon = QFUNC(csw_getProxyWeapon); magazineLocation = "_target selectionPosition 'usti hlavne'"; + container = "ACE_Box_82mm_Mo_Combo"; }; class Turrets: Turrets { class MainTurret: MainTurret { diff --git a/docs/wiki/framework/crew-served-weapons-framework.md b/docs/wiki/framework/crew-served-weapons-framework.md index 9b3ef28d4fb..2d2d19b4ae1 100644 --- a/docs/wiki/framework/crew-served-weapons-framework.md +++ b/docs/wiki/framework/crew-served-weapons-framework.md @@ -102,12 +102,12 @@ class ACE_CSW_Groups { class prefix_100rnd_hmg_csw_mag { // Same name as the carryable magazine prefix_100rnd_hmg_mag = 1; // Vehicle magazine that will be loaded when loading this magazine }; - + // Using an existing CSW magazine class ace_csw_100Rnd_127x99_mag { banana_dummy_ammo = 1; }; - + /* Carryable magazines already defined by ACE: - ace_csw_100Rnd_127x99_mag @@ -134,16 +134,18 @@ class CfgVehicles { class StaticMGWeapon; class prefix_hmg: StaticMGWeapon { class ACE_CSW { - enabled = 1; // Enables ACE CSW for this weapon + enabled = 1; // Enables ACE CSW for this weapon proxyWeapon = "prefix_hmg_weapon_proxy"; // The proxy weapon created above magazineLocation = "_target selectionPosition 'magazine'"; // Ammo handling interaction point location disassembleWeapon = "prefix_hmg_carry"; // Carryable weapon created above disassembleTurret = "ace_csw_m3Tripod"; // Which static tripod will appear when weapon is disassembled - ammoLoadTime = 7; // How long it takes in seconds to load ammo into the weapon + ammoLoadTime = 7; // How long it takes in seconds to load ammo into the weapon ammoUnloadTime = 5; // How long it takes in seconds to unload ammo from the weapon desiredAmmo = 100; // When the weapon is reloaded it will try and reload to this ammo capacity // Optional callback function for when the CSW gets disassembled, called with [tripod, staticWeapon] disassembleFunc = "prefix_fnc_handleDisassembly"; + // Optional object to store unloaded magazines in + container = "ReammoBox_F"; }; }; }; From ed44c0d44552bee94d808a8c0520dd68bd1506a2 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 13:20:21 +0300 Subject: [PATCH 14/37] more headers --- .../fnc_aceRearmGetCarryMagazines.sqf | 2 +- addons/csw/functions/fnc_ai_handleGetIn.sqf | 14 +++++++------- addons/csw/functions/fnc_ai_reload.sqf | 18 +++++++++--------- addons/csw/functions/fnc_getIn.sqf | 8 ++++---- addons/csw/functions/fnc_proxyWeapon.sqf | 2 +- .../csw/functions/fnc_reload_actionsLoad.sqf | 2 +- .../csw/functions/fnc_reload_actionsUnload.sqf | 2 +- .../fnc_reload_getVehicleMagazine.sqf | 2 +- .../csw/functions/fnc_reload_loadMagazine.sqf | 4 ++-- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf b/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf index ac51d03347e..ac833d64fd4 100644 --- a/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf +++ b/addons/csw/functions/fnc_aceRearmGetCarryMagazines.sqf @@ -4,7 +4,7 @@ * Helper function for ace_rearm; Gets magazines that should be loaded by csw * * Arguments: - * 0: Vehicle + * 0: CSW * 1: Specific Turret or pass bool to check all turrets (default: true) * * Return Value: diff --git a/addons/csw/functions/fnc_ai_handleGetIn.sqf b/addons/csw/functions/fnc_ai_handleGetIn.sqf index 94d43e4691b..f8d89c97961 100644 --- a/addons/csw/functions/fnc_ai_handleGetIn.sqf +++ b/addons/csw/functions/fnc_ai_handleGetIn.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: LinkIsGrim - * Handles AI GetIn on an empty weapon + * Handles AI GetIn on an empty CSW * * Arguments: * GetIn EH @@ -11,11 +11,11 @@ * * Public: No */ -params ["_staticWeapon", "_role", "_gunner", "_turret"]; -TRACE_3("getInEH:",_staticWeapon,_role,_gunner); +params ["_vehicle", "_role", "_gunner", "_turret"]; +TRACE_3("getInEH:",_vehicle,_role,_gunner); if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; -if (someAmmo _staticWeapon) exitWith {}; +if (someAmmo _vehicle) exitWith {}; // turret can be empty when AI is forcefully moved to the vehicle if (_turret isEqualTo []) then { @@ -23,7 +23,7 @@ if (_turret isEqualTo []) then { }; // this doesn't handle multi-weapon turrets, need a "turretWeapon" event or a PFH to do that -private _weapon = (_staticWeapon weaponsTurret _turret) select 0; -TRACE_4("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon,_turret,_weapon); +private _weapon = (_vehicle weaponsTurret _turret) select 0; +TRACE_4("need ammo",someAmmo _vehicle,magazinesAllTurrets _vehicle,_turret,_weapon); -[_staticWeapon, _gunner, _weapon] call FUNC(ai_reload); +[_vehicle, _gunner, _weapon] call FUNC(ai_reload); diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index 2c45c9b650a..b3429c11674 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -4,7 +4,7 @@ * Handles AI reloading * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Gunner * 2: Weapon * @@ -13,11 +13,11 @@ * * Public: No */ -params ["_staticWeapon", "_gunner", "_weapon"]; -TRACE_3("AI reload",_staticWeapon,_gunner,_weapon); +params ["_vehicle", "_gunner", "_weapon"]; +TRACE_3("AI reload",_vehicle,_gunner,_weapon); -private _loadableMagazines = [_staticWeapon, _gunner, true] call FUNC(reload_getLoadableMagazines); -if (_loadableMagazines isEqualTo []) exitWith {TRACE_1("could not find reloadable mag",_staticWeapon)}; +private _loadableMagazines = [_vehicle, _gunner, true] call FUNC(reload_getLoadableMagazines); +if (_loadableMagazines isEqualTo []) exitWith {TRACE_1("could not find reloadable mag",_vehicle)}; private _bestAmmo = 0; private _magazineInfo = []; @@ -36,14 +36,14 @@ _magazineInfo params ["_carryMag", "_turretPath", "_loadInfo", "_magSource", "", // see fnc_reload_loadMagazine #L54 // AI never returns ammo and removes the magazine before reloading, so we can skip distance and weaponHolder checks -private _eventParams = [_staticWeapon, _turretPath, objNull, _carryMag, _ammo, _gunner]; +private _eventParams = [_vehicle, _turretPath, objNull, _carryMag, _ammo, _gunner]; -private _timeToLoad = GET_NUMBER(configOf _staticWeapon >> QUOTE(ADDON) >> "ammoLoadTime", 1); +private _timeToLoad = GET_NUMBER(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime", 1); TRACE_1("Reloading in progress",_timeToLoad); [{ - params ["_staticWeapon", "", "", "", "", "_gunner"]; - if !(alive _staticWeapon && {alive _gunner}) exitWith {TRACE_2("invalid state",alive _staticWeapon,alive _gunner);}; + params ["_vehicle", "", "", "", "", "_gunner"]; + if !(alive _vehicle && {alive _gunner}) exitWith {TRACE_2("invalid state",alive _vehicle,alive _gunner);}; // Reload the static weapon TRACE_1("calling addTurretMag event: AI reload",_this); diff --git a/addons/csw/functions/fnc_getIn.sqf b/addons/csw/functions/fnc_getIn.sqf index 9a11553ce99..75485d1025c 100644 --- a/addons/csw/functions/fnc_getIn.sqf +++ b/addons/csw/functions/fnc_getIn.sqf @@ -6,7 +6,7 @@ * the gun and can't be acssesed from the back, I am implementing this to get around that issue. * * Arguments: - * 0: Static Weapon + * 0: CSW * 1: Unit * * Return Value: @@ -18,7 +18,7 @@ * Public: No */ -params ["_staticWeapon", "_player"]; -TRACE_2("getIn",_staticWeapon,_player); +params ["_vehicle", "_player"]; +TRACE_2("getIn",_vehicle,_player); -_player moveInTurret [_staticWeapon, [0]]; +_player moveInTurret [_vehicle, [0]]; diff --git a/addons/csw/functions/fnc_proxyWeapon.sqf b/addons/csw/functions/fnc_proxyWeapon.sqf index 2ad18406cf6..1557ae4fe6c 100644 --- a/addons/csw/functions/fnc_proxyWeapon.sqf +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -4,7 +4,7 @@ * Handles the use of proxy weapons to fix engine-reload times * * Arguments: - * 0: Weapon + * 0: CSW * 1: Turret * 2: Proxy weapon needed * 2: Weapon should be emptied diff --git a/addons/csw/functions/fnc_reload_actionsLoad.sqf b/addons/csw/functions/fnc_reload_actionsLoad.sqf index a5387813cee..7a1f49980e2 100644 --- a/addons/csw/functions/fnc_reload_actionsLoad.sqf +++ b/addons/csw/functions/fnc_reload_actionsLoad.sqf @@ -4,7 +4,7 @@ * Gets sub actions for what the player can load into the CSW * * Arguments: - * 0: Target + * 0: CSW * 1: Player * * Return Value: diff --git a/addons/csw/functions/fnc_reload_actionsUnload.sqf b/addons/csw/functions/fnc_reload_actionsUnload.sqf index 043683e37f5..118072b8c26 100644 --- a/addons/csw/functions/fnc_reload_actionsUnload.sqf +++ b/addons/csw/functions/fnc_reload_actionsUnload.sqf @@ -4,7 +4,7 @@ * Gets sub actions for what the player can unload from the CSW * * Arguments: - * 0: Target + * 0: CSW * 1: Player * * Return Value: diff --git a/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf index f8053df3b97..3668469f9f3 100644 --- a/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf +++ b/addons/csw/functions/fnc_reload_getVehicleMagazine.sqf @@ -4,7 +4,7 @@ * Finds the best vehicle magazines to create from a carryable magazine for a given weapon. * * Arguments: - * 0: Vehicle + * 0: CSW * 1: Turret * 2: Magazine that is carryable * diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf index 26df08d1ac2..03f8cb86b76 100644 --- a/addons/csw/functions/fnc_reload_loadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -1,10 +1,10 @@ #include "script_component.hpp" /* * Author: PabstMirror - * Loads a magazine into a static weapon from a magazine carried by or next to the player. + * Loads a magazine into a CSW from a magazine carried by or next to the player. * * Arguments: - * 0: Vehicle + * 0: CSW * 1: Turret * 2: Unit Carried Magazine * 3: Magazine source From aa8fff304169b327d8f3d4210f8248a9855b7116 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 13:45:52 +0300 Subject: [PATCH 15/37] fix case sensitivy, move container creation --- .../csw/functions/fnc_compatibleMagazines.sqf | 4 +++- .../fnc_getSourceCompatibleMagazines.sqf | 2 +- addons/csw/functions/fnc_proxyWeapon.sqf | 7 ++++-- .../functions/fnc_reload_handleReturnAmmo.sqf | 16 ++++++++++++- .../fnc_staticWeaponInit_unloadExtraMags.sqf | 24 +------------------ 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/addons/csw/functions/fnc_compatibleMagazines.sqf b/addons/csw/functions/fnc_compatibleMagazines.sqf index d4cfbf7382f..7357becd0c9 100644 --- a/addons/csw/functions/fnc_compatibleMagazines.sqf +++ b/addons/csw/functions/fnc_compatibleMagazines.sqf @@ -18,10 +18,12 @@ */ params [["_csw", objNull, [objNull]]]; -if !(typeOf _csw in GVAR(initializedStaticTypes)) exitWith {createHashMap}; +if !((typeOf _csw) in GVAR(initializedStaticTypes)) exitWith {createHashMap}; // fast exit for csw with single weapon, most common scenario if (count allTurrets _csw isEqualTo 1 && {count weapons _csw isEqualTo 1}) exitWith { + systemChat "has single weapon"; + systemChat str (weapons _csw); GVAR(compatibleMagsCache) get ((weapons _csw) select 0) // return }; diff --git a/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf b/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf index 38e0bde4462..b6786ae128a 100644 --- a/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf +++ b/addons/csw/functions/fnc_getSourceCompatibleMagazines.sqf @@ -13,7 +13,7 @@ * Magazine ammo * * Example: - * [player, cursorObject] call ace_csw_fnc_getSourceCompatibleMagazines + * [backpackContainer player, cursorObject] call ace_csw_fnc_getSourceCompatibleMagazines * * Public: Yes */ diff --git a/addons/csw/functions/fnc_proxyWeapon.sqf b/addons/csw/functions/fnc_proxyWeapon.sqf index 1557ae4fe6c..edd3084238a 100644 --- a/addons/csw/functions/fnc_proxyWeapon.sqf +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -37,11 +37,14 @@ if ((missionNamespace getVariable [_proxyWeapon, objNull]) isEqualType {}) then }; if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); }; +// Config case for hashmap key +_proxyWeapon = configName (configFile >> "CfgWeapons" >> _proxyWeapon); + // Cache compatible magazines -if !(_proxyWeapon in GVAR(compatibleVehicleMagsCache)) then { +if !(_proxyWeapon in GVAR(compatibleMagsCache)) then { private _compatibleMagazines = compatibleMagazines _proxyWeapon; GVAR(compatibleVehicleMagsCache) set [_proxyWeapon, _compatibleMagazines]; - GVAR(compatibleCarryMagsCache) set [_proxyWeapon, (_compatibleMagazines apply {_x call FUNC(getCarryMagazine)}) createHashMapFromArray []]; + GVAR(compatibleMagsCache) set [_proxyWeapon, (_compatibleMagazines apply {_x call FUNC(getCarryMagazine)}) createHashMapFromArray []]; }; TRACE_2("swapping to proxy weapon",_currentWeapon,_proxyWeapon); diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index a661b81710f..b8e4f63b8b6 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -56,8 +56,22 @@ if ((maxLoad _container) isEqualTo 0) then { if (isNull _container) then { // Create ammo storage container + private _containerType = getText (configOf _vehicle >> QUOTE(ADDON) >> "container"); + + // Use setting if container already created or not defined + if (_containerType isEqualTo "" || {!isNull (_vehicle getVariable [QGVAR(container), objNull])}) then { + _containerType = ["GroundWeaponHolder", QGVAR(ammo_holder)] select GVAR(handleExtraMagazinesType); + }; + + _container = createVehicle [_containerType, [0, 0, 0], [], 0, "CAN_COLLIDE"]; + if ((loadAbs _container) isNotEqualTo 0) then { + clearItemCargoGlobal _container; + clearWeaponCargoGlobal _container; + clearBackpackCargoGlobal _container; + clearMagazineCargoGlobal _container; + }; + private _weaponRelPos = (_unloadTo getRelPos RELATIVE_DIRECTION(270)) vectorAdd [0, 0, 0.05]; - _container = createVehicle [["GroundWeaponHolder", QGVAR(ammo_holder)] select GVAR(handleExtraMagazinesType), [0, 0, 0], [], 0, "CAN_COLLIDE"]; _unloadTo setVariable [QGVAR(container), _container, true]; _container setDir random [0, 180, 360]; _container setPosATL _weaponRelPos; diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 75a45dcd764..8709c1c1cd0 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -81,29 +81,7 @@ if (_vehicle getVariable [QGVAR(secondaryWeaponMagazine), ""] isNotEqualTo "") t if (_storeExtraMagazines) then { TRACE_1("saving extra mags to container",_containerMagazineCount); - // Create container from config if available, use setting if not - private _containerType = getText (configOf _vehicle >> QUOTE(ADDON) >> "container"); - if (_containerType isNotEqualTo "") then { - private _relPos = (_vehicle getRelPos RELATIVE_DIRECTION(270)) vectorAdd [0, 0, 0.05]; - _container = createVehicle [_containerType, [0, 0, 0], [], 0, "CAN_COLLIDE"]; - _vehicle setVariable [QGVAR(container), _container, true]; - _container setDir random [0, 180, 360]; - _container setPosATL _relPos; - if ((_relPos select 2) < 0.5) then { - _container setVectorUp (surfaceNormal _relPos); - }; - - // empty container inventory - // TODO: make a function in common? - clearItemCargoGlobal _container; - clearWeaponCargoGlobal _container; - clearMagazineCargoGlobal _container; - clearBackpackCargoGlobal _container; - } else { - _container = _vehicle; - }; - { - [_container, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); + [_vehicle, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); } forEach _containerMagazineClassnames; }; From 4b92ef2ade704a93b25bc0b07838cc67590e4438 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 13:48:11 +0300 Subject: [PATCH 16/37] remove systemChat --- addons/csw/functions/fnc_compatibleMagazines.sqf | 2 -- addons/csw/script_component.hpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/csw/functions/fnc_compatibleMagazines.sqf b/addons/csw/functions/fnc_compatibleMagazines.sqf index 7357becd0c9..2c8e3a090b4 100644 --- a/addons/csw/functions/fnc_compatibleMagazines.sqf +++ b/addons/csw/functions/fnc_compatibleMagazines.sqf @@ -22,8 +22,6 @@ if !((typeOf _csw) in GVAR(initializedStaticTypes)) exitWith {createHashMap}; // fast exit for csw with single weapon, most common scenario if (count allTurrets _csw isEqualTo 1 && {count weapons _csw isEqualTo 1}) exitWith { - systemChat "has single weapon"; - systemChat str (weapons _csw); GVAR(compatibleMagsCache) get ((weapons _csw) select 0) // return }; diff --git a/addons/csw/script_component.hpp b/addons/csw/script_component.hpp index 42b292c17ef..905510555a9 100644 --- a/addons/csw/script_component.hpp +++ b/addons/csw/script_component.hpp @@ -4,7 +4,7 @@ // #define FAST_PROGRESSBARS // #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE +#define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_CSW From e5a9fadcec09ea31e3858c32ba75541132dafaff Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 13:53:50 +0300 Subject: [PATCH 17/37] add check for invalid proxyWeapon --- addons/csw/functions/fnc_proxyWeapon.sqf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/csw/functions/fnc_proxyWeapon.sqf b/addons/csw/functions/fnc_proxyWeapon.sqf index edd3084238a..8771dc8b390 100644 --- a/addons/csw/functions/fnc_proxyWeapon.sqf +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -26,19 +26,20 @@ if (_vehicle getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exit private _proxyWeapon = getText (configOf _vehicle >> "ace_csw" >> "proxyWeapon"); TRACE_2("",typeOf _vehicle,_proxyWeapon); -if (_proxyWeapon == "") exitWith {}; +if (_proxyWeapon isEqualTo "") exitWith {}; private _currentWeapon = (_vehicle weaponsTurret [0]) param [0, "#none"]; if ((missionNamespace getVariable [_proxyWeapon, objNull]) isEqualType {}) then { // check if string is a function TRACE_1("Calling proxyWeapon function",_proxyWeapon); // This function may replace magazines or do other things to the static weapon _proxyWeapon = [_vehicle, _turret, _currentWeapon, _needed, _emptyWeapon] call (missionNamespace getVariable _proxyWeapon); - _needed = _proxyWeapon != ""; + _needed = _proxyWeapon isNotEqualTo "" && {_proxyWeapon isNotEqualTo _currentWeapon}; }; if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); }; // Config case for hashmap key _proxyWeapon = configName (configFile >> "CfgWeapons" >> _proxyWeapon); +if (_proxyWeapon isEqualTo "") exitWith {ERROR_1("proxy weapon non-existent for [%1]", _currentWeapon)} // Cache compatible magazines if !(_proxyWeapon in GVAR(compatibleMagsCache)) then { From ddf1f1149dbd6f6ac9083e0a0687da08daffe5a4 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 13:55:08 +0300 Subject: [PATCH 18/37] remove stupid --- addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf index bf4ed48f643..6b19dcf996f 100644 --- a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf +++ b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf @@ -22,7 +22,7 @@ params ["_mortar", "_turret", "_currentWeapon", "_proxyWeaponNeeded"]; TRACE_4("csw_getProxyWeapon",_mortar,_turret,_currentWeapon,_proxyWeaponNeeded); -private _newWeapon = _currentWeapon; +private _newWeapon = ""; if (GVAR(useAmmoHandling)) then { if (_currentWeapon != "mortar_82mm") exitWith { ERROR_2("unknown weapon [%1 - %2]",typeOf _mortar,_currentWeapon); }; From 17156d54808c1d9de98c2fb0911236ec15a022c0 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 13:56:40 +0300 Subject: [PATCH 19/37] missing semicolon --- addons/csw/functions/fnc_proxyWeapon.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/csw/functions/fnc_proxyWeapon.sqf b/addons/csw/functions/fnc_proxyWeapon.sqf index 8771dc8b390..bd49e3f3ddf 100644 --- a/addons/csw/functions/fnc_proxyWeapon.sqf +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -39,7 +39,7 @@ if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); }; // Config case for hashmap key _proxyWeapon = configName (configFile >> "CfgWeapons" >> _proxyWeapon); -if (_proxyWeapon isEqualTo "") exitWith {ERROR_1("proxy weapon non-existent for [%1]", _currentWeapon)} +if (_proxyWeapon isEqualTo "") exitWith {ERROR_1("proxy weapon non-existent for [%1]", _currentWeapon)}; // Cache compatible magazines if !(_proxyWeapon in GVAR(compatibleMagsCache)) then { From 078857b5a9b12b17d261939199f45710623ffbea Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 14:51:26 +0300 Subject: [PATCH 20/37] add getAvailableAmmo --- addons/csw/XEH_PREP.hpp | 1 + addons/csw/functions/fnc_getAvailableAmmo.sqf | 59 +++++++++++++++++++ addons/csw/functions/fnc_getNearbySources.sqf | 25 +++++--- 3 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 addons/csw/functions/fnc_getAvailableAmmo.sqf diff --git a/addons/csw/XEH_PREP.hpp b/addons/csw/XEH_PREP.hpp index 36e898913a7..cc3545042b2 100644 --- a/addons/csw/XEH_PREP.hpp +++ b/addons/csw/XEH_PREP.hpp @@ -20,6 +20,7 @@ PREP(canGetIn); PREP(getIn); PREP(compatibleMagazines); +PREP(getAvailableAmmo); PREP(getCarryMagazine); PREP(getNearbySources); PREP(getSourceCompatibleMagazines); diff --git a/addons/csw/functions/fnc_getAvailableAmmo.sqf b/addons/csw/functions/fnc_getAvailableAmmo.sqf new file mode 100644 index 00000000000..cd296eebcb0 --- /dev/null +++ b/addons/csw/functions/fnc_getAvailableAmmo.sqf @@ -0,0 +1,59 @@ +#include "script_component.hpp" +/* + * Author: LinkIsGrim + * Gets available ammo for a CSW + * + * Arguments: + * 0: CSW + * 1: Only loaded magazines (default: false) + * 2: Skip ammo from vehicles (default: true) + * 3: Include CSW crew (default: true) + * + * Return Value: + * Available Ammo + * Magazine classname + * Total Ammo + * + * Example: + * [cursorObject] call ace_csw_fnc_getAvailableAmmo + * + * Public: Yes + */ +params [["_vehicle", objNull, [objNull]], ["_onlyLoaded", false, [false]], ["_skipVehicles", true, [true]], ["_includeCrew", true, [true]]]; + +if (isNull _vehicle) exitWith {createHashMap}; + +private _availableMagazines = createHashMap; + +private _fnc_addAmmo = { + params ["_magazine", "_ammo"]; + if !(_magazine in _availableMagazines) then { + _availableMagazines set [_magazine, _ammo]; + } else { + _availableMagazines set [_magazine, (_availableMagazines get _magazine) + _ammo]; + }; +}; + +{ + _x params ["_xMag", "", "_xAmmo"]; + + private _carryMag = _xMag call FUNC(getCarryMagazine); + if (_carryMag isEqualTo "") then {continue}; + + [_carryMag, _xAmmo] call _fnc_addAmmo +} forEach (magazinesAllTurrets _vehicle); + +if (_onlyLoaded) exitWith {_availableMagazines}; + +[QGVAR(clearNearbySourcesCache), []] call CBA_fnc_localEvent; +private _sources = [_vehicle, _skipVehicles, _includeCrew] call FUNC(getNearbySources); +if (_sources isEqualTo []) exitWith {_availableMagazines}; + +{ + private _source = _x; + { + _x call _fnc_addAmmo + } forEach ([_source, _vehicle] call FUNC(getSourceCompatibleMagazines)); +} forEach _sources; + +_availableMagazines // return diff --git a/addons/csw/functions/fnc_getNearbySources.sqf b/addons/csw/functions/fnc_getNearbySources.sqf index 22fd19f045f..4fb98d11175 100644 --- a/addons/csw/functions/fnc_getNearbySources.sqf +++ b/addons/csw/functions/fnc_getNearbySources.sqf @@ -4,7 +4,9 @@ * Gets available ammo sources for loading a CSW * * Arguments: - * 0: Unit attempting to load + * 0: Unit or vehicle attempting to load + * 1: Skip vehicle sources (default: false) + * 2: Include CSW crew (default: false) * * Return Value: * Ammo sources @@ -14,16 +16,25 @@ * * Public: No */ -params ["_unit"]; - -[_unit, { - params ["_unit"]; +[_this, { + params ["_unit", ["_skipVehicles", false], ["_includeCrew", false]]; private _nearSupplies = (_unit nearSupplies 5) select { isNull (group _x) || {!([_x] call EFUNC(common,isPlayer)) && {[side group _unit, side group _x] call BIS_fnc_sideIsFriendly}} }; - _nearSupplies pushBack _unit; + if (_includeCrew) then { + _nearSupplies append (crew _unit); + }; + + if (_skipVehicles) then { + _nearSupplies = _nearSupplies select { + private _source = _x; + (["Ship", "Car", "Air", "Tank"] findIf {_source isKindOf _x}) == -1 + }; + }; + + _nearSupplies pushBackUnique _unit; { if (_x isKindOf "CAManBase") then { _nearSupplies append [uniformContainer _x, vestContainer _x, backpackContainer _x]; @@ -37,4 +48,4 @@ params ["_unit"]; } forEach _nearSupplies; _nearSupplies select {!(_x isKindOf "CAManBase")} // return -}, _unit, QGVAR(nearbySourcesCache), NEARBY_SOURCES_CACHE_EXPIRY, QGVAR(clearNearbySourcesCache)] call EFUNC(common,cachedCall); +}, _this select 0, QGVAR(nearbySourcesCache), NEARBY_SOURCES_CACHE_EXPIRY, QGVAR(clearNearbySourcesCache)] call EFUNC(common,cachedCall); From 6774da03478227153e66988d3fea8ac4d45ddd53 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 17:23:52 +0300 Subject: [PATCH 21/37] fix mk6 mortar? --- .../csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf | 2 +- addons/mk6mortar/CfgWeapons.hpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 092e01f3fef..e51e99e3450 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -19,7 +19,7 @@ params ["_vehicle", "_assemblyMode", "_emptyWeapon"]; TRACE_3("staticWeaponInit_unloadExtraMags",_vehicle,_assemblyMode,_emptyWeapon); if (!_assemblyMode) exitWith {}; -if (_staticWeapon getVariable [QGVAR(disabled), false]) exitWith {}; +if (_vehicle getVariable [QGVAR(disabled), false]) exitWith {}; private _desiredAmmo = getNumber (configOf _vehicle >> QUOTE(ADDON) >> "desiredAmmo"); private _storeExtraMagazines = GVAR(handleExtraMagazines); diff --git a/addons/mk6mortar/CfgWeapons.hpp b/addons/mk6mortar/CfgWeapons.hpp index 3e247910fbf..1c242b29c79 100644 --- a/addons/mk6mortar/CfgWeapons.hpp +++ b/addons/mk6mortar/CfgWeapons.hpp @@ -16,16 +16,19 @@ class CfgWeapons { class CannonCore; class mortar_82mm: CannonCore { class Single1; + class Burst1; // need this for doArtilleryFire to work }; class ACE_mortar_82mm: mortar_82mm { author = ECSTRING(common,ACETeam); magazines[] = {"ACE_1Rnd_82mm_Mo_HE","ACE_1Rnd_82mm_Mo_Smoke","ACE_1Rnd_82mm_Mo_Illum", "ACE_1Rnd_82mm_Mo_HE_Guided","ACE_1Rnd_82mm_Mo_HE_LaserGuided"}; - modes[] = {"Single1","Single2","Single3"}; reloadTime = 0.5; magazineReloadTime = 0.5; class Single1: Single1 { reloadTime = 0.5; }; + class Burst1: Burst1 { + reloadTime = 0.5; + }; }; }; From 1be677da8ff86c199641d7321c2db68a2bfbb1eb Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 17:31:54 +0300 Subject: [PATCH 22/37] add disabled check --- addons/artillerytables/functions/fnc_doArtilleryFire.sqf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf index 31d204405d4..249aaa3fd79 100644 --- a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf +++ b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf @@ -35,8 +35,9 @@ if (["ace_mk6mortar"] call EFUNC(common,isModLoaded) && {_vehicle isKindOf "Stat _usingCSW = EGVAR(mk6mortar,useAmmoHandling); }; -if (_usingCSW && {EGVAR(csw,ammoHandling) < 2}) exitWith {false}; +_usingCSW = _usingCSW && {!(_vehicle getVariable [QEGVAR(csw,disabled), false])}; +if (_usingCSW && {EGVAR(csw,ammoHandling) < 2}) exitWith {false}; if (_usingCSW) then { private _isCarryMag = isClass (configFile >> QEGVAR(csw,groups) >> _magazine); From 73bc33170179e6f8fb7e5b45d527ae9f567a8b7d Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 19:52:56 +0300 Subject: [PATCH 23/37] function header --- addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf index 5eb32479b3d..56f94619803 100644 --- a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf @@ -7,7 +7,7 @@ * Arguments: * 0: CSW * 1: Turret Path - * 2: Magainze Unit Can Carry + * 2: Magazine Unit Can Carry * 3: Magazine To Remove From Static * 4: Unit or container to unload to * From cafe1f40e83658528208b314dc261f73a4bfb64b Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 19:53:10 +0300 Subject: [PATCH 24/37] compile cache --- addons/csw/script_component.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/csw/script_component.hpp b/addons/csw/script_component.hpp index 905510555a9..42b292c17ef 100644 --- a/addons/csw/script_component.hpp +++ b/addons/csw/script_component.hpp @@ -4,7 +4,7 @@ // #define FAST_PROGRESSBARS // #define DEBUG_MODE_FULL -#define DISABLE_COMPILE_CACHE +// #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_CSW From 76471236836b7db8ad9a3e9289707ea0538d93f5 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 19:53:57 +0300 Subject: [PATCH 25/37] add forcedMag and ai_unloadMagazines --- addons/csw/XEH_PREP.hpp | 1 + addons/csw/functions/fnc_ai_reload.sqf | 22 +++++++--- .../csw/functions/fnc_ai_unloadMagazines.sqf | 43 +++++++++++++++++++ 3 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 addons/csw/functions/fnc_ai_unloadMagazines.sqf diff --git a/addons/csw/XEH_PREP.hpp b/addons/csw/XEH_PREP.hpp index cc3545042b2..7985e2aff98 100644 --- a/addons/csw/XEH_PREP.hpp +++ b/addons/csw/XEH_PREP.hpp @@ -5,6 +5,7 @@ PREP(aceRearmGetCarryMagazines); PREP(ai_handleFired); PREP(ai_handleGetIn); PREP(ai_reload); +PREP(ai_unloadMagazines); PREP(assemble_canDeployTripod); PREP(assemble_canDeployWeapon); diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index b3429c11674..3b53d3c71c1 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -6,38 +6,50 @@ * Arguments: * 0: CSW * 1: Gunner - * 2: Weapon + * 2: Skip reload time (default: false) * * Return Value: * None * * Public: No */ -params ["_vehicle", "_gunner", "_weapon"]; -TRACE_3("AI reload",_vehicle,_gunner,_weapon); +params ["_vehicle", "_gunner", ["_instantReload", false]]; +TRACE_3("AI reload",_vehicle,_gunner,_instantReload); private _loadableMagazines = [_vehicle, _gunner, true] call FUNC(reload_getLoadableMagazines); if (_loadableMagazines isEqualTo []) exitWith {TRACE_1("could not find reloadable mag",_vehicle)}; +// API, to be used by artillerytables +private _forcedMag = _vehicle getVariable [QGVAR(forcedMag), ""]; + +// If this is called while CSW has ammo, unload mags in gunner's turret +if (someAmmo _vehicle) then {[_vehicle, _gunner, [_gunner] call EFUNC(common,getTurretIndex)] call FUNC(ai_unloadMagazine)}; + private _bestAmmo = 0; private _magazineInfo = []; { - _x params ["", "", "", "", "", "_ammo"]; + _x params ["_xMag", "", "", "", "", "_ammo"]; + if (_forcedMag isNotEqualTo "" && {_xMag != _forcedMag}) then {continue}; if (_ammo > _bestAmmo) then { _bestAmmo = _ammo; _magazineInfo = _x; }; } forEach _loadableMagazines; +if (_magazineInfo isEqualTo []) exitWith {}; _magazineInfo params ["_carryMag", "_turretPath", "_loadInfo", "_magSource", "", "_ammo"]; // Remove the mag from the source [_magSource, _carryMag, _ammo] call EFUNC(common,removeSpecificMagazine); -// see fnc_reload_loadMagazine #L54 // AI never returns ammo and removes the magazine before reloading, so we can skip distance and weaponHolder checks private _eventParams = [_vehicle, _turretPath, objNull, _carryMag, _ammo, _gunner]; +if (_instantReload) exitWith { + TRACE_1("calling addTurretMag event: instant AI reload",_this); + [QGVAR(addTurretMag), _eventParams] call CBA_fnc_globalEvent; +}; + private _timeToLoad = GET_NUMBER(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime", 1); TRACE_1("Reloading in progress",_timeToLoad); diff --git a/addons/csw/functions/fnc_ai_unloadMagazines.sqf b/addons/csw/functions/fnc_ai_unloadMagazines.sqf new file mode 100644 index 00000000000..544944dd595 --- /dev/null +++ b/addons/csw/functions/fnc_ai_unloadMagazines.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * Author: LinkIsGrim + * Switch loaded magazine on an AI CSW + * + * Arguments: + * 0: CSW + * 1: Gunner + * 2: Turret Path + * + * Return Value: + * None + * + * Public: No + */ +params ["_vehicle", "_gunner", "_turretPath"]; + +private _magsToRemove = []; +private _containerMagazineClassnames = []; +private _containerMagazineCount = []; + +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + if (_xTurret isNotEqualTo _turretPath) then {continue}; + private _carryMag = _xMag call FUNC(getCarryMagazine); + if (_carryMag != "") then { + _magsToRemove pushBackUnique [_xMag, _xTurret]; + private _index = _containerMagazineClassnames find _carryMag; + if (_index < 0) then { + _index = _containerMagazineClassnames pushBack _carryMag; + _containerMagazineCount pushBack 0; + }; + _containerMagazineCount set [_index, (_containerMagazineCount select _index) + _xAmmo]; + }; +} forEach (_vehicle magazinesAllTurrets _vehicle); + +{ + _vehicle removeMagazinesTurret _x; +} forEach _magsToRemove; + +{ + [_vehicle, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); +} forEach _containerMagazineClassnames; From 4e8c69e08a7b4a70715cfa08328faed4a11075fd Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 20:01:33 +0300 Subject: [PATCH 26/37] make public --- addons/csw/XEH_PREP.hpp | 2 +- addons/csw/functions/fnc_ai_reload.sqf | 2 +- ...dMagazines.sqf => fnc_unloadMagazines.sqf} | 25 ++++++++++++------- 3 files changed, 18 insertions(+), 11 deletions(-) rename addons/csw/functions/{fnc_ai_unloadMagazines.sqf => fnc_unloadMagazines.sqf} (60%) diff --git a/addons/csw/XEH_PREP.hpp b/addons/csw/XEH_PREP.hpp index 7985e2aff98..27e6b6f90bc 100644 --- a/addons/csw/XEH_PREP.hpp +++ b/addons/csw/XEH_PREP.hpp @@ -5,7 +5,6 @@ PREP(aceRearmGetCarryMagazines); PREP(ai_handleFired); PREP(ai_handleGetIn); PREP(ai_reload); -PREP(ai_unloadMagazines); PREP(assemble_canDeployTripod); PREP(assemble_canDeployWeapon); @@ -37,6 +36,7 @@ PREP(reload_handleAddTurretMag); PREP(reload_handleRemoveTurretMag); PREP(reload_handleReturnAmmo); PREP(reload_loadMagazine); +PREP(unloadMagazines); PREP(staticWeaponInit); PREP(staticWeaponInit_unloadExtraMags); diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index 3b53d3c71c1..4f4c066381d 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -23,7 +23,7 @@ if (_loadableMagazines isEqualTo []) exitWith {TRACE_1("could not find reloadabl private _forcedMag = _vehicle getVariable [QGVAR(forcedMag), ""]; // If this is called while CSW has ammo, unload mags in gunner's turret -if (someAmmo _vehicle) then {[_vehicle, _gunner, [_gunner] call EFUNC(common,getTurretIndex)] call FUNC(ai_unloadMagazine)}; +if (someAmmo _vehicle) then {[_vehicle, [_gunner] call EFUNC(common,getTurretIndex)] call FUNC(unloadMagazines)}; private _bestAmmo = 0; private _magazineInfo = []; diff --git a/addons/csw/functions/fnc_ai_unloadMagazines.sqf b/addons/csw/functions/fnc_unloadMagazines.sqf similarity index 60% rename from addons/csw/functions/fnc_ai_unloadMagazines.sqf rename to addons/csw/functions/fnc_unloadMagazines.sqf index 544944dd595..7e1fbffb193 100644 --- a/addons/csw/functions/fnc_ai_unloadMagazines.sqf +++ b/addons/csw/functions/fnc_unloadMagazines.sqf @@ -1,19 +1,24 @@ #include "script_component.hpp" /* * Author: LinkIsGrim - * Switch loaded magazine on an AI CSW + * Unloads and returns magazines from a CSW * * Arguments: - * 0: CSW - * 1: Gunner - * 2: Turret Path + * 0: CSW (default: objNull) + * 1: Turret Path (default: [0], gunner turret) + * 2: Return removed magazines (default: true) * * Return Value: * None * - * Public: No + * Example: + * [cursorTarget, [0]] call ace_csw_fnc_unloadMagazines + * + * Public: Yes */ -params ["_vehicle", "_gunner", "_turretPath"]; +params [["_vehicle", objNull, [objNull]], ["_turretPath", [0], [0]], ["_returnMags", true, [true]]]; + +if (isNull _vehicle) exitWith {}; private _magsToRemove = []; private _containerMagazineClassnames = []; @@ -38,6 +43,8 @@ private _containerMagazineCount = []; _vehicle removeMagazinesTurret _x; } forEach _magsToRemove; -{ - [_vehicle, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); -} forEach _containerMagazineClassnames; +if (_returnMags) then { + { + [_vehicle, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo); + } forEach _containerMagazineClassnames; +}; From c3909b696cfbae0695ac66966acde644ea407632 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 23:19:11 +0300 Subject: [PATCH 27/37] doArtilleryFire --- .../functions/fnc_doArtilleryFire.sqf | 37 ++++++++++++++----- .../functions/fnc_doArtilleryFirePFEH.sqf | 5 ++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf index 249aaa3fd79..7c86bda9637 100644 --- a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf +++ b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf @@ -6,7 +6,7 @@ * * Arguments: * 0: Vehicle - * 1: Target Position (AGL) + * 1: Target * 2: Magazine Type * 3: Rounds to fire * @@ -18,13 +18,13 @@ * * Public: Yes */ -params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[]]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; +params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; -if (isNull _vehicle || {_rounds isEqualTo 0} || {_magazine isEqualTo ""}) exitWith {false}; +if (isNull _vehicle || {_rounds isEqualTo 0} || {_magazine isEqualTo ""} || {!(_vehicle turretLocal [0])}) exitWith {false}; -// Needs to be config case -_magazine = configName (configFile >> "CfgMagazines" >> _magazine); -if (_magazine isEqualTo "") exitWith {false}; +if (_position isEqualType objNull) then { + _position = getPos _objNull; +}; private _usingCSW = false; if (["ace_csw"] call EFUNC(common,isModLoaded)) then { @@ -39,16 +39,33 @@ _usingCSW = _usingCSW && {!(_vehicle getVariable [QEGVAR(csw,disabled), false])} if (_usingCSW && {EGVAR(csw,ammoHandling) < 2}) exitWith {false}; +private _vehicleMagazine = _magazine; if (_usingCSW) then { private _isCarryMag = isClass (configFile >> QEGVAR(csw,groups) >> _magazine); - if (isCarryMag) then { + if (_isCarryMag) then { _vehicle setVariable [QEGVAR(csw,forcedMag), _magazine, true]; - _magazine = [_vehicle, [0], _magazine] call EFUNC(csw,reload_getVehicleMagazine); + _vehicleMagazine = [_vehicle, [0], _magazine] call EFUNC(csw,reload_getVehicleMagazine); + } else { + _vehicle setVariable [QEGVAR(csw,forcedMag), [_magazine] call EFUNC(csw,getCarryMagazine), true]; + }; + + if !(_vehicleMagazine in (getArtilleryAmmo [_vehicle])) then { + // TODO: use public functions for this + private _currentMagazine = currentMagazine _vehicle; + private _currentCarryMagazine = [_currentMagazine] call EFUNC(csw,getCarryMagazine); + [_vehicle, [0], _currentCarryMagazine, _currentMagazine, _vehicle] call EFUNC(csw,reload_handleRemoveTurretMag); + [_vehicle, gunner _vehicle, "", true] call EFUNC(csw,ai_reload); }; }; -if ((_vehicle getArtilleryETA [_position, _magazine]) isEqualTo -1) exitWith {false}; +// Needs to be config case +_vehicleMagazine = configName (configFile >> "CfgMagazines" >> _vehicleMagazine); +if (_vehicleMagazine isEqualTo "") exitWith {false}; + +if ((_vehicle getArtilleryETA [_position, _vehicleMagazine]) isEqualTo -1) exitWith {false}; + +_vehicle doWatch _position; -[LINKFUNC(doArtilleryFirePFEH), 0, [_vehicle, _position, _magazine, _rounds, _usingCSW, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(doArtilleryFirePFEH), 0, [_vehicle, _position, _vehicleMagazine, _rounds, _usingCSW, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; true diff --git a/addons/artillerytables/functions/fnc_doArtilleryFirePFEH.sqf b/addons/artillerytables/functions/fnc_doArtilleryFirePFEH.sqf index 72447ae562b..09cd66b95f0 100644 --- a/addons/artillerytables/functions/fnc_doArtilleryFirePFEH.sqf +++ b/addons/artillerytables/functions/fnc_doArtilleryFirePFEH.sqf @@ -24,13 +24,16 @@ _args params ["_vehicle", "_position", "_magazine", "_roundsLeft", "_usingCSW", // Exit on timeout or rounds complete if (CBA_missionTime - _lastFired >= 30 || {_roundsLeft isEqualTo 0}) exitWith { + [{_this doWatch objNull}, _vehicle, 5] call CBA_fnc_waitAndExecute; _vehicle setVariable [QEGVAR(csw,forcedMag), nil, true]; [_id] call CBA_fnc_removePerFrameHandler; }; (weaponState [_vehicle, [0]]) params ["", "", "", "", "_ammoCount", "_roundReloadPhase", "_magazineReloadPhase"]; -if (_ammoCount > 0 && {_roundReloadPhase isEqualTo 0} && {_magazineReloadPhase isEqualTo 0}) exitWith { +if !(unitReady (gunner _vehicle) && {_roundReloadPhase isEqualTo 0} && {_magazineReloadPhase isEqualTo 0}) exitWith {}; + +if (_ammoCount > 0) exitWith { _vehicle doArtilleryFire [_position, _magazine, 1]; _args set [3, _roundsLeft - 1]; _args set [6, CBA_missionTime]; From 676924f139a44a8d1c4512761704596e98ff4d11 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 23:41:47 +0300 Subject: [PATCH 28/37] better loop --- addons/artillerytables/XEH_PREP.hpp | 1 - .../functions/fnc_doArtilleryFire.sqf | 43 +++++++++++++------ .../functions/fnc_doArtilleryFirePFEH.sqf | 40 ----------------- 3 files changed, 30 insertions(+), 54 deletions(-) delete mode 100644 addons/artillerytables/functions/fnc_doArtilleryFirePFEH.sqf diff --git a/addons/artillerytables/XEH_PREP.hpp b/addons/artillerytables/XEH_PREP.hpp index d6f8f3b42a7..14a737c14f3 100644 --- a/addons/artillerytables/XEH_PREP.hpp +++ b/addons/artillerytables/XEH_PREP.hpp @@ -1,7 +1,6 @@ TRACE_1("prep",_this); PREP(doArtilleryFire); -PREP(doArtilleryFirePFEH); PREP(firedEH); PREP(interactMenuOpened); PREP(rangeTableOpen); diff --git a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf index 7c86bda9637..a4eb3a7a020 100644 --- a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf +++ b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf @@ -1,14 +1,15 @@ #include "script_component.hpp" /* - * Author: LinkIsGrim + * Author: LinkIsGrim, mharris001 * Wrapper for engine doArtilleryFire, fires barrage one round at a time. * Handles CSW magazines. * * Arguments: * 0: Vehicle * 1: Target - * 2: Magazine Type - * 3: Rounds to fire + * 2: Spread in meters + * 3: Magazine Type + * 4: Rounds to fire * * Return Value: * Barrage Started @@ -18,7 +19,7 @@ * * Public: Yes */ -params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; +params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull]], ["_spread", 0, [0]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; if (isNull _vehicle || {_rounds isEqualTo 0} || {_magazine isEqualTo ""} || {!(_vehicle turretLocal [0])}) exitWith {false}; @@ -27,16 +28,16 @@ if (_position isEqualType objNull) then { }; private _usingCSW = false; -if (["ace_csw"] call EFUNC(common,isModLoaded)) then { - _usingCSW = EGVAR(csw,ammoHandling) > 0; -}; - -if (["ace_mk6mortar"] call EFUNC(common,isModLoaded) && {_vehicle isKindOf "StaticMortar"}) then { - _usingCSW = EGVAR(mk6mortar,useAmmoHandling); +if ((typeOf _vehicle) in GVAR(initializedStaticTypes)) then { + if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + _usingCSW = EGVAR(csw,ammoHandling) > 0; + }; + if (["ace_mk6mortar"] call EFUNC(common,isModLoaded) && {_vehicle isKindOf "StaticMortar"}) then { + _usingCSW = EGVAR(mk6mortar,useAmmoHandling); + }; + _usingCSW = _usingCSW && {_vehicle getVariable [QEGVAR(csw,assemblyMode), 3] isNotEqualTo 0} }; -_usingCSW = _usingCSW && {!(_vehicle getVariable [QEGVAR(csw,disabled), false])}; - if (_usingCSW && {EGVAR(csw,ammoHandling) < 2}) exitWith {false}; private _vehicleMagazine = _magazine; @@ -66,6 +67,22 @@ if ((_vehicle getArtilleryETA [_position, _vehicleMagazine]) isEqualTo -1) exitW _vehicle doWatch _position; -[LINKFUNC(doArtilleryFirePFEH), 0, [_vehicle, _position, _vehicleMagazine, _rounds, _usingCSW, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; +[{ + params ["_vehicle", "_position", "_spread", "_magazine", "_roundsLeft", "_lastFired"]; + if (CBA_missionTime - _lastFired > 30) exitWith {true}; + + if (unitReady _vehicle) then { + _vehicle doArtilleryFire [[_position, _spread] call CBA_fnc_randPos, _magazine, 1]; + _this set [4, _roundsLeft - 1]; + _this set [5, CBA_missionTime]; + }; + + if (_rounds <= 0 || {!alive _vehicle} || {!alive (gunner _vehicle)}) exitWith { + [{_this doWatch objNull}, _vehicle, 5] call CBA_fnc_waitAndExecute; + _vehicle setVariable [QEGVAR(csw,forcedMag), nil, true]; + true + }; + false +}, {}, [_vehicle, _position, _spread, _vehicleMagazine, _rounds, CBA_missionTime]] call CBA_fnc_waitUntilAndExecute; true diff --git a/addons/artillerytables/functions/fnc_doArtilleryFirePFEH.sqf b/addons/artillerytables/functions/fnc_doArtilleryFirePFEH.sqf deleted file mode 100644 index 09cd66b95f0..00000000000 --- a/addons/artillerytables/functions/fnc_doArtilleryFirePFEH.sqf +++ /dev/null @@ -1,40 +0,0 @@ -#include "script_component.hpp" -/* - * Author: LinkIsGrim - * PFEH for FUNC(doArtilleryFire). Handles reloading and weapon downtime. - * - * Arguments: - * 0: Vehicle - * 1: Target Position (AGL) - * 2: Magazine Type - * 3: Rounds left - * 4: Vehicle uses CSW - * 5: Time of last round fired - * - * Return Value: - * None - * - * Example: - * [cursorObject] call ace_artillerytables_fnc_doArtilleryFire - * - * Public: No - */ -params ["_args", "_id"]; -_args params ["_vehicle", "_position", "_magazine", "_roundsLeft", "_usingCSW", "_lastFired"]; - -// Exit on timeout or rounds complete -if (CBA_missionTime - _lastFired >= 30 || {_roundsLeft isEqualTo 0}) exitWith { - [{_this doWatch objNull}, _vehicle, 5] call CBA_fnc_waitAndExecute; - _vehicle setVariable [QEGVAR(csw,forcedMag), nil, true]; - [_id] call CBA_fnc_removePerFrameHandler; -}; - -(weaponState [_vehicle, [0]]) params ["", "", "", "", "_ammoCount", "_roundReloadPhase", "_magazineReloadPhase"]; - -if !(unitReady (gunner _vehicle) && {_roundReloadPhase isEqualTo 0} && {_magazineReloadPhase isEqualTo 0}) exitWith {}; - -if (_ammoCount > 0) exitWith { - _vehicle doArtilleryFire [_position, _magazine, 1]; - _args set [3, _roundsLeft - 1]; - _args set [6, CBA_missionTime]; -}; From cbb9312fe2b7624fa810ca9f1b06e41ca7fd96aa Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 23:49:48 +0300 Subject: [PATCH 29/37] add mapgrid pos --- .../artillerytables/functions/fnc_doArtilleryFire.sqf | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf index a4eb3a7a020..f041efa26d7 100644 --- a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf +++ b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf @@ -6,7 +6,7 @@ * * Arguments: * 0: Vehicle - * 1: Target + * 1: Target * 2: Spread in meters * 3: Magazine Type * 4: Rounds to fire @@ -19,12 +19,16 @@ * * Public: Yes */ -params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull]], ["_spread", 0, [0]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; +params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull, ""], 3], ["_spread", 0, [0]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; if (isNull _vehicle || {_rounds isEqualTo 0} || {_magazine isEqualTo ""} || {!(_vehicle turretLocal [0])}) exitWith {false}; if (_position isEqualType objNull) then { - _position = getPos _objNull; + _position = ASLtoAGL getPosASL _position; +}; + +if (_position isEqualType "") then { + _position = [_position, true] call CBA_fnc_mapGridToPos; }; private _usingCSW = false; From 354ab78b5fd745cf1cbe2b14667210eb4b3395a7 Mon Sep 17 00:00:00 2001 From: Salluci Date: Sun, 2 Jul 2023 22:10:22 +0300 Subject: [PATCH 30/37] add csw override --- .../csw/functions/fnc_reload_actionsLoad.sqf | 3 ++- .../functions/fnc_reload_actionsUnload.sqf | 3 ++- .../fnc_staticWeaponInit_unloadExtraMags.sqf | 1 + addons/mk6mortar/XEH_preInit.sqf | 13 +++++++++++ .../functions/fnc_csw_getProxyWeapon.sqf | 22 +++++-------------- addons/mk6mortar/stringtable.xml | 16 ++------------ .../crew-served-weapons-framework.md | 11 ++++++++++ 7 files changed, 37 insertions(+), 32 deletions(-) diff --git a/addons/csw/functions/fnc_reload_actionsLoad.sqf b/addons/csw/functions/fnc_reload_actionsLoad.sqf index 7a1f49980e2..70f29830d2c 100644 --- a/addons/csw/functions/fnc_reload_actionsLoad.sqf +++ b/addons/csw/functions/fnc_reload_actionsLoad.sqf @@ -32,7 +32,8 @@ private _condition = { params ["_target", "_player", "_params"]; _params params ["_carryMag", "_turretPath", "", "_magSource"]; - ([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0 + !(_target getVariable [QGVAR(disabled), false]) && + {([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0} }; private _cfgMagazines = configFile >> "CfgMagazines"; // micro-optimization diff --git a/addons/csw/functions/fnc_reload_actionsUnload.sqf b/addons/csw/functions/fnc_reload_actionsUnload.sqf index 118072b8c26..585cbf96e22 100644 --- a/addons/csw/functions/fnc_reload_actionsUnload.sqf +++ b/addons/csw/functions/fnc_reload_actionsUnload.sqf @@ -46,7 +46,8 @@ private _statement = { private _condition = { params ["_target", "_player", "_params"]; _params params ["_vehMag", "_turretPath", "_carryMag"]; - [_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine) + !(_target getVariable [QGVAR(disabled), false]) && + {[_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine)} }; private _actions = []; diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 8709c1c1cd0..092e01f3fef 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -19,6 +19,7 @@ params ["_vehicle", "_assemblyMode", "_emptyWeapon"]; TRACE_3("staticWeaponInit_unloadExtraMags",_vehicle,_assemblyMode,_emptyWeapon); if (!_assemblyMode) exitWith {}; +if (_staticWeapon getVariable [QGVAR(disabled), false]) exitWith {}; private _desiredAmmo = getNumber (configOf _vehicle >> QUOTE(ADDON) >> "desiredAmmo"); private _storeExtraMagazines = GVAR(handleExtraMagazines); diff --git a/addons/mk6mortar/XEH_preInit.sqf b/addons/mk6mortar/XEH_preInit.sqf index 9361d05015e..100217ffe4e 100644 --- a/addons/mk6mortar/XEH_preInit.sqf +++ b/addons/mk6mortar/XEH_preInit.sqf @@ -8,4 +8,17 @@ PREP_RECOMPILE_END; #include "initSettings.sqf" +["Mortar_01_base_F", "Init", { // override CSW's ammo handling with Mk6 setting + params ["_mortar"]; + _mortar setVariable [QEGVAR(csw,disabled), !GVAR(useAmmoHandling)]; +}] call CBA_fnc_addClassEventHandler; + +GVAR(ammoHandlingMagazineReplacement) = createHashMapFromArray [ + ["8Rnd_82mm_Mo_shells", "ACE_1Rnd_82mm_Mo_HE"], + ["8Rnd_82mm_Mo_Smoke_white", "ACE_1Rnd_82mm_Mo_Smoke"], + ["8Rnd_82mm_Mo_Flare_white", "ACE_1Rnd_82mm_Mo_Illum"], + ["8Rnd_82mm_Mo_guided", "ACE_1Rnd_82mm_Mo_HE_Guided"], + ["8Rnd_82mm_Mo_LG", "ACE_1Rnd_82mm_Mo_HE_LaserGuided"] +]; + ADDON = true; diff --git a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf index fd4804b98f6..bf4ed48f643 100644 --- a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf +++ b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf @@ -22,9 +22,9 @@ params ["_mortar", "_turret", "_currentWeapon", "_proxyWeaponNeeded"]; TRACE_4("csw_getProxyWeapon",_mortar,_turret,_currentWeapon,_proxyWeaponNeeded); -private _newWeapon = ""; +private _newWeapon = _currentWeapon; -if (_proxyWeaponNeeded || GVAR(useAmmoHandling)) then { +if (GVAR(useAmmoHandling)) then { if (_currentWeapon != "mortar_82mm") exitWith { ERROR_2("unknown weapon [%1 - %2]",typeOf _mortar,_currentWeapon); }; // Replace weapon with fast reloading version @@ -36,23 +36,13 @@ if (_proxyWeaponNeeded || GVAR(useAmmoHandling)) then { private _convertedMags = []; { _x params ["_xMag", "_xTurret", "_xAmmo"]; - if (_xTurret isEqualTo _turret) then { - private _replaceMag = switch (true) do { - case (_xMag == "8Rnd_82mm_Mo_shells"): {"ACE_1Rnd_82mm_Mo_HE"}; - case (_xMag == "8Rnd_82mm_Mo_Smoke_white"): {"ACE_1Rnd_82mm_Mo_Smoke"}; - case (_xMag == "8Rnd_82mm_Mo_Flare_white"): {"ACE_1Rnd_82mm_Mo_Illum"}; - case (_xMag == "8Rnd_82mm_Mo_guided"): {"ACE_1Rnd_82mm_Mo_HE_Guided"}; - case (_xMag == "8Rnd_82mm_Mo_LG"): {"ACE_1Rnd_82mm_Mo_HE_LaserGuided"}; - default {""}; - }; + private _replaceMag = GVAR(ammoHandlingMagazineReplacement) getOrDefault [_xMag, ""]; if (_replaceMag != "") then { _magsToRemove pushBackUnique [_xMag, _xTurret]; - if (!GVAR(useAmmoHandling)) then { - TRACE_3("replacing",_xMag,_replaceMag,_xAmmo); - for "_i" from 1 to _xAmmo do { - _convertedMags pushBack [_replaceMag, _xTurret, 1]; - }; + TRACE_3("replacing",_xMag,_replaceMag,_xAmmo); + for "_i" from 1 to _xAmmo do { + _convertedMags pushBack [_replaceMag, _xTurret, 1]; }; } else { WARNING_1("unknown mag %1", _xMag); diff --git a/addons/mk6mortar/stringtable.xml b/addons/mk6mortar/stringtable.xml index 464d6543462..26ef489f5e9 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -218,7 +218,7 @@ 這個模塊允許你設定MK6迫擊砲的相關功能 - Use Ammunition handling + Use Ammunition Handling Aktiviere Munitionshandhabung Usar manejo de munición. Aktywuj obsługę amunicji @@ -233,19 +233,7 @@ Používat ruční manipulaci s municí - Removes mortar magazines, requiring individual rounds to be loaded by the gunner or loader. Does not affect AI mortars. - Enfernt das Magzin des Mörsers. Es ist nun erforderlich, die einzelnen Patronen manuell zu laden. Dies beeinflusst nicht die KI-Truppen. - Elimina los cargadores del mortero, requiriendo al artillero o cargador la carga manual de cada rondas. No afecta morteros controlados por IA. - Usuwa magazynki moździerza, wymagając ładowania pojedynczych pocisków przez strzelca lub ładowniczego. Nie dotyczy moździerzy AI. - Enlève les chargeurs de mortier, ce qui oblige le tireur ou le servant à charger les obus manuellement. N'affecte pas les mortiers IA. - Toglie i proiettili dal mortaio. I colpi singoli devono essere caricati dall'operatore. Non cambia quado l'IA spara. - Elimina os carregadores do morteiro, requerendo que o atirador ou carregador utilize de forma individual a munição. Não afeta os morteiros controlados pela IA. - Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжающим. Не влияет на артиллерию ИИ. - 迫撃砲から弾薬を除去します。射手か装填手により予め装填されている必要があります。AI 迫撃砲へ影響を与えません。 - 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야 합니다. 인공지능은 영향을 받지 않습니다. - 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填。此功能并不影响由 AI 射击的迫击炮 - 開啟此功能時。迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填。此功能並不影響由AI射擊的迫擊砲 - Odstraní z minometu zásobník a vynucuje nabíjení po každém výstřelu buď mířičem nebo nabíječem. Tato možnost neovlivňuje AI posádky. + Converts mortar magazines into their single round versions, requiring individual rounds to be loaded by the crew.\nOverrides Crew Served Weapon's Ammo Handling. Remove Round diff --git a/docs/wiki/framework/crew-served-weapons-framework.md b/docs/wiki/framework/crew-served-weapons-framework.md index 2d2d19b4ae1..d0faa7d9478 100644 --- a/docs/wiki/framework/crew-served-weapons-framework.md +++ b/docs/wiki/framework/crew-served-weapons-framework.md @@ -151,6 +151,17 @@ class CfgVehicles { }; ``` +### 1.5 Custom Ammo Handling + +ACE's ammo handling (including AI reloading, and initial unloading and conversion of the weapon's magazines) can be blocked by setting the `ace_csw_disabled` variable on init. +This will also block reloading and unloading the weapon manually through ACE. +This variable needs to be set where the weapon is local. + +```sqf +myCustomStaticWeapon = createVehicle ["B_Mortar_01_F", [0, 0, 0]]; +myCustomStaticWeapon setVariable ["ace_csw_disabled", true, true]; // blocks ammo handling +``` + ## 2. Making a new Tripod If none of the existing ACE tripods fit your weapon, you can create your own. Creating a tripod is similar to creating a crew served weapon and consists of two parts: From 8636c072c80ababd01f01d69c6d781f41b992a5f Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Mon, 3 Jul 2023 04:26:03 +0300 Subject: [PATCH 31/37] Update docs/wiki/framework/crew-served-weapons-framework.md --- docs/wiki/framework/crew-served-weapons-framework.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/wiki/framework/crew-served-weapons-framework.md b/docs/wiki/framework/crew-served-weapons-framework.md index d0faa7d9478..22d84af5fd0 100644 --- a/docs/wiki/framework/crew-served-weapons-framework.md +++ b/docs/wiki/framework/crew-served-weapons-framework.md @@ -155,7 +155,7 @@ class CfgVehicles { ACE's ammo handling (including AI reloading, and initial unloading and conversion of the weapon's magazines) can be blocked by setting the `ace_csw_disabled` variable on init. This will also block reloading and unloading the weapon manually through ACE. -This variable needs to be set where the weapon is local. +This variable needs to be set globally. ```sqf myCustomStaticWeapon = createVehicle ["B_Mortar_01_F", [0, 0, 0]]; From ef90520280c2d4be8f56a36f88a6cbf2dd14f2ff Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 13:55:08 +0300 Subject: [PATCH 32/37] remove stupid --- addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf index bf4ed48f643..6b19dcf996f 100644 --- a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf +++ b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf @@ -22,7 +22,7 @@ params ["_mortar", "_turret", "_currentWeapon", "_proxyWeaponNeeded"]; TRACE_4("csw_getProxyWeapon",_mortar,_turret,_currentWeapon,_proxyWeaponNeeded); -private _newWeapon = _currentWeapon; +private _newWeapon = ""; if (GVAR(useAmmoHandling)) then { if (_currentWeapon != "mortar_82mm") exitWith { ERROR_2("unknown weapon [%1 - %2]",typeOf _mortar,_currentWeapon); }; From 64b681766a9f61da2a96c06fd7d8503691ad4ece Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 17:23:52 +0300 Subject: [PATCH 33/37] fix mk6 mortar? --- .../csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf | 2 +- addons/mk6mortar/CfgWeapons.hpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 092e01f3fef..e51e99e3450 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -19,7 +19,7 @@ params ["_vehicle", "_assemblyMode", "_emptyWeapon"]; TRACE_3("staticWeaponInit_unloadExtraMags",_vehicle,_assemblyMode,_emptyWeapon); if (!_assemblyMode) exitWith {}; -if (_staticWeapon getVariable [QGVAR(disabled), false]) exitWith {}; +if (_vehicle getVariable [QGVAR(disabled), false]) exitWith {}; private _desiredAmmo = getNumber (configOf _vehicle >> QUOTE(ADDON) >> "desiredAmmo"); private _storeExtraMagazines = GVAR(handleExtraMagazines); diff --git a/addons/mk6mortar/CfgWeapons.hpp b/addons/mk6mortar/CfgWeapons.hpp index 3e247910fbf..1c242b29c79 100644 --- a/addons/mk6mortar/CfgWeapons.hpp +++ b/addons/mk6mortar/CfgWeapons.hpp @@ -16,16 +16,19 @@ class CfgWeapons { class CannonCore; class mortar_82mm: CannonCore { class Single1; + class Burst1; // need this for doArtilleryFire to work }; class ACE_mortar_82mm: mortar_82mm { author = ECSTRING(common,ACETeam); magazines[] = {"ACE_1Rnd_82mm_Mo_HE","ACE_1Rnd_82mm_Mo_Smoke","ACE_1Rnd_82mm_Mo_Illum", "ACE_1Rnd_82mm_Mo_HE_Guided","ACE_1Rnd_82mm_Mo_HE_LaserGuided"}; - modes[] = {"Single1","Single2","Single3"}; reloadTime = 0.5; magazineReloadTime = 0.5; class Single1: Single1 { reloadTime = 0.5; }; + class Burst1: Burst1 { + reloadTime = 0.5; + }; }; }; From 3248424771ffadae4b746d82114bb9d83b8f43a3 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 17:31:54 +0300 Subject: [PATCH 34/37] add disabled check --- .../functions/fnc_doArtilleryFire.sqf | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 addons/artillerytables/functions/fnc_doArtilleryFire.sqf diff --git a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf new file mode 100644 index 00000000000..249aaa3fd79 --- /dev/null +++ b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf @@ -0,0 +1,54 @@ +#include "script_component.hpp" +/* + * Author: LinkIsGrim + * Wrapper for engine doArtilleryFire, fires barrage one round at a time. + * Handles CSW magazines. + * + * Arguments: + * 0: Vehicle + * 1: Target Position (AGL) + * 2: Magazine Type + * 3: Rounds to fire + * + * Return Value: + * Barrage Started + * + * Example: + * [cursorObject] call ace_artillerytables_fnc_doArtilleryFire + * + * Public: Yes + */ +params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[]]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; + +if (isNull _vehicle || {_rounds isEqualTo 0} || {_magazine isEqualTo ""}) exitWith {false}; + +// Needs to be config case +_magazine = configName (configFile >> "CfgMagazines" >> _magazine); +if (_magazine isEqualTo "") exitWith {false}; + +private _usingCSW = false; +if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + _usingCSW = EGVAR(csw,ammoHandling) > 0; +}; + +if (["ace_mk6mortar"] call EFUNC(common,isModLoaded) && {_vehicle isKindOf "StaticMortar"}) then { + _usingCSW = EGVAR(mk6mortar,useAmmoHandling); +}; + +_usingCSW = _usingCSW && {!(_vehicle getVariable [QEGVAR(csw,disabled), false])}; + +if (_usingCSW && {EGVAR(csw,ammoHandling) < 2}) exitWith {false}; + +if (_usingCSW) then { + private _isCarryMag = isClass (configFile >> QEGVAR(csw,groups) >> _magazine); + if (isCarryMag) then { + _vehicle setVariable [QEGVAR(csw,forcedMag), _magazine, true]; + _magazine = [_vehicle, [0], _magazine] call EFUNC(csw,reload_getVehicleMagazine); + }; +}; + +if ((_vehicle getArtilleryETA [_position, _magazine]) isEqualTo -1) exitWith {false}; + +[LINKFUNC(doArtilleryFirePFEH), 0, [_vehicle, _position, _magazine, _rounds, _usingCSW, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; + +true From 121c1a47c4eeb5ad1a67142514eb79594521458c Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 23:19:11 +0300 Subject: [PATCH 35/37] doArtilleryFire --- .../functions/fnc_doArtilleryFire.sqf | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf index 249aaa3fd79..7c86bda9637 100644 --- a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf +++ b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf @@ -6,7 +6,7 @@ * * Arguments: * 0: Vehicle - * 1: Target Position (AGL) + * 1: Target * 2: Magazine Type * 3: Rounds to fire * @@ -18,13 +18,13 @@ * * Public: Yes */ -params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[]]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; +params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; -if (isNull _vehicle || {_rounds isEqualTo 0} || {_magazine isEqualTo ""}) exitWith {false}; +if (isNull _vehicle || {_rounds isEqualTo 0} || {_magazine isEqualTo ""} || {!(_vehicle turretLocal [0])}) exitWith {false}; -// Needs to be config case -_magazine = configName (configFile >> "CfgMagazines" >> _magazine); -if (_magazine isEqualTo "") exitWith {false}; +if (_position isEqualType objNull) then { + _position = getPos _objNull; +}; private _usingCSW = false; if (["ace_csw"] call EFUNC(common,isModLoaded)) then { @@ -39,16 +39,33 @@ _usingCSW = _usingCSW && {!(_vehicle getVariable [QEGVAR(csw,disabled), false])} if (_usingCSW && {EGVAR(csw,ammoHandling) < 2}) exitWith {false}; +private _vehicleMagazine = _magazine; if (_usingCSW) then { private _isCarryMag = isClass (configFile >> QEGVAR(csw,groups) >> _magazine); - if (isCarryMag) then { + if (_isCarryMag) then { _vehicle setVariable [QEGVAR(csw,forcedMag), _magazine, true]; - _magazine = [_vehicle, [0], _magazine] call EFUNC(csw,reload_getVehicleMagazine); + _vehicleMagazine = [_vehicle, [0], _magazine] call EFUNC(csw,reload_getVehicleMagazine); + } else { + _vehicle setVariable [QEGVAR(csw,forcedMag), [_magazine] call EFUNC(csw,getCarryMagazine), true]; + }; + + if !(_vehicleMagazine in (getArtilleryAmmo [_vehicle])) then { + // TODO: use public functions for this + private _currentMagazine = currentMagazine _vehicle; + private _currentCarryMagazine = [_currentMagazine] call EFUNC(csw,getCarryMagazine); + [_vehicle, [0], _currentCarryMagazine, _currentMagazine, _vehicle] call EFUNC(csw,reload_handleRemoveTurretMag); + [_vehicle, gunner _vehicle, "", true] call EFUNC(csw,ai_reload); }; }; -if ((_vehicle getArtilleryETA [_position, _magazine]) isEqualTo -1) exitWith {false}; +// Needs to be config case +_vehicleMagazine = configName (configFile >> "CfgMagazines" >> _vehicleMagazine); +if (_vehicleMagazine isEqualTo "") exitWith {false}; + +if ((_vehicle getArtilleryETA [_position, _vehicleMagazine]) isEqualTo -1) exitWith {false}; + +_vehicle doWatch _position; -[LINKFUNC(doArtilleryFirePFEH), 0, [_vehicle, _position, _magazine, _rounds, _usingCSW, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(doArtilleryFirePFEH), 0, [_vehicle, _position, _vehicleMagazine, _rounds, _usingCSW, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; true From ad96397532a243595ae60f4500e67a54d23d5449 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 23:41:47 +0300 Subject: [PATCH 36/37] better loop --- addons/artillerytables/XEH_PREP.hpp | 1 + .../functions/fnc_doArtilleryFire.sqf | 43 +++++++++++++------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/addons/artillerytables/XEH_PREP.hpp b/addons/artillerytables/XEH_PREP.hpp index 7ef48b61dd8..14a737c14f3 100644 --- a/addons/artillerytables/XEH_PREP.hpp +++ b/addons/artillerytables/XEH_PREP.hpp @@ -1,5 +1,6 @@ TRACE_1("prep",_this); +PREP(doArtilleryFire); PREP(firedEH); PREP(interactMenuOpened); PREP(rangeTableOpen); diff --git a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf index 7c86bda9637..a4eb3a7a020 100644 --- a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf +++ b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf @@ -1,14 +1,15 @@ #include "script_component.hpp" /* - * Author: LinkIsGrim + * Author: LinkIsGrim, mharris001 * Wrapper for engine doArtilleryFire, fires barrage one round at a time. * Handles CSW magazines. * * Arguments: * 0: Vehicle * 1: Target - * 2: Magazine Type - * 3: Rounds to fire + * 2: Spread in meters + * 3: Magazine Type + * 4: Rounds to fire * * Return Value: * Barrage Started @@ -18,7 +19,7 @@ * * Public: Yes */ -params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; +params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull]], ["_spread", 0, [0]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; if (isNull _vehicle || {_rounds isEqualTo 0} || {_magazine isEqualTo ""} || {!(_vehicle turretLocal [0])}) exitWith {false}; @@ -27,16 +28,16 @@ if (_position isEqualType objNull) then { }; private _usingCSW = false; -if (["ace_csw"] call EFUNC(common,isModLoaded)) then { - _usingCSW = EGVAR(csw,ammoHandling) > 0; -}; - -if (["ace_mk6mortar"] call EFUNC(common,isModLoaded) && {_vehicle isKindOf "StaticMortar"}) then { - _usingCSW = EGVAR(mk6mortar,useAmmoHandling); +if ((typeOf _vehicle) in GVAR(initializedStaticTypes)) then { + if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + _usingCSW = EGVAR(csw,ammoHandling) > 0; + }; + if (["ace_mk6mortar"] call EFUNC(common,isModLoaded) && {_vehicle isKindOf "StaticMortar"}) then { + _usingCSW = EGVAR(mk6mortar,useAmmoHandling); + }; + _usingCSW = _usingCSW && {_vehicle getVariable [QEGVAR(csw,assemblyMode), 3] isNotEqualTo 0} }; -_usingCSW = _usingCSW && {!(_vehicle getVariable [QEGVAR(csw,disabled), false])}; - if (_usingCSW && {EGVAR(csw,ammoHandling) < 2}) exitWith {false}; private _vehicleMagazine = _magazine; @@ -66,6 +67,22 @@ if ((_vehicle getArtilleryETA [_position, _vehicleMagazine]) isEqualTo -1) exitW _vehicle doWatch _position; -[LINKFUNC(doArtilleryFirePFEH), 0, [_vehicle, _position, _vehicleMagazine, _rounds, _usingCSW, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; +[{ + params ["_vehicle", "_position", "_spread", "_magazine", "_roundsLeft", "_lastFired"]; + if (CBA_missionTime - _lastFired > 30) exitWith {true}; + + if (unitReady _vehicle) then { + _vehicle doArtilleryFire [[_position, _spread] call CBA_fnc_randPos, _magazine, 1]; + _this set [4, _roundsLeft - 1]; + _this set [5, CBA_missionTime]; + }; + + if (_rounds <= 0 || {!alive _vehicle} || {!alive (gunner _vehicle)}) exitWith { + [{_this doWatch objNull}, _vehicle, 5] call CBA_fnc_waitAndExecute; + _vehicle setVariable [QEGVAR(csw,forcedMag), nil, true]; + true + }; + false +}, {}, [_vehicle, _position, _spread, _vehicleMagazine, _rounds, CBA_missionTime]] call CBA_fnc_waitUntilAndExecute; true From 29567ce0409c372c58bba9fe8f5a183c2e22a048 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 13 Jul 2023 23:49:48 +0300 Subject: [PATCH 37/37] add mapgrid pos --- .../artillerytables/functions/fnc_doArtilleryFire.sqf | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf index a4eb3a7a020..f041efa26d7 100644 --- a/addons/artillerytables/functions/fnc_doArtilleryFire.sqf +++ b/addons/artillerytables/functions/fnc_doArtilleryFire.sqf @@ -6,7 +6,7 @@ * * Arguments: * 0: Vehicle - * 1: Target + * 1: Target * 2: Spread in meters * 3: Magazine Type * 4: Rounds to fire @@ -19,12 +19,16 @@ * * Public: Yes */ -params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull]], ["_spread", 0, [0]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; +params [["_vehicle", objNull, [objNull]], ["_position", [0, 0, 0], [[], objNull, ""], 3], ["_spread", 0, [0]], ["_magazine", "", [""]], ["_rounds", 0, [0]]]; if (isNull _vehicle || {_rounds isEqualTo 0} || {_magazine isEqualTo ""} || {!(_vehicle turretLocal [0])}) exitWith {false}; if (_position isEqualType objNull) then { - _position = getPos _objNull; + _position = ASLtoAGL getPosASL _position; +}; + +if (_position isEqualType "") then { + _position = [_position, true] call CBA_fnc_mapGridToPos; }; private _usingCSW = false;