Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Headless - Improve group transfer and add API #9874

Merged
merged 8 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions addons/headless/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ ACEX_PREP(endMissionNoPlayers);
ACEX_PREP(handleConnectHC);
ACEX_PREP(handleDisconnect);
ACEX_PREP(handleSpawn);
ACEX_PREP(modifyUnitsBlacklist);
johnb432 marked this conversation as resolved.
Show resolved Hide resolved
ACEX_PREP(moduleInit);
ACEX_PREP(rebalance);
ACEX_PREP(transferGroups);
50 changes: 50 additions & 0 deletions addons/headless/functions/fnc_modifyUnitsBlacklist.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "..\script_component.hpp"
/*
* Author: johnb43
* Modifies which units are blacklisted from being transferred to HCs.
*
* Arguments:
* 0: Units <OBJECT, GROUP, ARRAY>
* 1: Add (true) or remove (false) from blacklist <BOOL> (default: true)
* 2: Transfer to server if blacklisted <BOOL> (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
};
};
johnb432 marked this conversation as resolved.
Show resolved Hide resolved
} forEach _units;

// Try to move AI back to server
if (_blacklist && _transferToServer) then {
{
_x setGroupOwner 2;
} forEach (_groups arrayIntersect _groups);
};
182 changes: 126 additions & 56 deletions addons/headless/functions/fnc_transferGroups.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -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]],
Expand All @@ -36,103 +39,170 @@ 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 {
_currentHC = 2;
};
};

if (!local _HC3) then {
if (!local _HC3 && !isNull _HC3) then {
_idHC3 = owner _HC3;

if (_currentHC == 0) then {
_currentHC = 3;
};
};

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], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API

private _transferred = _x setGroupOwner _idHC1;

[QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // 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], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API

private _transferred = _x setGroupOwner _idHC2;

[QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // 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], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API

private _transferred = _x setGroupOwner _idHC2;

[QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API

if (_transferred) then {
_numTransferredHC3 = _numTransferredHC3 + 1;
};
};
};
Expand Down