diff --git a/src/TerraSharp/Core/Hotkeys.cs b/src/TerraSharp/Core/Hotkeys.cs index cbe6467..9987a49 100644 --- a/src/TerraSharp/Core/Hotkeys.cs +++ b/src/TerraSharp/Core/Hotkeys.cs @@ -76,6 +76,7 @@ public static class Hotkeys Toggle("World", "FreezeTime", "Freeze Time", () => Settings.FreezeTime, v => Settings.FreezeTime = v), Toggle("World", "SpawnRate", "Spawn Rate", () => Settings.SpawnRateBoost, v => Settings.SpawnRateBoost = v), new("World", "SavePosition", "Save Current Position", Waypoints.AddHere), + new("World", "RevealMap", "Reveal Map", MapFeatures.StartReveal), ]; // Windows virtual-key codes for mouse buttons; XNA's Keys leaves them unassigned. diff --git a/src/TerraSharp/Features/MapFeatures.cs b/src/TerraSharp/Features/MapFeatures.cs new file mode 100644 index 0000000..ea97b61 --- /dev/null +++ b/src/TerraSharp/Features/MapFeatures.cs @@ -0,0 +1,48 @@ +using System; +using Terraria; + +namespace TerraSharp.Features; + +public static class MapFeatures +{ + const int ColumnsPerTick = 24; + + // MapHelper.GetBackgroundType samples map tiles up to 36 away; WorldMap.UnlockMapSection keeps the same margin. + const int Margin = 40; + + static int _revealColumn = -1; + + public static bool Revealing => _revealColumn >= 0; + + public static float RevealProgress => Revealing ? (_revealColumn - Margin) / (float)(Main.maxTilesX - 2 * Margin) : 0f; + + public static void StartReveal() => _revealColumn = Margin; + + // Main.DoUpdate postfix. + public static void Update() + { + if (Main.gameMenu) + { + _revealColumn = -1; + return; + } + + RevealStep(); + } + + // A large world is about 20 million map tiles, so the reveal is spread over ticks. + static void RevealStep() + { + if (_revealColumn < 0) + return; + + int start = _revealColumn, end = Math.Min(Main.maxTilesX - Margin, start + ColumnsPerTick); + _revealColumn = end < Main.maxTilesX - Margin ? end : -1; + for (int x = start; x < end; x++) + for (int y = Margin; y < Main.maxTilesY - Margin; y++) + Main.Map.Update(x, y, byte.MaxValue); + + if (_revealColumn < 0) + Main.refreshMap = true; + } +} diff --git a/src/TerraSharp/Patches/MainPatches.cs b/src/TerraSharp/Patches/MainPatches.cs index 5f44888..58fa809 100644 --- a/src/TerraSharp/Patches/MainPatches.cs +++ b/src/TerraSharp/Patches/MainPatches.cs @@ -44,6 +44,7 @@ internal static class MainUpdatePatch Hotkeys.Update(); Sandbox.NewTick(); WorldFeatures.Update(); + MapFeatures.Update(); Settings.AutoSave(); Profiler.EndTick(); } diff --git a/src/TerraSharp/UI/MainWindow.Pages.cs b/src/TerraSharp/UI/MainWindow.Pages.cs index 6ea1c47..436b957 100644 --- a/src/TerraSharp/UI/MainWindow.Pages.cs +++ b/src/TerraSharp/UI/MainWindow.Pages.cs @@ -251,6 +251,10 @@ public sealed partial class MainWindow if (WorldFeatures.InvasionName is { } active && Buttons($"Stop {active}") == 0) WorldFeatures.StopInvasion(); + Group("Map"); + if (Buttons(MapFeatures.Revealing ? $"Revealing... {MapFeatures.RevealProgress:0%}" : "Reveal Map") == 0 && !MapFeatures.Revealing) + MapFeatures.StartReveal(); + Group("Spawning"); Note(NpcSpawner.Multiplayer ? "Multiplayer: boss summons only, spawn rate is ignored." : "Spawn rate only affects single player."); if (Toggle("Spawn Rate", ref Settings.SpawnRateBoost)) diff --git a/src/TerraSharp/UI/MainWindow.Tooltips.cs b/src/TerraSharp/UI/MainWindow.Tooltips.cs index bdaf37d..537706f 100644 --- a/src/TerraSharp/UI/MainWindow.Tooltips.cs +++ b/src/TerraSharp/UI/MainWindow.Tooltips.cs @@ -57,6 +57,7 @@ public sealed partial class MainWindow ["Biome Sight"] = "Makes Corruption, Crimson and Hallow blocks glow.", ["Full Bright"] = "Lights everything at full brightness.", ["Extended Zoom"] = "Zoom in up to 8x and out until the edge of what the game draws.", + ["Reveal Map"] = "Reveals the whole map. Multiplayer only reveals areas the server has sent.", ["Full Heal"] = "Refills health and mana.", ["TP to Spawn"] = "Recalls like a Magic Mirror: to your bed if set, otherwise the world's spawn point.", ["Reset Learned Ballistics"] = "Clears learned projectile data. Learns it again as you shoot.",