mirror of
https://github.com/evennia/evennia.git
synced 2026-03-26 09:46:32 +01:00
Resolves issue 155. Cleaned up the copy functionality and a few minor bugs at the same time. Copying an active character is somewhat confusing though (and deleting a character will currently make the player unable to log back in).
This commit is contained in:
parent
4519169e1c
commit
695317e699
8 changed files with 82 additions and 33 deletions
|
|
@ -370,7 +370,13 @@ class CmdSetHandler(object):
|
|||
self.permanent_paths[0] = [self.permanent_paths[0]]
|
||||
self.obj.cmdset_storage = self.permanent_paths
|
||||
self.update()
|
||||
|
||||
|
||||
def all(self):
|
||||
"""
|
||||
Returns all cmdsets.
|
||||
"""
|
||||
return self.cmdset_stack
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
Force reload of all cmdsets in handler. This should be called
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ class CmdCopy(ObjManipCommand):
|
|||
caller = self.caller
|
||||
args = self.args
|
||||
if not args:
|
||||
caller.msg("Usage: @copy <obj> [=new_name[;alias;alias..]][:new_location]")
|
||||
caller.msg("Usage: @copy <obj> [=new_name[;alias;alias..]][:new_location] [, new_name2...]")
|
||||
return
|
||||
|
||||
if not self.rhs:
|
||||
|
|
@ -201,12 +201,11 @@ class CmdCopy(ObjManipCommand):
|
|||
if not from_obj:
|
||||
return
|
||||
to_obj_name = "%s_copy" % from_obj_name
|
||||
to_obj_aliases = from_obj.aliases
|
||||
to_obj_location = from_obj.location
|
||||
copiedobj = ObjectDB.objects.copy_object(from_obj, to_obj_name,
|
||||
to_obj_location, to_obj_aliases)
|
||||
to_obj_aliases = ["%s_copy" % alias for alias in from_obj.aliases]
|
||||
copiedobj = ObjectDB.objects.copy_object(from_obj, new_name=to_obj_name,
|
||||
new_aliases=to_obj_aliases)
|
||||
if copiedobj:
|
||||
string = "Identical copy of %s, named '%s' was created." % (to_obj_name, to_obj_name)
|
||||
string = "Identical copy of %s, named '%s' was created." % (from_obj_name, to_obj_name)
|
||||
else:
|
||||
string = "There was an error copying %s."
|
||||
else:
|
||||
|
|
@ -215,16 +214,22 @@ class CmdCopy(ObjManipCommand):
|
|||
from_obj = caller.search(from_obj_name)
|
||||
if not from_obj:
|
||||
return
|
||||
for objdef in self.lhs_objs:
|
||||
for objdef in self.rhs_objs:
|
||||
print objdef.items()
|
||||
# loop through all possible copy-to targets
|
||||
to_obj_name = objdef['name']
|
||||
to_obj_aliases = objdef['aliases']
|
||||
to_obj_location = objdef['option']
|
||||
copiedobj = ObjectDB.objects.copy_object(from_obj, to_obj_name,
|
||||
to_obj_location, to_obj_aliases)
|
||||
if to_obj_location:
|
||||
to_obj_location = caller.search(to_obj_location, global_search=True)
|
||||
if not to_obj_location:
|
||||
return
|
||||
|
||||
copiedobj = ObjectDB.objects.copy_object(from_obj, new_name=to_obj_name,
|
||||
new_location=to_obj_location, new_aliases=to_obj_aliases)
|
||||
if copiedobj:
|
||||
string = "Copied %s to '%s' (aliases: %s)." % (from_obj_name, to_obj_name,
|
||||
to_obj_aliases)
|
||||
to_obj_aliases)
|
||||
else:
|
||||
string = "There was an error copying %s to '%s'." % (from_obj_name,
|
||||
to_obj_name)
|
||||
|
|
@ -523,12 +528,12 @@ class CmdDestroy(MuxCommand):
|
|||
if not obj:
|
||||
continue
|
||||
objname = obj.name
|
||||
if obj.player and not 'override' in self.switches:
|
||||
string = "Object %s is a player object. Use /override to delete anyway." % objname
|
||||
continue
|
||||
if not obj.access(caller, 'delete'):
|
||||
string = "You don't have permission to delete %s." % objname
|
||||
continue
|
||||
if obj.player and not 'override' in self.switches:
|
||||
string = "Object %s is controlled by an active player. Use /override to delete anyway." % objname
|
||||
continue
|
||||
# do the deletion
|
||||
okay = obj.delete()
|
||||
if not okay:
|
||||
|
|
|
|||
|
|
@ -269,7 +269,8 @@ class ObjectManager(TypedObjectManager):
|
|||
#
|
||||
|
||||
def copy_object(self, original_object, new_name=None,
|
||||
new_location=None, new_home=None, new_aliases=None):
|
||||
new_location=None, new_player=None, new_home=None,
|
||||
new_permissions=None, new_locks=None, new_aliases=None):
|
||||
"""
|
||||
Create and return a new object as a copy of the source object. All will
|
||||
be identical to the original except for the arguments given specifically
|
||||
|
|
@ -289,19 +290,38 @@ class ObjectManager(TypedObjectManager):
|
|||
if not new_location:
|
||||
new_location = original_object.location
|
||||
if not new_home:
|
||||
new_home = original_object.new_home
|
||||
new_home = original_object.home
|
||||
if not new_player:
|
||||
new_player = original_object.player
|
||||
if not new_aliases:
|
||||
new_aliases = original_object.aliases
|
||||
if not new_locks:
|
||||
new_locks = original_object.db_lock_storage
|
||||
if not new_permissions:
|
||||
new_permissions = original_object.permissions
|
||||
|
||||
# create new object
|
||||
from src import create
|
||||
new_object = create.create_object(new_name, typeclass_path, new_location,
|
||||
new_home, user=None, aliases=new_aliases)
|
||||
from src.utils import create
|
||||
from src.scripts.models import ScriptDB
|
||||
new_object = create.create_object(typeclass_path, new_name, new_location,
|
||||
new_home, new_player, new_permissions,
|
||||
new_locks, new_aliases)
|
||||
if not new_object:
|
||||
return None
|
||||
|
||||
for attr in original_object.attr():
|
||||
# copy over all attributes from old to new.
|
||||
new_object.attr(attr.attr_name, attr.value)
|
||||
# copy over all attributes from old to new.
|
||||
for attr in original_object.get_all_attributes():
|
||||
new_object.set_attribute(attr.key, attr.value)
|
||||
|
||||
# copy over all cmdsets, if any
|
||||
for icmdset, cmdset in enumerate(original_object.cmdset.all()):
|
||||
if icmdset == 0:
|
||||
new_object.cmdset.add_default(cmdset)
|
||||
else:
|
||||
new_object.cmdset.add(cmdset)
|
||||
|
||||
# copy over all scripts, if any
|
||||
for script in original_object.scripts.all():
|
||||
ScriptDB.objects.copy_script(script, new_obj=new_object.dbobj)
|
||||
|
||||
return new_object
|
||||
|
|
|
|||
|
|
@ -748,12 +748,8 @@ class ObjectDB(TypedObject):
|
|||
# See if we need to kick the player off.
|
||||
for session in self.sessions:
|
||||
session.msg("Your character %s has been destroyed. Goodbye." % self.name)
|
||||
session.handle_close()
|
||||
|
||||
# # If the object is a player, set the player account
|
||||
# # object to inactive. We generally avoid deleting a
|
||||
# # player completely in case it messes with things
|
||||
# # like sent-message memory etc in some games.
|
||||
session.session_disconnect()
|
||||
|
||||
# if self.player:
|
||||
# self.player.user.is_active = False
|
||||
# self.player.user.save()
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ def returns_player_list(method):
|
|||
# there is something wrong with get_profile. But
|
||||
# there is a 1-1 relation between Users-Players, so we
|
||||
# try to go the other way instead.
|
||||
from src.players.models import PlayerDB
|
||||
from src.players.models import PlayerDB
|
||||
match = PlayerDB.objects.filter(user=user)
|
||||
if match:
|
||||
players.append(match[0])
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ class PlayerDB(TypedObject):
|
|||
#@property
|
||||
def character_get(self):
|
||||
"Getter. Allows for value = self.character"
|
||||
return self.obj
|
||||
return self.db_obj
|
||||
#@character.setter
|
||||
def character_set(self, value):
|
||||
"Setter. Allows for self.character = value"
|
||||
|
|
@ -169,7 +169,8 @@ class PlayerDB(TypedObject):
|
|||
#@character.deleter
|
||||
def character_del(self):
|
||||
"Deleter. Allows for del self.character"
|
||||
del self.obj
|
||||
self.db_obj = None
|
||||
self.save()
|
||||
character = property(character_get, character_set, character_del)
|
||||
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -169,3 +169,20 @@ class ScriptManager(TypedObjectManager):
|
|||
if only_timed:
|
||||
scripts = scripts.exclude(interval=0)
|
||||
return scripts
|
||||
|
||||
def copy_script(self, original_script, new_key=None, new_obj=None, new_locks=None):
|
||||
"""
|
||||
Make an identical copy of the original_script
|
||||
"""
|
||||
|
||||
typeclass = original_script.typeclass_path
|
||||
if not new_key:
|
||||
new_key = original_script.key
|
||||
if not new_obj:
|
||||
new_obj = original_script.obj
|
||||
if not new_locks:
|
||||
new_locks = original_script.db_lock_storage
|
||||
|
||||
from src.utils import create
|
||||
new_script = create.create_script(typeclass, key=new_key, obj=new_obj, locks=new_locks, autostart=True)
|
||||
return new_script
|
||||
|
|
|
|||
|
|
@ -238,12 +238,14 @@ class Attribute(SharedMemoryModel):
|
|||
|
||||
We handle only lists and dicts for iterables.
|
||||
"""
|
||||
#print "in validate_data:", item
|
||||
if isinstance(item, basestring):
|
||||
# a string is unmodified
|
||||
ret = item
|
||||
ret = item
|
||||
elif type(item) == PackedDBobject:
|
||||
# unpack a previously packed object
|
||||
try:
|
||||
#print "unpack:", item.id, item.db_model
|
||||
mclass = ContentType.objects.get(model=item.db_model).model_class()
|
||||
try:
|
||||
ret = mclass.objects.dbref_search(item.id)
|
||||
|
|
@ -265,10 +267,12 @@ class Attribute(SharedMemoryModel):
|
|||
elif has_parent('django.db.models.base.Model', item) or has_parent(PARENTS['typeclass'], item):
|
||||
# db models must be stored as dbrefs
|
||||
db_model = [parent for parent, path in PARENTS.items() if has_parent(path, item)]
|
||||
#print "db_model", db_model
|
||||
if db_model and db_model[0] == 'typeclass':
|
||||
# the typeclass alone can't help us, we have to know the db object.
|
||||
db_model = [parent for parent, path in PARENTS.items()
|
||||
if has_parent(path, item.dbobj)]
|
||||
if has_parent(path, item.dbobj)]
|
||||
#print "db_model2", db_model
|
||||
if db_model:
|
||||
# store the object in an easily identifiable container
|
||||
ret = PackedDBobject(str(item.id), db_model[0])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue