From 5eac62fd4a40e01571bf7662a14c1dd2cdffc787 Mon Sep 17 00:00:00 2001 From: InspectorCaracal Date: Tue, 1 Nov 2022 10:50:11 -0600 Subject: [PATCH] add optional fallback string to emotes --- evennia/contrib/rpg/rpsystem/rpsystem.py | 15 +++++++++++---- evennia/contrib/rpg/rpsystem/tests.py | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/evennia/contrib/rpg/rpsystem/rpsystem.py b/evennia/contrib/rpg/rpsystem/rpsystem.py index cb1b340a8e..aff8996d47 100644 --- a/evennia/contrib/rpg/rpsystem/rpsystem.py +++ b/evennia/contrib/rpg/rpsystem/rpsystem.py @@ -319,7 +319,7 @@ def parse_language(speaker, emote): return emote, mapping -def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_sensitive=True): +def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_sensitive=True, fallback=None): """ Read a raw emote and parse it into an intermediary format for distributing to all observers. @@ -332,11 +332,13 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_ string (str): The string (like an emote) we want to analyze for keywords. search_mode (bool, optional): If `True`, the "emote" is a query string we want to analyze. If so, the return value is changed. - case_sensitive (bool, optional); If set, the case of /refs matter, so that + case_sensitive (bool, optional): If set, the case of /refs matter, so that /tall will come out as 'tall man' while /Tall will become 'Tall man'. This allows for more grammatically correct emotes at the cost of being a little more to learn for players. If disabled, the original sdesc case is always kept and are inserted as-is. + fallback (string, optional): If set, any references that don't match a target + will be replaced with the fallback string. Returns: (emote, mapping) (tuple): If `search_mode` is `False` @@ -485,7 +487,11 @@ def parse_sdescs_and_recogs(sender, candidates, string, search_mode=False, case_ # single-object search mode. Don't continue loop. break elif nmatches == 0: - errors.append(_EMOTE_NOMATCH_ERROR.format(ref=marker_match.group())) + if fallback: + # replace unmatched reference with the fallback string + string = f"{head}{fallback}{tail}" + else: + 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 "" @@ -560,9 +566,10 @@ def send_emote(sender, receivers, emote, msg_type="pose", anonymous_add="first", """ case_sensitive = kwargs.pop("case_sensitive", True) + fallback = kwargs.pop("fallback", None) try: emote, obj_mapping = parse_sdescs_and_recogs( - sender, receivers, emote, case_sensitive=case_sensitive + sender, receivers, emote, case_sensitive=case_sensitive, fallback=fallback ) emote, language_mapping = parse_language(sender, emote) except (EmoteError, LanguageError) as err: diff --git a/evennia/contrib/rpg/rpsystem/tests.py b/evennia/contrib/rpg/rpsystem/tests.py index a84103d0c6..03d2659b2b 100644 --- a/evennia/contrib/rpg/rpsystem/tests.py +++ b/evennia/contrib/rpg/rpsystem/tests.py @@ -243,6 +243,26 @@ class TestRPSystem(BaseEvenniaTest): 'receiver of emotes.|n and |mReceiver2|n. She says |w"This is a test."|n', ) + def test_send_emote_fallback(self): + speaker = self.speaker + receiver1 = self.receiver1 + receivers = [speaker, receiver1] + speaker.sdesc.add(sdesc0) + receiver1.sdesc.add(sdesc1) + speaker.msg = lambda text, **kwargs: setattr(self, "out0", text) + receiver1.msg = lambda text, **kwargs: setattr(self, "out1", text) + rpsystem.send_emote(speaker, receivers, emote, case_sensitive=False, fallback="something") + self.assertEqual( + self.out0[0], + "With a flair, |mSender|n looks at |bThe first receiver of emotes.|n " + 'and |bsomething|n. She says |w"This is a test."|n', + ) + self.assertEqual( + self.out1[0], + "With a flair, |bA nice sender of emotes|n looks at |mReceiver1|n and " + '|bsomething|n. She says |w"This is a test."|n', + ) + def test_send_case_sensitive_emote(self): """Test new case-sensitive rp-parsing""" speaker = self.speaker