/* * 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 (default: true) * 1: Force interface (default: true) * * Return Value: * None * * 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 ace_spectator_fnc_setSpectator; true }; }]; }; }, !_force] call EFUNC(common,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);