ChessBuilder/Systems/Cards/Supernova.gd

128 lines
4.8 KiB
GDScript

class_name SupernovaCard extends Card
const CAPTURE_RADIUS = 4
func _init():
super._init()
cardName = "Supernova"
rank = Rank.RANK_0
effectType = EffectType.PIECE_EFFECT
duration = 5
description = "All enemy units within 4 radius are captured"
unitWhitelist = ["King"]
func apply_effect(target_piece = null, board_flow = null, game_state = null):
if !super.apply_effect(target_piece, board_flow, game_state):
return false
if !target_piece or !board_flow or !game_state:
return false
# Get king's position
var king_pos = target_piece.get_parent().name.split("-")
var king_x = int(king_pos[0])
var king_y = int(king_pos[1])
# Collect all tiles within radius to check
var tiles_to_check = []
# Check in all directions (up, down, left, right and diagonals)
for dx in range(-CAPTURE_RADIUS, CAPTURE_RADIUS + 1):
for dy in range(-CAPTURE_RADIUS, CAPTURE_RADIUS + 1):
# Skip if outside Manhattan distance
if abs(dx) + abs(dy) > CAPTURE_RADIUS:
continue
# Calculate target coordinates
var target_x = king_x + dx
var target_y = king_y + dy
# Skip if outside board bounds
if target_x < 0 or target_x >= 8 or target_y < 0 or target_y >= 8:
continue
# Skip king's own position
if dx == 0 and dy == 0:
continue
# Add tile to check list
tiles_to_check.append(str(target_x) + "-" + str(target_y))
# Process each tile and capture pieces
for tile_name in tiles_to_check:
var tile = board_flow.get_node("Flow/" + tile_name)
if tile.get_child_count() > 0:
var piece = tile.get_child(0)
if piece.Item_Color != target_piece.Item_Color: # Only capture enemy pieces
game_state.updatePoints(piece)
piece.queue_free()
# Visual feedback
for tile_name in tiles_to_check:
var tile = board_flow.get_node("Flow/" + tile_name)
var style = StyleBoxFlat.new()
style.bg_color = Color(1, 0, 0, 0.3) # Red tint
tile.add_theme_stylebox_override("normal", style)
# Remove highlight after delay
var timer = Timer.new()
board_flow.add_child(timer)
timer.wait_time = 0.5
timer.one_shot = true
timer.timeout.connect(func():
tile.remove_theme_stylebox_override("normal")
timer.queue_free()
)
timer.start()
# game_state.stateMachine.transitionToNextState(Constants.POST_MOVE)
return true
func setup_persistent_effect(king, game_state):
# Connect to the turn change signal if not already connected
if !game_state.is_connected("turn_changed", Callable(self, "on_turn_changed")):
game_state.connect("turn_changed", Callable(self, "on_turn_changed"))
func on_turn_changed():
if attached_piece and remaining_turns > 0:
# Reapply the effect at the start of each turn
apply_effect(attached_piece, attached_piece.get_parent().get_parent(), attached_piece.get_parent().get_parent().owner)
remaining_turns -= 1
if remaining_turns <= 0:
remove_effect()
func remove_effect():
if attached_piece:
var game_state = attached_piece.get_parent().get_parent().owner
if game_state.is_connected("turn_changed", Callable(self, "on_turn_changed")):
game_state.disconnect("turn_changed", Callable(self, "on_turn_changed"))
super.remove_effect()
func update_visual_effect(king, board_flow):
# Could be extended with visual feedback like particles or highlighting
var radius_tiles = []
var king_pos = king.get_parent().name.split("-")
var king_x = int(king_pos[0])
var king_y = int(king_pos[1])
for x in range(max(0, king_x - CAPTURE_RADIUS), min(8, king_x + CAPTURE_RADIUS + 1)):
for y in range(max(0, king_y - CAPTURE_RADIUS), min(8, king_y + CAPTURE_RADIUS + 1)):
if abs(x - king_x) + abs(y - king_y) <= CAPTURE_RADIUS:
var tile_name = str(x) + "-" + str(y)
radius_tiles.append(board_flow.get_node(tile_name))
# Highlight affected tiles briefly
for tile in radius_tiles:
var style = StyleBoxFlat.new()
style.bg_color = Color(1, 0, 0, 0.3) # Red tint
tile.add_theme_stylebox_override("normal", style)
# Remove highlight after a short delay
var timer = Timer.new()
board_flow.add_child(timer)
timer.wait_time = 0.5
timer.one_shot = true
timer.timeout.connect(func():
tile.remove_theme_stylebox_override("normal")
timer.queue_free()
)
timer.start()