Skip to content

Commit

Permalink
God Mode - Expand and Improve (IDI-Systems#1001)
Browse files Browse the repository at this point in the history
Co-authored-by: Ferran Obon <[email protected]>
  • Loading branch information
jonpas and TheMagnetar authored Aug 13, 2020
1 parent 5537e54 commit 1f363d0
Show file tree
Hide file tree
Showing 35 changed files with 434 additions and 142 deletions.
2 changes: 2 additions & 0 deletions addons/api/CfgFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ class CfgFunctions {
class GodMode {
PATHTO_FNC(godModeConfigureAccess);
PATHTO_FNC(godModeModifyGroup);
PATHTO_FNC(godModeNameGroup);
PATHTO_FNC(godModeSendText);
PATHTO_FNC(godModeGetGroupTargets);
};
};

Expand Down
3 changes: 2 additions & 1 deletion addons/api/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class CfgPatches {
"acre_sys_prc148",
"acre_sys_prc77",
"acre_sys_prc343",
"acre_sys_core"
"acre_sys_core",
"acre_sys_godmode"
};
author = ECSTRING(main,Author);
authors[] = {"Jaynus", "Nou"};
Expand Down
37 changes: 37 additions & 0 deletions addons/api/fnc_godModeGetGroupTargets.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "script_component.hpp"
/*
* Author: ACRE2Team
* Returns given group's current targets.
*
* Arguments:
* 1: Group (0-based index or -1 for current channel) <NUMBER> (default: 0)
*
* Return Value:
* Group targets <ARRAY>
*
* Example:
* [0] call acre_api_fnc_godModeGetGroupTargets
*
* Public: Yes
*/

params [["_group", 0, [0]]];

private _targets = [];

if ((_group < -1) || {_group >= GODMODE_NUMBER_OF_GROUPS}) exitWith {
ERROR_1("Invalid group ID. Group ID must be between -1 and %1, but %2 is entered.",GODMODE_NUMBER_OF_GROUPS-1,_group);
[]
};

if (_group < -1) then {
_targets = [] call EFUNC(sys_godmode,getUnitsBIChannel);
} else {
_targets = EGVAR(sys_godmode,groupPresets) select _group;
};

if (_targets isEqualType {}) then {
_targets = call _targets;
};

_targets
20 changes: 16 additions & 4 deletions addons/api/fnc_godModeModifyGroup.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@
* Modifies who can hear a message from God Mode.
*
* Arguments:
* 0: Unit or array of units <OJECT, ARRAY> (default: [])
* 0: Unit or UID or array of either or code returning array of units <OBJECT, STRING, ARRAY, CODE> (default: [])
* 1: Group to effect (0-based index) <NUMBER> (default: 0)
* 2: Action. 0 for set, 1 for add and 2 for subtract <NUMBER> (default: 0)
*
* Return Value:
* Text message sent successfully <BOOL>
* Group modified successfully <BOOL>
*
* Example:
* [[unit1, unit2], 0, 1] call acre_api_fnc_godModeModifyGroup
* [["76561198040512062", "76561198046921073"], 0, 1] call acre_api_fnc_godModeModifyGroup
* [{allUnits select {alive _x}}, 0, 1] call acre_api_fnc_godModeModifyGroup
*
* Public: Yes
*/

params [
["_units", [], [objNull, []]],
["_units", [], [objNull, "", [], {}]],
["_group", 0, [0]],
["_action", 0, [0]]
];
Expand All @@ -33,7 +35,17 @@ if ((_action < GODMODE_ACTION_SET) || {_action > GODMODE_ACTION_SUBTRACT}) exitW
false
};

