Merge pull request #4146 from acemod/taggingFramework

Tagging Framework and Improvements
This commit is contained in:
jonpas 2016-08-08 23:04:28 +02:00 committed by GitHub
commit c6f3627c70
20 changed files with 463 additions and 103 deletions

View File

@ -0,0 +1,11 @@
class ACE_Settings {
class GVAR(quickTag) {
category = CSTRING(Tagging);
displayName = CSTRING(QuickTag);
description = CSTRING(QuickTagDesc);
typeName = "SCALAR";
value = 1;
values[] = {ECSTRING(Common,Disabled), CSTRING(LastUsed), CSTRING(RandomX), CSTRING(Random)};
isClientSettable = 1;
};
};

View File

@ -0,0 +1,26 @@
class ACE_Tags {
class ACE_XBlack {
displayName = CSTRING(XBlack);
requiredItem = "ACE_SpraypaintBlack";
textures[] = {QPATHTOF(UI\tags\black\0.paa), QPATHTOF(UI\tags\black\1.paa), QPATHTOF(UI\tags\black\2.paa)};
icon = QPATHTOF(UI\icons\iconTaggingBlack.paa);
};
class ACE_XRed {
displayName = CSTRING(XRed);
requiredItem = "ACE_SpraypaintRed";
textures[] = {QPATHTOF(UI\tags\red\0.paa), QPATHTOF(UI\tags\red\1.paa), QPATHTOF(UI\tags\red\2.paa)};
icon = QPATHTOF(UI\icons\iconTaggingRed.paa);
};
class ACE_XGreen {
displayName = CSTRING(XGreen);
requiredItem = "ACE_SpraypaintGreen";
textures[] = {QPATHTOF(UI\tags\green\0.paa), QPATHTOF(UI\tags\green\1.paa), QPATHTOF(UI\tags\green\2.paa)};
icon = QPATHTOF(UI\icons\iconTaggingGreen.paa);
};
class ACE_XBlue {
displayName = CSTRING(XBlue);
requiredItem = "ACE_SpraypaintBlue";
textures[] = {QPATHTOF(UI\tags\blue\0.paa), QPATHTOF(UI\tags\blue\1.paa), QPATHTOF(UI\tags\blue\2.paa)};
icon = QPATHTOF(UI\icons\iconTaggingBlue.paa);
};
};

View File

@ -1,38 +1,59 @@
class CfgVehicles {
class Man;
class CAManBase: Man {
class ACE_SelfActions {
class ACE_Equipment {
class ACE_TagBlack {
displayName = CSTRING(TagBlack);
condition = QUOTE(('ACE_SpraypaintBlack' in items ACE_player) && {[] call FUNC(checkTaggable)});
statement = QUOTE([ARR_2(ACE_player,'black' call FUNC(getTexture))] call FUNC(tag));
showDisabled = 0;
priority = 3;
icon = QPATHTOF(UI\icons\iconTaggingBlack.paa);
};
class ACE_TagRed: ACE_TagBlack {
displayName = CSTRING(TagRed);
condition = QUOTE(('ACE_SpraypaintRed' in items ACE_player) && {[] call FUNC(checkTaggable)});
statement = QUOTE([ARR_2(ACE_player,'red' call FUNC(getTexture))] call FUNC(tag));
icon = QPATHTOF(UI\icons\iconTaggingRed.paa);
};
class ACE_TagGreen: ACE_TagBlack {
displayName = CSTRING(TagGreen);
condition = QUOTE(('ACE_SpraypaintGreen' in items ACE_player) && {[] call FUNC(checkTaggable)});
statement = QUOTE([ARR_2(ACE_player,'green' call FUNC(getTexture))] call FUNC(tag));
icon = QPATHTOF(UI\icons\iconTaggingGreen.paa);
};
class ACE_TagBlue: ACE_TagBlack {
displayName = CSTRING(TagBlue);
condition = QUOTE(('ACE_SpraypaintBlue' in items ACE_player) && {[] call FUNC(checkTaggable)});
statement = QUOTE([ARR_2(ACE_player,'blue' call FUNC(getTexture))] call FUNC(tag));
icon = QPATHTOF(UI\icons\iconTaggingBlue.paa);
class ACE_Module;
class ACE_ModuleTagging: ACE_Module {
author = ECSTRING(common,ACETeam);
category = "ACE";
displayName = CSTRING(Tagging);
function = QFUNC(moduleInit);
scope = 2;
isGlobal = 1;
icon = QPATHTOF(UI\Icon_Module_Tagging_ca.paa);
class Arguments {
class quickTag {
displayName = CSTRING(QuickTag);
description = CSTRING(QuickTagDesc);
typeName = "NUMBER";
class values {
class disabled {
name = ECSTRING(Common,Disabled);
value = 0;
};
class lastUsed {
name = CSTRING(LastUsed);
value = 1;
default = 1;
};
class randomX {
name = CSTRING(RandomX);
value = 2;
};
class random {
name = CSTRING(Random);
value = 3;
};
};
};
};
class ModuleDescription {
description = CSTRING(ModuleDescription);
};
};
class Man;
class CAManBase: Man {
class ACE_SelfActions {
class ACE_Tags {
displayName = CSTRING(Tag);
condition = QUOTE(_player call FUNC(checkTaggable));
statement = QUOTE(_player call FUNC(quickTag));
icon = QPATHTOF(UI\icons\iconTaggingBlack.paa);
insertChildren = QUOTE(_player call FUNC(addTagActions));
};
};
};
class Item_Base_F;
class ACE_Item_SpraypaintBlack: Item_Base_F {
author = "jokoho48";

Binary file not shown.

View File

@ -1,5 +1,10 @@
PREP(addCustomTag);
PREP(addTagActions);
PREP(applyCustomTag);
PREP(checkTaggable);
PREP(compileConfigTags);
PREP(createTag);
PREP(getTexture);
PREP(moduleInit);
PREP(quickTag);
PREP(tag);
PREP(tagTestingThread);

View File

@ -39,6 +39,24 @@ for "_index" from 0 to (_countOptions - 1) do {
};
};
if (hasInterface) then {
// Compile and cache config tags
call FUNC(compileConfigTags);
// Scripted tag adding EH
[QGVAR(applyCustomTag), FUNC(applyCustomTag)] call CBA_fnc_addEventHandler;
// Keybind
["ACE3 Equipment", QGVAR(quickTag), localize LSTRING(QuickTag), {
// Conditions
if !(ACE_player call FUNC(checkTaggable)) exitWith {false};
// Statement
ACE_player call FUNC(quickTag);
true
}, {false}, [0, [false, false, false]], false] call CBA_fnc_addKeybind; // Unbound
};
if (!isServer) exitWith {};
GVAR(testingThread) = false;

View File

@ -4,4 +4,7 @@ ADDON = false;
#include "XEH_PREP.hpp"
GVAR(cachedTags) = [];
GVAR(cachedRequiredItems) = [];
ADDON = true;

View File

@ -8,12 +8,14 @@ class CfgPatches {
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_interaction"};
author = ECSTRING(common,ACETeam);
authors[] = {"BaerMitUmlaut","esteldunedain"};
authors[] = {"BaerMitUmlaut", "esteldunedain", "Jonpas"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};
#include "ACE_Settings.hpp"
#include "ACE_Tags.hpp"
#include "CfgEventHandlers.hpp"
#include "CfgVehicles.hpp"
#include "CfgWeapons.hpp"

View File

@ -0,0 +1,54 @@
/*
* Author: Jonpas
* Adds custom tag. Has to be executed on one machine only.
*
* Arguments:
* 0: Unique Identifier <STRING>
* 1: Display Name <STRING>
* 2: Required Item <STRING>
* 3: Textures Paths <ARRAY>
* 4: Icon Path <STRING> (default: "")
*
* Return Value:
* Sucessfully Added Tag <BOOL>
*
* Example:
* ["ace_victoryRed", "Victory Red", "ACE_SpraypaintRed", ["path\to\texture1.paa", "path\to\texture2.paa"], "path\to\icon.paa"] call ace_tagging_fnc_addCustomTag
*
* Public: Yes
*/
#include "script_component.hpp"
params [
["_identifier", "", [""]],
["_displayName", "", [""]],
["_requiredItem", "", [""]],
["_textures", [], [[]]],
["_icon", "", [""]]
];
// Verify
if (_identifier == "") exitWith {
ACE_LOGERROR("Failed adding custom tag - missing identifier");
};
if (_displayName == "") exitWith {
ACE_LOGERROR_1("Failed adding custom tag: %1 - missing displayName",_identifier);
};
if (_requiredItem == "") exitWith {
ACE_LOGERROR_1("Failed adding custom tag: %1 - missing requiredItem",_identifier);
};
if (!isClass (configFile >> "CfgWeapons" >> _requiredItem)) exitWith {
ACE_LOGERROR_2("Failed adding custom tag: %1 - requiredItem %2 does not exist",_identifier,_requiredItem);
};
if (_textures isEqualTo []) exitWith {
ACE_LOGERROR_1("Failed adding custom tag: %1 - missing textures",_identifier);
};
_identifier = [_identifier] call EFUNC(common,stringRemoveWhiteSpace);
_requiredItem = toLower _requiredItem;
// Add
[QGVAR(applyCustomTag), [_identifier, _displayName, _requiredItem, _textures, _icon]] call CBA_fnc_globalEventJIP;

View File

@ -0,0 +1,46 @@
/*
* Author: Jonpas
* Compiles tags from ACE_Tags and returns children actions.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [unit] call ace_tagging_fnc_addTagActions
*
* Public: No
*/
#include "script_component.hpp"
params ["_unit"];
private _actions = [];
{
_x params ["_class", "_displayName", "_requiredItem", "_textures", "_icon"];
_actions pushBack [
[
format ["ACE_ConfigTag_%1", _class],
_displayName,
_icon,
{
(_this select 2) params ["_unit", "_class", "_textures"];
[_unit, selectRandom _textures] call FUNC(tag);
_unit setVariable [QGVAR(lastUsedTag), _class];
},
{
(_this select 2) params ["_unit", "", "", "_requiredItem"];
_requiredItem in ((items _unit) apply {toLower _x})
},
{},
[_unit, _class, _textures, _requiredItem]
] call EFUNC(interact_menu,createAction),
[],
_unit
];
} forEach GVAR(cachedTags);
_actions

View File

@ -0,0 +1,33 @@
/*
* Author: Jonpas
* Applies custom tag to the cache.
*
* Arguments:
* 0: Unique Identifier <STRING>
* 1: Display Name <STRING>
* 2: Required Item <STRING>
* 3: Textures Paths <ARRAY>
* 4: Icon Path <STRING> (default: "")
*
* Return Value:
* None
*
* Example:
* ["ace_victoryRed", "Victory Red", "ACE_SpraypaintRed", ["path\to\texture1.paa", "path\to\texture2.paa"], "path\to\icon.paa"] call ace_tagging_fnc_addCustomTagLocal
*
* Public: No
*/
#include "script_component.hpp"
params ["_identifier", "_displayName", "_requiredItem"];
// Add only if tag not already added (compare identifiers)
if (GVAR(cachedTags) select {_x select 0 == _identifier} isEqualTo []) then {
GVAR(cachedTags) pushBack _this;
if !(_requiredItem in GVAR(cachedRequiredItems)) then {
GVAR(cachedRequiredItems) pushBack _requiredItem;
};
TRACE_1("Added custom script tag",_this);
} else {
ACE_LOGINFO_2("Tag with selected identifier already exists: %1 (%2)",_identifier,_displayName)
};

View File

@ -3,26 +3,33 @@
* Checks if there is a taggable surface within 2.5m in front of the player.
*
* Arguments:
* None
* 0: Unit <OBJECT>
*
* Return Value:
* Is wall taggable <BOOL>
* Is surface taggable <BOOL>
*
* Example:
* [] call ace_tagging_fnc_checkTaggable
* [unit] call ace_tagging_fnc_checkTaggable
*
* Public: No
*/
#include "script_component.hpp"
[[], {
private _startPosASL = eyePos ACE_player;
params ["_unit"];
[[_unit], {
params ["_unit"];
// Exit if no required item in inventory
if ((GVAR(cachedRequiredItems) arrayIntersect ((items _unit) apply {toLower _x})) isEqualTo []) exitWith {false};
private _startPosASL = eyePos _unit;
private _cameraPosASL = AGLToASL positionCameraToWorld [0, 0, 0];
private _cameraDir = (AGLToASL positionCameraToWorld [0, 0, 1]) vectorDiff _cameraPosASL;
private _endPosASL = _startPosASL vectorAdd (_cameraDir vectorMultiply 2.5);
private _intersections = lineIntersectsSurfaces [_startPosASL, _endPosASL, ACE_player, objNull, true, 1, "FIRE", "GEOM"];
private _intersections = lineIntersectsSurfaces [_startPosASL, _endPosASL, _unit, objNull, true, 1, "FIRE", "GEOM"];
// If there's no intersections
if (_intersections isEqualTo []) exitWith {false};

View File

@ -0,0 +1,53 @@
/*
* Author: Jonpas
* Compiles and caches tags from ACE_Tags config.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call ace_tagging_fnc_compileConfigTags
*
* Public: No
*/
#include "script_component.hpp"
{
private _failure = false;
private _class = configName _x;
private _displayName = getText (_x >> "displayName");
if (_displayName == "") then {
ACE_LOGERROR_1("Failed compiling ACE_Tags for tag: %1 - missing displayName",_class);
_failure = true;
};
private _requiredItem = toLower (getText (_x >> "requiredItem"));
if (_requiredItem == "") then {
ACE_LOGERROR_1("Failed compiling ACE_Tags for tag: %1 - missing requiredItem",_class);
_failure = true;
} else {
if (!isClass (configFile >> "CfgWeapons" >> _requiredItem)) then {
ACE_LOGERROR_2("Failed compiling ACE_Tags for tag: %1 - requiredItem %2 does not exist",_class,_requiredItem);
_failure = true;
};
};
private _textures = getArray (_x >> "textures");
if (_textures isEqualTo []) then {
ACE_LOGERROR_1("Failed compiling ACE_Tags for tag: %1 - missing textures",_class);
_failure = true;
};
private _icon = getText (_x >> "icon");
if (!_failure) then {
GVAR(cachedTags) pushBack [_class, _displayName, _requiredItem, _textures, _icon];
if !(_requiredItem in GVAR(cachedRequiredItems)) then {
GVAR(cachedRequiredItems) pushBack _requiredItem;
};
};
} forEach ("true" configClasses (configFile >> "ACE_Tags"));

View File

@ -1,26 +0,0 @@
/*
* Author: BaerMitUmlaut, esteldunedain, Jonpas
* Puts together a full path to the given tag color texture. Internal ACE3 textures only.
*
* Arguments:
* 0: The colour of the tag (valid colours are black, red, green and blue) <STRING>
*
* Return Value:
* Texture (full path), "" if not found <STRING>
*
* Example:
* texture = ["blue"] call ace_tagging_fnc_getTexture
*
* Public: No
*/
#include "script_component.hpp"
params ["_color"];
if !((toLower _color) in ["black", "red", "green", "blue"]) exitWith {
ACE_LOGERROR_1("%1 is not a valid tag colour.",_color);
""
};
QUOTE(PATHTOF(UI)) + "\tags\" + _color + "\" + str (floor (random 3)) + ".paa"

View File

@ -0,0 +1,25 @@
/*
* Author: Jonpas
* Initializes the Tagging module.
*
* Arguments:
* 0: The module logic <LOGIC>
* 1: Units <ARRAY>
* 2: Activated <BOOL>
*
* Return Value:
* None
*
* Public: No
*/
#include "script_component.hpp"
if (!isServer) exitWith {};
params ["_logic", "", "_activated"];
if (!_activated) exitWith {};
[_logic, QGVAR(quickTag), "quickTag"] call EFUNC(common,readSettingFromModule);
ACE_LOGINFO("Tagging Module Initialized.");

View File

@ -0,0 +1,51 @@
/*
* Author: Jonpas
* Selects random tag and applies it.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player] call ace_tagging_fnc_quickTag
*
* Public: No
*/
#include "script_component.hpp"
// Exit if Quick Tag disabled
if (GVAR(quickTag) == 0) exitWith {};
params ["_unit"];
private _possibleTags = [];
// Last Used
if (GVAR(quickTag) == 1) then {
private _lastUsedTagClass = _unit getVariable [QGVAR(lastUsedTag), nil];
if (!isNil "_lastUsedTagClass") then {
private _lastUsedTag = GVAR(cachedTags) select {(_x select 0) == _lastUsedTagClass};
_possibleTags = _lastUsedTag;
};
};
// Random X
if (GVAR(quickTag == 2)) then {
private _xTags = GVAR(cachedTags) select {(_x select 0) in ["ACE_XBlack", "ACE_XRed", "ACE_XGreen", "ACE_XBlue"]};
_possibleTags = _xTags;
};
// Random
if (GVAR(quickTag) == 3) then {
_possibleTags = GVAR(cachedTags);
};
// Tag
if !(_possibleTags isEqualTo []) then {
private _availableTags = _possibleTags select {(_x select 2) in ((items _unit) apply {toLower _x})};
[_unit, selectRandom ((selectRandom _availableTags) select 3)] call FUNC(tag);
};

View File

@ -7,12 +7,12 @@
// #define CBA_DEBUG_SYNCHRONOUS
// #define ENABLE_PERFORMANCE_COUNTERS
#ifdef DEBUG_ENABLED_BLANK
#ifdef DEBUG_ENABLED_TAGGING
#define DEBUG_MODE_FULL
#endif
#ifdef DEBUG_SETTINGS_BLANK
#define DEBUG_SETTINGS DEBUG_SETTINGS_BLANK
#ifdef DEBUG_SETTINGS_TAGGING
#define DEBUG_SETTINGS DEBUG_SETTINGS_TAGGING
#endif
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -1,45 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="ACE">
<Package name="Tagging">
<Key ID="STR_ACE_Tagging_TagBlack">
<English>Tag black</English>
<German>Schwarz markieren</German>
<Spanish>Marcar en negro</Spanish>
<Polish>Oznakuj na czarno</Polish>
<French>Tag noir</French>
<Italian>Marca nero</Italian>
<Czech>Označit černě</Czech>
<Portuguese>Marcar em preto</Portuguese>
<Key ID="STR_ACE_Tagging_Tagging">
<English>Tagging</English>
</Key>
<Key ID="STR_ACE_Tagging_TagRed">
<English>Tag red</English>
<German>Rot markieren</German>
<Spanish>Marcar en rojo</Spanish>
<Polish>Oznakuj na czerwono</Polish>
<French>Tag rouge</French>
<Italian>Marca rosso</Italian>
<Czech>Označit červeně</Czech>
<Portuguese>Marcar em vermelho</Portuguese>
<Key ID="STR_ACE_Tagging_ModuleDesc">
<English>Configure how the tagging system will operate by default.</English>
</Key>
<Key ID="STR_ACE_Tagging_TagGreen">
<English>Tag green</English>
<German>Grün markieren</German>
<Spanish>Marcar en verde</Spanish>
<Polish>Oznakuj na zielono</Polish>
<French>Tag vert</French>
<Italian>Marca verde</Italian>
<Czech>Označit zeleně</Czech>
<Portuguese>Marcar em verde</Portuguese>
<Key ID="STR_ACE_Tagging_QuickTag">
<English>Quick Tag</English>
</Key>
<Key ID="STR_ACE_Tagging_TagBlue">
<English>Tag blue</English>
<German>Blau markieren</German>
<Spanish>Marcar en azul</Spanish>
<Polish>Oznakuj na niebiesko</Polish>
<French>Tag bleu</French>
<Italian>Marca blu</Italian>
<Czech>Označit modře</Czech>
<Portuguese>Marcar em azul</Portuguese>
<Key ID="STR_ACE_Tagging_QuickTagDesc">
<English>Action performed on main tag interaction point.</English>
</Key>
<Key ID="STR_ACE_Tagging_LastUsed">
<English>Last Used</English>
</Key>
<Key ID="STR_ACE_Tagging_RandomX">
<English>Random X</English>
</Key>
<Key ID="STR_ACE_Tagging_Random">
<English>Random</English>
</Key>
<Key ID="STR_ACE_Tagging_Tag">
<English>Tag</English>
<German>Markieren</German>
<Spanish>Marcar</Spanish>
<Polish>Oznakuj</Polish>
<French>Tag</French>
<Italian>Marca</Italian>
<Czech>Označit</Czech>
<Portuguese>Marcar</Portuguese>
</Key>
<Key ID="STR_ACE_Tagging_XBlack">
<English>X black</English>
<German>Schwarz X</German>
<Spanish>X en negro</Spanish>
<Polish>X na czarno</Polish>
<French>X noir</French>
<Italian>X nero</Italian>
<Czech>X černě</Czech>
<Portuguese>X em preto</Portuguese>
</Key>
<Key ID="STR_ACE_Tagging_XRed">
<English>X red</English>
<German>Rot X</German>
<Spanish>X en rojo</Spanish>
<Polish>X na czerwono</Polish>
<French>X rouge</French>
<Italian>X rosso</Italian>
<Czech>X červeně</Czech>
<Portuguese>X em vermelho</Portuguese>
</Key>
<Key ID="STR_ACE_Tagging_XGreen">
<English>X green</English>
<German>Grün X</German>
<Spanish>X en verde</Spanish>
<Polish>X na zielono</Polish>
<French>X vert</French>
<Italian>X verde</Italian>
<Czech>X zeleně</Czech>
<Portuguese>X em verde</Portuguese>
</Key>
<Key ID="STR_ACE_Tagging_XBlue">
<English>X blue</English>
<German>Blau X</German>
<Spanish>X en azul</Spanish>
<Polish>X na niebiesko</Polish>
<French>X bleu</French>
<Italian>X blu</Italian>
<Czech>X modře</Czech>
<Portuguese>X em azul</Portuguese>
</Key>
<Key ID="STR_ACE_Tagging_SpraypaintBlack">
<English>Black spray paint</English>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB