194 lines
6.7 KiB
GDScript
194 lines
6.7 KiB
GDScript
class_name TileManager
|
|
extends Node
|
|
|
|
var active_tiles: Dictionary = {} # location: Tile
|
|
var board_flow: FlowContainer
|
|
var game: ChessGame
|
|
const PortalTile = preload("res://Systems/Tiles/Portal.gd")
|
|
func _init(flow: FlowContainer = null, chess_game: ChessGame = null) -> void:
|
|
if flow:
|
|
initialize(flow)
|
|
|
|
game = chess_game
|
|
|
|
func initialize(flow: FlowContainer) -> void:
|
|
board_flow = flow
|
|
clear_tiles()
|
|
|
|
func add_tile(location: String, tile: Tile) -> void:
|
|
if !board_flow:
|
|
push_error("TileManager not initialized with board_flow")
|
|
return
|
|
|
|
var container = board_flow.get_node_or_null(location) as PieceContainer
|
|
if !container:
|
|
push_error("Container not found at location: " + location)
|
|
return
|
|
|
|
# Remove any existing tile
|
|
remove_tile(location)
|
|
|
|
tile.game = game
|
|
# Add new tile
|
|
active_tiles[location] = tile
|
|
tile.effect_expired.connect(func(): remove_tile(location))
|
|
tile.update_appearance()
|
|
|
|
func remove_tile(location: String) -> void:
|
|
if active_tiles.has(location):
|
|
var tile = active_tiles[location]
|
|
tile.restore_base_appearance()
|
|
active_tiles.erase(location)
|
|
|
|
func get_tile(location: String) -> Tile:
|
|
return active_tiles.get(location, null)
|
|
|
|
func update_tile_durations() -> void:
|
|
if active_tiles.is_empty():
|
|
return
|
|
|
|
var expired_locations = []
|
|
var locations = active_tiles.keys()
|
|
for location in locations:
|
|
var tile = active_tiles[location]
|
|
tile.update_duration()
|
|
if !tile.is_effect_active():
|
|
expired_locations.append(location)
|
|
|
|
for location in expired_locations:
|
|
remove_tile(location)
|
|
|
|
func apply_tile_effects() -> void:
|
|
if active_tiles.is_empty():
|
|
return
|
|
|
|
for location in active_tiles:
|
|
var tile = active_tiles[location]
|
|
var container = board_flow.get_node(location) as PieceContainer
|
|
if container && container.has_piece():
|
|
var piece = container.get_piece()
|
|
if tile.can_affect_piece(piece):
|
|
tile.apply_effect(piece)
|
|
|
|
func clear_tiles() -> void:
|
|
var locations = active_tiles.keys()
|
|
for location in locations:
|
|
remove_tile(location)
|
|
|
|
# Function to place random game tiles at the start of each match
|
|
func place_random_game_tiles(num_tiles: int = 0) -> void:
|
|
if !board_flow:
|
|
push_error("TileManager not initialized with board_flow")
|
|
return
|
|
|
|
var fen_parts = game.FEN.split(" ")
|
|
var rows = fen_parts[0].split("/")
|
|
var available_positions = []
|
|
|
|
# Find empty rows from FEN
|
|
for y in range(rows.size()):
|
|
var row = rows[y]
|
|
# If row is all empty squares (like "8" in standard chess)
|
|
if row.is_valid_int() && int(row) == game.boardXSize:
|
|
var board_y = (game.boardYSize - 1) - y # Flip y coordinate to match board orientation
|
|
# Add all positions in this empty row
|
|
for x in range(game.boardXSize):
|
|
available_positions.append(str(x) + "-" + str(board_y))
|
|
|
|
available_positions.shuffle()
|
|
|
|
var skipNext = false;
|
|
|
|
var wall: Tile
|
|
var p = '0-2'
|
|
var cntr = board_flow.get_node(p) as PieceContainer
|
|
var w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
|
|
wall = WallTile.new(cntr, w, -1)
|
|
add_tile(p, wall)
|
|
p = '1-2'
|
|
cntr = board_flow.get_node(p) as PieceContainer
|
|
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
|
|
wall = WallTile.new(cntr, w, -1)
|
|
add_tile(p, wall)
|
|
p = '2-2'
|
|
cntr = board_flow.get_node(p) as PieceContainer
|
|
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
|
|
wall = WallTile.new(cntr, w, -1)
|
|
add_tile(p, wall)
|
|
p = '5-2'
|
|
cntr = board_flow.get_node(p) as PieceContainer
|
|
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
|
|
wall = WallTile.new(cntr, w, -1)
|
|
add_tile(p, wall)
|
|
p = '6-2'
|
|
cntr = board_flow.get_node(p) as PieceContainer
|
|
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
|
|
wall = WallTile.new(cntr, w, -1)
|
|
add_tile(p, wall)
|
|
p = '7-2'
|
|
cntr = board_flow.get_node(p) as PieceContainer
|
|
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
|
|
wall = WallTile.new(cntr, w, -1)
|
|
add_tile(p, wall)
|
|
|
|
# Skip over an iteration for a paired tile
|
|
for i in range(min(num_tiles, available_positions.size())):
|
|
if skipNext:
|
|
skipNext = false
|
|
continue
|
|
var pos = available_positions[i]
|
|
var container = board_flow.get_node(pos) as PieceContainer
|
|
if !container:
|
|
continue
|
|
|
|
var is_white = (int(pos.split("-")[0]) + int(pos.split("-")[1])) % 2 == 0
|
|
|
|
# Randomly choose a tile type
|
|
var rng = RandomNumberGenerator.new()
|
|
rng.randomize()
|
|
var tile_type = rng.randi() % 3
|
|
# tile_type = 4;
|
|
# remove the set 2
|
|
var tile: Tile
|
|
match tile_type:
|
|
0: # Wall tile
|
|
tile = WallTile.new(container, is_white, -1)
|
|
add_tile(pos, tile)
|
|
continue
|
|
1: # Double Wall
|
|
tile = DoubleWallTile.new(container, is_white, -1)
|
|
add_tile(pos, tile)
|
|
continue
|
|
2: # Portal pair
|
|
# Only create portal pair if this isn't the last tile
|
|
if i < available_positions.size() - 1:
|
|
var next_pos = available_positions[i + 1]
|
|
var next_container = board_flow.get_node(next_pos) as PieceContainer
|
|
if next_container:
|
|
place_portal_pair(pos, i, available_positions, container, is_white)
|
|
skipNext = true
|
|
else:
|
|
# If we can't make a pair, fall back to a wall tile
|
|
tile = WallTile.new(container, is_white, -1)
|
|
add_tile(pos, tile)
|
|
|
|
func place_portal_pair(pos: String = "", i: int = 0, available_positions: Array = [], container: PieceContainer = null, is_white: bool = false) -> void:
|
|
var next_pos = available_positions[i + 1]
|
|
var next_container = board_flow.get_node(next_pos) as PieceContainer
|
|
if next_container:
|
|
var next_is_white = (int(next_pos.split("-")[0]) + int(next_pos.split("-")[1])) % 2 == 0
|
|
|
|
# Create portal pair with alternating blue/orange colors
|
|
# var portal_color = Color.ORANGE if (i % 2 == 0) else Color.BLUE
|
|
var portals = PortalTile.create_portal_pair(
|
|
container, is_white,
|
|
next_container, next_is_white,
|
|
-1, # permanent duration
|
|
i, # pair id
|
|
Color.ORANGE,
|
|
Color.BLUE
|
|
)
|
|
|
|
# Add both portals
|
|
add_tile(pos, portals[0])
|
|
add_tile(next_pos, portals[1])
|