mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-26 15:03:25 -07:00
88 lines
2.4 KiB
Python
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)
|