CSW - Add reloading from nearSupplies (#8776)

* allow players to reload from nearSupplies

* limit reloading to friendly sides

* add handling for ai getting inside empty weapon

* configOf for lookup

* add getin handler, hammer out remaining bugs

* configOf lookup

* improve friendly/object filter

* more configOf lookups

* Capitalize settings, add ammo storage setting

* remove systemChat

Co-authored-by: PabstMirror <pabstmirror@gmail.com>

* fix TRACE

Co-authored-by: PabstMirror <pabstmirror@gmail.com>

Co-authored-by: PabstMirror <pabstmirror@gmail.com>
This commit is contained in:
GhostIsSpooky 2022-03-07 15:29:19 -03:00 committed by GitHub
parent 5a72b61a50
commit a4ae61f1fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 286 additions and 164 deletions

View File

@ -31,9 +31,8 @@ private _fnc_removeMagazine = {
if (_specificMagazineIndex > -1) exitWith { if (_specificMagazineIndex > -1) exitWith {
clearMagazineCargoGlobal _container; clearMagazineCargoGlobal _container;
private _containerType = typeOf _container; if (_container isKindOf "WeaponHolder" && {_allMagazines isNotEqualTo []}) then {
if (_containerType in ["GroundWeaponHolder", "WeaponHolderSimulated"]) then { _container = createVehicle [typeOf _container, getPosATL _container, [], 0, "CAN_COLLIDE"];
_container = createVehicle [_containerType, getPosATL _container, [], 0, "CAN_COLLIDE"];
}; };
{ {
_container addMagazineAmmoCargo [_x select 0, 1, _x select 1]; _container addMagazineAmmoCargo [_x select 0, 1, _x select 1];

View File

@ -272,5 +272,15 @@ class CfgVehicles {
ammoUnloadTime = 3; ammoUnloadTime = 3;
}; };
}; };
// Ammo holder for returning ammo
class ReammoBox_F;
class GVAR(ammo_holder): ReammoBox_F {
EGVAR(cargo,canLoad) = 0;
EGVAR(cargo,noRename) = 1;
EGVAR(dragging,canCarry) = 1; // Allow this to be moved alongside the weapon
EGVAR(dragging,canDrag) = 1;
scope = 1;
maximumLoad = 0; // don't allow anything to be placed inside, only removed
model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d";
};
}; };

View File

@ -3,6 +3,8 @@ TRACE_1("",QUOTE(ADDON));
PREP(aceRearmGetCarryMagazines); PREP(aceRearmGetCarryMagazines);
PREP(ai_handleFired); PREP(ai_handleFired);
PREP(ai_handleGetIn);
PREP(ai_reload);
PREP(assemble_canDeployTripod); PREP(assemble_canDeployTripod);
PREP(assemble_canDeployWeapon); PREP(assemble_canDeployWeapon);

View File

@ -1,6 +1,6 @@
#include "script_component.hpp" #include "script_component.hpp"
GVAR(vehicleMagCache) = call CBA_fnc_createNamespace; GVAR(vehicleMagCache) = createHashMap;
["CBA_settingsInitialized", { ["CBA_settingsInitialized", {
TRACE_3("settingsInit",GVAR(defaultAssemblyMode),GVAR(handleExtraMagazines),GVAR(ammoHandling)); TRACE_3("settingsInit",GVAR(defaultAssemblyMode),GVAR(handleExtraMagazines),GVAR(ammoHandling));

View File

@ -31,11 +31,11 @@ private _allCarryMags = [];
private _weapon = _x; private _weapon = _x;
{ {
private _xMag = _x; private _xMag = _x;
private _carryMag = GVAR(vehicleMagCache) getVariable _xMag; private _carryMag = GVAR(vehicleMagCache) get _xMag;
if (isNil "_carryMag") then { if (isNil "_carryMag") then {
private _groups = "getNumber (_x >> _xMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" configClasses (configFile >> QGVAR(groups)); private _groups = "getNumber (_x >> _xMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" configClasses (configFile >> QGVAR(groups));
_carryMag = configName (_groups param [0, configNull]); _carryMag = configName (_groups param [0, configNull]);
GVAR(vehicleMagCache) setVariable [_x, _carryMag]; GVAR(vehicleMagCache) set [_x, _carryMag];
TRACE_2("setting cache",_xMag,_carryMag); TRACE_2("setting cache",_xMag,_carryMag);
}; };
if (_carryMag != "") then { if (_carryMag != "") then {

View File

@ -1,92 +1,23 @@
#include "script_component.hpp" #include "script_component.hpp"
/* /*
* Author: PabstMirror * Author: PabstMirror
* Initializes weapon to disable weapon disassembling * Handles AI Fired EH
* *
* Arguments: * Arguments:
* 0: Weapon <OBJECT> * Fired EH
* *
* Return Value: * Return Value:
* None * None
* *
* Example:
* [weapon] call ace_csw_fnc_ai_handleFired
*
* Public: No * Public: No
*/ */
params ["_staticWeapon", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; params ["_staticWeapon", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"];
TRACE_8("firedEH:",_staticWeapon, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _gunner); TRACE_8("firedEH:",_staticWeapon,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner);
if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {};
if (someAmmo _staticWeapon) exitWith {}; if (someAmmo _staticWeapon) exitWith {};
TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon);
private _turretPath = [_gunner] call EFUNC(common,getTurretIndex); [_staticWeapon, _gunner, _weapon, _magazine] call FUNC(ai_reload);
private _reloadSource = objNull;
private _reloadMag = "";
private _reloadNeededAmmo = -1;
// Find if there is anything we can reload with
{
scopeName "findSource";
private _xSource = _x;
private _cswMagazines = [];
{
if (isClass (configFile >> QGVAR(groups) >> _x)) then { _cswMagazines pushBackUnique _x; };
} forEach (if (_xSource isKindOf "CaManBase") then {magazines _x} else {magazineCargo _x});
TRACE_2("",_xSource,_cswMagazines);
private _compatibleMags = [_magazine] + ([_weapon] call CBA_fnc_compatibleMagazines); // Check current mag first
{
private _xWeaponMag = _x;
{
if ((getNumber (configFile >> QGVAR(groups) >> _x >> _xWeaponMag)) == 1) then {
private _loadInfo = [_staticWeapon, _turretPath, _reloadMag, objNull] 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 _compatibleMags;
} forEach ([_gunner] + (_staticWeapon nearSupplies 10));
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;
};
};
} forEach (if (_reloadSource isKindOf "CaManBase") then {magazinesAmmo _reloadSource} else {magazinesAmmoCargo _reloadSource});
TRACE_4("",_reloadSource,_reloadMag,_reloadNeededAmmo,_bestAmmoToSend);
if (_bestAmmoToSend == -1) exitWith {ERROR("No ammo");};
// Remove the mag from the source
[_reloadSource, _reloadMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine);
private _timeToLoad = 1;
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);};
// Reload the static weapon
TRACE_5("calling addTurretMag event",_staticWeapon, _turretPath, _gunner, _reloadMag, _bestAmmoToSend);
[QGVAR(addTurretMag), _this] call CBA_fnc_globalEvent;
}, [_staticWeapon, _turretPath, _gunner, _reloadMag, _bestAmmoToSend], _timeToLoad] call CBA_fnc_waitAndExecute;

View File

@ -0,0 +1,22 @@
#include "script_component.hpp"
/*
* Author: GhostIsSpooky
* Handles AI GetIn on an empty weapon
*
* Arguments:
* GetIn EH
*
* Return Value:
* None
*
* Public: No
*/
params ["_staticWeapon", "_role", "_gunner"];
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);
[_staticWeapon, _gunner, currentWeapon _staticWeapon] call FUNC(ai_reload);

View File

@ -0,0 +1,95 @@
#include "script_component.hpp"
/*
* Author: PabstMirror, modified by GhostIsSpooky
* Handles AI reloading
*
* Arguments:
* 0: Static Weapon <OBJECT>
* 1: Gunner <OBJECT>
* 2: Weapon <STRING>
* 3: Magazine <STRING> (default: "")
*
* Return Value:
* None
*
* Public: No
*/
params ["_staticWeapon", "_gunner", "_weapon", ["_magazine", ""]];
private _turretPath = [_gunner] call EFUNC(common,getTurretIndex);
private _reloadSource = objNull;
private _reloadMag = "";
private _reloadNeededAmmo = -1;
private _cfgMagGroups = configFile >> QGVAR(groups);
private _nearSupplies = [_gunner] + ((_staticWeapon nearSupplies 10) select {
isNull (group _x) ||
{!([_x] call EFUNC(common,isPlayer)) && {[side group _gunner, side group _x] call BIS_fnc_sideIsFriendly}}
});
// Find if there is anything we can reload with
{
scopeName "findSource";
private _xSource = _x;
private _cswMagazines = [];
{
_cswMagazines pushBackUnique _x;
} forEach ((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;
{
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 _compatibleMags;
} forEach _nearSupplies;
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;
};
};
} forEach (if (_reloadSource isKindOf "CaManBase") then {magazinesAmmo _reloadSource} else {magazinesAmmoCargo _reloadSource});
TRACE_4("",_reloadSource,_reloadMag,_reloadNeededAmmo,_bestAmmoToSend);
if (_bestAmmoToSend == -1) exitWith {ERROR("No ammo");};
// Remove the mag from the source
[_reloadSource, _reloadMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine);
private _timeToLoad = 1;
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);};
// Reload the static weapon
TRACE_5("calling addTurretMag event",_staticWeapon,_turretPath,_gunner,_reloadMag,_bestAmmoToSend);
[QGVAR(addTurretMag), _this] call CBA_fnc_globalEvent;
}, [_staticWeapon, _turretPath, _gunner, _reloadMag, _bestAmmoToSend], _timeToLoad] call CBA_fnc_waitAndExecute;

View File

@ -41,11 +41,11 @@
{ {
_x params ["_xMag", "", "_xAmmo"]; _x params ["_xMag", "", "_xAmmo"];
private _carryMag = GVAR(vehicleMagCache) getVariable _xMag; private _carryMag = GVAR(vehicleMagCache) get _xMag;
if (isNil "_carryMag") then { if (isNil "_carryMag") then {
private _groups = "getNumber (_x >> _xMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" configClasses (configFile >> QGVAR(groups)); private _groups = "getNumber (_x >> _xMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" configClasses (configFile >> QGVAR(groups));
_carryMag = configName (_groups param [0, configNull]); _carryMag = configName (_groups param [0, configNull]);
GVAR(vehicleMagCache) setVariable [_xMag, _carryMag]; GVAR(vehicleMagCache) set [_xMag, _carryMag];
TRACE_2("setting cache",_xMag,_carryMag); TRACE_2("setting cache",_xMag,_carryMag);
}; };
if ((_xAmmo > 0) && {_carryMag != ""}) then { if ((_xAmmo > 0) && {_carryMag != ""}) then {
@ -93,4 +93,3 @@
[TIME_PROGRESSBAR(_pickupTime), [_staticWeapon, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, localize LSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar); [TIME_PROGRESSBAR(_pickupTime), [_staticWeapon, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, localize LSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar);
}, _this] call CBA_fnc_execNextFrame; }, _this] call CBA_fnc_execNextFrame;

View File

@ -23,8 +23,7 @@ TRACE_4("proxyWeapon",_staticWeapon,_turret,_needed,_emptyWeapon);
if (_staticWeapon getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _staticWeapon); }; if (_staticWeapon getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _staticWeapon); };
private _typeOf = typeOf _staticWeapon; private _proxyWeapon = getText (configOf _staticWeapon >> "ace_csw" >> "proxyWeapon");
private _proxyWeapon = getText(configFile >> "CfgVehicles" >> _typeOf >> "ace_csw" >> "proxyWeapon");
TRACE_2("",_typeOf,_proxyWeapon); TRACE_2("",_typeOf,_proxyWeapon);
if (_proxyWeapon == "") exitWith {}; if (_proxyWeapon == "") exitWith {};

View File

@ -23,24 +23,26 @@ private _loadableMagazines = [_vehicle, _player] call FUNC(reload_getLoadableMag
private _statement = { private _statement = {
params ["_target", "_player", "_params"]; params ["_target", "_player", "_params"];
_params params ["_carryMag", "_turretPath"]; _params params ["_carryMag", "_turretPath", "", "_magSource"];
[_target, _turretPath, _carryMag, _player] call FUNC(reload_loadMagazine); [_target, _turretPath, _carryMag, _magSource, _player] call FUNC(reload_loadMagazine);
}; };
private _condition = { private _condition = {
params ["_target", "_player", "_params"]; params ["_target", "_player", "_params"];
_params params ["_carryMag", "_turretPath"]; _params params ["_carryMag", "_turretPath", "", "_magSource"];
([_target, _turretPath, _carryMag, _player] call FUNC(reload_canLoadMagazine)) select 0 ([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0
}; };
private _cfgMagazines = configFile >> "CfgMagazines"; // micro-optimization
{ {
_x params ["_carryMag", "_turretPath", "_loadInfo"]; _x params ["_carryMag", "", "_loadInfo"];
_loadInfo params ["", "", "", "_isBeltLinking"]; _loadInfo params ["", "", "", "_isBeltLinking"];
private _displayName = getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName"); private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName");
private _picture = getText (configFile >> "CfgMagazines" >> _carryMag >> "picture"); private _picture = getText (_cfgMagazines >> _carryMag >> "picture");
private _text = if (_isBeltLinking) then { private _text = if (_isBeltLinking) then {
format [localize LSTRING(actionLink), _displayName]; format [localize LSTRING(actionLink), _displayName];
} else { } else {
@ -53,4 +55,3 @@ private _condition = {
TRACE_1("loadActions",count _actions); TRACE_1("loadActions",count _actions);
_actions _actions

View File

@ -1,7 +1,7 @@
#include "script_component.hpp" #include "script_component.hpp"
/* /*
* Author: PabstMirror * Author: PabstMirror
* Gets sub actions for what the player can load into the static weapon * Gets sub actions for what the player can unload from the static weapon
* *
* Arguments: * Arguments:
* 0: Target <OBJECT> * 0: Target <OBJECT>
@ -52,25 +52,27 @@ private _condition = {
private _actions = []; private _actions = [];
private _handeledMagTypes = []; private _handeledMagTypes = [];
private _cfgMagazines = configFile >> "CfgMagazines";
// Go through magazines on static weapon and check if any are unloadable // Go through magazines on static weapon and check if any are unloadable
{ {
_x params ["_xMag", "_xTurret", "_xAmmo"]; _x params ["_xMag", "_xTurret", "_xAmmo"];
if ((_xAmmo > 0) && {!(_xMag in _handeledMagTypes)}) then { if ((_xAmmo > 0) && {!(_xMag in _handeledMagTypes)}) then {
_handeledMagTypes pushBack _xMag; _handeledMagTypes pushBack _xMag;
private _carryMag = GVAR(vehicleMagCache) getVariable _xMag; private _carryMag = GVAR(vehicleMagCache) get _xMag;
if (isNil "_carryMag") then { if (isNil "_carryMag") then {
private _groups = "getNumber (_x >> _xMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" configClasses (configFile >> QGVAR(groups)); private _groups = "getNumber (_x >> _xMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" configClasses (configFile >> QGVAR(groups));
_carryMag = configName (_groups param [0, configNull]); _carryMag = configName (_groups param [0, configNull]);
GVAR(vehicleMagCache) setVariable [_xMag, _carryMag]; GVAR(vehicleMagCache) set [_xMag, _carryMag];
TRACE_2("setting cache",_xMag,_carryMag); TRACE_2("setting cache",_xMag,_carryMag);
}; };
if (_carryMag == "") exitWith {}; if (_carryMag == "") exitWith {};
private _displayName = getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName"); private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName");
private _text = format [LLSTRING(unloadX), _displayName]; private _text = format [LLSTRING(unloadX), _displayName];
private _picture = getText (configFile >> "CfgMagazines" >> _carryMag >> "picture"); private _picture = getText (_cfgMagazines >> _carryMag >> "picture");
private _action = [format ["unload_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, [_xMag, _xTurret, _carryMag]] call EFUNC(interact_menu,createAction); private _action = [format ["unload_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, [_xMag, _xTurret, _carryMag]] call EFUNC(interact_menu,createAction);
_actions pushBack [_action, [], _vehicle]; _actions pushBack [_action, [], _vehicle];
}; };
@ -78,4 +80,3 @@ private _handeledMagTypes = [];
TRACE_1("unloadActions",count _actions); TRACE_1("unloadActions",count _actions);
_actions _actions

View File

@ -7,7 +7,7 @@
* 0: Static Weapon <OBJECT> * 0: Static Weapon <OBJECT>
* 1: Turret Path <ARRAY> * 1: Turret Path <ARRAY>
* 2: Carryable Magazine <STRING> * 2: Carryable Magazine <STRING>
* 3: Player <OBJECT> * 3: Supplier <OBJECT>
* *
* Return Value: * Return Value:
* [CanLoad<BOOL>, LoadedMag<STRING>, AmmoNeeded<NUMBER>, IsBeltLinking<BOOL>]<ARRAY> * [CanLoad<BOOL>, LoadedMag<STRING>, AmmoNeeded<NUMBER>, IsBeltLinking<BOOL>]<ARRAY>
@ -18,17 +18,30 @@
* Public: No * Public: No
*/ */
params ["_vehicle", "_turret", "_carryMag", ["_unit", objNull]]; params ["_vehicle", "_turret", "_carryMag", ["_magSource", objNull]];
// TRACE_4("reload_canLoadMagazine",_vehicle,_turret,_carryMag,_unit); // TRACE_4("reload_canLoadMagazine",_vehicle,_turret,_carryMag,_magSource);
private _return = [false, "", -2, false];
// Handle disassembled or deleted // Handle disassembled or deleted
if (!alive _vehicle) exitWith { [false, "", -1, false] }; if (!alive _vehicle) exitWith { _return };
// Verify unit has carry magazine // Verify holder has carry magazine
if ((!isNull _unit) && {((_vehicle distance _unit) > 5) || {((magazines _unit) findIf {_x == _carryMag}) == -1}}) exitWith { [false, "", -2, false] }; 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 };
// solve config lookups
private _cfgMagazines = configFile >> "CfgMagazines";
private _cfgMagazinesCarryMag = _cfgMagazines >> _carryMag;
private _desiredAmmo = getNumber (configOf _vehicle >> QUOTE(ADDON) >> "desiredAmmo"); private _desiredAmmo = getNumber (configOf _vehicle >> QUOTE(ADDON) >> "desiredAmmo");
if (_desiredAmmo == 0) then { _desiredAmmo = 100; }; if (_desiredAmmo == 0) then { _desiredAmmo = 100; };
private _ammoNeeded = _desiredAmmo min getNumber (configFile >> "CfgMagazines" >> _carryMag >> "count"); // assume it needs full carry mag private _ammoNeeded = _desiredAmmo min getNumber (_cfgMagazinesCarryMag >> "count"); // assume it needs full carry mag
private _loadedMag = ""; private _loadedMag = "";
private _isBeltLinking = false; private _isBeltLinking = false;
@ -40,13 +53,13 @@ scopeName "main";
_loadedMag = _xMag; _loadedMag = _xMag;
if (_xAmmo > 0) then { if (_xAmmo > 0) then {
// There is a magazine with ammo loaded in the turret (are there any multi-muzzle static weapons??), see if we can add to this mag // There is a magazine with ammo loaded in the turret (are there any multi-muzzle static weapons??), see if we can add to this mag
if (getNumber (configFile >> QGVAR(groups) >> _carryMag >> _xMag) != 1) exitWith { if (getNumber (_cfgMagazinesCarryMag >> _xMag) != 1) exitWith {
[false, _loadedMag, -4, false] breakOut "main"; // Carry mag cannot be added to existing vehicle mag (e.g. red to green tracers) [false, _loadedMag, -4, false] breakOut "main"; // Carry mag cannot be added to existing vehicle mag (e.g. red to green tracers)
}; };
if (getNumber (configFile >> "CfgMagazines" >> _carryMag >> "ACE_isBelt") == 0) exitWith { if (getNumber (_cfgMagazinesCarryMag >> "ACE_isBelt") == 0) exitWith {
[false, _loadedMag, -5, false] breakOut "main"; // Non-linkable mag loaded, can't add any more [false, _loadedMag, -5, false] breakOut "main"; // Non-linkable mag loaded, can't add any more
}; };
private _maxMagazineAmmo = _desiredAmmo min getNumber (configFile >> "CfgMagazines" >> _xMag >> "count"); private _maxMagazineAmmo = _desiredAmmo min getNumber (_cfgMagazines >> _xMag >> "count");
if (_xAmmo >= _maxMagazineAmmo) exitWith { if (_xAmmo >= _maxMagazineAmmo) exitWith {
[false, _loadedMag, -6, false] breakOut "main"; // Already at capicity [false, _loadedMag, -6, false] breakOut "main"; // Already at capicity
}; };

View File

@ -9,7 +9,7 @@
* *
* Return Value: * Return Value:
* Mags <ARRAY> * Mags <ARRAY>
* [Carry Magazine <STRING>, Turret Path <ARRAY>, Ammo Needed <NUMBER>] * [Carry Magazine <STRING>, Turret Path <ARRAY>, Load Info <NUMBER>, Magazine Source <OBJECT>]
* *
* Example: * Example:
* [cursorObject, player] call ace_csw_fnc_reload_getLoadableMagazines * [cursorObject, player] call ace_csw_fnc_reload_getLoadableMagazines
@ -19,15 +19,37 @@
params ["_vehicle", "_player"]; params ["_vehicle", "_player"];
private _carriedMagazines = []; 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 _nearSupplies = ((_vehicle nearSupplies 10) select {
isNull (group _x) ||
{!([_x] call EFUNC(common,isPlayer)) && {[side group _player, side group _x] call BIS_fnc_sideIsFriendly}}
});
// backpacks/uniforms/etc need to be added manually.
// array can't be modified while iterating, use copy
{
{
_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;
{ {
if (isClass (configFile >> QGVAR(groups) >> _x)) then { private _xSource = _x;
_carriedMagazines pushBackUnique _x; private _mags = magazineCargo _xSource;
};
} forEach (magazines _player);
if (_carriedMagazines isEqualTo []) exitWith { [] }; // fast exit if no carry mags {
_availableMagazines set [_x, _xSource];
} forEach (_mags select {isClass (_magGroupsConfig >> _x)});
} forEach _nearSupplies;
if (_availableMagazines isEqualTo createHashMap) exitWith { [] }; // fast exit if no available mags
private _loadInfo = []; private _loadInfo = [];
private _return = []; private _return = [];
@ -37,14 +59,19 @@ private _return = [];
{ {
private _weapon = _x; private _weapon = _x;
{ {
//IGNORE_PRIVATE_WARNING ["_x", "_y"];
private _carryMag = _x; private _carryMag = _x;
private _carryGroup = configFile >> QGVAR(groups) >> _carryMag; private _magSource = _y;
private _carryGroup = _magGroupsConfig >> _carryMag;
{ {
if (((getNumber (_carryGroup >> _x)) == 1) && {_loadInfo = [_vehicle, _turretPath, _carryMag, _player] call FUNC(reload_canLoadMagazine); _loadInfo select 0}) exitWith { if (
_return pushBack [_carryMag, _turretPath, _loadInfo]; ((getNumber (_carryGroup >> _x)) == 1) &&
{_loadInfo = [_vehicle, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine); _loadInfo select 0}
) exitWith {
_return pushBack [_carryMag, _turretPath, _loadInfo, _magSource];
}; };
} forEach ([_weapon] call CBA_fnc_compatibleMagazines); } forEach ([_weapon] call CBA_fnc_compatibleMagazines);
} forEach _carriedMagazines; } forEach _availableMagazines;
} forEach (_vehicle weaponsTurret _turretPath); } forEach (_vehicle weaponsTurret _turretPath);
} forEach (allTurrets _vehicle); } forEach (allTurrets _vehicle);
// Note: these nested forEach's looks terrible, but most only have one element // Note: these nested forEach's looks terrible, but most only have one element

View File

@ -7,9 +7,10 @@
* Arguments: * Arguments:
* 0: Static Weapon <OBJECT> * 0: Static Weapon <OBJECT>
* 1: Turret Path <ARRAY> * 1: Turret Path <ARRAY>
* 2: Unit doing action <OBJECT> * 2: Source of magazine <OBJECT>
* 3: Vehicle Magazine <STRING> * 3: Vehicle Magazine <STRING>
* 4: Ammo in magazine <NUMBER> * 4: Ammo in magazine <NUMBER>
* 5: Unit or object to return ammo to <OBJECT>
* *
* Return Value: * Return Value:
* None * None
@ -20,8 +21,8 @@
* Public: No * Public: No
*/ */
params ["_vehicle", "_turret", "_unit", "_carryMag" ,"_ammoRecieved"]; params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived", ["_returnTo", _magSource]];
TRACE_5("reload_handleAddTurretMag",_vehicle,_turret,_unit,_carryMag,_ammoRecieved); TRACE_6("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_returnTo);
TRACE_2("",local _vehicle, _vehicle turretLocal _turret); TRACE_2("",local _vehicle, _vehicle turretLocal _turret);
if (!(_vehicle turretLocal _turret)) exitWith {}; if (!(_vehicle turretLocal _turret)) exitWith {};
@ -29,9 +30,9 @@ if (!(_vehicle turretLocal _turret)) exitWith {};
([_vehicle, _turret, _carryMag] call FUNC(reload_canLoadMagazine)) params ["_canAdd", "_loadedMag", "_neededAmmo", "_isBeltLinking"]; ([_vehicle, _turret, _carryMag] call FUNC(reload_canLoadMagazine)) params ["_canAdd", "_loadedMag", "_neededAmmo", "_isBeltLinking"];
TRACE_4("canLoad",_canAdd,_loadedMag,_neededAmmo,_isBeltLinking); TRACE_4("canLoad",_canAdd,_loadedMag,_neededAmmo,_isBeltLinking);
private _ammoRemaining = _ammoRecieved; private _ammoRemaining = _ammoReceived;
if (_canAdd) then { if (_canAdd) then {
private _ammoUsed = _neededAmmo min _ammoRecieved; private _ammoUsed = _neededAmmo min _ammoReceived;
_ammoRemaining = _ammoRemaining - _ammoUsed; _ammoRemaining = _ammoRemaining - _ammoUsed;
if (_isBeltLinking) then { if (_isBeltLinking) then {
@ -46,7 +47,6 @@ if (_canAdd) then {
_vehicle setAmmo [_weapon, _currentAmmo]; _vehicle setAmmo [_weapon, _currentAmmo];
private _currentAmmo = _vehicle magazineTurretAmmo [_loadedMag, _turret]; private _currentAmmo = _vehicle magazineTurretAmmo [_loadedMag, _turret];
if ((_weapon == "") || {_currentAmmo != _currentAmmo}) then { ERROR_1("failed to setAmmo - %1", _this); }; if ((_weapon == "") || {_currentAmmo != _currentAmmo}) then { ERROR_1("failed to setAmmo - %1", _this); };
} else { } else {
if (_loadedMag != "") then { if (_loadedMag != "") then {
TRACE_1("Removing emtpy mag",_loadedMag); TRACE_1("Removing emtpy mag",_loadedMag);
@ -60,7 +60,6 @@ if (_canAdd) then {
}; };
if (_ammoRemaining > 0) then { if (_ammoRemaining > 0) then {
TRACE_3("Returning ammo",_unit,_carryMag,_ammoRemaining); TRACE_3("Returning ammo",_returnTo,_carryMag,_ammoRemaining);
[QGVAR(returnAmmo), [_unit, _carryMag, _ammoRemaining], _unit] call CBA_fnc_targetEvent; [QGVAR(returnAmmo), [_returnTo, _carryMag, _ammoRemaining], _returnTo] call CBA_fnc_targetEvent;
}; };

View File

@ -9,7 +9,7 @@
* 1: Turret Path <ARRAY> * 1: Turret Path <ARRAY>
* 2: Magainze Unit Can Carry <STRING> * 2: Magainze Unit Can Carry <STRING>
* 3: Magazine To Remove From Static <STRING> * 3: Magazine To Remove From Static <STRING>
* 4: Unit to unload to <OBJECT> * 4: Unit or container to unload to <OBJECT>
* *
* Return Value: * Return Value:
* None * None
@ -20,10 +20,10 @@
* Public: No * Public: No
*/ */
params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unit"]; params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unloadTo"];
TRACE_5("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unit); TRACE_5("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unloadTo);
TRACE_3("",local _vehicle, _vehicle turretLocal _turretPath,local _unit); TRACE_3("",local _vehicle, _vehicle turretLocal _turretPath,local _unloadTo);
if (!(_vehicle turretLocal _turretPath)) exitWith {}; if (!(_vehicle turretLocal _turretPath)) exitWith {};
private _magsInWeapon = []; // Check how much ammo it has now: private _magsInWeapon = []; // Check how much ammo it has now:
@ -75,5 +75,5 @@ if ((_magsInWeapon isEqualTo []) && {_ammoInFirstMag > _ammoRemoved}) then {
} forEach _magsInWeapon; } forEach _magsInWeapon;
}; };
TRACE_3("Returning ammo",_unit,_carryMag,_ammoRemoved); TRACE_3("Returning ammo",_unloadTo,_carryMag,_ammoRemoved);
[QGVAR(returnAmmo), [_unit, _carryMag, _ammoRemoved], _unit] call CBA_fnc_targetEvent; [QGVAR(returnAmmo), [_unloadTo, _carryMag, _ammoRemoved], _unloadTo] call CBA_fnc_targetEvent;

View File

@ -39,18 +39,17 @@ if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {};
// Try to use existing container // Try to use existing container
private _container = _unloadTo getVariable [QGVAR(container), objNull]; private _container = _unloadTo getVariable [QGVAR(container), objNull];
if ((_container distance _unloadTo) > 4) then { _container = objNull; }; if ((_container distance _unloadTo) > 10) then { _container = objNull; };
if (isNull _container) then { if (isNull _container) then {
_container = (nearestObjects [_unloadTo, ["groundWeaponHolder"], 4]) param [0, objNull]; _container = (nearestObjects [_unloadTo, [QGVAR(ammo_holder), "GroundWeaponHolder"], 10]) param [0, objNull];
}; };
if (isNull _container) then { if (isNull _container) then {
// Create ground weapon holder container // Create ammo storage container
private _weaponRelPos = _unloadTo getRelPos RELATIVE_DIRECTION(270); private _weaponRelPos = _unloadTo getRelPos RELATIVE_DIRECTION(270);
_weaponRelPos set [2, ((getPosATL _unloadTo) select 2) + 0.05]; _weaponRelPos set [2, ((getPosATL _unloadTo) select 2) + 0.05];
_container = createVehicle ["groundWeaponHolder", [0, 0, 0], [], 0, "NONE"]; _container = createVehicle [["GroundWeaponHolder", QGVAR(ammo_holder)] select GVAR(handleExtraMagazinesType), [0, 0, 0], [], 0, "NONE"];
// ToDo: Unload to ammo box??
_unloadTo setVariable [QGVAR(container), _container, true]; _unloadTo setVariable [QGVAR(container), _container, true];
_container setDir random [0, 180, 360]; _container setDir random [0, 180, 360];
_container setPosATL _weaponRelPos; _container setPosATL _weaponRelPos;

View File

@ -1,25 +1,26 @@
#include "script_component.hpp" #include "script_component.hpp"
/* /*
* Author: PabstMirror * Author: PabstMirror
* Loads a magazine into a static weapon from a magazine carried by the player. * Loads a magazine into a static weapon from a magazine carried by or next to the player.
* *
* Arguments: * Arguments:
* 0: Vehicle <OBJECT> * 0: Vehicle <OBJECT>
* 1: Turret <ARRAY> * 1: Turret <ARRAY>
* 2: Unit Carried Magazine <STRING> * 2: Unit Carried Magazine <STRING>
* 3: Player <OBJECT> * 3: Magazine source <OBJECT>
* 4: Unit doing the action <OBJECT>
* *
* Return Value: * Return Value:
* None * None
* *
* Example: * Example:
* [cursorTarget, [0], "ACE_csw_100Rnd_127x99_mag_red", player] call ace_csw_fnc_reload_loadMagazine * [cursorTarget, [0], "ACE_csw_100Rnd_127x99_mag_red", player, player] call ace_csw_fnc_reload_loadMagazine
* *
* Public: No * Public: No
*/ */
params ["_vehicle", "_turret", "_carryMag", "_unit"]; params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"];
TRACE_4("loadMagazine",_vehicle,_turret,_carryMag,_unit); TRACE_5("loadMagazine",_vehicle,_turret,_carryMag,_magSource,_unit);
private _timeToLoad = 1; private _timeToLoad = 1;
if (!isNull(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime")) then { if (!isNull(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime")) then {
@ -29,10 +30,10 @@ if (!isNull(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime")) then {
private _displayName = format [localize LSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")]; private _displayName = format [localize LSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")];
private _onFinish = { private _onFinish = {
(_this select 0) params ["_vehicle", "_turret", "_carryMag", "_unit"]; (_this select 0) params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"];
TRACE_4("load progressBar finish",_vehicle,_turret,_carryMag,_unit); TRACE_5("load progressBar finish",_vehicle,_turret,_carryMag,_magSource,_unit);
([_vehicle, _turret, _carryMag, _unit] call FUNC(reload_canLoadMagazine)) params ["", "", "_neededAmmo", ""]; ([_vehicle, _turret, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) params ["", "", "_neededAmmo", ""];
if (_neededAmmo <= 0) exitWith { ERROR_1("Can't load ammo - %1",_this); }; if (_neededAmmo <= 0) exitWith { ERROR_1("Can't load ammo - %1",_this); };
// Figure out what we can add from the magazines we have // Figure out what we can add from the magazines we have
@ -44,20 +45,20 @@ private _onFinish = {
_bestAmmoToSend = _xAmmo; _bestAmmoToSend = _xAmmo;
}; };
}; };
} forEach (magazinesAmmo _unit); } forEach (magazinesAmmo _magSource);
if (_bestAmmoToSend == -1) exitWith {ERROR_2("No ammo [%1 - %2]?",_xMag,_bestAmmoToSend);}; if (_bestAmmoToSend == -1) exitWith {ERROR_2("No ammo [%1 - %2]?",_xMag,_bestAmmoToSend);};
[_unit, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); [_magSource, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine);
if (_bestAmmoToSend == 0) exitWith {}; if (_bestAmmoToSend == 0) exitWith {};
TRACE_5("calling addTurretMag event",_vehicle,_turret,_unit,_carryMag,_bestAmmoToSend); TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend, _unit);
[QGVAR(addTurretMag), [_vehicle, _turret, _unit, _carryMag, _bestAmmoToSend]] call CBA_fnc_globalEvent; [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend, _unit]] call CBA_fnc_globalEvent;
}; };
[ [
TIME_PROGRESSBAR(_timeToLoad), TIME_PROGRESSBAR(_timeToLoad),
[_vehicle, _turret, _carryMag, _unit], [_vehicle, _turret, _carryMag, _magSource],
_onFinish, _onFinish,
{TRACE_1("load progressBar fail",_this);}, {TRACE_1("load progressBar fail",_this);},
_displayName, _displayName,

View File

@ -17,13 +17,15 @@
params ["_staticWeapon"]; params ["_staticWeapon"];
private _typeOf = typeOf _staticWeapon; private _typeOf = typeOf _staticWeapon;
private _configEnabled = (getNumber (configFile >> "CfgVehicles" >> _typeOf >> "ace_csw" >> "enabled")) == 1; private _configOf = configOf _staticWeapon;
private _assemblyConfig = _configEnabled && {(getText (configFile >> "CfgVehicles" >> _typeOf >> "ace_csw" >> "disassembleWeapon")) != ""}; 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",_staticWeapon,_typeOf,_configEnabled,_assemblyConfig);
if (_configEnabled && {GVAR(ammoHandling) == 2}) then { if (_configEnabled && {GVAR(ammoHandling) == 2}) then {
TRACE_1("adding AI fired handler",_staticWeapon); TRACE_1("adding AI fired handler",_staticWeapon);
_staticWeapon addEventHandler ["Fired", LINKFUNC(ai_handleFired)]; _staticWeapon addEventHandler ["Fired", LINKFUNC(ai_handleFired)];
_staticWeapon addEventHandler ["GetIn", LINKFUNC(ai_handleGetIn)]; // handle AI getting inside weapon with no ammo
}; };
TRACE_2("",local _staticWeapon,_staticWeapon turretLocal [0]); TRACE_2("",local _staticWeapon,_staticWeapon turretLocal [0]);
@ -65,7 +67,7 @@ if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then {
private _ammoActionPath = []; private _ammoActionPath = [];
private _magazineLocation = getText (configFile >> "CfgVehicles" >> _typeOf >> QUOTE(ADDON) >> "magazineLocation"); private _magazineLocation = getText (_configOf >> QUOTE(ADDON) >> "magazineLocation");
private _condition = { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; private _condition = { //IGNORE_PRIVATE_WARNING ["_target", "_player"];
// If magazine handling is enabled or weapon assembly/disassembly is enabled we enable ammo handling // If magazine handling is enabled or weapon assembly/disassembly is enabled we enable ammo handling
if ((GVAR(ammoHandling) == 0) && {!([false, true, true, GVAR(defaultAssemblyMode)] select (_target getVariable [QGVAR(assemblyMode), 3]))}) exitWith { false }; if ((GVAR(ammoHandling) == 0) && {!([false, true, true, GVAR(defaultAssemblyMode)] select (_target getVariable [QGVAR(assemblyMode), 3]))}) exitWith { false };

View File

@ -36,11 +36,11 @@ private _containerMagazineCount = [];
{ {
_x params ["_xMag", "_xTurret", "_xAmmo"]; _x params ["_xMag", "_xTurret", "_xAmmo"];
private _carryMag = GVAR(vehicleMagCache) getVariable _xMag; private _carryMag = GVAR(vehicleMagCache) get _xMag;
if (isNil "_carryMag") then { if (isNil "_carryMag") then {
private _groups = "getNumber (_x >> _xMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" configClasses (configFile >> QGVAR(groups)); private _groups = "getNumber (_x >> _xMag) == 1 && {isClass (configFile >> 'CfgMagazines' >> configName _x)}" configClasses (configFile >> QGVAR(groups));
_carryMag = configName (_groups param [0, configNull]); _carryMag = configName (_groups param [0, configNull]);
GVAR(vehicleMagCache) setVariable [_xMag, _carryMag]; GVAR(vehicleMagCache) set [_xMag, _carryMag];
TRACE_2("setting cache",_xMag,_carryMag); TRACE_2("setting cache",_xMag,_carryMag);
}; };
if (_carryMag != "") then { if (_carryMag != "") then {

View File

@ -20,6 +20,16 @@ private _categoryArray = [format ["ACE %1", localize LSTRING(DisplayName)]];
true // Needs mission restart true // Needs mission restart
] call CBA_fnc_addSetting; ] call CBA_fnc_addSetting;
[
QGVAR(handleExtraMagazinesType), "LIST",
[LSTRING(handleExtraMagazinesType_displayName), LSTRING(handleExtraMagazinesType_description)],
_categoryArray,
[[0, 1], [LSTRING(handleExtraMagazinesType_weaponHolder), LSTRING(handleExtraMagazinesType_ammoBox)], 0],
true, // isGlobal
{[QGVAR(handleExtraMagazinesType), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_fnc_addSetting;
[ [
QGVAR(ammoHandling), "LIST", QGVAR(ammoHandling), "LIST",
[LSTRING(ammoHandling_displayName), LSTRING(ammoHandling_description)], [LSTRING(ammoHandling_displayName), LSTRING(ammoHandling_description)],

View File

@ -114,7 +114,7 @@
<Korean>%1 연결</Korean> <Korean>%1 연결</Korean>
</Key> </Key>
<Key ID="STR_ACE_CSW_defaultAssemblyMode_displayName"> <Key ID="STR_ACE_CSW_defaultAssemblyMode_displayName">
<English>Advanced assembly</English> <English>Advanced Assembly</English>
<German>Erweiterter Zusammenbau</German> <German>Erweiterter Zusammenbau</German>
<Portuguese>Montagem Avançada</Portuguese> <Portuguese>Montagem Avançada</Portuguese>
<French>Assemblage avancé</French> <French>Assemblage avancé</French>
@ -129,7 +129,7 @@
<Korean>고급 조립</Korean> <Korean>고급 조립</Korean>
</Key> </Key>
<Key ID="STR_ACE_CSW_defaultAssemblyMode_description"> <Key ID="STR_ACE_CSW_defaultAssemblyMode_description">
<English>Use ace for Assemble/Disassemble of supported static weapons. Loaded ammo is reduced to a single magazine.</English> <English>Use ACE for Assemble/Disassemble of supported static weapons. Loaded ammo is reduced to a single magazine.</English>
<German>Benutze ACE um unterstützte statische Waffen zu montieren/demontieren. Geladene Munition ist auf ein einzelnes Magazin reduziert.</German> <German>Benutze ACE um unterstützte statische Waffen zu montieren/demontieren. Geladene Munition ist auf ein einzelnes Magazin reduziert.</German>
<Portuguese>Usar o ACE para Montar/Desmontar armas estáticas suportadas. Munição carregada é reduzida para um único carregador.</Portuguese> <Portuguese>Usar o ACE para Montar/Desmontar armas estáticas suportadas. Munição carregada é reduzida para um único carregador.</Portuguese>
<French>Utilise ACE pour l'assemblage/le désassemblage des armes statiques supportées.\nLes munitions chargées sont réduites à un seul chargeur.</French> <French>Utilise ACE pour l'assemblage/le désassemblage des armes statiques supportées.\nLes munitions chargées sont réduites à un seul chargeur.</French>
@ -144,7 +144,7 @@
<Korean>ACE의 조립/분해 기능을 사용하여 공용화기를 다룹니다. 장전된 탄은 한 탄창으로 제한됩니다.</Korean> <Korean>ACE의 조립/분해 기능을 사용하여 공용화기를 다룹니다. 장전된 탄은 한 탄창으로 제한됩니다.</Korean>
</Key> </Key>
<Key ID="STR_ACE_CSW_handleExtraMagazines_displayName"> <Key ID="STR_ACE_CSW_handleExtraMagazines_displayName">
<English>Save extra ammo</English> <English>Save Extra Ammo</English>
<German>Spare extra Munition</German> <German>Spare extra Munition</German>
<Portuguese>Economizar munição extra</Portuguese> <Portuguese>Economizar munição extra</Portuguese>
<French>Conserver le surplus de munitions</French> <French>Conserver le surplus de munitions</French>
@ -173,6 +173,18 @@
<Russian>Хранить дополнительные магазины рядом со статическим оружием</Russian> <Russian>Хранить дополнительные магазины рядом со статическим оружием</Russian>
<Korean>공용화기 옆에 남은 탄들을 저장합니다.</Korean> <Korean>공용화기 옆에 남은 탄들을 저장합니다.</Korean>
</Key> </Key>
<Key ID="STR_ACE_CSW_handleExtraMagazinesType_displayName">
<English>Ammo Storage</English>
</Key>
<Key ID="STR_ACE_CSW_handleExtraMagazinesType_description">
<English>Determines whether extra magazines are stored on the ground or inside an ammo box</English>
</Key>
<Key ID="STR_ACE_CSW_handleExtraMagazinesType_weaponHolder">
<English>Ground</English>
</Key>
<Key ID="STR_ACE_CSW_handleExtraMagazinesType_ammoBox">
<English>Ammo Box</English>
</Key>
<Key ID="STR_ACE_CSW_ammoHandling_displayName"> <Key ID="STR_ACE_CSW_ammoHandling_displayName">
<English>Ammo handling</English> <English>Ammo handling</English>
<German>Munitionsmanagement</German> <German>Munitionsmanagement</German>
@ -234,7 +246,7 @@
<Korean>공용화기의 조립 및 재장전 속도를에 관여하는 계수입니다.</Korean> <Korean>공용화기의 조립 및 재장전 속도를에 관여하는 계수입니다.</Korean>
</Key> </Key>
<Key ID="STR_ACE_CSW_dragAfterDeploy_displayName"> <Key ID="STR_ACE_CSW_dragAfterDeploy_displayName">
<English>Drag tripods after deploying</English> <English>Drag Tripods after Deploying</English>
<German>Ziehe Dreibeine nach Aufbau</German> <German>Ziehe Dreibeine nach Aufbau</German>
<Portuguese>Arrastar tripés após montar</Portuguese> <Portuguese>Arrastar tripés após montar</Portuguese>
<French>Glisser le trépied après déploiement</French> <French>Glisser le trépied après déploiement</French>
@ -622,7 +634,7 @@
<English>M3 Tripod</English> <English>M3 Tripod</English>
<Spanish>Trípode M3</Spanish> <Spanish>Trípode M3</Spanish>
<German>M3 Dreibein</German> <German>M3 Dreibein</German>
<Portuguese>M3 Tripé</Portuguese> <Portuguese>Tripé M3</Portuguese>
<French>Trépied M3</French> <French>Trépied M3</French>
<Japanese>M3 三脚</Japanese> <Japanese>M3 三脚</Japanese>
<Chinese>M3 三腳架</Chinese> <Chinese>M3 三腳架</Chinese>
@ -750,7 +762,7 @@
<English>[CSW] M3 Deployable Tripod</English> <English>[CSW] M3 Deployable Tripod</English>
<Spanish>[CSW] Trípode desplegable M3</Spanish> <Spanish>[CSW] Trípode desplegable M3</Spanish>
<German>[CSW] M3 aufstellbares Dreibein</German> <German>[CSW] M3 aufstellbares Dreibein</German>
<Portuguese>[CSW] M3 Tripe Ajustável</Portuguese> <Portuguese>[CSW] Tripe Ajustável M3</Portuguese>
<French>[CSW] M3 Trépied déployable</French> <French>[CSW] M3 Trépied déployable</French>
<Japanese>[CSW] M3 設置型三脚</Japanese> <Japanese>[CSW] M3 設置型三脚</Japanese>
<Chinese>[CSW] M3 部屬型三腳架</Chinese> <Chinese>[CSW] M3 部屬型三腳架</Chinese>