Cleaned up @link, @open and @dig, making these commands more useful and less buggy with strange input. Also made them work not only with #dbrefs but with any unique game object (possibly one should limit this to e.g. room's); if there's a multiple match a list of the relevant dbrefs are shown. You can also now inspect links/home settins using this command.
@open also supports script_parents when creating exits. /Griatch
This commit is contained in:
parent
66095a0b16
commit
42254355a0
3 changed files with 201 additions and 105 deletions
|
|
@ -439,6 +439,8 @@ def cmd_create(command):
|
||||||
have a correct parent object defined in parents/examples/red_button.py, you would
|
have a correct parent object defined in parents/examples/red_button.py, you would
|
||||||
load create a new object inheriting from this parent like this:
|
load create a new object inheriting from this parent like this:
|
||||||
@create button:examples.red_button
|
@create button:examples.red_button
|
||||||
|
|
||||||
|
(See also @destroy, @dig and @open.)
|
||||||
"""
|
"""
|
||||||
source_object = command.source_object
|
source_object = command.source_object
|
||||||
|
|
||||||
|
|
@ -557,77 +559,119 @@ GLOBAL_CMD_TABLE.add_command("@nextfree", cmd_nextfree,
|
||||||
priv_tuple=("objects.info",),auto_help=True,staff_help=True)
|
priv_tuple=("objects.info",),auto_help=True,staff_help=True)
|
||||||
|
|
||||||
def cmd_open(command):
|
def cmd_open(command):
|
||||||
"""
|
"""@open
|
||||||
Handle the opening of exits.
|
Usage:
|
||||||
|
@open <new exit> [:parent] [= <destination> [,<return exit> [:parent]]]
|
||||||
|
|
||||||
Forms:
|
Handles the creation of exits. If a destination is given, the exit
|
||||||
@open <Name>
|
will point there. The <return exit> argument sets up an exit at the
|
||||||
@open <Name>=<Dbref>
|
destination leading back to the current room. Destination name
|
||||||
@open <Name>=<Dbref>,<Name>
|
can be given both as a #dbref and a name, if that name is globally
|
||||||
|
unique.
|
||||||
|
|
||||||
|
(See also @create, @dig and @link.)
|
||||||
"""
|
"""
|
||||||
source_object = command.source_object
|
source_object = command.source_object
|
||||||
|
args = command.command_argument
|
||||||
if not command.command_argument:
|
if not args:
|
||||||
source_object.emit_to("Usage: @open <name> [=dbref [,<name>]]")
|
source_object.emit_to("Usage: @open <new exit> [:parent] [= <destination> [,<return exit> [:parent]]]")
|
||||||
return
|
return
|
||||||
|
dest_name = ""
|
||||||
|
return_exit = ""
|
||||||
|
exit_parent = None
|
||||||
|
return_exit_parent = None
|
||||||
|
# handle all arguments
|
||||||
|
arglist = args.split('=', 1)
|
||||||
|
#left side of =
|
||||||
|
largs = arglist[0].split(':')
|
||||||
|
if len(largs) > 1:
|
||||||
|
exit_name, exit_parent = largs[0].strip(), largs[1].strip()
|
||||||
|
else:
|
||||||
|
exit_name = largs[0].strip()
|
||||||
|
if len(arglist) > 1:
|
||||||
|
# right side of =
|
||||||
|
rargs = arglist[1].split(',',1)
|
||||||
|
if len(rargs) > 1:
|
||||||
|
dest_name, rargs = rargs[0].strip(),rargs[1].strip()
|
||||||
|
rargs = rargs.split(":")
|
||||||
|
if len(rargs) > 1:
|
||||||
|
return_exit, return_exit_parent = rargs[0].strip(), rargs[1].strip()
|
||||||
|
else:
|
||||||
|
return_exit = rargs[0].strip()
|
||||||
|
else:
|
||||||
|
dest_name = rargs[0].strip()
|
||||||
|
|
||||||
eq_args = command.command_argument.split('=', 1)
|
# sanity checking
|
||||||
exit_name = eq_args[0]
|
if not exit_name:
|
||||||
|
|
||||||
if len(exit_name) == 0:
|
|
||||||
source_object.emit_to("You must supply an exit name.")
|
source_object.emit_to("You must supply an exit name.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# If we have more than one entry in our '=' delimited argument list,
|
if not dest_name:
|
||||||
# then we're doing a @open <Name>=<Dbref>[,<Name>]. If not, we're doing
|
# we want an unlinked exit.
|
||||||
# an un-linked exit, @open <Name>.
|
new_object = Object.objects.create_object(exit_name,
|
||||||
if len(eq_args) > 1:
|
defines_global.OTYPE_EXIT,
|
||||||
# Opening an exit to another location via @open <Name>=<Dbref>[,<Name>].
|
source_object.get_location(),
|
||||||
comma_split = eq_args[1].split(',', 1)
|
source_object,
|
||||||
# Use search_for_object to handle duplicate/nonexistant results.
|
None,
|
||||||
destination = source_object.search_for_object(comma_split[0])
|
script_parent=exit_parent)
|
||||||
|
ptext = ""
|
||||||
|
if exit_parent:
|
||||||
|
if new_object.get_script_parent() == exit_parent:
|
||||||
|
ptext += " of type %s" % exit_parent
|
||||||
|
else:
|
||||||
|
ptext += " of default type (parent '%s' failed!)" % exit_parent
|
||||||
|
source_object.emit_to("Created unlinked exit%s named '%s'." % (ptext,new_object))
|
||||||
|
|
||||||
|
else:
|
||||||
|
# We have the name of a destination. Try to find it.
|
||||||
|
destination = Object.objects.global_object_name_search(dest_name)
|
||||||
if not destination:
|
if not destination:
|
||||||
|
source_object.emit_to("No matches found for '%s'." % dest_name)
|
||||||
return
|
return
|
||||||
|
if len(destination) > 1:
|
||||||
|
s = "There are multiple matches. Please use #dbref to be more specific."
|
||||||
|
for d in destination:
|
||||||
|
s += "\n %s" % destination.get_name()
|
||||||
|
source_object.emit_to(s)
|
||||||
|
return
|
||||||
|
destination = destination[0]
|
||||||
|
|
||||||
if destination.is_exit():
|
if destination.is_exit():
|
||||||
source_object.emit_to("You can't open an exit to an exit!")
|
source_object.emit_to("You can't open an exit to an exit!")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
#build the exit from here to destination
|
||||||
new_object = Object.objects.create_object(exit_name,
|
new_object = Object.objects.create_object(exit_name,
|
||||||
defines_global.OTYPE_EXIT,
|
defines_global.OTYPE_EXIT,
|
||||||
source_object.get_location(),
|
source_object.get_location(),
|
||||||
source_object,
|
source_object,
|
||||||
destination)
|
destination,
|
||||||
|
script_parent=exit_parent)
|
||||||
|
ptext = ""
|
||||||
|
if exit_parent:
|
||||||
|
if new_object.get_script_parent() == exit_parent:
|
||||||
|
ptext += " of type %s" % exit_parent
|
||||||
|
else:
|
||||||
|
ptext += " of default type (parent '%s' failed!)" % exit_parent
|
||||||
|
source_object.emit_to("Created exit%s to %s named '%s'." % (ptext,destination,new_object))
|
||||||
|
|
||||||
source_object.emit_to("You open the an exit - %s to %s" % (
|
if return_exit:
|
||||||
new_object.get_name(),
|
new_object = Object.objects.create_object(return_exit,
|
||||||
destination.get_name()))
|
|
||||||
if len(comma_split) > 1:
|
|
||||||
second_exit_name = ','.join(comma_split[1:])
|
|
||||||
#odat = {"name": second_exit_name,
|
|
||||||
# "type": defines_global.OTYPE_EXIT,
|
|
||||||
# "location": destination,
|
|
||||||
# "owner": source_object,
|
|
||||||
# "home": source_object.get_location()}
|
|
||||||
new_object = Object.objects.create_object(second_exit_name,
|
|
||||||
defines_global.OTYPE_EXIT,
|
defines_global.OTYPE_EXIT,
|
||||||
destination,
|
destination,
|
||||||
source_object,
|
source_object,
|
||||||
source_object.get_location())
|
source_object.get_location(),
|
||||||
source_object.emit_to("You open the an exit - %s to %s" % (
|
script_parent=return_exit_parent)
|
||||||
new_object.get_name(),
|
ptext = ""
|
||||||
source_object.get_location().get_name()))
|
if return_exit_parent:
|
||||||
|
if new_object.get_script_parent() == return_exit_parent:
|
||||||
else:
|
ptext += " of type %s" % return_exit_parent
|
||||||
# Create an un-linked exit.
|
else:
|
||||||
new_object = Object.objects.create_object(exit_name,
|
ptext += " of default type (parent '%s' failed!)" % return_exit_parent
|
||||||
defines_global.OTYPE_EXIT,
|
source_object.emit_to("Created exit%s back from %s named %s." % \
|
||||||
source_object.get_location(),
|
(ptext, destination, new_object))
|
||||||
source_object,
|
|
||||||
None)
|
|
||||||
source_object.emit_to("You open an unlinked exit - %s" % new_object)
|
|
||||||
GLOBAL_CMD_TABLE.add_command("@open", cmd_open,
|
GLOBAL_CMD_TABLE.add_command("@open", cmd_open,
|
||||||
priv_tuple=("objects.dig",))
|
priv_tuple=("objects.dig",),auto_help=True,staff_help=True)
|
||||||
|
|
||||||
def cmd_chown(command):
|
def cmd_chown(command):
|
||||||
"""
|
"""
|
||||||
|
|
@ -733,56 +777,95 @@ def cmd_chzone(command):
|
||||||
GLOBAL_CMD_TABLE.add_command("@chzone", cmd_chzone, priv_tuple=("objects.dig",))
|
GLOBAL_CMD_TABLE.add_command("@chzone", cmd_chzone, priv_tuple=("objects.dig",))
|
||||||
|
|
||||||
def cmd_link(command):
|
def cmd_link(command):
|
||||||
"""
|
"""@link
|
||||||
Sets an object's home or an exit's destination.
|
Usage:
|
||||||
|
@link <object> = <target>
|
||||||
|
@link <object> =
|
||||||
|
@link <object>
|
||||||
|
|
||||||
Forms:
|
If <object> is an exit, set its destination. For all other object types, this
|
||||||
@link <Object>=<Target>
|
command sets the object's Home.
|
||||||
|
The second form sets the destination/home to None and the third form inspects
|
||||||
|
the current value of destination/home on <object>.
|
||||||
|
|
||||||
|
(See also @create, @dig and @open)
|
||||||
"""
|
"""
|
||||||
source_object = command.source_object
|
source_object = command.source_object
|
||||||
|
|
||||||
if not command.command_argument:
|
if not command.command_argument:
|
||||||
source_object.emit_to("Usage: @link <object> = <target>")
|
source_object.emit_to("Usage: @link <object> = <target>")
|
||||||
return
|
return
|
||||||
|
dest_name = ""
|
||||||
|
arglist = command.command_argument.split('=', 1)
|
||||||
|
if len(arglist) > 1:
|
||||||
|
obj_name, dest_name = arglist[0].strip(), arglist[1].strip()
|
||||||
|
else:
|
||||||
|
obj_name = arglist[0].strip()
|
||||||
|
|
||||||
eq_args = command.command_argument.split('=', 1)
|
# sanity checks
|
||||||
target_name = eq_args[0]
|
if not obj_name:
|
||||||
dest_name = eq_args[1]
|
|
||||||
|
|
||||||
if len(target_name) == 0:
|
|
||||||
source_object.emit_to("What do you want to link?")
|
source_object.emit_to("What do you want to link?")
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(eq_args) > 1:
|
# Use search_for_object to handle duplicate/nonexistant results.
|
||||||
target_obj = source_object.search_for_object(target_name)
|
obj = source_object.search_for_object(obj_name)
|
||||||
# Use search_for_object to handle duplicate/nonexistant results.
|
if not obj:
|
||||||
if not target_obj:
|
return
|
||||||
return
|
otype = obj.get_type()
|
||||||
|
|
||||||
if not source_object.controls_other(target_obj):
|
if not dest_name:
|
||||||
|
# We haven't provided a target.
|
||||||
|
if len(arglist) > 1:
|
||||||
|
# the command looks like '@link obj =', this means we unlink the
|
||||||
|
if not source_object.controls_other(obj):
|
||||||
|
source_object.emit_to(defines_global.NOCONTROL_MSG)
|
||||||
|
return
|
||||||
|
oldhome = obj.get_home()
|
||||||
|
ohome_text = ""
|
||||||
|
if oldhome:
|
||||||
|
ohome_text = " (was %s)" % oldhome
|
||||||
|
obj.set_home(None)
|
||||||
|
if otype == "EXIT":
|
||||||
|
source_object.emit_to("You have unlinked %s%s." % (obj,ohome_text))
|
||||||
|
else:
|
||||||
|
source_object.emit_to("You removed %s's home setting%s." % (obj,ohome_text))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
# the command looks like '@link obj', we just inspect the object.
|
||||||
|
if otype == "EXIT":
|
||||||
|
source_object.emit_to("%s currently links to %s." % (obj.get_name(), obj.get_home()))
|
||||||
|
else:
|
||||||
|
source_object.emit_to("%s's current home is %s." % (obj.get_name(), obj.get_home()))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
# we have a destination, search for it globally.
|
||||||
|
if not source_object.controls_other(obj):
|
||||||
source_object.emit_to(defines_global.NOCONTROL_MSG)
|
source_object.emit_to(defines_global.NOCONTROL_MSG)
|
||||||
return
|
return
|
||||||
|
destination = Object.objects.global_object_name_search(dest_name)
|
||||||
# If we do something like "@link blah=", we unlink the object.
|
|
||||||
if len(dest_name) == 0:
|
|
||||||
target_obj.set_home(None)
|
|
||||||
source_object.emit_to("You have unlinked %s." % (target_obj,))
|
|
||||||
return
|
|
||||||
|
|
||||||
destination = source_object.search_for_object(dest_name)
|
|
||||||
# Use search_for_object to handle duplicate/nonexistant results.
|
|
||||||
if not destination:
|
if not destination:
|
||||||
|
source_object.emit_to("No matches found for '%s'." % dest_name)
|
||||||
return
|
return
|
||||||
|
if len(destination) > 1:
|
||||||
|
s = "There are multiple matches. Please use #dbref to be more specific."
|
||||||
|
for d in destination:
|
||||||
|
s += "\n %s" % destination.get_name()
|
||||||
|
source_object.emit_to(s)
|
||||||
|
return
|
||||||
|
destination = destination[0]
|
||||||
|
|
||||||
target_obj.set_home(destination)
|
# do the link.
|
||||||
source_object.emit_to("You link %s to %s." % (target_obj, destination))
|
oldhome = obj.get_home()
|
||||||
|
ohome_text = ""
|
||||||
else:
|
if oldhome:
|
||||||
# We haven't provided a target.
|
ohome_text = " (was %s)" % oldhome
|
||||||
source_object.emit_to("You must provide a destination to link to.")
|
obj.set_home(destination)
|
||||||
return
|
if otype == "EXIT":
|
||||||
|
source_object.emit_to("You link %s to %s%s." % (obj, destination, ohome_text))
|
||||||
|
else:
|
||||||
|
source_object.emit_to("You set the home location of %s to %s%s." % (obj, destination, ohome_text))
|
||||||
GLOBAL_CMD_TABLE.add_command("@link", cmd_link,
|
GLOBAL_CMD_TABLE.add_command("@link", cmd_link,
|
||||||
priv_tuple=("objects.dig",))
|
priv_tuple=("objects.dig",), auto_help=True, staff_help=True)
|
||||||
|
|
||||||
def cmd_unlink(command):
|
def cmd_unlink(command):
|
||||||
"""
|
"""
|
||||||
|
|
@ -811,20 +894,19 @@ GLOBAL_CMD_TABLE.add_command("@unlink", cmd_unlink,
|
||||||
priv_tuple=("objects.dig",))
|
priv_tuple=("objects.dig",))
|
||||||
|
|
||||||
def cmd_dig(command):
|
def cmd_dig(command):
|
||||||
"""
|
"""@dig
|
||||||
Creates a new room object and optionally connects it to
|
|
||||||
where you are.
|
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
@dig[/switches] roomname [:parent] [= exit_to_there [: parent][;alias]] [, exit_to_here [: parent][;alias]]
|
@dig[/switches] roomname [:parent] [= exit_to_there [: parent][;alias]] [, exit_to_here [: parent][;alias]]
|
||||||
|
|
||||||
switches:
|
switches:
|
||||||
teleport - move yourself to the new room
|
teleport - move yourself to the new room
|
||||||
|
|
||||||
example:
|
example:
|
||||||
@dig kitchen = north; n, south; s
|
@dig kitchen = north; n, south; s
|
||||||
|
|
||||||
|
This command is a convenient way to build rooms quickly; it creates the new room and you can optionally
|
||||||
|
set up exits back and forth between your current room and the new one.
|
||||||
|
((NOTE - ALIASES ARE NOT YET FUNCTIONAL.))
|
||||||
|
|
||||||
|
(See also @create, @open and @link.)
|
||||||
"""
|
"""
|
||||||
source_object = command.source_object
|
source_object = command.source_object
|
||||||
args = command.command_argument
|
args = command.command_argument
|
||||||
|
|
@ -894,7 +976,8 @@ def cmd_dig(command):
|
||||||
defines_global.OTYPE_EXIT,
|
defines_global.OTYPE_EXIT,
|
||||||
location,
|
location,
|
||||||
source_object,
|
source_object,
|
||||||
destination)
|
destination,
|
||||||
|
script_parent=exit_parents[0])
|
||||||
ptext = ""
|
ptext = ""
|
||||||
if exit_parents[0]:
|
if exit_parents[0]:
|
||||||
script_parent = exit_parents[0]
|
script_parent = exit_parents[0]
|
||||||
|
|
@ -915,7 +998,8 @@ def cmd_dig(command):
|
||||||
defines_global.OTYPE_EXIT,
|
defines_global.OTYPE_EXIT,
|
||||||
destination,
|
destination,
|
||||||
source_object,
|
source_object,
|
||||||
location)
|
location,
|
||||||
|
script_parent=exit_parents[1])
|
||||||
ptext = ""
|
ptext = ""
|
||||||
if exit_parents[1]:
|
if exit_parents[1]:
|
||||||
script_parent = exit_parents[1]
|
script_parent = exit_parents[1]
|
||||||
|
|
@ -935,7 +1019,7 @@ def cmd_dig(command):
|
||||||
source_object.move_to(new_room)
|
source_object.move_to(new_room)
|
||||||
|
|
||||||
GLOBAL_CMD_TABLE.add_command("@dig", cmd_dig,
|
GLOBAL_CMD_TABLE.add_command("@dig", cmd_dig,
|
||||||
priv_tuple=("objects.dig",))
|
priv_tuple=("objects.dig",), auto_help=True, staff_help=True)
|
||||||
|
|
||||||
def cmd_name(command):
|
def cmd_name(command):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1104,6 +1188,8 @@ def cmd_destroy(command):
|
||||||
@recover command. The contents of a room will be moved out before it is destroyed,
|
@recover command. The contents of a room will be moved out before it is destroyed,
|
||||||
and all exits leading to and fro the room will also be destroyed. Note that destroyed
|
and all exits leading to and fro the room will also be destroyed. Note that destroyed
|
||||||
player objects can not be recovered by the @recover command.
|
player objects can not be recovered by the @recover command.
|
||||||
|
|
||||||
|
(See also @create and @open.)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
source_object = command.source_object
|
source_object = command.source_object
|
||||||
|
|
|
||||||
|
|
@ -133,15 +133,20 @@ class ObjectManager(models.Manager):
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def global_object_name_search(self, ostring, exact_match=False):
|
def global_object_name_search(self, ostring, exact_match=False, limit_types=[]):
|
||||||
"""
|
"""
|
||||||
Searches through all objects for a name match.
|
Searches through all objects for a name match.
|
||||||
|
limit_types is a list of types as defined in defines_global.
|
||||||
"""
|
"""
|
||||||
|
if self.is_dbref(ostring):
|
||||||
|
return [self.dbref_search(ostring, limit_types=limit_types)]
|
||||||
|
|
||||||
if exact_match:
|
if exact_match:
|
||||||
o_query = self.filter(name__iexact=ostring)
|
o_query = self.filter(name__iexact=ostring)
|
||||||
else:
|
else:
|
||||||
o_query = self.filter(name__icontains=ostring)
|
o_query = self.filter(name__icontains=ostring)
|
||||||
|
if limit_types:
|
||||||
|
o_query = o_query.include(type__in=limit_types)
|
||||||
return o_query.exclude(type__in=[defines_global.OTYPE_GARBAGE,
|
return o_query.exclude(type__in=[defines_global.OTYPE_GARBAGE,
|
||||||
defines_global.OTYPE_GOING])
|
defines_global.OTYPE_GOING])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
This is where all of the crucial, core object models reside.
|
This is where all of the crucial, core object models reside.
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
|
import traceback
|
||||||
|
|
||||||
try: import cPickle as pickle
|
try: import cPickle as pickle
|
||||||
except ImportError: import pickle
|
except ImportError: import pickle
|
||||||
|
|
@ -603,12 +604,16 @@ class Object(models.Model):
|
||||||
attrib: (str) The attribute's name.
|
attrib: (str) The attribute's name.
|
||||||
"""
|
"""
|
||||||
if self.has_attribute(attrib):
|
if self.has_attribute(attrib):
|
||||||
attrib = Attribute.objects.filter(attr_object=self).filter(attr_name=attrib)[0]
|
try:
|
||||||
|
attrib = Attribute.objects.filter(attr_object=self).filter(attr_name=attrib)[0]
|
||||||
|
except:
|
||||||
|
# safety, if something goes wrong (like unsynced db), catch it.
|
||||||
|
logger.log_errmsg(traceback.print_exc())
|
||||||
|
return default
|
||||||
return attrib.get_value()
|
return attrib.get_value()
|
||||||
else:
|
else:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
def get_attribute_obj(self, attrib):
|
def get_attribute_obj(self, attrib):
|
||||||
"""
|
"""
|
||||||
Returns the attribute object matching the specified name.
|
Returns the attribute object matching the specified name.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue