class_name Board extends Node2D signal board_state_changed enum Direction { NONE, UP, DOWN, LEFT, RIGHT } const GROUND = preload("uid://c5y5ksmwhevd") const UP_SPAWN = preload("uid://6ywvgci44ttv") const RIGHT_SPAWN = preload("uid://c1y3s7daosghf") const DOWN_SPAWN = preload("uid://d4ltd1geg7s2p") const LEFT_SPAWN = preload("uid://noi2ko4hceus") var tiles: Dictionary[Vector2i, Tile] = {} var buildings: Dictionary[Vector2i, Building] = {} var active_building: Building var active_tile: Tile var current_map_coord: Vector2i var prev_map_coord: Vector2i var is_controlling_camera: bool = false @onready var tile_map: TileMapLayer = %Tiles @onready var board_state: Node2D = %BoardState func _input(event: InputEvent) -> void: if event.is_action_pressed("camera_engage"): is_controlling_camera = true return if event.is_action_released("camera_engage"): is_controlling_camera = false if is_controlling_camera: return #if Globals.board_game.current_board_state.current_player != Globals.game.this_player: #return if event is InputEventMouseMotion: current_map_coord = tile_map.local_to_map(tile_map.get_local_mouse_position()) if active_tile != null: active_tile.position = tile_map.map_to_local(current_map_coord) if active_building != null: active_building.position = tile_map.map_to_local(current_map_coord) prev_map_coord = current_map_coord if event.is_action_pressed("select"): if active_tile != null: place_active_tile() elif active_building != null: place_active_building() _handle_building_rotation(event) #_handle_spawn_rotation(event) func set_active_tile(tile: Tile) -> void: active_tile = tile board_state.add_child(active_tile) active_tile.modulate = Color(1, 1, 1, 0.5) active_tile.is_placing = true func set_active_building(building: Building) -> void: active_building = building board_state.add_child(active_building) if active_building is Home: active_building.player = Globals.board_game.current_board_state.current_player active_building.modulate = Color(1, 1, 1, 0.5) active_building.is_placing = true func place_active_tile() -> void: if tiles.has(current_map_coord) and tiles[current_map_coord] is Ground: tiles[current_map_coord].queue_free() tiles.erase(current_map_coord) if !tiles.has(current_map_coord) and !buildings.has(current_map_coord): Globals.board_game.current_board_state.players[0].money -= active_tile.cost active_tile.modulate = Color(1, 1, 1, 1) active_tile.coords = current_map_coord tiles[current_map_coord] = active_tile active_tile = null board_state_changed.emit() func place_active_building() -> void: active_building.starting_coord = current_map_coord if active_building is Home: active_building.player = Globals.board_game.current_board_state.current_player for coord in active_building.get_tile_coords(): if tiles.has(coord) and !(tiles[coord] is Ground): return if buildings.has(coord): return for surr_coord in tile_map.get_surrounding_cells(coord): if buildings.has(surr_coord): return Globals.board_game.current_board_state.players[0].money -= active_building.cost active_building.modulate = Color(1, 1, 1, 1) for coord in active_building.get_tile_coords(): buildings[coord] = active_building tiles[coord].queue_free() tiles.erase(coord) active_building = null board_state_changed.emit() func _handle_building_rotation(event: InputEvent) -> void: if active_building == null: return if event.is_action_pressed("rotate_tile_up"): active_building.rotation_degrees += 90 active_building.tile_rotation = get_next_direction(active_building.tile_rotation) elif event.is_action_pressed("rotate_tile_down"): active_building.rotation_degrees -= 90 active_building.tile_rotation = get_previous_direction(active_building.tile_rotation) func reset() -> void: for child in board_state.get_children(): child.queue_free() func set_board_state(bs: BoardState) -> void: for tile in bs.tiles: board_state.add_child(tile) tiles[tile.coords] = tile tile.position = tile_map.map_to_local(tile.coords) for building in bs.buildings: board_state.add_child(building) for coord in building.get_tile_coords(): buildings[coord] = building building.position = tile_map.map_to_local(building.starting_coord) building.rotation_degrees += 90 * building.get_rotation_count() func initialize() -> void: var max_x: int = 0 var max_y: int = 0 for i in range(Globals.game.players.size()): var random_spawn = Vector2i(randi_range(0, 9), randi_range(0, 9)) for x in range(10): for y in range(10): var coord = Vector2i(x, y) if i == 1: coord.x += 10 if i == 2: coord.y += 10 if i == 3: coord += Vector2i(10, 10) max_x = coord.x max_y = coord.y if x == random_spawn.x and y == random_spawn.y: var possible_spawns = [UP_SPAWN, RIGHT_SPAWN, DOWN_SPAWN, LEFT_SPAWN] if random_spawn.x == 9: possible_spawns.erase(RIGHT_SPAWN) elif random_spawn.x == 0: possible_spawns.erase(LEFT_SPAWN) if random_spawn.y == 9: possible_spawns.erase(DOWN_SPAWN) elif random_spawn.y == 0: possible_spawns.erase(UP_SPAWN) var spawn: Tile = possible_spawns.pick_random().instantiate() board_state.add_child(spawn) spawn.coords = coord spawn.position = tile_map.map_to_local(coord) tiles[coord] = spawn else: var ground: Tile = GROUND.instantiate() board_state.add_child(ground) ground.coords = coord ground.position = tile_map.map_to_local(coord) tiles[coord] = ground #var extra_spawn_coord := Vector2i(randi_range(1, max_x - 1), randi_range(1, max_y - 1)) #var extra_spawn = [UP_SPAWN, RIGHT_SPAWN, DOWN_SPAWN, LEFT_SPAWN].pick_random().instantiate() #board_state.add_child(extra_spawn) #extra_spawn.coords = extra_spawn_coord #extra_spawn.position = tile_map.map_to_local(extra_spawn_coord) #tiles[extra_spawn_coord] = extra_spawn static func get_next_direction(direction: Direction, count: int = 1) -> Direction: var result := direction if count == 0: return result match direction: Direction.UP: result = Direction.RIGHT Direction.RIGHT: result = Direction.DOWN Direction.DOWN: result = Direction.LEFT Direction.LEFT: result = Direction.UP if count == 1: return result return get_next_direction(result, count - 1) static func get_previous_direction(direction: Direction) -> Direction: match direction: Direction.UP: return Direction.LEFT Direction.RIGHT: return Direction.UP Direction.DOWN: return Direction.RIGHT Direction.LEFT: return Direction.DOWN _: return direction static func get_direction_vector(direction: Direction) -> Vector2i: match direction: Direction.UP: return Vector2i.UP Direction.RIGHT: return Vector2i.RIGHT Direction.DOWN: return Vector2i.DOWN Direction.LEFT: return Vector2i.LEFT _: return Vector2i.ZERO #func generate() -> void: #for child in get_children(): #child.queue_free() #for x in range(width): #for y in range(height): #var tile: Control #if x == 1 and y == 1: #tile = spawn_scene.instantiate() #else: #tile = ground_scene.instantiate() #add_child(tile) #tile.position = get_coordinate(x, y) #tile.owner = self