From 1822b010860c9637278f4777b1a788449acb1a9b Mon Sep 17 00:00:00 2001 From: Jonathan Piacenti Date: Sat, 20 Jun 2015 14:37:05 -0500 Subject: [PATCH] Add display_name and disambiguation_tag for dynamic naming. --- evennia/commands/cmdparser.py | 36 +++------------------------ evennia/commands/command.py | 12 +++++++++ evennia/commands/default/building.py | 37 +++++++++++++++------------- evennia/comms/channelhandler.py | 6 +++++ evennia/objects/objects.py | 9 +++++++ evennia/typeclasses/models.py | 25 +++++++++++++++++++ 6 files changed, 75 insertions(+), 50 deletions(-) diff --git a/evennia/commands/cmdparser.py b/evennia/commands/cmdparser.py index 1835b6679..e392444b0 100644 --- a/evennia/commands/cmdparser.py +++ b/evennia/commands/cmdparser.py @@ -187,9 +187,6 @@ def at_search_result(msg_obj, ostring, results, global_search=False, # we have more than one match. We will display a # list of the form 1-objname, 2-objname etc. - # check if the msg_object may se dbrefs - show_dbref = global_search - if multimatch_string: # custom header string = multimatch_string @@ -199,14 +196,7 @@ def at_search_result(msg_obj, ostring, results, global_search=False, string = _(string) for num, result in enumerate(results): - invtext = "" - dbreftext = "" - if hasattr(result, _("location")) and result.location == msg_obj: - invtext = _(" (carried)") - if show_dbref: - dbreftext = "(#%i)" % result.dbid - string += "\n %i-%s%s%s" % (num + 1, result.name, - dbreftext, invtext) + string += "\n %i-%s%s" % (num + 1, result.name, result.get_extra_info(msg_obj)) results = None else: # we have exactly one match. @@ -292,26 +282,6 @@ def at_multimatch_cmd(caller, matches): # each match is a tuple (candidate, cmd) cmdname, arg, cmd, dum, dum = match - is_channel = hasattr(cmd, "is_channel") and cmd.is_channel - if is_channel: - is_channel = _(" (channel)") - else: - is_channel = "" - if cmd.is_exit and cmd.destination: - is_exit = (" (exit to %s)") % cmd.destination - else: - is_exit = "" - - id1 = "" - id2 = "" - if (not (is_channel or is_exit) and - (hasattr(cmd, 'obj') and cmd.obj != caller) and - hasattr(cmd.obj, "key")): - # the command is defined on some other object - id1 = "%s-%s" % (num + 1, cmdname) - id2 = " (%s)" % (cmd.obj.key) - else: - id1 = "%s-%s" % (num + 1, cmdname) - id2 = "" - string += "\n %s%s%s%s" % (id1, id2, is_channel, is_exit) + get_extra_info = cmd.get_extra_info(caller) + string += "%s-%s%s" % (num + 1, cmdname, get_extra_info) return string diff --git a/evennia/commands/command.py b/evennia/commands/command.py index 2a8dc4134..99b21fba3 100644 --- a/evennia/commands/command.py +++ b/evennia/commands/command.py @@ -348,3 +348,15 @@ class Command(object): string += fill("current cmdset (self.cmdset): {w%s{n\n" % (self.cmdset.key if self.cmdset.key else self.cmdset.__class__)) self.caller.msg(string) + + def get_extra_info(self, caller, **kwargs): + """ + Display some extra information that may help distinguish this command from others, for instance, + in a disambiguity prompt. + + If this command is a potential match in an ambiguous situation, one distinguishing + feature may be its attachment to a nearby object, so we include this by default if available. + """ + if hasattr(self, 'obj'): + return " (%s)" % self.obj.display_name(caller) + return "" diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index f56034a3e..7faa05681 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -138,9 +138,9 @@ class CmdSetObjAlias(MuxCommand): # no =, so we just list aliases on object. aliases = obj.aliases.all() if aliases: - caller.msg("Aliases for '%s': %s" % (obj.key, ", ".join(aliases))) + caller.msg("Aliases for '%s': %s" % (obj.display_name(caller), ", ".join(aliases))) else: - caller.msg("No aliases exist for '%s'." % obj.key) + caller.msg("No aliases exist for '%s'." % obj.display_name(caller)) return if not obj.access(caller, 'edit'): @@ -151,7 +151,7 @@ class CmdSetObjAlias(MuxCommand): # we have given an empty =, so delete aliases old_aliases = obj.aliases.all() if old_aliases: - caller.msg("Cleared aliases from %s: %s" % (obj.key, ", ".join(old_aliases))) + caller.msg("Cleared aliases from %s: %s" % (obj.display_name(caller), ", ".join(old_aliases))) obj.aliases.clear() else: caller.msg("No aliases to clear.") @@ -175,7 +175,7 @@ class CmdSetObjAlias(MuxCommand): obj.at_cmdset_get(force_init=True) # report all aliases on the object - caller.msg("Alias(es) for '%s' set to %s." % (obj.key, str(obj.aliases))) + caller.msg("Alias(es) for '%s' set to %s." % (obj.display_name(caller), str(obj.aliases))) class CmdCopy(ObjManipCommand): @@ -587,7 +587,7 @@ class CmdDesc(MuxCommand): desc = self.args obj.db.desc = desc - caller.msg("The description was set on %s." % obj.key) + caller.msg("The description was set on %s." % obj.display_name(caller)) class CmdDestroy(MuxCommand): @@ -2085,8 +2085,7 @@ class CmdFind(MuxCommand): string += "\n {RNo match found for '%s' in #dbref interval.{n" % (searchstring) else: result=result[0] - string += "\n{g %s(%s) - %s{n" % (result.key, result.dbref, - result.path) + string += "\n{g %s - %s{n" % (result.display_name(caller), result.path) else: # Not a player/dbref search but a wider search; build a queryset. # Searchs for key and aliases @@ -2118,10 +2117,10 @@ class CmdFind(MuxCommand): if nresults > 1: string = "{w%i Matches{n(#%i-#%i%s):" % (nresults, low, high, restrictions) for res in results: - string += "\n {g%s(%s) - %s{n" % (res.key, res.dbref, res.path) + string += "\n {g%s - %s{n" % (res.display_name(caller), res.path) else: string = "{wOne Match{n(#%i-#%i%s):" % (low, high, restrictions) - string += "\n {g%s(%s) - %s{n" % (results[0].key, results[0].dbref, results[0].path) + string += "\n {g%s - %s{n" % (results[0].display_name(caller), results[0].path) else: string = "{wMatch{n(#%i-#%i%s):" % (low, high, restrictions) string += "\n {RNo matches found for '%s'{n" % searchstring @@ -2279,18 +2278,18 @@ class CmdScript(MuxCommand): # no rhs means we want to operate on all scripts scripts = obj.scripts.all() if not scripts: - string += "No scripts defined on %s." % obj.key + string += "No scripts defined on %s." % obj.display_name(caller) elif not self.switches: # view all scripts from evennia.commands.default.system import format_script_list string += format_script_list(scripts) elif "start" in self.switches: num = sum([obj.scripts.start(script.key) for script in scripts]) - string += "%s scripts started on %s." % (num, obj.key) + string += "%s scripts started on %s." % (num, obj.display_name(caller)) elif "stop" in self.switches: for script in scripts: - string += "Stopping script %s on %s." % (script.key, - obj.key) + string += "Stopping script %s on %s." % (script.display_name(caller), + obj.display_name(caller)) script.stop() string = string.strip() obj.scripts.validate() @@ -2299,9 +2298,13 @@ class CmdScript(MuxCommand): # adding a new script, and starting it ok = obj.scripts.add(self.rhs, autostart=True) if not ok: - string += "\nScript %s could not be added and/or started on %s." % (self.rhs, obj.key) + string += "\nScript %s could not be added and/or started on %s." % ( + self.rhs, obj.display_name(caller) + ) else: - string = "Script {w%s{n successfully added and started on %s." % (self.rhs, obj.key) + string = "Script {w%s{n successfully added and started on %s." % ( + self.rhs, obj.display_name(caller) + ) else: paths = [self.rhs] + ["%s.%s" % (prefix, self.rhs) @@ -2371,7 +2374,7 @@ class CmdTag(MuxCommand): if nobjs > 0: catstr = " (category: '{w%s{n')" % category if category else \ ("" if nobjs == 1 else " (may have different tag categories)") - matchstr = ", ".join("{w%s{n(#%i)" % (o.key, o.dbid) for o in objs) + matchstr = ", ".join(o.display_name(self.caller) for o in objs) string = "Found {w%i{n object%s with tag '{w%s{n'%s:\n %s" % (nobjs, "s" if nobjs > 1 else "", @@ -2525,6 +2528,6 @@ class CmdSpawn(MuxCommand): prototype["location"] = self.caller.location for obj in spawn(prototype): - self.caller.msg("Spawned %s." % obj.key) + self.caller.msg("Spawned %s." % obj.display_name(self.caller)) diff --git a/evennia/comms/channelhandler.py b/evennia/comms/channelhandler.py index 27b3f5222..f559038d2 100644 --- a/evennia/comms/channelhandler.py +++ b/evennia/comms/channelhandler.py @@ -81,6 +81,12 @@ class ChannelCommand(command.Command): return channel.msg(msg, senders=self.caller, online=True) + def get_extra_info(self, caller, **kwargs): + """ + Let users know that this exit is for communicating on a channel. + """ + return _(" (channel)") + class ChannelHandler(object): """ diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 1a0a283d4..08abc3ebd 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -1476,6 +1476,15 @@ class ExitCommand(command.Command): # No shorthand error message. Call hook. self.obj.at_failed_traverse(self.caller) + def get_extra_info(self, caller, **kwargs): + """ + Shows a bit of information on where the exit leads. + """ + if self.obj.destination: + return " (exit to %s)" % self.obj.destination.display_name(caller) + else: + return " (%s)" % self.obj.display_name(caller) + # # Base Exit object # diff --git a/evennia/typeclasses/models.py b/evennia/typeclasses/models.py index 850b97bc7..4281bed9a 100644 --- a/evennia/typeclasses/models.py +++ b/evennia/typeclasses/models.py @@ -610,3 +610,28 @@ class TypedObject(SharedMemoryModel): raise Exception("Cannot delete the ndb object!") ndb = property(__ndb_get, __ndb_set, __ndb_del) + def display_name(self, looker, **kwargs): + """ + Displays the name of the object in a viewer-aware manner. + + Note that this function could be extended to change how object names + appear to users, but be wary. This function does not change an object's keys or + aliases when searching, and is expected to produce something useful for builders. + """ + if self.access(looker, access_type='controls'): + return "{}(#{})".format(self.name, self.id) + return self.name + + def get_extra_info(self, viewer, **kwargs): + """ + Used when an object is in a list of ambiguous objects as an additional + information tag. + + For instance, if you had potions which could have varying levels of liquid + left in them, you might want to display how many drinks are left in each when + selecting which to drop, but not in your normal inventory listing. + """ + + if self.location == viewer: + return " (carried)" + return ""