diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index 8616b7dafa..b41b5c40e9 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -2840,8 +2840,14 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS): |wdestination|n - only valid for exits (object or dbref) |wpermissions|n - string or list of permission strings |wlocks |n - a lock-string - |waliases |n - string or list of strings + |waliases |n - string or list of strings. |wndb_|n - value of a nattribute (ndb_ is stripped) + + |wprototype_key|n - name of this prototype. Used to store/retrieve from db + |wprototype_desc|n - desc of this prototype. Used in listings + |wprototype_locks|n - locks of this prototype. Limits who may use prototype + |wprototype_tags|n - tags of this prototype. Used to find prototype + any other keywords are interpreted as Attributes and their values. The available prototypes are defined globally in modules set in diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index 950b934125..ffb877c3e3 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -369,7 +369,8 @@ class TestBuilding(CommandTest): # Tests "@spawn " without specifying location. self.call(building.CmdSpawn(), - "{'key':'goblin', 'typeclass':'evennia.DefaultCharacter'}", "Spawned goblin") + "{'prototype_key': 'testprot', 'key':'goblin', " + "'typeclass':'evennia.DefaultCharacter'}", "Spawned goblin") goblin = getObject(self, "goblin") # Tests that the spawned object's type is a DefaultCharacter. @@ -394,7 +395,7 @@ class TestBuilding(CommandTest): self.assertEqual(goblin.location, spawnLoc) goblin.delete() - spawner.save_db_prototype(self.char1, "ball", {'key': 'Ball', 'prototype': 'GOBLIN'}) + spawner.save_db_prototype(self.char1, {'key': 'Ball', 'prototype': 'GOBLIN'}, 'ball') # Tests "@spawn " self.call(building.CmdSpawn(), "ball", "Spawned Ball") diff --git a/evennia/utils/spawner.py b/evennia/utils/spawner.py index daf4b23c3f..335eea9341 100644 --- a/evennia/utils/spawner.py +++ b/evennia/utils/spawner.py @@ -172,13 +172,14 @@ for mod in settings.PROTOTYPE_MODULES: _MODULE_PROTOTYPE_MODULES.update({prototype_key: mod for prototype_key, _ in prots}) # make sure the prototype contains all meta info for prototype_key, prot in prots: + actual_prot_key = prot.get('prototype_key', prototype_key).lower() prot.update({ - "prototype_key": prot.get('prototype_key', prototype_key.lower()), + "prototype_key": actual_prot_key, "prototype_desc": prot['prototype_desc'] if 'prototype_desc' in prot else mod, - "prototype_locks": prot['prototype_locks'] if 'prototype_locks' in prot else "use:all()", - "prototype_tags": set(make_iter(prot['prototype_tags']) - if 'prototype_tags' in prot else ["base-prototype"])}) - _MODULE_PROTOTYPES[prototype_key] = prot + "prototype_locks": (prot['prototype_locks'] + if 'prototype_locks' in prot else "use:all();edit:false()"), + "prototype_tags": list(set(make_iter(prot.get('prototype_tags', [])) + ["module"]))}) + _MODULE_PROTOTYPES[actual_prot_key] = prot for mod in settings.PROTOTYPEFUNC_MODULES: @@ -537,8 +538,11 @@ def list_prototypes(caller, key=None, tags=None, show_non_use=False, show_non_ed caller, prototype.get('prototype_locks', ''), access_type='use') if not show_non_use and not lock_use: continue - lock_edit = caller.locks.check_lockstring( - caller, prototype.get('prototype_locks', ''), access_type='edit') + if prototype.get('prototype_key', '') in _MODULE_PROTOTYPES: + lock_edit = False + else: + lock_edit = caller.locks.check_lockstring( + caller, prototype.get('prototype_locks', ''), access_type='edit') if not show_non_edit and not lock_edit: continue ptags = [] @@ -566,8 +570,8 @@ def list_prototypes(caller, key=None, tags=None, show_non_use=False, show_non_ed table.append([str(display_tuple[i]) for display_tuple in display_tuples]) table = EvTable("Key", "Desc", "Use/Edit", "Tags", table=table, crop=True, width=width) table.reformat_column(0, width=22) - table.reformat_column(1, width=31) - table.reformat_column(2, width=9, align='r') + table.reformat_column(1, width=29) + table.reformat_column(2, width=11, align='c') table.reformat_column(3, width=16) return table @@ -617,7 +621,7 @@ def validate_prototype(prototype, protkey=None, protparents=None, _visited=None) if _visited is None: _visited = [] - protkey = protkey and protkey.lower() or prototype.get('prototype_key', "") + protkey = protkey and protkey.lower() or prototype.get('prototype_key', None) assert isinstance(prototype, dict) @@ -796,8 +800,10 @@ def spawn(*prototypes, **kwargs): val = prot.pop("tags", []) tags = validate_spawn_value(val, make_iter) - # we make sure to add a tag identifying which prototype created this object - tags.append((prototype['prototype_key'], _PROTOTYPE_TAG_CATEGORY)) + prototype_key = prototype.get('prototype_key', None) + if prototype_key: + # we make sure to add a tag identifying which prototype created this object + tags.append((prototype_key, _PROTOTYPE_TAG_CATEGORY)) val = prot.pop("exec", "") execs = validate_spawn_value(val, make_iter)