cirnogodot/Scripts/UI/Minimap.cs
2025-04-15 17:28:03 +02:00

157 lines
No EOL
5.4 KiB
C#

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<Vector2I, RogueliteRoom> RoomGrid => RoomManager.RoomGrid;
private List<RogueliteRoom> SpawnedRooms => RoomManager.SpawnedRooms;
private List<RoomConnection> 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 void SetRoomGrid(Dictionary<Vector2I, RogueliteRoom> 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);
}
private void DrawRoomConnections(List<RoomConnection> 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.Gold,
RoomType.Regular => Colors.Blue,
RoomType.Starter => Colors.Green,
_ => Colors.DimGray
};
}
}