Merge branch 'change_ic_behavior' into develop

This commit is contained in:
Griatch 2020-07-20 22:17:05 +02:00
commit 81a22b0b5d
4 changed files with 94 additions and 36 deletions

View file

@ -945,6 +945,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
nofound_string=None,
multimatch_string=None,
use_nicks=True,
quiet=False,
**kwargs,
):
"""
@ -971,9 +972,13 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
message to echo if `searchdata` leads to multiple matches.
If not given, will fall back to the default handler.
use_nicks (bool, optional): Use account-level nick replacement.
quiet (bool, optional): If set, will not show any error to the user,
and will also lead to returning a list of matches.
Return:
match (Account, Object or None): A single Account or Object match.
list: If `quiet=True` this is a list of 0, 1 or more Account or Object matches.
Notes:
Extra keywords are ignored, but are allowed in call in
order to make API more consistent with
@ -985,28 +990,33 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
# handle wrapping of common terms
if searchdata.lower() in ("me", "*me", "self", "*self"):
return self
searchdata = self.nicks.nickreplace(
searchdata, categories=("account",), include_account=False
)
if search_object:
matches = ObjectDB.objects.object_search(
searchdata, typeclass=typeclass, use_nicks=use_nicks
searchdata, typeclass=typeclass
)
else:
searchdata = self.nicks.nickreplace(
searchdata, categories=("account",), include_account=False
)
matches = AccountDB.objects.account_search(searchdata, typeclass=typeclass)
matches = _AT_SEARCH_RESULT(
matches,
self,
query=searchdata,
nofound_string=nofound_string,
multimatch_string=multimatch_string,
)
if matches and return_puppet:
try:
return matches.puppet
except AttributeError:
return None
if quiet:
matches = list(matches)
if return_puppet:
matches = [match.puppet for match in matches]
else:
matches = _AT_SEARCH_RESULT(
matches,
self,
query=searchdata,
nofound_string=nofound_string,
multimatch_string=multimatch_string,
)
if matches and return_puppet:
try:
matches = matches.puppet
except AttributeError:
return None
return matches
def access(

View file

@ -301,27 +301,60 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
session = self.session
new_character = None
character_candidates = []
if not self.args:
new_character = account.db._last_puppet
if not new_character:
character_candidates = [account.db._last_puppet] or []
if not character_candidates:
self.msg("Usage: ic <character>")
return
if not new_character:
# search for a matching character
new_character = [
char for char in search.object_search(self.args) if char.access(account, "puppet")
]
if not new_character:
self.msg("That is not a valid character choice.")
return
if len(new_character) > 1:
self.msg(
"Multiple targets with the same name:\n %s"
% ", ".join("%s(#%s)" % (obj.key, obj.id) for obj in new_character)
else:
# argument given
if account.db._playable_characters:
# look at the playable_characters list first
character_candidates.extend(
account.search(self.args, candidates=account.db._playable_characters,
search_object=True, quiet=True)
)
return
else:
new_character = new_character[0]
if account.locks.check_lockstring(account, "perm(Builder)"):
# builders and higher should be able to puppet more than their
# playable characters.
if session.puppet:
# start by local search - this helps to avoid the user
# getting locked into their playable characters should one
# happen to be named the same as another. We replace the suggestion
# from playable_characters here - this allows builders to puppet objects
# with the same name as their playable chars should it be necessary
# (by going to the same location).
character_candidates = [
char
for char in session.puppet.search(self.args, quiet=True)
if char.access(account, "puppet")
]
if not character_candidates:
# fall back to global search only if Builder+ has no
# playable_characers in list and is not standing in a room
# with a matching char.
character_candidates.extend([
char for char in search.object_search(self.args) if char.access(account, "puppet")]
)
# handle possible candidates
if not character_candidates:
self.msg("That is not a valid character choice.")
return
if len(character_candidates) > 1:
self.msg(
"Multiple targets with the same name:\n %s"
% ", ".join("%s(#%s)" % (obj.key, obj.id) for obj in character_candidates)
)
return
else:
new_character = character_candidates[0]
# do the puppet puppet
try:
account.puppet_object(session, new_character)
account.db._last_puppet = new_character

View file

@ -366,11 +366,27 @@ class TestAccount(CommandTest):
self.call(account.CmdOOC(), "", "You go OOC.", caller=self.account)
def test_ic(self):
self.account.db._playable_characters = [self.char1]
self.account.unpuppet_object(self.session)
self.call(
account.CmdIC(), "Char", "You become Char.", caller=self.account, receiver=self.char1
)
def test_ic__other_object(self):
self.account.db._playable_characters = [self.obj1]
self.account.unpuppet_object(self.session)
self.call(
account.CmdIC(), "Obj", "You become Obj.", caller=self.account, receiver=self.obj1
)
def test_ic__nonaccess(self):
self.account.unpuppet_object(self.session)
self.call(
account.CmdIC(), "Nonexistent", "That is not a valid character choice.",
caller=self.account, receiver=self.account
)
def test_password(self):
self.call(
account.CmdPassword(),

View file

@ -393,8 +393,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
- `me,self`: self-reference to this object
- `<num>-<string>` - can be used to differentiate
between multiple same-named matches
global_search (bool): Search all objects globally. This is overruled
by `location` keyword.
global_search (bool): Search all objects globally. This overrules 'location' data.
use_nicks (bool): Use nickname-replace (nicktype "object") on `searchdata`.
typeclass (str or Typeclass, or list of either): Limit search only
to `Objects` with this typeclass. May be a list of typeclasses