cache nearby ammo sources

This commit is contained in:
Salluci 2023-07-01 20:33:42 +03:00
parent f3c393f50c
commit 76a20760f5
8 changed files with 65 additions and 36 deletions

View File

@ -20,6 +20,7 @@ PREP(canGetIn);
PREP(getIn);
PREP(getCarryMagazine);
PREP(getNearbySources);
PREP(proxyWeapon);
PREP(reload_actionsLoad);

View File

@ -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);

View File

@ -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

View File

@ -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 <OBJECT>
*
* Return Value:
* Ammo sources <ARRAY of OBJECT>
*
* 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);

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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