ACE3/addons/spectator/functions/fnc_setSpectator.sqf

174 lines
4.9 KiB
Plaintext

/*
* Author: SilentSpike
* Sets local client to the given spectator state (virtually)
* To physically handle a spectator see ace_spectator_fnc_stageSpectator
*
* Client will be able to communicate in ACRE/TFAR as appropriate
* The spectator interface will be opened/closed
*
* Arguments:
* 0: Spectator state of local client <BOOL> (default: true)
* 1: Force interface <BOOL> (default: true)
*
* Return Value:
* None <NIL>
*
* Example:
* [true] call ace_spectator_fnc_setSpectator
*
* Public: Yes
*/
#include "script_component.hpp"
params [["_set",true,[true]], ["_force",true,[true]]];
// Only clients can be spectators
if !(hasInterface) exitWith {};
// Exit if no change
if (_set isEqualTo GVAR(isSet)) exitWith {};
// Handle common addon audio
if (["ace_hearing"] call EFUNC(common,isModLoaded)) then {
EGVAR(hearing,disableVolumeUpdate) = _set;
EGVAR(hearing,deafnessDV) = 0;
};
if (["acre_sys_radio"] call EFUNC(common,isModLoaded)) then {[_set] call acre_api_fnc_setSpectator};
if (["task_force_radio"] call EFUNC(common,isModLoaded)) then {[player, _set] call TFAR_fnc_forceSpectator};
if (_set) then {
// Initalize camera variables
GVAR(camBoom) = 0;
GVAR(camDolly) = [0,0];
GVAR(camGun) = false;
// Initalize display variables
GVAR(ctrlKey) = false;
GVAR(heldKeys) = [];
GVAR(heldKeys) resize 255;
GVAR(mouse) = [false,false];
GVAR(mousePos) = [0.5,0.5];
// Update units before opening to support pre-set camera unit
[] call FUNC(updateUnits);
// Initalize the camera objects
GVAR(freeCamera) = "Camera" camCreate (ASLtoATL GVAR(camPos));
GVAR(unitCamera) = "Camera" camCreate [0,0,0];
GVAR(targetCamera) = "Camera" camCreate [0,0,0];
// Initalize view
GVAR(unitCamera) camSetTarget GVAR(targetCamera);
GVAR(unitCamera) camCommit 0;
[] call FUNC(transitionCamera);
// Cache current channel to switch back to on exit
GVAR(channelCache) = currentChannel;
// Channel index starts count after the 5 default channels
GVAR(channel) radioChannelAdd [player];
setCurrentChannel (5 + GVAR(channel));
// Close map and clear the chat
openMap [false,false];
clearRadio;
enableRadio false;
// Disable BI damage effects
BIS_fnc_feedback_allowPP = false;
// Close any open dialogs
while {dialog} do {
closeDialog 0;
};
[{
disableSerialization;
// Create the display
_display = (findDisplay 46) createDisplay QGVAR(interface);
// If not forced, make esc end spectator
if (_this) then {
_display displayAddEventHandler ["KeyDown", {
if (_this select 1 == 1) then {
[false] call FUNC(setSpectator);
true
};
}];
};
}, !_force] call CBA_fnc_execNextFrame;
// Cache and disable nametag settings
if (["ace_nametags"] call EFUNC(common,isModLoaded)) then {
GVAR(nametagSettingCache) = [EGVAR(nametags,showPlayerNames), EGVAR(nametags,showNamesForAI)];
EGVAR(nametags,showPlayerNames) = 0;
EGVAR(nametags,showNamesForAI) = false;
};
} else {
// Close any open dialogs (could be interrupts)
while {dialog} do {
closeDialog 0;
};
// Kill the display
(GETUVAR(GVAR(interface),displayNull)) closeDisplay 0;
// Terminate camera
GVAR(freeCamera) cameraEffect ["terminate", "back"];
camDestroy GVAR(freeCamera);
camDestroy GVAR(unitCamera);
camDestroy GVAR(targetCamera);
// Remove from spectator chat
GVAR(channel) radioChannelRemove [player];
// Restore cached channel and delete cache
setCurrentChannel GVAR(channelCache);
GVAR(channelCache) = nil;
// Clear any residual spectator chat
clearRadio;
enableRadio true;
// Return to player view
player switchCamera "internal";
// Enable BI damage effects
BIS_fnc_feedback_allowPP = true;
// Cleanup camera variables
GVAR(camBoom) = nil;
GVAR(camDolly) = nil;
GVAR(camGun) = nil;
GVAR(freeCamera) = nil;
GVAR(unitCamera) = nil;
GVAR(targetCamera) = nil;
//Kill these PFEH handlers now because the PFEH can run before the `onunload` event is handled
GVAR(camHandler) = nil;
GVAR(compHandler) = nil;
GVAR(toolHandler) = nil;
// Cleanup display variables
GVAR(ctrlKey) = nil;
GVAR(heldKeys) = nil;
GVAR(mouse) = nil;
GVAR(mousePos) = nil;
// Reset nametag settings
if (["ace_nametags"] call EFUNC(common,isModLoaded)) then {
EGVAR(nametags,showPlayerNames) = GVAR(nametagSettingCache) select 0;
EGVAR(nametags,showNamesForAI) = GVAR(nametagSettingCache) select 1;
GVAR(nametagSettingCache) = nil;
};
};
// Reset interruptions
GVAR(interrupts) = [];
// Mark spectator state for reference
GVAR(isSet) = _set;
["spectatorSet",[_set]] call EFUNC(common,localEvent);