Rearm bugfixing (#5411)

* Added workaround functions for turret magazine ammo.

* Switched to retrieving turrets dynamically instead of looking them up from an array.

* Refactoring only, no functional changes

* Repurposed getNeedRearmMagazines as a general purpose rearm info function + more.

* The function retrieves all non-full magazines. This code was previously repeated in many different functions, but is now centralized in one.
* Empty pylon filling is no longer supported in favor of the upcoming "pylons" ACE-module.

Fixed bugs:

* Rearm was using broken commands "magazineTurretAmmo" and "setMagazineTurretAmmo". They are now replaced with their corresponding workaround functions.
* Pylon rearm was trying to set ammo count on empty pylons.

Note: rearmSuccessLocal is not yet fixed!

* Rearming no longer switches shell types in cannons/mortars.

* Added Tuupertunut to authors.

* Rearming no longer switches shell types. 2nd try.

Last time it was fixed only if the turret is manned. Now it is fixed even when unmanned.

* Updated fnc_rearm to support the earlier repurposing of fnc_getNeedRearmMagazines.

* Small fixes and comments.

* Renamed fnc_getVehicleMagazines to fnc_getTurretConfigMagazines.

The latter describes much better what the function actually does.

* Removed redundant checks.

* Refactoring.

* Fixed spaces in macros.

* Renamed fnc_getAllTurrets to fnc_getAllRearmTurrets
This commit is contained in:
Tuupertunut 2017-09-29 22:53:25 +03:00 committed by PabstMirror
parent 9dfc76b6d5
commit 0644ad9ca2
35 changed files with 326 additions and 254 deletions

View File

@ -128,6 +128,7 @@ Tessa Elieff <Fastroping Sound - CreativeCommons Attributions 3.0>
Toaster <jonathan.pereira@gmail.com> Toaster <jonathan.pereira@gmail.com>
Tonic Tonic
Tourorist <tourorist@gmail.com> Tourorist <tourorist@gmail.com>
Tuupertunut
Valentin Torikian <valentin.torikian@gmail.com> Valentin Torikian <valentin.torikian@gmail.com>
voiper voiper
VyMajoris(W-Cephei)<vycanismajoriscsa@gmail.com> VyMajoris(W-Cephei)<vycanismajoriscsa@gmail.com>

View File

@ -9,12 +9,14 @@ PREP(canTakeAmmo);
PREP(createDummy); PREP(createDummy);
PREP(disable); PREP(disable);
PREP(dropAmmo); PREP(dropAmmo);
PREP(getAllRearmTurrets);
PREP(getCaliber); PREP(getCaliber);
PREP(getHardpointMagazines); PREP(getHardpointMagazines);
PREP(getMaxMagazines); PREP(getMaxMagazines);
PREP(getNeedRearmMagazines); PREP(getNeedRearmMagazines);
PREP(getSupplyCount); PREP(getSupplyCount);
PREP(getVehicleMagazines); PREP(getTurretConfigMagazines);
PREP(getTurretMagazineAmmo);
PREP(grabAmmo); PREP(grabAmmo);
PREP(handleKilled); PREP(handleKilled);
PREP(handleUnconscious); PREP(handleUnconscious);
@ -32,6 +34,7 @@ PREP(rearmSuccess);
PREP(rearmSuccessLocal); PREP(rearmSuccessLocal);
PREP(removeMagazineFromSupply); PREP(removeMagazineFromSupply);
PREP(setSupplyCount); PREP(setSupplyCount);
PREP(setTurretMagazineAmmo);
PREP(storeAmmo); PREP(storeAmmo);
PREP(takeAmmo); PREP(takeAmmo);
PREP(takeSuccess); PREP(takeSuccess);

View File

@ -3,7 +3,7 @@
* Show the resupplyable ammunition of all surrounding vehicles. * Show the resupplyable ammunition of all surrounding vehicles.
* *
* Arguments: * Arguments:
* 0: Target <OBJECT> * 0: Ammo Truck <OBJECT>
* *
* Return Value: * Return Value:
* ChildActions <ARRAY> * ChildActions <ARRAY>
@ -15,7 +15,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [["_truck", objNull, [objNull]]]; params ["_truck"];
private _vehicles = nearestObjects [_truck, ["AllVehicles"], 20]; private _vehicles = nearestObjects [_truck, ["AllVehicles"], 20];
_vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && {!(_x getVariable [QGVAR(disabled), false])}}; _vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && {!(_x getVariable [QGVAR(disabled), false])}};
@ -23,49 +23,12 @@ _vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} &&
private _vehicleActions = []; private _vehicleActions = [];
{ {
private _vehicle = _x; private _vehicle = _x;
private _magazineHelper = [];
{
private _turretPath = _x;
private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines);
{
private _magazine = _x;
if (!(_magazine in _magazineHelper)) then {
private _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath);
private _maxMagazines = [_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines);
if ((_currentMagazines < _maxMagazines) || {(_vehicle magazineTurretAmmo [_magazine, _turretPath]) < getNumber (configFile >> "CfgMagazines" >> _magazine >> "count")}) then { // Array of magazines that can be rearmed in the vehicle
_magazineHelper pushBack _magazine; private _needRearmMags = ([_vehicle] call FUNC(getNeedRearmMagazines)) apply {_x select 0};
};
};
false
} count _magazines;
false
} count REARM_TURRET_PATHS;
// 1.70 pylons // _needRearmMags without duplicates
private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; private _magazineHelper = _needRearmMags arrayIntersect _needRearmMags;
{
private _pylonName = configName _x;
private _pylonAmmo = _vehicle ammoOnPylon _pylonName;
private _pylonMagazine = (getPylonMagazines _vehicle) select _forEachIndex;
TRACE_3("",_pylonName,_pylonAmmo,_pylonMagazine);
if (_pylonAmmo > 0) then {
// Try to refill current pylon:
private _magAmmo = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count");
if ((!(_pylonMagazine in _magazineHelper)) && {_pylonAmmo < _magAmmo}) then {
_magazineHelper pushBack _pylonMagazine;
};
} else {
// See what we magazines can add to the empty pylon:
private _hardpointMags = [_x] call FUNC(getHardpointMagazines);
{
if (!(_x in _magazineHelper)) then {
_magazineHelper pushBack _x;
};
} forEach _hardpointMags;
};
} forEach _pylonConfigs;
_magazineHelper = _magazineHelper select {[_truck, _x] call FUNC(hasEnoughSupply)}; _magazineHelper = _magazineHelper select {[_truck, _x] call FUNC(hasEnoughSupply)};
TRACE_2("can add",_x,_magazineHelper); TRACE_2("can add",_x,_magazineHelper);
@ -77,40 +40,46 @@ private _vehicleActions = [];
}; };
if (GVAR(level) == 0) then { if (GVAR(level) == 0) then {
// [Level 0] adds a single action to rearm the entire vic // [Level 0] adds a single action to rearm the entire vic
private _action = [_vehicle, private _action = [
_vehicle,
getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"),
_icon, _icon,
{_this call FUNC(rearmEntireVehicle)}, {_this call FUNC(rearmEntireVehicle)},
{true}, {true},
{}, {},
_vehicle] call EFUNC(interact_menu,createAction); _vehicle
] call EFUNC(interact_menu,createAction);
_vehicleActions pushBack [_action, [], _truck]; _vehicleActions pushBack [_action, [], _truck];
} else { } else {
// [Level 1,2] - Add actions for each magazine // [Level 1,2] - Add actions for each magazine
private _actions = []; private _actions = [];
{ {
private _action = [_x, private _action = [
_x,
getText(configFile >> "CfgMagazines" >> _x >> "displayName"), getText(configFile >> "CfgMagazines" >> _x >> "displayName"),
getText(configFile >> "CfgMagazines" >> _x >> "picture"), getText(configFile >> "CfgMagazines" >> _x >> "picture"),
{_this call FUNC(takeAmmo)}, {_this call FUNC(takeAmmo)},
{true}, {true},
{}, {},
[_x, _vehicle]] call EFUNC(interact_menu,createAction); [_x, _vehicle]
] call EFUNC(interact_menu,createAction);
_actions pushBack [_action, [], _truck]; _actions pushBack [_action, [], _truck];
} forEach _magazineHelper; } forEach _magazineHelper;
private _action = [_vehicle, private _action = [
_vehicle,
getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"),
_icon, _icon,
{}, {},
{true}, {true},
{}, {},
[]] call EFUNC(interact_menu,createAction); []
] call EFUNC(interact_menu,createAction);
_vehicleActions pushBack [_action, _actions, _truck]; _vehicleActions pushBack [_action, _actions, _truck];
}; };
}; };
false } forEach _vehicles;
} count _vehicles;
_vehicleActions _vehicleActions

