Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ee0ba35
Add plotting tools
Timi007 Mar 6, 2025
d826afc
Fix return syntax
Timi007 Mar 6, 2025
9d7d0a5
Merge branch 'zen-mod:master' into plotting
Timi007 Mar 6, 2025
6b0e3bd
Fix attaching plots to objects
Timi007 Mar 6, 2025
7b31bb2
Use lines for radius
Timi007 Mar 6, 2025
ac1e521
Fix rectangular cuboid
Timi007 Mar 7, 2025
32e6f82
Remove obsolete files
Timi007 Mar 7, 2025
1e0e028
Add icons and localized text
Timi007 Mar 7, 2025
6ee55b2
Fix line width on map
Timi007 Mar 7, 2025
3fcd254
Add docs
Timi007 Mar 7, 2025
e3ac446
Improve icons
Timi007 Mar 9, 2025
ced4e49
Rename var
Timi007 Mar 9, 2025
b7b453e
Add measure distance from camera
Timi007 Mar 11, 2025
49a066d
Add max render distance
Timi007 Mar 11, 2025
9e82bc9
Add function to set active plot
Timi007 Mar 11, 2025
a6fa17d
Cleanup
Timi007 Mar 12, 2025
1fa239d
Fix key handlers not always register input
Timi007 Mar 12, 2025
7896fdf
Add undo keybind
Timi007 Mar 12, 2025
65bddc4
Fix pos in cylinder
Timi007 Mar 12, 2025
d458b3c
Cleanup
Timi007 Mar 12, 2025
17ae982
Replace nautical miles with yards
Timi007 Mar 12, 2025
681ce90
Add mile
Timi007 Mar 12, 2025
f28459b
Fix formatter sorting
Timi007 Mar 13, 2025
b12efd9
Remove _value
Timi007 Mar 13, 2025
87b831f
Remove yards and miles, change decimals based on distance, add thousa…
Timi007 Mar 25, 2025
6e50153
Add travel time to line plot
Timi007 Mar 25, 2025
726f83c
Add docs
Timi007 Mar 25, 2025
a889ec4
Show speed of unit if attached to it
Timi007 Mar 26, 2025
6acd716
Update docs
Timi007 Mar 26, 2025
743e11d
Limit attaching end points to one unit at a time
Timi007 Mar 26, 2025
dde0706
Update docs
Timi007 Mar 26, 2025
746d921
Fix speed for radius
Timi007 Mar 26, 2025
24411f2
Fix speed for radius
Timi007 Oct 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions addons/plotting/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x\zen\addons\plotting
39 changes: 39 additions & 0 deletions addons/plotting/CfgContext.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class EGVAR(context_menu,actions) {
class Plots {
displayName = CSTRING(DisplayName);
icon = QPATHTOF(ui\ruler.paa);
statement = QUOTE(call FUNC(selectPosition));
args = "LINE";
priority = 15;

class MeasureDistance {
displayName = CSTRING(MeasureDistance);
icon = QPATHTOF(ui\ruler.paa);
statement = QUOTE(call FUNC(selectPosition));
args = "LINE";
};
class MeasureDistanceFromCamera {
displayName = CSTRING(MeasureDistanceFromCamera);
icon = QPATHTOF(ui\ruler.paa);
statement = QUOTE([ARR_2(_args,curatorCamera)] call FUNC(setActivePlot));
args = "LINE";
};
class MeasureRadius {
displayName = CSTRING(MeasureRadius);
icon = QPATHTOF(ui\radius.paa);
statement = QUOTE(call FUNC(selectPosition));
args = "RADIUS";
};
class MeasureOffset {
displayName = CSTRING(MeasureOffset);
icon = QPATHTOF(ui\cuboid.paa);
statement = QUOTE(call FUNC(selectPosition));
args = "RECTANGLE";
};
class ClearPlots {
displayName = CSTRING(ClearPlots);
icon = "A3\3den\Data\Displays\Display3DEN\PanelLeft\entityList_delete_ca.paa";
statement = QUOTE([QQGVAR(plotsCleared)] call CBA_fnc_localEvent);
};
};
};
17 changes: 17 additions & 0 deletions addons/plotting/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
};
};

