- Add cursored self interaction menu (for using inside vehicles)

- Renamed the base menu "SelfActions" to "ACE_SelfActions"
- Limit the amount of objects the player is shown interactions with. This are the 3 nearest objects which have active action points visible on screen.
- Cull action points that are not visible, to far away, etc before checking if they are active.
This commit is contained in:
Nicolás Badano 2015-02-28 17:48:46 -03:00
parent 2371bc1bb0
commit 85a77150c9
11 changed files with 163 additions and 57 deletions

View File

@ -0,0 +1,47 @@
class GVAR(cursorMenu) {
idd = 91919;
movingEnable = false;
onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(dlgCursorMenu)),_this select 0)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(cursorMenuOpened)),true)]);
onUnload = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(cursorMenuOpened)),false)]);
objects[] = {};
/*class controlsBackground {
class Background {
idc = 91920;
moving = 0;
font = "TahomaB";
text = "";
sizeEx = 0;
lineSpacing = 0;
access = 0;
type = 0;
style = 0;
size = 1;
colorBackground[] = {0, 0, 0, 0.5};
colorText[] = {0, 0, 0, 0};
x = "safezoneX";
y = "safezoneY";
w = "safezoneW";
h = "safezoneH";
};
};*/
class controls {
class Canvas {
idc = 91921;
moving = 0;
font = "TahomaB";
text = "";
sizeEx = 0;
lineSpacing = 0;
access = 0;
type = 0;
style = 0;
size = 1;
colorBackground[] = {0, 0, 0, 0};
colorText[] = {0, 0, 0, 0};
x = "safezoneX";
y = "safezoneY";
w = "safezoneW";
h = "safezoneH";
};
};
};

View File

@ -13,3 +13,5 @@ class CfgPatches {
};
#include "CfgEventHandlers.hpp"
#include "CursorMenus.hpp"

View File

@ -89,7 +89,7 @@ missionNamespace setVariable [_actionsVarName, [_actionsCfg, []] call _recurseFn
1,
[],
uid,
["MainActions","TeamManagement","MyAction"]
["ACE_MainActions","TeamManagement","MyAction"]
]
]
*/

View File

@ -81,9 +81,9 @@ _actions = [[
{ true },
{ true },
10,
[_actionsCfg, ["SelfActions"]] call _recurseFnc,
[_actionsCfg, ["ACE_SelfActions"]] call _recurseFnc,
GVAR(uidCounter),
["SelfActions"]
["ACE_SelfActions"]
]
];
GVAR(uidCounter) = GVAR(uidCounter) + 1;

View File

@ -13,6 +13,10 @@
#include "script_component.hpp"
if(!GVAR(keyDown)) then {
// Only interact with others if on foot
if (vehicle ACE_player != ACE_player) exitWith {};
GVAR(keyDown) = true;
GVAR(keyDownTime) = diag_tickTime;
};

View File

@ -17,6 +17,22 @@ if(!GVAR(keyDownSelfAction)) then {
GVAR(keyDown) = false;
GVAR(keyDownTime) = diag_tickTime;
GVAR(selfMenuOffset) = [sin getDir ACE_player, cos getDir ACE_player, 0] vectorMultiply 2;
GVAR(useCursorMenu) = (vehicle ACE_player != ACE_player) || visibleMap;
if (GVAR(useCursorMenu)) then {
closeDialog 0;
createDialog QGVAR(cursorMenu);
// The dialog sets:
// uiNamespace getVariable QGVAR(dlgCursorMenu);
// uiNamespace getVariable QGVAR(cursorMenuOpened);
ctrlEnable [91921, true];
((finddisplay 91919) displayctrl 91921) ctrlAddEventHandler ["MouseMoving", {
GVAR(cursorPos) = [_this select 1, _this select 2, 0];
}];
setMousePosition [0.5, 0.5];
};
GVAR(selfMenuOffset) = (positionCameraToWorld [0, 0, 2]) vectorDiff (positionCameraToWorld [0, 0, 0]);
//systemChat format ["GVAR(selfMenuOffset) %1",GVAR(selfMenuOffset)];
};
true

View File