View File

@ -29,16 +29,17 @@ if (_vehicle isEqualType objNull) then {_vehicle = typeOf _vehicle};
if (_vehicle == "") exitWith { if (_vehicle == "") exitWith {
ERROR_1("VehicleType [%1] is empty in ace_rearm_fnc_addVehicleMagazinesToSupply",_string); ERROR_1("VehicleType [%1] is empty in ace_rearm_fnc_addVehicleMagazinesToSupply",_string);
}; };
private _turrets = [_vehicle] call FUNC(getAllRearmTurrets);
{ {
private _turretPath = _x; private _turretPath = _x;
private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines); private _magazines = [_vehicle, _turretPath] call FUNC(getTurretConfigMagazines);
TRACE_2("",_turretPath,_magazines); TRACE_2("",_turretPath,_magazines);
{ {
[_truck, _x] call FUNC(addMagazineToSupply); [_truck, _x] call FUNC(addMagazineToSupply);
false false
} count _magazines; } count _magazines;
false false
} count REARM_TURRET_PATHS; } count _turrets;
// 1.70 pylons // 1.70 pylons
private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"];

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_truck", "_unit"];
["_truck", objNull, [objNull]],
["_unit", objNull, [objNull]]
];
(alive _unit) (alive _unit)
&& {_unit isKindOf "CAManBase"} && {_unit isKindOf "CAManBase"}

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_vehicle", "_unit"];
["_vehicle", objNull, [objNull]],
["_unit", objNull, [objNull]]
];
if (!alive _vehicle) exitWith {false}; if (!alive _vehicle) exitWith {false};
if (GVAR(level) == 0 || {isNull _unit} || {!(_unit isKindOf "CAManBase")} || {!local _unit} || {_vehicle distance _unit > REARM_ACTION_DISTANCE} || {_vehicle getVariable [QGVAR(disabled), false]}) exitWith {false}; if (GVAR(level) == 0 || {isNull _unit} || {!(_unit isKindOf "CAManBase")} || {!local _unit} || {_vehicle distance _unit > REARM_ACTION_DISTANCE} || {_vehicle getVariable [QGVAR(disabled), false]}) exitWith {false};
@ -29,4 +26,9 @@ if (isNull _dummy) exitwith {false};
private _magazineClass = _dummy getVariable QGVAR(magazineClass); private _magazineClass = _dummy getVariable QGVAR(magazineClass);
if (isNil "_magazineClass") exitWith {false}; if (isNil "_magazineClass") exitWith {false};
([_vehicle, _magazineClass] call FUNC(getNeedRearmMagazines)) select 0 private _needRearmMags = [_vehicle] call FUNC(getNeedRearmMagazines);
// Testing if vehicle needs rearm on any magazines of class _magazineClass
private _needsRearm = ({(_x select 0) isEqualTo _magazineClass} count _needRearmMags) > 0;
_needsRearm

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_truck", "_unit"];
["_truck", objNull, [objNull]],
["_unit", objNull, [objNull]]
];
(alive _unit) (alive _unit)
&& {_unit isKindOf "CAManBase"} && {_unit isKindOf "CAManBase"}

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_truck", "_unit"];
["_truck", objNull, [objNull]],
["_unit", objNull, [objNull]]
];
(alive _unit) (alive _unit)
&& {_unit isKindOf "CAManBase"} && {_unit isKindOf "CAManBase"}

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_unit", "_magazineClass"];
["_unit", objNull, [objNull]],
["_magazineClass", "", [""]]
];
private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo");
private _dummyName = getText (configFile >> "CfgAmmo" >> _ammo >> QGVAR(dummy)); private _dummyName = getText (configFile >> "CfgAmmo" >> _ammo >> QGVAR(dummy));

