Finalized the spawner API and made the @spawn command also take prototypes directly, e.g. @spawn GOBLIN.

This commit is contained in:
Griatch 2014-07-01 19:39:12 +02:00
parent 221d56fecd
commit b9c8c1695c
2 changed files with 55 additions and 31 deletions

View file

@ -6,11 +6,12 @@ Building and world design commands
"""
from django.conf import settings
from src.objects.models import ObjectDB
from src.utils import create, utils, search
from src.utils.ansi import raw
from src.locks.lockhandler import LockException
from src.commands.default.muxcommand import MuxCommand
from src.commands.cmdhandler import get_and_merge_cmdsets
from src.utils import create, utils, search
from src.utils.spawner import spawn
from src.utils.ansi import raw
# limit symbol import for API
__all__ = ("ObjManipCommand", "CmdSetObjAlias", "CmdCopy",
@ -2258,14 +2259,16 @@ class CmdSpawn(MuxCommand):
spawn objects from prototype
Usage:
@spawn[/switches] {prototype dictionary}
@spawn
@spawn[/switch] prototype_name
@spawn[/switch] {prototype dictionary}
Switches:
noloc - allow location to None. Otherwise, location will default to
caller's current location
parents - show all available prototype parents
Switch:
noloc - allow location to be None if not specified explicitly. Otherwise,
location will default to caller's current location.
Example:
@spawn GOBLIN
@spawn {"key":"goblin", "typeclass":"monster.Monster", "location":"#2"}
Dictionary keys:
@ -2282,34 +2285,30 @@ class CmdSpawn(MuxCommand):
{wndb_{n<name> - value of a nattribute (ndb_ is stripped)
any other keywords are interpreted as Attributes and their values.
The parent prototypes are taken as dictionaries defined globally in
the settings.PROTOTYPE_MODULES.
The available prototypes are defined globally in modules set in
settings.PROTOTYPE_MODULES. If @spawn is used without arguments it
displays a list of available prototypes.
"""
key = "@spawn"
aliases = ["spawn"]
locks = "cmd:perm(spawn) or perm(Builders)"
help_category = "Building"
def func(self):
"Implements the spawner"
global _PROTOTYPE_PARENTS
if _PROTOTYPE_PARENTS is None:
if hasattr(settings, "PROTOTYPE_MODULES"):
# read prototype parents from setting
_PROTOTYPE_PARENTS = {}
for prototype_module in utils.make_iter(settings.PROTOTYPE_MODULES):
_PROTOTYPE_PARENTS.update(dict((key, val)
for key, val in utils.all_from_module(prototype_module).items() if isinstance(val, dict)))
def _show_prototypes(prototypes):
"Helper to show a list of available prototypes"
string = "\nAvailable prototypes:\n %s"
string = string % utils.fill(", ".join(sorted(prototypes.keys())))
return string
prototypes = spawn(return_prototypes=True)
if not self.args:
string = "Usage: @spawn {key:value, key, value, ...}\n" \
"Available prototypes: %s"
self.caller.msg(string % ", ".join(_PROTOTYPE_PARENTS.keys())
if _PROTOTYPE_PARENTS else None)
string = "Usage: @spawn {key:value, key, value, ... }"
self.caller.msg(string + _show_prototypes(prototypes))
return
from src.utils.spawner import spawn
try:
# make use of _convert_from_string from the SetAttribute command
prototype = _convert_from_string(self, self.args)
@ -2323,14 +2322,22 @@ class CmdSpawn(MuxCommand):
self.caller.msg(string)
return
if not isinstance(prototype, dict):
self.caller.msg("The prototype must be a Python dictionary.")
if isinstance(prototype, basestring):
# A prototype key
keystr = prototype
prototype = prototypes.get(prototype, None)
if not prototype:
string = "No prototype named '%s'." % keystr
self.caller.msg(string + _show_prototypes(prototypes))
return
elif not isinstance(prototype, dict):
self.caller.msg("The prototype must be a prototype key or a Python dictionary.")
return
if not "noloc" in self.switches and not "location" in prototype:
prototype["location"] = self.caller.location
for obj in spawn(prototype, prototype_parents=_PROTOTYPE_PARENTS):
for obj in spawn(prototype):
self.caller.msg("Spawned %s." % obj.key)

View file

@ -77,6 +77,7 @@ from django.conf import settings
from random import randint
from src.objects.models import ObjectDB
from src.utils.create import handle_dbref
from src.utils.utils import make_iter, all_from_module
_CREATE_OBJECT_KWARGS = ("key", "location", "home", "destination")
@ -155,14 +156,30 @@ def spawn(*prototypes, **kwargs):
Spawn a number of prototyped objects. Each argument should be a
prototype dictionary.
The keyword argument "prototype_parents" holds a dictionary of
prototype dictionaries, each with a unique key. The given
prototypes may call these as parents using the "prototype" key.
keyword args:
prototype_modules - a python-path to a
prototype module, or a list of such paths. These will be used
to build the global protparents dictionary accessible by the
input prototypes. If not given, it will instead look for modules
defined by settings.PROTOTYPE_MODULES.
return_prototypes - only return a list of the prototype-parents
(no object creation happens)
"""
objsparams = []
protparents = {}
protmodules = make_iter(kwargs.get("prototype_modules", []))
if not protmodules and hasattr(settings, "PROTOTYPE_MODULES"):
protmodules = make_iter(settings.PROTOTYPE_MODULES)
for prototype_module in protmodules:
protparents.update(dict((key, val)
for key, val in all_from_module(prototype_module).items() if isinstance(val, dict)))
if "return_prototypes" in kwargs:
# only return the parents
return protparents
objsparams = []
for prototype in prototypes:
protparents = kwargs.get("prototype_parents", None)
prot = _get_prototype(prototype, {}, protparents)
if not prot: