Merge branch 'remove-spectator' into release

This commit is contained in:
SilentSpike 2015-07-27 21:30:24 +01:00
commit a31e5795be
33 changed files with 0 additions and 2229 deletions

View File

@ -1 +0,0 @@
z\ace\addons\spectator

View File

@ -1,30 +0,0 @@
class ACE_Settings {
class GVAR(onDeath) {
typeName = "BOOL";
value = 0;
};
class GVAR(filterUnits) {
typeName = "SCALAR";
value = 1;
values[] = {CSTRING(units_none), CSTRING(units_players), CSTRING(units_all)};
};
class GVAR(filterSides) {
typeName = "SCALAR";
value = 0;
values[] = {CSTRING(sides_player), CSTRING(sides_friendly), CSTRING(sides_hostile), CSTRING(sides_all)};
};
class GVAR(restrictModes) {
typeName = "SCALAR";
value = 0;
values[] = {CSTRING(modes_all), CSTRING(modes_unit), CSTRING(modes_free), CSTRING(modes_internal), CSTRING(modes_external)};
};
class GVAR(restrictVisions) {
typeName = "SCALAR";
value = 0;
values[] = {CSTRING(modes_all), CSTRING(visions_nv), CSTRING(visions_ti), "$STR_Special_None"};
};
class GVAR(unitIcons) {
typeName = "BOOL";
value = 1;
};
};

View File

@ -1,11 +0,0 @@
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));
};
};

View File

@ -1,125 +0,0 @@
class CfgVehicles {
class ACE_Module;
class GVAR(moduleSettings): ACE_Module {
scope = 2;
displayName = CSTRING(Settings_DisplayName);
icon = PATHTOF(UI\Icon_Module_Spectator_ca.paa);
category = "ACE";
function = QFUNC(moduleSpectatorSettings);
isGlobal = 1;
author = ECSTRING(common,ACETeam);
class Arguments {
class systemEnable {
displayName = CSTRING(system_DisplayName);
description = CSTRING(system_Description);
typeName = "BOOL";
defaultValue = 0;
};
class unitsFilter {
displayName = CSTRING(units_DisplayName);
description = CSTRING(units_Description);
typeName = "NUMBER";
class values {
class none {
name = CSTRING(units_none);
value = 0;
};
class players {
name = CSTRING(units_players);
value = 1;
default = 1;
};
class all {
name = CSTRING(units_all);
value = 2;
};
};
};
class sidesFilter {
displayName = CSTRING(sides_DisplayName);
description = CSTRING(sides_Description);
typeName = "NUMBER";
class values {
class player {
name = CSTRING(sides_player);
value = 0;
default = 1;
};
class friendly {
name = CSTRING(sides_friendly);
value = 1;
};
class hostile {
name = CSTRING(sides_hostile);
value = 2;
};
class all {
name = CSTRING(sides_all);
value = 3;
};
};
};
class cameraModes {
displayName = CSTRING(modes_DisplayName);
description = CSTRING(modes_Description);
typeName = "NUMBER";
class values {
class all {
name = CSTRING(modes_all);
value = 0;
default = 1;
};
class unit {
name = CSTRING(modes_unit);
value = 1;
};
class free {
name = CSTRING(modes_free);
value = 2;
};
class internal {
name = CSTRING(modes_internal);
value = 3;
};
class external {
name = CSTRING(modes_external);
value = 4;
};
};
};
class visionModes {
displayName = CSTRING(visions_DisplayName);
description = CSTRING(visions_Description);
typeName = "NUMBER";
class values {
class all {
name = CSTRING(modes_all);
value = 0;
default = 1;
};
class nv {
name = CSTRING(visions_nv);
value = 1;
};
class ti {
name = CSTRING(visions_ti);
value = 2;
};
class none {
name = "$STR_Special_None";
value = 3;
};
};
};
class unitIcons {
displayName = CSTRING(icons_DisplayName);
description = CSTRING(icons_Description);
typeName = "BOOL";
defaultValue = 1;
};
};
class ModuleDescription {
description = CSTRING(Settings_Description);
};
};
};

View File

@ -1,10 +0,0 @@
ace_spectator
=======
Spectator. Includes features from Splendid Cam, and much more.
## Maintainers
The people responsible for merging changes to this component or answering potential questions.
- [SilentSpike](https://github.com/SilentSpike)

View File

@ -1,210 +0,0 @@
class RscButtonMenu;
class RscControlsGroupNoScrollbars;
class RscFrame;
class RscListNBox;
class RscMapControl;
class RscPicture;
class RscText;
class RscTree;
class GVAR(interface) {
idd = 12249;
enableSimulation = 1;
movingEnable = 0;
onLoad = QUOTE([ARR_2('onLoad',_this)] call FUNC(handleInterface));
onUnload = QUOTE([ARR_2('onUnload',_this)] call FUNC(handleInterface));
onKeyDown = QUOTE([ARR_2('onKeyDown',_this)] call FUNC(handleInterface));
onKeyUp = QUOTE([ARR_2('onKeyUp',_this)] call FUNC(handleInterface));
class controlsBackground {
class mouseHandler: RscControlsGroupNoScrollbars {
x = safeZoneXAbs;
y = safeZoneY;
w = safeZoneWAbs;
h = safeZoneH;
onMouseButtonDown = QUOTE([ARR_2('onMouseButtonDown',_this)] call FUNC(handleInterface));
onMouseButtonUp = QUOTE([ARR_2('onMouseButtonUp',_this)] call FUNC(handleInterface));
onMouseZChanged = QUOTE([ARR_2('onMouseZChanged',_this)] call FUNC(handleInterface));
onMouseMoving = QUOTE([ARR_2('onMouseMoving',_this)] call FUNC(handleInterface));
onMouseHolding = QUOTE([ARR_2('onMouseMoving',_this)] call FUNC(handleInterface));
};
};
class controls {
class compass: RscControlsGroupNoScrollbars {
idc = IDC_COMP;
x = COMPASS_X;
y = safeZoneY;
w = COMPASS_W;
h = TOOL_H;
class controls {
class compassBack: RscText {
x = 0;
y = 0;
w = COMPASS_W;
h = TOOL_H;
colorBackground[] = {COL_BACK};
};
class compass0_90: RscPicture {
idc = IDC_COMP_0;
x = COMPASS_W * 0.5;
y = 0;
w = COMPASS_W * 0.5;
h = TOOL_H;
text = "A3\UI_F_Curator\Data\CfgIngameUI\compass\texture180_ca.paa";
};
class compass90_180: compass0_90 {
idc = IDC_COMP_90;
x = COMPASS_W;
text = "A3\UI_F_Curator\Data\CfgIngameUI\compass\texture270_ca.paa";
};
class compass180_270: compass0_90 {
idc = IDC_COMP_180;
x = 0;
text = "A3\UI_F_Curator\Data\CfgIngameUI\compass\texture0_ca.paa";
};
class compass270_0: compass0_90 {
idc = IDC_COMP_270;
x = COMPASS_W * -0.5;
text = "A3\UI_F_Curator\Data\CfgIngameUI\compass\texture90_ca.paa";
};
class compassCaret: RscFrame {
x = COMPASS_W * 0.5;
y = 0;
w = 0;
h = TOOL_H;
colorText[] = {COL_FORE};
};
class compassFrame: compassBack {
style = 64;
shadow=2;
colorText[] = {COL_FORE};
};
};
};
class toolbar: RscControlsGroupNoScrollbars {
idc = IDC_TOOL;
x = safeZoneX;
y = safeZoneY + safeZoneH - TOOL_H;
w = safeZoneW;
h = TOOL_H;
class controls {
class nameTool: RscText {
idc = IDC_TOOL_NAME;
style = 2;
x = 0;
y = 0;
w = TOOL_W * 2;
h = TOOL_H;
shadow = 2;
colorText[]={COL_FORE};
colorBackground[] = {COL_BACK};
sizeEx = H_PART(1);
};
class nameFrame: nameTool {
idc = -1;
style = 64;
};
class viewTool: nameTool {
idc = IDC_TOOL_VIEW;
x = TOOL_W * 2 + MARGIN;
w = TOOL_W;
};
class viewFrame: viewTool {
idc = -1;
style = 64;
};
class fovTool: viewTool {
idc = IDC_TOOL_FOV;
x = TOOL_W * 3 + MARGIN * 2;
};
class fovFrame: fovTool {
idc = -1;
style = 64;
};
class clockTool: viewTool {
idc = IDC_TOOL_CLOCK;
x = safeZoneW - TOOL_W * 3 - MARGIN * 2;
};
class clockFrame: clockTool {
idc = -1;
style = 64;
};
class visionTool: viewTool {
idc = IDC_TOOL_VISION;
x = safeZoneW - TOOL_W * 2 - MARGIN;
};
class visionFrame: visionTool {
idc = -1;
style = 64;
};
class speedTool: viewTool {
idc = IDC_TOOL_SPEED;
x = safeZoneW - TOOL_W;
};
class speedFrame: speedTool {
idc = -1;
style = 64;
};
};
};
class unitTree: RscTree {
idc = IDC_UNIT;
x = safeZoneX;
y = safeZoneY + TOOL_H * 2;
w = TOOL_W * 2;
h = safeZoneH - TOOL_H * 4;
sizeEx = H_PART(0.8);
borderSize = 1;
colorBorder[] = {COL_FORE};
colorBackground[] = {COL_BACK};
colorSelect[] = {
"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.77])",
"(profilenamespace getvariable ['GUI_BCG_RGB_G',0.51])",
"(profilenamespace getvariable ['GUI_BCG_RGB_B',0.08])",
1
};
multiselectEnabled = 0;
onTreeDblClick = QUOTE([ARR_2('onTreeDblClick',_this)] call FUNC(handleInterface));
};
class mapOverlay: RscMapControl {
idc = IDC_MAP;
x = safeZoneX;
y = safeZoneY;
w = safeZoneW;
h = safeZoneH;
onMouseButtonDblClick = QUOTE([ARR_2('onMapDblClick',_this)] call FUNC(handleInterface));
onDraw = QUOTE([ARR_2('onDraw',_this)] call FUNC(handleInterface));
};
class helpSplash: RscControlsGroupNoScrollbars {
idc = IDC_HELP;
x = 0.5 - W_PART(12);
y = 0.5 - H_PART(12);
w = W_PART(24);
h = H_PART(24);
class controls {
class helpBack: RscText {
x = 0;
y = 0;
w = W_PART(24);
h = H_PART(24);
colorBackground[] = {COL_BACK};
};
class helpTitle: helpBack {
h = H_PART(1);
colorText[]={COL_FORE};
colorBackground[] = {COL_FORE_D};
sizeEx = H_PART(1);
text = CSTRING(HelpTitle);
};
class helpContent: RscListNBox {
idc = IDC_HELP_LIST;
x = W_PART(1);
y = H_PART(2);
W = W_PART(22);
H = H_PART(21);
default = 1;
columns[] = {0.01,0.5};
};
};
};
};
};

View File

@ -1,17 +0,0 @@
#include "script_component.hpp"
//#include "initKeybinds.sqf";
// Add interaction menu exception
["isNotSpectating", {!((_this select 0) getVariable [QGVAR(isSpectator), false])}] call EFUNC(common,addCanInteractWithCondition);
["SettingsInitialized", {
GVAR(availableModes) = [[0,1,2], [1,2], [0], [1], [2]] select GVAR(restrictModes);
GVAR(availableVisions) = [[-2,-1,0,1], [-2,-1], [-2,0,1], [-2]] select GVAR(restrictVisions);
if !(hasInterface) exitWith {};
if (GVAR(onDeath)) then {
player addEventHandler ["Killed",FUNC(handleKilled)];
player addEventHandler ["Respawn",FUNC(handleRespawn)];
};
}] call EFUNC(common,addEventHandler);

View File

@ -1,52 +0,0 @@
#include "script_component.hpp"
ADDON = false;
PREP(cacheUnitInfo);
PREP(cycleCamera);
PREP(handleCamera);
PREP(handleCompass);
PREP(handleIcons);
PREP(handleInterface);
PREP(handleKilled);
PREP(handleMouse);
PREP(handleRespawn);
PREP(handleToolbar);
PREP(handleUnits);
PREP(moduleSpectatorSettings);
PREP(setCameraAttributes);
PREP(setSpectator);
PREP(transitionCamera);
PREP(toggleInterface);
PREP(updateCameraModes);
PREP(updateSpectatableSides);
PREP(updateUnits);
PREP(updateVisionModes);
// Permanent variables
GVAR(availableModes) = [0,1,2];
GVAR(availableSides) = [west,east,resistance,civilian];
GVAR(availableVisions) = [-2,-1,0,1];
GVAR(camMode) = 0;
GVAR(camPan) = 0;
GVAR(camPos) = ATLtoASL [worldSize * 0.5, worldSize * 0.5, 20];
GVAR(camSpeed) = 1;
GVAR(camTilt) = -10;
GVAR(camUnit) = objNull;
GVAR(camVision) = -2;
GVAR(camZoom) = 1.25;
GVAR(showComp) = true;
GVAR(showHelp) = true;
GVAR(showIcons) = true;
GVAR(showInterface) = true;
GVAR(showMap) = false;
GVAR(showTool) = true;
GVAR(showUnit) = true;
GVAR(unitList) = [];
GVAR(unitBlacklist) = [];
GVAR(unitWhitelist) = [];
ADDON = true;

View File

@ -1,18 +0,0 @@
#include "script_component.hpp"
class CfgPatches {
class ADDON {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_common"};
author[] = {"F3 Project","Head","SilentSpike","voiper"};
authorUrl = "https://github.com/acemod";
VERSION_CONFIG;
};
};
#include "ACE_Settings.hpp"
#include "CfgEventHandlers.hpp"
#include "CfgVehicles.hpp"
#include "ui\interface.hpp"

View File

@ -1,33 +0,0 @@
/*
* Author: SilentSpike
* Caches the units information for quick retrevial in spectator interface PFHs
*
* Arguments:
* 0: Unit to have info cached for <OBJECT>
*
* Return Value:
* None <NIL>
*
* Example:
* [vehicle player] call ace_spectator_fnc_cacheUnitInfo
*
* Public: No
*/
#include "script_component.hpp"
params ["_unit"];
private ["_color","_icon","_name"];
_color = [side group _unit] call BIS_fnc_sideColor;
_icon = getText (configFile >> "CfgVehicles" >> typeOf _unit >> "Icon");
_name = [_unit,false] call EFUNC(common,getName);
// Handle CfgVehicleIcons
if isText (configFile >> "CfgVehicleIcons" >> _icon) then {
_icon = getText (configFile >> "CfgVehicleIcons" >> _icon);
};
SETVAR(_unit,GVAR(uColor),_color);
SETVAR(_unit,GVAR(uIcon),_icon);
SETVAR(_unit,GVAR(uName),_name);

View File

@ -1,58 +0,0 @@
/*
* Author: SilentSpike
* Cycle through the spectator camera vision/view/units in steps
*
* Arguments:
* 0: Camera mode steps <NUMBER>
* 1: Camera unit steps <NUMBER>
* 2: Vision mode steps <NUMBER>
*
* Return Value:
* None <NIL>
*
* Example:
* [0, -1] call ace_spectator_fnc_cycleCamera
*
* Public: No
*/
#include "script_component.hpp"
params [["_stepMode",0], ["_stepUnit",0], ["_stepVision",0]];
private ["_modes","_visions","_iMode","_iVision","_countModes","_countVisions","_newMode","_newVision","_newUnit"];
_modes = GVAR(availableModes);
_units = GVAR(unitList);
_visions = GVAR(availableVisions);
// Get current index
_iMode = (_modes find GVAR(camMode)) max 0;
_iUnit = (_units find GVAR(camUnit)) max 0;
_iVision = (_visions find GVAR(camVision)) max 0;
_countModes = count _modes;
_countUnits = count _units;
_countVisions = count _visions;
// Step index by step number (loop at ends)
if (_countModes != 0) then {
_iMode = (_iMode + _stepMode) % _countModes;
if (_iMode < 0) then { _iMode = _countModes + _iMode; };
};
if (_countUnits != 0) then {
_iUnit = (_iUnit + _stepUnit) % _countUnits;
if (_iUnit < 0) then { _iUnit = _countUnits + _iUnit; };
};
if (_countVisions != 0) then {
_iVision = (_iVision + _stepVision) % _countVisions;
if (_iVision < 0) then { _iVision = _countVisions + _iVision; };
};
// Get value at new index
_newMode = _modes select _iMode;
_newUnit = _units select _iUnit;
_newVision = _visions select _iVision;
[_newMode, _newUnit, _newVision] call FUNC(transitionCamera);

View File

@ -1,41 +0,0 @@
/*
* Author: F3 Project, Head, SilentSpike
* Handles free camera manipulation according to input
*
* Arguments:
* 0: Parameters <ANY>
* 1: PFH handle <NUMBER>
*
* Return Value:
* None <NIL>
*
* Example:
* [ace_spectator_fnc_handleCamera, 0] call CBA_fnc_addPerFrameHandler;
*
* Public: No
*/
#include "script_component.hpp"
// Kill PFH when not in free cam (or display is closed)
if (isNil QGVAR(camHandler)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; };
private ["_oldPos","_mX","_mY","_mZ","_pan","_x","_y","_z"];
_oldPos = getPosASL GVAR(camera);
_mX = GVAR(camDolly) select 0;
_mY = GVAR(camDolly) select 1;
_mZ = GVAR(camBoom);
_pan = (GVAR(camPan) + 360) % 360;
_x = (_oldPos select 0) + (_mX * cos(_pan)) + (_mY * sin(_pan));
_y = (_oldPos select 1) - (_mX * sin(_pan)) + (_mY * cos(_pan));
_z = (_oldPos select 2) + _mZ;
// Prevent camera going under terrain
GVAR(camPos) = [_x,_y,_z max (getTerrainHeightASL [_x,_y])];
// Update camera position and rotation
GVAR(camera) setPosASL GVAR(camPos);
GVAR(camera) setDir GVAR(camPan);
[GVAR(camera), GVAR(camTilt), 0] call BIS_fnc_setPitchBank;

View File

@ -1,67 +0,0 @@
/*
* Author: SilentSpike, voiper
* Handles the spectator UI compass
*
* Arguments:
* 0: Parameters <ANY>
* 1: PFH handle <NUMBER>
*
* Return Value:
* None <NIL>
*
* Example:
* [ace_spectator_fnc_handleCompass, 0, _display] call CBA_fnc_addPerFrameHandler;
*
* Public: No
*/
#include "script_component.hpp"
params ["_display"];
// Kill PFH when compass hidden (or display is closed)
if (isNil QGVAR(compHandler)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; };
private ["_compass","_NE","_ES","_SW","_WN","_compassW","_degree","_heading","_offset","_positions","_sequence"];
_compass = _display displayCtrl IDC_COMP;
_NE = _compass controlsGroupCtrl IDC_COMP_0;
_ES = _compass controlsGroupCtrl IDC_COMP_90;
_SW = _compass controlsGroupCtrl IDC_COMP_180;
_WN = _compass controlsGroupCtrl IDC_COMP_270;
_compassW = (ctrlPosition _compass) select 2;
_degree = _compassW / 180;
// Get direction of screen rather than object (accounts for unit freelook)
_heading = (positionCameraToWorld [0,0,1]) vectorDiff (positionCameraToWorld [0,0,0]);
_heading = (((_heading select 0) atan2 (_heading select 1)) + 360) % 360;
_offset = -(_heading % 90) * _degree;
_positions = [
[_compassW * -0.5 + _offset, 0],
[_offset, 0],
[_compassW * 0.5 + _offset, 0],
[_compassW + _offset, 0]
];
_sequence = if (_heading < 90) then {
[_SW, _WN, _NE, _ES]
} else {
if (_heading < 180) then {
[_WN, _NE, _ES, _SW]
} else {
if (_heading < 270) then {
[_NE, _ES, _SW, _WN]
} else {
[_ES, _SW, _WN, _NE]
};
};
};
{
_x ctrlSetPosition (_positions select _forEachIndex);
_x ctrlCommit 0;
} forEach _sequence;

View File

@ -1,57 +0,0 @@
/*
* Author: SilentSpike
* Handles rendering the spectator 3D unit icons
*
* Arguments:
* 0: Parameters <ANY>
* 1: PFH handle <NUMBER>
*
* Return Value:
* None <NIL>
*
* Example:
* [ace_spectator_fnc_handleIcons, 0] call CBA_fnc_addPerFrameHandler;
*
* Public: No
*/
#include "script_component.hpp"
// Kill PFH when not in free cam (or display is closed)
if (isNil QGVAR(iconHandler)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; };
if !(GVAR(showIcons)) exitWith {};
private ["_cachedVehicles","_unit","_cameraPos","_cameraDir","_lambda","_uPos","_cmd","_txt"];
_cachedVehicles = [];
{
_unit = vehicle _x;
// Only try each vehicle once
if !(_unit in _cachedVehicles) then {
_cachedVehicles pushBack _unit;
// Within 200m
if ((GVAR(camera) distanceSqr _unit) < 40000) then {
_cameraPos = (positionCameraToWorld [0, 0, 0]) call EFUNC(common,positionToASL);
_cameraDir = ((positionCameraToWorld [0, 0, 1]) call EFUNC(common,positionToASL)) vectorDiff _cameraPos;
// Quick oclussion test (taken from interact_menu)
_lambda = ((getPosASL _x) vectorDiff _cameraPos) vectorDotProduct _cameraDir;
if (_lambda > -1) then {
_uPos = worldToScreen (visiblePosition _unit);
// Only draw if onscreen
if ((_uPos select 0 > safeZoneXAbs) && (_uPos select 0 < safeZoneXAbs + safeZoneWAbs)) then {
if ((_uPos select 1 > safeZoneY) && (_uPos select 1 < safeZoneY + safeZoneH)) then {
// Use commander's info if available
_cmd = [_x, effectiveCommander _unit] select ((effectiveCommander _unit) in GVAR(unitList));
_txt = ["", GETVAR(_cmd,GVAR(uName),"")] select (isPlayer _cmd);
drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", GETVAR(_cmd,GVAR(uColor),[ARR_4(0,0,0,0)]), _unit modelToWorldVisual [0,0,3], 0.7, 0.7, 0, _txt, 1, 0.02];
};
};
};
};
};
} forEach GVAR(unitList);

View File

@ -1,485 +0,0 @@
/*
* Author: SilentSpike
* Handles spectator interface events
*
* Arguments:
* 0: Event name <STRING>
* 1: Event arguments <ANY>
*
* Return Value:
* None <NIL>
*
* Example:
* ["onLoad",_this] call ace_spectator_fnc_handleInterface
*
* Public: No
*/
#include "script_component.hpp"
params ["_mode",["_args",[]]];
switch (toLower _mode) do {
// Safely open/close the interface
case "open": {
// Prevent reopening
if !(isNull (GETUVAR(GVAR(display),displayNull))) exitWith {};
// Initalize camera variables
GVAR(camBoom) = 0;
GVAR(camDolly) = [0,0];
GVAR(camGun) = false;
// Initalize display variables
GVAR(ctrlKey) = false;
GVAR(heldKeys) = [];
GVAR(mouse) = [false,false];
GVAR(mousePos) = [0.5,0.5];
// Initalize the camera view
GVAR(camera) = "Camera" camCreate (ASLtoATL GVAR(camPos));
[] call FUNC(transitionCamera);
// Close all existing dialogs
while {dialog} do {
closeDialog 0;
};
// Create the dialog
createDialog QGVAR(interface);
// 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;
};
};
case "close": {
// Can't close a second time
if (isNull (GETUVAR(GVAR(display),displayNull))) exitWith {};
// Terminate interface
while {dialog} do {
closeDialog 0;
};
GETUVAR(GVAR(display),displayNull) closeDisplay 0;
// Terminate camera
GVAR(camera) cameraEffect ["terminate", "back"];
camDestroy GVAR(camera);
// Return to player view
ACE_Player switchCamera "internal";
// Cleanup camera variables
GVAR(camera) = nil;
GVAR(camBoom) = nil;
GVAR(camDolly) = nil;
GVAR(camGun) = 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;
};
};
// Dialog events
case "onload": {
_args params ["_display"];
with uiNamespace do {
GVAR(display) = _display;
};
// Always show interface and hide map upon opening
[_display,nil,nil,!GVAR(showInterface),GVAR(showMap)] call FUNC(toggleInterface);
// Keep unit list and tree up to date
[FUNC(handleUnits), 21, _display] call CBA_fnc_addPerFrameHandler;
// Populate the help splash
private "_help";
_help = (_display displayCtrl IDC_HELP) controlsGroupCtrl IDC_HELP_LIST;
{
// Add space before category titles
if (count _x == 1) then {
_help lnbAddRow [""];
};
_help lnbAddRow _x;
} forEach [
[localize LSTRING(uiControls),""],
[localize LSTRING(uiToggleHelp),"H"],
[localize LSTRING(uiToggleMap),"M"],
[localize LSTRING(uiToggleUnits),"1"],
[localize LSTRING(uiToggleTools),"2"],
[localize LSTRING(uiToggleCompass),"3"],
[localize LSTRING(uiToggleIcons),"4"],
[localize LSTRING(uiToggleInterface),"Backspace"],
[localize LSTRING(freeCamControls)],
[localize LSTRING(freeCamForward),"W"],
[localize LSTRING(freeCamBackward),"S"],
[localize LSTRING(freeCamLeft),"A"],
[localize LSTRING(freeCamRight),"D"],
[localize LSTRING(freeCamUp),"Q"],
[localize LSTRING(freeCamDown),"Z"],
[localize LSTRING(freeCamPan),"RMB (Hold)"],
[localize LSTRING(freeCamDolly),"LMB (Hold)"],
[localize LSTRING(freeCamSpeed),"Scrollwheel"],
[localize LSTRING(freeCamZoom),"Ctrl + Scrollwheel"],
[localize LSTRING(freeCamNextVis),"N"],
[localize LSTRING(freeCamPrevVis),"Ctrl + N"],
[localize LSTRING(otherControls)],
[localize LSTRING(nextCam),"Up Arrow"],
[localize LSTRING(prevCam),"Down Arrow"],
[localize LSTRING(nextUnit),"Right Arrow"],
[localize LSTRING(prevUnit),"Left Arrow"]
];
// Hacky way to enable keybindings
//_display displayAddEventHandler ["KeyUp", {[_this,'keyup'] call CBA_events_fnc_keyHandler}];
//_display displayAddEventHandler ["KeyDown", {[_this,'keydown'] call CBA_events_fnc_keyHandler}];
};
case "onunload": {
with uiNamespace do {
GVAR(display) = nil;
};
GVAR(camHandler) = nil;
GVAR(compHandler) = nil;
GVAR(iconHandler) = nil;
GVAR(toolHandler) = nil;
};
// Mouse events
case "onmousebuttondown": {
_args params ["_ctrl","_button"];
GVAR(mouse) set [_button,true];
// Detect right click
if ((_button == 1) && (GVAR(camMode) == 1)) then {
// In first person toggle sights mode
GVAR(camGun) = !GVAR(camGun);
[] call FUNC(transitionCamera);
};
};
case "onmousebuttonup": {
_args params ["_ctrl","_button"];
GVAR(mouse) set [_button,false];
if (_button == 0) then { GVAR(camDolly) = [0,0]; };
};
case "onmousezchanged": {
_args params ["_ctrl","_zChange"];
// Scroll to change speed, modifier for zoom
if (GVAR(ctrlKey)) then {
[nil,nil,nil,nil,nil,nil, GVAR(camZoom) + _zChange * 0.1] call FUNC(setCameraAttributes);
} else {
[nil,nil,nil,nil,nil,nil,nil, GVAR(camSpeed) + _zChange * 0.2] call FUNC(setCameraAttributes);
};
};
case "onmousemoving": {
_args params ["_ctrl","_x","_y"];
[_x,_y] call FUNC(handleMouse);
};
// Keyboard events
case "onkeydown": {
_args params ["_display","_dik","_shift","_ctrl","_alt"];
// Handle held keys (prevent repeat calling)
if (_dik in GVAR(heldKeys)) exitwith {};
// Exclude movement keys so that speed can be adjusted on fly
if !(_dik in [17,30,31,32]) then {
GVAR(heldKeys) pushBack _dik;
};
switch (_dik) do {
case 1: { // Esc
["escape", [_display]] call FUNC(handleInterface);
};
case 2: { // 1
[_display,nil,nil,nil,nil,nil,true] call FUNC(toggleInterface);
};
case 3: { // 2
[_display,nil,nil,nil,nil,true] call FUNC(toggleInterface);
};
case 4: { // 3
[_display,true] call FUNC(toggleInterface);
};
case 5: { // 4
GVAR(showIcons) = !GVAR(showIcons);
};
case 14: { // Backspace
[_display,nil,nil,true] call FUNC(toggleInterface);
};
case 16: { // Q
GVAR(camBoom) = 0.5;
};
case 17: { // W
GVAR(camDolly) set [1, GVAR(camSpeed)];
};
case 29: { // Ctrl
GVAR(ctrlKey) = true;
};
case 30: { // A
GVAR(camDolly) set [0, -GVAR(camSpeed)];
};
case 31: { // S
GVAR(camDolly) set [1, -GVAR(camSpeed)];
};
case 32: { // D
GVAR(camDolly) set [0, GVAR(camSpeed)];
};
case 35: { // H
[_display,nil,true] call FUNC(toggleInterface);
};
case 44: { // Z
GVAR(camBoom) = -0.5;
};
case 49: { // N
if (_ctrl) then {
[nil,nil,-1] call FUNC(cycleCamera);
} else {
[nil,nil,1] call FUNC(cycleCamera);
};
};
case 50: { // M
[_display,nil,nil,nil,true] call FUNC(toggleInterface);
};
case 57: { // Spacebar
// Freecam attachment here, if in external then set cam pos and attach
};
case 200: { // Up arrow
[-1] call FUNC(cycleCamera);
};
case 203: { // Left arrow
[nil,1] call FUNC(cycleCamera);
};
case 205: { // Right arrow
[nil,-1] call FUNC(cycleCamera);
};
case 208: { // Down arrow
[1] call FUNC(cycleCamera);
};
};
true
};
case "onkeyup": {
_args params ["_display","_dik","_shift","_ctrl","_alt"];
// No longer being held
GVAR(heldKeys) = GVAR(heldKeys) - [_dik];
switch (_dik) do {
case 16: { // Q
GVAR(camBoom) = 0;
};
case 17: { // W
GVAR(camDolly) set [1, 0];
};
case 29: { // Ctrl
GVAR(ctrlKey) = false;
};
case 30: { // A
GVAR(camDolly) set [0, 0];
};
case 31: { // S
GVAR(camDolly) set [1, 0];
};
case 32: { // D
GVAR(camDolly) set [0, 0];
};
case 44: { // Z
GVAR(camBoom) = 0;
};
};
true
};
// Tree events
case "ontreedblclick": {
// Update camera view when listbox unit is double clicked on
_args params ["_tree","_sel"];
// Ensure a unit was selected
if (count _sel == 3) then {
private ["_netID","_newUnit","_newMode"];
_netID = (_args select 0) tvData _sel;
_newUnit = objectFromNetId _netID;
// When unit is reselected, toggle camera mode
if (_newUnit == GVAR(camUnit) || GVAR(camMode) == 0) then {
_newMode = [2,2,1] select GVAR(camMode);
};
[_newMode,_newUnit] call FUNC(transitionCamera);
};
};
case "onunitsupdate": {
_args params ["_tree"];
private ["_curSelData","_cachedGrps","_cachedSides","_grp","_side","_sNode","_gNode","_uNode"];
// Cache current selection
_curSelData = _tree tvData (tvCurSel _tree);
// Clear the tree
tvClear _tree;
// Update the tree from the unit list
_cachedGrps = [];
_cachedSides = [];
{
_grp = group _x;
_side = [side _grp] call BIS_fnc_sideName;
// Use correct side node
if !(_side in _cachedSides) then {
// Add side node
_sNode = _tree tvAdd [[], _side];
_cachedSides pushBack _side;
_cachedSides pushBack _sNode;
} else {
// If side already processed, use existing node
_sNode = _cachedSides select ((_cachedSides find _side) + 1);
};
// Use correct group node
if !(_grp in _cachedGrps) then {
// Add group node
_gNode = _tree tvAdd [[_sNode], groupID _grp];
_cachedGrps pushBack _grp;
_cachedGrps pushBack _gNode;
} else {
// If group already processed, use existing node
_gNode = _cachedGrps select ((_cachedGrps find _grp) + 1);
};
_uNode = _tree tvAdd [[_sNode,_gNode], GETVAR(_x,GVAR(uName),"")];
_tree tvSetData [[_sNode,_gNode,_uNode], netID _x];
// Preserve the previous selection
if (_curSelData == (_tree tvData [_sNode,_gNode,_uNode])) then {
_tree tvSetCurSel [_sNode,_gNode,_uNode];
};
_tree tvSort [[_sNode,_gNode],false];
_tree tvExpand [_sNode,_gNode];
} forEach GVAR(unitList);
{
if (typeName _x == "SCALAR") then {
_tree tvSort [[_x],false];
_tree tvExpand [_x];
};
} forEach _cachedSides;
_tree tvSort [[],false];
};
// Map events
case "onmapdblclick": {
_args params ["_map","_button","_x","_y"];
private ["_newPos","_oldZ"];
if ((GVAR(camMode) == 0) && (_button == 0)) then {
_newPos = _map ctrlMapScreenToWorld [_x,_y];
_oldZ = (ASLtoATL GVAR(camPos)) select 2;
_newPos set [2, _oldZ];
[nil,nil,nil, _newPos] call FUNC(setCameraAttributes);
};
};
case "ondraw": {
_args params ["_map"];
if (GVAR(camMode) == 0) then {
_map drawIcon ["\A3\UI_F\Data\GUI\Rsc\RscDisplayMissionEditor\iconcamera_ca.paa",[0,0,0,1],GVAR(camera),24,24,GVAR(camPan)];
};
if !(GVAR(showIcons)) exitWith {};
private ["_cachedVehicles","_unit","_color","_icon"];
_cachedVehicles = [];
{
_unit = vehicle _x;
if !(_unit in _cachedVehicles) then {
_cachedVehicles pushBack _unit;
// Use previously cached info where possible
if (isNil { GETVAR(_unit,GVAR(uIcon),nil) }) then {
[_unit] call FUNC(cacheUnitInfo);
};
_color = GETVAR(_unit,GVAR(uColor),[ARR_4(0,0,0,0)]);
_icon = GETVAR(_unit,GVAR(uIcon),"");
_map drawIcon [_icon, _color, _unit, 24, 24, getDir _unit];
};
} forEach GVAR(unitList);
};
// Other
case "escape": {
_args params ["_display"];
private ["_dlg","_key","_index","_ctrl","_config"];
// Kill display
_display closeDisplay 0;
// Reset cam/UI vars
GVAR(camBoom) = 0;
GVAR(camDolly) = [0,0];
GVAR(ctrlKey) = false;
GVAR(heldKeys) = [];
GVAR(mouse) = [false,false];
GVAR(mousePos) = [0.5,0.5];
// Below is from EFUNC(common,disableUserInput)
createDialog (["RscDisplayInterrupt", "RscDisplayMPInterrupt"] select isMultiplayer);
disableSerialization;
_dlg = finddisplay 49;
_dlg displayAddEventHandler ["KeyDown", {
_key = _this select 1;
!(_key == 1)
}];
for "_index" from 100 to 2000 do {
(_dlg displayCtrl _index) ctrlEnable false;
};
_ctrl = _dlg displayctrl 103;
_ctrl ctrlSetEventHandler ["buttonClick", QUOTE(while {dialog} do {closeDialog 0}; failMission 'LOSER';)];
_ctrl ctrlEnable true;
_ctrl ctrlSetText "ABORT";
_ctrl ctrlSetTooltip "Abort.";
_ctrl = _dlg displayctrl ([104, 1010] select isMultiplayer);
_ctrl ctrlSetEventHandler ["buttonClick", QUOTE(closeDialog 0; player setDamage 1;)];
_ctrl ctrlEnable (call {_config = missionConfigFile >> "respawnButton"; !isNumber _config || {getNumber _config == 1}});
_ctrl ctrlSetText "RESPAWN";
_ctrl ctrlSetTooltip "Respawn.";
// PFH to re-open display when menu closes
[{
if !(isNull (findDisplay 49)) exitWith {};
createDialog QGVAR(interface);
[] call FUNC(transitionCamera);
[_this select 1] call CBA_fnc_removePerFrameHandler;
},0] call CBA_fnc_addPerFrameHandler;
};
};

