From 4614ee69a6f188911ca444738f1518f99f23be2f Mon Sep 17 00:00:00 2001 From: Kirill Andriiashin Date: Sat, 14 Sep 2024 01:27:14 +0300 Subject: [PATCH] Adjust helper functions to convert waypoints longer than 2 letters --- src/TSMapEditor/Helpers.cs | 49 ++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/TSMapEditor/Helpers.cs b/src/TSMapEditor/Helpers.cs index 10cd41391..52215e86c 100644 --- a/src/TSMapEditor/Helpers.cs +++ b/src/TSMapEditor/Helpers.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Text; using TSMapEditor.GameMath; using TSMapEditor.Models; using TSMapEditor.Models.Enums; @@ -174,38 +175,44 @@ public static int GetWaypointNumberFromAlphabeticalString(string str) if (string.IsNullOrEmpty(str)) return -1; - if (str.Length < 1 || str.Length > 2 || - str[0] < 'A' || str[0] > 'Z' || (str.Length == 2 && (str[1] < 'A' || str[1] > 'Z'))) - throw new InvalidOperationException("Waypoint values are only valid between A and ZZ. Invalid value: " + str); + const int charCount = 26; + str = str.ToUpperInvariant(); - if (str.Length == 1) - return str[0] - 'A'; + int n = 0; + for (int i = str.Length - 1, j = 1; i >= 0; i--, j *= charCount) + { + int c = str[i]; + + if (c is < 'A' or > 'Z') + throw new InvalidOperationException("Waypoints may only contain characters A through Z, invalid input: " + str); - const int CharCount = 26; + n += (c - '@') * j; // '@' = 'A' - 1 + } - int multiplier = (str[0] - 'A' + 1); - return (multiplier * CharCount) + (str[1] - 'A'); + return (n - 1); } public static string WaypointNumberToAlphabeticalString(int waypointNumber) { - if (waypointNumber < 0) - return string.Empty; - - const int WAYPOINT_MAX = 701; + Span buffer = stackalloc char[8]; + const int charCount = 26; - if (waypointNumber > WAYPOINT_MAX) - return "A"; // matches 0 - - const int CharCount = 26; + if (waypointNumber < 0) + return string.Empty; - int firstLetterValue = (waypointNumber / CharCount); - int secondLetterValue = waypointNumber % CharCount; + waypointNumber++; + int pos = buffer.Length; - if (firstLetterValue == 0) - return ((char)('A' + secondLetterValue)).ToString(); + while (waypointNumber > 0) + { + pos--; + int m = waypointNumber % charCount; + if (m == 0) m = charCount; + buffer[pos] = (char)(m + '@'); // '@' = 'A' - 1 + waypointNumber = (waypointNumber - m) / charCount; + } - return ((char)('A' + (firstLetterValue - 1))).ToString() + ((char)('A' + secondLetterValue)).ToString(); + return buffer.Slice(pos).ToString(); } private static Point2D[] visualDirectionToPointTable = new Point2D[]