Format code with black. Add makefile to run fmt/tests

This commit is contained in:
Griatch 2019-09-28 18:18:11 +02:00
parent d00bce9288
commit c2c7fa311a
299 changed files with 19037 additions and 11611 deletions

View file

@ -35,7 +35,7 @@ from evennia import syscmdkeys
from evennia.utils import variable_from_module
from .utils import create_evscaperoom_object
_AT_SEARCH_RESULT = variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
_AT_SEARCH_RESULT = variable_from_module(*settings.SEARCH_AT_RESULT.rsplit(".", 1))
_RE_ARGSPLIT = re.compile(r"\s(with|on|to|in|at)\s", re.I + re.U)
_RE_EMOTE_SPEECH = re.compile(r"(\".*?\")|(\'.*?\')")
@ -111,6 +111,7 @@ class CmdEvscapeRoom(Command):
command [<obj1>|<arg1>] [<prep> <obj2>|<arg2>]
"""
# always separate the command from any args with a space
arg_regex = r"(/\w+?(\s|$))|\s|$"
help_category = "Evscaperoom"
@ -210,6 +211,7 @@ class CmdGiveUp(CmdEvscapeRoom):
Abandons your attempts at escaping and of ever winning the pie-eating contest.
"""
key = "give up"
aliases = ("abort", "chicken out", "quit", "q")
@ -224,10 +226,10 @@ class CmdGiveUp(CmdEvscapeRoom):
warning = _QUIT_WARNING_CAN_COME_BACK.format(roomname=self.room.name)
warning = _QUIT_WARNING.format(warning=warning)
ret = yield(warning)
ret = yield (warning)
if ret.upper() == "QUIT":
self.msg("|R ... Oh. Okay then. Off you go.|n\n")
yield(1)
yield (1)
self.room.log(f"QUIT: {self.caller.key} used the quit command")
@ -250,6 +252,7 @@ class CmdLook(CmdEvscapeRoom):
look [obj]
"""
key = "look"
aliases = ["l", "ls"]
obj1_search = None
@ -276,6 +279,7 @@ class CmdWho(CmdEvscapeRoom, default_cmds.CmdWho):
server as a whole.
"""
key = "who"
obj1_search = False
@ -285,7 +289,7 @@ class CmdWho(CmdEvscapeRoom, default_cmds.CmdWho):
caller = self.caller
if self.args == 'all':
if self.args == "all":
table = self.style_table("|wName", "|wRoom")
sessions = SESSION_HANDLER.get_sessions()
for session in sessions:
@ -298,15 +302,19 @@ class CmdWho(CmdEvscapeRoom, default_cmds.CmdWho):
account = session.get_account()
table.add_row(account.get_display_name(caller), "(OOC)")
txt = (f"|cPlayers active on this server|n:\n{table}\n"
"(use 'who' to see only those in your room)")
txt = (
f"|cPlayers active on this server|n:\n{table}\n"
"(use 'who' to see only those in your room)"
)
else:
chars = [f"{obj.get_display_name(caller)} - {obj.db.desc.strip()}"
for obj in self.room.get_all_characters()
if obj != caller]
chars = [
f"{obj.get_display_name(caller)} - {obj.db.desc.strip()}"
for obj in self.room.get_all_characters()
if obj != caller
]
chars = "\n".join([f"{caller.key} - {caller.db.desc.strip()} (you)"] + chars)
txt = (f"|cPlayers in this room (room-name '{self.room.name}')|n:\n {chars}")
txt = f"|cPlayers in this room (room-name '{self.room.name}')|n:\n {chars}"
caller.msg(txt)
@ -320,6 +328,7 @@ class CmdSpeak(Command):
shout
"""
key = "say"
aliases = [";", "shout", "whisper"]
arg_regex = r"\w|\s|$"
@ -329,7 +338,7 @@ class CmdSpeak(Command):
args = self.args.strip()
caller = self.caller
action = self.cmdname
action = "say" if action == ';' else action
action = "say" if action == ";" else action
room = self.caller.location
if not self.args:
@ -365,6 +374,7 @@ class CmdEmote(Command):
emote /me points to /box and /lever.
"""
key = "emote"
aliases = [":", "pose"]
arg_regex = r"\w|\s|$"
@ -379,7 +389,7 @@ class CmdEmote(Command):
emote = self.args.strip()
if not emote:
self.caller.msg("Usage: emote /me points to /door, saying \"look over there!\"")
self.caller.msg('Usage: emote /me points to /door, saying "look over there!"')
return
speech_clr = "|c"
@ -438,6 +448,7 @@ class CmdFocus(CmdEvscapeRoom):
looks and what actions is available.
"""
key = "focus"
aliases = ["examine", "e", "ex", "unfocus"]
@ -454,7 +465,9 @@ class CmdFocus(CmdEvscapeRoom):
return
if self.focus != self.obj1:
self.room.msg_room(self.caller, f"~You ~examine *{self.obj1.key}.", skip_caller=True)
self.room.msg_room(
self.caller, f"~You ~examine *{self.obj1.key}.", skip_caller=True
)
self.focus = self.obj1
self.obj1.at_focus(self.caller)
elif not self.focus:
@ -473,11 +486,13 @@ class CmdOptions(CmdEvscapeRoom):
options
"""
key = "options"
aliases = ["option"]
def func(self):
from .menu import run_option_menu
run_option_menu(self.caller, self.session)
@ -486,6 +501,7 @@ class CmdGet(CmdEvscapeRoom):
Use focus / examine instead.
"""
key = "get"
aliases = ["inventory", "i", "inv", "give"]
@ -501,6 +517,7 @@ class CmdRerouter(default_cmds.MuxCommand):
<action> [arg]
"""
# reroute commands from the default cmdset to the catch-all
# focus function where needed. This allows us to override
# individual default commands without replacing the entire
@ -512,9 +529,10 @@ class CmdRerouter(default_cmds.MuxCommand):
def func(self):
# reroute to another command
from evennia.commands import cmdhandler
cmdhandler.cmdhandler(self.session, self.raw_string,
cmdobj=CmdFocusInteraction(),
cmdobj_key=self.cmdname)
cmdhandler.cmdhandler(
self.session, self.raw_string, cmdobj=CmdFocusInteraction(), cmdobj_key=self.cmdname
)
class CmdFocusInteraction(CmdEvscapeRoom):
@ -532,6 +550,7 @@ class CmdFocusInteraction(CmdEvscapeRoom):
as keys into the method.
"""
# all commands not matching something else goes here.
key = syscmdkeys.CMD_NOMATCH
@ -571,19 +590,18 @@ class CmdStand(CmdEvscapeRoom):
Stand up from whatever position you had.
"""
key = "stand"
def func(self):
# Positionable objects will set this flag on you.
pos = self.caller.attributes.get(
"position", category=self.room.tagcategory)
pos = self.caller.attributes.get("position", category=self.room.tagcategory)
if pos:
# we have a position, clean up.
obj, position = pos
self.caller.attributes.remove(
"position", category=self.room.tagcategory)
self.caller.attributes.remove("position", category=self.room.tagcategory)
del obj.db.positions[self.caller]
self.room.msg_room(self.caller, "~You ~are back standing on the floor again.")
else:
@ -598,8 +616,9 @@ class CmdHelp(CmdEvscapeRoom, default_cmds.CmdHelp):
help <topic> or <command>
"""
key = 'help'
aliases = ['?']
key = "help"
aliases = ["?"]
def func(self):
if self.obj1:
@ -608,8 +627,10 @@ class CmdHelp(CmdEvscapeRoom, default_cmds.CmdHelp):
if not helptxt:
helptxt = f"There is no help to be had about {self.obj1.get_display_name(self.caller)}."
else:
helptxt = (f"|y{self.obj1.get_display_name(self.caller)}|n is "
"likely |rnot|n part of any of the Jester's trickery.")
helptxt = (
f"|y{self.obj1.get_display_name(self.caller)}|n is "
"likely |rnot|n part of any of the Jester's trickery."
)
elif self.arg1:
# fall back to the normal help command
super().func()
@ -621,6 +642,7 @@ class CmdHelp(CmdEvscapeRoom, default_cmds.CmdHelp):
# Debug/help command
class CmdCreateObj(CmdEvscapeRoom):
"""
Create command, only for Admins during debugging.
@ -631,6 +653,7 @@ class CmdCreateObj(CmdEvscapeRoom):
Here, :typeclass is a class in evscaperoom.commands
"""
key = "createobj"
aliases = ["cobj"]
locks = "cmd:perm(Admin)"
@ -668,6 +691,7 @@ class CmdSetFlag(CmdEvscapeRoom):
flag <obj> with <flagname>
"""
key = "flag"
aliases = ["setflag"]
locks = "cmd:perm(Admin)"
@ -700,6 +724,7 @@ class CmdJumpState(CmdEvscapeRoom):
jumpstate <statename>
"""
key = "jumpstate"
locks = "cmd:perm(Admin)"
@ -713,22 +738,26 @@ class CmdJumpState(CmdEvscapeRoom):
# Helper command to start the Evscaperoom menu
class CmdEvscapeRoomStart(Command):
"""
Go to the Evscaperoom start menu
"""
key = "evscaperoom"
help_category = "EvscapeRoom"
def func(self):
# need to import here to break circular import
from .menu import run_evscaperoom_menu
run_evscaperoom_menu(self.caller)
# command sets
class CmdSetEvScapeRoom(CmdSet):
priority = 1

View file

@ -55,7 +55,7 @@ def _move_to_room(caller, raw_string, **kwargs):
Helper to move a user to a room
"""
room = kwargs['room']
room = kwargs["room"]
room.msg_char(caller, f"Entering room |c'{room.name}'|n ...")
room.msg_room(caller, f"~You |c~were just tricked in here too!|n")
# we do a manual move since we don't want all hooks to fire.
@ -78,7 +78,9 @@ def _create_new_room(caller, raw_string, **kwargs):
_move_to_room(caller, "", room=room)
nrooms = EvscapeRoom.objects.all().count()
logger.log_info(f"Evscaperoom: {caller.key} created room '{key}' (#{room.id}). Now {nrooms} room(s) active.")
logger.log_info(
f"Evscaperoom: {caller.key} created room '{key}' (#{room.id}). Now {nrooms} room(s) active."
)
room.log(f"JOIN: {caller.key} created and joined room")
return "node_quit", {"quiet": True}
@ -96,10 +98,12 @@ def _get_all_rooms(caller):
if not room.pk or room.db.deleting:
continue
stats = room.db.stats or {"progress": 0}
progress = int(stats['progress'])
progress = int(stats["progress"])
nplayers = len(room.get_all_characters())
desc = (f"Join room |c'{room.get_display_name(caller)}'|n "
f"(complete: {progress}%, players: {nplayers})")
desc = (
f"Join room |c'{room.get_display_name(caller)}'|n "
f"(complete: {progress}%, players: {nplayers})"
)
room_map[desc] = room
room_option_descs.append(desc)
caller.ndb._menutree.room_map = room_map
@ -121,24 +125,34 @@ def node_start(caller, raw_string, **kwargs):
# build a list of available rooms
options = (
{"key": ("|y[s]et your description|n", "set your description",
"set", "desc", "description", "s"),
"goto": "node_set_desc"},
{"key": ("|y[c]reate/join a new room|n", "create a new room", "create", "c"),
"goto": "node_create_room"},
{"key": ("|r[q]uit the challenge", "quit", "q"),
"goto": "node_quit"})
{
"key": (
"|y[s]et your description|n",
"set your description",
"set",
"desc",
"description",
"s",
),
"goto": "node_set_desc",
},
{
"key": ("|y[c]reate/join a new room|n", "create a new room", "create", "c"),
"goto": "node_create_room",
},
{"key": ("|r[q]uit the challenge", "quit", "q"), "goto": "node_quit"},
)
return text, options
def node_set_desc(caller, raw_string, **kwargs):
current_desc = kwargs.get('desc', caller.db.desc)
current_desc = kwargs.get("desc", caller.db.desc)
text = ("Your current description is\n\n "
f" \"{current_desc}\""
"\n\nEnter your new description!")
text = (
"Your current description is\n\n " f' "{current_desc}"' "\n\nEnter your new description!"
)
def _temp_description(caller, raw_string, **kwargs):
desc = raw_string.strip()
@ -154,12 +168,10 @@ def node_set_desc(caller, raw_string, **kwargs):
return "node_start"
options = (
{"key": "_default",
"goto": _temp_description},
{"key": ("|g[a]ccept", "a"),
"goto": (_set_description, {"desc": current_desc})},
{"key": ("|r[c]ancel", "c"),
"goto": "node_start"})
{"key": "_default", "goto": _temp_description},
{"key": ("|g[a]ccept", "a"), "goto": (_set_description, {"desc": current_desc})},
{"key": ("|r[c]ancel", "c"), "goto": "node_start"},
)
return text, options
@ -168,34 +180,31 @@ def node_create_room(caller, raw_string, **kwargs):
text = _CREATE_ROOM_TEXT
options = (
{"key": ("|g[c]reate new room and start game|n", "c"),
"goto": _create_new_room},
{"key": ("|r[a]bort and go back|n", "a"),
"goto": "node_start"})
{"key": ("|g[c]reate new room and start game|n", "c"), "goto": _create_new_room},
{"key": ("|r[a]bort and go back|n", "a"), "goto": "node_start"},
)
return text, options
def node_join_room(caller, raw_string, **kwargs):
room = kwargs['room']
room = kwargs["room"]
stats = room.db.stats or {"progress": 0}
players = [char.key for char in room.get_all_characters()]
text = _JOIN_EXISTING_ROOM_TEXT.format(
roomname=room.get_display_name(caller),
percent=int(stats['progress']),
percent=int(stats["progress"]),
nplayers=len(players),
players=list_to_string(players)
players=list_to_string(players),
)
options = (
{"key": ("|g[a]ccept|n (default)", "a"),
"goto": (_move_to_room, kwargs)},
{"key": ("|r[c]ancel|n", "c"),
"goto": "node_start"},
{"key": "_default",
"goto": (_move_to_room, kwargs)})
{"key": ("|g[a]ccept|n (default)", "a"), "goto": (_move_to_room, kwargs)},
{"key": ("|r[c]ancel|n", "c"), "goto": "node_start"},
{"key": "_default", "goto": (_move_to_room, kwargs)},
)
return text, options
@ -210,9 +219,10 @@ def node_quit(caller, raw_string, **kwargs):
if caller.db.evscaperoom_standalone:
from evennia.commands import cmdhandler
from evennia import default_cmds
cmdhandler.cmdhandler(caller.ndb._menutree._session, "",
cmdobj=default_cmds.CmdQuit(),
cmdobj_key="@quit")
cmdhandler.cmdhandler(
caller.ndb._menutree._session, "", cmdobj=default_cmds.CmdQuit(), cmdobj_key="@quit"
)
return text, None # empty options exit the menu
@ -222,10 +232,11 @@ class EvscaperoomMenu(EvMenu):
Custom menu with a different formatting of options.
"""
node_border_char = "~"
def nodetext_formatter(self, text):
return justify(text.strip("\n").rstrip(), align='c', indent=1)
return justify(text.strip("\n").rstrip(), align="c", indent=1)
def options_formatter(self, optionlist):
main_options = []
@ -237,9 +248,7 @@ class EvscaperoomMenu(EvMenu):
main_options.append(key)
main_options = " | ".join(main_options)
room_choices = super().options_formatter(room_choices)
return "{}{}{}".format(main_options,
"\n\n" if room_choices else "",
room_choices)
return "{}{}{}".format(main_options, "\n\n" if room_choices else "", room_choices)
# access function
@ -248,20 +257,22 @@ def run_evscaperoom_menu(caller):
Run room selection menu
"""
menutree = {"node_start": node_start,
"node_quit": node_quit,
"node_set_desc": node_set_desc,
"node_create_room": node_create_room,
"node_join_room": node_join_room}
menutree = {
"node_start": node_start,
"node_quit": node_quit,
"node_set_desc": node_set_desc,
"node_create_room": node_create_room,
"node_join_room": node_join_room,
}
EvscaperoomMenu(caller, menutree, startnode="node_start",
cmd_on_exit=None, auto_quit=True)
EvscaperoomMenu(caller, menutree, startnode="node_start", cmd_on_exit=None, auto_quit=True)
# ------------------------------------------------------------
# In-game Options menu
# ------------------------------------------------------------
def _set_thing_style(caller, raw_string, **kwargs):
room = caller.location
options = caller.attributes.get("options", category=room.tagcategory, default={})
@ -272,7 +283,7 @@ def _set_thing_style(caller, raw_string, **kwargs):
def _toggle_screen_reader(caller, raw_string, **kwargs):
session = kwargs['session']
session = kwargs["session"]
# flip old setting
session.protocol_flags["SCREENREADER"] = not session.protocol_flags.get("SCREENREADER", False)
# sync setting with portal
@ -287,22 +298,33 @@ def node_options(caller, raw_string, **kwargs):
options = caller.attributes.get("options", category=room.tagcategory, default={})
things_style = options.get("things_style", 2)
session = kwargs['session'] # we give this as startnode_input when starting menu
session = kwargs["session"] # we give this as startnode_input when starting menu
screenreader = session.protocol_flags.get("SCREENREADER", False)
options = (
{"desc": "{}No item markings (hard mode)".format(
"|g(*)|n " if things_style == 0 else "( ) "),
"goto": (_set_thing_style, {"value": 0, 'session': session})},
{"desc": "{}Items marked as |yitem|n (with color)".format(
"|g(*)|n " if things_style == 1 else "( ) "),
"goto": (_set_thing_style, {"value": 1, 'session': session})},
{"desc": "{}Items are marked as |y[item]|n (screenreader friendly)".format(
"|g(*)|n " if things_style == 2 else "( ) "),
"goto": (_set_thing_style, {"value": 2, 'session': session})},
{"desc": "{}Screenreader mode".format(
"(*) " if screenreader else "( ) "),
"goto": (_toggle_screen_reader, kwargs)})
{
"desc": "{}No item markings (hard mode)".format(
"|g(*)|n " if things_style == 0 else "( ) "
),
"goto": (_set_thing_style, {"value": 0, "session": session}),
},
{
"desc": "{}Items marked as |yitem|n (with color)".format(
"|g(*)|n " if things_style == 1 else "( ) "
),
"goto": (_set_thing_style, {"value": 1, "session": session}),
},
{
"desc": "{}Items are marked as |y[item]|n (screenreader friendly)".format(
"|g(*)|n " if things_style == 2 else "( ) "
),
"goto": (_set_thing_style, {"value": 2, "session": session}),
},
{
"desc": "{}Screenreader mode".format("(*) " if screenreader else "( ) "),
"goto": (_toggle_screen_reader, kwargs),
},
)
return text, options
@ -310,6 +332,7 @@ class OptionsMenu(EvMenu):
"""
Custom display of Option menu
"""
def node_formatter(self, nodetext, optionstext):
return f"{nodetext}\n\n{optionstext}"
@ -321,5 +344,11 @@ def run_option_menu(caller, session):
"""
menutree = {"node_start": node_options}
OptionsMenu(caller, menutree, startnode="node_start",
cmd_on_exit="look", auto_quit=True, startnode_input=("", {"session": session}))
OptionsMenu(
caller,
menutree,
startnode="node_start",
cmd_on_exit="look",
auto_quit=True,
startnode_input=("", {"session": session}),
)

View file

@ -56,6 +56,7 @@ class EvscaperoomObject(DefaultObject):
Default object base for all objects related to the contrib.
"""
# these will be automatically filtered out by self.parse for
# focus-commands using arguments like (`combine [with] object`)
# override this per-class as necessary.
@ -63,10 +64,7 @@ class EvscaperoomObject(DefaultObject):
# this mapping allows for prettier descriptions of our current
# position
position_prep_map = {"sit": "sitting",
"kneel": "kneeling",
"lie": "lying",
"climb": "standing"}
position_prep_map = {"sit": "sitting", "kneel": "kneeling", "lie": "lying", "climb": "standing"}
def at_object_creation(self):
"""
@ -86,8 +84,9 @@ class EvscaperoomObject(DefaultObject):
@property
def tagcategory(self):
if not self._tagcategory:
self._tagcategory = (self.location.db.tagcategory
if self.location else self.db.tagcategory)
self._tagcategory = (
self.location.db.tagcategory if self.location else self.db.tagcategory
)
return self._tagcategory
@property
@ -162,16 +161,15 @@ class EvscaperoomObject(DefaultObject):
you = caller.key if caller else "they"
first_person, third_person = parse_for_perspectives(string, you=you)
for char in self.room.get_all_characters():
options = char.attributes.get(
"options", category=self.room.tagcategory, default={})
options = char.attributes.get("options", category=self.room.tagcategory, default={})
style = options.get("things_style", 2)
if char == caller:
if not skip_caller:
txt = parse_for_things(first_person, things_style=style)
char.msg((txt, {'type': 'your_action'}))
char.msg((txt, {"type": "your_action"}))
else:
txt = parse_for_things(third_person, things_style=style)
char.msg((txt, {'type': 'others_action'}))
char.msg((txt, {"type": "others_action"}))
def msg_char(self, caller, string, client_type="your_action"):
"""
@ -180,8 +178,7 @@ class EvscaperoomObject(DefaultObject):
"""
# we must clean away markers
first_person, _ = parse_for_perspectives(string)
options = caller.attributes.get(
"options", category=self.room.tagcategory, default={})
options = caller.attributes.get("options", category=self.room.tagcategory, default={})
style = options.get("things_style", 2)
txt = parse_for_things(first_person, things_style=style)
caller.msg((txt, {"type": client_type}))
@ -227,8 +224,7 @@ class EvscaperoomObject(DefaultObject):
"""
if new_position is None:
# reset position
caller.attributes.remove(
"position", category=self.tagcategory)
caller.attributes.remove("position", category=self.tagcategory)
if caller in self.db.positions:
del self.db.positions[caller]
else:
@ -279,8 +275,9 @@ class EvscaperoomObject(DefaultObject):
here.
"""
args = re.sub(r"|".join(r"^{}\s".format(prep) for prep in self.action_prepositions),
"", args)
args = re.sub(
r"|".join(r"^{}\s".format(prep) for prep in self.action_prepositions), "", args
)
return args
def get_cmd_signatures(self):
@ -307,11 +304,11 @@ class EvscaperoomObject(DefaultObject):
command_signatures = sorted(command_signatures)
if len(command_signatures) == 1:
helpstr = (f"It looks like {self.key} may be "
"suitable to {callsigns}.")
helpstr = f"It looks like {self.key} may be " "suitable to {callsigns}."
else:
helpstr = (f"At first glance, it looks like {self.key} might be "
"suitable to {callsigns}.")
helpstr = (
f"At first glance, it looks like {self.key} might be " "suitable to {callsigns}."
)
return command_signatures, helpstr
def get_short_desc(self, full_desc):
@ -319,7 +316,7 @@ class EvscaperoomObject(DefaultObject):
Extract the first sentence from the desc and use as the short desc.
"""
mat = re.match(r"(^.*?[.?!])", full_desc.strip(), re.M+re.U+re.I+re.S)
mat = re.match(r"(^.*?[.?!])", full_desc.strip(), re.M + re.U + re.I + re.S)
if mat:
return mat.group(0).strip()
return full_desc
@ -336,8 +333,7 @@ class EvscaperoomObject(DefaultObject):
callsigns = list_to_string(["*" + sig for sig in command_signatures], endsep="or")
# parse for *thing markers (use these as items)
options = caller.attributes.get(
"options", category=self.room.tagcategory, default={})
options = caller.attributes.get("options", category=self.room.tagcategory, default={})
style = options.get("things_style", 2)
helpstr = helpstr.format(callsigns=callsigns)
@ -354,7 +350,7 @@ class EvscaperoomObject(DefaultObject):
# accept a custom desc
desc = kwargs.get("desc", self.db.desc)
if kwargs.get('unfocused', False):
if kwargs.get("unfocused", False):
# use the shorter description
focused = ""
desc = self.get_short_desc(desc)
@ -364,8 +360,11 @@ class EvscaperoomObject(DefaultObject):
helptxt = kwargs.get("helptxt", f"\n\n({self.get_help(looker)})")
obj, pos = self.get_position(looker)
pos = (f" |w({self.position_prep_map[pos]} on "
f"{obj.get_display_name(looker)})" if obj else "")
pos = (
f" |w({self.position_prep_map[pos]} on " f"{obj.get_display_name(looker)})"
if obj
else ""
)
return f" ~~ |y{self.get_display_name(looker)}|n{focused}{pos}|n ~~\n\n{desc}{helptxt}"
@ -375,6 +374,7 @@ class Feelable(EvscaperoomObject):
Any object that you can feel the surface of.
"""
def at_focus_feel(self, caller, **kwargs):
self.msg_char(caller, f"You feel *{self.key}.")
@ -384,6 +384,7 @@ class Listenable(EvscaperoomObject):
Any object one can listen to.
"""
def at_focus_listen(self, caller, **kwargs):
self.msg_char(caller, f"You listen to *{self.key}")
@ -393,6 +394,7 @@ class Smellable(EvscaperoomObject):
Any object you can smell.
"""
def at_focus_smell(self, caller, **kwargs):
self.msg_char(caller, f"You smell *{self.key}.")
@ -402,6 +404,7 @@ class Rotatable(EvscaperoomObject):
Any object that you can lift up and look at from different angles
"""
rotate_flag = "rotatable"
start_rotatable = True
@ -417,6 +420,7 @@ class Rotatable(EvscaperoomObject):
self.at_rotate(caller)
else:
self.at_cannot_rotate(caller)
at_focus_turn = at_focus_rotate
def at_rotate(self, caller):
@ -432,6 +436,7 @@ class Openable(EvscaperoomObject):
a flag.
"""
# this flag must be set for item to open. None for unlocked.
unlock_flag = "unlocked"
open_flag = "open"
@ -482,6 +487,7 @@ class Readable(EvscaperoomObject):
from a flag.
"""
# this must be set to be able to read. None to
# always be able to read.
@ -515,11 +521,7 @@ class IndexReadable(Readable):
"""
# keys should be lower-key
index = {
"page1": "This is page1",
"page2": "This is page2",
"page two": "page2" # alias
}
index = {"page1": "This is page1", "page2": "This is page2", "page two": "page2"} # alias
def at_focus_read(self, caller, **kwargs):
@ -536,8 +538,10 @@ class IndexReadable(Readable):
self.at_read(caller, topic, entry)
def get_cmd_signatures(self):
txt = (f"You don't have the time to read this from beginning to end. "
"Use *read <topic> to look up something in particular.")
txt = (
f"You don't have the time to read this from beginning to end. "
"Use *read <topic> to look up something in particular."
)
return [], txt
def at_cannot_read(self, caller, topic, *args, **kwargs):
@ -556,10 +560,10 @@ class Movable(EvscaperoomObject):
change.
"""
# these are the possible locations (or directions) to move to
# name: callable
move_positions = {"left": "at_left",
"right": "at_right"}
move_positions = {"left": "at_left", "right": "at_right"}
start_position = "left"
def at_object_creation(self):
@ -571,7 +575,7 @@ class Movable(EvscaperoomObject):
return ["move", "push", "shove left/right"], txt
def at_focus_move(self, caller, **kwargs):
pos = self.parse(kwargs['args'])
pos = self.parse(kwargs["args"])
callfunc_name = self.move_positions.get(pos)
if callfunc_name:
@ -610,6 +614,7 @@ class BaseConsumable(EvscaperoomObject):
a custom object if needed).
"""
consume_flag = "consume"
# may only consume once
one_consume_only = True
@ -647,6 +652,7 @@ class Edible(BaseConsumable):
Any object specifically possible to eat.
"""
consume_flag = "eat"
def at_focus_eat(self, caller, **kwargs):
@ -658,6 +664,7 @@ class Drinkable(BaseConsumable):
Any object specifically possible to drink.
"""
consume_flag = "drink"
def at_focus_drink(self, caller, **kwargs):
@ -679,6 +686,7 @@ class BaseApplicable(EvscaperoomObject):
This acts an an abstract base class.
"""
# the target object this is to be used with must
# have this flag. It'll likely be unique to this
# object combination.
@ -689,7 +697,7 @@ class BaseApplicable(EvscaperoomObject):
Wrap this with the at_focus methods in the child classes
"""
args = self.parse(kwargs['args'])
args = self.parse(kwargs["args"])
if not args:
self.msg_char(caller, "You need to specify a target.")
return
@ -717,6 +725,7 @@ class Usable(BaseApplicable):
Any object that can be used with another object.
"""
target_flag = "usable"
def at_focus_use(self, caller, **kwargs):
@ -736,6 +745,7 @@ class Insertable(BaseApplicable):
This would cover a key, for example.
"""
# this would likely be a custom name
target_flag = "insertable"
@ -759,6 +769,7 @@ class Combinable(BaseApplicable):
a new one.
"""
# the other object must have this flag to be able to be combined
# (this is likely unique for a given combination)
target_flag = "combinable"
@ -767,7 +778,8 @@ class Combinable(BaseApplicable):
new_create_dict = {
"typeclass": "evscaperoom.objects.Combinable",
"key": "sword",
"aliases": ["combined"]}
"aliases": ["combined"],
}
# if set, destroy the two components used to make the new one
destroy_components = True
@ -784,11 +796,12 @@ class Combinable(BaseApplicable):
def at_apply(self, caller, action, other_obj):
create_dict = self.new_create_dict
if "location" not in create_dict:
create_dict['location'] = self.location
create_dict["location"] = self.location
new_obj = create_evscaperoom_object(**create_dict)
if new_obj and self.destroy_components:
self.msg_char(caller,
f"You combine *{self.key} with {other_obj.key} to make {new_obj.key}!")
self.msg_char(
caller, f"You combine *{self.key} with {other_obj.key} to make {new_obj.key}!"
)
other_obj.delete()
self.delete()
@ -800,14 +813,11 @@ class Mixable(EvscaperoomObject):
the ingredients should be 'used' with this object in order
mix, calling at_mix when they do.
"""
# ingredients can check for this before they allow to mix at all
mixer_flag = "mixer"
# ingredients must have these flags and this order
ingredient_recipe = [
"ingredient1",
"ingredient2",
"ingredient3"
]
ingredient_recipe = ["ingredient1", "ingredient2", "ingredient3"]
def at_object_creation(self):
super().at_object_creation()
@ -847,7 +857,9 @@ class Mixable(EvscaperoomObject):
if self.check_mixture():
self.at_mix_success(caller, ingredient, **kwargs)
else:
self.room.log(f"{self.name} mix failure: Tried {' + '.join([ing.key for ing in self.db.ingredients if ing])}")
self.room.log(
f"{self.name} mix failure: Tried {' + '.join([ing.key for ing in self.db.ingredients if ing])}"
)
self.db.ingredients = []
self.at_mix_failure(caller, ingredient, **kwargs)
@ -866,25 +878,31 @@ class HasButtons(EvscaperoomObject):
Any object with buttons to push/press
"""
# mapping keys/aliases to calling method
buttons = {'green button': "at_green_button",
'green': "at_green_button",
'red button': "at_red_button",
'red': "at_red_button"}
buttons = {
"green button": "at_green_button",
"green": "at_green_button",
"red button": "at_red_button",
"red": "at_red_button",
}
def get_cmd_signatures(self):
helptxt = ("It looks like you should be able to operate "
f"*{self.key} by means of "
"{callsigns}.")
helptxt = (
"It looks like you should be able to operate "
f"*{self.key} by means of "
"{callsigns}."
)
return ["push", "press red/green button"], helptxt
def at_focus_press(self, caller, **kwargs):
arg = self.parse(kwargs['args'])
arg = self.parse(kwargs["args"])
callfunc_name = self.buttons.get(arg)
if callfunc_name:
getattr(self, callfunc_name)(caller)
else:
self.at_nomatch(caller)
at_focus_push = at_focus_press
def at_nomatch(self, caller):
@ -903,6 +921,7 @@ class CodeInput(EvscaperoomObject):
to have an effect happen.
"""
# the code of this
code = "PASSWORD"
code_hint = "eight letters A-Z"
@ -912,7 +931,7 @@ class CodeInput(EvscaperoomObject):
def at_focus_code(self, caller, **kwargs):
args = self.parse(kwargs['args'].strip())
args = self.parse(kwargs["args"].strip())
if not args:
self.at_no_code(caller)
@ -967,6 +986,7 @@ class BasePositionable(EvscaperoomObject):
object or not.
"""
def at_object_creation(self):
super().at_object_creation()
# mapping {object: position}.
@ -992,11 +1012,16 @@ class BasePositionable(EvscaperoomObject):
self.at_position(caller, new_pos)
def at_cannot_position(self, caller, position, old_obj, old_pos):
self.msg_char(caller, f"You can't; you are currently {self.position_prep_map[old_pos]} on *{old_obj.key} "
"(better |wstand|n first).")
self.msg_char(
caller,
f"You can't; you are currently {self.position_prep_map[old_pos]} on *{old_obj.key} "
"(better |wstand|n first).",
)
def at_again_position(self, caller, position):
self.msg_char(caller, f"But you are already {self.position_prep_map[position]} on *{self.key}?")
self.msg_char(
caller, f"But you are already {self.position_prep_map[position]} on *{self.key}?"
)
def at_position(self, caller, position):
self.msg_room(caller, f"~You ~{position} on *{self.key}.")
@ -1017,6 +1042,7 @@ class Liable(BasePositionable):
Any object you can lie down on.
"""
def at_focus_lie(self, caller, **kwargs):
super().handle_position(caller, "lie", **kwargs)
@ -1026,6 +1052,7 @@ class Kneelable(BasePositionable):
Any object you can kneel on.
"""
def at_focus_kneel(self, caller, **kwargs):
super().handle_position(caller, "kneel", **kwargs)
@ -1037,6 +1064,7 @@ class Climbable(BasePositionable):
command, which resets your position.
"""
def at_focus_climb(self, caller, **kwargs):
super().handle_position(caller, "climb", **kwargs)
@ -1047,6 +1075,7 @@ class Positionable(Sittable, Liable, Kneelable, Climbable):
supported ways (sit, lie, kneel or climb)
"""
def get_cmd_signatures(self):
txt = "It looks like you can {callsigns} on it."
return ["sit", "lie", "kneel", "climb"], txt