View File

@ -1,27 +0,0 @@
/*
* Author: SilentSpike
* Cache necessary details and process unit for spectator on death
* Part of the basic spectator system
*
* Arguments:
* 0: Corpse <OBJECT>
* 1: Killer <OBJECT>
*
* Return Value:
* None <NIL>
*
* Public: No
*/
#include "script_component.hpp"
params ["_unit","_killer"];
// Remove from group to prevent appearing on HUD upon respawn
[_unit, true, QGVAR(isSpectator), side group _unit] call EFUNC(common,switchToGroupSide);
if (isNull _killer) then {
[2,_unit] call FUNC(setCameraAttributes);
} else {
[2,_killer] call FUNC(setCameraAttributes);
};

View File

@ -1,43 +0,0 @@
/*
* Author: F3 Project, Head, SilentSpike
* Processes the change in mouse position for the spectator camera
*
* Arguments:
* 0: Mouse x coord <NUMBER>
* 1: Mouse y coord <NUMBER>
*
* Return Value:
* None <NIL>
*
* Example:
* [0.5, 0.5] call ace_spectator_fnc_handleMouse;
*
* Public: No
*/
#include "script_component.hpp"
params ["_x","_y"];
private ["_leftButton","_rightButton","_oldX","_oldY","_deltaX","_deltaY"];
_leftButton = GVAR(mouse) select 0;
_rightButton = GVAR(mouse) select 1;
_oldX = GVAR(mousePos) select 0;
_oldY = GVAR(mousePos) select 1;
// Get change in pos
_deltaX = _oldX - _x;
_deltaY = _oldY - _y;
if (_leftButton) then {
GVAR(camDolly) set [0, _deltaX * -100 * GVAR(camSpeed)];
GVAR(camDolly) set [1, _deltaY * 100 * GVAR(camSpeed)];
} else {
if (_rightButton) then {
GVAR(camPan) = GVAR(camPan) - (_deltaX * 360);
GVAR(camTilt) = ((GVAR(camTilt) + (_deltaY * 180)) min 89) max -89;
};
};
GVAR(mousePos) = [_x,_y];

View File

@ -1,18 +0,0 @@
/*
* Author: SilentSpike
* Start the interface on respawn
* Part of the basic spectator system
*
* Arguments:
* 0: New unit <OBJECT>
* 1: Old unit <OBJECT>
*
* Return Value:
* None <NIL>
*
* Public: No
*/
#include "script_component.hpp"
[_this select 0] call FUNC(setSpectator);

View File

@ -1,54 +0,0 @@
/*
* Author: Karel Moricky, SilentSpike
* Handles the spectator UI toolbar values and applies them to the camera
*
* Arguments:
* 0: Parameters <ANY>
* 1: PFH handle <NUMBER>
*
* Return Value:
* None <NIL>
*
* Example:
* [ace_spectator_fnc_handleToolbar, 0, _display] call CBA_fnc_addPerFrameHandler;
*
* Public: No
*/
#include "script_component.hpp"
params ["_display"];
// Kill PFH when toolbar hidden (or display is closed)
if (isNil QGVAR(toolHandler)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; };
private ["_name","_vision","_fov","_speed","_mode","_time","_toolbar"];
_toolbar = _display displayCtrl IDC_TOOL;
// Find all tool values
if (GVAR(camMode) == 0) then {
_vision = if (GVAR(camVision) >= 0) then {localize LSTRING(VisionThermal)} else { [localize LSTRING(VisionNight), localize LSTRING(VisionNormal)] select (GVAR(camVision) < -1) };
_fov = format ["%1x", floor(GVAR(camZoom) * 100) * 0.01];
_speed = format ["%1 m/s", floor(GVAR(camSpeed) * 100) * 0.01];
} else {
_vision = format ["%1 m", floor(getPosASL GVAR(camUnit) select 2)];
_fov = [side group GVAR(camUnit)] call BIS_fnc_sideName;
_speed = format ["%1 km/h", floor(speed GVAR(camUnit)) max 0];
};
if (isNull GVAR(camUnit)) then {
_name = localize "STR_Special_None";
} else {
_name = GETVAR(GVAR(camUnit),GVAR(uName),"");
};
_mode = [localize LSTRING(ViewFree),localize LSTRING(ViewInternal),localize LSTRING(ViewExternal)] select GVAR(camMode);
_time = [daytime,"HH:MM"] call BIS_fnc_timeToString;
// Update the UI tools
(_toolbar controlsGroupCtrl IDC_TOOL_CLOCK) ctrlSetText _time;
(_toolbar controlsGroupCtrl IDC_TOOL_VISION) ctrlSetText _vision;
(_toolbar controlsGroupCtrl IDC_TOOL_FOV) ctrlSetText _fov;
(_toolbar controlsGroupCtrl IDC_TOOL_NAME) ctrlSetText _name;
(_toolbar controlsGroupCtrl IDC_TOOL_SPEED) ctrlSetText _speed;
(_toolbar controlsGroupCtrl IDC_TOOL_VIEW) ctrlSetText _mode;

View File

@ -1,38 +0,0 @@
/*
* Author: SilentSpike
* Maintains the spectatable unit list and updates the unit tree accordingly
* Also updates current camera unit when status changes
*
* Arguments:
* 0: Parameters <ANY>
* 1: PFH handle <NUMBER>
*
* Return Value:
* None <NIL>
*
* Example:
* [ace_spectator_fnc_handleUnits, 10, _display] call CBA_fnc_addPerFrameHandler;
*
* Public: No
*/
#include "script_component.hpp"
params ["_display"];
// Kill PFH when display is closed
if (isNull _display) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; };
// Remove all dead and null units from the list
[] call FUNC(updateUnits);
// Camera shouldn't stay on unit that isn't in the list
if !(GVAR(camUnit) in GVAR(unitList)) then {
[nil,1] call FUNC(cycleCamera);
};
// Reduce overhead when unit tree is hidden
if (ctrlShown (_display displayCtrl IDC_UNIT)) then {
// Reduce overhead by spreading across frames
[FUNC(handleInterface),["onUnitsUpdate",[_display displayCtrl IDC_UNIT]],1] call EFUNC(common,waitAndExecute);
};

View File

@ -1,27 +0,0 @@
/*
* Author: SilentSpike
* Read spectator settings from module
*
* Arguments:
* 0: The module logic <LOGIC>
* 1: units <ARRAY>
* 2: activated <BOOL>
*
* Return Value:
* None <NIL>
*
* Public: No
*/
#include "script_component.hpp"
params ["_logic", "_units", "_activated"];
if !(_activated) exitWith {};
[_logic, QGVAR(onDeath), "systemEnable"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(filterUnits), "unitsFilter"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(filterSides), "sidesFilter"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(restrictModes), "cameraModes"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(restrictVisions), "visionModes"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(unitIcons), "unitIcons"] call EFUNC(common,readSettingFromModule);

View File

@ -1,66 +0,0 @@
/*
* Author: SilentSpike
* Sets the spectator camera attributes as desired
*
* Arguments:
* 0: Camera mode <NUMBER> <OPTIONAL>
* - 0: Free
* - 1: Internal
* - 2: External
* 1: Camera unit (objNull for random) <OBJECT> <OPTIONAL>
* 2: Camera vision <NUMBER> <OPTIONAL>
* - -2: Normal
* - -1: Night vision
* - 0: Thermal white hot
* - 1: Thermal black hot
* 3: Camera position (ATL) <ARRAY> <OPTIONAL>
* 4: Camera pan (0 - 360) <NUMBER> <OPTIONAL>
* 5: Camera tilt (-90 - 90) <NUMBER> <OPTIONAL>
* 6: Camera zoom (0.01 - 2) <NUMBER> <OPTIONAL>
* 7: Camera speed in m/s (0.05 - 10) <NUMBER> <OPTIONAL>
*
* Return Value:
* None <NIL>
*
* Example:
* [1, objNull] call ace_spectator_fnc_setCameraAttributes
*
* Public: Yes
*/
#include "script_component.hpp"
params [
["_mode",GVAR(camMode),[0]],
["_unit",GVAR(camUnit),[objNull]],
["_vision",GVAR(camVision),[0]],
["_position",ASLtoATL GVAR(camPos),[[]],3],
["_heading",GVAR(camPan),[0]],
["_tilt",GVAR(camTilt),[0]],
["_zoom",GVAR(camZoom),[0]],
["_speed",GVAR(camSpeed),[0]]
];
// Normalize input
if !(_mode in GVAR(availableModes)) then {
_mode = GVAR(availableModes) select ((GVAR(availableModes) find GVAR(camMode)) max 0);
};
if !(_vision in GVAR(availableVisions)) then {
_vision = GVAR(availableVisions) select ((GVAR(availableVisions) find GVAR(camVision)) max 0);
};
GVAR(camPan) = _heading % 360;
GVAR(camPosition) = (ATLtoASL _position);
GVAR(camSpeed) = (_speed max 0.05) min 10;
GVAR(camTilt) = (_tilt max -89) min 89;
GVAR(camUnit) = _unit;
GVAR(camVision) = _vision;
GVAR(camZoom) = (_zoom min 2) max 0.01;
// Apply if camera exists
if !(isNil QGVAR(camera)) then {
[_mode,_unit,_vision] call FUNC(transitionCamera);
} else {
GVAR(camMode) = _mode;
};

View File

@ -1,77 +0,0 @@
/*
* Author: SilentSpike
* Sets target unit to the given spectator state
*
* Arguments:
* 0: Unit to put into spectator state <OBJECT>
* 1: New spectator state <BOOL> <OPTIONAL>
*
* Return Value:
* None <NIL>
*
* Example:
* [player, true] call ace_spectator_fnc_setSpectator
*
* Public: Yes
*/
#include "script_component.hpp"
params ["_unit",["_set",true,[true]],["_target",objNull,[objNull]]];
// No change, no service (but allow spectators who respawn to be reset)
if !(_set || (_unit getVariable [QGVAR(isSpectator), false])) exitWith {};
// Only run for player units
if !(isPlayer _unit) exitWith {};
if !(local _unit) exitwith {
[[_unit, _set, _target], QFUNC(setSpectator), _unit] call EFUNC(common,execRemoteFnc);
};
// Prevent player falling into water
_unit enableSimulation !_set;
// Move to/from group as appropriate
[_unit, _set, QGVAR(isSpectator), side group _unit] call EFUNC(common,switchToGroupSide);
if (_set) then {
// Move and hide the player ASAP to avoid being seen
_unit setPos (getMarkerPos QGVAR(respawn));
// Ghosts can't talk
[_unit, QGVAR(isSpectator)] call EFUNC(common,hideUnit);
[_unit, QGVAR(isSpectator)] call EFUNC(common,muteUnit);
["open"] call FUNC(handleInterface);
} else {
["close"] call FUNC(handleInterface);
// Physical beings can talk
[_unit, QGVAR(isSpectator)] call EFUNC(common,unhideUnit);
[_unit, QGVAR(isSpectator)] call EFUNC(common,unmuteUnit);
private "_marker";
_marker = ["respawn_west","respawn_east","respawn_guerrila","respawn_civilian"] select ([west,east,resistance,civilian] find (side group _unit));
_unit setPos (getMarkerPos _marker);
};
// Enable/disable input as appropriate
//[QGVAR(isSpectator), _set] call EFUNC(common,setDisableUserInputStatus);
// Handle common addon audio
if (["ace_hearing"] call EFUNC(common,isModLoaded)) then {EGVAR(hearing,disableVolumeUpdate) = _set};
if (["acre_sys_radio"] call EFUNC(common,isModLoaded)) then {[_set] call acre_api_fnc_setSpectator};
if (["task_force_radio"] call EFUNC(common,isModLoaded)) then {[_unit, _set] call TFAR_fnc_forceSpectator};
// Spectators ignore damage (vanilla and ace_medical)
_unit allowDamage !_set;
_unit setVariable [QEGVAR(medical,allowDamage), !_set];
// No theoretical change if an existing spectator was reset
if !(_set && (_unit getVariable [QGVAR(isSpectator), false])) then {
// Mark spectator state for reference
_unit setVariable [QGVAR(isSpectator), _set, true];
["spectatorChanged",[_set]] call EFUNC(common,localEvent);
};

View File

@ -1,89 +0,0 @@
/*
* Author: SilentSpike
* Correctly handles toggling of spectator interface elements for clean UX
*
* Arguments:
* 0: Display
* 1: Toogle compass <BOOL> <OPTIONAL>
* 2: Toogle help <BOOL> <OPTIONAL>
* 3: Toogle interface <BOOL> <OPTIONAL>
* 4: Toogle map <BOOL> <OPTIONAL>
* 5: Toogle toolbar <BOOL> <OPTIONAL>
* 6: Toogle unit list <BOOL> <OPTIONAL>
*
* Return Value:
* None <NIL>
*
* Example:
* [_dsiplay, nil, true] call ace_spectator_fnc_toggleInterface
*
* Public: No
*/
#include "script_component.hpp"
params ["_display", ["_toggleComp",false], ["_toggleHelp",false], ["_toggleInterface",false], ["_toggleMap",false], ["_toggleTool",false], ["_toggleUnit",false]];
private ["_comp","_help","_map","_tool","_unit"];
_comp = _display displayCtrl IDC_COMP;
_help = _display displayCtrl IDC_HELP;
_map = _display displayCtrl IDC_MAP;
_tool = _display displayCtrl IDC_TOOL;
_unit = _display displayCtrl IDC_UNIT;
// Map and help operate outside of interface
GVAR(showHelp) = [GVAR(showHelp), !GVAR(showHelp)] select _toggleHelp;
GVAR(showMap) = [GVAR(showMap), !GVAR(showMap)] select _toggleMap;
// When help changes with map open, minimise the map
if (GVAR(showMap) && _toggleHelp) then {
GVAR(showHelp) = true;
GVAR(showMap) = false;
};
_help ctrlShow GVAR(showHelp);
_map ctrlShow GVAR(showMap);
if (GVAR(showMap)) then {
// When map is shown, temporarily hide interface to stop overlapping
{
_x ctrlShow false;
} forEach [_comp,_help,_tool,_unit];
// Centre map on camera/unit upon opening
if (_toggleMap) then {
_map ctrlMapAnimAdd [0, 0.5, [GVAR(camUnit),GVAR(camera)] select (GVAR(camMode) == 0)];
ctrlMapAnimCommit _map;
};
} else {
// Can only toggle interface with map minimised
GVAR(showInterface) = [GVAR(showInterface), !GVAR(showInterface)] select _toggleInterface;
if (GVAR(showInterface)) then {
// Can only toggle interface elements with interface shown
GVAR(showComp) = [GVAR(showComp), !GVAR(showComp)] select _toggleComp;
GVAR(showTool) = [GVAR(showTool), !GVAR(showTool)] select _toggleTool;
GVAR(showUnit) = [GVAR(showUnit), !GVAR(showUnit)] select _toggleUnit;
_comp ctrlShow GVAR(showComp);
_tool ctrlShow GVAR(showTool);
_unit ctrlShow GVAR(showUnit);
} else {
{
_x ctrlShow false;
} forEach [_comp,_tool,_unit];
};
};
// Only run PFHs when respective control is shown, otherwise kill
if (ctrlShown _comp) then {
if (isNil QGVAR(compHandler)) then { GVAR(compHandler) = [FUNC(handleCompass), 0, _display] call CBA_fnc_addPerFrameHandler; };
} else {
GVAR(compHandler) = nil;
};
if (ctrlShown _tool) then {
if (isNil QGVAR(toolHandler)) then { GVAR(toolHandler) = [FUNC(handleToolbar), 0, _display] call CBA_fnc_addPerFrameHandler; };
} else {
GVAR(toolHandler) = nil;
};

View File

@ -1,112 +0,0 @@
/*
* Author: SilentSpike
* Transitions the spectator camera vision/view/unit
*
* Arguments:
* 0: Camera mode <NUMBER>
* - 0: Free
* - 1: Internal
* - 2: External
* 1: Camera unit <OBJECT>
* 2: Vision mode <NUMBER>
* - -2: Normal
* - -1: NV
* - 0: White hot
* - 1: Black hot
*
* Return Value:
* None <NIL>
*
* Example:
* [0,objNull] call ace_spectator_fnc_transitionCamera
*
* Public: No
*/
#include "script_component.hpp"
params [["_newMode",GVAR(camMode)], ["_newUnit",GVAR(camUnit)], ["_newVision",GVAR(camVision)]];
// If new mode isn't available then keep current (unless current also isn't)
if !(_newMode in GVAR(availableModes)) then {
_newMode = GVAR(availableModes) select ((GVAR(availableModes) find GVAR(camMode)) max 0);
};
// When no units available to spectate, exit to freecam
if (GVAR(unitList) isEqualTo []) then {
_newMode = 0;
_newUnit = objNull;
};
// Reset gun cam if not internal
if (_newMode != 1) then {
GVAR(camGun) = false;
};
if (_newMode == 0) then { // Free
// Preserve camUnit value for consistency when manually changing view
GVAR(camera) cameraEffect ["internal", "back"];
showCinemaBorder false;
cameraEffectEnableHUD true;
// Apply the camera zoom
GVAR(camera) camSetFov -(linearConversion [0.01,2,GVAR(camZoom),-2,-0.01,true]);
GVAR(camera) camCommit 0;
// Switch to camera to stop AI group chat
ACE_Player switchCamera "internal";
clearRadio;
// If new vision isn't available then keep current (unless current also isn't)
if !(_newVision in GVAR(availableVisions)) then {
_newVision = GVAR(availableVisions) select ((GVAR(availableVisions) find GVAR(camVision)) max 0);
};
// Vision mode only applies to free cam
if (_newVision < 0) then {
false setCamUseTi 0;
camUseNVG (_newVision >= -1);
} else {
true setCamUseTi _newVision;
};
GVAR(camVision) = _newVision;
// Handle camera movement
if (isNil QGVAR(camHandler)) then { GVAR(camHandler) = [FUNC(handleCamera), 0] call CBA_fnc_addPerFrameHandler; };
// Handle unit icons
if (GVAR(unitIcons)) then {
if (isNil QGVAR(iconHandler)) then { GVAR(iconHandler) = [FUNC(handleIcons), 0] call CBA_fnc_addPerFrameHandler; };
};
} else {
// When null unit is given choose random
if (isNull _newUnit) then {
_newUnit = GVAR(unitList) select floor(random(count GVAR(unitList)));
};
if (_newMode == 1) then { // Internal
// Handle gun cam
if (GVAR(camGun)) then {
_newUnit switchCamera "gunner";
} else {
_newUnit switchCamera "internal";
};
} else { // External
_newUnit switchCamera "external";
};
// Clear radio if group changed
if (group _newUnit != group GVAR(camUnit)) then {
clearRadio;
};
GVAR(camUnit) = _newUnit;
// Terminate camera view
GVAR(camera) cameraEffect ["terminate", "back"];
GVAR(camHandler) = nil;
GVAR(iconHandler) = nil;
cameraEffectEnableHUD true;
};
GVAR(camMode) = _newMode;

View File

@ -1,48 +0,0 @@
/*
* Author: SilentSpike
* Adds or removes spectator camera modes from the selection available to the local player.
* Possible camera modes are:
* - 0: Free
* - 1: Internal
* - 2: External
*
* Arguments:
* 0: Camera modes to add <ARRAY>
* 1: Camera modes to remove <ARRAY>
*
* Return Value:
* Available camera modes <ARRAY>
*
* Example:
* [[0], [1,2]] call ace_spectator_fnc_updateCameraModes
*
* Public: Yes
*/
#include "script_component.hpp"
params [["_addModes",[],[[]]], ["_removeModes",[],[[]]]];
private ["_newModes","_currentModes"];
_currentModes = GVAR(availableModes);
// Restrict additions to only possible values
_newModes = _addModes arrayIntersect [0,1,2];
_newModes append (_currentModes - _removeModes);
_newModes = _newModes arrayIntersect _newModes;
_newModes sort true;
// Can't become an empty array
if (_newModes isEqualTo []) then {
["Cannot remove all camera modes (%1)", QFUNC(updateCameraModes)] call BIS_fnc_error;
} else {
GVAR(availableModes) = _newModes;
};
// Update camera in case of change
if !(isNil QGVAR(camera)) then {
[] call FUNC(transitionCamera);
};
_newModes

View File

@ -1,33 +0,0 @@
/*
* Author: SilentSpike
* Adds or removes sides from the selection available to spectate by the local player.
* Note that the side filter setting is applied to the available sides dynamically.
*
* Default selection is [west,east,resistance,civilian]
*
* Arguments:
* 0: Sides to add <ARRAY>
* 1: Sides to remove <ARRAY>
*
* Return Value:
* Spectatable sides <ARRAY>
*
* Example:
* [[west], [east,civilian]] call ace_spectator_fnc_updateSpectatableSides
*
* Public: Yes
*/
#include "script_component.hpp"
params [["_addSides",[],[[]]], ["_removeSides",[],[[]]]];
// Add and remove sides
_addSides append (GVAR(availableSides) - _removeSides);
// Only need array of unique sides
_addSides = _addSides arrayIntersect _addSides;
GVAR(availableSides) = _addSides;
_addSides

View File

@ -1,72 +0,0 @@
/*
* Author: SilentSpike
* Adds units to spectator whitelist/blacklist and refreshes the filter units
*
* Arguments:
* 0: Units to add to the whitelist <ARRAY>
* 1: Use blacklist <BOOL> <OPTIONAL>
*
* Return Value:
* None <NIL>
*
* Example:
* [allUnits,true] call ace_spectator_fnc_updateUnits
*
* Public: Yes
*/
#include "script_component.hpp"
params [["_newUnits",[],[[]]],["_blacklist",false,[false]]];
// Function only matters on player clients
if !(hasInterface) exitWith {};
// If adding to a list we can exit here, since it won't show up until the UI refreshes anyway
if !(_newUnits isEqualTo []) exitWith {
if (_blacklist) then {
GVAR(unitWhitelist) = GVAR(unitWhitelist) - _newUnits;
GVAR(unitBlacklist) append _newUnits;
} else {
GVAR(unitBlacklist) = GVAR(unitBlacklist) - _newUnits;
GVAR(unitWhitelist) append _newUnits;
};
};
private ["_sides","_cond","_filteredUnits","_color","_icon"];
// Unit setting filter
_newUnits = [[],allPlayers,allUnits] select GVAR(filterUnits);
// Side setting filter
_sides = [];
_cond = [{_this == (side group player)},{(_this getFriend (side group player)) >= 0.6},{(_this getFriend (side group player)) < 0.6},{true}] select GVAR(filterSides);
{
if (_x call _cond) then {
_sides pushBack _x;
};
} forEach GVAR(availableSides);
// Filter units and append to list
_filteredUnits = [];
{
if (
(alive _x) &&
{(_x isKindOf "CAManBase")} &&
{(side group _x) in _sides} && // Side filter
{simulationEnabled _x} &&
{!(_x getVariable [QGVAR(isSpectator), false])} // Who watches the watchmen?
) then {
_filteredUnits pushBack _x;
};
} forEach (_newUnits - GVAR(unitBlacklist));
_filteredUnits append GVAR(unitWhitelist);
// Cache icons and colour for drawing
{
// Intentionally re-applied to units in case their status changes
[_x] call FUNC(cacheUnitInfo);
} forEach _filteredUnits;
// Replace previous list entirely (removes any no longer valid)
GVAR(unitList) = _filteredUnits arrayIntersect _filteredUnits;

View File

@ -1,56 +0,0 @@
/*
* Author: SilentSpike
* Adds or removes spectator vision modes from the selection available to the local player.
* The default selection is [-2,-1,0,1].
* Possible vision modes are:
* - -2: Normal
* - -1: Night vision
* - 0: White hot
* - 1: Black hot
* - 2: Light Green Hot / Darker Green cold
* - 3: Black Hot / Darker Green cold
* - 4: Light Red Hot / Darker Red Cold
* - 5: Black Hot / Darker Red Cold
* - 6: White Hot / Darker Red Cold
* - 7: Thermal (Shade of Red and Green, Bodies are white)
*
* Arguments:
* 0: Vision modes to add <ARRAY>
* 1: Vision modes to remove <ARRAY>
*
* Return Value:
* Available vision modes <ARRAY>
*
* Example:
* [[0], [1,2]] call ace_spectator_fnc_updateVisionModes
*
* Public: Yes
*/
#include "script_component.hpp"
params [["_addModes",[],[[]]], ["_removeModes",[],[[]]]];
private ["_newModes","_currentModes"];
_currentModes = GVAR(availableVisions);
// Restrict additions to only possible values
_newModes = _addModes arrayIntersect [-2,-1,0,1,2,3,4,5,6,7];
_newModes append (_currentModes - _removeModes);
_newModes = _newModes arrayIntersect _newModes;
_newModes sort true;
// Can't become an empty array
if (_newModes isEqualTo []) then {
["Cannot remove all vision modes (%1)", QFUNC(updateVisionModes)] call BIS_fnc_error;
} else {
GVAR(availableVisions) = _newModes;
};
// Update camera in case of change
if !(isNil QGVAR(camera)) then {
[] call FUNC(transitionCamera);
};
_newModes

View File

@ -1 +0,0 @@
#include "\z\ace\addons\spectator\script_component.hpp"

View File

@ -1,56 +0,0 @@
#define COMPONENT spectator
#include "\z\ace\addons\main\script_mod.hpp"
#ifdef DEBUG_ENABLED_SPECTATOR
#define DEBUG_MODE_FULL
#endif
#ifdef DEBUG_SETTINGS_SPECTATOR
#define DEBUG_SETTINGS DEBUG_SETTINGS_SPECTATOR
#endif
#include "\z\ace\addons\main\script_macros.hpp"
// UI grid
#define SIZEX ((safezoneW / safezoneH) min 1.2)
#define SIZEY (SIZEX / 1.2)
#define W_PART(num) (num * (SIZEX / 40))
#define H_PART(num) (num * (SIZEY / 25))
#define X_PART(num) (W_PART(num) + (safezoneX + (safezoneW - SIZEX)/2))
#define Y_PART(num) (H_PART(num) + (safezoneY + (safezoneH - SIZEY)/2))
// UI tools
#define TOOL_H H_PART(1)
#define TOOL_W W_PART(5)
#define MARGIN TOOL_W * 0.05
// UI compass
#define COMPASS_W (TOOL_W * 4)
#define COMPASS_X (safeZoneX + safeZoneW * 0.5 - COMPASS_W * 0.5)
// UI IDCs
#define IDC_COMP 4490
#define IDC_COMP_0 5000
#define IDC_COMP_90 5090
#define IDC_COMP_180 5180
#define IDC_COMP_270 5270
#define IDC_HELP 7631
#define IDC_HELP_LIST 7622
#define IDC_MAP 6791
#define IDC_TOOL 3000
#define IDC_TOOL_CLOCK 3003
#define IDC_TOOL_FOV 3005
#define IDC_TOOL_NAME 3001
#define IDC_TOOL_SPEED 3006
#define IDC_TOOL_VIEW 3002
#define IDC_TOOL_VISION 3004
#define IDC_UNIT 6002
// UI colours
#define COL_BACK 0.1,0.1,0.1,0.8
#define COL_FORE 1,1,1,1
#define COL_FORE_D 0.1,0.1,0.1,1

View File

@ -1,197 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="ACE">
<Package name="Spectator">
<Key ID="STR_ACE_Spectator_Settings_DisplayName">
<English>Spectator Settings</English>
</Key>
<Key ID="STR_ACE_Spectator_Settings_Descripton">
<English>Configure how the spectator system will operate by default.</English>
</Key>
<Key ID="STR_ACE_Spectator_system_DisplayName">
<English>Spectate on death</English>
</Key>
<Key ID="STR_ACE_Spectator_system_Description">
<English>Enables spectator upon death.</English>
</Key>
<Key ID="STR_ACE_Spectator_units_DisplayName">
<English>Unit filter</English>
</Key>
<Key ID="STR_ACE_Spectator_units_Description">
<English>Method of filtering spectatable units.</English>
</Key>
<Key ID="STR_ACE_Spectator_units_none">
<English>No units</English>
</Key>
<Key ID="STR_ACE_Spectator_units_players">
<English>Only players</English>
</Key>
<Key ID="STR_ACE_Spectator_units_all">
<English>All units</English>
</Key>
<Key ID="STR_ACE_Spectator_sides_DisplayName">
<English>Side filter</English>
</Key>
<Key ID="STR_ACE_Spectator_sides_Description">
<English>Method of filtering spectatable sides.</English>
</Key>
<Key ID="STR_ACE_Spectator_sides_player">
<English>Player side</English>
</Key>
<Key ID="STR_ACE_Spectator_sides_friendly">
<English>Friendly sides</English>
</Key>
<Key ID="STR_ACE_Spectator_sides_hostile">
<English>Hostile sides</English>
</Key>
<Key ID="STR_ACE_Spectator_sides_all">
<English>All sides</English>
</Key>
<Key ID="STR_ACE_Spectator_modes_DisplayName">
<English>Camera modes</English>
</Key>
<Key ID="STR_ACE_Spectator_modes_Description">
<English>Camera modes that can be used.</English>
</Key>
<Key ID="STR_ACE_Spectator_modes_all">
<English>All</English>
</Key>
<Key ID="STR_ACE_Spectator_modes_free">
<English>Free only</English>
</Key>
<Key ID="STR_ACE_Spectator_modes_internal">
<English>Internal only</English>
</Key>
<Key ID="STR_ACE_Spectator_modes_external">
<English>External only</English>
</Key>
<Key ID="STR_ACE_Spectator_modes_unit">
<English>Internal and external</English>
</Key>
<Key ID="STR_ACE_Spectator_visions_DisplayName">
<English>Vision modes</English>
</Key>
<Key ID="STR_ACE_Spectator_visions_Description">
<English>Vision modes that can be used.</English>
</Key>
<Key ID="STR_ACE_Spectator_visions_nv">
<English>Night vision</English>
</Key>
<Key ID="STR_ACE_Spectator_visions_ti">
<English>Thermal imaging</English>
</Key>
<Key ID="STR_ACE_Spectator_icons_DisplayName">
<English>Unit icons</English>
</Key>
<Key ID="STR_ACE_Spectator_icons_Description">
<English>Render icons above spectatable units.</English>
</Key>
<!-- Interface strings -->
<Key ID="STR_ACE_Spectator_HelpTitle">
<English>Spectator Controls</English>
</Key>
<Key ID="STR_ACE_Spectator_ViewFree">
<English>Free</English>
</Key>
<Key ID="STR_ACE_Spectator_ViewInternal">
<English>Internal</English>
</Key>
<Key ID="STR_ACE_Spectator_ViewExternal">
<English>External</English>
</Key>
<Key ID="STR_ACE_Spectator_VisionNormal">
<English>Normal</English>
</Key>
<Key ID="STR_ACE_Spectator_VisionNight">
<English>Night</English>
</Key>
<Key ID="STR_ACE_Spectator_VisionThermal">
<English>Thermal</English>
</Key>
<!-- Controls -->
<Key ID="STR_ACE_Spectator_freeCamControls">
<English>Free Camera Controls</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamForward">
<English>Camera Forward</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamBackward">
<English>Camera Backward</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamLeft">
<English>Camera Left</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamRight">
<English>Camera Right</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamUp">
<English>Camera Up</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamDown">
<English>Camera Down</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamPan">
<English>Pan Camera</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamDolly">
<English>Dolly Camera</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamLock">
<English>Lock Camera to Target</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamZoom">
<English>Zoom In/Out</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamSpeed">
<English>Speed Up/Down</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamNextVis">
<English>Next Vision Mode</English>
</Key>
<Key ID="STR_ACE_Spectator_freeCamPrevVis">
<English>Previous Vision Mode</English>
</Key>
<Key ID="STR_ACE_Spectator_uiControls">
<English>Interface Controls</English>
</Key>
<Key ID="STR_ACE_Spectator_uiToggleInterface">
<English>Toggle Interface</English>
</Key>
<Key ID="STR_ACE_Spectator_uiToggleIcons">
<English>Toggle Unit Icons</English>
</Key>
<Key ID="STR_ACE_Spectator_uiToggleUnits">
<English>Toggle Unit List</English>
</Key>
<Key ID="STR_ACE_Spectator_uiToggleTools">
<English>Toggle Toolbar</English>
</Key>
<Key ID="STR_ACE_Spectator_uiToggleCompass">
<English>Toggle Compass</English>
</Key>
<Key ID="STR_ACE_Spectator_uiToggleMap">
<English>Toggle Map</English>
</Key>
<Key ID="STR_ACE_Spectator_uiToggleHelp">
<English>Toggle Help</English>
</Key>
<Key ID="STR_ACE_Spectator_otherControls">
<English>Other Controls</English>
</Key>
<Key ID="STR_ACE_Spectator_nextCam">
<English>Next Camera</English>
</Key>
<Key ID="STR_ACE_Spectator_prevCam">
<English>Previous Camera</English>
</Key>
<Key ID="STR_ACE_Spectator_nextUnit">
<English>Next Unit</English>
</Key>
<Key ID="STR_ACE_Spectator_prevUnit">
<English>Previous Unit</English>
</Key>
</Package>
</Project>