diff --git a/addons/common/fnc_deleteEntity.sqf b/addons/common/fnc_deleteEntity.sqf index 302dfeb1e..97dc53bb3 100644 --- a/addons/common/fnc_deleteEntity.sqf +++ b/addons/common/fnc_deleteEntity.sqf @@ -43,7 +43,15 @@ switch (typeName _entity) do { case "GROUP" : { (units _entity) call CBA_fnc_deleteEntity; {deleteWaypoint _x} forEach (wayPoints _entity); - deleteGroup _entity; + if (local _entity) then { + deleteGroup _entity; + } else { + if (isServer) then { + _entity remoteExecCall ["CBA_fnc_deleteEntity", groupOwner _entity]; + } else { + _entity remoteExecCall ["CBA_fnc_deleteEntity", 2]; + }; + }; }; case "LOCATION" : { deleteLocation _entity; diff --git a/addons/common/fnc_waitUntilAndExecute.sqf b/addons/common/fnc_waitUntilAndExecute.sqf index 9c0c6ac80..5dcf7f388 100644 --- a/addons/common/fnc_waitUntilAndExecute.sqf +++ b/addons/common/fnc_waitUntilAndExecute.sqf @@ -3,13 +3,15 @@ Function: CBA_fnc_waitUntilAndExecute Description: Executes a code once in unscheduled environment after a condition is true. - It's also possible to add a timeout, in which case a different code is executed. + It's also possible to add a timeout >= 0, in which case a different code is executed. + Then it will be waited until _timeout time has elapsed or _condition evaluates to true. Parameters: _condition - The function to evaluate as condition. _statement - The function to run once the condition is true. _args - Parameters passed to the functions (statement and condition) executing. (optional) - _timeout - Timeout for the condition in seconds. (optional) + _timeout - If >= 0, timeout for the condition in seconds. If < 0, no timeout. + Exactly 0 means timeout immediately on the next iteration.(optional, default -1) _timeoutCode - Will execute instead of _statement if the condition times out. (optional) Passed Arguments: @@ -37,11 +39,11 @@ params [ ["_condition", {}, [{}]], ["_statement", {}, [{}]], ["_args", []], - ["_timeout", 0, [0]], + ["_timeout", -1, [0]], ["_timeoutCode", {}, [{}]] ]; -if (_timeout == 0) then { +if (_timeout < 0) then { GVAR(waitUntilAndExecArray) pushBack [_condition, _statement, _args]; } else { GVAR(waitUntilAndExecArray) pushBack [{ diff --git a/addons/ui/CfgFunctions.hpp b/addons/ui/CfgFunctions.hpp index 6e35a8ebc..dbd309a30 100644 --- a/addons/ui/CfgFunctions.hpp +++ b/addons/ui/CfgFunctions.hpp @@ -18,6 +18,7 @@ class CfgFunctions { file = QUOTE(PATHTOF(flexiMenu\fnc_openMenuByDef.sqf)); }; PATHTO_FNC(addPauseMenuOption); + PATHTO_FNC(progressBar); }; }; }; diff --git a/addons/ui/CfgUIGrids.hpp b/addons/ui/CfgUIGrids.hpp new file mode 100644 index 000000000..69dbb249e --- /dev/null +++ b/addons/ui/CfgUIGrids.hpp @@ -0,0 +1,30 @@ +class CfgUIGrids { + class IGUI { + class Presets { + class Arma3 { + class Variables { + GVAR(grid)[] = { + { + 1 * GUI_GRID_CENTER_W + GUI_GRID_CENTER_X, + 0 * GUI_GRID_CENTER_H + GUI_GRID_CENTER_Y, + 38 * GUI_GRID_CENTER_W, + 1 * GUI_GRID_CENTER_H + }, + 0.5 * GUI_GRID_CENTER_W, + 0.5 * GUI_GRID_CENTER_H + }; + }; + }; + }; + + class Variables { + class GVAR(grid) { + displayName = CSTRING(ProgressBarPositionName); + description = CSTRING(ProgressBarPositionDescription); + preview = "#(argb,8,8,3)color(0,0,0,1)"; + saveToProfile[] = {0,1,2,3}; + canResize = 1; + }; + }; + }; +}; diff --git a/addons/ui/RscTitles.hpp b/addons/ui/RscTitles.hpp new file mode 100644 index 000000000..ed9f9dc9e --- /dev/null +++ b/addons/ui/RscTitles.hpp @@ -0,0 +1,57 @@ +class RscText; +class RscProgress; +class RscMapControl; + +class RscTitles { + class GVAR(ProgressBar) { + onLoad = uiNamespace setVariable ['GVAR(ProgressBar)', _this select 0]; + idd = -1; + duration = 1e+11; + fadeIn = 0; + fadeOut = 0; + + controls[] = {"Background", "TitleBackground", "ProgressBar", "TitleText", "Script"}; + + class Background: RscText { + colorBackground[] = {0,0,0,0}; + x = "safezoneXAbs"; + y = "safezoneY"; + w = "safezoneWAbs"; + h = "safezoneH"; + }; + + class TitleBackground: RscText { + idc = IDC_PROGRESSBAR_BACKGROUND; + style = ST_CENTER; + sizeEx = 1 * GUI_GRID_CENTER_H; + colorBackground[] = {0,0,0,0.5}; + x = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),X)', 0]; + y = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),Y)', 0]; + w = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),W)', 0]; + h = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),H)', 0]; + }; + + class TitleText: TitleBackground { + idc = IDC_PROGRESSBAR_TITLE; + colorBackground[] = {0,0,0,0}; + colorText[] = {1,1,1,1}; + }; + + class ProgressBar: RscProgress { + idc = IDC_PROGRESSBAR_BAR; + colorFrame[] = {0,0,0,0.5}; + colorBar[] = GUI_BCG_COLOR; + texture = "#(argb,8,8,3)color(1,1,1,0.7)"; + x = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),X)', 0]; + y = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),Y)', 0]; + w = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),W)', 0]; + h = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),H)', 0]; + }; + + class Script: RscMapControl { + idc = IDC_PROGRESSBAR_SCRIPT; + w = 0; + h = 0; + }; + }; +}; diff --git a/addons/ui/XEH_preClientInit.sqf b/addons/ui/XEH_preClientInit.sqf index dbac001d0..6febc990e 100644 --- a/addons/ui/XEH_preClientInit.sqf +++ b/addons/ui/XEH_preClientInit.sqf @@ -3,3 +3,10 @@ LOG(MSG_INIT); call COMPILE_FILE(flexiMenu\init); + +// recreate after loading a savegame +addMissionEventHandler ["Loaded", { + if (!isNil QGVAR(ProgressBarParams)) then { + QGVAR(ProgressBar) cutRsc [QGVAR(ProgressBar), "PLAIN"]; + }; +}]; diff --git a/addons/ui/config.cpp b/addons/ui/config.cpp index 4bc0a57cc..cbbb4d0c4 100644 --- a/addons/ui/config.cpp +++ b/addons/ui/config.cpp @@ -19,9 +19,11 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgFunctions.hpp" +#include "RscTitles.hpp" +#include "CfgUIGrids.hpp" + //----------------------------------------------------------------------------- // TODO: Delete these rsc/_flexiMenu_RscShortcutButton classes soon and transfer properties to menu classes, if any. -class RscText; class RscShortcutButton; class _flexiMenu_RscShortcutButton: RscShortcutButton { class HitZone { diff --git a/addons/ui/fnc_progressBar.sqf b/addons/ui/fnc_progressBar.sqf new file mode 100644 index 000000000..89dd1da9e --- /dev/null +++ b/addons/ui/fnc_progressBar.sqf @@ -0,0 +1,149 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_progressBar + +Description: + Opens a progress bar. Closes the currently active progress bar. + +Parameters: + _title - Title of the progress bar + _totalTime - Time for the progress bar to complete + _condition - Execute every frame. If reports false, close the progress bar + _onSuccess - Script to execute if the progress bar completed + _onFailure - Script to execute if the progress bar was aborted prematurely + (optional, default: {}) + _arguments - Arguments passed to the scripts (optional, default: []) + _blockMouse - Block mouse input (optional, default: true) + _blockKeys - Block keyboard input + requires _blockMouse to be set to true (optional, default: true) + _allowClose - Allow ESC key to abort the progress bar + requires _blockMouse to be set to true (optional, default: true) + +Arguments: + _this: + #0 - same as _arguments + #1 - true: success, false: failure + #2 - elapsed time, not more than _totalTime + #3 - total time, same as _totalTime + +Returns: + Nothing + +Examples: + (begin example) + ["progress bar", 5, {true}, {hint "done"}, {hint "aborted"}] call CBA_fnc_progressBar; + (end) + +Author: + commy2 +---------------------------------------------------------------------------- */ +#include "script_component.hpp" + +// no progress bar without interface +if (!hasInterface) exitWith {}; + +// execute in unscheduled environment +if (canSuspend) exitWith { + [CBA_fnc_progressBar, _this] call CBA_fnc_directCall; +}; + +// arguments +params [ + ["_title", "", [""]], + ["_totalTime", 0, [0]], + ["_condition", {}, [{true}]], + ["_onSuccess", {}, [{}]], + ["_onFailure", {}, [{}]], + ["_arguments", []], + ["_blockMouse", true, [false]], + ["_blockKeys", true, [false]], + ["_allowClose", true, [false]] +]; + +if (isLocalized _title) then { + _title = localize _title; +}; + +// show progress bar and set title +QGVAR(ProgressBar) cutRsc [QGVAR(ProgressBar), "PLAIN"]; +private _display = uiNamespace getVariable QGVAR(ProgressBar); + +private _ctrlTitle = _display displayCtrl IDC_PROGRESSBAR_TITLE; +_ctrlTitle ctrlSetText _title; + +// run failure code on previous progress bar +if (!isNil QGVAR(ProgressBarParams)) then { + GVAR(ProgressBarParams) params ["_arguments", "", "", "_onFailure", "_startTime", "_totalTime"]; + private _elapsedTime = (CBA_missionTime - _startTime) min _totalTime; + + [_onFailure, [_arguments, false, _elapsedTime, _totalTime]] call CBA_fnc_execNextFrame; +}; + +GVAR(ProgressBarParams) = [_arguments, _condition, _onSuccess, _onFailure, CBA_missionTime, _totalTime, _blockMouse, _blockKeys, _allowClose]; + +// update bar, check condition, execute success or failure scripts +private _ctrlScript = _display displayCtrl IDC_PROGRESSBAR_SCRIPT; +_ctrlScript ctrlAddEventHandler ["Draw", { + params ["_ctrlScript"]; + private _display = ctrlParent _ctrlScript; + + GVAR(ProgressBarParams) params ["_arguments", "_condition", "_onSuccess", "_onFailure", "_startTime", "_totalTime"]; + private _elapsedTime = (CBA_missionTime - _startTime) min _totalTime; + + private _continue = [[_arguments, true, _elapsedTime, _totalTime], _condition] call { + private ["_ctrlScript", "_display", "_arguments", "_condition", "_onSuccess", "_onFailure", "_startTime", "_totalTime", "_elapsedTime"]; + _this#0 call _this#1; + }; + + private _blockInputDisplay = uiNamespace getVariable [QGVAR(BlockInputDisplay), displayNull]; + + if (!_continue) exitWith { + GVAR(ProgressBarParams) = nil; + {QGVAR(ProgressBar) cutText ["", "PLAIN"]} call CBA_fnc_execNextFrame; // game would crash if display is killed from Draw event + _blockInputDisplay closeDisplay 0; + [_onFailure, [_arguments, false, _elapsedTime, _totalTime]] call CBA_fnc_execNextFrame; + }; + + if (_elapsedTime >= _totalTime) exitWith { + GVAR(ProgressBarParams) = nil; + {QGVAR(ProgressBar) cutText ["", "PLAIN"]} call CBA_fnc_execNextFrame; // game would crash if display is killed from Draw event + _blockInputDisplay closeDisplay 0; + [_onSuccess, [_arguments, true, _elapsedTime, _totalTime]] call CBA_fnc_execNextFrame; + }; + + private _ctrlBar = _display displayCtrl IDC_PROGRESSBAR_BAR; + _ctrlBar progressSetPosition (_elapsedTime / _totalTime); +}]; + +// block input while the bar is shown +private _blockInputDisplay = uiNamespace getVariable [QGVAR(BlockInputDisplay), displayNull]; +_blockInputDisplay closeDisplay 0; + +if (_blockMouse) then { + private _mission = uiNamespace getVariable "RscDisplayMission"; + _blockInputDisplay = _mission createDisplay "RscDisplayEmpty"; + uiNamespace setVariable [QGVAR(BlockInputDisplay), _blockInputDisplay]; + + _blockInputDisplay displayAddEventHandler ["KeyDown", { + params ["_blockInputDisplay", "_key", "_shift", "_control", "_alt"]; + + GVAR(ProgressBarParams) params ["_arguments", "", "", "_onFailure", "_startTime", "_totalTime", "_blockMouse", "_blockKeys", "_allowClose"]; + private _elapsedTime = (CBA_missionTime - _startTime) min _totalTime; + + if (_key isEqualTo DIK_ESCAPE) then { + if (_allowClose) then { + GVAR(ProgressBarParams) = nil; + QGVAR(ProgressBar) cutText ["", "PLAIN"]; + _blockInputDisplay closeDisplay 0; + [_onFailure, [_arguments, false, _elapsedTime, _totalTime]] call CBA_fnc_execNextFrame; + + _blockKeys = false; + } else { + _blockKeys = true; + }; + }; + + _blockKeys + }]; +}; + +nil diff --git a/addons/ui/script_component.hpp b/addons/ui/script_component.hpp index dcef8b91e..a048bec61 100644 --- a/addons/ui/script_component.hpp +++ b/addons/ui/script_component.hpp @@ -1,6 +1,8 @@ #define COMPONENT ui #include "\x\cba\addons\main\script_mod.hpp" +//#define DEBUG_MODE_FULL +//#define DISABLE_COMPILE_CACHE //#define DEBUG_ENABLED_UI #ifdef DEBUG_ENABLED_UI @@ -14,9 +16,14 @@ #include "\x\cba\addons\main\script_macros.hpp" #include "\a3\ui_f\hpp\defineCommonGrids.inc" +#include "\a3\ui_f\hpp\defineCommonColors.inc" #include "\a3\ui_f\hpp\defineDIKCodes.inc" #include "\a3\ui_f\hpp\defineResincl.inc" +#define IDC_PROGRESSBAR_TITLE 10 +#define IDC_PROGRESSBAR_BAR 11 +#define IDC_PROGRESSBAR_SCRIPT 12 + #define IDC_ADDON_CONTROLS 127303 #define IDC_ADDON_OPTIONS 127307 diff --git a/addons/ui/stringtable.xml b/addons/ui/stringtable.xml index 3ad2eb42f..c1577076d 100644 --- a/addons/ui/stringtable.xml +++ b/addons/ui/stringtable.xml @@ -9,5 +9,13 @@ Extensões de Base Comunitária - Interface ao Usuário Community Base Addons - Пользовательский Интерфейс + + Progress Bar + Fortschrittsanzeige + + + Position of the progress bar. + Position der Fortschrittsanzeige. + diff --git a/addons/versioning/XEH_postInitServer.sqf b/addons/versioning/XEH_postInitServer.sqf index cd5348b38..8b0d37206 100644 --- a/addons/versioning/XEH_postInitServer.sqf +++ b/addons/versioning/XEH_postInitServer.sqf @@ -20,6 +20,9 @@ FUNC(paranoid) = { QGVAR(versions_serv) addPublicVariableEventHandler { (_this select 1) call FUNC(paranoid) }; +// Skip missing mod check if it is disabled. +if (getNumber (configFile >> "CBA_disableMissingModCheck") == 1) exitWith {}; + // Missing Modfolder check FUNC(handleMismatch) = { params ["_machine","_mod"]; diff --git a/optionals/disable_missing_mod_check/$PBOPREFIX$ b/optionals/disable_missing_mod_check/$PBOPREFIX$ new file mode 100644 index 000000000..4a8bff6da --- /dev/null +++ b/optionals/disable_missing_mod_check/$PBOPREFIX$ @@ -0,0 +1 @@ +x\cba\addons\disable_missing_mod_check \ No newline at end of file diff --git a/optionals/disable_missing_mod_check/config.cpp b/optionals/disable_missing_mod_check/config.cpp new file mode 100644 index 000000000..3b9e1b632 --- /dev/null +++ b/optionals/disable_missing_mod_check/config.cpp @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + author = "$STR_CBA_Author"; + name = ECSTRING(Optional,Component); + url = "$STR_CBA_URL"; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"CBA_extended_eventhandlers", "CBA_versioning"}; + version = VERSION; + authors[] = {"Dedmen"}; + }; +}; + +CBA_disableMissingModCheck = 1; diff --git a/optionals/disable_missing_mod_check/script_component.hpp b/optionals/disable_missing_mod_check/script_component.hpp new file mode 100644 index 000000000..8c55df94a --- /dev/null +++ b/optionals/disable_missing_mod_check/script_component.hpp @@ -0,0 +1,13 @@ +#define COMPONENT disable_missing_mod_check +#include "\x\cba\addons\main\script_mod.hpp" + + +#ifdef DEBUG_ENABLED_DISABLE_MISSING_MOD_CHECK + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_DISABLE_MISSING_MOD_CHECK + #define DEBUG_SETTINGS DEBUG_SETTINGS_DISABLE_MISSING_MOD_CHECK +#endif + +#include "\x\cba\addons\main\script_macros.hpp"