View File

@ -18,9 +18,9 @@
#include "script_component.hpp" #include "script_component.hpp"
params [ params [
["_unit", objNull, [objNull]], "_unit",
["_delete", false, [false]], ["_delete", false],
["_unholster", true, [true]] ["_unholster", true]
]; ];
private _dummy = _unit getVariable [QGVAR(dummy), objNull]; private _dummy = _unit getVariable [QGVAR(dummy), objNull];

View File

@ -0,0 +1,28 @@
/*
* Author: Tuupertunut
* Returns all turrets in a vehicle.
*
* BIS command "allTurrets" does not return the driver turret at the time of writing (2017-07-16).
* This function just adds driver turret to the array returned by "allTurrets".
*
* Arguments:
* 0: Vehicle <OBJECT>
*
* Return Value:
* Turret paths <ARRAY>
*
* Example:
* [vehicle] call ace_rearm_fnc_getAllRearmTurrets
*
* Public: No
*/
#include "script_component.hpp"
params ["_vehicle"];
private _turrets = allTurrets _vehicle;
// Adding the driver turret "[-1]".
_turrets pushBack [-1];
_turrets

View File

@ -18,7 +18,7 @@
#include "script_component.hpp" #include "script_component.hpp"
params [ params [
["_magazineClass", "", [""]] ["_magazineClass", ""]
]; ];
if (_magazineClass isEqualTo "") exitWith {[8, 2]}; if (_magazineClass isEqualTo "") exitWith {[8, 2]};

View File

@ -17,13 +17,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_vehicle", "_turretPath", "_magazineClass"];
["_vehicle", objNull, [objNull]],
["_turretPath", [], [[]]],
["_magazineClass", "", [""]]
];
if (isNull _vehicle) exitWith {0}; private _count = {_x == _magazineClass} count ([_vehicle, _turretPath] call FUNC(getTurretConfigMagazines));
private _count = {_x == _magazineClass} count ([_vehicle, _turretPath] call FUNC(getVehicleMagazines));
_count _count

View File