View file

@ -32,7 +32,7 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
super().at_object_creation()
# starting state
self.db.state = None # name
self.db.state = None # name
self.db.prev_state = None
# this is used for tagging of all objects belonging to this
@ -43,11 +43,11 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
# room progress statistics
self.db.stats = {
"progress": 0, # in percent
"score": {}, # reason: score
"score": {}, # reason: score
"max_score": 100,
"hints_used": 0, # total across all states
"hints_total": 41,
"total_achievements": 14
"total_achievements": 14,
}
self.cmdset.add(CmdSetEvScapeRoom, permanent=True)
@ -69,21 +69,21 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
caller = f"[caller.key]: " if caller else ""
logger.log_file(
strip_ansi(f"{caller}{message.strip()}"),
filename=self.tagcategory + ".log")
strip_ansi(f"{caller}{message.strip()}"), filename=self.tagcategory + ".log"
)
def score(self, new_score, reason):
"""
We don't score individually but for everyone in room together.
You can only be scored for a given reason once."""
if reason not in self.db.stats['score']:
if reason not in self.db.stats["score"]:
self.log(f"score: {reason} ({new_score}pts)")
self.db.stats['score'][reason] = new_score
self.db.stats["score"][reason] = new_score
def progress(self, new_progress):
"Progress is what we set it to be (0-100%)"
self.log(f"progress: {new_progress}%")
self.db.stats['progress'] = new_progress
self.db.stats["progress"] = new_progress
def achievement(self, caller, achievement, subtext=""):
"""
@ -96,8 +96,7 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
subtext (str, optional): Eventual subtext/explanation
of the achievement.
"""
achievements = caller.attributes.get(
"achievements", category=self.tagcategory)
achievements = caller.attributes.get("achievements", category=self.tagcategory)
if not achievements:
achievements = {}
if achievement not in achievements:
@ -173,6 +172,7 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
"""
self.log(f"EXIT: {char} left room")
from .menu import run_evscaperoom_menu
self.character_cleanup(char)
char.location = char.home
@ -223,15 +223,18 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
def return_appearance(self, looker, **kwargs):
obj, pos = self.get_position(looker)
pos = (f"\n|x[{self.position_prep_map[pos]} on "
f"{obj.get_display_name(looker)}]|n" if obj else "")
pos = (
f"\n|x[{self.position_prep_map[pos]} on " f"{obj.get_display_name(looker)}]|n"
if obj
else ""
)
admin_only = ""
if self.check_perm(looker, "Admin"):
# only for admins
objs = DefaultObject.objects.filter_family(
db_location=self).exclude(id=looker.id)
admin_only = "\n|xAdmin only: " + \
list_to_string([obj.get_display_name(looker) for obj in objs])
objs = DefaultObject.objects.filter_family(db_location=self).exclude(id=looker.id)
admin_only = "\n|xAdmin only: " + list_to_string(
[obj.get_display_name(looker) for obj in objs]
)
return f"{self.db.desc}{pos}{admin_only}"

View file

@ -13,7 +13,6 @@ from evscaperoom.room import EvscapeRoom
class CleanupScript(DefaultScript):
def at_script_creation(self):
self.key = "evscaperoom_cleanup"

View file

@ -35,11 +35,13 @@ _GA = object.__getattribute__
# handler for managing states on room
class StateHandler(object):
"""
This sits on the room and is used to progress through the states.
"""
def __init__(self, room):
self.room = room
self.current_state_name = room.db.state or _FIRST_STATE
@ -109,12 +111,14 @@ class StateHandler(object):
# base state class
class BaseState(object):
"""
Base object holding all callables for a state. This is here to
allow easy overriding for child states.
"""
next_state = "unset"
# a sequence of hints to describe this state.
hints = []
@ -144,15 +148,20 @@ class BaseState(object):
Wrapper handling state method errors.
"""
@wraps(method)
def decorator(*args, **kwargs):
try:
return method(*args, **kwargs)
except Exception:
logger.log_trace(f"Error in State {__name__}")
self.room.msg_room(None, f"|rThere was an unexpected error in State {__name__}. "
"Please |wreport|r this as an issue.|n")
self.room.msg_room(
None,
f"|rThere was an unexpected error in State {__name__}. "
"Please |wreport|r this as an issue.|n",
)
raise # TODO
return decorator
def __getattribute__(self, key):
@ -176,8 +185,10 @@ class BaseState(object):
# return the next hint in the sequence.
self.room.db.state_hint_level = next_level
self.room.db.stats["hints_used"] += 1
self.room.log(f"HINT: {self.name.split('.')[-1]}, level {next_level + 1} "
f"(total used: {self.room.db.stats['hints_used']})")
self.room.log(
f"HINT: {self.name.split('.')[-1]}, level {next_level + 1} "
f"(total used: {self.room.db.stats['hints_used']})"
)
return self.hints[next_level]
else:
# no more hints for this state
@ -191,8 +202,7 @@ class BaseState(object):
if cinematic:
message = msg_cinematic(message, borders=borders)
if target:
options = target.attributes.get(
"options", category=self.room.tagcategory, default={})
options = target.attributes.get("options", category=self.room.tagcategory, default={})
style = options.get("things_style", 2)
# we assume this is a char
target.msg(parse_for_things(message, things_style=style))
@ -205,7 +215,7 @@ class BaseState(object):
"""
self.msg(message, target=target, borders=True, cinematic=True)
def create_object(self, typeclass=None, key='testobj', location=None, **kwargs):
def create_object(self, typeclass=None, key="testobj", location=None, **kwargs):
"""
This is a convenience-wrapper for quickly building EvscapeRoom objects.
@ -223,8 +233,12 @@ class BaseState(object):
if not location:
location = self.room
return create_evscaperoom_object(
typeclass=typeclass, key=key, location=location,
tags=[("room", self.room.tagcategory.lower())], **kwargs)
typeclass=typeclass,
key=key,
location=location,
tags=[("room", self.room.tagcategory.lower())],
**kwargs,
)
def get_object(self, key):
"""
@ -237,7 +251,8 @@ class BaseState(object):
"""
match = EvscaperoomObject.objects.filter_family(
db_key__iexact=key, db_tags__db_category=self.room.tagcategory.lower())
db_key__iexact=key, db_tags__db_category=self.room.tagcategory.lower()
)
if not match:
logger.log_err(f"get_object: No match for '{key}' in state ")
return None

