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:
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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}))")
|
||||
|
||||
@@ -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]:
|
||||
"""
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -13,5 +13,5 @@ from . import vars
|
||||
# Build the game state
|
||||
game = Game(
|
||||
database=database,
|
||||
room=database.rooms["cabin_inside"],
|
||||
room=database.rooms["prelude"],
|
||||
)
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user