More work on survival mode.

This commit is contained in:
Storm Dragon
2025-09-07 11:13:01 -04:00
parent ce353d0ed9
commit 2bc27c0e28
19 changed files with 154 additions and 41 deletions

View File

@@ -119,6 +119,10 @@ class WickedQuest:
def auto_save(self):
"""Automatically save the game if player has enough bone dust"""
# Don't save in survival mode
if hasattr(self, 'currentLevel') and self.currentLevel and self.currentLevel.levelId == 999:
return False
if not self.player.can_save():
return False
@@ -191,7 +195,11 @@ class WickedQuest:
# Status queries
if keys[pygame.K_c]:
speak(f"{player.get_coins()} bone dust for extra lives, {player.get_save_bone_dust()} bone dust for saves")
# Different status message for survival vs story mode
if hasattr(self, 'currentLevel') and self.currentLevel and self.currentLevel.levelId == 999:
speak(f"{player.get_coins()} bone dust collected")
else:
speak(f"{player.get_coins()} bone dust for extra lives, {player.get_save_bone_dust()} bone dust for saves")
if keys[pygame.K_h]:
speak(f"{player.get_health()} health of {player.get_max_health()}")
if keys[pygame.K_i]:
@@ -277,6 +285,29 @@ class WickedQuest:
cut_scene(self.sounds, "game_over")
display_text(report)
def display_survival_stats(self, timeTaken):
"""Display survival mode completion statistics."""
# Convert time from milliseconds to minutes:seconds
minutes = timeTaken // 60000
seconds = (timeTaken % 60000) // 1000
report = [f"Survival Mode Complete!"]
report.append(f"Final Wave Reached: {self.survivalWave}")
report.append(f"Final Score: {self.survivalScore}")
report.append(f"Time Survived: {minutes} minutes and {seconds} seconds")
report.append("") # Blank line
# Add all total stats
for key in self.currentLevel.player.stats.total:
if key not in ['Total time', 'levelsCompleted']: # Skip these
report.append(f"Total {key}: {self.currentLevel.player.stats.get_total_stat(key)}")
if self.currentLevel.player.scoreboard.check_high_score():
pygame.event.clear()
self.currentLevel.player.scoreboard.add_high_score()
display_text(report)
def game_loop(self, startingLevelNum=1):
"""Main game loop handling updates and state changes."""
clock = pygame.time.Clock()
@@ -426,7 +457,7 @@ class WickedQuest:
if self.currentGame:
# Ask player to choose game mode
mode_choice = game_mode_menu(self.sounds)
if mode_choice == "campaign":
if mode_choice == "story":
self.player = None # Reset player for new game
self.gameStartTime = pygame.time.get_ticks()
if self.load_level(1):
@@ -454,11 +485,13 @@ class WickedQuest:
self.player = Player(0, 0, self.sounds)
self.gameStartTime = pygame.time.get_ticks()
# Show intro message before level starts
messagebox(f"Survival Mode - Wave {self.survivalWave}! Survive as long as you can!")
# Generate first survival segment
levelData = self.survivalGenerator.generate_survival_level(self.survivalWave, 300)
self.currentLevel = Level(levelData, self.sounds, self.player)
messagebox(f"Survival Mode - Wave {self.survivalWave}! Survive as long as you can!")
self.survival_loop()
def survival_loop(self):
@@ -473,7 +506,12 @@ class WickedQuest:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
messagebox(f"Survival ended! Final score: {self.survivalScore}")
# Stop all sounds before exiting
pygame.mixer.stop()
pygame.mixer.music.stop()
# Calculate survival time
survivalTime = pygame.time.get_ticks() - self.gameStartTime
self.display_survival_stats(survivalTime)
return
elif event.key in [pygame.K_CAPSLOCK, pygame.K_TAB]:
self.runLock = not self.runLock
@@ -497,14 +535,23 @@ class WickedQuest:
# Check if player reached end of segment - generate new one
if self.player.xPos >= self.currentLevel.rightBoundary - 20:
self.advance_survival_wave()
# Check lock system - only advance if no active enemies remain
if self.currentLevel.isLocked and any(enemy.isActive for enemy in self.currentLevel.enemies):
speak("You must defeat all enemies before proceeding to the next wave!")
play_sound(self.sounds['locked'])
# Push player back a bit
self.player.xPos -= 5
else:
self.advance_survival_wave()
# Check for death first (following main game loop pattern)
if self.currentLevel.player.get_health() <= 0:
if self.currentLevel.player.get_lives() <= 0:
# Game over - stop all sounds
pygame.mixer.stop()
messagebox(f"Game Over! Final wave: {self.survivalWave}, Final score: {self.survivalScore}")
# Calculate survival time
survivalTime = pygame.time.get_ticks() - self.gameStartTime
self.display_survival_stats(survivalTime)
return
else:
# Player died but has lives left - respawn
@@ -527,6 +574,9 @@ class WickedQuest:
self.currentLevel.projectiles.clear()
pygame.mixer.stop() # Stop any ongoing catapult/enemy sounds
# Announce new wave before starting level
speak(f"Wave {self.survivalWave}!")
# Generate new segment
segmentLength = min(500, 300 + (self.survivalWave * 20)) # Longer segments over time
levelData = self.survivalGenerator.generate_survival_level(self.survivalWave, segmentLength)
@@ -537,8 +587,6 @@ class WickedQuest:
# Create new level
self.currentLevel = Level(levelData, self.sounds, self.player)
speak(f"Wave {self.survivalWave}! Difficulty increased!")
def game_mode_menu(sounds):
@@ -550,10 +598,10 @@ def game_mode_menu(sounds):
Returns:
str: Selected game mode or None if cancelled
"""
choice = instruction_menu(sounds, "Select game mode:", "Campaign", "Survival Mode")
choice = instruction_menu(sounds, "Select game mode:", "Story", "Survival Mode")
if choice == "Campaign":
return "campaign"
if choice == "Story":
return "story"
elif choice == "Survival Mode":
return "survival"
else:
@@ -563,3 +611,4 @@ def game_mode_menu(sounds):
if __name__ == "__main__":
game = WickedQuest()
game.run()