Merge pull request #144 from KoffeinFlummi/cseSoundWaves

CSE sound waves
This commit is contained in:
PabstMirror 2015-02-27 15:32:16 -06:00
commit 901a06587d
20 changed files with 283 additions and 88 deletions

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";
@ -40,8 +46,19 @@ class ACE_Settings {
typeName = "BOOL";
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,16 +4,18 @@
* 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.
*/
#include "script_component.hpp"
#define TEXTURES_RANKS [ \
"", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\private_gs.paa", \
@ -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

@ -9,4 +9,10 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_NAMETAGS
#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"?>
<!-- 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>
</Project>