diff --git a/Systems/DeckManager.gd b/Systems/DeckManager.gd index 8b86d07..8ee7b59 100644 --- a/Systems/DeckManager.gd +++ b/Systems/DeckManager.gd @@ -8,11 +8,20 @@ var discard: Array = [] var attached_cards: Dictionary = {} # piece_id: card var attached_effects: Dictionary = {} # piece_id: [card] var hand_size: int = 5 - -# Card costs for shop +var preloaded_hand_cards: Array = [] # array of string ids func _init(): print("************************DECK INIT*****************") + + + +func preload_cards(card_array = []): + var cnt = 0 + preloaded_hand_cards.clear() + for card in card_array: + preloaded_hand_cards.append(card.id) + + func set_hand_size(size: int): hand_size = size @@ -50,6 +59,13 @@ func shuffleDeck(): deck.shuffle() func drawStartingHand(): + for id in preloaded_hand_cards: + var matchCard = func matchCardId(card): + return "id" in card and card.id == id + var cardIndex = deck.find_custom(matchCard.bind()) + if cardIndex != -1: + hand.append(deck.pop_at(cardIndex)) + for i in range(min(hand_size, deck.size())): drawCard() diff --git a/Systems/Game/ChessGame.gd b/Systems/Game/ChessGame.gd index b70793d..8b23356 100644 --- a/Systems/Game/ChessGame.gd +++ b/Systems/Game/ChessGame.gd @@ -108,7 +108,7 @@ func _ready() -> void: call_deferred("initialize_game_system") turnIndicator.visible = false deckManager = DeckManager.new() - player = Player.new(85, 2, 0, self) + player = Player.new(85, 2, 15, self) # 2rnbqkbnr1R/2ppp1pppp2/5p6/75/66/66/66/66/66/66/2PPPPPPPP2/2RNBQKBN3 b KQkq - 0 3 # clear prev wind conditions? func _on_new_game_requested(options = {}): diff --git a/Systems/Game/HandPreloadScreen.gd b/Systems/Game/HandPreloadScreen.gd new file mode 100644 index 0000000..34c4297 --- /dev/null +++ b/Systems/Game/HandPreloadScreen.gd @@ -0,0 +1,249 @@ +extends Control +class_name HandPreloadScreen + +signal back_pressed +signal preload_visibility_changed(isvisible) + +# Node references +@onready var deckGrid = $MainContainer/GridScrollContainer/GridContainer +@onready var bankContainer = $MainContainer/BankContainer/ScrollContainer/VBoxContainer +@onready var backButton = $BackButton +@onready var card_preview = $CardPreviewPanel +@onready var token_label = $TokenLabel +@onready var cost_label = $CostLabel + +var handSize = 2 +var deckManager = null +var player = null +var bankCards = [] # Cards available +var tokens = 0 + +var usedSlots = [] +var currentHand = [] +var current_preview_card = null + +func _ready(): + # Connect back button + if backButton: + backButton.connect("pressed", Callable(self, "_on_backButton_pressed")) + + if card_preview: + card_preview.visible = false + if cost_label: + cost_label.visible = false + + +func initialize(options = null): + # Find the DeckManager instance + var board = get_node_or_null("/root/Board") as ChessGame + if board and "deckManager" in board: + deckManager = board.deckManager + print("Found deck manager:", deckManager) + else: + print("DeckManager not found on Board node") + if board and "player" in board: + player = board.player + handSize = player.hand_size + tokens = player.tokens + updateTokenLabel() + else: + print("Player not found on Board node") + + # Load cards from deck and bank + loadCards() + + # Set up the grid with empty card containers + setupDeckGrid() + + # Populate the bank with available cards + populateBank() + + +func updateTokenLabel(): + if token_label: + token_label.text = str(tokens) + " TOKENS" + +func loadCards(): + if deckManager: + currentHand.clear() + usedSlots.clear() + # Clone the deck to work with + bankCards = deckManager.deck.duplicate() + for id in deckManager.preloaded_hand_cards: + var matchCard = func matchCardId(card): + return "id" in card and card.id == id + var cardIndex = bankCards.find_custom(matchCard.bind()) + if cardIndex != -1: + currentHand.append(bankCards[cardIndex].id) + usedSlots.append(true) + + else: + # Fallback with empty collections if deck manager not found + currentHand = [] + bankCards = [] + print("Warning: DeckManager not found") + + +func setupDeckGrid(): + # Clear existing children + for child in deckGrid.get_children(): + child.queue_free() + + # Calculate grid dimensions + var cols = 4 #check screen to deteremine + var rows = handSize / cols + deckGrid.columns = cols + + # Create card slots + for i in range(handSize): + var card_slot = preload("res://card_slot.tscn").instantiate() + deckGrid.add_child(card_slot) + + # Connect signals + card_slot.connect("card_selected", Callable(self, "_on_hand_card_selected")) + _connect_hover_signals(card_slot) + + # Set card if available + if i < currentHand.size(): + var matchCard = func matchCardId(card): + return "id" in card and card.id == currentHand[i] + var cardIndex = bankCards.find_custom(matchCard.bind()) + if cardIndex != -1: + card_slot.set_card(bankCards[cardIndex]) + else: + card_slot.clear() + +func _connect_hover_signals(node): + # Add hover signals for preview functionality + if node.is_class("Control"): + node.mouse_entered.connect(Callable(self, "_on_card_mouse_entered").bind(node)) + # node.mouse_exited.connect(Callable(self, "_on_card_mouse_exited").bind(node)) + + +func populateBank(): + for child in bankContainer.get_children(): + child.queue_free() + + # Add each bank card to the list + for card in bankCards: + var card_item = preload("res://card_bank_item.tscn").instantiate() + bankContainer.add_child(card_item) + card_item.set_card(card) + card_item.connect("card_selected", Callable(self, "_on_bank_card_selected")) + _connect_hover_signals(card_item) + +func _on_hand_card_selected(card_slot, card): + if card: + # Remove card from deck + var index = currentHand.find(card.id) + if index >= 0: + currentHand.remove_at(index) + if index < usedSlots.size() and usedSlots[index] != true: + tokens += Utils.TokenCosts[card.rank] + usedSlots.remove_at(index) + updateTokenLabel() + + + # Update UI + card_slot.clear() + populateBank() + if current_preview_card == card: + hide_card_preview() + +func _on_bank_card_selected(card_item, card): + print("_on_bank_card_selected ", card.id) + # Find first empty slot in deck + var empty_slot_index = -1 + for i in range(deckGrid.get_child_count()): + var slot = deckGrid.get_child(i) + if !slot.has_card(): + empty_slot_index = i + break + + # print("_on_bank_card_selected ", currentHand, " ", handSize, " ", empty_slot_index, ) + # print("_on_bank_card_selected ", empty_slot_index >= 0, " ", currentHand.size() < handSize, " ", currentHand.find(card.id)) + if empty_slot_index >= 0 and currentHand.size() < handSize and currentHand.find(card.id) == -1 and tokens - Utils.TokenCosts[card.rank] > 0: + # print("currentHand append ", card.id) + + tokens -= Utils.TokenCosts[card.rank] + updateTokenLabel() + currentHand.append(card.id) + usedSlots.append(false) + + deckGrid.get_child(empty_slot_index).set_card(card) + populateBank() + +func _on_card_mouse_entered(node): + var card = null + + # Get the card from the node + if node.has_method("has_card") and node.has_card(): + # This is a CardSlot + card = node.current_card + elif node.has_method("set_card") and node.current_card: + # This is a CardBankItem + card = node.current_card + + if card: + show_card_preview(card) + +# func _on_card_mouse_exited(node): +# # Add a short delay before hiding the preview +# # This prevents flickering when moving between cards +# await get_tree().create_timer(0.1).timeout + +# # Only hide if we're not hovering over another card that shows the same preview +# if current_preview_card: +# hide_card_preview() + +func show_card_preview(card): + if card_preview and card: + current_preview_card = card + card_preview.preview_card(card) + if cost_label: + cost_label.visible = true + cost_label.text = "Cost: " + str(Utils.TokenCosts[card.rank]) + " tokens" + +func hide_card_preview(): + if cost_label: + cost_label.visible = false + if card_preview: + current_preview_card = null + card_preview.hide_preview() + +func savePreloadCards(): + if deckManager: + # Save the current deck to the deck manager + deckManager.preloaded_hand_cards = currentHand.duplicate() + + print("Preloads saved with ", currentHand.size(), " cards") + player.tokens = tokens + +func _on_backButton_pressed(): + # Save changes before returning + savePreloadCards() + + # Emit signal to go back + emit_signal("back_pressed") + + # Hide this screen + visible = false + + + + +# Notification +func _notification(what): + if what == NOTIFICATION_VISIBILITY_CHANGED: + _on_visibility_changed(visible) + +func _on_visibility_changed(is_visible): + + print("Preload Screen visibility changed to: ", is_visible) + if is_visible: + loadCards() + setupDeckGrid() + else: + print("Preload Screen is now invisible") + + emit_signal("preload_visibility_changed", is_visible) diff --git a/Systems/Game/HandPreloadScreen.gd.uid b/Systems/Game/HandPreloadScreen.gd.uid new file mode 100644 index 0000000..3e8ac5f --- /dev/null +++ b/Systems/Game/HandPreloadScreen.gd.uid @@ -0,0 +1 @@ +uid://b7b2xlfvhgipb diff --git a/Systems/Game/Lobby/LobbyScreen.gd b/Systems/Game/Lobby/LobbyScreen.gd index f43ff73..809915f 100644 --- a/Systems/Game/Lobby/LobbyScreen.gd +++ b/Systems/Game/Lobby/LobbyScreen.gd @@ -3,14 +3,17 @@ class_name LobbyScreen signal vanilla_selected signal shop_selected(options) +signal preload_selected(options) signal deeper_selected signal back_pressed +signal lobby_screen_visibility_changed(isvisible) # Node references @onready var vanilla_button = $BottomContainer/VanillaButton @onready var shop_button = $CenterContainer/ShopButton @onready var deeper_button = $BottomContainer/DeeperButton @onready var back_button = $BackButton +@onready var preload_button = $PreloadButton @onready var run_count_label = $TopBar/RunCountLabel @onready var token_label = $TopBar/TokenContainer/TokenLabel @@ -30,6 +33,9 @@ func _ready(): if back_button: back_button.connect("pressed", Callable(self, "_on_back_button_pressed")) + + if preload_button: + preload_button.connect("pressed", Callable(self, "_on_preload_button_pressed")) func initialize(options = null): game = get_node_or_null("/root/Board") as ChessGame @@ -46,6 +52,10 @@ func update_display(): if token_label: token_label.text = str(player.tokens) + " TOKENS" +func _on_preload_button_pressed(): + emit_signal("preload_selected") + self.visible = false + func _on_vanilla_button_pressed(): emit_signal("vanilla_selected") self.visible = false diff --git a/Systems/Game/Lobby/LobbyShopScreen.gd b/Systems/Game/Lobby/LobbyShopScreen.gd index f129604..dd41a2c 100644 --- a/Systems/Game/Lobby/LobbyShopScreen.gd +++ b/Systems/Game/Lobby/LobbyShopScreen.gd @@ -3,6 +3,7 @@ class_name LobbyShopScreen signal back_pressed signal card_unlocked(card, token_cost) +signal lobby_shop_visibility_changed(isvisible) signal hand_size_increased # Node references @@ -29,12 +30,7 @@ var mouse_over_any_card = false var game: ChessGame var player: Player -var card_costs = { - Card.Rank.RANK_0: 15, # Most expensive (one-time use) - Card.Rank.RANK_1: 10, # Expensive (once per match) - Card.Rank.RANK_2: 5, # Medium (multiple uses) - Card.Rank.RANK_3: 3 # Cheapest (basic cards) -} +var card_costs = Utils.TokenCosts var fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144] @@ -88,29 +84,32 @@ func initialize(options = null): func generate_shop_cards(deck_manager): var shop_cards = [] + var all_available_cards = [] - var all_cards = [] - var card_classes = [ - HopscotchCard, - FieryCapeCard, - FieryTrailCard, - ExplosiveBootsCard, - DoubleTimeCard, - DrunkDrivingCard, - SupernovaCard - ] + for rank in player.cards_by_rank: + for card in player.cards_by_rank[rank]: + var is_unlocked = false + for unlocked_card in player.unlocked_cards: + if unlocked_card.cardName == card.cardName: + is_unlocked = true + break + + if not is_unlocked: + var card_instance = card.duplicate() + all_available_cards.append(card_instance) - for card_class in card_classes: - var card = card_class.new() - all_cards.append(card) + if all_available_cards.is_empty(): + print("No new cards available for the shop") + return [] + + all_available_cards.shuffle() - all_cards.shuffle() - - var num_shop_cards = min(randi_range(5, 7), all_cards.size()) + var num_shop_cards = min(randi_range(5, 7), all_available_cards.size()) for i in range(num_shop_cards): - shop_cards.append(all_cards[i % card_classes.size()]) + shop_cards.append(all_available_cards[i]) + print("Generated shop with " + str(shop_cards.size()) + " cards") return shop_cards func populate_carousel(): diff --git a/Systems/Game/Menu/MenuContainer.gd b/Systems/Game/Menu/MenuContainer.gd index 6b010a2..a5bd608 100644 --- a/Systems/Game/Menu/MenuContainer.gd +++ b/Systems/Game/Menu/MenuContainer.gd @@ -34,6 +34,7 @@ signal deeper_mode_selected @onready var game = get_node_or_null("/root/Board") as ChessGame @onready var lobbyScreen = get_node_or_null("/root/Board/LobbyScreen") @onready var lobbyShopScreen = get_node_or_null("/root/Board/LobbyShopScreen") +@onready var preloadhandScreen = get_node_or_null("/root/Board/HandPreloadScreen") @@ -67,6 +68,9 @@ func _ready(): deckManagerScreen.connect("back_pressed", Callable(self, "_on_deck_manager_back_pressed")) deckManagerScreen.visible = false + if preloadhandScreen: + preloadhandScreen.connect("back_pressed", Callable(self, "_on_preload_back_pressed")) + preloadhandScreen.visible = false if progressionScreen: progressionScreen.connect("save_pressed", Callable(self, "_on_progression_save_pressed")) progressionScreen.visible = false @@ -86,6 +90,7 @@ func _ready(): rewardScreen.visible = false if lobbyScreen: lobbyScreen.connect("vanilla_selected", Callable(self, "_on_vanilla_selected")) + lobbyScreen.connect("preload_selected", Callable(self, "_on_preload_selected")) lobbyScreen.connect("shop_selected", Callable(self, "_on_lobby_shop_open_requested")) lobbyScreen.connect("deeper_selected", Callable(self, "_on_deeper_selected")) lobbyScreen.connect("back_pressed", Callable(self, "_on_lobby_back_pressed")) @@ -137,6 +142,19 @@ func _connect_button(button, method_name): if !button.is_connected("pressed", Callable(self, method_name)): button.connect("pressed", Callable(self, method_name)) + + + + + + +func _on_preload_back_pressed(): + if preloadhandScreen: + preloadhandScreen.visible = false + if lobbyScreen: + lobbyScreen.visible = true + + # Handle New Game button press func _on_new_game_pressed(): print("New Game pressed, showing game menu") @@ -164,6 +182,11 @@ func _on_lobby_back_pressed(): lobbyScreen.visible = false self.visible = true +func _on_preload_selected(): + print("Preload mode selected") + preloadhandScreen.initialize(null) + preloadhandScreen.visible = true + func _on_vanilla_selected(): print("Vanilla mode selected") if gameMenuScreen: diff --git a/board.tscn b/board.tscn index 8a76c31..cdd3460 100644 --- a/board.tscn +++ b/board.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=35 format=3 uid="uid://d0qyk6v20uief"] +[gd_scene load_steps=36 format=3 uid="uid://d0qyk6v20uief"] [ext_resource type="Script" uid="uid://cbcu68o863pfp" path="res://Systems/Game/ChessGame.gd" id="1_fkb2r"] [ext_resource type="Script" uid="uid://d2bfw6edgkhfa" path="res://Systems/StateMachine/GameStates/WhiteTurn.gd" id="3_276ip"] @@ -34,6 +34,7 @@ [ext_resource type="PackedScene" uid="uid://c6cgcs22ox0no" path="res://progression_screen.tscn" id="32_eq1pg"] [ext_resource type="PackedScene" uid="uid://depsrpx00pnl5" path="res://lobby_shop_screen.tscn" id="33_ccaoj"] [ext_resource type="PackedScene" uid="uid://c1u88sbx0am7b" path="res://lobby_screen.tscn" id="34_yqcr4"] +[ext_resource type="PackedScene" uid="uid://4oqq2vwhqpqn" path="res://hand_preload_screen.tscn" id="35_hqp5w"] [node name="Board" type="Control"] layout_mode = 3 @@ -425,3 +426,7 @@ layout_mode = 1 [node name="LobbyScreen" parent="." instance=ExtResource("34_yqcr4")] visible = false layout_mode = 1 + +[node name="HandPreloadScreen" parent="." instance=ExtResource("35_hqp5w")] +visible = false +layout_mode = 1 diff --git a/hand_preload_screen.tscn b/hand_preload_screen.tscn new file mode 100644 index 0000000..626d522 --- /dev/null +++ b/hand_preload_screen.tscn @@ -0,0 +1,142 @@ +[gd_scene load_steps=4 format=3 uid="uid://4oqq2vwhqpqn"] + +[ext_resource type="Script" uid="uid://b7b2xlfvhgipb" path="res://Systems/Game/HandPreloadScreen.gd" id="1_gokg4"] +[ext_resource type="PackedScene" uid="uid://xxxxxxxx" path="res://card_preview_panel.tscn" id="3_abcde"] +[ext_resource type="Script" uid="uid://bfjmon81nckns" path="res://Systems/Game/GameMenuButton.gd" id="4_gokg4"] + +[node name="HandPreloadScreen" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_gokg4") + +[node name="Background" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.08, 0.08, 0.12, 1) + +[node name="TitleLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_top = 20.0 +offset_bottom = 72.0 +grow_horizontal = 2 +theme_override_font_sizes/font_size = 36 +text = "Preload Your Hand" +horizontal_alignment = 1 + +[node name="TokenLabel" type="Label" parent="."] +offset_left = 1008.0 +offset_top = 29.0 +offset_right = 1121.0 +offset_bottom = 63.0 +theme_override_font_sizes/font_size = 24 +text = "0 TOKENS" + +[node name="CostLabel" type="Label" parent="."] +offset_left = 537.0 +offset_top = 536.0 +offset_right = 673.0 +offset_bottom = 564.0 +size_flags_horizontal = 3 +theme_override_font_sizes/font_size = 20 +text = "Cost: 3 tokens" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="CardPreviewPanel" parent="." instance=ExtResource("3_abcde")] +layout_mode = 2 +anchors_preset = 0 +anchor_right = 0.0 +anchor_bottom = 0.0 +offset_left = 20.0 +offset_top = 100.0 +offset_right = 320.0 +offset_bottom = 588.0 +grow_horizontal = 1 +grow_vertical = 1 + +[node name="MainContainer" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 325.0 +offset_top = 100.0 +offset_right = -20.0 +offset_bottom = -60.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="GridScrollContainer" type="ScrollContainer" parent="MainContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +size_flags_stretch_ratio = 3.0 +horizontal_scroll_mode = 0 + +[node name="GridContainer" type="GridContainer" parent="MainContainer/GridScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_constants/h_separation = 10 +theme_override_constants/v_separation = 10 +columns = 5 + +[node name="BankContainer" type="VBoxContainer" parent="MainContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="MainContainer/BankContainer"] +layout_mode = 2 +text = "AVAILABLE CARDS" +horizontal_alignment = 1 + +[node name="HSeparator" type="HSeparator" parent="MainContainer/BankContainer"] +layout_mode = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="MainContainer/BankContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="MainContainer/BankContainer/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_constants/separation = 5 + +[node name="BackButton" type="RichTextLabel" parent="."] +layout_mode = 1 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_left = 20.0 +offset_top = -50.0 +offset_right = 155.0 +offset_bottom = -20.0 +grow_vertical = 0 +text = "BACK" +script = ExtResource("4_gokg4") + +[node name="SaveLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -223.0 +offset_top = -40.0 +offset_right = -20.0 +offset_bottom = -15.0 +grow_horizontal = 0 +grow_vertical = 0 +text = "Changes will be saved automatically" +horizontal_alignment = 2 diff --git a/lobby_screen.tscn b/lobby_screen.tscn index cc63a2e..a7d4c6b 100644 --- a/lobby_screen.tscn +++ b/lobby_screen.tscn @@ -146,6 +146,19 @@ theme_override_font_sizes/font_size = 24 theme_override_styles/normal = SubResource("StyleBoxFlat_bmpt2") text = "DEEPER" +[node name="PreloadButton" type="RichTextLabel" parent="."] +custom_minimum_size = Vector2(100, 40) +offset_left = 1046.0 +offset_top = 496.0 +offset_right = 1146.0 +offset_bottom = 536.0 +size_flags_horizontal = 0 +size_flags_vertical = 4 +text = "Preload" +horizontal_alignment = 1 +vertical_alignment = 2 +script = ExtResource("2_uhnf6") + [node name="BackButton" type="RichTextLabel" parent="."] custom_minimum_size = Vector2(100, 40) layout_mode = 2