mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Draw Straight Lines with maptool (#4410)
* Draw Straight Lines * Fix roamer sides, handle closing map mid-draw * Add missing privates / formula notes
This commit is contained in:
@ -7,4 +7,11 @@ class ACE_Settings {
|
|||||||
description = CSTRING(rotateModifierKey_description);
|
description = CSTRING(rotateModifierKey_description);
|
||||||
values[] = {"$STR_A3_OPTIONS_DISABLED", "ALT", "CTRL", "SHIFT"};
|
values[] = {"$STR_A3_OPTIONS_DISABLED", "ALT", "CTRL", "SHIFT"};
|
||||||
};
|
};
|
||||||
|
class GVAR(drawStaightLines) {
|
||||||
|
value = 1;
|
||||||
|
typeName = "BOOL";
|
||||||
|
isClientSettable = 1;
|
||||||
|
displayName = CSTRING(drawStaightLines_displayName);
|
||||||
|
description = CSTRING(drawStaightLines_description);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
PREP(calculateMapScale);
|
PREP(calculateMapScale);
|
||||||
PREP(canUseMapGPS);
|
PREP(canUseMapGPS);
|
||||||
PREP(canUseMapTools);
|
PREP(canUseMapTools);
|
||||||
|
PREP(drawLinesOnRoamer);
|
||||||
PREP(handleMouseButton);
|
PREP(handleMouseButton);
|
||||||
PREP(handleMouseMove);
|
PREP(handleMouseMove);
|
||||||
PREP(isInsideMapTool);
|
PREP(isInsideMapTool);
|
||||||
|
@ -30,5 +30,13 @@ GVAR(mapTool_isRotating) = false;
|
|||||||
} else {
|
} else {
|
||||||
// Hide GPS
|
// Hide GPS
|
||||||
[false] call FUNC(openMapGps);
|
[false] call FUNC(openMapGps);
|
||||||
|
|
||||||
|
// Handle closing map in middle of line drawing (it's never created)
|
||||||
|
GVAR(freedrawing) = false;
|
||||||
};
|
};
|
||||||
}] call CBA_fnc_addPlayerEventHandler;
|
}] call CBA_fnc_addPlayerEventHandler;
|
||||||
|
|
||||||
|
|
||||||
|
GVAR(freeDrawingData) = [];
|
||||||
|
GVAR(freedrawing) = false;
|
||||||
|
|
||||||
|
144
addons/maptools/functions/fnc_drawLinesOnRoamer.sqf
Normal file
144
addons/maptools/functions/fnc_drawLinesOnRoamer.sqf
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Author: PabstMirror
|
||||||
|
* Prevents the cursor from entering the roamer when drawing lines and records the positions
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: The Map <CONTROL>
|
||||||
|
* 1: Roamer Width <NUMBER>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Nothing
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [map, 300] call ace_maptools_fnc_drawLinesOnRoamer
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
if (!GVAR(drawStaightLines)) exitWith {};
|
||||||
|
|
||||||
|
params ["_theMap", "_roamerWidth"];
|
||||||
|
GVAR(mapTool_pos) params ["_roamerPosX", "_roamerPosY"];
|
||||||
|
|
||||||
|
private _posCenter = [_roamerPosX, _roamerPosY, 0];
|
||||||
|
|
||||||
|
private _posTopRight = [
|
||||||
|
_roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth,
|
||||||
|
_roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth,
|
||||||
|
0];
|
||||||
|
|
||||||
|
private _posTopLeft = [
|
||||||
|
_roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth,
|
||||||
|
_roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth,
|
||||||
|
0];
|
||||||
|
|
||||||
|
private _posBottomLeft = [
|
||||||
|
_roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth,
|
||||||
|
_roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth,
|
||||||
|
0];
|
||||||
|
|
||||||
|
private _posBottomRight = [
|
||||||
|
_roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth,
|
||||||
|
_roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth,
|
||||||
|
0];
|
||||||
|
|
||||||
|
private _fnc_Distance = { // Get distance point _p is from a line made from _a to _b (uses 3d array commands, but z should be 0)
|
||||||
|
// Ref: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation
|
||||||
|
params ["_a", "_b", "_p"];
|
||||||
|
private _n = _b vectorDiff _a;
|
||||||
|
private _pa = _a vectorDiff _p;
|
||||||
|
private _c = _n vectorMultiply ((_pa vectorDotProduct _n) / (_n vectorDotProduct _n));
|
||||||
|
private _d = _pa vectorDiff _c;
|
||||||
|
sqrt (_d vectorDotProduct _d);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _currentMousePos = _theMap ctrlMapScreenToWorld getMousePosition;
|
||||||
|
_currentMousePos set [2, 0];
|
||||||
|
|
||||||
|
// Break the roamer rectangle into 4 triangle, one for each side
|
||||||
|
switch (true) do {
|
||||||
|
case (_currentMousePos inPolygon [_posCenter, _posTopLeft, _posBottomLeft]): { // Left
|
||||||
|
private _distanceToRoamerLine = ([_posTopLeft, _posBottomLeft, _currentMousePos] call _fnc_Distance);
|
||||||
|
_currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) - 90) ,0] call CBA_fnc_polar2vect);
|
||||||
|
if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line
|
||||||
|
GVAR(freeDrawingData) = ["left", _currentMousePos, _currentMousePos];
|
||||||
|
} else {
|
||||||
|
if ((GVAR(freeDrawingData) select 0) == "left") then { // We are already drawing on this line, find best spot
|
||||||
|
if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then {
|
||||||
|
GVAR(freeDrawingData) set [1, _currentMousePos];
|
||||||
|
};
|
||||||
|
if ((_currentMousePos distance2d _posBottomLeft) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomLeft)) then {
|
||||||
|
GVAR(freeDrawingData) set [2, _currentMousePos];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos;
|
||||||
|
setMousePosition _screenPosOfCorrectedPos;
|
||||||
|
};
|
||||||
|
case (_currentMousePos inPolygon [_posCenter, _posTopLeft, _posTopRight]): { // Top
|
||||||
|
private _distanceToRoamerLine = ([_posTopLeft, _posTopRight, _currentMousePos] call _fnc_Distance);
|
||||||
|
_currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 0) ,0] call CBA_fnc_polar2vect);
|
||||||
|
if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line
|
||||||
|
GVAR(freeDrawingData) = ["top", _currentMousePos, _currentMousePos];
|
||||||
|
} else {
|
||||||
|
if ((GVAR(freeDrawingData) select 0) == "top") then { // We are already drawing on this line, find best spot
|
||||||
|
if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then {
|
||||||
|
GVAR(freeDrawingData) set [1, _currentMousePos];
|
||||||
|
};
|
||||||
|
if ((_currentMousePos distance2d _posTopRight) < ((GVAR(freeDrawingData) select 2) distance2d _posTopRight)) then {
|
||||||
|
GVAR(freeDrawingData) set [2, _currentMousePos];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos;
|
||||||
|
setMousePosition _screenPosOfCorrectedPos;
|
||||||
|
};
|
||||||
|
case (_currentMousePos inPolygon [_posCenter, _posTopRight, _posBottomRight]): { // Right
|
||||||
|
private _distanceToRoamerLine = ([_posTopRight, _posBottomRight, _currentMousePos] call _fnc_Distance);
|
||||||
|
_currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 90) ,0] call CBA_fnc_polar2vect);
|
||||||
|
if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line
|
||||||
|
GVAR(freeDrawingData) = ["right", _currentMousePos, _currentMousePos];
|
||||||
|
} else {
|
||||||
|
if ((GVAR(freeDrawingData) select 0) == "right") then { // We are already drawing on this line, find best spot
|
||||||
|
if ((_currentMousePos distance2d _posTopRight) < ((GVAR(freeDrawingData) select 1) distance2d _posTopRight)) then {
|
||||||
|
GVAR(freeDrawingData) set [1, _currentMousePos];
|
||||||
|
};
|
||||||
|
if ((_currentMousePos distance2d _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomRight)) then {
|
||||||
|
GVAR(freeDrawingData) set [2, _currentMousePos];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos;
|
||||||
|
setMousePosition _screenPosOfCorrectedPos;
|
||||||
|
};
|
||||||
|
case (_currentMousePos inPolygon [_posCenter, _posBottomLeft, _posBottomRight]): { // Bottom
|
||||||
|
private _distanceToRoamerLine = ([_posBottomLeft, _posBottomRight, _currentMousePos] call _fnc_Distance);
|
||||||
|
_currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 180) ,0] call CBA_fnc_polar2vect);
|
||||||
|
if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line
|
||||||
|
GVAR(freeDrawingData) = ["bottom", _currentMousePos, _currentMousePos];
|
||||||
|
} else {
|
||||||
|
if ((GVAR(freeDrawingData) select 0) == "bottom") then { // We are already drawing on this line, find best spot
|
||||||
|
if ((_currentMousePos distance2d _posBottomLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posBottomLeft)) then {
|
||||||
|
GVAR(freeDrawingData) set [1, _currentMousePos];
|
||||||
|
};
|
||||||
|
if ((_currentMousePos distance2d _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomRight)) then {
|
||||||
|
GVAR(freeDrawingData) set [2, _currentMousePos];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos;
|
||||||
|
setMousePosition _screenPosOfCorrectedPos;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef DEBUG_MODE_FULL
|
||||||
|
_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posTopRight,24,24,getDir player,'1,1',1,0.03,'TahomaB','right'];
|
||||||
|
_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posTopLeft,24,24,getDir player,'-1,1',1,0.03,'TahomaB','right'];
|
||||||
|
_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posBottomLeft,24,24,getDir player,'-1,-1',1,0.03,'TahomaB','right'];
|
||||||
|
_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posBottomRight,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right'];
|
||||||
|
if !(GVAR(freeDrawingData) isEqualTo []) then {
|
||||||
|
_theMap drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 1,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right'];
|
||||||
|
_theMap drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 2,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right'];
|
||||||
|
};
|
||||||
|
#endif
|
@ -15,6 +15,51 @@ params ["_dir", "_params"];
|
|||||||
_params params ["_control", "_button", "_screenPosX", "_screenPosY", "_shiftKey", "_ctrlKey", "_altKey"];
|
_params params ["_control", "_button", "_screenPosX", "_screenPosY", "_shiftKey", "_ctrlKey", "_altKey"];
|
||||||
TRACE_2("params",_dir,_params);
|
TRACE_2("params",_dir,_params);
|
||||||
|
|
||||||
|
// Using line drawing
|
||||||
|
if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith {
|
||||||
|
if (GVAR(freedrawing) && {_dir == 0}) then {
|
||||||
|
GVAR(freedrawing) = false;
|
||||||
|
GVAR(drawPosEnd) = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY];
|
||||||
|
TRACE_1("Ending Line",GVAR(freedrawing),GVAR(drawPosEnd));
|
||||||
|
[{
|
||||||
|
if (allMapMarkers isEqualTo []) exitWith {};
|
||||||
|
private _markerName = allMapMarkers select (count allMapMarkers - 1);
|
||||||
|
private _markerPos = getMarkerPos _markerName;
|
||||||
|
private _distanceCheck = _markerPos distance2d GVAR(drawPosStart);
|
||||||
|
|
||||||
|
TRACE_3("Line Drawn",_markerName,_markerPos,_distanceCheck);
|
||||||
|
|
||||||
|
if (_distanceCheck > 1) exitWith {WARNING("Wrong Marker!");};
|
||||||
|
if ((count GVAR(freeDrawingData)) != 3) exitWith {TRACE_1("never touched roamer",GVAR(freeDrawingData));};
|
||||||
|
|
||||||
|
GVAR(freeDrawingData) params ["", "_startStraightPos", "_endStraightPos"];
|
||||||
|
_startStraightPos set [2, 0];
|
||||||
|
_endStraightPos set [2, 0];
|
||||||
|
|
||||||
|
// Convert marker to rectangle and change it's pos/size/dir
|
||||||
|
_markerName setMarkerShape "RECTANGLE";
|
||||||
|
|
||||||
|
private _difPos = _endStraightPos vectorDiff _startStraightPos;
|
||||||
|
private _mag = vectorMagnitude _difPos;
|
||||||
|
_markerName setMarkerPos (_startStraightPos vectorAdd (_difPos vectorMultiply 0.5));
|
||||||
|
_markerName setMarkerSize [10, _mag / 2];
|
||||||
|
_markerName setMarkerDir (_difPos call CBA_fnc_vectDir);
|
||||||
|
|
||||||
|
}, []] call CBA_fnc_execNextFrame;
|
||||||
|
} else {
|
||||||
|
if (_ctrlKey && {_dir == 1}) then {
|
||||||
|
GVAR(freeDrawingData) = [];
|
||||||
|
GVAR(freedrawing) = true;
|
||||||
|
GVAR(drawPosStart) = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY];
|
||||||
|
TRACE_2("Starting Line",GVAR(freedrawing),GVAR(drawPosStart));
|
||||||
|
} else {
|
||||||
|
GVAR(freedrawing) = false;
|
||||||
|
TRACE_1("weird - reseting",GVAR(freedrawing));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
private _handled = false;
|
private _handled = false;
|
||||||
|
|
||||||
// If it's not a left button event, exit
|
// If it's not a left button event, exit
|
||||||
|
@ -11,11 +11,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
#define TEXTURE_WIDTH_IN_M 6205
|
|
||||||
#define DIST_BOTTOM_TO_CENTER_PERC -0.33
|
|
||||||
#define DIST_TOP_TO_CENTER_PERC 0.65
|
|
||||||
#define DIST_LEFT_TO_CENTER_PERC 0.30
|
|
||||||
|
|
||||||
if (GVAR(mapTool_Shown) == 0) exitWith {false};
|
if (GVAR(mapTool_Shown) == 0) exitWith {false};
|
||||||
private _textureWidth = [TEXTURE_WIDTH_IN_M, TEXTURE_WIDTH_IN_M / 2] select (GVAR(mapTool_Shown) - 1);
|
private _textureWidth = [TEXTURE_WIDTH_IN_M, TEXTURE_WIDTH_IN_M / 2] select (GVAR(mapTool_Shown) - 1);
|
||||||
|
|
||||||
|
@ -12,10 +12,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
#define TEXTURE_WIDTH_IN_M 6205
|
|
||||||
#define CENTER_OFFSET_Y_PERC 0.1606
|
|
||||||
#define CONSTANT_SCALE 0.2
|
|
||||||
|
|
||||||
params ["_theMap"];
|
params ["_theMap"];
|
||||||
|
|
||||||
if ((GVAR(mapTool_Shown) == 0) || {!("ACE_MapTools" in items ACE_player)}) exitWith {};
|
if ((GVAR(mapTool_Shown) == 0) || {!("ACE_MapTools" in items ACE_player)}) exitWith {};
|
||||||
@ -30,6 +26,8 @@ if (GVAR(mapTool_Shown) == 1) then {
|
|||||||
_textureWidth = TEXTURE_WIDTH_IN_M / 2;
|
_textureWidth = TEXTURE_WIDTH_IN_M / 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (GVAR(freedrawing)) then {[_theMap, _textureWidth] call FUNC(drawLinesOnRoamer);};
|
||||||
|
|
||||||
// Update scale of both parts
|
// Update scale of both parts
|
||||||
getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"];
|
getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"];
|
||||||
private _scaleX = 32 * _textureWidth * CONSTANT_SCALE * (call FUNC(calculateMapScale));
|
private _scaleX = 32 * _textureWidth * CONSTANT_SCALE * (call FUNC(calculateMapScale));
|
||||||
|
@ -15,3 +15,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "\z\ace\addons\main\script_macros.hpp"
|
#include "\z\ace\addons\main\script_macros.hpp"
|
||||||
|
|
||||||
|
#define TEXTURE_WIDTH_IN_M 6205
|
||||||
|
#define CENTER_OFFSET_Y_PERC 0.1606
|
||||||
|
#define CONSTANT_SCALE 0.2
|
||||||
|
#define DIST_BOTTOM_TO_CENTER_PERC -0.33
|
||||||
|
#define DIST_TOP_TO_CENTER_PERC 0.65
|
||||||
|
#define DIST_LEFT_TO_CENTER_PERC 0.30
|
||||||
|
@ -158,5 +158,11 @@
|
|||||||
<Japanese>マップ ツールを回転させるキーを編集できます。</Japanese>
|
<Japanese>マップ ツールを回転させるキーを編集できます。</Japanese>
|
||||||
<Polish>Modyfikator pozwalający na obracanie narzędzi nawigacyjnych</Polish>
|
<Polish>Modyfikator pozwalający na obracanie narzędzi nawigacyjnych</Polish>
|
||||||
</Key>
|
</Key>
|
||||||
|
<Key ID="STR_ACE_MapTools_drawStaightLines_displayName">
|
||||||
|
<English>Draw straight lines with maptools</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_MapTools_drawStaightLines_description">
|
||||||
|
<English>Draw on the edge of maptools to draw straight lines. Note: Must hover at midpoint to delete.</English>
|
||||||
|
</Key>
|
||||||
</Package>
|
</Package>
|
||||||
</Project>
|
</Project>
|
||||||
|
Reference in New Issue
Block a user