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 root = true
[*] [*]
end_of_line = lf end_of_line = crlf
insert_final_newline = true insert_final_newline = true
charset = utf-8 charset = utf-8
indent_style = space indent_style = space

View File

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

View File

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

View File

@ -1,39 +1,40 @@
/* /*
* Author: commy2 and NouberNou * Author: commy2, NouberNou and CAA-Picard
* Add an ACE action to an object or inside a parent action. Note: This function is NOT global. * Add an ACE action to an object, under a certain config path
* Note: This function is NOT global.
* *
* Argument: * Argument:
* 0: Object the action should be assigned to or parent action <OBJECT> or <ARRAY> * 0: Object the action should be assigned to <OBJECT>
* 1: Name of the action shown in the menu <STRING> * 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Icon <STRING> * 2: Full path of the new action <ARRAY>
* 3: Position (Position or Selection Name) <POSITION> or <STRING> * 3: Name of the action shown in the menu <STRING>
* 4: Statement <CODE> * 4: Icon <STRING>
* 5: Condition <CODE> * 5: Position (Position or Selection Name) <POSITION> or <STRING>
* 6: Distance <NUMBER> * 6: Statement <CODE>
* 7: Condition <CODE>
* 8: Distance <NUMBER>
* *
* Return value: * 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 * Public: No
*/ */
#include "script_component.hpp" #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"]; _varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum;
_actions = []; _actions = _object getVariable [_varName, []];
if(IS_OBJECT(_object)) then { if((count _actions) == 0) then {
_actions = _object getVariable [QUOTE(GVAR(actionData)), []]; _object setVariable [_varName, _actions];
if((count _actions) == 0) then {
_object setVariable [QUOTE(GVAR(actionData)), _actions]
};
} else {
if(IS_ARRAY(_object)) then {
_actions = _object select 6;
};
}; };
private "_entry";
_entry = [ _entry = [
_displayName, _displayName,
_icon, _icon,
@ -42,8 +43,11 @@ _entry = [
_condition, _condition,
_distance, _distance,
[], [],
GVAR(uidCounter) GVAR(uidCounter),
+ _fullPath
]; ];
GVAR(uidCounter) = GVAR(uidCounter) + 1; GVAR(uidCounter) = GVAR(uidCounter) + 1;
_actions pushBack _entry; _actions pushBack _entry;
_entry;
_fullPath

View File

@ -1,6 +1,6 @@
/* /*
* Author: NouberNou * Author: NouberNou and CAA-Picard
* Compile the action menu from config for a given object. * Compile the action menu from config for an object's class
* *
* Argument: * Argument:
* 0: Object <OBJECT> * 0: Object <OBJECT>
@ -14,31 +14,21 @@
EXPLODE_1_PVT(_this,_object); EXPLODE_1_PVT(_this,_object);
/* private ["_objectType","_actionsVarName"];
[
[
"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"];
_objectType = typeOf _object; _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 = { _recurseFnc = {
private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_selection", "_condition", "_showDisabled", 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 = []; _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; _entryCfg = _actionsCfg select _i;
if(isClass _entryCfg) then { if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName"); _displayName = getText (_entryCfg >> "displayName");
@ -58,8 +48,12 @@ _recurseFnc = {
_showDisabled = getNumber (_entryCfg >> "showDisabled"); _showDisabled = getNumber (_entryCfg >> "showDisabled");
_enableInside = getNumber (_entryCfg >> "enableInside"); _enableInside = getNumber (_entryCfg >> "enableInside");
_fullPath = (+ _parentPath);
_fullPath pushBack (configName _entryCfg);
_condition = compile _condition; _condition = compile _condition;
_children = [_entryCfg] call _recurseFnc; _children = [_entryCfg, _fullPath] call _recurseFnc;
_entry = [ _entry = [
_displayName, _displayName,
_icon, _icon,
@ -68,8 +62,10 @@ _recurseFnc = {
_condition, _condition,
_distance, _distance,
_children, _children,
GVAR(uidCounter) GVAR(uidCounter),
_fullPath
]; ];
GVAR(uidCounter) = GVAR(uidCounter) + 1; GVAR(uidCounter) = GVAR(uidCounter) + 1;
_actions pushBack _entry; _actions pushBack _entry;
}; };
@ -77,6 +73,23 @@ _recurseFnc = {
_actions _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 * 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: * Argument:
* 0: Object <OBJECT> * 0: Object <OBJECT>
@ -14,34 +14,25 @@
EXPLODE_1_PVT(_this,_object); EXPLODE_1_PVT(_this,_object);
/* private ["_objectType","_actionsVarName"];
[
[
"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"];
_objectType = typeOf _object; _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 = { _recurseFnc = {
private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_condition", "_showDisabled", 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 = []; _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; _entryCfg = _actionsCfg select _i;
if(isClass _entryCfg) then { if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName"); _displayName = getText (_entryCfg >> "displayName");
_icon = getText (_entryCfg >> "icon"); _icon = getText (_entryCfg >> "icon");
_statement = compile (getText (_entryCfg >> "statement")); _statement = compile (getText (_entryCfg >> "statement"));
@ -54,8 +45,12 @@ _recurseFnc = {
_showDisabled = getNumber (_entryCfg >> "showDisabled"); _showDisabled = getNumber (_entryCfg >> "showDisabled");
_enableInside = getNumber (_entryCfg >> "enableInside"); _enableInside = getNumber (_entryCfg >> "enableInside");
_fullPath = (+ _parentPath);
_fullPath pushBack (configName _entryCfg);
_condition = compile _condition; _condition = compile _condition;
_children = [_entryCfg] call _recurseFnc; _children = [_entryCfg, _fullPath] call _recurseFnc;
_entry = [ _entry = [
_displayName, _displayName,
_icon, _icon,
@ -64,8 +59,10 @@ _recurseFnc = {
_condition, _condition,
10, //distace 10, //distace
_children, _children,
GVAR(uidCounter) GVAR(uidCounter),
_fullPath
]; ];
GVAR(uidCounter) = GVAR(uidCounter) + 1; GVAR(uidCounter) = GVAR(uidCounter) + 1;
_actions pushBack _entry; _actions pushBack _entry;
}; };
@ -73,7 +70,8 @@ _recurseFnc = {
_actions _actions
}; };
_actions = [_actionsCfg] call _recurseFnc; private "_actionsCfg";
_actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_SelfActions";
// Create a master action to base on self action // Create a master action to base on self action
_actions = [[ _actions = [[
@ -83,10 +81,11 @@ _actions = [[
{ true }, { true },
{ true }, { true },
10, 10,
_actions, [_actionsCfg, ["SelfActions"]] call _recurseFnc,
GVAR(uidCounter) GVAR(uidCounter),
["SelfActions"]
] ]
]; ];
GVAR(uidCounter) = GVAR(uidCounter) + 1; 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); this = GVAR(selectedTarget);
_player = ACE_Player; _player = ACE_Player;
_target = GVAR(selectedTarget); _target = GVAR(selectedTarget);
[GVAR(selectedTarget), player] call GVAR(selectedAction); [GVAR(selectedTarget), ACE_player] call GVAR(selectedAction);
}; };
GVAR(expanded) = false; GVAR(expanded) = false;
GVAR(lastPath) = []; GVAR(lastPath) = [];

View File

@ -17,7 +17,7 @@ if(GVAR(actionSelected)) then {
this = GVAR(selectedTarget); this = GVAR(selectedTarget);
_player = ACE_Player; _player = ACE_Player;
_target = GVAR(selectedTarget); _target = GVAR(selectedTarget);
[GVAR(selectedTarget), player] call GVAR(selectedAction); [GVAR(selectedTarget), ACE_player] call GVAR(selectedAction);
}; };
GVAR(expanded) = false; GVAR(expanded) = false;
GVAR(lastPath) = []; 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 * Remove an action from an object
* *
* Argument: * Argument:
* 0: Object the action should be assigned to <OBJECT> * 0: Object the action is assigned to <OBJECT>
* 1: Entry to remove <ARRAY> or <NUMBER> * 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Full path of the action to remove <ARRAY>
* *
* Return value: * Return value:
* None * None
* *
* Example:
* [cursorTarget,0,["ACE_TapShoulderRight","VulcanPinch"]] call ace_interact_menu_fnc_removeAction;
*
* Public: No * Public: No
*/ */
#include "script_component.hpp" #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}; if ((_x select 8) isEqualTo _fullPath) exitWith {
_actions deleteAt _forEachIndex;
_actions = _object getVariable [QUOTE(GVAR(actionData)), []]; };
if(IS_ARRAY(_entry)) then { } forEach _actions;
_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;