View file

@ -40,6 +40,7 @@ class Door(objects.Openable):
The door leads out of the room.
"""
start_open = False
def at_object_creation(self):
@ -108,7 +109,6 @@ On the wall is a button marked
class HelpButton(objects.EvscaperoomObject):
def at_focus_push(self, caller, **kwargs):
"this adds the 'push' action to the button"
@ -116,8 +116,9 @@ class HelpButton(objects.EvscaperoomObject):
if hint is None:
self.msg_char(caller, "There are no more hints to be had.")
else:
self.msg_room(caller, f"{caller.key} pushes *button and gets the "
f"hint:\n \"{hint.strip()}\"|n")
self.msg_room(
caller, f"{caller.key} pushes *button and gets the " f'hint:\n "{hint.strip()}"|n'
)
# state
@ -144,9 +145,7 @@ class State(BaseState):
"""
# this makes these hints available to the .get_hint method.
hints = [STATE_HINT_LVL1,
STATE_HINT_LVL2,
STATE_HINT_LVL3]
hints = [STATE_HINT_LVL1, STATE_HINT_LVL2, STATE_HINT_LVL3]
def character_enters(self, char):
"Called when char enters room at this state"
@ -159,16 +158,13 @@ class State(BaseState):
self.room.db.desc = ROOM_DESC
# create the room objects
door = self.create_object(
Door, key="door to the cabin", aliases=["door"])
door = self.create_object(Door, key="door to the cabin", aliases=["door"])
door.db.desc = DOOR_DESC.strip()
key = self.create_object(
Key, key="key", aliases=["room key"])
key = self.create_object(Key, key="key", aliases=["room key"])
key.db.desc = KEY_DESC.strip()
button = self.create_object(
HelpButton, key="button", aliases=["help button"])
button = self.create_object(HelpButton, key="button", aliases=["help button"])
button.db.desc = BUTTON_DESC.strip()
def clean(self):

