Rearm - Pylon Support and Dynamically Add Supply Actions (#5183)

* Dynamic Add

* Support 1.70 Pylon Loadouts

* Properly handle old compat pbos - Update RHS Compat

* Re-add documentation

* cleanup headers (note from other pr)

* Cleanup

* Fix var spelling
This commit is contained in:
PabstMirror 2017-06-08 11:47:52 -05:00 committed by GitHub
parent 1be9e7ca30
commit f35f80ee82
39 changed files with 678 additions and 541 deletions

View File

@ -6,7 +6,7 @@
* 0: Text <ANY>
* 1: Size of the textbox <NUMBER> (default: 1.5)
* 2: Target Unit. Will only display if target is the player controlled object <OBJECT> (default: ACE_player)
* 3: Custom Width <NUMBER> (optional)
* 3: Custom Width <NUMBER> (default: 10)
*
* Return Value:
* None

View File

@ -3,7 +3,7 @@
#include "\z\ace\addons\main\script_mod.hpp"
// #define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE
#define DISABLE_COMPILE_CACHE
// #define ENABLE_PERFORMANCE_COUNTERS
#ifdef DEBUG_ENABLED_COMMON

View File

@ -1,64 +1,16 @@
#define MACRO_REARM_ACTIONS \
class ACE_Actions { \
class ACE_MainActions { \
class GVAR(Rearm) { \
displayName = CSTRING(Rearm); \
distance = REARM_ACTION_DISTANCE; \
condition = QUOTE(_this call FUNC(canRearm)); \
statement = QUOTE(_this call FUNC(rearm)); \
exceptions[] = {"isNotInside"}; \
icon = QPATHTOF(ui\icon_rearm_interact.paa); \
}; \
class ACE_Actions { \
class ACE_MainActions { \
class GVAR(Rearm) { \
displayName = CSTRING(Rearm); \
distance = REARM_ACTION_DISTANCE; \
condition = QUOTE(_this call FUNC(canRearm)); \
statement = QUOTE(_this call FUNC(rearm)); \
exceptions[] = {"isNotInside"}; \
icon = QPATHTOF(ui\icon_rearm_interact.paa); \
}; \
};
#define MACRO_REARM_TRUCK_ACTIONS \
class ACE_Actions: ACE_Actions { \
class ACE_MainActions: ACE_MainActions { \
class GVAR(ReadSupplyCounter) { \
displayName = CSTRING(ReadSupplyCounter); \
distance = REARM_ACTION_DISTANCE; \
condition = QUOTE(_this call FUNC(canReadSupplyCounter)); \
statement = QUOTE(_this call FUNC(readSupplyCounter)); \
exceptions[] = {"isNotInside"}; \
showDisabled = 0; \
priority = 2; \
icon = PATHTOF(ui\icon_rearm_interact.paa); \
}; \
class GVAR(Rearm) { \
displayName = CSTRING(Rearm); \
distance = REARM_ACTION_DISTANCE; \
condition = QUOTE(_this call FUNC(canRearmVehicle)); \
insertChildren = QUOTE(_target call FUNC(addRearmActions)); \
exceptions[] = {"isNotInside"}; \
showDisabled = 0; \
priority = 2; \
icon = PATHTOF(ui\icon_rearm_interact.paa); \
}; \
class GVAR(TakeAmmo) { \
displayName = CSTRING(TakeAmmo); \
distance = REARM_ACTION_DISTANCE; \
condition = QUOTE(_this call FUNC(canTakeAmmo)); \
insertChildren = QUOTE(_target call FUNC(addRearmActions)); \
exceptions[] = {"isNotInside"}; \
showDisabled = 0; \
priority = 2; \
icon = QPATHTOF(ui\icon_rearm_interact.paa); \
}; \
class GVAR(StoreAmmo) { \
displayName = CSTRING(StoreAmmo); \
distance = REARM_ACTION_DISTANCE; \
condition = QUOTE(_this call FUNC(canStoreAmmo)); \
statement = QUOTE(_this call FUNC(storeAmmo)); \
exceptions[] = {"isNotInside"}; \
icon = QPATHTOF(ui\icon_rearm_interact.paa); \
}; \
}; \
};
#define MACRO_REARM_DEFAULT_SUPPLY \
GVAR(defaultSupply) = 1200;
}; \
};
class CBA_Extended_EventHandlers;
@ -148,96 +100,71 @@ class CfgVehicles {
MACRO_REARM_ACTIONS
};
// Ammo Vehicles (with full inheritance for granted ACE_Actions)
class Car_F: Car {};
class Truck_F: Car_F {};
class Tank_F: Tank {};
class Truck_03_base_F: Truck_F {};
class Truck_03_base_F;
class O_Truck_03_ammo_F: Truck_03_base_F {
transportAmmo = 0;
MACRO_REARM_DEFAULT_SUPPLY
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class Truck_02_base_F: Truck_F {};
class Truck_02_Ammo_base_F: Truck_02_base_F {};
class Truck_02_Ammo_base_F;
class I_Truck_02_ammo_F: Truck_02_Ammo_base_F {
transportAmmo = 0;
MACRO_REARM_DEFAULT_SUPPLY
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class O_Truck_02_Ammo_F: Truck_02_Ammo_base_F {
transportAmmo = 0;
MACRO_REARM_DEFAULT_SUPPLY
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class Truck_01_base_F: Truck_F {};
class B_Truck_01_transport_F: Truck_01_base_F {};
class B_Truck_01_mover_F: B_Truck_01_transport_F {};
class B_Truck_01_mover_F;
class B_Truck_01_ammo_F: B_Truck_01_mover_F {
transportAmmo = 0;
MACRO_REARM_DEFAULT_SUPPLY
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class APC_Tracked_01_base_F: Tank_F {};
class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {};
class B_APC_Tracked_01_base_F;
class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F {
transportAmmo = 0;
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class Helicopter_Base_F: Helicopter {};
class Helicopter_Base_H: Helicopter_Base_F {};
class Heli_Transport_04_base_F: Helicopter_Base_H {};
class Heli_Transport_04_base_F;
class O_Heli_Transport_04_ammo_F: Heli_Transport_04_base_F {
transportAmmo = 0;
MACRO_REARM_DEFAULT_SUPPLY
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class ThingX;
class ReammoBox_F: ThingX {
class ACE_Actions {
class ACE_MainActions {};
};
};
class Slingload_base_F: ReammoBox_F {};
class Slingload_01_Base_F: Slingload_base_F {};
class Pod_Heli_Transport_04_base_F: Slingload_base_F {};
class Pod_Heli_Transport_04_base_F;
class Land_Pod_Heli_Transport_04_ammo_F: Pod_Heli_Transport_04_base_F {
transportAmmo = 0;
MACRO_REARM_DEFAULT_SUPPLY
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class Slingload_01_Base_F;
class B_Slingload_01_Ammo_F: Slingload_01_Base_F {
transportAmmo = 0;
MACRO_REARM_DEFAULT_SUPPLY
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class ReammoBox_F;
class NATO_Box_Base: ReammoBox_F{};
class Box_NATO_AmmoVeh_F: NATO_Box_Base {
transportAmmo = 0;
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class EAST_Box_Base: ReammoBox_F{};
class Box_East_AmmoVeh_F: EAST_Box_Base {
transportAmmo = 0;
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
class IND_Box_Base: ReammoBox_F{};
class Box_IND_AmmoVeh_F: IND_Box_Base {
transportAmmo = 0;
MACRO_REARM_TRUCK_ACTIONS
GVAR(defaultSupply) = 1200;
};
// Dummy Vehicles
class ThingX;
class GVAR(defaultCarriedObject): ThingX {
class EventHandlers {
class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};

View File

@ -4,14 +4,13 @@ PREP(addRearmActions);
PREP(addVehicleMagazinesToSupply);
PREP(canReadSupplyCounter);
PREP(canRearm);
PREP(canRearmVehicle);
PREP(canStoreAmmo);
PREP(canTakeAmmo);
PREP(createDummy);
PREP(disable);
PREP(dropAmmo);
PREP(getCaliber);
PREP(getConfigMagazines);
PREP(getHardpointMagazines);
PREP(getMaxMagazines);
PREP(getNeedRearmMagazines);
PREP(getSupplyCount);
@ -20,7 +19,7 @@ PREP(grabAmmo);
PREP(handleKilled);
PREP(handleUnconscious);
PREP(hasEnoughSupply);
PREP(magazineInSupply);
PREP(initSupplyVehicle);
PREP(makeDummy);
PREP(moduleRearmSettings);
PREP(pickUpAmmo);

View File

@ -1,5 +1,13 @@
#include "script_component.hpp"
GVAR(hardpointGroupsCache) = [] call CBA_fnc_createNamespace;
GVAR(configTypesAdded) = [];
["ace_settingsInitialized", {
TRACE_2("settingsInit",GVAR(level),GVAR(supply));
["LandVehicle", "Init", {_this call FUNC(initSupplyVehicle)}, true, ["StaticWeapon"], true] call CBA_fnc_addClassEventHandler;
["ReammoBox_F", "Init", {_this call FUNC(initSupplyVehicle)}, true, [], true] call CBA_fnc_addClassEventHandler;
}] call CBA_fnc_addEventHandler;
["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler;
["vehicle", {
params ["_unit"];

View File

@ -1,11 +1,11 @@
/*
* Author: GitHawk
* Adds magazines to the supply.
* Adds magazines to the supply. [Global Effects]
*
* Arguments:
* 0: Ammo Truck <OBJECT>
* 1: Magazine Classname <STRING>
* 2: Only partial <BOOL>(optional)
* 2: Only partial <BOOL> (default: false)
*
* Return Value:
* None
@ -17,27 +17,30 @@
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]],
["_magazineClass", "", [""]],
["_partial", false, [false]]
];
if !(EGVAR(common,settingsInitFinished)) exitWith { // only run this after the settings are initialized
EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addMagazineToSupply), _this];
};
if (isNull _truck ||
{_magazineClass isEqualTo ""} ||
{GVAR(supply) == 0}) exitWith {};
params [["_truck", objNull, [objNull]], ["_magazineClass", "", [""]], ["_partial", false, [false]]];
TRACE_3("addMagazineToSupply",_truck,_magazineClass,_partial);
if (GVAR(supply) == 0) exitWith {WARNING("supply setting is set to unlimited");};
if (isNull _truck || {_magazineClass isEqualTo ""}) exitWith {};
([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"];
// With limited supply, we add the caliber to the supply count
if (GVAR(supply) == 1) then {
private _supply = [_truck] call FUNC(getSupplyCount);
if (!_partial || {GVAR(level) == 1}) then {
[_truck, _supply + _cal] call FUNC(setSupplyCount);
private _amountToAdd = if (!_partial || {GVAR(level) == 1}) then {
_cal
} else {
private _magazinePart = ((REARM_COUNT select _idx) / (getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"))) min 1;
[_truck, (_supply + (_cal * _magazinePart))] call FUNC(setSupplyCount);
_cal * _magazinePart
};
TRACE_1("Adding",_amountToAdd);
[_truck, (_supply + _amountToAdd)] call FUNC(setSupplyCount);
};
// With magazine specific supply, we add or update the magazineSupply array
@ -56,7 +59,7 @@ if (GVAR(supply) == 2) then {
_roundsPerTransaction = _roundsPerTransaction min (REARM_COUNT select _idx);
};
if (_magazineIdx == -1) then {
if (count _magazineSupply == 0) then {
if (_magazineSupply isEqualTo []) then {
_magazineSupply = [[_magazineClass, _roundsPerTransaction]];
} else {
_magazineSupply append [[_magazineClass, _roundsPerTransaction]];

View File

@ -15,77 +15,92 @@
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]]
];
params [["_truck", objNull, [objNull]]];
private _vehicles = nearestObjects [_truck, ["AllVehicles"], 20];
if (count _vehicles < 2) exitWith {false}; // Rearming needs at least 2 vehicles
_vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && {!(_x getVariable [QGVAR(disabled), false])}};
private _vehicleActions = [];
{
private _actions = [];
private _vehicle = _x;
private _needToAdd = false;
private _action = [];
if !((_vehicle == _truck) || (_vehicle isKindOf "CAManBase")) then {
private _magazineHelper = [];
private _magazineHelper = [];
{
private _turretPath = _x;
private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines);
{
private _turretPath = _x;
private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines);
{
private _magazine = _x;
private _magazine = _x;
if (!(_magazine in _magazineHelper)) then {
private _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath);
if ((_currentMagazines < ([_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines))) && !(_magazine in _magazineHelper)) then {
_action = [_magazine,
getText(configFile >> "CfgMagazines" >> _magazine >> "displayName"),
getText(configFile >> "CfgMagazines" >> _magazine >> "picture"),
{_this call FUNC(takeAmmo)},
{true},
{},
[_magazine, _vehicle]] call EFUNC(interact_menu,createAction);
if (GVAR(supply) == 0 || {(GVAR(supply) == 1) && ([_truck, _magazine] call FUNC(hasEnoughSupply))} || {(GVAR(supply) == 2) && ([_truck, _magazine] call FUNC(magazineInSupply))}) then {
_actions pushBack [_action, [], _truck];
_magazineHelper pushBack _magazine;
_needToAdd = true;
};
} else {
if (((_vehicle magazineTurretAmmo [_magazine, _turretPath]) < getNumber (configFile >> "CfgMagazines" >> _magazine >> "count")) && !(_magazine in _magazineHelper)) then {
_action = [_magazine,
getText(configFile >> "CfgMagazines" >> _magazine >> "displayName"),
getText(configFile >> "CfgMagazines" >> _magazine >> "picture"),
{_this call FUNC(takeAmmo)},
{true},
{},
[_magazine, _vehicle]] call EFUNC(interact_menu,createAction);
if (GVAR(supply) == 0 || {(GVAR(supply) == 1) && ([_truck, _magazine] call FUNC(hasEnoughSupply))} || {(GVAR(supply) == 2) && ([_truck, _magazine] call FUNC(magazineInSupply))}) then {
_actions pushBack [_action, [], _truck];
_magazineHelper pushBack _magazine;
_needToAdd = true;
};
};
private _maxMagazines = [_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines);
if ((_currentMagazines < _maxMagazines) || {(_vehicle magazineTurretAmmo [_magazine, _turretPath]) < getNumber (configFile >> "CfgMagazines" >> _magazine >> "count")}) then {
_magazineHelper pushBack _magazine;
};
false
} count _magazines;
};
false
} count REARM_TURRET_PATHS;
};
if (_needToAdd && !(_vehicle getVariable [QGVAR(disabled), false])) then {
} count _magazines;
false
} count REARM_TURRET_PATHS;
// 1.70 pylons
private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"];
{
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)};
TRACE_2("can add",_x,_magazineHelper);
if (!(_magazineHelper isEqualTo [])) then {
private _icon = getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Icon");
if !((_icon select [0, 1]) == "\") then {
_icon = "";
};
if (GVAR(level) == 0) then {
_action = [_vehicle,
getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"),
_icon,
{_this call FUNC(rearmEntireVehicle)},
{true},
{},
_vehicle] call EFUNC(interact_menu,createAction);
// [Level 0] adds a single action to rearm the entire vic
private _action = [_vehicle,
getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"),
_icon,
{_this call FUNC(rearmEntireVehicle)},
{true},
{},
_vehicle] call EFUNC(interact_menu,createAction);
_vehicleActions pushBack [_action, [], _truck];
} else {
_action = [_vehicle,
// [Level 1,2] - Add actions for each magazine
private _actions = [];
{
private _action = [_x,
getText(configFile >> "CfgMagazines" >> _x >> "displayName"),
getText(configFile >> "CfgMagazines" >> _x >> "picture"),
{_this call FUNC(takeAmmo)},
{true},
{},
[_x, _vehicle]] call EFUNC(interact_menu,createAction);
_actions pushBack [_action, [], _truck];
} forEach _magazineHelper;
private _action = [_vehicle,
getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"),
_icon,
{},

View File

@ -4,7 +4,7 @@
*
* Arguments:
* 0: Ammo Truck <OBJECT>
* 1: Vehicle or Vehicle class <OBJECT/STRING>
* 1: Vehicle object or Vehicle class <OBJECT><STRING>
*
* Return Value:
* None
@ -17,24 +17,33 @@
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]],
["_vehicle", objNull, [objNull, ""]]
];
if !(EGVAR(common,settingsInitFinished)) exitWith { // only run this after the settings are initialized
EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addVehicleMagazinesToSupply), _this];
};
if (isNull _truck ||
{_vehicle isEqualType objNull}) exitWith {};
params [["_truck", objNull, [objNull]], ["_vehicle", objNull, [objNull, ""]]];
TRACE_2("addVehicleMagazinesToSupply",_truck,_vehicle);
private _string = [_vehicle, typeOf _vehicle] select (_vehicle isEqualType objNull);
if (_string == "") exitWith {
ERROR_1("_string [%1] is empty in ace_rearm_fnc_addVehicleMagazinesToSupply",_string);
if (isNull _truck) exitWith {};
if (_vehicle isEqualType objNull) then {_vehicle = typeOf _vehicle};
if (_vehicle == "") exitWith {
ERROR_1("VehicleType [%1] is empty in ace_rearm_fnc_addVehicleMagazinesToSupply",_string);
};
{
private _turretPath = _x;
private _magazines = [_string, _turretPath] call FUNC(getConfigMagazines);
private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines);
TRACE_2("",_turretPath,_magazines);
{
[_truck, _x] call FUNC(addMagazineToSupply);
false
} count _magazines;
false
} count REARM_TURRET_PATHS;
// 1.70 pylons
private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"];
{
private _defaultMag = getText (_x >> "attachment");
TRACE_3("",_defaultMag,configName _x,_forEachIndex);
[_truck, _defaultMag] call FUNC(addMagazineToSupply);
} forEach _pylonConfigs;

View File

@ -1,6 +1,6 @@
/*
* Author: GitHawk
* Checks if unit can read supply counter.
* Checks if unit can read supply counter. [Only for GVAR(supply) > 0]
*
* Arguments:
* 0: Ammo Truck <OBJECT>
@ -21,9 +21,11 @@ params [
["_unit", objNull, [objNull]]
];
!(isNull _unit ||
{!(_unit isKindOf "CAManBase")} ||
{!local _unit} ||
{!alive _truck} ||
{(_truck distance _unit) > REARM_ACTION_DISTANCE} ||
{GVAR(supply) == 0})
(alive _unit)
&& {_unit isKindOf "CAManBase"}
&& {local _unit}
&& {alive _truck}
&& {(_truck distance _unit) < REARM_ACTION_DISTANCE}
&& {GVAR(supply) > 0}
&& {[_unit, _truck, ["IsNotInside"]] call EFUNC(common,canInteractWith)} // manually added actions need this

View File

@ -1,29 +0,0 @@
/*
* Author: GitHawk
* Check if a unit can rearm a vehicle.
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Unit <OBJECT>
*
* Return Value:
* Can Pick Up Ammo <BOOL>
*
* Example:
* [tank, player] call ace_rearm_fnc_canRearmVehicle
*
* Public: No
*/
#include "script_component.hpp"
params [
["_vehicle", objNull, [objNull]],
["_unit", objNull, [objNull]]
];
!(isNull _unit ||
{!(_unit isKindOf "CAManBase")} ||
{!local _unit} ||
{(_vehicle distance _unit) > REARM_ACTION_DISTANCE} ||
{!isNull (_unit getVariable [QGVAR(dummy), objNull])} ||
{GVAR(level) > 0})

View File

@ -21,9 +21,10 @@ params [
["_unit", objNull, [objNull]]
];
!(isNull _unit ||
{!alive _truck} ||
{!(_unit isKindOf "CAManBase")} ||
{!local _unit} ||
{(_truck distance _unit) > REARM_ACTION_DISTANCE} ||
{isNull (_unit getVariable [QGVAR(dummy), objNull])})
(alive _unit)
&& {_unit isKindOf "CAManBase"}
&& {local _unit}
&& {!isNull (_unit getVariable [QGVAR(dummy), objNull])}
&& {alive _truck}
&& {(_truck distance _unit) < REARM_ACTION_DISTANCE}
&& {[_unit, _truck, ["IsNotInside"]] call EFUNC(common,canInteractWith)} // manually added actions need this

View File

@ -21,10 +21,10 @@ params [
["_unit", objNull, [objNull]]
];
!(isNull _unit ||
{!alive _truck} ||
{!(_unit isKindOf "CAManBase")} ||
{!local _unit} ||
{(_truck distance _unit) > REARM_ACTION_DISTANCE} ||
{!isNull (_unit getVariable [QGVAR(dummy), objNull])} ||
{GVAR(level) == 0})
(alive _unit)
&& {_unit isKindOf "CAManBase"}
&& {local _unit}
&& {alive _truck}
&& {(_truck distance _unit) < REARM_ACTION_DISTANCE}
&& {isNull (_unit getVariable [QGVAR(dummy), objNull])}
&& {[_unit, _truck, ["IsNotInside"]] call EFUNC(common,canInteractWith)} // manually added actions need this

View File

@ -32,4 +32,6 @@ if !(_dummyName == "") then {
_dummy allowDamage false;
_dummy setVariable [QGVAR(magazineClass), _magazineClass, true];
TRACE_4("createdDummy",_unit,_magazineClass,_dummyName,_dummy);
_dummy

View File

@ -1,6 +1,6 @@
/*
* Author: GitHawk
* Disables rearm for a vehicle.
* Disables being able to rearm a vehicle's turrets. [Global Effects]
*
* Arguments:
* 0: Vehicle <OBJECT>

View File

@ -1,58 +0,0 @@
/*
* Author: GitHawk, Jonpas
* Returns all magazines a turret of a vehicle class can hold according to config.
*
* Arguments:
* 0: Vehicle class <STRING>
* 1: Turret Path <ARRAY>
*
* Return Value:
* Magazine classes in TurretPath <ARRAY>
*
* Example:
* ["B_MBT_01_arty_F", [0]] call ace_rearm_fnc_getConfigMagazines
*
* Public: No
*/
#include "script_component.hpp"
params [
["_cfgString", "", [""]],
["_turretPath", [], [[]]]
];
if (_cfgString == "") exitWith {[]};
private _cfg = configFile >> "CfgVehicles" >> _cfgString >> "Turrets";
if !(isClass _cfg) exitWith {[]};
if (count _turretPath == 1) then {
_turretPath params ["_subPath"];
if (_subPath == -1) exitWith {
_cfg = configFile >> "CfgVehicles" >> _cfgString;
};
if (count _cfg > _subPath) then {
_cfg = _cfg select _subPath;
} else {
_cfg = nil;
};
} else {
_turretPath params ["", "_subPath"];
if (count _cfg > 0) then {
_cfg = (_cfg select 0) >> "Turrets";
if (count _cfg > _subPath) then {
_cfg = _cfg select _subPath;
} else {
_cfg = nil;
};
} else {
_cfg = nil;
};
};
if !(isClass _cfg) exitWith {[]};
getArray (_cfg >> "magazines")

View File

@ -0,0 +1,39 @@
/*
* Author: PabstMirror
* Gets possible magazines that can be added to a pylon.
*
* Arguments:
* 0: Pylon config <CONFIG>
*
* Return Value:
* Magazines <ARRAY>
*
* Example:
* [config] call ace_rearm_fnc_getHardpointMagazines
*
* Public: No
*/
#include "script_component.hpp"
params ["_pylonConfig"];
private _return = GVAR(hardpointGroupsCache) getVariable (str _pylonConfig);
if (isNil "_return") then {
_return = [];
private _hardpoints = (getArray (_pylonConfig >> "hardpoints")) apply {toLower _x};
private _maxWeight = if (isNumber (_pylonConfig >> "maxWeight")) then {getNumber (_pylonConfig >> "maxWeight")} else {1e5};
private _mags = configProperties [configFile >> "CfgMagazines", "(isClass _x) && {isArray (_x >> 'hardpoints')}"];
{
if ((getNumber (_x >> "mass")) < _maxWeight) then {
private _magHardpoints = (getArray (_x >> "hardpoints")) apply {toLower _x};
if (!((_hardpoints arrayIntersect _magHardpoints) isEqualTo [])) then {
_return pushBack configName _x;
};
};
} forEach _mags;
if ((str _pylonConfig) != "") then {
GVAR(hardpointGroupsCache) setVariable [(str _pylonConfig), _return];
};
};
_return;

View File

@ -11,6 +11,7 @@
* 0: Can Rearm <BOOL>
* 1: TurretPath <ARRAY>
* 2: Number of current magazines in turret path <NUMBER>
* 3: Pylon Index (-1 if not a pylon) <NUMBER>
*
* Example:
* [tank, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_getNeedRearmMagazines
@ -19,12 +20,9 @@
*/
#include "script_component.hpp"
params [
["_vehicle", objNull, [objNull]],
["_magazineClass", "", [""]]
];
params [["_vehicle", objNull, [objNull]], ["_magazineClass", "", [""]]];
private _return = [false, [], 0];
private _return = [false, [], 0, -1];
{
private _magazines = [_vehicle, _x] call FUNC(getVehicleMagazines);
@ -32,11 +30,11 @@ private _return = [false, [], 0];
private _currentMagazines = {_x == _magazineClass} count (_vehicle magazinesTurret _x);
if ((_vehicle magazineTurretAmmo [_magazineClass, _x]) < getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count")) exitWith {
_return = [true, _x, _currentMagazines];
_return = [true, _x, _currentMagazines, -1];
};
if (_currentMagazines < ([_vehicle, _x, _magazineClass] call FUNC(getMaxMagazines))) exitWith {
_return = [true, _x, _currentMagazines];
_return = [true, _x, _currentMagazines, -1];
};
};
@ -44,4 +42,37 @@ private _return = [false, [], 0];
false
} count REARM_TURRET_PATHS;
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 _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 {
if (_magazineClass == _pylonMagazine) then { // Try to refill current pylon:
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);
_return

View File

@ -15,15 +15,24 @@
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]]
];
params [["_truck", objNull, [objNull]]];
if (GVAR(supply) != 1) exitWith {
WARNING("supply setting is not set to limited"); // func shouldn't have been called
-1
};
private _supply = _truck getVariable QGVAR(currentSupply);
if (isNil "_supply") then {
_supply = getNumber (configFile >> "CfgVehicles" >> typeOf _truck >> QGVAR(defaultSupply));
_truck setVariable [QGVAR(currentSupply), _supply, true];
if (isNumber (configFile >> "CfgVehicles" >> typeOf _truck >> QGVAR(defaultSupply))) then {
_supply = getNumber (configFile >> "CfgVehicles" >> typeOf _truck >> QGVAR(defaultSupply));
} else {
_supply = 1200;
};
if (_supply > 0) then {
_truck setVariable [QGVAR(currentSupply), _supply, true];
};
};
_supply

View File

@ -3,7 +3,7 @@
* Returns all magazines a turret of a vehicle object can hold according to config.
*
* Arguments:
* 0: Vehicle <OBJECT>
* 0: Vehicle object or typeOf <OBJECT><STRING>
* 1: Turret Path <ARRAY>
*
* Return Value:
@ -16,11 +16,4 @@
*/
#include "script_component.hpp"
params [
["_vehicle", objNull, [objNull]],
["_turretPath", [], [[]]]
];
if (isNull _vehicle) exitWith {[]};
([typeOf _vehicle, _turretPath] call FUNC(getConfigMagazines))
getArray ((_this call CBA_fnc_getTurret) >> "magazines")

View File

@ -25,7 +25,7 @@ REARM_HOLSTER_WEAPON;
[_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set);
[
5,
TIME_PROGRESSBAR(5),
[_dummy, _unit],
{
private ["_actionID"];

View File

@ -1,42 +1,52 @@
/*
* Author: GitHawk
* Check whether enough supply is left to take the magazine.
*
* Arguments:
* 0: Ammo Truck <OBJECT>
* 1: Magazine Classname <STRING>
*
* Return Value:
* Enough supply <BOOL>
*
* Example:
* [ammo_truck, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_hasEnoughSupply
*
* Public: No
*/
* Author: GitHawk
* Check whether enough supply is left to take the magazine.
*
* Arguments:
* 0: Ammo Truck <OBJECT>
* 1: Magazine Classname <STRING>
*
* Return Value:
* Enough supply <BOOL>
*
* Example:
* [ammo_truck, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_hasEnoughSupply
*
* Public: No
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]],
["_magazineClass", "", [""]]
];
params [["_truck", objNull, [objNull]], ["_magazineClass", "", [""]]];
if (isNull _truck ||
{_magazineClass isEqualTo ""}) exitWith {false};
if (isNull _truck || {_magazineClass isEqualTo ""}) exitWith {false};
// With infinite supply, there is always enough
if (GVAR(supply) == 0) exitWith {true};
// With magazine specific supply, we need to check stored magazines
if (GVAR(supply) == 2) exitWith {_this call FUNC(magazineInSupply)};
private _supply = [_truck] call FUNC(getSupplyCount);
([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"];
// With caliber based rearming, we only need partial supply
if (GVAR(level) == 2) exitWith {
// If REARM_COUNT is bigger than the magazine size, we might get a bigger number than 1
private _magazinePart = ((REARM_COUNT select _idx) / (getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"))) min 1;
(_cal * _magazinePart <= _supply)
// With limited supply, we need to check supply
if (GVAR(supply) == 1) exitWith {
private _supply = [_truck] call FUNC(getSupplyCount);
([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"];
// With caliber based rearming, we only need partial supply
if (GVAR(level) == 2) exitWith {
// If REARM_COUNT is bigger than the magazine size, we might get a bigger number than 1
private _magazinePart = ((REARM_COUNT select _idx) / (getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"))) min 1;
(_cal * _magazinePart <= _supply)
};
(_cal <= _supply)
};
(_cal <= _supply)
// With magazine specific supply, we need to check stored magazines
if (GVAR(supply) == 2) exitWith {
private _magazineSupply = _truck getVariable [QGVAR(magazineSupply), []];
private _magazinePresent = false;
{
_x params ["_magazine", "_rounds"];
if ((_magazine isEqualTo _magazineClass) && (_rounds > 0)) exitWith {_magazinePresent = true; };
false
} count _magazineSupply;
_magazinePresent
};

View File

@ -0,0 +1,76 @@
/*
* Author: Githawk, PabstMirror
* Adds rearm supply actions to a vehicle or ammo container.
*
* Arguments:
* 0: Object <OBJECT>
*
* Return Value:
* None
*
* Example:
* [ammoTruck] call ace_rearm_fnc_initSupplyVehicle;
*
* Public: No
*/
#include "script_component.hpp"
if (!hasInterface) exitWith {}; // For now we just add actions, so no need non-clients
params ["_vehicle"];
private _typeOf = typeOf _vehicle;
TRACE_2("initSupplyVehicle",_vehicle,_typeOf);
if (!alive _vehicle) exitWith {};
private _configSupply = getNumber (configFile >> "CfgVehicles" >> _typeOf >> QGVAR(defaultSupply));
private _isSupplyVehicle = _vehicle getVariable [QGVAR(isSupplyVehicle), false];
private _oldRearmConfig = isClass (configFile >> "CfgVehicles" >> _typeOf >> "ACE_Actions" >> "ACE_MainActions" >> QGVAR(takeAmmo));
TRACE_3("",_configSupply,_isSupplyVehicle,_oldRearmConfig);
if ((_configSupply <= 0) && {!_isSupplyVehicle} && {!_oldRearmConfig}) exitWith {}; // Ignore if not enabled
if ((_oldRearmConfig || {_configSupply > 0}) && {_typeOf in GVAR(configTypesAdded)}) exitWith {}; // Only add class actions once
if (_oldRearmConfig || {_configSupply > 0}) then {GVAR(configTypesAdded) pushBack _typeOf};
private _actionReadSupplyCounter = [ // GVAR(supply) > 0
QGVAR(ReadSupplyCounter),
localize LSTRING(ReadSupplyCounter), // Check remaining ammunition
QPATHTOF(ui\icon_rearm_interact.paa),
{_this call FUNC(readSupplyCounter)},
{_this call FUNC(canReadSupplyCounter)}
] call EFUNC(interact_menu,createAction);
private _actionTakeAmmo = [
QGVAR(takeAmmo),
localize ([LSTRING(Rearm), LSTRING(TakeAmmo)] select (GVAR(level) > 0)),
QPATHTOF(ui\icon_rearm_interact.paa),
{},
{_this call FUNC(canTakeAmmo)},
{_this call FUNC(addRearmActions)}
] call EFUNC(interact_menu,createAction);
private _actionStoreAmmo = [
QGVAR(StoreAmmo),
localize LSTRING(StoreAmmo), // "Store ammo"
QPATHTOF(ui\icon_rearm_interact.paa),
{_this call FUNC(storeAmmo)},
{_this call FUNC(canStoreAmmo)}
] call EFUNC(interact_menu,createAction);
if (_oldRearmConfig || {_configSupply > 0}) then {
TRACE_1("Adding Class Actions",_typeOf);
[_typeOf, 0, ["ACE_MainActions"], _actionReadSupplyCounter] call EFUNC(interact_menu,addActionToClass);
if (!_oldRearmConfig) then {
[_typeOf, 0, ["ACE_MainActions"], _actionTakeAmmo] call EFUNC(interact_menu,addActionToClass);
[_typeOf, 0, ["ACE_MainActions"], _actionStoreAmmo] call EFUNC(interact_menu,addActionToClass);
} else {
WARNING_1("Actions already present on [%1]. Old Compat PBO?",_typeOf);
};
} else {
TRACE_1("Adding Object Actions",_typeOf);
[_vehicle, 0, ["ACE_MainActions"], _actionReadSupplyCounter] call EFUNC(interact_menu,addActionToObject);
[_vehicle, 0, ["ACE_MainActions"], _actionTakeAmmo] call EFUNC(interact_menu,addActionToObject);
[_vehicle, 0, ["ACE_MainActions"], _actionStoreAmmo] call EFUNC(interact_menu,addActionToObject);
};

View File

@ -1,42 +0,0 @@
/*
* Author: GitHawk
* Returns true if the magazine is in the current supply
*
* Arguments:
* 0: Ammo Truck <OBJECT>
* 1: Magazine Classname <STRING>
*
* Return Value:
* Magazine in supply <BOOL>
*
* Example:
* [ammo_truck, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_magazineInSupply
*
* Public: No
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]],
["_magazineClass", "", [""]]
];
if (isNull _truck ||
{_magazineClass isEqualTo ""}) exitWith {false};
// With limited supply, we need to check supply
if (GVAR(supply) == 1) exitWith {_this call FUNC(hasEnoughSupply)};
// With magazine specific supply, we need to check them
if (GVAR(supply) == 2) exitWith {
private _magazineSupply = _truck getVariable [QGVAR(magazineSupply), []];
private _magazinePresent = false;
{
_x params ["_magazine", "_rounds"];
if ((_magazine isEqualTo _magazineClass) && (_rounds > 0)) exitWith {_magazinePresent = true; };
false
} count _magazineSupply;
_magazinePresent
};
// With infinite supply, there is always one left
true

View File

@ -16,16 +16,14 @@
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]],
["_unit", objNull, [objNull]]
];
params [["_truck", objNull, [objNull]],["_unit", objNull, [objNull]]];
TRACE_2("readSupplyCounter",_truck,_unit);
if (GVAR(supply) == 0) exitWith {};
if (GVAR(supply) == 0) exitWith {WARNING("Supply is unlimited");};
if (GVAR(supply) == 1) then {
[
5,
TIME_PROGRESSBAR(5),
[_unit, _truck, [_truck] call FUNC(getSupplyCount)],
{
params ["_args"];
@ -44,7 +42,7 @@ if (GVAR(supply) == 1) then {
] call EFUNC(common,progressBar);
} else {
[
5,
TIME_PROGRESSBAR(5),
[_unit, _truck],
{
params ["_args"];

View File

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

View File

@ -24,7 +24,7 @@ params [
];
[
10,
TIME_PROGRESSBAR(10),
[_truck, _vehicle],
FUNC(rearmEntireVehicleSuccess),
"",

View File

@ -17,11 +17,28 @@
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]],
["_vehicle", objNull, [objNull]],
["_turretPath", [], [[]]]
];
params [["_truck", objNull, [objNull]], ["_vehicle", objNull, [objNull]], ["_turretPath", [], [[]]]];
TRACE_3("rearmEntireVehicleSuccessLocal",_truck,_vehicle,_turretPath);
// 1.70 pylons
private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"];
{
private _pylonTurret = getArray (_x >> "turret");
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);
if (isNil "_magazines") exitWith {};
@ -40,27 +57,20 @@ if (isNil "_magazines") exitWith {};
};
if (_currentMagazines < _maxMagazines) then {
private _success = true;
if (GVAR(supply) > 0) then {
_success = [_truck, _magazine, (_maxRounds - _currentRounds)] call FUNC(removeMagazineFromSupply);
};
if (_success) then {
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 {
_success = true;
if (GVAR(supply) > 0) then {
_success = [_truck, _magazine, _maxRounds] call FUNC(removeMagazineFromSupply);
};
};
for "_idx" from 1 to (_maxMagazines - _currentMagazines) do {
if ((GVAR(supply) == 0) || {[_truck, _magazine, _maxRounds] call FUNC(removeMagazineFromSupply)}) then {
_vehicle addMagazineTurret [_magazine, _turretPath];
};
};
} else {
private _success = true;
if (GVAR(supply) > 0) then {
_success = [_truck, _magazine, (_maxRounds - _currentRounds)] call FUNC(removeMagazineFromSupply);
};
if (_success) then {
if ((GVAR(supply) == 0) || {[_truck, _magazine, (_maxRounds - _currentRounds)] call FUNC(removeMagazineFromSupply)}) then {
_vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath];
};
};
false
} count _magazines;

View File

@ -1,36 +1,35 @@
/*
* Author: GitHawk
* Rearms a vehicle.
* Rearms a vehicle, after progress bar finishes, pass args to machine where turret is local.
*
* Arguments:
* 0: Params <ARRAY>
* 0: Vehicle <OBJECT>
* 1: Unit <OBJECT>
* 2: Turret Path <ARRAY>
* 3: Number of magazines <NUMBER>
* 4: Magazine Classname <STRING>
* 5: Number of rounds <NUMBER>
* 0: Vehicle <OBJECT>
* 1: Unit <OBJECT>
* 2: Turret Path <ARRAY>
* 3: Number of magazines <NUMBER>
* 4: Magazine Classname <STRING>
* 5: Number of rounds <NUMBER>
* 6: Pylon Index <NUMBER>
*
* Return Value:
* None
*
* Example:
* [[vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500]] call ace_rearm_fnc_rearmSuccess
* [vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500, -1] call ace_rearm_fnc_rearmSuccess
*
* Public: No
*/
#include "script_component.hpp"
params [
["_args", [objNull, objNull, [], 0, "", 0], [[]], [6]]
];
_args params ["_vehicle", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds"];
TRACE_6("rearmSuccess",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds);
params [["_vehicle", objNull, [objNull]], ["_unit", objNull, [objNull]], "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"];
TRACE_7("rearmSuccess",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds,_pylon);
if (local _unit) then {
[_unit, true, true] call FUNC(dropAmmo);
};
if (!alive _vehicle) exitWith {WARNING("vehicle dead/null");};
if (isServer) then {
private _turretOwnerID = _vehicle turretOwner _turretPath;
if (_turretOwnerID == 0) then {

View File

@ -3,31 +3,38 @@
* Rearms a vehicle on the turret owner.
*
* Arguments:
* 0: Params <ARRAY>
* 0: Vehicle <OBJECT>
* 1: Unit <OBJECT>
* 2: Turret Path <ARRAY>
* 3: Number of magazines <NUMBER>
* 4: Magazine Classname <STRING>
* 5: Number of rounds <NUMBER>
* 0: Vehicle <OBJECT>
* 1: Unit <OBJECT>
* 2: Turret Path <ARRAY>
* 3: Number of magazines <NUMBER>
* 4: Magazine Classname <STRING>
* 5: Number of rounds <NUMBER>
* 6: Pylon Index <NUMBER>
*
* Return Value:
* None
*
* Example:
* [[vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500]] call ace_rearm_fnc_rearmSuccessLocal
* [vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500, ""] call ace_rearm_fnc_rearmSuccessLocal
*
* Public: No
*/
#include "script_component.hpp"
params [
["_args", [objNull, objNull, [], 0, "", 0], [[]], [6]]
];
_args params ["_vehicle", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds"];
TRACE_6("rearmSuccessLocal",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds);
params ["_vehicle", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"];
TRACE_7("rearmSuccessLocal",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds,_pylon);
private _rounds = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count");
if (_pylon > 0) exitWith {
if (_turretPath isEqualTo [-1]) then {_turretPath = [];}; // Convert back to pylon turret format
private _currentCount = _vehicle ammoOnPylon _pylon;
private _newCount = ((_currentCount max 0) + _numRounds) min _rounds;
TRACE_2("",_pylon,_magazineClass,_newCount);
_vehicle setPylonLoadOut [_pylon, _magazineClass, false, _turretPath];
_vehicle setAmmoOnPylon [_pylon, _newCount];
};
private _currentRounds = 0;
private _maxMagazines = [_vehicle, _turretPath, _magazineClass] call FUNC(getMaxMagazines);

View File

@ -5,7 +5,7 @@
* Arguments:
* 0: Ammo Truck <OBJECT>
* 1: Magazine Classname <STRING>
* 2: Number of Rounds to withdraw <NUMBER>(optional)
* 2: Number of Rounds to withdraw <NUMBER> (default: -1)
*
* Return Value:
* Magazine was removed <BOOL>
@ -17,18 +17,19 @@
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]],
["_magazineClass", "", [""]],
["_numRounds", -1, [0]]
];
params [["_truck", objNull, [objNull]], ["_magazineClass", "", [""]], ["_numRounds", -1, [0]]];
TRACE_3("removeMagazineFromSupply",_truck,_magazineClass,_numRounds);
if (isNull _truck ||
{_magazineClass isEqualTo ""}) exitWith {false};
if (isNull _truck || {_magazineClass isEqualTo ""}) exitWith {false};
private _return = false;
([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"];
if (GVAR(supply) == 0) then {
WARNING("supply setting is set to unlimited"); // func shouldn't have been called
_return = true;
};
if (GVAR(supply) == 1) then {
private _supply = [_truck] call FUNC(getSupplyCount);
if (GVAR(level) == 2) then {
@ -50,6 +51,7 @@ if (GVAR(supply) == 1) then {
};
};
};
if (GVAR(supply) == 2) then {
private _magazineSupply = _truck getVariable [QGVAR(magazineSupply), []];
private _magazineIdx = -1;

View File

@ -1,6 +1,6 @@
/*
* Author: GitHawk
* Sets the supply count.
* Sets the supply count. [Global Effects]
*
* Arguments:
* 0: Ammo Truck <OBJECT>
@ -16,11 +16,13 @@
*/
#include "script_component.hpp"
params [
["_truck", objNull, [objNull]],
["_supply", 0, [0]]
];
if !(EGVAR(common,settingsInitFinished)) exitWith { // only run this after the settings are initialized
EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setSupplyCount), _this];
};
if (isNull _truck) exitWith {};
params [["_truck", objNull, [objNull]], ["_supply", 0, [0]]];
if (GVAR(supply) != 1) exitWith {WARNING("supply setting is not set to limited");};
if (isNull _truck) exitWith {WARNING_1("Truck is null [%1]", _truck);};
_truck setVariable [QGVAR(currentSupply), (_supply max 0), true];

View File

@ -25,7 +25,7 @@ private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull];
if (isNull _attachedDummy) exitwith {};
[
5,
TIME_PROGRESSBAR(5),
[_unit, _truck, _attachedDummy],
{
params ["_args"];

View File

@ -25,13 +25,14 @@ params [
["_args", ["", objNull], [[]]]
];
_args params ["_magazineClass", "_vehicle"];
TRACE_5("takeAmmo",_truck,_unit,_args,_magazineClass,_vehicle);
([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"];
REARM_HOLSTER_WEAPON;
[
(REARM_DURATION_TAKE select _idx),
TIME_PROGRESSBAR(REARM_DURATION_TAKE select _idx),
[_unit, _magazineClass, _truck],
FUNC(takeSuccess),
"",

View File

@ -18,16 +18,15 @@
*/
#include "script_component.hpp"
params [
["_args", [objNull, "", objNull], [[]], 3]
];
params [["_args", [objNull, "", objNull], [[]], 3]];
_args params ["_unit", "_magazineClass", "_truck"];
TRACE_3("takeSuccess",_unit,_magazineClass,_truck);
private _success = true;
if (GVAR(supply) > 0) then {
_success = [_truck, _magazineClass] call FUNC(removeMagazineFromSupply);
};
if !(_success) exitWith {};
if !(_success) exitWith {WARNING_2("takeSuccess failed to take [%1] from [%2]",_magazineClass,_truck);};
[_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set);
private _dummy = [_unit, _magazineClass] call FUNC(createDummy);
@ -41,6 +40,6 @@ private _actionID = _unit addAction [
false,
true,
"",
'!isNull (_truck getVariable [QGVAR(dummy), objNull])'
'!isNull (_target getVariable [QGVAR(dummy), objNull])'
];
_unit setVariable [QGVAR(ReleaseActionID), _actionID];

View File

@ -5,6 +5,7 @@
// #define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE
// #define ENABLE_PERFORMANCE_COUNTERS
// #define FAST_PROGRESSBARS
#ifdef DEBUG_ENABLED_REARM
#define DEBUG_MODE_FULL
@ -38,3 +39,9 @@
_unit selectWeapon _weaponSelect; \
_unit setVariable [QGVAR(selectedWeaponOnRearm), nil]; \
};
#ifdef FAST_PROGRESSBARS
#define TIME_PROGRESSBAR(X) ((X) * 0.075)
#else
#define TIME_PROGRESSBAR(X) (X)
#endif

View File

@ -17,14 +17,16 @@ version:
This adds the option to rearm vehicles. The module settings allow you to configure ACE3 Rearm for both casual gaming and simulation game modes. Both the rearm speed and the availability of ammunition supply can be configured.
## 2. Rearming
## 2. Rearm Settings
### 2.1 Rearming a vehicle with setting `Entire vehicle`
## 2.1 Rearm Amount (`ace_rearm_level`)
### 2.1.1 Rearming a vehicle with setting `Entire vehicle`
- Interact with the ammo truck <kbd>&nbsp;Win</kbd> (ACE3 default key bind `Interact Key`).
- Move over `Rearm` and a list of vehicles within 20 meters that can be rearmed will be shown.
- Select the vehicle from the list. It takes a few seconds to rearm the vehicle.
### 2.2 Rearming a vehicle with setting `Entire Magazine`
### 2.1.2 Rearming a vehicle with setting `Entire Magazine`
- Interact with the ammo truck <kbd>&nbsp;Win</kbd> (ACE3 default key bind `Interact Key`).
- Move over `Take ammo` and a list of vehicles within 20 meters that can be rearmed will be shown.
- Select the vehicle and the magazine from the list. You will pick up an ammo box.
@ -33,7 +35,7 @@ This adds the option to rearm vehicles. The module settings allow you to configu
If a weapon carries multiple magazines of the same type, you have to repeat the procedure for every (partially) spent magazine.
### 2.3 Rearming a vehicle with setting `Amount based on caliber`
### 2.1.3 Rearming a vehicle with setting `Amount based on caliber`
It's the same process as with setting `Entire Magazine`, but most magazines will require several ammo boxes.
| Caliber in mm | 6 | 7 | 8 | 13 | 19 | 20 | 25 | 30 | 35 | 39 | 40 | 60 | 70 | 80 | 82 | 100 | 105 | 120 | 122 | 125 | 155 | 230 | 250 |
@ -43,6 +45,23 @@ It's the same process as with setting `Entire Magazine`, but most magazines will
The caliber of the weapon will be rounded to the nearest number and the number of rounds is calculated using the table above.
To fully rearm 2000 rounds of 7.62mm machine gun, you need five ammo boxes.
## 2.2 Ammunition supply (`ace_rearm_supply`)
### 2.2.1 Unlimited
- Rearm vehicle has unlimited supply
### 2.2.2 Limited ammo supply based on caliber
- Supply vehicle starts with a certian number of "points" (default is 1200)
- Resupplying vehicle will use up points based on number of rounds and caliber
- Can check number of points left on supply vehicle
- With 1000 points worth of ammunition supply, you can rearm four magazines of 250mm caliber (i.e. bombs) or eight magazines of 120mm caliber (i.e. tank rounds) or 125 magazines of 7.62mm caliber.
### 2.2.3 Specific Magazines
- Supply vehicles start **empty**
- Magazines must be added via `ace_rearm_fnc_addMagazineToSupply` / `ace_rearm_fnc_addVehicleMagazinesToSupply`
- Can only resupply vehicles with specific magazines that have been loaded
- Can check what magazines are loaded on supply vehicle
## 3. FAQ
@ -61,12 +80,13 @@ Mod developers can use the framework to use their custom models as ammo box repl
### Does rearm work with vehicles from mods?
Yes, if the vehicle has the correct config entries or uses inheritance from vanilla ammo. Otherwise there is a compatibility mode.
Any vehicle can be turned into a supply vehicle by adding `this setVariable ["ace_rearm_isSupplyVehicle", true]` to it's init box.
### How do I replenish the ammunition supply on an ammo truck?
Please check the framework description for more details.
Please check the <a href="{{ site.baseurl }}/wiki/framework/rearm-framework.html">framework</a> description for more details.
### The limited supply option `Only specific Magazines` doesn't work. What's wrong?
The mission creator has to use the framework to add specific magazines to the ammo truck(s). On this setting all ammo trucks are empty by default. For more information, please check the framework description.
The mission creator has to use the framework to add specific magazines to the ammo truck(s). On this setting all ammo trucks are empty by default. For more information, please check the <a href="{{ site.baseurl }}/wiki/framework/rearm-framework.html">framework</a> description.
## 5. Dependencies

View File

@ -14,6 +14,8 @@ version:
## 1. Config Values
### 1.1 Ammo Configs
```cpp
class CfgAmmo {
class MyLaserGuidedRocket {
@ -36,9 +38,80 @@ class CfgVehicles {
<p>ace_rearm_dummy is only needed if you have a custom ammunition model. For each model you should create a dummy vehicle extending ace_rearm_defaultCarriedObject.</p>
</div>
### 1.2 Setting vehicle as a supply
A vehicle will be set as a supply vehicle based on the config `ace_rearm_defaultSupply`
```cpp
class MyTruck: Car_F {
ace_rearm_defaultSupply = 1200;
};
```
<div class="panel callout">
<h5>Note:</h5>
<p>Mission makers can also use `this setVariable ["ace_rearm_isSupplyVehicle", true]`</p>
</div>
## 2. Functions
### 2.1 Adding specific magazines
`ace_rearm_fnc_addMagazineToSupply`
| Arguments | Type | Optional (default value)
---| --------- | ---- | ------------------------
0 | Ammo Truck | Object | Required
1 | Magazine Classname | String | Required
2 | Only add content of one ammo box | Boolean | Optional (default: `false`)
**R** | None | None | Return value
This function is most useful with the module setting `Only specific Magazines`. Note that this function only adds one magazine of a specific class. Other magazines of the same size are not available on this module setting. It has to be used to replenish the ammo truck on `Only specific Magazines` setting.
This function can also be used to increase the supply count on setting `Limited ammo supply based on caliber` by a certain caliber value.
#### 2.1.1 Example
`[ammo_truck, "32Rnd_155mm_Mo_shells"] call ace_rearm_fnc_addMagazineToSupply;`
| Arguments | Explanation
---| --------- | -----------
0 | `ammo_truck` | My ammo truck object
1 | `"32Rnd_155mm_Mo_shells"` | Some magazine class
The 32 artillery shells are added to the supply count or the magazine storage of the specified ammo truck.
### 2.2 Adding all magazines of a specific vehicle
`ace_rearm_fnc_addVehicleMagazinesToSupply`
| Arguments | Type | Optional (default value)
---| --------- | ---- | ------------------------
0 | Ammo Truck | Object | Required
1 | Any vehicle object or class name | Object or String | Required
**R** | None | None | Return value
This functions wraps `ace_rearm_fnc_addMagazineToSupply` and uses it to add all default magazines of all supported turrets of the vehicle to the ammo truck.
#### 2.2.1 Example 1
`[ammo_truck, tank] call ace_rearm_fnc_addVehicleMagazinesToSupply;`
| Arguments | Explanation
---| --------- | -----------
0 | `ammo_truck` | My ammo truck object
1 | `tank`| A vehicle object
All magazines found in the class config of the object `tank` are made available.
#### 2.2.2 Example 2
`[ammo_truck, "B_MBT_01_arty_F"] call ace_rearm_fnc_addVehicleMagazinesToSupply;`
| Arguments | Explanation
---| --------- | -----------
0 | `ammo_truck` | My ammo truck object
1 | `"B_MBT_01_arty_F"`| Vehicle class name
All magazines found in the config of the vehicle class `B_MBT_01_arty_F` are made available.
### 2.3 Enabling / disabling rearming
`ace_rearm_fnc_disable`
@ -71,3 +144,79 @@ Disables rearming on the object `tank`.
1 | `false`| Rearming is enabled
Enables rearming on the object `tank`.
### 2.4 Getting the supply count
`ace_rearm_fnc_getSupplyCount`
| Arguments | Type | Optional (default value)
---| --------- | ---- | ------------------------
0 | Ammo Truck | Object | Required
**R** | Supply count | Number | Return value
This functions returns the current supply count of the ammo truck.
#### 2.4.1 Example
`[ammo_truck] call ace_rearm_fnc_getSupplyCount;`
| Arguments | Explanation
---| --------- | -----------
0 | `ammo_truck` | My object
The remaining supply count of `ammo_truck` will be returned.
### 2.5 Removing magazines from supply
`ace_rearm_fnc_removeMagazineFromSupply`
| Arguments | Type | Optional (default value)
---| --------- | ---- | ------------------------
0 | Ammo Truck | Object | Required
1 | Magazine Classname | String | Required
2 | Number of Rounds to withdraw | Number | Optional (default: `-1`)
**R** | Magazine could be removed successfully | Boolean | Return value
#### 2.5.1 Example 1
`[ammo_truck, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_removeMagazineFromSupply;`
| Arguments | Explanation
---| --------- | -----------
0 | `ammo_truck` | My ammo truck object
1 | `"500Rnd_127x99_mag_Tracer_Red"`| Carrying is enabled
Removes one ammo box worth of 500Rnd_127x99_mag_Tracer_Red from the supply. Depending on the module setting the ammo box does hold an entire magazine or only the caliber based amount of rounds.
#### 2.5.2 Example 2
`[ammo_truck, "500Rnd_127x99_mag_Tracer_Red", 50] call ace_rearm_fnc_removeMagazineFromSupply;`
| Arguments | Explanation
---| --------- | -----------
0 | `ammo_truck` | My ammo truck object
1 | `"500Rnd_127x99_mag_Tracer_Red"`| Carrying is enabled
2 | `50` | Number of rounds
Removes one ammo box with 50 rounds of 500Rnd_127x99_mag_Tracer_Red from the supply. This is 10% of the supply of an entire magazine.
### 2.6 Setting the supply count
`ace_rearm_fnc_setSupplyCount`
| Arguments | Type | Optional (default value)
---| --------- | ---- | ------------------------
0 | Ammo Truck | Object | Required
1 | Supply Count | Boolean | Required
**R** | None | None | Return value
This function sets the current supply count of the ammo truck. It can be used to replenish the ammo truck on `Limited ammo supply based on caliber` setting.
#### 2.6.1 Example
`[ammo_truck, 1000] call ace_rearm_fnc_setSupplyCount;`
| Arguments | Explanation
---| --------- | -----------
0 | `ammo_truck` | My ammo truck object
1 | `1000`| Supply Count

View File

@ -1,27 +1,3 @@
#define MACRO_REARM_TRUCK_ACTIONS \
class ACE_Actions: ACE_Actions { \
class ACE_MainActions: ACE_MainActions { \
class EGVAR(rearm,TakeAmmo) { \
displayName = ECSTRING(rearm,TakeAmmo); \
distance = 7; \
condition = QUOTE(_this call EFUNC(rearm,canTakeAmmo)); \
insertChildren = QUOTE(_target call EFUNC(rearm,addRearmActions)); \
exceptions[] = {"isNotInside"}; \
showDisabled = 0; \
priority = 2; \
icon = QPATHTOEF(rearm,ui\icon_rearm_interact.paa); \
}; \
class EGVAR(rearm,StoreAmmo) { \
displayName = ECSTRING(rearm,StoreAmmo); \
distance = 7; \
condition = QUOTE(_this call EFUNC(rearm,canStoreAmmo)); \
statement = QUOTE(_this call EFUNC(rearm,storeAmmo)); \
exceptions[] = {"isNotInside"}; \
icon = QPATHTOEF(rearm,ui\icon_rearm_interact.paa); \
}; \
}; \
};
#define MACRO_REFUEL_ACTIONS \
class ACE_Actions: ACE_Actions { \
class ACE_MainActions: ACE_MainActions { \
@ -408,7 +384,7 @@ class CfgVehicles {
class rhs_gaz66_ammo_base: rhs_gaz66_vmf {
transportAmmo = 0;
MACRO_REARM_TRUCK_ACTIONS
ace_rearm_supply = 1200;
};
class MRAP_02_base_F;

View File

@ -11,30 +11,6 @@
}; \
}
#define MACRO_REARM_TRUCK_ACTIONS \
class ACE_Actions: ACE_Actions { \
class ACE_MainActions: ACE_MainActions { \
class EGVAR(rearm,TakeAmmo) { \
displayName = ECSTRING(rearm,TakeAmmo); \
distance = 7; \
condition = QUOTE(_this call EFUNC(rearm,canTakeAmmo)); \
insertChildren = QUOTE(_target call EFUNC(rearm,addRearmActions)); \
exceptions[] = {"isNotInside"}; \
showDisabled = 0; \
priority = 2; \
icon = QPATHTOEF(rearm,ui\icon_rearm_interact.paa); \
}; \
class EGVAR(rearm,StoreAmmo) { \
displayName = ECSTRING(rearm,StoreAmmo); \
distance = 7; \
condition = QUOTE(_this call EFUNC(rearm,canStoreAmmo)); \
statement = QUOTE(_this call EFUNC(rearm,storeAmmo)); \
exceptions[] = {"isNotInside"}; \
icon = QPATHTOEF(rearm,ui\icon_rearm_interact.paa); \
}; \
}; \
};
#define MACRO_REFUEL_ACTIONS \
class ACE_Actions: ACE_Actions { \
class ACE_MainActions: ACE_MainActions { \
@ -316,19 +292,19 @@ class CfgVehicles {
class rhsusf_M977A4_usarmy_wd: rhsusf_HEMTT_A4_base {};
class rhsusf_M977A4_AMMO_usarmy_wd: rhsusf_M977A4_usarmy_wd {
transportAmmo = 0;
MACRO_REARM_TRUCK_ACTIONS
ace_rearm_supply = 1200;
};
class rhsusf_M977A4_BKIT_usarmy_wd: rhsusf_M977A4_usarmy_wd {};
class rhsusf_M977A4_AMMO_BKIT_usarmy_wd: rhsusf_M977A4_BKIT_usarmy_wd {
transportAmmo = 0;
MACRO_REARM_TRUCK_ACTIONS
ace_rearm_supply = 1200;
};
class rhsusf_M977A4_BKIT_M2_usarmy_wd: rhsusf_M977A4_usarmy_wd {};
class rhsusf_M977A4_AMMO_BKIT_M2_usarmy_wd: rhsusf_M977A4_BKIT_M2_usarmy_wd {
transportAmmo = 0;
MACRO_REARM_TRUCK_ACTIONS
ace_rearm_supply = 1200;
};
class rhsusf_M978A4_usarmy_wd: rhsusf_M977A4_usarmy_wd {
@ -373,7 +349,7 @@ class CfgVehicles {
class rhsusf_m113_usarmy: rhsusf_m113tank_base {};
class rhsusf_m113_usarmy_supply: rhsusf_m113_usarmy {
transportAmmo = 0;
MACRO_REARM_TRUCK_ACTIONS
ace_rearm_supply = 1200;
};
class APC_Tracked_03_base_F;