From 8fd19928b2553d65a2c391841bd1a5b50fb0fa88 Mon Sep 17 00:00:00 2001 From: InspectorCaracal Date: Wed, 6 Jul 2022 15:03:40 -0600 Subject: [PATCH 01/14] add special handling for self-references --- evennia/contrib/rpg/rpsystem/rpsystem.py | 27 +++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/evennia/contrib/rpg/rpsystem/rpsystem.py b/evennia/contrib/rpg/rpsystem/rpsystem.py index f50ad88326..89e284dcb9 100644 --- a/evennia/contrib/rpg/rpsystem/rpsystem.py +++ b/evennia/contrib/rpg/rpsystem/rpsystem.py @@ -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\b|@", _RE_FLAGS) # regex for non-alphanumberic end of a string _RE_CHAREND = re.compile(r"\W+$", _RE_FLAGS) @@ -365,6 +365,31 @@ 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 = "~" # 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 = matched.lstrip(_PREFIX) + if matchtext.istitle(): + case = "t" + elif matchtext.isupper(): + case = "^" + elif matchtext.islower(): + case = "v" + + key = f"#{sender.id}{case}" + # replaced with ref + string = string.replace(matched,f"{{{key}}}") + 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 From 169ec4fa5949e8c3ec8c39aa98559e75c3dba4e6 Mon Sep 17 00:00:00 2001 From: InspectorCaracal Date: Wed, 6 Jul 2022 15:37:52 -0600 Subject: [PATCH 02/14] move the case-ref analysis to a helper --- evennia/contrib/rpg/rpsystem/rpsystem.py | 56 ++++++++++-------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/evennia/contrib/rpg/rpsystem/rpsystem.py b/evennia/contrib/rpg/rpsystem/rpsystem.py index 89e284dcb9..f4db843ec0 100644 --- a/evennia/contrib/rpg/rpsystem/rpsystem.py +++ b/evennia/contrib/rpg/rpsystem/rpsystem.py @@ -235,6 +235,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): @@ -368,22 +388,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_ # first, find and replace any self-refs for self_match in list(_RE_SELF_REF.finditer(string)): matched = self_match.group() - 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 = matched.lstrip(_PREFIX) - if matchtext.istitle(): - case = "t" - elif matchtext.isupper(): - case = "^" - elif matchtext.islower(): - case = "v" - + case = _get_case_ref(matched.lstrip(_PREFIX)) if case_sensitive else "~" key = f"#{sender.id}{case}" # replaced with ref string = string.replace(matched,f"{{{key}}}") @@ -481,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 From dbaaf80e5e29e3408bfa62f635014a69c9134bcf Mon Sep 17 00:00:00 2001 From: InspectorCaracal Date: Mon, 11 Jul 2022 10:42:50 -0600 Subject: [PATCH 03/14] quick patch to be consistent with test expectations --- evennia/contrib/rpg/rpsystem/rpsystem.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evennia/contrib/rpg/rpsystem/rpsystem.py b/evennia/contrib/rpg/rpsystem/rpsystem.py index f4db843ec0..1e79af0b04 100644 --- a/evennia/contrib/rpg/rpsystem/rpsystem.py +++ b/evennia/contrib/rpg/rpsystem/rpsystem.py @@ -388,7 +388,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_ # 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 "~" + case = _get_case_ref(matched.lstrip(_PREFIX)) if case_sensitive else "" key = f"#{sender.id}{case}" # replaced with ref string = string.replace(matched,f"{{{key}}}") @@ -486,7 +486,7 @@ 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 = _get_case_ref(marker_match.group()) if case_sensitive else "~" + 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}" From add1518c95c4917444764116adb6f84dff749642 Mon Sep 17 00:00:00 2001 From: InspectorCaracal Date: Mon, 11 Jul 2022 11:12:40 -0600 Subject: [PATCH 04/14] match punctuated self-ref cases with regex --- evennia/contrib/rpg/rpsystem/rpsystem.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/evennia/contrib/rpg/rpsystem/rpsystem.py b/evennia/contrib/rpg/rpsystem/rpsystem.py index 1e79af0b04..8592feb108 100644 --- a/evennia/contrib/rpg/rpsystem/rpsystem.py +++ b/evennia/contrib/rpg/rpsystem/rpsystem.py @@ -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\b|@", _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) @@ -359,7 +359,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"): @@ -391,10 +391,9 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_ case = _get_case_ref(matched.lstrip(_PREFIX)) if case_sensitive else "" key = f"#{sender.id}{case}" # replaced with ref - string = string.replace(matched,f"{{{key}}}") + 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 From 303f836fa19b2785ad9832c1f9d861379fde6819 Mon Sep 17 00:00:00 2001 From: InspectorCaracal Date: Mon, 11 Jul 2022 11:23:17 -0600 Subject: [PATCH 05/14] update tests --- evennia/contrib/rpg/rpsystem/tests.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/evennia/contrib/rpg/rpsystem/tests.py b/evennia/contrib/rpg/rpsystem/tests.py index bd2ea32896..b8c7048c8d 100644 --- a/evennia/contrib/rpg/rpsystem/tests.py +++ b/evennia/contrib/rpg/rpsystem/tests.py @@ -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,7 +141,7 @@ 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) @@ -149,9 +150,9 @@ class TestRPSystem(BaseEvenniaTest): result = ( 'With a flair, {#9} looks at {#10} and {#11}. 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", + "#11": self.receiver2, + "#10": self.receiver1, + "#9": speaker, }, ) self.assertEqual( @@ -164,6 +165,24 @@ 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) + candidates = (self.receiver1, self.receiver2) + result = ( + "{#9} frowns at {#10} for trying to steal {#9}'s test.", + { + "#10": self.receiver1, + "#9": 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 From c9772e199fd8b2fb2af2e6ffaf4acfdf2dc5b8c8 Mon Sep 17 00:00:00 2001 From: InspectorCaracal Date: Mon, 11 Jul 2022 11:54:18 -0600 Subject: [PATCH 06/14] actually update tests --- evennia/contrib/rpg/rpsystem/tests.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/evennia/contrib/rpg/rpsystem/tests.py b/evennia/contrib/rpg/rpsystem/tests.py index b8c7048c8d..f62c77f63b 100644 --- a/evennia/contrib/rpg/rpsystem/tests.py +++ b/evennia/contrib/rpg/rpsystem/tests.py @@ -146,13 +146,16 @@ class TestRPSystem(BaseEvenniaTest): 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": self.receiver2, - "#10": self.receiver1, - "#9": speaker, + id2: self.receiver2, + id1: self.receiver1, + id0: speaker, }, ) self.assertEqual( @@ -170,12 +173,15 @@ class TestRPSystem(BaseEvenniaTest): 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 = ( - "{#9} frowns at {#10} for trying to steal {#9}'s test.", + "{"+id0+"} frowns at {"+id1+"} for trying to steal {"+id0+"}'s test.", { - "#10": self.receiver1, - "#9": speaker, + id1: self.receiver1, + id0: speaker, }, ) self.assertEqual( From c99cd45f93a7dfdc6a424f115af35c70649e94db Mon Sep 17 00:00:00 2001 From: Andrew Bastien Date: Sun, 10 Jul 2022 19:36:57 -0400 Subject: [PATCH 07/14] Added move_type to obj.move_to and its many hooks and what calls it. --- docs/source/Howtos/NPC-shop-Tutorial.md | 2 +- docs/source/Howtos/Tutorial-Vehicles.md | 4 +- evennia/commands/default/building.py | 5 ++- evennia/commands/default/general.py | 8 ++-- .../full_systems/evscaperoom/commands.py | 2 +- .../contrib/game_systems/clothing/clothing.py | 6 +-- evennia/contrib/grid/slow_exit/slow_exit.py | 2 +- .../contrib/tutorials/tutorial_world/rooms.py | 10 ++--- .../contrib/tutorials/tutorial_world/tests.py | 4 +- evennia/objects/objects.py | 42 ++++++++++++------- 10 files changed, 48 insertions(+), 37 deletions(-) diff --git a/docs/source/Howtos/NPC-shop-Tutorial.md b/docs/source/Howtos/NPC-shop-Tutorial.md index db37508f95..209f2d17f3 100644 --- a/docs/source/Howtos/NPC-shop-Tutorial.md +++ b/docs/source/Howtos/NPC-shop-Tutorial.md @@ -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) diff --git a/docs/source/Howtos/Tutorial-Vehicles.md b/docs/source/Howtos/Tutorial-Vehicles.md index a62aa485f3..acb074de6a 100644 --- a/docs/source/Howtos/Tutorial-Vehicles.md +++ b/docs/source/Howtos/Tutorial-Vehicles.md @@ -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): diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index c81c320b3e..feac9de984 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -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: diff --git a/evennia/commands/default/general.py b/evennia/commands/default/general.py index ca66727d94..98ad671e7a 100644 --- a/evennia/commands/default/general.py +++ b/evennia/commands/default/general.py @@ -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: diff --git a/evennia/contrib/full_systems/evscaperoom/commands.py b/evennia/contrib/full_systems/evscaperoom/commands.py index 15695e7caa..16a5706ecf 100644 --- a/evennia/contrib/full_systems/evscaperoom/commands.py +++ b/evennia/contrib/full_systems/evscaperoom/commands.py @@ -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) diff --git a/evennia/contrib/game_systems/clothing/clothing.py b/evennia/contrib/game_systems/clothing/clothing.py index 04554f7580..8c11f27d4e 100644 --- a/evennia/contrib/game_systems/clothing/clothing.py +++ b/evennia/contrib/game_systems/clothing/clothing.py @@ -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) diff --git a/evennia/contrib/grid/slow_exit/slow_exit.py b/evennia/contrib/grid/slow_exit/slow_exit.py index 2b4ff0f003..e5050e3f76 100644 --- a/evennia/contrib/grid/slow_exit/slow_exit.py +++ b/evennia/contrib/grid/slow_exit/slow_exit.py @@ -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: diff --git a/evennia/contrib/tutorials/tutorial_world/rooms.py b/evennia/contrib/tutorials/tutorial_world/rooms.py index 8f23363134..620f8c0ce4 100644 --- a/evennia/contrib/tutorials/tutorial_world/rooms.py +++ b/evennia/contrib/tutorials/tutorial_world/rooms.py @@ -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): @@ -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 " @@ -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. diff --git a/evennia/contrib/tutorials/tutorial_world/tests.py b/evennia/contrib/tutorials/tutorial_world/tests.py index 07f4391a72..8a0b722cf9 100644 --- a/evennia/contrib/tutorials/tutorial_world/tests.py +++ b/evennia/contrib/tutorials/tutorial_world/tests.py @@ -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): diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index d2a2b6e8a4..0497152258 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -836,6 +836,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): use_destination=True, to_none=False, move_hooks=True, + move_type="move", **kwargs, ): """ @@ -857,6 +858,10 @@ 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): Will be used for generating the text tuple {"type": move_type}, + and can be used for log filtering in hooks. Evennia has only a few + move_types for move_to to start with, like "teleport", "traverse", + "get", "give", and "drop". Keyword Args: Passed on to announce_move_to and announce_move_from hooks. @@ -906,7 +911,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): # Before the move, call eventual pre-commands. if move_hooks: 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) @@ -918,7 +923,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 @@ -926,7 +931,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 @@ -941,7 +946,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 @@ -950,7 +955,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 @@ -959,7 +964,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 @@ -1020,7 +1025,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): @@ -1472,13 +1477,14 @@ 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. Args: destination (Object): The object we are moving to + move_type (str): The type of move. "give", "traverse", etc. **kwargs (dict): Arbitrary, optional arguments for users overriding the call (unused by default). @@ -1496,7 +1502,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 @@ -1506,6 +1512,7 @@ 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. **kwargs (dict): Arbitrary, optional arguments for users overriding the call (unused by default). @@ -1541,9 +1548,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. @@ -1552,6 +1559,7 @@ 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. **kwargs (dict): Arbitrary, optional arguments for users overriding the call (unused by default). @@ -1605,7 +1613,7 @@ 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): """ @@ -1624,20 +1632,21 @@ 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. **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. @@ -1645,6 +1654,7 @@ 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. **kwargs (dict): Arbitrary, optional arguments for users overriding the call (unused by default). @@ -2381,7 +2391,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. @@ -2859,7 +2869,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: From 93aae906bff10ae3b9119cc08f0074e063e1622f Mon Sep 17 00:00:00 2001 From: Andrew Bastien Date: Mon, 11 Jul 2022 21:52:52 -0400 Subject: [PATCH 08/14] Improving documentation. --- evennia/objects/objects.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 0497152258..b5a2c8d338 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -858,10 +858,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): Will be used for generating the text tuple {"type": move_type}, - and can be used for log filtering in hooks. Evennia has only a few - move_types for move_to to start with, like "teleport", "traverse", - "get", "give", and "drop". + 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. @@ -1513,6 +1514,9 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): 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). @@ -1560,6 +1564,9 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): 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). @@ -1655,6 +1662,9 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): 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). From 641811ec1cd9b6ab0c95f8e8a92e40987eaf80b3 Mon Sep 17 00:00:00 2001 From: Andrew Bastien Date: Thu, 14 Jul 2022 19:43:08 -0400 Subject: [PATCH 09/14] Added msg_type to rpsystem.send_emote() --- evennia/contrib/rpg/rpsystem/rpsystem.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/evennia/contrib/rpg/rpsystem/rpsystem.py b/evennia/contrib/rpg/rpsystem/rpsystem.py index f50ad88326..1089f38ed2 100644 --- a/evennia/contrib/rpg/rpsystem/rpsystem.py +++ b/evennia/contrib/rpg/rpsystem/rpsystem.py @@ -513,7 +513,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 +523,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 +602,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 +913,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 From 22353b2e92ce28c53e08c57385e67aac3f9ba378 Mon Sep 17 00:00:00 2001 From: Andrew Bastien Date: Thu, 14 Jul 2022 19:46:49 -0400 Subject: [PATCH 10/14] Added msg_type to rpsystem.send_emote() --- evennia/contrib/rpg/rpsystem/rpsystem.py | 41 ++++++++++++------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/evennia/contrib/rpg/rpsystem/rpsystem.py b/evennia/contrib/rpg/rpsystem/rpsystem.py index 1089f38ed2..5c10cc9a0b 100644 --- a/evennia/contrib/rpg/rpsystem/rpsystem.py +++ b/evennia/contrib/rpg/rpsystem/rpsystem.py @@ -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. @@ -375,7 +376,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 +422,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) @@ -513,7 +514,7 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_ return string, mapping -def send_emote(sender, receivers, emote, msg_type = "pose", anonymous_add="first", **kwargs): +def send_emote(sender, receivers, emote, msg_type="pose", anonymous_add="first", **kwargs): """ Main access function for distribute an emote. @@ -1256,19 +1257,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 @@ -1352,10 +1353,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 From 8ae1650b05b99c49e2b6c70dea9a15bdff4c5677 Mon Sep 17 00:00:00 2001 From: Andrew Bastien Date: Thu, 14 Jul 2022 20:02:47 -0400 Subject: [PATCH 11/14] Added msg_type to rpsystem.send_emote() --- evennia/contrib/rpg/rpsystem/tests.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/evennia/contrib/rpg/rpsystem/tests.py b/evennia/contrib/rpg/rpsystem/tests.py index bd2ea32896..370ba2e8aa 100644 --- a/evennia/contrib/rpg/rpsystem/tests.py +++ b/evennia/contrib/rpg/rpsystem/tests.py @@ -197,17 +197,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 +226,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.", From e0dc224d088f59f34c6803b7df1f7d0e41bbb91b Mon Sep 17 00:00:00 2001 From: Andrew Bastien Date: Thu, 14 Jul 2022 22:53:37 -0400 Subject: [PATCH 12/14] Fixed remaining issues. All tests pass. --- .../base_systems/ingame_python/typeclasses.py | 24 +++++++++---------- .../contrib/full_systems/evscaperoom/room.py | 4 ++-- evennia/contrib/grid/wilderness/wilderness.py | 2 +- .../contrib/tutorials/tutorial_world/rooms.py | 18 +++++++------- evennia/objects/objects.py | 16 ++++++++++--- 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/evennia/contrib/base_systems/ingame_python/typeclasses.py b/evennia/contrib/base_systems/ingame_python/typeclasses.py index de70631218..804b4c4a93 100644 --- a/evennia/contrib/base_systems/ingame_python/typeclasses.py +++ b/evennia/contrib/base_systems/ingame_python/typeclasses.py @@ -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) diff --git a/evennia/contrib/full_systems/evscaperoom/room.py b/evennia/contrib/full_systems/evscaperoom/room.py index 9b4a8205e8..934f363ecc 100644 --- a/evennia/contrib/full_systems/evscaperoom/room.py +++ b/evennia/contrib/full_systems/evscaperoom/room.py @@ -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. diff --git a/evennia/contrib/grid/wilderness/wilderness.py b/evennia/contrib/grid/wilderness/wilderness.py index 7ad043240d..418ad4253d 100644 --- a/evennia/contrib/grid/wilderness/wilderness.py +++ b/evennia/contrib/grid/wilderness/wilderness.py @@ -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. diff --git a/evennia/contrib/tutorials/tutorial_world/rooms.py b/evennia/contrib/tutorials/tutorial_world/rooms.py index 620f8c0ce4..54a46c3fea 100644 --- a/evennia/contrib/tutorials/tutorial_world/rooms.py +++ b/evennia/contrib/tutorials/tutorial_world/rooms.py @@ -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 """ @@ -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. @@ -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") diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index b5a2c8d338..7ae296bf2c 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -1486,6 +1486,9 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): 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). @@ -1622,7 +1625,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): 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 @@ -1630,6 +1633,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). @@ -1647,6 +1654,9 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): 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). @@ -2668,9 +2678,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) # From 9c7d3c6fc7957d8d3857bb5cecc8fe110bd4d9f3 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 24 Jul 2022 08:49:31 +0200 Subject: [PATCH 13/14] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be0527668a..e85f54ba8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -168,6 +168,8 @@ Up requirements to Django 4.0+, Twisted 22+, Python 3.9 or 3.10 now return `None` instead of `.db.desc` if no sdesc is set; fallback in hook (inspectorCaracal) - Reworked text2html parser to avoid problems with stateful color tags (inspectorCaracal) - Simplified `EvMenu.options_formatter` hook to use `EvColumn` and f-strings (inspectorcaracal) +- Added `move_type` str kwarg to `move_to()` calls, optionally identifying the type of + move being done ('teleport', 'disembark', 'give' etc). (volund) ## Evennia 0.9.5 From 99d300799e8dc74be9f451b2157b6495001ca94a Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 24 Jul 2022 08:58:44 +0200 Subject: [PATCH 14/14] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e85f54ba8b..3fef5c9181 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -170,6 +170,8 @@ 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) - 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