View file

@ -16,11 +16,9 @@ from . import utils
class TestEvscaperoomCommands(CommandTest):
def setUp(self):
super().setUp()
self.room1 = utils.create_evscaperoom_object(
"evscaperoom.room.EvscapeRoom", key='Testroom')
self.room1 = utils.create_evscaperoom_object("evscaperoom.room.EvscapeRoom", key="Testroom")
self.char1.location = self.room1
self.obj1.location = self.room1
@ -114,7 +112,7 @@ class TestEvscaperoomCommands(CommandTest):
self.assertEqual(cmd.obj1, None)
self.assertEqual(cmd.obj2, self.obj1)
self.assertEqual(cmd.arg1, 'foo')
self.assertEqual(cmd.arg1, "foo")
self.assertEqual(cmd.arg2, None)
cmd = commands.CmdEvscapeRoom()
@ -127,7 +125,7 @@ class TestEvscaperoomCommands(CommandTest):
self.assertEqual(cmd.obj1, self.obj1)
self.assertEqual(cmd.obj2, None)
self.assertEqual(cmd.arg1, None)
self.assertEqual(cmd.arg2, 'foo')
self.assertEqual(cmd.arg2, "foo")
cmd = commands.CmdEvscapeRoom()
cmd.caller = self.char1
@ -152,21 +150,20 @@ class TestEvscaperoomCommands(CommandTest):
cmd.caller = self.char1
cmd.room = self.room1
cmd.focus = self.obj1
self.assertEqual(self.char1.attributes.get(
"focus", category=self.room1.tagcategory), self.obj1)
self.assertEqual(
self.char1.attributes.get("focus", category=self.room1.tagcategory), self.obj1
)
def test_focus(self):
# don't focus on a non-room object
self.call(commands.CmdFocus(), "obj")
self.assertEqual(self.char1.attributes.get(
"focus", category=self.room1.tagcategory), None)
self.assertEqual(self.char1.attributes.get("focus", category=self.room1.tagcategory), None)
# should focus correctly
myobj = utils.create_evscaperoom_object(
objects.EvscaperoomObject, "mytestobj", location=self.room1)
objects.EvscaperoomObject, "mytestobj", location=self.room1
)
self.call(commands.CmdFocus(), "mytestobj")
self.assertEqual(self.char1.attributes.get(
"focus", category=self.room1.tagcategory), myobj)
self.assertEqual(self.char1.attributes.get("focus", category=self.room1.tagcategory), myobj)
def test_look(self):
self.call(commands.CmdLook(), "at obj", "Obj")
@ -181,31 +178,31 @@ class TestEvscaperoomCommands(CommandTest):
self.call(commands.CmdSpeak(), "Hi.", "You whisper: Hi.", cmdstring="whisper")
self.call(commands.CmdSpeak(), "HELLO!", "You shout: HELLO!", cmdstring="shout")
self.call(commands.CmdSpeak(), "Hello to obj",
"You say: Hello", cmdstring="say")
self.call(commands.CmdSpeak(), "Hello to obj",
"You shout: Hello", cmdstring="shout")
self.call(commands.CmdSpeak(), "Hello to obj", "You say: Hello", cmdstring="say")
self.call(commands.CmdSpeak(), "Hello to obj", "You shout: Hello", cmdstring="shout")
def test_emote(self):
self.call(commands.CmdEmote(),
"/me smiles to /obj",
f"Char(#{self.char1.id}) smiles to Obj(#{self.obj1.id})")
self.call(
commands.CmdEmote(),
"/me smiles to /obj",
f"Char(#{self.char1.id}) smiles to Obj(#{self.obj1.id})",
)
def test_focus_interaction(self):
self.call(commands.CmdFocusInteraction(), "", "Hm?")
class TestUtils(EvenniaTest):
def test_overwrite(self):
room = utils.create_evscaperoom_object(
"evscaperoom.room.EvscapeRoom", key='Testroom')
room = utils.create_evscaperoom_object("evscaperoom.room.EvscapeRoom", key="Testroom")
obj1 = utils.create_evscaperoom_object(
objects.EvscaperoomObject, key="testobj", location=room)
objects.EvscaperoomObject, key="testobj", location=room
)
id1 = obj1.id
obj2 = utils.create_evscaperoom_object(
objects.EvscaperoomObject, key="testobj", location=room)
objects.EvscaperoomObject, key="testobj", location=room
)
id2 = obj2.id
# we should have created a new object, deleting the old same-named one
@ -231,14 +228,12 @@ class TestUtils(EvenniaTest):
self.assertEqual(utils.parse_for_things(string, 2), "Looking at |y[book]|n and |y[key]|n.")
class TestEvScapeRoom(EvenniaTest):
def setUp(self):
super().setUp()
self.room = utils.create_evscaperoom_object(
"evscaperoom.room.EvscapeRoom", key='Testroom',
home=self.room1)
"evscaperoom.room.EvscapeRoom", key="Testroom", home=self.room1
)
self.roomtag = "evscaperoom_{}".format(self.room.key)
def tearDown(self):
@ -253,24 +248,21 @@ class TestEvScapeRoom(EvenniaTest):
self.assertEqual(list(room.get_all_characters()), [self.char1])
room.tag_character(self.char1, "opened_door")
self.assertEqual(self.char1.tags.get(
"opened_door", category=self.roomtag), "opened_door")
self.assertEqual(self.char1.tags.get("opened_door", category=self.roomtag), "opened_door")
room.tag_all_characters("tagged_all")
self.assertEqual(self.char1.tags.get(
"tagged_all", category=self.roomtag), "tagged_all")
self.assertEqual(self.char1.tags.get("tagged_all", category=self.roomtag), "tagged_all")
room.character_cleanup(self.char1)
self.assertEqual(self.char1.tags.get(category=self.roomtag), None)
class TestStates(EvenniaTest):
def setUp(self):
super().setUp()
self.room = utils.create_evscaperoom_object(
"evscaperoom.room.EvscapeRoom", key='Testroom',
home=self.room1)
"evscaperoom.room.EvscapeRoom", key="Testroom", home=self.room1
)
self.roomtag = "evscaperoom_#{}".format(self.room.id)
def tearDown(self):
@ -280,7 +272,8 @@ class TestStates(EvenniaTest):
dirname = path.join(path.dirname(__file__), "states")
states = []
for imp, module, ispackage in pkgutil.walk_packages(
path=[dirname], prefix="evscaperoom.states."):
path=[dirname], prefix="evscaperoom.states."
):
mod = mod_import(module)
states.append(mod)
return states