@ -1,78 +1,90 @@
/* /*
* Author: GitHawk, Jonpas * Author: Tuupertunut
* Get rearm return value. * Returns information about every magazine that can be rearmed in the vehicle. Multiple mags of
* same class in the same turret are grouped together for practical reasons.
* *
* Arguments: * Arguments:
* 0: Vehicle <OBJECT> * 0: Vehicle <OBJECT>
* 1: Magazine Classname <STRING>
* *
* Return Value: * Return Value:
* Return Value <ARRAY> * Magazine info <ARRAY of ARRAYs>
* 0: Can Rearm <BOOL> * Child arrays:
* 1: TurretPath <ARRAY> * 0: Magazine class <STRING>
* 2: Number of current magazines in turret path <NUMBER> * 1: Turret path <ARRAY>
* 3: Pylon Index (-1 if not a pylon) <NUMBER> * 2: Is pylon magazine <BOOLEAN>
* 3: Pylon index (-1 if not pylon) <NUMBER>
* 4: Max magazines <NUMBER>
* 5: Current magazines <NUMBER>
* 6: Max rounds per magazine <NUMBER>
* 7: Current rounds in magazines <ARRAY of NUMBERs>
* *
* Example: * Example:
* [tank, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_getNeedRearmMagazines * [tank] call ace_rearm_fnc_getNeedRearmMagazines
* *
* Public: No * Public: No
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [["_vehicle", objNull, [objNull]], ["_magazineClass", "", [""]]]; params ["_vehicle"];
private _return = [false, [], 0, -1]; private _magazineInfo = [];
// 1.70 pylons
private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"];
{ {
private _magazines = [_vehicle, _x] call FUNC(getVehicleMagazines); private _pylonConfig = _x;
if (_magazineClass in _magazines) then { // Strangely, a 1-based index.
private _currentMagazines = {_x == _magazineClass} count (_vehicle magazinesTurret _x); private _pylonIndex = _forEachIndex + 1;
if ((_vehicle magazineTurretAmmo [_magazineClass, _x]) < getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count")) exitWith { // Retrieving pylon magazine by index. If the pylon is empty, it is marked with "".
_return = [true, _x, _currentMagazines, -1]; private _pylonMagazine = (getPylonMagazines _vehicle) select (_pylonIndex - 1);
};
if (_currentMagazines < ([_vehicle, _x, _magazineClass] call FUNC(getMaxMagazines))) exitWith { // Only care about pylons that have a magazine.
_return = [true, _x, _currentMagazines, -1]; if (!(_pylonMagazine isEqualTo "")) then {
private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count");
private _currentRounds = _vehicle ammoOnPylon _pylonIndex;
if (_currentRounds < _maxRounds) then {
private _pylonTurret = getArray (_pylonConfig >> "turret");
// Converting to expected array for driver.
if (_pylonTurret isEqualTo []) then {_pylonTurret = [-1];};
_magazineInfo pushBack [_pylonMagazine, _pylonTurret, true, _pylonIndex, 1, 1, _maxRounds, [_currentRounds]];
}; };
}; };
} forEach _pylonConfigs;
if (_return select 0) exitWith {}; private _turrets = [_vehicle] call FUNC(getAllRearmTurrets);
false {
} count REARM_TURRET_PATHS; private _turretPath = _x;
private _magazines = [_vehicle, _turretPath] call FUNC(getTurretConfigMagazines);
// _magazines without duplicates
private _magazineClasses = _magazines arrayIntersect _magazines;
if (!(_return select 0)) then {
// 1.70 pylons
private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"];
{ {
private _pylonName = configName _x; private _magazineClass = _x;
private _pylonIndex = _forEachIndex + 1; // WTF BIS
private _pylonAmmo = _vehicle ammoOnPylon _pylonName;
private _pylonMagazine = (getPylonMagazines _vehicle) select _forEachIndex;
private _pylonTurret = getArray (_x >> "turret");
if (_pylonTurret isEqualTo []) then {_pylonTurret = [-1];}; // convert to expected array for driver
TRACE_4("",_pylonName,_pylonAmmo,_pylonMagazine,_pylonTurret);
if (_pylonAmmo > 0) then { private _maxMagazines = [_vehicle, _turretPath, _magazineClass] call FUNC(getMaxMagazines);
if (_magazineClass == _pylonMagazine) then { // Try to refill current pylon: private _maxRoundsPerMag = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count");
private _magAmmo = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count");
if (_pylonAmmo < _magAmmo) then {
_return = [true, _pylonTurret, 0, _pylonIndex];
};
};
} else {
// See what we magazines can add to the empty pylon:
private _hardpointMags = [_x] call FUNC(getHardpointMagazines);
{
if (_x == _magazineClass) then {
_return = [true, _pylonTurret, 0, _pylonIndex];
};
} forEach _hardpointMags;
};
if (_return select 0) exitWith {};
} forEach _pylonConfigs;
};
TRACE_3("getNeedRearmMagazines",_vehicle,_magazineClass,_return); /* Array of ammo counts in every magazine. Example: [200, 200, 152] means 2 mags with 200
_return * rounds and 1 mag with 152 rounds. */
private _currentRounds = [_vehicle, _turretPath, _magazineClass] call FUNC(getTurretMagazineAmmo);
private _currentMagazines = count _currentRounds;
/* If there is space for new magazines or if some magazines are not full, add the magazine
* type to _magazineInfo. */
if ((_currentMagazines < _maxMagazines) || {({_x < _maxRoundsPerMag} count _currentRounds) > 0}) then {
_magazineInfo pushBack [_magazineClass, _turretPath, false, -1, _maxMagazines, _currentMagazines, _maxRoundsPerMag, _currentRounds];
};
} forEach _magazineClasses;
} forEach _turrets;
TRACE_2("getNeedRearmMagazines",_vehicle,_magazineInfo);
_magazineInfo

