Merge branch 'master' into explosiveInteraction

This commit is contained in:
Garth L-H de Wet 2015-03-01 14:31:06 +02:00
commit 3ff1bff2bf
38 changed files with 697 additions and 418 deletions

View File

@ -1,7 +1,7 @@
root = true
[*]
end_of_line = lf
end_of_line = crlf
insert_final_newline = true
charset = utf-8
indent_style = space

View File

@ -4,14 +4,8 @@
_fnc = {
_this call FUNC(render);
};
// [_fnc, 0, []] call cba_fnc_addPerFrameHandler;
addMissionEventHandler ["Draw3D", _fnc];
_fnc = {
_this call FUNC(probe);
};
[_fnc, 0.5, []] call cba_fnc_addPerFrameHandler;
["ACE3",
"Interact Key",
{_this call FUNC(keyDown)},

View File

@ -9,15 +9,13 @@ PREP(keyDown);
PREP(keyDownSelfAction);
PREP(keyUp);
PREP(keyUpSelfAction);
PREP(probe);
PREP(removeAction);
PREP(render);
PREP(renderIcon);
PREP(renderMenu);
PREP(rotateVectLine);
PREP(rotateVectLineGetMap);
GVAR(toRender) = [];
PREP(updateVecLineMap);
GVAR(keyDown) = false;
GVAR(keyDownSelfAction) = false;
@ -30,11 +28,7 @@ GVAR(selectedAction) = {};
GVAR(actionSelected) = false;
GVAR(selectedTarget) = objNull;
GVAR(filter) = [];
GVAR(menuDepthPath) = [];
GVAR(renderDepth) = 0;
GVAR(lastRenderDepth) = 0;
GVAR(vecLineMap) = [];
GVAR(lastPos) = [0,0,0];
@ -44,13 +38,10 @@ GVAR(lastPath) = [];
GVAR(expanded) = false;
GVAR(maxRenderDepth) = 0;
GVAR(startHoverTime) = diag_tickTime;
GVAR(iconCtrls) = [];
GVAR(iconCount) = 0;
GVAR(objectActionsHash) = HASH_CREATE;
GVAR(uidCounter) = 0;
ADDON = true;

View File

@ -1,39 +1,40 @@
/*
* Author: commy2 and NouberNou
* Add an ACE action to an object or inside a parent action. Note: This function is NOT global.
* Author: commy2, NouberNou and CAA-Picard
* Add an ACE action to an object, under a certain config path
* Note: This function is NOT global.
*
* Argument:
* 0: Object the action should be assigned to or parent action <OBJECT> or <ARRAY>
* 1: Name of the action shown in the menu <STRING>
* 2: Icon <STRING>
* 3: Position (Position or Selection Name) <POSITION> or <STRING>
* 4: Statement <CODE>
* 5: Condition <CODE>
* 6: Distance <NUMBER>
* 0: Object the action should be assigned to <OBJECT>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Full path of the new action <ARRAY>
* 3: Name of the action shown in the menu <STRING>
* 4: Icon <STRING>
* 5: Position (Position or Selection Name) <POSITION> or <STRING>
* 6: Statement <CODE>
* 7: Condition <CODE>
* 8: Distance <NUMBER>
*
* Return value:
* The entry array, which can be used to remove the entry, or add children entries <ARRAY>.
* The entry full path, which can be used to remove the entry, or add children entries <ARRAY>.
*
* Example:
* [cursorTarget,0,["ACE_TapShoulderRight","VulcanPinch"],"Vulcan Pinch","",[0,0,0],{_target setDamage 1;},{true},100] call ace_interact_menu_fnc_addAction;
*
* Public: No
*/
#include "script_component.hpp"
EXPLODE_7_PVT(_this,_object,_displayName,_icon,_position,_statement,_condition,_distance);
EXPLODE_9_PVT(_this,_object,_typeNum,_fullPath,_displayName,_icon,_position,_statement,_condition,_distance);
private ["_varName","_actions"];
private ["_actions","_entry"];
_actions = [];
if(IS_OBJECT(_object)) then {
_actions = _object getVariable [QUOTE(GVAR(actionData)), []];
if((count _actions) == 0) then {
_object setVariable [QUOTE(GVAR(actionData)), _actions]
};
} else {
if(IS_ARRAY(_object)) then {
_actions = _object select 6;
};
_varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum;
_actions = _object getVariable [_varName, []];
if((count _actions) == 0) then {
_object setVariable [_varName, _actions];
};
private "_entry";
_entry = [
_displayName,
_icon,
@ -42,8 +43,11 @@ _entry = [
_condition,
_distance,
[],
GVAR(uidCounter)
GVAR(uidCounter),
+ _fullPath
];
GVAR(uidCounter) = GVAR(uidCounter) + 1;
_actions pushBack _entry;
_entry;
_fullPath

View File

@ -1,6 +1,6 @@
/*
* Author: NouberNou
* Compile the action menu from config for a given object.
* Author: NouberNou and CAA-Picard
* Compile the action menu from config for an object's class
*
* Argument:
* 0: Object <OBJECT>
@ -14,31 +14,21 @@
EXPLODE_1_PVT(_this,_object);
/*
[
[
"Launch",
"\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa",
[0,0,0],
{ (_this select 0) setVelocity [0,0,10]; },
{ true },
1,
[]
]
]
*/
private ["_objectType","_recurseFnc","_actions"];
private ["_objectType","_actionsVarName"];
_objectType = typeOf _object;
_actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_Actions";
_actionsVarName = format [QGVAR(Act_%1), _objectType];
// Exit if the action menu is already compiled for this class
if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {};
private "_recurseFnc";
_recurseFnc = {
private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_selection", "_condition", "_showDisabled",
"_enableInside", "_children", "_entry", "_actionsCfg"];
"_enableInside", "_children", "_entry", "_entryCfg", "_fullPath"];
EXPLODE_2_PVT(_this,_actionsCfg,_parentPath);
_actions = [];
_actionsCfg = _this select 0;
for "_i" from 0 to (count _actionsCfg)-1 do {
for "_i" from 0 to (count _actionsCfg) - 1 do {
_entryCfg = _actionsCfg select _i;
if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName");
@ -58,8 +48,12 @@ _recurseFnc = {
_showDisabled = getNumber (_entryCfg >> "showDisabled");
_enableInside = getNumber (_entryCfg >> "enableInside");
_fullPath = (+ _parentPath);
_fullPath pushBack (configName _entryCfg);
_condition = compile _condition;
_children = [_entryCfg] call _recurseFnc;
_children = [_entryCfg, _fullPath] call _recurseFnc;
_entry = [
_displayName,
_icon,
@ -68,8 +62,10 @@ _recurseFnc = {
_condition,
_distance,
_children,
GVAR(uidCounter)
GVAR(uidCounter),
_fullPath
];
GVAR(uidCounter) = GVAR(uidCounter) + 1;
_actions pushBack _entry;
};
@ -77,6 +73,23 @@ _recurseFnc = {
_actions
};
_actions = [_actionsCfg] call _recurseFnc;
private "_actionsCfg";
_actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_Actions";
_object setVariable [QUOTE(GVAR(actionData)), _actions];
missionNamespace setVariable [_actionsVarName, [_actionsCfg, []] call _recurseFnc];
/*
[
[
"My Action",
"\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa",
[0,0,0],
{ (_this select 0) setVelocity [0,0,10]; },
{ true },
1,
[],
uid,
["MainActions","TeamManagement","MyAction"]
]
]
*/

View File

@ -1,6 +1,6 @@
/*
* Author: NouberNou and CAA-Picard
* Compile the self action menu from config for a given object.
* Compile the self action menu from config for an object's class
*
* Argument:
* 0: Object <OBJECT>
@ -14,34 +14,25 @@
EXPLODE_1_PVT(_this,_object);
/*
[
[
"Launch",
"\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa",
[0,0,0],
{ (_this select 0) setVelocity [0,0,10]; },
{ true },
1,
[]
]
]
*/
private ["_objectType","_recurseFnc","_actions"];
private ["_objectType","_actionsVarName"];
_objectType = typeOf _object;
_actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_SelfActions";
_actionsVarName = format [QGVAR(SelfAct_%1), _objectType];
// Exit if the action menu is already compiled for this class
if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {};
private "_recurseFnc";
_recurseFnc = {
private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_condition", "_showDisabled",
"_enableInside", "_children", "_entry", "_actionsCfg"];
private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_selection", "_condition", "_showDisabled",
"_enableInside", "_children", "_entry", "_entryCfg", "_fullPath"];
EXPLODE_2_PVT(_this,_actionsCfg,_parentPath);
_actions = [];
_actionsCfg = _this select 0;
for "_i" from 0 to (count _actionsCfg)-1 do {
for "_i" from 0 to (count _actionsCfg) - 1 do {
_entryCfg = _actionsCfg select _i;
if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName");
_icon = getText (_entryCfg >> "icon");
_statement = compile (getText (_entryCfg >> "statement"));
@ -54,8 +45,12 @@ _recurseFnc = {
_showDisabled = getNumber (_entryCfg >> "showDisabled");
_enableInside = getNumber (_entryCfg >> "enableInside");
_fullPath = (+ _parentPath);
_fullPath pushBack (configName _entryCfg);
_condition = compile _condition;
_children = [_entryCfg] call _recurseFnc;
_children = [_entryCfg, _fullPath] call _recurseFnc;
_entry = [
_displayName,
_icon,
@ -64,8 +59,10 @@ _recurseFnc = {
_condition,
10, //distace
_children,
GVAR(uidCounter)
GVAR(uidCounter),
_fullPath
];
GVAR(uidCounter) = GVAR(uidCounter) + 1;
_actions pushBack _entry;
};
@ -73,7 +70,8 @@ _recurseFnc = {
_actions
};
_actions = [_actionsCfg] call _recurseFnc;
private "_actionsCfg";
_actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_SelfActions";
// Create a master action to base on self action
_actions = [[
@ -83,10 +81,11 @@ _actions = [[
{ true },
{ true },
10,
_actions,
GVAR(uidCounter)
[_actionsCfg, ["SelfActions"]] call _recurseFnc,
GVAR(uidCounter),
["SelfActions"]
]
];
GVAR(uidCounter) = GVAR(uidCounter) + 1;
_object setVariable [QUOTE(GVAR(selfActionData)), _actions];
missionNamespace setVariable [_actionsVarName, _actions];

View File

@ -17,7 +17,7 @@ if(GVAR(actionSelected)) then {
this = GVAR(selectedTarget);
_player = ACE_Player;
_target = GVAR(selectedTarget);
[GVAR(selectedTarget), player] call GVAR(selectedAction);
[GVAR(selectedTarget), ACE_player] call GVAR(selectedAction);
};
GVAR(expanded) = false;
GVAR(lastPath) = [];

View File

@ -17,7 +17,7 @@ if(GVAR(actionSelected)) then {
this = GVAR(selectedTarget);
_player = ACE_Player;
_target = GVAR(selectedTarget);
[GVAR(selectedTarget), player] call GVAR(selectedAction);
[GVAR(selectedTarget), ACE_player] call GVAR(selectedAction);
};
GVAR(expanded) = false;
GVAR(lastPath) = [];

View File

@ -1,55 +0,0 @@
/*
* Author: NouberNou
* Scan de vicinity of the player and collect every interaction available around it on
* the GVAR(toRender) array.
*
* Argument:
* None
*
* Return value:
* None
*
* Public: No
*/
#include "script_component.hpp"
private ["_nearestObjects", "_actionObject", "_x", "_actionData", "_renderData", "_actionItem", "_active", "_renderItem", "_object", "_forEachIndex"];
if(!GVAR(keyDown)) then {
_nearestObjects = nearestObjects [(getPos ACE_player), ["All"], 100];
GVAR(toRender) = [];
{
_actionObject = _x;
_actionData = _actionObject getVariable [QUOTE(GVAR(actionData)), []];
if((count _actionData) > 0) then {
_renderData = [];
{
_actionItem = _x;
this = _actionObject;
_target = _actionObject;
_player = ACE_player;
_active = [_target, ACE_player] call (_actionItem select 4);
systemChat format ["%1 %2 is active %3", _actionObject, _actionItem select 0, _active];
// player sideChat format["_active: %1 %2", _actionItem select 0, _active];
if(_active) then {
_renderItem = +_actionItem;
_renderItem set[4, true];
_renderData set[(count _renderData), _renderItem];
};
} forEach _actionData;
if((count _renderData) > 0) then {
GVAR(toRender) set[(count GVAR(toRender)), [_actionObject, _renderData]];
};
};
} forEach _nearestObjects;
// player sideChat format["p: %1", count GVAR(toRender)];
} else {
GVAR(filter) = [];
{
_object = _x select 0;
if(_object distance ACE_player > 100) then {
GVAR(filter) set[(count GVAR(filter)), _forEachIndex];
};
} forEach GVAR(toRender);
};

View File

@ -1,50 +1,30 @@
/*
* Author: commy2 and NouberNou
* Author: commy2, NouberNou and CAA-Picard
* Remove an action from an object
*
* Argument:
* 0: Object the action should be assigned to <OBJECT>
* 1: Entry to remove <ARRAY> or <NUMBER>
* 0: Object the action is assigned to <OBJECT>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Full path of the action to remove <ARRAY>
*
* Return value:
* None
*
* Example:
* [cursorTarget,0,["ACE_TapShoulderRight","VulcanPinch"]] call ace_interact_menu_fnc_removeAction;
*
* Public: No
*/
#include "script_component.hpp"
EXPLODE_2_PVT(_this,_object,_entry);
EXPLODE_3_PVT(_this,_object,_typeNum,_fullPath);
private ["_found", "_actions", "_searchFnc"];
private ["_varName","_actions"];
_varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum;
_actions = _object getVariable [_varName, []];
if(!IS_OBJECT(_object)) exitWith {false};
_actions = _object getVariable [QUOTE(GVAR(actionData)), []];
if(IS_ARRAY(_entry)) then {
_entry = _entry select 7;
};
_found = false;
_searchFnc = {
private ["_actions", "_entry", "_childActions"];
_actions = _this select 0;
_entry = _this select 1;
{
if((_x select 7) == _entry) then {
_actions set[_forEachIndex, "aceactiondelete"];
_actions = _actions - ["aceactiondelete"];
_found = true;
} else {
if(!_found && {count (_x select 6) > 0}) then {
_childActions = [(_x select 6), _entry] call _searchFnc;
_x set[6, _childActions];
};
};
} forEach _actions;
_actions;
};
_actions = [_actions, _entry] call _searchFnc;
_object setVariable [QUOTE(GVAR(actionData)), _actions];
_found;
{
if ((_x select 8) isEqualTo _fullPath) exitWith {
_actions deleteAt _forEachIndex;
};
} forEach _actions;

View File

@ -16,41 +16,91 @@ private ["_cursorPos1", "_cursorPos2", "_cursorVec", "_p1", "_p2", "_p", "_v", "
_foundTarget = false;
_cursorPos1 = positionCameraToWorld [0, 0, 0];
_cursorPos2 = positionCameraToWorld [0, 0, 2];
GVAR(currentOptions) = [];
if((count GVAR(toRender)) > 0 && (GVAR(keyDown) || GVAR(keyDownSelfAction))) then {
if((count GVAR(vecLineMap)) == 0 || ((count GVAR(menuDepthPath)) > 0 && (getPosASL player) distance GVAR(lastPos) > 0.01)) then {
GVAR(lastPos) = getPosASL player;
_cursorVec = [_cursorPos2, _cursorPos1] call BIS_fnc_vectorFromXtoY;
_p1 = [0,0,0];
_p2 = +_cursorVec;
_p = (_cursorVec call CBA_fnc_vect2polar);
_v = [(_p select 0), (_p select 1), (_p select 2)+90] call CBA_fnc_polar2vect;
_cp = [_cursorVec, _v] call BIS_fnc_crossProduct;
GVAR(vecLineMap) = [_cp, _p1, _p2] call FUNC(rotateVectLineGetMap);
};
if (GVAR(keyDown)) then {
// Render all nearby interaction menus
private ["_actionsVarName","_classActions","_objectActions","_target","_player","_actionItem","_active"];
if (GVAR(keyDown)) then {
[] call FUNC(updateVecLineMap);
// Render all nearby interaction menus
_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), []];
{
if(!(_forEachIndex in GVAR(filter))) then {
GVAR(renderDepth) = 0;
_renderTargets = _x;
{
[_renderTargets select 0, _x, 0, [180, 360]] call FUNC(renderMenu);
} forEach (_renderTargets select 1);
};
} forEach GVAR(toRender);
} else {
// Render only the self action menu
_actions = (ACE_player getVariable QGVAR(selfActionData)) select 0;
_pos = (ACE_player modelToWorld (ACE_player selectionPosition "spine3")) vectorAdd GVAR(selfMenuOffset) vectorAdd [0,0,0.25];
[ACE_player, _actions, 0, [180, 360], _pos] call FUNC(renderMenu);
};
_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);
// player sideChat format["c: %1", count GVAR(toRender)];
if (_active) then {
[_target, _actionItem, 0, [180, 360]] call FUNC(renderMenu);
};
};
} 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;
} forEach _nearestObjects;
} else {
if (GVAR(keyDownSelfAction)) then {
[] call FUNC(updateVecLineMap);
// 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
if (count (_actionItem select 8) == 1) then {
_active = [_target, ACE_player] call (_actionItem select 4);
if (_active) then {
[_target, _actionItem, 0, [180, 360]] call FUNC(renderMenu);
};
};
} forEach GVAR(objectActions);
// Iterate through base level class actions and render them if appropiate
_actionsVarName = format [QGVAR(SelfAct_%1), typeOf _target];
_classActions = missionNamespace getVariable [_actionsVarName, []];
{
_actionItem = _x;
_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);
};
} forEach _classActions;
};
};
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"];
_cursorScreenPos = worldToScreen _cursorPos2;
_closestDistance = 1000000;
@ -67,48 +117,48 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then {
};
} forEach GVAR(currentOptions);
if(_closestSelection != -1) then {
_closest = GVAR(currentOptions) select _closestSelection;
if(_closestSelection == -1) exitWith {};
_pos = _closest select 1;
_cTime = diag_tickTime;
_delta = _cTime - GVAR(lastTime);
GVAR(lastTime) = _cTime;
GVAR(rotationAngle) = GVAR(rotationAngle) + (180*_delta);
if(GVAR(rotationAngle) > 360) then {
GVAR(rotationAngle) = GVAR(rotationAngle) - 360;
};
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,.75], _pos, 0.6*SafeZoneW, 0.6*SafeZoneW, GVAR(rotationAngle), "", 0.5, 0.025, "TahomaB"];
_foundTarget = true;
GVAR(actionSelected) = true;
GVAR(selectedTarget) = (_closest select 0) select 0;
GVAR(selectedAction) = ((_closest select 0) select 1) select 3;
_misMatch = false;
_hoverPath = (_closest select 2);
if((count GVAR(lastPath)) != (count _hoverPath)) then {
_misMatch = true;
} else {
{
if(_x != (_hoverPath select _forEachIndex)) exitWith {
_misMatch = true;
};
} forEach GVAR(lastPath);
};
_closest = GVAR(currentOptions) select _closestSelection;
if(_misMatch) then {
GVAR(lastPath) = _hoverPath;
GVAR(startHoverTime) = diag_tickTime;
GVAR(expanded) = false;
} else {
if(!GVAR(expanded) && diag_tickTime-GVAR(startHoverTime) > 0.25) then {
GVAR(expanded) = true;
GVAR(menuDepthPath) = +GVAR(lastPath);
_pos = _closest select 1;
_cTime = diag_tickTime;
_delta = _cTime - GVAR(lastTime);
GVAR(lastTime) = _cTime;
GVAR(rotationAngle) = GVAR(rotationAngle) + (180*_delta);
if(GVAR(rotationAngle) > 360) then {
GVAR(rotationAngle) = GVAR(rotationAngle) - 360;
};
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,.75], _pos, 0.6*SafeZoneW, 0.6*SafeZoneW, GVAR(rotationAngle), "", 0.5, 0.025, "TahomaB"];
_foundTarget = true;
GVAR(actionSelected) = true;
GVAR(selectedTarget) = (_closest select 0) select 0;
GVAR(selectedAction) = ((_closest select 0) select 1) select 3;
_misMatch = false;
_hoverPath = (_closest select 2);
if((count GVAR(lastPath)) != (count _hoverPath)) then {
_misMatch = true;
} else {
{
if(_x != (_hoverPath select _forEachIndex)) exitWith {
_misMatch = true;
};
} forEach GVAR(lastPath);
};
if(_misMatch) then {
GVAR(lastPath) = _hoverPath;
GVAR(startHoverTime) = diag_tickTime;
GVAR(expanded) = false;
} else {
if(!GVAR(expanded) && diag_tickTime-GVAR(startHoverTime) > 0.25) then {
GVAR(expanded) = true;
GVAR(menuDepthPath) = +GVAR(lastPath);
};
};
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selected_ca.paa", [1,0,0,1], _cursorPos2, 1, 1, 0, "", 0.5, 0.025, "TahomaB"];
};
if(!_foundTarget && GVAR(actionSelected)) then {
GVAR(actionSelected) = false;
GVAR(expanded) = false;

View File

@ -24,6 +24,8 @@ _color = _this select 1;
_pos = _this select 2;
_icon = _this select 6;
//systemChat format ["Icon %1 - %2,%3,%4", _text, _pos select 0, _pos select 1, _pos select 2];
_sPos = worldToScreen _pos;
// _sPos = _pos;
if(count _sPos > 0) then {

View File

@ -1,6 +1,6 @@
/*
* Author: NouberNou and CAA-Picard
* Render a interaction menu
* Render a interaction menu and it's children recursively
*
* Argument:
* 0: Object <OBJECT>
@ -8,7 +8,6 @@
* 2: ?
* 3: Angle range available for rendering <ARRAY>
* 4: 3D position <ARRAY> (Optional)
* 5: Path of UIDs <ARRAY> (Optional)
*
* Return value:
* None
@ -17,16 +16,15 @@
*/
#include "script_component.hpp"
private ["_object", "_actionData", "_distance", "_uid", "_pos", "_cursorScreenPos", "_path", "_menuDepth", "_opacity", "_currentRenderDepth", "_radialOffset", "_active", "_x", "_offset", "_newPos", "_forEachIndex"];
private ["_distance", "_uid", "_pos", "_cursorScreenPos", "_path", "_menuDepth", "_opacity", "_currentRenderDepth", "_radialOffset", "_active", "_x", "_offset", "_newPos", "_forEachIndex"];
_object = _this select 0;
_actionData = _this select 1;
_uid = _actionData select 7;//_this select 2;
_angles = _this select 3;
_distance = _actionData select 5;
EXPLODE_4_PVT(_this,_object,_actionData,_dummy,_angles);
EXPLODE_2_PVT(_angles,_centerAngle,_maxAngleSpan);
_uid = _actionData select 7;
_distance = _actionData select 5;
// Obtain a 3D position for the action
if((count _this) > 4) then {
_pos = _this select 4;
} else {
@ -36,70 +34,108 @@ if((count _this) > 4) then {
_pos = _object modelToWorld (_object selectionPosition (_actionData select 2));
};
};
_cursorScreenPos = (positionCameraToWorld [0, 0, 0]);
if(_cursorScreenPos distance _pos <= _distance) then {
_path = [];
if((count _this) > 5) then {
_path = +(_this select 5);
// Exit if the action is too far away
if(_cursorScreenPos distance _pos >= _distance) exitWith {};
// Exit if the action is behind you
if(_cursorScreenPos select 2 < 0) exitWith {};
_menuDepth = (count GVAR(menuDepthPath)) - 1;
// Store path to action
_path = [_object];
_path = _path + (_actionData select 8);
// Check if the menu is on the selected path
private "_menuInSelectedPath";
_menuInSelectedPath = true;
{
if (_forEachIndex >= (count GVAR(menuDepthPath))) exitWith {
_menuInSelectedPath = false;
};
_menuDepth = (count GVAR(menuDepthPath));
// ARGB Color (First Hex Pair is transparancy)
_color = "#FFFFFFFF";
if(_menuDepth > 0 && _uid != (GVAR(menuDepthPath) select (GVAR(renderDepth)))) then {
_color = format ["#%1FFFFFF", [255 * (((GVAR(renderDepth)/_menuDepth)) max 0.25)] call EFUNC(common,toHex)];
if (_x != (GVAR(menuDepthPath) select _forEachIndex)) exitWith {
_menuInSelectedPath = false;
};
_path set[(count _path), _uid];
[_actionData select 0, _color, _pos, 1, 1, 0, _actionData select 1, 0.5, 0.025, "TahomaB"] call FUNC(renderIcon);
GVAR(currentOptions) set[(count GVAR(currentOptions)), [_this, _pos, _path]];
_currentRenderDepth = -1;
_currentRenderDepth = GVAR(renderDepth);
GVAR(renderDepth) = GVAR(renderDepth) + 1;
if(_uid == (GVAR(menuDepthPath) select (GVAR(renderDepth)-1))) then {
// Count how many actions are active
private "_numActions";
_numActions = 0;
{
this = _object;
_target = _object;
_player = ACE_player;
_active = [_object, ACE_player] call (_x select 4);
if(_active) then {
_numActions = _numActions + 1;
};
} forEach (_actionData select 6);
systemChat format ["Menu %1, _numActions: %2", _actionData select 0, _numActions];
} forEach _path;
private "_angleSpan";
_angleSpan = _maxAngleSpan min (55 * (_numActions - 1));
private "_angle";
_angle = _centerAngle - _angleSpan / 2;
{
this = _object;
_target = _object;
_player = ACE_player;
_active = [_object, ACE_player] call (_x select 4);
// diag_log text format["_active: %1: %2", (_x select 0), _active];
if(_active) then {
//systemChat format ["_angle: %1", _angle];
_offset = [GVAR(vecLineMap), _angle] call FUNC(rotateVectLine);
_mod = 0.15 max (0.15 * (_cursorScreenPos distance _pos)); //0.5;//0.1*_distance;
_newPos = [
(_pos select 0) + ((_offset select 0)*_mod),
(_pos select 1) + ((_offset select 1)*_mod),
(_pos select 2) + ((_offset select 2)*_mod)
];
// drawLine3D [_pos, _newPos, [1,0,0,0.5]];
[_object, _x, _forEachIndex, [_angle, 150], _newPos, _path] call FUNC(renderMenu);
if (_angle == 360) then {
_angle = _angle + _angleSpan / _numActions;
} else {
_angle = _angle + _angleSpan / ((_numActions-1) max 1);
};
};
} forEach (_actionData select 6);
};
GVAR(renderDepth) = GVAR(renderDepth) - 1;
// Render icon
// ARGB Color (First Hex Pair is transparancy)
_color = "#FFFFFFFF";
if(_menuDepth > 0 && !_menuInSelectedPath) then {
_color = format ["#%1FFFFFF", [255 * ((((count _path) - 2)/_menuDepth) max 0.25)] call EFUNC(common,toHex)];
};
[_actionData select 0, _color, _pos, 1, 1, 0, _actionData select 1, 0.5, 0.025, "TahomaB"] call FUNC(renderIcon);
// Add the action to current options
GVAR(currentOptions) pushBack [_this, _pos, _path];
// Exit without rendering children if it isn't
if !(_menuInSelectedPath) exitWith {};
// Collect all active children actions
private "_activeChildren";
_activeChildren = [];
// Collect children class actions
{
_target = _object;
_player = ACE_player;
_active = [_object, ACE_player] call (_x select 4);
if(_active) then {
_activeChildren pushBack _x;
};
} forEach (_actionData select 6);
// Collect children object actions
{
_actionItem = _x;
// Check if the action is children of the selected menu
if ((count (_actionItem select 8)) == (count _path)) then {
// Compare parent path to see if it's a suitable child
private "_isChild";
_isChild = true;
for "_i" from 0 to (count (_actionItem select 8)) - 2 do {
if !(((_actionItem select 8) select _i) isEqualTo (_path select (_i + 1))) exitWith {
_isChild = false;
};
};
if (_isChild) exitWith {
_target = _object;
_player = ACE_player;
_active = [_target, ACE_player] call (_actionItem select 4);
if (_active) then {
_activeChildren pushBack _actionItem;
};
};
};
} forEach GVAR(objectActions);
private ["_angleSpan","_angle"];
_angleSpan = _maxAngleSpan min (55 * ((count _activeChildren) - 1));
if (_angleSpan >= 305) then {
_angleSpan = 360;
};
_angle = _centerAngle - _angleSpan / 2;
{
_target = _object;
_player = ACE_player;
_offset = [GVAR(vecLineMap), _angle] call FUNC(rotateVectLine);
_mod = 0.15 max (0.15 * (_cursorScreenPos distance _pos));
_newPos = _pos vectorAdd (_offset vectorMultiply _mod);
// drawLine3D [_pos, _newPos, [1,0,0,0.5]];
[_object, _x, _forEachIndex, [_angle, 140], _newPos] call FUNC(renderMenu);
if (_angleSpan == 360) then {
_angle = _angle + _angleSpan / (count _activeChildren);
} else {
_angle = _angle + _angleSpan / (((count _activeChildren)-1) max 1);
};
} forEach _activeChildren;

View File

@ -0,0 +1,13 @@
#include "script_component.hpp";
if((count GVAR(vecLineMap)) == 0 || ((count GVAR(menuDepthPath)) > 0 && (getPosASL player) distance GVAR(lastPos) > 0.01)) then {
GVAR(lastPos) = getPosASL player;
_cursorVec = [_cursorPos2, _cursorPos1] call BIS_fnc_vectorFromXtoY;
_p1 = [0,0,0];
_p2 = +_cursorVec;
_p = (_cursorVec call CBA_fnc_vect2polar);
_v = [(_p select 0), (_p select 1), (_p select 2)+90] call CBA_fnc_polar2vect;
_cp = [_cursorVec, _v] call BIS_fnc_crossProduct;
GVAR(vecLineMap) = [_cp, _p1, _p2] call FUNC(rotateVectLineGetMap);
};

View File

@ -1,4 +1,18 @@
// by commy2
/*
* Author: commy2
* Tests the the player can climb.
*
* Arguments:
* 0: The Unit (usually the player) <OBJECT>
*
* Return Value:
* The return value <BOOL>
*
* Example:
* _bool = [player] call ace_movement_fnc_canClimb
*
* Public: No
*/
#include "script_component.hpp"
private ["_unit", "_pos", "_dir"];
@ -20,6 +34,6 @@ _checkPos1end = _checkPos1beg vectorAdd _dir;
/*
drawLine3D [ASLToATL _checkPos0beg, ASLToATL _checkPos0end, [1,0,0,1]];
drawLine3D [ASLToATL _checkPos1beg, ASLToATL _checkPos1end, [1,0,0,1]];
*/
*/
lineIntersects [_checkPos0beg, _checkPos0end] && {!(lineIntersects [_checkPos1beg, _checkPos1end])}

View File

@ -1,4 +1,18 @@
// by commy2
/*
* Author: commy2
* Make the player climb over short walls.
*
* Arguments:
* 0: The Unit (usually the player) <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player] call ace_movement_fnc_climb
*
* Public: No
*/
#include "script_component.hpp"
private "_unit";
@ -6,15 +20,15 @@ private "_unit";
_unit = _this select 0;
if !([_unit] call FUNC(canClimb)) exitWith {
[localize "STR_ACE_Movement_CanNotClimb"] call EFUNC(common,displayTextStructured);
[localize "STR_ACE_Movement_CanNotClimb"] call EFUNC(common,displayTextStructured);
};
if !(_unit getVariable [QGVAR(isClimbInit), false]) then {
_unit addEventHandler ["AnimDone", {
if (local (_this select 0) && {_this select 1 == "ACE_Climb"}) then {_this call FUNC(handleClimb)};
}];
_unit addEventHandler ["AnimDone", {
if (local (_this select 0) && {_this select 1 == "ACE_Climb"}) then {_this call FUNC(handleClimb)};
}];
_unit setVariable [QGVAR(isClimbInit), true];
_unit setVariable [QGVAR(isClimbInit), true];
};
[_unit] call EFUNC(common,fixLoweredRifleAnimation);

View File

@ -1,4 +1,18 @@
// by commy2
/*
* Author: commy2
* Returns the weight (from the loadAbs command) in lbs/kg (based on user option)
*
* Arguments:
* 0: The Unit (usually the player) <OBJECT>
*
* Return Value:
* The return value <NUMBER>
*
* Example:
* _bool = [player] call ace_movement_fnc_getWeight
*
* Public: No
*/
#include "script_component.hpp"
private ["_unit", "_weight"];

View File

@ -1,4 +1,19 @@
// by commy2
/*
* Author: commy2
* Handles the climb animation finishing. Called from "AnimDone" event handler.
*
* Arguments:
* 0: The Unit (usually the player) <OBJECT>
* 1: The finisehd animation <STRING>
*
* Return Value:
* Nothing
*
* Example:
* [player, "ACE_climb"] call ace_movement_fnc_handleClimb
*
* Public: No
*/
#include "script_component.hpp"
private ["_unit", "_anim", "_pos"];

View File

@ -55,6 +55,15 @@ class CfgVehicles {
};
};
};
class showCursorTagForVehicles {
displayName = "Show for Vehicles";
description = "Show cursor NameTag for vehicle commander (only if client has name tags enabled)Default: No";
typeName = "BOOL";
class values {
class Yes {name = "Yes"; value = 1;};
class No {default = 1; name = "No"; value = 0;};
};
};
};
};
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,8 @@
// by commy2 and CAA-Picard
#include "script_component.hpp"
[] call FUNC(initIsSpeaking);
if (!hasInterface) exitWith {};
@ -25,57 +27,4 @@ if (!hasInterface) exitWith {};
// Draw handle
addMissionEventHandler ["Draw3D", {
if (GVAR(showPlayerNames) == 0) exitWith {};
_player = ACE_player;
if (GVAR(showPlayerNames) in [2,4]) then { //only on cursor
_target = cursorTarget;
_target = if (_target in allUnitsUAV) then {objNull} else {effectiveCommander _target};
if (!isNull _target && {side group _target == playerSide} && {_target != _player} && {isPlayer _target || {GVAR(ShowNamesForAI)}} && {!(_target getVariable ["ACE_hideName", false])}) then {
_distance = _player distance _target;
_alpha = ((1 - 0.2 * (_distance - GVAR(PlayerNamesViewDistance))) min 1) * GVAR(PlayerNamesMaxAlpha);
if ((GVAR(showPlayerNames) in [3,4])) then { //only on keypress
_alpha = _alpha min (1 - (time - GVAR(ShowNamesTime) - 1));
};
[_player, _target, _alpha, _distance * 0.026] call FUNC(drawNameTagIcon);
};
} else {
_pos = positionCameraToWorld [0, 0, 0];
_targets = _pos nearObjects ["Man", GVAR(PlayerNamesViewDistance) + 5];
if (!surfaceIsWater _pos) then {
_pos = ATLtoASL _pos;
};
_pos2 = positionCameraToWorld [0, 0, 1];
if (!surfaceIsWater _pos2) then {
_pos2 = ATLtoASL _pos2;
};
_vecy = _pos2 vectorDiff _pos;
{
_target = if (_x in allUnitsUAV) then {objNull} else {effectiveCommander _x};
if (!isNull _target && {side group _target == playerSide} && {_target != _player} && {isPlayer _target || {GVAR(ShowNamesForAI)}} && {!(_target getVariable ["ACE_hideName", false])}) then {
_relPos = (visiblePositionASL _target) vectorDiff _pos;
_distance = vectorMagnitude _relPos;
_projDist = _relPos vectorDistance (_vecy vectorMultiply (_relPos vectorDotProduct _vecy));
_alpha = ((1 - 0.2 * (_distance - GVAR(PlayerNamesViewDistance))) min (1 - 0.15 * (_projDist * 5 - _distance - 3)) min 1) * GVAR(PlayerNamesMaxAlpha);
if ((GVAR(showPlayerNames) in [3,4])) then { //only on keypress
_alpha = _alpha min (1 - (time - GVAR(ShowNamesTime) - 1));
};
// Check if there is line of sight
if (_alpha > 0) then {
if (lineIntersects [_pos, (visiblePositionASL _target) vectorAdd [0,0,1], vehicle _player, _target]) then {
_alpha = 0;
};
};
[_player, _target, _alpha, _distance * 0.026] call FUNC(drawNameTagIcon);
};
} forEach _targets;
};
}];
addMissionEventHandler ["Draw3D", {_this call FUNC(onDraw3d);}];

View File

@ -6,7 +6,9 @@ PREP(canShow);
PREP(doShow);
PREP(drawNameTagIcon);
PREP(getVehicleData);
PREP(initIsSpeaking);
PREP(moduleNameTags);
PREP(onDraw3d);
PREP(onMouseZChanged);
PREP(setText);

View File

@ -16,6 +16,12 @@ class CfgPatches {
#include "CfgVehicles.hpp"
class ACE_Settings {
class GVAR(defaultNametagColor) {
value[] = {0.77, 0.51, 0.08, 1};
typeName = "COLOR";
isClientSetable = 1;
displayName = "$STR_ACE_NameTags_DefaultNametagColor";
};
class GVAR(showPlayerNames) {
value = 1;
typeName = "SCALAR";
@ -41,7 +47,18 @@ class ACE_Settings {
isClientSetable = 1;
displayName = "$STR_ACE_NameTags_ShowNamesForAI";
};
class GVAR(showCursorTagForVehicles) {
value = 0;
typeName = "BOOL";
isClientSetable = 0;
};
class GVAR(showSoundWaves) {
value = 1;
typeName = "SCALAR";
isClientSetable = 1;
displayName = "$STR_ACE_NameTags_ShowSoundWaves";
values[] = {"Disabled", "Use Nametag settings", "Always Show All"};
};
class GVAR(PlayerNamesViewDistance) {
value = 5;
typeName = "SCALAR";

View File

@ -4,9 +4,11 @@
* Draw the nametag and rank icon.
*
* Argument:
* 0: Unit (Array)
* 1: alpha (Number)
* 2: Height offset (Number)
* 0: Unit (Player) <OBJECT>
* 1: Target <OBJECT>
* 2: alpha (Number)
* 4: Height offset (Number)
* 5: Draw Type <NUMBER>
*
* Return value:
* None.
@ -23,41 +25,58 @@
"\A3\Ui_f\data\GUI\Cfg\Ranks\captain_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\major_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\colonel_gs.paa" \
]
]
private ["_player", "_target", "_alpha", "_heightOffset", "_height", "_position", "_color", "_name", "_rank", "_size"];
private ["_height", "_position", "_color", "_name", "_rank", "_size"];
_player = _this select 0;
_target = _this select 1;
_alpha = _this select 2;
_heightOffset = _this select 3;
PARAMS_5(_player,_target,_alpha,_heightOffset,_iconType);
_height = [2, 1.5, 1, 1.5, 1] select (["STAND", "CROUCH", "PRONE", "UNDEFINED", ""] find stance _target);
if (_alpha < 0) exitWith {}; //Don't waste time if not visable
if (_iconType == ICON_NONE) exitWith {}; //Don't waste time if not visable
_position = visiblePositionASL _target;
// Convert position to ASLW (expected by drawIcon3D) and add height offsets
_position set [2, ((_target modelToWorld [0,0,0]) select 2) + _height + _heightOffset];
_color = if !(group _target == group _player) then {
[0.77, 0.51, 0.08, _alpha]
//Set Text:
_name = if (_iconType in [ICON_NAME, ICON_NAME_RANK, ICON_NAME_SPEAK]) then {
[_target, true] call EFUNC(common,getName)
} else {
[[1, 1, 1, _alpha], [1, 0, 0, _alpha], [0, 1, 0, _alpha], [0, 0, 1, _alpha], [1, 1, 0, _alpha]] select (["MAIN", "RED", "GREEN", "BLUE", "YELLOW"] find (if (_target == _player) then {0} else {assignedTeam _target})) max 0
""
};
_name = [_target, true] call EFUNC(common,getName);
//Set Icon:
_icon = "";
_size = 0;
if ((_iconType == ICON_NAME_SPEAK) || (_iconType == ICON_SPEAK)) then {
_icon = QUOTE(PATHTOF(UI\soundwave)) + str (floor (random 10)) + ".paa";
_size = 0.75;
_alpha = _alpha + 0.6;//Boost alpha when speaking
} else {
if (_iconType == ICON_NAME_RANK) then {
_icon = TEXTURES_RANKS select ((["PRIVATE", "CORPORAL", "SERGEANT", "LIEUTENANT", "CAPTAIN", "MAJOR", "COLONEL"] find (rank _target)) + 1);
_size = 0.75;
};
};
_rank = TEXTURES_RANKS select ((["PRIVATE", "CORPORAL", "SERGEANT", "LIEUTENANT", "CAPTAIN", "MAJOR", "COLONEL"] find rank _target) + 1);
_size = [0, 1] select GVAR(showPlayerRanks);
//Set Color:
if !(group _target == group _player) then {
_color = +GVAR(defaultNametagColor); //Make a copy, then multiply both alpha values (allows client to decrease alpha in settings)
_color set [3, (_color select 3) * _alpha];
} else {
_color = [[1, 1, 1, _alpha], [1, 0, 0, _alpha], [0, 1, 0, _alpha], [0, 0, 1, _alpha], [1, 1, 0, _alpha]] select (["MAIN", "RED", "GREEN", "BLUE", "YELLOW"] find (if (_target == _player) then {0} else {assignedTeam _target})) max 0
};
_height = [2, 1.5, 1, 1.5, 1] select (["STAND", "CROUCH", "PRONE", "UNDEFINED", ""] find (stance _target));
// Convert position to ASLW (expected by drawIcon3D) and add height offsets
_position = _target modelToWorldVisual [0, 0, (_height + _heightOffset)];
drawIcon3D [
_rank,
_color,
_position,
_size,
_size,
0,
_name,
2,
0.033,
"PuristaMedium"
_icon,
_color,
_position,
_size,
_size,
0,
_name,
2,
0.033,
"PuristaMedium"
];

View File

@ -0,0 +1,76 @@
/*
* Author: Glowbal, PabstMirror
* Starts up a PFEH to monitor the when players are talking.
* Compatiblity with TFR/ACRE and Arma's VON
*
* Arguments:
* NONE
*
* Return Value:
* NONE
*
* Example:
* [] call ACE_nametags_fnc_initIsSpeaking
*
* Public: No
*/
#include "script_component.hpp"
if (isServer) then {
//If someone disconnects while speaking, reset their variable
addMissionEventHandler ["HandleDisconnect", {
PARAMS_1(_disconnectedPlayer);
if (_disconnectedPlayer getVariable [QGVAR(isSpeaking), false]) then {
_disconnectedPlayer setVariable [QGVAR(isSpeaking), false, true];
};
}];
};
if (!hasInterface) exitWith {};
["playerChanged", {
//When player changes, make sure to reset old unit's variable
PARAMS_2(_newUnit,_oldUnit);
if (_oldUnit getVariable [QGVAR(isSpeaking), false]) then {
_oldUnit setVariable [QGVAR(isSpeaking), false, true];
};
}] call EFUNC(common,addEventHandler);
//For performance, chose different code paths at mission start based on installed mods (once, instead of checking each time)
_pfEHCode = switch (true) do {
case (isClass (configFile >> "cfgPatches" >> "acre_api")): {
{
_oldSetting = ACE_player getVariable [QGVAR(isSpeaking), false];
_newSetting = ([ACE_player] call ACRE_api_fnc_isBroadcasting) || {!(isNull findDisplay 55)};
if (!(_oldSetting isEqualTo _newSetting)) then {
ACE_player setVariable [QGVAR(isSpeaking), _newSetting, true];
};
};
};
case (isClass (configFile >> "cfgPatches" >> "task_force_radio")): {
//Note: TFAR has a TFAR_fnc_isSpeaking function, but it has a fairly costly `callExtension`
//I think it's much faster to use the internal "tf_isSpeaking" variable
//If we don't care about the built-in VON, we could switch this to a pure event driven system
{
_oldSetting = ACE_player getVariable [QGVAR(isSpeaking), false];
_newSetting = (ACE_player getVariable ["tf_isSpeaking", false]) || {!(isNull findDisplay 55)};
if (!(_oldSetting isEqualTo _newSetting)) then {
ACE_player setVariable [QGVAR(isSpeaking), _newSetting, true];
};
};
};
default {
//Note: class RscDisplayVoiceChat {idd = 55}; //only present when talking
{
_oldSetting = ACE_player getVariable [QGVAR(isSpeaking), false];
_newSetting = (!(isNull findDisplay 55));
if (!(_oldSetting isEqualTo _newSetting)) then {
ACE_player setVariable [QGVAR(isSpeaking), _newSetting, true];
};
};
};
};
//Is 0.05sec precision enough??
[_pfEHCode, 0.05, []] call CBA_fnc_addPerFrameHandler;

View File

@ -25,5 +25,6 @@ GVAR(Module) = true;
[_logic, QGVAR(PlayerNamesViewDistance), "PlayerNamesViewDistance" ] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(ShowNamesForAI), "ShowNamesForAI" ] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(showVehicleCrewInfo), "showVehicleCrewInfo" ] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(showCursorTagForVehicles), "showCursorTagForVehicles" ] call EFUNC(common,readSettingFromModule);
diag_log text "[ACE]: NameTags Module Initialized.";

View File

@ -0,0 +1,108 @@
#include "script_component.hpp"
_player = ACE_player;
//don't show nametags in spectator
if (!alive _player) exitWith {};
_onKeyPressAlphaMax = if ((GVAR(showPlayerNames) in [3,4])) then {
2 + (GVAR(ShowNamesTime) - time); //after release 1 second of full opacity, 1 second of fading to 0
} else {
1
};
_defaultIcon = if (GVAR(showPlayerRanks)) then {
ICON_NAME_RANK;
} else {
ICON_NAME;
};
//When cursorTarget is on a vehicle show the nametag for the commander.
//If set to "Only On Keypress" settings, fade just like main tags
if (GVAR(showCursorTagForVehicles) && {_onKeyPressAlphaMax > 0}) then {
_target = cursorTarget;
if ((!(_target isKindOf "CAManBase")) && {!(_target in allUnitsUAV)}) then {
_target = effectiveCommander _target;
if ((!isNull _target) &&
{(side (group _target)) == (side (group _player))} &&
{_target != _player} &&
{GVAR(ShowNamesForAI) || {[_target] call EFUNC(common,isPlayer)}} &&
{!(_target getVariable ["ACE_hideName", false])}) then {
_distance = _player distance _target;
_alpha = ((1 - 0.2 * (_distance - GVAR(PlayerNamesViewDistance))) min 1) * GVAR(PlayerNamesMaxAlpha);
_alpha = _alpha min _onKeyPressAlphaMax;
[_player, _target, _alpha, _distance * 0.026, _defaultIcon] call FUNC(drawNameTagIcon);
};
};
};
//"Only Cursor" mode, only show nametags for humans on cursorTarget
if ((GVAR(showPlayerNames) in [2,4]) && {_onKeyPressAlphaMax > 0}) then {
_target = cursorTarget;
if ((!isNull _target) &&
{_target isKindOf "CAManBase"} &&
{(side (group _target)) == (side (group _player))} &&
{_target != _player} &&
{GVAR(ShowNamesForAI) || {[_target] call EFUNC(common,isPlayer)}} &&
{!(_target getVariable ["ACE_hideName", false])}) then {
_distance = _player distance _target;
_alpha = ((1 - 0.2 * (_distance - GVAR(PlayerNamesViewDistance))) min 1) * GVAR(PlayerNamesMaxAlpha);
_alpha = _alpha min _onKeyPressAlphaMax;
_icon = ICON_NONE;
if (GVAR(showSoundWaves) == 2) then { //icon will be drawn below, so only show name here
_icon = if ((_target getVariable [QGVAR(isSpeaking), false]) && {(vehicle _target) == _target}) then {ICON_NAME} else {_defaultIcon};
} else {
_icon = if ((_target getVariable [QGVAR(isSpeaking), false]) && {(vehicle _target) == _target} && {GVAR(showSoundWaves) > 0}) then {ICON_NAME_SPEAK} else {_defaultIcon};
};
[_player, _target, _alpha, _distance * 0.026, _icon] call FUNC(drawNameTagIcon);
};
};
if (((GVAR(showPlayerNames) in [1,3]) && {_onKeyPressAlphaMax > 0}) || {GVAR(showSoundWaves) == 2}) then {
_pos = positionCameraToWorld [0, 0, 0];
_targets = _pos nearObjects ["CAManBase", GVAR(PlayerNamesViewDistance) + 5];
if (!surfaceIsWater _pos) then {
_pos = ATLtoASL _pos;
};
_pos2 = positionCameraToWorld [0, 0, 1];
if (!surfaceIsWater _pos2) then {
_pos2 = ATLtoASL _pos2;
};
_vecy = _pos2 vectorDiff _pos;
{
_target = _x;
_icon = ICON_NONE;
if ((GVAR(showPlayerNames) in [1,3]) && {_onKeyPressAlphaMax > 0}) then {
if ((_target getVariable [QGVAR(isSpeaking), false]) && {(vehicle _target) == _target} && {GVAR(showSoundWaves) > 0}) then {_icon = ICON_NAME_SPEAK;} else {_icon = _defaultIcon};
} else {
//showSoundWaves must be 2, only draw speak icon
if ((_target getVariable [QGVAR(isSpeaking), false]) && {(vehicle _target) == _target}) then {_icon = ICON_SPEAK;};
};
if ((_icon != ICON_NONE) &&
{(side (group _target)) == (side (group _player))} &&
{_target != _player} &&
{GVAR(ShowNamesForAI) || {[_target] call EFUNC(common,isPlayer)}} &&
{!(_target getVariable ["ACE_hideName", false])}) then {
if (lineIntersects [_pos, (visiblePositionASL _target) vectorAdd [0,0,1], vehicle _player, _target]) exitWith {}; // Check if there is line of sight
_relPos = (visiblePositionASL _target) vectorDiff _pos;
_distance = vectorMagnitude _relPos;
_projDist = _relPos vectorDistance (_vecy vectorMultiply (_relPos vectorDotProduct _vecy));
_alpha = ((1 - 0.2 * (_distance - GVAR(PlayerNamesViewDistance))) min (1 - 0.15 * (_projDist * 5 - _distance - 3)) min 1) * GVAR(PlayerNamesMaxAlpha);
if ((GVAR(showSoundWaves) == 2) && {(_target getVariable [QGVAR(isSpeaking), false]) && {(vehicle _target) == _target}}) then {
_alpha = 1;
} else {
_alpha = _alpha min _onKeyPressAlphaMax;
};
[_player, _target, _alpha, _distance * 0.026, _icon] call FUNC(drawNameTagIcon);
};
} forEach _targets;
};

View File

@ -10,3 +10,9 @@
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#define ICON_NONE 0
#define ICON_NAME 1
#define ICON_NAME_RANK 2
#define ICON_NAME_SPEAK 3
#define ICON_SPEAK 4

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Edited with tabler - 2014-12-17 -->
<!-- Edited with tabler - 2015-02-13 -->
<Project name="ACE">
<Package name="NameTags">
<Key ID="STR_ACE_NameTags_ShowNames">
@ -69,5 +69,13 @@
<Key ID="STR_ACE_NameTags_ShowNamesForAI">
<English>Show name tags for AI units</English>
</Key>
<Key ID="STR_ACE_NameTags_ShowSoundWaves">
<English>Show SoundWaves (requires player names)</English>
<German>Zeigen Schallwelle (benötigt spielernamen)</German>
<Spanish>Mostrar onda sonora (requiere Mostrar nombres de jugadores)</Spanish>
</Key>
<Key ID="STR_ACE_NameTags_DefaultNametagColor">
<English>Default Nametag Color (Non Group Members)</English>
</Key>
</Package>
</Project>