diff --git a/deckbuilder/src/lib.rs b/deckbuilder/src/lib.rs index 7d2ab37..a00780c 100644 --- a/deckbuilder/src/lib.rs +++ b/deckbuilder/src/lib.rs @@ -11,6 +11,7 @@ pub struct Card { pub name: String, pub attack: u32, pub defense: u32, + pub lucky: bool, } pub struct CoreGameState { @@ -52,11 +53,29 @@ impl CoreGameState { pub fn log(&mut self, message: String) { self.logger.add_entry(message.clone()); } - - pub fn draw_card(&mut self) { - self.player.draw_card(); + pub fn draw_card(&mut self) -> Option { + if self.player.deck.is_empty() && !self.player.discard_pile.is_empty() { + self.player.deck.append(&mut self.player.discard_pile); + self.player.deck.shuffle(&mut rand::thread_rng()); + self.log("Discard pile reshuffled into deck.".to_string()); + } + if let Some(mut card) = self.player.draw_card() { + let is_lucky = rand::random::() < 0.1; // 10% chance for a Lucky Draw + if is_lucky { + card.lucky = true; + card.attack += 1; + card.defense += 1; + self.log(format!("Lucky Draw! {} got +1 attack and +1 defense.", card.name)); + } + self.log(format!("Drew a card: {} (Attack: {}, Defense: {})", card.name, card.attack, card.defense)); + Some(card) + } else if self.player.hand.is_empty() && self.player.deck.is_empty() { + self.log("No more cards available to draw.".to_string()); + None + } else { + None + } } - pub fn play_card(&mut self, card_index: i32) -> String { if card_index < 0 || card_index as usize >= self.player.hand.len() { let message = "Invalid card index".to_string(); @@ -71,13 +90,13 @@ impl CoreGameState { let card = self.player.hand.remove(card_index as usize); let result = handle_combat(&mut self.player, &mut self.enemy, &card); self.log(format!("Played card: {}. {}", card.name, result)); + self.player.discard_pile.push(card); result } - pub fn enemy_turn(&mut self) { let damage = self.enemy.attack; self.player.health = self.player.health.saturating_sub(damage); - self.log(format!("Enemy attacks! You take {} damage.", damage)); + self.log(format!("Enemy attacks! You take {} damage. Your current health: {}", damage, self.player.health)); } pub fn get_player_health(&self) -> u32 { @@ -179,7 +198,7 @@ impl GameState { pub fn enemy_turn(&mut self) { let damage = self.core.enemy.attack; self.core.player.health = self.core.player.health.saturating_sub(damage); - godot_print!("Enemy attacks! You take {} damage.", damage); + godot_print!("Enemy attacks! You take {} damage. Your current health: {}", damage, self.core.player.health); } #[func] @@ -242,6 +261,7 @@ impl INode for GameState { pub struct Player { pub deck: Vec, pub hand: Vec, + pub discard_pile: Vec, pub health: u32, } @@ -250,15 +270,30 @@ impl Player { Player { deck: Vec::new(), hand: Vec::new(), + discard_pile: Vec::new(), health: 30, } } - - pub fn draw_card(&mut self) { - if let Some(card) = self.deck.pop() { - self.hand.push(card); + pub fn draw_card(&mut self) -> Option { + if let Some(mut card) = self.deck.pop() { + let is_lucky = rand::random::() < 0.1; // 10% chance for a Lucky Draw + if is_lucky { + card.lucky = true; + card.attack += 1; + card.defense += 1; + } + self.hand.push(card.clone()); + Some(card) + } else { + None } } + + pub fn reshuffle_discard(&mut self) { + self.deck.append(&mut self.discard_pile); + self.deck.shuffle(&mut rand::thread_rng()); + } + } #[derive(Default)] @@ -306,23 +341,25 @@ pub fn handle_combat(player: &mut Player, enemy: &mut Enemy, card: &Card) -> Str combat_log } - pub fn initialize_deck() -> Vec { let initial_cards = vec![ Card { name: "Warrior".to_string(), attack: 3, defense: 2, + lucky: false, }, Card { name: "Archer".to_string(), attack: 2, defense: 1, + lucky: false, }, Card { name: "Knight".to_string(), attack: 4, defense: 4, + lucky: false, }, ]; diff --git a/deckbuilder/src/main.rs b/deckbuilder/src/main.rs index 77c355f..5b52d40 100644 --- a/deckbuilder/src/main.rs +++ b/deckbuilder/src/main.rs @@ -25,6 +25,20 @@ fn main() { // Main game loop loop { + + // Check if hand is empty and draw cards if necessary + if game.player.hand.is_empty() { + println!("Your hand is empty. Drawing new cards..."); + for _ in 0..5 { + if let Some(card) = game.draw_card() { + println!("Drew: {} (Attack: {}, Defense: {})", card.name, card.attack, card.defense); + } else { + println!("No more cards to draw!"); + break; + } + } + } + // Display player's hand println!("Your hand:"); for (i, card) in game.player.hand.iter().enumerate() { diff --git a/deckbuilder/src/tutorial.rs b/deckbuilder/src/tutorial.rs index 0e6e57f..ff49f8e 100644 --- a/deckbuilder/src/tutorial.rs +++ b/deckbuilder/src/tutorial.rs @@ -36,11 +36,10 @@ impl TutorialState { self.step += 1; self.get_current_instruction() } - pub fn get_current_instruction(&self) -> String { match self.step { - 0 => "Welcome to the Deckbuilder Tutorial! Let's start by looking at your hand. Press Enter or type 'next' to continue.".to_string(), - 1 => "You start with 5 cards in your hand. Each card has an Attack and Defense value. Press Enter or type 'next' to continue.".to_string(), + 0 => "Welcome to the Deckbuilder Tutorial! Let's start by looking at your hand. Press Enter to continue.".to_string(), + 1 => "You start with 5 cards in your hand. Each card has an Attack and Defense value. Press Enter to continue.".to_string(), 2 => "Let's play your first card. Type '1' to play the first card in your hand.".to_string(), 3 => { let card = self.card_played.as_ref().unwrap(); @@ -63,7 +62,7 @@ BATTLE ACTION SUMMARY: ENEMY - Health: {}, Attack: {} -------------------------------------------------- Great job! You've successfully attacked the enemy and survived their counterattack. -Press Enter or type 'next' to continue the tutorial."#, +Press Enter to continue the tutorial."#, card.name, card.attack, card.defense, self.enemy_health_before, self.core_game.enemy.health, self.enemy_damage_dealt, self.player_health_before, self.core_game.player.health, self.player_damage_taken, @@ -77,18 +76,17 @@ Press Enter or type 'next' to continue the tutorial."#, self.core_game.enemy.health, self.core_game.enemy.attack ) }, - 4 => "Now it's the enemy's turn. They will attack you. Press Enter or type 'next' to see what happens.".to_string(), + 4 => "Now it's the enemy's turn. They will attack you. Press Enter to see what happens.".to_string(), 5 => format!( - "The enemy attacked you! You took {} damage. Your health decreased from {} to {}. The game continues until either you or the enemy runs out of health. Press Enter or type 'next' to continue.", + "The enemy attacked you! You took {} damage. Your health decreased from {} to {}. The game continues until either you or the enemy runs out of health. Press Enter to continue.", self.enemy_turn_damage, self.player_health_before, self.core_game.player.health ), - 6 => "That's the basics of combat! Keep playing cards and defeating enemies. Press Enter or type 'end' to finish the tutorial.".to_string(), + 6 => "That's the basics of combat! Keep playing cards and defeating enemies. Press Enter to finish the tutorial.".to_string(), _ => "Tutorial complete! You can now start a real game.".to_string(), } } - pub fn handle_input(&mut self, input: &str) -> String { match self.step { 2 => { @@ -98,7 +96,7 @@ Press Enter or type 'next' to continue the tutorial."#, self.card_played = self.core_game.player.hand.get(0).cloned(); let result = self.core_game.play_card(0); println!("{}", result); // Print the result of playing the card - if let Some(card) = &self.card_played { + if let Some(_card) = &self.card_played { self.enemy_damage_dealt = self.enemy_health_before - self.core_game.enemy.health; self.player_damage_taken = @@ -111,44 +109,32 @@ Press Enter or type 'next' to continue the tutorial."#, } } - 4 => { - if input.is_empty() || input == "next" { - self.player_health_before = self.core_game.player.health; - self.core_game.enemy_turn(); - self.enemy_turn_damage = - self.player_health_before - self.core_game.player.health; - self.next_step(); - format!( - "The enemy attacks! You take {} damage.", - self.enemy_turn_damage - ) - } else { - "Press Enter or type 'next' to see what happens.".to_string() - } - } - 5 => { - if input.is_empty() || input == "next" { - self.next_step(); - String::new() - } else { - "Press Enter or type 'next' to continue.".to_string() - } - } - - 6 => { - if input == "end" || input.is_empty() { - self.next_step(); - String::new() // Return empty string when advancing + 4 | 5 | 6 => { + if input.is_empty() { + if self.step == 4 { + self.player_health_before = self.core_game.player.health; + self.core_game.enemy_turn(); + self.enemy_turn_damage = + self.player_health_before - self.core_game.player.health; + self.next_step(); + format!( + "The enemy attacks! You take {} damage.", + self.enemy_turn_damage + ) + } else { + self.next_step(); + String::new() + } } else { - "Type 'end' or press Enter to finish the tutorial.".to_string() + "Press Enter to continue.".to_string() } } _ => { - if input == "next" || input.is_empty() { + if input.is_empty() { self.next_step(); String::new() // Return empty string when advancing } else { - "Press Enter or type 'next' to continue.".to_string() + "Press Enter to continue.".to_string() } } }