Remove locations tab from spectator (#5431)

* Fix incorrect function input for spectator hiding
* Remove locations tab from spectator

- Doesn't add much value, adds complexity and the implementation is half
baked. Would rather add back in at a later date (if at all) with a
better implementation.
- I have an idea to replace the locations tab with a meta tab so users
can toggle things like projectile drawing via the UI and are not forced
to use a hotkey. Might also be a good place to display the extended controls.
This commit is contained in:
SilentSpike 2017-08-17 12:50:43 +01:00 committed by GitHub
parent d9ea680afa
commit 85c5fbabe9
30 changed files with 36 additions and 409 deletions

View File

@ -19,10 +19,4 @@ class ACE_Settings {
value = 0;
values[] = {CSTRING(modes_all), CSTRING(visions_nv), CSTRING(visions_ti), "$STR_Special_None"};
};
class GVAR(mapLocations) {
displayName = CSTRING(mapLocations_DisplayName);
description = CSTRING(mapLocations_Description);
typeName = "BOOL";
value = 0;
};
};

View File

@ -67,12 +67,6 @@ class CfgVehicles {
};
};
};
class mapLocations {
displayName = CSTRING(mapLocations_DisplayName);
description = CSTRING(mapLocations_Description);
typeName = "BOOL";
defaultValue = 0;
};
};
class ModuleDescription {
description = CSTRING(Settings_Description);

View File

@ -23,7 +23,6 @@ PREP(ui_handleMouseButtonDblClick);
PREP(ui_handleMouseButtonDown);
PREP(ui_handleMouseMoving);
PREP(ui_handleMouseZChanged);
PREP(ui_handleTabSelected);
PREP(ui_toggleMap);
PREP(ui_toggleUI);
PREP(ui_updateCamButtons);
@ -31,7 +30,6 @@ PREP(ui_updateHelp);
PREP(ui_updateIconsToDraw);
PREP(ui_updateListEntities);
PREP(ui_updateListFocus);
PREP(ui_updateListLocations);
PREP(ui_updateWidget);
// Utility functions
@ -48,10 +46,8 @@ PREP(stageSpectator);
PREP(switchFocus);
// Public functions
PREP(addLocation);
PREP(getCameraAttributes);
PREP(players);
PREP(removeLocation);
PREP(setCameraAttributes);
PREP(setSpectator);
PREP(updateCameraModes);

View File

@ -3,17 +3,6 @@
["ace_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 (GVAR(mapLocations)) then {
private _worldWidth = worldSize / 2;
{
[locationPosition _x, [text _x] call CBA_fnc_capitalize] call FUNC(addLocation);
} forEach nearestLocations [
[_worldWidth, _worldWidth],
["NameVillage", "NameCity", "NameCityCapital", "NameLocal", "NameMarine"],
_worldWidth * sqrt 2
];
};
}] call CBA_fnc_addEventHandler;
if (isServer) then {

View File

@ -11,8 +11,6 @@ GVAR(availableModes) = [MODE_FREE, MODE_FPS, MODE_FOLLOW];
GVAR(availableSides) = [west,east,resistance,civilian];
GVAR(availableVisions) = [VISION_NORM,VISION_NVG,0,1];
GVAR(interrupts) = [];
GVAR(locationCount) = 0;
GVAR(locationsList) = [];
GVAR(unitBlacklist) = [];
GVAR(unitWhitelist) = [];

View File

@ -1,73 +0,0 @@
/*
* Author: Nelson Duarte, SilentSpike
* Add a location that can be seen in spectator view. Local effect.
*
* Arguments:
* 0: Position <ARRAY or OBJECT>
* 1: Display Name <STRING> (Default: "")
* 2: Description <STRING> (Default: "")
* 3: Texture <STRING> (Default: "")
* 4: Camera Offset Vector <Array> (Default: [0,0,0])
*
* Notes:
* - Position array is of form ATL
* - Position objects will remove location upon objNull
* - If an empty name is supplied, a descriptive name will be used
* - Camera offset is used when teleporting to location, default is treated as random
*
* Return Value:
* Unique ID (used to remove a location) <STRING>
*
* Example:
* [[2000, 3202, 0], "Objective Alpha"] call ace_spectator_fnc_addLocation
*
* Public: Yes
*/
#include "script_component.hpp"
params [
["_pos",[],[[],objNull],3],
["_name","",[""]],
["_description","",[""]],
["_texture","",[""]],
["_offset",[0,0,0],[[]],3]
];
private _id = "";
if (_pos isEqualTo []) then {
WARNING("Invalid position supplied");
} else {
// Get a unique ID
INC(GVAR(locationCount));
_id = [QGVAR(id),GVAR(locationCount)] joinString "";
// Must have a name to display in the list
if (_name == "") then {
if (_pos isEqualType objNull) then {
_name = [_pos] call EFUNC(common,getName);
} else {
_name = _pos call BIS_fnc_locationDescription;
};
};
// AGL is used for rendering purposes, but it makes sense for public function to take ATL
if (_pos isEqualType []) then {
_pos = ASLtoAGL ATLtoASL _pos;
};
// When no texture, just use a transparent procedural
if (_texture == "") then { _texture = "#(rgb,8,8,3)color(0,0,0,0)"; };
GVAR(locationsList) pushBack [_id, _name, _description, _texture, _pos, _offset];
// Update the list if appropriate
if !(isNull SPEC_DISPLAY) then {
if (GVAR(uiListType) == LIST_LOCATIONS) then {
[] call FUNC(ui_updateListLocations);
};
};
};
_id

View File

@ -29,7 +29,6 @@ if (_init) then {
ISNILS(GVAR(camMode),MODE_FREE);
ISNILS(GVAR(camVision),VISION_NORM);
ISNILS(GVAR(camTarget),objNull);
ISNILS(GVAR(camOnLocation),false);
// Ticking related
GVAR(camDeltaTime) = 0;
@ -128,7 +127,6 @@ if (_init) then {
GVAR(camMode) = nil;
GVAR(camVision) = nil;
GVAR(camTarget) = nil;
GVAR(camOnLocation) = nil;
GVAR(camDeltaTime) = nil;
GVAR(camLastTickTime) = nil;
GVAR(camHasTarget) = nil;

View File

@ -29,8 +29,8 @@ if !(_newMode in _modes) then {
_newMode = _modes select ((_modes find _oldMode) max 0);
};
// Can't switch camera from free mode when focus is a location
if (!(isNull _focus || GVAR(camOnLocation)) || _newMode == MODE_FREE) then {
// Can't switch camera from free mode with no focus selected
if (!isNull _focus || _newMode == MODE_FREE) then {
private _camera = GVAR(camera);
private _showHUD = [true,true,true,true,true,true,true,true];

View File

@ -25,4 +25,3 @@ if !(_activated) exitWith {};
[_logic, QGVAR(enableAI), "enableAI"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(restrictModes), "cameraModes"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(restrictVisions), "visionModes"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(mapLocations), "mapLocations"] call EFUNC(common,readSettingFromModule);

View File

@ -1,39 +0,0 @@
/*
* Author: Nelson Duarte, SilentSpike
* Remove a location that can be seen in spectator view. Local effect.
*
* Arguments:
* 0: Unique ID <STRING>
*
* Return Value:
* Success <BOOL>
*
* Example:
* [_id] call ace_spectator_fnc_removeLocation
*
* Public: Yes
*/
#include "script_component.hpp"
params [["_id","",[""]]];
private _index = -1;
{
if ((_x select 0) == _id) exitWith {
_index = _forEachIndex;
};
} forEach GVAR(locationsList);
GVAR(locationsList) deleteAt _index;
// Update the list if appropriate
if !(isNull SPEC_DISPLAY) then {
if (GVAR(uiListType) == LIST_LOCATIONS) then {
[] call FUNC(ui_updateListLocations);
};
};
// Return
_index != -1

View File

@ -55,7 +55,7 @@ if !(isNil QGVAR(camera)) then {
if !(isNil "_mode") then {
// If mode not free and no focus, find focus
if ((_mode != MODE_FREE) && {isNull GVAR(camTarget) || GVAR(camOnLocation)}) then {
if ((_mode != MODE_FREE) && {isNull GVAR(camTarget)}) then {
[true] call FUNC(setFocus);
};

View File

@ -4,20 +4,19 @@
*
* Arguments:
* 0: New focus <OBJECT>
* 1: Focus is a location <BOOL>
*
* Return Value:
* None
*
* Example:
* [player, false] call ace_spectator_fnc_setFocus
* [player] call ace_spectator_fnc_setFocus
*
* Public: No
*/
#include "script_component.hpp"
params [["_newFocus", objNull, [objNull,true]], ["_focusIsLocation",false]];
params [["_newFocus", objNull, [objNull,true]]];
// If boolean provided then first find a focus
if (_newFocus isEqualType true) then {
@ -47,17 +46,9 @@ if (_newFocus != GVAR(camTarget) && { !(isNull _newFocus && { isNull GVAR(camTar
} else {
[MODE_FREE] call FUNC(cam_setCameraMode);
};
} else {
// Locations can only be focused on in free camera
if (_focusIsLocation) then {
[MODE_FREE] call FUNC(cam_setCameraMode);
} else {
[GVAR(camMode)] call FUNC(cam_setCameraMode);
};
};
// GVAR used to prevent camera switching and UI info on locations
GVAR(camOnLocation) = _focusIsLocation;
// Only update display if it exists, this function is independent of it
if !(isNull SPEC_DISPLAY) then {

View File

@ -109,8 +109,8 @@ if (alive player) then {
[player, _hidden, QGVAR(isSet), side group player] call EFUNC(common,switchToGroupSide);
// Ghosts can't talk
[_hidden, QGVAR(isSet)] call EFUNC(common,hideUnit);
[_hidden, QGVAR(isSet)] call EFUNC(common,muteUnit);
[player, QGVAR(isSet)] call EFUNC(common,hideUnit);
[player, QGVAR(isSet)] call EFUNC(common,muteUnit);
};
// Reset interruptions

View File

@ -83,7 +83,5 @@ if !(_set isEqualTo (GETVAR(_unit,GVAR(isStaged),false))) then {
// If display exists already update the entity list to hide player
if !(isNull SPEC_DISPLAY) then {
if (GVAR(uiListType) == LIST_ENTITIES) then {
[] call FUNC(ui_updateListEntities);
};
};

View File

@ -45,15 +45,11 @@ if (_init) then {
GVAR(entitiesToDraw) = [];
GVAR(grenadesToDraw) = [];
GVAR(iconsToDraw) = [];
GVAR(locationsToDraw) = [];
GVAR(projectilesToDraw) = [];
// RMB tracking is used for follow camera mode
GVAR(holdingRMB) = false;
// List type is used for list updates and interaction
GVAR(uiListType) = LIST_ENTITIES;
// Highlighted map object is used for click and drawing events
GVAR(uiMapHighlighted) = objNull;
@ -94,12 +90,7 @@ if (_init) then {
// Periodically update list and focus widget
GVAR(uiPFH) = [{
if (GVAR(uiListType) == LIST_ENTITIES) then {
[] call FUNC(ui_updateListEntities);
} else {
[] call FUNC(ui_updateListLocations);
};
[] call FUNC(ui_updateWidget);
}, 5] call CBA_fnc_addPerFrameHandler;
} else {
@ -123,7 +114,6 @@ if (_init) then {
GVAR(uiMapVisible) = nil;
GVAR(uiWidgetVisible) = nil;
GVAR(holdingRMB) = nil;
GVAR(uiListType) = nil;
GVAR(uiMapHighlighted) = nil;
GVAR(curList) = nil;
GVAR(uiHelpH) = nil;
@ -134,7 +124,6 @@ if (_init) then {
GVAR(entitiesToDraw) = nil;
GVAR(grenadesToDraw) = nil;
GVAR(iconsToDraw) = nil;
GVAR(locationsToDraw) = nil;
GVAR(projectilesToDraw) = nil;
// Reset view distance

View File

@ -70,19 +70,6 @@ if !(GVAR(uiMapVisible)) then {
nil // Speed loop
} count GVAR(iconsToDraw);
// Draw locations
{
_x params ["_pos", "_name", "_texture"];
if (_pos isEqualType objNull) then {
_pos = (_pos modelToWorldVisual (_pos selectionPosition "Head")) vectorAdd [0,0,2*HEIGHT_OFFSET];
};
drawIcon3D [_texture, [1,1,1,0.4], _pos, 0.8, 0.8, 0, _name];
nil // Speed loop
} count (GVAR(locationsToDraw));
END_COUNTER(drawTags);
};

View File

@ -1,6 +1,6 @@
/*
* Author: Nelson Duarte, AACO
* Function used to fade/unfade the entitiy/location list
* Function used to fade/unfade the entitiy list
*
* Arguments:
* 0: Fade the list <BOOL>

View File

@ -1,6 +1,6 @@
/*
* Author: Nelson Duarte, AACO
* Function used to find a tree path of a unit
* Function used to find the tree path of an entity
*
* Arguments:
* 0: Data to search tree for <STRING>
@ -24,7 +24,6 @@ scopeName QGVAR(getTreeDataIndex);
if (_data != "") then {
private _ctrl = CTRL_LIST;
// This also handles the locations list (_sideIndex = _locationIndex)
for "_sideIndex" from 0 to ((_ctrl tvCount []) - 1) do {
if (_ctrl tvData [_sideIndex] == _data) then {
[_sideIndex] breakOut QGVAR(getTreeDataIndex);

View File

@ -24,14 +24,12 @@ params ["_dblClick","_params"];
_params params ["_list","_index"];
private _handled = false;
private _entityList = GVAR(uiListType) == LIST_ENTITIES;
private _data = _list tvData _index;
if (_entityList) then {
// List contains unique object variables
private _object = missionNamespace getVariable [_data, objNull];
// List contains unique object variables
private _object = missionNamespace getVariable [_data, objNull];
if !(isNull _object) then {
if !(isNull _object) then {
if (_dblClick) then {
// Place camera within ~10m of the object and above ground level
private _pos = getPosASLVisual _object;
@ -49,58 +47,6 @@ if (_entityList) then {
_handled = true;
};
};
};
} else {
private _location = [];
// Try to find the location
{
if ((_x select 0) == _data) exitWith {
// Don't want to accidentally modify the GVAR
_location = +_x;
};
} forEach GVAR(locationsList);
if !(_location isEqualTo []) then {
_location params ["", "_name", "_description", "", "_pos", "_offset"];
// Use dummy object if location is a position array
private _dummy = GVAR(camDummy);
if (_pos isEqualType objNull) then {
_dummy = _pos;
} else {
// Use dummy to have camera target the location position
detach _dummy;
_dummy setPosASL _pos;
};
// If in a unit camera mode then only focus when double click
if (GVAR(camMode) == MODE_FREE || {_dblClick && {FREE_MODE in GVAR(availableModes)}}) then {
// Reset the focus
[objNull] call FUNC(setFocus);
[_dummy, true] call FUNC(setFocus);
};
// If double clicked ande mode is now free camera, teleport the camera
if (_dblClick && {GVAR(camMode) == MODE_FREE}) then {
// If location has unspecified offset place randomly within ~30m above ground level
if (_offset isEqualTo [0,0,0]) then {
_pos = AGLtoASL (_pos getPos [5 + random 30, random 360]) vectorAdd [0,0,2 + random 28];
} else {
if (_pos isEqualType objNull) then {
_pos = (getPosASL _pos) vectorAdd _offset;
} else {
_pos = (AGLtoASL _pos) vectorAdd _offset;
};
};
GVAR(camera) setPosASL _pos;
// Location info text
[parseText format [ "<t align='right' size='1.2'><t font='PuristaBold' size='1.6'>""%1""</t><br/>%2</t>", _name, _description], true, nil, 7, 0.7, 0] spawn BIS_fnc_textTiles;
};
_handled = true;
};
};
if (_handled) then {

View File

@ -85,12 +85,4 @@ if !(isNil QGVAR(camera)) then {
_map drawArrow [_cameraPos, (_cameraPos getPos [300, _cameraDir]), [0.5, 1, 0.5, 1]];
};
// Draw locations
{
_x params ["", "_name", "", "_texture", "_pos"];
_map drawIcon [_texture, [1,1,1,0.5], _pos, 36, 36, 0, _name, true, 0.04, "TahomaB", "right"];
nil // Speed loop
} count (GVAR(locationsList));
END_COUNTER(drawMap);

View File

@ -1,37 +0,0 @@
/*
* Author: Nelson Duarte, SilentSpike
* Function used to handle list tab change
*
* Arguments:
* 0: Control <CONTROL>
* 1: New tab index <NUMBER>
*
* Return Value:
* None
*
* Example:
* _this call ace_spectator_fnc_ui_handleTabSelected
*
* Public: No
*/
#include "script_component.hpp"
params ["_ctrl", "_index"];
// Nothing to do if it's the same tab
private _newType = [LIST_ENTITIES, LIST_LOCATIONS] select _index;
if (GVAR(uiListType) == _newType) exitWith {};
// Clear list
tvClear CTRL_LIST;
// Force initial update
if (_index == 0) then {
[] call FUNC(ui_updateListEntities);
} else {
[] call FUNC(ui_updateListLocations);
};
// Track current list type
GVAR(uiListType) = _newType;

View File

@ -45,7 +45,7 @@ if (_cameraMode == MODE_FREE) then {
};
// When the camera has a focus, switch mode applies (if other modes are available)
if (_hasTarget && {!GVAR(camOnLocation)} && {count _availableModes > 1}) then {
if (_hasTarget && {count _availableModes > 1}) then {
_controls pushBack [
format ["[%1]", toUpper ([DIK_SPACE] call CBA_fnc_localizeKey)],
localize "STR_A3_Spectator_Helper_CameraMode"

View File

@ -143,20 +143,5 @@ private _entitiesToDraw = [];
nil // Speed loop
} count ([] call FUNC(getTargetEntities));
// Remove object locations that are now null
{
_x params ["_id", "_name", "", "_texture", "_pos"];
if ((_pos isEqualType objNull) && {isNull _pos}) then {
[_id] call FUNC(removeLocation);
} else {
if ((GVAR(camera) distanceSqr _pos) < DISTANCE_NAMES_SQR) then {
GVAR(locationsToDraw) pushBack [_pos, _name, _texture];
};
};
nil // Speed loop
} count (GVAR(locationsList));
GVAR(iconsToDraw) = _iconsToDraw;
GVAR(entitiesToDraw) = _entitiesToDraw;

View File

@ -16,7 +16,4 @@
#include "script_component.hpp"
// Don't update list when in location mode or focus is a location
if (!GVAR(camOnLocation) && {GVAR(uiListType) != LIST_LOCATIONS}) then {
CTRL_LIST tvSetCurSel ([[GVAR(camTarget)] call BIS_fnc_objectVar] call FUNC(ui_getTreeDataIndex));
};
CTRL_LIST tvSetCurSel ([[GVAR(camTarget)] call BIS_fnc_objectVar] call FUNC(ui_getTreeDataIndex));

View File

@ -1,69 +0,0 @@
/*
* Author: Nelson Duarte, AACO, SilentSpike
* Updates spectator UI list of locations
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call ace_spectator_fnc_ui_updateListLocations
*
* Public: No
*/
#include "script_component.hpp"
private _newLocations = [];
private _newList = GVAR(locationsList);
// Whether an update to the list is required (really only if something changed)
if !(GVAR(curList) isEqualTo _newList) then {
private _ctrl = CTRL_LIST;
// Remove locations that are no longer there
for "_locationIndex" from ((_ctrl tvCount []) - 1) to 0 step -1 do {
private _lookup = _newLocations find (_ctrl tvData [_locationIndex]);
if (_lookup < 0) then {
_ctrl tvDelete [_locationIndex];
} else {
_newLocations deleteAt _lookup;
};
};
// Hash location lookups, note hashing assumes unique location data
private _locationDataToPathHash = [[], []];
for "_locationIndex" from 0 to ((_ctrl tvCount []) - 1) do {
(_locationDataToPathHash select 0) pushBack (_ctrl tvData [_locationIndex]);
(_locationDataToPathHash select 1) pushBack [_locationIndex];
};
{
_x params ["_id", "_name", "_description", "_texture"];
private _lookup = (_locationDataToPathHash select 0) find _id;
if (_lookup < 0) then {
private _locationIndex = _ctrl tvAdd [[], _name];
_ctrl tvSetData [[_locationIndex], _id];
_ctrl tvSetPicture [[_locationIndex], _texture];
_ctrl tvSetPictureColor [[_locationIndex], [1,1,1,1]];
_ctrl tvSetTooltip [[_locationIndex], _description];
} else {
// pop data out of hash to improve later lookups
(_locationDataToPathHash select 0) deleteAt _lookup;
private _path = (_locationDataToPathHash select 1) deleteAt _lookup;
_ctrl tvSetText [_path, _name];
_ctrl tvSetPicture [_path, _texture];
_ctrl tvSetPictureColor [_path, [1,1,1,1]];
_ctrl tvSetTooltip [_path, _description];
};
nil // Speed loop
} count _newList;
GVAR(curList) = _newList;
};

View File

@ -20,8 +20,8 @@
#define IMG_GUNNER "a3\Ui_f\data\IGUI\Cfg\CommandBar\imageGunner_ca.paa"
#define IMG_CARGO "a3\Ui_f\data\IGUI\Cfg\CommandBar\imageCommander_ca.paa"
// Hide if no target, or target is a location or widget is toggled off
if (!GVAR(uiWidgetVisible) || {GVAR(camOnLocation)} || {isNull GVAR(camTarget)}) exitWith {CTRL_WIDGET ctrlShow false};
// Hide if no target or widget is toggled off
if (!GVAR(uiWidgetVisible) || {isNull GVAR(camTarget)}) exitWith {CTRL_WIDGET ctrlShow false};
private _focus = GVAR(camTarget);

View File

@ -49,7 +49,7 @@ if (_newModes isEqualTo []) then {
// Update camera in case of change
if !(isNil QGVAR(camera)) then {
// If mode was free and no longer available, find a focus
if (!(MODE_FREE in _newModes) && {GVAR(camMode) == MODE_FREE} && {isNull GVAR(camTarget) || GVAR(camOnLocation)}) then {
if (!(MODE_FREE in _newModes) && {GVAR(camMode) == MODE_FREE} && {isNull GVAR(camTarget)}) then {
[true] call FUNC(setFocus);
};

View File

@ -50,8 +50,7 @@
#define DISTANCE_NAMES_SQR 30625 // Names are rendered within 175m, squared for `distanceSqr` speed
#define NAME_MAX_CHARACTERS 17
#define LIST_ENTITIES localize "STR_A3_Spectator_Entities"
#define LIST_LOCATIONS localize "STR_A3_Spectator_Locations"
#define LIST_ENTITIES 0
#define LIST_UPDATE_RATE 1
// Revive variables

View File

@ -238,12 +238,6 @@
<Chinesesimp>热成像</Chinesesimp>
<Chinese>熱成像</Chinese>
</Key>
<Key ID="STR_ACE_Spectator_mapLocations_DisplayName">
<English>Add Map Locations</English>
</Key>
<Key ID="STR_ACE_Spectator_mapLocations_Description">
<English>Add map locations to the spectator UI</English>
</Key>
<!-- Controls -->
<Key ID="STR_ACE_Spectator_uiIcons">
<English>Icons</English>

View File

@ -73,7 +73,7 @@ class GVAR(display) {
class Tabs: RscToolbox {
idc = IDC_TABS;
onToolBoxSelChanged = QUOTE(_this call FUNC(ui_handleTabSelected));
//onToolBoxSelChanged = QUOTE(_this call FUNC(ui_handleTabSelected));
onMouseEnter = QUOTE([false] call FUNC(ui_fadeList));
onMouseExit = QUOTE([true] call FUNC(ui_fadeList));
@ -84,9 +84,9 @@ class GVAR(display) {
fade = 0.8;
rows = 1;
columns = 2;
strings[] = {"$STR_A3_Spectator_Entities","$STR_A3_Spectator_Locations"};
values[] = {0,1};
columns = 1;
strings[] = {"$STR_A3_Spectator_Entities"};
values[] = {0};
sizeEx = H_PART(1);
colorBackground[] = {0,0,0,0.75};
colorSelectedBg[] = {0,0,0,0.65};