fixed crash on board size change and turn interaction with explosive cards
This commit is contained in:
parent
8e23e34a66
commit
c09ddcb1a2
13 changed files with 498 additions and 42 deletions
|
|
@ -17,6 +17,7 @@ func reset():
|
|||
valid = false
|
||||
|
||||
func apply_effect(target_piece = null, board_flow = null, game_state = null):
|
||||
print("EXPLOSIVE apply_effect", )
|
||||
attached_piece = target_piece
|
||||
stored_board_flow = board_flow
|
||||
stored_game_state = game_state
|
||||
|
|
@ -26,6 +27,7 @@ func apply_effect(target_piece = null, board_flow = null, game_state = null):
|
|||
setup_persistent_effect(game_state)
|
||||
# dont apply on card attachment
|
||||
if !valid:
|
||||
print("EXPLOSIVE apply_effect INVALID", )
|
||||
return true
|
||||
var piece_pos = target_piece.get_parent().name.split("-")
|
||||
var piece_x = int(piece_pos[0])
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ func _init():
|
|||
func initializeStartingDeck():
|
||||
deck.clear();
|
||||
# for i in range(2):
|
||||
# deck.append(DoubleTimeCard.new())
|
||||
deck.append(HopscotchCard.new())
|
||||
deck.append(FieryCapeCard.new())
|
||||
deck.append(FieryTrailCard.new())
|
||||
# deck.append(DoubleTimeCard.new())
|
||||
# deck.append(HopscotchCard.new())
|
||||
# deck.append(FieryCapeCard.new())
|
||||
# deck.append(FieryTrailCard.new())
|
||||
deck.append(ExplosiveBootsCard.new())
|
||||
deck.append(DoubleTimeCard.new())
|
||||
deck.append(DrunkDrivingCard.new())
|
||||
deck.append(SupernovaCard.new())
|
||||
# deck.append(DrunkDrivingCard.new())
|
||||
# deck.append(SupernovaCard.new())
|
||||
|
||||
func initializeStartingBank():
|
||||
# sample
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
class_name ChessGame extends Control
|
||||
|
||||
# Constants
|
||||
const PieceContainer = preload("res://Systems/PieceContainer.gd")
|
||||
const WHITE = "white"
|
||||
const BLACK = "black"
|
||||
const StockfishController = preload("res://Systems/FairyStockfish/StockfishClient.gd")
|
||||
|
|
@ -60,6 +59,10 @@ var currentNode = null;
|
|||
@onready var menuContainer = get_node_or_null("/root/Board/MenuContainer")
|
||||
@onready var mapContainer = get_node_or_null("/root/Board/MapScreen")
|
||||
|
||||
var winConditionManager: WinConditionManager
|
||||
var currentWinCondition = Utils.WinConditionType.CAPTURE_UNIT
|
||||
var currentLossCondition = Utils.LossConditionType.UNIT_LOST
|
||||
|
||||
|
||||
# Export parameters
|
||||
@export var boardXSize = 12
|
||||
|
|
@ -109,16 +112,20 @@ func _on_new_game_requested(options = {}):
|
|||
cpuElo = options.metadata.elo
|
||||
if cameraController:
|
||||
cameraController.reset_view()
|
||||
if options and "metadata" in options:
|
||||
if winConditionManager:
|
||||
winConditionManager.load_condition_from_metadata(options.metadata)
|
||||
|
||||
currentNode = options
|
||||
print("ChessGame FEN ", currentFen)
|
||||
print("ChessGame DIMENSIONS ", get_board_dimensions(currentFen))
|
||||
if is_initialized:
|
||||
resetBoard()
|
||||
initializeDeckSystem()
|
||||
initializeBoard()
|
||||
if cardDisplay:
|
||||
cardDisplay.visible = true
|
||||
if stateMachine:
|
||||
stateMachine.start()
|
||||
stateMachine.transitionToNextState(Constants.WHITE_TURN)
|
||||
else:
|
||||
initialize_game_system()
|
||||
|
|
@ -126,6 +133,7 @@ func _on_new_game_requested(options = {}):
|
|||
stockfishController.start_board(cpuElo, get_board_dimensions(currentFen))
|
||||
else:
|
||||
stockfishController.start_board(cpuElo, "8x8")
|
||||
resetHighlights()
|
||||
func initialize_game_system():
|
||||
print("Initializing game system")
|
||||
# Set up basic styles first
|
||||
|
|
@ -140,6 +148,11 @@ func initialize_game_system():
|
|||
add_child(stockfishController)
|
||||
stockfishController.connect_to_engine(stockfishPath, self)
|
||||
|
||||
winConditionManager = WinConditionManager.new(self)
|
||||
add_child(winConditionManager)
|
||||
winConditionManager.connect("win_condition_met", Callable(self, "_on_win_condition_met"))
|
||||
winConditionManager.connect("loss_condition_met", Callable(self, "_on_loss_condition_met"))
|
||||
|
||||
# Start the state machine
|
||||
if stateMachine:
|
||||
stateMachine.start()
|
||||
|
|
@ -217,9 +230,10 @@ func initializeDeckSystem() -> void:
|
|||
deckManager.shuffleDeck()
|
||||
deckManager.drawStartingHand()
|
||||
# Initialize the deck manager and card display
|
||||
cardDisplay = CardDisplay.new()
|
||||
add_child(deckManager)
|
||||
add_child(cardDisplay)
|
||||
if cardDisplay == null:
|
||||
cardDisplay = CardDisplay.new()
|
||||
add_child(cardDisplay)
|
||||
add_child(deckManager)
|
||||
|
||||
# Set up signals for card interaction
|
||||
if !deckManager.has_user_signal("card_pressed"):
|
||||
|
|
@ -301,7 +315,17 @@ func get_base_style(is_white: bool) -> StyleBoxFlat:
|
|||
# ===========================================================================
|
||||
|
||||
func createBoard() -> void:
|
||||
boardContainer.add_to_group("Flow")
|
||||
|
||||
for child in boardContainer.get_children():
|
||||
boardContainer.remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
# Reset container size
|
||||
boardContainer.size = Vector2.ZERO
|
||||
|
||||
# Add to group if not already in it
|
||||
if not boardContainer.is_in_group("Flow"):
|
||||
boardContainer.add_to_group("Flow")
|
||||
var numberX = 0
|
||||
var numberY = 0
|
||||
var isWhite = true
|
||||
|
|
@ -461,7 +485,6 @@ func _unhandled_input(event: InputEvent) -> void:
|
|||
func resetBoard() -> void:
|
||||
clearSelection()
|
||||
clearBoard()
|
||||
setupPiecesFromFEN()
|
||||
Turn = 0
|
||||
currentPlayer = WHITE
|
||||
p1Points = 0
|
||||
|
|
@ -558,20 +581,48 @@ func executeMove(targetLocation: String) -> void:
|
|||
hasMoved = true
|
||||
currentlyMovingPiece = piece
|
||||
resetHighlights()
|
||||
if winConditionManager:
|
||||
winConditionManager.on_piece_moved(piece, old_location, targetLocation)
|
||||
|
||||
|
||||
# Additional helper function to check if a specific tile has been reached
|
||||
func is_tile_reached(location: String, piece_name: String = "") -> bool:
|
||||
var container = get_node("Flow/" + location) as PieceContainer
|
||||
if container and container.has_piece():
|
||||
var piece = container.get_piece()
|
||||
if piece_name == "" or piece.name == piece_name:
|
||||
return piece.Item_Color == 0 # Player's piece
|
||||
return false
|
||||
|
||||
|
||||
# func resolveMoveEffects() -> void:
|
||||
# # Resolve effects after a move is made
|
||||
# print("resolveMoveEffects", currentlyMovingPiece)
|
||||
# togglePieceChessEffect()
|
||||
|
||||
# selectedNode = ""
|
||||
# Turn = 1 if Turn == 0 else 0
|
||||
# updateTurnIndicator()
|
||||
# resetHighlights()
|
||||
# hasMoved = false
|
||||
# currentlyMovingPiece = null
|
||||
# emit_signal("turn_changed")
|
||||
|
||||
|
||||
func resolveMoveEffects() -> void:
|
||||
# Resolve effects after a move is made
|
||||
print("resolveMoveEffects", currentlyMovingPiece)
|
||||
togglePieceChessEffect()
|
||||
|
||||
selectedNode = ""
|
||||
Turn = 1 if Turn == 0 else 0
|
||||
updateTurnIndicator()
|
||||
resetHighlights()
|
||||
hasMoved = false
|
||||
currentlyMovingPiece = null
|
||||
emit_signal("turn_changed")
|
||||
Turn = 1 if Turn == 0 else 0
|
||||
updateTurnIndicator()
|
||||
|
||||
func endTurn() -> void:
|
||||
print("turn_changed")
|
||||
|
||||
|
||||
func togglePieceChessEffect() -> void:
|
||||
|
|
@ -687,27 +738,56 @@ func isNull(location: String) -> bool:
|
|||
|
||||
func updatePointsAndCapture(capturedPiece: Pawn, animate: bool = true) -> void:
|
||||
# Update points and handle piece capture
|
||||
if Turn == 0:
|
||||
|
||||
print(Turn, " updatePointsAndCapture ", capturedPiece.Item_Color)
|
||||
if animate:
|
||||
animatePieceCapture(capturedPiece)
|
||||
if Turn == 0: # Player's turn
|
||||
gold += capturedPiece.Points;
|
||||
p1Points += capturedPiece.Points
|
||||
p1String.text = str(p1Points)
|
||||
else:
|
||||
|
||||
# Player captured an enemy piece
|
||||
print("winConditionManager and capturedPiece.Item_Color == 1")
|
||||
if winConditionManager and capturedPiece.Item_Color == 1: # Enemy piece (black)
|
||||
print("Player captured an enemy piece ")
|
||||
winConditionManager.on_piece_captured(capturedPiece)
|
||||
else: # Enemy's turn
|
||||
p2Points += capturedPiece.Points
|
||||
p2String.text = str(p2Points)
|
||||
if animate:
|
||||
animatePieceCapture(capturedPiece)
|
||||
|
||||
# Enemy captured a player piece
|
||||
print("winConditionManager and capturedPiece.Item_Color == 0")
|
||||
if winConditionManager and capturedPiece.Item_Color == 0: # Player piece (white)
|
||||
print("ENemy captured an player piece ")
|
||||
winConditionManager.on_piece_lost(capturedPiece)
|
||||
|
||||
|
||||
if capturedPiece.name == "King":
|
||||
print("Game Over!")
|
||||
emit_signal("node_completed", {
|
||||
"node": currentNode,
|
||||
"completed": true,
|
||||
"success": true
|
||||
})
|
||||
gamecheckMate = true
|
||||
|
||||
|
||||
|
||||
func _on_win_condition_met(condition_data):
|
||||
print("Win condition met: ", condition_data)
|
||||
emit_signal("node_completed", {
|
||||
"node": currentNode,
|
||||
"completed": true,
|
||||
"success": true,
|
||||
"condition": condition_data
|
||||
})
|
||||
# endRound()
|
||||
|
||||
func _on_loss_condition_met(condition_data):
|
||||
print("Loss condition met: ", condition_data)
|
||||
emit_signal("node_completed", {
|
||||
"node": currentNode,
|
||||
"completed": true,
|
||||
"success": false,
|
||||
"condition": condition_data
|
||||
})
|
||||
# endRound()
|
||||
|
||||
func animatePieceCapture(capturedPiece: Pawn) -> void:
|
||||
# Animate the capture of a piece
|
||||
var container = capturedPiece.get_parent() as PieceContainer
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ func generate_boss_data(node):
|
|||
"is_escape": node.metadata.is_escape if node.metadata.has("is_escape") else false,
|
||||
"fen": fen + fen_ending,
|
||||
"game_type": "chess",
|
||||
"win_condition": Utils.WinCondition.King,
|
||||
"win_condition": Utils.WinConditionType.CAPTURE_UNIT,
|
||||
"reward": {
|
||||
"gold": 50 * node.level,
|
||||
"cards": [],
|
||||
|
|
@ -310,7 +310,6 @@ func generate_boss_data(node):
|
|||
}
|
||||
|
||||
|
||||
|
||||
func generate_shop_data(node):
|
||||
var num_shop_cards = min(randi_range(5, 7), Utils.CardTypes.size())
|
||||
return {
|
||||
|
|
@ -346,7 +345,7 @@ func generate_event_data(node):
|
|||
"is_escape": node.metadata.is_escape if node.metadata.has("is_escape") else false,
|
||||
"fen": "8/4p3/8/8/8/8 w KQkq - 0 1",
|
||||
"game_type": "maze",
|
||||
"win_condition": Utils.WinCondition.Tile,
|
||||
"win_condition": Utils.WinConditionType.TILE_REACHED,
|
||||
"elo": node.elo,
|
||||
}
|
||||
# "rnbqkbnr1/pppppppp1/9/9/9/9/9/PPPPPPPP1/RNBQKBNR1 w KQkq - 0 1"
|
||||
|
|
@ -384,17 +383,83 @@ func generate_chess_data(node):
|
|||
fen += pawn_string.to_upper() + "/" + unit_string.to_upper()
|
||||
var fen_ending = " w KQkq - 0 1"
|
||||
# print("generate_chess_data ", fen + fen_ending)
|
||||
return {
|
||||
var win_condition = Utils.WinConditionType.CAPTURE_UNIT # Default
|
||||
var loss_condition = Utils.LossConditionType.UNIT_LOST # Default
|
||||
|
||||
# Randomly select a win condition with increasing variety at higher levels
|
||||
var rng_val = _rng.randf()
|
||||
var conditions_pool = [Utils.WinConditionType.CAPTURE_UNIT] # Default pool
|
||||
|
||||
# # Add more varied win conditions at higher levels
|
||||
# if node.level >= 3:
|
||||
# conditions_pool.append(Utils.WinConditionType.BOARD_CLEARED)
|
||||
# if node.level >= 5:
|
||||
# conditions_pool.append(Utils.WinConditionType.TILE_REACHED)
|
||||
# if node.level >= 7:
|
||||
# conditions_pool.append(Utils.WinConditionType.TURN_NUMBER)
|
||||
|
||||
# # For certain special nodes, always use specific conditions
|
||||
# if node.type == Utils.RoomType.EVENT:
|
||||
# win_condition = Utils.WinConditionType.TILE_REACHED
|
||||
# elif node.type == Utils.RoomType.BOSS and node.level > 5:
|
||||
# # Bosses at higher levels have more varied win conditions
|
||||
# win_condition = conditions_pool[_rng.randi() % conditions_pool.size()]
|
||||
# else:
|
||||
# # Regular nodes have weighted randomness
|
||||
# if rng_val < 0.7: # 70% chance of default capture king
|
||||
# win_condition = Utils.WinConditionType.CAPTURE_UNIT
|
||||
# else:
|
||||
# # Pick randomly from the conditions pool
|
||||
# win_condition = conditions_pool[_rng.randi() % conditions_pool.size()]
|
||||
|
||||
# Create additional metadata for specific win conditions
|
||||
var additional_metadata = {}
|
||||
|
||||
# match win_condition:
|
||||
# Utils.WinConditionType.TILE_REACHED:
|
||||
# # Generate target tiles for the Tile win condition
|
||||
# var target_tiles = []
|
||||
# var target_count = 1 # Default to 1 target tile
|
||||
|
||||
# # Determine target unit (default is any piece)
|
||||
# var target_unit = ""
|
||||
# if _rng.randf() < 0.5: # 50% chance of specific piece
|
||||
# var pieces = ["Pawn", "Knight", "Bishop", "Rook", "Queen"]
|
||||
# target_unit = pieces[_rng.randi() % pieces.size()]
|
||||
|
||||
# # Create target tiles at the enemy's back rank
|
||||
# var target_x = _rng.randi() % unit_string.length()
|
||||
# target_tiles.append(str(target_x) + "-0") # Top row
|
||||
|
||||
# additional_metadata["target_tiles"] = target_tiles
|
||||
# additional_metadata["target_unit"] = target_unit
|
||||
|
||||
# Utils.WinConditionType.TURN_NUMBER:
|
||||
# # Set a target turn number
|
||||
# additional_metadata["target_turn"] = (node.level * 2) + _rng.randi_range(5, 10)
|
||||
|
||||
# # Also add a turn limit for loss condition
|
||||
# loss_condition = Utils.LossConditionType.TURN_NUMBER
|
||||
# additional_metadata["turn_limit"] = additional_metadata["target_turn"] + _rng.randi_range(5, 15)
|
||||
|
||||
# Build the result metadata
|
||||
var result = {
|
||||
"is_escape": node.metadata.is_escape if node.metadata.has("is_escape") else false,
|
||||
"fen": fen + fen_ending,
|
||||
"game_type": "chess",
|
||||
"win_condition": Utils.WinCondition.King,
|
||||
"win_condition": win_condition,
|
||||
"loss_condition": loss_condition,
|
||||
"elo": node.elo,
|
||||
"reward": {
|
||||
"gold": 50 * node.level
|
||||
}
|
||||
}
|
||||
|
||||
# Merge additional metadata
|
||||
for key in additional_metadata:
|
||||
result[key] = additional_metadata[key]
|
||||
|
||||
return result
|
||||
|
||||
func map_to_array_index(current_value, min_value, max_value, min_index, max_index):
|
||||
# Ensure the current value is within bounds
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ class_name MenuContainer
|
|||
const VERSION_FILE_PATH = "res://Game.json"
|
||||
# Signal to notify parent when a new game is requested
|
||||
# signal new_game_requested
|
||||
signal reward_closed
|
||||
signal new_game_requested(options)
|
||||
signal shop_open_requested(options)
|
||||
signal reward_open_requested(options)
|
||||
|
|
@ -28,6 +29,10 @@ signal card_purchased(card, price)
|
|||
# back up if game isn't loaded yet?
|
||||
var player_gold = 10
|
||||
var back_to_map = false
|
||||
var winConditionManager: WinConditionManager
|
||||
var currentWinCondition = Utils.WinConditionType.CAPTURE_UNIT
|
||||
var currentLossCondition = Utils.LossConditionType.UNIT_LOST
|
||||
|
||||
|
||||
func _ready():
|
||||
# Connect menu option signals
|
||||
|
|
|
|||
297
Systems/Game/WinConditionManager.gd
Normal file
297
Systems/Game/WinConditionManager.gd
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
extends Node
|
||||
class_name WinConditionManager
|
||||
|
||||
# Signals
|
||||
signal win_condition_met(condition_data)
|
||||
signal loss_condition_met(condition_data)
|
||||
signal condition_progress_updated(progress_data)
|
||||
|
||||
# References
|
||||
var chess_game: ChessGame
|
||||
var tile_manager: TileManager
|
||||
|
||||
# Condition configuration
|
||||
var win_condition: Utils.WinConditionType = Utils.WinConditionType.CAPTURE_UNIT
|
||||
var loss_condition: Utils.LossConditionType = Utils.LossConditionType.UNIT_LOST
|
||||
var win_condition_data: Dictionary = {}
|
||||
var loss_condition_data: Dictionary = {}
|
||||
|
||||
# Progress tracking
|
||||
var captured_pieces = []
|
||||
var turn_count = 0
|
||||
var target_tiles = []
|
||||
var condition_progress = {}
|
||||
|
||||
func _init(game: ChessGame):
|
||||
chess_game = game
|
||||
if chess_game:
|
||||
tile_manager = chess_game.tileManager
|
||||
# Connect to relevant signals
|
||||
chess_game.connect("turn_changed", Callable(self, "_on_turn_changed"))
|
||||
chess_game.connect("game_initialized", Callable(self, "_on_game_initialized"))
|
||||
|
||||
func _on_game_initialized():
|
||||
reset_conditions()
|
||||
|
||||
func reset_conditions():
|
||||
captured_pieces.clear()
|
||||
turn_count = 0
|
||||
target_tiles.clear()
|
||||
condition_progress.clear()
|
||||
|
||||
# Setup initial progress tracking
|
||||
match win_condition:
|
||||
Utils.WinConditionType.BOARD_CLEARED:
|
||||
condition_progress["total_enemy_pieces"] = count_enemy_pieces()
|
||||
condition_progress["remaining_enemy_pieces"] = condition_progress["total_enemy_pieces"]
|
||||
Utils.WinConditionType.TILE_REACHED:
|
||||
if "target_tiles" in win_condition_data:
|
||||
target_tiles = win_condition_data["target_tiles"]
|
||||
highlight_target_tiles()
|
||||
condition_progress["tiles_reached"] = []
|
||||
Utils.WinConditionType.TURN_NUMBER:
|
||||
if "target_turn" in win_condition_data:
|
||||
condition_progress["target_turn"] = win_condition_data["target_turn"]
|
||||
condition_progress["current_turn"] = 0
|
||||
|
||||
func highlight_target_tiles():
|
||||
# Highlight target tiles on the board with a special visual style
|
||||
for tile_loc in target_tiles:
|
||||
if tile_manager:
|
||||
# Create a goal tile if needed
|
||||
var container = chess_game.get_node("Flow/" + tile_loc) as PieceContainer
|
||||
if container:
|
||||
# Create a visual indicator - use a styled container
|
||||
var style = StyleBoxFlat.new()
|
||||
style.bg_color = Color(0.2, 0.8, 0.2, 0.4) # Green translucent
|
||||
style.border_width_all = 2
|
||||
style.border_color = Color(0.3, 1.0, 0.3, 0.8)
|
||||
|
||||
# Apply the style while respecting chess pattern
|
||||
var coord = tile_loc.split("-")
|
||||
var isWhiteSquare = (int(coord[0]) + int(coord[1])) % 2 == 0
|
||||
var baseStyle = chess_game.lightStyle if isWhiteSquare else chess_game.darkStyle
|
||||
var combinedStyle = StyleBoxFlat.new()
|
||||
combinedStyle.bg_color = baseStyle.bg_color + style.bg_color
|
||||
combinedStyle.border_width_all = style.border_width_all
|
||||
combinedStyle.border_color = style.border_color
|
||||
|
||||
container.add_theme_stylebox_override("normal", combinedStyle)
|
||||
|
||||
func set_win_condition(type: Utils.WinConditionType, data: Dictionary = {}):
|
||||
win_condition = type
|
||||
win_condition_data = data
|
||||
reset_conditions()
|
||||
|
||||
func set_loss_condition(type: Utils.LossConditionType, data: Dictionary = {}):
|
||||
loss_condition = type
|
||||
loss_condition_data = data
|
||||
reset_conditions()
|
||||
|
||||
func _on_turn_changed():
|
||||
turn_count += 1
|
||||
|
||||
# Update progress for turn-based conditions
|
||||
if win_condition == Utils.WinConditionType.TURN_NUMBER:
|
||||
condition_progress["current_turn"] = turn_count
|
||||
emit_signal("condition_progress_updated", condition_progress)
|
||||
|
||||
if "target_turn" in win_condition_data and turn_count >= win_condition_data["target_turn"]:
|
||||
emit_signal("win_condition_met", {
|
||||
"type": Utils.WinConditionType.TURN_NUMBER,
|
||||
"message": "Turn limit reached!"
|
||||
})
|
||||
|
||||
if loss_condition == Utils.LossConditionType.TURN_NUMBER:
|
||||
if "turn_limit" in loss_condition_data and turn_count >= loss_condition_data["turn_limit"]:
|
||||
emit_signal("loss_condition_met", {
|
||||
"type": Utils.LossConditionType.TURN_NUMBER,
|
||||
"message": "Turn limit exceeded!"
|
||||
})
|
||||
|
||||
# Check all conditions after turn change
|
||||
check_conditions()
|
||||
|
||||
func on_piece_captured(piece):
|
||||
# First verify this is an enemy piece (with opposite color to current player)
|
||||
var is_enemy_piece = piece.Item_Color == (1 if chess_game.Turn == 0 else 0)
|
||||
print("on_piece_captured ISEnemy ", is_enemy_piece)
|
||||
if is_enemy_piece:
|
||||
captured_pieces.append(piece)
|
||||
|
||||
# Update progress for board-cleared condition
|
||||
if win_condition == Utils.WinConditionType.BOARD_CLEARED:
|
||||
condition_progress["remaining_enemy_pieces"] -= 1
|
||||
emit_signal("condition_progress_updated", condition_progress)
|
||||
|
||||
if condition_progress["remaining_enemy_pieces"] <= 0:
|
||||
emit_signal("win_condition_met", {
|
||||
"type": Utils.WinConditionType.BOARD_CLEARED,
|
||||
"message": "Board cleared of enemy pieces!"
|
||||
})
|
||||
|
||||
# Check for specific unit capture (default: King)
|
||||
if win_condition == Utils.WinConditionType.CAPTURE_UNIT:
|
||||
var target_unit = win_condition_data.get("unit", "King")
|
||||
if piece.name == target_unit:
|
||||
emit_signal("win_condition_met", {
|
||||
"type": Utils.WinConditionType.CAPTURE_UNIT,
|
||||
"message": "Enemy " + target_unit + " captured!"
|
||||
})
|
||||
|
||||
# Check all conditions after capture
|
||||
check_conditions()
|
||||
|
||||
func on_piece_lost(piece):
|
||||
# First verify this is a player piece (same color as current player)
|
||||
var is_player_piece = piece.Item_Color == (0 if chess_game.Turn == 0 else 1)
|
||||
print("on_piece_lost isPlayer ", is_player_piece)
|
||||
|
||||
if is_player_piece:
|
||||
# Check for unit loss (default: King)
|
||||
if loss_condition == Utils.LossConditionType.UNIT_LOST:
|
||||
var target_unit = loss_condition_data.get("unit", "King")
|
||||
if piece.name == target_unit:
|
||||
emit_signal("loss_condition_met", {
|
||||
"type": Utils.LossConditionType.UNIT_LOST,
|
||||
"message": "Your " + target_unit + " was captured!"
|
||||
})
|
||||
|
||||
# Check all conditions after loss
|
||||
check_conditions()
|
||||
|
||||
func on_piece_moved(piece, from_location, to_location):
|
||||
# Check for tile reached condition
|
||||
if win_condition == Utils.WinConditionType.TILE_REACHED:
|
||||
# Verify this is a player's piece (white if Turn==0, black if Turn==1)
|
||||
var is_player_piece = piece.Item_Color == (0 if chess_game.Turn == 0 else 1)
|
||||
|
||||
if is_player_piece and target_tiles.has(to_location):
|
||||
# If specific unit is required
|
||||
if "unit" in win_condition_data and win_condition_data["unit"] != "":
|
||||
if piece.name == win_condition_data["unit"]:
|
||||
if not condition_progress.has("tiles_reached"):
|
||||
condition_progress["tiles_reached"] = []
|
||||
|
||||
# Avoid duplicates
|
||||
if not condition_progress["tiles_reached"].has(to_location):
|
||||
condition_progress["tiles_reached"].append(to_location)
|
||||
emit_signal("condition_progress_updated", condition_progress)
|
||||
|
||||
if condition_progress["tiles_reached"].size() >= target_tiles.size():
|
||||
emit_signal("win_condition_met", {
|
||||
"type": Utils.WinConditionType.TILE_REACHED,
|
||||
"message": "Target tile reached by " + piece.name + "!"
|
||||
})
|
||||
else:
|
||||
# Any player unit can reach the tile
|
||||
if not condition_progress.has("tiles_reached"):
|
||||
condition_progress["tiles_reached"] = []
|
||||
|
||||
# Avoid duplicates
|
||||
if not condition_progress["tiles_reached"].has(to_location):
|
||||
condition_progress["tiles_reached"].append(to_location)
|
||||
emit_signal("condition_progress_updated", condition_progress)
|
||||
|
||||
if condition_progress["tiles_reached"].size() >= target_tiles.size():
|
||||
emit_signal("win_condition_met", {
|
||||
"type": Utils.WinConditionType.TILE_REACHED,
|
||||
"message": "Target tile reached!"
|
||||
})
|
||||
|
||||
# Check all conditions after move
|
||||
check_conditions()
|
||||
|
||||
func check_conditions():
|
||||
# This allows for custom condition checking beyond the standard events
|
||||
|
||||
# Check board cleared condition
|
||||
if win_condition == Utils.WinConditionType.BOARD_CLEARED:
|
||||
var remaining = count_enemy_pieces()
|
||||
if remaining <= 0:
|
||||
emit_signal("win_condition_met", {
|
||||
"type": Utils.WinConditionType.BOARD_CLEARED,
|
||||
"message": "Board cleared of enemy pieces!"
|
||||
})
|
||||
|
||||
# Update the UI with current progress
|
||||
emit_signal("condition_progress_updated", condition_progress)
|
||||
|
||||
func count_enemy_pieces() -> int:
|
||||
var count = 0
|
||||
|
||||
# Determine enemy color based on current turn
|
||||
# In your system:
|
||||
# - White pieces have Item_Color == 0
|
||||
# - Black pieces have Item_Color == 1
|
||||
# - Turn == 0 means white's turn, Turn == 1 means black's turn
|
||||
var enemy_color = 1 if chess_game.Turn == 0 else 0
|
||||
|
||||
# Iterate through the board to count enemy pieces
|
||||
for y in range(chess_game.boardYSize):
|
||||
for x in range(chess_game.boardXSize):
|
||||
var piece = chess_game.board[y][x]
|
||||
if piece != null and piece.Item_Color == enemy_color:
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
# Helper methods for game integration
|
||||
|
||||
func load_condition_from_metadata(metadata: Dictionary):
|
||||
if metadata.has("win_condition"):
|
||||
match metadata["win_condition"]:
|
||||
Utils.WinConditionType.CAPTURE_UNIT:
|
||||
set_win_condition(Utils.WinConditionType.CAPTURE_UNIT, {"unit": "King"})
|
||||
Utils.WinConditionType.TILE_REACHED:
|
||||
# Get target tiles from metadata if available
|
||||
var target_tiles = metadata.get("target_tiles", [])
|
||||
set_win_condition(Utils.WinConditionType.TILE_REACHED, {"target_tiles": target_tiles, "unit": metadata.get("target_unit", "")})
|
||||
Utils.WinConditionType.BOARD_CLEARED:
|
||||
set_win_condition(Utils.WinConditionType.BOARD_CLEARED)
|
||||
Utils.WinConditionType.TURN_NUMBER:
|
||||
set_win_condition(Utils.WinConditionType.TURN_NUMBER, {"target_turn": metadata.get("target_turn", 20)})
|
||||
|
||||
if metadata.has("loss_condition"):
|
||||
match metadata["loss_condition"]:
|
||||
Utils.LossConditionType.UNIT_LOST:
|
||||
set_loss_condition(Utils.LossConditionType.UNIT_LOST, {"unit": "King"})
|
||||
Utils.LossConditionType.TURN_NUMBER:
|
||||
set_loss_condition(Utils.LossConditionType.TURN_NUMBER, {"turn_limit": metadata.get("turn_limit", 50)})
|
||||
|
||||
# Debug methods
|
||||
|
||||
func print_debug_info():
|
||||
print("=== WIN CONDITION SYSTEM DEBUG INFO ===")
|
||||
print("Current win condition: ", _win_condition_type_to_string(win_condition))
|
||||
print("Current loss condition: ", _loss_condition_type_to_string(loss_condition))
|
||||
print("Win condition data: ", win_condition_data)
|
||||
print("Loss condition data: ", loss_condition_data)
|
||||
print("Turn count: ", turn_count)
|
||||
print("Target tiles: ", target_tiles)
|
||||
print("Captured pieces: ", captured_pieces.size())
|
||||
print("Condition progress: ", condition_progress)
|
||||
print("Enemy pieces remaining: ", count_enemy_pieces())
|
||||
print("=====================================")
|
||||
|
||||
func _win_condition_type_to_string(type: Utils.WinConditionType) -> String:
|
||||
match type:
|
||||
Utils.WinConditionType.CAPTURE_UNIT:
|
||||
return "CAPTURE_UNIT"
|
||||
Utils.WinConditionType.BOARD_CLEARED:
|
||||
return "BOARD_CLEARED"
|
||||
Utils.WinConditionType.TILE_REACHED:
|
||||
return "TILE_REACHED"
|
||||
Utils.WinConditionType.TURN_NUMBER:
|
||||
return "TURN_NUMBER"
|
||||
_:
|
||||
return "UNKNOWN"
|
||||
|
||||
func _loss_condition_type_to_string(type: Utils.LossConditionType) -> String:
|
||||
match type:
|
||||
Utils.LossConditionType.UNIT_LOST:
|
||||
return "UNIT_LOST"
|
||||
Utils.LossConditionType.TURN_NUMBER:
|
||||
return "TURN_NUMBER"
|
||||
_:
|
||||
return "UNKNOWN"
|
||||
1
Systems/Game/WinConditionManager.gd.uid
Normal file
1
Systems/Game/WinConditionManager.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://mgoqcb66wpc3
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
extends "res://Systems/StateMachine/ChessGameState.gd"
|
||||
|
||||
const ATTACHMENT_PHASE_DURATION = 15 # Duration in seconds
|
||||
const ATTACHMENT_PHASE_DURATION = 8 # Duration in seconds
|
||||
var timer: Timer
|
||||
var tile_pressed_connection: Signal
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ extends "res://Systems/StateMachine/ChessGameState.gd"
|
|||
|
||||
func enter(_previous: String, data := {}) -> void:
|
||||
print("ENTERING STATE ", Constants.CLEANUP)
|
||||
game.cleanupPhase()
|
||||
game.endTurn()
|
||||
|
||||
if "endCondition" in data:
|
||||
finished.emit(Constants.ROUND_END)
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ func handleRegularMove(node: PieceContainer, consume: bool, generated: bool = f
|
|||
func moveAndConsume(node: PieceContainer, consume: bool) -> void:
|
||||
var sourceContainer = game.get_node("Flow/" + game.selectedNode) as PieceContainer
|
||||
var piece = sourceContainer.get_piece()
|
||||
print("Removing Piece 1")
|
||||
# print("Removing Piece 1")
|
||||
node.animate_movement(sourceContainer, piece);
|
||||
game.currentlyMovingPiece = piece
|
||||
if consume:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ extends "res://Systems/StateMachine/ChessGameState.gd"
|
|||
|
||||
func enter(_previous: String, _data := {}) -> void:
|
||||
print("ENTERING STATE ", Constants.POST_MOVE)
|
||||
# game.resolveMoveEffects()
|
||||
|
||||
if (game.isPlayerTurn()):
|
||||
game.updateEffectDurations()
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ func start() -> void:
|
|||
|
||||
await owner.ready
|
||||
state.enter("")
|
||||
func enter() -> void:
|
||||
state.enter("")
|
||||
|
||||
func unhandledInput(event: InputEvent) -> void:
|
||||
# print("StateMachine received input:", event)
|
||||
|
|
|
|||
|
|
@ -67,13 +67,18 @@ enum RoomType {
|
|||
EVENT
|
||||
}
|
||||
|
||||
|
||||
enum WinCondition{
|
||||
King,
|
||||
Clear,
|
||||
Tile,
|
||||
enum WinConditionType {
|
||||
CAPTURE_UNIT, # Default: King capture
|
||||
BOARD_CLEARED, # Clear the board of all opponent pieces
|
||||
TILE_REACHED, # Reach a specific tile with a specific unit
|
||||
TURN_NUMBER # Reach a specific turn number
|
||||
}
|
||||
|
||||
# Loss condition types
|
||||
enum LossConditionType {
|
||||
UNIT_LOST, # Default: King loss
|
||||
TURN_NUMBER # Turn limit reached
|
||||
}
|
||||
|
||||
|
||||
static var CardTypes = [
|
||||
|
|
|
|||
Loading…
Reference in a new issue