diff --git a/f/common/functions.hpp b/f/common/functions.hpp
index bbe2b7f2..2e4fe947 100644
--- a/f/common/functions.hpp
+++ b/f/common/functions.hpp
@@ -75,8 +75,13 @@ class F // Defines the "owner"
};
class nametag
{
- file = "f\nametag";
- class drawNameTag{};
+ file = "f\nametag\functions";
+ class nametagUpdate {};
+ class nametagDraw {};
+ class nametagGetData {};
+ class nametagCache {};
+ class nametagResetFont {};
+ class getZoom {};
};
class preMount
{
diff --git a/f/nametag/f_nametagCONFIG.sqf b/f/nametag/f_nametagCONFIG.sqf
new file mode 100644
index 00000000..e7b237dc
--- /dev/null
+++ b/f/nametag/f_nametagCONFIG.sqf
@@ -0,0 +1,81 @@
+//=======================================================================================
+//
+// f_nametagConfig.sqf - Contains configurable values for WH nametags.
+//
+// Note: If CBA is enabled, many of these settings (DRAWCURSORONLY, for instance) can
+// be altered by individual clients to their preference.
+//
+// @ /u/Whalen207 | Whale #5963
+//
+//=======================================================================================
+
+//---------------------------------------------------------------------------------------
+// Configuration Values. Feel free to modify.
+//---------------------------------------------------------------------------------------
+
+// Main Values (Default values)
+F_NT_DRAWCURSORONLY = false; // Only draw nametags on mouse cursor. (Default: false)
+ // Can save FPS in crowded areas.
+ // Clients can change with CBA settings menu.
+
+F_NT_ACTIONKEY = "timeInc"; // Key that can be pressed to toggle tags. ("timeInc")
+ // Default is "timeInc", which is normally
+ // the (=) key. Other keys available here:
+ // https://community.bistudio.com/wiki/inputAction/actions/bindings
+ // Don't want any key? Comment out the line.
+
+F_NT_NIGHT = true; // Whether night will affect tag visibility. (true)
+
+// Information Shown
+F_NT_SHOW_GROUP = true; // Show group name under unit's name. (true)
+F_NT_SHOW_ROLE = true; // Show unit's role (rifleman, driver). (true)
+F_NT_SHOW_VEHICLEINFO = true; // Show vehicle info. Requires SHOW_ROLE. (true)
+
+// Draw Distances
+F_NT_DRAWDISTANCE_CURSOR = 20; // Distance to draw nametags when pointing at a unit. (20)
+ // Should be greater than DISTANCE_ALL.
+ // Can be altered significantly depending on player FOV.
+F_NT_DRAWDISTANCE_NEAR = 10; // Distance within which all nametags will be drawn. (10)
+ // Increasing this will cost performance.
+ // Due to a bug this will seem ~3m shorter in third person.
+ // If you want to truly disable non-cursor tags, set this to 0.
+// Font Fade
+F_NT_FADETIME = 1; // Fade time for cursor tags after player mouses away. (1)
+
+// Text Configuration: Typeface
+// To manually alter these options, see functions\nametagResetFont.sqf.
+// Options:
+// - "Roboto" (DEFAULT)
+// - "RobotoLight"
+// - "Purista"
+// - "PuristaLight"
+// - "Etelka"
+// - "Tahoma"
+F_NT_FONT_FACE = "Roboto"; // Typeface set for nametag system. ("Roboto")
+
+// Text Configuration: Size
+F_NT_FONT_SIZE_RAW = 0.036; // Default raw font size. (0.036)
+ // Used directly for names, and used with
+ // below modifiers for all else.
+F_NT_FONT_SIZE_SEC_MULTI = 0.861; // Multiplier for group and role tags. (0.861)
+F_NT_FONT_SIZE_MULTI = 1; // A general multiplier that can be used (1)
+ // if you don't like the other ones.
+ // Multipliers may be overriden by CBA settings.
+// Text Configuration: Spacing
+F_NT_FONT_SPREAD_MULTI = 1; // Multiplier for vertical font spacing. (1)
+ // may be overriden by CBA settings.
+
+// Text Configuration: Color
+// To manually alter these options, see functions\nametagResetFont.sqf.
+// Options:
+// - WHGreen
+// - ACERust
+// - TMTMTeal
+// - COALCrimson
+// - FAWhite
+// - STSand
+// - BromaPurple
+F_NT_FONT_COLOR = "WHGreen"; // Font color set for nametag system. ("WHGreen")
+
+// Text Configuration: Position
+F_NT_FONT_HEIGHT_ONHEAD = true; // Attaches nametags to head (like ACE) (false)
diff --git a/f/nametag/f_nametagInit.sqf b/f/nametag/f_nametagInit.sqf
new file mode 100644
index 00000000..5dbcb40e
--- /dev/null
+++ b/f/nametag/f_nametagInit.sqf
@@ -0,0 +1,80 @@
+//====================================================================================
+//
+// f_nametagInit.sqf - Initializes values for WH nametags.
+//
+// [] execVM "f\nametag\f_nametagInit.sqf";
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// Initial setup.
+//------------------------------------------------------------------------------------
+
+// Make sure this isn't a dedicated server or headless client.
+if (!hasInterface) exitWith {};
+
+// Global variable that will be flipped on and off using the disableKey and CBA.
+F_NT_NAMETAGS_ON = true;
+
+// Determine which mods are active.
+#include "include\f_nametagCheckMods.sqf";
+
+
+//------------------------------------------------------------------------------------
+// Configuration and settings import and setup.
+//------------------------------------------------------------------------------------
+
+// Allows for missionmaker configuration of important settings.
+#include "f_nametagCONFIG.sqf"
+
+// Allows for player (client) configuration of other settings.
+#include "include\f_nametagSettings.sqf"
+
+
+//------------------------------------------------------------------------------------
+// More preparation.
+//------------------------------------------------------------------------------------
+
+// Let the player initialize properly.
+waitUntil{!isNull player};
+waitUntil{player == player};
+
+// Reset font spacing and size to (possibly) new conditions.
+call f_fnc_nametagResetFont;
+
+// Setting up cursor cache and fader.
+F_NT_CACHE_CURSOR = objNull;
+F_NT_CACHE_CURSOR_DATA = [];
+F_NT_CACHE_FADE = [[],[],[]];
+
+// Wait for player to get ingame.
+waitUntil {!isNull (findDisplay 46)};
+
+// Setting up our disableKey (Default '+')
+#include "include\f_nametagDisableKey.sqf"
+
+
+//------------------------------------------------------------------------------------
+// Keep an updated cache of all tags to draw.
+//------------------------------------------------------------------------------------
+
+#include "include\f_nametagCacheLoop.sqf"
+
+
+//------------------------------------------------------------------------------------
+// Render nametags from the cache every frame.
+//------------------------------------------------------------------------------------
+
+F_NT_EVENTHANDLER = addMissionEventHandler
+["Draw3D",
+{
+ if F_NT_NAMETAGS_ON then
+ { call f_fnc_nametagUpdate };
+}];
+
+//------------------------------------------------------------------------------------
+// Add briefing with configurable options.
+//------------------------------------------------------------------------------------
+
+#include "include\f_nametagBrief.sqf"
\ No newline at end of file
diff --git a/f/nametag/f_nametags.sqf b/f/nametag/f_nametags.sqf
deleted file mode 100644
index 2c540d5d..00000000
--- a/f/nametag/f_nametags.sqf
+++ /dev/null
@@ -1,240 +0,0 @@
-// F3 - Nametags
-// Credits: Please see the F3 online manual (http://www.ferstaberinde.com/f3/en/)
-// ====================================================================================
-
-// MAKE SURE THE PLAYER INITIALIZES PROPERLY
-
-if (!isDedicated && (isNull player)) then
-{
- waitUntil {sleep 0.1; !isNull player};
-};
-
-// ====================================================================================
-
-// SET GLOBAL VARIABLES
-
-// MODIFYABLE
-
-// Default values (can be modified by players in the briefing entry)
-// Comment any of these to deactivate the feature entirely
-f_showGroup_Nametags = true; // Show unit's group next to unit name (except for player's own group)
-f_showDistance_Nametags = false; // Show distance to unit under name
-f_showVehicle_Nametags = false; // Show type of vehicle under driver's name
-f_showCursorOnly_Nametags = false; // Show only units under cursor target (disable 360° view)
-
-// Other values
-f_distCursor_Nametags = 28; // Distance to display name tag for unit under cursor
-f_distAll_Nametags = 10; // Distance to display name tags for all units around
-F_KEY_NAMETAGS = "TeamSwitch"; // The action key to toggle the name tags. See possible keys here: http://community.bistudio.com/wiki/Category:Key_Actions
-
-// Display values
-f_size_Nametags = 0.023; // The size the names are displayed in
-f_height_standing_Nametags = 2; // Height above standing infantry unit
-f_height_crouch_Nametags = 1.5; // Height above crouching infantry unit
-f_height_prone_Nametags = 0.9; // Height above prone infantry unit
-f_vheight_Nametags = 0; // The height of the name tags for units in vehicles (0 = hovering over vehicle)
-F_SHADOW_NAMETAGS = 2; // The shadow for the name tags (0 - 2)
-f_color_Nametags = [1,1,1,0.9]; // The color for infantry and units in vehicle cargo (in [red,green, blue, opacity])
-f_color2_Nametags = [1,0.1,0.2,0.9]; // The color for units in driver, gunner and other vehicle positions positions
-f_groupColor_Nametags = [0,1,0.7,0.9]; // The color for units of the same group
-F_FONT_NAMETAGS = "EtelkaMonospaceProBold"; // Font for the names
-
-// SCRIPTSIDE
-
-F_DRAW_NAMETAGS = false;
-F_ACTIONKEY_NAMETAGS = (actionKeys F_KEY_NAMETAGS) select 0;
-F_KEYNAME_NAMETAGS = actionKeysNames F_KEY_NAMETAGS;
-if (isNil "F_ACTIONKEY_NAMETAGS") then {F_ACTIONKEY_NAMETAGS = 20; F_KEYNAME_NAMETAGS = 'U';}; // If the user has not bound 'TeamSwitch' to a key we default to 'U' to toggle the tags
-
-F_KEYUP_NAMETAG = {
- _key = _this select 1;
- _handeld = false;
- if(_key == F_ACTIONKEY_NAMETAGS) then
- {
- _handeld = true;
- };
- _handeld;
-};
-
-F_KEYDOWN_NAMETAG = {
- _key = _this select 1;
- _handeld = false;
- if(_key == F_ACTIONKEY_NAMETAGS) then
- {
- F_DRAW_NAMETAGS = !F_DRAW_NAMETAGS;
- _handeld = true;
- };
- _handeld;
-};
-
-// ====================================================================================
-
-// ADD BRIEFING SECTION
-// A section is added to the player's briefing to inform them about name tags being available.
-
-[] spawn {
- waitUntil {scriptDone f_script_briefing};
-
- _bstr = format ["F3 NAME TAGS
Toggle name tags for friendly units by pressing %1.
-Name tags are displayed when aiming at individual units up to %4m away, and constantly for all units within %3m.
- ",F_KEYNAME_NAMETAGS, F_KEY_NAMETAGS,F_DISTALL_NAMETAGS,F_DISTCursor_NAMETAGS];
-
- _bstr = _bstr + "
TOGGLE CONSTANT TAGS.
Constantly displays name tags for nearby units.";
-
- if !(isNil "F_SHOWGROUP_NAMETAGS") then {
- _bstr = _bstr + "
TOGGLE GROUP NAME DISPLAY.
Displays the group name next to a unit's name.";
- };
-
- if !(isNil "F_SHOWDISTANCE_NAMETAGS") then {
- _bstr = _bstr + "
TOGGLE DISTANCE DISPLAY.
Displays distance to other units under each name tag.";
- };
-
- if !(isNil "f_showVehicle_Nametags") then {
- _bstr = _bstr + "
TOGGLE VEHICLE TYPE DISPLAY.
Displays the vehicle type under the driver's name.";
- };
-
- _bstr = _bstr + "
COLORS
- Friendly
- Fireteam
- Vehicle Crew";
-
- player createDiaryRecord ["Diary", ["F3 NameTags (Options)",_bstr]];
-
- // NOTIFY PLAYER ABOUT NAMETAGS VIA HINT
- sleep 5;
- hintsilent format ["Press %1 to toggle name tags", F_KEYNAME_NAMETAGS];
-};
-
-// ====================================================================================
-
-// ADD EVENTHANDLERS
-// After the mission has initialized eventhandlers are added to the register keypresses.
-
-sleep 0.1;
-
-waitUntil {!isNull (findDisplay 46)}; // Make sure the display we need is initialized
-
-F_DRAW_NAMETAGS = true; // Enable nametags from the start
-
-(findDisplay 46) displayAddEventHandler ["keyup", "_this call F_KEYUP_NAMETAG"];
-(findDisplay 46) displayAddEventHandler ["keydown", "_this call F_KEYDOWN_NAMETAG"];
-
-// ====================================================================================
-// the real code.
-
-addMissionEventHandler ["Draw3D", {
-
- if(F_DRAW_NAMETAGS) then
- {
-
- private ["_ents","_veh","_color","_inc","_suffix","_pos","_angle"];
-
- _ents = [];
-
- // Unless disabled, collect all entities in the relevant distance
- if !(f_showCursorOnly_Nametags) then {
- _ents = (position player) nearEntities [["CAManBase","LandVehicle","Helicopter","Plane","Ship_F"], f_distAll_Nametags];
- };
-
- if (!(cursorTarget in _ents) && {((player distance cursorTarget) <= f_distCursor_Nametags) && player knowsAbout cursorTarget >= 1.5}) then {_ents append [cursorTarget]};
-
- /*if (f_cursortarget_nametags) then {
- if ((player distance cursorTarget) <= F_DIST_NAMETAGS) then {_ents = [cursortarget]};
- } else {
- _ents = (position player) nearEntities [["CAManBase","LandVehicle","Helicopter","Plane","Ship_F"], f_distAll_Nametags];
- };*/
-
- // Start looping through all entities
- {
- // Filter entities
- if (
- // Only for the player's side
- (faction _x == faction player || side _x == side player || group _x == group player) &&
- // Only other players & no virtual units
- {_x != player && !(player iskindof "VirtualMan_F")}
- )
- then
- {
-
- // If the entity is Infantry
- if((typeof _x) iskindof "Man") then
- {
- _pos = visiblePosition _x;
- [_x,_pos] call f_fnc_drawNameTag;
- }
-
- // Else (if it's a vehicle)
- else
- {
-
- _veh = _x;
- _inc = 1;
- _alternate = 0;
-
- {
- // Get the various crew slots
- _suffix = switch (true) do {
- case (driver _veh == _x && !((_veh isKindOf "helicopter") || (_veh isKindOf "plane"))):{" - D"};
- case (driver _veh == _x && ((_veh isKindOf "helicopter") || (_veh isKindOf "plane"))):{" - P"};
- case (commander _veh == _x);
- case (effectiveCommander _veh == _x):{" - CO"};
- case (gunner _veh == _x):{" - G"};
- case (assignedVehicleRole _x select 0 == "Turret" && commander _veh != _x && gunner _veh != _x && driver _veh != _x):{" - C"};
- default {""};
- };
-
- _pos = visiblePosition _x;
-
- // Only display tags for non-driver crew and cargo if player is up close
- if (effectiveCommander _veh == _x || group _x == group player || _pos distance player <= f_distAll_Nametags) then {
-
- // If the unit is the driver, calculate the available and taken seats
- if (effectiveCommander _veh == _x) then {
- // Workaround for http://feedback.arma3.com/view.php?id=21602
- _maxSlots = getNumber(configfile >> "CfgVehicles" >> typeof _veh >> "transportSoldier") + (count allTurrets [_veh, true] - count allTurrets _veh);
- _freeSlots = _veh emptyPositions "cargo";
-
- if (_maxSlots > 0) then {
- _suffix = _suffix + format [" (%1/%2)",(_maxSlots-_freeSlots),_maxSlots];
- };
- };
-
- // If the unit is in a turret, a passenger or the driver
- if (_pos distance (getPosVisual (driver _veh)) > 0.1 || driver _veh == _x) then
- {
- [_x,_pos,_suffix] call f_fnc_drawNameTag;
- }
- else // Gunners and all other slots
- {
- if(_x == gunner _veh) then
- {
- _pos = [_veh modeltoworld (_veh selectionPosition "gunnerview") select 0,_veh modeltoworld (_veh selectionPosition "gunnerview") select 1,(visiblePosition _x) select 2];
- }
- else
- {
- _angle = (getdir _veh)+180;
- _pos = [((_pos select 0) + sin(_angle)*(0.6*_inc)) , (_pos select 1) + cos(_angle)*(0.6*_inc),_pos select 2 + F_VHEIGHT_NAMETAGS];
- _inc = _inc + 1;
- };
-
- [_x,_pos,_suffix] call f_fnc_drawNameTag;
- };
-
- };
-
- } foreach crew _veh;
- };
- };
- } foreach _ents;
-
- }; // Outmost if scope
-
-}]; // End of the Eventhandler Scope
-
diff --git a/f/nametag/fn_drawNametag.sqf b/f/nametag/fn_drawNametag.sqf
deleted file mode 100644
index 684277a1..00000000
--- a/f/nametag/fn_drawNametag.sqf
+++ /dev/null
@@ -1,52 +0,0 @@
-// F3 - Draw Nametag
-// Credits: Please see the F3 online manual (http://www.ferstaberinde.com/f3/en/)
-// ====================================================================================
-
-private ["_u","_pos","_suffix","_color","_str","_height","_showgroup","_showdis","_showveh","_veh"];
-
-// Declare variables
-_u = _this select 0;
-_pos = _this select 1;
-_height =
-switch (stance _u) do {
- case "CROUCH": {
- f_height_crouch_Nametags;
- };
- case "PRONE": {
- f_height_prone_Nametags;
- };
- default {f_height_standing_Nametags};
-};
-_suffix = if (count _this > 2) then {_this select 2} else {""};
-
-_str = name _u + _suffix;
-
-//If the unit is dead, exit.
-if (!alive _u) exitWith {};
-
-// Define the color of the nametag
-_color = F_COLOR_NAMETAGS; // Default color
-if (_suffix != "") then {_color = F_COLOR2_NAMETAGS}; // Mounted units
-if(_x in units player) then { _color = f_groupColor_Nametags }; // Units of same group
-
-// Check which tags to show
-_showgroup = if (!isNil "F_SHOWGROUP_NAMETAGS") then [{F_SHOWGROUP_NAMETAGS},{false}];
-_showdis = if (!isNil "F_SHOWDISTANCE_NAMETAGS") then [{F_SHOWDISTANCE_NAMETAGS},{false}];
-_showveh = if (!isNil "f_showVehicle_Nametags") then [{f_showVehicle_Nametags},{false}];
-
-// Show group name for other groups only
-if (_showgroup && group _u != group player) then {_str = format ["%1 ",groupID (group _u)] + _str};
-
-// Show distance for units in over 3m distance only
-if (_showdis && {_pos distance player >= 3}) then {
- _str = _str + format [" - %1m",round (_pos distance player)];
- //drawIcon3D ["", _color, [_pos select 0,_pos select 1,(getPosATL _x select 2) - _height], 0, 0, 0, _str, F_SHADOW_NAMETAGS,(F_SIZE_NAMETAGS - 0.005), F_FONT_NAMETAGS];
-};
-
-drawIcon3D ["", _color, [_pos select 0,_pos select 1,(getPosATL _x select 2) + _height], 0, 0, 0, _str, F_SHADOW_NAMETAGS,F_SIZE_NAMETAGS, F_FONT_NAMETAGS];
-
-// Show vehicle type only for vehicles the player is not crewing himself
-if (_showveh && {!(typeOf (vehicle _u) isKindof "Man") && vehicle _u != vehicle player && ((_u == driver vehicle _u) || (_u == gunner vehicle _u))}) then {
- _str = format ["%1",getText (configFile >> "CfgVehicles" >> (typeOf vehicle _u) >> "displayname")];
- drawIcon3D ["", _color, [_pos select 0,_pos select 1,(getPosATL _x select 2) + _height - 0.2], 0, 0, 0, _str,F_SHADOW_NAMETAGS,F_SIZE_NAMETAGS,F_FONT_NAMETAGS];
-};
\ No newline at end of file
diff --git a/f/nametag/functions/fn_getZoom.sqf b/f/nametag/functions/fn_getZoom.sqf
new file mode 100644
index 00000000..a1eb0143
--- /dev/null
+++ b/f/nametag/functions/fn_getZoom.sqf
@@ -0,0 +1,24 @@
+//====================================================================================
+//
+// fn_getZoom.sqf - Gets player zoom, where default is 1.0
+// > _zoom = call f_fnc_getZoom; <
+//
+// Adapted from code by Killzone Kid.
+// http://killzonekid.com/arma-scripting-tutorials-get-zoom/
+//
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+(
+ (
+ [0.5,0.5]
+ distance2D
+ worldToScreen
+ positionCameraToWorld
+ [0,3,4]
+ ) * (
+ getResolution
+ select 5
+ ) / 2
+) + 0.66666
diff --git a/f/nametag/functions/fn_nametagCache.sqf b/f/nametag/functions/fn_nametagCache.sqf
new file mode 100644
index 00000000..46fcab62
--- /dev/null
+++ b/f/nametag/functions/fn_nametagCache.sqf
@@ -0,0 +1,71 @@
+//====================================================================================
+//
+// fn_nametagCache.sqf - Updates global cache of near entities and their data.
+// Updates some other stuff, too.
+//
+// > call f_fnc_nametagCache; <
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// If the nametag system is on, check all the stuff we need to check!
+//------------------------------------------------------------------------------------
+
+if F_NT_NAMETAGS_ON then
+{
+ // Collect the current player.
+ _player = player;
+
+ // Check the day night cycle...
+ F_NT_VAR_NIGHT = if F_NT_NIGHT then
+ { linearConversion [0, 1, sunOrMoon, 0.25+0.5*(currentVisionMode _player),1,true]; }
+ else { 1 };
+
+ // Check the day night cycle...
+ F_NT_VAR_NIGHT = if F_NT_NIGHT then
+ { linearConversion [0, 1, sunOrMoon, 0.25+0.5*(currentVisionMode _player),1,true]; }
+ else { 1 };
+
+ F_NT_VAR_VEHICLETPP =
+ if (!(isNull objectParent _player) && {(cameraView isEqualTo "EXTERNAL")})
+ then { true }
+ else { false };
+
+ //--------------------------------------------------------------------------------
+ // If not set to only draw the cursor, collect nearEntities.
+ //--------------------------------------------------------------------------------
+
+ if !F_NT_DRAWCURSORONLY then
+ {
+ // Reset the data variable.
+ _data = [];
+
+ // Collect the player's group.
+ _playerGroup = group _player;
+
+ // Get the position of the player's camera.
+ _cameraPositionAGL = positionCameraToWorld[0,0,0];
+ _cameraPositionASL = AGLtoASL _cameraPositionAGL;
+
+ // Collect all nearEntities of the types we want.
+ _entities =
+ _player nearEntities [["CAManBase","LandVehicle","Helicopter","Plane","Ship_F"],
+ ((F_NT_DRAWDISTANCE_NEAR+(F_NT_DRAWDISTANCE_NEAR*0.25)+1)*F_NT_VAR_NIGHT)]
+ select
+ {
+ !(_x isEqualTo _player)
+ && {(side group _x) isEqualTo (side _playerGroup)}
+ && {!WH_NT_VAR_VEHICLETPP || {(vehicle _x != vehicle _player)}}
+ };
+
+ // Collect each filter entities' data.
+ _data = [_player,_playerGroup,_cameraPositionAGL,_cameraPositionASL,_entities,false]
+ call f_fnc_nametagGetData;
+
+ // Push all those names and their data to the global cache.
+ F_NT_CACHE =+ _data;
+ }
+ else
+ { F_NT_CACHE = [[],[]] };
+};
\ No newline at end of file
diff --git a/f/nametag/functions/fn_nametagDraw.sqf b/f/nametag/functions/fn_nametagDraw.sqf
new file mode 100644
index 00000000..e17cf44d
--- /dev/null
+++ b/f/nametag/functions/fn_nametagDraw.sqf
@@ -0,0 +1,177 @@
+//====================================================================================
+//
+// fn_nametagDraw.sqf - Initializes values for WH nametags (heavily based on F3 and ST)
+//
+// [_name,_nameColor,_locationData,_role,_groupName,_drawRoleAndGroup,_isCommander,
+// _cameraPositionAGL,_zoom] call f_fnc_nametagDraw;
+//
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// Declare variables.
+//------------------------------------------------------------------------------------
+
+params ["_unit","_vehicle","_name","_nameColor","_locationData","_role","_groupName",
+ "_drawRoleAndGroup","_isPassenger","_isCommander","_cameraPositionAGL",
+ "_zoom","_time","_startTime"];
+
+// _unit (CAManBase): Unit the tag is being rendered on.
+// _vehicle (Entity): Vehicle the unit is in. Possibly the unit.
+// _name (string): Friendly name of tag to be rendered.
+// _nameColor (color array [[],[],[],]): Original color of center nametag.
+// _locationData {code}: Code that will be used to find the location to draw the tag.
+// _role (string): Friendly role name to be rendered on top.
+// _groupName (string): Friendly group name to be rendered on bottom.
+// _drawRoleAndGroup (boolean): A flag used to point out noncursor units and prevent
+// them from having group and role tags.
+// _isCommander (boolean): A flag used to point out vehicle non-commanders and prevent
+// them from being rendered as far as vehicle commanders.
+// _cameraPositionAGL (positionAGL array [[],[],[]]): Current position of player camera.
+// _zoom (decimal): Current zoom level of player camera.
+// _time (decimal): For fading tags and displaying voice comms -- current time.
+// _startTime (OPTIONAL, decimal): For fading tags -- time tag was originally rendered.
+
+// Get player from global player setting.
+// This is necessary for Zeus remote control support.
+_player = player;
+
+
+//------------------------------------------------------------------------------------
+// Get distance from player to target.
+//------------------------------------------------------------------------------------
+
+// Find position tag will be rendered at using location data.
+_targetPositionAGL = call _locationData;
+
+// Find the distance from the player camera to this location.
+_camDistance = _cameraPositionAGL distance _targetPositionAGL;
+_distance = _player distance _targetPositionAGL;
+
+
+//------------------------------------------------------------------------------------
+// Change the nametag if the target is speaking.
+//------------------------------------------------------------------------------------
+
+// If the unit is speaking, apply little carets around their name.
+// TODO: move up a few scopes. GetData? Will stick on cursor
+
+if (_unit getVariable ["wh_nt_isSpeaking", false]) then
+{
+ _timeEven = ((round time) % 2 == 0);
+ _nameColor set [3,0.90];
+ _name =
+ if _timeEven then
+ { "> " + _name + " <" }
+ else
+ { ">" + _name + "<" };
+};
+
+
+//------------------------------------------------------------------------------------
+// Applying initial transparency to tag depending on distance and time of day.
+//------------------------------------------------------------------------------------
+
+_alpha =
+if (!_drawRoleAndGroup || {!(_isCommander)})
+then { linearConversion[F_NT_DRAWDISTANCE_NEAR/1.3,F_NT_DRAWDISTANCE_NEAR,
+ (_distance / F_NT_VAR_NIGHT),1,0,true] }
+else { linearConversion[(((F_NT_DRAWDISTANCE_CURSOR)*(_zoom))/1.3),
+ (F_NT_DRAWDISTANCE_CURSOR*_zoom),(((_distance) / F_NT_VAR_NIGHT)),1,0,true] };
+
+// Apply the alpha coating to each color's transparency.
+_nameColor set [3, (_nameColor select 3) * _alpha];
+
+
+//------------------------------------------------------------------------------------
+// Adjust font size depending on player current zoom level.
+//------------------------------------------------------------------------------------
+
+// TODO: Move up to Update scope.
+// Max out zoom at 1.67 regardless to avoid HUGE text.
+_zmin = _zoom min 1.67;
+
+// Adjust font sizes.
+_sizeMain = F_NT_FONT_SIZE_MAIN* _zmin;
+_sizeSecondary = F_NT_FONT_SIZE_SEC * _zmin;
+_sizeVehicle = F_NT_FONT_SIZE_VEH * _zmin;
+
+
+//------------------------------------------------------------------------------------
+// If the tag being drawn is on cursor, render the role and group.
+//------------------------------------------------------------------------------------
+
+if (_drawRoleAndGroup && {!(_isPassenger)}) then
+{
+ // Set the color for secondary tags.
+ _color =+ F_NT_FONT_COLOR_OTHER;
+ _color set [3, (_color select 3) * _alpha];
+
+ // If we're working with a fading tag, fade it out according to the difference
+ // between the start time and now.
+ if (!isNil "_startTime") then
+ {
+ _alphaCoef = (((_startTime + F_NT_FADETIME) - _time)/F_NT_FADETIME);
+ _nameColor set [3, (_namecolor select 3) * _alphaCoef];
+ _color set [3, (_color select 3) * _alphaCoef];
+ };
+
+ //--------------------------------------------------------------------------------
+ // Use space magic to realign the tags with the player's view.
+ // IE: If the player is above the target, normally the nametags (which are stacked -
+ // - vertically) would appear scrunched inside one another.
+ // This alleviates this by realigning them vertically.
+ //
+ // Special thanks to cptnnick for this idea, code, implementation, everything!
+ //--------------------------------------------------------------------------------
+
+ // First, get vector pointing directly forward from the player's view, wherever it is.
+ // TODO: Move up to update scope.
+ _vectorDir = _cameraPositionAGL vectorFromTo (positionCameraToWorld[0,0,1]);
+
+ // Second, and the biggest step, get the normal (magnitude 1) vector going upwards
+ // along the player's screen (visually) by taking the cross product of the player's
+ // model upward vector and the player's view vector, and then take the cross product
+ // of that and a vector going directly from the camera to the nametag.
+
+ // Better explanation here
+ // ( forums.bistudio.com/forums/topic/206072-multi-line-text-in-drawicon3d )
+
+ // TODO: Simplify this code if possible.
+ // If not possible, cache what you can (vectorUp player vectorCrossProduct _vectorDir)
+ // in nametagUpdate.
+ _vectorDiff = (vectorNormalized (((_vectorDir) vectorCrossProduct (vectorUp _player)) vectorCrossProduct (_targetPositionAGL vectorDiff _cameraPositionAGL)));
+
+ // Take that new normal vector and multiply it by the distance, then divide it by the zoom.
+
+ _targetPositionAGLTop = _targetPositionAGL vectorAdd (_vectorDiff vectorMultiply (F_NT_FONT_SPREAD_TOP_MULTI * _camDistance / _zoom));
+ _targetPositionAGLBottom = _targetPositionAGL vectorAdd ((_vectorDiff vectorMultiply (F_NT_FONT_SPREAD_BOTTOM_MULTI * _camDistance / _zoom)) vectorMultiply -1);
+
+
+ //--------------------------------------------------------------------------------
+ // Render the nametags.
+ //--------------------------------------------------------------------------------
+
+ // Role tag (top).
+ if ( !(_role isEqualTo "") && {F_NT_SHOW_ROLE} ) then
+ {
+ drawIcon3D ["", _color, _targetPositionAGLTop,
+ 0, 0, 0, _role,F_NT_FONT_SHADOW,_sizeSecondary,F_NT_FONT_FACE_SEC];
+ };
+
+ // Group tag (bottom).
+ if ( !(_groupName isEqualTo "") && {F_NT_SHOW_GROUP} ) then
+ {
+ drawIcon3D ["", _color, _targetPositionAGLBottom,
+ 0, 0, 0, _groupName,F_NT_FONT_SHADOW,_sizeSecondary,F_NT_FONT_FACE_SEC];
+ };
+};
+
+// TODO: Remove this testing thing
+// Name tag (middle).
+//drawIcon3D ["\A3\ui_f\data\map\markers\flags\AAF_ca.paa", [0,0,0,1], _targetPositionAGL, 1, 1, 0, "",0,(_sizeMain+(_sizeMain*0.2)),F_NT_FONT_FACE_MAIN];
+
+// Name tag (middle).
+drawIcon3D ["", _nameColor, _targetPositionAGL, 0,0,0, _name,F_NT_FONT_SHADOW,_sizeMain,F_NT_FONT_FACE_MAIN];
+
diff --git a/f/nametag/functions/fn_nametagGetData.sqf b/f/nametag/functions/fn_nametagGetData.sqf
new file mode 100644
index 00000000..7717cfb8
--- /dev/null
+++ b/f/nametag/functions/fn_nametagGetData.sqf
@@ -0,0 +1,288 @@
+//====================================================================================
+//
+// fn_nametagUpdate.sqf - Updates values for F3 nametags
+// Intended to be run each frame.
+//
+// > _data = [_player,_playerGroup,_cameraPositionAGL,_cameraPositionASL,_entities,
+// false] call f_fnc_nametagGetData; <
+//
+// Returns [_names,_data].
+// Names is an array of references to units (CAManBase).
+// Data is nametag data, for each.
+//
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// Initializing variables.
+//------------------------------------------------------------------------------------
+
+params ["_player","_playerGroup","_cameraPositionAGL","_cameraPositionASL",
+ "_entities","_isCursor"];
+
+// _player (object CAManBase): Current player that will be rendering tags.
+// _playerGroup: Group of said player.
+// _cameraPositionAGL (positionAGL array [[],[],[]]): Current position of player camera.
+// _cameraPositionASL (positionASL array [[],[],[]]): Current position of player camera.
+// _entities (array of objects CAManBase or vehicle): Entities tags will be processed for.
+// _isCursor (boolean): Flag signaling that said entities are under cursor.
+
+
+//------------------------------------------------------------------------------------
+// Establishing arrays to be filled with unit names and unit data, respectively.
+//------------------------------------------------------------------------------------
+
+// TODO: Do these need to be private?
+private _names= [];
+private _data = [];
+
+// Temporary fix for zoom not being in here.
+private _zoom = 1;
+
+
+//------------------------------------------------------------------------------------
+// Main loop. Fills above arrays with data for each entity in _entities.
+//------------------------------------------------------------------------------------
+
+// For every entity in _entities...
+{
+ // Store said entity. It may be a vehicle (with multiple people inside), and it
+ // may just be a single unit. We do not know, so we will just process data for
+ // each of the "vehicles" (or units) "crew" (or self).
+ _entity = _x;
+
+ if !(_entity in allUnitsUAV) then // TODO: Find a better solution for this.
+ {
+ {
+ // Reset variables used for each unit.
+ _locationData = {};
+ _role = "";
+ _show = false;
+ _drawRoleAndGroup = false;
+ _isCommander = false;
+ _isPassenger = false; // TODO : Find a smoother solution for this.
+
+ if !(_x isEqualTo _player) then
+ {
+ // If the unit is NOT in a vehicle...
+ if (isNull objectParent _x) then
+ {
+ // Get the data that will be processed (later) to determine where
+ // to draw the nametag. Either their chest, or above their head.
+ _locationData =
+ if !F_NT_FONT_HEIGHT_ONHEAD
+ then { {_x modelToWorldVisual (_x selectionPosition "spine3")} }
+ else { {_x modelToWorldVisual (_x selectionPosition "pilot")
+ vectorAdd [0,0,((0.2 + (((_cameraPositionAGL distance _x) * 1.5 *
+ F_NT_FONT_SPREAD_BOTTOM_MULTI)/_zoom)))]} };
+
+ _isCommander = true;
+
+ // If the unit is NOT in a vehicle and NOT under the cursor...
+ if !_isCursor then
+ {
+ // Get the location of that unit...
+ _targetPositionAGL = call _locationData;
+ _targetPositionASL = AGLtoASL _targetPositionAGL;
+
+ // ...and check...
+ if
+ (
+ // ( If the man is within the boundaries of the screen )
+ !(worldToScreen _targetPositionAGL isEqualTo []) &&
+ // AND ( If the game can draw a line from the player to the man without hitting anything )
+ { lineIntersectsSurfaces [_cameraPositionASL, _targetPositionASL, _player, _x] isEqualTo [] }
+ )
+ // If those criteria are met, let the system know that the tag will be shown.
+ then { _show = true };
+ }
+ else
+ {
+ // If the unit is NOT in a vehicle but IS under the cursor,
+ // show it, and let the system know that the role and group
+ // should be rendered.
+ _show = true;
+ _drawRoleAndGroup = true;
+ };
+ }
+
+ // Otherwise (if the unit IS in a vehicle)...
+ else
+ {
+ // The vehicle is the thing we're processing the crew for.
+ _vehicle = vehicle _x; //objectParent _x
+
+ // Depending on where the unit is in a vehicle, store it's 'role.'
+ _role = call
+ {
+ if ( commander _vehicle isEqualTo _x ) exitWith {"Commander"};
+ if ( gunner _vehicle isEqualTo _x ) exitWith {"Gunner"};
+ if ( !(driver _vehicle isEqualTo _x)) exitWith {""};
+ if ( driver _vehicle isEqualTo _x && {!(_vehicle isKindOf "helicopter") && {!(_vehicle isKindOf "plane")}} ) exitWith {"Driver"};
+ if ( driver _vehicle isEqualTo _x && { (_vehicle isKindOf "helicopter") || { (_vehicle isKindOf "plane")}} ) exitWith {"Pilot"};
+ ""
+ };
+
+ // The location data is different for vehicles, since many vehicle
+ // positions do not work properly with modelToWorldVisual.
+ _locationData =
+ { ASLtoAGL (getPosASLVisual _x) vectorAdd [0,0,(0.4)] };
+
+ // Use the above location data to get the unit's location.
+ _targetPositionAGL = call _locationData;
+ _targetPositionASL = AGLtoASL _targetPositionAGL;
+
+ // If the unit has a role (isn't a passenger) then...
+ if !(_role isEqualTo "") then
+ {
+ // ...if it's effectively the commander of the vehicle...
+ if ( effectiveCommander _vehicle isEqualTo _x ) then
+ {
+ // ...set a flag that lets the system know if a player has this
+ // vehicle under his cursor from far away, only this guy should
+ // be rendered.
+ _isCommander = true;
+
+ // Also, if the missionmaker has configured vehicle information
+ // to be shown, store that for later.
+ if F_NT_SHOW_VEHICLEINFO then
+ {
+ // Get the vehicle's friendly name from configs.
+ _vehicleName = format ["%1",getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayname")];
+
+ // Get the maximum number of (passenger) seats from configs.
+ _maxSlots = getNumber(configfile >> "CfgVehicles" >> typeof _vehicle >> "transportSoldier") + (count allTurrets [_vehicle, true] - count allTurrets _vehicle);
+
+ // Get the number of empty seats.
+ _freeSlots = _vehicle emptyPositions "cargo";
+
+ // If meaningful, append vehicle name.
+ if !(_vehicleName isEqualTo "") then
+ { _role = format ["%1 %2",_vehicleName,_role]};
+
+ // If meaningful, append some info on seats onto the vehicle info.
+ if (_maxSlots > 0) then
+ { _role = format["%1 [%2/%3]",_role,(_maxSlots-_freeSlots),_maxSlots]; };
+ };
+
+
+ };
+
+ // If the unit is the gunner and is uncomfortably close to the driver (many Arma APCs
+ // without interiors do this), then render the nametag where the turret is.
+ if ( _role isEqualTo "Gunner" && {_targetPositionASL distance (getPosASLVisual(driver _vehicle)) < 0.5} ) then
+ {
+ _locationData =
+ { _vehicle modelToWorldVisual (_vehicle selectionPosition "gunnerview") };
+ };
+
+ // If the unit's location is on-screen...
+ if !(worldToScreen _targetPositionAGL isEqualTo []) then
+ {
+ // Then show it.
+ _show = true;
+
+ // If it's player's vehicle, or if it's under the cursor,
+ // then draw the role and group, too.
+ if ( _vehicle isEqualTo vehicle _player || {_isCursor} ) then
+ { _drawRoleAndGroup = true };
+ };
+ }
+
+ // Otherwise (if it IS a passenger)...
+ else
+ {
+ if
+ (
+ // ( If the man is within the boundaries of the screen )
+ !(worldToScreen _targetPositionAGL isEqualTo []) &&
+ // AND ( If the game can draw a line from the player to the man without hitting anything )
+ { lineIntersectsSurfaces [_cameraPositionASL, _targetPositionASL, _player, _x] isEqualTo [] } &&
+ {_targetPositionAGL distance (ASLToAGL getPosASLVisual(driver _vehicle)) > 0.5}
+ )
+ then
+ {
+ // Don't draw the role and group no matter what.
+ _isPassenger = true;
+ _show = true;
+ };
+ }
+ };
+
+ //----------------------------------------------------------------------------
+ // If the tag's going to be shown, get and add the data.
+ //----------------------------------------------------------------------------
+
+ // If it's shown...
+ if _show then
+ {
+ // Get the unit's name.
+ _name = name _x;
+
+ // Default the unit's nametag color to the mission default.
+ _nameColor =+ F_NT_FONT_COLOR_DEFAULT;
+
+ // Get the unit's group.
+ _unitGroup = group _x;
+
+ // If the unit is in the same group as the player,
+ // then erase the group tag. It does not need to be shown.
+ _sameGroup = (_unitGroup isEqualTo _playerGroup);
+ _groupName = if !_sameGroup then { groupID _unitGroup } else { "" };
+
+ // ...For normal people...
+ if (_role isEqualTo "") then
+ {
+ // Grab the variable set in F3 AssignGear, if present.
+ // If it's not there, grab the possibly-ugly name from configs.
+ _role = (_x getVariable ["f_var_assignGear_friendly",
+ getText (configFile >> "CfgVehicles" >> typeOf _x >> "displayname")]);
+ }
+ // ...and for vehicle crew, where a role is already present.
+ else { _nameColor =+ F_NT_FONT_COLOR_CREW };
+
+ // For units in the same group as the player, set their color according to color team.
+ if _sameGroup then
+ {
+ _team = assignedTeam _x;
+ _nameColor = switch _team do
+ {
+ case "RED": { +F_NT_FONT_COLOR_GROUPR };
+ case "GREEN": { +F_NT_FONT_COLOR_GROUPG };
+ case "BLUE": { +F_NT_FONT_COLOR_GROUPB };
+ case "YELLOW": { +F_NT_FONT_COLOR_GROUPY };
+ default { +F_NT_FONT_COLOR_GROUP };
+ };
+ };
+
+ // Huck all this data into an array...
+ _unitData = [];
+ _unitData pushBack _x;
+ _unitData pushBack _entity; // Index 0
+ _unitData pushBack _name; // Index 1
+ _unitData pushBack _nameColor; // Index 2
+ _unitData pushBack _locationData; // Index 3
+ _unitData pushBack _role; // Index 4
+ _unitData pushBack _groupName; // Index 5
+ _unitData pushBack _drawRoleAndGroup; // Index 6
+ _unitData pushBack _isPassenger;
+ _unitData pushBack _isCommander;
+
+ // ...Then add the unit's name to the name array...
+ _names pushBack _x;
+
+ // ...and the unit's data to the data array.
+ _data append [_unitData];
+ };
+ };
+ } forEach (crew _entity);
+ };
+} count _entities;
+
+
+//------------------------------------------------------------------------------------
+// Returns arrays of names and data for all valid entities.
+//------------------------------------------------------------------------------------
+
+[_names,_data]
\ No newline at end of file
diff --git a/f/nametag/functions/fn_nametagResetFont.sqf b/f/nametag/functions/fn_nametagResetFont.sqf
new file mode 100644
index 00000000..4fa16d84
--- /dev/null
+++ b/f/nametag/functions/fn_nametagResetFont.sqf
@@ -0,0 +1,115 @@
+//====================================================================================
+//
+// fn_nametagResetFont.sqf - Interprets font sets into typefaces and weights.
+// Updates font size and spread depending on a dynamic
+// spread coefficient and possible CBA setting alterations.
+//
+// > call f_fnc_nametagResetFont; <
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// Interpret font presets and parse into primary and secondary typefaces and weights.
+//------------------------------------------------------------------------------------
+
+// Spacing may very between fonts greatly. Etelka is especially broken.
+// Format: [Primary font, secondary font, spacing top, spacing bottom, shadow]
+_fontData =
+switch F_NT_FONT_FACE do
+{
+ case "Roboto": {["RobotoCondensedBold","RobotoCondensed",0.50,0.65,2]};
+ case "RobotoLight": {["RobotoCondensed","RobotoCondensedLight",0.50,0.65,2]};
+ case "Purista": {["PuristaBold","PuristaMedium",0.47,0.65,2]};
+ case "PuristaLight":{["PuristaMedium","PuristaLight",0.47,0.65,2]};
+ case "Etelka": {["EtelkaNarrowMediumPro","EtelkaNarrowMediumPro",0.4,0.7,2]};
+ case "Tahoma": {["TahomaB","TahomaB",0.55,0.65,2]};
+ default {["RobotoCondensedBold","RobotoCondensed",0.50,0.65,2]};
+};
+
+F_NT_FONT_FACE_MAIN = (_fontData select 0);
+F_NT_FONT_FACE_SEC = (_fontData select 1);
+F_NT_FONT_SHADOW = (_fontData select 4);
+
+
+//------------------------------------------------------------------------------------
+// Interpret font color presets and parse accordingly.
+//------------------------------------------------------------------------------------
+
+// Spacing may very between fonts greatly. Etelka is especially broken.
+// Format: [Main color, secondary color, crew color, same group team white color,
+// team red color, team green color, team blue color, team yellow color]
+_colorData =
+switch F_NT_FONT_COLOR do
+{
+ case "WHGreen":
+ {[[0.68,0.90,0.36,0.85],[0.90,0.90,0.90,0.85],[0.95,0.80,0.10,0.85],
+ [0.90,0.90,0.90,0.85],[0.90,0.25,0.25,0.85],[0.50,0.90,0.40,0.85],
+ [0.45,0.45,0.90,0.85],[0.90,0.90,0.30,0.85]]};
+ //case "UIColor": TODO: Implement
+ //{[[(profilenamespace getVariable ['IGUI_TEXT_RGB_R',0]),(profilenamespace getVariable ['IGUI_TEXT_RGB_G',0]),(profilenamespace getVariable ['IGUI_TEXT_RGB_B',0]),(profilenamespace getVariable ['IGUI_TEXT_RGB_A',0])],[0.90,0.90,0.90,0.85],[0.95,0.80,0.10,0.85],
+ //[0.90,0.90,0.90,0.85],[0.90,0.25,0.25,0.85],[0.50,0.90,0.40,0.85],
+ //[0.45,0.45,0.90,0.85],[0.90,0.90,0.30,0.85]]};
+ case "ACERust":
+ {[[0.77, 0.51, 0.08, 0.95],[0.90,0.75,0,0.85],[0.77, 0.51, 0.08, 0.95],
+ [1, 1, 1, 0.95],[1,0,0,0.95],[0,1,0,0.95],
+ [0,0,1,0.95],[1,1,0,0.95]]};
+ case "TMTMTeal":
+ {[[0.35,0.80,0.90,0.85],[0.90,0.90,0.90,0.85],[0.15,0.70,0.90,0.85],
+ [0.90,0.90,0.90,0.85],[0.90,0.25,0.25,0.85],[0.50,0.90,0.40,0.85],
+ [0.45,0.45,0.90,0.85],[0.90,0.90,0.30,0.85]]};
+ case "COALCrimson":
+ {[[0.90,0.10,0.10,0.85],[0.80,0.78,0.78,0.85],[0.85,0.6,0.2,0.85],
+ [0.90,0.90,0.90,0.85],[0.90,0.25,0.25,0.85],[0.50,0.90,0.40,0.85],
+ [0.45,0.45,0.90,0.85],[0.90,0.90,0.30,0.85]]};
+ case "FAWhite":
+ {[[0.90,0.90,0.90,0.85],[0.90,0.90,0.90,0.85],[0.80,0.80,0.80,0.85],
+ [0.90,0.90,0.90,0.85],[0.90,0.70,0.70,0.85],[0.70,0.90,0.70,0.85],
+ [0.75,0.75,0.90,0.85],[0.80,0.80,0.55,0.85]]};
+ case "STSand":
+ {[[0.90,0.75,0,0.85],[0.90,0.90,0.90,0.85],[0.90,0.75,0,0.85],
+ [0.90,0.90,0.90,0.85],[0.90,0.25,0.25,0.85],[0.50,0.90,0.40,0.85],
+ [0.45,0.45,0.90,0.85],[0.90,0.90,0.30,0.85]]};
+ case "BromaPurple":
+ {[[0.85,0.50,0.90,0.85],[0.68,0.90,0.36,0.85],[0.85,0.50,0.90,0.85],
+ [0.85,0.50,0.90,0.85],[0.90,0.4,0.4,0.85],[0.85,0.50,0.90,0.85],
+ [0.6,0.6,0.90,0.85],[0.90,0.90,0.6,0.85]]};
+ default
+ {[[0.68,0.90,0.36,0.85],[0.90,0.90,0.90,0.85],[0.95,0.80,0.10,0.85],
+ [0.90,0.90,0.90,0.85],[0.90,0.25,0.25,0.85],[0.50,0.90,0.40,0.85],
+ [0.45,0.45,0.90,0.85],[0.90,0.90,0.30,0.85]]};
+};
+
+// Distribute colors from data array to global color settings.
+F_NT_FONT_COLOR_DEFAULT= (_colorData select 0);
+F_NT_FONT_COLOR_OTHER = (_colorData select 1);
+F_NT_FONT_COLOR_CREW = (_colorData select 2);
+
+F_NT_FONT_COLOR_GROUP = (_colorData select 3);
+F_NT_FONT_COLOR_GROUPR = (_colorData select 4);
+F_NT_FONT_COLOR_GROUPG = (_colorData select 5);
+F_NT_FONT_COLOR_GROUPB = (_colorData select 6);
+F_NT_FONT_COLOR_GROUPY = (_colorData select 7);
+
+
+//------------------------------------------------------------------------------------
+// Update global font sizes.
+//------------------------------------------------------------------------------------
+
+F_NT_FONT_SIZE_MAIN = F_NT_FONT_SIZE_RAW * F_NT_FONT_SIZE_MULTI;
+F_NT_FONT_SIZE_SEC = F_NT_FONT_SIZE_MAIN * F_NT_FONT_SIZE_SEC_MULTI;
+
+
+//------------------------------------------------------------------------------------
+// Update global font spread.
+//------------------------------------------------------------------------------------
+
+_spacingMultiplier = F_NT_FONT_SPREAD_MULTI * F_NT_FONT_SIZE_SEC;
+
+// Coefficients are used. Should be changed if you change the default font, probably.
+_topMultiplier = (_fontData select 2); // Default: (0.50)
+_bottomMultiplier = (_fontData select 3); // Default: (0.65)
+
+// Top and bottom are separate to avoid a wonky appearance.
+F_NT_FONT_SPREAD_TOP_MULTI = _spacingMultiplier * _topMultiplier;
+F_NT_FONT_SPREAD_BOTTOM_MULTI = _spacingMultiplier * _bottomMultiplier;
diff --git a/f/nametag/functions/fn_nametagUpdate.sqf b/f/nametag/functions/fn_nametagUpdate.sqf
new file mode 100644
index 00000000..f966ad17
--- /dev/null
+++ b/f/nametag/functions/fn_nametagUpdate.sqf
@@ -0,0 +1,204 @@
+//====================================================================================
+//
+// fn_nametagUpdate.sqf - Updates values for F3 nametags
+// Intended to be run each frame.
+//
+// > F_NT_EVENTHANDLER = addMissionEventHandler
+// ["Draw3D", { call f_fnc_nametagUpdate }]; <
+//
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// Initializing variables.
+//------------------------------------------------------------------------------------
+// TODO: all of this only if there's something to draw
+// Store the player and the player's group.
+_player = player;
+_playerGroup = group _player;
+// TODO: Maybe just use playerSide?
+
+// Find player camera's position.
+_cameraPositionAGL = positionCameraToWorld[0,0,0];
+_cameraPositionASL = AGLtoASL _cameraPositionAGL;
+
+// Get zoom, which will be used to adjust size and spacing of text.
+_zoom = call f_fnc_getZoom;
+
+// Make a copy of the global cache containing nearby entities and their data.
+_toDraw =+ F_NT_CACHE;
+
+// Initialize other variables to be used.
+_time = time;
+
+
+//------------------------------------------------------------------------------------
+// Collect player cursor target for drawing tags.
+//------------------------------------------------------------------------------------
+
+// Only collect the cursor target if it's within range and on the player's side.
+_cursorObject =
+if ( (_player distance cursorTarget) <= (((F_NT_DRAWDISTANCE_CURSOR) * F_NT_VAR_NIGHT) * _zoom) &&
+ {(side group cursorTarget isEqualTo side _playerGroup)} )
+then { cursorTarget }
+else { objNull };
+
+
+//------------------------------------------------------------------------------------
+// If the cursor target fits above criteria, get the data for it.
+//------------------------------------------------------------------------------------
+
+// Only worry about the cursorObject at all if it's not null.
+if !( isNull _cursorObject ) then
+{
+ // Clean out any previous data.
+ _newData = [[],[]];
+ _cursorInCache = false;
+ {
+ // If the cursor target is already in the global cache (ie: cursor target
+ // is nearby)...
+ if ( _x in (_toDraw select 0) ) then
+ {
+ // ...then just take that data...
+ _index = (_toDraw select 0) find _x;
+ _unitData =+ ((_toDraw select 1) select _index);
+
+ // ...adjust it so it knows it's the cursor target...
+ _unitData set [7,true];
+
+ // ...take it out of the copy of the global cache...
+ (_toDraw select 0) deleteAt _index;
+ (_toDraw select 1) deleteAt _index;
+
+ // ...and save it for later.
+ (_newData select 0) pushBack _x;
+ (_newData select 1) pushBack _unitData;
+
+ // Also, let us know we don't need to process cursor any further.
+ _cursorInCache = true;
+ }
+ else
+ { _cursorInCache = false };
+ } count (crew _cursorObject);
+
+ // If the cursor target is not already in our global cache...
+ if !_cursorInCache then
+ {
+ // Check the cursor cache, which is used in case we're staring continuously
+ // at something far away.
+ if ( _cursorObject isEqualTo F_NT_CACHE_CURSOR ) then
+ // If it's in there, just take that data.
+ { _newData =+ F_NT_CACHE_CURSOR_DATA }
+ else
+ {
+ // If all else fails and the data is not in the cursor cache nor the global
+ // cache, then find the data anew.
+ _newData =
+ [_player,_playerGroup,_cameraPositionAGL,_cameraPositionASL,[_cursorObject],true]
+ call f_fnc_nametagGetData;
+ };
+ };
+
+ // Whatever data we did save for later, add it to the cursor cache...
+ F_NT_CACHE_CURSOR_DATA =+ _newData;
+
+ // ...and add it to the temporary copy of the global cache, too.
+ (_toDraw select 0) append (_newData select 0);
+ (_toDraw select 1) append (_newData select 1);
+};
+
+
+//------------------------------------------------------------------------------------
+// Draw everything currently in the temporary copy of the global cache.
+// This usually means drawing all nearby entities and the cursor.
+//------------------------------------------------------------------------------------
+
+{
+ _unitData =+ ( (_toDraw select 1) select _forEachIndex );
+
+ // Pass in the player's camera and zoom level.
+ _unitData append [_cameraPositionAGL,_zoom,_time,nil];
+
+ // Call the draw function with the above parameters.
+ _unitData call f_fnc_nametagDraw;
+} forEach (_toDraw select 0);
+
+
+//------------------------------------------------------------------------------------
+// Also, draw everything currently being faded out (ie: moused over it, moused away.)
+//------------------------------------------------------------------------------------
+
+// For every name in the cache of data for fading names...
+{
+ // Get the time we started rendering this tag.
+ _startTime = ( (F_NT_CACHE_FADE select 2) select _forEachIndex );
+
+ // If it hasn't been long enough that it should be invisible, draw it.
+ if ( _time < _startTime + F_NT_FADETIME) then
+ {
+ _unitData =+ ( (F_NT_CACHE_FADE select 1) select _forEachIndex );
+ _unitData append [_cameraPositionAGL,_zoom,_time,_startTime];
+ _unitData call f_fnc_nametagDraw;
+ }
+ // If it has been that long, delete it.
+ else
+ {
+ (F_NT_CACHE_FADE select 0) deleteAt _forEachIndex;
+ (F_NT_CACHE_FADE select 1) deleteAt _forEachIndex;
+ (F_NT_CACHE_FADE select 2) deleteAt _forEachIndex;
+ };
+} forEach (F_NT_CACHE_FADE select 0);
+
+
+//------------------------------------------------------------------------------------
+// If the cursor changed last frame, add the previous cursor to the cache of things
+// to fade out.
+//------------------------------------------------------------------------------------
+
+// TODO: move all fade shit to it's own function
+
+// If the last cursor is something we can draw a tag on...
+// ...and if the last cursor is not the current cursor...
+// ...and this thing isn't already being faded out...
+// ...and we're not already fading too much stuff...
+if (
+ !(isNull F_NT_CACHE_CURSOR)
+ && {!(_cursorObject isEqualTo F_NT_CACHE_CURSOR)}
+ ) then
+{
+ // Prevent the fade system from fading more than four tags
+ // at a time. Give priority to new fades.
+ if ( count (F_NT_CACHE_FADE select 0) > 4) then
+ {
+ _index = (count (F_NT_CACHE_FADE select 0)) - 4;
+
+ for "_i" from 0 to _index do
+ {
+ (F_NT_CACHE_FADE select 0) deleteAt 0;
+ (F_NT_CACHE_FADE select 1) deleteAt 0;
+ (F_NT_CACHE_FADE select 2) deleteAt 0;
+ };
+ };
+
+ // Prevent the fade system from fading the same tag twice.
+ if (((F_NT_CACHE_CURSOR_DATA select 0) select 0) in (F_NT_CACHE_FADE select 0)) then
+ {
+ {
+ _index =
+ (F_NT_CACHE_FADE select 0) find ((F_NT_CACHE_CURSOR_DATA select 0) select _forEachIndex);
+
+ (F_NT_CACHE_FADE select 0) deleteAt _index;
+ (F_NT_CACHE_FADE select 1) deleteAt _index;
+ (F_NT_CACHE_FADE select 2) deleteAt _index;
+ } forEach (F_NT_CACHE_CURSOR_DATA select 0);
+ };
+
+ // Then chuck all that data from the thing into the array of things to fade.
+ (F_NT_CACHE_FADE select 0) append (F_NT_CACHE_CURSOR_DATA select 0);
+ (F_NT_CACHE_FADE select 1) append (F_NT_CACHE_CURSOR_DATA select 1);
+ { (F_NT_CACHE_FADE select 2) pushBack time } forEach (F_NT_CACHE_CURSOR_DATA select 0);
+};
+
+// For the next frame, set the cache of the cursor to the current cursor.
+F_NT_CACHE_CURSOR = _cursorObject;
diff --git a/f/nametag/include/f_nametagBrief.sqf b/f/nametag/include/f_nametagBrief.sqf
new file mode 100644
index 00000000..a502f002
--- /dev/null
+++ b/f/nametag/include/f_nametagBrief.sqf
@@ -0,0 +1,62 @@
+//====================================================================================
+//
+// f_nametagBrief.sqf - Gives non-CBA players options in briefing to config nametags.
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// Construct a briefing depending on present settings.
+//------------------------------------------------------------------------------------
+
+[] spawn
+{
+ waitUntil {scriptDone f_script_briefing};
+
+ _bstr = format ["F3 NAMETAGS
Toggle name tags for friendly units by pressing %1.
Name tags are displayed when aiming at individual units up to and above %4m away, and constantly for all units within %3m.
Note that using CBA will disable this menu and replace it with an enchanced one under ADDON OPTIONS.
+ ",F_NT_ACTIONKEY_KEYNAME, F_NT_ACTIONKEY_KEY,F_NT_DRAWDISTANCE_NEAR,F_NT_DRAWDISTANCE_CURSOR];
+
+ if !F_NT_MOD_CBA then
+ {
+ _bstr = _bstr + "
TOGGLE NEARBY TAGS
Constantly displays name tags for nearby units.";
+
+ if !(isNil "F_NT_FONT_HEIGHT_ONHEAD") then
+ {
+ _bstr = _bstr + "
TOGGLE TAG POSITION
Whether tags are rendered on chest or above head.";
+ };
+
+ if !(isNil "F_NT_SHOW_ROLE") then
+ {
+ _bstr = _bstr + "
TOGGLE ROLE DISPLAY
Displays the unit's role above their name.";
+ };
+
+ if !(isNil "F_NT_SHOW_GROUP") then
+ {
+ _bstr = _bstr + "
TOGGLE GROUP DISPLAY
Displays the group name below a unit's name.";
+ };
+
+ if !(isNil "F_NT_SHOW_VEHICLEINFO") then
+ {
+ _bstr = _bstr + "
TOGGLE VEHICLE TYPE DISPLAY
Displays the vehicle type with the commander's name. Requires role display.";
+ };
+
+ //_bstr = _bstr + "
COLORS
+ //Friendly
+ //Fireteam
+ //Vehicle Crew";
+
+
+ };
+
+ // Add brief to map screen.
+ player createDiaryRecord ["Diary", ["F3 Nametags (Options)",_bstr]];
+};
diff --git a/f/nametag/include/f_nametagCacheLoop.sqf b/f/nametag/include/f_nametagCacheLoop.sqf
new file mode 100644
index 00000000..2344ee0a
--- /dev/null
+++ b/f/nametag/include/f_nametagCacheLoop.sqf
@@ -0,0 +1,54 @@
+//====================================================================================
+//
+// f_nametagCacheLoop.sqf - Checks near entities and processes them for tag data.
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// Initial setup.
+//------------------------------------------------------------------------------------
+
+// Array that will hold all cache data.
+F_NT_CACHE = [];
+
+// Variable that will be used to keep track of Arma's day/night cycle.
+F_NT_VAR_NIGHT = 1;
+
+
+//------------------------------------------------------------------------------------
+// Loops every second as long as the scheduler complies.
+//------------------------------------------------------------------------------------
+
+// Check if CBA is present.
+if F_NT_MOD_CBA then
+{
+ F_NT_CACHE_LOOP =
+ [
+ {
+ if F_NT_NAMETAGS_ON then
+ { call f_fnc_nametagCache };
+ },
+ 0.5,
+ []
+ ] call CBA_fnc_addPerFrameHandler;
+}
+else
+{
+ F_NT_CACHE_LOOP = [] spawn
+ {
+ _delay = 0.5;
+ F_NT_CACHE_LOOP_RUN = true;
+
+ // While the above variable is true, run the loop.
+ while {F_NT_CACHE_LOOP_RUN} do
+ {
+ // ...Cache all nearby units and their data...
+ if F_NT_NAMETAGS_ON then
+ { call f_fnc_nametagCache };
+
+ // ...and then wait for the delay before doing it again.
+ sleep _delay;
+ };
+ };
+};
diff --git a/f/nametag/include/f_nametagCheckMods.sqf b/f/nametag/include/f_nametagCheckMods.sqf
new file mode 100644
index 00000000..a98f40cd
--- /dev/null
+++ b/f/nametag/include/f_nametagCheckMods.sqf
@@ -0,0 +1,14 @@
+//====================================================================================
+//
+// f_nametagInitMods.sqf - Checks for ACE, ACRE, and/or TFAR presence.
+//
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// Checking for mods.
+//------------------------------------------------------------------------------------
+
+// CBA
+F_NT_MOD_CBA = isClass(configFile >> "CfgPatches" >> "cba_settings");
\ No newline at end of file
diff --git a/f/nametag/include/f_nametagDisableKey.sqf b/f/nametag/include/f_nametagDisableKey.sqf
new file mode 100644
index 00000000..417fb62d
--- /dev/null
+++ b/f/nametag/include/f_nametagDisableKey.sqf
@@ -0,0 +1,48 @@
+//====================================================================================
+//
+// f_nametagDisableKey.sqf - Sets up a key that can be used to flip the nametag
+// system on and off with a press.
+//
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// Setup the Action Key, default '='.
+//------------------------------------------------------------------------------------
+
+// None of this will execute if the actionkey line in CONFIG is commented out.
+if (!isNil "F_NT_ACTIONKEY") then
+{
+ F_NT_ACTIONKEY_KEY = (actionKeys F_NT_ACTIONKEY) select 0;// This key, a global variable.
+ F_NT_ACTIONKEY_KEYNAME = actionKeysNames F_NT_ACTIONKEY; // Which is named this...
+
+ // Function that will determine when the disableKey is depressed.
+ F_NT_KEYDOWN =
+ {
+ _key = _this select 1;
+ _handled = false;
+ if(_key == F_NT_ACTIONKEY_KEY) then
+ {
+ F_NT_NAMETAGS_ON = !F_NT_NAMETAGS_ON;
+ _handled = true;
+ };
+ _handled;
+ };
+
+ // Function that will determine when the disableKey is released.
+ F_NT_KEYUP =
+ {
+ _key = _this select 1;
+ _handled = false;
+ if(_key == F_NT_ACTIONKEY_KEY) then
+ {
+ _handled = true;
+ };
+ _handled;
+ };
+
+ // Add eventhandlers (functions above).
+ (findDisplay 46) displayAddEventHandler ["keydown", "_this call F_NT_KEYDOWN"];
+ (findDisplay 46) displayAddEventHandler ["keyup", "_this call F_NT_KEYUP"];
+};
\ No newline at end of file
diff --git a/f/nametag/include/f_nametagInitTalking.sqf b/f/nametag/include/f_nametagInitTalking.sqf
new file mode 100644
index 00000000..53bd519d
--- /dev/null
+++ b/f/nametag/include/f_nametagInitTalking.sqf
@@ -0,0 +1,59 @@
+//====================================================================================
+//
+// f_nametagInitTalking.sqf - Places monitors on all players to check if they are
+// speaking.
+//
+// Adapted from code by Killzone Kid, and from ACE3 code.
+// - http://killzonekid.com/arma-scripting-tutorials-whos-talking/
+// - https://github.com/acemod/ACE3
+//
+// Code previously from CSE. Credit to commy2.
+//
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+//------------------------------------------------------------------------------------
+// CBA version, if CBA is present.
+//------------------------------------------------------------------------------------
+
+if F_NT_MOD_CBA then
+{
+ [{
+ // Change setting only if new isn't equal to old.
+ private _old = player getVariable ["wh_nt_isSpeaking", false];
+ private _new = (!(isNull findDisplay 55));
+
+ // Broadcast variable across server.
+ if (!(_oldSetting isEqualTo _newSetting)) then
+ { player setVariable ["wh_nt_isSpeaking", _newSetting, true] };
+ } , 0.25, []] call CBA_fnc_addPerFrameHandler;
+}
+
+//------------------------------------------------------------------------------------
+// Scheduled version, if CBA is not present.
+//------------------------------------------------------------------------------------
+
+else
+{
+ F_NT_TALKING_LOOP = [] spawn
+ {
+ _delay = 0.25;
+ F_NT_TALKING_LOOP_RUN = true;
+
+ // While the above variable is true, run the loop.
+ while {F_NT_TALKING_LOOP_RUN} do
+ {
+ // Change setting only if new isn't equal to old.
+ private _old = player getVariable ["wh_nt_isSpeaking", false];
+ private _new = (!(isNull findDisplay 55));
+
+ // Broadcast variable across server.
+ if (!(_oldSetting isEqualTo _newSetting)) then
+ { player setVariable ["wh_nt_isSpeaking", _newSetting, true] };
+
+ // ...and then wait for the delay before doing it again.
+ sleep _delay;
+ };
+ };
+};
\ No newline at end of file
diff --git a/f/nametag/include/f_nametagSettings.sqf b/f/nametag/include/f_nametagSettings.sqf
new file mode 100644
index 00000000..d5705cb4
--- /dev/null
+++ b/f/nametag/include/f_nametagSettings.sqf
@@ -0,0 +1,173 @@
+//====================================================================================
+//
+// f_nametagSettings.sqf - Contains optional CBA addon settings.
+// @ /u/Whalen207 | Whale #5963
+//
+//====================================================================================
+
+// Check if CBA is present.
+if F_NT_MOD_CBA then
+{
+ // Setting for disabling the entire system.
+ [
+ "F_NT_NAMETAGS_ON", // Internal setting name and value set.
+ "CHECKBOX", // Setting type.
+ "F3 Nametag System", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ true // Setting type-specific data.
+ ] call CBA_Settings_fnc_init;
+
+ // Setting for changing the typeface.
+ [
+ "F_NT_FONT_FACE", // Internal setting name and value set.
+ "LIST", // Setting type.
+ "Font Face", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ [
+ [F_NT_FONT_FACE,"Roboto","RobotoLight","Purista","PuristaLight","Etelka","Tahoma"],
+ ["Default","Roboto (Bold) *","Roboto (Light)","Purista (Bold)","Purista (Light)","Etelka Narrow","Tahoma (Bold)"],
+ 0
+ ], // Setting type-specific data.
+ nil,
+ { call f_fnc_nametagResetFont; }
+ // Executed at mission start and every change.
+ ] call CBA_Settings_fnc_init;
+
+ // Setting for changing typeface color.
+ [
+ "F_NT_FONT_COLOR", // Internal setting name and value set.
+ "LIST", // Setting type.
+ "Font Color", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ [
+ [F_NT_FONT_COLOR,"WHGreen","ACERust","TMTMTeal","COALCrimson","FAWhite","STSand","BromaPurple"],
+ ["Default","WH Green *","ACE Rust","TMTM Teal","COAL Crimson","FA White","ST Sand","BromA Purple"],
+ 0
+ ], // Setting type-specific data.
+ nil,
+ { call f_fnc_nametagResetFont; }
+ // Executed at mission start and every change.
+ ] call CBA_Settings_fnc_init;
+
+ // Setting to dynamically alter font size.
+ [
+ "F_NT_FONT_SIZE_MULTI", // Internal setting name and value set.
+ "SLIDER", // Setting type.
+ "Font Size", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ [0.75, 1.25, 1, 2], // Setting type-specific data.
+ nil, // Nil or 0 for changeable, 1 to reset to default, 2 to lock.
+ { call f_fnc_nametagResetFont; }
+ // Executed at mission start and every change.
+ ] call CBA_Settings_fnc_init;
+
+ // Setting to dynamically alter font spread.
+ [
+ "F_NT_FONT_SPREAD_MULTI", // Internal setting name and value set.
+ "SLIDER", // Setting type.
+ "Font Spread", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ [0.75, 1.25, 1, 2], // Setting type-specific data.
+ nil, // Nil or 0 for changeable, 1 to reset to default, 2 to lock.
+ { call f_fnc_nametagResetFont; }
+ // Executed at mission start and every change.
+ ] call CBA_Settings_fnc_init;
+
+ // Setting to flip drawcursoronly.
+ if (!F_NT_DRAWCURSORONLY) then
+ {
+ [
+ "F_NT_DRAWCURSORONLY", // Internal setting name and value set.
+ "CHECKBOX", // Setting type.
+ "Cursor Only (Saves FPS)", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ false // Setting type-specific data.
+ ] call CBA_Settings_fnc_init;
+ }
+ // Changes the default if the missionmaker changes it.
+ else
+ {
+ [
+ "F_NT_DRAWCURSORONLY", // Internal setting name and value set.
+ "CHECKBOX", // Setting type.
+ "Cursor Only (Saves FPS)", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ true // Setting type-specific data.
+ ] call CBA_Settings_fnc_init;
+ };
+
+ // Changes whether nametags draw the role and group when under cursor.
+ // Missionmaker can force these off in nametagCONFIG.
+ if (F_NT_SHOW_ROLE || {F_NT_SHOW_GROUP}) then
+ {
+ switch true do
+ {
+ case (F_NT_SHOW_ROLE && F_NT_SHOW_GROUP):
+ {
+ // Option to not show role and group tags.
+ [
+ "F_NT_SHOW_ROLEANDGROUP", // Internal setting name and value set.
+ "CHECKBOX", // Setting type.
+ "Show Role and Group", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ true, // Setting type-specific data.
+ nil, // Nil or 0 for changeable.
+ {
+ if F_NT_SHOW_ROLEANDGROUP
+ then { F_NT_SHOW_ROLE = true; F_NT_SHOW_GROUP = true; }
+ else { F_NT_SHOW_ROLE = false; F_NT_SHOW_GROUP = false; };
+ }
+ ] call CBA_Settings_fnc_init;
+ };
+ case (!F_NT_SHOW_ROLE&& F_NT_SHOW_GROUP):
+ {
+ // Option to not show group tags.
+ [
+ "F_NT_SHOW_GROUP", // Internal setting name and value set.
+ "CHECKBOX", // Setting type.
+ "Show Group Names", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ true, // Setting type-specific data.
+ nil, // Nil or 0 for changeable.
+ {}
+ ] call CBA_Settings_fnc_init;
+ };
+ case (F_NT_SHOW_ROLE &&!F_NT_SHOW_GROUP):
+ {
+ // Option to not show role tags.
+ [
+ "F_NT_SHOW_ROLE", // Internal setting name and value set.
+ "CHECKBOX", // Setting type.
+ "Show Unit Roles", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ true, // Setting type-specific data.
+ nil, // Nil or 0 for changeable.
+ {}
+ ] call CBA_Settings_fnc_init;
+ };
+ };
+ };
+
+ // Attaches nametags to player heads, like ACE.
+ // Missionmaker can change the default setting.
+ if !F_NT_FONT_HEIGHT_ONHEAD then
+ {
+ [
+ "F_NT_FONT_HEIGHT_ONHEAD", // Internal setting name and value set.
+ "CHECKBOX", // Setting type.
+ "Show Above Head", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ false // Setting type-specific data.
+ ] call CBA_Settings_fnc_init;
+ }
+ else
+ {
+ [
+ "F_NT_FONT_HEIGHT_ONHEAD", // Internal setting name and value set.
+ "CHECKBOX", // Setting type.
+ "Show Above Head", // Name shown in menu.
+ "F3 Nametags", // Category shown in menu.
+ true // Setting type-specific data.
+ ] call CBA_Settings_fnc_init;
+ };
+};
\ No newline at end of file
diff --git a/init.sqf b/init.sqf
index 1424702f..59f7309b 100644
--- a/init.sqf
+++ b/init.sqf
@@ -194,7 +194,7 @@ f_var_cachingAggressiveness = 2;
// F3 - Name Tags
// Credits: Please see the F3 online manual (http://www.ferstaberinde.com/f3/en/)
-// [] execVM "f\nametag\f_nametags.sqf";
+// [] execVM "f\nametag\f_nametagInit.sqf";
// ====================================================================================