diff --git a/addons/inventory/CfgEventHandlers.hpp b/addons/inventory/CfgEventHandlers.hpp new file mode 100644 index 0000000000..0cd959a047 --- /dev/null +++ b/addons/inventory/CfgEventHandlers.hpp @@ -0,0 +1,12 @@ + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; diff --git a/addons/inventory/XEH_postInit.sqf b/addons/inventory/XEH_postInit.sqf new file mode 100644 index 0000000000..d0e3fb042a --- /dev/null +++ b/addons/inventory/XEH_postInit.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +GVAR(customFilters) = []; +GVAR(selectedFilterIndex) = -1; + +["inventoryDisplayLoaded", {_this call FUNC(inventoryDisplayLoaded)}] call EFUNC(common,addEventHandler); + +// add custom filters + +// generate list of grenades +GVAR(Grenades_ItemList) = []; + +{ + GVAR(Grenades_ItemList) append getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"); + false +} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); + +// make list case insensitive +GVAR(Grenades_ItemList) = [GVAR(Grenades_ItemList), {toLower _this}] call EFUNC(common,map); + +// filter duplicates +GVAR(Grenades_ItemList) = GVAR(Grenades_ItemList) arrayIntersect GVAR(Grenades_ItemList); + +[localize LSTRING(Grenades), QFUNC(filterGrenades)] call FUNC(addCustomFilter); + +[localize LSTRING(Backpacks), QFUNC(filterBackpacks)] call FUNC(addCustomFilter); +[localize LSTRING(Uniforms), QFUNC(filterUniforms)] call FUNC(addCustomFilter); +[localize LSTRING(Vests), QFUNC(filterVests)] call FUNC(addCustomFilter); +[localize LSTRING(Headgear), QFUNC(filterHeadgear)] call FUNC(addCustomFilter); + +// generate list of medical items +GVAR(Medical_ItemList) = []; + +{ + GVAR(Medical_ItemList) append getArray (_x >> "items"); + false +} count ( + ("true" configClasses (configFile >> QEGVAR(Medical,Actions) >> "Basic")) + + ("true" configClasses (configFile >> QEGVAR(Medical,Actions) >> "Advanced")) +); + +// make list case insensitive +GVAR(Medical_ItemList) = [GVAR(Medical_ItemList), {if (_this isEqualType "") then {toLower _this}}] call EFUNC(common,map); + +// filter duplicates +GVAR(Medical_ItemList) = GVAR(Medical_ItemList) arrayIntersect GVAR(Medical_ItemList); + +[localize LSTRING(Medical), QFUNC(filterMedical)] call FUNC(addCustomFilter); diff --git a/addons/inventory/XEH_preInit.sqf b/addons/inventory/XEH_preInit.sqf new file mode 100644 index 0000000000..d574cacf3b --- /dev/null +++ b/addons/inventory/XEH_preInit.sqf @@ -0,0 +1,64 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP(addCustomFilter); +PREP(currentItemListBox); +PREP(forceItemListUpdate); +PREP(inventoryDisplayLoaded); +PREP(onLBSelChanged); + +// cache config +// items in the inventory display can only be distinguished by their lb names and pictures +// this can cause collisions (mainly weapons with attachments), +// but if the item has the same name and picture it at least shouldn't change the filter anyway +// luckily we don't need private items, so dummy and parent classes are out of the picture + +if !(uiNamespace getVariable [QGVAR(configCached), false]) then { + private _fnc_addToCache = { + private _displayName = getText (_this >> "displayName"); + private _picture = getText (_this >> "picture"); + + // list box seems to delete the leading backslash + if (_picture select [0,1] == "\") then { + _picture = _picture select [1]; + }; + + uiNamespace setVariable [format [QGVAR(ItemKey:%1:%2), _displayName, _picture], _this]; + }; + + // weapons and items + { + if (getNumber (_x >> "scope") > 0) then {_x call _fnc_addToCache}; + false + } count ( + ("true" configClasses (configFile >> "CfgWeapons")) + + ("true" configClasses (configFile >> "CfgGlasses")) + ); + + // magazines + { + if (getNumber (_x >> "scope") == 2) then {_x call _fnc_addToCache}; + false + } count ("true" configClasses (configFile >> "CfgMagazines")); + + // backpacks + { + if (getNumber (_x >> "scope") > 0 && {getNumber (_x >> "isBackpack") == 1}) then {_x call _fnc_addToCache}; + false + } count ("true" configClasses (configFile >> "CfgVehicles")); + + uiNamespace setVariable [QGVAR(configCached), true]; +}; + +PREP(filterWeapons); +PREP(filterMagazines); +PREP(filterItems); +PREP(filterHeadgear); +PREP(filterUniforms); +PREP(filterVests); +PREP(filterBackpacks); +PREP(filterGrenades); +PREP(filterMedical); + +ADDON = true; diff --git a/addons/inventory/config.cpp b/addons/inventory/config.cpp index 1190525901..f0982a46b4 100644 --- a/addons/inventory/config.cpp +++ b/addons/inventory/config.cpp @@ -6,11 +6,13 @@ class CfgPatches { weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; - author[] = {"Pabst Mirror"}; + author[] = {"Pabst Mirror, commy2"}; authorUrl = "https://github.com/PabstMirror/"; VERSION_CONFIG; }; }; +#include "CfgEventHandlers.hpp" + #include "RscDisplayInventory.hpp" #include "ACE_Settings.hpp" diff --git a/addons/inventory/functions/fnc_addCustomFilter.sqf b/addons/inventory/functions/fnc_addCustomFilter.sqf new file mode 100644 index 0000000000..44e43bdbf0 --- /dev/null +++ b/addons/inventory/functions/fnc_addCustomFilter.sqf @@ -0,0 +1,19 @@ +/* + * Author: commy2 + * Adds a custom filter list to the inventory display. + * Functions are here as strings, because list boxes can only store numbers and strings. + * + * Arguments: + * 0: Localized filter display name + * 1: Filter function name + * + * Return Value: + * None + * + * Public: No + */ +#include "script_component.hpp" + +params [["_filterName", "ERROR: No Name", [""]], ["_fncName", "", [""]]]; + +GVAR(customFilters) pushBack [_filterName, _fncName]; diff --git a/addons/inventory/functions/fnc_currentItemListBox.sqf b/addons/inventory/functions/fnc_currentItemListBox.sqf new file mode 100644 index 0000000000..1f1b528e93 --- /dev/null +++ b/addons/inventory/functions/fnc_currentItemListBox.sqf @@ -0,0 +1,30 @@ +/* + * Author: commy2 + * Returns the current item list box of given inventory display. + * These can be Ground, Soldier, Uniform, Backpack or Vest. + * Can also be Weapon since 1.52, but that apparently uses one of the above. + * + * Arguments: + * 0: Inventory display + * + * Return Value: + * Currently selected item list box + * + * Public: No + */ +#include "script_component.hpp" + +params ["_display"]; + +scopeName "main"; + +{ + private _control = _display displayCtrl _x; + + if (ctrlShown _control) then { + _control breakOut "main"; + }; + false +} count [IDC_ITEMLIST_GROUND, IDC_ITEMLIST_SOLDIER, IDC_ITEMLIST_UNIFORM, IDC_ITEMLIST_VEST, IDC_ITEMLIST_BACKPACK]; + +-1 diff --git a/addons/inventory/functions/fnc_filterBackpacks.sqf b/addons/inventory/functions/fnc_filterBackpacks.sqf new file mode 100644 index 0000000000..9b629de66f --- /dev/null +++ b/addons/inventory/functions/fnc_filterBackpacks.sqf @@ -0,0 +1,17 @@ +/* + * Author: commy2 + * Filter condition for the Backpacks filter list + * + * Arguments: + * 0: Item config entry + * + * Return Value: + * Item should appear in this list? + * + * Public: No + */ +#include "script_component.hpp" + +params ["_config"]; + +getNumber (_config >> "isBackpack") == 1 diff --git a/addons/inventory/functions/fnc_filterGrenades.sqf b/addons/inventory/functions/fnc_filterGrenades.sqf new file mode 100644 index 0000000000..0acfbcaa2c --- /dev/null +++ b/addons/inventory/functions/fnc_filterGrenades.sqf @@ -0,0 +1,17 @@ +/* + * Author: commy2 + * Filter condition for the Grenades filter list + * + * Arguments: + * 0: Item config entry + * + * Return Value: + * Item should appear in this list? + * + * Public: No + */ +#include "script_component.hpp" + +params ["_config"]; + +toLower configName _config in GVAR(Grenades_ItemList) diff --git a/addons/inventory/functions/fnc_filterHeadgear.sqf b/addons/inventory/functions/fnc_filterHeadgear.sqf new file mode 100644 index 0000000000..056406a3d1 --- /dev/null +++ b/addons/inventory/functions/fnc_filterHeadgear.sqf @@ -0,0 +1,17 @@ +/* + * Author: commy2 + * Filter condition for the Headgear filter list + * + * Arguments: + * 0: Item config entry + * + * Return Value: + * Item should appear in this list? + * + * Public: No + */ +#include "script_component.hpp" + +params ["_config"]; + +getNumber (_config >> "ItemInfo" >> "type") in [TYPE_HEADGEAR, TYPE_HMD] || {isClass (configFile >> "CfgGlasses" >> configName _config)} diff --git a/addons/inventory/functions/fnc_filterItems.sqf b/addons/inventory/functions/fnc_filterItems.sqf new file mode 100644 index 0000000000..b9bf9baeea --- /dev/null +++ b/addons/inventory/functions/fnc_filterItems.sqf @@ -0,0 +1,17 @@ +/* + * Author: commy2 + * Remove uniforms, vests and backpacks from Items filter. + * + * Arguments: + * 0: Item config entry + * + * Return Value: + * Item should appear in this list? + * + * Public: No + */ +#include "script_component.hpp" + +params ["_config"]; + +!(getNumber (_config >> "ItemInfo" >> "type") in [TYPE_UNIFORM, TYPE_VESTS, TYPE_HEADGEAR]) && {!(_this call FUNC(filterBackpacks))} diff --git a/addons/inventory/functions/fnc_filterMagazines.sqf b/addons/inventory/functions/fnc_filterMagazines.sqf new file mode 100644 index 0000000000..dfd357f61d --- /dev/null +++ b/addons/inventory/functions/fnc_filterMagazines.sqf @@ -0,0 +1,15 @@ +/* + * Author: commy2 + * Remove backpacks and grenades from Magazines filter. + * + * Arguments: + * 0: Item config entry + * + * Return Value: + * Item should appear in this list? + * + * Public: No + */ +#include "script_component.hpp" + +!(_this call FUNC(filterBackpacks)) && {!(_this call FUNC(filterGrenades))} diff --git a/addons/inventory/functions/fnc_filterMedical.sqf b/addons/inventory/functions/fnc_filterMedical.sqf new file mode 100644 index 0000000000..397be50f06 --- /dev/null +++ b/addons/inventory/functions/fnc_filterMedical.sqf @@ -0,0 +1,17 @@ +/* + * Author: commy2 + * Filter condition for the Medical filter list + * + * Arguments: + * 0: Item config entry + * + * Return Value: + * Item should appear in this list? + * + * Public: No + */ +#include "script_component.hpp" + +params ["_config"]; + +toLower configName _config in GVAR(Medical_ItemList) diff --git a/addons/inventory/functions/fnc_filterUniforms.sqf b/addons/inventory/functions/fnc_filterUniforms.sqf new file mode 100644 index 0000000000..4c135dfa88 --- /dev/null +++ b/addons/inventory/functions/fnc_filterUniforms.sqf @@ -0,0 +1,17 @@ +/* + * Author: commy2 + * Filter condition for the Uniforms filter list + * + * Arguments: + * 0: Item config entry + * + * Return Value: + * Item should appear in this list? + * + * Public: No + */ +#include "script_component.hpp" + +params ["_config"]; + +getNumber (_config >> "ItemInfo" >> "type") == TYPE_UNIFORM diff --git a/addons/inventory/functions/fnc_filterVests.sqf b/addons/inventory/functions/fnc_filterVests.sqf new file mode 100644 index 0000000000..646e23d04d --- /dev/null +++ b/addons/inventory/functions/fnc_filterVests.sqf @@ -0,0 +1,17 @@ +/* + * Author: commy2 + * Filter condition for the Vests filter list + * + * Arguments: + * 0: Item config entry + * + * Return Value: + * Item should appear in this list? + * + * Public: No + */ +#include "script_component.hpp" + +params ["_config"]; + +getNumber (_config >> "ItemInfo" >> "type") == TYPE_VEST diff --git a/addons/inventory/functions/fnc_filterWeapons.sqf b/addons/inventory/functions/fnc_filterWeapons.sqf new file mode 100644 index 0000000000..94a92814ae --- /dev/null +++ b/addons/inventory/functions/fnc_filterWeapons.sqf @@ -0,0 +1,15 @@ +/* + * Author: commy2 + * Remove backpacks from Weapons filter. + * + * Arguments: + * 0: Item config entry + * + * Return Value: + * Item should appear in this list? + * + * Public: No + */ +#include "script_component.hpp" + +!(_this call FUNC(filterBackpacks)) diff --git a/addons/inventory/functions/fnc_forceItemListUpdate.sqf b/addons/inventory/functions/fnc_forceItemListUpdate.sqf new file mode 100644 index 0000000000..89142b99ff --- /dev/null +++ b/addons/inventory/functions/fnc_forceItemListUpdate.sqf @@ -0,0 +1,40 @@ +/* + * Author: commy2 + * Updates item list and removes every entry that does not fit in the currently selected filter list. + * + * Arguments: + * 0: Inventory display + * + * Return Value: + * None + * + * Public: No + */ +#include "script_component.hpp" + +disableSerialization; +params ["_display"]; + +private _index = GVAR(selectedFilterIndex); +private _itemList = _display call FUNC(currentItemListBox); +private _filterFunction = missionNamespace getVariable ((_display displayCtrl IDC_FILTERLISTS) lbData _index); + +if (_filterFunction isEqualType {}) then { + private _i = 0; + + while {_i < lbSize _itemList} do { + private _config = uiNamespace getVariable [ + format [QGVAR(ItemKey:%1:%2), _itemList lbText _i, _itemList lbPicture _i], + configNull + ]; + + if (!isNull _config && {!(_config call _filterFunction)}) then { + _itemList lbDelete _i; + + // in case the filter function returns nil. Otherwise could lock up the game. + _i = _i - 1; + }; + + _i = _i + 1; + }; +}; diff --git a/addons/inventory/functions/fnc_inventoryDisplayLoaded.sqf b/addons/inventory/functions/fnc_inventoryDisplayLoaded.sqf new file mode 100644 index 0000000000..6e48c1ec2a --- /dev/null +++ b/addons/inventory/functions/fnc_inventoryDisplayLoaded.sqf @@ -0,0 +1,77 @@ +/* + * Author: commy2 + * Executed every time an inventory display is opened. + * + * Arguments: + * 0: Inventory display + * + * Return Value: + * None + * + * Public: No + */ +#include "script_component.hpp" + +disableSerialization; +params ["_display"]; + +private _filter = _display displayCtrl IDC_FILTERLISTS; + +// engine defined behaviour is the following: +// lb value, data and text don't matter, only the index. +// the first three indecies are hard coded: 0 - weapons , 1 - magazines, 2 - items +// all of them show backpacks, because BI +// all other indecies show everything, so all we have to do is delete stuff we dont like +_filter ctrlAddEventHandler ["LBSelChanged", {_this call FUNC(onLBSelChanged)}]; + +// have to add these a frame later, because this event happens before the engine adds the default filters +[{ + disableSerialization; + params ["_filter"]; + + // remove "All", so we can push it to the back later. + // to keep localization we can keep the lbText (displayed name). + private _index = lbSize _filter - 1; + private _nameAll = _filter lbText _index; + _filter lbDelete _index; + + // add additional filter functions to the default filters. These remove backpacks etc. + _filter lbSetData [0, QFUNC(filterWeapons)]; + _filter lbSetData [1, QFUNC(filterMagazines)]; + _filter lbSetData [2, QFUNC(filterItems)]; + + // add our custom filters + { + _x params ["_name", "_fncName"]; + + _index = _filter lbAdd _name; + _filter lbSetData [_index, _fncName]; + + false + } count GVAR(customFilters); + + // readd "All" filter to last position and select it + _index = _filter lbAdd _nameAll; + _filter lbSetCurSel _index; +}, [_filter]] call EFUNC(common,execNextFrame); + +// monitor changes that can happen and force our update +private _dummyControl = _display ctrlCreate ["RscMapControl", -1]; + +_dummyControl ctrlSetPosition [0,0,0,0]; +_dummyControl ctrlCommit 0; + +_dummyControl ctrlAddEventHandler ["Draw", { + disableSerialization; + params ["_dummyControl"]; + + private _display = ctrlParent _dummyControl; + + private _itemList = _display call FUNC(currentItemListBox); + + // monitoring is done by setting a lb value. These are unused here and are reset every time the list box updates. + if (_itemList lbValue 0 != DUMMY_VALUE) then { + _display call FUNC(forceItemListUpdate); + _itemList lbSetValue [0, DUMMY_VALUE]; + }; +}]; diff --git a/addons/inventory/functions/fnc_onLBSelChanged.sqf b/addons/inventory/functions/fnc_onLBSelChanged.sqf new file mode 100644 index 0000000000..61e4b12b10 --- /dev/null +++ b/addons/inventory/functions/fnc_onLBSelChanged.sqf @@ -0,0 +1,27 @@ +/* + * Author: commy2 + * Executed when the filter list box is changed. + * Sets new filter list index. + * + * Arguments: + * 0: Filter list box + * 1: Filter list index + * + * Return Value: + * None + * + * Public: No + */ +#include "script_component.hpp" + +disableSerialization; +params ["_filter", "_index"]; + +GVAR(selectedFilterIndex) = _index; + +[{ + disableSerialization; + params ["_display"]; + + [_display] call FUNC(forceItemListUpdate); +}, [ctrlParent _filter]] call EFUNC(common,execNextFrame); diff --git a/addons/inventory/functions/script_component.hpp b/addons/inventory/functions/script_component.hpp new file mode 100644 index 0000000000..07c5e38d2d --- /dev/null +++ b/addons/inventory/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\inventory\script_component.hpp" \ No newline at end of file diff --git a/addons/inventory/script_component.hpp b/addons/inventory/script_component.hpp index 248f324b36..b013e08570 100644 --- a/addons/inventory/script_component.hpp +++ b/addons/inventory/script_component.hpp @@ -2,11 +2,20 @@ #include "\z\ace\addons\main\script_mod.hpp" #ifdef DEBUG_ENABLED_INVENTORY - #define DEBUG_MODE_FULL + #define DEBUG_MODE_FULL #endif #ifdef DEBUG_SETTINGS_INVENTORY - #define DEBUG_SETTINGS DEBUG_SETTINGS_INVENTORY + #define DEBUG_SETTINGS DEBUG_SETTINGS_INVENTORY #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define IDC_FILTERLISTS 6554 +#define IDC_ITEMLIST_GROUND 632 +#define IDC_ITEMLIST_SOLDIER 640 +#define IDC_ITEMLIST_UNIFORM 633 +#define IDC_ITEMLIST_VEST 638 +#define IDC_ITEMLIST_BACKPACK 619 + +#define DUMMY_VALUE 127 diff --git a/addons/inventory/stringtable.xml b/addons/inventory/stringtable.xml index 04cac46b87..af21fe3ddf 100644 --- a/addons/inventory/stringtable.xml +++ b/addons/inventory/stringtable.xml @@ -25,5 +25,33 @@ Normalmente il menù inventario è scalato in base alle dimensioni interfaccia. Questa opzione di permette di ingrandirlo ulteriormente ma senza aumentare la dimensione del testo. Normalmente o tamanho da tela do inventário é ditada pelo tamanho da UI. Isso permite aumentar o tamanho da tela de inventário, mas não aumenta o tamanho da fonte, permitindo que mais linhas sejam visualizadas. + + Backpacks + Rucksäcke + + + Headgear + Kopfbedeckungen + + + Glasses + Brillen + + + Uniforms + Uniformen + + + Vests + Westen + + + Grenades + Granaten + + + Medical + Sanimaterial + diff --git a/addons/main/script_macros.hpp b/addons/main/script_macros.hpp index 62d0b33a6c..fdb020c114 100644 --- a/addons/main/script_macros.hpp +++ b/addons/main/script_macros.hpp @@ -38,25 +38,48 @@ #define MACRO_ADDWEAPON(WEAPON,COUNT) class _xx_##WEAPON { \ - weapon = #WEAPON; \ - count = COUNT; \ + weapon = #WEAPON; \ + count = COUNT; \ } #define MACRO_ADDITEM(ITEM,COUNT) class _xx_##ITEM { \ - name = #ITEM; \ - count = COUNT; \ + name = #ITEM; \ + count = COUNT; \ } #define MACRO_ADDMAGAZINE(MAGAZINE,COUNT) class _xx_##MAGAZINE { \ - magazine = #MAGAZINE; \ - count = COUNT; \ + magazine = #MAGAZINE; \ + count = COUNT; \ } #define MACRO_ADDBACKPACK(BACKPACK,COUNT) class _xx_##BACKPACK { \ - backpack = #BACKPACK; \ - count = COUNT; \ + backpack = #BACKPACK; \ + count = COUNT; \ } +// item types +#define TYPE_DEFAULT 0 +#define TYPE_MUZZLE 101 +#define TYPE_OPTICS 201 +#define TYPE_FLASHLIGHT 301 +#define TYPE_BIPOD 302 +#define TYPE_FIRST_AID_KIT 401 +#define TYPE_FINS 501 // not implemented +#define TYPE_BREATHING_BOMB 601 // not implemented +#define TYPE_NVG 602 +#define TYPE_GOGGLE 603 +#define TYPE_SCUBA 604 // not implemented +#define TYPE_HEADGEAR 605 +#define TYPE_FACTOR 607 +#define TYPE_RADIO 611 +#define TYPE_HMD 616 +#define TYPE_BINOCULAR 617 +#define TYPE_MEDIKIT 619 +#define TYPE_TOOLKIT 620 +#define TYPE_UAV_TERMINAL 621 +#define TYPE_VEST 701 +#define TYPE_UNIFORM 801 +#define TYPE_BACKPACK 901 #ifdef DISABLE_COMPILE_CACHE #define PREP(fncName) DFUNC(fncName) = compile preprocessFileLineNumbers QUOTE(PATHTOF(functions\DOUBLES(fnc,fncName).sqf))