Add room entry auto-triggers, player input, and more

* When you teleport to a room, the teleport auto-triggers fire.
* Rooms have auto-triggers. None by default. They are run every time you
  teleport to a room, and when the game starts. Gate behavior behind a
  variable.
* PlayerInputAction waits for player input (and potentially write it
  into a variable)

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2021-11-18 20:32:02 -08:00
parent b67034d2fa
commit 2f86df2930
7 changed files with 119 additions and 16 deletions

View File

@@ -2,6 +2,7 @@ import argparse
import importlib.util
from pathlib import Path
import sys
from agame.color import colorize
# Parse args
@@ -21,11 +22,18 @@ game_module = importlib.import_module(package)
game = game_module.game # type: ignore
# Run
game.print_room()
game.say("=" * 70)
game.say("Type ((help)) for help, or ((quit)) to exit.")
game.say("=" * 70)
game.say()
game.do_teleport_actions()
while True:
try:
game.say()
line = input("> ")
line = input(colorize("{{>}} "))
if line.lower() == "quit":
break
game.say()
game.run_command(line)
except (KeyboardInterrupt, EOFError):

View File

@@ -11,8 +11,9 @@ __all__ = (
"Action",
"SleepAction",
"PrintAction",
"TeleportAction",
"PrintRoomAction",
"PlayerInputAction",
"TeleportAction",
"GetAction",
"CheckInvItemsAction",
"CheckRoomItemsAction",
@@ -73,6 +74,35 @@ class PrintAction(Action):
game.say(line)
@dataclasses.dataclass
class PrintRoomAction(Action):
"""
Prints the current room.
"""
def act(self, game: "Game"):
game.say("", "." * 70, "")
game.print_room()
@dataclasses.dataclass
class PlayerInputAction(Action):
"""
Waits for a user to press a key, or press enter, or whatever.
"""
prompt: str = "Press enter to continue..."
store_var_id: Optional[str] = None
def act(self, game: "Game"):
line = input(self.prompt)
if self.store_var_id:
assert (
self.store_var_id in game.vars
), f"could not find var with id {self.store_var_id}"
game.vars[self.store_var_id] = line
@dataclasses.dataclass
class TeleportAction(Action):
"""
@@ -90,22 +120,12 @@ class TeleportAction(Action):
assert (
self.room_id in game.database.rooms
), f"could not find room with id {self.room_id}"
game.room = game.database.rooms[self.room_id]
game.teleport(game.database.rooms[self.room_id])
if self.announce:
game.say("", "." * 70, "")
game.print_room()
class PrintRoomAction(Action):
"""
Prints the current room.
"""
def act(self, game: "Game"):
game.say("", "." * 70, "")
game.print_room()
@dataclasses.dataclass
class GetAction(Action):
"""

View File

@@ -1,6 +1,6 @@
import dataclasses
import textwrap
from typing import Any, MutableMapping, List, Match, Optional, Sequence
from typing import Any, MutableMapping, List, Match, Optional, Sequence, Union
from agame.action import Action
from agame.color import colorize
from agame.item import Item, ItemInst
@@ -98,6 +98,17 @@ class Game:
for action in actions:
action.act(self)
def do_teleport_actions(self):
"Executes the teleport actions for the current room."
self.do_actions(self.room.teleport_actions)
def teleport(self, room: Union[str, Room]):
if isinstance(room, str):
assert room in self.database.rooms, f"could not find room with id {room}"
room = self.database.rooms[room]
self.room = room
self.do_teleport_actions()
def print_room(self):
"Prints this room's description."
self.say(f"(({self.room.name}))")

View File

@@ -3,6 +3,9 @@ from typing import MutableMapping, Optional, Sequence, Union, TYPE_CHECKING
from agame.item import ItemInst
from agame.util import search_item_name
if TYPE_CHECKING:
from agame.action import Action
__all__ = ("Room",)
@@ -13,6 +16,8 @@ class Room:
name: str
desc: Union[str, Sequence[str]]
items: MutableMapping[str, ItemInst]
# Actions that are executed upon teleport or entrance to this room.
teleport_actions: Sequence["Action"]
def __init__(
self,
@@ -20,6 +25,7 @@ class Room:
name: str,
desc: Union[str, Sequence[str]],
items: Union[Sequence[ItemInst], MutableMapping[str, ItemInst]],
teleport_actions: Sequence["Action"] = [],
):
self.id = id
self.name = name
@@ -28,6 +34,7 @@ class Room:
self.items = items
else:
self.items = {item.id: item for item in items}
self.teleport_actions = teleport_actions
def search_item_name(self, item_name: str) -> Optional[ItemInst]:
"""

View File

@@ -84,6 +84,7 @@ class HelpTrigger(Trigger):
game.say()
for trigger in game.database.triggers:
game.say(trigger.help())
game.say("To quit the game, type ((quit)).")
class GetTrigger(Trigger):