View File

@ -16,41 +16,91 @@ private ["_cursorPos1", "_cursorPos2", "_cursorVec", "_p1", "_p2", "_p", "_v", "
_foundTarget = false; _foundTarget = false;
_cursorPos1 = positionCameraToWorld [0, 0, 0]; _cursorPos1 = positionCameraToWorld [0, 0, 0];
_cursorPos2 = positionCameraToWorld [0, 0, 2]; _cursorPos2 = positionCameraToWorld [0, 0, 2];
GVAR(currentOptions) = []; 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); private ["_actionsVarName","_classActions","_objectActions","_target","_player","_actionItem","_active"];
}; if (GVAR(keyDown)) then {
if (GVAR(keyDown)) then { [] call FUNC(updateVecLineMap);
// Render all nearby interaction menus
// 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 { _actionItem = _x;
GVAR(renderDepth) = 0; // Only render them directly if they are base level actions
_renderTargets = _x; if (count (_actionItem select 8) == 1) then {
{ _active = [_target, ACE_player] call (_actionItem select 4);
[_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);
};
// 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 { 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; _cursorScreenPos = worldToScreen _cursorPos2;
_closestDistance = 1000000; _closestDistance = 1000000;
@ -67,48 +117,48 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then {
}; };
} forEach GVAR(currentOptions); } forEach GVAR(currentOptions);
if(_closestSelection != -1) then {
_closest = GVAR(currentOptions) select _closestSelection; if(_closestSelection == -1) exitWith {};
_pos = _closest select 1; _closest = GVAR(currentOptions) select _closestSelection;
_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 { _pos = _closest select 1;
GVAR(lastPath) = _hoverPath; _cTime = diag_tickTime;
GVAR(startHoverTime) = diag_tickTime; _delta = _cTime - GVAR(lastTime);
GVAR(expanded) = false; GVAR(lastTime) = _cTime;
} else { GVAR(rotationAngle) = GVAR(rotationAngle) + (180*_delta);
if(!GVAR(expanded) && diag_tickTime-GVAR(startHoverTime) > 0.25) then { if(GVAR(rotationAngle) > 360) then {
GVAR(expanded) = true; GVAR(rotationAngle) = GVAR(rotationAngle) - 360;
GVAR(menuDepthPath) = +GVAR(lastPath); };
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 { if(!_foundTarget && GVAR(actionSelected)) then {
GVAR(actionSelected) = false; GVAR(actionSelected) = false;
GVAR(expanded) = false; GVAR(expanded) = false;

View File

@ -24,6 +24,8 @@ _color = _this select 1;
_pos = _this select 2; _pos = _this select 2;
_icon = _this select 6; _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 = worldToScreen _pos;
// _sPos = _pos; // _sPos = _pos;
if(count _sPos > 0) then { if(count _sPos > 0) then {

View File

@ -1,6 +1,6 @@
/* /*
* Author: NouberNou and CAA-Picard * Author: NouberNou and CAA-Picard
* Render a interaction menu * Render a interaction menu and it's children recursively
* *
* Argument: * Argument:
* 0: Object <OBJECT> * 0: Object <OBJECT>
@ -8,7 +8,6 @@
* 2: ? * 2: ?
* 3: Angle range available for rendering <ARRAY> * 3: Angle range available for rendering <ARRAY>
* 4: 3D position <ARRAY> (Optional) * 4: 3D position <ARRAY> (Optional)
* 5: Path of UIDs <ARRAY> (Optional)
* *
* Return value: * Return value:
* None * None
@ -17,16 +16,15 @@
*/ */
#include "script_component.hpp" #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; EXPLODE_4_PVT(_this,_object,_actionData,_dummy,_angles);
_actionData = _this select 1;
_uid = _actionData select 7;//_this select 2;
_angles = _this select 3;
_distance = _actionData select 5;
EXPLODE_2_PVT(_angles,_centerAngle,_maxAngleSpan); 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 { if((count _this) > 4) then {
_pos = _this select 4; _pos = _this select 4;
} else { } else {
@ -36,70 +34,108 @@ if((count _this) > 4) then {
_pos = _object modelToWorld (_object selectionPosition (_actionData select 2)); _pos = _object modelToWorld (_object selectionPosition (_actionData select 2));
}; };
}; };
_cursorScreenPos = (positionCameraToWorld [0, 0, 0]); _cursorScreenPos = (positionCameraToWorld [0, 0, 0]);
if(_cursorScreenPos distance _pos <= _distance) then { // Exit if the action is too far away
_path = []; if(_cursorScreenPos distance _pos >= _distance) exitWith {};
if((count _this) > 5) then {
_path = +(_this select 5); // 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)); if (_x != (GVAR(menuDepthPath) select _forEachIndex)) exitWith {
_menuInSelectedPath = false;
// 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)];
}; };
_path set[(count _path), _uid]; } forEach _path;
[_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];
private "_angleSpan"; // Render icon
_angleSpan = _maxAngleSpan min (55 * (_numActions - 1)); // ARGB Color (First Hex Pair is transparancy)
_color = "#FFFFFFFF";
private "_angle"; if(_menuDepth > 0 && !_menuInSelectedPath) then {
_angle = _centerAngle - _angleSpan / 2; _color = format ["#%1FFFFFF", [255 * ((((count _path) - 2)/_menuDepth) max 0.25)] call EFUNC(common,toHex)];
{
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;
}; };
[_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" #include "script_component.hpp"
private ["_unit", "_pos", "_dir"]; private ["_unit", "_pos", "_dir"];
@ -20,6 +34,6 @@ _checkPos1end = _checkPos1beg vectorAdd _dir;
/* /*
drawLine3D [ASLToATL _checkPos0beg, ASLToATL _checkPos0end, [1,0,0,1]]; drawLine3D [ASLToATL _checkPos0beg, ASLToATL _checkPos0end, [1,0,0,1]];
drawLine3D [ASLToATL _checkPos1beg, ASLToATL _checkPos1end, [1,0,0,1]]; drawLine3D [ASLToATL _checkPos1beg, ASLToATL _checkPos1end, [1,0,0,1]];
*/ */
lineIntersects [_checkPos0beg, _checkPos0end] && {!(lineIntersects [_checkPos1beg, _checkPos1end])} 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" #include "script_component.hpp"
private "_unit"; private "_unit";
@ -6,15 +20,15 @@ private "_unit";
_unit = _this select 0; _unit = _this select 0;
if !([_unit] call FUNC(canClimb)) exitWith { 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 { if !(_unit getVariable [QGVAR(isClimbInit), false]) then {
_unit addEventHandler ["AnimDone", { _unit addEventHandler ["AnimDone", {
if (local (_this select 0) && {_this select 1 == "ACE_Climb"}) then {_this call FUNC(handleClimb)}; 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); [_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" #include "script_component.hpp"
private ["_unit", "_weight"]; 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" #include "script_component.hpp"
private ["_unit", "_anim", "_pos"]; 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 // by commy2 and CAA-Picard
#include "script_component.hpp" #include "script_component.hpp"
[] call FUNC(initIsSpeaking);
if (!hasInterface) exitWith {}; if (!hasInterface) exitWith {};
@ -25,57 +27,4 @@ if (!hasInterface) exitWith {};
// Draw handle // Draw handle
addMissionEventHandler ["Draw3D", { addMissionEventHandler ["Draw3D", {_this call FUNC(onDraw3d);}];
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;
};
}];

View File

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

View File

@ -16,6 +16,12 @@ class CfgPatches {
#include "CfgVehicles.hpp" #include "CfgVehicles.hpp"
class ACE_Settings { 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) { class GVAR(showPlayerNames) {
value = 1; value = 1;
typeName = "SCALAR"; typeName = "SCALAR";
@ -41,7 +47,18 @@ class ACE_Settings {
isClientSetable = 1; isClientSetable = 1;
displayName = "$STR_ACE_NameTags_ShowNamesForAI"; 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) { class GVAR(PlayerNamesViewDistance) {
value = 5; value = 5;
typeName = "SCALAR"; typeName = "SCALAR";

View File

@ -4,9 +4,11 @@
* Draw the nametag and rank icon. * Draw the nametag and rank icon.
* *
* Argument: * Argument:
* 0: Unit (Array) * 0: Unit (Player) <OBJECT>
* 1: alpha (Number) * 1: Target <OBJECT>
* 2: Height offset (Number) * 2: alpha (Number)
* 4: Height offset (Number)
* 5: Draw Type <NUMBER>
* *
* Return value: * Return value:
* None. * None.
@ -23,41 +25,58 @@
"\A3\Ui_f\data\GUI\Cfg\Ranks\captain_gs.paa", \ "\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\major_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\colonel_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; PARAMS_5(_player,_target,_alpha,_heightOffset,_iconType);
_target = _this select 1;
_alpha = _this select 2;
_heightOffset = _this select 3;
_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 { //Set Text:
[0.77, 0.51, 0.08, _alpha] _name = if (_iconType in [ICON_NAME, ICON_NAME_RANK, ICON_NAME_SPEAK]) then {
[_target, true] call EFUNC(common,getName)
} else { } 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); //Set Color:
_size = [0, 1] select GVAR(showPlayerRanks); 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 [ drawIcon3D [
_rank, _icon,
_color, _color,
_position, _position,
_size, _size,
_size, _size,
0, 0,
_name, _name,
2, 2,
0.033, 0.033,
"PuristaMedium" "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(PlayerNamesViewDistance), "PlayerNamesViewDistance" ] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(ShowNamesForAI), "ShowNamesForAI" ] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(ShowNamesForAI), "ShowNamesForAI" ] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(showVehicleCrewInfo), "showVehicleCrewInfo" ] 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."; 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 #endif
#include "\z\ace\addons\main\script_macros.hpp" #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"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Edited with tabler - 2014-12-17 --> <!-- Edited with tabler - 2015-02-13 -->
<Project name="ACE"> <Project name="ACE">
<Package name="NameTags"> <Package name="NameTags">
<Key ID="STR_ACE_NameTags_ShowNames"> <Key ID="STR_ACE_NameTags_ShowNames">
@ -69,5 +69,13 @@
<Key ID="STR_ACE_NameTags_ShowNamesForAI"> <Key ID="STR_ACE_NameTags_ShowNamesForAI">
<English>Show name tags for AI units</English> <English>Show name tags for AI units</English>
</Key> </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> </Package>
</Project> </Project>