Dynamically Spawn A Mob

From Multiverse

Jump to: navigation, search
Contributed by: Multiverse Last Tested: 27 Oct 08 Tested By: Jason MacWilliams Tested With: 1.5

A tutorial that demonstrates a command to dynamically spawn a zombie, it is an update of a previous version that was incompatible with the 1.5 server. The tutorial also demonstrates some basic server-server message passing, and writing a plugin (but these are not the focus ofthis article). It is not hard to modify the code below to spawn any mob you want as long as a template is defined for it. This is covered at the end of the tutorial.

Contents

extensions_proxy.py

In extensions_proxy.py we add the slash command handler for "/spawnzombie". This class prepares and sends a message to the mobserver which handles the object spawn.

Add these lines in extensions_proxy.py

class SpawnAZombie (ProxyPlugin.CommandParser):
   def parse(self, cmdEvent):
        cmd = cmdEvent.getCommand()
        playerOid = cmdEvent.getObjectOid()
        # create a spawn zombie message
        myMsg = GenericMessage()
        myMsg.setMsgType(MessageType.intern("spawnamob"))
        myMsg.setProperty("mob_type", "Zombie")
        # we pass the palayer's oid so we can get lots of information on the other end
        myMsg.setProperty("source_objoid", str(playerOid))
        # a bit of debugging information
        pt = WorldManagerClient.getObjectInfo(playerOid).loc
        Log.debug("SpawnAZombie: Attempting to spawn a zombie at " + str(pt))
        # send message
        Engine.getAgent().sendBroadcast(myMsg)
        # give the player some feedback
        WorldManagerClient.sendObjChatMsg(playerOid, 1, "I have spawned a zombie")
        return None

# register the slash command
proxyPlugin.registerCommand("/spawnzombie", SpawnAZombie())

mobserver.py

The mobserver code has become a bit more complicated since previous server versions. We create the hook that manages the message, then we have to create a plugin to manage the hook. The plugin needs its type set, and we have to add the hook (if you skim through the mars package, you can see how plugins and hooks work). Finally we create a new message filter for our spawnamob message and subscribe our plugin to it.

Add the following lines to mobserver.py:

class SpawnMobHandler(Hook):
    def processMessage(self, msg, flags):
        Log.debug("Received a spawn mob message")
        # the template name of the mob to spawn
        templname = msg.getProperty("mob_type")
        # the source loc was swapped for the source object so we can get orientation
        # information for it
        source_objoid = int(msg.getProperty("source_objoid"))
        source_obj = WorldManagerClient.getObjectInfo(source_objoid)

        # create the new mob
        z =  MobManagerPlugin.createObject(templname, source_obj.instanceOid, source_obj.loc, source_obj.orient)
        z.addBehavior(BaseBehavior())
        # you can add additional behaviors here
        z.spawn()

SpawnMobPlugin = EnginePlugin("SpawnMobPlugin")
SpawnMobPlugin.setPluginType("SpawnMobPlugin")

# add the message hook
# this plugin listens for "spawnamob" messages
SpawnMobPlugin.getHookManager().addHook(MessageType.intern("spawnamob"), SpawnMobHandler())
Engine.registerPlugin(SpawnMobPlugin)

# create the filter
myFilter = MessageTypeFilter()
myFilter.addType(MessageType.intern("spawnamob"))
Engine.getAgent().createSubscription(myFilter, SpawnMobPlugin)

proxy-ads.txt

We also have to tell the messaging system that the proxy server now advertises a new message type. At the end of proxy-ads.txt, add:

  ...
  spawnamob

worldmessages.py

Once that's done, we have to add our message to the message catalog in /config/worldname/worldmessage.py.

Add the line at the end of the file:

  MessageCatalog.addMsgTypeTranslation(worldMessageCatalog, MessageType.intern("spawnamob"))

multiverse.sh

And we have to tell the master server script of our new plugin, so in /bin/multiverse.sh we append it to the plugins list

PLUGIN_TYPES="-p Login,1 -p Proxy,1 -p ObjectManager,1 ... -p Startup,1 -p SpawnMobPlugin,1"

Don't worry about adding an agent.

How to use/change it

To run the sample, just type /spawnzombie and a zombie will be spawned where your player is.

You can spawn any type of mob, as long as there is a template defined and registered in your templates.py file. Simply replace the "Zombie" in this line (from extensions_proxy.py):

myMsg.setProperty("mob_type", "Zombie")

with "Wolf", "Orc", etc... (so long as that mob template is defined)

Personal tools