CSE Nametags module

Initial version of the name tags module port from CSE to ACE structure.
This commit is contained in:
Thomas Kooi 2015-01-12 18:45:28 +01:00
parent b46f7a349e
commit 1a200e11b8
24 changed files with 452 additions and 0 deletions

View File

@ -0,0 +1,11 @@
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE( call compile preprocessFileLineNumbers PATHTOF(XEH_preInit.sqf) );
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE( call compile preprocessFileLineNumbers PATHTOF(XEH_postInit.sqf) );
};
};

View File

@ -0,0 +1,64 @@
// TODO Check what faction classes are available within ACE and move this to a core pbo
class CfgFactionClasses
{
class NO_CATEGORY;
class ACEMisc: NO_CATEGORY {
displayName = "ACE Misc Modules";
};
};
class CfgVehicles
{
class Logic;
class Module_F: Logic {
class ArgumentsBaseUnits {
};
};
class GVAR(Module): Module_F {
scope = 2;
displayName = $STR_ACE_NameTags_Title;
icon = QUOTE(PATHOF(data\module_icon.paa));
category = "ACEMisc";
function = QUOTE(FUNC(initalizeModule));
functionPriority = 1;
isGlobal = 1;
isTriggerActivated = 0;
class Arguments {
class enableModule {
displayName = $STR_ACE_NameTags_Arg_enable;
description = $STR_ACE_NameTags_Arg_enable_Desc;
typeName = "BOOL";
defaultValue = 0;
};
class indirectDistance {
displayName = $STR_ACE_NameTags_Arg_indirectDistance;
description = $STR_ACE_NameTags_Arg_indirectDistance_Desc;
typeName = "NUMBER";
defaultValue = 7.5;
};
class cursorTargetDistance {
displayName = $STR_ACE_NameTags_Arg_directDistance;
description = $STR_ACE_NameTags_Arg_directDistance_Desc;
typeName = "NUMBER";
defaultValue = 20;
};
class allowDifferentSides {
displayName = $STR_ACE_NameTags_Arg_differentSides;
description = $STR_ACE_NameTags_Arg_differentSides_Desc;
typeName = "BOOL";
defaultValue = 0;
};
class enableSoundWaves {
displayName = $STR_ACE_NameTags_Arg_soundWaves;
description = $STR_ACE_NameTags_Arg_soundWaves_Desc;
typeName = "BOOL";
defaultValue = 0;
};
};
class ModuleDescription {
description = $STR_ACE_NameTags_ModuleDesc;
sync[] = {};
};
};
};

View File

@ -0,0 +1,66 @@
/**
* XEH_postInit.sqf
* @Descr: N/A
* @Author: Glowbal
*
* @Arguments: []
* @Return:
* @PublicAPI: false
*/
if (!hasInterface) exitwith {}; // No need for this module on HC or dedicated server.
#include "script_component.hpp"
// Settings
if (isNil QUOTE(ACE_NameTagsModule)) then {
GVAR(INDIRECT_TAGS_DISTANCE) = 7.5;
GVAR(DIRECT_TAG_DISTANCE) = 20;
GVAR(ENABLE_SOUNDWAVES) = false;
GVAR(ALLOW_OWN_SIDE_ONLY) = true;
GVAR(ENABLE_MODULE) = true;
};
// In case the module has been placed and the enable setting has been put to false
if (!GVAR(ENABLE_MODULE)) exitwith {};
// Client side options
// TODO Implement a framework for adjusting client side settings.
GVAR(DRAW_TAG_ICONS) = true;
GVAR(ENABLE_INDIRECT) = false;
GVAR(TAG_DISPLAY_COLOR) = [1,1,1,1];
GVAR(SHOW_SOUNDWAVES) = false;
GVAR(DISPLAY_RANK) = false;
// If the distance values are set incorrectly, ensure we handle this
if (GVAR(DIRECT_TAG_DISTANCE) < GVAR(INDIRECT_TAGS_DISTANCE)) then {
GVAR(DIRECT_TAG_DISTANCE) = GVAR(INDIRECT_TAGS_DISTANCE);
};
// If both are below 1m, exit because they will not show up.
if (GVAR(DIRECT_TAG_DISTANCE) < 1) exitwith {};
// Draw the icons for each nametag
// TODO Look into replacement with cutRsc instead of icon3d
addMissionEventHandler ["Draw3D", FUNC(drawNameTags)];
if (GVAR(ENABLE_SOUNDWAVES)) then {
GVAR(SOUNDWAVE_ICONS) = [QUOTE(PATHTOF(data\soundwaves\soundwave1.paa)),QUOTE(PATHTOF(data\soundwaves\soundwave2.paa)), QUOTE(PATHTOF(data\soundwaves\soundwave3.paa)), QUOTE(PATHTOF(data\soundwaves\soundwave4.paa)), QUOTE(PATHTOF(data\soundwaves\soundwave5.paa)), QUOTE(PATHTOF(data\soundwaves\soundwave6.paa)), QUOTE(PATHTOF(data\soundwaves\soundwave7.paa)), QUOTE(PATHTOF(data\soundwaves\soundwave8.paa)), QUOTE(PATHTOF(data\soundwaves\soundwave9.paa)), QUOTE(PATHTOF(data\soundwaves\soundwave_silent.paa))];
// TODO Implement function for checking if an addon is loaded
//if (["task_force_radio"] call ace_fnc_isModLoaded_F) then {
if (isnil "TFAR_fnc_isSpeaking") then {
TFAR_fnc_isSpeaking = { if (!isnil "TF_tangent_lr_pressed") then {(TF_tangent_lr_pressed || TF_tangent_sw_pressed || TF_tangent_dd_pressed)} else { false }; };
};
//};
// TODO Move to unscheduled environment with PFH
[] spawn {
waituntil{
waituntil {alive player};
/*ACE_player*/ player call FUNC(handleSpeaking);
!GVAR(ENABLE_SOUNDWAVES); // exit when the soundwaves have been disabled
};
};
};

