diff --git a/addons/ui/CfgEventHandlers.hpp b/addons/ui/CfgEventHandlers.hpp index b9df43f07..9b8ec74bd 100644 --- a/addons/ui/CfgEventHandlers.hpp +++ b/addons/ui/CfgEventHandlers.hpp @@ -29,4 +29,10 @@ class Extended_DisplayLoad_EventHandlers { class RscDisplayRemoteMissions { ADDON = QUOTE(_this call (uiNamespace getVariable 'FUNC(initDisplayRemoteMissions)')); }; + class Display3DEN { + ADDON = QUOTE(_this call (uiNamespace getVariable 'FUNC(initDisplay3DEN)')); + }; + class RscDisplayCurator { + ADDON = QUOTE(_this call (uiNamespace getVariable 'FUNC(initDisplayCurator)')); + }; }; diff --git a/addons/ui/XEH_preStart.sqf b/addons/ui/XEH_preStart.sqf index 076187991..572bd302c 100644 --- a/addons/ui/XEH_preStart.sqf +++ b/addons/ui/XEH_preStart.sqf @@ -1,7 +1,14 @@ #include "script_component.hpp" +if (!hasInterface) exitWith {}; + PREP(initDisplayInterrupt); PREP(initDisplayMultiplayerSetup); PREP(initDisplayOptionsLayout); PREP(initDisplayPassword); PREP(initDisplayRemoteMissions); +PREP(initDisplay3DEN); +PREP(initDisplayCurator); + +PREP(preload3DEN); +PREP(preloadCurator); diff --git a/addons/ui/fnc_initDisplay3DEN.sqf b/addons/ui/fnc_initDisplay3DEN.sqf new file mode 100644 index 000000000..0a227520b --- /dev/null +++ b/addons/ui/fnc_initDisplay3DEN.sqf @@ -0,0 +1,10 @@ +#include "script_component.hpp" + +params ["_display"]; + +with uiNamespace do { + private _timeStart = diag_tickTime; + if (call FUNC(preload3DEN)) then { + INFO_1("3DEN item list preloaded. Time: %1 ms",round ((diag_tickTime - _timeStart) * 1000)); + }; +}; diff --git a/addons/ui/fnc_initDisplayCurator.sqf b/addons/ui/fnc_initDisplayCurator.sqf new file mode 100644 index 000000000..56cb94175 --- /dev/null +++ b/addons/ui/fnc_initDisplayCurator.sqf @@ -0,0 +1,12 @@ +#include "script_component.hpp" + +params ["_display"]; + +with uiNamespace do { + private _timeStart = diag_tickTime; + if (call FUNC(preloadCurator)) then { + INFO_1("Curator item list preloaded. Time: %1 ms",round ((diag_tickTime - _timeStart) * 1000)); + }; +}; + +RscAttrbuteInventory_weaponAddons = uiNamespace getVariable QGVAR(curatorItemCache); // spelling is "Attrbute" diff --git a/addons/ui/fnc_preload3DEN.sqf b/addons/ui/fnc_preload3DEN.sqf new file mode 100644 index 000000000..5f3c228f2 --- /dev/null +++ b/addons/ui/fnc_preload3DEN.sqf @@ -0,0 +1,188 @@ +#include "script_component.hpp" +/* ---------------------------------------------------------------------------- +Internal Function: cba_ui_fnc_preload3DEN + +Description: + Preload 3den editor ammo box item list. + +Parameters: + None + +Returns: + true: preloaded successfully, false: already preloaded + +Examples: + (begin example) + call cba_ui_fnc_preload3DEN + (end) + +Notes: + To disable cache use: uiNamespace setVariable ["AmmoBox_list", nil]; + +Author: + commy2 +---------------------------------------------------------------------------- */ + +if (!isNil {uiNamespace getVariable "AmmoBox_list"}) exitWith { + INFO("3DEN item list already preloaded."); + false +}; + +private _list = [[],[],[],[],[],[],[],[],[],[],[],[]]; +uiNamespace setVariable ["AmmoBox_list", _list]; + +private _itemTypes = call CBA_fnc_createNamespace; +_itemTypes setVariable ["AssaultRifle", 0]; +_itemTypes setVariable ["Shotgun", 0]; +_itemTypes setVariable ["Rifle", 0]; +_itemTypes setVariable ["SubmachineGun", 0]; +_itemTypes setVariable ["MachineGun", 1]; +_itemTypes setVariable ["SniperRifle", 2]; +_itemTypes setVariable ["Launcher", 3]; +_itemTypes setVariable ["MissileLauncher", 3]; +_itemTypes setVariable ["RocketLauncher", 3]; +_itemTypes setVariable ["Handgun", 4]; +_itemTypes setVariable ["UnknownWeapon", 5]; +_itemTypes setVariable ["AccessoryMuzzle", 6]; +_itemTypes setVariable ["AccessoryPointer", 6]; +_itemTypes setVariable ["AccessorySights", 6]; +_itemTypes setVariable ["AccessoryBipod", 6]; +_itemTypes setVariable ["Uniform", 7]; +_itemTypes setVariable ["Vest", 8]; +_itemTypes setVariable ["Backpack", 9]; +_itemTypes setVariable ["Headgear", 10]; +_itemTypes setVariable ["Glasses", 10]; +_itemTypes setVariable ["Binocular", 11]; +_itemTypes setVariable ["Compass", 11]; +_itemTypes setVariable ["FirstAidKit", 11]; +_itemTypes setVariable ["GPS", 11]; +_itemTypes setVariable ["LaserDesignator", 11]; +_itemTypes setVariable ["Map", 11]; +_itemTypes setVariable ["Medikit", 11]; +_itemTypes setVariable ["MineDetector", 11]; +_itemTypes setVariable ["NVGoggles", 11]; +_itemTypes setVariable ["Radio", 11]; +_itemTypes setVariable ["Toolkit", 11]; +_itemTypes setVariable ["Watch", 11]; +_itemTypes setVariable ["UAVTerminal", 11]; + +//--- Weapons, Magazines and Items +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; + +private _magazines = []; +private _magazinesLists = []; + +{ + private _item = toLower configName _x; + (_item call BIS_fnc_itemType) params ["_itemCategory", "_itemType"]; + + private _index = _itemTypes getVariable [_itemType, -1]; + if (_index >= 0 && {_itemCategory != "VehicleWeapon"}) then { + private _weaponConfig = _x; + private _isPublic = getNumber (_weaponConfig >> "scope") == 2; + private _listItem = _list select _index; + + if (_isPublic) then { + _displayName = getText (_weaponConfig >> "displayName"); + + // append display name with attachment names + { + _displayName = format [ + "%1 + %2", + _displayName, + getText (_cfgWeapons >> getText (_x >> "item") >> "displayName") + ]; + } forEach ("true" configClasses (_weaponConfig >> "linkeditems")); //configProperties [_weaponConfig >> "linkeditems", "isClass _x"]; + + _listItem pushBack [ + _displayName, + _item, + getText (_weaponConfig >> "picture"), + parseNumber (getNumber (_weaponConfig >> "type") in [4096, 131072]), + false + ]; + }; + + //--- Magazines + if (_isPublic || {_item in ["throw","put"]}) then { + { + private _muzzleConfig = _weaponConfig; + + if (_x != "this") then { + _muzzleConfig = _weaponConfig >> _x; + }; + + { + private _item = toLower _x; + + if (_magazinesLists pushBackUnique [_item, _listItem] != -1) then { + private _magazineConfig = _cfgMagazines >> _item; + + if (getNumber (_magazineConfig >> "scope") == 2) then { + _listItem pushBack [ + getText (_magazineConfig >> "displayName"), + _item, + getText (_magazineConfig >> "picture"), + 2, + _item in _magazines + ]; + + _magazines pushBack _item; + }; + }; + } forEach getArray (_muzzleConfig >> "magazines"); + } forEach getArray (_weaponConfig >> "muzzles"); + }; + }; +} forEach ("true" configClasses _cfgWeapons); + +//--- Backpacks +{ +// In case you are executing the unit test with addons loaded, should an addon +// use the same classname in CfgVehicles and CfgWeapons this isBackpack +// optimization prevents the item from added by twice. +#ifdef DEBUG_MODE_FULL + if (getNumber (_x >> "scope") == 2) +#else + if (getNumber (_x >> "isBackpack") == 1 && {getNumber (_x >> "scope") == 2}) +#endif + then { + private _item = toLower configName _x; + private _itemType = _item call BIS_fnc_itemType select 1; + + private _index = _itemTypes getVariable [_itemType, -1]; + if (_index >= 0) then { + (_list select _index) pushBack [ + getText (_x >> "displayName"), + _item, + getText (_x >> "picture"), + 3, + false + ]; + }; + }; +} forEach ("true" configClasses (configFile >> "CfgVehicles")); + +//--- Glasses +private _listHeadgear = _list select 10; + +{ + if (getNumber (_x >> "scope") == 2) then { + _listHeadgear pushBack [ + getText (_x >> "displayName"), + toLower configName _x, + getText (_x >> "picture"), + 3, + false + ]; + }; +} forEach ("true" configClasses (configFile >> "CfgGlasses")); + +{ + _x sort true; +} forEach _list; + +_itemTypes call CBA_fnc_deleteNamespace; + +true diff --git a/addons/ui/fnc_preloadCurator.sqf b/addons/ui/fnc_preloadCurator.sqf new file mode 100644 index 000000000..773e54f76 --- /dev/null +++ b/addons/ui/fnc_preloadCurator.sqf @@ -0,0 +1,196 @@ +#include "script_component.hpp" +/* ---------------------------------------------------------------------------- +Internal Function: cba_ui_fnc_preloadCurator + +Description: + Preload Zeus ammo box item list. + +Parameters: + None + +Returns: + true: preloaded successfully, false: already preloaded + +Examples: + (begin example) + call cba_ui_fnc_preloadCurator + (end) + +Notes: + To disable cache use in init.sqf: RscAttrbuteInventory_weaponAddons = nil; + +Author: + commy2 +---------------------------------------------------------------------------- */ + +if (!isNil {uiNamespace getVariable QGVAR(curatorItemCache)}) exitWith { + INFO("Curator item list already preloaded."); + false +}; + +private _list = []; +uiNamespace setVariable [QGVAR(curatorItemCache), _list]; + +private _itemTypes = call CBA_fnc_createNamespace; +_itemTypes setVariable ["AssaultRifle", 0]; +_itemTypes setVariable ["Shotgun", 0]; +_itemTypes setVariable ["Rifle", 0]; +_itemTypes setVariable ["SubmachineGun", 0]; +_itemTypes setVariable ["MachineGun", 1]; +_itemTypes setVariable ["SniperRifle", 2]; +_itemTypes setVariable ["Launcher", 3]; +_itemTypes setVariable ["MissileLauncher", 3]; +_itemTypes setVariable ["RocketLauncher", 3]; +_itemTypes setVariable ["Handgun", 4]; +_itemTypes setVariable ["UnknownWeapon", 5]; +_itemTypes setVariable ["AccessoryMuzzle", 6]; +_itemTypes setVariable ["AccessoryPointer", 6]; +_itemTypes setVariable ["AccessorySights", 6]; +_itemTypes setVariable ["AccessoryBipod", 6]; +_itemTypes setVariable ["Uniform", 7]; +_itemTypes setVariable ["Vest", 8]; +_itemTypes setVariable ["Backpack", 9]; +_itemTypes setVariable ["Headgear", 10]; +_itemTypes setVariable ["Glasses", 10]; +_itemTypes setVariable ["Binocular", 11]; +_itemTypes setVariable ["Compass", 11]; +_itemTypes setVariable ["FirstAidKit", 11]; +_itemTypes setVariable ["GPS", 11]; +_itemTypes setVariable ["LaserDesignator", 11]; +_itemTypes setVariable ["Map", 11]; +_itemTypes setVariable ["Medikit", 11]; +_itemTypes setVariable ["MineDetector", 11]; +_itemTypes setVariable ["NVGoggles", 11]; +_itemTypes setVariable ["Radio", 11]; +_itemTypes setVariable ["Toolkit", 11]; +_itemTypes setVariable ["Watch", 11]; +_itemTypes setVariable ["UAVTerminal", 11]; + +//--- Weapons, Magazines and Items +private _cfgPatches = configFile >> "CfgPatches"; +private _cfgVehicles = configFile >> "CfgVehicles"; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; + +private _magazines = []; +private _magazinesLists = []; + +{ + private _patchConfig = _cfgPatches >> _x; + _addon = toLower _x; + + private _addonList = [[],[],[],[],[],[],[],[],[],[],[],[]]; + + { + private _item = toLower _x; + (_item call BIS_fnc_itemType) params ["_itemCategory", "_itemType"]; + + private _index = _itemTypes getVariable [_itemType, -1]; + if (_index >= 0 && {_itemCategory != "VehicleWeapon"}) then { + private _weaponConfig = _cfgWeapons >> _item; + private _isPublic = getNumber (_weaponConfig >> "scope") == 2; + private _listItem = _addonList select _index; + + if (_isPublic) then { + _displayName = getText (_weaponConfig >> "displayName"); + + // append display name with attachment names + { + _displayName = format [ + "%1 + %2", + _displayName, + getText (_cfgWeapons >> getText (_x >> "item") >> "displayName") + ]; + } forEach ("true" configClasses (_weaponConfig >> "linkeditems")); //configProperties [_weaponConfig >> "linkeditems", "isClass _x"]; + + private _displayNameShort = _displayName; + private _displayNameShortArray = toArray _displayNameShort; + + if (count _displayNameShortArray > 41) then { + _displayNameShortArray resize 41; + _displayNameShort = format ["%1...", toString _displayNameShortArray]; + }; + + _listItem pushBack [ + _item, + _displayName, + _displayNameShort, + getText (_weaponConfig >> "picture"), + parseNumber (getNumber (_weaponConfig >> "type") in [4096, 131072]), + false + ]; + }; + + //--- Magazines + if (_isPublic || {_item in ["throw","put"]}) then { + { + private _muzzleConfig = _weaponConfig; + + if (_x != "this") then { + _muzzleConfig = _weaponConfig >> _x; + }; + + { + private _item = toLower _x; + + if (_magazinesLists pushBackUnique [_item, _listItem] != -1) then { + private _magazineConfig = _cfgMagazines >> _item; + + if (getNumber (_magazineConfig >> "scope") == 2) then { + private _displayName = getText (_magazineConfig >> "displayName"); + + _listItem pushBack [ + _item, + _displayName, + _displayName, + getText (_magazineConfig >> "picture"), + 2, + _item in _magazines + ]; + + _magazines pushBack _item; + }; + }; + } forEach getArray (_muzzleConfig >> "magazines"); + } forEach getArray (_weaponConfig >> "muzzles"); + }; + }; + } forEach getArray (_patchConfig >> "weapons"); + + { + private _item = toLower _x; + private _weaponConfig = _cfgVehicles >> _item; + +// In case you are executing the unit test with addons loaded, should an addon +// use the same classname in CfgVehicles and CfgWeapons this isBackpack +// optimization prevents the item from added by twice. +#ifdef DEBUG_MODE_FULL + if (getNumber (_weaponConfig >> "scope") == 2) +#else + if (getNumber (_weaponConfig >> "isBackpack") == 1 && {getNumber (_weaponConfig >> "scope") == 2}) +#endif + then { + private _itemType = _item call BIS_fnc_itemType select 1; + + private _index = _itemTypes getVariable [_itemType, -1]; + if (_index >= 0) then { + private _displayName = getText (_weaponConfig >> "displayName"); + + (_addonList select _index) pushBack [ + _item, + _displayName, + _displayName, + getText (_weaponConfig >> "picture"), + 3, + false + ]; + }; + }; + } forEach getArray (_patchConfig >> "units"); + + _list append [_addon, _addonList]; +} forEach call (uiNamespace getVariable QEGVAR(common,addons)); + +_itemTypes call CBA_fnc_deleteNamespace; + +true diff --git a/addons/ui/script_component.hpp b/addons/ui/script_component.hpp index 7c6bed8f5..739e89540 100644 --- a/addons/ui/script_component.hpp +++ b/addons/ui/script_component.hpp @@ -13,6 +13,7 @@ #define DEBUG_SETTINGS DEBUG_SETTINGS_UI #endif +#define DEBUG_SYNCHRONOUS #include "\x\cba\addons\main\script_macros.hpp" #include "\a3\ui_f\hpp\defineCommonGrids.inc" diff --git a/addons/ui/test_preload.sqf b/addons/ui/test_preload.sqf new file mode 100644 index 000000000..4c9628a7e --- /dev/null +++ b/addons/ui/test_preload.sqf @@ -0,0 +1,45 @@ +#include "script_component.hpp" +// execVM "\x\cba\addons\ui\test_preload.sqf"; + +isNil { + with uiNamespace do { + // 3DEN + TEST_DEFINED(QFUNC(preload3DEN),""); + + AmmoBox_list = nil; + ["onLoad", [controlNull]] call compile preprocessFile "\a3\3den\UI\Attributes\AmmoBox.sqf"; + private _vanilla = AmmoBox_list; + + AmmoBox_list = nil; + call FUNC(preload3DEN); + private _cba = AmmoBox_list; + + TEST_TRUE(_vanilla isEqualTo _cba,QFUNC(preload3DEN)); + + // Curator + TEST_DEFINED(QFUNC(preloadCurator),""); + + private _unit = player; + private _curator = getAssignedCuratorLogic _unit; + + if (isNull _curator) then { + _curator = createGroup sideLogic createUnit ["ModuleCurator_F", [0,0,0], [], 0, "NONE"]; + _unit assignCurator _curator; + }; + + _curator removeCuratorAddons call EGVAR(common,addons); + _curator addCuratorAddons call EGVAR(common,addons); + + missionNamespace setVariable ["RscAttrbuteInventory_weaponAddons", nil]; + ["onLoad", [displayNull], objNull] call compile preprocessFile "\a3\ui_f_curator\UI\RscCommon\RscAttributeInventory.sqf"; + _vanilla = RscAttributeInventory_list; + + GVAR(curatorItemCache) = nil; + call FUNC(preloadCurator); + missionNamespace setVariable ["RscAttrbuteInventory_weaponAddons", GVAR(curatorItemCache)]; + ["onLoad", [displayNull], objNull] call compile preprocessFile "\a3\ui_f_curator\UI\RscCommon\RscAttributeInventory.sqf"; + _cba = RscAttributeInventory_list; + + TEST_TRUE(_vanilla isEqualTo _cba,QFUNC(preloadCurator)); + }; +};