adding TIle Support and fixed peice container overlays

This commit is contained in:
2ManyProjects 2025-02-05 00:23:51 -06:00
parent 828bf85eea
commit 7012ea4f16
11 changed files with 261 additions and 253 deletions

View file

@ -69,7 +69,7 @@ func apply_effect(target_piece = null, board_flow = null, game_state = null):
# Setup timer to remove overlays # Setup timer to remove overlays
var timer = Timer.new() var timer = Timer.new()
board_flow.add_child(timer) board_flow.add_child(timer)
timer.wait_time = 0.5 timer.wait_time = 1
timer.one_shot = true timer.one_shot = true
timer.timeout.connect(func(): timer.timeout.connect(func():
for tile_name in tiles_to_check: for tile_name in tiles_to_check:

View file

@ -52,6 +52,13 @@ func apply_effect(target_piece = null, board_flow = null, game_state = null):
# Add tile to check list # Add tile to check list
tiles_to_check.append(str(target_x) + "-" + str(target_y)) tiles_to_check.append(str(target_x) + "-" + str(target_y))
for tile_name in tiles_to_check:
var tile = board_flow.get_node(tile_name) as PieceContainer
if tile.get_piece() != null:
var piece = tile.get_piece()
if piece.Item_Color != target_piece.Item_Color: # Only capture enemy pieces
game_state.updatePoints(piece)
tile.remove_piece()
# Process tiles and add overlay # Process tiles and add overlay
for tile_name in tiles_to_check: for tile_name in tiles_to_check:
var container = board_flow.get_node(tile_name) as PieceContainer var container = board_flow.get_node(tile_name) as PieceContainer
@ -76,7 +83,7 @@ func apply_effect(target_piece = null, board_flow = null, game_state = null):
# Setup timer to remove overlays # Setup timer to remove overlays
var timer = Timer.new() var timer = Timer.new()
board_flow.add_child(timer) board_flow.add_child(timer)
timer.wait_time = 0.5 timer.wait_time = 1
timer.one_shot = true timer.one_shot = true
timer.timeout.connect(func(): timer.timeout.connect(func():
for tile_name in tiles_to_check: for tile_name in tiles_to_check:

View file

@ -8,7 +8,6 @@ signal send_location(location: String)
signal turn_changed signal turn_changed
var currentPlayer: String = WHITE var currentPlayer: String = WHITE
var board: Array var board: Array
var activeEffects: Array
var currentHand: Array var currentHand: Array
var selectedNode: String = "" var selectedNode: String = ""
var locationX: String = "" var locationX: String = ""
@ -26,7 +25,7 @@ var Turn: int = 0
@onready var p1String: RichTextLabel = $Player1Points @onready var p1String: RichTextLabel = $Player1Points
@onready var p2String: RichTextLabel = $Player2Points @onready var p2String: RichTextLabel = $Player2Points
@onready var deckManager: DeckManager @onready var deckManager: DeckManager
# @onready var tileManager: TileManager @onready var tileManager: TileManager
@onready var cardDisplay: CardDisplay @onready var cardDisplay: CardDisplay
@onready var cardPreview: CardPreview @onready var cardPreview: CardPreview
@ -45,14 +44,16 @@ var highlightStyle = null
func _ready() -> void: func _ready() -> void:
initializeGame() initializeGame()
initializeTiles()
stateMachine.transitionToNextState(Constants.WHITE_TURN) stateMachine.transitionToNextState(Constants.WHITE_TURN)
# initializeTiles()
# func initializeTiles() -> void: func initializeTiles() -> void:
# tileManager = TileManager.new(boardContainer, self) tileManager = TileManager.new()
# add_child(tileManager) add_child(tileManager)
# tileManager.setup_initial_tiles() await get_tree().process_frame
tileManager.initialize(boardContainer)
tileManager.place_random_game_tiles()
func get_base_style(is_white: bool) -> StyleBoxFlat: func get_base_style(is_white: bool) -> StyleBoxFlat:
return lightStyle if is_white else darkStyle return lightStyle if is_white else darkStyle
@ -265,16 +266,11 @@ func clearBoard() -> void:
# pass # pass
func updateEffectDurations() -> void: func updateEffectDurations() -> void:
for effect in activeEffects: deckManager.updateCardDurations()
effect.duration -= 1 tileManager.update_tile_durations()
if effect.duration <= 0:
activeEffects.erase(effect)
func applyTileEffects() -> void: func applyTileEffects() -> void:
for piece in get_tree().get_nodes_in_group("Pieces"): tileManager.apply_tile_effects()
var tile = piece.get_parent()
if tile.has_effect():
tile.apply_effect(piece)
func applyCardEffects() -> void: func applyCardEffects() -> void:
@ -342,9 +338,17 @@ func getMovableAreas() -> void:
highlightValidMoves() highlightValidMoves()
func highlightValidMoves() -> void: func highlightValidMoves() -> void:
# print("HIGHLIGHTING VALID MOVES")
for move in areas: for move in areas:
var button = boardContainer.get_node(move) var button = boardContainer.get_node(move)
# If there's an active tile effect, combine with its current style instead
if tileManager && tileManager.get_tile(move):
var current_style = button.get_theme_stylebox("normal")
var highlightedStyle = StyleBoxFlat.new()
highlightedStyle.bg_color = current_style.bg_color + highlightStyle.bg_color
button.add_theme_stylebox_override("normal", highlightedStyle)
else:
# Default chess pattern highlighting
var isWhiteSquare = (int(move.split("-")[0]) + int(move.split("-")[1])) % 2 == 0 var isWhiteSquare = (int(move.split("-")[0]) + int(move.split("-")[1])) % 2 == 0
var baseStyle = lightStyle if isWhiteSquare else darkStyle var baseStyle = lightStyle if isWhiteSquare else darkStyle
var combinedStyle = StyleBoxFlat.new() var combinedStyle = StyleBoxFlat.new()
@ -407,6 +411,11 @@ func resetHighlights():
for button in boardContainer.get_children(): for button in boardContainer.get_children():
if !button.name.contains("-"): if !button.name.contains("-"):
continue continue
# Skip if this tile has an active effect
if tileManager && tileManager.get_tile(button.name):
continue
var coord = button.name.split("-") var coord = button.name.split("-")
var isWhiteSquare = (int(coord[0]) + int(coord[1])) % 2 == 0 var isWhiteSquare = (int(coord[0]) + int(coord[1])) % 2 == 0
if isWhiteSquare: if isWhiteSquare:

View file

@ -1,18 +1,14 @@
class_name PieceContainer extends Button class_name PieceContainer extends Button
var piece: Pawn = null var piece: Pawn = null
@onready var overlays: Node = $Overlays var effects: Node # Keep effects as a sub-node
@onready var effects: Node = $Effects var overlay_nodes: Array[Node] = []
func _init() -> void: func _init() -> void:
# Create containers for different types of children # Setup effects node
var overlays_node = Node.new() effects = Node.new()
overlays_node.name = "Overlays" effects.name = "Effects"
add_child(overlays_node) add_child(effects)
var effects_node = Node.new()
effects_node.name = "Effects"
add_child(effects_node)
func set_piece(new_piece: Pawn) -> void: func set_piece(new_piece: Pawn) -> void:
remove_piece() # Clean up any existing piece remove_piece() # Clean up any existing piece
@ -35,15 +31,26 @@ func remove_piece(keep_piece: bool = false) -> Pawn:
return old_piece return old_piece
func add_overlay(overlay: Node) -> void: func add_overlay(overlay: Node) -> void:
overlays.add_child(overlay) if overlay is ColorRect:
overlay.size = size
overlay.position = Vector2.ZERO
overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(overlay)
overlay_nodes.append(overlay)
func remove_overlay(overlay_name: String) -> void: func remove_overlay(overlay_name: String) -> void:
var overlay = overlays.get_node_or_null(overlay_name) for overlay in overlay_nodes:
if overlay: if overlay.name == overlay_name:
remove_child(overlay)
overlay_nodes.erase(overlay)
overlay.queue_free() overlay.queue_free()
break
func get_overlay(overlay_name: String) -> Node: func get_overlay(overlay_name: String) -> Node:
return overlays.get_node_or_null(overlay_name) for overlay in overlay_nodes:
if overlay.name == overlay_name:
return overlay
return null
func has_piece() -> bool: func has_piece() -> bool:
return piece != null return piece != null

View file

@ -1,6 +1,6 @@
extends "res://Systems/StateMachine/ChessGameState.gd" extends "res://Systems/StateMachine/ChessGameState.gd"
const ATTACHMENT_PHASE_DURATION = 15 # Duration in seconds const ATTACHMENT_PHASE_DURATION = 5 # Duration in seconds
var timer: Timer var timer: Timer
var tile_pressed_connection: Signal var tile_pressed_connection: Signal

View file

@ -1,99 +1,72 @@
@tool
class_name Tile class_name Tile
extends Resource
enum TileType { enum TileType {
GENERAL, # Effects apply to any piece GENERAL, # Affects any unit
SPECIFIC, # Effects apply to specific pieces SPECIFIC, # Affects specific unit type
GLOBAL # Effects apply globally while conditions are met GLOBAL # Affects all units of a color while active
} }
enum TileOwner { enum TileOwner {
PLAYER, # White player's tiles PLAYER, # White player
ENEMY, # Black player's tiles ENEMY, # Black player
GAME # Neutral game tiles GAME # Neutral/game-owned
} }
const TILE_COLORS = { var tile_name: String = ""
TileOwner.PLAYER: Color(0.2, 0.8, 0.2, 0.5), var description: String = ""
TileOwner.ENEMY: Color(0.8, 0.2, 0.2, 0.5), var duration: int = -1 # -1 for permanent tiles
TileOwner.GAME: Color(0.2, 0.2, 0.8, 0.5) var remaining_turns: int = 0
} var tile_owner: TileOwner = TileOwner.GAME
var type: TileType = TileType.GENERAL
var target_piece_type: String = "" # For SPECIFIC type tiles
var base_button: Button # Reference to the tile button
var base_is_white: bool # Original tile color
var type: TileType signal effect_expired
var tile_owner: TileOwner
var duration: int = -1 # -1 for permanent effects
var remaining_turns: int
var occupied_by: Pawn = null
var active: bool = false
var tile_name: String
var description: String
var id: String = Utils.generate_guid()
var base_button: Button # Reference to the board square button
var base_is_white: bool # Original color of the square
func _init(button: Button, is_white: bool) -> void: func _init(button: Button, is_white: bool) -> void:
base_button = button base_button = button
base_is_white = is_white base_is_white = is_white
func initialize(tile_type: TileType, owner_type: TileOwner, turns: int = -1) -> void:
print("initi Tile")
type = tile_type
tile_owner = owner_type
duration = turns
remaining_turns = duration remaining_turns = duration
update_appearance()
func is_effect_active() -> bool:
return duration == -1 || remaining_turns > 0
func update_duration() -> void:
if duration != -1:
remaining_turns -= 1
if remaining_turns <= 0:
effect_expired.emit()
func can_affect_piece(piece: Pawn) -> bool:
match type:
TileType.SPECIFIC:
return piece.name == target_piece_type
TileType.GLOBAL, TileType.GENERAL:
# Check owner alignment
match tile_owner:
TileOwner.PLAYER:
return piece.Item_Color == 0 # White
TileOwner.ENEMY:
return piece.Item_Color == 1 # Black
TileOwner.GAME:
return true
return false
func apply_effect(piece: Pawn = null) -> void:
# Override in child classes
pass
func remove_effect(piece: Pawn = null) -> void:
# Override in child classes
pass
func update_appearance() -> void: func update_appearance() -> void:
if is_effect_active() && base_button:
var style = StyleBoxFlat.new()
var tile_color = TILE_COLORS[tile_owner]
# Mix the tile color with the base square color
var base_color = Color(0.8, 0.8, 0.8) if base_is_white else Color(0.2, 0.2, 0.2)
var mixed_color = Color(
(base_color.r + tile_color.r) / 2,
(base_color.g + tile_color.g) / 2,
(base_color.b + tile_color.b) / 2
)
style.bg_color = mixed_color
style.border_width_left = 2
style.border_width_right = 2
style.border_width_top = 2
style.border_width_bottom = 2
style.border_color = tile_color
base_button.add_theme_stylebox_override("normal", style)
# Add hover style
var hover_style = style.duplicate()
hover_style.bg_color = tile_color.lightened(0.2)
base_button.add_theme_stylebox_override("hover", hover_style)
else:
restore_base_appearance() restore_base_appearance()
func restore_base_appearance() -> void: func restore_base_appearance() -> void:
if base_button: if base_button:
var board = base_button.get_parent() var style = StyleBoxFlat.new()
if board && board.has_method("get_base_style"): style.bg_color = Color(0.8, 0.8, 0.8, 1) if base_is_white else Color(0.2, 0.2, 0.2, 1)
var base_style = board.get_base_style(base_is_white) base_button.add_theme_stylebox_override("normal", style)
base_button.add_theme_stylebox_override("normal", base_style)
base_button.add_theme_stylebox_override("hover", base_style)
func is_effect_active() -> bool:
return active && (duration == -1 || remaining_turns > 0)
func update_duration() -> bool:
if duration > 0:
remaining_turns -= 1
if remaining_turns <= 0:
restore_base_appearance()
return true # Tile should be removed
return false
# Virtual methods to be overridden by specific tile effects
func apply_effect(piece: Pawn, board_flow = null, game_state = null) -> void:
pass
func remove_effect(piece: Pawn, board_flow = null, game_state = null) -> void:
pass

View file

@ -1,93 +1,112 @@
extends Node
class_name TileManager class_name TileManager
const INITIAL_GAME_TILES = 3 # Number of neutral tiles to place at game start extends Node
var active_tiles: Dictionary = {} # location -> Tile var active_tiles: Dictionary = {} # location: Tile
var game_board: Node # Reference to the game board var board_flow: FlowContainer
var game_state: Node # Reference to the game state
const DoubleMovementTile = preload("res://Systems/Tiles/DoubleMovement.gd") const DoubleMovementTile = preload("res://Systems/Tiles/DoubleMovement.gd")
const FireWallTile = preload("res://Systems/Tiles/FireWall.gd") const FireWallTile = preload("res://Systems/Tiles/FireWall.gd")
const PawnBoostTile = preload("res://Systems/Tiles/PawnBoost.gd") const PawnBoostTile = preload("res://Systems/Tiles/PawnBoost.gd")
func _init(flow: FlowContainer = null) -> void:
if flow:
initialize(flow)
# Available tile classes func initialize(flow: FlowContainer) -> void:
const TILE_TYPES = { board_flow = flow
"double_movement": DoubleMovementTile, clear_tiles()
"fire_wall": FireWallTile,
"pawn_boost": PawnBoostTile
}
func _init(board: Node, state: Node = null) -> void: func add_tile(location: String, tile: Tile) -> void:
game_board = board if !board_flow:
game_state = state push_error("TileManager not initialized with board_flow")
return
func setup_initial_tiles() -> void: var container = board_flow.get_node_or_null(location) as PieceContainer
var available_positions = ["4-4", "4-6", "2-4"] if !container:
# get_available_positions() push_error("Container not found at location: " + location)
available_positions.shuffle() return
for i in range(min(INITIAL_GAME_TILES, available_positions.size())): # Remove any existing tile
var pos = available_positions[i] remove_tile(location)
var tile_type = TILE_TYPES.keys()[randi() % TILE_TYPES.size()]
create_tile(pos, tile_type, Tile.TileOwner.GAME)
func create_tile(location: String, tile_type: String, tile_owner: int, duration: int = -1) -> Tile:
print("CREATING TILES", location)
if location in active_tiles:
print("In Active tiles ", location)
var old_tile = active_tiles[location]
old_tile.restore_base_appearance()
active_tiles.erase(location)
if !TILE_TYPES.has(tile_type):
push_error("Invalid tile type: " + tile_type)
return null
var board_button = game_board.get_node(location)
if !board_button:
print("no Board Btn present ", location)
return null
# Determine if it's a white square based on coordinates
var coords = location.split("-")
var is_white_square = (int(coords[0]) + int(coords[1])) % 2 == 0
var tile = TILE_TYPES[tile_type].new(board_button, is_white_square)
print("Tile: ", tile)
tile.initialize(tile.type, tile_owner, duration)
# Add new tile
active_tiles[location] = tile active_tiles[location] = tile
return tile tile.effect_expired.connect(func(): remove_tile(location))
tile.update_appearance()
func create_fire_wall(start_pos: String, affected_positions: Array) -> void: func remove_tile(location: String) -> void:
for pos in affected_positions: if active_tiles.has(location):
create_tile(pos, "fire_wall", Tile.TileOwner.PLAYER, 3)
func get_available_positions() -> Array:
var positions = []
# Skip edge tiles and starting rows
for x in range(1, 7):
for y in range(2, 6):
var pos = str(x) + "-" + str(y)
if !active_tiles.has(pos):
positions.append(pos)
return positions
func update_tiles() -> void:
var expired_tiles = []
for location in active_tiles:
var tile = active_tiles[location]
if tile.update_duration():
expired_tiles.append(location)
for location in expired_tiles:
active_tiles.erase(location)
func get_tile_at(location: String) -> Tile:
return active_tiles.get(location)
func clear_tiles() -> void:
for location in active_tiles:
var tile = active_tiles[location] var tile = active_tiles[location]
tile.restore_base_appearance() tile.restore_base_appearance()
active_tiles.clear() 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 = []
for location in active_tiles:
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 = 3) -> void:
if !board_flow:
push_error("TileManager not initialized with board_flow")
return
var available_positions = []
for x in range(8):
for y in range(8):
if y > 1 && y < 6: # Don't place on starting rows
available_positions.append(str(x) + "-" + str(y))
available_positions.shuffle()
for i in range(min(num_tiles, available_positions.size())):
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
var tile: Tile
match tile_type:
0: # Double Movement tile
tile = DoubleMovementTile.new(container, is_white)
1: # FireWallTile
tile = FireWallTile.new(container, is_white)
2: # Pawn Boost tile
tile = PawnBoostTile.new(container, is_white)
add_tile(pos, tile)

View file

@ -4,36 +4,28 @@ extends Tile
func _init(button: Button, is_white: bool) -> void: func _init(button: Button, is_white: bool) -> void:
super._init(button, is_white) super._init(button, is_white)
tile_name = "Double Movement" tile_name = "Double Movement"
description = "Double movement for 3 turns" description = "Any unit that starts its turn here gets double movement for 2 turns"
type = TileType.GENERAL type = TileType.GENERAL
tile_owner = TileOwner.GAME
duration = -1 # Permanent tile
func apply_effect(piece: Pawn = null) -> void:
if piece && is_effect_active():
# Add double movement effect to the piece
var deck_manager = piece.get_parent().get_parent().get_parent().deckManager
var double_time = DoubleTimeCard.new()
double_time.duration = 2
deck_manager.playCard(double_time, piece)
func update_appearance() -> void: func update_appearance() -> void:
print("TILE UPDATE APPR"); if is_effect_active() && base_button:
if true && base_button:
var style = StyleBoxFlat.new() var style = StyleBoxFlat.new()
var tile_color = TILE_COLORS[tile_owner] var tile_color = Color(0, 0.8, 0.8) # Cyan for speed
var base_color = Color(0.8, 0.8, 0.8) if base_is_white else Color(0.2, 0.2, 0.2) var base_color = Color(0.8, 0.8, 0.8) if base_is_white else Color(0.2, 0.2, 0.2)
# Brighten the color slightly for double movement
tile_color = tile_color.lightened(0.2)
style.bg_color = Color( style.bg_color = Color(
(base_color.r + tile_color.r) / 2, (base_color.r + tile_color.r) / 2,
(base_color.g + tile_color.g) / 2, (base_color.g + tile_color.g) / 2,
(base_color.b + tile_color.b) / 2 (base_color.b + tile_color.b) / 2
) )
# Add distinctive border pattern
style.border_width_left = 4
style.border_width_right = 4
style.border_width_top = 4
style.border_width_bottom = 4
style.border_color = tile_color
base_button.add_theme_stylebox_override("normal", style) base_button.add_theme_stylebox_override("normal", style)
var hover_style = style.duplicate()
hover_style.bg_color = tile_color.lightened(0.2)
base_button.add_theme_stylebox_override("hover", hover_style)
else:
restore_base_appearance()

View file

@ -1,10 +1,21 @@
class_name FireWallTile class_name FireWallTile
extends Tile extends Tile
func _init(button: Button, is_white: bool) -> void: func _init(button: Button, is_white: bool) -> void:
super._init(button, is_white) super._init(button, is_white)
tile_name = "Fire Wall" tile_name = "Fire Wall"
description = "Captures any piece that moves through" description = "Captures any piece that moves through"
type = TileType.GENERAL type = TileType.GENERAL
duration = 3
func apply_effect(piece: Pawn = null) -> void:
if piece && is_effect_active():
# Get the parent container and remove the piece
var container = piece.get_parent() as PieceContainer
if container:
var board = container.get_parent().get_parent() as ChessGame
board.updatePoints(piece)
container.remove_piece()
func update_appearance() -> void: func update_appearance() -> void:
if is_effect_active() && base_button: if is_effect_active() && base_button:
@ -18,17 +29,13 @@ func update_appearance() -> void:
(base_color.b + tile_color.b) / 2 (base_color.b + tile_color.b) / 2
) )
# Thick border for danger # Add overlay effect for fire
style.border_width_left = 5 var overlay = ColorRect.new()
style.border_width_right = 5 overlay.name = "FireOverlay"
style.border_width_top = 5 overlay.color = Color(1, 0.4, 0, 0.3) # Semi-transparent orange
style.border_width_bottom = 5 overlay.size = base_button.size
style.border_color = tile_color overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE
base_button.add_theme_stylebox_override("normal", style) base_button.add_child(overlay)
var hover_style = style.duplicate()
hover_style.bg_color = tile_color.lightened(0.2)
base_button.add_theme_stylebox_override("hover", hover_style)
else: else:
restore_base_appearance() restore_base_appearance()

View file

@ -3,14 +3,22 @@ extends Tile
func _init(button: Button, is_white: bool) -> void: func _init(button: Button, is_white: bool) -> void:
super._init(button, is_white) super._init(button, is_white)
tile_name = "Fire Wall" tile_name = "Pawn Boost"
description = "Captures any piece that moves through" description = "While a Bishop is here, friendly pawns can move 2 spots"
type = TileType.GENERAL type = TileType.GLOBAL
target_piece_type = "Bishop"
tile_owner = TileOwner.GAME
duration = -1
func apply_effect(piece: Pawn = null) -> void:
if piece && is_effect_active() && piece.name == "Bishop":
# This would be implemented in the pawn movement calculation
pass
func update_appearance() -> void: func update_appearance() -> void:
if is_effect_active() && base_button: if is_effect_active() && base_button:
var style = StyleBoxFlat.new() var style = StyleBoxFlat.new()
var tile_color = Color(1, 0.4, 0) # Orange for fire var tile_color = Color(0, 0.8, 0) # Green for boost
var base_color = Color(0.8, 0.8, 0.8) if base_is_white else Color(0.2, 0.2, 0.2) var base_color = Color(0.8, 0.8, 0.8) if base_is_white else Color(0.2, 0.2, 0.2)
style.bg_color = Color( style.bg_color = Color(
@ -18,18 +26,4 @@ func update_appearance() -> void:
(base_color.g + tile_color.g) / 2, (base_color.g + tile_color.g) / 2,
(base_color.b + tile_color.b) / 2 (base_color.b + tile_color.b) / 2
) )
# Thick border for danger
style.border_width_left = 5
style.border_width_right = 5
style.border_width_top = 5
style.border_width_bottom = 5
style.border_color = tile_color
base_button.add_theme_stylebox_override("normal", style) base_button.add_theme_stylebox_override("normal", style)
var hover_style = style.duplicate()
hover_style.bg_color = tile_color.lightened(0.2)
base_button.add_theme_stylebox_override("hover", hover_style)
else:
restore_base_appearance()