mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Fix merge conflicts
This commit is contained in:
commit
33d247cff0
16 changed files with 194 additions and 116 deletions
|
|
@ -174,6 +174,10 @@ Up requirements to Django 4.0+, Twisted 22+, Python 3.9 or 3.10
|
|||
- Simplified `EvMenu.options_formatter` hook to use `EvColumn` and f-strings (inspectorcaracal)
|
||||
- Allow `# CODE`, `# HEADER` etc as well as `#CODE`/`#HEADER` in batchcode
|
||||
files - this works better with black linting.
|
||||
- Added `move_type` str kwarg to `move_to()` calls, optionally identifying the type of
|
||||
move being done ('teleport', 'disembark', 'give' etc). (volund)
|
||||
- Made RPSystem contrib msg calls pass `pose` or `say` as msg-`type` for use in
|
||||
e.g. webclient pane filtering where desired. (volund)
|
||||
|
||||
|
||||
## Evennia 0.9.5
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ def menunode_inspect_and_buy(caller, raw_string):
|
|||
if wealth >= value:
|
||||
rtext = f"You pay {value} gold and purchase {ware.key}!"
|
||||
caller.db.gold -= value
|
||||
ware.move_to(caller, quiet=True)
|
||||
ware.move_to(caller, quiet=True, move_type="buy")
|
||||
else:
|
||||
rtext = f"You cannot afford {value} gold for {ware.key}!"
|
||||
caller.msg(rtext)
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class CmdEnterTrain(Command):
|
|||
def func(self):
|
||||
train = self.obj
|
||||
self.caller.msg("You board the train.")
|
||||
self.caller.move_to(train)
|
||||
self.caller.move_to(train, move_type="board")
|
||||
|
||||
|
||||
class CmdLeaveTrain(Command):
|
||||
|
|
@ -107,7 +107,7 @@ class CmdLeaveTrain(Command):
|
|||
def func(self):
|
||||
train = self.obj
|
||||
parent = train.location
|
||||
self.caller.move_to(parent)
|
||||
self.caller.move_to(parent, move_type="disembark")
|
||||
|
||||
|
||||
class CmdSetTrain(CmdSet):
|
||||
|
|
|
|||
|
|
@ -603,7 +603,7 @@ class CmdCreate(ObjManipCommand):
|
|||
if "drop" in self.switches:
|
||||
if caller.location:
|
||||
obj.home = caller.location
|
||||
obj.move_to(caller.location, quiet=True)
|
||||
obj.move_to(caller.location, quiet=True, move_type="drop")
|
||||
if string:
|
||||
caller.msg(string)
|
||||
|
||||
|
|
@ -993,7 +993,7 @@ class CmdDig(ObjManipCommand):
|
|||
)
|
||||
caller.msg("%s%s%s" % (room_string, exit_to_string, exit_back_string))
|
||||
if new_room and "teleport" in self.switches:
|
||||
caller.move_to(new_room)
|
||||
caller.move_to(new_room, move_type="teleport")
|
||||
|
||||
|
||||
class CmdTunnel(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -3709,6 +3709,7 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
|||
quiet="quiet" in self.switches,
|
||||
emit_to_obj=caller,
|
||||
use_destination="intoexit" not in self.switches,
|
||||
move_type="teleport"
|
||||
):
|
||||
|
||||
if obj_to_teleport == caller:
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class CmdHome(COMMAND_DEFAULT_CLASS):
|
|||
caller.msg("You are already home!")
|
||||
else:
|
||||
caller.msg("There's no place like home ...")
|
||||
caller.move_to(home)
|
||||
caller.move_to(home, move_type="teleport")
|
||||
|
||||
|
||||
class CmdLook(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -434,7 +434,7 @@ class CmdGet(COMMAND_DEFAULT_CLASS):
|
|||
if not obj.at_pre_get(caller):
|
||||
return
|
||||
|
||||
success = obj.move_to(caller, quiet=True)
|
||||
success = obj.move_to(caller, quiet=True, move_type="get")
|
||||
if not success:
|
||||
caller.msg("This can't be picked up.")
|
||||
else:
|
||||
|
|
@ -484,7 +484,7 @@ class CmdDrop(COMMAND_DEFAULT_CLASS):
|
|||
if not obj.at_pre_drop(caller):
|
||||
return
|
||||
|
||||
success = obj.move_to(caller.location, quiet=True)
|
||||
success = obj.move_to(caller.location, quiet=True, move_type="drop")
|
||||
if not success:
|
||||
caller.msg("This couldn't be dropped.")
|
||||
else:
|
||||
|
|
@ -538,7 +538,7 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# give object
|
||||
success = to_give.move_to(target, quiet=True)
|
||||
success = to_give.move_to(target, quiet=True, move_type="get")
|
||||
if not success:
|
||||
caller.msg("This could not be given.")
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ class EventCharacter(DefaultCharacter):
|
|||
"""Return the CallbackHandler."""
|
||||
return CallbackHandler(self)
|
||||
|
||||
def announce_move_from(self, destination, msg=None, mapping=None):
|
||||
def announce_move_from(self, destination, msg=None, move_type="move", mapping=None, **kwargs):
|
||||
"""
|
||||
Called if the move is to be announced. This is
|
||||
called while we are still standing in the old
|
||||
|
|
@ -234,9 +234,9 @@ class EventCharacter(DefaultCharacter):
|
|||
if not string:
|
||||
return
|
||||
|
||||
super().announce_move_from(destination, msg=string, mapping=mapping)
|
||||
super().announce_move_from(destination, msg=string, move_type=move_type, mapping=mapping, **kwargs)
|
||||
|
||||
def announce_move_to(self, source_location, msg=None, mapping=None):
|
||||
def announce_move_to(self, source_location, msg=None, move_type="move", mapping=None, **kwargs):
|
||||
"""
|
||||
Called after the move if the move was not quiet. At this point
|
||||
we are standing in the new location.
|
||||
|
|
@ -292,9 +292,9 @@ class EventCharacter(DefaultCharacter):
|
|||
if not string:
|
||||
return
|
||||
|
||||
super().announce_move_to(source_location, msg=string, mapping=mapping)
|
||||
super().announce_move_to(source_location, msg=string, move_type=move_type, mapping=mapping, **kwargs)
|
||||
|
||||
def at_pre_move(self, destination):
|
||||
def at_pre_move(self, destination, move_type="move", **kwargs):
|
||||
"""
|
||||
Called just before starting to move this object to
|
||||
destination.
|
||||
|
|
@ -334,7 +334,7 @@ class EventCharacter(DefaultCharacter):
|
|||
|
||||
return True
|
||||
|
||||
def at_post_move(self, source_location):
|
||||
def at_post_move(self, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Called after move has completed, regardless of quiet mode or
|
||||
not. Allows changes to the object due to the location it is
|
||||
|
|
@ -644,7 +644,7 @@ class EventExit(DefaultExit):
|
|||
"""Return the CallbackHandler."""
|
||||
return CallbackHandler(self)
|
||||
|
||||
def at_traverse(self, traversing_object, target_location):
|
||||
def at_traverse(self, traversing_object, target_location, **kwargs):
|
||||
"""
|
||||
This hook is responsible for handling the actual traversal,
|
||||
normally by calling
|
||||
|
|
@ -665,7 +665,7 @@ class EventExit(DefaultExit):
|
|||
if not allow:
|
||||
return
|
||||
|
||||
super().at_traverse(traversing_object, target_location)
|
||||
super().at_traverse(traversing_object, target_location, **kwargs)
|
||||
|
||||
# After traversing
|
||||
if is_character:
|
||||
|
|
@ -732,7 +732,7 @@ class EventObject(DefaultObject):
|
|||
"""Return the CallbackHandler."""
|
||||
return CallbackHandler(self)
|
||||
|
||||
def at_get(self, getter):
|
||||
def at_get(self, getter, **kwargs):
|
||||
"""
|
||||
Called by the default `get` command when this object has been
|
||||
picked up.
|
||||
|
|
@ -745,10 +745,10 @@ class EventObject(DefaultObject):
|
|||
permissions for that.
|
||||
|
||||
"""
|
||||
super().at_get(getter)
|
||||
super().at_get(getter, **kwargs)
|
||||
self.callbacks.call("get", getter, self)
|
||||
|
||||
def at_drop(self, dropper):
|
||||
def at_drop(self, dropper, **kwargs):
|
||||
"""
|
||||
Called by the default `drop` command when this object has been
|
||||
dropped.
|
||||
|
|
@ -761,7 +761,7 @@ class EventObject(DefaultObject):
|
|||
permissions from that.
|
||||
|
||||
"""
|
||||
super().at_drop(dropper)
|
||||
super().at_drop(dropper, **kwargs)
|
||||
self.callbacks.call("drop", dropper, self)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ class CmdGiveUp(CmdEvscapeRoom):
|
|||
# manually call move hooks
|
||||
self.room.msg_room(self.caller, f"|r{self.caller.key} gave up and was whisked away!|n")
|
||||
self.room.at_object_leave(self.caller, self.caller.home)
|
||||
self.caller.move_to(self.caller.home, quiet=True, move_hooks=False)
|
||||
self.caller.move_to(self.caller.home, quiet=True, move_hooks=False, move_type="teleport")
|
||||
|
||||
# back to menu
|
||||
run_evscaperoom_menu(self.caller)
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
|
|||
|
||||
# Evennia hooks
|
||||
|
||||
def at_object_receive(self, moved_obj, source_location):
|
||||
def at_object_receive(self, moved_obj, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Called when an object arrives in the room. This can be used to
|
||||
sum up the situation, set tags etc.
|
||||
|
|
@ -195,7 +195,7 @@ class EvscapeRoom(EvscaperoomObject, DefaultRoom):
|
|||
self.log(f"JOIN: {moved_obj} joined room")
|
||||
self.state.character_enters(moved_obj)
|
||||
|
||||
def at_object_leave(self, moved_obj, target_location, **kwargs):
|
||||
def at_object_leave(self, moved_obj, target_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Called when an object leaves the room; if this is a Character we need
|
||||
to clean them up and move them to the menu state.
|
||||
|
|
|
|||
|
|
@ -611,7 +611,7 @@ class CmdDrop(MuxCommand):
|
|||
if obj.db.worn:
|
||||
obj.remove(caller, quiet=True)
|
||||
|
||||
obj.move_to(caller.location, quiet=True)
|
||||
obj.move_to(caller.location, quiet=True, move_type="drop")
|
||||
caller.msg("You drop %s." % (obj.name,))
|
||||
caller.location.msg_contents("%s drops %s." % (caller.name, obj.name), exclude=caller)
|
||||
# Call the object script's at_drop() method.
|
||||
|
|
@ -664,10 +664,10 @@ class CmdGive(MuxCommand):
|
|||
# Remove clothes if they're given.
|
||||
if to_give.db.worn:
|
||||
to_give.remove(caller)
|
||||
to_give.move_to(caller.location, quiet=True)
|
||||
to_give.move_to(caller.location, quiet=True, move_type="remove")
|
||||
# give object
|
||||
caller.msg("You give %s to %s." % (to_give.key, target.key))
|
||||
to_give.move_to(target, quiet=True)
|
||||
to_give.move_to(target, quiet=True, move_type="give")
|
||||
target.msg("%s gives you %s." % (caller.key, to_give.key))
|
||||
# Call the object script's at_give() method.
|
||||
to_give.at_give(caller, target)
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class SlowExit(DefaultExit):
|
|||
def move_callback():
|
||||
"This callback will be called by utils.delay after move_delay seconds."
|
||||
source_location = traversing_object.location
|
||||
if traversing_object.move_to(target_location):
|
||||
if traversing_object.move_to(target_location, move_type="traverse"):
|
||||
self.at_post_traverse(traversing_object, source_location)
|
||||
else:
|
||||
if self.db.err_traverse:
|
||||
|
|
|
|||
|
|
@ -538,7 +538,7 @@ class WildernessRoom(DefaultRoom):
|
|||
# This object wasn't in the wilderness yet. Let's add it.
|
||||
itemcoords[moved_obj] = self.coordinates
|
||||
|
||||
def at_object_leave(self, moved_obj, target_location):
|
||||
def at_object_leave(self, moved_obj, target_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Called just before an object leaves from inside this object. This is a
|
||||
default Evennia hook.
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ _RE_RIGHT_BRACKETS = re.compile(r"\}+", _RE_FLAGS)
|
|||
_RE_REF = re.compile(r"\{+\#([0-9]+[\^\~tv]{0,1})\}+")
|
||||
|
||||
# This regex is used to quickly reference one self in an emote.
|
||||
_RE_SELF_REF = re.compile(r"/me|@", _RE_FLAGS)
|
||||
_RE_SELF_REF = re.compile(r"(/me|@)(?=\W+)", _RE_FLAGS)
|
||||
|
||||
# regex for non-alphanumberic end of a string
|
||||
_RE_CHAREND = re.compile(r"\W+$", _RE_FLAGS)
|
||||
|
|
@ -213,6 +213,7 @@ _RE_REF_LANG = re.compile(r"\{+\##([0-9]+)\}+")
|
|||
# this regex returns in groups (langname, say), where langname can be empty.
|
||||
_RE_LANGUAGE = re.compile(r"(?:\((\w+)\))*(\".+?\")")
|
||||
|
||||
|
||||
# the emote parser works in two steps:
|
||||
# 1) convert the incoming emote into an intermediary
|
||||
# form with all object references mapped to ids.
|
||||
|
|
@ -235,6 +236,26 @@ class RecogError(Exception):
|
|||
class LanguageError(Exception):
|
||||
pass
|
||||
|
||||
def _get_case_ref(string):
|
||||
"""
|
||||
Helper function which parses capitalization and
|
||||
returns the appropriate case-ref character for emotes.
|
||||
"""
|
||||
# default to retaining the original case
|
||||
case = "~"
|
||||
# internal flags for the case used for the original /query
|
||||
# - t for titled input (like /Name)
|
||||
# - ^ for all upercase input (like /NAME)
|
||||
# - v for lower-case input (like /name)
|
||||
# - ~ for mixed case input (like /nAmE)
|
||||
if string.istitle():
|
||||
case = "t"
|
||||
elif string.isupper():
|
||||
case = "^"
|
||||
elif string.islower():
|
||||
case = "v"
|
||||
|
||||
return case
|
||||
|
||||
# emoting mechanisms
|
||||
def parse_language(speaker, emote):
|
||||
|
|
@ -339,7 +360,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_
|
|||
"""
|
||||
# build a list of candidates with all possible referrable names
|
||||
# include 'me' keyword for self-ref
|
||||
candidate_map = [(sender, "me")]
|
||||
candidate_map = []
|
||||
for obj in candidates:
|
||||
# check if sender has any recogs for obj and add
|
||||
if hasattr(sender, "recog"):
|
||||
|
|
@ -365,6 +386,15 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_
|
|||
errors = []
|
||||
obj = None
|
||||
nmatches = 0
|
||||
# first, find and replace any self-refs
|
||||
for self_match in list(_RE_SELF_REF.finditer(string)):
|
||||
matched = self_match.group()
|
||||
case = _get_case_ref(matched.lstrip(_PREFIX)) if case_sensitive else ""
|
||||
key = f"#{sender.id}{case}"
|
||||
# replaced with ref
|
||||
string = _RE_SELF_REF.sub(f"{{{key}}}", string, count=1)
|
||||
mapping[key] = sender
|
||||
|
||||
for marker_match in reversed(list(_RE_OBJ_REF_START.finditer(string))):
|
||||
# we scan backwards so we can replace in-situ without messing
|
||||
# up later occurrences. Given a marker match, query from
|
||||
|
|
@ -375,7 +405,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_
|
|||
match_index = marker_match.start()
|
||||
# split the emote string at the reference marker, to process everything after it
|
||||
head = string[:match_index]
|
||||
tail = string[match_index + 1 :]
|
||||
tail = string[match_index + 1:]
|
||||
|
||||
if search_mode:
|
||||
# match the candidates against the whole search string after the marker
|
||||
|
|
@ -421,7 +451,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_
|
|||
# save search string
|
||||
matched_text = "".join(tail[1:iend])
|
||||
# recombine remainder of emote back into a string
|
||||
tail = "".join(tail[iend + 1 :])
|
||||
tail = "".join(tail[iend + 1:])
|
||||
|
||||
nmatches = len(bestmatches)
|
||||
|
||||
|
|
@ -456,24 +486,9 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_
|
|||
errors.append(_EMOTE_NOMATCH_ERROR.format(ref=marker_match.group()))
|
||||
elif nmatches == 1:
|
||||
# a unique match - parse into intermediary representation
|
||||
case = "~" # retain original case of sdesc
|
||||
if case_sensitive:
|
||||
# case sensitive mode
|
||||
# internal flags for the case used for the original /query
|
||||
# - t for titled input (like /Name)
|
||||
# - ^ for all upercase input (like /NAME)
|
||||
# - v for lower-case input (like /name)
|
||||
# - ~ for mixed case input (like /nAmE)
|
||||
matchtext = marker_match.group().lstrip(_PREFIX)
|
||||
if matchtext.istitle():
|
||||
case = "t"
|
||||
elif matchtext.isupper():
|
||||
case = "^"
|
||||
elif matchtext.islower():
|
||||
case = "v"
|
||||
|
||||
key = f"#{obj.id}{case}"
|
||||
case = _get_case_ref(marker_match.group()) if case_sensitive else ""
|
||||
# recombine emote with matched text replaced by ref
|
||||
key = f"#{obj.id}{case}"
|
||||
string = f"{head}{{{key}}}{tail}"
|
||||
mapping[key] = obj
|
||||
|
||||
|
|
@ -513,7 +528,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_
|
|||
return string, mapping
|
||||
|
||||
|
||||
def send_emote(sender, receivers, emote, anonymous_add="first", **kwargs):
|
||||
def send_emote(sender, receivers, emote, msg_type="pose", anonymous_add="first", **kwargs):
|
||||
"""
|
||||
Main access function for distribute an emote.
|
||||
|
||||
|
|
@ -523,6 +538,9 @@ def send_emote(sender, receivers, emote, anonymous_add="first", **kwargs):
|
|||
will also form the basis for which sdescs are
|
||||
'valid' to use in the emote.
|
||||
emote (str): The raw emote string as input by emoter.
|
||||
msg_type (str): The type of emote this is. "say" or "pose"
|
||||
for example. This is arbitrary and used for generating
|
||||
extra data for .msg(text) tuple.
|
||||
anonymous_add (str or None, optional): If `sender` is not
|
||||
self-referencing in the emote, this will auto-add
|
||||
`sender`'s data to the emote. Possible values are
|
||||
|
|
@ -599,7 +617,7 @@ def send_emote(sender, receivers, emote, anonymous_add="first", **kwargs):
|
|||
)
|
||||
|
||||
# do the template replacement of the sdesc/recog {#num} markers
|
||||
receiver.msg(sendemote.format(**receiver_sdesc_mapping), from_obj=sender, **kwargs)
|
||||
receiver.msg(text=(sendemote.format(**receiver_sdesc_mapping), {"type": msg_type}), from_obj=sender, **kwargs)
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
|
|
@ -910,7 +928,7 @@ class CmdSay(RPCommand): # replaces standard say
|
|||
# calling the speech modifying hook
|
||||
speech = caller.at_pre_say(self.args)
|
||||
targets = self.caller.location.contents
|
||||
send_emote(self.caller, targets, speech, anonymous_add=None)
|
||||
send_emote(self.caller, targets, speech, msg_type="say", anonymous_add=None)
|
||||
|
||||
|
||||
class CmdSdesc(RPCommand): # set/look at own sdesc
|
||||
|
|
@ -1253,19 +1271,19 @@ class ContribRPObject(DefaultObject):
|
|||
self.sdesc.add("Something")
|
||||
|
||||
def search(
|
||||
self,
|
||||
searchdata,
|
||||
global_search=False,
|
||||
use_nicks=True,
|
||||
typeclass=None,
|
||||
location=None,
|
||||
attribute_name=None,
|
||||
quiet=False,
|
||||
exact=False,
|
||||
candidates=None,
|
||||
nofound_string=None,
|
||||
multimatch_string=None,
|
||||
use_dbref=None,
|
||||
self,
|
||||
searchdata,
|
||||
global_search=False,
|
||||
use_nicks=True,
|
||||
typeclass=None,
|
||||
location=None,
|
||||
attribute_name=None,
|
||||
quiet=False,
|
||||
exact=False,
|
||||
candidates=None,
|
||||
nofound_string=None,
|
||||
multimatch_string=None,
|
||||
use_dbref=None,
|
||||
):
|
||||
"""
|
||||
Returns an Object matching a search string/condition, taking
|
||||
|
|
@ -1349,10 +1367,10 @@ class ContribRPObject(DefaultObject):
|
|||
)
|
||||
|
||||
if global_search or (
|
||||
is_string
|
||||
and searchdata.startswith("#")
|
||||
and len(searchdata) > 1
|
||||
and searchdata[1:].isdigit()
|
||||
is_string
|
||||
and searchdata.startswith("#")
|
||||
and len(searchdata) > 1
|
||||
and searchdata[1:].isdigit()
|
||||
):
|
||||
# only allow exact matching if searching the entire database
|
||||
# or unique #dbrefs
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ recog02 = "Mr Receiver2"
|
|||
recog10 = "Mr Sender"
|
||||
emote = 'With a flair, /me looks at /first and /colliding sdesc-guy. She says "This is a test."'
|
||||
case_emote = "/Me looks at /first. Then, /me looks at /FIRST, /First and /Colliding twice."
|
||||
poss_emote = "/Me frowns at /first for trying to steal /me's test."
|
||||
|
||||
|
||||
class TestRPSystem(BaseEvenniaTest):
|
||||
|
|
@ -140,18 +141,21 @@ class TestRPSystem(BaseEvenniaTest):
|
|||
),
|
||||
)
|
||||
|
||||
def parse_sdescs_and_recogs(self):
|
||||
def test_parse_sdescs_and_recogs(self):
|
||||
speaker = self.speaker
|
||||
speaker.sdesc.add(sdesc0)
|
||||
self.receiver1.sdesc.add(sdesc1)
|
||||
self.receiver2.sdesc.add(sdesc2)
|
||||
id0 = f"#{speaker.id}"
|
||||
id1 = f"#{self.receiver1.id}"
|
||||
id2 = f"#{self.receiver2.id}"
|
||||
candidates = (self.receiver1, self.receiver2)
|
||||
result = (
|
||||
'With a flair, {#9} looks at {#10} and {#11}. She says "This is a test."',
|
||||
'With a flair, {'+id0+'} looks at {'+id1+'} and {'+id2+'}. She says "This is a test."',
|
||||
{
|
||||
"#11": "Another nice colliding sdesc-guy for tests",
|
||||
"#10": "The first receiver of emotes.",
|
||||
"#9": "A nice sender of emotes",
|
||||
id2: self.receiver2,
|
||||
id1: self.receiver1,
|
||||
id0: speaker,
|
||||
},
|
||||
)
|
||||
self.assertEqual(
|
||||
|
|
@ -164,6 +168,27 @@ class TestRPSystem(BaseEvenniaTest):
|
|||
result,
|
||||
)
|
||||
|
||||
def test_possessive_selfref(self):
|
||||
speaker = self.speaker
|
||||
speaker.sdesc.add(sdesc0)
|
||||
self.receiver1.sdesc.add(sdesc1)
|
||||
self.receiver2.sdesc.add(sdesc2)
|
||||
id0 = f"#{speaker.id}"
|
||||
id1 = f"#{self.receiver1.id}"
|
||||
id2 = f"#{self.receiver2.id}"
|
||||
candidates = (self.receiver1, self.receiver2)
|
||||
result = (
|
||||
"{"+id0+"} frowns at {"+id1+"} for trying to steal {"+id0+"}'s test.",
|
||||
{
|
||||
id1: self.receiver1,
|
||||
id0: speaker,
|
||||
},
|
||||
)
|
||||
self.assertEqual(
|
||||
rpsystem.parse_sdescs_and_recogs(speaker, candidates, poss_emote, case_sensitive=False),
|
||||
result,
|
||||
)
|
||||
|
||||
def test_get_sdesc(self):
|
||||
looker = self.speaker # Sender
|
||||
target = self.receiver1 # Receiver1
|
||||
|
|
@ -197,17 +222,17 @@ class TestRPSystem(BaseEvenniaTest):
|
|||
receiver2.msg = lambda text, **kwargs: setattr(self, "out2", text)
|
||||
rpsystem.send_emote(speaker, receivers, emote, case_sensitive=False)
|
||||
self.assertEqual(
|
||||
self.out0,
|
||||
self.out0[0],
|
||||
"With a flair, |mSender|n looks at |bThe first receiver of emotes.|n "
|
||||
'and |bAnother nice colliding sdesc-guy for tests|n. She says |w"This is a test."|n',
|
||||
)
|
||||
self.assertEqual(
|
||||
self.out1,
|
||||
self.out1[0],
|
||||
"With a flair, |bA nice sender of emotes|n looks at |mReceiver1|n and "
|
||||
'|bAnother nice colliding sdesc-guy for tests|n. She says |w"This is a test."|n',
|
||||
)
|
||||
self.assertEqual(
|
||||
self.out2,
|
||||
self.out2[0],
|
||||
"With a flair, |bA nice sender of emotes|n looks at |bThe first "
|
||||
'receiver of emotes.|n and |mReceiver2|n. She says |w"This is a test."|n',
|
||||
)
|
||||
|
|
@ -226,19 +251,19 @@ class TestRPSystem(BaseEvenniaTest):
|
|||
receiver2.msg = lambda text, **kwargs: setattr(self, "out2", text)
|
||||
rpsystem.send_emote(speaker, receivers, case_emote)
|
||||
self.assertEqual(
|
||||
self.out0,
|
||||
self.out0[0],
|
||||
"|mSender|n looks at |bthe first receiver of emotes.|n. Then, |mSender|n "
|
||||
"looks at |bTHE FIRST RECEIVER OF EMOTES.|n, |bThe first receiver of emotes.|n "
|
||||
"and |bAnother nice colliding sdesc-guy for tests|n twice.",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.out1,
|
||||
self.out1[0],
|
||||
"|bA nice sender of emotes|n looks at |mReceiver1|n. Then, "
|
||||
"|ba nice sender of emotes|n looks at |mReceiver1|n, |mReceiver1|n "
|
||||
"and |bAnother nice colliding sdesc-guy for tests|n twice.",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.out2,
|
||||
self.out2[0],
|
||||
"|bA nice sender of emotes|n looks at |bthe first receiver of emotes.|n. "
|
||||
"Then, |ba nice sender of emotes|n looks at |bTHE FIRST RECEIVER OF EMOTES.|n, "
|
||||
"|bThe first receiver of emotes.|n and |mReceiver2|n twice.",
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ class CmdTutorialGiveUp(default_cmds.MuxCommand):
|
|||
)
|
||||
return
|
||||
|
||||
self.caller.move_to(outro_room)
|
||||
self.caller.move_to(outro_room, move_type="teleport")
|
||||
|
||||
|
||||
class TutorialRoomCmdSet(CmdSet):
|
||||
|
|
@ -259,7 +259,7 @@ class TutorialRoom(DefaultRoom):
|
|||
)
|
||||
self.cmdset.add_default(TutorialRoomCmdSet)
|
||||
|
||||
def at_object_receive(self, new_arrival, source_location):
|
||||
def at_object_receive(self, new_arrival, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
When an object enter a tutorial room we tell other objects in
|
||||
the room about it by trying to call a hook on them. The Mob object
|
||||
|
|
@ -451,7 +451,7 @@ class IntroRoom(TutorialRoom):
|
|||
"the account."
|
||||
)
|
||||
|
||||
def at_object_receive(self, character, source_location):
|
||||
def at_object_receive(self, character, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Assign properties on characters
|
||||
"""
|
||||
|
|
@ -523,7 +523,7 @@ class CmdEast(Command):
|
|||
# Move to the east room.
|
||||
eexit = search_object(self.obj.db.east_exit)
|
||||
if eexit:
|
||||
caller.move_to(eexit[0])
|
||||
caller.move_to(eexit[0], move_type="traverse")
|
||||
else:
|
||||
caller.msg("No east exit was found for this room. Contact an admin.")
|
||||
return
|
||||
|
|
@ -570,7 +570,7 @@ class CmdWest(Command):
|
|||
# Move to the west room.
|
||||
wexit = search_object(self.obj.db.west_exit)
|
||||
if wexit:
|
||||
caller.move_to(wexit[0])
|
||||
caller.move_to(wexit[0], move_type="traverse")
|
||||
else:
|
||||
caller.msg("No west exit was found for this room. Contact an admin.")
|
||||
return
|
||||
|
|
@ -658,7 +658,7 @@ class CmdLookBridge(Command):
|
|||
fall_exit = search_object(self.obj.db.fall_exit)
|
||||
if fall_exit:
|
||||
self.caller.msg("|r%s|n" % FALL_MESSAGE)
|
||||
self.caller.move_to(fall_exit[0], quiet=True)
|
||||
self.caller.move_to(fall_exit[0], quiet=True, move_type="fall")
|
||||
# inform others on the bridge
|
||||
self.obj.msg_contents(
|
||||
"A plank gives way under %s's feet and "
|
||||
|
|
@ -770,7 +770,7 @@ class BridgeRoom(WeatherRoom):
|
|||
# send a message most of the time
|
||||
self.msg_contents("|w%s|n" % random.choice(BRIDGE_WEATHER))
|
||||
|
||||
def at_object_receive(self, character, source_location):
|
||||
def at_object_receive(self, character, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
This hook is called by the engine whenever the player is moved
|
||||
into this room.
|
||||
|
|
@ -796,7 +796,7 @@ class BridgeRoom(WeatherRoom):
|
|||
character.db.tutorial_bridge_position = 0
|
||||
character.execute_cmd("look")
|
||||
|
||||
def at_object_leave(self, character, target_location):
|
||||
def at_object_leave(self, character, target_location, move_type="move", **kwargs):
|
||||
"""
|
||||
This is triggered when the player leaves the bridge room.
|
||||
"""
|
||||
|
|
@ -1038,7 +1038,7 @@ class DarkRoom(TutorialRoom):
|
|||
# put players in darkness
|
||||
char.msg("The room is completely dark.")
|
||||
|
||||
def at_object_receive(self, obj, source_location):
|
||||
def at_object_receive(self, obj, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Called when an object enters the room.
|
||||
"""
|
||||
|
|
@ -1048,7 +1048,7 @@ class DarkRoom(TutorialRoom):
|
|||
# in case the new guy carries light with them
|
||||
self.check_light_state()
|
||||
|
||||
def at_object_leave(self, obj, target_location):
|
||||
def at_object_leave(self, obj, target_location, move_type="move", **kwargs):
|
||||
"""
|
||||
In case people leave with the light, we make sure to clear the
|
||||
DarkCmdSet if necessary. This also works if they are
|
||||
|
|
@ -1103,7 +1103,7 @@ class TeleportRoom(TutorialRoom):
|
|||
self.db.failure_teleport_msg = "You fail!"
|
||||
self.db.failure_teleport_to = "dark cell"
|
||||
|
||||
def at_object_receive(self, character, source_location):
|
||||
def at_object_receive(self, character, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
This hook is called by the engine whenever the player is moved into
|
||||
this room.
|
||||
|
|
@ -1130,7 +1130,7 @@ class TeleportRoom(TutorialRoom):
|
|||
else:
|
||||
character.msg(self.db.failure_teleport_msg)
|
||||
# teleport quietly to the new place
|
||||
character.move_to(results[0], quiet=True, move_hooks=False)
|
||||
character.move_to(results[0], quiet=True, move_hooks=False, move_type="teleport")
|
||||
# we have to call this manually since we turn off move_hooks
|
||||
# - this is necessary to make the target dark room aware of an
|
||||
# already carried light.
|
||||
|
|
@ -1167,7 +1167,7 @@ class OutroRoom(TutorialRoom):
|
|||
"character."
|
||||
)
|
||||
|
||||
def at_object_receive(self, character, source_location):
|
||||
def at_object_receive(self, character, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Do cleanup.
|
||||
"""
|
||||
|
|
@ -1183,6 +1183,6 @@ class OutroRoom(TutorialRoom):
|
|||
obj.delete()
|
||||
character.tags.clear(category="tutorial_world")
|
||||
|
||||
def at_object_leave(self, character, destination):
|
||||
def at_object_leave(self, character, destination, move_type="move", **kwargs):
|
||||
if character.account:
|
||||
character.account.execute_cmd("unquell")
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ class TestTutorialWorldRooms(BaseEvenniaCommandTest):
|
|||
def test_bridgeroom(self):
|
||||
room = create_object(tutrooms.BridgeRoom, key="bridgeroom")
|
||||
room.update_weather()
|
||||
self.char1.move_to(room)
|
||||
self.char1.move_to(room, move_type="teleport")
|
||||
self.call(
|
||||
tutrooms.CmdBridgeHelp(),
|
||||
"",
|
||||
|
|
@ -181,7 +181,7 @@ class TestTutorialWorldRooms(BaseEvenniaCommandTest):
|
|||
|
||||
def test_darkroom(self):
|
||||
room = create_object(tutrooms.DarkRoom, key="darkroom")
|
||||
self.char1.move_to(room)
|
||||
self.char1.move_to(room, move_type="teleport")
|
||||
self.call(tutrooms.CmdDarkHelp(), "", "Can't help you until")
|
||||
|
||||
def test_teleportroom(self):
|
||||
|
|
|
|||
|
|
@ -847,6 +847,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
use_destination=True,
|
||||
to_none=False,
|
||||
move_hooks=True,
|
||||
move_type="move",
|
||||
**kwargs,
|
||||
):
|
||||
"""
|
||||
|
|
@ -868,6 +869,11 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
move_hooks (bool): If False, turn off the calling of move-related hooks
|
||||
(at_pre/post_move etc) with quiet=True, this is as quiet a move
|
||||
as can be done.
|
||||
move_type (str): The "kind of move" being performed, such as "teleport", "traverse",
|
||||
"get", "give", or "drop". The value can be arbitrary. By default, it only affects
|
||||
the text message generated by announce_move_to and announce_move_from by defining
|
||||
their {"type": move_type} for outgoing text. This can be used for altering
|
||||
messages and/or overloaded hook behaviors.
|
||||
|
||||
Keyword Args:
|
||||
Passed on to announce_move_to and announce_move_from hooks.
|
||||
|
|
@ -924,7 +930,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
if move_hooks:
|
||||
# check if we are okay to move
|
||||
try:
|
||||
if not self.at_pre_move(destination, **kwargs):
|
||||
if not self.at_pre_move(destination, move_type=move_type, **kwargs):
|
||||
return False
|
||||
except Exception as err:
|
||||
logerr(errtxt.format(err="at_pre_move()"), err)
|
||||
|
|
@ -947,7 +953,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
# Call hook on source location
|
||||
if move_hooks and source_location:
|
||||
try:
|
||||
source_location.at_object_leave(self, destination, **kwargs)
|
||||
source_location.at_object_leave(self, destination, move_type=move_type, **kwargs)
|
||||
except Exception as err:
|
||||
logerr(errtxt.format(err="at_object_leave()"), err)
|
||||
return False
|
||||
|
|
@ -955,7 +961,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
if not quiet:
|
||||
# tell the old room we are leaving
|
||||
try:
|
||||
self.announce_move_from(destination, **kwargs)
|
||||
self.announce_move_from(destination, move_type=move_type, **kwargs)
|
||||
except Exception as err:
|
||||
logerr(errtxt.format(err="announce_move_from()"), err)
|
||||
return False
|
||||
|
|
@ -970,7 +976,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
if not quiet:
|
||||
# Tell the new room we are there.
|
||||
try:
|
||||
self.announce_move_to(source_location, **kwargs)
|
||||
self.announce_move_to(source_location, move_type=move_type, **kwargs)
|
||||
except Exception as err:
|
||||
logerr(errtxt.format(err="announce_move_to()"), err)
|
||||
return False
|
||||
|
|
@ -979,7 +985,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
# Perform eventual extra commands on the receiving location
|
||||
# (the object has already arrived at this point)
|
||||
try:
|
||||
destination.at_object_receive(self, source_location, **kwargs)
|
||||
destination.at_object_receive(self, source_location, move_type=move_type, **kwargs)
|
||||
except Exception as err:
|
||||
logerr(errtxt.format(err="at_object_receive()"), err)
|
||||
return False
|
||||
|
|
@ -988,7 +994,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
# (usually calling 'look')
|
||||
if move_hooks:
|
||||
try:
|
||||
self.at_post_move(source_location, **kwargs)
|
||||
self.at_post_move(source_location, move_type=move_type, **kwargs)
|
||||
except Exception as err:
|
||||
logerr(errtxt.format(err="at_post_move"), err)
|
||||
return False
|
||||
|
|
@ -1049,7 +1055,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
# Famous last words: The account should never see this.
|
||||
string = "This place should not exist ... contact an admin."
|
||||
obj.msg(_(string))
|
||||
obj.move_to(home)
|
||||
obj.move_to(home, move_type="teleport")
|
||||
|
||||
@classmethod
|
||||
def create(cls, key, account=None, **kwargs):
|
||||
|
|
@ -1501,13 +1507,17 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
|
||||
# hooks called when moving the object
|
||||
|
||||
def at_pre_move(self, destination, **kwargs):
|
||||
def at_pre_move(self, destination, move_type="move", **kwargs):
|
||||
"""
|
||||
Called just before starting to move this object to
|
||||
destination. Return False to abort move.
|
||||
|
||||
Args:
|
||||
destination (Object): The object we are moving to
|
||||
move_type (str): The type of move. "give", "traverse", etc.
|
||||
This is an arbitrary string provided to obj.move_to().
|
||||
Useful for altering messages or altering logic depending
|
||||
on the kind of movement.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
|
|
@ -1565,7 +1575,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
# deprecated alias
|
||||
at_before_move = at_pre_move
|
||||
|
||||
def announce_move_from(self, destination, msg=None, mapping=None, **kwargs):
|
||||
def announce_move_from(self, destination, msg=None, mapping=None, move_type="move", **kwargs):
|
||||
"""
|
||||
Called if the move is to be announced. This is
|
||||
called while we are still standing in the old
|
||||
|
|
@ -1575,6 +1585,10 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
destination (Object): The place we are going to.
|
||||
msg (str, optional): a replacement message.
|
||||
mapping (dict, optional): additional mapping objects.
|
||||
move_type (str): The type of move. "give", "traverse", etc.
|
||||
This is an arbitrary string provided to obj.move_to().
|
||||
Useful for altering messages or altering logic depending
|
||||
on the kind of movement.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
|
|
@ -1610,9 +1624,9 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
}
|
||||
)
|
||||
|
||||
location.msg_contents(string, exclude=(self,), from_obj=self, mapping=mapping)
|
||||
location.msg_contents((string, {"type": move_type}), exclude=(self,), from_obj=self, mapping=mapping)
|
||||
|
||||
def announce_move_to(self, source_location, msg=None, mapping=None, **kwargs):
|
||||
def announce_move_to(self, source_location, msg=None, mapping=None, move_type="move", **kwargs):
|
||||
"""
|
||||
Called after the move if the move was not quiet. At this point
|
||||
we are standing in the new location.
|
||||
|
|
@ -1621,6 +1635,10 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
source_location (Object): The place we came from
|
||||
msg (str, optional): the replacement message if location.
|
||||
mapping (dict, optional): additional mapping objects.
|
||||
move_type (str): The type of move. "give", "traverse", etc.
|
||||
This is an arbitrary string provided to obj.move_to().
|
||||
Useful for altering messages or altering logic depending
|
||||
on the kind of movement.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
|
|
@ -1674,9 +1692,9 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
}
|
||||
)
|
||||
|
||||
destination.msg_contents(string, exclude=(self,), from_obj=self, mapping=mapping)
|
||||
destination.msg_contents((string, {"type": move_type}), exclude=(self,), from_obj=self, mapping=mapping)
|
||||
|
||||
def at_post_move(self, source_location, **kwargs):
|
||||
def at_post_move(self, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Called after move has completed, regardless of quiet mode or
|
||||
not. Allows changes to the object due to the location it is
|
||||
|
|
@ -1684,6 +1702,10 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
|
||||
Args:
|
||||
source_location (Object): Wwhere we came from. This may be `None`.
|
||||
move_type (str): The type of move. "give", "traverse", etc.
|
||||
This is an arbitrary string provided to obj.move_to().
|
||||
Useful for altering messages or altering logic depending
|
||||
on the kind of movement.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
|
|
@ -1693,20 +1715,24 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
# deprecated
|
||||
at_after_move = at_post_move
|
||||
|
||||
def at_object_leave(self, moved_obj, target_location, **kwargs):
|
||||
def at_object_leave(self, moved_obj, target_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Called just before an object leaves from inside this object
|
||||
|
||||
Args:
|
||||
moved_obj (Object): The object leaving
|
||||
target_location (Object): Where `moved_obj` is going.
|
||||
move_type (str): The type of move. "give", "traverse", etc.
|
||||
This is an arbitrary string provided to obj.move_to().
|
||||
Useful for altering messages or altering logic depending
|
||||
on the kind of movement.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def at_object_receive(self, moved_obj, source_location, **kwargs):
|
||||
def at_object_receive(self, moved_obj, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
Called after an object has been moved into this object.
|
||||
|
||||
|
|
@ -1714,6 +1740,10 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
|||
moved_obj (Object): The object moved into this one
|
||||
source_location (Object): Where `moved_object` came from.
|
||||
Note that this could be `None`.
|
||||
move_type (str): The type of move. "give", "traverse", etc.
|
||||
This is an arbitrary string provided to obj.move_to().
|
||||
Useful for altering messages or altering logic depending
|
||||
on the kind of movement.
|
||||
**kwargs (dict): Arbitrary, optional arguments for users
|
||||
overriding the call (unused by default).
|
||||
|
||||
|
|
@ -2450,7 +2480,7 @@ class DefaultCharacter(DefaultObject):
|
|||
# add the default cmdset
|
||||
self.cmdset.add_default(settings.CMDSET_CHARACTER, persistent=True)
|
||||
|
||||
def at_post_move(self, source_location, **kwargs):
|
||||
def at_post_move(self, source_location, move_type="move", **kwargs):
|
||||
"""
|
||||
We make sure to look around after a move.
|
||||
|
||||
|
|
@ -2717,9 +2747,9 @@ class ExitCommand(_COMMAND_DEFAULT_CLASS):
|
|||
|
||||
"""
|
||||
if self.obj.destination:
|
||||
return " (exit to %s)" % self.obj.destination.get_display_name(caller)
|
||||
return " (exit to %s)" % self.obj.destination.get_display_name(caller, **kwargs)
|
||||
else:
|
||||
return " (%s)" % self.obj.get_display_name(caller)
|
||||
return " (%s)" % self.obj.get_display_name(caller, **kwargs)
|
||||
|
||||
|
||||
#
|
||||
|
|
@ -2928,7 +2958,7 @@ class DefaultExit(DefaultObject):
|
|||
|
||||
"""
|
||||
source_location = traversing_object.location
|
||||
if traversing_object.move_to(target_location):
|
||||
if traversing_object.move_to(target_location, move_type="traverse"):
|
||||
self.at_post_traverse(traversing_object, source_location)
|
||||
else:
|
||||
if self.db.err_traverse:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue