2[WorkbenchToolAttribute(
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
14 [
Attribute(defvalue:
"0 0 0",
desc:
"Position in world space to set the camera position to.",
category:
"Coordinates")]
17 [
Attribute(defvalue:
"0 0 0",
desc:
"Pitch, yaw, roll to set the camera rotation to.",
category:
"Coordinates")]
18 protected vector m_vRotation;
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;
27 [
Attribute(defvalue:
"0",
desc:
"Use full link and save/load world, otherwise only save/load coordinates",
category:
"Data")]
28 protected bool m_bUseFullLink;
31 protected ref array<ref SCR_CoordsTool_CoordsEntry>
m_aEntries;
33 protected static const float MIN_CAMERA_Y = 5;
34 protected static const string WEB_PREFIX =
"https://enfusionengine.com/api/redirect?to=";
36 protected static const string PLUGIN_NAME =
"Coords Tool";
42 protected void SetCamera(vector pos, vector rot)
44 vector yawPitchRoll = { rot[1], rot[0], rot[2] };
45 vector lookDirection = yawPitchRoll.AnglesToVector();
46 m_API.SetCamera(pos, lookDirection);
57 protected bool GetCoordsFromInput(
string input, out vector pos, out vector rot)
63 if (GetCoordsFromString(input, pos, rot))
66 if (GetCoordsFromMapCoordsString(input, pos, rot))
73 protected bool GetCoordsFromString(
string input, out vector pos, out vector rot)
75 input.Replace(WEB_PREFIX,
"");
79 if (input.Contains(
";") && input.StartsWith(
"enfusion"))
81 int separatorIndex = input.IndexOf(
";");
82 input = input.Substring(separatorIndex + 1, input.Length() - separatorIndex - 1);
86 array<string> values = {};
87 input.Split(
";", values,
true);
90 int length = values.Count();
95 string posString = values[0];
96 posString.Replace(
",",
" ");
97 if (SCR_StringHelper.IsEmptyOrWhiteSpace(posString))
100 pos = posString.ToVector();
103 string rotString = values[1];
104 if (!rotString.IsEmpty())
106 rotString.Replace(
",",
" ");
107 rot = rotString.ToVector();
115 protected bool GetCoordsFromMapCoordsString(
string input, out vector pos, out vector rot)
120 string mapCoordinates = SCR_StringHelper.Filter(input, SCR_StringHelper.DIGITS);
121 int length = mapCoordinates.Length();
126 int halfLength = length * 0.5;
127 int leftCoords = mapCoordinates.Substring(0, halfLength).ToInt();
128 int rightCoords = mapCoordinates.Substring(halfLength, halfLength).ToInt();
130 float multiplier = Math.Pow(10, 5 - halfLength);
134 pos = { leftCoords * multiplier + 0.5 * multiplier, 0, rightCoords * multiplier };
135 pos[1] = m_API.GetTerrainSurfaceY(pos[0], pos[2]);
137 if (multiplier < MIN_CAMERA_Y)
138 multiplier = MIN_CAMERA_Y;
143 pos[1] = pos[1] + multiplier;
145 PrintFormat(
"Parsed game coordinates: %1 %2", leftCoords.ToString(halfLength), rightCoords.ToString(halfLength), level:
LogLevel.NORMAL);
157 string link = SCR_WorldEditorToolHelper.GetCurrentWorldEditorLink();
167 int semicolonIndex = link.IndexOf(
";");
168 if (semicolonIndex > -1)
169 link = link.Substring(semicolonIndex + 1, link.Length() - semicolonIndex - 1);
172 foreach (
int i, SCR_CoordsTool_CoordsEntry entry :
m_aEntries)
174 if (entry.m_sLink == link)
177 Print(
"Current position is the last entry",
LogLevel.NORMAL);
179 Print(
"Current position is already stored as entry #" + (i + 1),
LogLevel.NORMAL);
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;
189 UpdatePropertyPanel();
194 protected void NavigateToClipboardLink()
196 string input = System.ImportFromClipboard();
198 if (!GetCoordsFromInput(input, pos, rot))
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)",
209 if (m_bUseFullLink && input.StartsWith(
"enfusion://WorldEditor/"))
212 m_API.GetWorldPath(worldPath);
213 if (worldPath.StartsWith(
"$"))
214 worldPath =
"~" + worldPath.Substring(1, worldPath.Length() - 1);
216 if (!input.Contains(worldPath))
218 input = input.Substring(23, input.Length() - 23);
219 int charIndex = input.IndexOf(
";");
221 input = input.Substring(0, charIndex);
223 charIndex = input.IndexOf(
"~");
226 charIndex = input.IndexOfFrom(charIndex,
":");
228 input = input.Substring(charIndex + 1, input.Length() - charIndex - 1);
231 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
232 worldEditor.SetOpenedResource(input);
242 protected void NavigateToCoords()
245 if (GetCoordsFromMapCoordsString(m_sMapCoordinates, pos, rot))
256class SCR_CoordsTool_CoordsEntry
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
Widget AddEntry(ResourceName entryPath, SCR_WorkshopItemActionDownload action)
Add new widget in category based based on category type.
SCR_Faction ScriptedFaction SCR_BaseContainerCustomTitleField("m_sCallsign")
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.
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