Implements mini map and updates door lights
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
extends Control
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Layout constants
|
||||
# ---------------------------------------------------------------------------
|
||||
const MAP_SIZE := Vector2(150, 150)
|
||||
const ROOM_SIZE := Vector2(18, 10) # 16:9 aspect ratio like actual rooms
|
||||
const ROOM_GAP := 4.0
|
||||
const PADDING := 10.0
|
||||
const CONNECTION_WIDTH := 2.0
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Colors (brightened versions of room.gd floor colors)
|
||||
# ---------------------------------------------------------------------------
|
||||
const ROOM_COLORS := {
|
||||
RoomData.RoomType.START: Color(0.24, 0.24, 0.36), # blue-grey
|
||||
RoomData.RoomType.COMBAT: Color(0.24, 0.24, 0.36), # blue-grey
|
||||
RoomData.RoomType.ITEM: Color(0.20, 0.32, 0.20), # green
|
||||
RoomData.RoomType.SHOP: Color(0.32, 0.24, 0.16), # brown
|
||||
RoomData.RoomType.BOSS: Color(0.40, 0.16, 0.16), # red
|
||||
}
|
||||
const CURRENT_OUTLINE := Color(1.0, 1.0, 0.4) # bright yellow
|
||||
const CONNECTION_COLOR := Color(0.5, 0.5, 0.6)
|
||||
const UNVISITED_ALPHA := 0.35
|
||||
const BACKGROUND_COLOR := Color(0.08, 0.08, 0.10, 0.85)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# State
|
||||
# ---------------------------------------------------------------------------
|
||||
var _rooms_data: Dictionary = {} # Vector2i -> RoomData
|
||||
var _current_pos: Vector2i = Vector2i.ZERO
|
||||
var _grid_min: Vector2i = Vector2i.ZERO
|
||||
var _grid_max: Vector2i = Vector2i.ZERO
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Setup
|
||||
# ---------------------------------------------------------------------------
|
||||
func _ready() -> void:
|
||||
# Position in top-right corner
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_top = 0.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = -MAP_SIZE.x - PADDING
|
||||
offset_right = -PADDING
|
||||
offset_top = PADDING
|
||||
offset_bottom = MAP_SIZE.y + PADDING
|
||||
custom_minimum_size = MAP_SIZE
|
||||
|
||||
# Connect signals
|
||||
EventBus.floor_map_ready.connect(_on_floor_map_ready)
|
||||
EventBus.room_entered_at.connect(_on_room_entered)
|
||||
EventBus.run_ended.connect(_on_run_ended)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Signal handlers
|
||||
# ---------------------------------------------------------------------------
|
||||
func _on_floor_map_ready(rooms_data: Dictionary) -> void:
|
||||
_rooms_data = rooms_data
|
||||
_compute_grid_bounds()
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _on_room_entered(grid_pos: Vector2i) -> void:
|
||||
_current_pos = grid_pos
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _on_run_ended(_reached_hub: bool) -> void:
|
||||
_rooms_data.clear()
|
||||
queue_redraw()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
func _compute_grid_bounds() -> void:
|
||||
if _rooms_data.is_empty():
|
||||
_grid_min = Vector2i.ZERO
|
||||
_grid_max = Vector2i.ZERO
|
||||
return
|
||||
|
||||
var first := true
|
||||
for pos in _rooms_data.keys():
|
||||
if first:
|
||||
_grid_min = pos
|
||||
_grid_max = pos
|
||||
first = false
|
||||
else:
|
||||
_grid_min.x = mini(_grid_min.x, pos.x)
|
||||
_grid_min.y = mini(_grid_min.y, pos.y)
|
||||
_grid_max.x = maxi(_grid_max.x, pos.x)
|
||||
_grid_max.y = maxi(_grid_max.y, pos.y)
|
||||
|
||||
|
||||
func _get_visible_rooms() -> Dictionary:
|
||||
# Returns {Vector2i -> {"data": RoomData, "visited": bool}}
|
||||
var visible := {}
|
||||
var known_positions: Array[Vector2i] = []
|
||||
|
||||
# First pass: collect visited rooms and their adjacent positions
|
||||
for pos in _rooms_data.keys():
|
||||
var room: RoomData = _rooms_data[pos]
|
||||
if room.visited:
|
||||
visible[pos] = {"data": room, "visited": true}
|
||||
for conn_pos in room.connections.values():
|
||||
if conn_pos not in known_positions:
|
||||
known_positions.append(conn_pos)
|
||||
|
||||
# Second pass: add adjacent (known but unvisited) rooms
|
||||
for pos in known_positions:
|
||||
if pos not in visible and _rooms_data.has(pos):
|
||||
visible[pos] = {"data": _rooms_data[pos], "visited": false}
|
||||
|
||||
return visible
|
||||
|
||||
|
||||
func _grid_to_map_pos(grid_pos: Vector2i) -> Vector2:
|
||||
# Convert grid position to local drawing coordinates
|
||||
var cell_size := ROOM_SIZE + Vector2(ROOM_GAP, ROOM_GAP)
|
||||
var grid_size := Vector2i(_grid_max.x - _grid_min.x + 1, _grid_max.y - _grid_min.y + 1)
|
||||
var total_size := Vector2(grid_size.x, grid_size.y) * cell_size - Vector2(ROOM_GAP, ROOM_GAP)
|
||||
|
||||
# Center the map within the control
|
||||
var centering := (MAP_SIZE - total_size) / 2.0
|
||||
var offset := Vector2(
|
||||
(grid_pos.x - _grid_min.x) * cell_size.x,
|
||||
(grid_pos.y - _grid_min.y) * cell_size.y
|
||||
)
|
||||
return centering + offset
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Drawing
|
||||
# ---------------------------------------------------------------------------
|
||||
func _draw() -> void:
|
||||
if _rooms_data.is_empty():
|
||||
return
|
||||
|
||||
# Background panel
|
||||
draw_rect(Rect2(Vector2.ZERO, MAP_SIZE), BACKGROUND_COLOR)
|
||||
|
||||
var visible := _get_visible_rooms()
|
||||
|
||||
# Draw connections first (under rooms)
|
||||
for pos in visible.keys():
|
||||
var room: RoomData = visible[pos]["data"]
|
||||
var room_center := _grid_to_map_pos(pos) + ROOM_SIZE / 2.0
|
||||
for dir in room.connections.keys():
|
||||
var conn_pos: Vector2i = room.connections[dir]
|
||||
if visible.has(conn_pos):
|
||||
var conn_center := _grid_to_map_pos(conn_pos) + ROOM_SIZE / 2.0
|
||||
# Only draw each connection once (from lower to higher grid pos)
|
||||
if pos.x < conn_pos.x or (pos.x == conn_pos.x and pos.y < conn_pos.y):
|
||||
draw_line(room_center, conn_center, CONNECTION_COLOR, CONNECTION_WIDTH)
|
||||
|
||||
# Draw rooms
|
||||
for pos in visible.keys():
|
||||
var info: Dictionary = visible[pos]
|
||||
var room: RoomData = info["data"]
|
||||
var is_visited: bool = info["visited"]
|
||||
var map_pos := _grid_to_map_pos(pos)
|
||||
var rect := Rect2(map_pos, ROOM_SIZE)
|
||||
|
||||
# Room color with alpha based on visited state
|
||||
var color: Color = ROOM_COLORS.get(room.type, ROOM_COLORS[RoomData.RoomType.COMBAT])
|
||||
if not is_visited:
|
||||
color.a = UNVISITED_ALPHA
|
||||
draw_rect(rect, color)
|
||||
|
||||
# Current room indicator - bright outline
|
||||
if pos == _current_pos:
|
||||
draw_rect(rect, CURRENT_OUTLINE, false, 2.0)
|
||||
Reference in New Issue
Block a user