class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
};
};

class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
};
};
44 changes: 44 additions & 0 deletions addons/plotting/CfgFormatters.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class GVAR(formatters) {
// Formats distance: _this is distance in meters
class Distance {
class Meter {
formatter = QUOTE(FORMAT_1('%1 m',[ARR_3(_this,1,parseNumber (abs _this < 100))] call CBA_fnc_formatNumber));
priority = 100;
};
class Feet {
formatter = QUOTE(FORMAT_1('%1 ft',[ARR_3(_this * 3.281,1,0)] call CBA_fnc_formatNumber));
priority = 90;
};
};

// Formats custom speeds: _this is [distance (m), speed (m/s)]
class Speed {
class kmh {
formatter = QUOTE(call FUNC(formatSpeedKmh));
priority = 100;

// Defines static speeds for this format to cycle through when plot is not attached to object
// Must have at least one entry
speeds[] = {
3.333, // Unit with weapon lowered running in fast combat pace: takes ~12 km/h -> 3.333 m/s. This is with ACE mod loaded. Without ACE, the unit is a bit faster.
8.333, // Vehicle at 30 km/h
13.889, // Vehicle at 50 km/h
27.778, // Vehicle at 100 km/h
69.444, // Helicopter at 250 km/h
166.667, // Jet at 600 km/h
};
};
};

// Formats direction: _this is direction in the range 0..360 degrees.
class Azimuth {
class Degree {
formatter = QUOTE(FORMAT_1('%1°',_this toFixed 0));
priority = 100;
};
class NATOMil {
formatter = QUOTE(FORMAT_1('%1 mil',(_this * 17.7778) toFixed 0));
priority = 90;
};
};
};
19 changes: 19 additions & 0 deletions addons/plotting/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
PREP(addPlot);
PREP(clearPlots);
PREP(compileFormatters);
PREP(drawLine);
PREP(drawPlots);
PREP(drawRadius);
PREP(drawRectangle);
PREP(formatSpeedKmh);
PREP(formatTravelTime);
PREP(isPosInCylinder);
PREP(isValidPlot);
PREP(onDraw);
PREP(onDraw3D);
PREP(onKeyDown);
PREP(onLoad);
PREP(onMouseButtonDown);
PREP(onUnload);
PREP(selectPosition);
PREP(setActivePlot);
9 changes: 9 additions & 0 deletions addons/plotting/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "script_component.hpp"

if (hasInterface) then {
["zen_curatorDisplayLoaded", LINKFUNC(onLoad)] call CBA_fnc_addEventHandler;
["zen_curatorDisplayUnloaded", LINKFUNC(onUnload)] call CBA_fnc_addEventHandler;

[QGVAR(plotAdded), LINKFUNC(addPlot)] call CBA_fnc_addEventHandler;
[QGVAR(plotsCleared), LINKFUNC(clearPlots)] call CBA_fnc_addEventHandler;
};
38 changes: 38 additions & 0 deletions addons/plotting/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "script_component.hpp"

ADDON = false;

PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;

if (hasInterface) then {
GVAR(draw3DAdded) = false;

GVAR(plotTypes) = createHashMapFromArray [
["LINE", LINKFUNC(drawLine)],
["RADIUS", LINKFUNC(drawRadius)],
["RECTANGLE", LINKFUNC(drawRectangle)]
];

GVAR(currentDistanceFormatter) = 0;
GVAR(currentSpeedFormatter) = 0;
GVAR(currentSpeedIndex) = 0;
GVAR(currentAzimuthFormatter) = 0;

// Unique ID for creating plots
GVAR(nextID) = 0;
// Currently active plot shown at cursor in format [type, start]
GVAR(activePlot) = [];
// All plots, keys are IDs, values [type, start, end]
GVAR(plots) = createHashMap;
// All plot IDs ordered by creation time, last is newest
GVAR(history) = [];
};

