- Tagging cleanup.

- Replaced "Tag wall" and "Tag ground" for a single "Tag" action.
- Added more reliable checks before placing the tag
- Allowed non-player units to tag (via API).
- Replaced execRemoteFnc by events
This commit is contained in:
esteldunedain 2016-01-21 19:59:27 -03:00
parent a22203a02a
commit ad96617d3a
14 changed files with 227 additions and 155 deletions

View File

@ -4,3 +4,9 @@ class Extended_PreInit_EventHandlers {
init = QUOTE(call COMPILE_FILE(XEH_preInit));
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_postInit));
};
};

View File

@ -6,7 +6,7 @@ class CfgVehicles {
class ACE_tagWallBlack {
displayName = CSTRING(tagWallBlack);
condition = QUOTE(('ACE_SpraypaintBlack' in items ACE_player) && ([] call FUNC(checkTaggable)));
statement = QUOTE(['black'] call FUNC(tagWall));
statement = QUOTE([ARR_2(ACE_player,'black')] call FUNC(tagWall));
showDisabled = 0;
priority = 3;
icon = QUOTE(PATHTOF(UI\icons\iconTaggingBlack.paa));
@ -14,25 +14,25 @@ class CfgVehicles {
class ACE_tagWallRed: ACE_tagWallBlack {
displayName = CSTRING(tagWallRed);
condition = QUOTE(('ACE_SpraypaintRed' in items ACE_player) && ([] call FUNC(checkTaggable)));
statement = QUOTE(['red'] call FUNC(tagWall));
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(['green'] call FUNC(tagWall));
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(['blue'] call FUNC(tagWall));
statement = QUOTE([ARR_2(ACE_player,'blue')] call FUNC(tagWall));
icon = QUOTE(PATHTOF(UI\icons\iconTaggingBlue.paa));
};
class ACE_tagGroundBlack {
/*class ACE_tagGroundBlack {
displayName = CSTRING(tagGroundBlack);
condition = QUOTE('ACE_SpraypaintBlack' in items ACE_player);
statement = QUOTE(['black'] call FUNC(tagGround));
statement = QUOTE([ARR_2(ACE_player, 'black')] call FUNC(tagGround));
showDisabled = 0;
priority = 3;
icon = QUOTE(PATHTOF(UI\icons\iconTaggingBlack.paa));
@ -40,21 +40,21 @@ class CfgVehicles {
class ACE_tagGroundRed: ACE_tagGroundBlack {
displayName = CSTRING(tagGroundRed);
condition = QUOTE('ACE_SpraypaintRed' in items ACE_player);
statement = QUOTE(['red'] call FUNC(tagGround));
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(['green'] call FUNC(tagGround));
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(['blue'] call FUNC(tagGround));
statement = QUOTE([ARR_2(ACE_player, 'blue')] call FUNC(tagGround));
icon = QUOTE(PATHTOF(UI\icons\iconTaggingBlue.paa));
};
};*/
};
};
};

View File

@ -30,4 +30,4 @@ class CfgWeapons {
picture = QUOTE(PATHTOF(UI\items\itemSpraypaintBlue.paa));
hiddenSelectionsTextures[] = {QUOTE(PATHTOF(data\spraycanBlue_co.paa))};
};
};
};

View File

@ -0,0 +1,6 @@
// by esteldunedain
#include "script_component.hpp"
if (!isServer) exitWith {};
["createTag", DFUNC(createTag)] call EFUNC(common,addEventHandler);

View File

@ -3,8 +3,9 @@
ADDON = false;
PREP(checkTaggable);
PREP(createTag);
PREP(tagDirection);
PREP(tagWall);
PREP(tagGround);
PREP(handleTagDestruction);
ADDON = true;

View File

@ -6,7 +6,7 @@ class CfgPatches {
weapons[] = {"ACE_SpraypaintBlack", "ACE_SpraypaintRed", "ACE_SpraypaintGreen", "ACE_SpraypaintBlue"};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_interaction"};
author[] = {"BaerMitUmlaut"};
author[] = {"BaerMitUmlaut","esteldunedain"};
authorUrl = "https://github.com/BaerMitUmlaut";
VERSION_CONFIG;
};
@ -14,4 +14,4 @@ class CfgPatches {
#include "CfgEventHandlers.hpp"
#include "CfgVehicles.hpp"
#include "CfgWeapons.hpp"
#include "CfgWeapons.hpp"

View File

@ -1,10 +1,10 @@
/*
* Author: BaerMitUmlaut
* Checks if there is a wall within 2m in front of the player.
* 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 <BOOL>
*
@ -14,31 +14,24 @@
* Public: No
*/
#include "script_component.hpp"
private ["_posCheck", "_objectsLeft", "_intersectsLeft", "_objectsRight", "_intersectsRight"];
_posCheck = ACE_player modelToWorldVisual [-0.5, 2, 0];
_posCheck set [2, (eyePos ACE_player) select 2];
[[], {
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);
_objectsLeft = lineIntersectsWith [eyePos ACE_player, _posCheck, ACE_player, objNull, false];
_intersectsLeft = false;
{
if (_x isKindOf "Static") exitWith {_intersectsLeft = true};
} count _objectsLeft;
private _intersections = lineIntersectsSurfaces [_startPosASL, _endPosASL, ACE_player, objNull, true, 1, "FIRE", "GEOM"];
if (!_intersectsLeft) exitWith {false};
// If there's no intersections
if (_intersections isEqualTo []) exitWith {false};
(_intersections select 0) params ["", "", "", "_object"];
_posCheck = ACE_player modelToWorldVisual [0.5, 2, 0];
_posCheck set [2, (eyePos ACE_player) select 2];
// Exit if trying to tag a non static object
TRACE_1("Obj:",_intersections);
if (!isNull _object && {!(_object isKindOf "Static")}) exitWith {false};
_objectsRight = lineIntersectsWith [eyePos ACE_player, _posCheck, ACE_player, objNull, false];
_intersectsRight = false;
{
if (_x isKindOf "Static") exitWith {_intersectsRight = true};
} count _objectsRight;
//for readability...
(_intersectsLeft && _intersectsRight)
true
}, missionNamespace, QGVAR(checkTaggableCache), 0.5] call EFUNC(common,cachedCall);

View File

@ -0,0 +1,56 @@
/*
* Author: BaerMitUmlaut and esteldunedain
* Creates a tag and handle its destruction. Only execute on the server.
*
* Arguments:
* 0: Position ASL <ARRAY>
* 1: Vector dir and up <ARRAY>
* 2: Colour of the tag (valid colours are black, red, green and blue) <STRING>
* 3: Object it should be tied too <OBJECT>
*
* 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
// 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 = [tags];
_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), []];
};
}];

View File

@ -1,38 +0,0 @@
/*
* Author: BaerMitUmlaut
* Handles tag destruction when the object they are attached to gets destroyed.
*
* Arguments:
* 0: The tag that should get destroyed <OBJECT>
* 1: The object the tag is attached to <OBJECT>
*
* Return Value:
* None
*
* Example:
* [tag, object] call ace_tagging_fnc_handleTagDestruction
*
* Public: No
*/
#include "script_component.hpp"
private ["_tag", "_attachedTags", "_object"];
params ["_tag", "_object"];
if (count (_object getVariable [QGVAR(attachedTags), []]) == 0) then {
_object setVariable [QGVAR(attachedTags), [_tag]];
_object addEventHandler ["HandleDamage", {
if ((_this select 1) == "" && (_this select 2) >= 1) then {
{
deleteVehicle _x;
} foreach ((_this select 0) getVariable ["ace_tagging_attachedTags", []]);
(_this select 0) setVariable ["ace_tagging_attachedTags", []];
};
}];
} else {
_attachedTags = _object getVariable [QGVAR(attachedTags), []];
_attachedTags pushBack _tag;
_object setVariable [QGVAR(attachedTags), _attachedTags];
};

View File

@ -0,0 +1,92 @@
/*
* 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 <ARRAY>
* 2: End position ASL <ARRAY>
* 3: The colour of the tag (valid colours are black, red, green and blue) <STRING>
*
* Return Value:
* Sucess <BOOLEAN>
*
* 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 && {!(_object isKindOf "Static")}) 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_1("Unit:", _unit);
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

View File

@ -1,53 +1,25 @@
/*
* Author: BaerMitUmlaut
* Creates a tag on a wall that is within 2m on front of the player.
* Author: BaerMitUmlaut and esteldunedain
* Creates a tag on the ground beneath the unit
*
* Arguments:
* 0: The colour of the tag (valid colours are black, red, green and blue) <STRING>
*
* 0: Unit <OBJECT>
* 1: The colour of the tag (valid colours are black, red, green and blue) <STRING>
*
* Return Value:
* None
*
* Example:
* ["blue"] call ace_tagging_fnc_tagGround
* [player, "blue"] call ace_tagging_fnc_tagGround
*
* Public: No
*/
#include "script_component.hpp"
private ["_tagPos", "_groundPos", "_vectorDirAndUp"];
params ["_color"];
if !((toLower _color) in ["black", "red", "green", "blue"]) exitWith {
["%1 is not a valid tag colour.", _color] call BIS_fnc_error;
};
params ["_unit", "_color"];
_tagPos = ACE_player modelToWorld [0, 1.2, 0];
_vectorDirAndUp = [];
private _startPosASL = getPosASL _unit;
private _endPosASL = _startPosASL vectorAdd [0, 0, -2] vectorAdd eyeDirection _unit;
_groundPos = getPosATL ACE_player;
_groundPos set [2, 0];
//Check if we're in or on top of some object
if (lineIntersects [getPosASL ACE_player, ATLToASL _groundPos, ACE_player, objNull]) then {
_tagPos set [2, (getPosATL ACE_player) select 2];
_vectorDirAndUp = [[0,0,-1], vectorDir ACE_player];
} else {
_tagPos set [2, 0];
_vectorDirAndUp = [(surfaceNormal _tagPos) vectorMultiply -1, vectorDir ACE_player];
};
ACE_player playActionNow "PutDown";
[{
private ["_tag"];
params ["_tagPos", "_vectorDirAndUp", "_color"];
playSound3D [QUOTE(PATHTO_R(sounds\spray.ogg)), ACE_player, false, (eyePos ACE_player), 10, 1, 15];
_tag = "UserTexture1m_F" createVehicle [0,0,0];
_tag setObjectTextureGlobal [0, '\z\ace\addons\tagging\UI\tags\' + _color + '\' + str (floor (random 3)) + '.paa'];
_tag setPosATL _tagPos;
_tag setVectorDirAndUp _vectorDirAndUp;
}, [_tagPos, _vectorDirAndUp, _color], 0.6] call EFUNC(common,waitAndExecute);
[_unit, _startPosASL, _endPosASL, _color] call FUNC(tagDirection);

View File

@ -1,46 +1,27 @@
/*
* Author: BaerMitUmlaut
* Creates a tag on a wall that is on the closest surface within 2m on front of the player.
* 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: The colour of the tag (valid colours are black, red, green and blue) <STRING>
*
* 0: Unit <OBJECT>
* 1: The colour of the tag (valid colours are black, red, green and blue) <STRING>
*
* Return Value:
* None
*
* Example:
* ["blue"] call ace_tagging_fnc_tagWall
* [player, "blue"] call ace_tagging_fnc_tagWall
*
* Public: No
*/
#include "script_component.hpp"
private ["_posIntersect"];
params ["_color"];
if !((toLower _color) in ["black", "red", "green", "blue"]) exitWith {
["%1 is not a valid tag colour.", _color] call BIS_fnc_error;
};
params ["_unit", "_color"];
_posIntersect = ACE_player modelToWorldVisual [0, 2, 0];
_posIntersect set [2, (eyepos ACE_player) select 2];
((lineIntersectsSurfaces [eyepos ACE_player, _posIntersect, ACE_player, objNull, true, 1, "FIRE", "GEOM"]) select 0) params ["_touchingPoint", "_surfaceNormal", "", "_object"];
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);
ACE_player playActionNow "PutDown";
[{
private ["_tag"];
params ["_touchingPoint", "_surfaceNormal", "_color", "_object"];
playSound3D [QUOTE(PATHTO_R(sounds\spray.ogg)), ACE_player, false, (eyePos ACE_player), 10, 1, 15];
_tag = "UserTexture1m_F" createVehicle [0,0,0];
_tag setObjectTextureGlobal [0, '\z\ace\addons\tagging\UI\tags\' + _color + '\' + str (floor (random 3)) + '.paa'];
//Add 6cm so it doesn't get placed "into" the wall.
//6cm works with most building surfaces, but not with all of them. The LODs precision varies between 1cm and around 8cm+.
_tag setPosASL (_touchingPoint vectorAdd (_surfaceNormal vectorMultiply 0.06));
_tag setVectorDirAndUp [(_surfaceNormal vectorMultiply -1), [0,0,1]];
[[_tag, _object], QUOTE(FUNC(handleTagDestruction)), 1] call EFUNC(common,execRemoteFnc);
}, [_touchingPoint, _surfaceNormal, _color, _object], 0.6] call EFUNC(common,waitAndExecute);
[_unit, _startPosASL, _endPosASL, _color] call FUNC(tagDirection);

View File

@ -1,6 +1,9 @@
#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
@ -9,4 +12,4 @@
#define DEBUG_SETTINGS DEBUG_SETTINGS_BLANK
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -2,20 +2,20 @@
<Project name="ACE">
<Package name="Tagging">
<Key ID="STR_ACE_tagging_tagWallBlack">
<English>Tag wall black</English>
<German>Wand schwarz markieren</German>
<English>Tag black</English>
<German>Schwarz markieren</German>
</Key>
<Key ID="STR_ACE_tagging_tagWallRed">
<English>Tag wall red</English>
<German>Wand rot markieren</German>
<English>Tag red</English>
<German>Rot markieren</German>
</Key>
<Key ID="STR_ACE_tagging_tagWallGreen">
<English>Tag wall green</English>
<German>Wand grün markieren</German>
<English>Tag green</English>
<German>Grün markieren</German>
</Key>
<Key ID="STR_ACE_tagging_tagWallBLue">
<English>Tag wall blue</English>
<German>Wand blau markieren</German>
<English>Tag blue</English>
<German>Blau markieren</German>
</Key>
<Key ID="STR_ACE_tagging_tagGroundBlack">
<English>Tag ground black</English>
@ -54,4 +54,4 @@
<German>Eine Farbsprühdose um Wände zu markieren.</German>
</Key>
</Package>
</Project>
</Project>