init game files

This commit is contained in:
2026-01-24 16:29:11 -05:00
commit ea2028cf13
171 changed files with 191733 additions and 0 deletions

230
scripts/Main.gd Normal file
View File

@@ -0,0 +1,230 @@
extends Node3D
## Main - Root scene that coordinates the game
# Components
var table_setup: TableSetup
var game_ui: GameUI
var hand_display: HandDisplay
var hand_layer: CanvasLayer
# Player damage displays
var damage_displays: Array[DamageDisplay] = []
func _ready() -> void:
_setup_table()
_setup_ui()
_connect_signals()
# Start game when ready
if GameManager.is_initialized:
_start_game()
else:
GameManager.game_ready.connect(_start_game)
func _setup_table() -> void:
table_setup = TableSetup.new()
add_child(table_setup)
# Connect table signals
table_setup.card_clicked.connect(_on_table_card_clicked)
func _setup_ui() -> void:
# Main game UI overlay (has its own CanvasLayer)
game_ui = GameUI.new()
game_ui.layer = 10 # Base UI layer
add_child(game_ui)
# Hand display needs its own CanvasLayer to render on top of 3D
hand_layer = CanvasLayer.new()
hand_layer.layer = 11 # Above the game UI
add_child(hand_layer)
# Container for hand at bottom of screen - must fill the viewport
var hand_container = Control.new()
hand_layer.add_child(hand_container)
hand_container.set_anchors_preset(Control.PRESET_FULL_RECT)
hand_container.mouse_filter = Control.MOUSE_FILTER_IGNORE
# Hand display positioned at bottom - use explicit positioning
hand_display = HandDisplay.new()
hand_container.add_child(hand_display)
# Position at bottom of screen with explicit coordinates
# We'll update position in _process or use a deferred call after container is sized
call_deferred("_position_hand_display")
hand_display.card_selected.connect(_on_hand_card_selected)
hand_display.card_hovered.connect(_on_hand_card_hovered)
hand_display.card_unhovered.connect(_on_hand_card_unhovered)
# Create damage displays (positioned by 3D camera overlay later)
for i in range(2):
var damage_display = DamageDisplay.new()
damage_displays.append(damage_display)
func _position_hand_display() -> void:
# Get viewport size and position hand at bottom
var viewport = get_viewport()
if viewport:
var vp_size = viewport.get_visible_rect().size
hand_display.position = Vector2(50, vp_size.y - 180)
hand_display.size = Vector2(vp_size.x - 100, 170)
func _connect_signals() -> void:
# GameManager signals
GameManager.game_started.connect(_on_game_started)
GameManager.game_ended.connect(_on_game_ended)
GameManager.turn_changed.connect(_on_turn_changed)
GameManager.phase_changed.connect(_on_phase_changed)
GameManager.damage_dealt.connect(_on_damage_dealt)
func _start_game() -> void:
GameManager.start_new_game()
# Force an update of visuals after a frame to ensure everything is ready
call_deferred("_force_initial_update")
func _force_initial_update() -> void:
_sync_visuals()
_update_hand_display()
_update_cp_display()
func _on_game_started() -> void:
_sync_visuals()
_update_hand_display()
func _on_game_ended(winner_name: String) -> void:
game_ui.show_message(winner_name + " wins the game!")
func _on_turn_changed(_player_name: String, _turn_number: int) -> void:
_sync_visuals()
_update_hand_display()
_update_cp_display()
func _on_phase_changed(_phase_name: String) -> void:
_update_playable_highlights()
_update_cp_display()
func _on_damage_dealt(player_name: String, _amount: int) -> void:
# Find player index
if GameManager.game_state:
for i in range(2):
var player = GameManager.game_state.get_player(i)
if player and player.player_name == player_name:
if i < damage_displays.size():
damage_displays[i].set_damage(player.damage_zone.get_count())
func _sync_visuals() -> void:
if GameManager.game_state and table_setup:
table_setup.sync_with_game_state(GameManager.game_state)
func _update_hand_display() -> void:
if not GameManager.game_state:
return
# Show current player's hand
var current_player = GameManager.get_current_player()
if current_player:
var cards = current_player.hand.get_cards()
hand_display.update_hand(cards)
func _update_cp_display() -> void:
if not GameManager.game_state:
return
var current_player = GameManager.get_current_player()
if current_player:
game_ui.update_cp_display(current_player.cp_pool)
func _update_playable_highlights() -> void:
if not GameManager.game_state:
return
var phase = GameManager.get_current_phase()
var player = GameManager.get_current_player()
if not player:
hand_display.clear_highlights()
return
match phase:
Enums.TurnPhase.MAIN_1, Enums.TurnPhase.MAIN_2:
# Highlight cards that can be played
hand_display.highlight_playable(func(card: CardInstance) -> bool:
return player.cp_pool.can_afford_card(card.card_data)
)
_:
hand_display.clear_highlights()
func _on_hand_card_selected(card: CardInstance) -> void:
print("Main: Card selected: ", card.card_data.name, " input_mode=", GameManager.input_mode)
var input_mode = GameManager.input_mode
match input_mode:
GameManager.InputMode.SELECT_CARD_TO_PLAY:
print("Main: Trying to play card")
GameManager.try_play_card(card)
_sync_visuals()
_update_hand_display()
_update_cp_display()
GameManager.InputMode.SELECT_CP_SOURCE:
# Discard for CP
print("Main: Discarding for CP")
GameManager.discard_card_for_cp(card)
_update_hand_display()
_update_cp_display()
_:
print("Main: Input mode not handled: ", input_mode)
func _on_hand_card_hovered(card: CardInstance) -> void:
game_ui.show_card_detail(card)
func _on_hand_card_unhovered() -> void:
game_ui.hide_card_detail()
func _on_table_card_clicked(card: CardInstance, zone_type: Enums.ZoneType, player_index: int) -> void:
var input_mode = GameManager.input_mode
match input_mode:
GameManager.InputMode.SELECT_CP_SOURCE:
# Check if it's a backup we can dull
if zone_type == Enums.ZoneType.FIELD_BACKUPS:
if player_index == GameManager.game_state.turn_manager.current_player_index:
GameManager.dull_backup_for_cp(card)
_sync_visuals()
_update_cp_display()
GameManager.InputMode.SELECT_ATTACKER:
# Select attacker
if zone_type == Enums.ZoneType.FIELD_FORWARDS:
if player_index == GameManager.game_state.turn_manager.current_player_index:
GameManager.declare_attack(card)
_sync_visuals()
GameManager.InputMode.SELECT_BLOCKER:
# Select blocker
if zone_type == Enums.ZoneType.FIELD_FORWARDS:
var opponent_index = 1 - GameManager.game_state.turn_manager.current_player_index
if player_index == opponent_index:
GameManager.declare_block(card)
_sync_visuals()
# Show card detail on any click
game_ui.show_card_detail(card)
func _input(event: InputEvent) -> void:
# Keyboard shortcuts
if event is InputEventKey and event.pressed:
match event.keycode:
KEY_SPACE:
# Pass priority / end phase
GameManager.pass_priority()
_sync_visuals()
_update_hand_display()
_update_cp_display()
KEY_ESCAPE:
# Cancel current selection
GameManager.clear_selection()
table_setup.clear_all_highlights()
hand_display.clear_highlights()