call FUNC(compileFormatters);

#include "initSettings.inc.sqf"
#include "initKeybinds.inc.sqf"

ADDON = true;
3 changes: 3 additions & 0 deletions addons/plotting/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

#include "XEH_PREP.hpp"
21 changes: 21 additions & 0 deletions addons/plotting/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"zen_common", "zen_context_menu"};
author = ECSTRING(main,Author);
authors[] = {"Timi007"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};

PRELOAD_ADDONS;

#include "CfgEventHandlers.hpp"
#include "CfgContext.hpp"
#include "CfgFormatters.hpp"
40 changes: 40 additions & 0 deletions addons/plotting/functions/fnc_addPlot.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "script_component.hpp"
/*
* Authors: Timi007
* Adds a new plot to be drawn.
*
* Arguments:
* 0: Type of plot <STRING>
* 1: Start position ASL or attached object <ARRAY or OBJECT>
* 2: End position ASL or attached object <ARRAY or OBJECT>
*
* Return Value:
* ID of new plot or -1 on error <NUMBER>
*
* Example:
* ["RADIUS", player, [100, 100, 10]] call zen_plotting_fnc_addPlot
*
* Public: No
*/

params [
["_type", "LINE", [""]],
["_startPos", [0, 0, 0], [[], objNull], [3]],
["_endPos", [0, 0, 0], [[], objNull], [3]]
];

if (!(_type in GVAR(plotTypes)) || {_startPos isEqualTo objNull} || {_endPos isEqualTo objNull}) exitWith {-1};

private _id = GVAR(nextID);
GVAR(plots) set [_id, [_type, _startPos, _endPos]];
GVAR(history) pushBack _id;

GVAR(nextID) = GVAR(nextID) + 1;

if (_endPos isEqualType objNull) then {
_endPos setVariable [QGVAR(attachedPlot), _id];
};

TRACE_4("Plot added",_id,_type,_startPos,_endPos);

_id
19 changes: 19 additions & 0 deletions addons/plotting/functions/fnc_clearPlots.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "script_component.hpp"
/*
* Authors: Timi007
* Clears of plots.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call zen_plotting_fnc_clearPlots
*
* Public: No
*/

GVAR(plots) = createHashMap;
GVAR(history) = [];
50 changes: 50 additions & 0 deletions addons/plotting/functions/fnc_compileFormatters.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "script_component.hpp"
/*
* Authors: Timi007
* Compiles formatters from config and saves them in missionNamespace.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call zen_plotting_fnc_compileFormatters
*
* Public: No
*/

private _fnc_getFormatters = {
params ["_cfgFormatters"];

private _formatters = [];
{
private _entryConfig = _x;

private _formatterName = configName _entryConfig;
private _formatter = compile getText (_entryConfig >> "formatter");
private _priority = getNumber (_entryConfig >> "priority");
private _speeds = if (isArray (_entryConfig >> "speeds")) then {getArray (_entryConfig >> "speeds")} else {[]};

private _formatterEntry = [
_formatterName,
_formatter,
_priority,
_speeds
];

_formatters pushBack _formatterEntry;
} forEach configProperties [_cfgFormatters, "isClass _x", true];

[_formatters, 2, false] call CBA_fnc_sortNestedArray
};

private _cfgFormatters = configFile >> QGVAR(formatters);
private _distanceFormatters = [_cfgFormatters >> "Distance"] call _fnc_getFormatters;
private _speedFormatters = [_cfgFormatters >> "Speed"] call _fnc_getFormatters;
private _azimuthFormatters = [_cfgFormatters >> "Azimuth"] call _fnc_getFormatters;

missionNamespace setVariable [QGVAR(distanceFormatters), _distanceFormatters];
missionNamespace setVariable [QGVAR(speedFormatters), _speedFormatters];
missionNamespace setVariable [QGVAR(azimuthFormatters), _azimuthFormatters];
85 changes: 85 additions & 0 deletions addons/plotting/functions/fnc_drawLine.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "script_component.hpp"
/*
* Authors: Timi007
* Draws a line plot in 3D or on the map. Must be called every frame.
*
* Arguments:
* 0: Start position ASL or attached object <ARRAY or OBJECT>
* 1: End position ASL or attached object <ARRAY or OBJECT>
* 2: Visual properties <ARRAY>
* 0: Icon <STRING>
* 1: Color RGBA <ARRAY>
* 2: Scale <NUMBER>
* 3: Angle <NUMBER>
* 4: Line width <NUMBER>
* 3: Formatters <ARRAY>
* 0: Distance formatter <CODE>
* 1: Travel time formatter <CODE>
* 2: Azimuth formatter <CODE>
* 4: Additional arguments <ARRAY> (default: [])
* 5: Map control <CONTROL> (default: Draw in 3D)
*
* Return Value:
* None
*
* Example:
* [[0, 0, 0], [100, 100, 0], ["", [1, 0, 0, 1], 1, 0, 5], [{_this toFixed 0}, {[_this, 3.333] call FUNC(formatTravelTime)}, {_this toFixed 1}]] call zen_plotting_fnc_drawLine
*
* Public: No
*/

params ["_startPosOrObj", "_endPosOrObj", "_visualProperties", "_formatters", ["_args", [], [[]]], ["_ctrlMap", controlNull, [controlNull]]];
_visualProperties params ["_icon", "_color", "_scale", "_angle", "_lineWidth"];
_args params [["_speed", 0, [0]]];

// Don't draw start icon and line in 3D if Zeus camera is start pos
// Also don't use speed of camera
private _startPosIsNotCamera = curatorCamera isNotEqualTo _startPosOrObj;

private _startPos = _startPosOrObj;
if (_startPosOrObj isEqualType objNull) then {
_startPos = getPosASLVisual _startPosOrObj;

if (_startPosIsNotCamera) then {
_speed = velocityModelSpace _startPosOrObj select 1;
};
};

private _endPos = _endPosOrObj;
if (_endPosOrObj isEqualType objNull) then {
_endPos = getPosASLVisual _endPosOrObj;
};

private _distance = _startPos vectorDistance _endPos;
private _azimuth = _startPos getDir _endPos;

private _fnc_format = {
params ["_distance", "_speed", "_azimuth", "_formatters"];
_formatters params ["_fnc_formatDistance", "_fnc_formatTime", "_fnc_formatAzimuth"];

format ["%1 (%2) - %3",
_distance call _fnc_formatDistance,
[_distance, _speed] call _fnc_formatTime,
_azimuth call _fnc_formatAzimuth
]
};

if (isNull _ctrlMap) then { // 3D
private _camPos = getPosASL curatorCamera;

if (_startPosIsNotCamera && {CAN_RENDER_ICON(_camPos,_startPos)}) then {
drawIcon3D [_icon, _color, ASLToAGL _startPos, _scale, _scale, _angle];
};

if (_startPosIsNotCamera && {CAN_RENDER_LINE(_camPos,_startPos,_endPos)}) then {
drawLine3D [ASLToAGL _startPos, ASLToAGL _endPos, _color, _lineWidth];
};

if (CAN_RENDER_ICON(_camPos,_endPos)) then {
drawIcon3D [_icon, _color, ASLToAGL _endPos, _scale, _scale, _angle, [_distance, _speed, _azimuth, _formatters] call _fnc_format];
};
} else { // Map
_ctrlMap drawIcon [_icon, _color, _startPos, _scale, _scale, _angle];
_ctrlMap drawLine [_startPos, _endPos, _color];
_ctrlMap drawIcon [_icon, _color, _endPos, _scale, _scale, _angle, [_distance, _speed, _azimuth, _formatters] call _fnc_format];
};
Loading
Loading