diff --git a/addons/csw/XEH_PREP.hpp b/addons/csw/XEH_PREP.hpp index 5966578aca..5d461ae415 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 c45fff5364..90c071eddb 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 4861fb5ead..fcf4bb904b 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 0000000000..7c9e3e96ba --- /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 2906c33b79..58d8a6b9c9 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 46b0000fdc..f2f07c1761 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 411c8717b4..cdc0dff751 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 29521039f2..3917dad901 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