Update example game some, update engine some
* Add RevealAction/UnrevealAction for revealing/hiding items in a room * Add a lot of checks for items being revealed when it's attempted to be triggered * Implement TeleportAction (mostly) * For all Check* family of actions, the `yes` and `no` values may be just be a single action instead of an array of actions * Change up how room descriptions and stuff work, mostly so that you can specify multiple lines in an array so you can preserve paragraph breaks when displayed. * Example game has some more content Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
104
agame/action.py
104
agame/action.py
@@ -19,6 +19,8 @@ __all__ = (
|
|||||||
"Var",
|
"Var",
|
||||||
"CheckVarAction",
|
"CheckVarAction",
|
||||||
"SetVarAction",
|
"SetVarAction",
|
||||||
|
"RevealItemAction",
|
||||||
|
"UnrevealItemAction",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -79,8 +81,10 @@ class TeleportAction(Action):
|
|||||||
room_id: str
|
room_id: str
|
||||||
|
|
||||||
def act(self, game: "Game"):
|
def act(self, game: "Game"):
|
||||||
# TODO
|
assert (
|
||||||
raise NotImplementedError("TODO - implement teleport action")
|
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]
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
@@ -126,6 +130,24 @@ class CheckInvItemsAction(Action):
|
|||||||
yes: Sequence[Action]
|
yes: Sequence[Action]
|
||||||
no: Sequence[Action]
|
no: Sequence[Action]
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
item_ids: Union[str, Sequence[str]],
|
||||||
|
yes: Union[Action, Sequence[Action]] = [],
|
||||||
|
no: Union[Action, Sequence[Action]] = [],
|
||||||
|
):
|
||||||
|
self.item_ids = item_ids
|
||||||
|
# Put the "yes" action into an array if necessary
|
||||||
|
if isinstance(yes, Action):
|
||||||
|
self.yes = [yes]
|
||||||
|
else:
|
||||||
|
self.yes = yes
|
||||||
|
# Put the "no" action into an array if necessary
|
||||||
|
if isinstance(no, Action):
|
||||||
|
self.no = [no]
|
||||||
|
else:
|
||||||
|
self.no = no
|
||||||
|
|
||||||
def act(self, game: "Game"):
|
def act(self, game: "Game"):
|
||||||
# If the item_ids are just a string, use that as a list.
|
# If the item_ids are just a string, use that as a list.
|
||||||
items = [self.item_ids] if isinstance(self.item_ids, str) else self.item_ids
|
items = [self.item_ids] if isinstance(self.item_ids, str) else self.item_ids
|
||||||
@@ -143,10 +165,28 @@ class CheckRoomItemsAction(Action):
|
|||||||
appropriate action sequence.
|
appropriate action sequence.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
item_ids: str
|
item_ids: Union[str, Sequence[str]]
|
||||||
yes: Sequence[Action]
|
yes: Sequence[Action]
|
||||||
no: Sequence[Action]
|
no: Sequence[Action]
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
item_ids: Union[str, Sequence[str]],
|
||||||
|
yes: Union[Action, Sequence[Action]] = [],
|
||||||
|
no: Union[Action, Sequence[Action]] = [],
|
||||||
|
):
|
||||||
|
self.item_ids = item_ids
|
||||||
|
# Put the "yes" action into an array if necessary
|
||||||
|
if isinstance(yes, Action):
|
||||||
|
self.yes = [yes]
|
||||||
|
else:
|
||||||
|
self.yes = yes
|
||||||
|
# Put the "no" action into an array if necessary
|
||||||
|
if isinstance(no, Action):
|
||||||
|
self.no = [no]
|
||||||
|
else:
|
||||||
|
self.no = no
|
||||||
|
|
||||||
def act(self, game: "Game"):
|
def act(self, game: "Game"):
|
||||||
items = [self.item_ids] if isinstance(self.item_ids, str) else self.item_ids
|
items = [self.item_ids] if isinstance(self.item_ids, str) else self.item_ids
|
||||||
for item_id in items:
|
for item_id in items:
|
||||||
@@ -225,10 +265,37 @@ class CheckVarAction(Action):
|
|||||||
# The action to execute when this is false.
|
# The action to execute when this is false.
|
||||||
no: Sequence[Action]
|
no: Sequence[Action]
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
var_id: str,
|
||||||
|
compare: Compare = Compare.EQUALS,
|
||||||
|
against: Any = True,
|
||||||
|
yes: Union[Action, Sequence[Action]] = [],
|
||||||
|
no: Union[Action, Sequence[Action]] = [],
|
||||||
|
):
|
||||||
|
self.var_id = var_id
|
||||||
|
self.compare = compare
|
||||||
|
self.against = against
|
||||||
|
# Put the "yes" action into an array if necessary
|
||||||
|
if isinstance(yes, Action):
|
||||||
|
self.yes = [yes]
|
||||||
|
else:
|
||||||
|
self.yes = yes
|
||||||
|
# Put the "no" action into an array if necessary
|
||||||
|
if isinstance(no, Action):
|
||||||
|
self.no = [no]
|
||||||
|
else:
|
||||||
|
self.no = no
|
||||||
|
|
||||||
def act(self, game: "Game"):
|
def act(self, game: "Game"):
|
||||||
|
assert self.var_id in game.vars, f"variable '{self.var_id}' does not exist"
|
||||||
|
|
||||||
val = game.vars.get(self.var_id, None)
|
val = game.vars.get(self.var_id, None)
|
||||||
compare_val = None
|
compare_val = None
|
||||||
if isinstance(self.against, Var):
|
if isinstance(self.against, Var):
|
||||||
|
assert (
|
||||||
|
self.against.id in game.vars
|
||||||
|
), f"variable '{self.against.id}' does not exist"
|
||||||
compare_val = game.vars.get(self.against.id, None)
|
compare_val = game.vars.get(self.against.id, None)
|
||||||
else:
|
else:
|
||||||
compare_val = self.against
|
compare_val = self.against
|
||||||
@@ -288,7 +355,38 @@ class SetVarAction(Action):
|
|||||||
value: Any
|
value: Any
|
||||||
|
|
||||||
def act(self, game: "Game"):
|
def act(self, game: "Game"):
|
||||||
|
assert self.var_id in game.vars, f"variable '{self.var_id}' does not exist"
|
||||||
value = (
|
value = (
|
||||||
game.vars.get(self.value.id) if isinstance(self.value, Var) else self.value
|
game.vars.get(self.value.id) if isinstance(self.value, Var) else self.value
|
||||||
)
|
)
|
||||||
game.vars[self.var_id] = value
|
game.vars[self.var_id] = value
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class RevealItemAction(Action):
|
||||||
|
"""
|
||||||
|
Reveal an item in the current room.
|
||||||
|
"""
|
||||||
|
|
||||||
|
item_id: str
|
||||||
|
|
||||||
|
def act(self, game: "Game"):
|
||||||
|
assert (
|
||||||
|
self.item_id in game.room.items
|
||||||
|
), f"item id {self.item_id} does not exist in the current room {game.room.id}"
|
||||||
|
game.room.items[self.item_id].revealed = True
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class UnrevealItemAction(Action):
|
||||||
|
"""
|
||||||
|
Unreveal an item in the current room.
|
||||||
|
"""
|
||||||
|
|
||||||
|
item_id: str
|
||||||
|
|
||||||
|
def act(self, game: "Game"):
|
||||||
|
assert (
|
||||||
|
self.item_id in game.room.items
|
||||||
|
), f"item id {self.item_id} does not exist in the current room {game.room.id}"
|
||||||
|
game.room.items[self.item_id].revealed = False
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ class Game:
|
|||||||
UseTrigger(),
|
UseTrigger(),
|
||||||
PutTrigger(),
|
PutTrigger(),
|
||||||
LookTrigger(),
|
LookTrigger(),
|
||||||
|
ReadTrigger(),
|
||||||
OpenTrigger(),
|
OpenTrigger(),
|
||||||
CloseTrigger(),
|
CloseTrigger(),
|
||||||
GoTrigger(),
|
GoTrigger(),
|
||||||
@@ -83,24 +84,40 @@ class Game:
|
|||||||
|
|
||||||
def print_room(self):
|
def print_room(self):
|
||||||
"Prints this room's description."
|
"Prints this room's description."
|
||||||
self.say(self.room.name)
|
self.say(f"(({self.room.name}))")
|
||||||
self.say()
|
if isinstance(self.room.desc, str):
|
||||||
self.say(self.room.desc)
|
self.say(self.room.desc)
|
||||||
|
else:
|
||||||
|
assert isinstance(
|
||||||
|
self.room.desc, Sequence
|
||||||
|
), f"room.desc is not a list or a string from room id {room.id}"
|
||||||
|
self.say(*self.room.desc)
|
||||||
# Look at revealed text
|
# Look at revealed text
|
||||||
for item in self.room.items.values():
|
for (index, item) in enumerate(self.room.items.values()):
|
||||||
if not item.revealed or item.room_desc is None:
|
if not item.revealed or item.room_desc is None or item.room_desc == []:
|
||||||
continue
|
continue
|
||||||
if item.room_desc == "":
|
|
||||||
# TODO - pluralization, 'a' vs 'an'
|
|
||||||
self.say(f"You see a (({item.name})).")
|
|
||||||
else:
|
|
||||||
self.say(item.room_desc)
|
|
||||||
|
|
||||||
def say(self, message: Optional[str] = None):
|
if index != 0:
|
||||||
|
# Space this out with blank lines
|
||||||
|
self.say()
|
||||||
|
|
||||||
|
if isinstance(item.room_desc, str):
|
||||||
|
self.say(item.room_desc)
|
||||||
|
else:
|
||||||
|
assert isinstance(item.room_desc, Sequence)
|
||||||
|
self.say(*item.room_desc)
|
||||||
|
|
||||||
|
def say(self, *lines: str):
|
||||||
"Format, colorize, wrap, and print the message."
|
"Format, colorize, wrap, and print the message."
|
||||||
message = message or ""
|
if lines:
|
||||||
message = textwrap.fill(message)
|
head = textwrap.fill(lines[0])
|
||||||
print(colorize(message))
|
print(colorize(head))
|
||||||
|
for line in lines[1:]:
|
||||||
|
message = textwrap.fill(line)
|
||||||
|
print()
|
||||||
|
print(colorize(message))
|
||||||
|
else:
|
||||||
|
print()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rooms(self):
|
def rooms(self):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import dataclasses
|
import dataclasses
|
||||||
from typing import Mapping, Optional, Sequence
|
from typing import Mapping, Optional, Sequence, Union
|
||||||
from agame.action import Action
|
from agame.action import Action
|
||||||
|
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ class ItemInst:
|
|||||||
return self.item.synonyms
|
return self.item.synonyms
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def room_desc(self) -> Optional[str]:
|
def room_desc(self) -> Optional[Union[str, Sequence[str]]]:
|
||||||
return self.item.room_desc
|
return self.item.room_desc
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -87,7 +87,7 @@ class Item:
|
|||||||
#
|
#
|
||||||
# Otherwise, the `room_desc` string will be colorized and printed as
|
# Otherwise, the `room_desc` string will be colorized and printed as
|
||||||
# written.
|
# written.
|
||||||
room_desc: Optional[str] = None
|
room_desc: Optional[Union[str, Sequence[str]]] = None
|
||||||
|
|
||||||
# A list of triggers that a game may use. Since this is just a mapping of
|
# A list of triggers that a game may use. Since this is just a mapping of
|
||||||
# strings to action sequences, only one set of actions is allowed per
|
# strings to action sequences, only one set of actions is allowed per
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ __all__ = ("Room",)
|
|||||||
class Room:
|
class Room:
|
||||||
id: str
|
id: str
|
||||||
name: str
|
name: str
|
||||||
desc: str
|
desc: Union[str, Sequence[str]]
|
||||||
items: MutableMapping[str, ItemInst]
|
items: MutableMapping[str, ItemInst]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
id: str,
|
id: str,
|
||||||
name: str,
|
name: str,
|
||||||
desc: str,
|
desc: Union[str, Sequence[str]],
|
||||||
items: Union[Sequence[ItemInst], MutableMapping[str, ItemInst]],
|
items: Union[Sequence[ItemInst], MutableMapping[str, ItemInst]],
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
|||||||
@@ -12,12 +12,13 @@ if TYPE_CHECKING:
|
|||||||
# use [a[n]/the] x [with/on [a[n]/the] y]
|
# use [a[n]/the] x [with/on [a[n]/the] y]
|
||||||
# put [a[n]/the] x on/in [a[n]/the] y
|
# put [a[n]/the] x on/in [a[n]/the] y
|
||||||
# look [[at] [a[n]/the] x]
|
# look [[at] [a[n]/the] x]
|
||||||
|
# read [a[n]/the] x
|
||||||
# open x
|
# open x
|
||||||
# close x
|
# close x
|
||||||
# go/(go to)/leave/exit x
|
# go/(go to)/leave/exit x
|
||||||
# give [a[n]/the] x to [a[n]/the] y
|
# give [a[n]/the] x to [a[n]/the] y - TODO
|
||||||
# push [a[n]/the] x
|
# push [a[n]/the] x - TODO
|
||||||
# pull [a[n]/the] x
|
# pull [a[n]/the] x - TODO
|
||||||
# (put down)/drop [a[n]/the] x
|
# (put down)/drop [a[n]/the] x
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"Trigger",
|
"Trigger",
|
||||||
@@ -25,6 +26,7 @@ __all__ = (
|
|||||||
"UseTrigger",
|
"UseTrigger",
|
||||||
"PutTrigger",
|
"PutTrigger",
|
||||||
"LookTrigger",
|
"LookTrigger",
|
||||||
|
"ReadTrigger",
|
||||||
"OpenTrigger",
|
"OpenTrigger",
|
||||||
"CloseTrigger",
|
"CloseTrigger",
|
||||||
"GoTrigger",
|
"GoTrigger",
|
||||||
@@ -32,6 +34,7 @@ __all__ = (
|
|||||||
"USE",
|
"USE",
|
||||||
"PUT",
|
"PUT",
|
||||||
"LOOK",
|
"LOOK",
|
||||||
|
"READ",
|
||||||
"OPEN",
|
"OPEN",
|
||||||
"CLOSE",
|
"CLOSE",
|
||||||
"GO",
|
"GO",
|
||||||
@@ -40,6 +43,7 @@ GET = "get"
|
|||||||
USE = "use"
|
USE = "use"
|
||||||
PUT = "put"
|
PUT = "put"
|
||||||
LOOK = "look"
|
LOOK = "look"
|
||||||
|
READ = "read"
|
||||||
OPEN = "open"
|
OPEN = "open"
|
||||||
CLOSE = "close"
|
CLOSE = "close"
|
||||||
GO = "go"
|
GO = "go"
|
||||||
@@ -73,8 +77,8 @@ class GetTrigger(Trigger):
|
|||||||
otrigger = match["trigger"].lower().capitalize()
|
otrigger = match["trigger"].lower().capitalize()
|
||||||
game.say(f"{otrigger} what?")
|
game.say(f"{otrigger} what?")
|
||||||
return
|
return
|
||||||
item = game.room.search_item_name(item_name.lower())
|
item = game.room.search_item_name(item_name)
|
||||||
if item and GET in item.triggers:
|
if item and item.revealed and GET in item.triggers:
|
||||||
actions = item.triggers[GET]
|
actions = item.triggers[GET]
|
||||||
# if there are any actions, do them. else do the default action
|
# if there are any actions, do them. else do the default action
|
||||||
game.do_actions(actions)
|
game.do_actions(actions)
|
||||||
@@ -106,9 +110,9 @@ class UseTrigger(Trigger):
|
|||||||
|
|
||||||
# Get the item from inventory or room
|
# Get the item from inventory or room
|
||||||
item = game.room.search_item_name(item_name) or search_item_name(
|
item = game.room.search_item_name(item_name) or search_item_name(
|
||||||
game.inventory.values(), item_name.lower()
|
game.inventory.values(), item_name
|
||||||
)
|
)
|
||||||
if not item:
|
if not item or not item.revealed:
|
||||||
game.say(f"I'm not sure what you mean by {item_name}.")
|
game.say(f"I'm not sure what you mean by {item_name}.")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -116,9 +120,9 @@ class UseTrigger(Trigger):
|
|||||||
if target_name:
|
if target_name:
|
||||||
# Get the target from inventory or room
|
# Get the target from inventory or room
|
||||||
target = game.room.search_item_name(target_name) or search_item_name(
|
target = game.room.search_item_name(target_name) or search_item_name(
|
||||||
game.inventory.values(), target_name.lower()
|
game.inventory.values(), target_name
|
||||||
)
|
)
|
||||||
if not target:
|
if not target or not target.revealed:
|
||||||
game.say(f"I'm not sure what you mean by {target_name}.")
|
game.say(f"I'm not sure what you mean by {target_name}.")
|
||||||
# Check if the target can be used on something
|
# Check if the target can be used on something
|
||||||
elif target.id in item.use_actions:
|
elif target.id in item.use_actions:
|
||||||
@@ -168,14 +172,42 @@ class LookTrigger(Trigger):
|
|||||||
if not item_name:
|
if not item_name:
|
||||||
game.print_room()
|
game.print_room()
|
||||||
return
|
return
|
||||||
item = game.room.search_item_name(item_name.lower())
|
item = game.room.search_item_name(item_name) or search_item_name(
|
||||||
if item and LOOK in item.triggers:
|
game.inventory.values(), item_name
|
||||||
|
)
|
||||||
|
if item and LOOK in item.triggers and item.revealed:
|
||||||
actions = item.triggers[LOOK]
|
actions = item.triggers[LOOK]
|
||||||
game.do_actions(actions)
|
game.do_actions(actions)
|
||||||
else:
|
else:
|
||||||
game.say("Can't see that.")
|
game.say("Can't see that.")
|
||||||
|
|
||||||
|
|
||||||
|
class ReadTrigger(Trigger):
|
||||||
|
@staticmethod
|
||||||
|
def pattern() -> Pattern:
|
||||||
|
return re.compile(
|
||||||
|
r"""
|
||||||
|
(?P<trigger>read)
|
||||||
|
([ ]+((an?|the)[ ]+)?(?P<item>.+?))?
|
||||||
|
""",
|
||||||
|
re.IGNORECASE | re.VERBOSE,
|
||||||
|
)
|
||||||
|
|
||||||
|
def trigger(self, game: "Game", match: Match):
|
||||||
|
item_name = match["item"]
|
||||||
|
if not item_name:
|
||||||
|
game.print_room()
|
||||||
|
return
|
||||||
|
item = game.room.search_item_name(item_name) or search_item_name(
|
||||||
|
game.inventory.values(), item_name
|
||||||
|
)
|
||||||
|
if item and READ in item.triggers and item.revealed:
|
||||||
|
actions = item.triggers[READ]
|
||||||
|
game.do_actions(actions)
|
||||||
|
else:
|
||||||
|
game.say("Can't read that.")
|
||||||
|
|
||||||
|
|
||||||
class OpenTrigger(Trigger):
|
class OpenTrigger(Trigger):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def pattern() -> Pattern:
|
def pattern() -> Pattern:
|
||||||
@@ -192,8 +224,8 @@ class OpenTrigger(Trigger):
|
|||||||
if not item_name:
|
if not item_name:
|
||||||
game.say("Open what?")
|
game.say("Open what?")
|
||||||
return
|
return
|
||||||
item = game.room.search_item_name(item_name.lower())
|
item = game.room.search_item_name(item_name)
|
||||||
if item and OPEN in item.triggers:
|
if item and OPEN in item.triggers and item.revealed:
|
||||||
actions = item.triggers[OPEN]
|
actions = item.triggers[OPEN]
|
||||||
game.do_actions(actions)
|
game.do_actions(actions)
|
||||||
else:
|
else:
|
||||||
@@ -216,8 +248,8 @@ class CloseTrigger(Trigger):
|
|||||||
if not item_name:
|
if not item_name:
|
||||||
game.say("Close what?")
|
game.say("Close what?")
|
||||||
return
|
return
|
||||||
item = game.room.search_item_name(item_name.lower())
|
item = game.room.search_item_name(item_name)
|
||||||
if item and CLOSE in item.triggers:
|
if item and CLOSE in item.triggers and item.revealed:
|
||||||
actions = item.triggers[CLOSE]
|
actions = item.triggers[CLOSE]
|
||||||
game.do_actions(actions)
|
game.do_actions(actions)
|
||||||
else:
|
else:
|
||||||
@@ -229,7 +261,7 @@ class GoTrigger(Trigger):
|
|||||||
def pattern() -> Pattern:
|
def pattern() -> Pattern:
|
||||||
return re.compile(
|
return re.compile(
|
||||||
r"""
|
r"""
|
||||||
(?P<trigger>go|go[ ]*to|leave|exit)
|
(?P<trigger>go([ ]*to)?|leave|exit)
|
||||||
(((an?|the)[ ]+)?[ ]+(?P<item>.+?))?
|
(((an?|the)[ ]+)?[ ]+(?P<item>.+?))?
|
||||||
""",
|
""",
|
||||||
re.IGNORECASE | re.VERBOSE,
|
re.IGNORECASE | re.VERBOSE,
|
||||||
@@ -241,7 +273,9 @@ class GoTrigger(Trigger):
|
|||||||
otrigger = match["trigger"].lower().capitalize()
|
otrigger = match["trigger"].lower().capitalize()
|
||||||
game.say(f"{otrigger} where?")
|
game.say(f"{otrigger} where?")
|
||||||
return
|
return
|
||||||
item = game.room.search_item_name(item_name.lower())
|
item = game.room.search_item_name(item_name)
|
||||||
if item and GO in item.triggers:
|
if item and GO in item.triggers and item.revealed:
|
||||||
actions = item.triggers[GO]
|
actions = item.triggers[GO]
|
||||||
game.do_actions(actions)
|
game.do_actions(actions)
|
||||||
|
else:
|
||||||
|
game.say("Can't go there.")
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
def search_item_name(seq: Iterable["ItemInst"], item_name: str) -> Optional["ItemInst"]:
|
def search_item_name(seq: Iterable["ItemInst"], item_name: str) -> Optional["ItemInst"]:
|
||||||
for item in seq:
|
for item in seq:
|
||||||
if item.name == item_name or item_name in item.synonyms:
|
if item.name.lower() == item_name.lower() or item_name.lower() in item.synonyms:
|
||||||
return item
|
return item
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ from agame.trigger import *
|
|||||||
# This is the *game* here
|
# This is the *game* here
|
||||||
database = Database()
|
database = Database()
|
||||||
|
|
||||||
from . import items
|
|
||||||
from . import rooms
|
from . import rooms
|
||||||
from . import vars
|
from . import vars
|
||||||
|
|
||||||
# Build the game state
|
# Build the game state
|
||||||
game = Game(
|
game = Game(
|
||||||
database=database,
|
database=database,
|
||||||
room=database.rooms["start"],
|
room=database.rooms["inside_cabin"],
|
||||||
vars=vars.vars,
|
vars=vars.vars,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
from agame.item import Item
|
|
||||||
from agame.trigger import *
|
|
||||||
from agame.action import *
|
|
||||||
from . import database
|
|
||||||
|
|
||||||
database.add_items(
|
|
||||||
Item(
|
|
||||||
id="glowing_rock",
|
|
||||||
name="glowing rock",
|
|
||||||
desc="This rock is glowing.",
|
|
||||||
synonyms=("rock",),
|
|
||||||
room_desc="You see a ((glowing rock)). You have **got** to have it.",
|
|
||||||
triggers={
|
|
||||||
GET: [
|
|
||||||
PrintAction(
|
|
||||||
"You try to pick up the rock, but it slips out of your greasy hands.",
|
|
||||||
"Maybe you should wash your hands, you disgusting little man.",
|
|
||||||
)
|
|
||||||
],
|
|
||||||
LOOK: [PrintAction("Man, that rock looks awesome.")],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Item(
|
|
||||||
id="cell_door",
|
|
||||||
name="door",
|
|
||||||
room_desc="A ((door)) sits on the far wall.",
|
|
||||||
triggers={
|
|
||||||
GET: [PrintAction("The door is pretty attached to its wall.")],
|
|
||||||
OPEN: [
|
|
||||||
CheckVarAction(
|
|
||||||
"cell_door_open",
|
|
||||||
Compare.EQUALS,
|
|
||||||
True,
|
|
||||||
yes=[
|
|
||||||
PrintAction(
|
|
||||||
"It's already open. You push on the door even //more//, just in case."
|
|
||||||
),
|
|
||||||
SleepAction(1.0),
|
|
||||||
PrintAction("..."),
|
|
||||||
SleepAction(1.0),
|
|
||||||
PrintAction("Yup, still open."),
|
|
||||||
],
|
|
||||||
no=[
|
|
||||||
SetVarAction("cell_door_open", True),
|
|
||||||
PrintAction("The door swings open, thanks to you."),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
CLOSE: [
|
|
||||||
CheckVarAction(
|
|
||||||
"cell_door_open",
|
|
||||||
Compare.EQUALS,
|
|
||||||
True,
|
|
||||||
yes=[
|
|
||||||
PrintAction("You close that door. Nice job."),
|
|
||||||
SetVarAction("cell_door_open", False),
|
|
||||||
],
|
|
||||||
no=[PrintAction("The door is already closed.")],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
LOOK: [
|
|
||||||
CheckVarAction(
|
|
||||||
"cell_door_open",
|
|
||||||
Compare.EQUALS,
|
|
||||||
True,
|
|
||||||
yes=[PrintAction("It's a door, wide open, because you opened it.")],
|
|
||||||
no=[PrintAction("A closed door. You can change this.")],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@@ -1,14 +1,262 @@
|
|||||||
|
from agame.action import *
|
||||||
|
from agame.item import Item
|
||||||
from agame.room import Room
|
from agame.room import Room
|
||||||
|
from agame.trigger import *
|
||||||
from . import database
|
from . import database
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Inside the cabin
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
database.add_items(
|
||||||
|
Item(
|
||||||
|
id="cabin_inside_door",
|
||||||
|
name="Cabin door",
|
||||||
|
room_desc="A door rests upon the south wall.",
|
||||||
|
synonyms=("door",),
|
||||||
|
triggers={
|
||||||
|
LOOK: [PrintAction("A strong, sturdy door.")],
|
||||||
|
GET: [PrintAction("The door is firmly attached to the wall.")],
|
||||||
|
# Don't actually worry about the door being open here. It's just a
|
||||||
|
# nice flavoring.
|
||||||
|
GO: [PrintAction("You exit the cabin."), TeleportAction("outside_cabin")],
|
||||||
|
OPEN: [
|
||||||
|
CheckVarAction(
|
||||||
|
"cabin_door_open",
|
||||||
|
yes=PrintAction("The door is already open."),
|
||||||
|
no=[
|
||||||
|
PrintAction("You pull the cabin door open."),
|
||||||
|
SetVarAction("cabin_door_open", True),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
CLOSE: [
|
||||||
|
CheckVarAction(
|
||||||
|
"cabin_door_open",
|
||||||
|
yes=[
|
||||||
|
PrintAction("You shut the door tight."),
|
||||||
|
SetVarAction("cabin_door_open", False),
|
||||||
|
],
|
||||||
|
no=PrintAction("The door is already closed."),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Item(
|
||||||
|
id="cabin_inside_bed",
|
||||||
|
name="Bed",
|
||||||
|
room_desc="A bed, freshly made, sits in the corner.",
|
||||||
|
triggers={
|
||||||
|
LOOK: [
|
||||||
|
PrintAction("It's a comfortable looking bed, but no time for rest now.")
|
||||||
|
],
|
||||||
|
GET: [PrintAction("Uh, no.")],
|
||||||
|
USE: [
|
||||||
|
PrintAction("You've only just woken up, now is not the time for rest.")
|
||||||
|
],
|
||||||
|
GO: [
|
||||||
|
PrintAction("You've only just woken up, now is not the time for rest.")
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Item(
|
||||||
|
# The outside view, and also kind of a hack for the player to be allowed
|
||||||
|
# to say "go outside" and "look outside" without having an "outside"
|
||||||
|
# synonym for the door, so the player can't also do "open outside"
|
||||||
|
id="cabin_inside_outside",
|
||||||
|
name="Outside",
|
||||||
|
room_desc=None,
|
||||||
|
triggers={
|
||||||
|
LOOK: [PrintAction("It's brown and gray.")],
|
||||||
|
GO: [PrintAction("You exit the cabin."), TeleportAction("outside_cabin")],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Item(
|
||||||
|
id="cabin_inside_window",
|
||||||
|
name="Window",
|
||||||
|
room_desc="A dull light pours in from the solitary window on the east wall.",
|
||||||
|
synonyms=("outside window", "out window", "out the window"),
|
||||||
|
triggers={
|
||||||
|
LOOK: [PrintAction("It's brown and gray.")],
|
||||||
|
OPEN: [
|
||||||
|
PrintAction(
|
||||||
|
"This window is simply a pane of glass in a fixed frame, it be neither opened nor closed."
|
||||||
|
)
|
||||||
|
],
|
||||||
|
CLOSE: [
|
||||||
|
PrintAction(
|
||||||
|
"This window is simply a pane of glass in a fixed frame, it be neither opened nor closed."
|
||||||
|
)
|
||||||
|
],
|
||||||
|
GO: [PrintAction("Try using the door instead.")],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
database.add_room(
|
||||||
|
Room(
|
||||||
|
id="inside_cabin",
|
||||||
|
name="Inside the cabin",
|
||||||
|
desc="",
|
||||||
|
items=[
|
||||||
|
database.items["cabin_inside_door"].create_inst(),
|
||||||
|
database.items["cabin_inside_bed"].create_inst(),
|
||||||
|
database.items["cabin_inside_outside"].create_inst(),
|
||||||
|
database.items["cabin_inside_window"].create_inst(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Outside the cabin
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
ANJAS_LETTER = [
|
||||||
|
"Dear Juni!",
|
||||||
|
"If you are reading this message you have finally arrived in the West, near where "
|
||||||
|
"the horrible machine resides. Turn it off, and its life-sapping force in the "
|
||||||
|
"world will cease.",
|
||||||
|
"You are our only hope - we are counting on you!",
|
||||||
|
"Anja",
|
||||||
|
]
|
||||||
|
database.add_items(
|
||||||
|
Item(
|
||||||
|
id="anjas_letter",
|
||||||
|
name="Anja's letter",
|
||||||
|
synonyms=("letter", "anjas letter", "anja's letter"),
|
||||||
|
triggers={
|
||||||
|
GET: [GetAction("anjas_letter")],
|
||||||
|
LOOK: [PrintAction(*ANJAS_LETTER)],
|
||||||
|
READ: [PrintAction(*ANJAS_LETTER)],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Item(
|
||||||
|
id="mailbox",
|
||||||
|
name="Mailbox",
|
||||||
|
synonyms=("mailbox", "postbox", "rusty mailbox", "rusty postbox"),
|
||||||
|
room_desc="A rusty mailbox sits by the door to the cabin.",
|
||||||
|
triggers={
|
||||||
|
GET: [
|
||||||
|
PrintAction(
|
||||||
|
"The mailbox is firmly rooted in the ground. You don't have anywhere to put it, anyway."
|
||||||
|
)
|
||||||
|
],
|
||||||
|
LOOK: [
|
||||||
|
CheckVarAction(
|
||||||
|
var_id="mailbox_open",
|
||||||
|
yes=[
|
||||||
|
CheckRoomItemsAction(
|
||||||
|
item_ids="anjas_letter",
|
||||||
|
yes=PrintAction("A single letter sits in the mailbox."),
|
||||||
|
no=PrintAction("It's empty."),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
no=[
|
||||||
|
PrintAction("A rusty mailbox sits atop its post. It is closed.")
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
OPEN: [
|
||||||
|
CheckVarAction(
|
||||||
|
var_id="mailbox_open",
|
||||||
|
yes=PrintAction("The mailbox is already open."),
|
||||||
|
no=[
|
||||||
|
PrintAction(
|
||||||
|
"You unlatch the lid to the mailbox, and it pops open."
|
||||||
|
),
|
||||||
|
SetVarAction("mailbox_open", True),
|
||||||
|
CheckRoomItemsAction(
|
||||||
|
item_ids="anjas_letter",
|
||||||
|
yes=[
|
||||||
|
PrintAction("A single letter sits inside."),
|
||||||
|
RevealItemAction("anjas_letter"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
CLOSE: [
|
||||||
|
CheckVarAction(
|
||||||
|
var_id="mailbox_open",
|
||||||
|
yes=[
|
||||||
|
PrintAction("The mailbox snaps shut."),
|
||||||
|
SetVarAction("mailbox_open", False),
|
||||||
|
CheckRoomItemsAction(
|
||||||
|
"anjas_letter", yes=[UnrevealItemAction("anjas_letter")]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
no=PrintAction("It's already closed."),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Item(
|
||||||
|
id="west_path",
|
||||||
|
name="Western path",
|
||||||
|
synonyms=(
|
||||||
|
"path to west",
|
||||||
|
"path to the west",
|
||||||
|
"path leading west",
|
||||||
|
"path leading westward",
|
||||||
|
"west",
|
||||||
|
"westward",
|
||||||
|
"westward path",
|
||||||
|
"west path",
|
||||||
|
"western path",
|
||||||
|
),
|
||||||
|
room_desc=(
|
||||||
|
"A path leads westward, where the sky loses its color and becomes a dark gray. "
|
||||||
|
"The land becomes more barren in this direction."
|
||||||
|
),
|
||||||
|
triggers={
|
||||||
|
LOOK: [
|
||||||
|
PrintAction(
|
||||||
|
"A dirt path extends towards a barren wasteland. At one "
|
||||||
|
"point it had become overgrown with disuse, but most anything "
|
||||||
|
"that was once alive is either long gone or a husk of its "
|
||||||
|
"former self."
|
||||||
|
)
|
||||||
|
],
|
||||||
|
GO: [PrintAction("You head west."), TeleportAction("western_fork")],
|
||||||
|
USE: [PrintAction("You head west."), TeleportAction("western_fork")],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
database.add_rooms(
|
database.add_rooms(
|
||||||
Room(
|
Room(
|
||||||
id="start",
|
id="outside_cabin",
|
||||||
name="Test room",
|
name="Outside the cabin",
|
||||||
desc="You're in ((Todd's Test Cell)).",
|
desc=[],
|
||||||
items=[
|
items=[
|
||||||
database.items["glowing_rock"].create_inst(),
|
database.items["mailbox"].create_inst(),
|
||||||
database.items["cell_door"].create_inst(),
|
database.items["anjas_letter"].create_inst(revealed=False),
|
||||||
|
database.items["west_path"].create_inst(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Western fork
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
database.add_items(
|
||||||
|
Item(
|
||||||
|
id="eastern_path",
|
||||||
|
name="Eastern path",
|
||||||
|
room_desc="A path that leads eastward. Your cabin lies in this direction.",
|
||||||
|
synonyms=(
|
||||||
|
"path to east",
|
||||||
|
"path to the east",
|
||||||
|
"path leading east",
|
||||||
|
"path leading eastward",
|
||||||
|
"east",
|
||||||
|
"eastward",
|
||||||
|
"eastward path",
|
||||||
|
"east path",
|
||||||
|
"eastern path",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
database.add_rooms(Room(id="western_fork", name="Western fork", desc=[], items=[]))
|
||||||
|
|||||||
@@ -3,5 +3,6 @@ Define all game variables here.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
vars = {
|
vars = {
|
||||||
"cell_door_open": False,
|
"cabin_door_open": False,
|
||||||
|
"mailbox_open": False,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user