View file

@ -12,12 +12,13 @@ from evennia import create_object, search_object
from evennia.utils import justify, inherits_from
_BASE_TYPECLASS_PATH = "evscaperoom.objects."
_RE_PERSPECTIVE = re.compile(r"~(\w+)", re.I+re.U+re.M)
_RE_THING = re.compile(r"\*(\w+)", re.I+re.U+re.M)
_RE_PERSPECTIVE = re.compile(r"~(\w+)", re.I + re.U + re.M)
_RE_THING = re.compile(r"\*(\w+)", re.I + re.U + re.M)
def create_evscaperoom_object(typeclass=None, key="testobj", location=None,
delete_duplicates=True, **kwargs):
def create_evscaperoom_object(
typeclass=None, key="testobj", location=None, delete_duplicates=True, **kwargs
):
"""
This is a convenience-wrapper for quickly building EvscapeRoom objects. This
is called from the helper-method create_object on states, but is also useful
@ -38,25 +39,29 @@ def create_evscaperoom_object(typeclass=None, key="testobj", location=None,
"""
if not (callable(typeclass) or
typeclass.startswith("evennia") or
typeclass.startswith("typeclasses") or
typeclass.startswith("evscaperoom")):
if not (
callable(typeclass)
or typeclass.startswith("evennia")
or typeclass.startswith("typeclasses")
or typeclass.startswith("evscaperoom")
):
# unless we specify a full typeclass path or the class itself,
# auto-complete it
typeclass = _BASE_TYPECLASS_PATH + typeclass
if delete_duplicates:
old_objs = [obj for obj in search_object(key)
if not inherits_from(obj, "evennia.objects.objects.DefaultCharacter")]
old_objs = [
obj
for obj in search_object(key)
if not inherits_from(obj, "evennia.objects.objects.DefaultCharacter")
]
if location:
# delete only matching objects in the given location
[obj.delete() for obj in old_objs if obj.location == location]
else:
[obj.delete() for obj in old_objs]
new_obj = create_object(typeclass=typeclass, key=key,
location=location, **kwargs)
new_obj = create_object(typeclass=typeclass, key=key, location=location, **kwargs)
return new_obj
@ -74,9 +79,11 @@ def create_fantasy_word(length=5, capitalize=True):
if not length:
return ""
phonemes = ("ea oh ae aa eh ah ao aw ai er ey ow ia ih iy oy ua "
"uh uw a e i u y p b t d f v t dh "
"s z sh zh ch jh k ng g m n l r w").split()
phonemes = (
"ea oh ae aa eh ah ao aw ai er ey ow ia ih iy oy ua "
"uh uw a e i u y p b t d f v t dh "
"s z sh zh ch jh k ng g m n l r w"
).split()
word = [choice(phonemes)]
while len(word) < length:
word.append(choice(phonemes))
@ -113,6 +120,7 @@ def parse_for_perspectives(string, you=None):
"~You ~open"
-> "You open", "Bob opens"
"""
def _replace_third_person(match):
match = match.group(1)
lmatch = match.lower()
@ -122,7 +130,7 @@ def parse_for_perspectives(string, you=None):
if match[0].isupper():
return irregulars[lmatch].capitalize()
return irregulars[lmatch]
elif lmatch[-1] == 's':
elif lmatch[-1] == "s":
return match + "es"
else:
return match + "s" # simple, most normal form
@ -181,7 +189,7 @@ def msg_cinematic(text, borders=True):
"""
text = text.strip()
text = justify(text, align='c', indent=1)
text = justify(text, align="c", indent=1)
if borders:
text = add_msg_borders(text)
return text