diff --git a/game/gamesrc/parents/examples/__init__.py b/game/gamesrc/parents/examples/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/game/gamesrc/parents/examples/red_button.py b/game/gamesrc/parents/examples/red_button.py new file mode 100644 index 0000000000..c4977ff805 --- /dev/null +++ b/game/gamesrc/parents/examples/red_button.py @@ -0,0 +1,31 @@ +""" +An example script parent for a +""" +from src.cmdtable import CommandTable +from game.gamesrc.parents.base.basicobject import BasicObject + +COMMAND_TABLE = CommandTable() +def cmd_push_button(command): + """ + An example command to show how the pluggable command system works. + """ + # By building one big string and passing it at once, we cut down on a lot + # of emit_to() calls, which is generally a good idea. + retval = "Test" + command.source_object.emit_to(retval) +# Add the command to the object's command table. +COMMAND_TABLE.add_command("push button", cmd_push_button) + +class RedButton(BasicObject): + def __init__(self, source_obj, *args, **kwargs): + super(RedButton, self).__init__(source_obj, args, kwargs) + self.command_table = COMMAND_TABLE + +def class_factory(source_obj): + """ + This method is called any script you retrieve (via the scripthandler). It + creates an instance of the class and returns it transparently. + + source_obj: (Object) A reference to the object being scripted (the child). + """ + return RedButton(source_obj) \ No newline at end of file diff --git a/src/commands/general.py b/src/commands/general.py index 52de536f36..507f11cdcf 100644 --- a/src/commands/general.py +++ b/src/commands/general.py @@ -289,10 +289,7 @@ def cmd_examine(command): source_object.emit_to("Desc: %s" % target_obj.get_description(no_parsing=True)) source_object.emit_to("Owner: %s " % (target_obj.get_owner(),)) source_object.emit_to("Zone: %s" % (target_obj.get_zone(),)) - - parent_str = target_obj.script_parent - if parent_str and parent_str != '': - source_object.emit_to("Parent: %s " % (parent_str,)) + source_object.emit_to("Parent: %s " % target_obj.get_script_parent()) for attribute in target_obj.get_all_attributes(): source_object.emit_to(attribute.get_attrline()) diff --git a/src/commands/parents.py b/src/commands/parents.py index 3494eb5035..d03007ba6d 100644 --- a/src/commands/parents.py +++ b/src/commands/parents.py @@ -30,19 +30,64 @@ def show_cached_scripts(command): retval += "%d cached parents" % len(cache_dict) command.source_object.emit_to(retval) -def cmd_parent(command): +def cmd_scriptcache(command): """ Figure out what form of the command the user is using and branch off accordingly. """ - if "showcache" in command.command_switches: + if "show" in command.command_switches: show_cached_scripts(command) return - if "clearcache" in command.command_switches: + if "clear" in command.command_switches: clear_cached_scripts(command) return - command.source_object.emit_to("Must be specified with one of the following switches: showcache, clearcache") + command.source_object.emit_to("Must be specified with one of the following switches: show, clear") +GLOBAL_CMD_TABLE.add_command("@scriptcache", cmd_scriptcache, + priv_tuple=("genperms.builder")) + +def cmd_parent(command): + """ + Sets an object's script parent. + """ + source_object = command.source_object + + if not command.command_argument: + source_object.emit_to("Change the parent of what?") + return + + eq_args = command.command_argument.split('=', 1) + target_name = eq_args[0] + parent_name = eq_args[1] + + if len(target_name) == 0: + source_object.emit_to("Change the parent of what?") + return + + if len(eq_args) > 1: + target_obj = source_object.search_for_object(target_name) + # Use search_for_object to handle duplicate/nonexistant results. + if not target_obj: + return + + if not source_object.controls_other(target_obj): + source_object.emit_to(defines_global.NOCONTROL_MSG) + return + + # Allow the clearing of a zone + if parent_name.lower() == "none": + target_obj.set_script_parent(None) + source_object.emit_to("%s reverted to default parent." % (target_obj)) + return + + target_obj.set_script_parent(parent_name) + source_object.emit_to("%s is now a child of %s." % (target_obj, parent_name)) + + else: + # We haven't provided a target zone. + source_object.emit_to("What should the object's parent be set to?") + return GLOBAL_CMD_TABLE.add_command("@parent", cmd_parent, - priv_tuple=("genperms.builder")), \ No newline at end of file + priv_tuple=("genperms.builder")) + diff --git a/src/objects/models.py b/src/objects/models.py index b47d1acabd..9bd50b86d9 100755 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -738,16 +738,8 @@ class Object(models.Model): Returns an object's script parent. """ if not self.scriptlink_cached: - script_to_load = None - if not self.script_parent or self.script_parent.strip() == '': - # No parent value, assume the defaults based on type. - if self.is_player(): - script_to_load = settings.SCRIPT_DEFAULT_PLAYER - else: - script_to_load = settings.SCRIPT_DEFAULT_OBJECT - else: - # A parent has been set, load it from the field's value. - script_to_load = self.script_parent + script_to_load = self.get_script_parent() + # Load the script reference into the object's attribute. self.scriptlink_cached = scripthandler.scriptlink(self, script_to_load) @@ -759,6 +751,36 @@ class Object(models.Model): return None # Set a property to make accessing the scriptlink more transparent. scriptlink = property(fget=get_scriptlink) + + def get_script_parent(self): + """ + Returns a string representing the object's script parent. + """ + if not self.script_parent or self.script_parent.strip() == '': + # No parent value, assume the defaults based on type. + if self.is_player(): + return settings.SCRIPT_DEFAULT_PLAYER + else: + return settings.SCRIPT_DEFAULT_OBJECT + else: + # A parent has been set, load it from the field's value. + return self.script_parent + + def set_script_parent(self, parent_str): + """ + 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: + self.script_parent = parent_str.strip() + self.save() def get_attribute_value(self, attrib, default=False): """ diff --git a/src/script_parents/basicobject.py b/src/script_parents/basicobject.py index 88f7e0d522..50a35a01c1 100644 --- a/src/script_parents/basicobject.py +++ b/src/script_parents/basicobject.py @@ -10,7 +10,7 @@ SCRIPT_DEFAULT_OBJECT variable in settings.py to point to the new class. from src import ansi class EvenniaBasicObject(object): - def __init__(self, source_obj): + def __init__(self, source_obj, *args, **kwargs): """ Get our ducks in a row.