Dynamically Spawn A Mob
From Multiverse
| 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)