View File

@ -0,0 +1,17 @@
/**
* XEH_preInit.sqf
* @Descr: N/A
* @Author: Glowbal
*
* @Arguments: []
* @Return:
* @PublicAPI: false
*/
#include "script_component.hpp"
PREP(drawNameTags);
PREP(findNearbyUnits);
PREP(handleSpeaking);
PREP(allowSide);
PREP(initalizeModule);

View File

@ -0,0 +1,24 @@
#include "script_component.hpp"
class CfgPatches {
class ADDON {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ACE_gui","ACE_main"};
version = VERSION;
author[] = {$STR_ACE_Core_ACETeam};
authorUrl = "http://ACEmod.com"; // TODO website link?
};
};
class CfgAddons {
class PreloadAddons {
class ADDON {
list[] = {QUOTE(ADDON)};
};
};
};
#include "CfgVehicles.hpp"
#include "CfgEventHandlers.hpp"

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.

Binary file not shown.

View File

@ -0,0 +1,15 @@
/**
* fn_allowSide_TAGS.sqf
* @Descr: N/A
* @Author: Glowbal
*
* @Arguments: side
* @Return:
* @PublicAPI: false
*/
#include "script_component.hpp"
if (GVAR(ALLOW_OWN_SIDE_ONLY)) exitwith {
_this == playerSide; /* side ACE_player */
};
((_this getFriend playerSide /* side ACE_player */ ) >= 0.6);

View File

