using Godot; using System; using System.Collections.Generic; using Cirno.Scripts.Controllers; using Cirno.Scripts.Enums; public partial class Minimap : CanvasLayer { [Export] public RogueliteRoomManager RoomManager { get; private set; } private Rid _canvasItemRid; private Rid _parentCanvas; private Godot.Collections.Dictionary RoomGrid => RoomManager.RoomGrid; private List SpawnedRooms => RoomManager.SpawnedRooms; private List Connections => RoomManager.Connections; [Export] public int CellSize { get; private set; } = 16; [Export] public Vector2 Padding { get; private set; } = new Vector2(20, 20); [Export] public float Separation = 2f; private Vector2 _viewportSize; public override void _Ready() { RoomManager.MapCreated += RoomManagerOnMapCreated; _canvasItemRid = RenderingServer.CanvasItemCreate(); _parentCanvas = this.GetCanvas(); //GetCanvasItem(); // Gets the RID of this Node2D's canvas RenderingServer.CanvasItemSetParent(_canvasItemRid, _parentCanvas); RenderingServer.CanvasItemSetVisible(_canvasItemRid, true); } public override void _EnterTree() { // Get current window size to position minimap in top-right _viewportSize = GetViewport().GetVisibleRect().Size; } private void RoomManagerOnMapCreated() { RedrawMinimap(); } // public override void _Process(double delta) // { // //RedrawMinimap(); // } // public void SetRoomGrid(Dictionary roomGrid) // { // _roomGrid = roomGrid; // RedrawMinimap(); // } private void RedrawMinimap() { // Clear previous draw commands RenderingServer.CanvasItemClear(_canvasItemRid); if (SpawnedRooms == null) return; // Find bounds Vector2I min = new(int.MaxValue, int.MaxValue); Vector2I max = new(int.MinValue, int.MinValue); foreach (var room in SpawnedRooms) { min = new Vector2I(Math.Min(min.X, room.GridPosition.X), Math.Min(min.Y, room.GridPosition.Y)); max = new Vector2I(Math.Max(max.X, room.GridPosition.X + room.RoomResource.Size.X), Math.Max(max.Y, room.GridPosition.Y + room.RoomResource.Size.Y)); } Vector2 mapSize = (max - min) * CellSize; Vector2 offset = new Vector2( _viewportSize.X - mapSize.X - Padding.X, // padding from right Padding.Y // Top padding ); //Vector2 offset = Padding; // Padding foreach (var room in SpawnedRooms) { Vector2I pos = room.GridPosition; Vector2I size = room.RoomResource.Size; Vector2 drawPos = offset + (new Vector2((pos.X - min.X), (pos.Y - min.Y))) * (CellSize + Separation); Vector2 drawSize = new Vector2(size.X, size.Y) * CellSize + new Vector2((size.X - 1), (size.Y - 1)) * Separation; //Vector2 drawSize = new Vector2(size.X, size.Y) * CellSize; Color color = GetColorForRoomType(room.RoomResource.Type); RenderingServer.CanvasItemAddRect(_canvasItemRid, new Rect2(drawPos, drawSize), color); } DrawRoomConnections(Connections, min, offset); //DrawDebugGrid(); } private void DrawPlayer(Vector2I minGrid, Vector2 baseOffset) { var playerPosition = GameManager.Instance.PlayerPosition; //var scaledPos = playerPosition } private void DrawDebugGrid() { foreach (var room in SpawnedRooms) { var rect = new Rect2(room.GridPosition * RoomManager.TileSize * RoomManager.RoomSizeInTiles, RoomManager.TileSize * RoomManager.RoomSizeInTiles); RenderingServer.CanvasItemAddRect(_canvasItemRid, rect, new Color(0, 120,0, 125)); } } private void DrawRoomConnections(List connections, Vector2I minGrid, Vector2 baseOffset) { int spacing = (int)Separation; foreach (var connection in connections) { // Skip if either room is missing if (!RoomGrid.ContainsKey(connection.From) || !RoomGrid.ContainsKey(connection.To)) continue; // Convert grid coordinates to local minimap grid (relative to min) Vector2I fromGrid = connection.From - minGrid; Vector2I toGrid = connection.To - minGrid; // Center of the From cell in pixels Vector2 fromCenter = baseOffset + fromGrid * (CellSize + spacing) + new Vector2(CellSize / 2f, CellSize / 2f); // Center of the To cell in pixels Vector2 toCenter = baseOffset + toGrid * (CellSize + spacing) + new Vector2(CellSize / 2f, CellSize / 2f); // The gap center between rooms Vector2 gapCenter = (fromCenter + toCenter) * 0.5f; // Short line inside the separation gap Vector2 delta = (toCenter - fromCenter).Normalized(); Vector2 halfGap = delta * (spacing / 2f); Vector2 lineStart = gapCenter - halfGap; Vector2 lineEnd = gapCenter + halfGap; // Pick color based on type Color color = Colors.White; if (connection.IsSecret) color = Colors.Purple; else if (connection.IsLocked) color = Colors.Orange; float thickness = 1f; // Draw the line RenderingServer.CanvasItemAddLine(_canvasItemRid, lineStart, lineEnd, color, thickness); } } private Color GetColorForRoomType(RoomType type) { return type switch { RoomType.Boss => Colors.Red, RoomType.Shop => Colors.DarkKhaki, RoomType.Regular => Colors.Blue, RoomType.Key => Colors.Purple, RoomType.Secret => Colors.Bisque, RoomType.Treasure => Colors.Gold, RoomType.Starter => Colors.Green, _ => Colors.DimGray }; } }