View File

@ -10,7 +10,7 @@
* Magazine classes in TurretPath <ARRAY> * Magazine classes in TurretPath <ARRAY>
* *
* Example: * Example:
* [vehicle, [0]] call ace_rearm_fnc_getVehicleMagazines * [vehicle, [0]] call ace_rearm_fnc_getTurretConfigMagazines
* *
* Public: No * Public: No
*/ */

View File

@ -0,0 +1,27 @@
/*
* Author: Tuupertunut
* Returns the current ammo counts in all magazines of given class in turret.
*
* BIS command "magazineTurretAmmo" is broken at the time of writing (2017-06-24)
* (https://feedback.bistudio.com/T79689). This function is intended as a workaround for it,
* extracting the data from the array returned by "magazinesAllTurrets".
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Turret Path <ARRAY>
* 2: Magazine Classname <STRING>
*
* Return Value:
* Current ammo counts in magazines. <ARRAY of NUMBERs>
*
* Example:
* [vehicle, [0], "200Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_getTurretMagazineAmmo
*
* Public: No
*/
#include "script_component.hpp"
params ["_vehicle", "_turretPath", "_magazineClass"];
private _ammo = magazinesAllTurrets _vehicle select {(_x select 0) isEqualTo _magazineClass && {(_x select 1) isEqualTo _turretPath}} apply {_x select 2};
_ammo

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_dummy", "_unit"];
["_dummy", objNull, [objNull]],
["_unit", objNull, [objNull]]
];
REARM_HOLSTER_WEAPON; REARM_HOLSTER_WEAPON;
[_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set); [_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set);

View File

@ -15,9 +15,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_unit"];
["_unit", objNull, [objNull]]
];
if (!local _unit) exitWith {}; if (!local _unit) exitWith {};

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_unit", "_isUnconscious"];
["_unit", objNull, [objNull]],
["_isUnconscious", false, [false]]
];
if (!local _unit || {!_isUnconscious}) exitWith {}; if (!local _unit || {!_isUnconscious}) exitWith {};

View File

@ -16,9 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [["_truck", objNull, [objNull]], ["_magazineClass", "", [""]]]; params ["_truck", "_magazineClass"];
if (isNull _truck || {_magazineClass isEqualTo ""}) exitWith {false};
// With infinite supply, there is always enough // With infinite supply, there is always enough
if (GVAR(supply) == 0) exitWith {true}; if (GVAR(supply) == 0) exitWith {true};

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_obj", "_dirAndUp"];
["_obj", objNull, [objNull]],
["_dirAndUp", [[1,0,0],[0,0,1]], [[]]]
];
_obj setVectorDirAndUp _dirAndUp; _obj setVectorDirAndUp _dirAndUp;
_obj allowDamage false; _obj allowDamage false;

View File