@ -0,0 +1,71 @@
/**
* fn_drawNameTags_TAGS.sqf
* @Descr: N/A
* @Author: Glowbal
*
* @Arguments: []
* @Return:
* @PublicAPI: false
*/
#include "script_component.hpp"
#define FONT "EtelkaMonospacePro"
private ["_cursor","_soundWaves", "_nameOfUnit","_pos","_color", "_nearbyUnits", "_iconOptions", "_iconSets", "_unit", "_colorOfIcon", "_nearObj"];
if (visibleMap || !GVAR(DRAW_TAG_ICONS)) exitwith {};
_nearObj = if (isNull curatorCamera) then {/* ACE_player */ if (isNull (missionnamespace getvariable ["bis_fnc_moduleRemoteControl_unit",objnull])) then { player} else {(missionnamespace getvariable ["bis_fnc_moduleRemoteControl_unit",objnull]) }; } else { curatorCamera };
if (GVAR(ENABLE_INDIRECT)) then {
{
_nameOfUnit = _x select 0;
_pos = _x select 1;
_color = _x select 2;
_unit = _x select 3;
_iconDrawn = QUOTE(PATHTOF(data\empty.paa));
if (_unit getvariable [QGVAR(isSpeaking),false] && GVAR(SHOW_SOUNDWAVES)) then {
_iconDrawn = (GVAR(SOUNDWAVE_ICONS) select ((round(random (count GVAR(SOUNDWAVE_ICONS) - 1)))));
};
drawIcon3D [_iconDrawn,_color, _pos, 2, 2, 1 ,toUpper _nameOfUnit, 1, 0.03, FONT];
false;
}count (_nearObj call FUNC(findNearbyUnits));
};
_cursor = cursortarget;
if (_cursor == _cursor && isTouchingGround _cursor) then {
if (_cursor isKindOf "CAManBase" && ((_cursor distance _nearObj) < GVAR(DIRECT_TAG_DISTANCE)) && ((side _cursor) call FUNC(allowSide))) then {
// TODO Improve this switch statement
_pos = visiblePositionASL _cursor;
switch (stance _cursor) do {
case "STAND": {
_pos set [2, ((_cursor modelToWorld [0,0,0]) select 2)+2];
};
case "CROUCH": {
_pos set [2, ((_cursor modelToWorld [0,0,0]) select 2)+1.5];
};
case "PRONE": {
_pos set [2, ((_cursor modelToWorld [0,0,0]) select 2)+0.5];
};
default {
_pos set [2, ((_cursor modelToWorld [0,0,0]) select 2) + 1.5];
};
};
_color = +GVAR(TAG_DISPLAY_COLOR);
_nameOfUnit = name _cursor; //[_cursor] call FUNC(getName); // TODO Implement a getName function
// TODO implement module checking
/*if (ACE_NameTags_SYS_MEDICAL_SYSTEM_ENABLED_TAGS) then {
_status = [_cursor] call FUNC(getTriageStatus_CMS);
if ((_status select 1) >0) then {
_nameOfUnit = _nameOfUnit + " ["+ (_status select 0) + "]";
_color = _status select 2;
};
};*/
_iconDrawn = QUOTE(PATHTOF(data\empty.paa));
if (_unit getvariable [QGVAR(isSpeaking),false] && GVAR(SHOW_SOUNDWAVES)) then {
_iconDrawn = (GVAR(SOUNDWAVE_ICONS) select ((round(random (count GVAR(SOUNDWAVE_ICONS) - 1)))));
};
drawIcon3D [_iconDrawn,_color, _pos, 2, 2, 1 ,toUpper _nameOfUnit, 1, 0.03, FONT];
};
};

View File

@ -0,0 +1,65 @@
/**
* fn_findNearbyUnits_TAGS.sqf
* @Descr: N/A
* @Author: Glowbal
*
* @Arguments: []
* @Return:
* @PublicAPI: false
*/
#include "script_component.hpp"
private ["_info", "_nameOfUnit", "_color", "_isTalking", "_pos", "_nearest"];
_info = [];
if (alive player) then {
_nearest = (_this nearEntities [["CAManBase"], GVAR(INDIRECT_TAGS_DISTANCE)]);
{
if (_x != _this && (vehicle _x == _x) && isTouchingGround _X) then {
if (lineIntersects [eyePos _this, eyePos _x, _x, _this]) exitwith{};
if ((side _x) call FUNC(allowSide) && !(_x == cursortarget)) then {
_nameOfUnit = name _x;
if (_x getvariable ["ACE_isDead",false]) then { // TODO, how do we check for dead units?
_nameOfUnit = _unit getvariable ["ACE_name","Unknown"]; // TODO is there are function to get the name of a unit?
};
_pos = visiblePositionASL _x;
// TODO This can be done better
switch (stance _x) do {
case "STAND": {
_pos set [2, ((_x modelToWorld [0,0,0]) select 2)+2];
};
case "CROUCH": {
_pos set [2, ((_x modelToWorld [0,0,0]) select 2)+1.5];
};
case "PRONE": {
_pos set [2, ((_x modelToWorld [0,0,0]) select 2) + 0.5];
};
default {
_pos set [2, ((_x modelToWorld [0,0,0]) select 2) + 1.5];
};
};
_color = +GVAR(TAG_DISPLAY_COLOR);
_color set [3, 0];
_isTalking = (_x getvariable [QGVAR(isSpeaking),false]);
// TODO implement module checking
/*if (ACE_NameTags_SYS_MEDICAL_SYSTEM_ENABLED_TAGS) then {
_status = [_x] call FUNC(getTriageStatus_CMS;
if ((_status select 1) >0) then {
_nameOfUnit = _nameOfUnit + " ["+ (_status select 0) + "]";
_color = _status select 2;
};
};*/
if (GVAR(DISPLAY_RANK)) then {
_nameOfUnit = (rank _x) + " " + _nameOfUnit;
};
_color set [3,(1-((_x distance _this) / GVAR(INDIRECT_TAGS_DISTANCE))) + 0.05];
_info pushback [_nameOfUnit, _pos, _color, _x];
};
};
}foreach _nearest;
};
_info;

