mirror of
https://github.com/evennia/evennia.git
synced 2026-04-04 06:57:16 +02:00
Reworked object command tables.
Object commands used to require re-adding every call in the script parent's __init__ or factory functions, adding the commands to a new command table directly on the object. Since all other attributes can be set up in at_object_creation(), this was both inconsistent and a bit confusing to work with. There is now a method add_commands() directly defined on all objects. It takes the same arguments as the normal add_command()o but use a reserved attribute to create and update a command table on the object. This has the advantange of completely removing the __init__ call in the script parent, all definitions can now be kept in at_object_creation() and are, more importantly, persistent without having to be recreated every call. - I updated the examine command to show all the commands defined on an object (if any). - I updated gamesrc/parents/examples/red_button.py considerably using the new command methodology and also using the updated Events. . Griatch
This commit is contained in:
parent
5f6454ea1e
commit
c7cbc4854e
7 changed files with 252 additions and 53 deletions
|
|
@ -6,7 +6,7 @@ something.
|
|||
#import time
|
||||
from traceback import format_exc
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
#from django.contrib.contenttypes.models import ContentType
|
||||
from objects.models import Object
|
||||
import defines_global
|
||||
import cmdtable
|
||||
|
|
@ -420,9 +420,10 @@ def match_neighbor_ctables(command,test=False):
|
|||
neighbors = location.get_contents() + [location] + source_object.get_contents()
|
||||
for neighbor in neighbors:
|
||||
#print "neighbor:", neighbor
|
||||
if command_table_lookup(command,
|
||||
neighbor.scriptlink.command_table,
|
||||
test=test, neighbor=neighbor):
|
||||
obj_cmdtable = neighbor.get_cmdtable()
|
||||
if obj_cmdtable and command_table_lookup(command, obj_cmdtable,
|
||||
test=test,
|
||||
neighbor=neighbor):
|
||||
|
||||
# If there was a command match, set the scripted_obj attribute
|
||||
# for the script parent to pick up.
|
||||
|
|
|
|||
|
|
@ -241,12 +241,16 @@ def cmd_set(command):
|
|||
if not attrib_name:
|
||||
source_object.emit_to("Cannot set an empty attribute name.")
|
||||
return
|
||||
if attrib_name == "__command_table__":
|
||||
string = "This is a protected attribute, choose another name."
|
||||
source_object.emit_to(string)
|
||||
return
|
||||
if not Attribute.objects.is_modifiable_attrib(attrib_name):
|
||||
# In global_defines.py, see NOSET_ATTRIBS for protected attribute names.
|
||||
source_object.emit_to("You can't modify that attribute.")
|
||||
return
|
||||
if attrib_value:
|
||||
# An attribute value was specified, create or set the attribute.
|
||||
# An attribute value was specified, create or set the attribute.
|
||||
target.set_attribute(attrib_name, attrib_value)
|
||||
s = "Attribute %s=%s set to '%s'" % (target_name, attrib_name, attrib_value)
|
||||
else:
|
||||
|
|
@ -1630,8 +1634,16 @@ def cmd_examine(command):
|
|||
string += str("Location: %s" % target_obj.get_location()) + newl
|
||||
|
||||
# Render other attributes
|
||||
cmd_string = ""
|
||||
attr_string = ""
|
||||
for attribute in target_obj.get_all_attributes():
|
||||
string += str(attribute.get_attrline()) + newl
|
||||
if attribute.get_name() == "__command_table__":
|
||||
cmdtable = attribute.get_value()
|
||||
cmd_string = "Commands: "
|
||||
cmd_string += ", ".join(cmdtable.ctable.keys()) + newl
|
||||
else:
|
||||
attr_string += str(attribute.get_attrline()) + newl
|
||||
string += cmd_string + attr_string
|
||||
|
||||
# Render Contents display.
|
||||
if con_players or con_things:
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ class ObjectManager(models.Manager):
|
|||
"""
|
||||
Returns an object when given a dbref.
|
||||
"""
|
||||
if len(dbref)>1 and dbref[0]=="#":
|
||||
dbref = dbref[1:]
|
||||
try:
|
||||
return self.get(id=dbref)
|
||||
except self.model.DoesNotExist:
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ class Attribute(models.Model):
|
|||
"""
|
||||
Returns an attribute's value.
|
||||
"""
|
||||
attr_value = str(self.attr_value)
|
||||
attr_value = self.attr_value
|
||||
if self.attr_ispickled:
|
||||
attr_value = pickle.loads(attr_value)
|
||||
attr_value = pickle.loads(str(attr_value))
|
||||
return attr_value
|
||||
|
||||
def set_value(self, new_value):
|
||||
|
|
@ -650,6 +650,11 @@ class Object(models.Model):
|
|||
a str, the object will be stored as a pickle.
|
||||
"""
|
||||
|
||||
if attribute == "__command_table__":
|
||||
# protect the command table attribute,
|
||||
# this is only settable by self.add_command()
|
||||
return
|
||||
|
||||
attrib_obj = None
|
||||
if self.has_attribute(attribute):
|
||||
attrib_obj = \
|
||||
|
|
@ -689,6 +694,14 @@ class Object(models.Model):
|
|||
return attrib.get_value()
|
||||
else:
|
||||
return default
|
||||
|
||||
def get_attribute(self, attrib, default=None):
|
||||
"""
|
||||
Convenience function (to keep compatability). While
|
||||
get_attribute_value() is a correct name, it is not really
|
||||
consistent with set_attribute() anyway.
|
||||
"""
|
||||
return self.get_attribute_value(attrib, default)
|
||||
|
||||
def get_attribute_obj(self, attrib, auto_create=False):
|
||||
"""
|
||||
|
|
@ -697,7 +710,7 @@ class Object(models.Model):
|
|||
attrib: (str) The attribute's name.
|
||||
"""
|
||||
if self.has_attribute(attrib):
|
||||
return Attribute.objects.filter(attr_object=self).filter(attr_name=attrib)
|
||||
return Attribute.objects.filter(attr_object=self).filter(attr_name=attrib)[0]
|
||||
else:
|
||||
if auto_create:
|
||||
new_attrib = Attribute()
|
||||
|
|
@ -909,8 +922,7 @@ class Object(models.Model):
|
|||
(self.name,self.id,self.location_id))
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
def get_scriptlink(self):
|
||||
"""
|
||||
Returns an object's script parent.
|
||||
|
|
@ -1167,6 +1179,59 @@ class Object(models.Model):
|
|||
otype = int(self.type)
|
||||
return defines_global.OBJECT_TYPES[otype][1][0]
|
||||
|
||||
# object custom commands
|
||||
|
||||
def add_command(self, command_string, function,
|
||||
priv_tuple=None, extra_vals=None,
|
||||
help_category="", priv_help_tuple=None,
|
||||
auto_help_override=False):
|
||||
"""
|
||||
Add an object-based command to this object. The command
|
||||
definition is added to an attribute-stored command table
|
||||
(this table is created when adding the first command)
|
||||
|
||||
command_string: (string) Command string (IE: WHO, QUIT, look).
|
||||
function: (reference) The command's function.
|
||||
priv_tuple: (tuple) String tuple of permissions required for command.
|
||||
extra_vals: (dict) Dictionary to add to the Command object.
|
||||
|
||||
By default object commands are NOT added to the global help system
|
||||
with auto-help. You have to actively set auto_help_override to True
|
||||
if you explicitly want auto-help for your object command.
|
||||
|
||||
help_category (str): An overall help category where auto-help will place
|
||||
the help entry. If not given, 'General' is assumed.
|
||||
priv_help_tuple (tuple) String tuple of permissions required to view this
|
||||
help entry. If nothing is given, priv_tuple is used.
|
||||
auto_help_override (bool): If True, use auto-help. If None, use setting
|
||||
in settings.AUTO_HELP_ENABLED. Default is False
|
||||
for object commands.
|
||||
"""
|
||||
|
||||
# we save using the attribute object to avoid
|
||||
# the protection on the __command_table__ keyword
|
||||
# in set_attribute_value()
|
||||
attrib_obj = self.get_attribute_obj("__command_table__",
|
||||
auto_create=True)
|
||||
cmdtable = attrib_obj.get_value()
|
||||
if not cmdtable:
|
||||
# create new table if we didn't have one before
|
||||
from src.cmdtable import CommandTable
|
||||
had_table = False
|
||||
cmdtable = CommandTable()
|
||||
# add the command to the object's command table.
|
||||
cmdtable.add_command(command_string, function, priv_tuple, extra_vals,
|
||||
help_category, priv_help_tuple,
|
||||
auto_help_override)
|
||||
# store the cmdtable again
|
||||
attrib_obj.set_value(cmdtable)
|
||||
|
||||
def get_cmdtable(self):
|
||||
"""
|
||||
Return this object's local command table, if it exists.
|
||||
"""
|
||||
return self.get_attribute("__command_table__")
|
||||
|
||||
#state access functions
|
||||
|
||||
def get_state(self):
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ class EvenniaBasicObject(object):
|
|||
scripted_obj: (Object) A reference to the object being scripted (the child).
|
||||
"""
|
||||
self.scripted_obj = scripted_obj
|
||||
self.command_table = CommandTable()
|
||||
# below is now handled by self.scripted_obj.add_command() in
|
||||
# self.at_object_creation().
|
||||
#self.command_table = CommandTable()
|
||||
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue