Improve spectator drawing and selection (#5457)

* Optimise cursor object updates
* Restrict distance units can be selected from
* Fix potential for no icons to render in FPP
* Limit projectile drawing distance
* Optimise icon updates
* Fix group names not being drawn in vehicles
* Fix selection nameplate not drawing for vehicles
* Fix selection of non-spectatable entities
This commit is contained in:
SilentSpike 2017-08-30 11:40:12 +01:00 committed by GitHub
parent abc91f1564
commit 1ab7a886e7
3 changed files with 48 additions and 41 deletions

View File

@ -19,17 +19,21 @@
BEGIN_COUNTER(updateCursor);
private _camTarget = GVAR(camTarget);
private _camTargetVeh = vehicle _camTarget;
private _cursorObject = objNull;
// This function doesn't work for units underwater, due to use of screenToWorld. Would be complicated to work around this.
private _intersections = [getMousePosition select 0, getMousePosition select 1, _camTarget, vehicle _camTarget] call BIS_fnc_getIntersectionsUnderCursor;
// This doesn't work for units underwater due to use of screenToWorld
// Would be hard to work around due to parallax
private _start = AGLToASL positionCameraToWorld [0,0,0];
private _end = AGLToASL screenToWorld getMousePosition;
if !(_intersections isEqualTo []) then {
_cursorObject = (_intersections select 0) select 3;
};
// Can only select units within name drawing distance
if ((_start distanceSqr _end) <= DISTANCE_NAMES_SQR) then {
private _intersections = lineIntersectsSurfaces [_start, _end, _camTarget, _camTargetVeh];
if !(_cursorObject isKindOf "Man") then {
_cursorObject = effectiveCommander _cursorObject;
if !(_intersections isEqualTo []) then {
_cursorObject = effectiveCommander ((_intersections select 0) select 3);
};
};
GVAR(cursorObject) = _cursorObject;
@ -43,10 +47,11 @@ if !(GVAR(uiMapVisible)) then {
_x params ["_unit", "_type", "_icon"];
private _position = (_unit modelToWorldVisual (_unit selectionPosition "Head")) vectorAdd [0,0,HEIGHT_OFFSET];
if (_type == 2 && { _unit distanceSqr GVAR(camera) < DISTANCE_NAMES_SQR } && {_unit in _camTarget || _unit in _cursorObject}) then {
// Cursor object is always effectiveCommander so no need to check `in`
if (_type == 2 && {_unit in _camTargetVeh || _unit == _cursorObject}) then {
drawIcon3D [
ICON_BACKGROUND_UNIT,
[0, 0, 0, [0.4, 0.8] select (_unit in _camTarget)],
[0, 0, 0, [0.4, 0.8] select (_unit in _camTargetVeh)],
_position,
5,
4,

View File

@ -33,11 +33,13 @@ if (_button == 0) exitWith {
[objNull] call FUNC(setFocus);
};
} else {
playSound "ReadoutClick";
if (GVAR(cursorObject) in ([] call FUNC(getTargetEntities))) then {
playSound "ReadoutClick";
// Focus will be at screen center
[GVAR(cursorObject)] call FUNC(setFocus);
setMousePosition [0.5, 0.5];
// Focus will be at screen center
[GVAR(cursorObject)] call FUNC(setFocus);
setMousePosition [0.5, 0.5];
};
};
};

View File

@ -19,17 +19,17 @@
private _iconsToDraw = [];
private _entitiesToDraw = [];
// camToWorld is used instead of camera object to account for FPP
private _camPos = AGLToASL positionCameraToWorld [0,0,0];
{
private _vehicle = vehicle _x;
private _inVehicle = (_vehicle != _x);
private _distanceToCameraSqr = GVAR(camera) distanceSqr _x;
private _distanceToCameraSqr = _camPos distanceSqr _x;
if (_distanceToCameraSqr <= DISTANCE_ICONS_SQR && { !_inVehicle || { _x == effectiveCommander _vehicle } }) then {
private _group = group _x;
private _groupSide = side _group;
private _groupName = groupId _group;
private _groupLeader = leader _group;
private _groupColor = [_groupSide] call BIS_fnc_sideColor;
private _isLeader = _x == leader _group;
private _groupColor = [side _group] call BIS_fnc_sideColor;
// Calculate distance fade
(_distanceToCameraSqr call {
@ -54,19 +54,19 @@ private _entitiesToDraw = [];
// Apply color fade
_groupColor set [3, _fadeByDistance];
private _name = ([_x] call EFUNC(common,getName)) select [0, NAME_MAX_CHARACTERS];
if !(isPlayer _x) then { _name = format ["%1: %2", localize "str_player_ai", _name]; };
if (_inVehicle) then {
private _crewCount = (({alive _x} count (crew _vehicle)) - 1);
if (_crewCount > 0) then {
_name = format ["%1 (+%2)", _name, _crewCount];
};
};
// Show unit name only if camera is near enough
if (_distanceToCameraSqr < DISTANCE_NAMES_SQR) then {
// Unit name
private _name = ([_x] call EFUNC(common,getName)) select [0, NAME_MAX_CHARACTERS];
if !(isPlayer _x) then { _name = format ["%1: %2", localize "str_player_ai", _name]; };
if (_inVehicle) then {
private _crewCount = (({alive _x} count (crew _vehicle)) - 1);
if (_crewCount > 0) then {
_name = format ["%1 (+%2)", _name, _crewCount];
};
};
// Draw unit name for effective commander or all units on foot
_iconsToDraw pushBack [_x, 2, [
"",
[1,1,1,1],
@ -81,8 +81,8 @@ private _entitiesToDraw = [];
"center"
]];
} else {
if (_x == _groupLeader) then {
// Group name
// Draw group name for effective commander or leader on foot
if (_inVehicle || _isLeader) then {
_iconsToDraw pushBack [_x, 0, [
"",
[1,1,1,_fadeByDistance],
@ -90,7 +90,7 @@ private _entitiesToDraw = [];
0,
_heightByDistance,
0,
_groupName,
groupID _group,
2,
_fontSizeByDistance,
"PuristaMedium",
@ -99,8 +99,8 @@ private _entitiesToDraw = [];
};
};
if (_x == _groupLeader || { _inVehicle && { _x == effectiveCommander _vehicle } }) then {
// Group icon
// Draw group icon for effective commander or leader on foot
if (_inVehicle || _isLeader) then {
_iconsToDraw pushBack [_x, 0, [
[_group, true] call FUNC(getGroupIcon),
_groupColor,
@ -116,7 +116,7 @@ private _entitiesToDraw = [];
]];
};
// Draw unit icon
// Draw unit icon for effective commander or all units on foot
_iconsToDraw pushBack [_x, 1, [
[ICON_UNIT, ICON_REVIVE] select (NEEDS_REVIVE(_x)),
_groupColor,
@ -130,14 +130,14 @@ private _entitiesToDraw = [];
"PuristaMedium",
"center"
]];
};
// Track entities themselves for use with fired EH
_entitiesToDraw pushBack _vehicle;
// Track entities themselves for use with fired EH
_entitiesToDraw pushBack _vehicle;
// Add fired EH for drawing and icon highlighting
if (GETVAR(_vehicle,GVAR(firedEH),-1) == -1) then {
SETVAR(_vehicle,GVAR(firedEH),_vehicle addEventHandler [ARR_2("Fired",{_this call FUNC(handleFired)})]);
// Add fired EH for drawing and icon highlighting
if (GETVAR(_vehicle,GVAR(firedEH),-1) == -1) then {
SETVAR(_vehicle,GVAR(firedEH),_vehicle addEventHandler [ARR_2("Fired",{_this call FUNC(handleFired)})]);
};
};
nil // Speed loop