@ -1,6 +1,6 @@
/* /*
* Author: GitHawk * Author: GitHawk
* Module for adjusting the refuel settings. * Module for adjusting the rearm settings.
* *
* Arguments: * Arguments:
* 0: The module logic <OBJECT> * 0: The module logic <OBJECT>
@ -28,4 +28,4 @@ if (!_activated) exitWith {};
[_logic, QGVAR(level), "level"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(level), "level"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(supply), "supply"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(supply), "supply"] call EFUNC(common,readSettingFromModule);
INFO_2("Module Initialized [level: %1][supply: %2]", GVAR(level), GVAR(supply)); INFO_2("Module Initialized [level: %1][supply: %2]",GVAR(level),GVAR(supply));

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_dummy", "_unit"];
["_dummy", objNull, [objNull]],
["_unit", objNull, [objNull]]
];
private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull];
if !(isNull _attachedDummy) exitWith {}; if !(isNull _attachedDummy) exitWith {};

View File

@ -16,7 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [["_truck", objNull, [objNull]],["_unit", objNull, [objNull]]]; params ["_truck", "_unit"];
TRACE_2("readSupplyCounter",_truck,_unit); TRACE_2("readSupplyCounter",_truck,_unit);
if (GVAR(supply) == 0) exitWith {WARNING("Supply is unlimited");}; if (GVAR(supply) == 0) exitWith {WARNING("Supply is unlimited");};

View File

@ -16,7 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [["_target", objNull, [objNull]],["_unit", objNull, [objNull]]]; params ["_target", "_unit"];
TRACE_2("rearm",_target,_unit); TRACE_2("rearm",_target,_unit);
private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull];
@ -27,21 +27,24 @@ if (isNil "_magazineClass") exitWith {ERROR_1("magazineClass nil",_attachedDummy
([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"]; ([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"];
// Get magazines that can be rearmed // Get magazines that can be rearmed
private _needRearmMags = [_target, _magazineClass] call FUNC(getNeedRearmMagazines); private _needRearmMags = [_target] call FUNC(getNeedRearmMagazines);
_needRearmMags params ["_needRearm", "_turretPath", "_cnt", "_pylon"]; private _needRearmMagsOfClass = _needRearmMags select {(_x select 0) isEqualTo _magazineClass};
// Exit if no magazines need rearming // Exit if no magazines need rearming
if (!_needRearm) exitWith {ERROR_2("Could not find turret for %1 in %2", _magazineClass, typeOf _target);}; if ((count _needRearmMagsOfClass) == 0) exitWith {ERROR_2("Could not find turret for %1 in %2",_magazineClass,typeOf _target);};
private _currentRearmableMag = _needRearmMagsOfClass select 0;
_currentRearmableMag params ["", "_turretPath", "", "_pylon", "", "_magazineCount"];
private _magazineDisplayName = getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"); private _magazineDisplayName = getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName");
if (_magazineDisplayName == "") then { if (_magazineDisplayName == "") then {
_magazineDisplayName = _magazineClass; _magazineDisplayName = _magazineClass;
ERROR_1("Magazine is missing display name [%1]", _magazineClass); ERROR_1("Magazine is missing display name [%1]",_magazineClass);
}; };
[ [
TIME_PROGRESSBAR(REARM_DURATION_REARM select _idx), TIME_PROGRESSBAR(REARM_DURATION_REARM select _idx),
[_target, _unit, _turretPath, _cnt, _magazineClass, (REARM_COUNT select _idx), _pylon], [_target, _unit, _turretPath, _magazineCount, _magazineClass, (REARM_COUNT select _idx), _pylon],
{(_this select 0) call FUNC(rearmSuccess)}, {(_this select 0) call FUNC(rearmSuccess)},
"", "",
format [localize LSTRING(RearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName"), _magazineDisplayName], format [localize LSTRING(RearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName"), _magazineDisplayName],

View File

@ -17,11 +17,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_truck", "", "_vehicle"];
["_truck", objNull, [objNull]],
"",
["_vehicle", objNull, [objNull]]
];
[ [
TIME_PROGRESSBAR(10), TIME_PROGRESSBAR(10),

View File

@ -5,7 +5,7 @@
* Arguments: * Arguments:
* 0: Rearm information <ARRAY> * 0: Rearm information <ARRAY>
* 0: Ammo Truck <OBJECT> * 0: Ammo Truck <OBJECT>
* 1: Vehicle <OBJECT * 1: Vehicle <OBJECT>
* *
* Return Value: * Return Value:
* None * None
@ -18,10 +18,11 @@
#include "script_component.hpp" #include "script_component.hpp"
params ["_args"]; params ["_args"];
_args params [["_truck", objNull, [objNull]], ["_vehicle", objNull, [objNull]]]; _args params ["_truck", "_vehicle"];
TRACE_2("rearmEntireVehicleSuccess",_truck,_vehicle); TRACE_2("rearmEntireVehicleSuccess",_truck,_vehicle);
if (isServer) then { if (isServer) then {
private _turrets = [_vehicle] call FUNC(getAllRearmTurrets);
{ {
private _turretOwnerID = _vehicle turretOwner _x; private _turretOwnerID = _vehicle turretOwner _x;
if (_turretOwnerID == 0) then { if (_turretOwnerID == 0) then {
@ -30,7 +31,7 @@ if (isServer) then {
[QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _turretOwnerID] call CBA_fnc_ownerEvent; [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _turretOwnerID] call CBA_fnc_ownerEvent;
}; };
false false
} count REARM_TURRET_PATHS; } count _turrets;
} else { } else {
[QGVAR(rearmEntireVehicleSuccessEH), _this] call CBA_fnc_serverEvent; [QGVAR(rearmEntireVehicleSuccessEH), _this] call CBA_fnc_serverEvent;
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Author: GitHawk * Author: Tuupertunut
* Rearm an entire turret locally. * Rearm an entire turret locally.
* *
* Arguments: * Arguments:
@ -17,60 +17,42 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [["_truck", objNull, [objNull]], ["_vehicle", objNull, [objNull]], ["_turretPath", [], [[]]]]; params ["_truck", "_vehicle", "_turretPath"];
TRACE_3("rearmEntireVehicleSuccessLocal",_truck,_vehicle,_turretPath); TRACE_3("rearmEntireVehicleSuccessLocal",_truck,_vehicle,_turretPath);
// 1.70 pylons // Fetching all rearmable magazines in this turret
private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; private _magazines = ([_vehicle] call FUNC(getNeedRearmMagazines)) select {(_x select 1) isEqualTo _turretPath};
{ {
private _pylonTurret = getArray (_x >> "turret"); _x params ["_magazineClass", "_magTurretPath", "_isPylonMag", "_pylonIndex", "_maxMagazines", "_currentMagazines", "_maxRoundsPerMag", "_currentRounds"];
if (_pylonTurret isEqualTo []) then {_pylonTurret = [-1];}; // convert to expected array for driver
if (_pylonTurret isEqualTo _turretPath) then {
private _pylonIndex = _forEachIndex + 1; // GJ BIS
private _pylonAmmo = _vehicle ammoOnPylon _pylonIndex;
private _pylonMagazine = (getPylonMagazines _vehicle) select _forEachIndex;
private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count");
TRACE_4("",_pylonIndex,_pylonAmmo,_maxRounds,_pylonMagazine);
if (_pylonAmmo < _maxRounds) then {
if ((GVAR(supply) == 0) || {[_truck, _pylonMagazine, (_maxRounds - _pylonAmmo)] call FUNC(removeMagazineFromSupply)}) then {
TRACE_3("Adding Rounds",_vehicle,_pylonIndex,_maxRounds);
_vehicle setAmmoOnPylon [_pylonIndex, _maxRounds];
};
};
};
} forEach _pylonConfigs;
private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines); // Array of planned ammo counts in every magazine after the rearm is complete
if (isNil "_magazines") exitWith {}; private _plannedRounds = +_currentRounds;
{
private _magazine = _x;
private _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath);
private _maxMagazines = [_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines);
private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count");
private _currentRounds = _vehicle magazineTurretAmmo [_magazine, _turretPath];
TRACE_7("Rearmed Turret",_vehicle,_turretPath,_currentMagazines,_maxMagazines,_currentRounds,_maxRounds,_magazine); // Trying to fill all existing magazines.
{
if (_turretPath isEqualTo [-1] && _currentMagazines == 0) then { if (_x < _maxRoundsPerMag) then {
// On driver, the empty magazine is still there, but is not returned by magazinesTurret if ((GVAR(supply) == 0) || {[_truck, _magazineClass, (_maxRoundsPerMag - _x)] call FUNC(removeMagazineFromSupply)}) then {
_currentMagazines = _currentMagazines + 1; _plannedRounds set [_forEachIndex, _maxRoundsPerMag];
}; };
};
} forEach _currentRounds;
// Trying to add new full magazines, if there is space left.
if (_currentMagazines < _maxMagazines) then { if (_currentMagazines < _maxMagazines) then {
private _success = true;
if ((GVAR(supply) == 0) || {[_truck, _magazine, (_maxRounds - _currentRounds)] call FUNC(removeMagazineFromSupply)}) then {
_vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath];
};
for "_idx" from 1 to (_maxMagazines - _currentMagazines) do { for "_idx" from 1 to (_maxMagazines - _currentMagazines) do {
if ((GVAR(supply) == 0) || {[_truck, _magazine, _maxRounds] call FUNC(removeMagazineFromSupply)}) then { if ((GVAR(supply) == 0) || {[_truck, _magazineClass, _maxRoundsPerMag] call FUNC(removeMagazineFromSupply)}) then {
_vehicle addMagazineTurret [_magazine, _turretPath]; _plannedRounds pushBack _maxRoundsPerMag;
}; };
}; };
} else {
if ((GVAR(supply) == 0) || {[_truck, _magazine, (_maxRounds - _currentRounds)] call FUNC(removeMagazineFromSupply)}) then {
_vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath];
}; };
};
false TRACE_2("rearming",_x,_plannedRounds);
} count _magazines;
// Updating new ammo counts to vehicle.
if (_isPylonMag) then {
_vehicle setAmmoOnPylon [_pylonIndex, (_plannedRounds select 0)];
} else {
[_vehicle, _magTurretPath, _magazineClass, _plannedRounds] call FUNC(setTurretMagazineAmmo);
};
} forEach _magazines;

View File

@ -21,7 +21,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [["_vehicle", objNull, [objNull]], ["_unit", objNull, [objNull]], "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"]; params ["_vehicle", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"];
TRACE_7("rearmSuccess",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds,_pylon); TRACE_7("rearmSuccess",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds,_pylon);
if (local _unit) then { if (local _unit) then {

View File

@ -23,6 +23,6 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { // only run this after the s
params [["_truck", objNull, [objNull]], ["_supply", 0, [0]]]; params [["_truck", objNull, [objNull]], ["_supply", 0, [0]]];
if (GVAR(supply) != 1) exitWith {WARNING("supply setting is not set to limited");}; if (GVAR(supply) != 1) exitWith {WARNING("supply setting is not set to limited");};
if (isNull _truck) exitWith {WARNING_1("Truck is null [%1]", _truck);}; if (isNull _truck) exitWith {WARNING_1("Truck is null [%1]",_truck);};
_truck setVariable [QGVAR(currentSupply), (_supply max 0), true]; _truck setVariable [QGVAR(currentSupply), (_supply max 0), true];

View File

@ -0,0 +1,89 @@
/*
* Author: Tuupertunut
* Sets the ammo counts of all magazines of given class in turret.
*
* BIS command "setMagazineTurretAmmo" is broken at the time of writing (2017-06-24)
* (https://feedback.bistudio.com/T79689). This function is intended as a workaround for it. All
* magazines are removed and then added again with updated ammo counts.
* Note: As an unintended side effect, the turret reloads after running this function.
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Turret Path <ARRAY>
* 2: Magazine Classname <STRING>
* 3: Ammo Counts in Magazines <ARRAY of NUMBERs>
*
* Return Value:
* None
*
* Example:
* [vehicle, [0], "200Rnd_127x99_mag_Tracer_Red", [200, 152]] call ace_rearm_fnc_setTurretMagazineAmmo
*
* Public: No
*/
#include "script_component.hpp"
params ["_vehicle", "_turretPath", "_magazineClass", "_ammoCounts"];
// Checking if a magazine of given class is currently loaded in any weapon.
private _magLoadedInWeapon = false;
private _loadedWeapon = "";
{
private _currentlyLoadedMag = (weaponState [_vehicle, _turretPath, _x]) select 3;
if (_currentlyLoadedMag isEqualTo _magazineClass) exitWith {
_magLoadedInWeapon = true;
_loadedWeapon = _x;
};
} forEach (_vehicle weaponsTurret _turretPath);
if (!_magLoadedInWeapon) then {
/* The easy case:
* The magazine class was not loaded, so we can just remove those magazines and
* add them back with updated ammo counts. */
_vehicle removeMagazinesTurret [_magazineClass, _turretPath];
{
_vehicle addMagazineTurret [_magazineClass, _turretPath, _x];
} forEach _ammoCounts;
} else {
/* Special hack case:
* The magazine class was loaded into a weapon. If the weapon has more than one type of
* magazine (e.g. AP and HEAT in a cannon), then removing all magazines would trigger the
* weapon to load a different magazine type. For example, removing the HEAT shells while HEAT
* is loaded makes the cannon switch to AP.
*
* To prevent that, we must remove all magazines that would fit into the weapon and then add
* them back with the magazine-to-be-loaded being the first. */
private _allowedMagClassesInWeapon = getArray (configFile >> "CfgWeapons" >> _loadedWeapon >> "magazines");
/* Current ammo counts of all allowed magazine classes in weapon.
* Example: [["8Rnd_82mm_Mo_shells", [8, 8, 2]], ["8Rnd_82mm_Mo_Flare_white", [7]]] */
private _ammoCountsByMagClass = _allowedMagClassesInWeapon apply {[_x, ([_vehicle, _turretPath, _x] call FUNC(getTurretMagazineAmmo))]};
// Removing all magazines that fit into the weapon.
{
_vehicle removeMagazinesTurret [_x, _turretPath];
} forEach _allowedMagClassesInWeapon;
// Adding the mags of the given class first with updated ammo counts.
{
_vehicle addMagazineTurret [_magazineClass, _turretPath, _x];
} forEach _ammoCounts;
// Adding back all other magazines with their original ammo counts.
{
_x params ["_loopMagClass", "_loopAmmoCounts"];
if (!(_loopMagClass isEqualTo _magazineClass)) then {
{
_vehicle addMagazineTurret [_loopMagClass, _turretPath, _x];
} forEach _loopAmmoCounts;
};
} forEach _ammoCountsByMagClass;
};
TRACE_5("setTurretMagazineAmmo",_vehicle,_turretPath,_magazineClass,_ammoCounts,_loadedWeapon);

