diff --git a/Systems/Cards/Explosiveboots.gd b/Systems/Cards/Explosiveboots.gd index c34cf2f..1be51e5 100644 --- a/Systems/Cards/Explosiveboots.gd +++ b/Systems/Cards/Explosiveboots.gd @@ -69,7 +69,7 @@ func apply_effect(target_piece = null, board_flow = null, game_state = null): # Setup timer to remove overlays var timer = Timer.new() board_flow.add_child(timer) - timer.wait_time = 0.5 + timer.wait_time = 1 timer.one_shot = true timer.timeout.connect(func(): for tile_name in tiles_to_check: diff --git a/Systems/Cards/Supernova.gd b/Systems/Cards/Supernova.gd index 0080084..90f8d27 100644 --- a/Systems/Cards/Supernova.gd +++ b/Systems/Cards/Supernova.gd @@ -51,7 +51,14 @@ func apply_effect(target_piece = null, board_flow = null, game_state = null): # Add tile to check list 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 for tile_name in tiles_to_check: 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 var timer = Timer.new() board_flow.add_child(timer) - timer.wait_time = 0.5 + timer.wait_time = 1 timer.one_shot = true timer.timeout.connect(func(): for tile_name in tiles_to_check: diff --git a/Systems/Game/ChessGame.gd b/Systems/Game/ChessGame.gd index 47b972a..2e695fe 100644 --- a/Systems/Game/ChessGame.gd +++ b/Systems/Game/ChessGame.gd @@ -8,7 +8,6 @@ signal send_location(location: String) signal turn_changed var currentPlayer: String = WHITE var board: Array -var activeEffects: Array var currentHand: Array var selectedNode: String = "" var locationX: String = "" @@ -26,7 +25,7 @@ var Turn: int = 0 @onready var p1String: RichTextLabel = $Player1Points @onready var p2String: RichTextLabel = $Player2Points @onready var deckManager: DeckManager -# @onready var tileManager: TileManager +@onready var tileManager: TileManager @onready var cardDisplay: CardDisplay @onready var cardPreview: CardPreview @@ -45,14 +44,16 @@ var highlightStyle = null func _ready() -> void: initializeGame() + initializeTiles() stateMachine.transitionToNextState(Constants.WHITE_TURN) - # initializeTiles() -# func initializeTiles() -> void: -# tileManager = TileManager.new(boardContainer, self) -# add_child(tileManager) -# tileManager.setup_initial_tiles() +func initializeTiles() -> void: + tileManager = TileManager.new() + add_child(tileManager) + await get_tree().process_frame + tileManager.initialize(boardContainer) + tileManager.place_random_game_tiles() func get_base_style(is_white: bool) -> StyleBoxFlat: return lightStyle if is_white else darkStyle @@ -265,16 +266,11 @@ func clearBoard() -> void: # pass func updateEffectDurations() -> void: - for effect in activeEffects: - effect.duration -= 1 - if effect.duration <= 0: - activeEffects.erase(effect) - + deckManager.updateCardDurations() + tileManager.update_tile_durations() + func applyTileEffects() -> void: - for piece in get_tree().get_nodes_in_group("Pieces"): - var tile = piece.get_parent() - if tile.has_effect(): - tile.apply_effect(piece) + tileManager.apply_tile_effects() func applyCardEffects() -> void: @@ -342,14 +338,22 @@ func getMovableAreas() -> void: highlightValidMoves() func highlightValidMoves() -> void: - # print("HIGHLIGHTING VALID MOVES") for move in areas: var button = boardContainer.get_node(move) - var isWhiteSquare = (int(move.split("-")[0]) + int(move.split("-")[1])) % 2 == 0 - var baseStyle = lightStyle if isWhiteSquare else darkStyle - var combinedStyle = StyleBoxFlat.new() - combinedStyle.bg_color = baseStyle.bg_color + highlightStyle.bg_color - button.add_theme_stylebox_override("normal", combinedStyle) + + # 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 baseStyle = lightStyle if isWhiteSquare else darkStyle + var combinedStyle = StyleBoxFlat.new() + combinedStyle.bg_color = baseStyle.bg_color + highlightStyle.bg_color + button.add_theme_stylebox_override("normal", combinedStyle) func executeMove(targetLocation: String) -> void: print("executeMove ", targetLocation) @@ -407,6 +411,11 @@ func resetHighlights(): for button in boardContainer.get_children(): if !button.name.contains("-"): continue + + # Skip if this tile has an active effect + if tileManager && tileManager.get_tile(button.name): + continue + var coord = button.name.split("-") var isWhiteSquare = (int(coord[0]) + int(coord[1])) % 2 == 0 if isWhiteSquare: diff --git a/Systems/PieceContainer.gd b/Systems/PieceContainer.gd index 518748d..2130061 100644 --- a/Systems/PieceContainer.gd +++ b/Systems/PieceContainer.gd @@ -1,18 +1,14 @@ class_name PieceContainer extends Button var piece: Pawn = null -@onready var overlays: Node = $Overlays -@onready var effects: Node = $Effects +var effects: Node # Keep effects as a sub-node +var overlay_nodes: Array[Node] = [] func _init() -> void: - # Create containers for different types of children - var overlays_node = Node.new() - overlays_node.name = "Overlays" - add_child(overlays_node) - - var effects_node = Node.new() - effects_node.name = "Effects" - add_child(effects_node) + # Setup effects node + effects = Node.new() + effects.name = "Effects" + add_child(effects) func set_piece(new_piece: Pawn) -> void: remove_piece() # Clean up any existing piece @@ -35,15 +31,26 @@ func remove_piece(keep_piece: bool = false) -> Pawn: return old_piece 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: - var overlay = overlays.get_node_or_null(overlay_name) - if overlay: - overlay.queue_free() + for overlay in overlay_nodes: + if overlay.name == overlay_name: + remove_child(overlay) + overlay_nodes.erase(overlay) + overlay.queue_free() + break 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: return piece != null \ No newline at end of file diff --git a/Systems/StateMachine/GameStates/AttachCards.gd b/Systems/StateMachine/GameStates/AttachCards.gd index 772c454..ecf375b 100644 --- a/Systems/StateMachine/GameStates/AttachCards.gd +++ b/Systems/StateMachine/GameStates/AttachCards.gd @@ -1,6 +1,6 @@ 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 tile_pressed_connection: Signal diff --git a/Systems/StateMachine/GameStates/ResolvePersistentEffects.gd b/Systems/StateMachine/GameStates/ResolvePersistentEffects.gd index c242f38..2abf8d4 100644 --- a/Systems/StateMachine/GameStates/ResolvePersistentEffects.gd +++ b/Systems/StateMachine/GameStates/ResolvePersistentEffects.gd @@ -3,4 +3,4 @@ extends "res://Systems/StateMachine/ChessGameState.gd" func enter(_previous: String, _data := {}) -> void: print("ENTERING STATE ", Constants.PERSISTENT_EFFECTS) game.updateEffectDurations() - finished.emit(Constants.TILE_EFFECTS) \ No newline at end of file + finished.emit(Constants.TILE_EFFECTS) diff --git a/Systems/Tile.gd b/Systems/Tile.gd index c1ccff0..046d6ca 100644 --- a/Systems/Tile.gd +++ b/Systems/Tile.gd @@ -1,99 +1,72 @@ -@tool class_name Tile +extends Resource enum TileType { - GENERAL, # Effects apply to any piece - SPECIFIC, # Effects apply to specific pieces - GLOBAL # Effects apply globally while conditions are met + GENERAL, # Affects any unit + SPECIFIC, # Affects specific unit type + GLOBAL # Affects all units of a color while active } enum TileOwner { - PLAYER, # White player's tiles - ENEMY, # Black player's tiles - GAME # Neutral game tiles + PLAYER, # White player + ENEMY, # Black player + GAME # Neutral/game-owned } -const TILE_COLORS = { - TileOwner.PLAYER: Color(0.2, 0.8, 0.2, 0.5), - TileOwner.ENEMY: Color(0.8, 0.2, 0.2, 0.5), - TileOwner.GAME: Color(0.2, 0.2, 0.8, 0.5) -} +var tile_name: String = "" +var description: String = "" +var duration: int = -1 # -1 for permanent tiles +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 -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 +signal effect_expired func _init(button: Button, is_white: bool) -> void: base_button = button 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 - 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: - 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: if base_button: - var board = base_button.get_parent() - if board && board.has_method("get_base_style"): - var base_style = board.get_base_style(base_is_white) - 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 \ No newline at end of file + var style = StyleBoxFlat.new() + style.bg_color = Color(0.8, 0.8, 0.8, 1) if base_is_white else Color(0.2, 0.2, 0.2, 1) + base_button.add_theme_stylebox_override("normal", style) \ No newline at end of file diff --git a/Systems/TileManager.gd b/Systems/TileManager.gd index d2bf122..046440c 100644 --- a/Systems/TileManager.gd +++ b/Systems/TileManager.gd @@ -1,93 +1,112 @@ -extends Node 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 game_board: Node # Reference to the game board -var game_state: Node # Reference to the game state +var active_tiles: Dictionary = {} # location: Tile +var board_flow: FlowContainer const DoubleMovementTile = preload("res://Systems/Tiles/DoubleMovement.gd") const FireWallTile = preload("res://Systems/Tiles/FireWall.gd") const PawnBoostTile = preload("res://Systems/Tiles/PawnBoost.gd") +func _init(flow: FlowContainer = null) -> void: + if flow: + initialize(flow) -# Available tile classes -const TILE_TYPES = { - "double_movement": DoubleMovementTile, - "fire_wall": FireWallTile, - "pawn_boost": PawnBoostTile -} +func initialize(flow: FlowContainer) -> void: + board_flow = flow + clear_tiles() -func _init(board: Node, state: Node = null) -> void: - game_board = board - game_state = state - -func setup_initial_tiles() -> void: - var available_positions = ["4-4", "4-6", "2-4"] - # get_available_positions() - available_positions.shuffle() - - for i in range(min(INITIAL_GAME_TILES, available_positions.size())): - var pos = available_positions[i] - 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 +func add_tile(location: String, tile: Tile) -> void: + if !board_flow: + push_error("TileManager not initialized with board_flow") + return - # 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) + 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) + # Add new 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: - for pos in affected_positions: - 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: +func remove_tile(location: String) -> void: + if active_tiles.has(location): var tile = active_tiles[location] tile.restore_base_appearance() - active_tiles.clear() \ No newline at end of file + 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) \ No newline at end of file diff --git a/Systems/Tiles/DoubleMovement.gd b/Systems/Tiles/DoubleMovement.gd index 85e38b1..00d20e5 100644 --- a/Systems/Tiles/DoubleMovement.gd +++ b/Systems/Tiles/DoubleMovement.gd @@ -4,36 +4,28 @@ extends Tile func _init(button: Button, is_white: bool) -> void: super._init(button, is_white) 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 + 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: - print("TILE UPDATE APPR"); - if true && base_button: + if is_effect_active() && base_button: 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) - # Brighten the color slightly for double movement - tile_color = tile_color.lightened(0.2) - style.bg_color = Color( (base_color.r + tile_color.r) / 2, (base_color.g + tile_color.g) / 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) - - 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() diff --git a/Systems/Tiles/FireWall.gd b/Systems/Tiles/FireWall.gd index c530fc2..67ce420 100644 --- a/Systems/Tiles/FireWall.gd +++ b/Systems/Tiles/FireWall.gd @@ -1,10 +1,21 @@ class_name FireWallTile extends Tile + func _init(button: Button, is_white: bool) -> void: super._init(button, is_white) tile_name = "Fire Wall" description = "Captures any piece that moves through" 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: if is_effect_active() && base_button: @@ -18,17 +29,13 @@ func update_appearance() -> void: (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 + # Add overlay effect for fire + var overlay = ColorRect.new() + overlay.name = "FireOverlay" + overlay.color = Color(1, 0.4, 0, 0.3) # Semi-transparent orange + overlay.size = base_button.size + overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE - 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) + base_button.add_child(overlay) else: - restore_base_appearance() + restore_base_appearance() \ No newline at end of file diff --git a/Systems/Tiles/PawnBoost.gd b/Systems/Tiles/PawnBoost.gd index 9845222..1eb5121 100644 --- a/Systems/Tiles/PawnBoost.gd +++ b/Systems/Tiles/PawnBoost.gd @@ -3,14 +3,22 @@ extends Tile func _init(button: Button, is_white: bool) -> void: super._init(button, is_white) - tile_name = "Fire Wall" - description = "Captures any piece that moves through" - type = TileType.GENERAL + tile_name = "Pawn Boost" + description = "While a Bishop is here, friendly pawns can move 2 spots" + 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: if is_effect_active() && base_button: 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) style.bg_color = Color( @@ -18,18 +26,4 @@ func update_appearance() -> void: (base_color.g + tile_color.g) / 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) - - 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() + base_button.add_theme_stylebox_override("normal", style) \ No newline at end of file