mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge branch 'master' into pr/9758
This commit is contained in:
commit
a2909a97d4
@ -110,7 +110,7 @@ class Cfg3DEN {
|
|||||||
h = QUOTE(65 * ATTRIBUTE_H);
|
h = QUOTE(65 * ATTRIBUTE_H);
|
||||||
drawSideArrows = 1;
|
drawSideArrows = 1;
|
||||||
disableOverflow = 1;
|
disableOverflow = 1;
|
||||||
columns[] = {0.05, 0.15, 0.85};
|
columns[] = {0.05, 0.15, 0.83, 0.87};
|
||||||
};
|
};
|
||||||
class ArrowLeft: ctrlButton {
|
class ArrowLeft: ctrlButton {
|
||||||
idc = IDC_ATTRIBUTE_LIST_LEFT;
|
idc = IDC_ATTRIBUTE_LIST_LEFT;
|
||||||
|
@ -70,7 +70,7 @@ GVAR(lastSortDirectionRight) = DESCENDING;
|
|||||||
if (!isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then {
|
if (!isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then {
|
||||||
private _curSelData = _contentPanelCtrl lnbData [lnbCurSelRow _contentPanelCtrl, 1];
|
private _curSelData = _contentPanelCtrl lnbData [lnbCurSelRow _contentPanelCtrl, 1];
|
||||||
|
|
||||||
([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"];
|
([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"];
|
||||||
_extendedLoadout params ["_loadout"];
|
_extendedLoadout params ["_loadout"];
|
||||||
|
|
||||||
private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName];
|
private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName];
|
||||||
@ -81,10 +81,10 @@ GVAR(lastSortDirectionRight) = DESCENDING;
|
|||||||
_contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName];
|
_contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName];
|
||||||
|
|
||||||
// Set color of row, depending if items are unavailable/missing
|
// Set color of row, depending if items are unavailable/missing
|
||||||
if (_nullItemsAmount > 0) then {
|
if (_nullItemsList isNotEqualTo []) then {
|
||||||
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]];
|
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]];
|
||||||
} else {
|
} else {
|
||||||
if (_unavailableItemsAmount > 0) then {
|
if (_unavailableItemsList isNotEqualTo []) then {
|
||||||
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]];
|
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -48,4 +48,48 @@ call FUNC(compileStats);
|
|||||||
// Setup Tools tab
|
// Setup Tools tab
|
||||||
[keys (uiNamespace getVariable [QGVAR(configItemsTools), createHashMap]), LLSTRING(toolsTab), TOOLS_TAB_ICON, -1, true] call FUNC(addRightPanelButton);
|
[keys (uiNamespace getVariable [QGVAR(configItemsTools), createHashMap]), LLSTRING(toolsTab), TOOLS_TAB_ICON, -1, true] call FUNC(addRightPanelButton);
|
||||||
|
|
||||||
|
// TODO: make IDCs able to match IDX with simple math?
|
||||||
|
GVAR(idxMap) = createHashMapFromArray [
|
||||||
|
[IDC_buttonPrimaryWeapon, IDX_VIRT_PRIMARY_WEAPONS],
|
||||||
|
[IDC_buttonHandgun, IDX_VIRT_HANDGUN_WEAPONS],
|
||||||
|
[IDC_buttonSecondaryWeapon, IDX_VIRT_SECONDARY_WEAPONS],
|
||||||
|
[IDC_buttonHeadgear, IDX_VIRT_HEADGEAR],
|
||||||
|
[IDC_buttonUniform, IDX_VIRT_UNIFORM],
|
||||||
|
[IDC_buttonVest, IDX_VIRT_VEST],
|
||||||
|
[IDC_buttonBackpack, IDX_VIRT_BACKPACK],
|
||||||
|
[IDC_buttonGoggles, IDX_VIRT_GOGGLES],
|
||||||
|
[IDC_buttonNVG, IDX_VIRT_NVG],
|
||||||
|
[IDC_buttonBinoculars, IDX_VIRT_BINO],
|
||||||
|
[IDC_buttonMap, IDX_VIRT_MAP],
|
||||||
|
[IDC_buttonGPS, IDX_VIRT_COMMS],
|
||||||
|
[IDC_buttonRadio, IDX_VIRT_RADIO],
|
||||||
|
[IDC_buttonCompass, IDX_VIRT_COMPASS],
|
||||||
|
[IDC_buttonWatch, IDX_VIRT_WATCH]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Make new hashmaps for face/voice/insignia so mission makers can disable them
|
||||||
|
// Copies of hashmaps aren't final
|
||||||
|
GVAR(faceCache) = +(uiNamespace getVariable QGVAR(faceCache));
|
||||||
|
GVAR(voiceCache) = +(uiNamespace getVariable QGVAR(voiceCache));
|
||||||
|
GVAR(insigniaCache) = +(uiNamespace getVariable QGVAR(insigniaCache));
|
||||||
|
|
||||||
|
// Get mission/campaign insignias
|
||||||
|
// BIS_fnc_setUnitInsignia will look in mission config, then campaign, then global config last, so overwrite accordingly
|
||||||
|
private _insigniaCondition = toString {
|
||||||
|
if (isNumber (_x >> "scope")) then {
|
||||||
|
getNumber (_x >> "scope") == 2
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ref fnc_addListBoxItem, 0/nil = configFile, 1 = campaignConfigFile, 2 = missionConfigFile
|
||||||
|
{
|
||||||
|
GVAR(insigniaCache) set [_x, 1];
|
||||||
|
} forEach (_insigniaCondition configClasses (campaignConfigFile >> "CfgUnitInsignia"));
|
||||||
|
{
|
||||||
|
GVAR(insigniaCache) set [_x, 2];
|
||||||
|
} forEach (_insigniaCondition configClasses (missionConfigFile >> "CfgUnitInsignia"));
|
||||||
|
|
||||||
|
|
||||||
ADDON = true;
|
ADDON = true;
|
||||||
|
@ -270,6 +270,7 @@
|
|||||||
#define IDX_VIRT_UNIQUE_UNKNOWN_ITEMS 25
|
#define IDX_VIRT_UNIQUE_UNKNOWN_ITEMS 25
|
||||||
|
|
||||||
// Indexes of current items array
|
// Indexes of current items array
|
||||||
|
// Should match IDX_VIRT_X macros for any left panel tabs
|
||||||
#define IDX_CURR_PRIMARY_WEAPON 0
|
#define IDX_CURR_PRIMARY_WEAPON 0
|
||||||
#define IDX_CURR_SECONDARY_WEAPON 1
|
#define IDX_CURR_SECONDARY_WEAPON 1
|
||||||
#define IDX_CURR_HANDGUN_WEAPON 2
|
#define IDX_CURR_HANDGUN_WEAPON 2
|
||||||
@ -489,3 +490,6 @@ if (!isNil QGVAR(customRightPanelButtons)) then {\
|
|||||||
_contentPanelCtrl lnbSetPicture [[_newRow, 7], getText (configFile >> "CfgVehicles" >> (_loadout select IDX_LOADOUT_BACKPACK) select 0 >> "picture")];\
|
_contentPanelCtrl lnbSetPicture [[_newRow, 7], getText (configFile >> "CfgVehicles" >> (_loadout select IDX_LOADOUT_BACKPACK) select 0 >> "picture")];\
|
||||||
_contentPanelCtrl lnbSetPicture [[_newRow, 8], getText (_cfgWeapons >> _loadout select IDX_LOADOUT_HEADGEAR >> "picture")];\
|
_contentPanelCtrl lnbSetPicture [[_newRow, 8], getText (_cfgWeapons >> _loadout select IDX_LOADOUT_HEADGEAR >> "picture")];\
|
||||||
_contentPanelCtrl lnbSetPicture [[_newRow, 9], getText (configFile >> "CfgGlasses" >> _loadout select IDX_LOADOUT_GOGGLES >> "picture")];
|
_contentPanelCtrl lnbSetPicture [[_newRow, 9], getText (configFile >> "CfgGlasses" >> _loadout select IDX_LOADOUT_GOGGLES >> "picture")];
|
||||||
|
|
||||||
|
#define ACTION_TYPE_TEXT 0
|
||||||
|
#define ACTION_TYPE_BUTTON 1
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
#include "..\defines.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: johnb43
|
* Author: johnb43
|
||||||
* Adds custom action buttons.
|
* Adds custom action buttons.
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
* 1: Classname <STRING>
|
* 1: Classname <STRING>
|
||||||
* 2: Panel control <CONTROL>
|
* 2: Panel control <CONTROL>
|
||||||
* 3: Name of the picture entry in that Cfg class <STRING> (default: "picture")
|
* 3: Name of the picture entry in that Cfg class <STRING> (default: "picture")
|
||||||
|
* 4: Config root <NUMBER> (default: 0 -> configFile)
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
@ -19,7 +20,7 @@
|
|||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]]];
|
params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]], ["_configRoot", 0, [0]]];
|
||||||
|
|
||||||
private _skip = GVAR(favoritesOnly) && {!(_className in GVAR(currentItems))} && {!((toLower _className) in GVAR(favorites))};
|
private _skip = GVAR(favoritesOnly) && {!(_className in GVAR(currentItems))} && {!((toLower _className) in GVAR(favorites))};
|
||||||
if (_skip) then {
|
if (_skip) then {
|
||||||
@ -42,9 +43,9 @@ if (_skip) then {
|
|||||||
if (_skip) exitWith {};
|
if (_skip) exitWith {};
|
||||||
|
|
||||||
// Sanitise key, as it's public; If not in cache, find info and cache it for later use
|
// Sanitise key, as it's public; If not in cache, find info and cache it for later use
|
||||||
((uiNamespace getVariable QGVAR(addListBoxItemCache)) getOrDefaultCall [_configCategory + _className, {
|
((uiNamespace getVariable QGVAR(addListBoxItemCache)) getOrDefaultCall [_configCategory + _className + str _configRoot, {
|
||||||
// Get classname (config case), display name, picture and DLC
|
// Get classname (config case), display name, picture and DLC
|
||||||
private _configPath = configFile >> _configCategory >> _className;
|
private _configPath = ([configFile, campaignConfigFile, missionConfigFile] select _configRoot) >> _configCategory >> _className;
|
||||||
private _dlcName = _configPath call EFUNC(common,getAddon);
|
private _dlcName = _configPath call EFUNC(common,getAddon);
|
||||||
|
|
||||||
// If _pictureEntryName is empty, then this item has no picture (e.g. faces)
|
// If _pictureEntryName is empty, then this item has no picture (e.g. faces)
|
||||||
|
@ -46,6 +46,7 @@ private _cfgWeapons = configFile >> "CfgWeapons";
|
|||||||
private _cfgMagazines = configFile >> "CfgMagazines";
|
private _cfgMagazines = configFile >> "CfgMagazines";
|
||||||
private _cfgVehicles = configFile >> "CfgVehicles";
|
private _cfgVehicles = configFile >> "CfgVehicles";
|
||||||
private _cfgGlasses = configFile >> "CfgGlasses";
|
private _cfgGlasses = configFile >> "CfgGlasses";
|
||||||
|
private _dlcName = "";
|
||||||
|
|
||||||
// Exit with current items (no specific category)
|
// Exit with current items (no specific category)
|
||||||
if (_category == IDX_CAT_ALL) exitWith {
|
if (_category == IDX_CAT_ALL) exitWith {
|
||||||
@ -73,6 +74,12 @@ if (_category == IDX_CAT_ALL) exitWith {
|
|||||||
_listbox lnbSetData [[_index, 1], _x];
|
_listbox lnbSetData [[_index, 1], _x];
|
||||||
_listbox lnbSetPicture [[_index, 0], getText (_config >> "picture")];
|
_listbox lnbSetPicture [[_index, 0], getText (_config >> "picture")];
|
||||||
_listbox lnbSetTooltip [[_index, 0], _x];
|
_listbox lnbSetTooltip [[_index, 0], _x];
|
||||||
|
|
||||||
|
_dlcName = _config call EFUNC(common,getAddon);
|
||||||
|
|
||||||
|
if (_dlcName != "") then {
|
||||||
|
_listbox lnbSetPicture [[_index, 2], (modParams [_dlcName, ["logo"]]) param [0, ""]];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
} forEach _attributeItems;
|
} forEach _attributeItems;
|
||||||
|
|
||||||
@ -130,12 +137,20 @@ private _config = _cfgClass;
|
|||||||
_alpha = 0.5;
|
_alpha = 0.5;
|
||||||
};
|
};
|
||||||
|
|
||||||
_index = _listbox lnbAddRow ["", _displayName, _symbol];
|
_index = _listbox lnbAddRow ["", _displayName, "", _symbol];
|
||||||
_listbox lnbSetData [[_index, 1], _x];
|
_listbox lnbSetData [[_index, 1], _x];
|
||||||
_listbox lnbSetPicture [[_index, 0], getText (_config >> _x >> "picture")];
|
_listbox lnbSetPicture [[_index, 0], getText (_config >> _x >> "picture")];
|
||||||
_listbox lnbSetTooltip [[_index, 0], _x];
|
_listbox lnbSetTooltip [[_index, 0], _x];
|
||||||
_listbox lnbSetColor [[_index, 1], [1, 1, 1, _alpha]];
|
_listbox lnbSetColor [[_index, 1], [1, 1, 1, _alpha]];
|
||||||
_listbox lnbSetColor [[_index, 2], [1, 1, 1, _alpha]];
|
_listbox lnbSetColor [[_index, 3], [1, 1, 1, _alpha]];
|
||||||
|
|
||||||
|
// Mod icon is in column 2
|
||||||
|
_dlcName = (_config >> _x) call EFUNC(common,getAddon);
|
||||||
|
|
||||||
|
if (_dlcName != "") then {
|
||||||
|
_listbox lnbSetPicture [[_index, 2], (modParams [_dlcName, ["logo"]]) param [0, ""]];
|
||||||
|
_listbox lnbSetPictureColor [[_index, 2], [1, 1, 1, _alpha]];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
} forEach (keys _categoryItems);
|
} forEach (keys _categoryItems);
|
||||||
|
|
||||||
|
@ -35,9 +35,10 @@ if (_addItem && {_itemIndex == -1}) exitWith {
|
|||||||
_attributeItems pushBack _itemClassname;
|
_attributeItems pushBack _itemClassname;
|
||||||
|
|
||||||
// Change symbol and increase alpha
|
// Change symbol and increase alpha
|
||||||
_listbox lnbSetText [[_currentRow, 2], [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode];
|
_listbox lnbSetText [[_currentRow, 3], [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode];
|
||||||
_listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 1]];
|
_listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 1]];
|
||||||
_listbox lnbSetColor [[_currentRow, 2], [1, 1, 1, 1]];
|
_listbox lnbSetPictureColor [[_currentRow, 2], [1, 1, 1, 1]]; // mod icon is in column 2
|
||||||
|
_listbox lnbSetColor [[_currentRow, 3], [1, 1, 1, 1]];
|
||||||
};
|
};
|
||||||
|
|
||||||
// Remove item if in list
|
// Remove item if in list
|
||||||
@ -45,7 +46,8 @@ if (!_addItem && {_itemIndex != -1}) exitWith {
|
|||||||
_attributeItems deleteAt _itemIndex;
|
_attributeItems deleteAt _itemIndex;
|
||||||
|
|
||||||
// Change symbol and reduce alpha
|
// Change symbol and reduce alpha
|
||||||
_listbox lnbSetText [[_currentRow, 2], SYMBOL_ITEM_NONE];
|
_listbox lnbSetText [[_currentRow, 3], SYMBOL_ITEM_NONE];
|
||||||
_listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 0.5]];
|
_listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 0.5]];
|
||||||
_listbox lnbSetColor [[_currentRow, 2], [1, 1, 1, 0.5]];
|
_listbox lnbSetPictureColor [[_currentRow, 2], [1, 1, 1, 0.5]]; // mod icon is in column 2
|
||||||
|
_listbox lnbSetColor [[_currentRow, 3], [1, 1, 1, 0.5]];
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
#include "..\defines.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Brett Mayson
|
* Author: Brett Mayson
|
||||||
* Create the internal actions arrays when needed for the first time.
|
* Create the internal actions arrays when needed for the first time.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
#include "..\defines.hpp"
|
#include "..\defines.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Alganthe, johnb43
|
* Author: Alganthe, johnb43, LinkIsGrim
|
||||||
* Fills left panel.
|
* Fills left panel.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
@ -17,21 +17,28 @@
|
|||||||
|
|
||||||
params ["_display", "_control", ["_animate", true]];
|
params ["_display", "_control", ["_animate", true]];
|
||||||
|
|
||||||
|
private _ctrlIDC = ctrlIDC _control;
|
||||||
|
private _ctrlPanel = _display displayCtrl IDC_leftTabContent;
|
||||||
|
private _idxVirt = GVAR(idxMap) getOrDefault [_ctrlIDC, -1, true];
|
||||||
|
|
||||||
// Fade old control background
|
// Fade old control background
|
||||||
if (!isNil QGVAR(currentLeftPanel)) then {
|
if (!isNil QGVAR(currentLeftPanel)) then {
|
||||||
private _previousCtrlBackground = _display displayCtrl (GVAR(currentLeftPanel) - 1);
|
private _previousCtrlBackground = _display displayCtrl (GVAR(currentLeftPanel) - 1);
|
||||||
_previousCtrlBackground ctrlSetFade 1;
|
_previousCtrlBackground ctrlSetFade 1;
|
||||||
_previousCtrlBackground ctrlCommit ([0, FADE_DELAY] select _animate);
|
_previousCtrlBackground ctrlCommit ([0, FADE_DELAY] select _animate);
|
||||||
|
|
||||||
|
// When switching tabs, clear searchbox
|
||||||
|
if (GVAR(currentLeftPanel) != _ctrlIDC) then {
|
||||||
|
(_display displayCtrl IDC_leftSearchbar) ctrlSetText "";
|
||||||
|
(_display displayCtrl IDC_rightSearchbar) ctrlSetText "";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Show new control background
|
// Show new control background
|
||||||
private _ctrlIDC = ctrlIDC _control;
|
|
||||||
private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1);
|
private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1);
|
||||||
_ctrlBackground ctrlSetFade 0;
|
_ctrlBackground ctrlSetFade 0;
|
||||||
_ctrlBackground ctrlCommit ([0, FADE_DELAY] select _animate);
|
_ctrlBackground ctrlCommit ([0, FADE_DELAY] select _animate);
|
||||||
|
|
||||||
private _ctrlPanel = _display displayCtrl IDC_leftTabContent;
|
|
||||||
|
|
||||||
// Force a "refresh" animation of the panel
|
// Force a "refresh" animation of the panel
|
||||||
if (_animate) then {
|
if (_animate) then {
|
||||||
_ctrlPanel ctrlSetFade 1;
|
_ctrlPanel ctrlSetFade 1;
|
||||||
@ -41,212 +48,82 @@ if (_animate) then {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_ctrlPanel lbSetCurSel -1;
|
_ctrlPanel lbSetCurSel -1;
|
||||||
|
// Purge old data
|
||||||
|
lbClear _ctrlPanel;
|
||||||
|
|
||||||
// Handle icons and filling
|
// For every left tab except faces and voices, add "Empty" entry
|
||||||
private _selectedItem = switch (true) do {
|
if !(_ctrlIDC in [IDC_buttonFace, IDC_buttonVoice]) then {
|
||||||
// Primary weapons, secondary weapons, handgun weapons
|
private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"];
|
||||||
case (_ctrlIDC in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]): {
|
_ctrlPanel lbSetValue [_addEmpty, -1];
|
||||||
// Purge old data
|
|
||||||
lbClear _ctrlPanel;
|
|
||||||
|
|
||||||
// Add "Empty" entry
|
|
||||||
private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"];
|
|
||||||
_ctrlPanel lbSetValue [_addEmpty, -1];
|
|
||||||
|
|
||||||
// Add selected tab's weapons
|
|
||||||
private _index = [IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun] find _ctrlIDC;
|
|
||||||
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _index));
|
|
||||||
|
|
||||||
GVAR(currentItems) select _index
|
|
||||||
};
|
|
||||||
// Uniforms, vests, backpacks
|
|
||||||
case (_ctrlIDC in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]): {
|
|
||||||
// Purge old data
|
|
||||||
lbClear _ctrlPanel;
|
|
||||||
|
|
||||||
// Add "Empty" entry
|
|
||||||
private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"];
|
|
||||||
_ctrlPanel lbSetValue [_addEmpty, -1];
|
|
||||||
|
|
||||||
switch (_ctrlIDC) do {
|
|
||||||
// Add uniforms
|
|
||||||
case IDC_buttonUniform: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIFORM));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_UNIFORM
|
|
||||||
};
|
|
||||||
// Add vests
|
|
||||||
case IDC_buttonVest: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_VEST));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_VEST
|
|
||||||
};
|
|
||||||
// Add backpacks
|
|
||||||
case IDC_buttonBackpack: {
|
|
||||||
{
|
|
||||||
["CfgVehicles", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_BACKPACK));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_BACKPACK
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// Other
|
|
||||||
default {
|
|
||||||
// Don't reset right panel selection if left tab is binos
|
|
||||||
if (_ctrlIDC != IDC_buttonBinoculars) then {
|
|
||||||
GVAR(currentRightPanel) = nil;
|
|
||||||
};
|
|
||||||
|
|
||||||
lbClear _ctrlPanel;
|
|
||||||
|
|
||||||
// For every left tab except faces and voices, add "Empty" entry
|
|
||||||
if !(_ctrlIDC in [IDC_buttonFace, IDC_buttonVoice]) then {
|
|
||||||
private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"];
|
|
||||||
_ctrlPanel lbSetValue [_addEmpty, -1];
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (_ctrlIDC) do {
|
|
||||||
// Headgear
|
|
||||||
case IDC_buttonHeadgear: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_HEADGEAR));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_HEADGEAR
|
|
||||||
};
|
|
||||||
// Facewear
|
|
||||||
case IDC_buttonGoggles: {
|
|
||||||
{
|
|
||||||
["CfgGlasses", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_GOGGLES));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_GOGGLES
|
|
||||||
};
|
|
||||||
// NVGs
|
|
||||||
case IDC_buttonNVG: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_NVG));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_NVG
|
|
||||||
};
|
|
||||||
// Binoculars
|
|
||||||
case IDC_buttonBinoculars: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_BINO));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_BINO
|
|
||||||
};
|
|
||||||
// Maps
|
|
||||||
case IDC_buttonMap: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_MAP));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_MAP
|
|
||||||
};
|
|
||||||
// Compasses
|
|
||||||
case IDC_buttonCompass: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_COMPASS));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_COMPASS
|
|
||||||
};
|
|
||||||
// Radios
|
|
||||||
case IDC_buttonRadio: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_RADIO));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_RADIO
|
|
||||||
};
|
|
||||||
// Watches
|
|
||||||
case IDC_buttonWatch: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_WATCH));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_WATCH
|
|
||||||
};
|
|
||||||
// GPS and UAV Terminals
|
|
||||||
case IDC_buttonGPS: {
|
|
||||||
{
|
|
||||||
["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem);
|
|
||||||
} forEach (keys (GVAR(virtualItems) get IDX_VIRT_COMMS));
|
|
||||||
|
|
||||||
GVAR(currentItems) select IDX_CURR_COMMS
|
|
||||||
};
|
|
||||||
// Faces
|
|
||||||
case IDC_buttonFace: {
|
|
||||||
private _lbAdd = -1;
|
|
||||||
|
|
||||||
{
|
|
||||||
_y params ["_displayName", "_modPicture"];
|
|
||||||
|
|
||||||
_lbAdd = _ctrlPanel lbAdd _displayName;
|
|
||||||
_ctrlPanel lbSetData [_lbAdd, _x];
|
|
||||||
_ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _x]];
|
|
||||||
_ctrlPanel lbSetPictureRight [_lbAdd, ["", _modPicture] select GVAR(enableModIcons)];
|
|
||||||
} forEach (uiNamespace getVariable QGVAR(faceCache));
|
|
||||||
|
|
||||||
GVAR(currentFace)
|
|
||||||
};
|
|
||||||
// Voices
|
|
||||||
case IDC_buttonVoice: {
|
|
||||||
{
|
|
||||||
["CfgVoice", _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem);
|
|
||||||
} forEach (uiNamespace getVariable QGVAR(voiceCache));
|
|
||||||
|
|
||||||
GVAR(currentVoice)
|
|
||||||
};
|
|
||||||
// Insignia
|
|
||||||
case IDC_buttonInsignia: {
|
|
||||||
// Insignia from config
|
|
||||||
{
|
|
||||||
["CfgUnitInsignia", _x, _ctrlPanel, "texture"] call FUNC(addListBoxItem);
|
|
||||||
} forEach (uiNamespace getVariable QGVAR(insigniaCache));
|
|
||||||
|
|
||||||
private _displayName = "";
|
|
||||||
private _className = "";
|
|
||||||
private _lbAdd = -1;
|
|
||||||
|
|
||||||
// Insignia from mission file
|
|
||||||
{
|
|
||||||
_className = configName _x;
|
|
||||||
_displayName = getText (_x >> "displayName");
|
|
||||||
_lbAdd = _ctrlPanel lbAdd _displayName;
|
|
||||||
|
|
||||||
_ctrlPanel lbSetData [_lbAdd, _className];
|
|
||||||
_ctrlPanel lbSetPicture [_lbAdd, getText (_x >> "texture")];
|
|
||||||
_ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]];
|
|
||||||
} forEach ("(if (isNumber (_x >> 'scope')) then {getNumber (_x >> 'scope')} else {2}) == 2" configClasses (missionConfigFile >> "CfgUnitInsignia"));
|
|
||||||
|
|
||||||
GVAR(currentInsignia)
|
|
||||||
};
|
|
||||||
// Unknown
|
|
||||||
default {""};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// When switching tabs, clear searchbox
|
// Don't reset the current right panel for weapons, binos and containers
|
||||||
if (GVAR(currentLeftPanel) != _ctrlIDC) then {
|
if !(_idxVirt in [IDX_VIRT_PRIMARY_WEAPONS, IDX_VIRT_SECONDARY_WEAPONS, IDX_VIRT_HANDGUN_WEAPONS, IDX_VIRT_BINO, IDX_VIRT_UNIFORM, IDX_VIRT_VEST, IDX_VIRT_BACKPACK]) then {
|
||||||
(_display displayCtrl IDC_leftSearchbar) ctrlSetText "";
|
GVAR(currentRightPanel) = nil;
|
||||||
(_display displayCtrl IDC_rightSearchbar) ctrlSetText "";
|
};
|
||||||
|
GVAR(currentLeftPanel) = _ctrlIDC;
|
||||||
|
|
||||||
|
// Add items to the listbox
|
||||||
|
private _selectedItem = if (_idxVirt != -1) then { // Items
|
||||||
|
private _configParent = switch (_idxVirt) do {
|
||||||
|
case IDX_VIRT_GOGGLES: {"CfgGlasses"};
|
||||||
|
case IDX_VIRT_BACKPACK: {"CfgVehicles"};
|
||||||
|
default {"CfgWeapons"};
|
||||||
|
};
|
||||||
|
|
||||||
|
private _items = if (_idxVirt < IDX_VIRT_HEADGEAR) then {
|
||||||
|
keys ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _idxVirt)
|
||||||
|
} else {
|
||||||
|
keys (GVAR(virtualItems) get _idxVirt)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
[_configParent, _x, _ctrlPanel] call FUNC(addListBoxItem);
|
||||||
|
} forEach _items;
|
||||||
|
|
||||||
|
GVAR(currentItems) select _idxVirt
|
||||||
|
} else { // Special cases
|
||||||
|
switch (_ctrlIDC) do {
|
||||||
|
// Faces
|
||||||
|
case IDC_buttonFace: {
|
||||||
|
private _lbAdd = -1; // micro-optimization
|
||||||
|
// Faces need to be added like this because their config path is
|
||||||
|
// configFile >> "CfgFaces" >> face category >> className
|
||||||
|
{
|
||||||
|
_y params ["_displayName", "_modPicture"];
|
||||||
|
_lbAdd = _ctrlPanel lbAdd _displayName;
|
||||||
|
_ctrlPanel lbSetData [_lbAdd, _x];
|
||||||
|
_ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _x]];
|
||||||
|
_ctrlPanel lbSetPictureRight [_lbAdd, ["", _modPicture] select GVAR(enableModIcons)];
|
||||||
|
} forEach GVAR(faceCache); // HashMap, not array
|
||||||
|
|
||||||
|
GVAR(currentFace)
|
||||||
|
};
|
||||||
|
// Voices
|
||||||
|
case IDC_buttonVoice: {
|
||||||
|
{
|
||||||
|
["CfgVoice", _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem);
|
||||||
|
} forEach (keys GVAR(voiceCache));
|
||||||
|
|
||||||
|
GVAR(currentVoice)
|
||||||
|
};
|
||||||
|
// Insignia
|
||||||
|
case IDC_buttonInsignia: {
|
||||||
|
{
|
||||||
|
["CfgUnitInsignia", _x, _ctrlPanel, "texture", _y] call FUNC(addListBoxItem);
|
||||||
|
} forEach GVAR(insigniaCache);
|
||||||
|
|
||||||
|
GVAR(currentInsignia)
|
||||||
|
};
|
||||||
|
// Unknown
|
||||||
|
default {
|
||||||
|
WARNING_1("Unknown arsenal left panel with IDC %1, update ace_arsenal_idxMap and relevant macros if adding a new tab",_ctrlIDC);
|
||||||
|
""
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Trigger event
|
// Trigger event
|
||||||
GVAR(currentLeftPanel) = _ctrlIDC;
|
|
||||||
[QGVAR(leftPanelFilled), [_display, _ctrlIDC, GVAR(currentRightPanel)]] call CBA_fnc_localEvent;
|
[QGVAR(leftPanelFilled), [_display, _ctrlIDC, GVAR(currentRightPanel)]] call CBA_fnc_localEvent;
|
||||||
|
|
||||||
// Sort
|
// Sort
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
#include "..\defines.hpp"
|
#include "..\defines.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Alganthe, johnb43
|
* Author: Alganthe, johnb43, LinkIsGrim
|
||||||
* Fill loadouts list.
|
* Fill loadouts list over multiple frames. LOADOUTS_PER_FRAME macro does what it says on the tin.
|
||||||
|
* Should only ever be called by display load (with optional params as default) and by itself.
|
||||||
|
* Listen to ace_arsenal_loadoutsListFilled event if you need to iterate over the loadouts list.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Loadouts display <DISPLAY>
|
* 0: Loadouts display <DISPLAY>
|
||||||
* 1: Tab control <CONTROL>
|
* 1: Tab control <CONTROL>
|
||||||
|
* 2: Current frame filling loadouts list <NUMBER> (default: 0)
|
||||||
|
* 3: Frames necessary to fill loadouts list <NUMBER> (default: -1)
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
@ -14,29 +18,46 @@
|
|||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params ["_display", "_control"];
|
// Can just be modified directly, no further setup needed
|
||||||
|
#define LOADOUTS_PER_FRAME 10
|
||||||
|
|
||||||
(_display displayCtrl IDC_textEditBox) ctrlSetText "";
|
params ["_display", "_control", ["_currentFrame", 0], ["_framesToFill", -1]];
|
||||||
|
|
||||||
|
if (isNull _display) exitWith {
|
||||||
|
TRACE_2("display closed, aborting",_currentFrame,_framesToFill);
|
||||||
|
};
|
||||||
|
|
||||||
private _contentPanelCtrl = _display displayCtrl IDC_contentPanel;
|
private _contentPanelCtrl = _display displayCtrl IDC_contentPanel;
|
||||||
|
if (_currentFrame == 0) then {
|
||||||
|
(_display displayCtrl IDC_textEditBox) ctrlSetText "";
|
||||||
|
|
||||||
// Force a "refresh" animation of the panel
|
// Force a "refresh" animation of the panel
|
||||||
_contentPanelCtrl ctrlSetFade 1;
|
_contentPanelCtrl ctrlSetFade 1;
|
||||||
_contentPanelCtrl ctrlCommit 0;
|
_contentPanelCtrl ctrlCommit 0;
|
||||||
_contentPanelCtrl ctrlSetFade 0;
|
_contentPanelCtrl ctrlSetFade 0;
|
||||||
_contentPanelCtrl ctrlCommit FADE_DELAY;
|
_contentPanelCtrl ctrlCommit FADE_DELAY;
|
||||||
|
|
||||||
_contentPanelCtrl lnbSetCurSelRow -1;
|
_contentPanelCtrl lnbSetCurSelRow -1;
|
||||||
lnbClear _contentPanelCtrl;
|
lnbClear _contentPanelCtrl;
|
||||||
|
};
|
||||||
|
|
||||||
private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars);
|
private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars);
|
||||||
private _cfgWeapons = configFile >> "CfgWeapons";
|
private _cfgWeapons = configFile >> "CfgWeapons"; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove
|
||||||
private _newRow = -1;
|
private _newRow = -1;
|
||||||
|
|
||||||
if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
||||||
private _loadoutNameAndTab = "";
|
private _loadoutNameAndTab = "";
|
||||||
private _loadoutCachedInfo = "";
|
private _loadoutCachedInfo = "";
|
||||||
private _sharingEnabled = GVAR(allowSharedLoadouts) && {isMultiplayer};
|
private _sharingEnabled = GVAR(allowSharedLoadouts) && {isMultiplayer};
|
||||||
|
private _loadouts = [
|
||||||
|
profileNamespace getVariable [QGVAR(saved_loadouts), []],
|
||||||
|
GVAR(defaultLoadoutsList)
|
||||||
|
] select (ctrlIDC _control == IDC_buttonDefaultLoadouts);
|
||||||
|
if (_currentFrame == 0) then {
|
||||||
|
_framesToFill = floor ((count _loadouts) / LOADOUTS_PER_FRAME);
|
||||||
|
TRACE_2("filling loadouts list",_currentFrame,_framesToFill);
|
||||||
|
_this set [3, _framesToFill];
|
||||||
|
};
|
||||||
|
|
||||||
// Add all loadouts to loadout list
|
// Add all loadouts to loadout list
|
||||||
{
|
{
|
||||||
@ -50,10 +71,10 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
|||||||
_loadoutCachedInfo = [_loadoutData] call FUNC(verifyLoadout);
|
_loadoutCachedInfo = [_loadoutData] call FUNC(verifyLoadout);
|
||||||
_contentPanelCtrl setVariable [_loadoutNameAndTab, _loadoutCachedInfo];
|
_contentPanelCtrl setVariable [_loadoutNameAndTab, _loadoutCachedInfo];
|
||||||
|
|
||||||
_loadoutCachedInfo params ["", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"];
|
_loadoutCachedInfo params ["", "_nullItemsList", "_unavailableItemsList"];
|
||||||
|
|
||||||
// Log missing / nil items to RPT (only once per arsenal session)
|
// Log missing / nil items to RPT (only once per arsenal session)
|
||||||
if (GVAR(EnableRPTLog) && {(_nullItemsAmount > 0) || {_unavailableItemsAmount > 0}}) then {
|
if (GVAR(EnableRPTLog) && {(_nullItemsList isNotEqualTo []) || {_unavailableItemsList isNotEqualTo []}}) then {
|
||||||
private _printComponent = "ACE_Arsenal - Loadout:";
|
private _printComponent = "ACE_Arsenal - Loadout:";
|
||||||
private _printNullItemsList = ["Missing items:", str _nullItemsList] joinString " ";
|
private _printNullItemsList = ["Missing items:", str _nullItemsList] joinString " ";
|
||||||
private _printUnavailableItemsList = ["Unavailable items:", str _unavailableItemsList] joinString " ";
|
private _printUnavailableItemsList = ["Unavailable items:", str _unavailableItemsList] joinString " ";
|
||||||
@ -69,18 +90,18 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
|||||||
_contentPanelCtrl lnbSetColumnsPos [0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90];
|
_contentPanelCtrl lnbSetColumnsPos [0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90];
|
||||||
};
|
};
|
||||||
|
|
||||||
_loadoutCachedInfo params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"];
|
_loadoutCachedInfo params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"];
|
||||||
_extendedLoadout params ["_loadout"];
|
_extendedLoadout params ["_loadout"]; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove
|
||||||
|
|
||||||
_newRow = _contentPanelCtrl lnbAddRow ["", _loadoutName];
|
_newRow = _contentPanelCtrl lnbAddRow ["", _loadoutName];
|
||||||
|
|
||||||
ADD_LOADOUTS_LIST_PICTURES
|
ADD_LOADOUTS_LIST_PICTURES
|
||||||
|
|
||||||
// Change color on loadout lines that have items that aren't available or don't exist
|
// Change color on loadout lines that have items that aren't available or don't exist
|
||||||
if (_nullItemsAmount > 0) then {
|
if (_nullItemsList isNotEqualTo []) then {
|
||||||
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red
|
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red
|
||||||
} else {
|
} else {
|
||||||
if (_unavailableItemsAmount > 0) then {
|
if (_unavailableItemsList isNotEqualTo []) then {
|
||||||
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray
|
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -90,10 +111,16 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
|||||||
_contentPanelCtrl lnbSetPicture [[_newRow, 0], QPATHTOF(data\iconPublic.paa)];
|
_contentPanelCtrl lnbSetPicture [[_newRow, 0], QPATHTOF(data\iconPublic.paa)];
|
||||||
_contentPanelCtrl lnbSetValue [[_newRow, 0], 1];
|
_contentPanelCtrl lnbSetValue [[_newRow, 0], 1];
|
||||||
};
|
};
|
||||||
} forEach ([profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (ctrlIDC _control == IDC_buttonDefaultLoadouts));
|
} forEach (_loadouts select [_currentFrame * LOADOUTS_PER_FRAME, [LOADOUTS_PER_FRAME, count _loadouts] select is3DEN]);
|
||||||
} else {
|
} else {
|
||||||
private _allPlayerNames = allPlayers apply {name _x};
|
private _allPlayerNames = allPlayers apply {name _x};
|
||||||
|
private _loadouts = _sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x};
|
||||||
private _loadoutVar = "";
|
private _loadoutVar = "";
|
||||||
|
if (_currentFrame == 0) then {
|
||||||
|
_framesToFill = floor ((count _loadouts) / LOADOUTS_PER_FRAME);
|
||||||
|
TRACE_2("filling loadouts list",_currentFrame,_framesToFill);
|
||||||
|
_this set [3, _framesToFill];
|
||||||
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
_x params ["_playerName", "_loadoutName", "_loadoutData"];
|
_x params ["_playerName", "_loadoutName", "_loadoutData"];
|
||||||
@ -107,8 +134,8 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
|||||||
|
|
||||||
[QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent;
|
[QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent;
|
||||||
} else {
|
} else {
|
||||||
([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"];
|
([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"];
|
||||||
_extendedLoadout params ["_loadout"];
|
_extendedLoadout params ["_loadout"]; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove
|
||||||
|
|
||||||
_contentPanelCtrl lnbSetColumnsPos [0, 0.15, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90];
|
_contentPanelCtrl lnbSetColumnsPos [0, 0.15, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90];
|
||||||
_newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName];
|
_newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName];
|
||||||
@ -118,17 +145,23 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
|||||||
_contentPanelCtrl lnbSetData [[_newRow, 1], _loadoutVar];
|
_contentPanelCtrl lnbSetData [[_newRow, 1], _loadoutVar];
|
||||||
|
|
||||||
// Change color on loadout lines that have items that aren't available or don't exist
|
// Change color on loadout lines that have items that aren't available or don't exist
|
||||||
if (_nullItemsAmount > 0) then {
|
if (_nullItemsList isNotEqualTo []) then {
|
||||||
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red
|
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red
|
||||||
} else {
|
} else {
|
||||||
if (_unavailableItemsAmount > 0) then {
|
if (_unavailableItemsList isNotEqualTo []) then {
|
||||||
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray
|
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} forEach (_sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x});
|
} forEach (_loadouts select [_currentFrame * LOADOUTS_PER_FRAME, [LOADOUTS_PER_FRAME, count _loadouts] select is3DEN]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!is3DEN && _currentFrame != _framesToFill) exitWith {
|
||||||
|
_this set [2, _currentFrame + 1];
|
||||||
|
[FUNC(fillLoadoutsList), _this] call CBA_fnc_execNextFrame;
|
||||||
|
};
|
||||||
|
TRACE_3("finished",_currentFrame,_framesToFill,lnbSize _contentPanelCtrl);
|
||||||
|
|
||||||
[QGVAR(loadoutsListFilled), [_display, _control]] call CBA_fnc_localEvent;
|
[QGVAR(loadoutsListFilled), [_display, _control]] call CBA_fnc_localEvent;
|
||||||
|
|
||||||
// Sort loadouts alphabetically
|
// Sort loadouts alphabetically
|
||||||
|
@ -47,7 +47,7 @@ private _groups = (GVAR(actionList) select _panel) select {
|
|||||||
private _show = _groups isNotEqualTo [];
|
private _show = _groups isNotEqualTo [];
|
||||||
private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox;
|
private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox;
|
||||||
_actionsBoxCtrl ctrlShow _show;
|
_actionsBoxCtrl ctrlShow _show;
|
||||||
_actionsBoxCtrl ctrlCommit 0.15;
|
_actionsBoxCtrl ctrlCommit FADE_DELAY;
|
||||||
|
|
||||||
if (!_show) exitWith {};
|
if (!_show) exitWith {};
|
||||||
|
|
||||||
@ -77,7 +77,6 @@ private _items = _group select 3 select {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_actionsCurrentPageCtrl ctrlSetText (_group select 1);
|
_actionsCurrentPageCtrl ctrlSetText (_group select 1);
|
||||||
_actionsCurrentPageCtrl ctrlSetFade 0;
|
|
||||||
_actionsCurrentPageCtrl ctrlShow true;
|
_actionsCurrentPageCtrl ctrlShow true;
|
||||||
_actionsCurrentPageCtrl ctrlCommit 0;
|
_actionsCurrentPageCtrl ctrlCommit 0;
|
||||||
|
|
||||||
@ -85,36 +84,22 @@ private _activeCtrls = [];
|
|||||||
{
|
{
|
||||||
_x params ["", "_type", "_label", "_statement"];
|
_x params ["", "_type", "_label", "_statement"];
|
||||||
|
|
||||||
private _idc = IDC_actionsText1 + _forEachIndex * 2;
|
private _idc = IDC_actionsText1 + _type + _forEachIndex * 2;
|
||||||
private _actionTextCtrl = _display displayCtrl _idc;
|
private _actionCtrl = _display displayCtrl _idc;
|
||||||
private _actionButtonCtrl = _display displayCtrl (_idc + 1);
|
|
||||||
|
|
||||||
switch (_type) do {
|
switch (_type) do {
|
||||||
case ACTION_TYPE_BUTTON: {
|
case ACTION_TYPE_BUTTON: {
|
||||||
_actionButtonCtrl ctrlRemoveAllEventHandlers "ButtonClick";
|
_actionCtrl ctrlRemoveAllEventHandlers "ButtonClick";
|
||||||
_actionButtonCtrl ctrlAddEventHandler ["ButtonClick", {
|
_actionCtrl ctrlAddEventHandler ["ButtonClick", {
|
||||||
if (is3DEN) exitWith {[true] call FUNC(refresh)};
|
if (is3DEN) exitWith {[true] call FUNC(refresh)};
|
||||||
[{
|
[{
|
||||||
[true] call FUNC(refresh);
|
[true] call FUNC(refresh);
|
||||||
}] call CBA_fnc_execNextFrame;
|
}] call CBA_fnc_execNextFrame;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (_activeCtrls isNotEqualTo []) then {
|
_actionCtrl ctrlAddEventHandler ["ButtonClick", _statement];
|
||||||
(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"];
|
_actionCtrl ctrlSetText _label;
|
||||||
_actionButtonCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H);
|
_actionCtrl ctrlEnable true;
|
||||||
} else {
|
|
||||||
_actionButtonCtrl ctrlSetPositionY (6 * GRID_H);
|
|
||||||
};
|
|
||||||
|
|
||||||
_actionButtonCtrl ctrlAddEventHandler ["ButtonClick", _statement];
|
|
||||||
_actionButtonCtrl ctrlSetText _label;
|
|
||||||
_actionButtonCtrl ctrlSetFade 0;
|
|
||||||
_actionButtonCtrl ctrlEnable true;
|
|
||||||
_actionButtonCtrl ctrlCommit 0;
|
|
||||||
_actionTextCtrl ctrlSetFade 1;
|
|
||||||
_actionTextCtrl ctrlEnable false;
|
|
||||||
_actionTextCtrl ctrlCommit 0;
|
|
||||||
_activeCtrls pushBack _actionButtonCtrl;
|
|
||||||
};
|
};
|
||||||
case ACTION_TYPE_TEXT: {
|
case ACTION_TYPE_TEXT: {
|
||||||
private _text = call _statement;
|
private _text = call _statement;
|
||||||
@ -125,47 +110,35 @@ private _activeCtrls = [];
|
|||||||
if (_text isEqualType []) then {
|
if (_text isEqualType []) then {
|
||||||
_text = _text joinString endl;
|
_text = _text joinString endl;
|
||||||
};
|
};
|
||||||
if (_activeCtrls isNotEqualTo []) then {
|
|
||||||
(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"];
|
|
||||||
_actionTextCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H);
|
|
||||||
} else {
|
|
||||||
_actionTextCtrl ctrlSetPositionY (5 * GRID_H);
|
|
||||||
};
|
|
||||||
|
|
||||||
_actionTextCtrl ctrlSetText _text;
|
_actionCtrl ctrlSetText _text;
|
||||||
_actionTextCtrl ctrlSetPositionH (ctrlTextHeight _actionTextCtrl);
|
_actionCtrl ctrlSetPositionH (ctrlTextHeight _actionCtrl);
|
||||||
_actionTextCtrl ctrlSetFade 0;
|
_actionCtrl ctrlEnable false;
|
||||||
_actionTextCtrl ctrlEnable false;
|
|
||||||
_actionTextCtrl ctrlCommit 0;
|
|
||||||
_actionButtonCtrl ctrlSetFade 1;
|
|
||||||
_actionButtonCtrl ctrlEnable false;
|
|
||||||
_actionButtonCtrl ctrlCommit 0;
|
|
||||||
_activeCtrls pushBack _actionTextCtrl;
|
|
||||||
};
|
|
||||||
default {
|
|
||||||
_actionTextCtrl ctrlSetFade 1;
|
|
||||||
_actionTextCtrl ctrlCommit 0;
|
|
||||||
_actionButtonCtrl ctrlSetFade 1;
|
|
||||||
_actionButtonCtrl ctrlEnable false;
|
|
||||||
_actionButtonCtrl ctrlCommit 0;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (_activeCtrls isNotEqualTo []) then {
|
||||||
|
(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"];
|
||||||
|
_actionCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H);
|
||||||
|
} else {
|
||||||
|
_actionCtrl ctrlSetPositionY ((5 + _type) * GRID_H);
|
||||||
|
};
|
||||||
|
|
||||||
|
_actionCtrl ctrlShow true;
|
||||||
|
_actionCtrl ctrlCommit 0;
|
||||||
|
_activeCtrls pushBack _actionCtrl;
|
||||||
} forEach _items;
|
} forEach _items;
|
||||||
|
|
||||||
private _actionCount = count _items;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
private _idc = IDC_actionsText1 + _x * 2;
|
private _idc = ctrlIDC _x;
|
||||||
private _actionTextCtrl = _display displayCtrl _idc;
|
if (_idc < IDC_actionsText1 || _idc > IDC_actionsButton5) then {continue};
|
||||||
private _actionButtonCtrl = _display displayCtrl (_idc + 1);
|
|
||||||
|
|
||||||
_actionTextCtrl ctrlSetFade 1;
|
_x ctrlShow false;
|
||||||
_actionTextCtrl ctrlCommit 0;
|
_x ctrlEnable false;
|
||||||
_actionButtonCtrl ctrlSetFade 1;
|
_x ctrlSetPositionY 0;
|
||||||
_actionButtonCtrl ctrlCommit 0;
|
_x ctrlCommit 0;
|
||||||
} forEach ([0, 1, 2, 3, 4] select [_actionCount, 5]);
|
} forEach ((allControls _actionsBoxCtrl) select {!(_x in _activeCtrls)});
|
||||||
|
|
||||||
private _pos = ctrlPosition _actionsBoxCtrl;
|
|
||||||
(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"];
|
(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"];
|
||||||
private _actionsBoxHeight = _lastPosY + _lastPosH + GRID_H;
|
private _actionsBoxHeight = _lastPosY + _lastPosH + GRID_H;
|
||||||
_actionsBoxCtrl ctrlSetPositionH _actionsBoxHeight;
|
_actionsBoxCtrl ctrlSetPositionH _actionsBoxHeight;
|
||||||
|
@ -19,279 +19,58 @@ private _extendedInfo = createHashMap;
|
|||||||
|
|
||||||
// Check if the provided loadout is a CBA extended loadout
|
// Check if the provided loadout is a CBA extended loadout
|
||||||
if (count _loadout == 2) then {
|
if (count _loadout == 2) then {
|
||||||
_extendedInfo = _loadout select 1;
|
_extendedInfo = +(_loadout select 1); // Copy the hashmap to prevent events from modifiyng the profileNamespace extendedInfo
|
||||||
_loadout = _loadout select 0;
|
_loadout = _loadout select 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
private _cfgWeapons = configFile >> "CfgWeapons";
|
|
||||||
private _cfgMagazines = configFile >> "CfgMagazines";
|
|
||||||
private _cfgVehicles = configFile >> "CfgVehicles";
|
|
||||||
private _cfgGlasses = configFile >> "CfgGlasses";
|
|
||||||
|
|
||||||
private _weapons = GVAR(virtualItems) get IDX_VIRT_WEAPONS;
|
|
||||||
private _attachments = GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS;
|
|
||||||
|
|
||||||
private _name = "";
|
private _name = "";
|
||||||
private _nullItemsAmount = 0;
|
private _itemArray = [];
|
||||||
private _unavailableItemsAmount = 0;
|
|
||||||
private _nullItemsList = [];
|
private _nullItemsList = [];
|
||||||
private _unavailableItemsList = [];
|
private _unavailableItemsList = [];
|
||||||
|
|
||||||
// Search for all items and turn them into config case; Don't touch other value types
|
// Search for all items and check their availability
|
||||||
private _fnc_toConfigCase = {
|
private _fnc_filterLoadout = {
|
||||||
_this apply {
|
_this apply {
|
||||||
if (_x isEqualType "") then {
|
if (_x isEqualType "" && {_x != ""}) then {
|
||||||
if (_x != "") then {
|
_name = _x call EFUNC(common,getConfigName);
|
||||||
_name = _x call EFUNC(common,getConfigName);
|
|
||||||
|
|
||||||
// If item doesn't exist in config, "" is returned
|
// If item doesn't exist in config, "" is returned
|
||||||
// Just return unaltered item name in that case, so it can be documented as being unavailable
|
if (_name == "") then {
|
||||||
[_x, _name] select (_name != "");
|
_nullItemsList pushBack _x;
|
||||||
} else {
|
} else {
|
||||||
_x
|
// Check if item or its base weapon exist in the arsenal
|
||||||
|
if !(_name in GVAR(virtualItemsFlat)) then {
|
||||||
|
_name = _name call FUNC(baseWeapon);
|
||||||
|
if !(_name in GVAR(virtualItemsFlat)) then {
|
||||||
|
_unavailableItemsList pushBack _name;
|
||||||
|
_name = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_name
|
||||||
} else {
|
} else {
|
||||||
// Handle arrays
|
// Handle arrays
|
||||||
if (_x isEqualType []) then {
|
if (_x isEqualType []) then {
|
||||||
_x call _fnc_toConfigCase
|
_itemArray = _x call _fnc_filterLoadout;
|
||||||
|
// If "" is given as a container, an error is thrown, therefore, filter out all unavailable/null containers
|
||||||
|
if (count _itemArray == 2 && {(_itemArray select 0) isEqualTo ""} && {(_itemArray select 1) isEqualType []}) then {
|
||||||
|
_itemArray = [];
|
||||||
|
};
|
||||||
|
_itemArray
|
||||||
} else {
|
} else {
|
||||||
// All other types
|
// All other types and empty strings
|
||||||
_x
|
_x
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convert loadout to config case
|
// Convert loadout to config case and replace null/unavailable items
|
||||||
// Loadout might come from a different modpack, which might have different config naming
|
// Loadout might come from a different modpack, which might have different config naming
|
||||||
_loadout = _loadout call _fnc_toConfigCase;
|
_loadout = _loadout call _fnc_filterLoadout;
|
||||||
|
|
||||||
// Check a weapon, with its attachments and magazines, if items are available
|
// Raise event for 3rd party: mostly for handling extended info
|
||||||
private _fnc_weaponCheck = {
|
[QGVAR(loadoutVerified), [_loadout, _extendedInfo]] call CBA_fnc_localEvent;
|
||||||
params ["_weaponArray", ["_index", -1]];
|
|
||||||
|
|
||||||
{
|
[[_loadout, _extendedInfo], _nullItemsList arrayIntersect _nullItemsList, _unavailableItemsList arrayIntersect _unavailableItemsList]
|
||||||
// Weapons and attachments
|
|
||||||
if (_x isEqualType "") then {
|
|
||||||
if (_x != "") then {
|
|
||||||
// Check if item exists
|
|
||||||
if (isClass (_cfgWeapons >> _x)) then {
|
|
||||||
// Get base weapon
|
|
||||||
_x = _x call FUNC(baseWeapon);
|
|
||||||
|
|
||||||
// Check if item is available in arsenal
|
|
||||||
if !(
|
|
||||||
// Weapon class name is at the very start of the array
|
|
||||||
if (_forEachIndex == 0) then {
|
|
||||||
// If the type of weapon is known, only look through that array
|
|
||||||
if (_index != -1) then {
|
|
||||||
// If binos, choose differently
|
|
||||||
if (_index == IDX_LOADOUT_BINO) then {
|
|
||||||
_x in (GVAR(virtualItems) get IDX_VIRT_BINO)
|
|
||||||
} else {
|
|
||||||
_x in (_weapons get _index)
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_x in (_weapons get IDX_VIRT_PRIMARY_WEAPONS) ||
|
|
||||||
{_x in (_weapons get IDX_VIRT_SECONDARY_WEAPONS)} ||
|
|
||||||
{_x in (_weapons get IDX_VIRT_HANDGUN_WEAPONS)} ||
|
|
||||||
{_x in (GVAR(virtualItems) get IDX_VIRT_BINO)}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_x in (_attachments get IDX_VIRT_OPTICS_ATTACHMENTS) ||
|
|
||||||
{_x in (_attachments get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} ||
|
|
||||||
{_x in (_attachments get IDX_VIRT_MUZZLE_ATTACHMENTS)} ||
|
|
||||||
{_x in (_attachments get IDX_VIRT_BIPOD_ATTACHMENTS)}
|
|
||||||
}
|
|
||||||
) then {
|
|
||||||
_unavailableItemsList pushBackUnique _x;
|
|
||||||
_weaponArray set [_forEachIndex, ""];
|
|
||||||
INC(_unavailableItemsAmount);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_nullItemsList pushBackUnique _x;
|
|
||||||
_weaponArray set [_forEachIndex, ""];
|
|
||||||
INC(_nullItemsAmount);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// Magazines
|
|
||||||
if (_x isNotEqualTo []) then {
|
|
||||||
_x params ["_magazine"];
|
|
||||||
|
|
||||||
// Check if item exists
|
|
||||||
if (isClass (_cfgMagazines >> _magazine)) then {
|
|
||||||
// Check if item is available in arsenal
|
|
||||||
if !(_magazine in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) then {
|
|
||||||
_unavailableItemsList pushBackUnique _magazine;
|
|
||||||
_weaponArray set [_forEachIndex, []];
|
|
||||||
INC(_unavailableItemsAmount);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_nullItemsList pushBackUnique _magazine;
|
|
||||||
_weaponArray set [_forEachIndex, []];
|
|
||||||
INC(_nullItemsAmount);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} forEach _weaponArray;
|
|
||||||
};
|
|
||||||
|
|
||||||
private _item = "";
|
|
||||||
|
|
||||||
// Go through entire loadout to check if items are available in current arsenal
|
|
||||||
for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do {
|
|
||||||
switch (_dataIndex) do {
|
|
||||||
// Primary weapon, Secondary weapon, Handgun weapon, Binoculars
|
|
||||||
case IDX_LOADOUT_PRIMARY_WEAPON;
|
|
||||||
case IDX_LOADOUT_SECONDARY_WEAPON;
|
|
||||||
case IDX_LOADOUT_HANDGUN_WEAPON;
|
|
||||||
case IDX_LOADOUT_BINO: {
|
|
||||||
[_loadout select _dataIndex, _dataIndex] call _fnc_weaponCheck;
|
|
||||||
};
|
|
||||||
// Uniform, vest, backpack
|
|
||||||
case IDX_LOADOUT_UNIFORM;
|
|
||||||
case IDX_LOADOUT_VEST;
|
|
||||||
case IDX_LOADOUT_BACKPACK: {
|
|
||||||
(_loadout select _dataIndex) params [["_item", ""], ["_containerItems", []]];
|
|
||||||
|
|
||||||
if (_item != "") then {
|
|
||||||
// Check if item exists
|
|
||||||
if (isClass (_cfgVehicles >> _item) || {isClass (_cfgWeapons >> _item)}) then {
|
|
||||||
// Check if item is available in arsenal
|
|
||||||
if !(_item in (GVAR(virtualItems) get (_dataIndex + 1))) then {
|
|
||||||
_unavailableItemsList pushBackUnique _item;
|
|
||||||
_loadout set [_dataIndex, []];
|
|
||||||
INC(_unavailableItemsAmount);
|
|
||||||
} else {
|
|
||||||
{
|
|
||||||
switch (true) do {
|
|
||||||
// Magazines have each 3 entries: Name, number of magazines and ammo count
|
|
||||||
case (_x isEqualTypeArray ["", 0, 0]): {
|
|
||||||
_x params ["_item"];
|
|
||||||
|
|
||||||
// Check if item exists
|
|
||||||
if (isClass (_cfgMagazines >> _item)) then {
|
|
||||||
// Check if item is available in arsenal
|
|
||||||
if !(
|
|
||||||
_item in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL) ||
|
|
||||||
{_item in (GVAR(virtualItems) get IDX_VIRT_GRENADES)} ||
|
|
||||||
{_item in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES)} ||
|
|
||||||
{_item in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)}
|
|
||||||
) then {
|
|
||||||
_unavailableItemsList pushBackUnique _item;
|
|
||||||
((_loadout select _dataIndex) select 1) set [_forEachIndex, []];
|
|
||||||
INC(_unavailableItemsAmount);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_nullItemsList pushBackUnique _item;
|
|
||||||
((_loadout select _dataIndex) select 1) set [_forEachIndex, []];
|
|
||||||
INC(_nullItemsAmount);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// Weapons have 2 entries: Weapon info array and amount
|
|
||||||
case (_x isEqualTypeArray [[], 0]): {
|
|
||||||
[_x select 0] call _fnc_weaponCheck;
|
|
||||||
};
|
|
||||||
// Misc. items have 2 entries: Name and amount, containers have 2 entries: Name and isBackpack
|
|
||||||
default {
|
|
||||||
_x params ["_item"];
|
|
||||||
|
|
||||||
// Check if item exists
|
|
||||||
if (
|
|
||||||
isClass (_cfgWeapons >> _item) ||
|
|
||||||
{isClass (_cfgMagazines >> _item)} ||
|
|
||||||
{isClass (_cfgGlasses >> _item)} ||
|
|
||||||
{isClass (_cfgVehicles >> _item)}
|
|
||||||
) then {
|
|
||||||
// Check if item is available in arsenal
|
|
||||||
if !(_item in GVAR(virtualItemsFlat)) then {
|
|
||||||
_unavailableItemsList pushBackUnique _item;
|
|
||||||
((_loadout select _dataIndex) select 1) set [_forEachIndex, []];
|
|
||||||
INC(_unavailableItemsAmount);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_nullItemsList pushBackUnique _item;
|
|
||||||
((_loadout select _dataIndex) select 1) set [_forEachIndex, []];
|
|
||||||
INC(_nullItemsAmount);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
} forEach _containerItems;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_nullItemsList pushBackUnique _item;
|
|
||||||
_loadout set [_dataIndex, []];
|
|
||||||
INC(_nullItemsAmount);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// Headgear
|
|
||||||
case IDX_LOADOUT_HEADGEAR: {
|
|
||||||
_item = _loadout select _dataIndex;
|
|
||||||
|
|
||||||
if (_item != "") then {
|
|
||||||
// Check if item exists
|
|
||||||
if (isClass (_cfgWeapons >> _item)) then {
|
|
||||||
// Check if item is available in arsenal
|
|
||||||
if !(_item in (GVAR(virtualItems) get IDX_VIRT_HEADGEAR)) then {
|
|
||||||
_unavailableItemsList pushBackUnique _item;
|
|
||||||
_loadout set [_dataIndex, ""];
|
|
||||||
INC(_unavailableItemsAmount);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_nullItemsList pushBackUnique _item;
|
|
||||||
_loadout set [_dataIndex, ""];
|
|
||||||
INC(_nullItemsAmount);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// Facewear
|
|
||||||
case IDX_LOADOUT_GOGGLES: {
|
|
||||||
_item = _loadout select _dataIndex;
|
|
||||||
|
|
||||||
if (_item != "") then {
|
|
||||||
// Check if item exists
|
|
||||||
if (isClass (_cfgGlasses >> _item)) then {
|
|
||||||
// Check if item is available in arsenal
|
|
||||||
if !(_item in (GVAR(virtualItems) get IDX_VIRT_GOGGLES)) then {
|
|
||||||
_unavailableItemsList pushBackUnique _item;
|
|
||||||
_loadout set [_dataIndex, ""];
|
|
||||||
INC(_unavailableItemsAmount);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_nullItemsList pushBackUnique _item;
|
|
||||||
_loadout set [_dataIndex, ""];
|
|
||||||
INC(_nullItemsAmount);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs
|
|
||||||
case IDX_LOADOUT_ASSIGNEDITEMS: {
|
|
||||||
private _assignedItems = _loadout select _dataIndex;
|
|
||||||
|
|
||||||
for "_subIndex" from 0 to 5 do {
|
|
||||||
_item = _assignedItems select _subIndex;
|
|
||||||
|
|
||||||
if (_item != "") then {
|
|
||||||
// Check if item exists
|
|
||||||
if (isClass (_cfgWeapons >> _item)) then {
|
|
||||||
// Check if item is available in arsenal
|
|
||||||
if !(_item in (GVAR(virtualItems) get (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _subIndex)))) then {
|
|
||||||
_unavailableItemsList pushBackUnique _item;
|
|
||||||
_assignedItems set [_subIndex, ""];
|
|
||||||
INC(_unavailableItemsAmount);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
_nullItemsList pushBackUnique _item;
|
|
||||||
_assignedItems set [_subIndex, ""];
|
|
||||||
INC(_nullItemsAmount);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
[[_loadout, _extendedInfo], _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList]
|
|
||||||
|
@ -15,6 +15,3 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "\z\ace\addons\main\script_macros.hpp"
|
#include "\z\ace\addons\main\script_macros.hpp"
|
||||||
|
|
||||||
#define ACTION_TYPE_BUTTON 0
|
|
||||||
#define ACTION_TYPE_TEXT 1
|
|
||||||
|
@ -467,7 +467,6 @@ class GVAR(display) {
|
|||||||
};
|
};
|
||||||
class actionsText1: RscTextMulti {
|
class actionsText1: RscTextMulti {
|
||||||
idc = IDC_actionsText1;
|
idc = IDC_actionsText1;
|
||||||
fade = 1;
|
|
||||||
x = QUOTE(0 * GRID_W);
|
x = QUOTE(0 * GRID_W);
|
||||||
y = QUOTE(5 * GRID_H);
|
y = QUOTE(5 * GRID_H);
|
||||||
w = QUOTE(45 * GRID_W);
|
w = QUOTE(45 * GRID_W);
|
||||||
@ -479,8 +478,6 @@ class GVAR(display) {
|
|||||||
};
|
};
|
||||||
class actionsButton1: ctrlButton {
|
class actionsButton1: ctrlButton {
|
||||||
idc = IDC_actionsButton1;
|
idc = IDC_actionsButton1;
|
||||||
onMouseEnter = QUOTE(ctrlSetFocus (_this select 0));
|
|
||||||
fade = 1;
|
|
||||||
text = "";
|
text = "";
|
||||||
x = QUOTE(1 * GRID_W);
|
x = QUOTE(1 * GRID_W);
|
||||||
y = QUOTE(6 * GRID_H);
|
y = QUOTE(6 * GRID_H);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* 2: Namespace to store the cache on <NAMESPACE>
|
* 2: Namespace to store the cache on <NAMESPACE>
|
||||||
* 3: Cache uid <STRING>
|
* 3: Cache uid <STRING>
|
||||||
* 4: Max duration of the cache <NUMBER>
|
* 4: Max duration of the cache <NUMBER>
|
||||||
* 5: Event that clears the cache (default: nil) <STRING>
|
* 5: Events that clear the cache (default: nil) <STRING or ARRAY of STRING>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* Result of the function <ANY>
|
* Result of the function <ANY>
|
||||||
@ -20,41 +20,46 @@
|
|||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params ["_params", "_function", "_namespace", "_uid", "_duration", "_event"];
|
params ["_params", "_function", "_namespace", "_uid", "_duration", "_events"];
|
||||||
|
|
||||||
if ((_namespace getVariable [_uid, [-99999]]) select 0 < diag_tickTime) then {
|
if ((_namespace getVariable [_uid, [-99999]]) select 0 < diag_tickTime) then {
|
||||||
_namespace setVariable [_uid, [diag_tickTime + _duration, _params call _function]];
|
_namespace setVariable [_uid, [diag_tickTime + _duration, _params call _function]];
|
||||||
|
|
||||||
// Does the cache need to be cleared on an event?
|
// Does the cache need to be cleared on an event?
|
||||||
if (!isNil "_event") then {
|
if (!isNil "_events") then {
|
||||||
private _varName = format [QGVAR(clearCache_%1), _event];
|
if (_events isEqualType "") then {
|
||||||
private _cacheList = missionNamespace getVariable _varName;
|
_events = [_events];
|
||||||
|
|
||||||
// If there was no EH to clear these caches, add one
|
|
||||||
if (isNil "_cacheList") then {
|
|
||||||
_cacheList = [];
|
|
||||||
missionNamespace setVariable [_varName, _cacheList];
|
|
||||||
|
|
||||||
[_event, {
|
|
||||||
#ifdef DEBUG_MODE_FULL
|
|
||||||
INFO_1("Clear cached variables on event: %1",_eventName);
|
|
||||||
#endif
|
|
||||||
// Get the list of caches to clear
|
|
||||||
//IGNORE_PRIVATE_WARNING ["_eventName"];
|
|
||||||
// _eventName is defined on the function that calls the event
|
|
||||||
private _varName = format [QGVAR(clearCache_%1), _eventName];
|
|
||||||
private _cacheList = missionNamespace getVariable [_varName, []];
|
|
||||||
// Erase all the cached results
|
|
||||||
{
|
|
||||||
_x call FUNC(eraseCache);
|
|
||||||
} forEach _cacheList;
|
|
||||||
// Empty the list
|
|
||||||
missionNamespace setVariable [_varName, []];
|
|
||||||
}] call CBA_fnc_addEventHandler;
|
|
||||||
};
|
};
|
||||||
|
{
|
||||||
|
private _event = _x;
|
||||||
|
private _varName = format [QGVAR(clearCache_%1), _event];
|
||||||
|
private _cacheList = missionNamespace getVariable _varName;
|
||||||
|
|
||||||
// Add this cache to the list of the event
|
// If there was no EH to clear these caches, add one
|
||||||
_cacheList pushBack [_namespace, _uid];
|
if (isNil "_cacheList") then {
|
||||||
|
_cacheList = [];
|
||||||
|
missionNamespace setVariable [_varName, _cacheList];
|
||||||
|
|
||||||
|
[_event, {
|
||||||
|
#ifdef DEBUG_MODE_FULL
|
||||||
|
INFO_1("Clear cached variables on event: %1",_eventName);
|
||||||
|
#endif
|
||||||
|
// Get the list of caches to clear
|
||||||
|
//IGNORE_PRIVATE_WARNING ["_eventName"];
|
||||||
|
// _eventName is defined on the function that calls the event
|
||||||
|
private _varName = format [QGVAR(clearCache_%1), _eventName];
|
||||||
|
private _cacheList = missionNamespace getVariable [_varName, []];
|
||||||
|
// Erase all the cached results
|
||||||
|
{
|
||||||
|
_x call FUNC(eraseCache);
|
||||||
|
} forEach _cacheList;
|
||||||
|
// Empty the list
|
||||||
|
missionNamespace setVariable [_varName, []];
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
};
|
||||||
|
// Add this cache to the list of the event
|
||||||
|
_cacheList pushBack [_namespace, _uid];
|
||||||
|
} forEach _events;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
|
@ -95,7 +95,7 @@ if (_state) then {
|
|||||||
// Check if the necessary keys were pressed for a keybind
|
// Check if the necessary keys were pressed for a keybind
|
||||||
_return = _comboDikPressed &&
|
_return = _comboDikPressed &&
|
||||||
{_mainDevice == "KEYBOARD"} &&
|
{_mainDevice == "KEYBOARD"} &&
|
||||||
{((GVAR(keyboardInputMain) getOrDefault [_mainDik, [false, 0]]) select 1) > ([0, 1] select _isDoubleTap)}; // check how many times the main key was pressed
|
{((GVAR(keyboardInputMain) getOrDefault [_mainDik, [false, 0]]) select 1) > (parseNumber _isDoubleTap)}; // check how many times the main key was pressed
|
||||||
|
|
||||||
// Keybind was detected
|
// Keybind was detected
|
||||||
if (_return) exitWith {
|
if (_return) exitWith {
|
||||||
|
@ -63,6 +63,7 @@ _affected = _affected - [ACE_player];
|
|||||||
if (_flashReactionDebounce < CBA_missionTime) then {
|
if (_flashReactionDebounce < CBA_missionTime) then {
|
||||||
// Not used interally but could be useful for other mods
|
// Not used interally but could be useful for other mods
|
||||||
_unit setVariable [QGVAR(flashStrength), _strength, true];
|
_unit setVariable [QGVAR(flashStrength), _strength, true];
|
||||||
|
[QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent;
|
||||||
{
|
{
|
||||||
_unit setSkill [_x, (_unit skill _x) / 50];
|
_unit setSkill [_x, (_unit skill _x) / 50];
|
||||||
} forEach SUBSKILLS;
|
} forEach SUBSKILLS;
|
||||||
@ -162,5 +163,7 @@ if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then {
|
|||||||
private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true];
|
private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true];
|
||||||
private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1];
|
private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1];
|
||||||
ACE_player setDir (getDir ACE_player + _flinch);
|
ACE_player setDir (getDir ACE_player + _flinch);
|
||||||
|
|
||||||
|
[QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent;
|
||||||
};
|
};
|
||||||
true
|
true
|
||||||
|
@ -26,17 +26,30 @@ PREP_RECOMPILE_END;
|
|||||||
}, _this] call CBA_fnc_execNextFrame;
|
}, _this] call CBA_fnc_execNextFrame;
|
||||||
}] call CBA_fnc_addClassEventHandler;
|
}] call CBA_fnc_addClassEventHandler;
|
||||||
|
|
||||||
|
[QEGVAR(arsenal,loadoutVerified), {
|
||||||
|
params ["_loadout", "_extendedInfo"];
|
||||||
|
private _gunbagInfo = _extendedInfo getOrDefault [QGVAR(gunbagWeapon), []];
|
||||||
|
if (_gunbagInfo isEqualTo []) exitWith {};
|
||||||
|
|
||||||
|
private _weapon = (_gunbagInfo select 0) call EFUNC(arsenal,baseWeapon);
|
||||||
|
if !(_weapon in EGVAR(arsenal,virtualItemsFlat)) exitWith {
|
||||||
|
INFO_1("removing [%1] from loadout",_gunbagInfo);
|
||||||
|
_extendedInfo deleteAt QGVAR(gunbagWeapon);
|
||||||
|
};
|
||||||
|
{
|
||||||
|
private _class = _x param [0, ""];
|
||||||
|
private _defaultValue = ["", []] select {_x isEqualType []};
|
||||||
|
if (_class != "" && {!(_class in EGVAR(arsenal,virtualItemsFlat))}) then {
|
||||||
|
INFO_1("removing [%1] from loadout",_x);
|
||||||
|
_gunbagInfo set [_forEachIndex + 1, _defaultValue];
|
||||||
|
};
|
||||||
|
} forEach (_gunbagInfo select [1]); // weapon was verified above
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
["CBA_loadoutSet", {
|
["CBA_loadoutSet", {
|
||||||
params ["_unit", "_loadout", "_extendedInfo"];
|
params ["_unit", "_loadout", "_extendedInfo"];
|
||||||
private _gunbagWeapon = _extendedInfo getOrDefault [QGVAR(gunbagWeapon), []];
|
private _gunbagWeapon = _extendedInfo getOrDefault [QGVAR(gunbagWeapon), []];
|
||||||
if (_gunbagWeapon isNotEqualTo []) then {
|
if (_gunbagWeapon isNotEqualTo []) then {
|
||||||
if (!isNil QEGVAR(arsenal,virtualItemsFlatAll)) then {
|
|
||||||
private _weapon = (_gunbagWeapon select 0) call EFUNC(arsenal,baseWeapon);
|
|
||||||
if !(_weapon in EGVAR(arsenal,virtualItemsFlatAll)) then {
|
|
||||||
INFO_1("removing [%1] from loadout",_gunbagWeapon);
|
|
||||||
_gunbagWeapon = [];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
(backpackContainer _unit) setVariable [QGVAR(gunbagWeapon), _gunbagWeapon, true];
|
(backpackContainer _unit) setVariable [QGVAR(gunbagWeapon), _gunbagWeapon, true];
|
||||||
};
|
};
|
||||||
}] call CBA_fnc_addEventHandler;
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
@ -21,10 +21,6 @@ uiNamespace setVariable [QGVAR(backpackKeyCache), compileFinal createHashMapFrom
|
|||||||
if (_picture select [0, 1] == "\") then {
|
if (_picture select [0, 1] == "\") then {
|
||||||
_picture = _picture select [1];
|
_picture = _picture select [1];
|
||||||
};
|
};
|
||||||
if (count _picture > 0 && !(_picture regexMatch ".*?\.paa")) then { // handle missing file extension
|
|
||||||
if (!fileExists (_picture + ".paa")) exitWith {};
|
|
||||||
_picture = _picture + ".paa";
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle missing file extension, as inventory returns path with extension
|
// Handle missing file extension, as inventory returns path with extension
|
||||||
if (count _picture > 0 && !(_picture regexMatch ".*?\.paa")) then {
|
if (count _picture > 0 && !(_picture regexMatch ".*?\.paa")) then {
|
||||||
|
@ -53,7 +53,8 @@
|
|||||||
#define BLOOD_VOLUME_CLASS_2_HEMORRHAGE 5.100 // lost more than 15% blood, Class II Hemorrhage
|
#define BLOOD_VOLUME_CLASS_2_HEMORRHAGE 5.100 // lost more than 15% blood, Class II Hemorrhage
|
||||||
#define BLOOD_VOLUME_CLASS_3_HEMORRHAGE 4.200 // lost more than 30% blood, Class III Hemorrhage
|
#define BLOOD_VOLUME_CLASS_3_HEMORRHAGE 4.200 // lost more than 30% blood, Class III Hemorrhage
|
||||||
#define BLOOD_VOLUME_CLASS_4_HEMORRHAGE 3.600 // lost more than 40% blood, Class IV Hemorrhage
|
#define BLOOD_VOLUME_CLASS_4_HEMORRHAGE 3.600 // lost more than 40% blood, Class IV Hemorrhage
|
||||||
#define BLOOD_VOLUME_FATAL 3.0 // Lost more than 50% blood, Unrecoverable
|
// Lost more than 50% blood, Unrecoverable
|
||||||
|
#define BLOOD_VOLUME_FATAL 3.0
|
||||||
|
|
||||||
// Minimum blood volume, in liters, for a patient to have the chance to wake up
|
// Minimum blood volume, in liters, for a patient to have the chance to wake up
|
||||||
#define MINIMUM_BLOOD_FOR_STABLE_VITALS EGVAR(medical,const_stableVitalsBloodThreshold)
|
#define MINIMUM_BLOOD_FOR_STABLE_VITALS EGVAR(medical,const_stableVitalsBloodThreshold)
|
||||||
|
@ -8,4 +8,7 @@ PREP_RECOMPILE_END;
|
|||||||
|
|
||||||
#include "initSettings.inc.sqf"
|
#include "initSettings.inc.sqf"
|
||||||
|
|
||||||
|
// #9781 - register effects layer ASAP
|
||||||
|
QGVAR(display) cutText ["", "PLAIN"];
|
||||||
|
|
||||||
ADDON = true;
|
ADDON = true;
|
||||||
|
@ -48,10 +48,9 @@ if (GVAR(fogScaling) > 0) then {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note: Using BIS_fnc_rscLayer because of bug with string syntax - https://feedback.bistudio.com/T120768
|
QGVAR(display) cutText ["", "PLAIN"]; // Cleanup Old Display
|
||||||
(QGVAR(display) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; // Cleanup Old Display
|
|
||||||
if (_activated) then { // Create New Display
|
if (_activated) then { // Create New Display
|
||||||
(QGVAR(display) call BIS_fnc_rscLayer) cutRsc [QGVAR(title), "PLAIN", 0, false, false]; // draw under HUD
|
QGVAR(display) cutRsc [QGVAR(title), "PLAIN", 0, false, false]; // draw under HUD
|
||||||
};
|
};
|
||||||
|
|
||||||
// Cleanup Old PP Effects
|
// Cleanup Old PP Effects
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#define TO_COMPARTMENT_STRING(var) if !(var isEqualType "") then {var = format [ARR_2("Compartment%1",var)]}
|
#define TO_COMPARTMENT_STRING(var) if !(var isEqualType "") then {var = format [ARR_2("Compartment%1",var)]}
|
||||||
|
|
||||||
// if unit isn't moved to new seat in TAKEN_SEAT_TIMEOUT, we move him back to his seat
|
// if unit isn't moved to new seat in TAKEN_SEAT_TIMEOUT, we move him back to his seat
|
||||||
|
#pragma hemtt suppress pw3_padded_arg file
|
||||||
#define WAIT_IN_OR_MOVE_BACK \
|
#define WAIT_IN_OR_MOVE_BACK \
|
||||||
[ARR_5( \
|
[ARR_5( \
|
||||||
{!isNull objectParent (_this select 0)}, \
|
{!isNull objectParent (_this select 0)}, \
|
||||||
|
@ -63,28 +63,28 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r
|
|||||||
|
|
||||||
- Update the `Atmsphr` column and `Done`. Requirement: [Kestrel 4500]({{ site.baseurl }}/wiki/feature/kestrel4500.html).
|
- Update the `Atmsphr` column and `Done`. Requirement: [Kestrel 4500]({{ site.baseurl }}/wiki/feature/kestrel4500.html).
|
||||||
- *Check the new `Muzzle Velocity` in the `Gun` column.*
|
- *Check the new `Muzzle Velocity` in the `Gun` column.*
|
||||||
- Update the `Target` column and `Done`. Requirement: [wind arrow]({{ site.baseurl }}/wiki/feature/weather.html), [Protractor]({{ site.baseurl }}/wiki/feature/advanced-ballistics#22-protractor.html), [Map Tools]({{ site.baseurl }}/wiki/feature/maptools.html). For advanced tools: [ACE3 Equipment]({{ site.baseurl }}/wiki/feature.html).
|
- Update the `Target` column and `Done`. Requirement: [Wind arrow]({{ site.baseurl }}/wiki/feature/weather.html), [Protractor]({{ site.baseurl }}/wiki/feature/advanced-ballistics#22-protractor), [Map Tools]({{ site.baseurl }}/wiki/feature/maptools.html). For advanced tools: [ACE3 Equipment]({{ site.baseurl }}/wiki/feature.html).
|
||||||
- `Latitude`: *[ACE3 Github]({{ site.ace.githubUrl }}/blob/master/addons/common/functions/fnc_getMapData.sqf) or Eden Editor's Extended Debug Console: Watch:* `ace_common_maplatitude`.
|
- `Latitude`: *[ACE3 Github]({{ site.ace.githubUrl }}/blob/master/addons/common/functions/fnc_getMapData.sqf) or Eden Editor's Extended Debug Console: Watch:* `ace_common_maplatitude`.
|
||||||
- `Dir of Fire (deg from N)`: *The value is therefore given as the direction of the barrel axis from true north.* **[Horus manual p.14]**
|
- `Dir of Fire (deg from N)`: *The value is therefore given as the direction of the barrel axis from true north.* [Horus manual p.14]
|
||||||
- `Wind speed (m/s)`: *Two wind speed values (low and high) may be entered on the target screen,[...] Lead/Wind2 button on the screen.* **[Horus manual p.32]**
|
- `Wind speed (m/s)`: *Two wind speed values (low and high) may be entered on the target screen,[...] Lead/Wind2 button on the screen.* [Horus manual p.32]
|
||||||
- *Wind takes into account geographic location, season, time of day, obstacles, altitude and surface roughness: [Wind Profile](https://wind-data.ch/tools/profile.php?lng=en).*
|
- Wind takes into account geographic location, season, time of day, obstacles, altitude and surface roughness: [Wind Profile](https://wind-data.ch/tools/profile.php?lng=en).
|
||||||
- `Wind Direction (clock)`: *Wind Direction is expressed in clock points.[...], wind is always described in terms of where it is coming from.* **[Horus manual p.16]**
|
- `Wind Direction (clock)`: *Wind Direction is expressed in clock points.[...], wind is always described in terms of where it is coming from.* [Horus manual p.16]
|
||||||
- `Inclination Angle`: *The degrees field is marked with a “d” and the cosine field with a “c”.* **[Horus manual p.33]**
|
- `Inclination Angle`: *The degrees field is marked with a “d” and the cosine field with a “c”.* [Horus manual p.33]
|
||||||
- `Target Speed`: *Target Speed Assist* **[Horus manual p.21]**
|
- `Target Speed`: *Target Speed Assist* [Horus manual p.21]
|
||||||
- `Target Range (meters)`: *Parameter Limits minimum and maximum values: 25 - 3700 meters.* **[Horus manual p.17]**
|
- `Target Range (meters)`: *Parameter Limits minimum and maximum values: 25 - 3700 meters.* [Horus manual p.17]
|
||||||
- Apply vertical (Page Up and Down keys as default) and horizontal (Left Ctrl + Page Up and Down keys as default) elevations to the [scope]({{ site.baseurl }}/wiki/feature/scopes.html).
|
- Apply vertical (Page Up and Down keys as default) and horizontal (Left Ctrl + Page Up and Down keys as default) elevations to the [scope]({{ site.baseurl }}/wiki/feature/scopes.html).
|
||||||
- Hold Breath (Left Shift as default) and Fire (Prim. Mouse. Btn. as default).
|
- Hold Breath (Left Shift as default) and Fire (Prim. Mouse. Btn. as default).
|
||||||
|
|
||||||
### 3.3 Example with Truing tool
|
### 3.3 Example with Truing tool
|
||||||
|
|
||||||
> This process is called “Truing Drop”, or simply “Truing”. It involves taking 2 or 3 real flight data points (finding bullet drop at 2 or 3 places along its flight) and feeding it into the calculation parameters. **[Horus manual p.23]**
|
> This process is called “Truing Drop”, or simply “Truing”. It involves taking 2 or 3 real flight data points (finding bullet drop at 2 or 3 places along its flight) and feeding it into the calculation parameters. [Horus manual p.23]
|
||||||
|
|
||||||
> The Truing Drop function is opened from ATrag’s main screen by selecting “Options” [...], then selecting “Truing Drop” from the menu that appears. **[Horus manual p.23]**
|
> The Truing Drop function is opened from ATrag’s main screen by selecting “Options” [...], then selecting “Truing Drop” from the menu that appears. [Horus manual p.23]
|
||||||
|
|
||||||
> With C1, you can also insert the new BC into the C1 table (with the target range value), or you can replace the C1 table with the following values:
|
> With C1, you can also insert the new BC into the C1 table (with the target range value), or you can replace the C1 table with the following values:
|
||||||
> 1. first entry: Zero Range, original C1.
|
> 1. first entry: Zero Range, original C1.
|
||||||
> 2. second entry: range at 75% of distance between transonic start and subsonic start, with original C1.
|
> 2. second entry: range at 75% of distance between transonic start and subsonic start, with original C1.
|
||||||
> 3. third entry: range 200 (y/m) beyond subsonic start, with new calculated C1. **[Horus manual p.24]**
|
> 3. third entry: range 200 (y/m) beyond subsonic start, with new calculated C1. [Horus manual p.24]
|
||||||
|
|
||||||
- Basic example with ammunition 7.62x51mm G7 ballistic coefficient.
|
- Basic example with ammunition 7.62x51mm G7 ballistic coefficient.
|
||||||
- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`.
|
- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`.
|
||||||
@ -149,13 +149,13 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r
|
|||||||
|
|
||||||
### 3.6 Connecting AtragMx with Vector 21 and DAGR
|
### 3.6 Connecting AtragMx with Vector 21 and DAGR
|
||||||
|
|
||||||
- Requirement: [Vector]({{ site.baseurl }}/wiki/framework/vector.html) and [DAGR]({{ site.baseurl }}/wiki/framework/dagr.html).
|
- Requirement: [Vector]({{ site.baseurl }}/wiki/feature/vector.html) and [DAGR]({{ site.baseurl }}/wiki/feature/dagr.html).
|
||||||
- Open the self interaction menu <kbd>Ctrl</kbd> + <kbd>⊞ Win</kbd>.
|
- Open the self interaction menu <kbd>Ctrl</kbd> + <kbd>⊞ Win</kbd>.
|
||||||
- Select `Equipment`.
|
- Select `Equipment`.
|
||||||
- Select `Configure DAGR` and `CONNECT TO` (DOWN and HELP/SEL) `Vector 21`(HELP/SEL).
|
- Select `Configure DAGR` and `CONNECT TO` (DOWN and HELP/SEL) `Vector 21`(HELP/SEL).
|
||||||
- Equip and use the Vector (B key as default).
|
- Equip and use the Vector (B key as default).
|
||||||
- Check target's [slope distance and azimuth]({{ site.baseurl }}/wiki/feature/vector#23-slope-distance-and-azimuth.html) (hold both R and Tab keys as default).
|
- Check target's [slope distance and azimuth]({{ site.baseurl }}/wiki/feature/vector#23-slope-distance-and-azimuth) (hold both R and Tab keys as default).
|
||||||
- Open the [AtragMx properly configured before]({{ site.baseurl }}/wiki/feature/atragmx#32-example-with-m14-and-default-762mm-20rnd-mag.html) according to current rifle and ammunition.
|
- Open the [AtragMx properly configured before](#32-example-with-m14-and-default-762mm-20rnd-mag) according to current rifle and ammunition.
|
||||||
- Open the `Target` column: `Dir of Fire (deg from N)`, `Inclination Angle` and `Target Range (meters)` updated with Vector's values.
|
- Open the `Target` column: `Dir of Fire (deg from N)`, `Inclination Angle` and `Target Range (meters)` updated with Vector's values.
|
||||||
|
|
||||||
### 3.7 Adding AtragMx Presets
|
### 3.7 Adding AtragMx Presets
|
||||||
@ -205,13 +205,13 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r
|
|||||||
**In position:**
|
**In position:**
|
||||||
|
|
||||||
- **Do not update the `Atmsphr` column.** Default ballistic doesn't take into account temperature, pressure and humidity.
|
- **Do not update the `Atmsphr` column.** Default ballistic doesn't take into account temperature, pressure and humidity.
|
||||||
- Update the `Target` column and `Done`. Requirement: [wind arrow]({{ site.baseurl }}/wiki/feature/weather.html), [Protractor]({{ site.baseurl }}/wiki/feature/advanced-ballistics#22-protractor.html), [Map Tools]({{ site.baseurl }}/wiki/feature/maptools.html). For advanced tools: [ACE3 Equipment]({{ site.baseurl }}/wiki/feature.html).
|
- Update the `Target` column and `Done`. Requirement: [Wind arrow]({{ site.baseurl }}/wiki/feature/weather.html), [Protractor]({{ site.baseurl }}/wiki/feature/advanced-ballistics#22-protractor), [Map Tools]({{ site.baseurl }}/wiki/feature/maptools.html). For advanced tools: [ACE3 Equipment]({{ site.baseurl }}/wiki/feature.html).
|
||||||
- `Wind speed (m/s)`: *Two wind speed values (low and high) may be entered on the target screen,[...] Lead/Wind2 button on the screen.* **[Horus manual p.32]**
|
- `Wind speed (m/s)`: *Two wind speed values (low and high) may be entered on the target screen,[...] Lead/Wind2 button on the screen.* [Horus manual p.32]
|
||||||
- *Wind takes into account geographic location, season, time of day and obstacles.*
|
- Wind takes into account geographic location, season, time of day and obstacles.
|
||||||
- `Wind Direction (clock)`: *Wind Direction is expressed in clock points.[...], wind is always described in terms of where it is coming from.* **[Horus manual p.16]**
|
- `Wind Direction (clock)`: *Wind Direction is expressed in clock points.[...], wind is always described in terms of where it is coming from.* [Horus manual p.16]
|
||||||
- `Inclination Angle`: *The degrees field is marked with a “d” and the cosine field with a “c”.* **[Horus manual p.33]**
|
- `Inclination Angle`: *The degrees field is marked with a “d” and the cosine field with a “c”.* [Horus manual p.33]
|
||||||
- `Target Speed`: *Target Speed Assist* **[Horus manual p.21]**
|
- `Target Speed`: *Target Speed Assist* [Horus manual p.21]
|
||||||
- `Target Range (meters)`: *Parameter Limits minimum and maximum values: 25 - 3700 meters.* **[Horus manual p.17]**
|
- `Target Range (meters)`: *Parameter Limits minimum and maximum values: 25 - 3700 meters.* [Horus manual p.17]
|
||||||
- Apply vertical (Page Up and Down keys as default) and horizontal (Left Ctrl + Page Up and Down keys as default) elevations to the [scope]({{ site.baseurl }}/wiki/feature/scopes.html).
|
- Apply vertical (Page Up and Down keys as default) and horizontal (Left Ctrl + Page Up and Down keys as default) elevations to the [scope]({{ site.baseurl }}/wiki/feature/scopes.html).
|
||||||
- Hold Breath (Left Shift as default) and Fire (Prim. Mouse. Btn. as default).
|
- Hold Breath (Left Shift as default) and Fire (Prim. Mouse. Btn. as default).
|
||||||
|
|
||||||
|
@ -511,6 +511,7 @@ All are local.
|
|||||||
| ace_arsenal_loadoutsDisplayClosed | None | 3.12.3 |
|
| ace_arsenal_loadoutsDisplayClosed | None | 3.12.3 |
|
||||||
| ace_arsenal_loadoutsTabChanged | loadouts screen display (DISPLAY), tab control (CONTROL) | 3.12.3 |
|
| ace_arsenal_loadoutsTabChanged | loadouts screen display (DISPLAY), tab control (CONTROL) | 3.12.3 |
|
||||||
| ace_arsenal_loadoutsListFilled | loadouts screen display (DISPLAY), tab control (CONTROL) | 3.12.3 |
|
| ace_arsenal_loadoutsListFilled | loadouts screen display (DISPLAY), tab control (CONTROL) | 3.12.3 |
|
||||||
|
| ace_arsenal_loadoutVerified | loadout data (ARRAY), loadout CBA extended data (HASHMAP) | 3.17.0 |
|
||||||
| ace_arsenal_weaponItemChanged | weapon classname (STRING), item classname (STRING), item index (NUMBER, 0-5: muzzle, side, optic, bipod, magazine, underbarrel) | 3.16.0 |
|
| ace_arsenal_weaponItemChanged | weapon classname (STRING), item classname (STRING), item index (NUMBER, 0-5: muzzle, side, optic, bipod, magazine, underbarrel) | 3.16.0 |
|
||||||
|
|
||||||
## 9. Custom sub item categories
|
## 9. Custom sub item categories
|
||||||
|
@ -68,3 +68,13 @@ The average amount of time in seconds, after `explosionTime` has passed, between
|
|||||||
### 2.4 ace_grenades_flashbangIntervalMaxDeviation
|
### 2.4 ace_grenades_flashbangIntervalMaxDeviation
|
||||||
|
|
||||||
The amount of randomness in the fuse time.
|
The amount of randomness in the fuse time.
|
||||||
|
|
||||||
|
## 3. Events
|
||||||
|
|
||||||
|
### 3.1 Listenable
|
||||||
|
|
||||||
|
Event Name | Description | Passed Parameter(s) | Locality
|
||||||
|
---------- | ----------- | ------------------- | --------
|
||||||
|
`ace_flashbangExploded` | A flashbang exploded | `[_grenadePosASL]` | Global
|
||||||
|
`ace_grenades_flashbangedAI` | A local AI was affected by a flashbang | `[_unit, _strength, _grenadePosASL]` | Local
|
||||||
|
`ace_grenades_flashbangedPlayer` | The local player was affected by a flashbang | `[_strength, _grenadePosASL]` | Local
|
||||||
|
Loading…
Reference in New Issue
Block a user