From 35c8411c71b2d99a7d1c562de7d47c90daf2ccb3 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 25 Mar 2024 00:10:22 +0100 Subject: [PATCH 1/7] Update fnc_transferGroups.sqf --- .../headless/functions/fnc_transferGroups.sqf | 182 ++++++++++++------ 1 file changed, 126 insertions(+), 56 deletions(-) diff --git a/addons/headless/functions/fnc_transferGroups.sqf b/addons/headless/functions/fnc_transferGroups.sqf index 37580c4fff9..b4da49037b0 100644 --- a/addons/headless/functions/fnc_transferGroups.sqf +++ b/addons/headless/functions/fnc_transferGroups.sqf @@ -17,6 +17,9 @@ params ["_force"]; +// Filter out any invalid entries +GVAR(headlessClients) = GVAR(headlessClients) select {!isNull _x}; + GVAR(headlessClients) params [ ["_HC1", objNull, [objNull]], ["_HC2", objNull, [objNull]], @@ -36,12 +39,13 @@ private _idHC2 = -1; private _idHC3 = -1; private _currentHC = 0; -if (!local _HC1) then { +// objNull is never local +if (!local _HC1 && !isNull _HC1) then { _idHC1 = owner _HC1; _currentHC = 1; }; -if (!local _HC2) then { +if (!local _HC2 && !isNull _HC2) then { _idHC2 = owner _HC2; if (_currentHC == 0) then { @@ -49,7 +53,7 @@ if (!local _HC2) then { }; }; -if (!local _HC3) then { +if (!local _HC3 && !isNull _HC3) then { _idHC3 = owner _HC3; if (_currentHC == 0) then { @@ -57,82 +61,148 @@ if (!local _HC3) then { }; }; +if (_currentHC == 0) exitWith { + TRACE_1("No Valid HC to transfer to",_currentHC); + + if (XGVAR(log)) then { + INFO("No Valid HC to transfer to"); + }; +}; + // Prepare statistics private _numTransferredHC1 = 0; private _numTransferredHC2 = 0; private _numTransferredHC3 = 0; +private _units = []; +private _transfer = false; +private _previousOwner = -1; + // Transfer AI groups { - // No transfer if empty group - private _transfer = ((units _x) isNotEqualTo []) && {!(_x getVariable [QXGVAR(blacklist), false])}; - if (_transfer) then { - // No transfer if waypoints with synchronized triggers exist for the group - private _allWaypointsWithTriggers = (waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}; - if (_allWaypointsWithTriggers isNotEqualTo []) exitWith { + _units = units _x; + + // No transfer if empty group or if group is blacklisted + if (_units isEqualTo [] || {_x getVariable [QXGVAR(blacklist), false]}) then { + continue; + }; + + // No transfer if waypoints with synchronized triggers exist for the group + if (((waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}) isNotEqualTo []) then { + continue; + }; + + { + // No transfer if already transferred + if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { _transfer = false; }; - { - // No transfer if already transferred - if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { - _transfer = false; - }; + // No transfer if player in this group + if (isPlayer _x) exitWith { + _transfer = false; + }; - // No transfer if player in this group - if (isPlayer _x) exitWith { - _transfer = false; - }; + // No transfer if any unit in group is blacklisted + if (_x getVariable [QXGVAR(blacklist), false]) exitWith { + _transfer = false; + }; - // No transfer if any unit in group is blacklisted - if (_x getVariable [QXGVAR(blacklist), false]) exitWith { - _transfer = false; - }; + // No transfer if vehicle unit is in or crew in that vehicle is blacklisted + if (vehicle _x != _x && {(vehicle _x) getVariable [QXGVAR(blacklist), false]}) exitWith { + _transfer = false; + }; - // No transfer if vehicle unit is in or crew in that vehicle is blacklisted - if (vehicle _x != _x && {(vehicle _x) getVariable [QXGVAR(blacklist), false]}) exitWith { - _transfer = false; - }; + // Save gear if unit about to be transferred with current loadout (naked unit work-around) + if (XGVAR(transferLoadout) == 1) then { + _x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true]; + }; + } forEach _units; - // Save gear if unit about to be transferred with current loadout (naked unit work-around) - if (XGVAR(transferLoadout) == 1) then { - _x setVariable [QGVAR(loadout), [_x] call CBA_fnc_getLoadout, true]; - }; - } forEach (units _x); + if (!_transfer) then { + continue; }; // Round robin between HCs if load balance enabled, else pass all to one HC - if (_transfer) then { - switch (_currentHC) do { - case 1: { - private _transferred = _x setGroupOwner _idHC1; - if (_loadBalance) then { - _currentHC = [3, 2] select (!local _HC2); - }; - if (_transferred) then { - _numTransferredHC1 = _numTransferredHC1 + 1; + _previousOwner = groupOwner _x; + + switch (_currentHC) do { + case 1: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC2 != -1) then { + _currentHC = 2; + } else { + if (_idHC3 != -1) then { + _currentHC = 3; + }; }; }; - case 2: { - private _transferred = _x setGroupOwner _idHC2; - if (_loadBalance) then { - _currentHC = [1, 3] select (!local _HC3); - }; - if (_transferred) then { - _numTransferredHC2 = _numTransferredHC2 + 1; - }; + + // Don't transfer if it's already local to HC1 + if (_previousOwner == _idHC1) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1]] call CBA_fnc_globalEvent; // API + + private _transferred = _x setGroupOwner _idHC1; + + [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred]] call CBA_fnc_globalEvent; // API + + if (_transferred) then { + _numTransferredHC1 = _numTransferredHC1 + 1; }; - case 3: { - private _transferred = _x setGroupOwner _idHC3; - if (_loadBalance) then { - _currentHC = [2, 1] select (!local _HC1); + }; + case 2: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC3 != -1) then { + _currentHC = 3; + } else { + if (_idHC1 != -1) then { + _currentHC = 1; + }; }; - if (_transferred) then { - _numTransferredHC3 = _numTransferredHC3 + 1; + }; + + // Don't transfer if it's already local to HC2 + if (_previousOwner == _idHC2) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2]] call CBA_fnc_globalEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred]] call CBA_fnc_globalEvent; // API + + if (_transferred) then { + _numTransferredHC2 = _numTransferredHC2 + 1; + }; + }; + case 3: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC1 != -1) then { + _currentHC = 1; + } else { + if (_idHC2 != -1) then { + _currentHC = 2; + }; }; }; - default { - TRACE_1("No Valid HC to transfer to",_currentHC); + + // Don't transfer if it's already local to HC3 + if (_previousOwner == _idHC3) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3]] call CBA_fnc_globalEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred]] call CBA_fnc_globalEvent; // API + + if (_transferred) then { + _numTransferredHC3 = _numTransferredHC3 + 1; }; }; }; From dc674460ebe15edb04f0674de23e10743dc8a627 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 25 Mar 2024 00:37:03 +0100 Subject: [PATCH 2/7] Update fnc_transferGroups.sqf --- addons/headless/functions/fnc_transferGroups.sqf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/headless/functions/fnc_transferGroups.sqf b/addons/headless/functions/fnc_transferGroups.sqf index b4da49037b0..266a800830e 100644 --- a/addons/headless/functions/fnc_transferGroups.sqf +++ b/addons/headless/functions/fnc_transferGroups.sqf @@ -143,11 +143,11 @@ private _previousOwner = -1; // Don't transfer if it's already local to HC1 if (_previousOwner == _idHC1) exitWith {}; - [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1]] call CBA_fnc_globalEvent; // API + [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API private _transferred = _x setGroupOwner _idHC1; - [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred]] call CBA_fnc_globalEvent; // API + [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred]] call CBA_fnc_targetEvent; // API if (_transferred) then { _numTransferredHC1 = _numTransferredHC1 + 1; @@ -169,11 +169,11 @@ private _previousOwner = -1; // Don't transfer if it's already local to HC2 if (_previousOwner == _idHC2) exitWith {}; - [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2]] call CBA_fnc_globalEvent; // API + [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API private _transferred = _x setGroupOwner _idHC2; - [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred]] call CBA_fnc_globalEvent; // API + [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred]] call CBA_fnc_targetEvent; // API if (_transferred) then { _numTransferredHC2 = _numTransferredHC2 + 1; @@ -195,11 +195,11 @@ private _previousOwner = -1; // Don't transfer if it's already local to HC3 if (_previousOwner == _idHC3) exitWith {}; - [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3]] call CBA_fnc_globalEvent; // API + [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API private _transferred = _x setGroupOwner _idHC2; - [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred]] call CBA_fnc_globalEvent; // API + [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred]] call CBA_fnc_targetEvent; // API if (_transferred) then { _numTransferredHC3 = _numTransferredHC3 + 1; From b23b089543f64262bc833d3f1e949cbfb5da6c32 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 25 Mar 2024 00:37:56 +0100 Subject: [PATCH 3/7] Update fnc_transferGroups.sqf --- addons/headless/functions/fnc_transferGroups.sqf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/headless/functions/fnc_transferGroups.sqf b/addons/headless/functions/fnc_transferGroups.sqf index 266a800830e..7c822b790fe 100644 --- a/addons/headless/functions/fnc_transferGroups.sqf +++ b/addons/headless/functions/fnc_transferGroups.sqf @@ -143,11 +143,11 @@ private _previousOwner = -1; // Don't transfer if it's already local to HC1 if (_previousOwner == _idHC1) exitWith {}; - [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API + [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API private _transferred = _x setGroupOwner _idHC1; - [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred]] call CBA_fnc_targetEvent; // API + [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API if (_transferred) then { _numTransferredHC1 = _numTransferredHC1 + 1; @@ -169,11 +169,11 @@ private _previousOwner = -1; // Don't transfer if it's already local to HC2 if (_previousOwner == _idHC2) exitWith {}; - [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API + [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API private _transferred = _x setGroupOwner _idHC2; - [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred]] call CBA_fnc_targetEvent; // API + [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API if (_transferred) then { _numTransferredHC2 = _numTransferredHC2 + 1; @@ -195,11 +195,11 @@ private _previousOwner = -1; // Don't transfer if it's already local to HC3 if (_previousOwner == _idHC3) exitWith {}; - [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API + [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API private _transferred = _x setGroupOwner _idHC2; - [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred]] call CBA_fnc_targetEvent; // API + [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API if (_transferred) then { _numTransferredHC3 = _numTransferredHC3 + 1; From af6611c664403247250a6434f58fbc02254f06eb Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 25 Mar 2024 23:18:24 +0100 Subject: [PATCH 4/7] Added function to blacklist units --- addons/headless/XEH_PREP.hpp | 1 + .../functions/fnc_modifyUnitsBlacklist.sqf | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 addons/headless/functions/fnc_modifyUnitsBlacklist.sqf diff --git a/addons/headless/XEH_PREP.hpp b/addons/headless/XEH_PREP.hpp index 11e09adf100..af36e76402a 100644 --- a/addons/headless/XEH_PREP.hpp +++ b/addons/headless/XEH_PREP.hpp @@ -2,6 +2,7 @@ ACEX_PREP(endMissionNoPlayers); ACEX_PREP(handleConnectHC); ACEX_PREP(handleDisconnect); ACEX_PREP(handleSpawn); +ACEX_PREP(modifyUnitsBlacklist); ACEX_PREP(moduleInit); ACEX_PREP(rebalance); ACEX_PREP(transferGroups); diff --git a/addons/headless/functions/fnc_modifyUnitsBlacklist.sqf b/addons/headless/functions/fnc_modifyUnitsBlacklist.sqf new file mode 100644 index 00000000000..1ae62f2bcc4 --- /dev/null +++ b/addons/headless/functions/fnc_modifyUnitsBlacklist.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Modifies which units are blacklisted from being transferred to HCs. + * + * Arguments: + * 0: Units + * 1: Add (true) or remove (false) from blacklist (default: true) + * 2: Transfer to server if blacklisted (default: true) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true] call ace_headless_fnc_modifyUnitsBlacklist + * + * Public: Yes + */ + +params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_transferToServer", true, [false]]]; + +if !(_units isEqualType []) then { + _units = [_units]; +}; + +_units = _units select {_x isEqualType objNull || {_x isEqualType grpNull}}; +_units = _units select {!isNull _x}; + +if (_units isEqualTo []) exitWith {}; + +private _groups = []; + +{ + _x setVariable [QXGVAR(blacklist), _blacklist, true]; + + if (_blacklist && _transferToServer) then { + if (_x isEqualType objNull) then { + _groups pushBack _x; + } else { + _groups pushBack group _x + }; + }; +} forEach _units; + +// Try to move AI back to server +if (_blacklist && _transferToServer) then { + { + _x setGroupOwner 2; + } forEach (_groups arrayIntersect _groups); +}; From 25133da52136938affd6471e5316b962643ef605 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 26 Mar 2024 08:21:28 +0100 Subject: [PATCH 5/7] Transfer units to server if they are on HCs --- addons/headless/XEH_postInit.sqf | 15 +++++++++++++++ .../functions/fnc_modifyUnitsBlacklist.sqf | 4 +--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/addons/headless/XEH_postInit.sqf b/addons/headless/XEH_postInit.sqf index 103d5c18342..5cf4090c9ff 100644 --- a/addons/headless/XEH_postInit.sqf +++ b/addons/headless/XEH_postInit.sqf @@ -10,6 +10,21 @@ }; // Add disconnect EH addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + + [QGVAR(transferGroupsToServer), { + params ["_groups"]; + + // Filter out any invalid entries + GVAR(headlessClients) = GVAR(headlessClients) select {!isNull _x}; + + private _idsHC = GVAR(headlessClients) apply {owner _x}; + + { + if (groupOwner _x in _idsHC) then { + _x setGroupOwner 2; + }; + } forEach _groups; + }] call CBA_fnc_addEventHandler; } else { // Register HC (this part happens on HC only) [QXGVAR(headlessClientJoined), [player]] call CBA_fnc_globalEvent; // Global event for API purposes diff --git a/addons/headless/functions/fnc_modifyUnitsBlacklist.sqf b/addons/headless/functions/fnc_modifyUnitsBlacklist.sqf index 1ae62f2bcc4..249ed6da01b 100644 --- a/addons/headless/functions/fnc_modifyUnitsBlacklist.sqf +++ b/addons/headless/functions/fnc_modifyUnitsBlacklist.sqf @@ -44,7 +44,5 @@ private _groups = []; // Try to move AI back to server if (_blacklist && _transferToServer) then { - { - _x setGroupOwner 2; - } forEach (_groups arrayIntersect _groups); + [QGVAR(transferGroupsToServer), [_groups arrayIntersect _groups]] call CBA_fnc_serverEvent; }; From 6dbe9086cc10320f8e5fa8d99aa205038357a775 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 27 Mar 2024 23:55:16 +0100 Subject: [PATCH 6/7] Replaced transferToServer with ownerID --- addons/headless/XEH_PREP.hpp | 2 +- addons/headless/XEH_postInit.sqf | 13 +++---------- ...ifyUnitsBlacklist.sqf => fnc_blacklist.sqf} | 18 ++++++++++-------- 3 files changed, 14 insertions(+), 19 deletions(-) rename addons/headless/functions/{fnc_modifyUnitsBlacklist.sqf => fnc_blacklist.sqf} (65%) diff --git a/addons/headless/XEH_PREP.hpp b/addons/headless/XEH_PREP.hpp index af36e76402a..e1c65cc083d 100644 --- a/addons/headless/XEH_PREP.hpp +++ b/addons/headless/XEH_PREP.hpp @@ -1,8 +1,8 @@ +ACEX_PREP(blacklist); ACEX_PREP(endMissionNoPlayers); ACEX_PREP(handleConnectHC); ACEX_PREP(handleDisconnect); ACEX_PREP(handleSpawn); -ACEX_PREP(modifyUnitsBlacklist); ACEX_PREP(moduleInit); ACEX_PREP(rebalance); ACEX_PREP(transferGroups); diff --git a/addons/headless/XEH_postInit.sqf b/addons/headless/XEH_postInit.sqf index 5cf4090c9ff..bf7ac3797ca 100644 --- a/addons/headless/XEH_postInit.sqf +++ b/addons/headless/XEH_postInit.sqf @@ -11,18 +11,11 @@ // Add disconnect EH addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; - [QGVAR(transferGroupsToServer), { - params ["_groups"]; - - // Filter out any invalid entries - GVAR(headlessClients) = GVAR(headlessClients) select {!isNull _x}; - - private _idsHC = GVAR(headlessClients) apply {owner _x}; + [QGVAR(transferGroupsToOwner), { + params ["_groups", "_owner"]; { - if (groupOwner _x in _idsHC) then { - _x setGroupOwner 2; - }; + _x setGroupOwner _owner; } forEach _groups; }] call CBA_fnc_addEventHandler; } else { diff --git a/addons/headless/functions/fnc_modifyUnitsBlacklist.sqf b/addons/headless/functions/fnc_blacklist.sqf similarity index 65% rename from addons/headless/functions/fnc_modifyUnitsBlacklist.sqf rename to addons/headless/functions/fnc_blacklist.sqf index 249ed6da01b..1e1f5ca93d3 100644 --- a/addons/headless/functions/fnc_modifyUnitsBlacklist.sqf +++ b/addons/headless/functions/fnc_blacklist.sqf @@ -6,43 +6,45 @@ * Arguments: * 0: Units * 1: Add (true) or remove (false) from blacklist (default: true) - * 2: Transfer to server if blacklisted (default: true) + * 2: Owner to transfer units to (default: -1) * * Return Value: * None * * Example: - * [cursorObject, true] call ace_headless_fnc_modifyUnitsBlacklist + * [cursorObject, true] call ace_headless_fnc_blacklist * * Public: Yes */ -params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_transferToServer", true, [false]]]; +params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_newOwner", -1, [false]]]; if !(_units isEqualType []) then { _units = [_units]; }; +// Make sure passed arguments are objects or groups _units = _units select {_x isEqualType objNull || {_x isEqualType grpNull}}; _units = _units select {!isNull _x}; if (_units isEqualTo []) exitWith {}; +private _transfer = _blacklist && {_newOwner > 1}; private _groups = []; { _x setVariable [QXGVAR(blacklist), _blacklist, true]; - if (_blacklist && _transferToServer) then { + if (_transfer) then { if (_x isEqualType objNull) then { - _groups pushBack _x; + _groups pushBack group _x; } else { - _groups pushBack group _x + _groups pushBack _x; }; }; } forEach _units; // Try to move AI back to server -if (_blacklist && _transferToServer) then { - [QGVAR(transferGroupsToServer), [_groups arrayIntersect _groups]] call CBA_fnc_serverEvent; +if (_transfer) then { + [QGVAR(transferGroupsToOwner), [_groups arrayIntersect _groups, _newOwner]] call CBA_fnc_serverEvent; }; From 0649e8ec1e60aa7c33deae585e3e77dcc6d1e88d Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 13 Apr 2024 10:54:45 +0200 Subject: [PATCH 7/7] Added documentation and rebalance param --- addons/headless/XEH_postInit.sqf | 17 ++++++++++----- addons/headless/functions/fnc_blacklist.sqf | 11 +++++----- addons/headless/script_component.hpp | 4 ++++ docs/wiki/framework/events-framework.md | 10 +++++++-- docs/wiki/framework/headless-framework.md | 23 +++++++++++++++++++-- 5 files changed, 51 insertions(+), 14 deletions(-) diff --git a/addons/headless/XEH_postInit.sqf b/addons/headless/XEH_postInit.sqf index dee47aa1caf..d1106b40c9b 100644 --- a/addons/headless/XEH_postInit.sqf +++ b/addons/headless/XEH_postInit.sqf @@ -11,12 +11,19 @@ // Add disconnect EH addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; - [QGVAR(transferGroupsToOwner), { - params ["_groups", "_owner"]; + [QGVAR(transferGroupsRebalance), { + params ["_groups", "_owner", "_rebalance"]; - { - _x setGroupOwner _owner; - } forEach _groups; + if (_groups isNotEqualTo [] && {_owner > 1}) then { + { + _x setGroupOwner _owner; + } forEach _groups; + }; + + // Rebalance units + if (_rebalance in [REBALANCE, FORCED_REBALANCE]) then { + (_rebalance == FORCED_REBALANCE) call FUNC(rebalance); + }; }] call CBA_fnc_addEventHandler; } else { // Register HC (this part happens on HC only) diff --git a/addons/headless/functions/fnc_blacklist.sqf b/addons/headless/functions/fnc_blacklist.sqf index 1e1f5ca93d3..1c15406ba61 100644 --- a/addons/headless/functions/fnc_blacklist.sqf +++ b/addons/headless/functions/fnc_blacklist.sqf @@ -7,6 +7,7 @@ * 0: Units * 1: Add (true) or remove (false) from blacklist (default: true) * 2: Owner to transfer units to (default: -1) + * 3: Rebalance (default: 0) * * Return Value: * None @@ -17,7 +18,7 @@ * Public: Yes */ -params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_newOwner", -1, [false]]]; +params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_owner", -1, [false]], ["_rebalance", NO_REBALANCE, [0]]]; if !(_units isEqualType []) then { _units = [_units]; @@ -29,7 +30,7 @@ _units = _units select {!isNull _x}; if (_units isEqualTo []) exitWith {}; -private _transfer = _blacklist && {_newOwner > 1}; +private _transfer = _blacklist && {_owner > 1}; private _groups = []; { @@ -44,7 +45,7 @@ private _groups = []; }; } forEach _units; -// Try to move AI back to server -if (_transfer) then { - [QGVAR(transferGroupsToOwner), [_groups arrayIntersect _groups, _newOwner]] call CBA_fnc_serverEvent; +// Try to move AI to new owner; Also takes care of rebalancing groups +if (_transfer || {_rebalance in [REBALANCE, FORCED_REBALANCE]}) then { + [QGVAR(transferGroupsRebalance), [_groups arrayIntersect _groups, _owner, _rebalance]] call CBA_fnc_serverEvent; }; diff --git a/addons/headless/script_component.hpp b/addons/headless/script_component.hpp index 73761a7bb16..272b288d5f4 100644 --- a/addons/headless/script_component.hpp +++ b/addons/headless/script_component.hpp @@ -17,3 +17,7 @@ #include "\z\ace\addons\main\script_macros.hpp" #define DELAY_DEFAULT 15 + +#define NO_REBALANCE 0 +#define REBALANCE 1 +#define FORCED_REBALANCE 2 diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md index 8a50912e024..4023c9c2612 100644 --- a/docs/wiki/framework/events-framework.md +++ b/docs/wiki/framework/events-framework.md @@ -156,9 +156,15 @@ MenuType: 0 = Interaction, 1 = Self Interaction | Event Key | Parameters | Locality | Type | Description | |---------- |------------|----------|------|-------------| -|---------- |------------|----------|------|-------------| | `ace_interaction_doorOpeningStarted` | [_house, _door, _animations] | Local | Listen | Called when local unit starts interacting with doors -| `ace_interaction_doorOpeningStopped` | [_house, _door, _animations] | Local | Listen | Called when local unit stopps interacting with doors +| `ace_interaction_doorOpeningStopped` | [_house, _door, _animations] | Local | Listen | Called when local unit stops interacting with doors + +### 2.17 Headless (`ace_headless`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_headless_groupTransferPre` | [_group, _HC (OBJECT), _previousOwner, _idHC] | Target | Listen | Called just before a group is transferred from any machine to a HC. Called where group currently is local and on the HC, where group is going to be local. +| `ace_headless_groupTransferPost` | [_group, _HC (OBJECT), _previousOwner, _idHC, _transferredSuccessfully] | Target | Listen | Called just after a group is transferred from a machine to a HC. Called where group was local and on the HC, where group is now local. `_transferredSuccessfully` is passed so mods can actually check if the locality was properly transferred, as ownership transfer is not guaranteed. ## 3. Usage Also Reference [CBA Events System](https://github.com/CBATeam/CBA_A3/wiki/Custom-Events-System){:target="_blank"} documentation. diff --git a/docs/wiki/framework/headless-framework.md b/docs/wiki/framework/headless-framework.md index 6dbc83c5123..7a2a5a08221 100644 --- a/docs/wiki/framework/headless-framework.md +++ b/docs/wiki/framework/headless-framework.md @@ -30,14 +30,29 @@ As of ACEX v3.2.0 _(before merge into ACE3)_ this feature can also be enabled wi ## 2. Scripting -### 2.1 Disable Transferring for a Group +### 2.1 Manipulating HC Transfers of Groups via function -To prevent a group from transferring to a Headless Client use the following line on a group leader (or every unit in a group in case group leader may not spawn): +`ace_headless_fnc_blacklist` + + | Arguments | Type | Optional (default value) +---| --------- | ---- | ------------------------ +0 | Units | Object, Group or Array of both | Required +1 | Add (true) or remove (false) from blacklist | Bool | Optional (default: `true`) +2 | Owner to transfer units to | Number | Optional (default: `-1`) +3 | Rebalance (0 = no rebalance, 1 = rebalance, 2 = force rebalance) | Number | (default: `0`) +**R** | None | None | Return value + +`Force rebalance` means that all units, including the ones that are on the HCs, are rebalanced amongst the HCs, whereas `rebalance` means that newly spawned units are going to be evenly distributed amongst HCs. Therefore, `rebalance` does not guarantee that the HCs will have an equal amount of groups, whereas `force rebalance` does. + +### 2.2 Disable Transferring for a Group via variable + +To prevent a group from transferring to a Headless Client use the following line on a unit within a group: ```sqf this setVariable ["acex_headless_blacklist", true]; ``` +This variable can also be set on vehicles, disabling transferal of any groups having units in said vehicles. ## 3. Limitations @@ -48,3 +63,7 @@ Some Arma 3 features are incompatible, this is up to BI to add support. Disable Additionally, groups will not be transferred due to lack of support if they: - Have waypoints with synchronized triggers (waypoint would not change status based on trigger condition) (added in ACEX v3.2.0 - _before merge into ACE3_) + +Groups will not be transferred to avoid issues: +- If a player is within the group. +- If they contain UAVs.