mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Add Headless
This commit is contained in:
parent
32b4416c29
commit
a1866a561b
1
addons/headless/$PBOPREFIX$
Normal file
1
addons/headless/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\headless
|
20
addons/headless/ACE_Settings.hpp
Normal file
20
addons/headless/ACE_Settings.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
class ACE_Settings {
|
||||
class GVAR(Enabled) {
|
||||
value = 0;
|
||||
typeName = "BOOL";
|
||||
displayName = ECSTRING(common,Enabled);
|
||||
description = CSTRING(EnabledDesc);
|
||||
};
|
||||
class GVAR(Delay) {
|
||||
value = DELAY_DEFAULT;
|
||||
typeName = "SCALAR";
|
||||
displayName = CSTRING(Delay);
|
||||
description = CSTRING(DelayDesc);
|
||||
};
|
||||
class GVAR(Log) {
|
||||
value = 0;
|
||||
typeName = "BOOL";
|
||||
displayName = CSTRING(Log);
|
||||
description = CSTRING(LogDesc);
|
||||
};
|
||||
};
|
19
addons/headless/CfgEventHandlers.hpp
Normal file
19
addons/headless/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
class Extended_PreInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preInit));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PostInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_postInit));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_InitPost_EventHandlers {
|
||||
class AllVehicles {
|
||||
class ADDON {
|
||||
serverInit = QUOTE(_this call FUNC(handleInitPost));
|
||||
};
|
||||
};
|
||||
};
|
37
addons/headless/CfgVehicles.hpp
Normal file
37
addons/headless/CfgVehicles.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
class CfgVehicles {
|
||||
class ACE_Module;
|
||||
class GVAR(module): ACE_Module {
|
||||
author = ECSTRING(common,ACETeam);
|
||||
category = "ACE_missionModules";
|
||||
displayName = CSTRING(Module);
|
||||
function = QFUNC(moduleInit);
|
||||
scope = 2;
|
||||
isGlobal = 1; // Global
|
||||
isTriggerActivated = 0;
|
||||
isDisposable = 0;
|
||||
icon = QUOTE(PATHTOF(UI\Icon_Module_Headless_ca.paa));
|
||||
class Arguments {
|
||||
class Enabled {
|
||||
displayName = ECSTRING(common,Enabled);
|
||||
description = CSTRING(EnabledDesc);
|
||||
typeName = "BOOL";
|
||||
defaultValue = 0;
|
||||
};
|
||||
class Delay {
|
||||
displayName = CSTRING(Delay);
|
||||
description = CSTRING(DelayDesc);
|
||||
typeName = "NUMBER";
|
||||
defaultValue = DELAY_DEFAULT;
|
||||
};
|
||||
class Log {
|
||||
displayName = CSTRING(Log);
|
||||
description = CSTRING(LogDesc);
|
||||
typeName = "BOOL";
|
||||
defaultValue = 0;
|
||||
};
|
||||
};
|
||||
class ModuleDescription {
|
||||
description = CSTRING(ModuleDesc);
|
||||
};
|
||||
};
|
||||
};
|
16
addons/headless/README.md
Normal file
16
addons/headless/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
ace_headless
|
||||
============
|
||||
|
||||
Adds automatic passing of AI groups to (up to 3) Headless Clients.
|
||||
- Automatic Headless Client recognition
|
||||
- Event-based transferring (on unit spawn, Headless Client connect and disconnect)
|
||||
- Round-robin transferring when more than 1 Headless Client is present
|
||||
- Mission makers can use the following to prevent a group from transferring to a Headless Client:
|
||||
`this setVariable ["ace_headless_blacklist", true, true];`
|
||||
|
||||
|
||||
## Maintainers
|
||||
|
||||
The people responsible for merging changes to this component or answering potential questions.
|
||||
|
||||
- [Jonpas](http://github.com/jonpas)
|
BIN
addons/headless/UI/Icon_Module_Headless_ca.paa
Normal file
BIN
addons/headless/UI/Icon_Module_Headless_ca.paa
Normal file
Binary file not shown.
16
addons/headless/XEH_postInit.sqf
Normal file
16
addons/headless/XEH_postInit.sqf
Normal file
@ -0,0 +1,16 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
// Exit on player clients that are not hosts
|
||||
if (hasInterface && !isServer) exitWith {};
|
||||
|
||||
["SettingsInitialized", {
|
||||
// Exit if HC transferring disabled
|
||||
if (!GVAR(Enabled)) exitWith {};
|
||||
|
||||
if (isServer) then {
|
||||
addMissionEventHandler ["HandleDisconnect", {_this call FUNC(handleDisconnect)}];
|
||||
} else {
|
||||
// Register HC on server (this part happens on HC only)
|
||||
["ACE_HeadlessClientJoined", [player]] call EFUNC(common,serverEvent);
|
||||
};
|
||||
}] call EFUNC(common,addEventHandler);
|
18
addons/headless/XEH_preInit.sqf
Normal file
18
addons/headless/XEH_preInit.sqf
Normal file
@ -0,0 +1,18 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
ADDON = false;
|
||||
|
||||
PREP(handleConnectHC);
|
||||
PREP(handleDisconnect);
|
||||
PREP(handleInitPost);
|
||||
PREP(moduleInit);
|
||||
PREP(rebalance);
|
||||
PREP(transferGroups);
|
||||
|
||||
if (isServer) then {
|
||||
GVAR(headlessClients) = [];
|
||||
GVAR(inRebalance) = false;
|
||||
["ACE_HeadlessClientJoined", FUNC(handleConnectHC)] call EFUNC(common,addEventHandler);
|
||||
};
|
||||
|
||||
ADDON = true;
|
17
addons/headless/config.cpp
Normal file
17
addons/headless/config.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ace_common"};
|
||||
author[]= {"Jonpas"};
|
||||
authorUrl = "https://github.com/jonpas";
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
||||
#include "ACE_Settings.hpp"
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgVehicles.hpp"
|
31
addons/headless/functions/fnc_handleConnectHC.sqf
Normal file
31
addons/headless/functions/fnc_handleConnectHC.sqf
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Registers connected Headless Client for use.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Headless Client <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [headlessClient] call ace_headless_handleConnectHC;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_headlessClient"];
|
||||
|
||||
// Exit if already registered
|
||||
if (_headlessClient in GVAR(headlessClients)) exitWith {};
|
||||
|
||||
// Register for use
|
||||
GVAR(headlessClients) pushBack _headlessClient;
|
||||
|
||||
if (GVAR(Log)) then {
|
||||
ACE_LOGINFO_1("Registered HC: %1",_headlessClient);
|
||||
};
|
||||
|
||||
// Rebalance
|
||||
[true] call FUNC(rebalance);
|
34
addons/headless/functions/fnc_handleDisconnect.sqf
Normal file
34
addons/headless/functions/fnc_handleDisconnect.sqf
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Removes Headless Client from use.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Object <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Transfer To Server <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [unit] call ace_headless_handleDisconnect;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_object"];
|
||||
|
||||
// Exit if not HC
|
||||
if !(_object in GVAR(headlessClients)) exitWith {};
|
||||
|
||||
// Remove HC
|
||||
GVAR(headlessClients) deleteAt (GVAR(headlessClients) find _object);
|
||||
|
||||
if (GVAR(Log)) then {
|
||||
ACE_LOGINFO_1("Removed HC: %1",_object);
|
||||
};
|
||||
|
||||
// Rebalance
|
||||
[true] call FUNC(rebalance);
|
||||
|
||||
// Prevent transferring of HC to server
|
||||
false
|
31
addons/headless/functions/fnc_handleInitPost.sqf
Normal file
31
addons/headless/functions/fnc_handleInitPost.sqf
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Request a rebalance.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Object <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [object] call ace_headless_handleInitPost;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_object"];
|
||||
|
||||
TRACE_1("InitPost",_object);
|
||||
|
||||
// Delay until settings are initialized (for checking if HC trasnferring is enabled)
|
||||
if (!EGVAR(common,settingsInitFinished)) exitWith {
|
||||
EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(handleInitPost), _this];
|
||||
};
|
||||
|
||||
// Exit if HC transferring disabled or object not a unit (including unit inside vehicle) or is player
|
||||
if (!GVAR(Enabled) || {!(_object in allUnits)} || {isPlayer _object}) exitWith {};
|
||||
|
||||
// Rebalance
|
||||
[false] call FUNC(rebalance);
|
27
addons/headless/functions/fnc_moduleInit.sqf
Normal file
27
addons/headless/functions/fnc_moduleInit.sqf
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Initializes the Headless module.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The module logic <LOGIC>
|
||||
* 1: Units <ARRAY> (Unused)
|
||||
* 2: Activated <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (!isServer) exitWith {};
|
||||
|
||||
params ["_logic", "", "_activated"];
|
||||
|
||||
if (!_activated) exitWith {};
|
||||
|
||||
[_logic, QGVAR(Enabled), "Enabled"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(Delay), "Delay"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(Log), "Log"] call EFUNC(common,readSettingFromModule);
|
||||
|
||||
ACE_LOGINFO("Headless Module Initialized.");
|
29
addons/headless/functions/fnc_rebalance.sqf
Normal file
29
addons/headless/functions/fnc_rebalance.sqf
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Rebalance AI groups accross HCs.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Force <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [false] call ace_headless_rebalance;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_force"];
|
||||
|
||||
TRACE_3("Rebalance",GVAR(inRebalance),GVAR(headlessClients),_force);
|
||||
|
||||
// Exit if waiting for rebalance or no HCs present
|
||||
if (GVAR(inRebalance) || {GVAR(headlessClients) isEqualTo []}) exitWith {};
|
||||
|
||||
// Transfer after rebalance delay
|
||||
[FUNC(transferGroups), [_force], GVAR(Delay)] call EFUNC(common,waitAndExecute);
|
||||
|
||||
// Currently in rebalance flag
|
||||
GVAR(inRebalance) = true;
|
148
addons/headless/functions/fnc_transferGroups.sqf
Normal file
148
addons/headless/functions/fnc_transferGroups.sqf
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Transfers AI groups to Headess Client(s).
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Force <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [false] call ace_headless_fnc_transferGroups;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_force"];
|
||||
|
||||
GVAR(headlessClients) params [
|
||||
["_HC1", objNull, [objNull] ],
|
||||
["_HC2", objNull, [objNull] ],
|
||||
["_HC3", objNull, [objNull] ]
|
||||
];
|
||||
|
||||
if (GVAR(Log)) then {
|
||||
ACE_LOGINFO_2("Present HCs: %1 - Full Rebalance: %2",GVAR(headlessClients),_force);
|
||||
};
|
||||
|
||||
|
||||
// Enable round-robin load balancing if more than one HC is present
|
||||
private _loadBalance = [false, true] select (count GVAR(headlessClients) > 1);
|
||||
|
||||
|
||||
// Get IDs and determine first HC to start with
|
||||
private _idHC1 = -1;
|
||||
private _idHC2 = -1;
|
||||
private _idHC3 = -1;
|
||||
private _currentHC = 0;
|
||||
|
||||
if (!local _HC1) then {
|
||||
_idHC1 = owner _HC1;
|
||||
_currentHC = 1;
|
||||
};
|
||||
|
||||
if (!local _HC2) then {
|
||||
_idHC2 = owner _HC2;
|
||||
|
||||
if (_currentHC == 0) then {
|
||||
_currentHC = 2;
|
||||
};
|
||||
};
|
||||
|
||||
if (!local _HC3) then {
|
||||
_idHC3 = owner _HC3;
|
||||
|
||||
if (_currentHC == 0) then {
|
||||
_currentHC = 3;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Prepare statistics
|
||||
private _numTransferredHC1 = 0;
|
||||
private _numTransferredHC2 = 0;
|
||||
private _numTransferredHC3 = 0;
|
||||
|
||||
|
||||
// Transfer AI groups
|
||||
{
|
||||
private _transfer = true;
|
||||
|
||||
// No transfer if empty group
|
||||
if (_x isEqualTo []) then {
|
||||
_transfer = false;
|
||||
};
|
||||
|
||||
if (_transfer) then {
|
||||
{
|
||||
// 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 any unit in group is blacklisted
|
||||
if (_x getVariable [QGVAR(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 [QGVAR(blacklist), false]}) exitWith {
|
||||
_transfer = false;
|
||||
};
|
||||
} forEach (units _x);
|
||||
};
|
||||
|
||||
|
||||
// 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;
|
||||
};
|
||||
};
|
||||
case 2: {
|
||||
private _transferred = _x setGroupOwner _idHC2;
|
||||
if (_loadBalance) then {
|
||||
_currentHC = [1, 3] select (!local _HC3);
|
||||
};
|
||||
if (_transferred) then {
|
||||
_numTransferredHC2 = _numTransferredHC2 + 1;
|
||||
};
|
||||
};
|
||||
case 3: {
|
||||
private _transferred = _x setGroupOwner _idHC3;
|
||||
if (_loadBalance) then {
|
||||
_currentHC = [2, 1] select (!local _HC1);
|
||||
};
|
||||
if (_transferred) then {
|
||||
_numTransferredHC3 = _numTransferredHC3 + 1;
|
||||
};
|
||||
};
|
||||
default {
|
||||
TRACE_1("No Valid HC to transfer to",_currentHC);
|
||||
};
|
||||
};
|
||||
};
|
||||
} forEach allGroups;
|
||||
|
||||
|
||||
if (GVAR(Log)) then {
|
||||
private _numTransferredTotal = _numTransferredHC1 + _numTransferredHC2 + _numTransferredHC3;
|
||||
ACE_LOGINFO_4("Groups Transferred: Total: %1 - HC1: %2 - HC2: %3 - HC3: %4",_numTransferredTotal,_numTransferredHC1,_numTransferredHC2,_numTransferredHC3);
|
||||
};
|
||||
|
||||
|
||||
// Allow rebalance flag
|
||||
GVAR(inRebalance) = false;
|
1
addons/headless/functions/script_component.hpp
Normal file
1
addons/headless/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\headless\script_component.hpp"
|
15
addons/headless/script_component.hpp
Normal file
15
addons/headless/script_component.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#define COMPONENT headless
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
#ifdef DEBUG_ENABLED_HEADLESS
|
||||
#define DEBUG_MODE_FULL
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SETTINGS_HEADLESS
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_HEADLESS
|
||||
#endif
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
|
||||
#define DELAY_DEFAULT 15
|
33
addons/headless/stringtable.xml
Normal file
33
addons/headless/stringtable.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="ACE">
|
||||
<Package name="Headless">
|
||||
<Key ID="STR_ACE_Headless_Module">
|
||||
<English>Headless</English>
|
||||
<German>Headless</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Headless_ModuleDesc">
|
||||
<English>This module allows you to setup automatic transferring of AI to Headless Clients. (Default: No)</English>
|
||||
<German>Dieses Modul erlaubt es dir, die KI automatisch auf einen Headless Client zu transferieren. (Standard: Nein) </German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Headless_EnabledDesc">
|
||||
<English>Enables transferring of AI to Headless Clients.</English>
|
||||
<German>Aktiviert denTransfer der KI auf Headless Clients.</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Headless_Delay">
|
||||
<English>Delay</English>
|
||||
<German>Verzögerung</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Headless_DelayDesc">
|
||||
<English>Minimal delay between transfers, in seconds. (Default: 15)</English>
|
||||
<German>Minimale Verzögerung zwischen Transfers in Sekunden. (Standard: 15)</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Headless_Log">
|
||||
<English>Log</English>
|
||||
<German>Protokolldatei anlegen</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Headless_LogDesc">
|
||||
<English>Log transfer statistics and Headless Client (dis)connections to RPT. (Default: No)</English>
|
||||
<German>Zeichnet Transferstatistiken, Verbindungen und Verbindungsabbrüche in einer RPT-Datei auf. (Standard: Nein)</German>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user