diff --git a/GuideMarker.cs b/GuideMarker.cs index d66be51..7e0bff6 100644 --- a/GuideMarker.cs +++ b/GuideMarker.cs @@ -191,6 +191,7 @@ private static void PaintMeridians(PlatformSystem platformSystem) } } + // This version doesn't seem to ever be called so I didn't bother to update it with the new system used in MinorMeridianPainter.cs private static void PaintMinorMeridians(PlatformSystem platformSystem) { var planetRadius = platformSystem.planet.radius; @@ -208,7 +209,7 @@ private static void PaintMinorMeridians(PlatformSystem platformSystem) if (PluginConfig.LatitudeOutOfBounds(lat)) continue; - for (var meridianOffset = -180; meridianOffset < 180; meridianOffset += interval) + for (var meridianOffset = -180; meridianOffset < 180; meridianOffset += Mathf.RoundToInt(interval)) { var lonOffsetMin = -1; diff --git a/LatLon.cs b/LatLon.cs index 1446fed..5f36451 100644 --- a/LatLon.cs +++ b/LatLon.cs @@ -13,7 +13,7 @@ namespace Bulldozer public float Lat => Precision == 1 ? _lat : _lat / (float) Precision; public float Long => Precision == 1 ? _lng : _lng / (float) Precision; - public static LatLon Empty => new (-1000, -1000, 1); + public static LatLon Empty => new (0, 0, 0); private static readonly Dictionary> PoolLatToLonToInstance = new(); public readonly int Precision; @@ -44,8 +44,8 @@ public static LatLon FromCoords(double lat, double lon, int precisionMultiple = throw new InvalidDataException("Invalid precision multiple " + precisionMultiple); } - int newLat = lat < 0 ? Mathf.CeilToInt((float)lat * precisionMultiple) : Mathf.FloorToInt((float)lat * precisionMultiple); - int newLon = lon < 0 ? Mathf.CeilToInt((float)lon * precisionMultiple) : Mathf.FloorToInt((float)lon * precisionMultiple); + int newLat = Mathf.RoundToInt((float)lat * precisionMultiple); + int newLon = Mathf.RoundToInt((float)lon * precisionMultiple); if (!PoolLatToLonToInstance.TryGetValue(newLat, out var lonLookup)) { lonLookup = new Dictionary(); @@ -62,7 +62,7 @@ public static LatLon FromCoords(double lat, double lon, int precisionMultiple = public bool Equals(LatLon other) { - return _lat == other._lat && _lng == other._lng; + return _lat == other._lat && _lng == other._lng && Precision == other.Precision; } public override bool Equals(object obj) @@ -90,7 +90,7 @@ public override int GetHashCode() public bool IsEmpty() { - return Precision == 0 || _lat == Empty._lat && _lng == Empty._lng; + return Precision == 0; } public override string ToString() @@ -98,7 +98,7 @@ public override string ToString() return $"{Lat},{Long}"; } - public LatLon Offset(int latOffset, int lonOffset) + public LatLon Offset(float latOffset, float lonOffset) { return FromCoords(Lat + latOffset, Long + lonOffset, Precision); } diff --git a/PluginConfig.cs b/PluginConfig.cs index 6302676..d0fc8a6 100644 --- a/PluginConfig.cs +++ b/PluginConfig.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Collections; using System.ComponentModel; using BepInEx.Configuration; @@ -52,8 +53,8 @@ public static class PluginConfig public static ConfigEntry factoryTeardownRunTimePerFrame; public static ConfigEntry soilPileConsumption; public static ConfigEntry foundationConsumption; - public static ConfigEntry maxLatitude; - public static ConfigEntry minLatitude; + public static ConfigEntry maxLatitude; + public static ConfigEntry minLatitude; // used to make UI checkbox values persistent public static ConfigEntry addGuideLines; @@ -64,7 +65,7 @@ public static class PluginConfig public static ConfigEntry addGuideLinesMeridian; public static ConfigEntry addGuideLinesTropic; public static ConfigEntry addGuideLinesPoles; - public static ConfigEntry minorMeridianInterval; + public static ConfigEntry minorMeridianInterval; public static ConfigEntry guideLinesEquatorColor; public static ConfigEntry guideLinesTropicColor; @@ -94,13 +95,13 @@ public static void InitConfig(ConfigFile configFile) { PluginConfigFile = configFile; - minLatitude = configFile.Bind("Control", "Min Latitude", -90, + minLatitude = configFile.Bind("Control", "Min Latitude", -90f, new ConfigDescription("Minimum latitude to work on. Set equal to Max Latitude to apply to entire planet", - new AcceptableValueRange(-90, 90))); + new AcceptableValueRange(-90f, 90f))); - maxLatitude = configFile.Bind("Control", "Max Latitude", 90, + maxLatitude = configFile.Bind("Control", "Max Latitude", 90f, new ConfigDescription("Max latitude to work on, set min and max to the same value to apply to entire planet", - new AcceptableValueRange(-90, 90))); + new AcceptableValueRange(-90f, 90f))); minLatitude.SettingChanged += OnMinLatitudeChange; maxLatitude.SettingChanged += OnMaxLatitudeChange; @@ -141,10 +142,10 @@ public static void InitConfig(ConfigFile configFile) "Enable/disable of the tropic guidelines individually. No effect if AddGuideLines is disabled"); addGuideLinesPoles = configFile.Bind("Decoration", "AddGuideLinesPoles", false, "Enable/disable painting polar areas. No effect if AddGuideLines is disabled. Poles are considered first 2 tropics"); - minorMeridianInterval = configFile.Bind("Decoration", "MinorMeridianInterval", 0, + minorMeridianInterval = configFile.Bind("Decoration", "MinorMeridianInterval", 0f, new ConfigDescription( "Paint meridians starting at 0 and incrementing by this value. E.g., a value of 10 would add a meridian line every 10 degrees 18, 36 total. 0 to disable", - new AcceptableValueRange(0, 89), "meridians")); + new AcceptableValueRange(0f, 120f), "meridians")); guideLinesEquatorColor = configFile.Bind("CustomColors", "Equator Color", 7, new ConfigDescription("Index of color in palette to paint equator. Default is green", new AcceptableValueRange(0, 31), "color")); @@ -196,7 +197,7 @@ public static void InitConfig(ConfigFile configFile) private static void OnMaxLatitudeChange(object sender, EventArgs e) { - if (sender is ConfigEntry entry && minLatitude.Value > entry.Value) + if (sender is ConfigEntry entry && minLatitude.Value > entry.Value) { minLatitude.Value = maxLatitude.Value; } @@ -204,9 +205,9 @@ private static void OnMaxLatitudeChange(object sender, EventArgs e) private static void OnMinLatitudeChange(object sender, EventArgs e) { - if (sender is ConfigEntry entry && maxLatitude.Value < entry.Value) + if (sender is ConfigEntry entry && maxLatitude.Value < entry.Value) { - maxLatitude.Value = entry.Value; + maxLatitude.Value = minLatitude.Value; } } @@ -300,7 +301,7 @@ public static string GetLatRangeString() maxLatDir = "° "; } - return $"{minlat}{latDir} - {maxlat}{maxLatDir}"; + return $"{minlat.ToString("F2", CultureInfo.CurrentCulture)}{latDir} - {maxlat.ToString("F2", CultureInfo.CurrentCulture)}{maxLatDir}"; } } } \ No newline at end of file diff --git a/PluginConfigWindow.cs b/PluginConfigWindow.cs index e50bdb4..b7310a3 100644 --- a/PluginConfigWindow.cs +++ b/PluginConfigWindow.cs @@ -226,6 +226,11 @@ private static void DrawSetting(ConfigEntryBase configEntry) descriptionAdded = DrawRangeField(configEntry); } + if (!descriptionAdded && configEntry.SettingType == typeof(float)) + { + descriptionAdded = DrawFloatRangeField(configEntry); + } + if (!descriptionAdded) { //something went wrong, default to text field @@ -283,6 +288,47 @@ private static bool DrawRangeField(ConfigEntryBase configEntry) return true; } + private static bool DrawFloatRangeField(ConfigEntryBase configEntry) + { + if (configEntry.Description.AcceptableValues is not AcceptableValueRange acceptableValueRange) + { + return false; + } + + GUILayout.BeginHorizontal(); + AcceptableValueRange acceptableValues = acceptableValueRange; + var converted = (float)configEntry.BoxedValue; + var leftValue = acceptableValues.MinValue; + var rightValue = acceptableValues.MaxValue; + + var result = GUILayout.HorizontalSlider(converted, leftValue, rightValue, GUILayout.MinWidth(200)); + if (Math.Abs(result - converted) > Mathf.Abs(rightValue - leftValue) / 1000) + { + var newValue = Convert.ChangeType(Mathf.Round(result / 0.36f) * 0.36f, configEntry.SettingType, CultureInfo.InvariantCulture); + configEntry.BoxedValue = newValue; + } + + var strVal = ((float)configEntry.BoxedValue).ToString("F2", CultureInfo.CurrentCulture); + var strResult = GUILayout.TextField(strVal, GUILayout.Width(50)); + + GUILayout.EndHorizontal(); + if (strResult != strVal) + { + try + { + var resultVal = float.Parse(strResult, NumberStyles.Any, CultureInfo.CurrentCulture); + var clampedResultVal = Mathf.Clamp(resultVal, leftValue, rightValue); + configEntry.BoxedValue = clampedResultVal; + } + catch (FormatException) + { + // Ignore user typing in bad data + } + } + + return true; + } + public static Color GetColorByIndex(int index) { if (index < 0 || index > 31) diff --git a/ReformIndexInfoProvider.cs b/ReformIndexInfoProvider.cs index 1817933..2fa507b 100644 --- a/ReformIndexInfoProvider.cs +++ b/ReformIndexInfoProvider.cs @@ -11,6 +11,7 @@ namespace Bulldozer public class ReformIndexInfoProvider { private const int LatitudesPerPass = 10; + public const int latLonPrecision = 1000; private readonly Dictionary _llLookup = new(); private readonly LatLon[] _llModLookup = new LatLon[GameMain.localPlanet.data.modData.Length * 2]; private readonly HashSet _tropicsLatitudes = new(); @@ -18,7 +19,7 @@ public class ReformIndexInfoProvider private readonly HashSet _meridians = new(); public PlatformSystem platformSystem; private bool _lookupsCreated; - private float _latLookupWorkItemIndex = -89.9f; + private float _latLookupWorkItemIndex; private int _initUpdateCounter; private int _planetId; private int prevLength = -1; @@ -27,6 +28,7 @@ public ReformIndexInfoProvider(PlatformSystem platformSystem) { this.platformSystem = platformSystem; _planetId = platformSystem.planet.id; + _latLookupWorkItemIndex = -90f + 90f / platformSystem?.latitudeCount ?? 500f; } public int PlanetId => _planetId; @@ -37,13 +39,14 @@ private void SetInitValues(PlatformSystem newPlatformSystem, int planetId) _llLookup.Clear(); Array.Clear(_llModLookup, 0, _llLookup.Count); _tropicsLatitudes.Clear(); + prevLength = -1; _equatorLatitudes[0] = LatLon.Empty; _equatorLatitudes[1] = LatLon.Empty; _meridians.Clear(); _lookupsCreated = false; _planetId = planetId; platformSystem = newPlatformSystem; - _latLookupWorkItemIndex = -89.9f; + _latLookupWorkItemIndex = -90f + 90f / platformSystem?.latitudeCount ?? 500f; _initUpdateCounter = 0; } @@ -124,7 +127,6 @@ public void DoInitWork(PlanetData planetData) var planetRawData = platformSystem.planet.data; var start = DateTime.Now; var maxRuntimeMS = GetMaxRuntimeMS(); - var latLonPrecision = planetData.realRadius < 250f ? 10 : 10; var latitudeCount = platformSystem.latitudeCount; var latDegIncrement = (90 * 2.0f) / latitudeCount; @@ -137,10 +139,15 @@ public void DoInitWork(PlanetData planetData) continue; prevStart = startNdx; var longitudeCounts = endNdxExclusive - startNdx; - if (longitudeCounts != prevLength) + if (longitudeCounts != prevLength && prevLength >= 0) { // got ourselves a new tropic here - _tropicsLatitudes.Add(LatLon.FromCoords(_latLookupWorkItemIndex, 0, latLonPrecision)); + // mark the north side of the tropic in the southern hemisphere and the south side in the northern hemisphere + // it might be better to switch these or add a setting to choose + if (_latLookupWorkItemIndex < 0) + _tropicsLatitudes.Add(LatLon.FromCoords(_latLookupWorkItemIndex, 0, latLonPrecision)); + else + _tropicsLatitudes.Add(LatLon.FromCoords(_latLookupWorkItemIndex - latDegIncrement, 0, latLonPrecision)); } var latCoord = LatLon.FromCoords(_latLookupWorkItemIndex, 0, latLonPrecision); @@ -173,7 +180,7 @@ public void DoInitWork(PlanetData planetData) { var numLongitudes = (endNdxExclusive - startNdx); // longitudes above this index are in going west from 0 - var maxPositiveLongitudeIndex = (endNdxExclusive + startNdx) / 2; + var maxPositiveLongitudeIndex = (endNdxExclusive + startNdx) / 2 - 1; var negCounts = numLongitudes / 2; var degPerIndex = 180f / negCounts; var longMod = numLongitudes / 4; @@ -181,7 +188,7 @@ public void DoInitWork(PlanetData planetData) { if (desired > maxPositiveLongitudeIndex) { - var longDegrees = degPerIndex * (desired - maxPositiveLongitudeIndex); + var longDegrees = degPerIndex * (desired - maxPositiveLongitudeIndex - 0.5f); _llLookup[desired] = LatLon.FromCoords(_latLookupWorkItemIndex, -longDegrees, latLonPrecision); var pos = GeoUtil.LatLonToPosition(_latLookupWorkItemIndex, -longDegrees, platformSystem.planet.realRadius); @@ -190,7 +197,7 @@ public void DoInitWork(PlanetData planetData) } else { - var longDegrees = degPerIndex * (desired - startNdx); + var longDegrees = degPerIndex * (desired - startNdx + 0.5f); _llLookup[desired] = LatLon.FromCoords(_latLookupWorkItemIndex, longDegrees, latLonPrecision); var pos = GeoUtil.LatLonToPosition(_latLookupWorkItemIndex, longDegrees, platformSystem.planet.realRadius); var currentDataIndex = planetRawData.QueryIndex(pos); @@ -216,7 +223,7 @@ public void DoInitWork(PlanetData planetData) } } - if (_latLookupWorkItemIndex > 89) + if (_latLookupWorkItemIndex >= 90) { _lookupsCreated = true; } @@ -249,18 +256,11 @@ public int InitPercentComplete() public (int offsetStartIndex, int offsetEndIndex) GetReformIndexesForLatitude(float latDegrees) { - double latInRads = Mathf.Deg2Rad * latDegrees; - var latIndex = (float)(latInRads / (Mathf.PI * 2)) * platformSystem.segment; - var scaledLat = Mathf.Round(latIndex * 10f); - var absScaledLat = Mathf.Abs(scaledLat); - var scaledLatFloat = scaledLat >= 0.0 ? absScaledLat : -absScaledLat; - var latitudeSeg = scaledLatFloat / 10f; - - var scaledLatSeg = latitudeSeg > 0.0 ? Mathf.CeilToInt(latitudeSeg * 5f) : Mathf.FloorToInt(latitudeSeg * 5f); var latCountsHalf = platformSystem.latitudeCount / 2; - var y = scaledLatSeg > 0 ? scaledLatSeg - 1 : latCountsHalf - scaledLatSeg - 1; - var startIndex = platformSystem.reformOffsets[y]; - var unscaledCount = PlatformSystem.DetermineLongitudeSegmentCount(Mathf.FloorToInt(Mathf.Abs(latitudeSeg)), platformSystem.segment); + var scaledLat = Mathf.FloorToInt(Mathf.Abs(latDegrees) * platformSystem.latitudeCount / 180f); + var latIndex = latDegrees >= 0 ? scaledLat : scaledLat + latCountsHalf; + var startIndex = platformSystem.reformOffsets[latIndex]; + var unscaledCount = PlatformSystem.DetermineLongitudeSegmentCount(scaledLat / 5, platformSystem.segment); var endIndex = startIndex + unscaledCount * 5; return (startIndex, endIndex); diff --git a/RegionColorConfig.cs b/RegionColorConfig.cs index f7fb194..6e6fb6a 100644 --- a/RegionColorConfig.cs +++ b/RegionColorConfig.cs @@ -7,10 +7,10 @@ namespace Bulldozer { public class RegionColorConfig { - public int minLatitude; - public int maxLatitude; - public int minLongitude; - public int maxLongitude; + public float minLatitude; + public float maxLatitude; + public float minLongitude; + public float maxLongitude; public bool mirror; public int colorIndex; @@ -18,36 +18,54 @@ public bool ContainsPosition(float lat, float lng) { bool allLatitudes = minLatitude == maxLatitude; bool allLongs = minLongitude == maxLongitude; - if (allLatitudes && allLongs) - { - return true; - } + + if (!(allLatitudes || (minLatitude <= lat && maxLatitude >= lat) || mirror && (-minLatitude >= lat && -maxLatitude <= lat))) + return false; + if (minLongitude <= maxLongitude) + return allLongs || minLongitude <= lng && maxLongitude >= lng; + else + return !(maxLongitude < lng && minLongitude > lng); + } - if (!allLatitudes && allLongs) - { - - bool defaultLatsMatch = (minLatitude <= lat && maxLatitude >= lat); - if (defaultLatsMatch) - return true; + public List GetRects() + { + var result = new List(); + + var minLat = minLatitude; + var maxLat = maxLatitude; + var minLng = minLongitude; + var maxLng = maxLongitude; + + if(minLatitude == maxLatitude) + { + minLat = -90; + maxLat = 90; + } + if(minLongitude == maxLongitude) + { + minLng = -180; + maxLng = 180; + } + + var height = maxLat - minLat; + if(minLongitude > maxLongitude) + { + result.Add(new Rect(minLng, minLat, 180 - minLng, height)); + result.Add(new Rect(-180, minLat, maxLng + 180, height)); if (mirror) - return (-minLatitude >= lat && -maxLatitude <= lat); - return false; + { + result.Add(new Rect(minLng, -maxLat, 180 - minLng, height)); + result.Add(new Rect(-180, -maxLat, maxLng + 180, height)); + } } - if (allLatitudes && !allLongs) - { - - bool defaultLonsMatch = (minLongitude <= lng && maxLongitude >= lng); - if (defaultLonsMatch) - return true; - return false; + else + { + result.Add(new Rect(minLng, minLat, maxLng - minLng, height)); + if(mirror) + result.Add(new Rect(minLng, -maxLat, maxLng - minLng, height)); } - - if ((minLatitude <= lat && maxLatitude >= lat) && (minLongitude <= lng && maxLongitude >= lng)) - return true; - if (!mirror) - return false; - return (-minLatitude >= lat && -maxLatitude <= lat) - && minLongitude <= lng && maxLongitude >= lng; + + return result; } } diff --git a/RegionColorWindow.cs b/RegionColorWindow.cs index ccef115..42f8575 100644 --- a/RegionColorWindow.cs +++ b/RegionColorWindow.cs @@ -171,30 +171,27 @@ private static void CheckOverlap() { _overlapCheckDirty = false; lastOverLapCheckFailed = false; - for (int i = -90; i < 90; i++) + + var regions = _regionalColors.GetRegions(); + for (int i = 0; i < regions.Count - 1; i++) { - for (int j = -180; j < 180; j++) + var aRects = regions[i].GetRects(); + for (int j = i + 1; j < regions.Count; j++) { - int matchCount = 0; - List regionMatchingIndex = new List(); - - var regions = _regionalColors.GetRegions(); - for (int ndx = 0; ndx < regions.Count; ndx++) - { - var region = regions[ndx]; - if (region.ContainsPosition(i, j)) - { - matchCount++; - regionMatchingIndex.Add(ndx); - } - } - - if (matchCount > 1) - { - lastOverLapCheckFailed = true; - // var matchingIndexes = string.Join(",", regionMatchingIndex); - // Log.Debug($"overlap on points {i}, {j}, {matchingIndexes}"); - } + var bRects = regions[j].GetRects(); + foreach(var a in aRects) + { + foreach(var b in bRects) + { + if(a.Overlaps(b)) + { + lastOverLapCheckFailed = true; + _lastOverlapCheck = DateTime.Now; + return; + } + } + } + } } @@ -229,7 +226,7 @@ private static void DrawColorConfig(RegionColorConfig regionalColor) GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); - DrawSetting("Max Longitude", -180, 180, ref regionalColor.maxLongitude, regionalColor.minLongitude); + DrawSetting("Max Longitude", -180, 180, ref regionalColor.maxLongitude); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); @@ -324,25 +321,21 @@ private static void DrawCustomColor(int regionalColorColorIndex, ref int current } } - private static void DrawSetting(string title, int minVal, int maxVal, ref int current, int actualMin = -1) + private static void DrawSetting(string title, float minVal, float maxVal, ref float current, float actualMin = -1) { GUILayout.Label(title); - var converted = (float)Convert.ToDouble(current, CultureInfo.InvariantCulture); - var leftValue = (float)Convert.ToDouble(minVal, CultureInfo.InvariantCulture); - var rightValue = (float)Convert.ToDouble(maxVal, CultureInfo.InvariantCulture); - - var result = GUILayout.HorizontalSlider(converted, leftValue, rightValue, GUILayout.MinWidth(200)); - int newVal = current; - if (Math.Abs(result - converted) > Mathf.Abs(rightValue - leftValue) / 1000) + var result = GUILayout.HorizontalSlider(current, minVal, maxVal, GUILayout.MinWidth(200)); + float newVal = current; + if (Math.Abs(result - current) > Mathf.Abs(maxVal - minVal) / 1000) { - newVal = (int)result; + newVal = Mathf.Round(result / 0.36f) * 0.36f; } - var strResult = GUILayout.TextField(newVal.ToString(CultureInfo.CurrentCulture), GUILayout.Width(50)); + var strResult = GUILayout.TextField(newVal.ToString("F2", CultureInfo.CurrentCulture), GUILayout.Width(50)); try { - var updatedFromTextBox = int.Parse(strResult, NumberStyles.Any); + var updatedFromTextBox = float.Parse(strResult, NumberStyles.Any, CultureInfo.CurrentCulture); if (updatedFromTextBox >= minVal && updatedFromTextBox <= maxVal) { newVal = updatedFromTextBox; diff --git a/SelectiveDecoration/MinorMeridianPainter.cs b/SelectiveDecoration/MinorMeridianPainter.cs index 5340578..6cf468f 100644 --- a/SelectiveDecoration/MinorMeridianPainter.cs +++ b/SelectiveDecoration/MinorMeridianPainter.cs @@ -6,61 +6,26 @@ namespace Bulldozer.SelectiveDecoration { public class MinorMeridianPainter : ISelectivePlanetDecorator { - private readonly HashSet _minorMeridianLongitudes = new(); + private readonly HashSet _minorMeridianPoints = new(); private static DecorationConfig _minorMeridianConfig; + private readonly ReformIndexInfoProvider infoProvider; - - public MinorMeridianPainter() + public MinorMeridianPainter(ReformIndexInfoProvider reformIndexInfoProvider) { + infoProvider = reformIndexInfoProvider; _minorMeridianConfig = new DecorationConfig(PluginConfig.guideLinesMinorMeridianColor.Value); InitMeridianLongitudes(); } - private LatLon _lastRequest = LatLon.Empty; - private bool _lastResult; - public DecorationConfig GetDecorationForLocation(LatLon location) { - if (Math.Abs(location.Lat) > SelectiveDecorationBuilder.POLE_LATITUDE_START) - return DecorationConfig.None; - if (DistanceFromMajorMeridian(location.Long) < 5) - return DecorationConfig.None; - if (location.Long < 0) - { - if (_minorMeridianLongitudes.Contains(Mathf.CeilToInt(location.Long))) - { - _lastRequest = location; - _lastResult = true; - return _minorMeridianConfig; - } - } - else if (_minorMeridianLongitudes.Contains(Mathf.FloorToInt(location.Long))) - { - _lastRequest = location; - _lastResult = true; - return _minorMeridianConfig; - } - - // before returning false see if there's a point in between the last request and this one that would work - if (_lastRequest.RawLat() == location.RawLat() && !_lastResult) - { - var delta = Mathf.Abs(_lastRequest.Long - location.Long) / 3.0f; - for (int j = 1; j <= 3; j++) - { - var inBetween = Mathf.MoveTowards(_lastRequest.Long, location.Long, delta * j); + // This check probably isn't needed now that the lines aren't thick and misaligned, but I left the logic intact just in case. + //if (DistanceFromMajorMeridian(location.Long) < 5) + // return DecorationConfig.None; - if (_minorMeridianLongitudes.Contains((int)inBetween)) - { - _lastRequest = location; - _lastResult = true; - return _minorMeridianConfig; - } - } - } - - _lastRequest = location; - _lastResult = false; + if (_minorMeridianPoints.Contains(location)) + return _minorMeridianConfig; return DecorationConfig.None; } @@ -80,19 +45,37 @@ private int DistanceFromMajorMeridian(float lon) private void InitMeridianLongitudes() { var interval = PluginConfig.minorMeridianInterval.Value; - for (int i = 0; i < 180; i += interval) - { - _minorMeridianLongitudes.Add(i); - } - - - for (int i = 0 - interval; i > -180; i -= interval) - { - _minorMeridianLongitudes.Add(i); + var segment = infoProvider.platformSystem.segment; + var precision = ReformIndexInfoProvider.latLonPrecision; + var latitudeCount = infoProvider.platformSystem.latitudeCount; + var latDegIncrement = (90 * 2.0f) / latitudeCount; + + for (float lat = latDegIncrement / 2; lat <= SelectiveDecorationBuilder.POLE_LATITUDE_START; lat += latDegIncrement) + { + var latSegment = Mathf.FloorToInt(lat * latitudeCount / 180f) / 5; + var lonDivisions = PlatformSystem.DetermineLongitudeSegmentCount(latSegment, segment) * 5; + var lonStep = 360f / lonDivisions; + + // arbitrary value of just over half a tile so that if the meridian is right between two tiles it gets both + // this could be used to adjust thickness of the line and might be better as a config option in the future + var proximityThreshold = lonStep * 0.501f; + + for (float meridianLon = 0f; meridianLon <= 180f; meridianLon += interval) + { + var minLon = (Mathf.Round((meridianLon - proximityThreshold) / lonStep) + 0.5) * lonStep; + var maxLon = (Mathf.Round((meridianLon + proximityThreshold) / lonStep) - 0.5) * lonStep; + + for(var tileLon = minLon; tileLon <= maxLon; tileLon += lonStep) + { + _minorMeridianPoints.Add(LatLon.FromCoords(lat, tileLon, precision)); + _minorMeridianPoints.Add(LatLon.FromCoords(-lat, tileLon, precision)); + _minorMeridianPoints.Add(LatLon.FromCoords(lat, -tileLon, precision)); + _minorMeridianPoints.Add(LatLon.FromCoords(-lat, -tileLon, precision)); + } + } } - var meridianVals = string.Join(",", _minorMeridianLongitudes); - Log.Debug($"minor meridians for {interval} are {meridianVals}"); + Log.Debug($"Marked {_minorMeridianPoints.Count} tiles as minor meridians. Average thickness: {_minorMeridianPoints.Count / Mathf.Floor(360f / interval) / latitudeCount}"); } public string ActionSummary() diff --git a/SelectiveDecoration/SelectiveDecorationBuilder.cs b/SelectiveDecoration/SelectiveDecorationBuilder.cs index bfbb290..b2589ad 100644 --- a/SelectiveDecoration/SelectiveDecorationBuilder.cs +++ b/SelectiveDecoration/SelectiveDecorationBuilder.cs @@ -2,7 +2,7 @@ { public static class SelectiveDecorationBuilder { - public static readonly int POLE_LATITUDE_START = 85; + public static readonly float POLE_LATITUDE_START = 84.6f; public static SelectivePlanetPainter Build(ReformIndexInfoProvider reformIndexInfoProvider) { var result = new SelectivePlanetPainter(reformIndexInfoProvider); @@ -24,7 +24,7 @@ public static SelectivePlanetPainter Build(ReformIndexInfoProvider reformIndexIn if (PluginConfig.minorMeridianInterval.Value > 0) { - result.Register(new MinorMeridianPainter()); + result.Register(new MinorMeridianPainter(reformIndexInfoProvider)); } if (PluginConfig.addGuideLinesTropic.Value)