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):

View File

@@ -13,5 +13,5 @@ from . import vars
# Build the game state
game = Game(
database=database,
room=database.rooms["cabin_inside"],
room=database.rooms["prelude"],
)

View File

@@ -4,6 +4,61 @@ from agame.room import Room
from agame.trigger import *
from . import database
################################################################################
# Game intro
################################################################################
database.add_room(
Room(
id="prelude",
name="Prelude",
desc="",
items={},
teleport_actions=[
PrintAction(
"." * 70,
"Many stories have been told about this place. Some are tall "
"tales and mostly contradictory. Some others, however, are true.",
#
"This is one of those stories.",
"." * 70,
),
PlayerInputAction(),
PrintAction(
"." * 70,
#
"There used to be trees here. Fifteen years ago, we were sitting "
"in the shade, telling stories about last summer and what we hope "
"would happen next, our laughter unable to break past the leaves "
"and branches around us.",
#
"It is now desolate. Only the wind shakes the dry branches of the "
"remaining trees. They chitter and clack; any other noise is a "
"long echo. Nothing else stands tall enough to block the sound.",
#
"No animals patrol the sky nor ground. Life has left this place.",
"." * 70,
),
PlayerInputAction(),
PrintAction(
"." * 70,
"It is because of the ((machine)).",
"." * 70,
),
PlayerInputAction(),
SleepAction(1),
PrintAction("."),
SleepAction(1),
PrintAction(".."),
SleepAction(1),
PrintAction("..."),
SleepAction(1),
PrintAction("You awaken from a fitful sleep. Where are you again?"),
PlayerInputAction(),
TeleportAction("cabin_inside"),
],
)
)
################################################################################
# Inside the cabin
################################################################################
@@ -200,6 +255,7 @@ database.add_items(
id="cabin_outside_west_path",
name="Western path",
synonyms=(
"path",
"path to west",
"path to the west",
"path leading west",