extends Control # Minimap: shows explored dungeon tiles (uses same "explored" data as fog of war). # Populates as the player explores. Drawn in upper-right corner. const MINIMAP_WIDTH: int = 128 const MINIMAP_HEIGHT: int = 96 const COLOR_UNEXPLORED: Color = Color(0.08, 0.08, 0.1) const COLOR_WALL: Color = Color(0.22, 0.22, 0.26) const COLOR_FLOOR: Color = Color(0.38, 0.38, 0.44) const COLOR_PLAYER: Color = Color(1.0, 0.35, 0.35) const COLOR_OTHER_PLAYER: Color = Color(0.35, 0.6, 1.0) # Blue for other players const COLOR_EXIT: Color = Color(1.0, 1.0, 1.0) var _map_size: Vector2i = Vector2i.ZERO var _explored_map: PackedInt32Array = PackedInt32Array() var _grid: Array = [] # 2D grid [x][y]: 0=wall, 1=floor, 2=door, 3=corridor var _player_tile: Vector2i = Vector2i(-1, -1) var _other_player_tiles: Array = [] # Array of Vector2i for other players var _exit_tile: Vector2i = Vector2i(-1, -1) var _exit_discovered: bool = false func set_maps(explored_map: PackedInt32Array, map_size: Vector2i, grid: Array, player_tile: Vector2i = Vector2i(-1, -1), exit_tile: Vector2i = Vector2i(-1, -1), exit_discovered: bool = false, other_player_tiles: Array = []) -> void: _explored_map = explored_map _map_size = map_size _grid = grid _player_tile = player_tile _other_player_tiles = other_player_tiles _exit_tile = exit_tile _exit_discovered = exit_discovered queue_redraw() func _ready() -> void: custom_minimum_size = Vector2(MINIMAP_WIDTH, MINIMAP_HEIGHT) mouse_filter = Control.MOUSE_FILTER_IGNORE func _process(_delta: float) -> void: if _exit_discovered: queue_redraw() func _draw() -> void: if _map_size.x <= 0 or _map_size.y <= 0 or _explored_map.is_empty(): return var bw := float(MINIMAP_WIDTH) var bh := float(MINIMAP_HEIGHT) var tw := bw / float(_map_size.x) var th := bh / float(_map_size.y) for x in range(_map_size.x): for y in range(_map_size.y): var idx := x + y * _map_size.x if idx < 0 or idx >= _explored_map.size(): continue var explored := _explored_map[idx] != 0 var px := float(x) * tw var py := float(y) * th var rect := Rect2(px, py, tw, th) var col: Color if not explored: col = COLOR_UNEXPLORED else: var g: int = 0 if _grid.size() > x and _grid[x] is Array and (_grid[x] as Array).size() > y: var row = _grid[x] as Array g = int(row[y]) if g == 0: col = COLOR_WALL else: col = COLOR_FLOOR draw_rect(rect, col, true) if _player_tile.x >= 0 and _player_tile.y >= 0 and _player_tile.x < _map_size.x and _player_tile.y < _map_size.y: var px := float(_player_tile.x) * tw + tw * 0.5 var py := float(_player_tile.y) * th + th * 0.5 var r := maxf(2.0, minf(tw, th) * 0.4) draw_circle(Vector2(px, py), r, COLOR_PLAYER) for other_tile in _other_player_tiles: if other_tile is Vector2i and other_tile.x >= 0 and other_tile.y >= 0 and other_tile.x < _map_size.x and other_tile.y < _map_size.y: var ox := float(other_tile.x) * tw + tw * 0.5 var oy := float(other_tile.y) * th + th * 0.5 var or_ := maxf(1.5, minf(tw, th) * 0.32) draw_circle(Vector2(ox, oy), or_, COLOR_OTHER_PLAYER) if _exit_discovered and _exit_tile.x >= 0 and _exit_tile.y >= 0 and _exit_tile.x < _map_size.x and _exit_tile.y < _map_size.y: var ex := float(_exit_tile.x) * tw + tw * 0.5 var ey := float(_exit_tile.y) * th + th * 0.5 var er := maxf(2.0, minf(tw, th) * 0.35) var blink := sin(Time.get_ticks_msec() * 0.004) * 0.5 + 0.5 var exit_col := Color(COLOR_EXIT.r, COLOR_EXIT.g, COLOR_EXIT.b, 0.45 + 0.55 * blink) draw_circle(Vector2(ex, ey), er, exit_col)