283 lines
12 KiB
GDScript
283 lines
12 KiB
GDScript
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()
|
|
print("_on_game_initialized")
|
|
|
|
func reset_conditions():
|
|
print("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
|
|
|
|
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_conditions()
|
|
|
|
func on_piece_captured(piece):
|
|
# print("on_piece_captured ISEnemy ", piece)
|
|
var is_enemy_piece = piece.Item_Color == (1 if chess_game.Turn == 1 else 0)
|
|
print("on_piece_captured ISEnemy ", is_enemy_piece)
|
|
if is_enemy_piece:
|
|
captured_pieces.append(piece)
|
|
|
|
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!"
|
|
})
|
|
|
|
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_conditions()
|
|
|
|
func on_piece_lost(piece):
|
|
var is_player_piece = piece.Item_Color == (0 if chess_game.Turn == 1 else 1)
|
|
print("on_piece_lost isPlayer ", is_player_piece)
|
|
|
|
if is_player_piece:
|
|
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_conditions()
|
|
|
|
func on_piece_moved(piece, from_location, to_location):
|
|
if win_condition == Utils.WinConditionType.TILE_REACHED:
|
|
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 "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_conditions()
|
|
|
|
func check_conditions():
|
|
|
|
# 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!"
|
|
})
|
|
|
|
emit_signal("condition_progress_updated", condition_progress)
|
|
|
|
func count_enemy_pieces() -> int:
|
|
var count = 0
|
|
|
|
var enemy_color = 1 if chess_game.Turn == 0 else 0
|
|
|
|
for y in range(chess_game.boardYSize):
|
|
for x in range(chess_game.boardXSize):
|
|
var piece = (chess_game.get_node(str(x) + "-" + str(y)) as PieceContainer).get_piece()
|
|
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):
|
|
reset_conditions();
|
|
# print("load_condition_from_metadata ", metadata)
|
|
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
|
|
|
|
target_tiles = metadata.get("win_target", [])
|
|
# print("load_condition_from_metadata ", " target_tiles ", target_tiles)
|
|
set_win_condition(Utils.WinConditionType.TILE_REACHED, {"target_tiles": target_tiles, "unit": metadata.get("win_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("win_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("loss_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"
|