Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_CoordsTool.c
Go to the documentation of this file.
1#ifdef WORKBENCH
2[WorkbenchToolAttribute(
3 PLUGIN_NAME,
4 "Navigate to input/clipboard link/coordinates with bookmarks."
5 + "\nTo use an entry, copy its link/coordinates and use \"Go to clipboard link\"."
6 + "\nTo copy the current camera's link, use the World Editor's Ctrl+Shift+L shortcut.",
7 awesomeFontCode: 0xF5A0)]
8class SCR_CoordsTool : WorldEditorTool
9{
10 /*
11 Coordinates
12 */
13
14 [Attribute(defvalue: "0 0 0", desc: "Position in world space to set the camera position to.", category: "Coordinates")]
15 protected vector m_vPosition;
16
17 [Attribute(defvalue: "0 0 0", desc: "Pitch, yaw, roll to set the camera rotation to.", category: "Coordinates")]
18 protected vector m_vRotation;
19
20 [Attribute(desc: "In-game map coordinates - if defined, clicking \"Go to coords\" goes to these coordinates (empty the field to get the Position field to work again)", category: "Coordinates")]
21 protected string m_sMapCoordinates;
22
23 /*
24 Data
25 */
26
27 [Attribute(defvalue: "0", desc: "Use full link and save/load world, otherwise only save/load coordinates", category: "Data")]
28 protected bool m_bUseFullLink;
29
30 [Attribute(desc: "Logged entries - most recent entry at the top", category: "Data")]
31 protected ref array<ref SCR_CoordsTool_CoordsEntry> m_aEntries;
32
33 protected static const float MIN_CAMERA_Y = 5;
34 protected static const string WEB_PREFIX = "https://enfusionengine.com/api/redirect?to=";
35
36 protected static const string PLUGIN_NAME = "Coords Tool";
37
38 //------------------------------------------------------------------------------------------------
42 protected void SetCamera(vector pos, vector rot)
43 {
44 vector yawPitchRoll = { rot[1], rot[0], rot[2] };
45 vector lookDirection = yawPitchRoll.AnglesToVector();
46 m_API.SetCamera(pos, lookDirection);
47
48 PrintFormat("Camera set to Position %1 Rotation %2", pos, rot, level: LogLevel.NORMAL);
49 }
50
51 //------------------------------------------------------------------------------------------------
57 protected bool GetCoordsFromInput(string input, out vector pos, out vector rot)
58 {
59 input.TrimInPlace();
60 if (!input)
61 return false;
62
63 if (GetCoordsFromString(input, pos, rot))
64 return true;
65
66 if (GetCoordsFromMapCoordsString(input, pos, rot))
67 return true;
68
69 return false;
70 }
71
72 //------------------------------------------------------------------------------------------------
73 protected bool GetCoordsFromString(string input, out vector pos, out vector rot)
74 {
75 input.Replace(WEB_PREFIX, "");
76
77 // Try parse as enflink to get coords
78 // enf link is world;pos;rot
79 if (input.Contains(";") && input.StartsWith("enfusion"))
80 {
81 int separatorIndex = input.IndexOf(";");
82 input = input.Substring(separatorIndex + 1, input.Length() - separatorIndex - 1);
83 }
84
85 // split coords into two
86 array<string> values = {};
87 input.Split(";", values, true);
88
89 // check validity
90 int length = values.Count();
91 if (length < 1)
92 return false;
93
94 // parse values
95 string posString = values[0];
96 posString.Replace(",", " ");
97 if (SCR_StringHelper.IsEmptyOrWhiteSpace(posString))
98 return false;
99
100 pos = posString.ToVector();
101 if (length > 1)
102 {
103 string rotString = values[1];
104 if (!rotString.IsEmpty())
105 {
106 rotString.Replace(",", " ");
107 rot = rotString.ToVector();
108 }
109 }
110
111 return true;
112 }
113
114 //------------------------------------------------------------------------------------------------
115 protected bool GetCoordsFromMapCoordsString(string input, out vector pos, out vector rot)
116 {
117 if (!input)
118 return false;
119
120 string mapCoordinates = SCR_StringHelper.Filter(input, SCR_StringHelper.DIGITS);
121 int length = mapCoordinates.Length();
122
123 if (length % 2 != 0)
124 return false;
125
126 int halfLength = length * 0.5;
127 int leftCoords = mapCoordinates.Substring(0, halfLength).ToInt();
128 int rightCoords = mapCoordinates.Substring(halfLength, halfLength).ToInt();
129
130 float multiplier = Math.Pow(10, 5 - halfLength); // 1000 for 00 00, 100 for 000 000, 10 for 0000 0000
131 // 1 for 00000 00000, 0.1 for 000000 000000
132
133 rot = { -45, 0, 0 };
134 pos = { leftCoords * multiplier + 0.5 * multiplier, 0, rightCoords * multiplier };
135 pos[1] = m_API.GetTerrainSurfaceY(pos[0], pos[2]);
136
137 if (multiplier < MIN_CAMERA_Y)
138 multiplier = MIN_CAMERA_Y;
139
140 if (pos[1] <= 0)
141 pos[1] = multiplier;
142 else
143 pos[1] = pos[1] + multiplier;
144
145 PrintFormat("Parsed game coordinates: %1 %2", leftCoords.ToString(halfLength), rightCoords.ToString(halfLength), level: LogLevel.NORMAL);
146
147 return true;
148 }
149
150 //------------------------------------------------------------------------------------------------
151 [ButtonAttribute("Add entry")]
152 protected void AddEntry()
153 {
154 if (!m_aEntries)
155 m_aEntries = {};
156
157 string link = SCR_WorldEditorToolHelper.GetCurrentWorldEditorLink();
158 if (link.IsEmpty())
159 {
160 Print("Error obtaining the link", LogLevel.WARNING);
161 return;
162 }
163
164 // FOR NOW strip world path as it is not useful
165 if (!m_bUseFullLink)
166 {
167 int semicolonIndex = link.IndexOf(";");
168 if (semicolonIndex > -1)
169 link = link.Substring(semicolonIndex + 1, link.Length() - semicolonIndex - 1);
170 }
171
172 foreach (int i, SCR_CoordsTool_CoordsEntry entry : m_aEntries)
173 {
174 if (entry.m_sLink == link)
175 {
176 if (i == 0)
177 Print("Current position is the last entry", LogLevel.NORMAL);
178 else
179 Print("Current position is already stored as entry #" + (i + 1), LogLevel.NORMAL);
180
181 return;
182 }
183 }
184
185 SCR_CoordsTool_CoordsEntry entry = new SCR_CoordsTool_CoordsEntry();
186 entry.m_sName = string.Format("Link #%1 (%2 world)", m_aEntries.Count() + 1, SCR_WorldEditorToolHelper.GetWorldName());
187 entry.m_sLink = link;
188 m_aEntries.InsertAt(entry, 0);
189 UpdatePropertyPanel();
190 }
191
192 //------------------------------------------------------------------------------------------------
193 [ButtonAttribute("Load clipboard")]
194 protected void NavigateToClipboardLink()
195 {
196 string input = System.ImportFromClipboard();
197 vector pos, rot;
198 if (!GetCoordsFromInput(input, pos, rot))
199 {
200 Print("Clipboard data is in invalid format. Expected:"
201 + "\n- enfusion link format \"enfusion://WorldEditor/world/path.ent;x,y,z(;pitch,yaw,roll)\""
202 + "\n- coordinates format: \"x,y,z(;pitch,yaw,roll)\""
203 + "\n- game map coordinates format e.g \"123 456\" (any even length, with or without space)",
204 LogLevel.WARNING);
205
206 return;
207 }
208
209 if (m_bUseFullLink && input.StartsWith("enfusion://WorldEditor/"))
210 {
211 string worldPath;
212 m_API.GetWorldPath(worldPath);
213 if (worldPath.StartsWith("$"))
214 worldPath = "~" + worldPath.Substring(1, worldPath.Length() - 1);
215
216 if (!input.Contains(worldPath)) // same world, no need to reload
217 {
218 input = input.Substring(23, input.Length() - 23);
219 int charIndex = input.IndexOf(";");
220 if (charIndex > -1)
221 input = input.Substring(0, charIndex);
222
223 charIndex = input.IndexOf("~");
224 if (charIndex > -1)
225 {
226 charIndex = input.IndexOfFrom(charIndex, ":");
227 if (charIndex > -1)
228 input = input.Substring(charIndex + 1, input.Length() - charIndex - 1);
229 }
230
231 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
232 worldEditor.SetOpenedResource(input);
233 }
234 }
235
236 SetCamera(pos, rot);
237 }
238
239 //------------------------------------------------------------------------------------------------
241 [ButtonAttribute("Go to coords")]
242 protected void NavigateToCoords()
243 {
244 vector pos, rot;
245 if (GetCoordsFromMapCoordsString(m_sMapCoordinates, pos, rot))
246 {
247 SetCamera(pos, rot);
248 return;
249 }
250
251 SetCamera(m_vPosition, m_vRotation);
252 }
253}
254
256class SCR_CoordsTool_CoordsEntry
257{
258 [Attribute()]
259 string m_sName;
260
261 [Attribute()]
262 string m_sLink;
263}
264#endif // WORKBENCH
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
vector m_vPosition
Widget AddEntry(ResourceName entryPath, SCR_WorkshopItemActionDownload action)
Add new widget in category based based on category type.
SCR_Faction ScriptedFaction SCR_BaseContainerCustomTitleField("m_sCallsign")
LocalizedString m_sName
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
ref array< ref SCR_VONEntry > m_aEntries
class WorkbenchDialog_AbortRetryIgnore ButtonAttribute("OK", true)
proto external bool SetCamera(CameraBase pCam)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
proto void PrintFormat(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL, LogLevel level=LogLevel.NORMAL)
SCR_FieldOfViewSettings Attribute