Added a few hooks to the default building commands.
This commit is contained in:
parent
1c010b455a
commit
b106e7418a
1 changed files with 136 additions and 41 deletions
|
|
@ -276,6 +276,45 @@ class CmdCpAttr(ObjManipCommand):
|
||||||
locks = "cmd:perm(cpattr) or perm(Builders)"
|
locks = "cmd:perm(cpattr) or perm(Builders)"
|
||||||
help_category = "Building"
|
help_category = "Building"
|
||||||
|
|
||||||
|
def check_from_attr(self, obj, attr, clear=False):
|
||||||
|
"""
|
||||||
|
Hook for overriding on subclassed commands. Checks to make sure a
|
||||||
|
caller can copy the attr from the object in question. If not, return a
|
||||||
|
false value and the command will abort. An error message should be
|
||||||
|
provided by this function.
|
||||||
|
|
||||||
|
If clear is True, user is attempting to move the attribute.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def check_to_attr(self, obj, attr):
|
||||||
|
"""
|
||||||
|
Hook for overriding on subclassed commands. Checks to make sure a
|
||||||
|
caller can write to the specified attribute on the specified object.
|
||||||
|
If not, return a false value and the attribute will be skipped. An
|
||||||
|
error message should be provided by this function.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def check_has_attr(self, obj, attr):
|
||||||
|
"""
|
||||||
|
Hook for overriding on subclassed commands. Do any preprocessing
|
||||||
|
required and verify an object has an attribute.
|
||||||
|
"""
|
||||||
|
if not obj.attributes.has(attr):
|
||||||
|
self.caller.msg(
|
||||||
|
"%s doesn't have an attribute %s."
|
||||||
|
% (obj.name, attr))
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_attr(self, obj, attr):
|
||||||
|
"""
|
||||||
|
Hook for overriding on subclassed commands. Do any preprocessing
|
||||||
|
required and get the attribute from the object.
|
||||||
|
"""
|
||||||
|
return obj.attributes.get(attr)
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"""
|
"""
|
||||||
Do the copying.
|
Do the copying.
|
||||||
|
|
@ -301,25 +340,28 @@ class CmdCpAttr(ObjManipCommand):
|
||||||
# name on self.
|
# name on self.
|
||||||
from_obj_attrs = [from_obj_name]
|
from_obj_attrs = [from_obj_name]
|
||||||
from_obj = self.caller
|
from_obj = self.caller
|
||||||
from_obj_name = self.caller.name
|
|
||||||
else:
|
else:
|
||||||
from_obj = caller.search(from_obj_name)
|
from_obj = caller.search(from_obj_name)
|
||||||
if not from_obj or not to_objs:
|
if not from_obj or not to_objs:
|
||||||
caller.msg("You have to supply both source object and target(s).")
|
caller.msg("You have to supply both source object and target(s).")
|
||||||
return
|
return
|
||||||
if not from_obj.attributes.has(from_obj_attrs[0]):
|
|
||||||
caller.msg("%s doesn't have an attribute %s." % (from_obj_name,
|
|
||||||
from_obj_attrs[0]))
|
|
||||||
return
|
|
||||||
srcvalue = from_obj.attributes.get(from_obj_attrs[0])
|
|
||||||
|
|
||||||
#copy to all to_obj:ects
|
#copy to all to_obj:ects
|
||||||
if "move" in self.switches:
|
if "move" in self.switches:
|
||||||
string = "Moving "
|
clear = True
|
||||||
else:
|
else:
|
||||||
string = "Copying "
|
clear = False
|
||||||
string += "%s/%s (with value %s) ..." % (from_obj_name,
|
if not self.check_from_attr(from_obj, from_obj_attrs[0], clear=clear):
|
||||||
from_obj_attrs[0], srcvalue)
|
return
|
||||||
|
|
||||||
|
for attr in from_obj_attrs:
|
||||||
|
if not self.check_has_attr(from_obj, attr):
|
||||||
|
return
|
||||||
|
|
||||||
|
if (len(from_obj_attrs) != len(set(from_obj_attrs))) and clear:
|
||||||
|
self.caller.msg("{RCannot have duplicate source names when moving!")
|
||||||
|
return
|
||||||
|
|
||||||
|
string = ""
|
||||||
|
|
||||||
for to_obj in to_objs:
|
for to_obj in to_objs:
|
||||||
to_obj_name = to_obj['name']
|
to_obj_name = to_obj['name']
|
||||||
|
|
@ -335,18 +377,24 @@ class CmdCpAttr(ObjManipCommand):
|
||||||
# if there are too few attributes given
|
# if there are too few attributes given
|
||||||
# on the to_obj, we copy the original name instead.
|
# on the to_obj, we copy the original name instead.
|
||||||
to_attr = from_attr
|
to_attr = from_attr
|
||||||
to_obj.attributes.add(to_attr, srcvalue)
|
if not self.check_to_attr(to_obj, to_attr):
|
||||||
if ("move" in self.switches and not (from_obj == to_obj and
|
continue
|
||||||
|
value = self.get_attr(from_obj, from_attr)
|
||||||
|
to_obj.attributes.add(to_attr, value)
|
||||||
|
if (clear and not (from_obj == to_obj and
|
||||||
from_attr == to_attr)):
|
from_attr == to_attr)):
|
||||||
from_obj.attributes.remove(from_attr)
|
from_obj.attributes.remove(from_attr)
|
||||||
string += "\nMoved %s.%s -> %s.%s." % (from_obj.name,
|
string += "\nMoved %s.%s -> %s.%s. (value: %s)" % (from_obj.name,
|
||||||
from_attr,
|
from_attr,
|
||||||
to_obj_name, to_attr)
|
to_obj_name,
|
||||||
|
to_attr,
|
||||||
|
repr(value))
|
||||||
else:
|
else:
|
||||||
string += "\nCopied %s.%s -> %s.%s." % (from_obj.name,
|
string += "\nCopied %s.%s -> %s.%s. (value: %s)" % (from_obj.name,
|
||||||
from_attr,
|
from_attr,
|
||||||
to_obj_name,
|
to_obj_name,
|
||||||
to_attr)
|
to_attr,
|
||||||
|
repr(value))
|
||||||
caller.msg(string)
|
caller.msg(string)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1283,6 +1331,61 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
locks = "cmd:perm(set) or perm(Builders)"
|
locks = "cmd:perm(set) or perm(Builders)"
|
||||||
help_category = "Building"
|
help_category = "Building"
|
||||||
|
|
||||||
|
def check_obj(self, obj):
|
||||||
|
"""
|
||||||
|
This may be overridden by subclasses in case restrictions need to be
|
||||||
|
placed on whether certain objects can have attributes set by certain
|
||||||
|
players.
|
||||||
|
|
||||||
|
This function is expected to display its own error message.
|
||||||
|
|
||||||
|
Returning False will abort the command.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def check_attr(self, obj, attr_name):
|
||||||
|
"""
|
||||||
|
This may be overridden by subclasses in case restrictions need to be
|
||||||
|
placed on what attributes can be set by who beyond the normal lock.
|
||||||
|
|
||||||
|
This functions is expected to display its own error message. It is
|
||||||
|
run once for every attribute that is checked, blocking only those
|
||||||
|
attributes which are not permitted and letting the others through.
|
||||||
|
"""
|
||||||
|
return attr_name
|
||||||
|
|
||||||
|
def view_attr(self, obj, attr):
|
||||||
|
"""
|
||||||
|
Look up the value of an attribute and return a string displaying it.
|
||||||
|
"""
|
||||||
|
if obj.attributes.has(attr):
|
||||||
|
return "\nAttribute %s/%s = %s" % (obj.name, attr,
|
||||||
|
obj.attributes.get(attr))
|
||||||
|
else:
|
||||||
|
return "\n%s has no attribute '%s'." % (obj.name, attr)
|
||||||
|
|
||||||
|
def rm_attr(self, obj, attr):
|
||||||
|
"""
|
||||||
|
Remove an attribute from the object, and report back.
|
||||||
|
"""
|
||||||
|
if obj.attributes.has(attr):
|
||||||
|
val = obj.attributes.has(attr)
|
||||||
|
obj.attributes.remove(attr)
|
||||||
|
return "\nDeleted attribute '%s' (= %s) from %s." % (attr, val, obj.name)
|
||||||
|
else:
|
||||||
|
return "\n%s has no attribute '%s'." % (obj.name, attr)
|
||||||
|
|
||||||
|
def set_attr(self, obj, attr, value):
|
||||||
|
try:
|
||||||
|
obj.attributes.add(attr, value)
|
||||||
|
return "\nCreated attribute %s/%s = %s" % (obj.name, attr, value)
|
||||||
|
except SyntaxError:
|
||||||
|
# this means literal_eval tried to parse a faulty string
|
||||||
|
return ("\n{RCritical Python syntax error in your value. Only "
|
||||||
|
"primitive Python structures are allowed.\nYou also "
|
||||||
|
"need to use correct Python syntax. Remember especially "
|
||||||
|
"to put quotes around all strings inside lists and "
|
||||||
|
"dicts.{n")
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"Implement the set attribute - a limited form of @py."
|
"Implement the set attribute - a limited form of @py."
|
||||||
|
|
@ -1304,6 +1407,9 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
if not obj:
|
if not obj:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not self.check_obj(obj):
|
||||||
|
return
|
||||||
|
|
||||||
string = ""
|
string = ""
|
||||||
if not value:
|
if not value:
|
||||||
if self.rhs is None:
|
if self.rhs is None:
|
||||||
|
|
@ -1311,36 +1417,25 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
if not attrs:
|
if not attrs:
|
||||||
attrs = [attr.key for attr in obj.attributes.all()]
|
attrs = [attr.key for attr in obj.attributes.all()]
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
if obj.attributes.has(attr):
|
if not self.check_attr(obj, attr):
|
||||||
string += "\nAttribute %s/%s = %s" % (obj.name, attr,
|
continue
|
||||||
obj.attributes.get(attr))
|
string += self.view_attr(obj, attr)
|
||||||
else:
|
# we view it without parsing markup.
|
||||||
string += "\n%s has no attribute '%s'." % (obj.name, attr)
|
|
||||||
# we view it without parsing markup.
|
|
||||||
self.caller.msg(string.strip(), raw=True)
|
self.caller.msg(string.strip(), raw=True)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# deleting the attribute(s)
|
# deleting the attribute(s)
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
if obj.attributes.has(attr):
|
if not self.check_attr(obj, attr):
|
||||||
val = obj.attributes.has(attr)
|
continue
|
||||||
obj.attributes.remove(attr)
|
string += self.rm_attr(obj, attr)
|
||||||
string += "\nDeleted attribute '%s' (= %s) from %s." % (attr, val, obj.name)
|
|
||||||
else:
|
|
||||||
string += "\n%s has no attribute '%s'." % (obj.name, attr)
|
|
||||||
else:
|
else:
|
||||||
# setting attribute(s). Make sure to convert to real Python type before saving.
|
# setting attribute(s). Make sure to convert to real Python type before saving.
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
try:
|
if not self.check_attr(obj, attr):
|
||||||
obj.attributes.add(attr, _convert_from_string(self, value))
|
continue
|
||||||
string += "\nCreated attribute %s/%s = %s" % (obj.name, attr, value)
|
value = _convert_from_string(self, value)
|
||||||
except SyntaxError:
|
string += self.set_attr(obj, attr, value)
|
||||||
# this means literal_eval tried to parse a faulty string
|
|
||||||
string = "{RCritical Python syntax error in your value. "
|
|
||||||
string += "Only primitive Python structures are allowed. "
|
|
||||||
string += "\nYou also need to use correct Python syntax. "
|
|
||||||
string += "Remember especially to put quotes around all "
|
|
||||||
string += "strings inside lists and dicts.{n"
|
|
||||||
# send feedback
|
# send feedback
|
||||||
caller.msg(string.strip('\n'))
|
caller.msg(string.strip('\n'))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue