@tool class_name Grid extends Node2D @export var cells: int: set(val): cells = val _calc_dims() @export var cell_size: int: set(val): cell_size = val _calc_dims() var total_width: int var total_height: int var thickness: int var off: Vector2 var residents_field: Array[int] @onready var selection_manager: SelectionManager = Util.find(SelectionManager) func _enter_tree(): _calc_dims() func _ready(): _calc_dims() Engine.is_editor_hint() residents_field.resize(cells ** 2) for idx in len(residents_field): residents_field[idx] = 0 func _calc_dims(): total_width = cells * cell_size total_height = cells * cell_size thickness = 1 off = Vector2(total_width / -2, total_height / -2) func _process(_delta): queue_redraw() func _draw(): var r = Rect2(off, Vector2(total_width, total_height)) draw_rect(r, Color("222222"), true) var line_color = Color(1, 1, 1, 0.3) for i in range(cells + 1): draw_line(Vector2(i * cell_size, 0) + off, Vector2(i * cell_size, total_height) + off, line_color, thickness, false) for i in range(cells + 1): draw_line(Vector2(0, i * cell_size) + off, Vector2(total_width, i * cell_size) + off, line_color, thickness, false) for x in range(cells): for y in range(cells): var world_pos = Vector2i(x, y) var tile = _get_tile_at_tile_pos(world_pos) if tile == null: continue var t = Rect2( tile2world(world_pos), Vector2.ONE * cell_size ) draw_rect(t, Color("773322")) func tile2world(tile: Vector2i) -> Vector2i: return Vector2(tile) * cell_size + off func tile2world_rect(tile: Rect2i) -> Rect2: return Rect2(Vector2(tile.position) * cell_size + off, tile.size * cell_size) func tile2world_size(tile_size: Vector2i) -> Vector2: return Vector2(tile_size * cell_size) func world2tile(world_pos: Vector2) -> Vector2i: return Vector2i(((world_pos - off) / cell_size).floor()) func world2tile_f(world_pos: Vector2) -> Vector2: return (world_pos - off) / cell_size func world2tile_rect(rect: Rect2) -> Rect2i: var start = world2tile(rect.position) var end = world2tile(rect.end) return Rect2i(start, end - start) func quantize(world_position: Vector2, tile_size: Vector2i) -> Rect2: var q_pos = tile2world(world2tile(world_position)) return Rect2(q_pos, tile_size * cell_size) func quantize_on_objects(world_position: Vector2) -> Rect2: var tile_pos = world2tile(world_position) var size = Vector2i.ONE for tile in things: if tile.get_worldbox().has_point(world_position): return tile.get_worldbox() return quantize(world_position, Vector2.ONE) func _get_tile_at_tile_pos(pos: Vector2i) -> TileTransform: for tile in things: if tile.get_tilebox().has_point(pos): return tile return null func _get_tile_at_world_pos(pos: Vector2) -> TileTransform: #var world_pos = world2tile_f(pos) for tile in things: if tile.get_worldbox().has_point(pos): return tile return null func contains_world_pos(pos: Vector2) -> bool: var tile = world2tile(pos) if tile.x < 0 or tile.x > cells - 1: return false if tile.y < 0 or tile.y > cells - 1: return false return true func _shift_rect_half(rect: Rect2) -> Rect2: return Rect2(rect.position + rect.size / -2, rect.size) var things: Array[TileTransform] = [] var things_dict: Dictionary = {} func tile_pos2index(pos: Vector2i) -> int: return pos.x + pos.y * self.cells func idnex2tile_pos(idx: int) -> Vector2i: return Vector2i( idx % self.cells, floor(idx / self.cells) ) func register_tile(tile: TileTransform) -> void: things.append(tile) func remove_tile(tile: TileTransform) -> void: things.erase(tile)