mirror of
https://github.com/evennia/evennia.git
synced 2026-03-19 22:36:31 +01:00
* Refactored the structure of the code a bit, for easier plugin expansion. The create_object() function now handles all the basic aspects of setting up an object, instead of relying on @create/@dig to set up things like parents, default descs etc. This also calls the creation hook on_object_creation() now. As part of this, the set-script-parent mechanism changed a bit under the hood - the engine itself is calling the set_script_parent() method on Object now instead of setting it up on its own and/or trusting @create and @dig to do it. Also set up the default descs for different object classes into the defaults_global file for easier administration.
The @dig command now accepts the specification of parents for all entries (room and all exits). In principle it also supports ALIASes for each exit, but the ALIAS attribute does not seem to be operational at the moment. /Griatch
This commit is contained in:
parent
a5a0d92985
commit
ee1b891ef4
4 changed files with 168 additions and 121 deletions
|
|
@ -97,7 +97,7 @@ def cmd_alias(command):
|
|||
return
|
||||
|
||||
old_alias = target.get_attribute_value('ALIAS', default='')
|
||||
print "ALIAS", old_alias
|
||||
#print "ALIAS", old_alias
|
||||
duplicates = Object.objects.player_alias_search(source_object, new_alias)
|
||||
if not duplicates or old_alias.lower() == new_alias.lower():
|
||||
# Either no duplicates or just changing the case of existing alias.
|
||||
|
|
@ -442,27 +442,28 @@ def cmd_create(command):
|
|||
|
||||
eq_args = command.command_argument.split(':', 1)
|
||||
target_name = eq_args[0]
|
||||
|
||||
|
||||
#check if we want to set a custom parent
|
||||
script_parent = None
|
||||
if len(eq_args) > 1:
|
||||
script_parent = eq_args[1].strip()
|
||||
|
||||
# Create and set the object up.
|
||||
new_object = Object.objects.create_object(target_name,
|
||||
defines_global.OTYPE_THING,
|
||||
source_object,
|
||||
source_object)
|
||||
new_object.set_attribute('desc', 'Nothing special.')
|
||||
if len(eq_args)>1:
|
||||
parent_str = eq_args[1]
|
||||
if parent_str and new_object.set_script_parent(parent_str):
|
||||
source_object,
|
||||
script_parent=script_parent)
|
||||
if script_parent:
|
||||
if new_object.get_script_parent() == script_parent:
|
||||
source_object.emit_to("You create %s as a child of %s." %
|
||||
(new_object, parent_str))
|
||||
(new_object, script_parent))
|
||||
else:
|
||||
source_object.emit_to("'%s' is not a valid parent. Using default." %
|
||||
parent_str)
|
||||
script_parent)
|
||||
else:
|
||||
source_object.emit_to("You create a new thing: %s" % (new_object,))
|
||||
|
||||
# Trigger stuff to happen after said object is created.
|
||||
new_object.scriptlink.at_object_creation()
|
||||
|
||||
GLOBAL_CMD_TABLE.add_command("@create", cmd_create,
|
||||
priv_tuple=("genperms.builder"),auto_help=True)
|
||||
|
||||
|
|
@ -738,97 +739,124 @@ def cmd_dig(command):
|
|||
where you are.
|
||||
|
||||
Usage:
|
||||
@dig[/switches] roomname [:parent] [=exitthere,exithere]
|
||||
@dig[/switches] roomname [:parent] [= exitthere [: parent][;alias]] [, exithere [: parent][;alias]]
|
||||
|
||||
switches:
|
||||
teleport - move yourself to the new room
|
||||
|
||||
example:
|
||||
@dig kitchen = north; n, south; s
|
||||
|
||||
|
||||
"""
|
||||
source_object = command.source_object
|
||||
|
||||
source_object = command.source_object
|
||||
args = command.command_argument
|
||||
switches = command.command_switches
|
||||
|
||||
parent = ''
|
||||
exits = []
|
||||
|
||||
if not args:
|
||||
source_object.emit_to("Usage[/teleport]: @dig roomname [:parent] [= exitthere, exithere]")
|
||||
source_object.emit_to("Usage[/teleport]: @dig roomname [:parent][= exitthere [:parent] [;alias]] [, exithere [:parent] [;alias]]")
|
||||
return
|
||||
|
||||
#handle arguments
|
||||
if ':' in args:
|
||||
roomname, args = args.split(':',1)
|
||||
if '=' in args:
|
||||
parent, args = args.split('=',1)
|
||||
if ',' in args:
|
||||
exits = args.split(',',1)
|
||||
else:
|
||||
exits = args
|
||||
else:
|
||||
parent = args
|
||||
elif '=' in args:
|
||||
roomname, args = args.split('=',1)
|
||||
if ',' in args:
|
||||
exits = args.split(',',1)
|
||||
else:
|
||||
exits = [args]
|
||||
room_name = None
|
||||
room_parent = None
|
||||
exit_names = [None,None]
|
||||
exit_parents = [None,None]
|
||||
exit_aliases = [[], []]
|
||||
|
||||
#deal with arguments
|
||||
arg_list = args.split("=",1)
|
||||
if len(arg_list) < 2:
|
||||
#just create a room, no exits
|
||||
room_name = largs[0].strip()
|
||||
else:
|
||||
roomname = args
|
||||
#deal with args left of =
|
||||
larg = arg_list[0]
|
||||
try:
|
||||
room_name, room_parent = [s.strip() for s in larg.split(":",1)]
|
||||
except ValueError:
|
||||
room_name = larg.strip()
|
||||
|
||||
if not roomname:
|
||||
source_object.emit_to("You must supply a new room name.")
|
||||
else:
|
||||
new_room = Object.objects.create_object(roomname,
|
||||
defines_global.OTYPE_ROOM,
|
||||
None,
|
||||
source_object)
|
||||
new_room.set_attribute("desc", "There is nothing special about this place.")
|
||||
source_object.emit_to("Created a new room '%s'." % (new_room,))
|
||||
|
||||
if parent:
|
||||
#(try to) set the script parent
|
||||
if not new_room.set_script_parent(parent):
|
||||
source_object.emit_to("%s is not a valid parent. Used default room." % parent)
|
||||
#deal with args right of =
|
||||
rarg = arg_list[1]
|
||||
exits = rarg.split(",",1)
|
||||
for ie, exi in enumerate(exits):
|
||||
aliaslist = exi.split(";")
|
||||
name_and_parent = aliaslist.pop(0) #pops the first index
|
||||
exit_aliases[ie] = aliaslist #what remains are the aliases
|
||||
try:
|
||||
exit_names[ie], exit_parents[ie] = [s.strip() for s in name_and_parent.split(":",1)]
|
||||
except ValueError:
|
||||
exit_names[ie] = name_and_parent.strip()
|
||||
|
||||
# Run custon creation commands on the script parent
|
||||
new_room.scriptlink.at_object_creation()
|
||||
|
||||
if exits:
|
||||
#create exits to (and possibly back from) the new room)
|
||||
destination = new_room #search_for_object(roomname)
|
||||
#start creating things.
|
||||
if not room_name:
|
||||
source_object.emit_to("You must supply a new room name.")
|
||||
return
|
||||
|
||||
new_room = Object.objects.create_object(room_name,
|
||||
defines_global.OTYPE_ROOM,
|
||||
None,
|
||||
source_object,
|
||||
script_parent=room_parent)
|
||||
ptext = ""
|
||||
if room_parent:
|
||||
if new_room.get_script_parent() == room_parent:
|
||||
ptext += " of type '%s'" % room_parent
|
||||
else:
|
||||
ptext += " of default type (parent '%s' failed!)" % room_parent
|
||||
source_object.emit_to("Created a new room '%s'%s." % (new_room, ptext))
|
||||
|
||||
if exit_names[0] != None:
|
||||
#create exits to the new room
|
||||
destination = new_room
|
||||
|
||||
if destination and not destination.is_exit():
|
||||
#create an exit from this room
|
||||
location = source_object.get_location()
|
||||
|
||||
new_object = Object.objects.create_object(exits[0].strip(),
|
||||
defines_global.OTYPE_EXIT,
|
||||
location,
|
||||
source_object,
|
||||
destination)
|
||||
new_object.set_attribute("desc", "This is an exit out of here.")
|
||||
source_object.emit_to("Created exit from %s to %s named '%s'." % (location,destination,new_object))
|
||||
|
||||
# Run custon creation commands on the exit
|
||||
new_object.scriptlink.at_object_creation()
|
||||
|
||||
if len(exits)>1:
|
||||
new_object = Object.objects.create_object(exits[1].strip(),
|
||||
defines_global.OTYPE_EXIT,
|
||||
destination,
|
||||
source_object,
|
||||
location)
|
||||
new_object.set_attribute("desc", "This is an exit out of here.")
|
||||
source_object.emit_to("Created exit back from %s to %s named '%s'" % (destination, location, new_object))
|
||||
# Run custon creation commands on the exit
|
||||
new_object.scriptlink.at_object_creation()
|
||||
|
||||
if destination and not destination.is_exit():
|
||||
#create an exit from this room
|
||||
location = source_object.get_location()
|
||||
new_object = Object.objects.create_object(exit_names[0],
|
||||
defines_global.OTYPE_EXIT,
|
||||
location,
|
||||
source_object,
|
||||
destination)
|
||||
ptext = ""
|
||||
if exit_parents[0]:
|
||||
script_parent = exit_parents[0]
|
||||
if new_object.get_script_parent() == script_parent:
|
||||
ptext += " of type %s" % script_parent
|
||||
else:
|
||||
ptext += " of default type (parent '%s' failed!)" % script_parent
|
||||
source_object.emit_to("Created exit%s from %s to %s named '%s'." % (ptext,location,destination,new_object))
|
||||
#the ALIAS mechanism only works with one ALIAS at this time.
|
||||
try:
|
||||
new_object.set_attribute("ALIAS", exit_aliases[0][0])
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
if len(exit_names) > 1 and exit_names[1] != None:
|
||||
#create exit back from new room to this one.
|
||||
new_object = Object.objects.create_object(exit_names[1],
|
||||
defines_global.OTYPE_EXIT,
|
||||
destination,
|
||||
source_object,
|
||||
location)
|
||||
ptext = ""
|
||||
if exit_parents[1]:
|
||||
script_parent = exit_parents[1]
|
||||
if new_object.get_script_parent() == script_parent:
|
||||
ptext += " of type %s" % script_parent
|
||||
else:
|
||||
ptext += " of default type (parent '%s' failed!)" % script_parent
|
||||
source_object.emit_to("Created exit%s back from %s to %s named '%s'." % \
|
||||
(ptext, destination, location, new_object))
|
||||
#the ALIAS mechanism only works with one ALIAS at this time.
|
||||
try:
|
||||
new_object.set_attribute("ALIAS", exit_aliases[1][0])
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
if 'teleport' in switches:
|
||||
source_object.move_to(new_room)
|
||||
|
||||
|
||||
|
||||
GLOBAL_CMD_TABLE.add_command("@dig", cmd_dig,
|
||||
priv_tuple=("genperms.builder"),)
|
||||
|
||||
|
|
@ -992,12 +1020,13 @@ def cmd_destroy(command):
|
|||
override - The @destroy command will usually avoid accidentally destroying
|
||||
player objects as well as objects with the SAFE flag. This
|
||||
switch overrides this safety.
|
||||
instant - Destroy the object immediately, without delay.
|
||||
instant|now - Destroy the object immediately, without delay.
|
||||
|
||||
The objects are set to GOING and will be permanently destroyed next time the system
|
||||
does cleanup. Until then non-player objects can still be saved by using the
|
||||
@recover command. The contents of a room will be moved out before it is destroyed,
|
||||
but its exits will also be destroyed. Note that player objects can not be recovered.
|
||||
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.
|
||||
"""
|
||||
|
||||
source_object = command.source_object
|
||||
|
|
@ -1045,7 +1074,7 @@ def cmd_destroy(command):
|
|||
#destroy the object (sets it to GOING)
|
||||
target_obj.destroy()
|
||||
|
||||
if 'instant' in switches:
|
||||
if 'instant' in switches or 'now' in switches:
|
||||
#sets to GARBAGE right away (makes dbref available)
|
||||
target_obj.delete()
|
||||
source_object.emit_to("You destroy %s." % target_obj.get_name())
|
||||
|
|
|
|||
|
|
@ -41,3 +41,9 @@ NOPERMS_MSG = "You do not have the necessary permissions to do that."
|
|||
|
||||
# Message seen when object doesn't control the other object.
|
||||
NOCONTROL_MSG = "You don't have authority over that object."
|
||||
|
||||
# Default descs when creating new objects
|
||||
DESC_PLAYER = "An average person."
|
||||
DESC_ROOM = "There is nothing special about this place."
|
||||
DESC_THING = "You see nothing special."
|
||||
DESC_EXIT = "This is an exit out of here."
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ class ObjectManager(models.Manager):
|
|||
# ObjectManager Create methods
|
||||
#
|
||||
|
||||
def create_object(self, name, otype, location, owner, home=None):
|
||||
def create_object(self, name, otype, location, owner, home=None, script_parent=None):
|
||||
"""
|
||||
Create a new object
|
||||
|
||||
|
|
@ -379,42 +379,59 @@ class ObjectManager(models.Manager):
|
|||
owner: The creator of the object.
|
||||
home: Reference to another object to home to. If not specified,
|
||||
set to location.
|
||||
script_parent: The parent of this object (ignored if otype is OTYPE_PLAYER)
|
||||
"""
|
||||
#get_nextfree_dbnum() returns either an integer or an object to recycle.
|
||||
#get_nextfree_dbnum() returns either an integer or an old object to recycle.
|
||||
next_dbref = self.get_nextfree_dbnum()
|
||||
|
||||
if type(next_dbref) == type(int()):
|
||||
#create object with new dbref
|
||||
#create new object with a fresh dbref
|
||||
Object = ContentType.objects.get(app_label="objects",
|
||||
model="object").model_class()
|
||||
new_object = Object()
|
||||
new_object.id = next_dbref
|
||||
else:
|
||||
#recycle an old object's dbref
|
||||
#recycle an old object instead
|
||||
new_object = next_dbref
|
||||
|
||||
new_object.type = otype
|
||||
new_object.set_name(name)
|
||||
|
||||
# Set the script_parent.
|
||||
# If the script_parent string is not valid, the defaults will be used.
|
||||
# To see if it worked or not from outside this method, easiest is to use the
|
||||
# obj.get_script_parent() function to find out what was actually set.
|
||||
new_object.set_script_parent(script_parent)
|
||||
|
||||
# If this is a player, we don't want him owned by anyone.
|
||||
# The get_owner() function will return that the player owns
|
||||
# himself.
|
||||
if otype == defines_global.OTYPE_PLAYER:
|
||||
new_object.owner = None
|
||||
new_object.zone = None
|
||||
new_object.script_parent = settings.SCRIPT_DEFAULT_PLAYER
|
||||
new_object.zone = None
|
||||
else:
|
||||
new_object.owner = owner
|
||||
new_object.script_parent = settings.SCRIPT_DEFAULT_OBJECT
|
||||
|
||||
if new_object.get_owner().get_zone():
|
||||
new_object.zone = new_object.get_owner().get_zone()
|
||||
|
||||
# Run the script parent's oncreation function
|
||||
|
||||
|
||||
# Set default description, depending on type.
|
||||
default_desc = None
|
||||
if otype == defines_global.OTYPE_PLAYER:
|
||||
default_desc = defines_global.DESC_PLAYER
|
||||
elif otype == defines_global.OTYPE_ROOM:
|
||||
default_desc = defines_global.DESC_ROOM
|
||||
elif otype == defines_global.OTYPE_EXIT:
|
||||
default_desc = defines_global.DESC_EXIT
|
||||
else:
|
||||
default_desc = defines_global.DESC_THING
|
||||
new_object.set_attribute("desc", default_desc)
|
||||
|
||||
# Run the script parent's creation hook function.
|
||||
# This is where all customization happens.
|
||||
new_object.scriptlink.at_object_creation()
|
||||
|
||||
# If we have a 'home' key, use that for our home value. Otherwise use
|
||||
# the location key.
|
||||
# the location key. All objects must have this
|
||||
if home:
|
||||
new_object.home = home
|
||||
else:
|
||||
|
|
@ -425,7 +442,7 @@ class ObjectManager(models.Manager):
|
|||
|
||||
new_object.save()
|
||||
|
||||
# Rooms have a NULL location.
|
||||
# Rooms have a NULL location. Move everything else to new location.
|
||||
if not new_object.is_room():
|
||||
new_object.move_to(location, quiet=True, force_look=False)
|
||||
|
||||
|
|
|
|||
|
|
@ -798,8 +798,7 @@ class Object(models.Model):
|
|||
|
||||
# Load the script reference into the object's attribute.
|
||||
self.scriptlink_cached = scripthandler.scriptlink(self,
|
||||
script_to_load)
|
||||
|
||||
script_to_load)
|
||||
if self.scriptlink_cached:
|
||||
# If the scriptlink variable can't be populated, this will fail
|
||||
# silently and let the exception hit in the scripthandler.
|
||||
|
|
@ -822,28 +821,24 @@ class Object(models.Model):
|
|||
# A parent has been set, load it from the field's value.
|
||||
return self.script_parent
|
||||
|
||||
def set_script_parent(self, parent_str):
|
||||
def set_script_parent(self, script_parent=None):
|
||||
"""
|
||||
Sets the object's script_parent attribute and does any logistics.
|
||||
|
||||
parent_str: (string) String pythonic import path of the script parent
|
||||
assuming the python path is game/gamesrc/parents.
|
||||
"""
|
||||
|
||||
if parent_str == None:
|
||||
if self.is_player():
|
||||
self.script_parent = settings.SCRIPT_DEFAULT_PLAYER
|
||||
else:
|
||||
self.script_parent = settings.SCRIPT_DEFAULT_OBJECT
|
||||
elif parent_str:
|
||||
#check if this is actually a reasonable script parent
|
||||
#(storing with a non-valid parent path causes havoc!)
|
||||
parent_str = str(parent_str).strip()
|
||||
if not scripthandler.scriptlink(self, parent_str):
|
||||
return False
|
||||
self.script_parent = parent_str
|
||||
script_parent: (string) String pythonic import path of the script parent
|
||||
assuming the python path is game/gamesrc/parents.
|
||||
"""
|
||||
if script_parent != None and scripthandler.scriptlink(self, str(script_parent).strip()):
|
||||
#assigning a custom parent
|
||||
self.script_parent = str(script_parent).strip()
|
||||
self.save()
|
||||
return
|
||||
#use a default parent instead
|
||||
if self.is_player():
|
||||
self.script_parent = settings.SCRIPT_DEFAULT_PLAYER
|
||||
else:
|
||||
self.script_parent = settings.SCRIPT_DEFAULT_OBJECT
|
||||
self.save()
|
||||
return True
|
||||
|
||||
def get_contents(self, filter_type=None):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue