diff --git a/addons/cargo/CfgEventHandlers.hpp b/addons/cargo/CfgEventHandlers.hpp index 6c29240403..5fedbc4606 100644 --- a/addons/cargo/CfgEventHandlers.hpp +++ b/addons/cargo/CfgEventHandlers.hpp @@ -16,3 +16,11 @@ class Extended_PostInit_EventHandlers { init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; + +class Extended_InventoryOpened_EventHandlers { + class CAManBase { + class GVAR(onOpenInventory) { + clientInventoryOpened = QUOTE(if (_this select 0 == ACE_player) then {_this call FUNC(onOpenInventory)};); + }; + }; +}; diff --git a/addons/cargo/XEH_PREP.hpp b/addons/cargo/XEH_PREP.hpp index 95fefb4ba0..a86b6ef1f4 100644 --- a/addons/cargo/XEH_PREP.hpp +++ b/addons/cargo/XEH_PREP.hpp @@ -12,6 +12,7 @@ PREP(initVehicle); PREP(loadItem); PREP(moduleSettings); PREP(onMenuOpen); +PREP(onOpenInventory); PREP(paradropItem); PREP(removeCargoItem); PREP(renameObject); diff --git a/addons/cargo/functions/fnc_initVehicle.sqf b/addons/cargo/functions/fnc_initVehicle.sqf index 948fdf525e..c069a8ffe7 100644 --- a/addons/cargo/functions/fnc_initVehicle.sqf +++ b/addons/cargo/functions/fnc_initVehicle.sqf @@ -51,10 +51,29 @@ if (isServer) then { // Servers and HCs do not require action menus (beyond this point) if !(hasInterface) exitWith {}; +if (_vehicle getVariable [QGVAR(initVehicle),false]) exitWith {}; +private _tb = getNumber (_config >> "transportmaxbackpacks"); +private _tm = getNumber (_config >> "transportmaxmagazines"); +private _tw = getNumber (_config >> "transportmaxweapons"); +private _hasInventory = (_tb > 0 || _tm > 0 || _tw > 0); +_vehicle setVariable [QGVAR(hasInventory), _hasInventory]; + +// This is a Hack to add the Gear Action and thus the Cargo UI to vehicles/Objects that dont naturally have a Gear Action +if (!_hasInventory) then { + private _cfgAction = configFile >> "CfgActions" >> "Gear"; + private _title = getText (_cfgAction >> "text"); + private _hideOnUse = getNumber (_cfgAction >> "hideOnUse") == 1; + private _showWindow = getNumber (_cfgAction >> "showWindow") == 1; + private _textDefault = getText (_cfgAction >> "textDefault"); + private _shortcut = getText (_cfgAction >> "shortcut"); + private _id = _vehicle addAction [_title, { + ACE_Player action ["Gear", objNull]; + }, nil, 5.1, _showWindow, _hideOnUse, _shortcut, "!(lockedInventory _target)"]; + _vehicle setUserActionText [_id, _title, _textDefault]; +}; + // Unnecessary to add actions to a vehicle class that's already got them if (_type in GVAR(initializedVehicleClasses)) exitWith {}; -if (_vehicle getVariable [QGVAR(initVehicle),false]) exitWith {}; - // Vehicles given cargo via eden have their actions added to the object // So this function may run for multiple of the same class in that case if (_hasCargoConfig) then { diff --git a/addons/cargo/functions/fnc_onOpenInventory.sqf b/addons/cargo/functions/fnc_onOpenInventory.sqf new file mode 100644 index 0000000000..c7f0bd9e11 --- /dev/null +++ b/addons/cargo/functions/fnc_onOpenInventory.sqf @@ -0,0 +1,136 @@ +#include "..\script_component.hpp" +/* + * Author: joko // Jonas, BadGuy + * Handles Inventory UI when vehicle has a Cargo Inventory + * + * Arguments: + * 0: Unit + * 1: Container + * + * Return Value: + * None + * + * Example: + * [vehicle] call ace_cargo_fnc_addCargoItem + * + * Public: No + */ + +if !(GVAR(enable)) exitWith {}; + +params ["_unit", "_container"]; + +// This is the 2nd Part of the Hack for Vehicles that dont have an Inventory +if (_container isKindOf "GroundWeaponHolder") then { + private _target = cursorObject; + if (!(_target getVariable [QGVAR(hasInventory), true]) && ((ACE_Player distance _target) < MAX_LOAD_DISTANCE) && !lockedInventory _target) then { + _container = _target; + }; +}; + +if !(_container getVariable [QGVAR(hasCargo), getNumber (configOf _container >> QGVAR(hasCargo)) == 1]) exitWith {}; + +GVAR(interactionVehicle) = _container; + +GVAR(interactionParadrop) = _container isKindOf "Air" && { + private _turretPath = _unit call CBA_fnc_turretPath; + (_unit == (driver _container)) || // pilot + {(getNumber (([_container, _turretPath] call CBA_fnc_getTurret) >> "isCopilot")) == 1} || // coPilot + {_turretPath in (getArray (configOf _container >> QGVAR(loadmasterTurrets)))} // loadMaster turret from config + }; + +[{!isNull (findDisplay 602)}, { + private _display = (findDisplay 602); // Find Inventory Display + private _gY = ((((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25); + private _gX = (((safeZoneW / safeZoneH) min 1.2) / 40); + + + private _hasInventory = GVAR(interactionVehicle) getVariable [QGVAR(hasInventory), true]; + private _xOffset = [1, -5.25] select (_hasInventory); + + if (_hasInventory) then { + { + private _pos = ctrlPosition _x; + + _x ctrlSetPosition [ + (_pos select 0) + 6.25 * _gX, + (_pos select 1) + ]; + _x ctrlCommit 0; + } forEach allControls _display; + } else { + { + (_display displayCtrl _x) ctrlSetFade 1; + (_display displayCtrl _x) ctrlCommit 0; + } forEach [1001, 632, 6554, 6307, 6385, 6321]; + }; + + private _group = _display ctrlCreate ["RscControlsGroupNoScrollbars", -1]; + _group ctrlSetPosition [_xOffset * _gX + (safeZoneX + (safeZoneW - ((safeZoneW / safeZoneH) min 1.2)) / 2), _gY + (safeZoneY + (safeZoneH - (((safeZoneW / safeZoneH) min 1.2) / 1.2)) / 2), 12 * _gX, 22.55 * _gY]; + _group ctrlCommit 0; + + private _bg = _display ctrlCreate ["RscBackground", -1, _group]; + _bg ctrlSetPosition [0, 0, 12 * _gX, 23 * _gY]; + _bg ctrlSetBackgroundColor [0.05, 0.05, 0.05, 0.7]; + _bg ctrlCommit 0; + + private _header = _display ctrlCreate ["RscText", -1, _group]; + _header ctrlSetPosition [0.5 * _gX, 0.5 * _gY, 11 * _gX, 1.1 * _gY]; + _header ctrlSetBackgroundColor [0, 0, 0, 1]; + _header ctrlSetText (localize LSTRING(openMenu)); // This localization key is currently "borrowed" we could make it its own key but we dont need to + _header ctrlCommit 0; + + private _list = _display ctrlCreate ["RscListBox", -1, _group]; + _list ctrlSetPosition [0.5 * _gX, 1.7 * _gY, 11 * _gX, 17.8 * _gY]; + _list ctrlSetBackgroundColor [0, 0, 0, 0]; + _list ctrlCommit 0; + uiNamespace setVariable [QGVAR(CargoListBox), _list]; + + private _unloadBtn = _display ctrlCreate ["RscButton", -1, _group]; + _unloadBtn ctrlSetPosition [0.5 * _gX, 20 * _gY, 5.5 * _gX, 1 * _gY]; + _unloadBtn ctrlSetText localize ([LSTRING(unloadObject), LSTRING(paradropButton)] select GVAR(interactionParadrop)); + _unloadBtn ctrlAddEventHandler ["ButtonClick", { + private _index = lbCurSel (uiNamespace getVariable QGVAR(CargoListBox)); + if (_index == -1) exitWith {}; + closeDialog 602; + [_index] call FUNC(startUnload); + }]; + _unloadBtn ctrlCommit 0; + + private _loadBarFrame = _display ctrlCreate ["RscFrame", -1, _group]; + _loadBarFrame ctrlSetPosition [0.5 * _gX, 21.5 * _gY, 11 * _gX, 0.5 * _gY]; + _loadBarFrame ctrlSetTextColor [0.9, 0.9, 0.9, 0.5]; + _loadBarFrame ctrlCommit 0; + + private _loadBar = _display ctrlCreate ["RscProgress", -1, _group]; + _loadBar ctrlSetPosition [0.5 * _gX, 21.5 * _gY, 11 * _gX, 0.5 * _gY]; + _loadBar ctrlSetTextColor [0.9, 0.9, 0.9, 0.9]; + _loadBar progressSetPosition 0; + _loadBar ctrlCommit 0; + + // UPDATE LOOP + [{ + params ["_args", "_id"]; + + if (isNull (findDisplay 602)) exitWith { + [_id] call CBA_fnc_removePerFrameHandler; + }; + _args params ["_loadBar", "_list"]; + private _cargoItems = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; + lbClear _list; + { + private _displayName = [_x, true] call FUNC(getNameItem); + + if (GVAR(interactionParadrop)) then { + _displayName = format ["%1 (%2s)", _displayName, GVAR(paradropTimeCoefficent) * ([_x] call FUNC(getSizeItem))]; + }; + _list lbAdd _displayName; + } forEach _cargoItems; + + private _cargoCapacity = GVAR(interactionVehicle) getVariable [QGVAR(spaceMax), getNumber (configOf GVAR(interactionVehicle) >> QGVAR(space))]; + private _usedCargoCapacity = _cargoCapacity - ([GVAR(interactionVehicle)] call FUNC(getCargoSpaceLeft)); + + _loadBar progressSetPosition (_usedCargoCapacity / _cargoCapacity); + + }, 1, [_loadBar, _list]] call CBA_fnc_addPerFrameHandler; +}] call CBA_fnc_waitUntilAndExecute; \ No newline at end of file diff --git a/addons/cargo/functions/fnc_setSpace.sqf b/addons/cargo/functions/fnc_setSpace.sqf index f573019a11..278c0fe7d6 100644 --- a/addons/cargo/functions/fnc_setSpace.sqf +++ b/addons/cargo/functions/fnc_setSpace.sqf @@ -46,6 +46,8 @@ if (_newSpace == (_vehicle getVariable [QGVAR(space), CARGO_SPACE(typeOf _vehicl // Apply new space globally _vehicle setVariable [QGVAR(space), _newSpace, true]; +// Set Maximal Space required for Inventory UI +_vehicle setVariable [QGVAR(spaceMax), _newSpace, true]; // Necessary to update value, even if no space, as API could be used again _vehicle setVariable [QGVAR(hasCargo), _space > 0, true]; diff --git a/addons/cargo/functions/fnc_startUnload.sqf b/addons/cargo/functions/fnc_startUnload.sqf index cf00327dcc..1e51271c55 100644 --- a/addons/cargo/functions/fnc_startUnload.sqf +++ b/addons/cargo/functions/fnc_startUnload.sqf @@ -4,7 +4,7 @@ * Start unload action. * * Arguments: - * None + * 0: Index of Unloading Item (default: -1) * * Return Value: * None @@ -16,17 +16,22 @@ */ disableSerialization; +params [["_selected", -1, [0]]]; -private _display = uiNamespace getVariable QGVAR(menuDisplay); -if (isNil "_display") exitWith {}; +if (_select == -1) then { + private _display = uiNamespace getVariable QGVAR(menuDisplay); + if (isNil "_display") exitWith {}; + + private _ctrl = _display displayCtrl 100; + + _selected = (lbCurSel _ctrl) max 0; +}; + +if (_selected == -1) exitWith {}; private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; if (_loaded isEqualTo []) exitWith {}; -private _ctrl = _display displayCtrl 100; - -private _selected = (lbCurSel _ctrl) max 0; - if (count _loaded <= _selected) exitWith {}; private _item = _loaded select _selected; // This can be an object or a classname string