View File

@ -0,0 +1,40 @@
/**
* fn_handleSpeaking_TAGS.sqf
* @Descr: N/A
* @Author: Glowbal
*
* @Arguments: []
* @Return:
* @PublicAPI: false
*/
#include "script_component.hpp"
// TODO Implement a check mod loaded function
#define ACTION_PUSH_TO_TALK_PRESSED (inputAction "PushToTalk" > 0)
#define ACTION_TFAR_RADIO_ACTIVE false // [] call {if (["task_force_radio"] call FUNC(isModLoaded_F)) then {player call TFAR_fnc_isSpeaking} else { false };}
#define ACTION_ACRE_RADIO_ACTIVE false // [] call {if (["acre_api"] call FUNC(isModLoaded_F)) then {[player] call ACRE_api_fnc_isBroadcasting} else { false };}
private ["_unit"];
_unit = _this select 0;
if (_unit != player /* _unit != ACE_Player */) exitwith {};
// TODO check mod loaded function
/*if (["task_force_radio"] call FUNC(isModLoaded_F)) then {
waituntil {!isnil "TF_tangent_lr_pressed"};
};*/
waituntil {
if (ACTION_TFAR_RADIO_ACTIVE || ACTION_PUSH_TO_TALK_PRESSED || ACTION_ACRE_RADIO_ACTIVE) then {
if !(_unit getvariable [QGVAR(isSpeaking), false]) then {
_unit setvariable [QGVAR(isSpeaking), true, true];
};
} else {
if (_unit getvariable [QGVAR(isSpeaking), false]) then {
_unit setvariable [QGVAR(isSpeaking), false, true];
};
};
!(alive _unit) /* _unit != ACE_Player */
};
_unit setvariable [QGVAR(isSpeaking),nil,true];

View File

@ -0,0 +1,24 @@
/**
* fnc_initalizeModule.sqf
* @Descr: N/A
* @Author: Glowbal
*
* @Arguments: []
* @Return:
* @PublicAPI: false
*/
#include "script_component.hpp"
if (!hasInterface) exitwith {}; // No need for this module on HC or dedicated server.
private ["_logic"];
_logic = [_this,0,objNull,[objNull]] call BIS_fnc_param;
if (!isNull _logic) then {
// TODO default values should be defined somewhere through an include, so they are the same in CfgVehicles and here.
GVAR(ENABLE_MODULE) = _logic getvariable ["enableModule", false];
GVAR(INDIRECT_TAGS_DISTANCE) = _logic getvariable ["indirectDistance", 7.5];
GVAR(DIRECT_TAG_DISTANCE) = _logic getvariable ["cursorTargetDistance", 20];
GVAR(ALLOW_OWN_SIDE_ONLY) = !(_logic getvariable ["allowDifferentSides", false]);
GVAR(ENABLE_SOUNDWAVES) = _logic getvariable ["enableSoundWaves", false];
};

View File

@ -0,0 +1,12 @@
#define COMPONENT nametags
#include "\z\ace\addons\main\script_mod.hpp"
#ifdef DEBUG_ENABLED_NAMETAGS
#define DEBUG_MODE_FULL
#endif
#ifdef DEBUG_SETTINGS_NAMETAGS
#define DEBUG_SETTINGS DEBUG_SETTINGS_NAMETAGS
#endif
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project name="ACE3">
<Package name="nametags">
<Container ID="Module">
<Key ID="STR_ACE_NameTags_Title">
<Original>Name Tags [ACE]</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_enable">
<Original>Enable Name Tags</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_enable_Desc">
<Original>Enable the name tags</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_indirectDistance">
<Original>Indirect Distance</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_indirectDistance_Desc">
<Original>Distance for indirect Tags</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_directDistance">
<Original>Target Distance</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_directDistance_Desc">
<Original>Distance for the direct Tag (Cursortarget)</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_soundWaves">
<Original>Enable Soundwaves</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_soundWaves_Desc">
<Original>Enable Soundwaves when a player is speaking</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_differentSides">
<Original>Allow Different sides</Original>
</Key>
<Key ID="STR_ACE_NameTags_Arg_differentSides_Desc">
<Original>Allow name tags for all friendly sides, instead of only player side</Original>
</Key>
<Key ID="STR_ACE_NameTags_ModuleDesc">
<Original>Adjust the name tags settings.</Original>
</Key>
</Container>
</Package>
</Project>