Merge pull request #3636 from Machine-Garden-MUD/master

Add attr:category functionality on cpattr
This commit is contained in:
Griatch 2024-10-21 20:01:15 +02:00 committed by GitHub
commit 5b6e279e8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -167,7 +167,7 @@ class ObjManipCommand(COMMAND_DEFAULT_CLASS):
attrs = _attrs
# store data
obj_defs[iside].append({"name": objdef, "option": option, "aliases": aliases})
obj_attrs[iside].append({"name": objdef, "attrs": attrs})
obj_attrs[iside].append({"name": objdef, "attrs": attrs, "category": option})
# store for future access
self.lhs_objs = obj_defs[0]
@ -447,7 +447,7 @@ class CmdCpAttr(ObjManipCommand):
Usage:
cpattr[/switch] <obj>/<attr> = <obj1>/<attr1> [,<obj2>/<attr2>,<obj3>/<attr3>,...]
cpattr[/switch] <obj>/<attr> = <obj1> [,<obj2>,<obj3>,...]
cpattr[/switch] <attr> = <obj1>/<attr1> [,<obj2>/<attr2>,<obj3>/<attr3>,...]
cpattr[/switch] <attr>[:category] = <obj1>/<attr1>[:category] [,<obj2>/<attr2>,<obj3>/<attr3>,...]
cpattr[/switch] <attr> = <obj1>[,<obj2>,<obj3>,...]
Switches:
@ -459,6 +459,11 @@ class CmdCpAttr(ObjManipCommand):
copies the coolness attribute (defined on yourself), to attributes
on Anna and Tom.
cpattr box/width:dimension = tube/width:dimension
->
copies the box's width attribute in the dimension category, to be the
tube's width attribute in the dimension category
Copy the attribute one object to one or more attributes on another object.
If you don't supply a source object, yourself is used.
"""
@ -468,7 +473,7 @@ class CmdCpAttr(ObjManipCommand):
locks = "cmd:perm(cpattr) or perm(Builder)"
help_category = "Building"
def check_from_attr(self, obj, attr, clear=False):
def check_from_attr(self, obj, attr, category=None, 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
@ -479,7 +484,7 @@ class CmdCpAttr(ObjManipCommand):
"""
return True
def check_to_attr(self, obj, attr):
def check_to_attr(self, obj, attr, category=None):
"""
Hook for overriding on subclassed commands. Checks to make sure a
caller can write to the specified attribute on the specified object.
@ -488,22 +493,24 @@ class CmdCpAttr(ObjManipCommand):
"""
return True
def check_has_attr(self, obj, attr):
def check_has_attr(self, obj, attr, category=None):
"""
Hook for overriding on subclassed commands. Do any preprocessing
required and verify an object has an attribute.
"""
if not obj.attributes.has(attr):
self.msg(f"{obj.name} doesn't have an attribute {attr}.")
if not obj.attributes.has(attr, category=category):
self.msg(
f"{obj.name} doesn't have an attribute {attr}{f'[{category}]' if category else ''}."
)
return False
return True
def get_attr(self, obj, attr):
def get_attr(self, obj, attr, category=None):
"""
Hook for overriding on subclassed commands. Do any preprocessing
required and get the attribute from the object.
"""
return obj.attributes.get(attr)
return obj.attributes.get(attr, category=category)
def func(self):
"""
@ -513,7 +520,7 @@ class CmdCpAttr(ObjManipCommand):
if not self.rhs:
string = """Usage:
cpattr[/switch] <obj>/<attr> = <obj1>/<attr1> [,<obj2>/<attr2>,<obj3>/<attr3>,...]
cpattr[/switch] <obj>/<attr>[:category] = <obj1>/<attr1> [,<obj2>/<attr2>,<obj3>/<attr3>,...]
cpattr[/switch] <obj>/<attr> = <obj1> [,<obj2>,<obj3>,...]
cpattr[/switch] <attr> = <obj1>/<attr1> [,<obj2>/<attr2>,<obj3>/<attr3>,...]
cpattr[/switch] <attr> = <obj1>[,<obj2>,<obj3>,...]"""
@ -524,6 +531,8 @@ class CmdCpAttr(ObjManipCommand):
to_objs = self.rhs_objattr
from_obj_name = lhs_objattr[0]["name"]
from_obj_attrs = lhs_objattr[0]["attrs"]
from_obj_category = lhs_objattr[0]["category"] # None if unset
from_obj_category_str = f"[{from_obj_category}]" if from_obj_category else ""
if not from_obj_attrs:
# this means the from_obj_name is actually an attribute
@ -540,11 +549,13 @@ class CmdCpAttr(ObjManipCommand):
clear = True
else:
clear = False
if not self.check_from_attr(from_obj, from_obj_attrs[0], clear=clear):
if not self.check_from_attr(
from_obj, from_obj_attrs[0], clear=clear, category=from_obj_category
):
return
for attr in from_obj_attrs:
if not self.check_has_attr(from_obj, attr):
if not self.check_has_attr(from_obj, attr, category=from_obj_category):
return
if (len(from_obj_attrs) != len(set(from_obj_attrs))) and clear:
@ -552,10 +563,11 @@ class CmdCpAttr(ObjManipCommand):
return
result = []
for to_obj in to_objs:
to_obj_name = to_obj["name"]
to_obj_attrs = to_obj["attrs"]
to_obj_category = to_obj.get("category")
to_obj_category_str = f"[{to_obj_category}]" if to_obj_category else ""
to_obj = caller.search(to_obj_name)
if not to_obj:
result.append(f"\nCould not find object '{to_obj_name}'")
@ -567,19 +579,19 @@ class CmdCpAttr(ObjManipCommand):
# if there are too few attributes given
# on the to_obj, we copy the original name instead.
to_attr = from_attr
if not self.check_to_attr(to_obj, to_attr):
if not self.check_to_attr(to_obj, to_attr, to_obj_category):
continue
value = self.get_attr(from_obj, from_attr)
to_obj.attributes.add(to_attr, value)
value = self.get_attr(from_obj, from_attr, from_obj_category)
to_obj.attributes.add(to_attr, value, category=to_obj_category)
if clear and not (from_obj == to_obj and from_attr == to_attr):
from_obj.attributes.remove(from_attr)
from_obj.attributes.remove(from_attr, category=from_obj_category)
result.append(
f"\nMoved {from_obj.name}.{from_attr} -> {to_obj_name}.{to_attr}. (value:"
f"\nMoved {from_obj.name}.{from_attr}{from_obj_category_str} -> {to_obj_name}.{to_attr}{to_obj_category_str}. (value:"
f" {repr(value)})"
)
else:
result.append(
f"\nCopied {from_obj.name}.{from_attr} -> {to_obj.name}.{to_attr}. (value:"
f"\nCopied {from_obj.name}.{from_attr}{from_obj_category_str} -> {to_obj.name}.{to_attr}{to_obj_category_str}. (value:"
f" {repr(value)})"
)
caller.msg("".join(result))