from src.weapon import Weapon class Player: def __init__(self, xPos, yPos): # Movement attributes self.xPos = xPos self.yPos = yPos self.moveSpeed = 0.05 self.jumpDuration = 1000 # Jump duration in milliseconds self.jumpStartTime = 0 self.isJumping = False self.facingRight = True # Stats and tracking self._health = 10 self._maxHealth = 10 self._lives = 1 self.distanceSinceLastStep = 0 self.stepDistance = 0.5 # Inventory system self.inventory = [] self.collectedItems = [] self._coins = 0 # Combat related attributes self.weapons = [] self.currentWeapon = None self.isAttacking = False self.lastAttackTime = 0 # Power-up states self.isInvincible = False self.invincibilityStartTime = 0 self.invincibilityDuration = 5000 # 5 seconds of invincibility # Projectiles self.projectiles = [] # List of type and quantity tuples # Initialize starting weapon (rusty shovel) self.add_weapon(Weapon( name="rusty_shovel", damage=2, range=2, attackSound="player_shovel_attack", hitSound="player_shovel_hit", attackDuration=200 # 200ms attack duration )) def update(self, currentTime): """Update player state""" # Check if invincibility has expired if self.isInvincible and currentTime - self.invincibilityStartTime >= self.invincibilityDuration: self.isInvincible = False speak("Invincibility wore off!") def start_invincibility(self): """Activate invincibility from Hand of Glory""" self.isInvincible = True self.invincibilityStartTime = pygame.time.get_ticks() def add_projectile(self, projectile_type): """Add a projectile to inventory""" # Find if we already have this type for proj in self.projectiles: if proj[0] == projectile_type: proj[1] += 1 # Increase quantity speak(f"Now have {proj[1]} {projectile_type}s") return # If not found, add new type with quantity 1 self.projectiles.append([projectile_type, 1]) def throw_projectile(self): """Throw the first available projectile""" if not self.projectiles: speak("No projectiles to throw!") return None # Get the first projectile type projectile = self.projectiles[0] projectile[1] -= 1 # Decrease quantity if projectile[1] <= 0: self.projectiles.pop(0) # Remove if none left return { 'type': projectile[0], 'start_x': self.xPos, 'direction': 1 if self.facingRight else -1 } def get_health(self): """Get current health""" return self._health def get_max_health(self): """Get current max health""" return self._maxHealth def set_health(self, value): """Set health and handle death if needed""" if self.isInvincible: return # No damage while invincible self._health = max(0, value) # Health can't go below 0 if self._health == 0: self._lives -= 1 if self._lives > 0: self._health = 10 # Reset health if we still have lives def set_max_health(self, value): """Set max health""" self._maxHealth = value def get_coins(self): """Get remaining coins""" return self._coins def get_lives(self): """Get remaining lives""" return self._lives def add_weapon(self, weapon): """Add a new weapon to inventory and equip if first weapon""" self.weapons.append(weapon) if len(self.weapons) == 1: # If this is our first weapon, equip it self.equip_weapon(weapon) def equip_weapon(self, weapon): """Equip a specific weapon""" if weapon in self.weapons: self.currentWeapon = weapon def add_item(self, item): """Add an item to inventory""" self.inventory.append(item) self.collectedItems.append(item) def start_attack(self, currentTime): """Attempt to start an attack with the current weapon""" if self.currentWeapon and self.currentWeapon.start_attack(currentTime): self.isAttacking = True self.lastAttackTime = currentTime return True return False def get_attack_range(self, currentTime): """Get the current attack's range based on position and facing direction""" if not self.currentWeapon or not self.currentWeapon.is_attack_active(currentTime): return None return self.currentWeapon.get_attack_range(self.xPos, self.facingRight)