Files
Archipelago/worlds/apquest/game/player.py
NewSoupVi 23d319247f APQuest: Fix import of Protocol from bokeh instead of typing (#5674)
* APQuest: Fix import of Protocol from bokeh instead of typing

* bump world version
2025-11-25 23:45:55 +01:00

88 lines
2.4 KiB
Python

from collections import Counter
from collections.abc import Callable
from .events import Event, LocationClearedEvent, VictoryEvent
from .gameboard import Gameboard
from .graphics import Graphic
from .inputs import Direction
from .items import Item
class Player:
current_x: int
current_y: int
current_health: int
has_won: bool = False
facing: Direction
inventory: Counter[Item]
gameboard: Gameboard
push_event: Callable[[Event], None]
def __init__(self, gameboard: Gameboard, push_event: Callable[[Event], None]) -> None:
self.gameboard = gameboard
self.inventory = Counter()
self.push_event = push_event
self.respawn()
def respawn(self) -> None:
self.current_x = 4
self.current_y = 9
self.current_health = self.max_health
self.facing = Direction.DOWN
@property
def max_health(self) -> int:
return 2 + 2 * self.inventory[Item.HEALTH_UPGRADE]
def render(self) -> Graphic:
if not self.gameboard.ready:
return Graphic.EMPTY
if self.facing == Direction.LEFT:
return Graphic.PLAYER_LEFT
if self.facing == Direction.UP:
return Graphic.PLAYER_UP
if self.facing == Direction.RIGHT:
return Graphic.PLAYER_RIGHT
return Graphic.PLAYER_DOWN
def receive_item(self, item: Item) -> None:
assert item != Item.REMOTE_ITEM, "Player should not directly receive the remote item"
self.inventory[item] += 1
if item == Item.HEALTH_UPGRADE:
self.current_health += 2
def has_item(self, item: Item) -> bool:
return self.inventory[item] > 0
def remove_item(self, item: Item) -> None:
self.inventory[item] -= 1
def damage(self, damage: int) -> None:
if self.has_item(Item.SHIELD):
damage = damage // 2
self.current_health = max(0, self.current_health - damage)
if self.current_health <= 0:
self.die()
def die(self) -> None:
self.respawn()
self.gameboard.respawn_final_boss()
self.gameboard.heal_alive_enemies()
def location_cleared(self, location_id: int) -> None:
event = LocationClearedEvent(location_id)
self.push_event(event)
def victory(self) -> None:
self.has_won = True
event = VictoryEvent()
self.push_event(event)