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:
2021-11-18 16:26:16 -08:00
parent 1304b27944
commit 7f86aafc05
10 changed files with 446 additions and 121 deletions

View File

@@ -12,12 +12,13 @@ if TYPE_CHECKING:
# use [a[n]/the] x [with/on [a[n]/the] y]
# put [a[n]/the] x on/in [a[n]/the] y
# look [[at] [a[n]/the] x]
# read [a[n]/the] x
# open x
# close x
# go/(go to)/leave/exit x
# give [a[n]/the] x to [a[n]/the] y
# push [a[n]/the] x
# pull [a[n]/the] x
# give [a[n]/the] x to [a[n]/the] y - TODO
# push [a[n]/the] x - TODO
# pull [a[n]/the] x - TODO
# (put down)/drop [a[n]/the] x
__all__ = (
"Trigger",
@@ -25,6 +26,7 @@ __all__ = (
"UseTrigger",
"PutTrigger",
"LookTrigger",
"ReadTrigger",
"OpenTrigger",
"CloseTrigger",
"GoTrigger",
@@ -32,6 +34,7 @@ __all__ = (
"USE",
"PUT",
"LOOK",
"READ",
"OPEN",
"CLOSE",
"GO",
@@ -40,6 +43,7 @@ GET = "get"
USE = "use"
PUT = "put"
LOOK = "look"
READ = "read"
OPEN = "open"
CLOSE = "close"
GO = "go"
@@ -73,8 +77,8 @@ class GetTrigger(Trigger):
otrigger = match["trigger"].lower().capitalize()
game.say(f"{otrigger} what?")
return
item = game.room.search_item_name(item_name.lower())
if item and GET in item.triggers:
item = game.room.search_item_name(item_name)
if item and item.revealed and GET in item.triggers:
actions = item.triggers[GET]
# if there are any actions, do them. else do the default action
game.do_actions(actions)
@@ -106,9 +110,9 @@ class UseTrigger(Trigger):
# Get the item from inventory or room
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}.")
return
@@ -116,9 +120,9 @@ class UseTrigger(Trigger):
if target_name:
# Get the target from inventory or room
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}.")
# Check if the target can be used on something
elif target.id in item.use_actions:
@@ -168,14 +172,42 @@ class LookTrigger(Trigger):
if not item_name:
game.print_room()
return
item = game.room.search_item_name(item_name.lower())
if item and LOOK in item.triggers:
item = game.room.search_item_name(item_name) or search_item_name(
game.inventory.values(), item_name
)
if item and LOOK in item.triggers and item.revealed:
actions = item.triggers[LOOK]
game.do_actions(actions)
else:
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):
@staticmethod
def pattern() -> Pattern:
@@ -192,8 +224,8 @@ class OpenTrigger(Trigger):
if not item_name:
game.say("Open what?")
return
item = game.room.search_item_name(item_name.lower())
if item and OPEN in item.triggers:
item = game.room.search_item_name(item_name)
if item and OPEN in item.triggers and item.revealed:
actions = item.triggers[OPEN]
game.do_actions(actions)
else:
@@ -216,8 +248,8 @@ class CloseTrigger(Trigger):
if not item_name:
game.say("Close what?")
return
item = game.room.search_item_name(item_name.lower())
if item and CLOSE in item.triggers:
item = game.room.search_item_name(item_name)
if item and CLOSE in item.triggers and item.revealed:
actions = item.triggers[CLOSE]
game.do_actions(actions)
else:
@@ -229,7 +261,7 @@ class GoTrigger(Trigger):
def pattern() -> Pattern:
return re.compile(
r"""
(?P<trigger>go|go[ ]*to|leave|exit)
(?P<trigger>go([ ]*to)?|leave|exit)
(((an?|the)[ ]+)?[ ]+(?P<item>.+?))?
""",
re.IGNORECASE | re.VERBOSE,
@@ -241,7 +273,9 @@ class GoTrigger(Trigger):
otrigger = match["trigger"].lower().capitalize()
game.say(f"{otrigger} where?")
return
item = game.room.search_item_name(item_name.lower())
if item and GO in item.triggers:
item = game.room.search_item_name(item_name)
if item and GO in item.triggers and item.revealed:
actions = item.triggers[GO]
game.do_actions(actions)
else:
game.say("Can't go there.")