View File

@ -16,10 +16,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_truck", "_unit"];
["_truck", objNull, [objNull]],
["_unit", objNull, [objNull]]
];
private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull];
if (isNull _attachedDummy) exitwith {}; if (isNull _attachedDummy) exitwith {};

View File

@ -19,11 +19,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [ params ["_truck", "_unit", "_args"];
["_truck", objNull, [objNull]],
["_unit", objNull, [objNull]],
["_args", ["", objNull], [[]]]
];
_args params ["_magazineClass", "_vehicle"]; _args params ["_magazineClass", "_vehicle"];
TRACE_5("takeAmmo",_truck,_unit,_args,_magazineClass,_vehicle); TRACE_5("takeAmmo",_truck,_unit,_args,_magazineClass,_vehicle);

View File

@ -18,7 +18,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params [["_args", [objNull, "", objNull], [[]], 3]]; params ["_args"];
_args params ["_unit", "_magazineClass", "_truck"]; _args params ["_unit", "_magazineClass", "_truck"];
TRACE_3("takeSuccess",_unit,_magazineClass,_truck); TRACE_3("takeSuccess",_unit,_magazineClass,_truck);

View File

@ -19,7 +19,6 @@
#define REARM_ACTION_DISTANCE 7 #define REARM_ACTION_DISTANCE 7
#define REARM_TURRET_PATHS [[-1], [0], [0,0], [0,1], [1], [2], [0,2]]
#define REARM_CALIBERS [ 6, 7, 8, 13, 19, 20, 25, 30, 35, 39, 40, 60, 70, 80, 82, 100, 105, 120, 122, 125, 155, 230, 250] #define REARM_CALIBERS [ 6, 7, 8, 13, 19, 20, 25, 30, 35, 39, 40, 60, 70, 80, 82, 100, 105, 120, 122, 125, 155, 230, 250]
#define REARM_DURATION_TAKE [ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 13, 10] #define REARM_DURATION_TAKE [ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 13, 10]