From 082f369fe328138371d00be6ab5f7f50b3032860 Mon Sep 17 00:00:00 2001 From: Gustas <37534529+PunkPun@users.noreply.github.com> Date: Thu, 11 Sep 2025 13:21:21 +0300 Subject: [PATCH] Add smooth minimap to world movement --- OpenRA.Game/Graphics/Viewport.cs | 9 +++- OpenRA.Game/Graphics/WorldRenderer.cs | 12 +++++- OpenRA.Mods.Common/Widgets/RadarWidget.cs | 51 ++++++++++++++--------- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index f71a27c639..6b585a813d 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -250,7 +250,7 @@ namespace OpenRA.Graphics public CPos ViewToWorld(int2 view) { - var world = worldRenderer.Viewport.ViewToWorldPx(view); + var world = ViewToWorldPx(view); var map = worldRenderer.World.Map; var candidates = CandidateMouseoverCells(world).ToList(); @@ -337,6 +337,13 @@ namespace OpenRA.Graphics allCellsDirty = true; } + public void Center(float2 pos) + { + CenterLocation = worldRenderer.ScreenPosition(pos).Clamp(mapBounds); + cellsDirty = true; + allCellsDirty = true; + } + public void Scroll(float2 delta, bool ignoreBorders) { // Convert scroll delta from world-px to viewport-px diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index aa1e69afff..c3691ab7ec 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -384,12 +384,22 @@ namespace OpenRA.Graphics Game.Renderer.SetPalette(palette); } - // Conversion between world and screen coordinates + /// + /// Converts a world position to a screen position. + /// public float2 ScreenPosition(WPos pos) { return new float2((float)TileSize.Width * pos.X / TileScale, (float)TileSize.Height * (pos.Y - pos.Z) / TileScale); } + /// + /// Converts a world position to a screen position. + /// + public float2 ScreenPosition(float2 pos) + { + return new float2(TileSize.Width * pos.X / TileScale, TileSize.Height * pos.Y / TileScale); + } + public float3 Screen3DPosition(WPos pos) { // The projection from world coordinates to screen coordinates has diff --git a/OpenRA.Mods.Common/Widgets/RadarWidget.cs b/OpenRA.Mods.Common/Widgets/RadarWidget.cs index 769d18eedc..93252c14d8 100644 --- a/OpenRA.Mods.Common/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.Common/Widgets/RadarWidget.cs @@ -285,10 +285,12 @@ namespace OpenRA.Mods.Common.Widgets if (world == null || !hasRadar) return null; - var cell = MinimapPixelToCell(pos); - var worldPixel = worldRenderer.ScreenPxPosition(world.Map.CenterOfCell(cell)); - var location = worldRenderer.Viewport.WorldToViewPx(worldPixel); + var worldPos = MinimapPixelToWorldCoords(pos).ToInt2(); + var wpos = new WPos(worldPos.X, worldPos.Y, 0); + var cell = world.Map.CellContaining(wpos); + var worldPixel = worldRenderer.ScreenPxPosition(wpos); + var location = worldRenderer.Viewport.WorldToViewPx(worldPixel); var mi = new MouseInput { Location = location, @@ -311,33 +313,32 @@ namespace OpenRA.Mods.Common.Widgets if (!hasRadar) return true; - var cell = MinimapPixelToCell(mi.Location); - var pos = world.Map.CenterOfCell(cell); + var worldCoords = MinimapPixelToWorldCoords(mi.Location); if ((mi.Event == MouseInputEvent.Down || mi.Event == MouseInputEvent.Move) && mi.Button == Game.Settings.Game.MouseButtonPreference.Cancel) { - worldRenderer.Viewport.Center(pos); + worldRenderer.Viewport.Center(worldCoords); } - if (mi.Event == MouseInputEvent.Down && mi.Button == Game.Settings.Game.MouseButtonPreference.Action) + if (mi.Event == MouseInputEvent.Down && mi.Button == Game.Settings.Game.MouseButtonPreference.Action && WorldInteractionController != null) { + var worldPos = worldCoords.ToInt2(); + var wpos = new WPos(worldPos.X, worldPos.Y, 0); + // fake a mousedown/mouseup here - var location = worldRenderer.Viewport.WorldToViewPx(worldRenderer.ScreenPxPosition(pos)); + var location = worldRenderer.Viewport.WorldToViewPx(worldRenderer.ScreenPxPosition(wpos)); var fakemi = new MouseInput { Event = MouseInputEvent.Down, Button = Game.Settings.Game.MouseButtonPreference.Action, Modifiers = mi.Modifiers, - Location = location + Location = location, }; - if (WorldInteractionController != null) - { - var controller = Ui.Root.Get(WorldInteractionController); - controller.HandleMouseInput(fakemi); - fakemi.Event = MouseInputEvent.Up; - controller.HandleMouseInput(fakemi); - } + var controller = Ui.Root.Get(WorldInteractionController); + controller.HandleMouseInput(fakemi); + fakemi.Event = MouseInputEvent.Up; + controller.HandleMouseInput(fakemi); } return true; @@ -477,11 +478,21 @@ namespace OpenRA.Mods.Common.Widgets return new int2(mapRect.X + dx, mapRect.Y + dy); } - CPos MinimapPixelToCell(int2 p) + float2 MinimapPixelToWorldCoords(int2 pixel) { - var u = (int)((p.X - mapRect.X) / (previewScale * cellWidth)) + world.Map.Bounds.Left; - var v = (int)((p.Y - mapRect.Y) / previewScale) + world.Map.Bounds.Top; - return new MPos(u, v).ToCPos(world.Map); + var u = (pixel.X - mapRect.X) / (previewScale * cellWidth) + world.Map.Bounds.Left; + var v = (pixel.Y - mapRect.Y) / previewScale + world.Map.Bounds.Top; + + if (world.Map.Grid.Type == MapGridType.Rectangular) + { + return new float2(1024 * u + 512, 1024 * v + 512); + } + else + { + var y = v / 2.0f - u; + var x = v - y; + return new float2(724 * (x - y), 724 * (x + y)); + } } public override void Removed()