Make PEP8 cleanup of line spaces and character distances as well as indents
This commit is contained in:
parent
7ff783fea1
commit
b278337172
189 changed files with 2039 additions and 1583 deletions
|
|
@ -47,6 +47,7 @@ manually later.
|
|||
|
||||
# Helper functions
|
||||
|
||||
|
||||
def _green(string):
|
||||
if USE_COLOR:
|
||||
return "%s%s%s" % (ANSI_GREEN, string, ANSI_NORMAL)
|
||||
|
|
@ -98,12 +99,12 @@ def _case_sensitive_replace(string, old, new):
|
|||
all_upper = False
|
||||
# special cases - keep remaing case)
|
||||
if new_word.lower() in CASE_WORD_EXCEPTIONS:
|
||||
result.append(new_word[ind+1:])
|
||||
result.append(new_word[ind + 1:])
|
||||
# append any remaining characters from new
|
||||
elif all_upper:
|
||||
result.append(new_word[ind+1:].upper())
|
||||
result.append(new_word[ind + 1:].upper())
|
||||
else:
|
||||
result.append(new_word[ind+1:].lower())
|
||||
result.append(new_word[ind + 1:].lower())
|
||||
out.append("".join(result))
|
||||
# if we have more new words than old ones, just add them verbatim
|
||||
out.extend([new_word for ind, new_word in enumerate(new_words) if ind >= len(old_words)])
|
||||
|
|
@ -278,7 +279,7 @@ def rename_in_file(path, in_list, out_list, is_interactive):
|
|||
raw_input(_HELP_TEXT.format(sources=in_list, targets=out_list))
|
||||
elif ret.startswith("i"):
|
||||
# ignore one or more lines
|
||||
ignores = [int(ind)-1 for ind in ret[1:].split(',') if ind.strip().isdigit()]
|
||||
ignores = [int(ind) - 1 for ind in ret[1:].split(',') if ind.strip().isdigit()]
|
||||
if not ignores:
|
||||
raw_input("Ignore example: i 2,7,34,133\n (return to continue)")
|
||||
continue
|
||||
|
|
@ -287,12 +288,11 @@ def rename_in_file(path, in_list, out_list, is_interactive):
|
|||
continue
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Rename text in a source tree, or a single file")
|
||||
description="Rename text in a source tree, or a single file")
|
||||
|
||||
parser.add_argument('-i', '--input', action='append',
|
||||
help="Source word to rename (quote around multiple words)")
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ the python bin directory and makes the 'evennia' program available on
|
|||
the command %path%.
|
||||
"""
|
||||
|
||||
import os, sys
|
||||
import os
|
||||
import sys
|
||||
|
||||
# for pip install -e
|
||||
sys.path.insert(0, os.path.abspath(os.getcwd()))
|
||||
# main library path
|
||||
sys.path.insert(0, os.path.join(sys.prefix, "Lib", "site-packages"))
|
||||
|
||||
from evennia.server.evennia_launcher import main
|
||||
from evennia.server.evennia_launcher import main
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -109,9 +109,11 @@ def _create_version():
|
|||
pass
|
||||
return version
|
||||
|
||||
|
||||
__version__ = _create_version()
|
||||
del _create_version
|
||||
|
||||
|
||||
def _init():
|
||||
"""
|
||||
This function is called automatically by the launcher only after
|
||||
|
|
@ -124,7 +126,7 @@ def _init():
|
|||
global Command, CmdSet, default_cmds, syscmdkeys, InterruptCommand
|
||||
global search_object, search_script, search_account, search_channel, search_help, search_tag
|
||||
global create_object, create_script, create_account, create_channel, create_message, create_help_entry
|
||||
global settings,lockfuncs, logger, utils, gametime, ansi, spawn, managers
|
||||
global settings, lockfuncs, logger, utils, gametime, ansi, spawn, managers
|
||||
global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, CHANNEL_HANDLER, TASK_HANDLER
|
||||
|
||||
from .accounts.accounts import DefaultAccount
|
||||
|
|
@ -191,6 +193,7 @@ def _init():
|
|||
Parent for other containers
|
||||
|
||||
"""
|
||||
|
||||
def _help(self):
|
||||
"Returns list of contents"
|
||||
names = [name for name in self.__class__.__dict__ if not name.startswith('_')]
|
||||
|
|
@ -198,7 +201,6 @@ def _init():
|
|||
print(self.__doc__ + "-" * 60 + "\n" + ", ".join(names))
|
||||
help = property(_help)
|
||||
|
||||
|
||||
class DBmanagers(_EvContainer):
|
||||
"""
|
||||
Links to instantiated database managers.
|
||||
|
|
@ -241,7 +243,6 @@ def _init():
|
|||
managers = DBmanagers()
|
||||
del DBmanagers
|
||||
|
||||
|
||||
class DefaultCmds(_EvContainer):
|
||||
"""
|
||||
This container holds direct shortcuts to all default commands in Evennia.
|
||||
|
|
@ -266,8 +267,8 @@ def _init():
|
|||
self.__dict__.update(dict([(c.__name__, c) for c in cmdlist]))
|
||||
|
||||
from .commands.default import (admin, batchprocess,
|
||||
building, comms, general,
|
||||
account, help, system, unloggedin)
|
||||
building, comms, general,
|
||||
account, help, system, unloggedin)
|
||||
add_cmds(admin)
|
||||
add_cmds(building)
|
||||
add_cmds(batchprocess)
|
||||
|
|
@ -282,7 +283,6 @@ def _init():
|
|||
default_cmds = DefaultCmds()
|
||||
del DefaultCmds
|
||||
|
||||
|
||||
class SystemCmds(_EvContainer):
|
||||
"""
|
||||
Creating commands with keys set to these constants will make
|
||||
|
|
@ -313,6 +313,7 @@ def _init():
|
|||
del SystemCmds
|
||||
del _EvContainer
|
||||
|
||||
|
||||
del object
|
||||
del absolute_import
|
||||
del print_function
|
||||
|
|
|
|||
|
|
@ -528,7 +528,7 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)):
|
|||
|
||||
"""
|
||||
result = super(DefaultAccount, self).access(accessing_obj, access_type=access_type,
|
||||
default=default, no_superuser_bypass=no_superuser_bypass)
|
||||
default=default, no_superuser_bypass=no_superuser_bypass)
|
||||
self.at_access(result, accessing_obj, access_type, **kwargs)
|
||||
return result
|
||||
|
||||
|
|
@ -879,10 +879,10 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)):
|
|||
result.append(nsess == 1 and "\n\n|wConnected session:|n" or "\n\n|wConnected sessions (%i):|n" % nsess)
|
||||
for isess, sess in enumerate(sessions):
|
||||
csessid = sess.sessid
|
||||
addr = "%s (%s)" % (sess.protocol_key, isinstance(sess.address, tuple)
|
||||
and str(sess.address[0]) or str(sess.address))
|
||||
result.append("\n %s %s" % (session.sessid == csessid and "|w* %s|n" % (isess + 1)
|
||||
or " %s" % (isess + 1), addr))
|
||||
addr = "%s (%s)" % (sess.protocol_key, isinstance(sess.address, tuple) and
|
||||
str(sess.address[0]) or str(sess.address))
|
||||
result.append("\n %s %s" % (session.sessid == csessid and "|w* %s|n" % (isess + 1) or
|
||||
" %s" % (isess + 1), addr))
|
||||
result.append("\n\n |whelp|n - more commands")
|
||||
result.append("\n |wooc <Text>|n - talk on public channel")
|
||||
|
||||
|
|
@ -928,6 +928,7 @@ class DefaultGuest(DefaultAccount):
|
|||
This class is used for guest logins. Unlike Accounts, Guests and
|
||||
their characters are deleted after disconnection.
|
||||
"""
|
||||
|
||||
def at_post_login(self, session=None, **kwargs):
|
||||
"""
|
||||
In theory, guests only have one character regardless of which
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ class AccountInline(admin.StackedInline):
|
|||
fieldsets = (
|
||||
("In-game Permissions and Locks",
|
||||
{'fields': ('db_lock_storage',),
|
||||
#{'fields': ('db_permissions', 'db_lock_storage'),
|
||||
#{'fields': ('db_permissions', 'db_lock_storage'),
|
||||
'description': "<i>These are permissions/locks for in-game use. "
|
||||
"They are unrelated to website access rights.</i>"}),
|
||||
("In-game Account data",
|
||||
|
|
@ -215,11 +215,11 @@ class AccountDBAdmin(BaseUserAdmin):
|
|||
'db_lock_storage'),
|
||||
'description': '<i>These are attributes that are more relevant '
|
||||
'to gameplay.</i>'}))
|
||||
# ('Game Options', {'fields': (
|
||||
# 'db_typeclass_path', 'db_cmdset_storage',
|
||||
# 'db_permissions', 'db_lock_storage'),
|
||||
# 'description': '<i>These are attributes that are '
|
||||
# 'more relevant to gameplay.</i>'}))
|
||||
# ('Game Options', {'fields': (
|
||||
# 'db_typeclass_path', 'db_cmdset_storage',
|
||||
# 'db_permissions', 'db_lock_storage'),
|
||||
# 'description': '<i>These are attributes that are '
|
||||
# 'more relevant to gameplay.</i>'}))
|
||||
|
||||
add_fieldsets = (
|
||||
(None,
|
||||
|
|
@ -240,7 +240,7 @@ class AccountDBAdmin(BaseUserAdmin):
|
|||
"""
|
||||
obj.save()
|
||||
if not change:
|
||||
#calling hooks for new account
|
||||
# calling hooks for new account
|
||||
obj.set_class_from_typeclass(typeclass_path=settings.BASE_ACCOUNT_TYPECLASS)
|
||||
obj.basetype_setup()
|
||||
obj.at_account_creation()
|
||||
|
|
@ -252,4 +252,5 @@ class AccountDBAdmin(BaseUserAdmin):
|
|||
return HttpResponseRedirect(reverse("admin:accounts_accountdb_change", args=[obj.id]))
|
||||
return HttpResponseRedirect(reverse("admin:accounts_accountdb_change", args=[obj.id]))
|
||||
|
||||
|
||||
admin.site.register(AccountDB, AccountDBAdmin)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class BotStarter(DefaultScript):
|
|||
into gear when it is initialized.
|
||||
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
Called once, when script is created.
|
||||
|
|
@ -148,6 +149,7 @@ class IRCBot(Bot):
|
|||
Bot for handling IRC connections.
|
||||
|
||||
"""
|
||||
|
||||
def start(self, ev_channel=None, irc_botname=None, irc_channel=None, irc_network=None, irc_port=None, irc_ssl=None):
|
||||
"""
|
||||
Start by telling the portal to start a new session.
|
||||
|
|
@ -359,6 +361,7 @@ class RSSBot(Bot):
|
|||
its feed at regular intervals.
|
||||
|
||||
"""
|
||||
|
||||
def start(self, ev_channel=None, rss_url=None, rss_rate=None):
|
||||
"""
|
||||
Start by telling the portal to start a new RSS session
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class AccountDBManager(TypedObjectManager, UserManager):
|
|||
#swap_character
|
||||
|
||||
"""
|
||||
|
||||
def num_total_accounts(self):
|
||||
"""
|
||||
Get total number of accounts.
|
||||
|
|
@ -91,7 +92,7 @@ class AccountDBManager(TypedObjectManager, UserManager):
|
|||
tdelta = datetime.timedelta(days)
|
||||
start_date = end_date - tdelta
|
||||
return self.filter(last_login__range=(
|
||||
start_date, end_date)).order_by('-last_login')
|
||||
start_date, end_date)).order_by('-last_login')
|
||||
|
||||
def get_account_from_email(self, uemail):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
def convert_defaults(apps, schema_editor):
|
||||
AccountDB = apps.get_model("accounts", "AccountDB")
|
||||
for account in AccountDB.objects.filter(db_typeclass_path="src.accounts.account.Account"):
|
||||
account.db_typeclass_path = "typeclasses.accounts.Account"
|
||||
account.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
|
|
@ -16,5 +18,5 @@ class Migration(migrations.Migration):
|
|||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(convert_defaults),
|
||||
migrations.RunPython(convert_defaults),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class AccountDB(TypedObject, AbstractUser):
|
|||
help_text="If player is connected to game or not")
|
||||
# database storage of persistant cmdsets.
|
||||
db_cmdset_storage = models.CharField('cmdset', max_length=255, null=True,
|
||||
help_text="optional python path to a cmdset class. If creating a Character, this will default to settings.CMDSET_CHARACTER.")
|
||||
help_text="optional python path to a cmdset class. If creating a Character, this will default to settings.CMDSET_CHARACTER.")
|
||||
# marks if this is a "virtual" bot account object
|
||||
db_is_bot = models.BooleanField(default=False, verbose_name="is_bot", help_text="Used to identify irc/rss bots")
|
||||
|
||||
|
|
|
|||
|
|
@ -88,41 +88,41 @@ _SEARCH_AT_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit
|
|||
# is the normal "production message to echo to the account.
|
||||
|
||||
_ERROR_UNTRAPPED = (
|
||||
"""
|
||||
"""
|
||||
An untrapped error occurred.
|
||||
""",
|
||||
"""
|
||||
"""
|
||||
An untrapped error occurred. Please file a bug report detailing the steps to reproduce.
|
||||
""")
|
||||
|
||||
_ERROR_CMDSETS = (
|
||||
"""
|
||||
"""
|
||||
A cmdset merger-error occurred. This is often due to a syntax
|
||||
error in one of the cmdsets to merge.
|
||||
""",
|
||||
"""
|
||||
"""
|
||||
A cmdset merger-error occurred. Please file a bug report detailing the
|
||||
steps to reproduce.
|
||||
""")
|
||||
|
||||
_ERROR_NOCMDSETS = (
|
||||
"""
|
||||
"""
|
||||
No command sets found! This is a critical bug that can have
|
||||
multiple causes.
|
||||
""",
|
||||
"""
|
||||
"""
|
||||
No command sets found! This is a sign of a critical bug. If
|
||||
disconnecting/reconnecting doesn't" solve the problem, try to contact
|
||||
the server admin through" some other means for assistance.
|
||||
""")
|
||||
|
||||
_ERROR_CMDHANDLER = (
|
||||
"""
|
||||
"""
|
||||
A command handler bug occurred. If this is not due to a local change,
|
||||
please file a bug report with the Evennia project, including the
|
||||
traceback and steps to reproduce.
|
||||
""",
|
||||
"""
|
||||
"""
|
||||
A command handler bug occurred. Please notify staff - they should
|
||||
likely file a bug report with the Evennia project.
|
||||
""")
|
||||
|
|
@ -234,19 +234,23 @@ class NoCmdSets(Exception):
|
|||
|
||||
class ExecSystemCommand(Exception):
|
||||
"Run a system command"
|
||||
|
||||
def __init__(self, syscmd, sysarg):
|
||||
self.args = (syscmd, sysarg) # needed by exception error handling
|
||||
self.syscmd = syscmd
|
||||
self.sysarg = sysarg
|
||||
|
||||
|
||||
class ErrorReported(Exception):
|
||||
"Re-raised when a subsructure already reported the error"
|
||||
|
||||
def __init__(self, raw_string):
|
||||
self.args = (raw_string,)
|
||||
self.raw_string = raw_string
|
||||
|
||||
# Helper function
|
||||
|
||||
|
||||
@inlineCallbacks
|
||||
def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string):
|
||||
"""
|
||||
|
|
@ -318,11 +322,11 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
|||
# the no_superuser_bypass must be True)
|
||||
local_obj_cmdsets = \
|
||||
yield list(chain.from_iterable(
|
||||
lobj.cmdset.cmdset_stack for lobj in local_objlist
|
||||
if (lobj.cmdset.current and
|
||||
lobj.cmdset.cmdset_stack for lobj in local_objlist
|
||||
if (lobj.cmdset.current and
|
||||
lobj.access(caller, access_type='call', no_superuser_bypass=True))))
|
||||
for cset in local_obj_cmdsets:
|
||||
#This is necessary for object sets, or we won't be able to
|
||||
# This is necessary for object sets, or we won't be able to
|
||||
# separate the command sets from each other in a busy room. We
|
||||
# only keep the setting if duplicates were set to False/True
|
||||
# explicitly.
|
||||
|
|
@ -333,7 +337,6 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
|||
_msg_err(caller, _ERROR_CMDSETS)
|
||||
raise ErrorReported(raw_string)
|
||||
|
||||
|
||||
@inlineCallbacks
|
||||
def _get_cmdsets(obj):
|
||||
"""
|
||||
|
|
@ -346,7 +349,7 @@ def get_and_merge_cmdsets(caller, session, account, obj, callertype, raw_string)
|
|||
_msg_err(caller, _ERROR_CMDSETS)
|
||||
raise ErrorReported(raw_string)
|
||||
try:
|
||||
returnValue((obj.cmdset.current, list(obj.cmdset.cmdset_stack)))
|
||||
returnValue((obj.cmdset.current, list(obj.cmdset.cmdset_stack)))
|
||||
except AttributeError:
|
||||
returnValue(((None, None, None), []))
|
||||
|
||||
|
|
@ -550,9 +553,9 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
cmd.session = session
|
||||
cmd.account = account
|
||||
cmd.raw_string = unformatted_raw_string
|
||||
#cmd.obj # set via on-object cmdset handler for each command,
|
||||
# since this may be different for every command when
|
||||
# merging multuple cmdsets
|
||||
# cmd.obj # set via on-object cmdset handler for each command,
|
||||
# since this may be different for every command when
|
||||
# merging multuple cmdsets
|
||||
|
||||
if hasattr(cmd, 'obj') and hasattr(cmd.obj, 'scripts'):
|
||||
# cmd.obj is automatically made available by the cmdhandler.
|
||||
|
|
@ -615,7 +618,6 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
finally:
|
||||
_COMMAND_NESTING[called_by] -= 1
|
||||
|
||||
|
||||
raw_string = to_unicode(raw_string, force_string=True)
|
||||
|
||||
session, account, obj = session, None, None
|
||||
|
|
@ -653,7 +655,7 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
else:
|
||||
# no explicit cmdobject given, figure it out
|
||||
cmdset = yield get_and_merge_cmdsets(caller, session, account, obj,
|
||||
callertype, raw_string)
|
||||
callertype, raw_string)
|
||||
if not cmdset:
|
||||
# this is bad and shouldn't happen.
|
||||
raise NoCmdSets
|
||||
|
|
@ -701,8 +703,8 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
|
|||
# fallback to default error text
|
||||
sysarg = _("Command '%s' is not available.") % raw_string
|
||||
suggestions = string_suggestions(raw_string,
|
||||
cmdset.get_all_cmd_keys_and_aliases(caller),
|
||||
cutoff=0.7, maxnum=3)
|
||||
cmdset.get_all_cmd_keys_and_aliases(caller),
|
||||
cutoff=0.7, maxnum=3)
|
||||
if suggestions:
|
||||
sysarg += _(" Maybe you meant %s?") % utils.list_to_string(suggestions, _('or'), addquote=True)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from evennia.utils.logger import log_trace
|
|||
_MULTIMATCH_REGEX = re.compile(settings.SEARCH_MULTIMATCH_REGEX, re.I + re.U)
|
||||
_CMD_IGNORE_PREFIXES = settings.CMD_IGNORE_PREFIXES
|
||||
|
||||
|
||||
def cmdparser(raw_string, cmdset, caller, match_index=None):
|
||||
"""
|
||||
This function is called by the cmdhandler once it has
|
||||
|
|
@ -82,10 +83,10 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
|||
# use the cmdname as-is
|
||||
for cmd in cmdset:
|
||||
matches.extend([create_match(cmdname, raw_string, cmd, cmdname)
|
||||
for cmdname in [cmd.key] + cmd.aliases
|
||||
if cmdname and l_raw_string.startswith(cmdname.lower())
|
||||
and (not cmd.arg_regex or
|
||||
cmd.arg_regex.match(l_raw_string[len(cmdname):]))])
|
||||
for cmdname in [cmd.key] + cmd.aliases
|
||||
if cmdname and l_raw_string.startswith(cmdname.lower()) and
|
||||
(not cmd.arg_regex or
|
||||
cmd.arg_regex.match(l_raw_string[len(cmdname):]))])
|
||||
else:
|
||||
# strip prefixes set in settings
|
||||
for cmd in cmdset:
|
||||
|
|
@ -133,7 +134,7 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
|||
# See if it helps to analyze the match with preserved case but only if
|
||||
# it leaves at least one match.
|
||||
trimmed = [match for match in matches
|
||||
if raw_string.startswith(match[0])]
|
||||
if raw_string.startswith(match[0])]
|
||||
if trimmed:
|
||||
matches = trimmed
|
||||
|
||||
|
|
@ -151,10 +152,10 @@ def cmdparser(raw_string, cmdset, caller, match_index=None):
|
|||
quality = [mat[4] for mat in matches]
|
||||
matches = matches[-quality.count(quality[-1]):]
|
||||
|
||||
if len(matches) > 1 and match_index != None and 0 < match_index <= len(matches):
|
||||
if len(matches) > 1 and match_index is not None and 0 < match_index <= len(matches):
|
||||
# We couldn't separate match by quality, but we have an
|
||||
# index argument to tell us which match to use.
|
||||
matches = [matches[match_index-1]]
|
||||
matches = [matches[match_index - 1]]
|
||||
|
||||
# no matter what we have at this point, we have to return it.
|
||||
return matches
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class _CmdSetMeta(type):
|
|||
cls.key = cls.__name__
|
||||
cls.path = "%s.%s" % (cls.__module__, cls.__name__)
|
||||
|
||||
if not type(cls.key_mergetypes) == dict:
|
||||
if not isinstance(cls.key_mergetypes, dict):
|
||||
cls.key_mergetypes = {}
|
||||
|
||||
super(_CmdSetMeta, cls).__init__(*args, **kwargs)
|
||||
|
|
@ -188,7 +188,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
|
||||
# initialize system
|
||||
self.at_cmdset_creation()
|
||||
self._contains_cache = WeakKeyDictionary()#{}
|
||||
self._contains_cache = WeakKeyDictionary() # {}
|
||||
|
||||
# Priority-sensitive merge operations for cmdsets
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
cmdset_c.commands.extend(cmdset_b.commands)
|
||||
else:
|
||||
cmdset_c.commands.extend([cmd for cmd in cmdset_b
|
||||
if not cmd in cmdset_a])
|
||||
if cmd not in cmdset_a])
|
||||
return cmdset_c
|
||||
|
||||
def _intersect(self, cmdset_a, cmdset_b):
|
||||
|
|
@ -280,7 +280,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
"""
|
||||
|
||||
cmdset_c = cmdset_a._duplicate()
|
||||
cmdset_c.commands = [cmd for cmd in cmdset_b if not cmd in cmdset_a]
|
||||
cmdset_c.commands = [cmd for cmd in cmdset_b if cmd not in cmdset_a]
|
||||
return cmdset_c
|
||||
|
||||
def _instantiate(self, cmd):
|
||||
|
|
@ -411,7 +411,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
cmdset_c = self._replace(self, cmdset_a)
|
||||
elif mergetype == "Remove":
|
||||
cmdset_c = self._remove(self, cmdset_a)
|
||||
else: # Union
|
||||
else: # Union
|
||||
cmdset_c = self._union(self, cmdset_a)
|
||||
|
||||
# pass through options whenever they are set, unless the higher-prio
|
||||
|
|
@ -426,7 +426,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
# This is used for diagnosis.
|
||||
cmdset_c.actual_mergetype = mergetype
|
||||
|
||||
#print "__add__ for %s (prio %i) called with %s (prio %i)." % (self.key, self.priority, cmdset_a.key, cmdset_a.priority)
|
||||
# print "__add__ for %s (prio %i) called with %s (prio %i)." % (self.key, self.priority, cmdset_a.key, cmdset_a.priority)
|
||||
|
||||
# return the system commands to the cmdset
|
||||
cmdset_c.add(sys_commands)
|
||||
|
|
@ -604,7 +604,7 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)):
|
|||
names = []
|
||||
if caller:
|
||||
[names.extend(cmd._keyaliases) for cmd in self.commands
|
||||
if cmd.access(caller)]
|
||||
if cmd.access(caller)]
|
||||
else:
|
||||
[names.extend(cmd._keyaliases) for cmd in self.commands]
|
||||
return names
|
||||
|
|
|
|||
|
|
@ -86,32 +86,32 @@ _CMDSET_FALLBACKS = settings.CMDSET_FALLBACKS
|
|||
# Output strings
|
||||
|
||||
_ERROR_CMDSET_IMPORT = _(
|
||||
"""{traceback}
|
||||
"""{traceback}
|
||||
Error loading cmdset '{path}'
|
||||
(Traceback was logged {timestamp})""")
|
||||
|
||||
_ERROR_CMDSET_KEYERROR = _(
|
||||
"""Error loading cmdset: No cmdset class '{classname}' in '{path}'.
|
||||
"""Error loading cmdset: No cmdset class '{classname}' in '{path}'.
|
||||
(Traceback was logged {timestamp})""")
|
||||
|
||||
_ERROR_CMDSET_SYNTAXERROR = _(
|
||||
"""{traceback}
|
||||
"""{traceback}
|
||||
SyntaxError encountered when loading cmdset '{path}'.
|
||||
(Traceback was logged {timestamp})""")
|
||||
|
||||
_ERROR_CMDSET_EXCEPTION = _(
|
||||
"""{traceback}
|
||||
"""{traceback}
|
||||
Compile/Run error when loading cmdset '{path}'.",
|
||||
(Traceback was logged {timestamp})""")
|
||||
|
||||
_ERROR_CMDSET_FALLBACK = _(
|
||||
"""
|
||||
"""
|
||||
Error encountered for cmdset at path '{path}'.
|
||||
Replacing with fallback '{fallback_path}'.
|
||||
""")
|
||||
|
||||
_ERROR_CMDSET_NO_FALLBACK = _(
|
||||
"""Fallback path '{fallback_path}' failed to generate a cmdset."""
|
||||
"""Fallback path '{fallback_path}' failed to generate a cmdset."""
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -122,6 +122,7 @@ class _ErrorCmdSet(CmdSet):
|
|||
key = "_CMDSET_ERROR"
|
||||
errmessage = "Error when loading cmdset."
|
||||
|
||||
|
||||
class _EmptyCmdSet(CmdSet):
|
||||
"""
|
||||
This cmdset represents an empty cmdset
|
||||
|
|
@ -130,6 +131,7 @@ class _EmptyCmdSet(CmdSet):
|
|||
priority = -101
|
||||
mergetype = "Union"
|
||||
|
||||
|
||||
def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
||||
"""
|
||||
This helper function is used by the cmdsethandler to load a cmdset
|
||||
|
|
@ -154,11 +156,11 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
|||
|
||||
"""
|
||||
python_paths = [path] + ["%s.%s" % (prefix, path)
|
||||
for prefix in _CMDSET_PATHS if not path.startswith(prefix)]
|
||||
for prefix in _CMDSET_PATHS if not path.startswith(prefix)]
|
||||
errstring = ""
|
||||
for python_path in python_paths:
|
||||
|
||||
if "." in path:
|
||||
if "." in path:
|
||||
modpath, classname = python_path.rsplit(".", 1)
|
||||
else:
|
||||
raise ImportError("The path '%s' is not on the form modulepath.ClassName" % path)
|
||||
|
|
@ -191,7 +193,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
|||
continue
|
||||
_CACHED_CMDSETS[python_path] = cmdsetclass
|
||||
|
||||
#instantiate the cmdset (and catch its errors)
|
||||
# instantiate the cmdset (and catch its errors)
|
||||
if callable(cmdsetclass):
|
||||
cmdsetclass = cmdsetclass(cmdsetobj)
|
||||
return cmdsetclass
|
||||
|
|
@ -235,7 +237,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
|
|||
err_cmdset = _ErrorCmdSet()
|
||||
err_cmdset.errmessage = errstring
|
||||
return err_cmdset
|
||||
return None # undefined error
|
||||
return None # undefined error
|
||||
|
||||
# classes
|
||||
|
||||
|
|
@ -278,7 +280,7 @@ class CmdSetHandler(object):
|
|||
self.permanent_paths = [""]
|
||||
|
||||
if init_true:
|
||||
self.update(init_mode=True) #is then called from the object __init__.
|
||||
self.update(init_mode=True) # is then called from the object __init__.
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
|
|
@ -311,8 +313,8 @@ class CmdSetHandler(object):
|
|||
if mergelist:
|
||||
tmpstring = _(" <Merged {mergelist} {mergetype}, prio {prio}>: {current}")
|
||||
string += tmpstring.format(mergelist="+".join(mergelist),
|
||||
mergetype=mergetype, prio=self.current.priority,
|
||||
current=self.current)
|
||||
mergetype=mergetype, prio=self.current.priority,
|
||||
current=self.current)
|
||||
else:
|
||||
permstring = "non-perm"
|
||||
if self.current.permanent:
|
||||
|
|
@ -322,7 +324,7 @@ class CmdSetHandler(object):
|
|||
prio=self.current.priority,
|
||||
permstring=permstring,
|
||||
keylist=", ".join(cmd.key for
|
||||
cmd in sorted(self.current, key=lambda o: o.key)))
|
||||
cmd in sorted(self.current, key=lambda o: o.key)))
|
||||
return string.strip()
|
||||
|
||||
def _import_cmdset(self, cmdset_path, emit_to_obj=None):
|
||||
|
|
@ -542,7 +544,6 @@ class CmdSetHandler(object):
|
|||
# legacy alias
|
||||
delete_default = remove_default
|
||||
|
||||
|
||||
def all(self):
|
||||
"""
|
||||
Show all cmdsets.
|
||||
|
|
@ -588,16 +589,16 @@ class CmdSetHandler(object):
|
|||
else:
|
||||
print [cset.path for cset in self.cmdset_stack], cmdset.path
|
||||
return any([cset for cset in self.cmdset_stack
|
||||
if cset.path == cmdset.path])
|
||||
if cset.path == cmdset.path])
|
||||
else:
|
||||
# try it as a path or key
|
||||
if must_be_default:
|
||||
return self.cmdset_stack and (
|
||||
self.cmdset_stack[0].key == cmdset or
|
||||
self.cmdset_stack[0].path == cmdset)
|
||||
self.cmdset_stack[0].key == cmdset or
|
||||
self.cmdset_stack[0].path == cmdset)
|
||||
else:
|
||||
return any([cset for cset in self.cmdset_stack
|
||||
if cset.path == cmdset or cset.key == cmdset])
|
||||
if cset.path == cmdset or cset.key == cmdset])
|
||||
|
||||
# backwards-compatability alias
|
||||
has_cmdset = has
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ def _init_command(cls, **kwargs):
|
|||
if "cmd:" not in cls.locks:
|
||||
cls.locks = "cmd:all();" + cls.locks
|
||||
for lockstring in cls.locks.split(';'):
|
||||
if lockstring and not ':' in lockstring:
|
||||
if lockstring and ':' not in lockstring:
|
||||
lockstring = "cmd:%s" % lockstring
|
||||
temp.append(lockstring)
|
||||
cls.lock_storage = ";".join(temp)
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ class CmdSessions(COMMAND_DEFAULT_CLASS):
|
|||
for sess in sorted(sessions, key=lambda x: x.sessid):
|
||||
char = account.get_puppet(sess)
|
||||
table.add_row(str(sess.sessid), str(sess.protocol_key),
|
||||
type(sess.address) == tuple and sess.address[0] or sess.address,
|
||||
isinstance(sess.address, tuple) and sess.address[0] or sess.address,
|
||||
char and str(char) or "None",
|
||||
char and str(char.location) or "N/A")
|
||||
self.msg("|wYour current session(s):|n\n%s" % table)
|
||||
|
|
@ -508,7 +508,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
options["SCREENHEIGHT"] = options["SCREENHEIGHT"][0]
|
||||
else:
|
||||
options["SCREENHEIGHT"] = " \n".join("%s : %s" % (screenid, size)
|
||||
for screenid, size in options["SCREENHEIGHT"].iteritems())
|
||||
for screenid, size in options["SCREENHEIGHT"].iteritems())
|
||||
options.pop("TTYPE", None)
|
||||
|
||||
header = ("Name", "Value", "Saved") if saved_options else ("Name", "Value")
|
||||
|
|
@ -552,7 +552,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
flags[new_name] = new_val
|
||||
self.msg("Option |w%s|n was changed from '|w%s|n' to '|w%s|n'." % (new_name, old_val, new_val))
|
||||
return {new_name: new_val}
|
||||
except Exception, err:
|
||||
except Exception as err:
|
||||
self.msg("|rCould not set option |w%s|r:|n %s" % (new_name, err))
|
||||
return False
|
||||
|
||||
|
|
@ -578,7 +578,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
val = self.rhs.strip()
|
||||
optiondict = False
|
||||
if val and name in validators:
|
||||
optiondict = update(name, val, validators[name])
|
||||
optiondict = update(name, val, validators[name])
|
||||
else:
|
||||
self.msg("|rNo option named '|w%s|r'." % name)
|
||||
if optiondict:
|
||||
|
|
@ -664,7 +664,7 @@ class CmdQuit(COMMAND_DEFAULT_CLASS):
|
|||
if nsess == 2:
|
||||
account.msg("|RQuitting|n. One session is still connected.", session=self.session)
|
||||
elif nsess > 2:
|
||||
account.msg("|RQuitting|n. %i sessions are still connected." % (nsess-1), session=self.session)
|
||||
account.msg("|RQuitting|n. %i sessions are still connected." % (nsess - 1), session=self.session)
|
||||
else:
|
||||
# we are quitting the last available session
|
||||
account.msg("|RQuitting|n. Hope to see you again, soon.", session=self.session)
|
||||
|
|
@ -732,7 +732,7 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
for code, _ in ap.ansi_map[self.slice_dark_bg]]
|
||||
bright_bg = ["%s%s|n" % (code.replace("\\", ""), code.replace("|", "||").replace("\\", ""))
|
||||
for code, _ in ap.ansi_xterm256_bright_bg_map[self.slice_bright_bg]]
|
||||
dark_fg.extend(["" for _ in range(len(bright_fg)-len(dark_fg))])
|
||||
dark_fg.extend(["" for _ in range(len(bright_fg) - len(dark_fg))])
|
||||
table = utils.format_table([bright_fg, dark_fg, bright_bg, dark_bg])
|
||||
string = "ANSI colors:"
|
||||
for row in table:
|
||||
|
|
@ -751,16 +751,16 @@ class CmdColorTest(COMMAND_DEFAULT_CLASS):
|
|||
# foreground table
|
||||
table[ir].append("|%i%i%i%s|n" % (ir, ig, ib, "||%i%i%i" % (ir, ig, ib)))
|
||||
# background table
|
||||
table[6+ir].append("|%i%i%i|[%i%i%i%s|n"
|
||||
% (5 - ir, 5 - ig, 5 - ib, ir, ig, ib, "||[%i%i%i" % (ir, ig, ib)))
|
||||
table[6 + ir].append("|%i%i%i|[%i%i%i%s|n"
|
||||
% (5 - ir, 5 - ig, 5 - ib, ir, ig, ib, "||[%i%i%i" % (ir, ig, ib)))
|
||||
table = self.table_format(table)
|
||||
string = "Xterm256 colors (if not all hues show, your client might not report that it can handle xterm256):"
|
||||
string += "\n" + "\n".join("".join(row) for row in table)
|
||||
table = [[], [], [], [], [], [], [], [], [], [], [], []]
|
||||
for ibatch in range(4):
|
||||
for igray in range(6):
|
||||
letter = chr(97 + (ibatch*6 + igray))
|
||||
inverse = chr(122 - (ibatch*6 + igray))
|
||||
letter = chr(97 + (ibatch * 6 + igray))
|
||||
inverse = chr(122 - (ibatch * 6 + igray))
|
||||
table[0 + igray].append("|=%s%s |n" % (letter, "||=%s" % letter))
|
||||
table[6 + igray].append("|=%s|[=%s%s |n" % (inverse, letter, "||[=%s" % letter))
|
||||
for igray in range(6):
|
||||
|
|
|
|||
|
|
@ -171,9 +171,9 @@ class CmdBan(COMMAND_DEFAULT_CLASS):
|
|||
if not banlist:
|
||||
banlist = []
|
||||
|
||||
if not self.args or (self.switches
|
||||
and not any(switch in ('ip', 'name')
|
||||
for switch in self.switches)):
|
||||
if not self.args or (self.switches and
|
||||
not any(switch in ('ip', 'name')
|
||||
for switch in self.switches)):
|
||||
self.caller.msg(list_bans(banlist))
|
||||
return
|
||||
|
||||
|
|
@ -430,7 +430,7 @@ class CmdNewPassword(COMMAND_DEFAULT_CLASS):
|
|||
self.msg("%s - new password set to '%s'." % (account.name, self.rhs))
|
||||
if account.character != caller:
|
||||
account.msg("%s has changed your password to '%s'." % (caller.name,
|
||||
self.rhs))
|
||||
self.rhs))
|
||||
|
||||
|
||||
class CmdPerm(COMMAND_DEFAULT_CLASS):
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ _DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH
|
|||
|
||||
_PROTOTYPE_PARENTS = None
|
||||
|
||||
|
||||
class ObjManipCommand(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
This is a parent class for some of the defining objmanip commands
|
||||
|
|
@ -73,7 +74,7 @@ class ObjManipCommand(COMMAND_DEFAULT_CLASS):
|
|||
super(ObjManipCommand, self).parse()
|
||||
|
||||
obj_defs = ([], []) # stores left- and right-hand side of '='
|
||||
obj_attrs = ([], []) # "
|
||||
obj_attrs = ([], []) # "
|
||||
|
||||
for iside, arglist in enumerate((self.lhslist, self.rhslist)):
|
||||
# lhslist/rhslist is already split by ',' at this point
|
||||
|
|
@ -88,8 +89,8 @@ class ObjManipCommand(COMMAND_DEFAULT_CLASS):
|
|||
objdef, attrs = [part.strip() for part in objdef.split('/', 1)]
|
||||
attrs = [part.strip().lower() for part in attrs.split('/') if part.strip()]
|
||||
# store data
|
||||
obj_defs[iside].append({"name":objdef, 'option':option, 'aliases':aliases})
|
||||
obj_attrs[iside].append({"name":objdef, 'attrs':attrs})
|
||||
obj_defs[iside].append({"name": objdef, 'option': option, 'aliases': aliases})
|
||||
obj_attrs[iside].append({"name": objdef, 'attrs': attrs})
|
||||
|
||||
# store for future access
|
||||
self.lhs_objs = obj_defs[0]
|
||||
|
|
@ -242,9 +243,9 @@ class CmdCopy(ObjManipCommand):
|
|||
return
|
||||
|
||||
copiedobj = ObjectDB.objects.copy_object(from_obj,
|
||||
new_key=to_obj_name,
|
||||
new_location=to_obj_location,
|
||||
new_aliases=to_obj_aliases)
|
||||
new_key=to_obj_name,
|
||||
new_location=to_obj_location,
|
||||
new_aliases=to_obj_aliases)
|
||||
if copiedobj:
|
||||
string = "Copied %s to '%s' (aliases: %s)." % (from_obj_name, to_obj_name,
|
||||
to_obj_aliases)
|
||||
|
|
@ -350,7 +351,7 @@ class CmdCpAttr(ObjManipCommand):
|
|||
if not from_obj or not to_objs:
|
||||
caller.msg("You have to supply both source object and target(s).")
|
||||
return
|
||||
#copy to all to_obj:ects
|
||||
# copy to all to_obj:ects
|
||||
if "move" in self.switches:
|
||||
clear = True
|
||||
else:
|
||||
|
|
@ -387,7 +388,7 @@ class CmdCpAttr(ObjManipCommand):
|
|||
value = self.get_attr(from_obj, from_attr)
|
||||
to_obj.attributes.add(to_attr, value)
|
||||
if (clear and not (from_obj == to_obj and
|
||||
from_attr == to_attr)):
|
||||
from_attr == to_attr)):
|
||||
from_obj.attributes.remove(from_attr)
|
||||
result.append("\nMoved %s.%s -> %s.%s. (value: %s)" % (from_obj.name,
|
||||
from_attr,
|
||||
|
|
@ -522,6 +523,7 @@ class CmdCreate(ObjManipCommand):
|
|||
def _desc_load(caller):
|
||||
return caller.db.evmenu_target.db.desc or ""
|
||||
|
||||
|
||||
def _desc_save(caller, buf):
|
||||
"""
|
||||
Save line buffer to the desc prop. This should
|
||||
|
|
@ -531,10 +533,12 @@ def _desc_save(caller, buf):
|
|||
caller.msg("Saved.")
|
||||
return True
|
||||
|
||||
|
||||
def _desc_quit(caller):
|
||||
caller.attributes.remove("evmenu_target")
|
||||
caller.msg("Exited editor.")
|
||||
|
||||
|
||||
class CmdDesc(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
describe an object or the current room.
|
||||
|
|
@ -642,12 +646,12 @@ class CmdDestroy(COMMAND_DEFAULT_CLASS):
|
|||
objname = obj.name
|
||||
if not (obj.access(caller, "control") or obj.access(caller, 'delete')):
|
||||
return "\nYou don't have permission to delete %s." % objname
|
||||
if obj.account and not 'override' in self.switches:
|
||||
if obj.account and 'override' not in self.switches:
|
||||
return "\nObject %s is controlled by an active account. Use /override to delete anyway." % objname
|
||||
if obj.dbid == int(settings.DEFAULT_HOME.lstrip("#")):
|
||||
return "\nYou are trying to delete |c%s|n, which is set as DEFAULT_HOME. " \
|
||||
"Re-point settings.DEFAULT_HOME to another " \
|
||||
"object before continuing." % objname
|
||||
"Re-point settings.DEFAULT_HOME to another " \
|
||||
"object before continuing." % objname
|
||||
|
||||
had_exits = hasattr(obj, "exits") and obj.exits
|
||||
had_objs = hasattr(obj, "contents") and any(obj for obj in obj.contents
|
||||
|
|
@ -749,7 +753,7 @@ class CmdDig(ObjManipCommand):
|
|||
if new_room.aliases.all():
|
||||
alias_string = " (%s)" % ", ".join(new_room.aliases.all())
|
||||
room_string = "Created room %s(%s)%s of type %s." % (new_room,
|
||||
new_room.dbref, alias_string, typeclass)
|
||||
new_room.dbref, alias_string, typeclass)
|
||||
|
||||
# create exit to room
|
||||
|
||||
|
|
@ -763,7 +767,7 @@ class CmdDig(ObjManipCommand):
|
|||
"\nNo exit created to new room."
|
||||
elif not location:
|
||||
exit_to_string = \
|
||||
"\nYou cannot create an exit from a None-location."
|
||||
"\nYou cannot create an exit from a None-location."
|
||||
else:
|
||||
# Build the exit to the new room from the current one
|
||||
typeclass = to_exit["option"]
|
||||
|
|
@ -796,18 +800,18 @@ class CmdDig(ObjManipCommand):
|
|||
"\nNo back exit created."
|
||||
elif not location:
|
||||
exit_back_string = \
|
||||
"\nYou cannot create an exit back to a None-location."
|
||||
"\nYou cannot create an exit back to a None-location."
|
||||
else:
|
||||
typeclass = back_exit["option"]
|
||||
if not typeclass:
|
||||
typeclass = settings.BASE_EXIT_TYPECLASS
|
||||
new_back_exit = create.create_object(typeclass,
|
||||
back_exit["name"],
|
||||
new_room,
|
||||
aliases=back_exit["aliases"],
|
||||
locks=lockstring,
|
||||
destination=location,
|
||||
report_to=caller)
|
||||
back_exit["name"],
|
||||
new_room,
|
||||
aliases=back_exit["aliases"],
|
||||
locks=lockstring,
|
||||
destination=location,
|
||||
report_to=caller)
|
||||
alias_string = ""
|
||||
if new_back_exit.aliases.all():
|
||||
alias_string = " (%s)" % ", ".join(new_back_exit.aliases.all())
|
||||
|
|
@ -821,6 +825,7 @@ class CmdDig(ObjManipCommand):
|
|||
if new_room and ('teleport' in self.switches or "tel" in self.switches):
|
||||
caller.move_to(new_room)
|
||||
|
||||
|
||||
class CmdTunnel(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
create new rooms in cardinal directions only
|
||||
|
|
@ -893,7 +898,7 @@ class CmdTunnel(COMMAND_DEFAULT_CLASS):
|
|||
if "tel" in self.switches:
|
||||
telswitch = "/teleport"
|
||||
backstring = ""
|
||||
if not "oneway" in self.switches:
|
||||
if "oneway" not in self.switches:
|
||||
backstring = ", %s;%s" % (backname, backshort)
|
||||
|
||||
# build the string we will use to call @dig
|
||||
|
|
@ -951,7 +956,7 @@ class CmdLink(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
string = ""
|
||||
if not obj.destination:
|
||||
string += "Note: %s(%s) did not have a destination set before. Make sure you linked the right thing." % (obj.name,obj.dbref)
|
||||
string += "Note: %s(%s) did not have a destination set before. Make sure you linked the right thing." % (obj.name, obj.dbref)
|
||||
if "twoway" in self.switches:
|
||||
if not (target.location and obj.location):
|
||||
string = "To create a two-way link, %s and %s must both have a location" % (obj, target)
|
||||
|
|
@ -1199,7 +1204,7 @@ class CmdOpen(ObjManipCommand):
|
|||
|
||||
# a custom member method to chug out exits and do checks
|
||||
def create_exit(self, exit_name, location, destination,
|
||||
exit_aliases=None, typeclass=None):
|
||||
exit_aliases=None, typeclass=None):
|
||||
"""
|
||||
Helper function to avoid code duplication.
|
||||
At this point we know destination is a valid location
|
||||
|
|
@ -1484,10 +1489,11 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
old_value = obj.attributes.get(attr)
|
||||
if old_value is not None and not isinstance(old_value, basestring):
|
||||
typ = type(old_value).__name__
|
||||
self.caller.msg("|RWARNING! Saving this buffer will overwrite the "\
|
||||
self.caller.msg("|RWARNING! Saving this buffer will overwrite the "
|
||||
"current attribute (of type %s) with a string!|n" % typ)
|
||||
return str(old_value)
|
||||
return old_value
|
||||
|
||||
def save(caller, buf):
|
||||
"Called when editor saves its buffer."
|
||||
obj.attributes.add(attr, buf)
|
||||
|
|
@ -1495,7 +1501,6 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
# start the editor
|
||||
EvEditor(self.caller, load, save, key="%s/%s" % (obj, attr))
|
||||
|
||||
|
||||
def func(self):
|
||||
"Implement the set attribute - a limited form of @py."
|
||||
|
||||
|
|
@ -1523,7 +1528,7 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
if "edit" in self.switches:
|
||||
# edit in the line editor
|
||||
if len(attrs) > 1:
|
||||
caller.msg("The Line editor can only be applied " \
|
||||
caller.msg("The Line editor can only be applied "
|
||||
"to one attribute at a time.")
|
||||
return
|
||||
self.edit_handler(obj, attrs[0])
|
||||
|
|
@ -1538,7 +1543,7 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
continue
|
||||
result.append(self.view_attr(obj, attr))
|
||||
# we view it without parsing markup.
|
||||
self.caller.msg("".join(result).strip(), options={"raw":True})
|
||||
self.caller.msg("".join(result).strip(), options={"raw": True})
|
||||
return
|
||||
else:
|
||||
# deleting the attribute(s)
|
||||
|
|
@ -1644,7 +1649,7 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
is_same = obj.is_typeclass(new_typeclass, exact=True)
|
||||
if is_same and not 'force' in self.switches:
|
||||
if is_same and 'force' not in self.switches:
|
||||
string = "%s already has the typeclass '%s'. Use /force to override." % (obj.name, new_typeclass)
|
||||
else:
|
||||
update = "update" in self.switches
|
||||
|
|
@ -1654,14 +1659,14 @@ class CmdTypeclass(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# we let this raise exception if needed
|
||||
obj.swap_typeclass(new_typeclass, clean_attributes=reset,
|
||||
clean_cmdsets=reset, run_start_hooks=hooks)
|
||||
clean_cmdsets=reset, run_start_hooks=hooks)
|
||||
|
||||
if is_same:
|
||||
string = "%s updated its existing typeclass (%s).\n" % (obj.name, obj.path)
|
||||
else:
|
||||
string = "%s changed typeclass from %s to %s.\n" % (obj.name,
|
||||
old_typeclass_path,
|
||||
obj.typeclass_path)
|
||||
old_typeclass_path,
|
||||
obj.typeclass_path)
|
||||
if update:
|
||||
string += "Only the at_object_creation hook was run (update mode)."
|
||||
else:
|
||||
|
|
@ -1797,8 +1802,8 @@ class CmdLock(ObjManipCommand):
|
|||
# we have a = separator, so we are assigning a new lock
|
||||
if self.switches:
|
||||
swi = ", ".join(self.switches)
|
||||
caller.msg("Switch(es) |w%s|n can not be used with a "\
|
||||
"lock assignment. Use e.g. " \
|
||||
caller.msg("Switch(es) |w%s|n can not be used with a "
|
||||
"lock assignment. Use e.g. "
|
||||
"|w@lock/del objname/locktype|n instead." % swi)
|
||||
return
|
||||
|
||||
|
|
@ -1851,7 +1856,7 @@ class CmdExamine(ObjManipCommand):
|
|||
|
||||
"""
|
||||
key = "@examine"
|
||||
aliases = ["@ex","exam"]
|
||||
aliases = ["@ex", "exam"]
|
||||
locks = "cmd:perm(examine) or perm(Builder)"
|
||||
help_category = "Building"
|
||||
arg_regex = r"(/\w+?(\s|$))|\s|$"
|
||||
|
|
@ -1913,7 +1918,7 @@ class CmdExamine(ObjManipCommand):
|
|||
string += "\n|wAliases|n: %s" % (", ".join(utils.make_iter(str(obj.aliases))))
|
||||
if hasattr(obj, "sessions") and obj.sessions.all():
|
||||
string += "\n|wSession id(s)|n: %s" % (", ".join("#%i" % sess.sessid
|
||||
for sess in obj.sessions.all()))
|
||||
for sess in obj.sessions.all()))
|
||||
if hasattr(obj, "email") and obj.email:
|
||||
string += "\n|wEmail|n: |c%s|n" % obj.email
|
||||
if hasattr(obj, "has_account") and obj.has_account:
|
||||
|
|
@ -1957,20 +1962,19 @@ class CmdExamine(ObjManipCommand):
|
|||
locks_string = " Default"
|
||||
string += "\n|wLocks|n:%s" % locks_string
|
||||
|
||||
|
||||
if not (len(obj.cmdset.all()) == 1 and obj.cmdset.current.key == "_EMPTY_CMDSET"):
|
||||
# all() returns a 'stack', so make a copy to sort.
|
||||
stored_cmdsets = sorted(obj.cmdset.all(), key=lambda x: x.priority, reverse=True)
|
||||
string += "\n|wStored Cmdset(s)|n:\n %s" % ("\n ".join("%s [%s] (%s, prio %s)" % \
|
||||
(cmdset.path, cmdset.key, cmdset.mergetype, cmdset.priority)
|
||||
for cmdset in stored_cmdsets if cmdset.key != "_EMPTY_CMDSET"))
|
||||
string += "\n|wStored Cmdset(s)|n:\n %s" % ("\n ".join("%s [%s] (%s, prio %s)" %
|
||||
(cmdset.path, cmdset.key, cmdset.mergetype, cmdset.priority)
|
||||
for cmdset in stored_cmdsets if cmdset.key != "_EMPTY_CMDSET"))
|
||||
|
||||
# this gets all components of the currently merged set
|
||||
all_cmdsets = [(cmdset.key, cmdset) for cmdset in avail_cmdset.merged_from]
|
||||
# we always at least try to add account- and session sets since these are ignored
|
||||
# if we merge on the object level.
|
||||
if hasattr(obj, "account") and obj.account:
|
||||
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.account.cmdset.all()])
|
||||
all_cmdsets.extend([(cmdset.key, cmdset) for cmdset in obj.account.cmdset.all()])
|
||||
if obj.sessions.count():
|
||||
# if there are more sessions than one on objects it's because of multisession mode 3.
|
||||
# we only show the first session's cmdset here (it is -in principle- possible that
|
||||
|
|
@ -1986,14 +1990,13 @@ class CmdExamine(ObjManipCommand):
|
|||
pass
|
||||
all_cmdsets = [cmdset for cmdset in dict(all_cmdsets).values()]
|
||||
all_cmdsets.sort(key=lambda x: x.priority, reverse=True)
|
||||
string += "\n|wMerged Cmdset(s)|n:\n %s" % ("\n ".join("%s [%s] (%s, prio %s)" % \
|
||||
(cmdset.path, cmdset.key, cmdset.mergetype, cmdset.priority)
|
||||
for cmdset in all_cmdsets))
|
||||
|
||||
string += "\n|wMerged Cmdset(s)|n:\n %s" % ("\n ".join("%s [%s] (%s, prio %s)" %
|
||||
(cmdset.path, cmdset.key, cmdset.mergetype, cmdset.priority)
|
||||
for cmdset in all_cmdsets))
|
||||
|
||||
# list the commands available to this object
|
||||
avail_cmdset = sorted([cmd.key for cmd in avail_cmdset
|
||||
if cmd.access(obj, "cmd")])
|
||||
if cmd.access(obj, "cmd")])
|
||||
|
||||
cmdsetstr = utils.fill(", ".join(avail_cmdset), indent=2)
|
||||
string += "\n|wCommands available to %s (result of Merged CmdSets)|n:\n %s" % (obj.key, cmdsetstr)
|
||||
|
|
@ -2005,7 +2008,7 @@ class CmdExamine(ObjManipCommand):
|
|||
|
||||
# display Tags
|
||||
tags_string = utils.fill(", ".join("%s[%s]" % (tag, category)
|
||||
for tag, category in obj.tags.all(return_key_and_category=True)), indent=5)
|
||||
for tag, category in obj.tags.all(return_key_and_category=True)), indent=5)
|
||||
if tags_string:
|
||||
string += "\n|wTags[category]|n: %s" % tags_string.strip()
|
||||
|
||||
|
|
@ -2029,7 +2032,7 @@ class CmdExamine(ObjManipCommand):
|
|||
string += "\n|wContents|n: %s" % ", ".join(["%s(%s)" % (cont.name, cont.dbref) for cont in obj.contents
|
||||
if cont not in exits and cont not in pobjs])
|
||||
separator = "-" * _DEFAULT_WIDTH
|
||||
#output info
|
||||
# output info
|
||||
return '%s\n%s\n%s' % (separator, string.strip(), separator)
|
||||
|
||||
def func(self):
|
||||
|
|
@ -2053,7 +2056,7 @@ class CmdExamine(ObjManipCommand):
|
|||
if hasattr(caller, "location"):
|
||||
obj = caller.location
|
||||
if not obj.access(caller, 'examine'):
|
||||
#If we don't have special info access, just look at the object instead.
|
||||
# If we don't have special info access, just look at the object instead.
|
||||
self.msg(caller.at_look(obj))
|
||||
return
|
||||
# using callback for printing result whenever function returns.
|
||||
|
|
@ -2070,20 +2073,20 @@ class CmdExamine(ObjManipCommand):
|
|||
obj_attrs = objdef['attrs']
|
||||
|
||||
self.account_mode = utils.inherits_from(caller, "evennia.accounts.accounts.DefaultAccount") or \
|
||||
"account" in self.switches or obj_name.startswith('*')
|
||||
"account" in self.switches or obj_name.startswith('*')
|
||||
if self.account_mode:
|
||||
try:
|
||||
obj = caller.search_account(obj_name.lstrip('*'))
|
||||
except AttributeError:
|
||||
# this means we are calling examine from an account object
|
||||
obj = caller.search(obj_name.lstrip('*'), search_object = 'object' in self.switches)
|
||||
obj = caller.search(obj_name.lstrip('*'), search_object='object' in self.switches)
|
||||
else:
|
||||
obj = caller.search(obj_name)
|
||||
if not obj:
|
||||
continue
|
||||
|
||||
if not obj.access(caller, 'examine'):
|
||||
#If we don't have special info access, just look
|
||||
# If we don't have special info access, just look
|
||||
# at the object instead.
|
||||
self.msg(caller.at_look(obj))
|
||||
continue
|
||||
|
|
@ -2184,7 +2187,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
elif not low <= int(result[0].id) <= high:
|
||||
string += "\n |RNo match found for '%s' in #dbref interval.|n" % (searchstring)
|
||||
else:
|
||||
result=result[0]
|
||||
result = result[0]
|
||||
string += "\n|g %s - %s|n" % (result.get_display_name(caller), result.path)
|
||||
else:
|
||||
# Not an account/dbref search but a wider search; build a queryset.
|
||||
|
|
@ -2192,7 +2195,7 @@ class CmdFind(COMMAND_DEFAULT_CLASS):
|
|||
if "exact" in switches:
|
||||
keyquery = Q(db_key__iexact=searchstring, id__gte=low, id__lte=high)
|
||||
aliasquery = Q(db_tags__db_key__iexact=searchstring,
|
||||
db_tags__db_tagtype__iexact="alias",id__gte=low, id__lte=high)
|
||||
db_tags__db_tagtype__iexact="alias", id__gte=low, id__lte=high)
|
||||
else:
|
||||
keyquery = Q(db_key__istartswith=searchstring, id__gte=low, id__lte=high)
|
||||
aliasquery = Q(db_tags__db_key__istartswith=searchstring,
|
||||
|
|
@ -2283,14 +2286,14 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
|||
if obj_to_teleport.has_account:
|
||||
caller.msg("Cannot teleport a puppeted object "
|
||||
"(%s, puppeted by %s) to a None-location." % (
|
||||
obj_to_teleport.key, obj_to_teleport.account))
|
||||
obj_to_teleport.key, obj_to_teleport.account))
|
||||
return
|
||||
caller.msg("Teleported %s -> None-location." % obj_to_teleport)
|
||||
if obj_to_teleport.location and not tel_quietly:
|
||||
obj_to_teleport.location.msg_contents("%s teleported %s into nothingness."
|
||||
% (caller, obj_to_teleport),
|
||||
exclude=caller)
|
||||
obj_to_teleport.location=None
|
||||
obj_to_teleport.location = None
|
||||
return
|
||||
|
||||
# not teleporting to None location
|
||||
|
|
@ -2397,7 +2400,7 @@ class CmdScript(COMMAND_DEFAULT_CLASS):
|
|||
obj.get_display_name(caller)))
|
||||
script.stop()
|
||||
obj.scripts.validate()
|
||||
else: # rhs exists
|
||||
else: # rhs exists
|
||||
if not self.switches:
|
||||
# adding a new script, and starting it
|
||||
ok = obj.scripts.add(self.rhs, autostart=True)
|
||||
|
|
@ -2478,16 +2481,16 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
|
|||
nobjs = len(objs)
|
||||
if nobjs > 0:
|
||||
catstr = " (category: '|w%s|n')" % category if category else \
|
||||
("" if nobjs == 1 else " (may have different tag categories)")
|
||||
("" if nobjs == 1 else " (may have different tag categories)")
|
||||
matchstr = ", ".join(o.get_display_name(self.caller) for o in objs)
|
||||
|
||||
string = "Found |w%i|n object%s with tag '|w%s|n'%s:\n %s" % (nobjs,
|
||||
"s" if nobjs > 1 else "",
|
||||
tag,
|
||||
catstr, matchstr)
|
||||
"s" if nobjs > 1 else "",
|
||||
tag,
|
||||
catstr, matchstr)
|
||||
else:
|
||||
string = "No objects found with tag '%s%s'." % (tag,
|
||||
" (category: %s)" % category if category else "")
|
||||
" (category: %s)" % category if category else "")
|
||||
self.caller.msg(string)
|
||||
return
|
||||
if "del" in self.switches:
|
||||
|
|
@ -2504,14 +2507,14 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
|
|||
if obj.tags.get(tag, category=category):
|
||||
obj.tags.remove(tag, category=category)
|
||||
string = "Removed tag '%s'%s from %s." % (
|
||||
tag,
|
||||
" (category: %s)" % category if category else "",
|
||||
obj)
|
||||
tag,
|
||||
" (category: %s)" % category if category else "",
|
||||
obj)
|
||||
else:
|
||||
string = "No tag '%s'%s to delete on %s." % (
|
||||
tag,
|
||||
" (category: %s)" % category if category else "",
|
||||
obj)
|
||||
tag,
|
||||
" (category: %s)" % category if category else "",
|
||||
obj)
|
||||
else:
|
||||
# no tag specified, clear all tags
|
||||
old_tags = ["%s%s" % (tag, " (category: %s" % category if category else "")
|
||||
|
|
@ -2550,7 +2553,7 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
|
|||
categories = [" (category: %s)" % tup[1] if tup[1] else "" for tup in tagtuples]
|
||||
if ntags:
|
||||
string = "Tag%s on %s: %s" % ("s" if ntags > 1 else "", obj,
|
||||
", ".join("'%s'%s" % (tags[i], categories[i]) for i in range(ntags)))
|
||||
", ".join("'%s'%s" % (tags[i], categories[i]) for i in range(ntags)))
|
||||
else:
|
||||
string = "No tags attached to %s." % obj
|
||||
self.caller.msg(string)
|
||||
|
|
@ -2561,6 +2564,7 @@ class CmdTag(COMMAND_DEFAULT_CLASS):
|
|||
# Reload the server and the prototypes should be available.
|
||||
#
|
||||
|
||||
|
||||
class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
spawn objects from prototype
|
||||
|
|
@ -2608,7 +2612,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
|||
"Helper to show a list of available prototypes"
|
||||
prots = ", ".join(sorted(prototypes.keys()))
|
||||
return "\nAvailable prototypes (case sensistive): %s" % \
|
||||
("\n" + utils.fill(prots) if prots else "None")
|
||||
("\n" + utils.fill(prots) if prots else "None")
|
||||
|
||||
prototypes = spawn(return_prototypes=True)
|
||||
if not self.args:
|
||||
|
|
@ -2628,7 +2632,6 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
|||
self.caller.msg(string)
|
||||
return
|
||||
|
||||
|
||||
if isinstance(prototype, basestring):
|
||||
# A prototype key
|
||||
keystr = prototype
|
||||
|
|
@ -2647,9 +2650,8 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
|
|||
self.caller.msg("The prototype must be a prototype key or a Python dictionary.")
|
||||
return
|
||||
|
||||
if not "noloc" in self.switches and not "location" in prototype:
|
||||
if "noloc" in self.switches and not "location" not in prototype:
|
||||
prototype["location"] = self.caller.location
|
||||
|
||||
for obj in spawn(prototype):
|
||||
self.caller.msg("Spawned %s." % obj.get_display_name(self.caller))
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class AccountCmdSet(CmdSet):
|
|||
self.add(account.CmdOOC())
|
||||
self.add(account.CmdCharCreate())
|
||||
self.add(account.CmdCharDelete())
|
||||
#self.add(account.CmdSessions())
|
||||
# self.add(account.CmdSessions())
|
||||
self.add(account.CmdWho())
|
||||
self.add(account.CmdOption())
|
||||
self.add(account.CmdQuit())
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from evennia.commands.default import general, help, admin, system
|
|||
from evennia.commands.default import building
|
||||
from evennia.commands.default import batchprocess
|
||||
|
||||
|
||||
class CharacterCmdSet(CmdSet):
|
||||
"""
|
||||
Implements the default command set.
|
||||
|
|
@ -46,7 +47,7 @@ class CharacterCmdSet(CmdSet):
|
|||
self.add(system.CmdAbout())
|
||||
self.add(system.CmdTime())
|
||||
self.add(system.CmdServerLoad())
|
||||
#self.add(system.CmdPs())
|
||||
# self.add(system.CmdPs())
|
||||
self.add(system.CmdTickers())
|
||||
|
||||
# Admin commands
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ This module stores session-level commands.
|
|||
from evennia.commands.cmdset import CmdSet
|
||||
from evennia.commands.default import account
|
||||
|
||||
|
||||
class SessionCmdSet(CmdSet):
|
||||
"""
|
||||
Sets up the unlogged cmdset.
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
|||
clower = chan.key.lower()
|
||||
nicks = caller.nicks.get(category="channel", return_obj=True)
|
||||
comtable.add_row(*["%s%s" % (chan.key, chan.aliases.all() and
|
||||
"(%s)" % ",".join(chan.aliases.all()) or ""),
|
||||
"(%s)" % ",".join(chan.aliases.all()) or ""),
|
||||
"%s" % ",".join(nick.db_key for nick in make_iter(nicks)
|
||||
if nick and nick.value[3].lower() == clower),
|
||||
chan.db.desc])
|
||||
|
|
@ -614,7 +614,7 @@ class CmdClock(COMMAND_DEFAULT_CLASS):
|
|||
# Try to add the lock
|
||||
try:
|
||||
channel.locks.add(self.rhs)
|
||||
except LockException, err:
|
||||
except LockException as err:
|
||||
self.msg(err)
|
||||
return
|
||||
string = "Lock(s) applied. "
|
||||
|
|
@ -890,7 +890,7 @@ class CmdIRC2Chan(COMMAND_DEFAULT_CLASS):
|
|||
self.rhs = self.rhs.replace('#', ' ') # to avoid Python comment issues
|
||||
try:
|
||||
irc_network, irc_port, irc_channel, irc_botname = \
|
||||
[part.strip() for part in self.rhs.split(None, 4)]
|
||||
[part.strip() for part in self.rhs.split(None, 4)]
|
||||
irc_channel = "#%s" % irc_channel
|
||||
except Exception:
|
||||
string = "IRC bot definition '%s' is not valid." % self.rhs
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
# we are given a index in nicklist
|
||||
delindex = int(arg)
|
||||
if 0 < delindex <= len(nicklist):
|
||||
oldnick = nicklist[delindex-1]
|
||||
oldnick = nicklist[delindex - 1]
|
||||
_, _, old_nickstring, old_replstring = oldnick.value
|
||||
else:
|
||||
errstring += "Not a valid nick index."
|
||||
|
|
@ -419,6 +419,7 @@ class CmdSay(COMMAND_DEFAULT_CLASS):
|
|||
# Call the at_after_say hook on the character
|
||||
caller.at_say(speech)
|
||||
|
||||
|
||||
class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
Speak privately as your character to another
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class MuxCommand(Command):
|
|||
used by Evennia to create the automatic help entry for
|
||||
the command, so make sure to document consistently here.
|
||||
"""
|
||||
|
||||
def has_perm(self, srcobj):
|
||||
"""
|
||||
This is called by the cmdhandler to determine
|
||||
|
|
@ -191,6 +192,7 @@ class MuxAccountCommand(MuxCommand):
|
|||
creating a new property "character" that is set only if a
|
||||
character is actually attached to this Account and Session.
|
||||
"""
|
||||
|
||||
def parse(self):
|
||||
"""
|
||||
We run the parent parser as usual, then fix the result
|
||||
|
|
|
|||
|
|
@ -133,11 +133,11 @@ def _py_code(caller, buf):
|
|||
"""
|
||||
measure_time = caller.db._py_measure_time
|
||||
string = "Executing code%s ..." % (
|
||||
" (measure timing)" if measure_time else "")
|
||||
" (measure timing)" if measure_time else "")
|
||||
caller.msg(string)
|
||||
_run_code_snippet(caller, buf, mode="exec",
|
||||
measure_time=measure_time,
|
||||
show_input=False)
|
||||
measure_time=measure_time,
|
||||
show_input=False)
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ def _py_quit(caller):
|
|||
|
||||
|
||||
def _run_code_snippet(caller, pycode, mode="eval", measure_time=False,
|
||||
show_input=True):
|
||||
show_input=True):
|
||||
"""
|
||||
Run code and try to display information to the caller.
|
||||
|
||||
|
|
@ -166,18 +166,18 @@ def _run_code_snippet(caller, pycode, mode="eval", measure_time=False,
|
|||
# import useful variables
|
||||
import evennia
|
||||
available_vars = {
|
||||
'self': caller,
|
||||
'me': caller,
|
||||
'here': getattr(caller, "location", None),
|
||||
'evennia': evennia,
|
||||
'ev': evennia,
|
||||
'inherits_from': utils.inherits_from,
|
||||
'self': caller,
|
||||
'me': caller,
|
||||
'here': getattr(caller, "location", None),
|
||||
'evennia': evennia,
|
||||
'ev': evennia,
|
||||
'inherits_from': utils.inherits_from,
|
||||
}
|
||||
|
||||
if show_input:
|
||||
try:
|
||||
caller.msg(">>> %s" % pycode, session=session,
|
||||
options={"raw": True})
|
||||
options={"raw": True})
|
||||
except TypeError:
|
||||
caller.msg(">>> %s" % pycode, options={"raw": True})
|
||||
|
||||
|
|
@ -256,8 +256,8 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
|||
if "edit" in self.switches:
|
||||
caller.db._py_measure_time = "time" in self.switches
|
||||
EvEditor(self.caller, loadfunc=_py_load, savefunc=_py_code,
|
||||
quitfunc=_py_quit, key="Python exec: :w or :!", persistent=True,
|
||||
codefunc=_py_code)
|
||||
quitfunc=_py_quit, key="Python exec: :w or :!", persistent=True,
|
||||
codefunc=_py_code)
|
||||
return
|
||||
|
||||
if not pycode:
|
||||
|
|
@ -719,7 +719,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
now, _ = _IDMAPPER.cache_size()
|
||||
string = "The Idmapper cache freed |w{idmapper}|n database objects.\n" \
|
||||
"The Python garbage collector freed |w{gc}|n Python instances total."
|
||||
self.caller.msg(string.format(idmapper=(prev-now), gc=nflushed))
|
||||
self.caller.msg(string.format(idmapper=(prev - now), gc=nflushed))
|
||||
return
|
||||
|
||||
# display active processes
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class CommandTest(EvenniaTest):
|
|||
cmdobj.caller = caller
|
||||
cmdobj.cmdname = cmdstring if cmdstring else cmdobj.key
|
||||
cmdobj.raw_cmdname = cmdobj.cmdname
|
||||
cmdobj.cmdstring = cmdobj.cmdname # deprecated
|
||||
cmdobj.cmdstring = cmdobj.cmdname # deprecated
|
||||
cmdobj.args = args
|
||||
cmdobj.cmdset = cmdset
|
||||
cmdobj.session = SESSIONS.session_from_sessid(1)
|
||||
|
|
@ -79,17 +79,17 @@ class CommandTest(EvenniaTest):
|
|||
pass
|
||||
finally:
|
||||
# clean out evtable sugar. We only operate on text-type
|
||||
stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True))
|
||||
for name, args, kwargs in receiver.msg.mock_calls]
|
||||
stored_msg = [args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs, force_string=True))
|
||||
for name, args, kwargs in receiver.msg.mock_calls]
|
||||
# Get the first element of a tuple if msg received a tuple instead of a string
|
||||
stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
|
||||
if msg is not None:
|
||||
returned_msg = "||".join(_RE.sub("", mess) for mess in stored_msg)
|
||||
returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
|
||||
if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
|
||||
sep1 = "\n" + "="*30 + "Wanted message" + "="*34 + "\n"
|
||||
sep2 = "\n" + "="*30 + "Returned message" + "="*32 + "\n"
|
||||
sep3 = "\n" + "="*78
|
||||
sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
|
||||
sep2 = "\n" + "=" * 30 + "Returned message" + "=" * 32 + "\n"
|
||||
sep3 = "\n" + "=" * 78
|
||||
retval = sep1 + msg.strip() + sep2 + returned_msg + sep3
|
||||
raise AssertionError(retval)
|
||||
else:
|
||||
|
|
@ -271,7 +271,7 @@ class TestBuilding(CommandTest):
|
|||
|
||||
def test_typeclass(self):
|
||||
self.call(building.CmdTypeclass(), "Obj = evennia.objects.objects.DefaultExit",
|
||||
"Obj changed typeclass from evennia.objects.objects.DefaultObject to evennia.objects.objects.DefaultExit.")
|
||||
"Obj changed typeclass from evennia.objects.objects.DefaultObject to evennia.objects.objects.DefaultExit.")
|
||||
|
||||
def test_lock(self):
|
||||
self.call(building.CmdLock(), "Obj = test:perm(Developer)", "Added lock 'test:perm(Developer)' to Obj.")
|
||||
|
|
@ -294,10 +294,10 @@ class TestComms(CommandTest):
|
|||
|
||||
def test_toggle_com(self):
|
||||
self.call(comms.CmdAddCom(), "tc = testchan", "You are already connected to channel testchan. You can now", receiver=self.account)
|
||||
self.call(comms.CmdDelCom(), "tc", "Your alias 'tc' for channel testchan was cleared.", receiver=self.account)
|
||||
self.call(comms.CmdDelCom(), "tc", "Your alias 'tc' for channel testchan was cleared.", receiver=self.account)
|
||||
|
||||
def test_channels(self):
|
||||
self.call(comms.CmdChannels(), "" ,"Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
|
||||
self.call(comms.CmdChannels(), "", "Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
|
||||
|
||||
def test_all_com(self):
|
||||
self.call(comms.CmdAllCom(), "", "Available channels (use comlist,addcom and delcom to manage", receiver=self.account)
|
||||
|
|
@ -322,7 +322,7 @@ class TestComms(CommandTest):
|
|||
self.call(comms.CmdCBoot(), "", "Usage: @cboot[/quiet] <channel> = <account> [:reason]", receiver=self.account)
|
||||
|
||||
def test_cdestroy(self):
|
||||
self.call(comms.CmdCdestroy(), "testchan" ,"[testchan] TestAccount: testchan is being destroyed. Make sure to change your aliases.|Channel 'testchan' was destroyed.", receiver=self.account)
|
||||
self.call(comms.CmdCdestroy(), "testchan", "[testchan] TestAccount: testchan is being destroyed. Make sure to change your aliases.|Channel 'testchan' was destroyed.", receiver=self.account)
|
||||
|
||||
|
||||
class TestBatchProcess(CommandTest):
|
||||
|
|
@ -332,6 +332,7 @@ class TestBatchProcess(CommandTest):
|
|||
# we make sure to delete the button again here to stop the running reactor
|
||||
self.call(building.CmdDestroy(), "button", "button was destroyed.")
|
||||
|
||||
|
||||
class CmdInterrupt(Command):
|
||||
|
||||
key = "interrupt"
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ def create_normal_account(session, name, password):
|
|||
account (Account): the account which was created from the name and password.
|
||||
"""
|
||||
# check for too many login errors too quick.
|
||||
if _throttle(session, maxlim=5, timeout=5*60):
|
||||
if _throttle(session, maxlim=5, timeout=5 * 60):
|
||||
# timeout is 5 minutes.
|
||||
session.msg("|RYou made too many connection attempts. Try again in a few minutes.|n")
|
||||
return None
|
||||
|
|
@ -168,8 +168,8 @@ def create_normal_account(session, name, password):
|
|||
|
||||
# Check IP and/or name bans
|
||||
bans = ServerConfig.objects.conf("server_bans")
|
||||
if bans and (any(tup[0] == account.name.lower() for tup in bans)
|
||||
or
|
||||
if bans and (any(tup[0] == account.name.lower() for tup in bans) or
|
||||
|
||||
any(tup[2].match(session.address) for tup in bans if tup[2])):
|
||||
# this is a banned IP or name!
|
||||
string = "|rYou have been banned and cannot continue from here." \
|
||||
|
|
@ -209,7 +209,7 @@ class CmdUnconnectedConnect(COMMAND_DEFAULT_CLASS):
|
|||
session = self.caller
|
||||
|
||||
# check for too many login errors too quick.
|
||||
if _throttle(session, maxlim=5, timeout=5*60, storage=_LATEST_FAILED_LOGINS):
|
||||
if _throttle(session, maxlim=5, timeout=5 * 60, storage=_LATEST_FAILED_LOGINS):
|
||||
# timeout is 5 minutes.
|
||||
session.msg("|RYou made too many connection attempts. Try again in a few minutes.|n")
|
||||
return
|
||||
|
|
@ -301,8 +301,8 @@ class CmdUnconnectedCreate(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# Check IP and/or name bans
|
||||
bans = ServerConfig.objects.conf("server_bans")
|
||||
if bans and (any(tup[0] == accountname.lower() for tup in bans)
|
||||
or
|
||||
if bans and (any(tup[0] == accountname.lower() for tup in bans) or
|
||||
|
||||
any(tup[2].match(session.address) for tup in bans if tup[2])):
|
||||
# this is a banned IP or name!
|
||||
string = "|rYou have been banned and cannot continue from here." \
|
||||
|
|
|
|||
|
|
@ -12,46 +12,67 @@ from evennia.commands.command import Command
|
|||
|
||||
class _CmdA(Command):
|
||||
key = "A"
|
||||
|
||||
def __init__(self, cmdset, *args, **kwargs):
|
||||
super(_CmdA, self).__init__(*args, **kwargs)
|
||||
self.from_cmdset = cmdset
|
||||
|
||||
|
||||
class _CmdB(Command):
|
||||
key = "B"
|
||||
|
||||
def __init__(self, cmdset, *args, **kwargs):
|
||||
super(_CmdB, self).__init__(*args, **kwargs)
|
||||
self.from_cmdset = cmdset
|
||||
|
||||
|
||||
class _CmdC(Command):
|
||||
key = "C"
|
||||
|
||||
def __init__(self, cmdset, *args, **kwargs):
|
||||
super(_CmdC, self).__init__(*args, **kwargs)
|
||||
self.from_cmdset = cmdset
|
||||
|
||||
|
||||
class _CmdD(Command):
|
||||
key = "D"
|
||||
|
||||
def __init__(self, cmdset, *args, **kwargs):
|
||||
super(_CmdD, self).__init__(*args, **kwargs)
|
||||
self.from_cmdset = cmdset
|
||||
|
||||
|
||||
class _CmdSetA(CmdSet):
|
||||
key = "A"
|
||||
def at_cmdset_creation(self):
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
self.add(_CmdA("A"))
|
||||
self.add(_CmdB("A"))
|
||||
self.add(_CmdC("A"))
|
||||
self.add(_CmdD("A"))
|
||||
|
||||
|
||||
class _CmdSetB(CmdSet):
|
||||
key = "B"
|
||||
def at_cmdset_creation(self):
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
self.add(_CmdA("B"))
|
||||
self.add(_CmdB("B"))
|
||||
self.add(_CmdC("B"))
|
||||
|
||||
|
||||
class _CmdSetC(CmdSet):
|
||||
key = "C"
|
||||
def at_cmdset_creation(self):
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
self.add(_CmdA("C"))
|
||||
self.add(_CmdB("C"))
|
||||
|
||||
|
||||
class _CmdSetD(CmdSet):
|
||||
key = "D"
|
||||
def at_cmdset_creation(self):
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
self.add(_CmdA("D"))
|
||||
self.add(_CmdB("D"))
|
||||
self.add(_CmdC("D"))
|
||||
|
|
@ -59,8 +80,10 @@ class _CmdSetD(CmdSet):
|
|||
|
||||
# testing Command Sets
|
||||
|
||||
|
||||
class TestCmdSetMergers(TestCase):
|
||||
"Test merging of cmdsets"
|
||||
|
||||
def setUp(self):
|
||||
super(TestCmdSetMergers, self).setUp()
|
||||
self.cmdset_a = _CmdSetA()
|
||||
|
|
@ -70,16 +93,16 @@ class TestCmdSetMergers(TestCase):
|
|||
|
||||
def test_union(self):
|
||||
a, c = self.cmdset_a, self.cmdset_c
|
||||
cmdset_f = a + c # same-prio
|
||||
cmdset_f = a + c # same-prio
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2)
|
||||
cmdset_f = c + a # same-prio, inverse order
|
||||
cmdset_f = c + a # same-prio, inverse order
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
||||
a.priority = 1
|
||||
cmdset_f = a + c # high prio A
|
||||
cmdset_f = a + c # high prio A
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
||||
|
|
@ -87,16 +110,16 @@ class TestCmdSetMergers(TestCase):
|
|||
def test_intersect(self):
|
||||
a, c = self.cmdset_a, self.cmdset_c
|
||||
a.mergetype = "Intersect"
|
||||
cmdset_f = a + c # same-prio - c's Union kicks in
|
||||
cmdset_f = a + c # same-prio - c's Union kicks in
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2)
|
||||
cmdset_f = c + a # same-prio - a's Intersect kicks in
|
||||
cmdset_f = c + a # same-prio - a's Intersect kicks in
|
||||
self.assertEqual(len(cmdset_f.commands), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
||||
a.priority = 1
|
||||
cmdset_f = a + c # high prio A, intersect kicks in
|
||||
cmdset_f = a + c # high prio A, intersect kicks in
|
||||
self.assertEqual(len(cmdset_f.commands), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
||||
|
|
@ -104,16 +127,16 @@ class TestCmdSetMergers(TestCase):
|
|||
def test_replace(self):
|
||||
a, c = self.cmdset_a, self.cmdset_c
|
||||
c.mergetype = "Replace"
|
||||
cmdset_f = a + c # same-prio. C's Replace kicks in
|
||||
cmdset_f = a + c # same-prio. C's Replace kicks in
|
||||
self.assertEqual(len(cmdset_f.commands), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 0)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2)
|
||||
cmdset_f = c + a # same-prio. A's Union kicks in
|
||||
cmdset_f = c + a # same-prio. A's Union kicks in
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
||||
c.priority = 1
|
||||
cmdset_f = c + a # c higher prio. C's Replace kicks in
|
||||
cmdset_f = c + a # c higher prio. C's Replace kicks in
|
||||
self.assertEqual(len(cmdset_f.commands), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 0)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2)
|
||||
|
|
@ -121,16 +144,16 @@ class TestCmdSetMergers(TestCase):
|
|||
def test_remove(self):
|
||||
a, c = self.cmdset_a, self.cmdset_c
|
||||
c.mergetype = "Remove"
|
||||
cmdset_f = a + c # same-prio. C's Remove kicks in
|
||||
cmdset_f = a + c # same-prio. C's Remove kicks in
|
||||
self.assertEqual(len(cmdset_f.commands), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
||||
cmdset_f = c + a # same-prio. A's Union kicks in
|
||||
cmdset_f = c + a # same-prio. A's Union kicks in
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
||||
c.priority = 1
|
||||
cmdset_f = c + a # c higher prio. C's Remove kicks in
|
||||
cmdset_f = c + a # c higher prio. C's Remove kicks in
|
||||
self.assertEqual(len(cmdset_f.commands), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2)
|
||||
self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0)
|
||||
|
|
@ -138,15 +161,15 @@ class TestCmdSetMergers(TestCase):
|
|||
def test_order(self):
|
||||
"Merge in reverse- and forward orders, same priorities"
|
||||
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
||||
cmdset_f = d + c + b + a # merge in reverse order of priority
|
||||
cmdset_f = d + c + b + a # merge in reverse order of priority
|
||||
self.assertEqual(cmdset_f.priority, 0)
|
||||
self.assertEqual(cmdset_f.mergetype, "Union")
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A"))
|
||||
cmdset_f = a + b + c + d # merge in order of priority
|
||||
cmdset_f = a + b + c + d # merge in order of priority
|
||||
self.assertEqual(cmdset_f.priority, 0)
|
||||
self.assertEqual(cmdset_f.mergetype, "Union")
|
||||
self.assertEqual(len(cmdset_f.commands), 4) # duplicates setting from A transfers
|
||||
self.assertEqual(len(cmdset_f.commands), 4) # duplicates setting from A transfers
|
||||
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "D"))
|
||||
|
||||
def test_priority_order(self):
|
||||
|
|
@ -156,12 +179,12 @@ class TestCmdSetMergers(TestCase):
|
|||
b.priority = 1
|
||||
c.priority = 0
|
||||
d.priority = -1
|
||||
cmdset_f = d + c + b + a # merge in reverse order of priority
|
||||
cmdset_f = d + c + b + a # merge in reverse order of priority
|
||||
self.assertEqual(cmdset_f.priority, 2)
|
||||
self.assertEqual(cmdset_f.mergetype, "Union")
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A"))
|
||||
cmdset_f = a + b + c + d # merge in order of priority
|
||||
cmdset_f = a + b + c + d # merge in order of priority
|
||||
self.assertEqual(cmdset_f.priority, 2)
|
||||
self.assertEqual(cmdset_f.mergetype, "Union")
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
|
|
@ -176,13 +199,13 @@ class TestCmdSetMergers(TestCase):
|
|||
a.no_objs = True
|
||||
a.no_channels = True
|
||||
a.duplicates = True
|
||||
cmdset_f = d + c + b + a # reverse, same-prio
|
||||
cmdset_f = d + c + b + a # reverse, same-prio
|
||||
self.assertTrue(cmdset_f.no_exits)
|
||||
self.assertTrue(cmdset_f.no_objs)
|
||||
self.assertTrue(cmdset_f.no_channels)
|
||||
self.assertTrue(cmdset_f.duplicates)
|
||||
self.assertEqual(len(cmdset_f.commands), 8)
|
||||
cmdset_f = a + b + c + d # forward, same-prio
|
||||
cmdset_f = a + b + c + d # forward, same-prio
|
||||
self.assertTrue(cmdset_f.no_exits)
|
||||
self.assertTrue(cmdset_f.no_objs)
|
||||
self.assertTrue(cmdset_f.no_channels)
|
||||
|
|
@ -192,13 +215,13 @@ class TestCmdSetMergers(TestCase):
|
|||
b.priority = 1
|
||||
c.priority = 0
|
||||
d.priority = -1
|
||||
cmdset_f = d + c + b + a # reverse, A top priority
|
||||
cmdset_f = d + c + b + a # reverse, A top priority
|
||||
self.assertTrue(cmdset_f.no_exits)
|
||||
self.assertTrue(cmdset_f.no_objs)
|
||||
self.assertTrue(cmdset_f.no_channels)
|
||||
self.assertTrue(cmdset_f.duplicates)
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
cmdset_f = a + b + c + d # forward, A top priority. This never happens in practice.
|
||||
cmdset_f = a + b + c + d # forward, A top priority. This never happens in practice.
|
||||
self.assertTrue(cmdset_f.no_exits)
|
||||
self.assertTrue(cmdset_f.no_objs)
|
||||
self.assertTrue(cmdset_f.no_channels)
|
||||
|
|
@ -208,13 +231,13 @@ class TestCmdSetMergers(TestCase):
|
|||
b.priority = 0
|
||||
c.priority = 1
|
||||
d.priority = 2
|
||||
cmdset_f = d + c + b + a # reverse, A low prio. This never happens in practice.
|
||||
cmdset_f = d + c + b + a # reverse, A low prio. This never happens in practice.
|
||||
self.assertTrue(cmdset_f.no_exits)
|
||||
self.assertTrue(cmdset_f.no_objs)
|
||||
self.assertTrue(cmdset_f.no_channels)
|
||||
self.assertFalse(cmdset_f.duplicates)
|
||||
self.assertEqual(len(cmdset_f.commands), 4)
|
||||
cmdset_f = a + b + c + d # forward, A low prio
|
||||
cmdset_f = a + b + c + d # forward, A low prio
|
||||
self.assertTrue(cmdset_f.no_exits)
|
||||
self.assertTrue(cmdset_f.no_objs)
|
||||
self.assertTrue(cmdset_f.no_channels)
|
||||
|
|
@ -224,7 +247,7 @@ class TestCmdSetMergers(TestCase):
|
|||
b.no_objs = False
|
||||
d.duplicates = False
|
||||
# higher-prio sets will change the option up the chain
|
||||
cmdset_f = a + b + c + d # forward, A low prio
|
||||
cmdset_f = a + b + c + d # forward, A low prio
|
||||
self.assertFalse(cmdset_f.no_exits)
|
||||
self.assertFalse(cmdset_f.no_objs)
|
||||
self.assertTrue(cmdset_f.no_channels)
|
||||
|
|
@ -235,15 +258,19 @@ class TestCmdSetMergers(TestCase):
|
|||
c.priority = 0
|
||||
d.priority = 0
|
||||
c.duplicates = True
|
||||
cmdset_f = d + b + c + a # two last mergers duplicates=True
|
||||
cmdset_f = d + b + c + a # two last mergers duplicates=True
|
||||
self.assertEqual(len(cmdset_f.commands), 10)
|
||||
|
||||
# test cmdhandler functions
|
||||
|
||||
|
||||
from evennia.commands import cmdhandler
|
||||
from twisted.trial.unittest import TestCase as TwistedTestCase
|
||||
|
||||
|
||||
class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
||||
"Test the cmdhandler.get_and_merge_cmdsets function."
|
||||
|
||||
def setUp(self):
|
||||
super(TestGetAndMergeCmdSets, self).setUp()
|
||||
self.cmdset_a = _CmdSetA()
|
||||
|
|
@ -261,6 +288,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
a.no_channels = True
|
||||
self.set_cmdsets(self.session, a)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, None, None, "session", "")
|
||||
|
||||
def _callback(cmdset):
|
||||
self.assertEqual(cmdset.key, "A")
|
||||
deferred.addCallback(_callback)
|
||||
|
|
@ -273,6 +301,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
self.set_cmdsets(self.account, a)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.account, None, self.account, None, "account", "")
|
||||
# get_and_merge_cmdsets converts to lower-case internally.
|
||||
|
||||
def _callback(cmdset):
|
||||
pcmdset = AccountCmdSet()
|
||||
pcmdset.at_cmdset_creation()
|
||||
|
|
@ -286,7 +315,8 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
self.set_cmdsets(self.obj1, self.cmdset_a)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
|
||||
# get_and_merge_cmdsets converts to lower-case internally.
|
||||
_callback = lambda cmdset: self.assertEqual(sum(1 for cmd in cmdset.commands if cmd.key in ("a", "b", "c", "d")), 4)
|
||||
|
||||
def _callback(cmdset): return self.assertEqual(sum(1 for cmd in cmdset.commands if cmd.key in ("a", "b", "c", "d")), 4)
|
||||
deferred.addCallback(_callback)
|
||||
return deferred
|
||||
|
||||
|
|
@ -296,6 +326,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
a.no_channels = True
|
||||
self.set_cmdsets(self.obj1, a, b, c, d)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
|
||||
|
||||
def _callback(cmdset):
|
||||
self.assertTrue(cmdset.no_exits)
|
||||
self.assertTrue(cmdset.no_channels)
|
||||
|
|
@ -315,6 +346,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
||||
self.set_cmdsets(self.account, a, b, c, d)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, self.account, self.char1, "session", "")
|
||||
|
||||
def _callback(cmdset):
|
||||
pcmdset = AccountCmdSet()
|
||||
pcmdset.at_cmdset_creation()
|
||||
|
|
@ -332,6 +364,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest):
|
|||
d.duplicates = True
|
||||
self.set_cmdsets(self.obj1, a, b, c, d)
|
||||
deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "")
|
||||
|
||||
def _callback(cmdset):
|
||||
self.assertEqual(len(cmdset.commands), 9)
|
||||
deferred.addCallback(_callback)
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class ChannelAdmin(admin.ModelAdmin):
|
|||
list_select_related = True
|
||||
fieldsets = (
|
||||
(None, {'fields': (('db_key',), 'db_lock_storage', 'db_subscriptions')}),
|
||||
)
|
||||
)
|
||||
|
||||
def subscriptions(self, obj):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ from django.utils.translation import ugettext as _
|
|||
_CHANNEL_COMMAND_CLASS = None
|
||||
_CHANNELDB = None
|
||||
|
||||
|
||||
class ChannelCommand(command.Command):
|
||||
"""
|
||||
{channelkey} channel
|
||||
|
|
@ -130,8 +131,9 @@ class ChannelCommand(command.Command):
|
|||
if self.history_start is not None:
|
||||
# Try to view history
|
||||
log_file = channel.attributes.get("log_file", default="channel_%s.log" % channel.key)
|
||||
send_msg = lambda lines: self.msg("".join(line.split("[-]", 1)[1]
|
||||
if "[-]" in line else line for line in lines))
|
||||
|
||||
def send_msg(lines): return self.msg("".join(line.split("[-]", 1)[1]
|
||||
if "[-]" in line else line for line in lines))
|
||||
tail_log_file(log_file, self.history_start, 20, callback=send_msg)
|
||||
else:
|
||||
caller = caller if not hasattr(caller, 'account') else caller.account
|
||||
|
|
@ -164,6 +166,7 @@ class ChannelHandler(object):
|
|||
evennia.create_channel())
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initializes the channel handler's internal state.
|
||||
|
|
@ -208,12 +211,12 @@ class ChannelHandler(object):
|
|||
|
||||
# map the channel to a searchable command
|
||||
cmd = _CHANNEL_COMMAND_CLASS(
|
||||
key=channel.key.strip().lower(),
|
||||
aliases=channel.aliases.all(),
|
||||
locks="cmd:all();%s" % channel.locks,
|
||||
help_category="Channel names",
|
||||
obj=channel,
|
||||
is_channel=True)
|
||||
key=channel.key.strip().lower(),
|
||||
aliases=channel.aliases.all(),
|
||||
locks="cmd:all();%s" % channel.locks,
|
||||
help_category="Channel names",
|
||||
obj=channel,
|
||||
is_channel=True)
|
||||
# format the help entry
|
||||
key = channel.key
|
||||
cmd.__doc__ = cmd.__doc__.format(channelkey=key,
|
||||
|
|
@ -221,7 +224,7 @@ class ChannelHandler(object):
|
|||
channeldesc=channel.attributes.get("desc", default="").strip())
|
||||
self.cached_channel_cmds[channel] = cmd
|
||||
self.cached_cmdsets = {}
|
||||
add_channel = add # legacy alias
|
||||
add_channel = add # legacy alias
|
||||
|
||||
def remove(self, channel):
|
||||
"""
|
||||
|
|
@ -269,8 +272,8 @@ class ChannelHandler(object):
|
|||
# create a new cmdset holding all viable channels
|
||||
chan_cmdset = None
|
||||
chan_cmds = [channelcmd for channel, channelcmd in self.cached_channel_cmds.iteritems()
|
||||
if channel.subscriptions.has(source_object) and
|
||||
channelcmd.access(source_object, 'send')]
|
||||
if channel.subscriptions.has(source_object) and
|
||||
channelcmd.access(source_object, 'send')]
|
||||
if chan_cmds:
|
||||
chan_cmdset = cmdset.CmdSet()
|
||||
chan_cmdset.key = 'ChannelCmdSet'
|
||||
|
|
@ -281,5 +284,6 @@ class ChannelHandler(object):
|
|||
self.cached_cmdsets[source_object] = chan_cmdset
|
||||
return chan_cmdset
|
||||
|
||||
|
||||
CHANNEL_HANDLER = ChannelHandler()
|
||||
CHANNELHANDLER = CHANNEL_HANDLER # legacy
|
||||
CHANNELHANDLER = CHANNEL_HANDLER # legacy
|
||||
|
|
|
|||
|
|
@ -357,7 +357,6 @@ class DefaultChannel(with_metaclass(TypeclassBase, ChannelDB)):
|
|||
# hooks
|
||||
|
||||
def channel_prefix(self, msg=None, emit=False, **kwargs):
|
||||
|
||||
"""
|
||||
Hook method. How the channel should prefix itself for users.
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ def identify_object(inp):
|
|||
if clsname == "AccountDB":
|
||||
return inp, "account"
|
||||
elif clsname == "ObjectDB":
|
||||
return inp ,"object"
|
||||
return inp, "object"
|
||||
elif clsname == "ChannelDB":
|
||||
return inp, "channel"
|
||||
if isinstance(inp, basestring):
|
||||
|
|
@ -202,10 +202,10 @@ class MsgManager(TypedObjectManager):
|
|||
# explicitly exclude channel recipients
|
||||
if typ == 'account':
|
||||
return list(self.filter(db_sender_accounts=obj,
|
||||
db_receivers_channels__isnull=True).exclude(db_hide_from_accounts=obj))
|
||||
db_receivers_channels__isnull=True).exclude(db_hide_from_accounts=obj))
|
||||
elif typ == 'object':
|
||||
return list(self.filter(db_sender_objects=obj,
|
||||
db_receivers_channels__isnull=True).exclude(db_hide_from_objects=obj))
|
||||
db_receivers_channels__isnull=True).exclude(db_hide_from_objects=obj))
|
||||
else:
|
||||
raise CommError
|
||||
else:
|
||||
|
|
@ -332,6 +332,7 @@ class ChannelDBManager(TypedObjectManager):
|
|||
subscribed to the Channel.
|
||||
|
||||
"""
|
||||
|
||||
def get_all_channels(self):
|
||||
"""
|
||||
Get all channels.
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
def convert_defaults(apps, schema_editor):
|
||||
ChannelDB = apps.get_model("comms", "ChannelDB")
|
||||
for channel in ChannelDB.objects.filter(db_typeclass_path="src.comms.comms.Channel"):
|
||||
channel.db_typeclass_path = "typeclasses.channels.Channel"
|
||||
channel.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
|
|
@ -16,5 +18,5 @@ class Migration(migrations.Migration):
|
|||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(convert_defaults),
|
||||
migrations.RunPython(convert_defaults),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def convert_channelnames(apps, schema_editor):
|
||||
ChannelDB = apps.get_model("comms", "ChannelDB")
|
||||
for chan in ChannelDB.objects.filter(db_key="MUDinfo"):
|
||||
|
|
@ -13,6 +14,7 @@ def convert_channelnames(apps, schema_editor):
|
|||
chan.db_key = "MudInfo"
|
||||
chan.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
|
|
@ -20,5 +22,5 @@ class Migration(migrations.Migration):
|
|||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(convert_channelnames),
|
||||
migrations.RunPython(convert_channelnames),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -26,41 +26,41 @@ class Migration(migrations.Migration):
|
|||
db_cursor = connection.cursor()
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='channeldb',
|
||||
name='db_account_subscriptions',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='account_subscription_set', to='accounts.AccountDB', verbose_name=b'account subscriptions'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='channeldb',
|
||||
name='db_object_subscriptions',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='object_subscription_set', to='objects.ObjectDB', verbose_name=b'object subscriptions'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='msg',
|
||||
name='db_receivers_scripts',
|
||||
field=models.ManyToManyField(blank=True, help_text=b'script_receivers', related_name='receiver_script_set', to='scripts.ScriptDB'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='msg',
|
||||
name='db_sender_scripts',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='sender_script_set', to='scripts.ScriptDB', verbose_name=b'sender(script)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='channeldb',
|
||||
name='db_object_subscriptions',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='object_subscription_set', to='objects.ObjectDB', verbose_name=b'object subscriptions'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='msg',
|
||||
name='db_receivers_scripts',
|
||||
field=models.ManyToManyField(blank=True, help_text=b'script_receivers', related_name='receiver_script_set', to='scripts.ScriptDB'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='msg',
|
||||
name='db_sender_scripts',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='sender_script_set', to='scripts.ScriptDB', verbose_name=b'sender(script)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='channeldb',
|
||||
name='db_account_subscriptions',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='account_subscription_set', to='accounts.AccountDB', verbose_name=b'account subscriptions'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='channeldb',
|
||||
name='db_object_subscriptions',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='object_subscription_set', to='objects.ObjectDB', verbose_name=b'object subscriptions'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='msg',
|
||||
name='db_receivers_scripts',
|
||||
field=models.ManyToManyField(blank=True, help_text=b'script_receivers', related_name='receiver_script_set', to='scripts.ScriptDB'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='msg',
|
||||
name='db_sender_scripts',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='sender_script_set', to='scripts.ScriptDB', verbose_name=b'sender(script)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='channeldb',
|
||||
name='db_object_subscriptions',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='object_subscription_set', to='objects.ObjectDB', verbose_name=b'object subscriptions'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='msg',
|
||||
name='db_receivers_scripts',
|
||||
field=models.ManyToManyField(blank=True, help_text=b'script_receivers', related_name='receiver_script_set', to='scripts.ScriptDB'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='msg',
|
||||
name='db_sender_scripts',
|
||||
field=models.ManyToManyField(blank=True, db_index=True, related_name='sender_script_set', to='scripts.ScriptDB', verbose_name=b'sender(script)'),
|
||||
),
|
||||
]
|
||||
|
||||
if _table_exists(db_cursor, 'comms_msg_db_hide_from_players'):
|
||||
|
|
|
|||
|
|
@ -81,27 +81,27 @@ class Msg(SharedMemoryModel):
|
|||
# an IRC channel; normally there is only one, but if co-modification of
|
||||
# a message is allowed, there may be more than one "author"
|
||||
db_sender_accounts = models.ManyToManyField("accounts.AccountDB", related_name='sender_account_set',
|
||||
blank=True, verbose_name='sender(account)', db_index=True)
|
||||
blank=True, verbose_name='sender(account)', db_index=True)
|
||||
|
||||
db_sender_objects = models.ManyToManyField("objects.ObjectDB", related_name='sender_object_set',
|
||||
blank=True, verbose_name='sender(object)', db_index=True)
|
||||
db_sender_scripts = models.ManyToManyField("scripts.ScriptDB", related_name='sender_script_set',
|
||||
blank=True, verbose_name='sender(script)', db_index=True)
|
||||
db_sender_external = models.CharField('external sender', max_length=255, null=True, blank=True, db_index=True,
|
||||
help_text="identifier for external sender, for example a sender over an "
|
||||
"IRC connection (i.e. someone who doesn't have an exixtence in-game).")
|
||||
help_text="identifier for external sender, for example a sender over an "
|
||||
"IRC connection (i.e. someone who doesn't have an exixtence in-game).")
|
||||
# The destination objects of this message. Stored as a
|
||||
# comma-separated string of object dbrefs. Can be defined along
|
||||
# with channels below.
|
||||
db_receivers_accounts = models.ManyToManyField('accounts.AccountDB', related_name='receiver_account_set',
|
||||
blank=True, help_text="account receivers")
|
||||
blank=True, help_text="account receivers")
|
||||
|
||||
db_receivers_objects = models.ManyToManyField('objects.ObjectDB', related_name='receiver_object_set',
|
||||
blank=True, help_text="object receivers")
|
||||
db_receivers_scripts = models.ManyToManyField('scripts.ScriptDB', related_name='receiver_script_set',
|
||||
blank=True, help_text="script_receivers")
|
||||
db_receivers_channels = models.ManyToManyField("ChannelDB", related_name='channel_set',
|
||||
blank=True, help_text="channel recievers")
|
||||
blank=True, help_text="channel recievers")
|
||||
|
||||
# header could be used for meta-info about the message if your system needs
|
||||
# it, or as a separate store for the mail subject line maybe.
|
||||
|
|
@ -122,7 +122,7 @@ class Msg(SharedMemoryModel):
|
|||
db_hide_from_channels = models.ManyToManyField("ChannelDB", related_name='hide_from_channels_set', blank=True)
|
||||
|
||||
db_tags = models.ManyToManyField(Tag, blank=True,
|
||||
help_text='tags on this message. Tags are simple string markers to identify, group and alias messages.')
|
||||
help_text='tags on this message. Tags are simple string markers to identify, group and alias messages.')
|
||||
|
||||
# Database manager
|
||||
objects = managers.MsgManager()
|
||||
|
|
@ -156,10 +156,10 @@ class Msg(SharedMemoryModel):
|
|||
#@property
|
||||
def __senders_get(self):
|
||||
"Getter. Allows for value = self.sender"
|
||||
return list(self.db_sender_accounts.all()) + \
|
||||
list(self.db_sender_objects.all()) + \
|
||||
list(self.db_sender_scripts.all()) + \
|
||||
self.extra_senders
|
||||
return list(self.db_sender_accounts.all()) + \
|
||||
list(self.db_sender_objects.all()) + \
|
||||
list(self.db_sender_scripts.all()) + \
|
||||
self.extra_senders
|
||||
|
||||
#@sender.setter
|
||||
def __senders_set(self, senders):
|
||||
|
|
@ -225,9 +225,9 @@ class Msg(SharedMemoryModel):
|
|||
Returns four lists of receivers: accounts, objects, scripts and channels.
|
||||
"""
|
||||
return list(self.db_receivers_accounts.all()) + \
|
||||
list(self.db_receivers_objects.all()) + \
|
||||
list(self.db_receivers_scripts.all()) + \
|
||||
list(self.db_receivers_channels.all())
|
||||
list(self.db_receivers_objects.all()) + \
|
||||
list(self.db_receivers_scripts.all()) + \
|
||||
list(self.db_receivers_channels.all())
|
||||
|
||||
#@receivers.setter
|
||||
def __receivers_set(self, receivers):
|
||||
|
|
@ -250,7 +250,6 @@ class Msg(SharedMemoryModel):
|
|||
elif clsname == "ChannelDB":
|
||||
self.db_receivers_channels.add(receiver)
|
||||
|
||||
|
||||
#@receivers.deleter
|
||||
def __receivers_del(self):
|
||||
"Deleter. Clears all receivers"
|
||||
|
|
@ -370,6 +369,7 @@ class Msg(SharedMemoryModel):
|
|||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
class TempMsg(object):
|
||||
"""
|
||||
This is a non-persistent object for sending temporary messages
|
||||
|
|
@ -377,6 +377,7 @@ class TempMsg(object):
|
|||
doesn't require sender to be given.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, senders=None, receivers=None, channels=None, message="", header="", type="", lockstring="", hide_from=None):
|
||||
"""
|
||||
Creates the temp message.
|
||||
|
|
@ -471,6 +472,7 @@ class SubscriptionHandler(object):
|
|||
channel and hides away which type of entity is
|
||||
subscribing (Account or Object)
|
||||
"""
|
||||
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
Initialize the handler
|
||||
|
|
@ -620,10 +622,10 @@ class ChannelDB(TypedObject):
|
|||
|
||||
"""
|
||||
db_account_subscriptions = models.ManyToManyField("accounts.AccountDB",
|
||||
related_name="account_subscription_set", blank=True, verbose_name='account subscriptions', db_index=True)
|
||||
related_name="account_subscription_set", blank=True, verbose_name='account subscriptions', db_index=True)
|
||||
|
||||
db_object_subscriptions = models.ManyToManyField("objects.ObjectDB",
|
||||
related_name="object_subscription_set", blank=True, verbose_name='object subscriptions', db_index=True)
|
||||
related_name="object_subscription_set", blank=True, verbose_name='object subscriptions', db_index=True)
|
||||
|
||||
# Database manager
|
||||
objects = managers.ChannelDBManager()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ See README.md for more info.
|
|||
# own code, so somthing needs to be done here. See issue #766. /Griatch
|
||||
|
||||
#import evennia
|
||||
#evennia._init()
|
||||
# evennia._init()
|
||||
#import barter, dice, extended_room, menu_login, talking_npc
|
||||
#import chargen, email_login, gendersub, menusystem, slow_exit
|
||||
#import tutorial_world, tutorial_examples
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ class TradeTimeout(DefaultScript):
|
|||
"""
|
||||
This times out the trade request, in case player B did not reply in time.
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
Called when script is first created
|
||||
|
|
@ -136,6 +137,7 @@ class TradeHandler(object):
|
|||
Objects of this class handles the ongoing trade, notably storing the current
|
||||
offers from each side and wether both have accepted or not.
|
||||
"""
|
||||
|
||||
def __init__(self, part_a, part_b):
|
||||
"""
|
||||
Initializes the trade. This is called when part A tries to
|
||||
|
|
@ -391,6 +393,7 @@ class CmdTradeBase(Command):
|
|||
Base command for Trade commands to inherit from. Implements the
|
||||
custom parsing.
|
||||
"""
|
||||
|
||||
def parse(self):
|
||||
"""
|
||||
Parse the relevant parts and make it easily
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class CmdOOCLook(default_cmds.CmdLook):
|
|||
else:
|
||||
charlist = "You have no Characters."
|
||||
string = \
|
||||
""" You, %s, are an |wOOC ghost|n without form. The world is hidden
|
||||
""" You, %s, are an |wOOC ghost|n without form. The world is hidden
|
||||
from you and besides chatting on channels your options are limited.
|
||||
You need to have a Character in order to interact with the world.
|
||||
|
||||
|
|
@ -179,6 +179,7 @@ class OOCCmdSetCharGen(default_cmds.AccountCmdSet):
|
|||
"""
|
||||
Extends the default OOC cmdset.
|
||||
"""
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"""Install everything from the default set, then overload"""
|
||||
self.add(CmdOOCLook())
|
||||
|
|
|
|||
|
|
@ -88,11 +88,11 @@ CLOTHING_TYPE_ORDER = ['hat', 'jewelry', 'top', 'undershirt', 'gloves', 'fullbod
|
|||
'underpants', 'socks', 'shoes', 'accessory']
|
||||
# The maximum number of each type of clothes that can be worn. Unlimited if untyped or not specified.
|
||||
CLOTHING_TYPE_LIMIT = {
|
||||
'hat': 1,
|
||||
'gloves': 1,
|
||||
'socks': 1,
|
||||
'shoes': 1
|
||||
}
|
||||
'hat': 1,
|
||||
'gloves': 1,
|
||||
'socks': 1,
|
||||
'shoes': 1
|
||||
}
|
||||
# The maximum number of clothing items that can be worn, or None for unlimited.
|
||||
CLOTHING_OVERALL_LIMIT = 20
|
||||
# What types of clothes will automatically cover what other types of clothes when worn.
|
||||
|
|
@ -100,11 +100,11 @@ CLOTHING_OVERALL_LIMIT = 20
|
|||
# on that auto-covers it - for example, it's perfectly possible to have your underpants
|
||||
# showing if you put them on after your pants!
|
||||
CLOTHING_TYPE_AUTOCOVER = {
|
||||
'top': ['undershirt'],
|
||||
'bottom': ['underpants'],
|
||||
'fullbody': ['undershirt', 'underpants'],
|
||||
'shoes': ['socks']
|
||||
}
|
||||
'top': ['undershirt'],
|
||||
'bottom': ['underpants'],
|
||||
'fullbody': ['undershirt', 'underpants'],
|
||||
'shoes': ['socks']
|
||||
}
|
||||
# Types of clothes that can't be used to cover other clothes.
|
||||
CLOTHING_TYPE_CANT_COVER_WITH = ['jewelry']
|
||||
|
||||
|
|
@ -295,6 +295,7 @@ class ClothedCharacter(DefaultCharacter):
|
|||
just copy the return_appearance hook defined below to your own game's
|
||||
character typeclass.
|
||||
"""
|
||||
|
||||
def return_appearance(self, looker):
|
||||
"""
|
||||
This formats a description. It is the hook a 'look' command
|
||||
|
|
|
|||
|
|
@ -166,14 +166,14 @@ CURLY_COLOR_XTERM256_EXTRA_GFG = [r'\{=([a-z])'] # |=a - greyscale foregrou
|
|||
CURLY_COLOR_XTERM256_EXTRA_GBG = [r'\{\[=([a-z])'] # |[=a - greyscale background
|
||||
|
||||
CURLY_COLOR_ANSI_XTERM256_BRIGHT_BG_EXTRA_MAP = [
|
||||
(r'{[r', r'{[500'),
|
||||
(r'{[g', r'{[050'),
|
||||
(r'{[y', r'{[550'),
|
||||
(r'{[b', r'{[005'),
|
||||
(r'{[m', r'{[505'),
|
||||
(r'{[c', r'{[055'),
|
||||
(r'{[w', r'{[555'), # white background
|
||||
(r'{[x', r'{[222'), # dark grey background
|
||||
(r'{[r', r'{[500'),
|
||||
(r'{[g', r'{[050'),
|
||||
(r'{[y', r'{[550'),
|
||||
(r'{[b', r'{[005'),
|
||||
(r'{[m', r'{[505'),
|
||||
(r'{[c', r'{[055'),
|
||||
(r'{[w', r'{[555'), # white background
|
||||
(r'{[x', r'{[222'), # dark grey background
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -191,34 +191,34 @@ CURLY_COLOR_ANSI_XTERM256_BRIGHT_BG_EXTRA_MAP = [
|
|||
#############################################################
|
||||
|
||||
MUX_COLOR_ANSI_EXTRA_MAP = [
|
||||
(r'%cn', _ANSI_NORMAL), # reset
|
||||
(r'%ch', _ANSI_HILITE), # highlight
|
||||
(r'%r', _ANSI_RETURN), # line break
|
||||
(r'%R', _ANSI_RETURN), #
|
||||
(r'%t', _ANSI_TAB), # tab
|
||||
(r'%T', _ANSI_TAB), #
|
||||
(r'%b', _ANSI_SPACE), # space
|
||||
(r'%B', _ANSI_SPACE),
|
||||
(r'%cf', _ANSI_BLINK), # annoying and not supported by all clients
|
||||
(r'%ci', _ANSI_INVERSE), # invert
|
||||
(r'%cn', _ANSI_NORMAL), # reset
|
||||
(r'%ch', _ANSI_HILITE), # highlight
|
||||
(r'%r', _ANSI_RETURN), # line break
|
||||
(r'%R', _ANSI_RETURN), #
|
||||
(r'%t', _ANSI_TAB), # tab
|
||||
(r'%T', _ANSI_TAB), #
|
||||
(r'%b', _ANSI_SPACE), # space
|
||||
(r'%B', _ANSI_SPACE),
|
||||
(r'%cf', _ANSI_BLINK), # annoying and not supported by all clients
|
||||
(r'%ci', _ANSI_INVERSE), # invert
|
||||
|
||||
(r'%cr', _ANSI_RED),
|
||||
(r'%cg', _ANSI_GREEN),
|
||||
(r'%cy', _ANSI_YELLOW),
|
||||
(r'%cb', _ANSI_BLUE),
|
||||
(r'%cm', _ANSI_MAGENTA),
|
||||
(r'%cc', _ANSI_CYAN),
|
||||
(r'%cw', _ANSI_WHITE),
|
||||
(r'%cx', _ANSI_BLACK),
|
||||
(r'%cr', _ANSI_RED),
|
||||
(r'%cg', _ANSI_GREEN),
|
||||
(r'%cy', _ANSI_YELLOW),
|
||||
(r'%cb', _ANSI_BLUE),
|
||||
(r'%cm', _ANSI_MAGENTA),
|
||||
(r'%cc', _ANSI_CYAN),
|
||||
(r'%cw', _ANSI_WHITE),
|
||||
(r'%cx', _ANSI_BLACK),
|
||||
|
||||
(r'%cR', _ANSI_BACK_RED),
|
||||
(r'%cG', _ANSI_BACK_GREEN),
|
||||
(r'%cY', _ANSI_BACK_YELLOW),
|
||||
(r'%cB', _ANSI_BACK_BLUE),
|
||||
(r'%cM', _ANSI_BACK_MAGENTA),
|
||||
(r'%cC', _ANSI_BACK_CYAN),
|
||||
(r'%cW', _ANSI_BACK_WHITE),
|
||||
(r'%cX', _ANSI_BACK_BLACK)
|
||||
(r'%cR', _ANSI_BACK_RED),
|
||||
(r'%cG', _ANSI_BACK_GREEN),
|
||||
(r'%cY', _ANSI_BACK_YELLOW),
|
||||
(r'%cB', _ANSI_BACK_BLUE),
|
||||
(r'%cM', _ANSI_BACK_MAGENTA),
|
||||
(r'%cC', _ANSI_BACK_CYAN),
|
||||
(r'%cW', _ANSI_BACK_WHITE),
|
||||
(r'%cX', _ANSI_BACK_BLACK)
|
||||
]
|
||||
|
||||
MUX_COLOR_XTERM256_EXTRA_FG = [r'%c([0-5])([0-5])([0-5])'] # %c123 - foreground colour
|
||||
|
|
@ -227,12 +227,12 @@ MUX_COLOR_XTERM256_EXTRA_GFG = [r'%c=([a-z])'] # %c=a - greyscale foregroun
|
|||
MUX_COLOR_XTERM256_EXTRA_GBG = [r'%c\[=([a-z])'] # %c[=a - greyscale background
|
||||
|
||||
MUX_COLOR_ANSI_XTERM256_BRIGHT_BG_EXTRA_MAP = [
|
||||
(r'%ch%cR', r'%c[500'),
|
||||
(r'%ch%cG', r'%c[050'),
|
||||
(r'%ch%cY', r'%c[550'),
|
||||
(r'%ch%cB', r'%c[005'),
|
||||
(r'%ch%cM', r'%c[505'),
|
||||
(r'%ch%cC', r'%c[055'),
|
||||
(r'%ch%cW', r'%c[555'), # white background
|
||||
(r'%ch%cX', r'%c[222'), # dark grey background
|
||||
(r'%ch%cR', r'%c[500'),
|
||||
(r'%ch%cG', r'%c[050'),
|
||||
(r'%ch%cY', r'%c[550'),
|
||||
(r'%ch%cB', r'%c[005'),
|
||||
(r'%ch%cM', r'%c[505'),
|
||||
(r'%ch%cC', r'%c[055'),
|
||||
(r'%ch%cW', r'%c[555'), # white background
|
||||
(r'%ch%cX', r'%c[222'), # dark grey background
|
||||
]
|
||||
|
|
|
|||
|
|
@ -45,15 +45,15 @@ TIMEFACTOR = settings.TIME_FACTOR
|
|||
# Each unit must be consistent and expressed in seconds.
|
||||
UNITS = getattr(settings, "TIME_UNITS", {
|
||||
# default custom calendar
|
||||
"sec": 1,
|
||||
"min": 60,
|
||||
"hr": 60 * 60,
|
||||
"hour": 60 * 60,
|
||||
"day": 60 * 60 * 24,
|
||||
"week": 60 * 60 * 24 * 7,
|
||||
"month": 60 * 60 * 24 * 7 * 4,
|
||||
"yr": 60 * 60 * 24 * 7 * 4 * 12,
|
||||
"year": 60 * 60 * 24 * 7 * 4 * 12, })
|
||||
"sec": 1,
|
||||
"min": 60,
|
||||
"hr": 60 * 60,
|
||||
"hour": 60 * 60,
|
||||
"day": 60 * 60 * 24,
|
||||
"week": 60 * 60 * 24 * 7,
|
||||
"month": 60 * 60 * 24 * 7 * 4,
|
||||
"yr": 60 * 60 * 24 * 7 * 4 * 12,
|
||||
"year": 60 * 60 * 24 * 7 * 4 * 12, })
|
||||
|
||||
|
||||
def time_to_tuple(seconds, *divisors):
|
||||
|
|
@ -111,8 +111,8 @@ def gametime_to_realtime(format=False, **kwargs):
|
|||
name = name[:-1]
|
||||
|
||||
if name not in UNITS:
|
||||
raise ValueError("the unit {} isn't defined as a valid " \
|
||||
"game time unit".format(name))
|
||||
raise ValueError("the unit {} isn't defined as a valid "
|
||||
"game time unit".format(name))
|
||||
rtime += value * UNITS[name]
|
||||
rtime /= TIMEFACTOR
|
||||
if format:
|
||||
|
|
@ -121,7 +121,7 @@ def gametime_to_realtime(format=False, **kwargs):
|
|||
|
||||
|
||||
def realtime_to_gametime(secs=0, mins=0, hrs=0, days=0, weeks=0,
|
||||
months=0, yrs=0, format=False):
|
||||
months=0, yrs=0, format=False):
|
||||
"""
|
||||
This method calculates how much in-game time a real-world time
|
||||
interval would correspond to. This is usually a lot less
|
||||
|
|
@ -140,7 +140,7 @@ def realtime_to_gametime(secs=0, mins=0, hrs=0, days=0, weeks=0,
|
|||
|
||||
"""
|
||||
gtime = TIMEFACTOR * (secs + mins * 60 + hrs * 3600 + days * 86400 +
|
||||
weeks * 604800 + months * 2628000 + yrs * 31536000)
|
||||
weeks * 604800 + months * 2628000 + yrs * 31536000)
|
||||
if format:
|
||||
units = sorted(set(UNITS.values()), reverse=True)
|
||||
# Remove seconds from the tuple
|
||||
|
|
@ -149,6 +149,7 @@ def realtime_to_gametime(secs=0, mins=0, hrs=0, days=0, weeks=0,
|
|||
return time_to_tuple(gtime, *units)
|
||||
return gtime
|
||||
|
||||
|
||||
def custom_gametime(absolute=False):
|
||||
"""
|
||||
Return the custom game time as a tuple of units, as defined in settings.
|
||||
|
|
@ -168,6 +169,7 @@ def custom_gametime(absolute=False):
|
|||
del units[-1]
|
||||
return time_to_tuple(current, *units)
|
||||
|
||||
|
||||
def real_seconds_until(**kwargs):
|
||||
"""
|
||||
Return the real seconds until game time.
|
||||
|
|
@ -228,6 +230,7 @@ def real_seconds_until(**kwargs):
|
|||
|
||||
return (projected - current) / TIMEFACTOR
|
||||
|
||||
|
||||
def schedule(callback, repeat=False, **kwargs):
|
||||
"""
|
||||
Call the callback when the game time is up.
|
||||
|
|
@ -256,14 +259,16 @@ def schedule(callback, repeat=False, **kwargs):
|
|||
"""
|
||||
seconds = real_seconds_until(**kwargs)
|
||||
script = create_script("evennia.contrib.custom_gametime.GametimeScript",
|
||||
key="GametimeScript", desc="A timegame-sensitive script",
|
||||
interval=seconds, start_delay=True,
|
||||
repeats=-1 if repeat else 1)
|
||||
key="GametimeScript", desc="A timegame-sensitive script",
|
||||
interval=seconds, start_delay=True,
|
||||
repeats=-1 if repeat else 1)
|
||||
script.db.callback = callback
|
||||
script.db.gametime = kwargs
|
||||
return script
|
||||
|
||||
# Scripts dealing in gametime (use `schedule` to create it)
|
||||
|
||||
|
||||
class GametimeScript(DefaultScript):
|
||||
|
||||
"""Gametime-sensitive script."""
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ def roll_dice(dicenum, dicetype, modifier=None, conditional=None, return_tuple=F
|
|||
else:
|
||||
return result
|
||||
|
||||
|
||||
RE_PARTS = re.compile(r"(d|\+|-|/|\*|<|>|<=|>=|!=|==)")
|
||||
RE_MOD = re.compile(r"(\+|-|/|\*)")
|
||||
RE_COND = re.compile(r"(<|>|<=|>=|!=|==)")
|
||||
|
|
@ -255,6 +256,7 @@ class DiceCmdSet(CmdSet):
|
|||
a small cmdset for testing purposes.
|
||||
Add with @py self.cmdset.add("contrib.dice.DiceCmdSet")
|
||||
"""
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"""Called when set is created"""
|
||||
self.add(CmdDice())
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class EvenniaGameIndexClient(object):
|
|||
Evennia Game Index. Since EGI is in the early goings, this isn't
|
||||
incredibly configurable as far as what is being sent.
|
||||
"""
|
||||
|
||||
def __init__(self, on_bad_request=None):
|
||||
"""
|
||||
:param on_bad_request: Optional callable to trigger when a bad request
|
||||
|
|
@ -131,6 +132,7 @@ class SimpleResponseReceiver(protocol.Protocol):
|
|||
"""
|
||||
Used for pulling the response body out of an HTTP response.
|
||||
"""
|
||||
|
||||
def __init__(self, status_code, d):
|
||||
self.status_code = status_code
|
||||
self.buf = ''
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ class ExtendedRoom(DefaultRoom):
|
|||
time. It also allows for "details", together with a slightly modified
|
||||
look command.
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""Called when room is first created only."""
|
||||
self.db.spring_desc = ""
|
||||
|
|
@ -281,6 +282,7 @@ class CmdExtendedLook(default_cmds.CmdLook):
|
|||
|
||||
Observes your location, details at your location or objects in your vicinity.
|
||||
"""
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
Handle the looking - add fallback to details.
|
||||
|
|
|
|||
|
|
@ -38,22 +38,23 @@ _GENDER_PRONOUN_MAP = {"male": {"s": "he",
|
|||
"p": "his",
|
||||
"a": "his"},
|
||||
"female": {"s": "she",
|
||||
"o": "her",
|
||||
"p": "her",
|
||||
"a": "hers"},
|
||||
"o": "her",
|
||||
"p": "her",
|
||||
"a": "hers"},
|
||||
"neutral": {"s": "it",
|
||||
"o": "it",
|
||||
"p": "its",
|
||||
"a": "its"},
|
||||
"o": "it",
|
||||
"p": "its",
|
||||
"a": "its"},
|
||||
"ambiguous": {"s": "they",
|
||||
"o": "them",
|
||||
"p": "their",
|
||||
"a": "theirs"}
|
||||
}
|
||||
}
|
||||
_RE_GENDER_PRONOUN = re.compile(r'(?<!\|)\|(?!\|)[sSoOpPaA]')
|
||||
|
||||
# in-game command for setting the gender
|
||||
|
||||
|
||||
class SetGender(Command):
|
||||
"""
|
||||
Sets gender on yourself
|
||||
|
|
@ -72,7 +73,7 @@ class SetGender(Command):
|
|||
"""
|
||||
caller = self.caller
|
||||
arg = self.args.strip().lower()
|
||||
if not arg in ("male", "female", "neutral", "ambiguous"):
|
||||
if arg not in ("male", "female", "neutral", "ambiguous"):
|
||||
caller.msg("Usage: @gender male||female||neutral||ambiguous")
|
||||
return
|
||||
caller.db.gender = arg
|
||||
|
|
@ -109,7 +110,7 @@ class GenderCharacter(DefaultCharacter):
|
|||
- `|a`, `|A`: Absolute Possessive form: his, hers, its, His, Hers, Its, Theirs
|
||||
|
||||
"""
|
||||
typ = regex_match.group()[1] # "s", "O" etc
|
||||
typ = regex_match.group()[1] # "s", "O" etc
|
||||
gender = self.attributes.get("gender", default="ambiguous")
|
||||
gender = gender if gender in ("male", "female", "neutral") else "ambiguous"
|
||||
pronoun = _GENDER_PRONOUN_MAP[gender][typ.lower()]
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Module containing the CallbackHandler for individual objects.
|
|||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
class CallbackHandler(object):
|
||||
|
||||
"""
|
||||
|
|
@ -99,7 +100,7 @@ class CallbackHandler(object):
|
|||
handler = type(self).script
|
||||
if handler:
|
||||
return self.format_callback(handler.add_callback(self.obj, callback_name, code,
|
||||
author=author, valid=valid, parameters=parameters))
|
||||
author=author, valid=valid, parameters=parameters))
|
||||
|
||||
def edit(self, callback_name, number, code, author=None, valid=False):
|
||||
"""
|
||||
|
|
@ -122,7 +123,7 @@ class CallbackHandler(object):
|
|||
handler = type(self).script
|
||||
if handler:
|
||||
return self.format_callback(handler.edit_callback(self.obj, callback_name,
|
||||
number, code, author=author, valid=valid))
|
||||
number, code, author=author, valid=valid))
|
||||
|
||||
def remove(self, callback_name, number):
|
||||
"""
|
||||
|
|
@ -200,5 +201,6 @@ class CallbackHandler(object):
|
|||
|
||||
return Callback(**callback)
|
||||
|
||||
|
||||
Callback = namedtuple("Callback", ("obj", "name", "number", "code", "author",
|
||||
"valid", "parameters", "created_on", "updated_by", "updated_on"))
|
||||
"valid", "parameters", "created_on", "updated_by", "updated_on"))
|
||||
|
|
|
|||
|
|
@ -17,18 +17,18 @@ COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
|||
# Permissions
|
||||
WITH_VALIDATION = getattr(settings, "callbackS_WITH_VALIDATION", None)
|
||||
WITHOUT_VALIDATION = getattr(settings, "callbackS_WITHOUT_VALIDATION",
|
||||
"developer")
|
||||
"developer")
|
||||
VALIDATING = getattr(settings, "callbackS_VALIDATING", "developer")
|
||||
|
||||
# Split help text
|
||||
BASIC_HELP = "Add, edit or delete callbacks."
|
||||
|
||||
BASIC_USAGES = [
|
||||
"@call <object name> [= <callback name>]",
|
||||
"@call/add <object name> = <callback name> [parameters]",
|
||||
"@call/edit <object name> = <callback name> [callback number]",
|
||||
"@call/del <object name> = <callback name> [callback number]",
|
||||
"@call/tasks [object name [= <callback name>]]",
|
||||
"@call <object name> [= <callback name>]",
|
||||
"@call/add <object name> = <callback name> [parameters]",
|
||||
"@call/edit <object name> = <callback name> [callback number]",
|
||||
"@call/del <object name> = <callback name> [callback number]",
|
||||
"@call/tasks [object name [= <callback name>]]",
|
||||
]
|
||||
|
||||
BASIC_SWITCHES = [
|
||||
|
|
@ -39,7 +39,7 @@ BASIC_SWITCHES = [
|
|||
]
|
||||
|
||||
VALIDATOR_USAGES = [
|
||||
"@call/accept [object name = <callback name> [callback number]]",
|
||||
"@call/accept [object name = <callback name> [callback number]]",
|
||||
]
|
||||
|
||||
VALIDATOR_SWITCHES = [
|
||||
|
|
@ -73,6 +73,7 @@ them and when. You can then accept a specific callback:
|
|||
Use the /del switch to remove callbacks that should not be connected.
|
||||
"""
|
||||
|
||||
|
||||
class CmdCallback(COMMAND_DEFAULT_CLASS):
|
||||
|
||||
"""
|
||||
|
|
@ -141,8 +142,8 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
self.is_validator = validator
|
||||
self.autovalid = autovalid
|
||||
if self.handler is None:
|
||||
caller.msg("The event handler is not running, can't " \
|
||||
"access the event system.")
|
||||
caller.msg("The event handler is not running, can't "
|
||||
"access the event system.")
|
||||
return
|
||||
|
||||
# Before the equal sign, there is an object name or nothing
|
||||
|
|
@ -170,8 +171,8 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
elif switch in ["tasks", "task"]:
|
||||
self.list_tasks()
|
||||
else:
|
||||
caller.msg("Mutually exclusive or invalid switches were " \
|
||||
"used, cannot proceed.")
|
||||
caller.msg("Mutually exclusive or invalid switches were "
|
||||
"used, cannot proceed.")
|
||||
|
||||
def list_callbacks(self):
|
||||
"""Display the list of callbacks connected to the object."""
|
||||
|
|
@ -186,7 +187,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
created = callbacks.get(callback_name)
|
||||
if created is None:
|
||||
self.msg("No callback {} has been set on {}.".format(callback_name,
|
||||
obj))
|
||||
obj))
|
||||
return
|
||||
|
||||
if parameters:
|
||||
|
|
@ -197,7 +198,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
callback = callbacks[callback_name][number]
|
||||
except (ValueError, AssertionError, IndexError):
|
||||
self.msg("The callback {} {} cannot be found in {}.".format(
|
||||
callback_name, parameters, obj))
|
||||
callback_name, parameters, obj))
|
||||
return
|
||||
|
||||
# Display the callback's details
|
||||
|
|
@ -241,8 +242,8 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if updated_on:
|
||||
updated_on = "{} ago".format(time_format(
|
||||
(now - updated_on).total_seconds(),
|
||||
4).capitalize())
|
||||
(now - updated_on).total_seconds(),
|
||||
4).capitalize())
|
||||
else:
|
||||
updated_on = "|gUnknown|n"
|
||||
parameters = callback.get("parameters", "")
|
||||
|
|
@ -256,7 +257,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
names = list(set(list(types.keys()) + list(callbacks.keys())))
|
||||
table = EvTable("Callback name", "Number", "Description",
|
||||
valign="t", width=78)
|
||||
valign="t", width=78)
|
||||
table.reformat_column(0, width=20)
|
||||
table.reformat_column(1, width=10, align="r")
|
||||
table.reformat_column(2, width=48)
|
||||
|
|
@ -277,9 +278,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
types = self.handler.get_events(obj)
|
||||
|
||||
# Check that the callback exists
|
||||
if not callback_name.startswith("chain_") and not callback_name in types:
|
||||
self.msg("The callback name {} can't be found in {} of " \
|
||||
"typeclass {}.".format(callback_name, obj, type(obj)))
|
||||
if not callback_name.startswith("chain_") and callback_name not in types:
|
||||
self.msg("The callback name {} can't be found in {} of "
|
||||
"typeclass {}.".format(callback_name, obj, type(obj)))
|
||||
return
|
||||
|
||||
definition = types.get(callback_name, (None, "Chained event."))
|
||||
|
|
@ -288,7 +289,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# Open the editor
|
||||
callback = self.handler.add_callback(obj, callback_name, "",
|
||||
self.caller, False, parameters=self.parameters)
|
||||
self.caller, False, parameters=self.parameters)
|
||||
|
||||
# Lock this callback right away
|
||||
self.handler.db.locked.append((obj, callback_name, callback["number"]))
|
||||
|
|
@ -296,8 +297,8 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
# Open the editor for this callback
|
||||
self.caller.db._callback = callback
|
||||
EvEditor(self.caller, loadfunc=_ev_load, savefunc=_ev_save,
|
||||
quitfunc=_ev_quit, key="Callback {} of {}".format(
|
||||
callback_name, obj), persistent=True, codefunc=_ev_save)
|
||||
quitfunc=_ev_quit, key="Callback {} of {}".format(
|
||||
callback_name, obj), persistent=True, codefunc=_ev_save)
|
||||
|
||||
def edit_callback(self):
|
||||
"""Edit a callback."""
|
||||
|
|
@ -313,9 +314,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# Check that the callback exists
|
||||
if not callback_name in callbacks:
|
||||
if callback_name not in callbacks:
|
||||
self.msg("The callback name {} can't be found in {}.".format(
|
||||
callback_name, obj))
|
||||
callback_name, obj))
|
||||
return
|
||||
|
||||
# If there's only one callback, just edit it
|
||||
|
|
@ -335,7 +336,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
callback = callbacks[callback_name][number]
|
||||
except (ValueError, AssertionError, IndexError):
|
||||
self.msg("The callback {} {} cannot be found in {}.".format(
|
||||
callback_name, parameters, obj))
|
||||
callback_name, parameters, obj))
|
||||
return
|
||||
|
||||
# If caller can't edit without validation, forbid editing
|
||||
|
|
@ -361,7 +362,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
self.caller.db._callback = callback
|
||||
EvEditor(self.caller, loadfunc=_ev_load, savefunc=_ev_save,
|
||||
quitfunc=_ev_quit, key="Callback {} of {}".format(
|
||||
callback_name, obj), persistent=True, codefunc=_ev_save)
|
||||
callback_name, obj), persistent=True, codefunc=_ev_save)
|
||||
|
||||
def del_callback(self):
|
||||
"""Delete a callback."""
|
||||
|
|
@ -377,9 +378,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# Check that the callback exists
|
||||
if not callback_name in callbacks:
|
||||
if callback_name not in callbacks:
|
||||
self.msg("The callback name {} can't be found in {}.".format(
|
||||
callback_name, obj))
|
||||
callback_name, obj))
|
||||
return
|
||||
|
||||
# If there's only one callback, just delete it
|
||||
|
|
@ -388,8 +389,8 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
callback = callbacks[callback_name][0]
|
||||
else:
|
||||
if not parameters:
|
||||
self.msg("Which callback do you wish to delete? Specify " \
|
||||
"a number.")
|
||||
self.msg("Which callback do you wish to delete? Specify "
|
||||
"a number.")
|
||||
self.list_callbacks()
|
||||
return
|
||||
|
||||
|
|
@ -400,7 +401,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
callback = callbacks[callback_name][number]
|
||||
except (ValueError, AssertionError, IndexError):
|
||||
self.msg("The callback {} {} cannot be found in {}.".format(
|
||||
callback_name, parameters, obj))
|
||||
callback_name, parameters, obj))
|
||||
return
|
||||
|
||||
# If caller can't edit without validation, forbid deleting
|
||||
|
|
@ -417,7 +418,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
# Delete the callback
|
||||
self.handler.del_callback(obj, callback_name, number)
|
||||
self.msg("The callback {}[{}] of {} was deleted.".format(
|
||||
callback_name, number + 1, obj))
|
||||
callback_name, number + 1, obj))
|
||||
|
||||
def accept_callback(self):
|
||||
"""Accept a callback."""
|
||||
|
|
@ -428,7 +429,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
# If no object, display the list of callbacks to be checked
|
||||
if obj is None:
|
||||
table = EvTable("ID", "Type", "Object", "Name", "Updated by",
|
||||
"On", width=78)
|
||||
"On", width=78)
|
||||
table.reformat_column(0, align="r")
|
||||
now = datetime.now()
|
||||
for obj, name, number in self.handler.db.to_valid:
|
||||
|
|
@ -450,8 +451,8 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if updated_on:
|
||||
updated_on = "{} ago".format(time_format(
|
||||
(now - updated_on).total_seconds(),
|
||||
4).capitalize())
|
||||
(now - updated_on).total_seconds(),
|
||||
4).capitalize())
|
||||
else:
|
||||
updated_on = "|gUnknown|n"
|
||||
|
||||
|
|
@ -469,9 +470,9 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# Check that the callback exists
|
||||
if not callback_name in callbacks:
|
||||
if callback_name not in callbacks:
|
||||
self.msg("The callback name {} can't be found in {}.".format(
|
||||
callback_name, obj))
|
||||
callback_name, obj))
|
||||
return
|
||||
|
||||
if not parameters:
|
||||
|
|
@ -486,7 +487,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
callback = callbacks[callback_name][number]
|
||||
except (ValueError, AssertionError, IndexError):
|
||||
self.msg("The callback {} {} cannot be found in {}.".format(
|
||||
callback_name, parameters, obj))
|
||||
callback_name, parameters, obj))
|
||||
return
|
||||
|
||||
# Accept the callback
|
||||
|
|
@ -495,7 +496,7 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
self.handler.accept_callback(obj, callback_name, number)
|
||||
self.msg("The callback {} {} of {} has been accepted.".format(
|
||||
callback_name, parameters, obj))
|
||||
callback_name, parameters, obj))
|
||||
|
||||
def list_tasks(self):
|
||||
"""List the active tasks."""
|
||||
|
|
@ -520,40 +521,44 @@ class CmdCallback(COMMAND_DEFAULT_CLASS):
|
|||
self.msg(unicode(table))
|
||||
|
||||
# Private functions to handle editing
|
||||
|
||||
|
||||
def _ev_load(caller):
|
||||
return caller.db._callback and caller.db._callback.get("code", "") or ""
|
||||
|
||||
|
||||
def _ev_save(caller, buf):
|
||||
"""Save and add the callback."""
|
||||
lock = "perm({}) or perm(events_without_validation)".format(
|
||||
WITHOUT_VALIDATION)
|
||||
WITHOUT_VALIDATION)
|
||||
autovalid = caller.locks.check_lockstring(caller, lock)
|
||||
callback = caller.db._callback
|
||||
handler = get_event_handler()
|
||||
if not handler or not callback or not all(key in callback for key in \
|
||||
("obj", "name", "number", "valid")):
|
||||
if not handler or not callback or not all(key in callback for key in
|
||||
("obj", "name", "number", "valid")):
|
||||
caller.msg("Couldn't save this callback.")
|
||||
return False
|
||||
|
||||
if (callback["obj"], callback["name"], callback["number"]) in handler.db.locked:
|
||||
handler.db.locked.remove((callback["obj"], callback["name"],
|
||||
callback["number"]))
|
||||
callback["number"]))
|
||||
|
||||
handler.edit_callback(callback["obj"], callback["name"], callback["number"], buf,
|
||||
caller, valid=autovalid)
|
||||
caller, valid=autovalid)
|
||||
return True
|
||||
|
||||
|
||||
def _ev_quit(caller):
|
||||
callback = caller.db._callback
|
||||
handler = get_event_handler()
|
||||
if not handler or not callback or not all(key in callback for key in \
|
||||
("obj", "name", "number", "valid")):
|
||||
if not handler or not callback or not all(key in callback for key in
|
||||
("obj", "name", "number", "valid")):
|
||||
caller.msg("Couldn't save this callback.")
|
||||
return False
|
||||
|
||||
if (callback["obj"], callback["name"], callback["number"]) in handler.db.locked:
|
||||
handler.db.locked.remove((callback["obj"], callback["name"],
|
||||
callback["number"]))
|
||||
callback["number"]))
|
||||
|
||||
del caller.db._callback
|
||||
caller.msg("Exited the code editor.")
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Eventfuncs are just Python functions that can be used inside of calllbacks.
|
|||
from evennia import ObjectDB, ScriptDB
|
||||
from evennia.contrib.ingame_python.utils import InterruptEvent
|
||||
|
||||
|
||||
def deny():
|
||||
"""
|
||||
Deny, that is stop, the callback here.
|
||||
|
|
@ -22,6 +23,7 @@ def deny():
|
|||
"""
|
||||
raise InterruptEvent
|
||||
|
||||
|
||||
def get(**kwargs):
|
||||
"""
|
||||
Return an object with the given search option or None if None is found.
|
||||
|
|
@ -53,6 +55,7 @@ def get(**kwargs):
|
|||
|
||||
return object
|
||||
|
||||
|
||||
def call_event(obj, event_name, seconds=0):
|
||||
"""
|
||||
Call the specified event in X seconds.
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from evennia.contrib.ingame_python.utils import get_next_wait, EVENTS, Interrupt
|
|||
# Constants
|
||||
RE_LINE_ERROR = re.compile(r'^ File "\<string\>", line (\d+)')
|
||||
|
||||
|
||||
class EventHandler(DefaultScript):
|
||||
|
||||
"""
|
||||
|
|
@ -94,7 +95,7 @@ class EventHandler(DefaultScript):
|
|||
self.ndb.channel = ChannelDB.objects.get(db_key="everror")
|
||||
except ChannelDB.DoesNotExist:
|
||||
self.ndb.channel = create_channel("everror", desc="Event errors",
|
||||
locks="control:false();listen:perm(Builders);send:false()")
|
||||
locks="control:false();listen:perm(Builders);send:false()")
|
||||
|
||||
def get_events(self, obj):
|
||||
"""
|
||||
|
|
@ -131,7 +132,7 @@ class EventHandler(DefaultScript):
|
|||
for key, etype in all_events.get(typeclass_name, {}).items():
|
||||
if key in invalid:
|
||||
continue
|
||||
if etype[0] is None: # Invalidate
|
||||
if etype[0] is None: # Invalidate
|
||||
invalid.append(key)
|
||||
continue
|
||||
if key not in events:
|
||||
|
|
@ -200,7 +201,7 @@ class EventHandler(DefaultScript):
|
|||
return callbacks
|
||||
|
||||
def add_callback(self, obj, callback_name, code, author=None, valid=False,
|
||||
parameters=""):
|
||||
parameters=""):
|
||||
"""
|
||||
Add the specified callback.
|
||||
|
||||
|
|
@ -228,11 +229,11 @@ class EventHandler(DefaultScript):
|
|||
|
||||
# Add the callback in the list
|
||||
callbacks.append({
|
||||
"created_on": datetime.now(),
|
||||
"author": author,
|
||||
"valid": valid,
|
||||
"code": code,
|
||||
"parameters": parameters,
|
||||
"created_on": datetime.now(),
|
||||
"author": author,
|
||||
"valid": valid,
|
||||
"code": code,
|
||||
"parameters": parameters,
|
||||
})
|
||||
|
||||
# If not valid, set it in 'to_valid'
|
||||
|
|
@ -241,7 +242,7 @@ class EventHandler(DefaultScript):
|
|||
|
||||
# Call the custom_add if needed
|
||||
custom_add = self.get_events(obj).get(
|
||||
callback_name, [None, None, None, None])[3]
|
||||
callback_name, [None, None, None, None])[3]
|
||||
if custom_add:
|
||||
custom_add(obj, callback_name, len(callbacks) - 1, parameters)
|
||||
|
||||
|
|
@ -253,7 +254,7 @@ class EventHandler(DefaultScript):
|
|||
return definition
|
||||
|
||||
def edit_callback(self, obj, callback_name, number, code, author=None,
|
||||
valid=False):
|
||||
valid=False):
|
||||
"""
|
||||
Edit the specified callback.
|
||||
|
||||
|
|
@ -288,10 +289,10 @@ class EventHandler(DefaultScript):
|
|||
|
||||
# Edit the callback
|
||||
callbacks[number].update({
|
||||
"updated_on": datetime.now(),
|
||||
"updated_by": author,
|
||||
"valid": valid,
|
||||
"code": code,
|
||||
"updated_on": datetime.now(),
|
||||
"updated_by": author,
|
||||
"valid": valid,
|
||||
"code": code,
|
||||
})
|
||||
|
||||
# If not valid, set it in 'to_valid'
|
||||
|
|
@ -334,7 +335,7 @@ class EventHandler(DefaultScript):
|
|||
return
|
||||
else:
|
||||
logger.log_info("Deleting callback {} {} of {}:\n{}".format(
|
||||
callback_name, number, obj, code))
|
||||
callback_name, number, obj, code))
|
||||
del callbacks[number]
|
||||
|
||||
# Change IDs of callbacks to be validated
|
||||
|
|
@ -349,7 +350,7 @@ class EventHandler(DefaultScript):
|
|||
elif t_number > number:
|
||||
# Change the ID for this callback
|
||||
self.db.to_valid.insert(i, (t_obj, t_callback_name,
|
||||
t_number - 1))
|
||||
t_number - 1))
|
||||
del self.db.to_valid[i + 1]
|
||||
i += 1
|
||||
|
||||
|
|
@ -414,13 +415,13 @@ class EventHandler(DefaultScript):
|
|||
# Errors should not pass silently
|
||||
allowed = ("number", "parameters", "locals")
|
||||
if any(k for k in kwargs if k not in allowed):
|
||||
raise TypeError("Unknown keyword arguments were specified " \
|
||||
"to call callbacks: {}".format(kwargs))
|
||||
raise TypeError("Unknown keyword arguments were specified "
|
||||
"to call callbacks: {}".format(kwargs))
|
||||
|
||||
event = self.get_events(obj).get(callback_name)
|
||||
if locals is None and not event:
|
||||
logger.log_err("The callback {} for the object {} (typeclass " \
|
||||
"{}) can't be found".format(callback_name, obj, type(obj)))
|
||||
logger.log_err("The callback {} for the object {} (typeclass "
|
||||
"{}) can't be found".format(callback_name, obj, type(obj)))
|
||||
return False
|
||||
|
||||
# Prepare the locals if necessary
|
||||
|
|
@ -430,9 +431,9 @@ class EventHandler(DefaultScript):
|
|||
try:
|
||||
locals[variable] = args[i]
|
||||
except IndexError:
|
||||
logger.log_trace("callback {} of {} ({}): need variable " \
|
||||
"{} in position {}".format(callback_name, obj,
|
||||
type(obj), variable, i))
|
||||
logger.log_trace("callback {} of {} ({}): need variable "
|
||||
"{} in position {}".format(callback_name, obj,
|
||||
type(obj), variable, i))
|
||||
return False
|
||||
else:
|
||||
locals = {key: value for key, value in locals.items()}
|
||||
|
|
@ -482,9 +483,9 @@ class EventHandler(DefaultScript):
|
|||
number = callback["number"]
|
||||
obj = callback["obj"]
|
||||
oid = obj.id
|
||||
logger.log_err("An error occurred during the callback {} of " \
|
||||
"{} (#{}), number {}\n{}".format(callback_name, obj,
|
||||
oid, number + 1, "\n".join(trace)))
|
||||
logger.log_err("An error occurred during the callback {} of "
|
||||
"{} (#{}), number {}\n{}".format(callback_name, obj,
|
||||
oid, number + 1, "\n".join(trace)))
|
||||
|
||||
# Create the error message
|
||||
line = "|runknown|n"
|
||||
|
|
@ -505,8 +506,8 @@ class EventHandler(DefaultScript):
|
|||
|
||||
exc = raw(trace[-1].strip("\n").splitlines()[-1])
|
||||
err_msg = "Error in {} of {} (#{})[{}], line {}:" \
|
||||
" {}\n{}".format(callback_name, obj,
|
||||
oid, number + 1, lineno, line, exc)
|
||||
" {}\n{}".format(callback_name, obj,
|
||||
oid, number + 1, lineno, line, exc)
|
||||
|
||||
# Inform the last updater if connected
|
||||
updater = callback.get("updated_by")
|
||||
|
|
@ -517,8 +518,8 @@ class EventHandler(DefaultScript):
|
|||
updater.msg(err_msg)
|
||||
else:
|
||||
err_msg = "Error in {} of {} (#{})[{}], line {}:" \
|
||||
" {}\n {}".format(callback_name, obj,
|
||||
oid, number + 1, lineno, line, exc)
|
||||
" {}\n {}".format(callback_name, obj,
|
||||
oid, number + 1, lineno, line, exc)
|
||||
self.ndb.channel.msg(err_msg)
|
||||
|
||||
def add_event(self, typeclass, name, variables, help_text, custom_call, custom_add):
|
||||
|
|
@ -655,8 +656,8 @@ def complete_task(task_id):
|
|||
return
|
||||
|
||||
if task_id not in script.db.tasks:
|
||||
logger.log_err("The task #{} was scheduled, but it cannot be " \
|
||||
"found".format(task_id))
|
||||
logger.log_err("The task #{} was scheduled, but it cannot be "
|
||||
"found".format(task_id))
|
||||
return
|
||||
|
||||
delta, obj, callback_name, locals = script.db.tasks.pop(task_id)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ settings.EVENTS_CALENDAR = "standard"
|
|||
# Constants
|
||||
OLD_EVENTS = {}
|
||||
|
||||
|
||||
class TestEventHandler(EvenniaTest):
|
||||
|
||||
"""
|
||||
|
|
@ -31,7 +32,7 @@ class TestEventHandler(EvenniaTest):
|
|||
"""Create the event handler."""
|
||||
super(TestEventHandler, self).setUp()
|
||||
self.handler = create_script(
|
||||
"evennia.contrib.ingame_python.scripts.EventHandler")
|
||||
"evennia.contrib.ingame_python.scripts.EventHandler")
|
||||
|
||||
# Copy old events if necessary
|
||||
if OLD_EVENTS:
|
||||
|
|
@ -64,7 +65,7 @@ class TestEventHandler(EvenniaTest):
|
|||
"""Add a callback while needing validation."""
|
||||
author = self.char1
|
||||
self.handler.add_callback(self.room1, "dummy",
|
||||
"character.db.strength = 40", author=author, valid=False)
|
||||
"character.db.strength = 40", author=author, valid=False)
|
||||
callback = self.handler.get_callbacks(self.room1).get("dummy")
|
||||
callback = callback[0]
|
||||
self.assertIsNotNone(callback)
|
||||
|
|
@ -78,18 +79,18 @@ class TestEventHandler(EvenniaTest):
|
|||
self.char1.db.strength = 10
|
||||
locals = {"character": self.char1}
|
||||
self.assertTrue(self.handler.call(
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.assertEqual(self.char1.db.strength, 10)
|
||||
|
||||
def test_edit(self):
|
||||
"""Test editing a callback."""
|
||||
author = self.char1
|
||||
self.handler.add_callback(self.room1, "dummy",
|
||||
"character.db.strength = 60", author=author, valid=True)
|
||||
"character.db.strength = 60", author=author, valid=True)
|
||||
|
||||
# Edit it right away
|
||||
self.handler.edit_callback(self.room1, "dummy", 0,
|
||||
"character.db.strength = 65", author=self.char2, valid=True)
|
||||
"character.db.strength = 65", author=self.char2, valid=True)
|
||||
|
||||
# Check that the callback was written
|
||||
callback = self.handler.get_callbacks(self.room1).get("dummy")
|
||||
|
|
@ -103,35 +104,35 @@ class TestEventHandler(EvenniaTest):
|
|||
self.char1.db.strength = 10
|
||||
locals = {"character": self.char1}
|
||||
self.assertTrue(self.handler.call(
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.assertEqual(self.char1.db.strength, 65)
|
||||
|
||||
def test_edit_validation(self):
|
||||
"""Edit a callback when validation isn't automatic."""
|
||||
author = self.char1
|
||||
self.handler.add_callback(self.room1, "dummy",
|
||||
"character.db.strength = 70", author=author, valid=True)
|
||||
"character.db.strength = 70", author=author, valid=True)
|
||||
|
||||
# Edit it right away
|
||||
self.handler.edit_callback(self.room1, "dummy", 0,
|
||||
"character.db.strength = 80", author=self.char2, valid=False)
|
||||
"character.db.strength = 80", author=self.char2, valid=False)
|
||||
|
||||
# Run this dummy callback (shouldn't do anything)
|
||||
self.char1.db.strength = 10
|
||||
locals = {"character": self.char1}
|
||||
self.assertTrue(self.handler.call(
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.assertEqual(self.char1.db.strength, 10)
|
||||
|
||||
def test_del(self):
|
||||
"""Try to delete a callback."""
|
||||
# Add 3 callbacks
|
||||
self.handler.add_callback(self.room1, "dummy",
|
||||
"character.db.strength = 5", author=self.char1, valid=True)
|
||||
"character.db.strength = 5", author=self.char1, valid=True)
|
||||
self.handler.add_callback(self.room1, "dummy",
|
||||
"character.db.strength = 8", author=self.char2, valid=False)
|
||||
"character.db.strength = 8", author=self.char2, valid=False)
|
||||
self.handler.add_callback(self.room1, "dummy",
|
||||
"character.db.strength = 9", author=self.char1, valid=True)
|
||||
"character.db.strength = 9", author=self.char1, valid=True)
|
||||
|
||||
# Note that the second callback isn't valid
|
||||
self.assertIn((self.room1, "dummy", 1), self.handler.db.to_valid)
|
||||
|
|
@ -160,16 +161,16 @@ class TestEventHandler(EvenniaTest):
|
|||
self.char1.db.strength = 10
|
||||
locals = {"character": self.char1}
|
||||
self.assertTrue(self.handler.call(
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.assertEqual(self.char1.db.strength, 9)
|
||||
|
||||
def test_accept(self):
|
||||
"""Accept an callback."""
|
||||
# Add 2 callbacks
|
||||
self.handler.add_callback(self.room1, "dummy",
|
||||
"character.db.strength = 5", author=self.char1, valid=True)
|
||||
"character.db.strength = 5", author=self.char1, valid=True)
|
||||
self.handler.add_callback(self.room1, "dummy",
|
||||
"character.db.strength = 8", author=self.char2, valid=False)
|
||||
"character.db.strength = 8", author=self.char2, valid=False)
|
||||
|
||||
# Note that the second callback isn't valid
|
||||
self.assertIn((self.room1, "dummy", 1), self.handler.db.to_valid)
|
||||
|
|
@ -185,7 +186,7 @@ class TestEventHandler(EvenniaTest):
|
|||
self.char1.db.strength = 10
|
||||
locals = {"character": self.char1}
|
||||
self.assertTrue(self.handler.call(
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.room1, "dummy", locals=locals))
|
||||
self.assertEqual(self.char1.db.strength, 8)
|
||||
|
||||
def test_call(self):
|
||||
|
|
@ -201,14 +202,14 @@ class TestEventHandler(EvenniaTest):
|
|||
character.db.health = 0
|
||||
""".strip("\n"))
|
||||
self.handler.add_callback(self.room1, "dummy", code,
|
||||
author=self.char1, valid=True)
|
||||
author=self.char1, valid=True)
|
||||
|
||||
# Call the dummy callback
|
||||
self.assertTrue(self.handler.call(
|
||||
self.room1, "dummy", locals={"character": self.char1}))
|
||||
self.room1, "dummy", locals={"character": self.char1}))
|
||||
self.assertEqual(self.char1.db.health, 50)
|
||||
self.assertTrue(self.handler.call(
|
||||
self.room1, "dummy", locals={"character": self.char2}))
|
||||
self.room1, "dummy", locals={"character": self.char2}))
|
||||
self.assertEqual(self.char2.db.health, 0)
|
||||
|
||||
def test_handler(self):
|
||||
|
|
@ -217,7 +218,7 @@ class TestEventHandler(EvenniaTest):
|
|||
|
||||
# Add an callback
|
||||
callback = self.room1.callbacks.add("dummy", "pass", author=self.char1,
|
||||
valid=True)
|
||||
valid=True)
|
||||
self.assertEqual(callback.obj, self.room1)
|
||||
self.assertEqual(callback.name, "dummy")
|
||||
self.assertEqual(callback.code, "pass")
|
||||
|
|
@ -227,13 +228,13 @@ class TestEventHandler(EvenniaTest):
|
|||
|
||||
# Edit this very callback
|
||||
new = self.room1.callbacks.edit("dummy", 0, "character.db.say = True",
|
||||
author=self.char1, valid=True)
|
||||
author=self.char1, valid=True)
|
||||
self.assertIn([new], self.room1.callbacks.all().values())
|
||||
self.assertNotIn([callback], self.room1.callbacks.all().values())
|
||||
|
||||
# Try to call this callback
|
||||
self.assertTrue(self.room1.callbacks.call("dummy",
|
||||
locals={"character": self.char2}))
|
||||
locals={"character": self.char2}))
|
||||
self.assertTrue(self.char2.db.say)
|
||||
|
||||
# Delete the callback
|
||||
|
|
@ -249,7 +250,7 @@ class TestCmdCallback(CommandTest):
|
|||
"""Create the callback handler."""
|
||||
super(TestCmdCallback, self).setUp()
|
||||
self.handler = create_script(
|
||||
"evennia.contrib.ingame_python.scripts.EventHandler")
|
||||
"evennia.contrib.ingame_python.scripts.EventHandler")
|
||||
|
||||
# Copy old events if necessary
|
||||
if OLD_EVENTS:
|
||||
|
|
@ -287,7 +288,7 @@ class TestCmdCallback(CommandTest):
|
|||
|
||||
# Add some callback
|
||||
self.handler.add_callback(self.exit, "traverse", "pass",
|
||||
author=self.char1, valid=True)
|
||||
author=self.char1, valid=True)
|
||||
|
||||
# Try to obtain more details on a specific callback on exit
|
||||
table = self.call(CmdCallback(), "out = traverse")
|
||||
|
|
@ -355,18 +356,18 @@ class TestCmdCallback(CommandTest):
|
|||
def test_del(self):
|
||||
"""Add and remove an callback."""
|
||||
self.handler.add_callback(self.exit, "traverse", "pass",
|
||||
author=self.char1, valid=True)
|
||||
author=self.char1, valid=True)
|
||||
|
||||
# Try to delete the callback
|
||||
# char2 shouldn't be allowed to do so (that's not HIS callback)
|
||||
self.call(CmdCallback(), "/del out = traverse 1", caller=self.char2)
|
||||
self.assertTrue(len(self.handler.get_callbacks(self.exit).get(
|
||||
"traverse", [])) == 1)
|
||||
"traverse", [])) == 1)
|
||||
|
||||
# Now, char1 should be allowed to delete it
|
||||
self.call(CmdCallback(), "/del out = traverse 1")
|
||||
self.assertTrue(len(self.handler.get_callbacks(self.exit).get(
|
||||
"traverse", [])) == 0)
|
||||
"traverse", [])) == 0)
|
||||
|
||||
def test_lock(self):
|
||||
"""Test the lock of multiple editing."""
|
||||
|
|
@ -414,7 +415,7 @@ class TestDefaultCallbacks(CommandTest):
|
|||
"""Create the callback handler."""
|
||||
super(TestDefaultCallbacks, self).setUp()
|
||||
self.handler = create_script(
|
||||
"evennia.contrib.ingame_python.scripts.EventHandler")
|
||||
"evennia.contrib.ingame_python.scripts.EventHandler")
|
||||
|
||||
# Copy old events if necessary
|
||||
if OLD_EVENTS:
|
||||
|
|
@ -450,7 +451,7 @@ class TestDefaultCallbacks(CommandTest):
|
|||
|
||||
# Try the can_traverse callback
|
||||
self.handler.add_callback(self.exit, "can_traverse", code,
|
||||
author=self.char1, valid=True)
|
||||
author=self.char1, valid=True)
|
||||
|
||||
# Have char1 move through the exit
|
||||
self.call(ExitCommand(), "", "You can leave.", obj=self.exit)
|
||||
|
|
@ -458,13 +459,13 @@ class TestDefaultCallbacks(CommandTest):
|
|||
|
||||
# Have char2 move through this exit
|
||||
self.call(ExitCommand(), "", "You cannot leave.", obj=self.exit,
|
||||
caller=self.char2)
|
||||
caller=self.char2)
|
||||
self.assertIs(self.char2.location, self.room1)
|
||||
|
||||
# Try the traverse callback
|
||||
self.handler.del_callback(self.exit, "can_traverse", 0)
|
||||
self.handler.add_callback(self.exit, "traverse", "character.msg('Fine!')",
|
||||
author=self.char1, valid=True)
|
||||
author=self.char1, valid=True)
|
||||
|
||||
# Have char2 move through the exit
|
||||
self.call(ExitCommand(), "", obj=self.exit, caller=self.char2)
|
||||
|
|
@ -478,15 +479,15 @@ class TestDefaultCallbacks(CommandTest):
|
|||
# Test msg_arrive and msg_leave
|
||||
code = 'message = "{character} goes out."'
|
||||
self.handler.add_callback(self.exit, "msg_leave", code,
|
||||
author=self.char1, valid=True)
|
||||
author=self.char1, valid=True)
|
||||
|
||||
# Have char1 move through the exit
|
||||
old_msg = self.char2.msg
|
||||
try:
|
||||
self.char2.msg = Mock()
|
||||
self.call(ExitCommand(), "", obj=self.exit)
|
||||
stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True))
|
||||
for name, args, kwargs in self.char2.msg.mock_calls]
|
||||
stored_msg = [args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs, force_string=True))
|
||||
for name, args, kwargs in self.char2.msg.mock_calls]
|
||||
# Get the first element of a tuple if msg received a tuple instead of a string
|
||||
stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
|
||||
returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True)
|
||||
|
|
@ -496,18 +497,18 @@ class TestDefaultCallbacks(CommandTest):
|
|||
|
||||
# Create a return exit
|
||||
back = create_object("evennia.objects.objects.DefaultExit",
|
||||
key="in", location=self.room2, destination=self.room1)
|
||||
key="in", location=self.room2, destination=self.room1)
|
||||
code = 'message = "{character} goes in."'
|
||||
self.handler.add_callback(self.exit, "msg_arrive", code,
|
||||
author=self.char1, valid=True)
|
||||
author=self.char1, valid=True)
|
||||
|
||||
# Have char1 move through the exit
|
||||
old_msg = self.char2.msg
|
||||
try:
|
||||
self.char2.msg = Mock()
|
||||
self.call(ExitCommand(), "", obj=back)
|
||||
stored_msg = [args[0] if args and args[0] else kwargs.get("text",utils.to_str(kwargs, force_string=True))
|
||||
for name, args, kwargs in self.char2.msg.mock_calls]
|
||||
stored_msg = [args[0] if args and args[0] else kwargs.get("text", utils.to_str(kwargs, force_string=True))
|
||||
for name, args, kwargs in self.char2.msg.mock_calls]
|
||||
# Get the first element of a tuple if msg received a tuple instead of a string
|
||||
stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
|
||||
returned_msg = ansi.parse_ansi("\n".join(stored_msg), strip_ansi=True)
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ Variables you can use in this event:
|
|||
character: the character connected to this event.
|
||||
"""
|
||||
|
||||
|
||||
@register_events
|
||||
class EventCharacter(DefaultCharacter):
|
||||
|
||||
|
|
@ -208,12 +209,12 @@ class EventCharacter(DefaultCharacter):
|
|||
exits = [o for o in location.contents if o.location is location and o.destination is destination]
|
||||
mapping = mapping or {}
|
||||
mapping.update({
|
||||
"character": self,
|
||||
"character": self,
|
||||
})
|
||||
|
||||
if exits:
|
||||
exits[0].callbacks.call("msg_leave", self, exits[0],
|
||||
location, destination, string, mapping)
|
||||
location, destination, string, mapping)
|
||||
string = exits[0].callbacks.get_variable("message")
|
||||
mapping = exits[0].callbacks.get_variable("mapping")
|
||||
|
||||
|
|
@ -261,14 +262,14 @@ class EventCharacter(DefaultCharacter):
|
|||
exits = []
|
||||
mapping = mapping or {}
|
||||
mapping.update({
|
||||
"character": self,
|
||||
"character": self,
|
||||
})
|
||||
|
||||
if origin:
|
||||
exits = [o for o in destination.contents if o.location is destination and o.destination is origin]
|
||||
if exits:
|
||||
exits[0].callbacks.call("msg_arrive", self, exits[0],
|
||||
origin, destination, string, mapping)
|
||||
origin, destination, string, mapping)
|
||||
string = exits[0].callbacks.get_variable("message")
|
||||
mapping = exits[0].callbacks.get_variable("mapping")
|
||||
|
||||
|
|
@ -299,7 +300,7 @@ class EventCharacter(DefaultCharacter):
|
|||
Room = DefaultRoom
|
||||
if isinstance(origin, Room) and isinstance(destination, Room):
|
||||
can = self.callbacks.call("can_move", self,
|
||||
origin, destination)
|
||||
origin, destination)
|
||||
if can:
|
||||
can = origin.callbacks.call("can_move", self, origin)
|
||||
if can:
|
||||
|
|
@ -489,6 +490,7 @@ Variables you can use in this event:
|
|||
destination: the character's location after moving.
|
||||
"""
|
||||
|
||||
|
||||
@register_events
|
||||
class EventExit(DefaultExit):
|
||||
|
||||
|
|
@ -520,7 +522,7 @@ class EventExit(DefaultExit):
|
|||
is_character = inherits_from(traversing_object, DefaultCharacter)
|
||||
if is_character:
|
||||
allow = self.callbacks.call("can_traverse", traversing_object,
|
||||
self, self.location)
|
||||
self, self.location)
|
||||
if not allow:
|
||||
return
|
||||
|
||||
|
|
@ -529,7 +531,7 @@ class EventExit(DefaultExit):
|
|||
# After traversing
|
||||
if is_character:
|
||||
self.callbacks.call("traverse", traversing_object,
|
||||
self, self.location, self.destination)
|
||||
self, self.location, self.destination)
|
||||
|
||||
|
||||
# Object help
|
||||
|
|
@ -573,6 +575,7 @@ Variables you can use in this event:
|
|||
object: the object connected to this event.
|
||||
"""
|
||||
|
||||
|
||||
@register_events
|
||||
class EventObject(DefaultObject):
|
||||
|
||||
|
|
@ -621,6 +624,7 @@ class EventObject(DefaultObject):
|
|||
super(EventObject, self).at_drop(dropper)
|
||||
self.callbacks.call("drop", dropper, self)
|
||||
|
||||
|
||||
# Room help
|
||||
ROOM_CAN_DELETE = """
|
||||
Can the room be deleted?
|
||||
|
|
@ -742,6 +746,7 @@ Variables you can use in this event:
|
|||
room: the room connected to this event.
|
||||
"""
|
||||
|
||||
|
||||
@register_events
|
||||
class EventRoom(DefaultRoom):
|
||||
|
||||
|
|
@ -792,7 +797,7 @@ class EventRoom(DefaultRoom):
|
|||
|
||||
"""
|
||||
allow = self.callbacks.call("can_say", speaker, self, message,
|
||||
parameters=message)
|
||||
parameters=message)
|
||||
if not allow:
|
||||
return
|
||||
|
||||
|
|
@ -802,7 +807,7 @@ class EventRoom(DefaultRoom):
|
|||
for present in [o for o in self.contents if isinstance(
|
||||
o, DefaultCharacter) and o is not speaker]:
|
||||
allow = present.callbacks.call("can_say", speaker, present,
|
||||
message, parameters=message)
|
||||
message, parameters=message)
|
||||
if not allow:
|
||||
return
|
||||
|
||||
|
|
@ -811,10 +816,10 @@ class EventRoom(DefaultRoom):
|
|||
# We force the next event to be called after the message
|
||||
# This will have to change when the Evennia API adds new hooks
|
||||
delay(0, self.callbacks.call, "say", speaker, self, message,
|
||||
parameters=message)
|
||||
parameters=message)
|
||||
for present in [o for o in self.contents if isinstance(
|
||||
o, DefaultCharacter) and o is not speaker]:
|
||||
delay(0, present.callbacks.call, "say", speaker, present, message,
|
||||
parameters=message)
|
||||
parameters=message)
|
||||
|
||||
return message
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ from evennia.contrib.custom_gametime import real_seconds_until as custom_rsu
|
|||
# Temporary storage for events waiting for the script to be started
|
||||
EVENTS = []
|
||||
|
||||
|
||||
def get_event_handler():
|
||||
"""Return the event handler or None."""
|
||||
try:
|
||||
|
|
@ -30,6 +31,7 @@ def get_event_handler():
|
|||
|
||||
return script
|
||||
|
||||
|
||||
def register_events(path_or_typeclass):
|
||||
"""
|
||||
Register the events in this typeclass.
|
||||
|
|
@ -84,6 +86,8 @@ def register_events(path_or_typeclass):
|
|||
return typeclass
|
||||
|
||||
# Custom callbacks for specific event types
|
||||
|
||||
|
||||
def get_next_wait(format):
|
||||
"""
|
||||
Get the length of time in seconds before format.
|
||||
|
|
@ -104,8 +108,8 @@ def get_next_wait(format):
|
|||
"""
|
||||
calendar = getattr(settings, "EVENTS_CALENDAR", None)
|
||||
if calendar is None:
|
||||
logger.log_err("A time-related event has been set whereas " \
|
||||
"the gametime calendar has not been set in the settings.")
|
||||
logger.log_err("A time-related event has been set whereas "
|
||||
"the gametime calendar has not been set in the settings.")
|
||||
return
|
||||
elif calendar == "standard":
|
||||
rsu = standard_rsu
|
||||
|
|
@ -131,8 +135,8 @@ def get_next_wait(format):
|
|||
break
|
||||
|
||||
if not piece.isdigit():
|
||||
logger.log_trace("The time specified '{}' in {} isn't " \
|
||||
"a valid number".format(piece, format))
|
||||
logger.log_trace("The time specified '{}' in {} isn't "
|
||||
"a valid number".format(piece, format))
|
||||
return
|
||||
|
||||
# Convert the piece to int
|
||||
|
|
@ -154,6 +158,7 @@ def get_next_wait(format):
|
|||
usual = gametime_to_realtime(**kwargs)
|
||||
return until, usual, details
|
||||
|
||||
|
||||
def time_event(obj, event_name, number, parameters):
|
||||
"""
|
||||
Create a time-related event.
|
||||
|
|
@ -173,6 +178,7 @@ def time_event(obj, event_name, number, parameters):
|
|||
script.db.number = number
|
||||
script.ndb.usual = usual
|
||||
|
||||
|
||||
def keyword_event(callbacks, parameters):
|
||||
"""
|
||||
Custom call for events with keywords (like push, or pull, or turn...).
|
||||
|
|
@ -201,6 +207,7 @@ def keyword_event(callbacks, parameters):
|
|||
|
||||
return to_call
|
||||
|
||||
|
||||
def phrase_event(callbacks, parameters):
|
||||
"""
|
||||
Custom call for events with keywords in sentences (like say or whisper).
|
||||
|
|
@ -236,6 +243,7 @@ def phrase_event(callbacks, parameters):
|
|||
|
||||
return to_call
|
||||
|
||||
|
||||
class InterruptEvent(RuntimeError):
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ _HEAD_CHAR = "|015-|n"
|
|||
_SUB_HEAD_CHAR = "-"
|
||||
_WIDTH = 78
|
||||
|
||||
|
||||
class CmdMail(default_cmds.MuxCommand):
|
||||
"""
|
||||
Commands that allow either IC or OOC communications
|
||||
|
|
@ -253,4 +254,3 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
self.caller.msg(_HEAD_CHAR * _WIDTH)
|
||||
else:
|
||||
self.caller.msg("There are no messages in your inbox.")
|
||||
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ def example1_build_temple(x, y, **kwargs):
|
|||
# This is generally mandatory.
|
||||
return room
|
||||
|
||||
|
||||
# Include your trigger characters and build functions in a legend dict.
|
||||
EXAMPLE1_LEGEND = {("♣", "♠"): example1_build_forest,
|
||||
("∩", "n"): example1_build_mountains,
|
||||
|
|
@ -225,17 +226,17 @@ def example2_build_verticle_exit(x, y, **kwargs):
|
|||
if kwargs["iteration"] == 0:
|
||||
return
|
||||
|
||||
north_room = kwargs["room_dict"][(x, y-1)]
|
||||
south_room = kwargs["room_dict"][(x, y+1)]
|
||||
north_room = kwargs["room_dict"][(x, y - 1)]
|
||||
south_room = kwargs["room_dict"][(x, y + 1)]
|
||||
|
||||
# create exits in the rooms
|
||||
create_object(exits.Exit, key="south",
|
||||
aliases=["s"], location=north_room,
|
||||
destination=south_room)
|
||||
aliases=["s"], location=north_room,
|
||||
destination=south_room)
|
||||
|
||||
create_object(exits.Exit, key="north",
|
||||
aliases=["n"], location=south_room,
|
||||
destination=north_room)
|
||||
aliases=["n"], location=south_room,
|
||||
destination=north_room)
|
||||
|
||||
kwargs["caller"].msg("Connected: " + north_room.key +
|
||||
" & " + south_room.key)
|
||||
|
|
@ -247,20 +248,21 @@ def example2_build_horizontal_exit(x, y, **kwargs):
|
|||
if kwargs["iteration"] == 0:
|
||||
return
|
||||
|
||||
west_room = kwargs["room_dict"][(x-1, y)]
|
||||
east_room = kwargs["room_dict"][(x+1, y)]
|
||||
west_room = kwargs["room_dict"][(x - 1, y)]
|
||||
east_room = kwargs["room_dict"][(x + 1, y)]
|
||||
|
||||
create_object(exits.Exit, key="east",
|
||||
aliases=["e"], location=west_room,
|
||||
destination=east_room)
|
||||
aliases=["e"], location=west_room,
|
||||
destination=east_room)
|
||||
|
||||
create_object(exits.Exit, key="west",
|
||||
aliases=["w"], location=east_room,
|
||||
destination=west_room)
|
||||
aliases=["w"], location=east_room,
|
||||
destination=west_room)
|
||||
|
||||
kwargs["caller"].msg("Connected: " + west_room.key +
|
||||
" & " + east_room.key)
|
||||
|
||||
|
||||
# Include your trigger characters and build functions in a legend dict.
|
||||
EXAMPLE2_LEGEND = {("♣", "♠"): example2_build_forest,
|
||||
("|"): example2_build_verticle_exit,
|
||||
|
|
@ -339,37 +341,38 @@ def build_map(caller, game_map, legend, iterations=1, build_exits=True):
|
|||
y = loc_key[1]
|
||||
|
||||
# north
|
||||
if (x, y-1) in room_dict:
|
||||
if room_dict[(x, y-1)]:
|
||||
if (x, y - 1) in room_dict:
|
||||
if room_dict[(x, y - 1)]:
|
||||
create_object(exits.Exit, key="north",
|
||||
aliases=["n"], location=location,
|
||||
destination=room_dict[(x, y-1)])
|
||||
destination=room_dict[(x, y - 1)])
|
||||
|
||||
# east
|
||||
if (x+1, y) in room_dict:
|
||||
if room_dict[(x+1, y)]:
|
||||
if (x + 1, y) in room_dict:
|
||||
if room_dict[(x + 1, y)]:
|
||||
create_object(exits.Exit, key="east",
|
||||
aliases=["e"], location=location,
|
||||
destination=room_dict[(x+1, y)])
|
||||
destination=room_dict[(x + 1, y)])
|
||||
|
||||
# south
|
||||
if (x, y+1) in room_dict:
|
||||
if room_dict[(x, y+1)]:
|
||||
if (x, y + 1) in room_dict:
|
||||
if room_dict[(x, y + 1)]:
|
||||
create_object(exits.Exit, key="south",
|
||||
aliases=["s"], location=location,
|
||||
destination=room_dict[(x, y+1)])
|
||||
destination=room_dict[(x, y + 1)])
|
||||
|
||||
# west
|
||||
if (x-1, y) in room_dict:
|
||||
if room_dict[(x-1, y)]:
|
||||
if (x - 1, y) in room_dict:
|
||||
if room_dict[(x - 1, y)]:
|
||||
create_object(exits.Exit, key="west",
|
||||
aliases=["w"], location=location,
|
||||
destination=room_dict[(x-1, y)])
|
||||
destination=room_dict[(x - 1, y)])
|
||||
|
||||
caller.msg("Map Created.")
|
||||
|
||||
# access command
|
||||
|
||||
|
||||
class CmdMapBuilder(COMMAND_DEFAULT_CLASS):
|
||||
"""
|
||||
Build a map from a 2D ASCII map.
|
||||
|
|
@ -478,4 +481,3 @@ class CmdMapBuilder(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# Pass map and legend to the build function.
|
||||
build_map(caller, game_map, legend, iterations, build_exits)
|
||||
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ def create_password(caller, string_input):
|
|||
permissions = settings.PERMISSION_ACCOUNT_DEFAULT
|
||||
typeclass = settings.BASE_CHARACTER_TYPECLASS
|
||||
new_account = unloggedin._create_account(caller, accountname,
|
||||
password, permissions)
|
||||
password, permissions)
|
||||
if new_account:
|
||||
if settings.MULTISESSION_MODE < 2:
|
||||
default_home = ObjectDB.objects.get_id(
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ def _update_store(caller, key=None, desc=None, delete=False, swapkey=None):
|
|||
|
||||
# eveditor save/load/quit functions
|
||||
|
||||
|
||||
def _save_editor(caller, buffer):
|
||||
"Called when the editor saves its contents"
|
||||
key = caller.db._multidesc_editkey
|
||||
|
|
@ -104,6 +105,7 @@ def _save_editor(caller, buffer):
|
|||
caller.msg("Saved description to key '%s'." % key)
|
||||
return True
|
||||
|
||||
|
||||
def _load_editor(caller):
|
||||
"Called when the editor loads contents"
|
||||
key = caller.db._multidesc_editkey
|
||||
|
|
@ -112,6 +114,7 @@ def _load_editor(caller):
|
|||
return caller.db.multidesc[match[0]][1]
|
||||
return ""
|
||||
|
||||
|
||||
def _quit_editor(caller):
|
||||
"Called when the editor quits"
|
||||
del caller.db._multidesc_editkey
|
||||
|
|
@ -161,13 +164,13 @@ class CmdMultiDesc(default_cmds.MuxCommand):
|
|||
# list all stored descriptions, either in full or cropped.
|
||||
# Note that we list starting from 1, not from 0.
|
||||
_update_store(caller)
|
||||
do_crop = not "full" in switches
|
||||
do_crop = "full" not in switches
|
||||
if do_crop:
|
||||
outtext = ["|w%s:|n %s" % (key, crop(desc))
|
||||
for key, desc in caller.db.multidesc]
|
||||
for key, desc in caller.db.multidesc]
|
||||
else:
|
||||
outtext = ["\n|w%s:|n|n\n%s\n%s" % (key, "-" * (len(key) + 1), desc)
|
||||
for key, desc in caller.db.multidesc]
|
||||
for key, desc in caller.db.multidesc]
|
||||
|
||||
caller.msg("|wStored descs:|n\n" + "\n".join(outtext))
|
||||
return
|
||||
|
|
@ -249,6 +252,6 @@ class CmdMultiDesc(default_cmds.MuxCommand):
|
|||
else:
|
||||
caller.msg("|wCurrent desc:|n\n%s" % caller.db.desc)
|
||||
|
||||
except DescValidateError, err:
|
||||
except DescValidateError as err:
|
||||
# This is triggered by _key_to_index
|
||||
caller.msg(err)
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ import time
|
|||
from evennia import DefaultScript, ScriptDB
|
||||
from evennia.utils.create import create_script
|
||||
|
||||
|
||||
class RejectedRegex(RuntimeError):
|
||||
|
||||
"""The provided regular expression has been rejected.
|
||||
|
|
@ -331,7 +332,7 @@ class RandomStringGenerator(object):
|
|||
generated = script.db.generated.get(self.name, [])
|
||||
if element not in generated:
|
||||
raise ValueError("the string {} isn't stored as generated by the generator {}".format(
|
||||
element, self.name))
|
||||
element, self.name))
|
||||
|
||||
generated.remove(element)
|
||||
|
||||
|
|
|
|||
|
|
@ -148,13 +148,13 @@ class LanguageHandler(DefaultScript):
|
|||
don't know the language well enough).
|
||||
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"Called when script is first started"
|
||||
self.key = "language_handler"
|
||||
self.persistent = True
|
||||
self.db.language_storage = {}
|
||||
|
||||
|
||||
def add(self, key="default", phonemes=_PHONEMES,
|
||||
grammar=_GRAMMAR, word_length_variance=0, noun_prefix="",
|
||||
noun_postfix="", vowels=_VOWELS, manual_translations=None,
|
||||
|
|
@ -240,8 +240,8 @@ class LanguageHandler(DefaultScript):
|
|||
word = word.strip()
|
||||
lword = len(word)
|
||||
new_word = ""
|
||||
wlen = max(0, lword + sum(randint(-1,1) for i
|
||||
in range(word_length_variance)))
|
||||
wlen = max(0, lword + sum(randint(-1, 1) for i
|
||||
in range(word_length_variance)))
|
||||
if wlen not in grammar:
|
||||
# always create a translation, use random length
|
||||
structure = choice(grammar[choice(list(grammar))])
|
||||
|
|
@ -257,7 +257,7 @@ class LanguageHandler(DefaultScript):
|
|||
translation.update(dict((key.lower(), value.lower()) for key, value in manual_translations.items()))
|
||||
|
||||
# store data
|
||||
storage = {"translation" : translation,
|
||||
storage = {"translation": translation,
|
||||
"grammar": grammar,
|
||||
"grammar2phonemes": dict(grammar2phonemes),
|
||||
"word_length_variance": word_length_variance,
|
||||
|
|
@ -296,8 +296,8 @@ class LanguageHandler(DefaultScript):
|
|||
else:
|
||||
# make up translation on the fly. Length can
|
||||
# vary from un-translated word.
|
||||
wlen = max(0, lword + sum(randint(-1,1) for i
|
||||
in range(self.language["word_length_variance"])))
|
||||
wlen = max(0, lword + sum(randint(-1, 1) for i
|
||||
in range(self.language["word_length_variance"])))
|
||||
grammar = self.language["grammar"]
|
||||
if wlen not in grammar:
|
||||
# this word has no direct translation!
|
||||
|
|
@ -347,6 +347,8 @@ class LanguageHandler(DefaultScript):
|
|||
# Language access functions
|
||||
|
||||
_LANGUAGE_HANDLER = None
|
||||
|
||||
|
||||
def obfuscate_language(text, level=0.0, language="default"):
|
||||
"""
|
||||
Main access method for the language parser.
|
||||
|
|
@ -412,7 +414,6 @@ def available_languages():
|
|||
return list(_LANGUAGE_HANDLER.attributes.get("language_storage", {}))
|
||||
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
# Whisper obscuration
|
||||
|
|
@ -427,6 +428,7 @@ def available_languages():
|
|||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
_RE_WHISPER_OBSCURE = [
|
||||
re.compile(r"^$", _RE_FLAGS), # This is a Test! #0 full whisper
|
||||
re.compile(r"[ae]", _RE_FLAGS), # This -s - Test! #1 add uy
|
||||
|
|
@ -434,7 +436,7 @@ _RE_WHISPER_OBSCURE = [
|
|||
re.compile(r"[aeiouy]", _RE_FLAGS), # Th-s -s - T-st! #3 add all consonants
|
||||
re.compile(r"[aeiouybdhjlmnpqrv]", _RE_FLAGS), # T--s -s - T-st! #4 add hard consonants
|
||||
re.compile(r"[a-eg-rt-z]", _RE_FLAGS), # T--s -s - T-s-! #5 add all capitals
|
||||
re.compile(r"[A-EG-RT-Za-eg-rt-z]", _RE_FLAGS), # ---s -s - --s-! #6 add f
|
||||
re.compile(r"[A-EG-RT-Za-eg-rt-z]", _RE_FLAGS), # ---s -s - --s-! #6 add f
|
||||
re.compile(r"[A-EG-RT-Za-rt-z]", _RE_FLAGS), # ---s -s - --s-! #7 add s
|
||||
re.compile(r"[A-EG-RT-Za-z]", _RE_FLAGS), # ---- -- - ----! #8 add capital F
|
||||
re.compile(r"[A-RT-Za-z]", _RE_FLAGS), # ---- -- - ----! #9 add capital S
|
||||
|
|
@ -460,4 +462,3 @@ def obfuscate_whisper(whisper, level=0.0):
|
|||
level = min(max(0.0, level), 1.0)
|
||||
olevel = int(13.0 * level)
|
||||
return _RE_WHISPER_OBSCURE[olevel].sub('...' if olevel == 13.0 else '-', whisper)
|
||||
|
||||
|
|
|
|||
|
|
@ -127,10 +127,10 @@ _NUM_SEP = "-"
|
|||
# Texts
|
||||
|
||||
_EMOTE_NOMATCH_ERROR = \
|
||||
"""|RNo match for |r{ref}|R.|n"""
|
||||
"""|RNo match for |r{ref}|R.|n"""
|
||||
|
||||
_EMOTE_MULTIMATCH_ERROR = \
|
||||
"""|RMultiple possibilities for {ref}:
|
||||
"""|RMultiple possibilities for {ref}:
|
||||
|r{reflist}|n"""
|
||||
|
||||
_RE_FLAGS = re.MULTILINE + re.IGNORECASE + re.UNICODE
|
||||
|
|
@ -142,7 +142,7 @@ _RE_PREFIX = re.compile(r"^%s" % _PREFIX, re.UNICODE)
|
|||
# marker. So entering "/tall man" will return groups ("", "tall")
|
||||
# and "/2-tall man" will return groups ("2", "tall").
|
||||
_RE_OBJ_REF_START = re.compile(r"%s(?:([0-9]+)%s)*(\w+)" %
|
||||
(_PREFIX, _NUM_SEP), _RE_FLAGS)
|
||||
(_PREFIX, _NUM_SEP), _RE_FLAGS)
|
||||
|
||||
_RE_LEFT_BRACKETS = re.compile(r"\{+", _RE_FLAGS)
|
||||
_RE_RIGHT_BRACKETS = re.compile(r"\}+", _RE_FLAGS)
|
||||
|
|
@ -168,6 +168,7 @@ _RE_LANGUAGE = re.compile(r"(?:\((\w+)\))*(\".+?\")")
|
|||
# 2) for every person seeing the emote, parse this
|
||||
# intermediary form into the one valid for that char.
|
||||
|
||||
|
||||
class EmoteError(Exception):
|
||||
pass
|
||||
|
||||
|
|
@ -240,6 +241,7 @@ def ordered_permutation_regex(sentence):
|
|||
regex = r"|".join(sorted(set(solution), key=len, reverse=True))
|
||||
return regex
|
||||
|
||||
|
||||
def regex_tuple_from_key_alias(obj):
|
||||
"""
|
||||
This will build a regex tuple for any object, not just from those
|
||||
|
|
@ -358,13 +360,13 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
|||
"""
|
||||
# Load all candidate regex tuples [(regex, obj, sdesc/recog),...]
|
||||
candidate_regexes = \
|
||||
([(_RE_SELF_REF, sender, sender.sdesc.get())] if hasattr(sender, "sdesc") else [])+ \
|
||||
([sender.recog.get_regex_tuple(obj) for obj in candidates] if hasattr(sender, "recog") else []) + \
|
||||
[obj.sdesc.get_regex_tuple()
|
||||
for obj in candidates if hasattr(obj, "sdesc")] + \
|
||||
[regex_tuple_from_key_alias(obj) # handle objects without sdescs
|
||||
for obj in candidates if not (hasattr(obj, "recog") and
|
||||
hasattr(obj, "sdesc"))]
|
||||
([(_RE_SELF_REF, sender, sender.sdesc.get())] if hasattr(sender, "sdesc") else []) + \
|
||||
([sender.recog.get_regex_tuple(obj) for obj in candidates] if hasattr(sender, "recog") else []) + \
|
||||
[obj.sdesc.get_regex_tuple()
|
||||
for obj in candidates if hasattr(obj, "sdesc")] + \
|
||||
[regex_tuple_from_key_alias(obj) # handle objects without sdescs
|
||||
for obj in candidates if not (hasattr(obj, "recog") and
|
||||
hasattr(obj, "sdesc"))]
|
||||
|
||||
# filter out non-found data
|
||||
candidate_regexes = [tup for tup in candidate_regexes if tup]
|
||||
|
|
@ -387,7 +389,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
|||
# start index forward for all candidates.
|
||||
|
||||
# first see if there is a number given (e.g. 1-tall)
|
||||
num_identifier, _ = marker_match.groups("") # return "" if no match, rather than None
|
||||
num_identifier, _ = marker_match.groups("") # return "" if no match, rather than None
|
||||
istart0 = marker_match.start()
|
||||
istart = istart0
|
||||
|
||||
|
|
@ -418,7 +420,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
|||
else:
|
||||
# multi-match.
|
||||
# was a numerical identifier given to help us separate the multi-match?
|
||||
inum = min(max(0, int(num_identifier) - 1), nmatches-1) if num_identifier else None
|
||||
inum = min(max(0, int(num_identifier) - 1), nmatches - 1) if num_identifier else None
|
||||
if inum is not None:
|
||||
# A valid inum is given. Use this to separate data.
|
||||
obj = bestmatches[inum][0]
|
||||
|
|
@ -438,10 +440,10 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False):
|
|||
mapping[key] = obj
|
||||
else:
|
||||
refname = marker_match.group()
|
||||
reflist = ["%s%s%s (%s%s)" % (inum+1, _NUM_SEP,
|
||||
_RE_PREFIX.sub("", refname), text,
|
||||
" (%s)" % sender.key if sender == ob else "")
|
||||
for inum, (ob, text) in enumerate(obj)]
|
||||
reflist = ["%s%s%s (%s%s)" % (inum + 1, _NUM_SEP,
|
||||
_RE_PREFIX.sub("", refname), text,
|
||||
" (%s)" % sender.key if sender == ob else "")
|
||||
for inum, (ob, text) in enumerate(obj)]
|
||||
errors.append(_EMOTE_MULTIMATCH_ERROR.format(
|
||||
ref=marker_match.group(), reflist="\n ".join(reflist)))
|
||||
if search_mode:
|
||||
|
|
@ -532,8 +534,8 @@ def send_emote(sender, receivers, emote, anonymous_add="first"):
|
|||
receiver_sdesc_mapping = dict((ref, process_recog(recog_get(obj), obj)) for ref, obj in obj_mapping.items())
|
||||
except AttributeError:
|
||||
receiver_sdesc_mapping = dict((ref, process_sdesc(obj.sdesc.get(), obj)
|
||||
if hasattr(obj, "sdesc") else process_sdesc(obj.key, obj))
|
||||
for ref, obj in obj_mapping.items())
|
||||
if hasattr(obj, "sdesc") else process_sdesc(obj.key, obj))
|
||||
for ref, obj in obj_mapping.items())
|
||||
# make sure receiver always sees their real name
|
||||
rkey = "#%i" % receiver.id
|
||||
if rkey in receiver_sdesc_mapping:
|
||||
|
|
@ -546,6 +548,7 @@ def send_emote(sender, receivers, emote, anonymous_add="first"):
|
|||
# Handlers for sdesc and recog
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
class SdescHandler(object):
|
||||
"""
|
||||
This Handler wraps all operations with sdescs. We
|
||||
|
|
@ -559,6 +562,7 @@ class SdescHandler(object):
|
|||
_regex - an empty dictionary
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
Initialize the handler
|
||||
|
|
@ -600,10 +604,10 @@ class SdescHandler(object):
|
|||
"""
|
||||
# strip emote components from sdesc
|
||||
sdesc = _RE_REF.sub(r"\1",
|
||||
_RE_REF_LANG.sub(r"\1",
|
||||
_RE_SELF_REF.sub(r"",
|
||||
_RE_LANGUAGE.sub(r"",
|
||||
_RE_OBJ_REF_START.sub(r"", sdesc)))))
|
||||
_RE_REF_LANG.sub(r"\1",
|
||||
_RE_SELF_REF.sub(r"",
|
||||
_RE_LANGUAGE.sub(r"",
|
||||
_RE_OBJ_REF_START.sub(r"", sdesc)))))
|
||||
|
||||
# make an sdesc clean of ANSI codes
|
||||
cleaned_sdesc = ansi.strip_ansi(sdesc)
|
||||
|
|
@ -656,6 +660,7 @@ class RecogHandler(object):
|
|||
_recog_obj2regex
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
Initialize the handler
|
||||
|
|
@ -679,9 +684,9 @@ class RecogHandler(object):
|
|||
obj2regex = self.obj.attributes.get("_recog_obj2regex", default={})
|
||||
obj2recog = self.obj.attributes.get("_recog_obj2recog", default={})
|
||||
self.obj2regex = dict((obj, re.compile(regex, _RE_FLAGS))
|
||||
for obj, regex in obj2regex.items() if obj)
|
||||
for obj, regex in obj2regex.items() if obj)
|
||||
self.obj2recog = dict((obj, recog)
|
||||
for obj, recog in obj2recog.items() if obj)
|
||||
for obj, recog in obj2recog.items() if obj)
|
||||
|
||||
def add(self, obj, recog, max_length=60):
|
||||
"""
|
||||
|
|
@ -705,10 +710,10 @@ class RecogHandler(object):
|
|||
"""
|
||||
# strip emote components from recog
|
||||
recog = _RE_REF.sub(r"\1",
|
||||
_RE_REF_LANG.sub(r"\1",
|
||||
_RE_SELF_REF.sub(r"",
|
||||
_RE_LANGUAGE.sub(r"",
|
||||
_RE_OBJ_REF_START.sub(r"", recog)))))
|
||||
_RE_REF_LANG.sub(r"\1",
|
||||
_RE_SELF_REF.sub(r"",
|
||||
_RE_LANGUAGE.sub(r"",
|
||||
_RE_OBJ_REF_START.sub(r"", recog)))))
|
||||
|
||||
# make an recog clean of ANSI codes
|
||||
cleaned_recog = ansi.strip_ansi(recog)
|
||||
|
|
@ -751,7 +756,7 @@ class RecogHandler(object):
|
|||
# to avoid revealing masked characters. If lock
|
||||
# does not exist, pass automatically.
|
||||
return self.obj2recog.get(obj, obj.sdesc.get()
|
||||
if hasattr(obj, "sdesc") else obj.key)
|
||||
if hasattr(obj, "sdesc") else obj.key)
|
||||
else:
|
||||
# recog_mask log not passed, disable recog
|
||||
return obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
||||
|
|
@ -785,6 +790,7 @@ class RecogHandler(object):
|
|||
|
||||
class RPCommand(Command):
|
||||
"simple parent"
|
||||
|
||||
def parse(self):
|
||||
"strip extra whitespace"
|
||||
self.args = self.args.strip()
|
||||
|
|
@ -828,7 +834,7 @@ class CmdEmote(RPCommand): # replaces the main emote
|
|||
send_emote(self.caller, targets, emote, anonymous_add='first')
|
||||
|
||||
|
||||
class CmdSay(RPCommand): # replaces standard say
|
||||
class CmdSay(RPCommand): # replaces standard say
|
||||
"""
|
||||
speak as your character
|
||||
|
||||
|
|
@ -843,7 +849,6 @@ class CmdSay(RPCommand): # replaces standard say
|
|||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
|
||||
"Run the say command"
|
||||
|
||||
caller = self.caller
|
||||
|
|
@ -860,7 +865,7 @@ class CmdSay(RPCommand): # replaces standard say
|
|||
send_emote(self.caller, targets, speech, anonymous_add=None)
|
||||
|
||||
|
||||
class CmdSdesc(RPCommand): # set/look at own sdesc
|
||||
class CmdSdesc(RPCommand): # set/look at own sdesc
|
||||
"""
|
||||
Assign yourself a short description (sdesc).
|
||||
|
||||
|
|
@ -884,13 +889,13 @@ class CmdSdesc(RPCommand): # set/look at own sdesc
|
|||
sdesc = _RE_CHAREND.sub("", self.args)
|
||||
try:
|
||||
sdesc = caller.sdesc.add(sdesc)
|
||||
except SdescError, err:
|
||||
except SdescError as err:
|
||||
caller.msg(err)
|
||||
return
|
||||
caller.msg("%s's sdesc was set to '%s'." % (caller.key, sdesc))
|
||||
|
||||
|
||||
class CmdPose(RPCommand): # set current pose and default pose
|
||||
class CmdPose(RPCommand): # set current pose and default pose
|
||||
"""
|
||||
Set a static pose
|
||||
|
||||
|
|
@ -976,7 +981,7 @@ class CmdPose(RPCommand): # set current pose and default pose
|
|||
# set the pose. We do one-time ref->sdesc mapping here.
|
||||
parsed, mapping = parse_sdescs_and_recogs(caller, caller.location.contents, pose)
|
||||
mapping = dict((ref, obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key)
|
||||
for ref, obj in mapping.iteritems())
|
||||
for ref, obj in mapping.iteritems())
|
||||
pose = parsed.format(**mapping)
|
||||
|
||||
if len(target_name) + len(pose) > 60:
|
||||
|
|
@ -988,7 +993,7 @@ class CmdPose(RPCommand): # set current pose and default pose
|
|||
caller.msg("Pose will read '%s %s'." % (target_name, pose))
|
||||
|
||||
|
||||
class CmdRecog(RPCommand): # assign personal alias to object in room
|
||||
class CmdRecog(RPCommand): # assign personal alias to object in room
|
||||
"""
|
||||
Recognize another person in the same room.
|
||||
|
||||
|
|
@ -1034,11 +1039,11 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
|
|||
if nmatches == 0:
|
||||
caller.msg(_EMOTE_NOMATCH_ERROR.format(ref=sdesc))
|
||||
elif nmatches > 1:
|
||||
reflist = ["%s%s%s (%s%s)" % (inum+1, _NUM_SEP,
|
||||
_RE_PREFIX.sub("", sdesc), caller.recog.get(obj),
|
||||
" (%s)" % caller.key if caller == obj else "")
|
||||
for inum, obj in enumerate(matches)]
|
||||
caller.msg(_EMOTE_MULTIMATCH_ERROR.format(ref=sdesc,reflist="\n ".join(reflist)))
|
||||
reflist = ["%s%s%s (%s%s)" % (inum + 1, _NUM_SEP,
|
||||
_RE_PREFIX.sub("", sdesc), caller.recog.get(obj),
|
||||
" (%s)" % caller.key if caller == obj else "")
|
||||
for inum, obj in enumerate(matches)]
|
||||
caller.msg(_EMOTE_MULTIMATCH_ERROR.format(ref=sdesc, reflist="\n ".join(reflist)))
|
||||
else:
|
||||
obj = matches[0]
|
||||
if not obj.access(self.obj, "enable_recog", default=True):
|
||||
|
|
@ -1053,7 +1058,7 @@ class CmdRecog(RPCommand): # assign personal alias to object in room
|
|||
sdesc = obj.sdesc.get() if hasattr(obj, "sdesc") else obj.key
|
||||
try:
|
||||
alias = caller.recog.add(obj, alias)
|
||||
except RecogError, err:
|
||||
except RecogError as err:
|
||||
caller.msg(err)
|
||||
return
|
||||
caller.msg("%s will now remember |w%s|n as |w%s|n." % (caller.key, sdesc, alias))
|
||||
|
|
@ -1095,7 +1100,7 @@ class CmdMask(RPCommand):
|
|||
caller.sdesc.add(sdesc)
|
||||
caller.msg("You wear a mask as '%s'." % sdesc)
|
||||
else:
|
||||
#unmask
|
||||
# unmask
|
||||
old_sdesc = caller.db.unmasked_sdesc
|
||||
if not old_sdesc:
|
||||
caller.msg("You are not wearing a mask.")
|
||||
|
|
@ -1110,6 +1115,7 @@ class RPSystemCmdSet(CmdSet):
|
|||
"""
|
||||
Mix-in for adding rp-commands to default cmdset.
|
||||
"""
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
self.add(CmdEmote())
|
||||
self.add(CmdSay())
|
||||
|
|
@ -1231,7 +1237,7 @@ class ContribRPObject(DefaultObject):
|
|||
searchdata = self.nicks.nickreplace(searchdata, categories=("object", "account"), include_account=True)
|
||||
|
||||
if(global_search or (is_string and searchdata.startswith("#") and
|
||||
len(searchdata) > 1 and searchdata[1:].isdigit())):
|
||||
len(searchdata) > 1 and searchdata[1:].isdigit())):
|
||||
# only allow exact matching if searching the entire database
|
||||
# or unique #dbrefs
|
||||
exact = True
|
||||
|
|
@ -1258,16 +1264,17 @@ class ContribRPObject(DefaultObject):
|
|||
# the sdesc-related substitution
|
||||
is_builder = self.locks.check_lockstring(self, "perm(Builder)")
|
||||
use_dbref = is_builder if use_dbref is None else use_dbref
|
||||
search_obj = lambda string: ObjectDB.objects.object_search(string,
|
||||
attribute_name=attribute_name,
|
||||
typeclass=typeclass,
|
||||
candidates=candidates,
|
||||
exact=exact,
|
||||
use_dbref=use_dbref)
|
||||
|
||||
def search_obj(string): return ObjectDB.objects.object_search(string,
|
||||
attribute_name=attribute_name,
|
||||
typeclass=typeclass,
|
||||
candidates=candidates,
|
||||
exact=exact,
|
||||
use_dbref=use_dbref)
|
||||
|
||||
if candidates:
|
||||
candidates = parse_sdescs_and_recogs(self, candidates,
|
||||
_PREFIX + searchdata, search_mode=True)
|
||||
_PREFIX + searchdata, search_mode=True)
|
||||
results = []
|
||||
for candidate in candidates:
|
||||
# we search by candidate keys here; this allows full error
|
||||
|
|
@ -1288,8 +1295,8 @@ class ContribRPObject(DefaultObject):
|
|||
|
||||
if quiet:
|
||||
return results
|
||||
return _AT_SEARCH_RESULT(results, self, query=searchdata,
|
||||
nofound_string=nofound_string, multimatch_string=multimatch_string)
|
||||
return _AT_SEARCH_RESULT(results, self, query=searchdata,
|
||||
nofound_string=nofound_string, multimatch_string=multimatch_string)
|
||||
|
||||
def get_display_name(self, looker, **kwargs):
|
||||
"""
|
||||
|
|
@ -1336,7 +1343,7 @@ class ContribRPObject(DefaultObject):
|
|||
return ""
|
||||
# get and identify all objects
|
||||
visible = (con for con in self.contents if con != looker and
|
||||
con.access(looker, "view"))
|
||||
con.access(looker, "view"))
|
||||
exits, users, things = [], [], []
|
||||
for con in visible:
|
||||
key = con.get_display_name(looker, pose=True)
|
||||
|
|
@ -1488,4 +1495,4 @@ class ContribRPCharacter(DefaultCharacter, ContribRPObject):
|
|||
return "%s|w%s|n" % ("|W(%s)" % language if language else "", text)
|
||||
|
||||
#from evennia.contrib import rplanguage
|
||||
#return "|w%s|n" % rplanguage.obfuscate_language(text, level=1.0)
|
||||
# return "|w%s|n" % rplanguage.obfuscate_language(text, level=1.0)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class SimpleDoor(DefaultExit):
|
|||
sides using `exitname.setlock("traverse:false())`
|
||||
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
Called the very first time the door is created.
|
||||
|
|
@ -115,7 +116,7 @@ class CmdOpen(default_cmds.CmdOpen):
|
|||
self.caller.msg("Note: A door-type exit was created - ignored eventual custom return-exit type.")
|
||||
self.return_exit_already_created = True
|
||||
back_exit = self.create_exit(exit_name, destination, location,
|
||||
exit_aliases=exit_aliases, typeclass=typeclass)
|
||||
exit_aliases=exit_aliases, typeclass=typeclass)
|
||||
new_exit.db.return_exit = back_exit
|
||||
back_exit.db.return_exit = new_exit
|
||||
return new_exit
|
||||
|
|
@ -159,10 +160,9 @@ class CmdOpenCloseDoor(default_cmds.MuxCommand):
|
|||
else:
|
||||
door.setlock("traverse:true()")
|
||||
self.caller.msg("You open %s." % door.key)
|
||||
else: # close
|
||||
else: # close
|
||||
if not door.locks.check(self.caller, "traverse"):
|
||||
self.caller.msg("%s is already closed." % door.key)
|
||||
else:
|
||||
door.setlock("traverse:false()")
|
||||
self.caller.msg("You close %s." % door.key)
|
||||
|
||||
|
|
|
|||
|
|
@ -42,10 +42,12 @@ MOVE_DELAY = {"stroll": 6,
|
|||
"run": 2,
|
||||
"sprint": 1}
|
||||
|
||||
|
||||
class SlowExit(DefaultExit):
|
||||
"""
|
||||
This overloads the way moving happens.
|
||||
"""
|
||||
|
||||
def at_traverse(self, traversing_object, target_location):
|
||||
"""
|
||||
Implements the actual traversal, using utils.delay to delay the move_to.
|
||||
|
|
@ -87,6 +89,7 @@ SPEED_DESCS = {"stroll": "strolling",
|
|||
"run": "running",
|
||||
"sprint": "sprinting"}
|
||||
|
||||
|
||||
class CmdSetSpeed(Command):
|
||||
"""
|
||||
set your movement speed
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ def info1(caller):
|
|||
|
||||
return text, options
|
||||
|
||||
|
||||
def info2(caller):
|
||||
text = "'My name is not really important ... I'm just an NPC after all.'"
|
||||
|
||||
|
|
@ -67,7 +68,6 @@ def info3(caller):
|
|||
{"desc": "Wait, why don't you tell me your name first?",
|
||||
"goto": "info2"})
|
||||
|
||||
|
||||
return text, options
|
||||
|
||||
|
||||
|
|
@ -82,6 +82,7 @@ def END(caller):
|
|||
# The talk command (sits on the NPC)
|
||||
#
|
||||
|
||||
|
||||
class CmdTalk(default_cmds.MuxCommand):
|
||||
"""
|
||||
Talks to an npc
|
||||
|
|
@ -112,6 +113,7 @@ class CmdTalk(default_cmds.MuxCommand):
|
|||
class TalkingCmdSet(CmdSet):
|
||||
"Stores the talk command."
|
||||
key = "talkingcmdset"
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"populates the cmdset"
|
||||
self.add(CmdTalk())
|
||||
|
|
@ -122,6 +124,7 @@ class TalkingNPC(DefaultObject):
|
|||
This implements a simple Object using the talk command and using
|
||||
the conversation defined above.
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"This is called when object is first created."
|
||||
self.db.desc = "This is a talkative NPC."
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ class TestLanguage(EvenniaTest):
|
|||
|
||||
# Testing of emoting / sdesc / recog system
|
||||
|
||||
|
||||
from evennia import create_object
|
||||
from evennia.contrib import rpsystem
|
||||
|
||||
|
|
@ -176,6 +177,7 @@ from evennia.contrib import extended_room
|
|||
from evennia import gametime
|
||||
from evennia.objects.objects import DefaultRoom
|
||||
|
||||
|
||||
class ForceUTCDatetime(datetime.datetime):
|
||||
|
||||
"""Force UTC datetime."""
|
||||
|
|
@ -185,6 +187,7 @@ class ForceUTCDatetime(datetime.datetime):
|
|||
"""Force fromtimestamp to run with naive datetimes."""
|
||||
return datetime.datetime.utcfromtimestamp(timestamp)
|
||||
|
||||
|
||||
@patch('evennia.contrib.extended_room.datetime.datetime', ForceUTCDatetime)
|
||||
class TestExtendedRoom(CommandTest):
|
||||
room_typeclass = extended_room.ExtendedRoom
|
||||
|
|
@ -208,7 +211,7 @@ class TestExtendedRoom(CommandTest):
|
|||
old_desc = DefaultRoom.return_appearance(self.room1, self.char1)
|
||||
# the new appearance should be the old one, but with the desc switched
|
||||
self.assertEqual(old_desc.replace(self.OLD_DESC, self.SPRING_DESC),
|
||||
self.room1.return_appearance(self.char1))
|
||||
self.room1.return_appearance(self.char1))
|
||||
self.assertEqual("spring", self.room1.ndb.last_season)
|
||||
self.assertEqual("evening", self.room1.ndb.last_timeslot)
|
||||
|
||||
|
|
@ -223,7 +226,7 @@ class TestExtendedRoom(CommandTest):
|
|||
def test_cmdextendeddesc(self):
|
||||
self.call(extended_room.CmdExtendedDesc(), "", "Details on Room", cmdstring="detail")
|
||||
self.call(extended_room.CmdExtendedDesc(), "thingie = newdetail with spaces",
|
||||
"Set Detail thingie to 'newdetail with spaces'.", cmdstring="detail")
|
||||
"Set Detail thingie to 'newdetail with spaces'.", cmdstring="detail")
|
||||
self.call(extended_room.CmdExtendedDesc(), "thingie", "Detail 'thingie' on Room:\n", cmdstring="detail")
|
||||
self.call(extended_room.CmdExtendedDesc(), "/del thingie", "Detail thingie deleted, if it existed.", cmdstring="detail")
|
||||
self.call(extended_room.CmdExtendedDesc(), "thingie", "Detail 'thingie' not found.", cmdstring="detail")
|
||||
|
|
@ -237,6 +240,7 @@ class TestExtendedRoom(CommandTest):
|
|||
|
||||
from evennia.contrib import barter
|
||||
|
||||
|
||||
class TestBarter(CommandTest):
|
||||
|
||||
def setUp(self):
|
||||
|
|
@ -295,7 +299,7 @@ class TestBarter(CommandTest):
|
|||
self.call(barter.CmdTrade(), "Char decline : Nope!", "You say, \"Nope!\"", caller=self.char2)
|
||||
self.call(barter.CmdTrade(), "Char2 : Hey wanna trade?", "You say, \"Hey wanna trade?\"", caller=self.char1)
|
||||
self.call(barter.CmdTrade(), "Char accept : Sure!", "You say, \"Sure!\"", caller=self.char2)
|
||||
self.call(barter.CmdOffer(), "TradeItem3", "Your trade action: You offer TradeItem3",caller=self.char2)
|
||||
self.call(barter.CmdOffer(), "TradeItem3", "Your trade action: You offer TradeItem3", caller=self.char2)
|
||||
self.call(barter.CmdOffer(), "TradeItem1 : Here's my offer.", "You say, \"Here's my offer.\"\n [You offer TradeItem1]")
|
||||
self.call(barter.CmdAccept(), "", "Your trade action: You accept the offer. Char2 must now also accept")
|
||||
self.call(barter.CmdDecline(), "", "Your trade action: You change your mind, declining the current offer.")
|
||||
|
|
@ -319,9 +323,11 @@ class TestBarter(CommandTest):
|
|||
|
||||
# Test wilderness
|
||||
|
||||
|
||||
from evennia.contrib import wilderness
|
||||
from evennia import DefaultCharacter
|
||||
|
||||
|
||||
class TestWilderness(EvenniaTest):
|
||||
|
||||
def setUp(self):
|
||||
|
|
@ -372,8 +378,8 @@ class TestWilderness(EvenniaTest):
|
|||
# be visible / traversable
|
||||
exits = [i for i in self.char1.location.contents
|
||||
if i.destination and (
|
||||
i.access(self.char1, "view") or
|
||||
i.access(self.char1, "traverse"))]
|
||||
i.access(self.char1, "view") or
|
||||
i.access(self.char1, "traverse"))]
|
||||
|
||||
self.assertEquals(len(exits), 3)
|
||||
exitsok = ["north", "northeast", "east"]
|
||||
|
|
@ -385,8 +391,8 @@ class TestWilderness(EvenniaTest):
|
|||
wilderness.enter_wilderness(self.char1, coordinates=(1, 1))
|
||||
exits = [i for i in self.char1.location.contents
|
||||
if i.destination and (
|
||||
i.access(self.char1, "view") or
|
||||
i.access(self.char1, "traverse"))]
|
||||
i.access(self.char1, "view") or
|
||||
i.access(self.char1, "traverse"))]
|
||||
self.assertEquals(len(exits), 8)
|
||||
exitsok = ["north", "northeast", "east", "southeast", "south",
|
||||
"southwest", "west", "northwest"]
|
||||
|
|
@ -438,9 +444,11 @@ class TestWilderness(EvenniaTest):
|
|||
new_loc = wilderness.get_new_coordinates(loc, direction)
|
||||
self.assertEquals(new_loc, correct_loc, direction)
|
||||
|
||||
|
||||
# Testing chargen contrib
|
||||
from evennia.contrib import chargen
|
||||
|
||||
|
||||
class TestChargen(CommandTest):
|
||||
|
||||
def test_ooclook(self):
|
||||
|
|
@ -451,13 +459,15 @@ class TestChargen(CommandTest):
|
|||
self.call(chargen.CmdOOCCharacterCreate(), "testchar", "The character testchar was successfully created!", caller=self.account)
|
||||
self.call(chargen.CmdOOCCharacterCreate(), "testchar", "Character testchar already exists.", caller=self.account)
|
||||
self.assertTrue(self.account.db._character_dbrefs)
|
||||
self.call(chargen.CmdOOCLook(), "", "You, TestAccount, are an OOC ghost without form.",caller=self.account)
|
||||
self.call(chargen.CmdOOCLook(), "", "You, TestAccount, are an OOC ghost without form.", caller=self.account)
|
||||
self.call(chargen.CmdOOCLook(), "testchar", "testchar(", caller=self.account)
|
||||
|
||||
|
||||
# Testing clothing contrib
|
||||
from evennia.contrib import clothing
|
||||
from evennia.objects.objects import DefaultRoom
|
||||
|
||||
|
||||
class TestClothingCmd(CommandTest):
|
||||
|
||||
def test_clothingcommands(self):
|
||||
|
|
@ -501,6 +511,7 @@ class TestClothingCmd(CommandTest):
|
|||
# Test inventory command.
|
||||
self.call(clothing.CmdInventory(), "", "You are not carrying or wearing anything.", caller=wearer)
|
||||
|
||||
|
||||
class TestClothingFunc(EvenniaTest):
|
||||
|
||||
def test_clothingfunctions(self):
|
||||
|
|
@ -537,42 +548,50 @@ class TestClothingFunc(EvenniaTest):
|
|||
test_pants.wear(wearer, True)
|
||||
self.assertEqual(clothing.get_worn_clothes(wearer), [test_hat, test_pants])
|
||||
|
||||
self.assertEqual(clothing.clothing_type_count(clothes_list), {'hat':1, 'top':1, 'bottom':1})
|
||||
self.assertEqual(clothing.clothing_type_count(clothes_list), {'hat': 1, 'top': 1, 'bottom': 1})
|
||||
|
||||
self.assertEqual(clothing.single_type_count(clothes_list, 'hat'), 1)
|
||||
|
||||
|
||||
|
||||
|
||||
# Testing custom_gametime
|
||||
from evennia.contrib import custom_gametime
|
||||
|
||||
|
||||
def _testcallback():
|
||||
pass
|
||||
|
||||
|
||||
class TestCustomGameTime(EvenniaTest):
|
||||
def setUp(self):
|
||||
super(TestCustomGameTime, self).setUp()
|
||||
gametime.gametime = Mock(return_value=2975000898.46) # does not seem to work
|
||||
gametime.gametime = Mock(return_value=2975000898.46) # does not seem to work
|
||||
|
||||
def tearDown(self):
|
||||
if hasattr(self, "timescript"):
|
||||
self.timescript.stop()
|
||||
|
||||
def test_time_to_tuple(self):
|
||||
self.assertEqual(custom_gametime.time_to_tuple(10000, 34,2,4,6,1), (294, 2, 0, 0, 0, 0))
|
||||
self.assertEqual(custom_gametime.time_to_tuple(10000, 3,3,4), (3333, 0, 0, 1))
|
||||
self.assertEqual(custom_gametime.time_to_tuple(100000, 239,24,3), (418, 4, 0, 2))
|
||||
self.assertEqual(custom_gametime.time_to_tuple(10000, 34, 2, 4, 6, 1), (294, 2, 0, 0, 0, 0))
|
||||
self.assertEqual(custom_gametime.time_to_tuple(10000, 3, 3, 4), (3333, 0, 0, 1))
|
||||
self.assertEqual(custom_gametime.time_to_tuple(100000, 239, 24, 3), (418, 4, 0, 2))
|
||||
|
||||
def test_gametime_to_realtime(self):
|
||||
self.assertEqual(custom_gametime.gametime_to_realtime(days=2, mins=4), 86520.0)
|
||||
self.assertEqual(custom_gametime.gametime_to_realtime(format=True, days=2), (0,0,0,1,0,0,0))
|
||||
self.assertEqual(custom_gametime.gametime_to_realtime(format=True, days=2), (0, 0, 0, 1, 0, 0, 0))
|
||||
|
||||
def test_realtime_to_gametime(self):
|
||||
self.assertEqual(custom_gametime.realtime_to_gametime(days=2, mins=34), 349680.0)
|
||||
self.assertEqual(custom_gametime.realtime_to_gametime(days=2, mins=34, format=True), (0, 0, 0, 4, 1, 8, 0))
|
||||
self.assertEqual(custom_gametime.realtime_to_gametime(format=True, days=2, mins=4), (0, 0, 0, 4, 0, 8, 0))
|
||||
|
||||
def test_custom_gametime(self):
|
||||
self.assertEqual(custom_gametime.custom_gametime(), (102, 5, 2, 6, 21, 8, 18))
|
||||
self.assertEqual(custom_gametime.custom_gametime(absolute=True), (102, 5, 2, 6, 21, 8, 18))
|
||||
|
||||
def test_real_seconds_until(self):
|
||||
self.assertEqual(custom_gametime.real_seconds_until(year=2300, month=11, day=6), 31911667199.77)
|
||||
|
||||
def test_schedule(self):
|
||||
self.timescript = custom_gametime.schedule(_testcallback, repeat=True, min=5, sec=0)
|
||||
self.assertEqual(self.timescript.interval, 1700.7699999809265)
|
||||
|
|
@ -585,9 +604,10 @@ class TestDice(CommandTest):
|
|||
def test_roll_dice(self, mocked_randint):
|
||||
# we must import dice here for the mocked randint to apply correctly.
|
||||
from evennia.contrib import dice
|
||||
self.assertEqual(dice.roll_dice(6, 6, modifier=('+', 4)), mocked_randint()*6 + 4)
|
||||
self.assertEqual(dice.roll_dice(6, 6, modifier=('+', 4)), mocked_randint() * 6 + 4)
|
||||
self.assertEqual(dice.roll_dice(6, 6, conditional=('<', 35)), True)
|
||||
self.assertEqual(dice.roll_dice(6, 6, conditional=('>', 33)), False)
|
||||
|
||||
def test_cmddice(self, mocked_randint):
|
||||
from evennia.contrib import dice
|
||||
self.call(dice.CmdDice(), "3d6 + 4", "You roll 3d6 + 4.| Roll(s): 5, 5 and 5. Total result is 19.")
|
||||
|
|
@ -596,29 +616,37 @@ class TestDice(CommandTest):
|
|||
|
||||
# Test email-login
|
||||
|
||||
|
||||
from evennia.contrib import email_login
|
||||
|
||||
|
||||
class TestEmailLogin(CommandTest):
|
||||
def test_connect(self):
|
||||
self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test", "The email 'mytest@test.com' does not match any accounts.")
|
||||
self.call(email_login.CmdUnconnectedCreate(), '"mytest" mytest@test.com test11111', "A new account 'mytest' was created. Welcome!")
|
||||
self.call(email_login.CmdUnconnectedConnect(), "mytest@test.com test11111", "", caller=self.account.sessions.get()[0])
|
||||
|
||||
def test_quit(self):
|
||||
self.call(email_login.CmdUnconnectedQuit(), "", "", caller=self.account.sessions.get()[0])
|
||||
|
||||
def test_unconnectedlook(self):
|
||||
self.call(email_login.CmdUnconnectedLook(), "", "==========")
|
||||
|
||||
def test_unconnectedhelp(self):
|
||||
self.call(email_login.CmdUnconnectedHelp(), "", "You are not yet logged into the game.")
|
||||
|
||||
# test gendersub contrib
|
||||
|
||||
|
||||
from evennia.contrib import gendersub
|
||||
|
||||
|
||||
class TestGenderSub(CommandTest):
|
||||
def test_setgender(self):
|
||||
self.call(gendersub.SetGender(), "male", "Your gender was set to male.")
|
||||
self.call(gendersub.SetGender(), "ambiguous", "Your gender was set to ambiguous.")
|
||||
self.call(gendersub.SetGender(), "Foo", "Usage: @gender")
|
||||
|
||||
def test_gendercharacter(self):
|
||||
char = create_object(gendersub.GenderCharacter, key="Gendered", location=self.room1)
|
||||
txt = "Test |p gender"
|
||||
|
|
@ -626,8 +654,10 @@ class TestGenderSub(CommandTest):
|
|||
|
||||
# test mail contrib
|
||||
|
||||
|
||||
from evennia.contrib import mail
|
||||
|
||||
|
||||
class TestMail(CommandTest):
|
||||
def test_mail(self):
|
||||
self.call(mail.CmdMail(), "2", "'2' is not a valid mail id.", caller=self.account)
|
||||
|
|
@ -635,7 +665,7 @@ class TestMail(CommandTest):
|
|||
self.call(mail.CmdMail(), "Char=Message 1", "You have received a new @mail from Char|You sent your message.", caller=self.char1)
|
||||
self.call(mail.CmdMail(), "Char=Message 2", "You sent your message.", caller=self.char2)
|
||||
self.call(mail.CmdMail(), "TestAccount2=Message 2",
|
||||
"You have received a new @mail from TestAccount2(account 2)|You sent your message.", caller=self.account2)
|
||||
"You have received a new @mail from TestAccount2(account 2)|You sent your message.", caller=self.account2)
|
||||
self.call(mail.CmdMail(), "TestAccount=Message 1", "You sent your message.", caller=self.account2)
|
||||
self.call(mail.CmdMail(), "TestAccount=Message 2", "You sent your message.", caller=self.account2)
|
||||
self.call(mail.CmdMail(), "", "| ID: From: Subject:", caller=self.account)
|
||||
|
|
@ -646,21 +676,23 @@ class TestMail(CommandTest):
|
|||
|
||||
# test map builder contrib
|
||||
|
||||
|
||||
from evennia.contrib import mapbuilder
|
||||
|
||||
|
||||
class TestMapBuilder(CommandTest):
|
||||
def test_cmdmapbuilder(self):
|
||||
self.call(mapbuilder.CmdMapBuilder(),
|
||||
"evennia.contrib.mapbuilder.EXAMPLE1_MAP evennia.contrib.mapbuilder.EXAMPLE1_LEGEND",
|
||||
"""Creating Map...|≈≈≈≈≈
|
||||
"evennia.contrib.mapbuilder.EXAMPLE1_MAP evennia.contrib.mapbuilder.EXAMPLE1_LEGEND",
|
||||
"""Creating Map...|≈≈≈≈≈
|
||||
≈♣n♣≈
|
||||
≈∩▲∩≈
|
||||
≈♠n♠≈
|
||||
≈≈≈≈≈
|
||||
|Creating Landmass...|""")
|
||||
self.call(mapbuilder.CmdMapBuilder(),
|
||||
"evennia.contrib.mapbuilder.EXAMPLE2_MAP evennia.contrib.mapbuilder.EXAMPLE2_LEGEND",
|
||||
"""Creating Map...|≈ ≈ ≈ ≈ ≈
|
||||
"evennia.contrib.mapbuilder.EXAMPLE2_MAP evennia.contrib.mapbuilder.EXAMPLE2_LEGEND",
|
||||
"""Creating Map...|≈ ≈ ≈ ≈ ≈
|
||||
|
||||
≈ ♣♣♣ ≈
|
||||
≈ ♣ ♣ ♣ ≈
|
||||
|
|
@ -674,6 +706,7 @@ class TestMapBuilder(CommandTest):
|
|||
|
||||
from evennia.contrib import menu_login
|
||||
|
||||
|
||||
class TestMenuLogin(CommandTest):
|
||||
def test_cmdunloggedlook(self):
|
||||
self.call(menu_login.CmdUnloggedinLook(), "", "======")
|
||||
|
|
@ -683,28 +716,31 @@ class TestMenuLogin(CommandTest):
|
|||
|
||||
from evennia.contrib import multidescer
|
||||
|
||||
|
||||
class TestMultidescer(CommandTest):
|
||||
def test_cmdmultidesc(self):
|
||||
self.call(multidescer.CmdMultiDesc(),"/list", "Stored descs:\ncaller:")
|
||||
self.call(multidescer.CmdMultiDesc(),"test = Desc 1", "Stored description 'test': \"Desc 1\"")
|
||||
self.call(multidescer.CmdMultiDesc(),"test2 = Desc 2", "Stored description 'test2': \"Desc 2\"")
|
||||
self.call(multidescer.CmdMultiDesc(),"/swap test-test2", "Swapped descs 'test' and 'test2'.")
|
||||
self.call(multidescer.CmdMultiDesc(),"test3 = Desc 3init", "Stored description 'test3': \"Desc 3init\"")
|
||||
self.call(multidescer.CmdMultiDesc(),"/list", "Stored descs:\ntest3: Desc 3init\ntest: Desc 1\ntest2: Desc 2\ncaller:")
|
||||
self.call(multidescer.CmdMultiDesc(),"test3 = Desc 3", "Stored description 'test3': \"Desc 3\"")
|
||||
self.call(multidescer.CmdMultiDesc(),"/set test1 + test2 + + test3", "test1 Desc 2 Desc 3\n\n"
|
||||
"The above was set as the current description.")
|
||||
self.call(multidescer.CmdMultiDesc(), "/list", "Stored descs:\ncaller:")
|
||||
self.call(multidescer.CmdMultiDesc(), "test = Desc 1", "Stored description 'test': \"Desc 1\"")
|
||||
self.call(multidescer.CmdMultiDesc(), "test2 = Desc 2", "Stored description 'test2': \"Desc 2\"")
|
||||
self.call(multidescer.CmdMultiDesc(), "/swap test-test2", "Swapped descs 'test' and 'test2'.")
|
||||
self.call(multidescer.CmdMultiDesc(), "test3 = Desc 3init", "Stored description 'test3': \"Desc 3init\"")
|
||||
self.call(multidescer.CmdMultiDesc(), "/list", "Stored descs:\ntest3: Desc 3init\ntest: Desc 1\ntest2: Desc 2\ncaller:")
|
||||
self.call(multidescer.CmdMultiDesc(), "test3 = Desc 3", "Stored description 'test3': \"Desc 3\"")
|
||||
self.call(multidescer.CmdMultiDesc(), "/set test1 + test2 + + test3", "test1 Desc 2 Desc 3\n\n"
|
||||
"The above was set as the current description.")
|
||||
self.assertEqual(self.char1.db.desc, "test1 Desc 2 Desc 3")
|
||||
|
||||
# test simpledoor contrib
|
||||
|
||||
|
||||
from evennia.contrib import simpledoor
|
||||
|
||||
|
||||
class TestSimpleDoor(CommandTest):
|
||||
def test_cmdopen(self):
|
||||
self.call(simpledoor.CmdOpen(), "newdoor;door:contrib.simpledoor.SimpleDoor,backdoor;door = Room2",
|
||||
"Created new Exit 'newdoor' from Room to Room2 (aliases: door).|Note: A doortype exit was "
|
||||
"created ignored eventual custom returnexit type.|Created new Exit 'newdoor' from Room2 to Room (aliases: door).")
|
||||
"Created new Exit 'newdoor' from Room to Room2 (aliases: door).|Note: A doortype exit was "
|
||||
"created ignored eventual custom returnexit type.|Created new Exit 'newdoor' from Room2 to Room (aliases: door).")
|
||||
self.call(simpledoor.CmdOpenCloseDoor(), "newdoor", "You close newdoor.", cmdstring="close")
|
||||
self.call(simpledoor.CmdOpenCloseDoor(), "newdoor", "newdoor is already closed.", cmdstring="close")
|
||||
self.call(simpledoor.CmdOpenCloseDoor(), "newdoor", "You open newdoor.", cmdstring="open")
|
||||
|
|
@ -712,8 +748,10 @@ class TestSimpleDoor(CommandTest):
|
|||
|
||||
# test slow_exit contrib
|
||||
|
||||
|
||||
from evennia.contrib import slow_exit
|
||||
slow_exit.MOVE_DELAY = {"stroll":0, "walk": 0, "run": 0, "sprint": 0}
|
||||
slow_exit.MOVE_DELAY = {"stroll": 0, "walk": 0, "run": 0, "sprint": 0}
|
||||
|
||||
|
||||
class TestSlowExit(CommandTest):
|
||||
def test_exit(self):
|
||||
|
|
@ -724,12 +762,14 @@ class TestSlowExit(CommandTest):
|
|||
|
||||
# test talking npc contrib
|
||||
|
||||
|
||||
from evennia.contrib import talking_npc
|
||||
|
||||
|
||||
class TestTalkingNPC(CommandTest):
|
||||
def test_talkingnpc(self):
|
||||
npc = create_object(talking_npc.TalkingNPC, key="npctalker", location=self.room1)
|
||||
self.call(talking_npc.CmdTalk(), "","(You walk up and talk to Char.)|")
|
||||
self.call(talking_npc.CmdTalk(), "", "(You walk up and talk to Char.)|")
|
||||
npc.delete()
|
||||
|
||||
|
||||
|
|
@ -739,6 +779,7 @@ class TestTalkingNPC(CommandTest):
|
|||
|
||||
from evennia.contrib.tutorial_world import mob
|
||||
|
||||
|
||||
class TestTutorialWorldMob(EvenniaTest):
|
||||
def test_mob(self):
|
||||
mobobj = create_object(mob.Mob, key="mob")
|
||||
|
|
@ -748,28 +789,34 @@ class TestTutorialWorldMob(EvenniaTest):
|
|||
mobobj.set_dead()
|
||||
self.assertEqual(mobobj.db.is_dead, True)
|
||||
mobobj._set_ticker(0, "foo", stop=True)
|
||||
#TODO should be expanded with further tests of the modes and damage etc.
|
||||
# TODO should be expanded with further tests of the modes and damage etc.
|
||||
|
||||
# test tutorial_world/objects
|
||||
|
||||
|
||||
from evennia.contrib.tutorial_world import objects as tutobjects
|
||||
|
||||
|
||||
class TestTutorialWorldObjects(CommandTest):
|
||||
def test_tutorialobj(self):
|
||||
obj1 = create_object(tutobjects.TutorialObject, key="tutobj")
|
||||
obj1.reset()
|
||||
self.assertEqual(obj1.location, obj1.home)
|
||||
|
||||
def test_readable(self):
|
||||
readable = create_object(tutobjects.Readable, key="book", location=self.room1)
|
||||
readable.db.readable_text = "Text to read"
|
||||
self.call(tutobjects.CmdRead(), "book","You read book:\n Text to read", obj=readable)
|
||||
self.call(tutobjects.CmdRead(), "book", "You read book:\n Text to read", obj=readable)
|
||||
|
||||
def test_climbable(self):
|
||||
climbable = create_object(tutobjects.Climbable, key="tree", location=self.room1)
|
||||
self.call(tutobjects.CmdClimb(), "tree", "You climb tree. Having looked around, you climb down again.", obj=climbable)
|
||||
self.assertEqual(self.char1.tags.get("tutorial_climbed_tree", category="tutorial_world"), "tutorial_climbed_tree")
|
||||
|
||||
def test_obelisk(self):
|
||||
obelisk = create_object(tutobjects.Obelisk, key="obelisk", location=self.room1)
|
||||
self.assertEqual(obelisk.return_appearance(self.char1).startswith("|cobelisk("), True)
|
||||
|
||||
def test_lightsource(self):
|
||||
light = create_object(tutobjects.LightSource, key="torch", location=self.room1)
|
||||
self.call(tutobjects.CmdLight(), "", "You light torch.", obj=light)
|
||||
|
|
@ -777,39 +824,44 @@ class TestTutorialWorldObjects(CommandTest):
|
|||
if hasattr(light, "deferred"):
|
||||
light.deferred.cancel()
|
||||
self.assertFalse(light.pk)
|
||||
|
||||
def test_crumblingwall(self):
|
||||
wall = create_object(tutobjects.CrumblingWall, key="wall", location=self.room1)
|
||||
self.assertFalse(wall.db.button_exposed)
|
||||
self.assertFalse(wall.db.exit_open)
|
||||
wall.db.root_pos = {"yellow":0, "green":0,"red":0,"blue":0}
|
||||
wall.db.root_pos = {"yellow": 0, "green": 0, "red": 0, "blue": 0}
|
||||
self.call(tutobjects.CmdShiftRoot(), "blue root right",
|
||||
"You shove the root adorned with small blue flowers to the right.", obj=wall)
|
||||
"You shove the root adorned with small blue flowers to the right.", obj=wall)
|
||||
self.call(tutobjects.CmdShiftRoot(), "red root left",
|
||||
"You shift the reddish root to the left.", obj=wall)
|
||||
"You shift the reddish root to the left.", obj=wall)
|
||||
self.call(tutobjects.CmdShiftRoot(), "yellow root down",
|
||||
"You shove the root adorned with small yellow flowers downwards.", obj=wall)
|
||||
"You shove the root adorned with small yellow flowers downwards.", obj=wall)
|
||||
self.call(tutobjects.CmdShiftRoot(), "green root up",
|
||||
"You shift the weedy green root upwards.|Holding aside the root you think you notice something behind it ...", obj=wall)
|
||||
"You shift the weedy green root upwards.|Holding aside the root you think you notice something behind it ...", obj=wall)
|
||||
self.call(tutobjects.CmdPressButton(), "",
|
||||
"You move your fingers over the suspicious depression, then gives it a decisive push. First", obj=wall)
|
||||
"You move your fingers over the suspicious depression, then gives it a decisive push. First", obj=wall)
|
||||
self.assertTrue(wall.db.button_exposed)
|
||||
self.assertTrue(wall.db.exit_open)
|
||||
wall.reset()
|
||||
if hasattr(wall, "deferred"):
|
||||
wall.deferred.cancel()
|
||||
wall.delete()
|
||||
|
||||
def test_weapon(self):
|
||||
weapon = create_object(tutobjects.Weapon, key="sword", location=self.char1)
|
||||
self.call(tutobjects.CmdAttack(), "Char", "You stab with sword.", obj=weapon, cmdstring="stab")
|
||||
self.call(tutobjects.CmdAttack(), "Char", "You slash with sword.", obj=weapon, cmdstring="slash")
|
||||
|
||||
def test_weaponrack(self):
|
||||
rack = create_object(tutobjects.WeaponRack, key="rack", location=self.room1)
|
||||
rack.db.available_weapons = ["sword"]
|
||||
self.call(tutobjects.CmdGetWeapon(), "", "You find Rusty sword.", obj=rack)
|
||||
|
||||
|
||||
# test tutorial_world/
|
||||
from evennia.contrib.tutorial_world import rooms as tutrooms
|
||||
|
||||
|
||||
class TestTutorialWorldRooms(CommandTest):
|
||||
def test_cmdtutorial(self):
|
||||
room = create_object(tutrooms.TutorialRoom, key="tutroom")
|
||||
|
|
@ -820,14 +872,17 @@ class TestTutorialWorldRooms(CommandTest):
|
|||
self.call(tutrooms.CmdTutorialLook(), "detail", "A detail", obj=room)
|
||||
self.call(tutrooms.CmdTutorialLook(), "foo", "A detail", obj=room)
|
||||
room.delete()
|
||||
|
||||
def test_weatherroom(self):
|
||||
room = create_object(tutrooms.WeatherRoom, key="weatherroom")
|
||||
room.update_weather()
|
||||
tutrooms.TICKER_HANDLER.remove(interval=room.db.interval, callback=room.update_weather, idstring="tutorial")
|
||||
room.delete()
|
||||
|
||||
def test_introroom(self):
|
||||
room = create_object(tutrooms.IntroRoom, key="introroom")
|
||||
room.at_object_receive(self.char1, self.room1)
|
||||
|
||||
def test_bridgeroom(self):
|
||||
room = create_object(tutrooms.BridgeRoom, key="bridgeroom")
|
||||
room.update_weather()
|
||||
|
|
@ -837,19 +892,24 @@ class TestTutorialWorldRooms(CommandTest):
|
|||
room.at_object_leave(self.char1, self.room1)
|
||||
tutrooms.TICKER_HANDLER.remove(interval=room.db.interval, callback=room.update_weather, idstring="tutorial")
|
||||
room.delete()
|
||||
|
||||
def test_darkroom(self):
|
||||
room = create_object(tutrooms.DarkRoom, key="darkroom")
|
||||
self.char1.move_to(room)
|
||||
self.call(tutrooms.CmdDarkHelp(), "", "Can't help you until")
|
||||
|
||||
def test_teleportroom(self):
|
||||
create_object(tutrooms.TeleportRoom, key="teleportroom")
|
||||
|
||||
def test_outroroom(self):
|
||||
create_object(tutrooms.OutroRoom, key="outroroom")
|
||||
|
||||
|
||||
# test turnbattle
|
||||
from evennia.contrib import turnbattle
|
||||
from evennia.objects.objects import DefaultRoom
|
||||
|
||||
|
||||
class TestTurnBattleCmd(CommandTest):
|
||||
|
||||
# Test combat commands
|
||||
|
|
@ -860,6 +920,7 @@ class TestTurnBattleCmd(CommandTest):
|
|||
self.call(turnbattle.CmdDisengage(), "", "You can only do that in combat. (see: help fight)")
|
||||
self.call(turnbattle.CmdRest(), "", "Char rests to recover HP.")
|
||||
|
||||
|
||||
class TestTurnBattleFunc(EvenniaTest):
|
||||
|
||||
# Test combat functions
|
||||
|
|
@ -944,6 +1005,7 @@ class TestTurnBattleFunc(EvenniaTest):
|
|||
|
||||
from evennia.contrib.unixcommand import UnixCommand
|
||||
|
||||
|
||||
class CmdDummy(UnixCommand):
|
||||
|
||||
"""A dummy UnixCommand."""
|
||||
|
|
@ -991,6 +1053,7 @@ class TestUnixCommand(CommandTest):
|
|||
import re
|
||||
from evennia.contrib import color_markups
|
||||
|
||||
|
||||
class TestColorMarkup(EvenniaTest):
|
||||
"""
|
||||
Note: Normally this would be tested by importing the ansi parser and run
|
||||
|
|
@ -999,6 +1062,7 @@ class TestColorMarkup(EvenniaTest):
|
|||
many other modules it appears that trying to overload
|
||||
settings to test it causes issues with unrelated tests.
|
||||
"""
|
||||
|
||||
def test_curly_markup(self):
|
||||
ansi_map = color_markups.CURLY_COLOR_ANSI_EXTRA_MAP
|
||||
self.assertIsNotNone(re.match(re.escape(ansi_map[7][0]), '{r'))
|
||||
|
|
@ -1047,10 +1111,12 @@ class TestColorMarkup(EvenniaTest):
|
|||
self.assertEqual(bright_map[0][1], '%c[500')
|
||||
self.assertEqual(bright_map[-1][1], '%c[222')
|
||||
|
||||
|
||||
from evennia.contrib import random_string_generator
|
||||
|
||||
SIMPLE_GENERATOR = random_string_generator.RandomStringGenerator("simple", "[01]{2}")
|
||||
|
||||
|
||||
class TestRandomStringGenerator(EvenniaTest):
|
||||
|
||||
def test_generate(self):
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ make sure to put it on yourself or you won't see any messages!
|
|||
import random
|
||||
from evennia import DefaultScript
|
||||
|
||||
|
||||
class BodyFunctions(DefaultScript):
|
||||
"""
|
||||
This class defines the script itself
|
||||
|
|
@ -21,7 +22,7 @@ class BodyFunctions(DefaultScript):
|
|||
self.key = "bodyfunction"
|
||||
self.desc = "Adds various timed events to a character."
|
||||
self.interval = 20 # seconds
|
||||
#self.repeats = 5 # repeat only a certain number of times
|
||||
# self.repeats = 5 # repeat only a certain number of times
|
||||
self.start_delay = True # wait self.interval until first call
|
||||
#self.persistent = True
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ class CmdSmashGlass(Command):
|
|||
string += " you should just try to open the lid instead?"
|
||||
self.caller.msg(string)
|
||||
self.caller.location.msg_contents("%s tries to smash the glass of the button." %
|
||||
(self.caller.name), exclude=self.caller)
|
||||
(self.caller.name), exclude=self.caller)
|
||||
|
||||
|
||||
class CmdOpenLid(Command):
|
||||
|
|
@ -146,7 +146,7 @@ class CmdOpenLid(Command):
|
|||
string += "the lid will soon close again."
|
||||
self.caller.msg(string)
|
||||
self.caller.location.msg_contents("%s opens the lid of the button." %
|
||||
(self.caller.name), exclude=self.caller)
|
||||
(self.caller.name), exclude=self.caller)
|
||||
# add the relevant cmdsets to button
|
||||
self.obj.cmdset.add(LidClosedCmdSet)
|
||||
# call object method
|
||||
|
|
@ -213,7 +213,7 @@ class CmdBlindLook(Command):
|
|||
string += "Until it wears off, all you can do is feel around blindly."
|
||||
self.caller.msg(string)
|
||||
self.caller.location.msg_contents("%s stumbles around, blinded." %
|
||||
(self.caller.name), exclude=self.caller)
|
||||
(self.caller.name), exclude=self.caller)
|
||||
|
||||
|
||||
class CmdBlindHelp(Command):
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#
|
||||
|
||||
|
||||
#HEADER
|
||||
# HEADER
|
||||
|
||||
# everything in this block will be appended to the beginning of
|
||||
# all other #CODE blocks when they are executed.
|
||||
|
|
@ -51,7 +51,7 @@ from evennia import DefaultObject
|
|||
limbo = search_object('Limbo')[0]
|
||||
|
||||
|
||||
#CODE
|
||||
# CODE
|
||||
|
||||
# This is the first code block. Within each block, Python
|
||||
# code works as normal. Note how we make use if imports and
|
||||
|
|
@ -61,12 +61,12 @@ limbo = search_object('Limbo')[0]
|
|||
|
||||
# create a red button in limbo
|
||||
red_button = create_object(red_button.RedButton, key="Red button",
|
||||
location=limbo, aliases=["button"])
|
||||
location=limbo, aliases=["button"])
|
||||
|
||||
# we take a look at what we created
|
||||
caller.msg("A %s was created." % red_button.key)
|
||||
|
||||
#CODE
|
||||
# CODE
|
||||
|
||||
# this code block has 'table' and 'chair' set as deletable
|
||||
# objects. This means that when the batchcode processor runs in
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class RedButton(DefaultObject):
|
|||
desc_lamp_broken - description when lamp is broken
|
||||
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
This function is called when object is created. Use this
|
||||
|
|
|
|||
|
|
@ -26,12 +26,14 @@ from evennia.contrib.tutorial_examples import cmdset_red_button as cmdsetexample
|
|||
# a bright light. The last one also has a timer component that allows it
|
||||
# to remove itself after a while (and the player recovers their eyesight).
|
||||
|
||||
|
||||
class ClosedLidState(DefaultScript):
|
||||
"""
|
||||
This manages the cmdset for the "closed" button state. What this
|
||||
means is that while this script is valid, we add the RedButtonClosed
|
||||
cmdset to it (with commands like open, nudge lid etc)
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"Called when script first created."
|
||||
self.desc = "Script that manages the closed-state cmdsets for red button."
|
||||
|
|
@ -44,7 +46,7 @@ class ClosedLidState(DefaultScript):
|
|||
checked so we don't need to worry about adding the script to an
|
||||
open lid.
|
||||
"""
|
||||
#All we do is add the cmdset for the closed state.
|
||||
# All we do is add the cmdset for the closed state.
|
||||
self.obj.cmdset.add(cmdsetexamples.LidClosedCmdSet)
|
||||
|
||||
def is_valid(self):
|
||||
|
|
@ -67,6 +69,7 @@ class OpenLidState(DefaultScript):
|
|||
This manages the cmdset for the "open" button state. This will add
|
||||
the RedButtonOpen
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"Called when script first created."
|
||||
self.desc = "Script that manages the opened-state cmdsets for red button."
|
||||
|
|
@ -105,6 +108,7 @@ class BlindedState(DefaultScript):
|
|||
restored. It's up to the function starting the script to actually
|
||||
set it on the right account object.
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
We set up the script here.
|
||||
|
|
@ -139,7 +143,7 @@ class BlindedState(DefaultScript):
|
|||
% self.obj.name,
|
||||
exclude=self.obj)
|
||||
self.obj.cmdset.delete() # this will clear the latest added cmdset,
|
||||
# (which is the blinded one).
|
||||
# (which is the blinded one).
|
||||
|
||||
|
||||
#
|
||||
|
|
@ -158,6 +162,7 @@ class CloseLidEvent(DefaultScript):
|
|||
script that should be started/created when the
|
||||
lid is opened.
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
Called when script object is first created. Sets things up.
|
||||
|
|
@ -172,7 +177,7 @@ class CloseLidEvent(DefaultScript):
|
|||
self.start_delay = True # we want to pospone the launch.
|
||||
self.repeats = 1 # we only close the lid once
|
||||
self.persistent = True # even if the server crashes in those 20 seconds,
|
||||
# the lid will still close once the game restarts.
|
||||
# the lid will still close once the game restarts.
|
||||
|
||||
def is_valid(self):
|
||||
"""
|
||||
|
|
@ -194,10 +199,12 @@ class CloseLidEvent(DefaultScript):
|
|||
"""
|
||||
self.obj.close_lid()
|
||||
|
||||
|
||||
class BlinkButtonEvent(DefaultScript):
|
||||
"""
|
||||
This timed script lets the button flash at regular intervals.
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
Sets things up. We want the button's lamp to blink at
|
||||
|
|
@ -206,9 +213,9 @@ class BlinkButtonEvent(DefaultScript):
|
|||
"""
|
||||
self.key = "blink_button"
|
||||
self.desc = "Blinks red buttons"
|
||||
self.interval = 35 #seconds
|
||||
self.start_delay = False #blink right away
|
||||
self.persistent = True #keep blinking also after server reboot
|
||||
self.interval = 35 # seconds
|
||||
self.start_delay = False # blink right away
|
||||
self.persistent = True # keep blinking also after server reboot
|
||||
|
||||
def is_valid(self):
|
||||
"""
|
||||
|
|
@ -223,6 +230,7 @@ class BlinkButtonEvent(DefaultScript):
|
|||
"""
|
||||
self.obj.blink()
|
||||
|
||||
|
||||
class DeactivateButtonEvent(DefaultScript):
|
||||
"""
|
||||
This deactivates the button for a short while (it won't blink, won't
|
||||
|
|
@ -231,13 +239,14 @@ class DeactivateButtonEvent(DefaultScript):
|
|||
in the AddBlindedCmdSet script since that script is defined on the *account*
|
||||
whereas this one must be defined on the *button*.
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
Sets things up.
|
||||
"""
|
||||
self.key = "deactivate_button"
|
||||
self.desc = "Deactivate red button temporarily"
|
||||
self.interval = 21 #seconds
|
||||
self.interval = 21 # seconds
|
||||
self.start_delay = True # wait with the first repeat for self.interval seconds.
|
||||
self.persistent = True
|
||||
self.repeats = 1 # only do this once
|
||||
|
|
|
|||
|
|
@ -5,4 +5,3 @@ This package holds the demo game of Evennia.
|
|||
from __future__ import absolute_import
|
||||
|
||||
from . import mob, objects, rooms
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from evennia import Command, CmdSet
|
|||
from evennia import logger
|
||||
from evennia.contrib.tutorial_world import objects as tut_objects
|
||||
|
||||
|
||||
class CmdMobOnOff(Command):
|
||||
"""
|
||||
Activates/deactivates Mob
|
||||
|
|
@ -51,9 +52,11 @@ class MobCmdSet(CmdSet):
|
|||
"""
|
||||
Holds the admin command controlling the mob
|
||||
"""
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
self.add(CmdMobOnOff())
|
||||
|
||||
|
||||
class Mob(tut_objects.TutorialObject):
|
||||
"""
|
||||
This is a state-machine AI mobile. It has several states which are
|
||||
|
|
@ -91,6 +94,7 @@ class Mob(tut_objects.TutorialObject):
|
|||
happen to roam into a room with no exits.
|
||||
|
||||
"""
|
||||
|
||||
def at_init(self):
|
||||
"""
|
||||
When initialized from cache (after a server reboot), set up
|
||||
|
|
@ -122,7 +126,7 @@ class Mob(tut_objects.TutorialObject):
|
|||
self.db.patrolling_pace = 6
|
||||
self.db.aggressive_pace = 2
|
||||
self.db.hunting_pace = 1
|
||||
self.db.death_pace = 100 # stay dead for 100 seconds
|
||||
self.db.death_pace = 100 # stay dead for 100 seconds
|
||||
|
||||
# we store the call to the tickerhandler
|
||||
# so we can easily deactivate the last
|
||||
|
|
@ -179,19 +183,19 @@ class Mob(tut_objects.TutorialObject):
|
|||
we need to remember this across reloads.
|
||||
|
||||
"""
|
||||
idstring = "tutorial_mob" # this doesn't change
|
||||
idstring = "tutorial_mob" # this doesn't change
|
||||
last_interval = self.db.last_ticker_interval
|
||||
last_hook_key = self.db.last_hook_key
|
||||
if last_interval and last_hook_key:
|
||||
# we have a previous subscription, kill this first.
|
||||
TICKER_HANDLER.remove(interval=last_interval,
|
||||
callback=getattr(self, last_hook_key), idstring=idstring)
|
||||
callback=getattr(self, last_hook_key), idstring=idstring)
|
||||
self.db.last_ticker_interval = interval
|
||||
self.db.last_hook_key = hook_key
|
||||
if not stop:
|
||||
# set the new ticker
|
||||
TICKER_HANDLER.add(interval=interval,
|
||||
callback=getattr(self, hook_key), idstring=idstring)
|
||||
callback=getattr(self, hook_key), idstring=idstring)
|
||||
|
||||
def _find_target(self, location):
|
||||
"""
|
||||
|
|
@ -206,7 +210,7 @@ class Mob(tut_objects.TutorialObject):
|
|||
|
||||
"""
|
||||
targets = [obj for obj in location.contents_get(exclude=self)
|
||||
if obj.has_account and not obj.is_superuser]
|
||||
if obj.has_account and not obj.is_superuser]
|
||||
return targets[0] if targets else None
|
||||
|
||||
def set_alive(self, *args, **kwargs):
|
||||
|
|
@ -379,7 +383,6 @@ class Mob(tut_objects.TutorialObject):
|
|||
else:
|
||||
logger.log_err("Mob: mob.db.send_defeated_to not found: %s" % self.db.send_defeated_to)
|
||||
|
||||
|
||||
# response methods - called by other objects
|
||||
|
||||
def at_hit(self, weapon, attacker, damage):
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ class CmdSetReadable(CmdSet):
|
|||
"""
|
||||
A CmdSet for readables.
|
||||
"""
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"""
|
||||
Called when the cmdset is created.
|
||||
|
|
@ -117,6 +118,7 @@ class Readable(TutorialObject):
|
|||
"""
|
||||
This simple object defines some attributes and
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
Called when object is created. We make sure to set the needed
|
||||
|
|
@ -176,6 +178,7 @@ class CmdClimb(Command):
|
|||
|
||||
class CmdSetClimbable(CmdSet):
|
||||
"""Climbing cmdset"""
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"""populate set"""
|
||||
self.add(CmdClimb())
|
||||
|
|
@ -303,6 +306,7 @@ class LightSource(TutorialObject):
|
|||
|
||||
When burned out, the object will be deleted.
|
||||
"""
|
||||
|
||||
def at_init(self):
|
||||
"""
|
||||
If this is called with the Attribute is_giving_light already
|
||||
|
|
@ -589,6 +593,7 @@ class CrumblingWall(TutorialObject, DefaultExit):
|
|||
whenever the button is pushed (this hides it as an exit
|
||||
until it actually is)
|
||||
"""
|
||||
|
||||
def at_init(self):
|
||||
"""
|
||||
Called when object is recalled from cache.
|
||||
|
|
@ -838,6 +843,7 @@ class CmdAttack(Command):
|
|||
|
||||
class CmdSetWeapon(CmdSet):
|
||||
"""Holds the attack command."""
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"""called at first object creation."""
|
||||
self.add(CmdAttack())
|
||||
|
|
@ -854,6 +860,7 @@ class Weapon(TutorialObject):
|
|||
type of attack) (0-10)
|
||||
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""Called at first creation of the object"""
|
||||
super(Weapon, self).at_object_creation()
|
||||
|
|
@ -987,7 +994,7 @@ WEAPON_PROTOTYPES = {
|
|||
"hit": 0.85,
|
||||
"parry": 0.7,
|
||||
"damage": 11}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CmdGetWeapon(Command):
|
||||
|
|
@ -1037,6 +1044,7 @@ class WeaponRack(TutorialObject):
|
|||
grab another one.
|
||||
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
called at creation
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@ class TutorialRoom(DefaultRoom):
|
|||
This is the base room type for all rooms in the tutorial world.
|
||||
It defines a cmdset on itself for reading tutorial info about the location.
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""Called when room is first created"""
|
||||
self.db.tutorial_info = "This is a tutorial room. It allows you to use the 'tutorial' command."
|
||||
|
|
@ -278,17 +279,17 @@ class TutorialRoom(DefaultRoom):
|
|||
|
||||
# These are rainy weather strings
|
||||
WEATHER_STRINGS = (
|
||||
"The rain coming down from the iron-grey sky intensifies.",
|
||||
"A gust of wind throws the rain right in your face. Despite your cloak you shiver.",
|
||||
"The rainfall eases a bit and the sky momentarily brightens.",
|
||||
"For a moment it looks like the rain is slowing, then it begins anew with renewed force.",
|
||||
"The rain pummels you with large, heavy drops. You hear the rumble of thunder in the distance.",
|
||||
"The wind is picking up, howling around you, throwing water droplets in your face. It's cold.",
|
||||
"Bright fingers of lightning flash over the sky, moments later followed by a deafening rumble.",
|
||||
"It rains so hard you can hardly see your hand in front of you. You'll soon be drenched to the bone.",
|
||||
"Lightning strikes in several thundering bolts, striking the trees in the forest to your west.",
|
||||
"You hear the distant howl of what sounds like some sort of dog or wolf.",
|
||||
"Large clouds rush across the sky, throwing their load of rain over the world.")
|
||||
"The rain coming down from the iron-grey sky intensifies.",
|
||||
"A gust of wind throws the rain right in your face. Despite your cloak you shiver.",
|
||||
"The rainfall eases a bit and the sky momentarily brightens.",
|
||||
"For a moment it looks like the rain is slowing, then it begins anew with renewed force.",
|
||||
"The rain pummels you with large, heavy drops. You hear the rumble of thunder in the distance.",
|
||||
"The wind is picking up, howling around you, throwing water droplets in your face. It's cold.",
|
||||
"Bright fingers of lightning flash over the sky, moments later followed by a deafening rumble.",
|
||||
"It rains so hard you can hardly see your hand in front of you. You'll soon be drenched to the bone.",
|
||||
"Lightning strikes in several thundering bolts, striking the trees in the forest to your west.",
|
||||
"You hear the distant howl of what sounds like some sort of dog or wolf.",
|
||||
"Large clouds rush across the sky, throwing their load of rain over the world.")
|
||||
|
||||
|
||||
class WeatherRoom(TutorialRoom):
|
||||
|
|
@ -300,6 +301,7 @@ class WeatherRoom(TutorialRoom):
|
|||
inherit from this.
|
||||
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
Called when object is first created.
|
||||
|
|
@ -355,6 +357,7 @@ class IntroRoom(TutorialRoom):
|
|||
properties to customize:
|
||||
char_health - integer > 0 (default 20)
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
Called when the room is first created.
|
||||
|
|
@ -377,7 +380,7 @@ class IntroRoom(TutorialRoom):
|
|||
character.db.health_max = health
|
||||
|
||||
if character.is_superuser:
|
||||
string = "-"*78 + SUPERUSER_WARNING + "-"*78
|
||||
string = "-" * 78 + SUPERUSER_WARNING + "-" * 78
|
||||
character.msg("|r%s|n" % string.format(name=character.key, quell="|w@quell|r"))
|
||||
|
||||
|
||||
|
|
@ -589,16 +592,16 @@ class BridgeCmdSet(CmdSet):
|
|||
|
||||
|
||||
BRIDGE_WEATHER = (
|
||||
"The rain intensifies, making the planks of the bridge even more slippery.",
|
||||
"A gust of wind throws the rain right in your face.",
|
||||
"The rainfall eases a bit and the sky momentarily brightens.",
|
||||
"The bridge shakes under the thunder of a closeby thunder strike.",
|
||||
"The rain pummels you with large, heavy drops. You hear the distinct howl of a large hound in the distance.",
|
||||
"The wind is picking up, howling around you and causing the bridge to sway from side to side.",
|
||||
"Some sort of large bird sweeps by overhead, giving off an eery screech. Soon it has disappeared in the gloom.",
|
||||
"The bridge sways from side to side in the wind.",
|
||||
"Below you a particularly large wave crashes into the rocks.",
|
||||
"From the ruin you hear a distant, otherwordly howl. Or maybe it was just the wind.")
|
||||
"The rain intensifies, making the planks of the bridge even more slippery.",
|
||||
"A gust of wind throws the rain right in your face.",
|
||||
"The rainfall eases a bit and the sky momentarily brightens.",
|
||||
"The bridge shakes under the thunder of a closeby thunder strike.",
|
||||
"The rain pummels you with large, heavy drops. You hear the distinct howl of a large hound in the distance.",
|
||||
"The wind is picking up, howling around you and causing the bridge to sway from side to side.",
|
||||
"Some sort of large bird sweeps by overhead, giving off an eery screech. Soon it has disappeared in the gloom.",
|
||||
"The bridge sways from side to side in the wind.",
|
||||
"Below you a particularly large wave crashes into the rocks.",
|
||||
"From the ruin you hear a distant, otherwordly howl. Or maybe it was just the wind.")
|
||||
|
||||
|
||||
class BridgeRoom(WeatherRoom):
|
||||
|
|
@ -625,6 +628,7 @@ class BridgeRoom(WeatherRoom):
|
|||
the CmdLookBridge command).
|
||||
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""Setups the room"""
|
||||
# this will start the weather room's ticker and tell
|
||||
|
|
@ -827,6 +831,7 @@ class DarkRoom(TutorialRoom):
|
|||
may have been beaten up by the ghostly apparition at this point.
|
||||
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
Called when object is first created.
|
||||
|
|
@ -942,6 +947,7 @@ class TeleportRoom(TutorialRoom):
|
|||
failure_teleport_msg - message to echo while teleporting to failure
|
||||
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"""Called at first creation"""
|
||||
super(TeleportRoom, self).at_object_creation()
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ class UnixCommandParser(argparse.ArgumentParser):
|
|||
"""
|
||||
prog = prog or command.key
|
||||
super(UnixCommandParser, self).__init__(
|
||||
prog=prog, description=description,
|
||||
conflict_handler='resolve', add_help=False, **kwargs)
|
||||
prog=prog, description=description,
|
||||
conflict_handler='resolve', add_help=False, **kwargs)
|
||||
self.command = command
|
||||
self.post_help = epilog
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ own cmdsets by inheriting from them or directly from `evennia.CmdSet`.
|
|||
|
||||
from evennia import default_cmds
|
||||
|
||||
|
||||
class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||
"""
|
||||
The `CharacterCmdSet` contains general in-game commands like `look`,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ line to your settings file:
|
|||
|
||||
"""
|
||||
|
||||
|
||||
def at_search_result(matches, caller, query="", quiet=False, **kwargs):
|
||||
"""
|
||||
This is a generic hook for handling all processing of a search
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ your settings file:
|
|||
|
||||
"""
|
||||
|
||||
|
||||
def cmdparser(raw_string, cmdset, caller, match_index=None):
|
||||
"""
|
||||
This function is called by the cmdhandler once it has
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ and can be used to customize it to each session.
|
|||
|
||||
"""
|
||||
|
||||
#def capitalize(text, *args, **kwargs):
|
||||
# def capitalize(text, *args, **kwargs):
|
||||
# "Silly capitalize example. Used as {capitalize() ... {/capitalize"
|
||||
# session = kwargs.get("session")
|
||||
# return text.capitalize()
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ lock functions from evennia.locks.lockfuncs.
|
|||
|
||||
"""
|
||||
|
||||
#def myfalse(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
# def myfalse(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
# """
|
||||
# called in lockstring with myfalse().
|
||||
# A simple logger that always returns false. Prints to stdout
|
||||
|
|
|
|||
|
|
@ -13,105 +13,105 @@ affect uptime).
|
|||
|
||||
"""
|
||||
|
||||
MSSPTable = {
|
||||
MSSPTable = {
|
||||
|
||||
# Required fieldss
|
||||
|
||||
"NAME": "Evennia",
|
||||
"NAME": "Evennia",
|
||||
|
||||
# Generic
|
||||
|
||||
"CRAWL DELAY": "-1", # limit how often crawler updates the listing. -1 for no limit
|
||||
"CRAWL DELAY": "-1", # limit how often crawler updates the listing. -1 for no limit
|
||||
|
||||
"HOSTNAME": "", # current or new hostname
|
||||
"PORT": ["4000"], # most important port should be last in list
|
||||
"CODEBASE": "Evennia",
|
||||
"CONTACT": "", # email for contacting the mud
|
||||
"CREATED": "", # year MUD was created
|
||||
"ICON": "", # url to icon 32x32 or larger; <32kb.
|
||||
"IP": "", # current or new IP address
|
||||
"LANGUAGE": "", # name of language used, e.g. English
|
||||
"LOCATION": "", # full English name of server country
|
||||
"MINIMUM AGE": "0", # set to 0 if not applicable
|
||||
"WEBSITE": "www.evennia.com",
|
||||
"HOSTNAME": "", # current or new hostname
|
||||
"PORT": ["4000"], # most important port should be last in list
|
||||
"CODEBASE": "Evennia",
|
||||
"CONTACT": "", # email for contacting the mud
|
||||
"CREATED": "", # year MUD was created
|
||||
"ICON": "", # url to icon 32x32 or larger; <32kb.
|
||||
"IP": "", # current or new IP address
|
||||
"LANGUAGE": "", # name of language used, e.g. English
|
||||
"LOCATION": "", # full English name of server country
|
||||
"MINIMUM AGE": "0", # set to 0 if not applicable
|
||||
"WEBSITE": "www.evennia.com",
|
||||
|
||||
# Categorisation
|
||||
|
||||
"FAMILY": "Custom", # evennia goes under 'Custom'
|
||||
"GENRE": "None", # Adult, Fantasy, Historical, Horror, Modern, None, or Science Fiction
|
||||
"GAMEPLAY": "", # Adventure, Educational, Hack and Slash, None,
|
||||
# Player versus Player, Player versus Environment,
|
||||
# Roleplaying, Simulation, Social or Strategy
|
||||
"STATUS": "Open Beta", # Alpha, Closed Beta, Open Beta, Live
|
||||
"GAMESYSTEM": "Custom", # D&D, d20 System, World of Darkness, etc. Use Custom if homebrew
|
||||
"SUBGENRE": "None", # LASG, Medieval Fantasy, World War II, Frankenstein,
|
||||
# Cyberpunk, Dragonlance, etc. Or None if not available.
|
||||
"FAMILY": "Custom", # evennia goes under 'Custom'
|
||||
"GENRE": "None", # Adult, Fantasy, Historical, Horror, Modern, None, or Science Fiction
|
||||
"GAMEPLAY": "", # Adventure, Educational, Hack and Slash, None,
|
||||
# Player versus Player, Player versus Environment,
|
||||
# Roleplaying, Simulation, Social or Strategy
|
||||
"STATUS": "Open Beta", # Alpha, Closed Beta, Open Beta, Live
|
||||
"GAMESYSTEM": "Custom", # D&D, d20 System, World of Darkness, etc. Use Custom if homebrew
|
||||
"SUBGENRE": "None", # LASG, Medieval Fantasy, World War II, Frankenstein,
|
||||
# Cyberpunk, Dragonlance, etc. Or None if not available.
|
||||
|
||||
# World
|
||||
|
||||
"AREAS": "0",
|
||||
"HELPFILES": "0",
|
||||
"MOBILES": "0",
|
||||
"OBJECTS": "0",
|
||||
"ROOMS": "0", # use 0 if room-less
|
||||
"CLASSES": "0", # use 0 if class-less
|
||||
"LEVELS": "0", # use 0 if level-less
|
||||
"RACES": "0", # use 0 if race-less
|
||||
"SKILLS": "0", # use 0 if skill-less
|
||||
"AREAS": "0",
|
||||
"HELPFILES": "0",
|
||||
"MOBILES": "0",
|
||||
"OBJECTS": "0",
|
||||
"ROOMS": "0", # use 0 if room-less
|
||||
"CLASSES": "0", # use 0 if class-less
|
||||
"LEVELS": "0", # use 0 if level-less
|
||||
"RACES": "0", # use 0 if race-less
|
||||
"SKILLS": "0", # use 0 if skill-less
|
||||
|
||||
# Protocols set to 1 or 0)
|
||||
|
||||
"ANSI": "1",
|
||||
"GMCP": "1",
|
||||
"ATCP": "0",
|
||||
"MCCP": "0",
|
||||
"MCP": "0",
|
||||
"MSDP": "0",
|
||||
"MSP": "0",
|
||||
"MXP": "0",
|
||||
"PUEBLO": "0",
|
||||
"SSL": "1",
|
||||
"UTF-8": "1",
|
||||
"VT100": "0",
|
||||
"ZMP": "0",
|
||||
"XTERM 256 COLORS": "0",
|
||||
"ANSI": "1",
|
||||
"GMCP": "1",
|
||||
"ATCP": "0",
|
||||
"MCCP": "0",
|
||||
"MCP": "0",
|
||||
"MSDP": "0",
|
||||
"MSP": "0",
|
||||
"MXP": "0",
|
||||
"PUEBLO": "0",
|
||||
"SSL": "1",
|
||||
"UTF-8": "1",
|
||||
"VT100": "0",
|
||||
"ZMP": "0",
|
||||
"XTERM 256 COLORS": "0",
|
||||
|
||||
# Commercial set to 1 or 0)
|
||||
|
||||
"PAY TO PLAY": "0",
|
||||
"PAY FOR PERKS": "0",
|
||||
"PAY TO PLAY": "0",
|
||||
"PAY FOR PERKS": "0",
|
||||
|
||||
# Hiring set to 1 or 0)
|
||||
|
||||
"HIRING BUILDERS": "0",
|
||||
"HIRING CODERS": "0",
|
||||
"HIRING BUILDERS": "0",
|
||||
"HIRING CODERS": "0",
|
||||
|
||||
# Extended variables
|
||||
|
||||
# World
|
||||
|
||||
"DBSIZE": "0",
|
||||
"EXITS": "0",
|
||||
"DBSIZE": "0",
|
||||
"EXITS": "0",
|
||||
"EXTRA DESCRIPTIONS": "0",
|
||||
"MUDPROGS": "0",
|
||||
"MUDTRIGS": "0",
|
||||
"RESETS": "0",
|
||||
"MUDPROGS": "0",
|
||||
"MUDTRIGS": "0",
|
||||
"RESETS": "0",
|
||||
|
||||
# Game (set to 1 or 0, or one of the given alternatives)
|
||||
|
||||
"ADULT MATERIAL": "0",
|
||||
"MULTICLASSING": "0",
|
||||
"NEWBIE FRIENDLY": "0",
|
||||
"PLAYER CITIES": "0",
|
||||
"PLAYER CLANS": "0",
|
||||
"PLAYER CRAFTING": "0",
|
||||
"PLAYER GUILDS": "0",
|
||||
"EQUIPMENT SYSTEM": "None", # "None", "Level", "Skill", "Both"
|
||||
"MULTIPLAYING": "None", # "None", "Restricted", "Full"
|
||||
"PLAYERKILLING": "None", # "None", "Restricted", "Full"
|
||||
"QUEST SYSTEM": "None", # "None", "Immortal Run", "Automated", "Integrated"
|
||||
"ROLEPLAYING": "None", # "None", "Accepted", "Encouraged", "Enforced"
|
||||
"TRAINING SYSTEM": "None", # "None", "Level", "Skill", "Both"
|
||||
"WORLD ORIGINALITY": "None", # "All Stock", "Mostly Stock", "Mostly Original", "All Original"
|
||||
"ADULT MATERIAL": "0",
|
||||
"MULTICLASSING": "0",
|
||||
"NEWBIE FRIENDLY": "0",
|
||||
"PLAYER CITIES": "0",
|
||||
"PLAYER CLANS": "0",
|
||||
"PLAYER CRAFTING": "0",
|
||||
"PLAYER GUILDS": "0",
|
||||
"EQUIPMENT SYSTEM": "None", # "None", "Level", "Skill", "Both"
|
||||
"MULTIPLAYING": "None", # "None", "Restricted", "Full"
|
||||
"PLAYERKILLING": "None", # "None", "Restricted", "Full"
|
||||
"QUEST SYSTEM": "None", # "None", "Immortal Run", "Automated", "Integrated"
|
||||
"ROLEPLAYING": "None", # "None", "Accepted", "Encouraged", "Enforced"
|
||||
"TRAINING SYSTEM": "None", # "None", "Level", "Skill", "Both"
|
||||
"WORLD ORIGINALITY": "None", # "All Stock", "Mostly Stock", "Mostly Original", "All Original"
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ settings file:
|
|||
|
||||
from evennia.server.serversession import ServerSession as BaseServerSession
|
||||
|
||||
|
||||
class ServerSession(BaseServerSession):
|
||||
"""
|
||||
This class represents a player's session and is a template for
|
||||
|
|
|
|||
|
|
@ -26,4 +26,3 @@ def at_webserver_root_creation(web_root):
|
|||
|
||||
"""
|
||||
return web_root
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ several more options for customizing the Guest account system.
|
|||
|
||||
from evennia import DefaultAccount, DefaultGuest
|
||||
|
||||
|
||||
class Account(DefaultAccount):
|
||||
"""
|
||||
This class describes the actual OOC account (i.e. the user connecting
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ to be modified.
|
|||
|
||||
from evennia import DefaultChannel
|
||||
|
||||
|
||||
class Channel(DefaultChannel):
|
||||
"""
|
||||
Working methods:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ creation commands.
|
|||
"""
|
||||
from evennia import DefaultCharacter
|
||||
|
||||
|
||||
class Character(DefaultCharacter):
|
||||
"""
|
||||
The Character defaults to reimplementing some of base Object's hook methods with the
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ for allowing Characters to traverse the exit to its destination.
|
|||
"""
|
||||
from evennia import DefaultExit
|
||||
|
||||
|
||||
class Exit(DefaultExit):
|
||||
"""
|
||||
Exits are connectors between rooms. Exits are normal Objects except
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ inheritance.
|
|||
"""
|
||||
from evennia import DefaultObject
|
||||
|
||||
|
||||
class Object(DefaultObject):
|
||||
"""
|
||||
This is the root typeclass object, implementing an in-game Evennia
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ See the `@spawn` command and `evennia.utils.spawner` for more info.
|
|||
|
||||
#from random import randint
|
||||
#
|
||||
#GOBLIN = {
|
||||
# GOBLIN = {
|
||||
# "key": "goblin grunt",
|
||||
# "health": lambda: randint(20,30),
|
||||
# "resists": ["cold", "poison"],
|
||||
|
|
@ -46,13 +46,13 @@ See the `@spawn` command and `evennia.utils.spawner` for more info.
|
|||
# "weaknesses": ["fire", "light"]
|
||||
# }
|
||||
#
|
||||
#GOBLIN_WIZARD = {
|
||||
# GOBLIN_WIZARD = {
|
||||
# "prototype": "GOBLIN",
|
||||
# "key": "goblin wizard",
|
||||
# "spells": ["fire ball", "lighting bolt"]
|
||||
# }
|
||||
#
|
||||
#GOBLIN_ARCHER = {
|
||||
# GOBLIN_ARCHER = {
|
||||
# "prototype": "GOBLIN",
|
||||
# "key": "goblin archer",
|
||||
# "attacks": ["short bow"]
|
||||
|
|
@ -62,12 +62,12 @@ See the `@spawn` command and `evennia.utils.spawner` for more info.
|
|||
# (nor key) of its own, so it should normally only be
|
||||
# used as a mix-in, as in the example of the goblin
|
||||
# archwizard below.
|
||||
#ARCHWIZARD_MIXIN = {
|
||||
# ARCHWIZARD_MIXIN = {
|
||||
# "attacks": ["archwizard staff"],
|
||||
# "spells": ["greater fire ball", "greater lighting"]
|
||||
#}
|
||||
#
|
||||
#GOBLIN_ARCHWIZARD = {
|
||||
# GOBLIN_ARCHWIZARD = {
|
||||
# "key": "goblin archwizard",
|
||||
# "prototype" : ("GOBLIN_WIZARD", "ARCHWIZARD_MIXIN")
|
||||
#}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ from django.contrib import admin
|
|||
from evennia.help.models import HelpEntry
|
||||
from evennia.typeclasses.admin import TagInline
|
||||
|
||||
|
||||
class HelpTagInline(TagInline):
|
||||
model = HelpEntry.db_tags.through
|
||||
related_field = "helpentry"
|
||||
|
||||
|
||||
|
||||
class HelpEntryForm(forms.ModelForm):
|
||||
"Defines how to display the help entry"
|
||||
class Meta(object):
|
||||
|
|
@ -22,8 +22,9 @@ class HelpEntryForm(forms.ModelForm):
|
|||
|
||||
db_help_category = forms.CharField(label="Help category", initial='General',
|
||||
help_text="organizes help entries in lists")
|
||||
db_lock_storage = forms.CharField(label="Locks", initial='view:all()',required=False,
|
||||
widget=forms.TextInput(attrs={'size':'40'}),)
|
||||
db_lock_storage = forms.CharField(label="Locks", initial='view:all()', required=False,
|
||||
widget=forms.TextInput(attrs={'size': '40'}),)
|
||||
|
||||
|
||||
class HelpEntryAdmin(admin.ModelAdmin):
|
||||
"Sets up the admin manaager for help entries"
|
||||
|
|
@ -38,9 +39,9 @@ class HelpEntryAdmin(admin.ModelAdmin):
|
|||
|
||||
form = HelpEntryForm
|
||||
fieldsets = (
|
||||
(None, {'fields':(('db_key', 'db_help_category'),
|
||||
(None, {'fields': (('db_key', 'db_help_category'),
|
||||
'db_entrytext', 'db_lock_storage'),
|
||||
'description':"Sets a Help entry. Set lock to <i>view:all()</I> unless you want to restrict it."}),)
|
||||
'description': "Sets a Help entry. Set lock to <i>view:all()</I> unless you want to restrict it."}),)
|
||||
|
||||
|
||||
admin.site.register(HelpEntry, HelpEntryAdmin)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class HelpEntryManager(TypedObjectManager):
|
|||
search_help (equivalent to evennia.search_helpentry)
|
||||
|
||||
"""
|
||||
|
||||
def find_topicmatch(self, topicstr, exact=False):
|
||||
"""
|
||||
Searches for matching topics or aliases based on player's
|
||||
|
|
|
|||
|
|
@ -52,14 +52,14 @@ class HelpEntry(SharedMemoryModel):
|
|||
db_key = models.CharField('help key', max_length=255, unique=True, help_text='key to search for')
|
||||
# help category
|
||||
db_help_category = models.CharField("help category", max_length=255, default="General",
|
||||
help_text='organizes help entries in lists')
|
||||
help_text='organizes help entries in lists')
|
||||
# the actual help entry text, in any formatting.
|
||||
db_entrytext = models.TextField('help entry', blank=True, help_text='the main body of help text')
|
||||
# lock string storage
|
||||
db_lock_storage = models.TextField('locks', blank=True, help_text='normally view:all().')
|
||||
# tags are primarily used for permissions
|
||||
db_tags = models.ManyToManyField(Tag, blank=True,
|
||||
help_text='tags on this object. Tags are simple string markers to identify, group and alias objects.')
|
||||
help_text='tags on this object. Tags are simple string markers to identify, group and alias objects.')
|
||||
# (deprecated, only here to allow MUX helpfile load (don't use otherwise)).
|
||||
# TODO: remove this when not needed anymore.
|
||||
db_staff_only = models.BooleanField(default=False)
|
||||
|
|
|
|||
|
|
@ -280,8 +280,8 @@ def pid(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
|
||||
# this is more efficient than multiple if ... elif statments
|
||||
CF_MAPPING = {'eq': lambda val1, val2: val1 == val2 or str(val1) == str(val2) or float(val1) == float(val2),
|
||||
'gt': lambda val1, val2: float(val1) > float(val2),
|
||||
'lt': lambda val1, val2: float(val1) < float(val2),
|
||||
'gt': lambda val1, val2: float(val1) > float(val2),
|
||||
'lt': lambda val1, val2: float(val1) < float(val2),
|
||||
'ge': lambda val1, val2: float(val1) >= float(val2),
|
||||
'le': lambda val1, val2: float(val1) <= float(val2),
|
||||
'ne': lambda val1, val2: float(val1) != float(val2),
|
||||
|
|
@ -346,8 +346,8 @@ def attr(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
# check attributes, if they exist
|
||||
if (hasattr(accessing_obj, 'attributes') and accessing_obj.attributes.has(attrname)):
|
||||
if value:
|
||||
return (hasattr(accessing_obj, 'attributes')
|
||||
and valcompare(accessing_obj.attributes.get(attrname), value, compare))
|
||||
return (hasattr(accessing_obj, 'attributes') and
|
||||
valcompare(accessing_obj.attributes.get(attrname), value, compare))
|
||||
# fails on False/None values
|
||||
return bool(accessing_obj.attributes.get(attrname))
|
||||
return False
|
||||
|
|
@ -366,6 +366,7 @@ def objattr(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
"""
|
||||
return attr(accessed_obj, accessed_obj, *args, **kwargs)
|
||||
|
||||
|
||||
def locattr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
|
|
@ -386,6 +387,7 @@ def locattr(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
return attr(accessing_obj.location, accessed_obj, *args, **kwargs)
|
||||
return False
|
||||
|
||||
|
||||
def objlocattr(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
|
|
@ -464,6 +466,7 @@ def attr_ne(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
"""
|
||||
return attr(accessing_obj, accessed_obj, *args, **{'compare': 'ne'})
|
||||
|
||||
|
||||
def tag(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
|
|
@ -481,6 +484,7 @@ def tag(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
category = args[1] if len(args) > 1 else None
|
||||
return accessing_obj.tags.get(tagkey, category=category)
|
||||
|
||||
|
||||
def objtag(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
|
|
@ -492,6 +496,7 @@ def objtag(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
"""
|
||||
return accessed_obj.tags.get(*args)
|
||||
|
||||
|
||||
def inside(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Usage:
|
||||
|
|
@ -548,7 +553,7 @@ def holds(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
if len(args) == 1:
|
||||
# command is holds(dbref/key) - check if given objname/dbref is held by accessing_ob
|
||||
return check_holds(args[0])
|
||||
elif len(args = 2):
|
||||
elif len(args=2):
|
||||
# command is holds(attrname, value) check if any held object has the given attribute and value
|
||||
for obj in contents:
|
||||
if obj.attributes.get(args[0]) == args[1]:
|
||||
|
|
@ -566,6 +571,7 @@ def superuser(*args, **kwargs):
|
|||
"""
|
||||
return False
|
||||
|
||||
|
||||
def has_account(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Only returns true if accessing_obj has_account is true, that is,
|
||||
|
|
@ -576,6 +582,7 @@ def has_account(accessing_obj, accessed_obj, *args, **kwargs):
|
|||
"""
|
||||
return hasattr(accessing_obj, "has_account") and accessing_obj.has_account
|
||||
|
||||
|
||||
def serversetting(accessing_obj, accessed_obj, *args, **kwargs):
|
||||
"""
|
||||
Only returns true if the Evennia settings exists, alternatively has
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ WARNING_LOG = settings.LOCKWARNING_LOG_FILE
|
|||
# by errors in lock definitions.
|
||||
#
|
||||
|
||||
|
||||
class LockException(Exception):
|
||||
"""
|
||||
Raised during an error in a lock.
|
||||
|
|
@ -133,6 +134,8 @@ class LockException(Exception):
|
|||
#
|
||||
|
||||
_LOCKFUNCS = {}
|
||||
|
||||
|
||||
def _cache_lockfuncs():
|
||||
"""
|
||||
Updates the cache.
|
||||
|
|
@ -146,6 +149,7 @@ def _cache_lockfuncs():
|
|||
# pre-compiled regular expressions
|
||||
#
|
||||
|
||||
|
||||
_RE_FUNCS = re.compile(r"\w+\([^)]*\)")
|
||||
_RE_SEPS = re.compile(r"(?<=[ )])AND(?=\s)|(?<=[ )])OR(?=\s)|(?<=[ )])NOT(?=\s)")
|
||||
_RE_OK = re.compile(r"%s|and|or|not")
|
||||
|
|
@ -229,7 +233,7 @@ class LockHandler(object):
|
|||
if not callable(func):
|
||||
elist.append(_("Lock: lock-function '%s' is not available.") % funcstring)
|
||||
continue
|
||||
args = list(arg.strip() for arg in rest.split(',') if arg and not '=' in arg)
|
||||
args = list(arg.strip() for arg in rest.split(',') if arg and '=' not in arg)
|
||||
kwargs = dict([arg.split('=', 1) for arg in rest.split(',') if arg and '=' in arg])
|
||||
lock_funcs.append((func, args, kwargs))
|
||||
evalstring = evalstring.replace(funcstring, '%s')
|
||||
|
|
@ -244,8 +248,8 @@ class LockHandler(object):
|
|||
continue
|
||||
if access_type in locks:
|
||||
duplicates += 1
|
||||
wlist.append(_("LockHandler on %(obj)s: access type '%(access_type)s' changed from '%(source)s' to '%(goal)s' " % \
|
||||
{"obj":self.obj, "access_type":access_type, "source":locks[access_type][2], "goal":raw_lockstring}))
|
||||
wlist.append(_("LockHandler on %(obj)s: access type '%(access_type)s' changed from '%(source)s' to '%(goal)s' " %
|
||||
{"obj": self.obj, "access_type": access_type, "source": locks[access_type][2], "goal": raw_lockstring}))
|
||||
locks[access_type] = (evalstring, tuple(lock_funcs), raw_lockstring)
|
||||
if wlist and WARNING_LOG:
|
||||
# a warning text was set, it's not an error, so only report
|
||||
|
|
@ -300,7 +304,7 @@ class LockHandler(object):
|
|||
"""
|
||||
# sanity checks
|
||||
for lockdef in lockstring.split(';'):
|
||||
if not ':' in lockstring:
|
||||
if ':' not in lockstring:
|
||||
self._log_error(_("Lock: '%s' contains no colon (:).") % lockdef)
|
||||
return False
|
||||
access_type, rhs = [part.strip() for part in lockdef.split(':', 1)]
|
||||
|
|
@ -391,7 +395,7 @@ class LockHandler(object):
|
|||
self._save_locks()
|
||||
return True
|
||||
return False
|
||||
delete = remove # alias for historical reasons
|
||||
delete = remove # alias for historical reasons
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
|
|
@ -449,9 +453,9 @@ class LockHandler(object):
|
|||
return True
|
||||
except AttributeError:
|
||||
# happens before session is initiated.
|
||||
if not no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
|
||||
or (hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser)
|
||||
or (hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
|
||||
if not no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or
|
||||
(hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser) or
|
||||
(hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
|
||||
return True
|
||||
|
||||
# no superuser or bypass -> normal lock operation
|
||||
|
|
@ -510,17 +514,17 @@ class LockHandler(object):
|
|||
if accessing_obj.locks.lock_bypass and not no_superuser_bypass:
|
||||
return True
|
||||
except AttributeError:
|
||||
if no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
|
||||
or (hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser)
|
||||
or (hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
|
||||
if no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) or
|
||||
(hasattr(accessing_obj, 'account') and hasattr(accessing_obj.account, 'is_superuser') and accessing_obj.account.is_superuser) or
|
||||
(hasattr(accessing_obj, 'get_account') and (not accessing_obj.get_account() or accessing_obj.get_account().is_superuser))):
|
||||
return True
|
||||
if not ":" in lockstring:
|
||||
if ":" not in lockstring:
|
||||
lockstring = "%s:%s" % ("_dummy", lockstring)
|
||||
|
||||
locks = self._parse_lockstring(lockstring)
|
||||
|
||||
if access_type:
|
||||
if not access_type in locks:
|
||||
if access_type not in locks:
|
||||
return default
|
||||
else:
|
||||
return self._eval_access_type(
|
||||
|
|
@ -541,7 +545,7 @@ def _test():
|
|||
obj1 = TestObj()
|
||||
obj2 = TestObj()
|
||||
|
||||
#obj1.lock_storage = "owner:dbref(#4);edit:dbref(#5) or perm(Admin);examine:perm(Builder);delete:perm(Admin);get:all()"
|
||||
# obj1.lock_storage = "owner:dbref(#4);edit:dbref(#5) or perm(Admin);examine:perm(Builder);delete:perm(Admin);get:all()"
|
||||
#obj1.lock_storage = "cmd:all();admin:id(1);listen:all();send:all()"
|
||||
obj1.lock_storage = "listen:perm(Developer)"
|
||||
|
||||
|
|
@ -550,7 +554,7 @@ def _test():
|
|||
obj2.permissions.add("Developer")
|
||||
obj2.id = 4
|
||||
|
||||
#obj1.locks.add("edit:attr(test)")
|
||||
# obj1.locks.add("edit:attr(test)")
|
||||
|
||||
print("comparing obj2.permissions (%s) vs obj1.locks (%s)" % (obj2.permissions, obj1.locks))
|
||||
print(obj1.locks.check(obj2, 'owner'))
|
||||
|
|
|
|||
|
|
@ -97,18 +97,18 @@ class ObjectDBAdmin(admin.ModelAdmin):
|
|||
form = ObjectEditForm
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': (('db_key', 'db_typeclass_path'), ('db_lock_storage', ),
|
||||
('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
|
||||
)}),
|
||||
)
|
||||
'fields': (('db_key', 'db_typeclass_path'), ('db_lock_storage', ),
|
||||
('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
|
||||
)}),
|
||||
)
|
||||
|
||||
add_form = ObjectCreateForm
|
||||
add_fieldsets = (
|
||||
(None, {
|
||||
'fields': (('db_key', 'db_typeclass_path'),
|
||||
('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
|
||||
)}),
|
||||
)
|
||||
'fields': (('db_key', 'db_typeclass_path'),
|
||||
('db_location', 'db_home'), 'db_destination', 'db_cmdset_storage'
|
||||
)}),
|
||||
)
|
||||
|
||||
def get_fieldsets(self, request, obj=None):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ class ObjectDBManager(TypedObjectManager):
|
|||
if exact:
|
||||
# exact match - do direct search
|
||||
return self.filter(cand_restriction & type_restriction & (Q(db_key__iexact=ostring) |
|
||||
Q(db_tags__db_key__iexact=ostring) & Q(db_tags__db_tagtype__iexact="alias"))).distinct()
|
||||
Q(db_tags__db_key__iexact=ostring) & Q(db_tags__db_tagtype__iexact="alias"))).distinct()
|
||||
elif candidates:
|
||||
# fuzzy with candidates
|
||||
search_candidates = self.filter(cand_restriction & type_restriction)
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
def convert_defaults(apps, schema_editor):
|
||||
ObjectDB = apps.get_model("objects", "ObjectDB")
|
||||
for obj in ObjectDB.objects.filter(db_typeclass_path="src.objects.objects.Object"):
|
||||
obj.db_typeclass_path = "typeclasses.objects.Object"
|
||||
obj.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
|
|
@ -16,5 +18,5 @@ class Migration(migrations.Migration):
|
|||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(convert_defaults),
|
||||
migrations.RunPython(convert_defaults),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ def forwards(apps, schema_editor):
|
|||
object.db_account = account
|
||||
object.save(update_fields=['db_account'])
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class ContentsHandler(object):
|
|||
for object-cmdsets). It is stored on the 'contents_cache' property
|
||||
of the ObjectDB.
|
||||
"""
|
||||
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
Sets up the contents handler.
|
||||
|
|
@ -171,12 +172,12 @@ class ObjectDB(TypedObject):
|
|||
|
||||
# If this is a character object, the account is connected here.
|
||||
db_account = models.ForeignKey("accounts.AccountDB", null=True, verbose_name='account', on_delete=models.SET_NULL,
|
||||
help_text='an Account connected to this object, if any.')
|
||||
help_text='an Account connected to this object, if any.')
|
||||
|
||||
# the session id associated with this account, if any
|
||||
db_sessid = models.CharField(null=True, max_length=32, validators=[validate_comma_separated_integer_list],
|
||||
verbose_name="session id",
|
||||
help_text="csv list of session ids of connected Account, if any.")
|
||||
verbose_name="session id",
|
||||
help_text="csv list of session ids of connected Account, if any.")
|
||||
# The location in the game world. Since this one is likely
|
||||
# to change often, we set this with the 'location' property
|
||||
# to transparently handle Typeclassing.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class ObjectSessionHandler(object):
|
|||
Handles the get/setting of the sessid
|
||||
comma-separated integer field
|
||||
"""
|
||||
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
Initializes the handler.
|
||||
|
|
@ -1211,10 +1212,10 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
mapping = {}
|
||||
|
||||
mapping.update({
|
||||
"object": self,
|
||||
"exit": exits[0] if exits else "somwhere",
|
||||
"origin": location or "nowhere",
|
||||
"destination": destination or "nowhere",
|
||||
"object": self,
|
||||
"exit": exits[0] if exits else "somwhere",
|
||||
"origin": location or "nowhere",
|
||||
"destination": destination or "nowhere",
|
||||
})
|
||||
|
||||
location.msg_contents(string, exclude=(self, ), mapping=mapping)
|
||||
|
|
@ -1267,10 +1268,10 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
mapping = {}
|
||||
|
||||
mapping.update({
|
||||
"object": self,
|
||||
"exit": exits[0] if exits else "somewhere",
|
||||
"origin": origin or "nowhere",
|
||||
"destination": destination or "nowhere",
|
||||
"object": self,
|
||||
"exit": exits[0] if exits else "somewhere",
|
||||
"origin": origin or "nowhere",
|
||||
"destination": destination or "nowhere",
|
||||
})
|
||||
|
||||
destination.msg_contents(string, exclude=(self, ), mapping=mapping)
|
||||
|
|
@ -1630,20 +1631,20 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
|
||||
mapping = mapping or {}
|
||||
mapping.update({
|
||||
"object": self,
|
||||
"location": self.location,
|
||||
"speech": message,
|
||||
"receiver": receiver
|
||||
})
|
||||
"object": self,
|
||||
"location": self.location,
|
||||
"speech": message,
|
||||
"receiver": receiver
|
||||
})
|
||||
|
||||
if msg_self:
|
||||
self_mapping = {k: v.get_display_name(self) if hasattr(
|
||||
v, "get_display_name") else str(v) for k, v in mapping.items()}
|
||||
v, "get_display_name") else str(v) for k, v in mapping.items()}
|
||||
self.msg(msg_self.format(**self_mapping))
|
||||
|
||||
if receiver and msg_receiver:
|
||||
receiver_mapping = {k: v.get_display_name(receiver) if hasattr(
|
||||
v, "get_display_name") else str(v) for k, v in mapping.items()}
|
||||
v, "get_display_name") else str(v) for k, v in mapping.items()}
|
||||
receiver.msg(msg_receiver.format(**receiver_mapping))
|
||||
|
||||
if self.location and msg_location:
|
||||
|
|
@ -1778,6 +1779,7 @@ class DefaultRoom(DefaultObject):
|
|||
This is the base room object. It's just like any Object except its
|
||||
location is always `None`.
|
||||
"""
|
||||
|
||||
def basetype_setup(self):
|
||||
"""
|
||||
Simple room setup setting locks to make sure the room
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ class ScriptDBAdmin(admin.ModelAdmin):
|
|||
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': (('db_key', 'db_typeclass_path'), 'db_interval',
|
||||
'db_repeats', 'db_start_delay', 'db_persistent',
|
||||
'db_obj')}),
|
||||
)
|
||||
'fields': (('db_key', 'db_typeclass_path'), 'db_interval',
|
||||
'db_repeats', 'db_start_delay', 'db_persistent',
|
||||
'db_obj')}),
|
||||
)
|
||||
inlines = [ScriptTagInline, ScriptAttributeInline]
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class ScriptDBManager(TypedObjectManager):
|
|||
copy_script
|
||||
|
||||
"""
|
||||
|
||||
def get_all_scripts_on_obj(self, obj, key=None):
|
||||
"""
|
||||
Find all Scripts related to a particular object.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue