diff --git a/AUTHORS.txt b/AUTHORS.txt index b812ed0ae7..3efd30a184 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -39,6 +39,7 @@ Alganthe Anthariel Arkhir Asgar Serran +BaerMitUmlaut Bamse Bla1337 BlackPixxel diff --git a/addons/tagging/$PBOPREFIX$ b/addons/tagging/$PBOPREFIX$ new file mode 100644 index 0000000000..d841d5d209 --- /dev/null +++ b/addons/tagging/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\tagging \ No newline at end of file diff --git a/addons/tagging/CfgEventHandlers.hpp b/addons/tagging/CfgEventHandlers.hpp new file mode 100644 index 0000000000..0cd959a047 --- /dev/null +++ b/addons/tagging/CfgEventHandlers.hpp @@ -0,0 +1,12 @@ + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; diff --git a/addons/tagging/CfgVehicles.hpp b/addons/tagging/CfgVehicles.hpp new file mode 100644 index 0000000000..30e3fada58 --- /dev/null +++ b/addons/tagging/CfgVehicles.hpp @@ -0,0 +1,101 @@ +class CfgVehicles { + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ACE_Equipment { + class ACE_tagWallBlack { + displayName = CSTRING(tagWallBlack); + condition = QUOTE(('ACE_SpraypaintBlack' in items ACE_player) && ([] call FUNC(checkTaggable))); + statement = QUOTE([ARR_2(ACE_player,'black')] call FUNC(tagWall)); + showDisabled = 0; + priority = 3; + icon = QUOTE(PATHTOF(UI\icons\iconTaggingBlack.paa)); + }; + class ACE_tagWallRed: ACE_tagWallBlack { + displayName = CSTRING(tagWallRed); + condition = QUOTE(('ACE_SpraypaintRed' in items ACE_player) && ([] call FUNC(checkTaggable))); + statement = QUOTE([ARR_2(ACE_player,'red')] call FUNC(tagWall)); + icon = QUOTE(PATHTOF(UI\icons\iconTaggingRed.paa)); + }; + class ACE_tagWallGreen: ACE_tagWallBlack { + displayName = CSTRING(tagWallGreen); + condition = QUOTE(('ACE_SpraypaintGreen' in items ACE_player) && ([] call FUNC(checkTaggable))); + statement = QUOTE([ARR_2(ACE_player,'green')] call FUNC(tagWall)); + icon = QUOTE(PATHTOF(UI\icons\iconTaggingGreen.paa)); + }; + class ACE_tagWallBlue: ACE_tagWallBlack { + displayName = CSTRING(tagWallBlue); + condition = QUOTE(('ACE_SpraypaintBlue' in items ACE_player) && ([] call FUNC(checkTaggable))); + statement = QUOTE([ARR_2(ACE_player,'blue')] call FUNC(tagWall)); + icon = QUOTE(PATHTOF(UI\icons\iconTaggingBlue.paa)); + }; + /*class ACE_tagGroundBlack { + displayName = CSTRING(tagGroundBlack); + condition = QUOTE('ACE_SpraypaintBlack' in items ACE_player); + statement = QUOTE([ARR_2(ACE_player, 'black')] call FUNC(tagGround)); + showDisabled = 0; + priority = 3; + icon = QUOTE(PATHTOF(UI\icons\iconTaggingBlack.paa)); + }; + class ACE_tagGroundRed: ACE_tagGroundBlack { + displayName = CSTRING(tagGroundRed); + condition = QUOTE('ACE_SpraypaintRed' in items ACE_player); + statement = QUOTE([ARR_2(ACE_player, 'red')] call FUNC(tagGround)); + icon = QUOTE(PATHTOF(UI\icons\iconTaggingRed.paa)); + }; + class ACE_tagGroundGreen: ACE_tagGroundBlack { + displayName = CSTRING(tagGroundGreen); + condition = QUOTE('ACE_SpraypaintGreen' in items ACE_player); + statement = QUOTE([ARR_2(ACE_player, 'green')] call FUNC(tagGround)); + icon = QUOTE(PATHTOF(UI\icons\iconTaggingGreen.paa)); + }; + class ACE_tagGroundBlue: ACE_tagGroundBlack { + displayName = CSTRING(tagGroundBlue); + condition = QUOTE('ACE_SpraypaintBlue' in items ACE_player); + statement = QUOTE([ARR_2(ACE_player, 'blue')] call FUNC(tagGround)); + icon = QUOTE(PATHTOF(UI\icons\iconTaggingBlue.paa)); + };*/ + }; + }; + }; + + class Item_Base_F; + class ACE_Item_SpraypaintBlack: Item_Base_F { + author = "jokoho48"; + scope = 2; + scopeCurator = 2; + displayName = CSTRING(spraypaintBlack); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_SpraypaintBlack,1); + }; + }; + class ACE_Item_SpraypaintRed: ACE_Item_SpraypaintBlack { + displayName = CSTRING(spraypaintRed); + class TransportItems { + MACRO_ADDITEM(ACE_SpraypaintRed,1); + }; + }; + class ACE_Item_SpraypaintGreen: ACE_Item_SpraypaintBlack { + displayName = CSTRING(spraypaintGreen); + class TransportItems { + MACRO_ADDITEM(ACE_SpraypaintGreen,1); + }; + }; + class ACE_Item_SpraypaintBlue: ACE_Item_SpraypaintBlack { + displayName = CSTRING(spraypaintBlue); + class TransportItems { + MACRO_ADDITEM(ACE_SpraypaintBlue,1); + }; + }; + + class Box_NATO_Support_F; + class ACE_Box_Misc: Box_NATO_Support_F { + class TransportItems { + MACRO_ADDITEM(ACE_SpraypaintBlack,5); + MACRO_ADDITEM(ACE_SpraypaintRed,5); + MACRO_ADDITEM(ACE_SpraypaintBlue,5); + MACRO_ADDITEM(ACE_SpraypaintGreen,5); + }; + }; +}; \ No newline at end of file diff --git a/addons/tagging/CfgWeapons.hpp b/addons/tagging/CfgWeapons.hpp new file mode 100644 index 0000000000..a805a75679 --- /dev/null +++ b/addons/tagging/CfgWeapons.hpp @@ -0,0 +1,33 @@ +class CfgWeapons { + class ACE_ItemCore; + class InventoryItem_Base_F; + + class ACE_SpraypaintBlack : ACE_ItemCore { + author = "jokoho48"; + displayname = CSTRING(spraypaintBlack); + descriptionShort = CSTRING(descSpraypaint); + picture = QUOTE(PATHTOF(UI\items\itemSpraypaintBlack.paa)); + model = QUOTE(PATHTOF(data\SprayCan.p3d)); + scope = 2; + hiddenSelections[] = {"camo"}; + hiddenSelectionsTextures[] = {QUOTE(PATHTOF(data\spraycanBlack_co.paa))}; + class ItemInfo: InventoryItem_Base_F { + mass = 10; + }; + }; + class ACE_SpraypaintRed : ACE_SpraypaintBlack { + displayname = CSTRING(spraypaintRed); + picture = QUOTE(PATHTOF(UI\items\itemSpraypaintRed.paa)); + hiddenSelectionsTextures[] = {QUOTE(PATHTOF(data\spraycanRed_co.paa))}; + }; + class ACE_SpraypaintGreen : ACE_SpraypaintBlack { + displayname = CSTRING(spraypaintGreen); + picture = QUOTE(PATHTOF(UI\items\itemSpraypaintGreen.paa)); + hiddenSelectionsTextures[] = {QUOTE(PATHTOF(data\spraycanGreen_co.paa))}; + }; + class ACE_SpraypaintBlue : ACE_SpraypaintBlack { + displayname = CSTRING(spraypaintBlue); + picture = QUOTE(PATHTOF(UI\items\itemSpraypaintBlue.paa)); + hiddenSelectionsTextures[] = {QUOTE(PATHTOF(data\spraycanBlue_co.paa))}; + }; +}; diff --git a/addons/tagging/README.md b/addons/tagging/README.md new file mode 100644 index 0000000000..1e29e16b6f --- /dev/null +++ b/addons/tagging/README.md @@ -0,0 +1,11 @@ +ace_tagging +=============== + +Adds a can of spray paint which allows you to tag buildings, walls and other static objects. + + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- []() \ No newline at end of file diff --git a/addons/tagging/UI/icons/iconTaggingBlack.paa b/addons/tagging/UI/icons/iconTaggingBlack.paa new file mode 100644 index 0000000000..fcc29807bb Binary files /dev/null and b/addons/tagging/UI/icons/iconTaggingBlack.paa differ diff --git a/addons/tagging/UI/icons/iconTaggingBlue.paa b/addons/tagging/UI/icons/iconTaggingBlue.paa new file mode 100644 index 0000000000..eb60a8b1a8 Binary files /dev/null and b/addons/tagging/UI/icons/iconTaggingBlue.paa differ diff --git a/addons/tagging/UI/icons/iconTaggingGreen.paa b/addons/tagging/UI/icons/iconTaggingGreen.paa new file mode 100644 index 0000000000..3c92b87375 Binary files /dev/null and b/addons/tagging/UI/icons/iconTaggingGreen.paa differ diff --git a/addons/tagging/UI/icons/iconTaggingRed.paa b/addons/tagging/UI/icons/iconTaggingRed.paa new file mode 100644 index 0000000000..cfed5fdb1f Binary files /dev/null and b/addons/tagging/UI/icons/iconTaggingRed.paa differ diff --git a/addons/tagging/UI/items/itemSpraypaintBlack.paa b/addons/tagging/UI/items/itemSpraypaintBlack.paa new file mode 100644 index 0000000000..b4df79a4f5 Binary files /dev/null and b/addons/tagging/UI/items/itemSpraypaintBlack.paa differ diff --git a/addons/tagging/UI/items/itemSpraypaintBlue.paa b/addons/tagging/UI/items/itemSpraypaintBlue.paa new file mode 100644 index 0000000000..c3fc18a74d Binary files /dev/null and b/addons/tagging/UI/items/itemSpraypaintBlue.paa differ diff --git a/addons/tagging/UI/items/itemSpraypaintGreen.paa b/addons/tagging/UI/items/itemSpraypaintGreen.paa new file mode 100644 index 0000000000..781b59880c Binary files /dev/null and b/addons/tagging/UI/items/itemSpraypaintGreen.paa differ diff --git a/addons/tagging/UI/items/itemSpraypaintRed.paa b/addons/tagging/UI/items/itemSpraypaintRed.paa new file mode 100644 index 0000000000..670bc3d8b3 Binary files /dev/null and b/addons/tagging/UI/items/itemSpraypaintRed.paa differ diff --git a/addons/tagging/UI/tags/black/0.paa b/addons/tagging/UI/tags/black/0.paa new file mode 100644 index 0000000000..eaf80ac9e6 Binary files /dev/null and b/addons/tagging/UI/tags/black/0.paa differ diff --git a/addons/tagging/UI/tags/black/1.paa b/addons/tagging/UI/tags/black/1.paa new file mode 100644 index 0000000000..41a7d633ea Binary files /dev/null and b/addons/tagging/UI/tags/black/1.paa differ diff --git a/addons/tagging/UI/tags/black/2.paa b/addons/tagging/UI/tags/black/2.paa new file mode 100644 index 0000000000..743410005c Binary files /dev/null and b/addons/tagging/UI/tags/black/2.paa differ diff --git a/addons/tagging/UI/tags/blue/0.paa b/addons/tagging/UI/tags/blue/0.paa new file mode 100644 index 0000000000..fcc9b28ec9 Binary files /dev/null and b/addons/tagging/UI/tags/blue/0.paa differ diff --git a/addons/tagging/UI/tags/blue/1.paa b/addons/tagging/UI/tags/blue/1.paa new file mode 100644 index 0000000000..78122eb7f1 Binary files /dev/null and b/addons/tagging/UI/tags/blue/1.paa differ diff --git a/addons/tagging/UI/tags/blue/2.paa b/addons/tagging/UI/tags/blue/2.paa new file mode 100644 index 0000000000..fb7b8c3d20 Binary files /dev/null and b/addons/tagging/UI/tags/blue/2.paa differ diff --git a/addons/tagging/UI/tags/green/0.paa b/addons/tagging/UI/tags/green/0.paa new file mode 100644 index 0000000000..19d89d6954 Binary files /dev/null and b/addons/tagging/UI/tags/green/0.paa differ diff --git a/addons/tagging/UI/tags/green/1.paa b/addons/tagging/UI/tags/green/1.paa new file mode 100644 index 0000000000..1f55002d28 Binary files /dev/null and b/addons/tagging/UI/tags/green/1.paa differ diff --git a/addons/tagging/UI/tags/green/2.paa b/addons/tagging/UI/tags/green/2.paa new file mode 100644 index 0000000000..79804cdfde Binary files /dev/null and b/addons/tagging/UI/tags/green/2.paa differ diff --git a/addons/tagging/UI/tags/red/0.paa b/addons/tagging/UI/tags/red/0.paa new file mode 100644 index 0000000000..540348b90c Binary files /dev/null and b/addons/tagging/UI/tags/red/0.paa differ diff --git a/addons/tagging/UI/tags/red/1.paa b/addons/tagging/UI/tags/red/1.paa new file mode 100644 index 0000000000..767cc1003e Binary files /dev/null and b/addons/tagging/UI/tags/red/1.paa differ diff --git a/addons/tagging/UI/tags/red/2.paa b/addons/tagging/UI/tags/red/2.paa new file mode 100644 index 0000000000..c2b7189133 Binary files /dev/null and b/addons/tagging/UI/tags/red/2.paa differ diff --git a/addons/tagging/XEH_postInit.sqf b/addons/tagging/XEH_postInit.sqf new file mode 100644 index 0000000000..31fd73d913 --- /dev/null +++ b/addons/tagging/XEH_postInit.sqf @@ -0,0 +1,47 @@ +// by esteldunedain +#include "script_component.hpp" + + +// Cache for static objects +GVAR(cacheStaticModels) = createLocation ["ACE_HashLocation", [-10000,-10000,-10000], 0, 0]; +GVAR(cacheStaticModels) setText QGVAR(cacheStaticModels); + +// Consider static everything vehicle that inherit from Static +// This include houses (which we don't need), but also walls, that we do +private _cfgBase = configFile >> "CfgVehicles"; +private _countOptions = count _cfgBase; +for "_index" from 0 to (_countOptions - 1) do { + private _cfgClass = _cfgBase select _index; + if (isClass _cfgClass) then { + if ((configName _cfgClass) isKindOf "Static") then { + private _model = getText (_cfgClass >> "model"); + if (_model != "") then { + private _array = _model splitString "\"; + GVAR(cacheStaticModels) setVariable [toLower (_array select ((count _array) - 2)), _cfgClass]; + }; + }; + }; +}; + +// Also consider static all object inheriting from bridges +_cfgBase = configFile >> "CfgNonAIVehicles"; +_countOptions = count _cfgBase; +for "_index" from 0 to (_countOptions - 1) do { + private _cfgClass = _cfgBase select _index; + if (isClass _cfgClass) then { + if ((configName _cfgClass) isKindOf ["Bridge_base_F", _cfgBase]) then { + private _model = getText (_cfgClass >> "model"); + if (_model != "") then { + private _array = _model splitString "\"; + GVAR(cacheStaticModels) setVariable [toLower (_array select ((count _array) - 2)), _cfgClass]; + }; + }; + }; +}; + +if (!isServer) exitWith {}; + +GVAR(testingThread) = false; +GVAR(tagsToTest) = []; + +["createTag", DFUNC(createTag)] call EFUNC(common,addEventHandler); diff --git a/addons/tagging/XEH_preInit.sqf b/addons/tagging/XEH_preInit.sqf new file mode 100644 index 0000000000..c3ceab4c03 --- /dev/null +++ b/addons/tagging/XEH_preInit.sqf @@ -0,0 +1,12 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP(checkTaggable); +PREP(createTag); +PREP(tagDirection); +PREP(tagGround); +PREP(tagWall); +PREP(tagTestingThread); + +ADDON = true; diff --git a/addons/tagging/config.cpp b/addons/tagging/config.cpp new file mode 100644 index 0000000000..dcd1fb845d --- /dev/null +++ b/addons/tagging/config.cpp @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + units[] = {"ACE_Item_SpraypaintBlack", "ACE_Item_SpraypaintRed", "ACE_Item_SpraypaintGreen", "ACE_Item_SpraypaintBlue"}; + weapons[] = {"ACE_SpraypaintBlack", "ACE_SpraypaintRed", "ACE_SpraypaintGreen", "ACE_SpraypaintBlue"}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interaction"}; + author[] = {"BaerMitUmlaut","esteldunedain"}; + authorUrl = "https://github.com/BaerMitUmlaut"; + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/tagging/data/SprayCan.p3d b/addons/tagging/data/SprayCan.p3d new file mode 100644 index 0000000000..54410046a9 Binary files /dev/null and b/addons/tagging/data/SprayCan.p3d differ diff --git a/addons/tagging/data/model.cfg b/addons/tagging/data/model.cfg new file mode 100644 index 0000000000..dda2be3d82 --- /dev/null +++ b/addons/tagging/data/model.cfg @@ -0,0 +1,20 @@ +class CfgSkeletons { + class Default { + isDiscrete = 1; + skeletonInherit = ""; + skeletonBones[] = {}; + }; +}; + +class CfgModels { + class Default { + sectionsInherit=""; + sections[] = {""}; + skeletonName = ""; + }; + class SprayCan { + sectionsInherit = ""; + sections[] = {"camo"}; + skeletonName = ""; + }; +}; \ No newline at end of file diff --git a/addons/tagging/data/spraycan.rvmat b/addons/tagging/data/spraycan.rvmat new file mode 100644 index 0000000000..18c91a1bf2 --- /dev/null +++ b/addons/tagging/data/spraycan.rvmat @@ -0,0 +1,82 @@ +class StageTI { + texture = "a3\data_f\default_glass_ti_ca.paa"; +}; +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.3,0.3,0.3,1}; +specularPower = 50; +PixelShaderID = "Super"; +VertexShaderID = "Super"; +class Stage1 { + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,NOHQ)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage2 { + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage3 { + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage4 { + texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage5 { + texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage6 { + texture = "#(ai,32,128,1)fresnel(0.85,0.36)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage7 { + useWorldEnvMap = "true"; + texture = "a3\data_f\env_interier_car_ca.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; diff --git a/addons/tagging/data/spraycanBlack_co.paa b/addons/tagging/data/spraycanBlack_co.paa new file mode 100644 index 0000000000..ff512a3ae1 Binary files /dev/null and b/addons/tagging/data/spraycanBlack_co.paa differ diff --git a/addons/tagging/data/spraycanBlue_co.paa b/addons/tagging/data/spraycanBlue_co.paa new file mode 100644 index 0000000000..e2013be084 Binary files /dev/null and b/addons/tagging/data/spraycanBlue_co.paa differ diff --git a/addons/tagging/data/spraycanGreen_co.paa b/addons/tagging/data/spraycanGreen_co.paa new file mode 100644 index 0000000000..8143f5a385 Binary files /dev/null and b/addons/tagging/data/spraycanGreen_co.paa differ diff --git a/addons/tagging/data/spraycanRed_co.paa b/addons/tagging/data/spraycanRed_co.paa new file mode 100644 index 0000000000..b7d499b50f Binary files /dev/null and b/addons/tagging/data/spraycanRed_co.paa differ diff --git a/addons/tagging/functions/fnc_checkTaggable.sqf b/addons/tagging/functions/fnc_checkTaggable.sqf new file mode 100644 index 0000000000..4c8f0c750a --- /dev/null +++ b/addons/tagging/functions/fnc_checkTaggable.sqf @@ -0,0 +1,56 @@ +/* + * Author: BaerMitUmlaut and esteldunedain + * Checks if there is a taggable surface within 2.5m in front of the player. + * + * Arguments: + * None + * + * Return Value: + * Is wall taggable + * + * Example: + * [] call ace_tagging_fnc_checkTaggable + * + * Public: No + */ + +#include "script_component.hpp" + +[[], { + private _startPosASL = eyePos ACE_player; + 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"]; + + // If there's no intersections + if (_intersections isEqualTo []) exitWith {false}; + + (_intersections select 0) params ["", "", "", "_object"]; + + // Exit if trying to tag a non static object + TRACE_1("Obj:",_intersections); + + // Exit if trying to tag a non static object + if ((!isNull _object) && { + // If the class is alright, do not exit + if (_object isKindOf "Static") exitWith {false}; + + // If the class is not categorized correctly search the cache + private _array = str(_object) splitString " "; + private _str = toLower (_array select 1); + TRACE_1("Object:",_str); + private _objClass = GVAR(cacheStaticModels) getVariable _str; + // If the class in not on the cache, exit + if (isNil "_objClass") exitWith { + false + }; + true + }) exitWith { + TRACE_1("Pointed object is non static",_object); + false + }; + + true +}, missionNamespace, QGVAR(checkTaggableCache), 0.5] call EFUNC(common,cachedCall); diff --git a/addons/tagging/functions/fnc_createTag.sqf b/addons/tagging/functions/fnc_createTag.sqf new file mode 100644 index 0000000000..fdb2cd08b0 --- /dev/null +++ b/addons/tagging/functions/fnc_createTag.sqf @@ -0,0 +1,71 @@ +/* + * Author: BaerMitUmlaut and esteldunedain + * Creates a tag and handle its destruction. Only execute on the server. + * + * Arguments: + * 0: Position ASL + * 1: Vector dir and up + * 2: Colour of the tag (valid colours are black, red, green and blue) + * 3: Object it should be tied too + * + * Return Value: + * None + * + * Example: + * [positionASL, vectorDirAndUp, "black", object] call ace_tagging_fnc_createTag + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_tagPosASL", "_vectorDirAndUp", "_color", "_object"]; +TRACE_4("createTag:", _tagPosASL, _vectorDirAndUp, _color, _object); + +if !((toLower _color) in ["black", "red", "green", "blue"]) exitWith { + ACE_LOGERROR_1("%1 is not a valid tag colour.", _color); +}; + +private _tag = "UserTexture1m_F" createVehicle [0,0,0]; +_tag setObjectTextureGlobal [0, '\z\ace\addons\tagging\UI\tags\' + _color + '\' + str (floor (random 3)) + '.paa']; +_tag setPosASL _tagPosASL; +_tag setVectorDirAndUp _vectorDirAndUp; + +if (isNull _object) exitWith {}; + +// If the tag is applied to an object, handle its destruction +_object setVariable [QGVAR(testVar), true]; +if (_object getVariable [QGVAR(testVar), false]) then { + // The object supports variables and hence HandleDamage too + // Use the cheaper alternative for handling destruction: HandleDamage + + // If the object already has tags attached, just add the new one to the list + private _attachedTags = _object getVariable QGVAR(attachedTags); + if !(isNil "_attachedTags ") exitWith { + _attachedTags pushBack _tag; + }; + + _attachedTags = [_tag]; + _object setVariable [QGVAR(attachedTags), _attachedTags]; + + // If it's the first tag attached to that object, add a handledamage event handler + _object addEventHandler ["HandleDamage", { + params ["_object", "_selection", "_damage"]; + if (_selection == "" && _damage >= 1) then { + { + deleteVehicle _x; + } foreach (_object getVariable [QGVAR(attachedTags), []]); + _object setVariable [QGVAR(attachedTags), []]; + }; + }]; +}; + +// Periodic test the tag: +// - For object that don't support handledamage +// - For object that do, to support doors opening/closing, etc +GVAR(tagsToTest) pushBack [_tag, _tagPosASL, _vectorDirAndUp]; + +// Run the test +if (!GVAR(testingThread)) then { + call FUNC(tagTestingThread); +}; diff --git a/addons/tagging/functions/fnc_tagDirection.sqf b/addons/tagging/functions/fnc_tagDirection.sqf new file mode 100644 index 0000000000..2c03d97fd0 --- /dev/null +++ b/addons/tagging/functions/fnc_tagDirection.sqf @@ -0,0 +1,107 @@ +/* + * Author: BaerMitUmlaut and esteldunedain + * If possible, create a tag on the first surface between Start and End positions + * + * Arguments: + * 0: Unit + * 1: Start position ASL + * 2: End position ASL + * 3: The colour of the tag (valid colours are black, red, green and blue) + * + * Return Value: + * Sucess + * + * Example: + * [startPosASL, directiom "blue"] call ace_tagging_fnc_tagDirection + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_unit", "_startPosASL", "_endPosASL", "_color"]; + +// Check for intersections below the unit +private _intersections = lineIntersectsSurfaces [_startPosASL, _endPosASL, _unit, objNull, true, 1, "GEOM", "FIRE"]; + +// If there's no intersections +if (_intersections isEqualTo []) exitWith { + TRACE_3("No intersections",_intersections); + false +}; + +(_intersections select 0) params ["_touchingPoint", "_surfaceNormal", "", "_object"]; +TRACE_3("",_touchingPoint, _surfaceNormal, _object); + +// Exit if trying to tag a non static object +if ((!isNull _object) && { + // If the class is alright, do not exit + if (_object isKindOf "Static") exitWith {false}; + + // If the class is not categorized correctly search the cache + private _array = str(_object) splitString " "; + private _str = toLower (_array select 1); + TRACE_1("Object:",_str); + private _objClass = GVAR(cacheStaticModels) getVariable _str; + // If the class in not on the cache, exit + if (isNil "_objClass") exitWith { + false + }; + true +}) exitWith { + TRACE_1("Pointed object is non static",_object); + false +}; + + +// If the surface normal points away, flip it. This happens in weird places like the Stratis Pier +if (_surfaceNormal vectorDotProduct (_endPosASL vectorDiff _startPosASL) > 0) then { + _surfaceNormal = _surfaceNormal vectorMultiply -1; +}; + +// Check if its a valid surface: big enough, reasonably plane +private _v1 = vectorNormalized (_surfaceNormal vectorMultiply -1); +private _v2 = vectorNormalized (_v1 vectorCrossProduct (_endPosASL vectorDiff _startPosASL)); +private _v3 = _v2 vectorCrossProduct _v1; + +TRACE_3("Reference:", _v1, _v2, _v3); + +_fnc_isOk = { + params ["_rx", "_ry"]; + private _startPosASL2 = _touchingPoint vectorAdd (_v2 vectorMultiply _rx) vectorAdd (_v3 vectorMultiply _ry) vectorAdd (_v1 vectorMultiply (-0.06)); + private _endPosASL2 = _startPosASL2 vectorAdd (_v1 vectorMultiply (0.12)); + private _intersections = lineIntersectsSurfaces [_startPosASL2, _endPosASL2, _unit, objNull, true, 1, "GEOM", "FIRE"]; + // If there's no intersections + if (_intersections isEqualTo []) exitWith {false;}; + + if !(((_intersections select 0) select 3) isEqualTo _object) exitWith {false;}; + + true +}; + +#define TAG_SIZE 0.6 + +if ( !([ 0.5*TAG_SIZE, 0.5*TAG_SIZE] call _fnc_isOk) || + {!([ 0.5*TAG_SIZE,-0.5*TAG_SIZE] call _fnc_isOk) || + {!([-0.5*TAG_SIZE, 0.5*TAG_SIZE] call _fnc_isOk) || + {!([-0.5*TAG_SIZE,-0.5*TAG_SIZE] call _fnc_isOk)}}}) exitWith { + TRACE_3("Unsuitable location:",_touchingPoint); + false +}; + +private _vectorDirAndUp = [_surfaceNormal vectorMultiply -1, _v3]; + +// Everything ok, make the unit create the tag +_unit playActionNow "PutDown"; + +[{ + params ["", "", "", "", "_unit"]; + TRACE_2("Unit:",_unit,_this); + + playSound3D [QUOTE(PATHTO_R(sounds\spray.ogg)), _unit, false, (eyePos _unit), 10, 1, 15]; + + // Tell the server to create the tag and handle its destruction + ["createTag", _this] call EFUNC(common,serverEvent); +}, [_touchingPoint vectorAdd (_surfaceNormal vectorMultiply 0.06), _vectorDirAndUp, _color, _object, _unit], 0.6] call EFUNC(common,waitAndExecute); + +true diff --git a/addons/tagging/functions/fnc_tagGround.sqf b/addons/tagging/functions/fnc_tagGround.sqf new file mode 100644 index 0000000000..fa8d1795bf --- /dev/null +++ b/addons/tagging/functions/fnc_tagGround.sqf @@ -0,0 +1,25 @@ +/* + * Author: BaerMitUmlaut and esteldunedain + * Creates a tag on the ground beneath the unit + * + * Arguments: + * 0: Unit + * 1: The colour of the tag (valid colours are black, red, green and blue) + * + * Return Value: + * None + * + * Example: + * [player, "blue"] call ace_tagging_fnc_tagGround + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_unit", "_color"]; + +private _startPosASL = getPosASL _unit; +private _endPosASL = _startPosASL vectorAdd [0, 0, -2] vectorAdd eyeDirection _unit; + +[_unit, _startPosASL, _endPosASL, _color] call FUNC(tagDirection); diff --git a/addons/tagging/functions/fnc_tagTestingThread.sqf b/addons/tagging/functions/fnc_tagTestingThread.sqf new file mode 100644 index 0000000000..18d14e2e4f --- /dev/null +++ b/addons/tagging/functions/fnc_tagTestingThread.sqf @@ -0,0 +1,46 @@ +/* + * Author: esteldunedain + * Checks if tags are still leaning on an object periodically. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_tagging_fnc_tagTestingThread + * + * Public: No + */ + +#include "script_component.hpp" + +_fnc_isLeaning = { + params ["_tag", "_tagPosASL", "_vectorDirAndUp"]; + + _vectorDirAndUp params ["_v1", "_v2"]; + + private _endPosASL = _tagPosASL vectorAdd (_v1 vectorMultiply 0.08); + + // Check for intersections below the unit + private _intersections = lineIntersectsSurfaces [_tagPosASL, _endPosASL, _tag, objNull, true, 1, "GEOM", "FIRE"]; + + // If there's no intersections + if (_intersections isEqualTo []) exitWith { + TRACE_1("No intersections, deleting:",_tag); + deleteVehicle _tag; + false + }; + true +}; +GVAR(tagsToTest) = [GVAR(tagsToTest), _fnc_isLeaning] call EFUNC(common,filter); + +// If there's no more tag +if (GVAR(tagsToTest) isEqualTo []) exitWith { + GVAR(testingThread) = false; +}; + +// Schedule for execution again after 5 seconds +[DFUNC(tagTestingThread), [], 5] call EFUNC(common,waitAndExecute); +GVAR(testingThread) = true; diff --git a/addons/tagging/functions/fnc_tagWall.sqf b/addons/tagging/functions/fnc_tagWall.sqf new file mode 100644 index 0000000000..9b6485f4e8 --- /dev/null +++ b/addons/tagging/functions/fnc_tagWall.sqf @@ -0,0 +1,27 @@ +/* + * Author: BaerMitUmlaut and esteldunedain + * Creates a tag on a wall that is on the closest surface within 2m on front of the unit. + * + * Arguments: + * 0: Unit + * 1: The colour of the tag (valid colours are black, red, green and blue) + * + * Return Value: + * None + * + * Example: + * [player, "blue"] call ace_tagging_fnc_tagWall + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_unit", "_color"]; + +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); + +[_unit, _startPosASL, _endPosASL, _color] call FUNC(tagDirection); diff --git a/addons/tagging/functions/script_component.hpp b/addons/tagging/functions/script_component.hpp new file mode 100644 index 0000000000..bc860f2283 --- /dev/null +++ b/addons/tagging/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\tagging\script_component.hpp" \ No newline at end of file diff --git a/addons/tagging/script_component.hpp b/addons/tagging/script_component.hpp new file mode 100644 index 0000000000..4217989fde --- /dev/null +++ b/addons/tagging/script_component.hpp @@ -0,0 +1,15 @@ +#define COMPONENT tagging +#include "\z\ace\addons\main\script_mod.hpp" + +#define DEBUG_MODE_FULL +#define DISABLE_COMPILE_CACHE + +#ifdef DEBUG_ENABLED_BLANK + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_BLANK + #define DEBUG_SETTINGS DEBUG_SETTINGS_BLANK +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/tagging/sounds/spray.ogg b/addons/tagging/sounds/spray.ogg new file mode 100644 index 0000000000..127dc9db75 Binary files /dev/null and b/addons/tagging/sounds/spray.ogg differ diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml new file mode 100644 index 0000000000..158e2429ba --- /dev/null +++ b/addons/tagging/stringtable.xml @@ -0,0 +1,57 @@ + + + + + Tag black + Schwarz markieren + + + Tag red + Rot markieren + + + Tag green + Grün markieren + + + Tag blue + Blau markieren + + + Tag ground black + Boden schwarz markieren + + + Tag ground red + Boden rot markieren + + + Tag ground green + Boden grün markieren + + + Tag ground blue + Boden blau markieren + + + Black spray paint + Schwarze Sprühfarbe + + + Red spray paint + Rote Sprühfarbe + + + Green spray paint + Grüne Sprühfarbe + + + Blue spray paint + Blaue Sprühfarbe + + + A can of spray paint for tagging walls. + Eine Farbsprühdose um Wände zu markieren. + + +