Add ability to pick up items and add to inventory
This commit is contained in:
parent
35862fcc19
commit
2b708b3b7f
27
actions.py
27
actions.py
@ -32,6 +32,33 @@ class Action:
|
||||
"""
|
||||
|
||||
|
||||
class PickupAction(Action):
|
||||
"""Pickup an item and add it to the inventory, if there is room for it."""
|
||||
|
||||
def __init__(self, entity: Actor):
|
||||
super().__init__(entity)
|
||||
|
||||
def perform(self) -> None:
|
||||
actor_location_x = self.entity.x
|
||||
actor_location_y = self.entity.y
|
||||
inventory = self.entity.inventory
|
||||
|
||||
for item in self.engine.game_map.items:
|
||||
if actor_location_x == item.x and actor_location_y == item.y:
|
||||
if len(inventory.items) >= inventory.capacity:
|
||||
raise exceptions.Impossible("Your inventory is full.")
|
||||
|
||||
self.engine.game_map.entities.remove(item)
|
||||
item.parent = self.entity.inventory
|
||||
inventory.items.append(item)
|
||||
|
||||
self.engine.message_log.add_message(f"You picked up the {item.name}!")
|
||||
|
||||
return
|
||||
|
||||
raise exceptions.Impossible("There is nothing here to pick up.")
|
||||
|
||||
|
||||
class ItemAction(Action):
|
||||
def __init__(
|
||||
self,
|
||||
|
28
components/inventory.py
Normal file
28
components/inventory.py
Normal file
@ -0,0 +1,28 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, TYPE_CHECKING
|
||||
|
||||
from components.base_component import BaseComponent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from entity import Actor, Item
|
||||
|
||||
|
||||
class Inventory(BaseComponent):
|
||||
parent: Actor
|
||||
|
||||
def __init__(self, capacity: int):
|
||||
self.capacity = capacity
|
||||
self.items: List[Item] = []
|
||||
|
||||
def drop(self, item: Item) -> None:
|
||||
"""
|
||||
Removes an item from the inventory and restores it to the game map,
|
||||
at the player's current location.
|
||||
:param item:
|
||||
:return:
|
||||
"""
|
||||
self.items.remove(item)
|
||||
item.place(self.parent.x, self.parent.y, self.gamemap)
|
||||
|
||||
self.engine.message_log.add_message(f"You dropped the {item.name}.")
|
@ -9,6 +9,7 @@ if TYPE_CHECKING:
|
||||
from components.ai import BaseAI
|
||||
from components.consumable import Consumable
|
||||
from components.fighter import Fighter
|
||||
from components.inventory import Inventory
|
||||
from game_map import GameMap
|
||||
|
||||
T = TypeVar("T", bound="Entity")
|
||||
@ -85,7 +86,8 @@ class Actor(Entity):
|
||||
color: Tuple[int, int, int] = (255, 255, 255),
|
||||
name: str = "<Unamed>",
|
||||
ai_cls: Type[BaseAI],
|
||||
fighter: Fighter
|
||||
fighter: Fighter,
|
||||
inventory: Inventory,
|
||||
):
|
||||
super().__init__(
|
||||
x=x,
|
||||
@ -102,6 +104,9 @@ class Actor(Entity):
|
||||
self.fighter = fighter
|
||||
self.fighter.parent = self
|
||||
|
||||
self.inventory = inventory
|
||||
self.inventory.parent = self
|
||||
|
||||
@property
|
||||
def is_alive(self) -> bool:
|
||||
"""Returns True as long as this actor can perform actions."""
|
||||
|
@ -1,6 +1,7 @@
|
||||
from components.ai import HostileEnemy
|
||||
from components.consumable import HealingConsumable
|
||||
from components.fighter import Fighter
|
||||
from components.inventory import Inventory
|
||||
from entity import Actor, Item
|
||||
|
||||
player = Actor(
|
||||
@ -9,6 +10,7 @@ player = Actor(
|
||||
name="PLayer",
|
||||
ai_cls=HostileEnemy,
|
||||
fighter=Fighter(hp=30, defense=2, power=5),
|
||||
inventory=Inventory(capacity=26),
|
||||
)
|
||||
|
||||
orc = Actor(
|
||||
@ -17,13 +19,15 @@ orc = Actor(
|
||||
name="Orc",
|
||||
ai_cls=HostileEnemy,
|
||||
fighter=Fighter(hp=10, defense=0, power=3),
|
||||
inventory=Inventory(capacity=0)
|
||||
)
|
||||
troll = Actor(
|
||||
char="T",
|
||||
color=(0, 127, 0),
|
||||
name="Troll",
|
||||
ai_cls=HostileEnemy,
|
||||
fighter=Fighter(hp=16, defense=1, power=4)
|
||||
fighter=Fighter(hp=16, defense=1, power=4),
|
||||
inventory=Inventory(capacity=0)
|
||||
)
|
||||
|
||||
health_potion = Item(
|
||||
|
@ -5,7 +5,7 @@ from typing import Iterable, Iterator, Optional, TYPE_CHECKING
|
||||
import numpy as np # type: ignore
|
||||
from tcod.console import Console
|
||||
|
||||
from entity import Actor
|
||||
from entity import Actor, Item
|
||||
import tile_types
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -50,6 +50,10 @@ class GameMap:
|
||||
if isinstance(entity, Actor) and entity.is_alive
|
||||
)
|
||||
|
||||
@property
|
||||
def items(self) -> Iterator[Item]:
|
||||
yield from (entity for entity in self.entities if isinstance(entity, Item))
|
||||
|
||||
def get_blocking_entity_at_location(
|
||||
self,
|
||||
location_x: int,
|
||||
|
@ -8,6 +8,7 @@ from actions import (
|
||||
Action,
|
||||
BumpAction,
|
||||
EscapeAction,
|
||||
PickupAction,
|
||||
WaitAction
|
||||
)
|
||||
import color
|
||||
@ -109,9 +110,13 @@ class MainGameEventHandler(EventHandler):
|
||||
|
||||
elif key == tcod.event.K_ESCAPE:
|
||||
action = EscapeAction(player)
|
||||
|
||||
elif key == tcod.event.K_v:
|
||||
self.engine.event_handler = HistoryViewer(self.engine)
|
||||
|
||||
elif key == tcod.event.K_g:
|
||||
action = PickupAction(player)
|
||||
|
||||
# No valid key was pressed
|
||||
return action
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user