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);
|
||||
drawSideArrows = 1;
|
||||
disableOverflow = 1;
|
||||
columns[] = {0.05, 0.15, 0.85};
|
||||
columns[] = {0.05, 0.15, 0.83, 0.87};
|
||||
};
|
||||
class ArrowLeft: ctrlButton {
|
||||
idc = IDC_ATTRIBUTE_LIST_LEFT;
|
||||
|
@ -70,7 +70,7 @@ GVAR(lastSortDirectionRight) = DESCENDING;
|
||||
if (!isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then {
|
||||
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"];
|
||||
|
||||
private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName];
|
||||
@ -81,10 +81,10 @@ GVAR(lastSortDirectionRight) = DESCENDING;
|
||||
_contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName];
|
||||
|
||||
// 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]];
|
||||
} else {
|
||||
if (_unavailableItemsAmount > 0) then {
|
||||
if (_unavailableItemsList isNotEqualTo []) then {
|
||||
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]];
|
||||
};
|
||||
};
|
||||
|
@ -48,4 +48,48 @@ call FUNC(compileStats);
|
||||
// Setup Tools tab
|
||||
[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;
|
||||
|
@ -270,6 +270,7 @@
|
||||
#define IDX_VIRT_UNIQUE_UNKNOWN_ITEMS 25
|
||||
|
||||
// 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_SECONDARY_WEAPON 1
|
||||
#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, 8], getText (_cfgWeapons >> _loadout select IDX_LOADOUT_HEADGEAR >> "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 "..\defines.hpp"
|
||||
/*
|
||||
* Author: johnb43
|
||||
* Adds custom action buttons.
|
||||
|
@ -9,6 +9,7 @@
|
||||
* 1: Classname <STRING>
|
||||
* 2: Panel control <CONTROL>
|
||||
* 3: Name of the picture entry in that Cfg class <STRING> (default: "picture")
|
||||
* 4: Config root <NUMBER> (default: 0 -> configFile)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -19,7 +20,7 @@
|
||||
* 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))};
|
||||
if (_skip) then {
|
||||
@ -42,9 +43,9 @@ if (_skip) then {
|
||||
if (_skip) exitWith {};
|
||||
|
||||
// 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
|
||||
private _configPath = configFile >> _configCategory >> _className;
|
||||
private _configPath = ([configFile, campaignConfigFile, missionConfigFile] select _configRoot) >> _configCategory >> _className;
|
||||
private _dlcName = _configPath call EFUNC(common,getAddon);
|
||||
|
||||
// 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 _cfgVehicles = configFile >> "CfgVehicles";
|
||||
private _cfgGlasses = configFile >> "CfgGlasses";
|
||||
private _dlcName = "";
|
||||
|
||||
// Exit with current items (no specific category)
|
||||
if (_category == IDX_CAT_ALL) exitWith {
|
||||
@ -73,6 +74,12 @@ if (_category == IDX_CAT_ALL) exitWith {
|
||||
_listbox lnbSetData [[_index, 1], _x];
|
||||
_listbox lnbSetPicture [[_index, 0], getText (_config >> "picture")];
|
||||
_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;
|
||||
|
||||
@ -130,12 +137,20 @@ private _config = _cfgClass;
|
||||
_alpha = 0.5;
|
||||
};
|
||||
|
||||
_index = _listbox lnbAddRow ["", _displayName, _symbol];
|
||||
_index = _listbox lnbAddRow ["", _displayName, "", _symbol];
|
||||
_listbox lnbSetData [[_index, 1], _x];
|
||||
_listbox lnbSetPicture [[_index, 0], getText (_config >> _x >> "picture")];
|
||||
_listbox lnbSetTooltip [[_index, 0], _x];
|
||||
_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);
|
||||
|
||||
|
@ -35,9 +35,10 @@ if (_addItem && {_itemIndex == -1}) exitWith {
|
||||
_attributeItems pushBack _itemClassname;
|
||||
|
||||
// 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, 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
|
||||
@ -45,7 +46,8 @@ if (!_addItem && {_itemIndex != -1}) exitWith {
|
||||
_attributeItems deleteAt _itemIndex;
|
||||
|
||||
// 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, 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 "..\defines.hpp"
|
||||
/*
|
||||
* Author: Brett Mayson
|
||||
* Create the internal actions arrays when needed for the first time.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "..\script_component.hpp"
|
||||
#include "..\defines.hpp"
|
||||
/*
|
||||
* Author: Alganthe, johnb43
|
||||
* Author: Alganthe, johnb43, LinkIsGrim
|
||||
* Fills left panel.
|
||||
*
|
||||
* Arguments:
|
||||
@ -17,21 +17,28 @@
|
||||
|
||||
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
|
||||
if (!isNil QGVAR(currentLeftPanel)) then {
|
||||
private _previousCtrlBackground = _display displayCtrl (GVAR(currentLeftPanel) - 1);
|
||||
_previousCtrlBackground ctrlSetFade 1;
|
||||
_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
|
||||
private _ctrlIDC = ctrlIDC _control;
|
||||
private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1);
|
||||
_ctrlBackground ctrlSetFade 0;
|
||||
_ctrlBackground ctrlCommit ([0, FADE_DELAY] select _animate);
|
||||
|
||||
private _ctrlPanel = _display displayCtrl IDC_leftTabContent;
|
||||
|
||||
// Force a "refresh" animation of the panel
|
||||
if (_animate) then {
|
||||
_ctrlPanel ctrlSetFade 1;
|
||||
@ -41,212 +48,82 @@ if (_animate) then {
|
||||
};
|
||||
|
||||
_ctrlPanel lbSetCurSel -1;
|
||||
// Purge old data
|
||||
lbClear _ctrlPanel;
|
||||
|
||||
// Handle icons and filling
|
||||
private _selectedItem = switch (true) do {
|
||||
// Primary weapons, secondary weapons, handgun weapons
|
||||
case (_ctrlIDC in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]): {
|
||||
// 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 {""};
|
||||
};
|
||||
};
|
||||
// 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];
|
||||
};
|
||||
|
||||
// When switching tabs, clear searchbox
|
||||
if (GVAR(currentLeftPanel) != _ctrlIDC) then {
|
||||
(_display displayCtrl IDC_leftSearchbar) ctrlSetText "";
|
||||
(_display displayCtrl IDC_rightSearchbar) ctrlSetText "";
|
||||
// Don't reset the current right panel for weapons, binos and containers
|
||||
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 {
|
||||
GVAR(currentRightPanel) = nil;
|
||||
};
|
||||
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
|
||||
GVAR(currentLeftPanel) = _ctrlIDC;
|
||||
[QGVAR(leftPanelFilled), [_display, _ctrlIDC, GVAR(currentRightPanel)]] call CBA_fnc_localEvent;
|
||||
|
||||
// Sort
|
||||
|
@ -1,12 +1,16 @@
|
||||
#include "..\script_component.hpp"
|
||||
#include "..\defines.hpp"
|
||||
/*
|
||||
* Author: Alganthe, johnb43
|
||||
* Fill loadouts list.
|
||||
* Author: Alganthe, johnb43, LinkIsGrim
|
||||
* 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:
|
||||
* 0: Loadouts display <DISPLAY>
|
||||
* 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:
|
||||
* None
|
||||
@ -14,29 +18,46 @@
|
||||
* 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;
|
||||
if (_currentFrame == 0) then {
|
||||
(_display displayCtrl IDC_textEditBox) ctrlSetText "";
|
||||
|
||||
// Force a "refresh" animation of the panel
|
||||
_contentPanelCtrl ctrlSetFade 1;
|
||||
_contentPanelCtrl ctrlCommit 0;
|
||||
_contentPanelCtrl ctrlSetFade 0;
|
||||
_contentPanelCtrl ctrlCommit FADE_DELAY;
|
||||
// Force a "refresh" animation of the panel
|
||||
_contentPanelCtrl ctrlSetFade 1;
|
||||
_contentPanelCtrl ctrlCommit 0;
|
||||
_contentPanelCtrl ctrlSetFade 0;
|
||||
_contentPanelCtrl ctrlCommit FADE_DELAY;
|
||||
|
||||
_contentPanelCtrl lnbSetCurSelRow -1;
|
||||
lnbClear _contentPanelCtrl;
|
||||
_contentPanelCtrl lnbSetCurSelRow -1;
|
||||
lnbClear _contentPanelCtrl;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
||||
private _loadoutNameAndTab = "";
|
||||
private _loadoutCachedInfo = "";
|
||||
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
|
||||
{
|
||||
@ -50,10 +71,10 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
||||
_loadoutCachedInfo = [_loadoutData] call FUNC(verifyLoadout);
|
||||
_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)
|
||||
if (GVAR(EnableRPTLog) && {(_nullItemsAmount > 0) || {_unavailableItemsAmount > 0}}) then {
|
||||
if (GVAR(EnableRPTLog) && {(_nullItemsList isNotEqualTo []) || {_unavailableItemsList isNotEqualTo []}}) then {
|
||||
private _printComponent = "ACE_Arsenal - Loadout:";
|
||||
private _printNullItemsList = ["Missing items:", str _nullItemsList] 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];
|
||||
};
|
||||
|
||||
_loadoutCachedInfo params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"];
|
||||
_extendedLoadout params ["_loadout"];
|
||||
_loadoutCachedInfo params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"];
|
||||
_extendedLoadout params ["_loadout"]; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove
|
||||
|
||||
_newRow = _contentPanelCtrl lnbAddRow ["", _loadoutName];
|
||||
|
||||
ADD_LOADOUTS_LIST_PICTURES
|
||||
|
||||
// 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
|
||||
} else {
|
||||
if (_unavailableItemsAmount > 0) then {
|
||||
if (_unavailableItemsList isNotEqualTo []) then {
|
||||
_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 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 {
|
||||
private _allPlayerNames = allPlayers apply {name _x};
|
||||
private _loadouts = _sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x};
|
||||
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"];
|
||||
@ -107,8 +134,8 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
||||
|
||||
[QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent;
|
||||
} else {
|
||||
([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"];
|
||||
_extendedLoadout params ["_loadout"];
|
||||
([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"];
|
||||
_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];
|
||||
_newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName];
|
||||
@ -118,17 +145,23 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
|
||||
_contentPanelCtrl lnbSetData [[_newRow, 1], _loadoutVar];
|
||||
|
||||
// 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
|
||||
} else {
|
||||
if (_unavailableItemsAmount > 0) then {
|
||||
if (_unavailableItemsList isNotEqualTo []) then {
|
||||
_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;
|
||||
|
||||
// Sort loadouts alphabetically
|
||||
|
@ -47,7 +47,7 @@ private _groups = (GVAR(actionList) select _panel) select {
|
||||
private _show = _groups isNotEqualTo [];
|
||||
private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox;
|
||||
_actionsBoxCtrl ctrlShow _show;
|
||||
_actionsBoxCtrl ctrlCommit 0.15;
|
||||
_actionsBoxCtrl ctrlCommit FADE_DELAY;
|
||||
|
||||
if (!_show) exitWith {};
|
||||
|
||||
@ -77,7 +77,6 @@ private _items = _group select 3 select {
|
||||
};
|
||||
|
||||
_actionsCurrentPageCtrl ctrlSetText (_group select 1);
|
||||
_actionsCurrentPageCtrl ctrlSetFade 0;
|
||||
_actionsCurrentPageCtrl ctrlShow true;
|
||||
_actionsCurrentPageCtrl ctrlCommit 0;
|
||||
|
||||
@ -85,36 +84,22 @@ private _activeCtrls = [];
|
||||
{
|
||||
_x params ["", "_type", "_label", "_statement"];
|
||||
|
||||
private _idc = IDC_actionsText1 + _forEachIndex * 2;
|
||||
private _actionTextCtrl = _display displayCtrl _idc;
|
||||
private _actionButtonCtrl = _display displayCtrl (_idc + 1);
|
||||
private _idc = IDC_actionsText1 + _type + _forEachIndex * 2;
|
||||
private _actionCtrl = _display displayCtrl _idc;
|
||||
|
||||
switch (_type) do {
|
||||
case ACTION_TYPE_BUTTON: {
|
||||
_actionButtonCtrl ctrlRemoveAllEventHandlers "ButtonClick";
|
||||
_actionButtonCtrl ctrlAddEventHandler ["ButtonClick", {
|
||||
_actionCtrl ctrlRemoveAllEventHandlers "ButtonClick";
|
||||
_actionCtrl ctrlAddEventHandler ["ButtonClick", {
|
||||
if (is3DEN) exitWith {[true] call FUNC(refresh)};
|
||||
[{
|
||||
[true] call FUNC(refresh);
|
||||
}] call CBA_fnc_execNextFrame;
|
||||
}];
|
||||
|
||||
if (_activeCtrls isNotEqualTo []) then {
|
||||
(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"];
|
||||
_actionButtonCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H);
|
||||
} 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;
|
||||
_actionCtrl ctrlAddEventHandler ["ButtonClick", _statement];
|
||||
_actionCtrl ctrlSetText _label;
|
||||
_actionCtrl ctrlEnable true;
|
||||
};
|
||||
case ACTION_TYPE_TEXT: {
|
||||
private _text = call _statement;
|
||||
@ -125,47 +110,35 @@ private _activeCtrls = [];
|
||||
if (_text isEqualType []) then {
|
||||
_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;
|
||||
_actionTextCtrl ctrlSetPositionH (ctrlTextHeight _actionTextCtrl);
|
||||
_actionTextCtrl ctrlSetFade 0;
|
||||
_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;
|
||||
_actionCtrl ctrlSetText _text;
|
||||
_actionCtrl ctrlSetPositionH (ctrlTextHeight _actionCtrl);
|
||||
_actionCtrl ctrlEnable false;
|
||||
};
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
private _actionCount = count _items;
|
||||
|
||||
{
|
||||
private _idc = IDC_actionsText1 + _x * 2;
|
||||
private _actionTextCtrl = _display displayCtrl _idc;
|
||||
private _actionButtonCtrl = _display displayCtrl (_idc + 1);
|
||||
private _idc = ctrlIDC _x;
|
||||
if (_idc < IDC_actionsText1 || _idc > IDC_actionsButton5) then {continue};
|
||||
|
||||
_actionTextCtrl ctrlSetFade 1;
|
||||
_actionTextCtrl ctrlCommit 0;
|
||||
_actionButtonCtrl ctrlSetFade 1;
|
||||
_actionButtonCtrl ctrlCommit 0;
|
||||
} forEach ([0, 1, 2, 3, 4] select [_actionCount, 5]);
|
||||
_x ctrlShow false;
|
||||
_x ctrlEnable false;
|
||||
_x ctrlSetPositionY 0;
|
||||
_x ctrlCommit 0;
|
||||
} forEach ((allControls _actionsBoxCtrl) select {!(_x in _activeCtrls)});
|
||||
|
||||
private _pos = ctrlPosition _actionsBoxCtrl;
|
||||
(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"];
|
||||
private _actionsBoxHeight = _lastPosY + _lastPosH + GRID_H;
|
||||
_actionsBoxCtrl ctrlSetPositionH _actionsBoxHeight;
|
||||
|
@ -19,279 +19,58 @@ private _extendedInfo = createHashMap;
|
||||
|
||||
// Check if the provided loadout is a CBA extended loadout
|
||||
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;
|
||||
};
|
||||
|
||||
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 _nullItemsAmount = 0;
|
||||
private _unavailableItemsAmount = 0;
|
||||
private _itemArray = [];
|
||||
private _nullItemsList = [];
|
||||
private _unavailableItemsList = [];
|
||||
|
||||
// Search for all items and turn them into config case; Don't touch other value types
|
||||
private _fnc_toConfigCase = {
|
||||
// Search for all items and check their availability
|
||||
private _fnc_filterLoadout = {
|
||||
_this apply {
|
||||
if (_x isEqualType "") then {
|
||||
if (_x != "") then {
|
||||
_name = _x call EFUNC(common,getConfigName);
|
||||
if (_x isEqualType "" && {_x != ""}) then {
|
||||
_name = _x call EFUNC(common,getConfigName);
|
||||
|
||||
// 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
|
||||
[_x, _name] select (_name != "");
|
||||
// If item doesn't exist in config, "" is returned
|
||||
if (_name == "") then {
|
||||
_nullItemsList pushBack _x;
|
||||
} 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 {
|
||||
// Handle arrays
|
||||
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 {
|
||||
// All other types
|
||||
// All other types and empty strings
|
||||
_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 = _loadout call _fnc_toConfigCase;
|
||||
_loadout = _loadout call _fnc_filterLoadout;
|
||||
|
||||
// Check a weapon, with its attachments and magazines, if items are available
|
||||
private _fnc_weaponCheck = {
|
||||
params ["_weaponArray", ["_index", -1]];
|
||||
// Raise event for 3rd party: mostly for handling extended info
|
||||
[QGVAR(loadoutVerified), [_loadout, _extendedInfo]] call CBA_fnc_localEvent;
|
||||
|
||||
{
|
||||
// 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]
|
||||
[[_loadout, _extendedInfo], _nullItemsList arrayIntersect _nullItemsList, _unavailableItemsList arrayIntersect _unavailableItemsList]
|
||||
|
@ -15,6 +15,3 @@
|
||||
#endif
|
||||
|
||||
#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 {
|
||||
idc = IDC_actionsText1;
|
||||
fade = 1;
|
||||
x = QUOTE(0 * GRID_W);
|
||||
y = QUOTE(5 * GRID_H);
|
||||
w = QUOTE(45 * GRID_W);
|
||||
@ -479,8 +478,6 @@ class GVAR(display) {
|
||||
};
|
||||
class actionsButton1: ctrlButton {
|
||||
idc = IDC_actionsButton1;
|
||||
onMouseEnter = QUOTE(ctrlSetFocus (_this select 0));
|
||||
fade = 1;
|
||||
text = "";
|
||||
x = QUOTE(1 * GRID_W);
|
||||
y = QUOTE(6 * GRID_H);
|
||||
|
@ -9,7 +9,7 @@
|
||||
* 2: Namespace to store the cache on <NAMESPACE>
|
||||
* 3: Cache uid <STRING>
|
||||
* 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:
|
||||
* Result of the function <ANY>
|
||||
@ -20,41 +20,46 @@
|
||||
* 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 {
|
||||
_namespace setVariable [_uid, [diag_tickTime + _duration, _params call _function]];
|
||||
|
||||
// Does the cache need to be cleared on an event?
|
||||
if (!isNil "_event") then {
|
||||
private _varName = format [QGVAR(clearCache_%1), _event];
|
||||
private _cacheList = missionNamespace getVariable _varName;
|
||||
|
||||
// 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;
|
||||
if (!isNil "_events") then {
|
||||
if (_events isEqualType "") then {
|
||||
_events = [_events];
|
||||
};
|
||||
{
|
||||
private _event = _x;
|
||||
private _varName = format [QGVAR(clearCache_%1), _event];
|
||||
private _cacheList = missionNamespace getVariable _varName;
|
||||
|
||||
// Add this cache to the list of the event
|
||||
_cacheList pushBack [_namespace, _uid];
|
||||
// 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;
|
||||
};
|
||||
// Add this cache to the list of the event
|
||||
_cacheList pushBack [_namespace, _uid];
|
||||
} forEach _events;
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
|
@ -95,7 +95,7 @@ if (_state) then {
|
||||
// Check if the necessary keys were pressed for a keybind
|
||||
_return = _comboDikPressed &&
|
||||
{_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
|
||||
if (_return) exitWith {
|
||||
|
@ -63,6 +63,7 @@ _affected = _affected - [ACE_player];
|
||||
if (_flashReactionDebounce < CBA_missionTime) then {
|
||||
// Not used interally but could be useful for other mods
|
||||
_unit setVariable [QGVAR(flashStrength), _strength, true];
|
||||
[QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent;
|
||||
{
|
||||
_unit setSkill [_x, (_unit skill _x) / 50];
|
||||
} 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 _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1];
|
||||
ACE_player setDir (getDir ACE_player + _flinch);
|
||||
|
||||
[QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent;
|
||||
};
|
||||
true
|
||||
|
@ -26,17 +26,30 @@ PREP_RECOMPILE_END;
|
||||
}, _this] call CBA_fnc_execNextFrame;
|
||||
}] 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", {
|
||||
params ["_unit", "_loadout", "_extendedInfo"];
|
||||
private _gunbagWeapon = _extendedInfo getOrDefault [QGVAR(gunbagWeapon), []];
|
||||
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];
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
@ -21,10 +21,6 @@ uiNamespace setVariable [QGVAR(backpackKeyCache), compileFinal createHashMapFrom
|
||||
if (_picture select [0, 1] == "\") then {
|
||||
_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
|
||||
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_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_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
|
||||
#define MINIMUM_BLOOD_FOR_STABLE_VITALS EGVAR(medical,const_stableVitalsBloodThreshold)
|
||||
|
@ -8,4 +8,7 @@ PREP_RECOMPILE_END;
|
||||
|
||||
#include "initSettings.inc.sqf"
|
||||
|
||||
// #9781 - register effects layer ASAP
|
||||
QGVAR(display) cutText ["", "PLAIN"];
|
||||
|
||||
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) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; // Cleanup Old Display
|
||||
QGVAR(display) cutText ["", "PLAIN"]; // Cleanup Old 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
|
||||
|
@ -29,6 +29,7 @@
|
||||
#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
|
||||
#pragma hemtt suppress pw3_padded_arg file
|
||||
#define WAIT_IN_OR_MOVE_BACK \
|
||||
[ARR_5( \
|
||||
{!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).
|
||||
- *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`.
|
||||
- `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 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]**
|
||||
- `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 Range (meters)`: *Parameter Limits minimum and maximum values: 25 - 3700 meters.* **[Horus manual p.17]**
|
||||
- `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 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]
|
||||
- `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 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).
|
||||
- Hold Breath (Left Shift as default) and Fire (Prim. Mouse. Btn. as default).
|
||||
|
||||
### 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:
|
||||
> 1. first entry: Zero Range, 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.
|
||||
- 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
|
||||
|
||||
- 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>.
|
||||
- Select `Equipment`.
|
||||
- Select `Configure DAGR` and `CONNECT TO` (DOWN and HELP/SEL) `Vector 21`(HELP/SEL).
|
||||
- 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).
|
||||
- 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.
|
||||
- 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](#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.
|
||||
|
||||
### 3.7 Adding AtragMx Presets
|
||||
@ -205,13 +205,13 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r
|
||||
**In position:**
|
||||
|
||||
- **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).
|
||||
- `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 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]**
|
||||
- `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]**
|
||||
- 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 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]
|
||||
- `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 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).
|
||||
- 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_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_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 |
|
||||
|
||||
## 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
|
||||
|
||||
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