if !(_units isEqualType []) then {
if ((_units isEqualType {}) && {_action != GODMODE_ACTION_SET}) exitWith {
ERROR_2("Invalid action %1. Only %2 (set) is supported for code argument.",_action,GODMODE_ACTION_SET);
false
};

if ((_units isEqualType {}) && {(EGVAR(sys_godmode,groupPresets) select _group) isEqualType {}}) exitWith {
ERROR_2("Invalid action %1. Only %2 (set) is supported when code exists in group.",_action,GODMODE_ACTION_SET);
false
};

if (!(_units isEqualType []) && {!(_units isEqualType {})}) then {
_units = [_units];
};

Expand Down
36 changes: 36 additions & 0 deletions addons/api/fnc_godModeNameGroup.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "script_component.hpp"
/*
* Author: ACRE2Team
* Sets a visible name for the given God Mode group.
*
* Arguments:
* 0: Name <STRING>
* 1: Group to effect (0-based index) <NUMBER> (default: 0)
*
* Return Value:
* Group name set successfully <BOOL>
*
* Example:
* ["Admin", 0] call acre_api_fnc_godModeNameGroup
*
* Public: Yes
*/

params [
["_name", "", [""]],
["_group", 0, [0]]
];

if ((_group < 0) || {_group >= GODMODE_NUMBER_OF_GROUPS}) exitWith {
ERROR_1("Invalid group ID. Group ID must be between 0 and %1, but %2 is entered.",GODMODE_NUMBER_OF_GROUPS-1,_group);
false
};

if (_name == "") exitWith {
ERROR_1("Invalid name for group ID %1. Name must not be empty!",_group);
false
};

[_name, _group] call EFUNC(sys_godmode,nameGroup);

true
12 changes: 12 additions & 0 deletions addons/main/script_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ Antenna Defines

#define AVERAGE_MAN_HEIGHT 1.8288

/*
Speaking Type Defines
SQF equivalent of extensions/src/ACRE2Shared/Types.h
*/
#define SPEAKING_TYPE_DIRECT 0
#define SPEAKING_TYPE_RADIO 1
#define SPEAKING_TYPE_UNKNOWN 2
#define SPEAKING_TYPE_INTERCOM 3
#define SPEAKING_TYPE_SPECTATE 4
#define SPEAKING_TYPE_GOD 5
#define SPEAKING_TYPE_ZEUS 6


#define MACRO_ADDWEAPON(WEAPON,COUNT) class _xx_##WEAPON { \
weapon = #WEAPON; \
Expand Down
11 changes: 10 additions & 1 deletion addons/sys_core/fnc_addDisplayPassthroughKeys.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,19 @@ if (isNull _display) exitWith {false};
// Toggle Headset
_display displayAddEventHandler ["KeyDown", {
params ["", "_key", "_shift", "_ctrl", "_alt"];

if ([_key, [_shift, _ctrl, _alt]] in ((["ACRE2", "HeadSet"] call CBA_fnc_getKeybind) select 8)) then {
[] call FUNC(toggleHeadset);
};

false
}];

true
private _return = true;

// God Mode
if (isClass (configFile >> "CfgPatches" >> "acre_sys_godmode")) then {
_return = [_display] call EFUNC(sys_godmode,addDisplayPassthroughKeys);
};

_return
11 changes: 7 additions & 4 deletions addons/sys_core/fnc_localStartSpeaking.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Arguments:
* 0: Speaking ID <STRING> (unused)
* 1: Net id of local player object <STRING> (unused)
* 2: On radio ("0" for false, "1" for true) <STRING>
* 2: Speaking Type <STRING>
* 3: Radio ID if talking on radio <STRING>
*
* Return Value:
Expand All @@ -19,11 +19,14 @@
*/

TRACE_1("LOCAL START SPEAKING ENTER", _this);
params ["", "", "_onRadio", ["_radioId", ""]];
_onRadio = _onRadio == "1";
params ["", "", "_speakingType", ["_radioId", ""]];

if (!(_speakingType isEqualType 0)) then { _speakingType = parseNumber _speakingType; };

private _onRadio = _speakingType == SPEAKING_TYPE_RADIO;

ACRE_LOCAL_SPEAKING = true;
["acre_startedSpeaking", [acre_player, _onRadio, _radioId]] call CBA_fnc_localEvent; // [unit, on radio, radio ID]
["acre_startedSpeaking", [acre_player, _onRadio, _radioId, _speakingType]] call CBA_fnc_localEvent; // [unit, speaking type, radio ID]

if (_onRadio) then {
ACRE_LOCAL_BROADCASTING = true;
Expand Down
2 changes: 1 addition & 1 deletion addons/sys_core/fnc_processDirectSpeaker.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private _zeusDistancePriority = false;

// Right now ACRE only supports one listener pos, use the closest position while in Zeus
if (_zeusAdjustments) then {
_speakingType = "g";
_speakingType = "z";
_zeusPos = getPosASL curatorCamera;
_zeusDistancePriority = (_zeusPos distance _emitterPos) < (_listenerPos distance _emitterPos);
if (_zeusDistancePriority) then {
Expand Down
20 changes: 10 additions & 10 deletions addons/sys_core/fnc_remoteStartSpeaking.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* 0: TeamSpeak ID of talking player <STRING>
* 1: Language ID <STRING>
* 2: Net ID of player object <STRING>
* 3: On radio <STRING>
* 3: Speaking Type <STRING>
* 4: Radio ID (default: ',') <STRING>
*
* Return Value:
Expand All @@ -33,15 +33,15 @@ CREATE_COUNTER(hearableRadios);
// PREP(processRadioSpeaker);

TRACE_1("START SPEAKING ENTER", _this);
params ["_speakingId","_languageId","_netId","_onRadio",["_radioId",","]];
params ["_speakingId","_languageId","_netId","_speakingType",["_radioId",","]];

if (!(_speakingId isEqualType 0)) then { _speakingId = parseNumber _speakingId; };
if (!(_languageId isEqualType 0)) then { _languageId = parseNumber _languageId; };
if (!(_onRadio isEqualType 0)) then { _onRadio = parseNumber _onRadio; };
if (!(_speakingType isEqualType 0)) then { _speakingType = parseNumber _speakingType; };


private _result = false;
//if (_onRadio != 1 || {_radioId != ACRE_BROADCASTING_RADIOID}) then {
//if (_speakingType != 1 || {_radioId != ACRE_BROADCASTING_RADIOID}) then {
private _unit = objectFromNetId _netId; // will be objNull if not found.

//Ensure unit wasn't previously speaking
Expand Down Expand Up @@ -79,7 +79,7 @@ private _result = false;
};

if (isNull _unit) exitWith {
WARNING_4("START SPEAKING: acre_player [%1] could not find a player with ID: %2 %3, On Radio: %4",acre_player,_speakingId,_netId,_onRadio);
WARNING_4("START SPEAKING: acre_player [%1] could not find a player with ID: %2 %3, Speaking Type: %4",acre_player,_speakingId,_netId,_speakingType);
false
};

Expand All @@ -89,12 +89,12 @@ private _result = false;
private _isMuted = IS_MUTED(_unit);
_unit setRandomLip true;

["acre_remoteStartedSpeaking", [_unit, _onRadio, _radioId]] call CBA_fnc_localEvent; // [unit, on radio, radio ID]
["acre_remoteStartedSpeaking", [_unit, _speakingType, _radioId]] call CBA_fnc_localEvent; // [unit, speaking type, radio ID]

if (!_isMuted) then {
TRACE_3("REMOTE STARTED SPEAKING",_speakingId,_onRadio,(_unit distance acre_player));
TRACE_3("REMOTE STARTED SPEAKING",_speakingId,_speakingType,(_unit distance acre_player));
_unit setVariable [QGVAR(lastSpeakingEventTime), diag_tickTime, false];
if (_onRadio == 1) then { // Radio
if (_speakingType == SPEAKING_TYPE_RADIO) then { // Radio
if ([_radioId] call EFUNC(sys_radio,radioExists)) then {
// Handle rack radios or shared manpack radios that are simultaneously in use.
if (_radioId in ACRE_ACCESSIBLE_RACK_RADIOS || {_radioId in ACRE_HEARABLE_RACK_RADIOS} || {_radioId in ACRE_EXTERNALLY_USED_MANPACK_RADIOS} || {_radioId in ACRE_ACTIVE_EXTERNAL_RADIOS}) then {
Expand Down Expand Up @@ -143,9 +143,9 @@ private _result = false;
WARNING_1("Got start speaking event with non-existent radio id: %1",_radioId);
};
} else {
if (_onRadio == 5) then { // God Mode / Zeus
if (_speakingType == SPEAKING_TYPE_GOD) then { // God Mode
GVAR(godSpeakers) pushBack _speakingId;
} else { // Direct / Intercom / Spectate / Unknown
} else { // Direct / Intercom / Spectate / Zeus / Unknown
if (_unit call FUNC(inRange)) then {
GVAR(speakers) pushBack _unit;
};
Expand Down
3 changes: 3 additions & 0 deletions addons/sys_core/fnc_remoteStopSpeaking.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,17 @@ _speakingId = parseNumber _speakingId;
ACRE_BROADCASTING_RADIOID = "";
};
};

if (_speakingId in ACRE_SPECTATORS_LIST) then {
_found = true;
REM(GVAR(spectatorSpeakers), _speakingId);
};

if (_speakingId in GVAR(godSpeakers)) then {
_found = true;
REM(GVAR(godSpeakers), _speakingId);
};

if (!_found) then {
private _msg = format ["STOP SPEAKING: Player [%1] could not find a player with ID: %2 %3", acre_player, _speakingId, _netId];
WARNING(_msg);
Expand Down
8 changes: 6 additions & 2 deletions addons/sys_core/fnc_speaking.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,12 @@ if !(GVAR(keyedMicRadios) isEqualTo []) then {

{
private _speakingId = _x;
private _params = ["g", _speakingId, 0, GVAR(godVolume)];
CALL_RPC("updateSpeakingData", _params);

// Check speaking gods to only allow hearing by the god's target group
if ((EGVAR(sys_godmode,speakingGods) find _speakingId) != -1) then {
private _params = ["g", _speakingId, 0, GVAR(godVolume)];
CALL_RPC("updateSpeakingData", _params);
};
} forEach GVAR(godSpeakers);

if (ACRE_IS_SPECTATOR) then {
Expand Down
3 changes: 2 additions & 1 deletion addons/sys_godmode/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
PREP(accessAllowed);
PREP(addDisplayPassthroughKeys);
PREP(getUnitsBIChannel);
PREP(handlePttKeyPress);
PREP(handlePttKeyPressUp);
PREP(modifyAllowedUIDS);
PREP(modifyGroup);
PREP(nameGroup);
PREP(sendText);
30 changes: 20 additions & 10 deletions addons/sys_godmode/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,49 @@ if (!hasInterface) exitWith {};

// CBA Event Handlers
[QGVAR(startSpeaking), {
params ["_speakingUnit", "_channel", "_channelEx"];
params ["_speakingId", "_speakingName", "_channel", "_channelEx"];

#ifndef ALLOW_SELF_RX
if (_speakingId == EGVAR(sys_core,ts3id)) exitWith {};
#endif

GVAR(speakingGods) pushBackUnique _speakingId;

if (GVAR(rxNotification)) then {
_channel = localize _channel;
if (_channelEx != "") then {
_channel = format ["%1 (%2)", _channel, localize _channelEx];
if (isLocalized _channelEx) then {
_channelEx = localize _channelEx;
};
_channel = format ["%1 (%2)", _channel, _channelEx];
};

private _notificationLayer = [
format ["RX: %1", localize LSTRING(god)],
_channel,
name _speakingUnit,
_speakingName,
-1,
GVAR(rxNotificationColor)
] call EFUNC(sys_list,displayHint);
GVAR(rxNotificationLayers) setVariable [getPlayerUID _speakingUnit, _notificationLayer];
GVAR(rxNotificationLayers) setVariable [str _speakingId, _notificationLayer];
};
}] call CBA_fnc_addEventHandler;

[QGVAR(stopSpeaking), {
params ["_speakingUnit"];
params ["_speakingId"];

GVAR(speakingGods) deleteAt (GVAR(speakingGods) find _speakingId);

private _speakingUID = getPlayerUID _speakingUnit;
private _notificationLayer = GVAR(rxNotificationLayers) getVariable [_speakingUID, ""];
private _notificationLayer = GVAR(rxNotificationLayers) getVariable [str _speakingId, ""];
if (_notificationLayer != "") then {
[_notificationLayer] call EFUNC(sys_list,hideHint);
GVAR(rxNotificationLayers) setVariable [_speakingUID, ""];
GVAR(rxNotificationLayers) setVariable [str _speakingId, ""];
}
}] call CBA_fnc_addEventHandler;

[QGVAR(showText), {
params ["_text"];
systemChat format ["God: %1", _text];
params ["_speakingName", "_text"];
systemChat format ["God (%1): %2", _speakingName, _text];
}] call CBA_fnc_addEventHandler;

// Keybinds - God Mode
Expand Down
2 changes: 2 additions & 0 deletions addons/sys_godmode/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ PREP_RECOMPILE_END;
if (hasInterface) then {
GVAR(targetUnits) = [];
GVAR(groupPresets) = [[], [], []];
GVAR(groupNames) = ["", "", ""];
GVAR(speakingGods) = [];
GVAR(accessAllowed) = [false, false];
GVAR(txNotificationLayer) = ""; // Name of the notification system layer where the current God TX is displayed
GVAR(rxNotificationLayers) = call CBA_fnc_createNamespace; // Name of the notification system layer where the current God RX is displayed
Expand Down
Loading

0 comments on commit 1f363d0

Please sign in to comment.