@ -12,6 +12,10 @@
*/
#include "script_component.hpp"
if (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]) then {
closeDialog 0;
};
GVAR(keyDownSelfAction) = false;
if(GVAR(actionSelected)) then {
this = GVAR(selectedTarget);

View File

@ -17,45 +17,59 @@ _foundTarget = false;
_cursorPos1 = positionCameraToWorld [0, 0, 0];
_cursorPos2 = positionCameraToWorld [0, 0, 2];
GVAR(selfMenuScale) = (((worldToScreen (positionCameraToWorld [1,0,2])) select 0) -
((worldToScreen (positionCameraToWorld [0,0,2])) select 0)) / 0.6;
//systemChat format ["selfMenuScale: %1", GVAR(selfMenuScale)];
GVAR(currentOptions) = [];
private ["_actionsVarName","_classActions","_objectActions","_target","_player","_actionItem","_active"];
_player = ACE_player;
if (GVAR(keyDown)) then {
[] call FUNC(updateVecLineMap);
// Render all nearby interaction menus
#define MAXINTERACTOBJECTS 3
private ["_numInteractObjects","_numInteractions"];
_numInteractObjects = 0;
_nearestObjects = nearestObjects [(getPos ACE_player), ["All"], 15];
{
_target = _x;
_player = ACE_player;
// Iterate through object actions, find base level actions and render them if appropiate
_actionsVarName = format [QGVAR(Act_%1), typeOf _target];
GVAR(objectActions) = _target getVariable [QGVAR(actions), []];
{
_actionItem = _x;
// Only render them directly if they are base level actions
if (count (_actionItem select 8) == 1) then {
_active = [_target, ACE_player] call (_actionItem select 4);
_numInteractions = 0;
// Prevent interacting with yourself or your own vehicle
if (_target != ACE_player && {_target != vehicle ACE_player}) then {
if (_active) then {
[_target, _actionItem, 0, [180, 360]] call FUNC(renderMenu);
// Iterate through object actions, find base level actions and render them if appropiate
_actionsVarName = format [QGVAR(Act_%1), typeOf _target];
GVAR(objectActions) = _target getVariable [QGVAR(actions), []];
{
_actionItem = _x;
// Only render them directly if they are base level actions
if (count (_actionItem select 8) == 1) then {
// Try to render the menu
if ([_target, _actionItem, false, [180, 360]] call FUNC(renderMenu)) then {
_numInteractions = _numInteractions + 1;
};
};
} forEach GVAR(objectActions);
// Iterate through base level class actions and render them if appropiate
_classActions = missionNamespace getVariable [_actionsVarName, []];
{
_actionItem = _x;
// Try to render the menu
if ([_target, _actionItem, false, [180, 360]] call FUNC(renderMenu)) then {
_numInteractions = _numInteractions + 1;
};
} forEach _classActions;
// Limit the amount of objects the player can interact with
if (_numInteractions > 0) then {
_numInteractObjects = _numInteractObjects + 1;
};
} forEach GVAR(objectActions);
// Iterate through base level class actions and render them if appropiate
_classActions = missionNamespace getVariable [_actionsVarName, []];
{
_actionItem = _x;
_active = [_target, ACE_player] call (_actionItem select 4);
if (_active) then {
[_target, _actionItem, 0, [180, 360]] call FUNC(renderMenu);
};
} forEach _classActions;
};
if (_numInteractObjects >= MAXINTERACTOBJECTS) exitWith {};
} forEach _nearestObjects;
@ -66,11 +80,11 @@ if (GVAR(keyDown)) then {
// Render only the self action menu
_target = vehicle ACE_player;
_player = ACE_player;
// Iterate through object actions, find base level actions and render them if appropiate
_actionsVarName = format [QGVAR(SelfAct_%1), typeOf _target];
GVAR(objectActions) = _target getVariable [QGVAR(selfActions), []];
/*
{
_actionItem = _x;
// Only render them directly if they are base level actions
@ -82,6 +96,7 @@ if (GVAR(keyDown)) then {
};
};
} forEach GVAR(objectActions);
*/
// Iterate through base level class actions and render them if appropiate
_actionsVarName = format [QGVAR(SelfAct_%1), typeOf _target];
@ -91,8 +106,9 @@ if (GVAR(keyDown)) then {
_active = [_target, ACE_player] call (_actionItem select 4);
if (_active) then {
_pos = (ACE_player modelToWorld (ACE_player selectionPosition "spine3")) vectorAdd GVAR(selfMenuOffset) vectorAdd [0,0,0.25];
[ACE_player, _actionItem, 0, [180, 360], _pos] call FUNC(renderMenu);
//_pos = (ACE_player modelToWorld (ACE_player selectionPosition "spine3")) vectorAdd GVAR(selfMenuOffset) vectorAdd [0,0,0.25];
_pos = _cursorPos1 vectorAdd GVAR(selfMenuOffset);
[_target, _actionItem, true, [180, 360], _pos] call FUNC(renderMenu);
};
} forEach _classActions;
};
@ -100,9 +116,13 @@ if (GVAR(keyDown)) then {
if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then {
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selected_ca.paa", [1,0,0,1], _cursorPos2, 1, 1, 0, "", 0.5, 0.025, "TahomaB"];
// Draw the red selector only when there's no cursor
if !(uiNamespace getVariable [QGVAR(cursorMenuOpened),false]) then {
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selected_ca.paa", [1,0,0,1], _cursorPos2, 1, 1, 0, "", 0.5, 0.025, "TahomaB"];
};
_cursorScreenPos = [worldToScreen _cursorPos2, GVAR(cursorPos)] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]);
_cursorScreenPos = worldToScreen _cursorPos2;
_closestDistance = 1000000;
_closestSelection = -1;
{

View File

@ -31,13 +31,16 @@ _sPos = worldToScreen _pos;
if(count _sPos > 0) then {
if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then {
GVAR(iconCtrls) pushBack ((findDisplay 46) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]);
_displayNum = [46,91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]);
//systemChat format ["Displaynum: %1", _displayNum];
GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]);
};
_ctrl = GVAR(iconCtrls) select GVAR(iconCount);
GVAR(iconCount) = GVAR(iconCount) + 1;
if(_icon == "") then {
_icon = DEFAULT_ICON;
};
//systemChat format ["Ctrl: %1, %2,%3", _text,_sPos select 0, _sPos select 1];
_text = format ["<img image='%1' color='%2' align='center'/><br/><t color ='%3' size='0.75' align='center'>%4</t>", _icon, _color, _color, _text];
_ctrl ctrlSetStructuredText (parseText _text);
_ctrl ctrlSetPosition [(_sPos select 0)-(0.2*SafeZoneW), (_sPos select 1)-(0.0095*SafeZoneW), 0.4*SafeZoneW, 0.035*SafeZoneW];

View File

@ -5,20 +5,20 @@
* Argument:
* 0: Object <OBJECT>
* 1: Action data <ARRAY>
* 2: ?
* 2: Was the condition already checked? <BOOL>
* 3: Angle range available for rendering <ARRAY>
* 4: 3D position <ARRAY> (Optional)
*
* Return value:
* None
* Was the menu rendered <BOOL>
*
* Public: No
*/
#include "script_component.hpp"
private ["_distance", "_uid", "_pos", "_cursorScreenPos", "_path", "_menuDepth", "_opacity", "_currentRenderDepth", "_radialOffset", "_active", "_x", "_offset", "_newPos", "_forEachIndex"];
private ["_distance", "_uid", "_pos", "_cameraPos", "_path", "_menuDepth", "_opacity", "_currentRenderDepth", "_radialOffset", "_active", "_x", "_offset", "_newPos", "_forEachIndex"];
EXPLODE_4_PVT(_this,_object,_actionData,_dummy,_angles);
EXPLODE_4_PVT(_this,_object,_actionData,_wasConditionChecked,_angles);
EXPLODE_2_PVT(_angles,_centerAngle,_maxAngleSpan);
_uid = _actionData select 7;
@ -35,12 +35,20 @@ if((count _this) > 4) then {
};
};
_cursorScreenPos = (positionCameraToWorld [0, 0, 0]);
// Exit if the action is too far away
if(_cursorScreenPos distance _pos >= _distance) exitWith {};
// For non-self actions, exit if the action is too far away
_cameraPos = positionCameraToWorld [0, 0, 0];
if (GVAR(keyDown) && {_cameraPos distance _pos >= _distance}) exitWith {false};
// Exit if the action is behind you
if(_cursorScreenPos select 2 < 0) exitWith {};
_sPos = worldToScreen _pos;
if(count _sPos == 0) exitWith {false};
// Exit if the action is off screen
if ((_sPos select 0) < safeZoneXAbs || (_sPos select 0) > safeZoneXAbs + safeZoneWAbs) exitWith {false};
if ((_sPos select 1) < safeZoneY || (_sPos select 1) > safeZoneY + safeZoneH) exitWith {false};
// If the condition was not checked, check it and exit if needed
if (!_wasConditionChecked && {!([_target, ACE_player] call (_actionItem select 4))}) exitWith {false};
_menuDepth = (count GVAR(menuDepthPath)) - 1;
@ -72,7 +80,7 @@ if(_menuDepth > 0 && !_menuInSelectedPath) then {
GVAR(currentOptions) pushBack [_this, _pos, _path];
// Exit without rendering children if it isn't
if !(_menuInSelectedPath) exitWith {};
if !(_menuInSelectedPath) exitWith {true};
// Collect all active children actions
private "_activeChildren";
@ -126,12 +134,12 @@ _angle = _centerAngle - _angleSpan / 2;
_player = ACE_player;
_offset = [GVAR(vecLineMap), _angle] call FUNC(rotateVectLine);
_mod = 0.15 max (0.15 * (_cursorScreenPos distance _pos));
_mod = (0.15 max (0.15 * (_cameraPos distance _pos))) / GVAR(selfMenuScale);
_newPos = _pos vectorAdd (_offset vectorMultiply _mod);
// drawLine3D [_pos, _newPos, [1,0,0,0.5]];
[_object, _x, _forEachIndex, [_angle, 140], _newPos] call FUNC(renderMenu);
[_object, _x, true, [_angle, 140], _newPos] call FUNC(renderMenu);
if (_angleSpan == 360) then {
_angle = _angle + _angleSpan / (count _activeChildren);
@ -139,3 +147,5 @@ _angle = _centerAngle - _angleSpan / 2;
_angle = _angle + _angleSpan / (((count _activeChildren)-1) max 1);
};
} forEach _activeChildren;
true

View File

@ -32,7 +32,7 @@ class CfgVehicles {
class ACE_Actions {
class ACE_MainActions {
displayName = "$STR_ACE_Interaction_MainAction";
distance = 4;
distance = 5;
condition = QUOTE(true);
statement = "";
icon = "\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa";
@ -40,7 +40,7 @@ class CfgVehicles {
class ACE_TeamManagement {
displayName = "$STR_ACE_Interaction_TeamManagement";
distance = 4;
distance = 5;
condition = QUOTE(alive _target && {!isPlayer _target} && {_target in units group _player} && {GVAR(EnableTeamManagement)});
statement = "";
showDisabled = 0;
@ -51,7 +51,7 @@ class CfgVehicles {
class ACE_JoinTeamRed {
displayName = "$STR_ACE_Interaction_JoinTeamRed";
distance = 4;
distance = 5;
condition = QUOTE(alive _target && {!isPlayer _target} && {_target in units group _player});
statement = QUOTE([ARR_2(_target,'RED')] call DFUNC(joinTeam));
showDisabled = 1;
@ -62,7 +62,7 @@ class CfgVehicles {
};
class ACE_JoinTeamGreen {
displayName = "$STR_ACE_Interaction_JoinTeamGreen";
distance = 4;
distance = 5;
condition = QUOTE(alive _target && {!isPlayer _target} && {_target in units group _player});
statement = QUOTE([ARR_2(_target,'GREEN')] call DFUNC(joinTeam));
showDisabled = 1;
@ -73,7 +73,7 @@ class CfgVehicles {
};
class ACE_JoinTeamBlue {
displayName = "$STR_ACE_Interaction_JoinTeamBlue";
distance = 4;
distance = 5;
condition = QUOTE(alive _target && {!isPlayer _target} && {_target in units group _player});
statement = QUOTE([ARR_2(_target,'BLUE')] call DFUNC(joinTeam));
showDisabled = 1;
@ -84,7 +84,7 @@ class CfgVehicles {
};
class ACE_JoinTeamYellow {
displayName = "$STR_ACE_Interaction_JoinTeamYellow";
distance = 4;
distance = 5;
condition = QUOTE(alive _target && {!isPlayer _target} && {_target in units group _player});
statement = QUOTE([ARR_2(_target,'YELLOW')] call DFUNC(joinTeam));
showDisabled = 1;
@ -96,7 +96,7 @@ class CfgVehicles {
class ACE_LeaveTeam {
displayName = "$STR_ACE_Interaction_LeaveTeam";
distance = 4;
distance = 5;
condition = QUOTE(alive _target && {!isPlayer _target} && {_target in units group _player} && {assignedTeam _player != 'MAIN'});
statement = QUOTE([ARR_2(_target,'MAIN')] call DFUNC(joinTeam));
showDisabled = 1;
@ -109,7 +109,7 @@ class CfgVehicles {
class ACE_JoinGroup {
displayName = "$STR_ACE_Interaction_JoinGroup";
distance = 4;
distance = 5;
condition = QUOTE(side group _player == side group _target && {group _player != group _target});
statement = QUOTE([_player] joinSilent group _target;);
showDisabled = 0;
@ -121,7 +121,7 @@ class CfgVehicles {
class ACE_GetDown {
displayName = "$STR_ACE_Interaction_GetDown";
distance = 4;
distance = 5;
condition = QUOTE([_target] call DFUNC(canInteractWith));
statement = QUOTE([_target] call DFUNC(getDown));
showDisabled = 0;
@ -129,7 +129,7 @@ class CfgVehicles {
};
class ACE_SendAway {
displayName = "$STR_ACE_Interaction_SendAway";
distance = 4;
distance = 5;
condition = QUOTE([_target] call DFUNC(canInteractWith));
statement = QUOTE([_target] call DFUNC(sendAway));
showDisabled = 0;
@ -137,7 +137,7 @@ class CfgVehicles {
};
class ACE_Pardon {
displayName = "$STR_ACE_Interaction_Pardon";
distance = 4;
distance = 5;
condition = QUOTE(rating _target < -2000 && {alive _target} && {side group _player == side group _target});
statement = QUOTE([ARR_3(_target,'{_this addRating -rating _this}',_target)] call DEFUNC(common,execRemoteFnc));
showDisabled = 0;