魔兽世界私服trinitycore2的架构(8)脚本

来源:互联网 发布:淘宝三心要几个好评 编辑:程序博客网 时间:2024/06/02 11:24

 TC2中,很多是通过script来完成。这个script和我们通常意义上的脚本有很大的不同,但他完成了许多功能,不可或缺。首先,要看下ScriptMgr.h中,Script的定义,他主体是有很多回调函数构成的,如:

    bool (*pItemUse             )(Player*, Item*, SpellCastTargets const& );

显然,这是在用户使用物品时触发的事件。这样,我们就必须关注下,究竟什么时候,这个回调会被调用呢?我用ItemUse这个单词搜索一下整个VS2005的解决方案,发现只有一个地方void WorldSession::HandleUseItemOpcode(WorldPacket&recvPacket);调用了if(!Script->ItemUse(pUser,pItem,targets));这个函数是SpellHandler.cpp文件中实现的,好像文件名有点不对,不过,因为Item使用时,总是伴随魔法,还说的过去。那HandleUseItemOpcode又是什么时候调用呢?查看下,Opcodes.cpp文件,如下:

    /*0x0AB*/ { "CMSG_USE_ITEM",  STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode },

可以发现,这个动作是伴随CMSG_USE_ITEM时触发的。

说了这么多,我们选个例子来看下。从src/bindings/scripts/scripts/world/item_scripts.cpp中,我们挑一个脚本“item_only_for_flight”,他在pItemUse绑定ItemUse_item_only_for_flight函数,我们看下他们的代码

 

从item_template中可以看到34475是奥术炸药,是用来做日常任务的,在飞行中轰炸。从代码中可以看出,这个脚本是限制你非飞行时使用奥术炸药。在item_template表中,entry=34475项的ScriptName字段的值,正好是,“item_only_for_flight” 。于是,我们可以得出这么个结论。

1、客户端点击物品时,向服务端端发出CMSG_USE_ITEM指令。

2、服务端收到这个指令时,就调用回调函数HandleUseItemOpcode。

3、HandleUseItemOpcode会根据该物品在数据库中注册的脚本名字,然后调用该脚本。

 

上面我们了解了脚本的基本工作机制,下面,我们再看下如何开发自己的脚本。还是以item_scripts.cpp为例,里面有个void AddSC_item_scripts()函数,

 

void AddSC_item_scripts()
{
    Script *newscript;

    newscript = new Script;
    newscript->Name = "item_only_for_flight";
    newscript->pItemUse = &ItemUse_item_only_for_flight;
    newscript->RegisterSelf();

 

    ....

}

 

通过newscript的RegisterSelf方法,自己注册一个Name="item_only_for_flight";捕获pItemUse事件的脚本。而src/bindings/scripts/system/ScriptLoader.cpp文件定义了extern void AddSC_item_scripts();并且在void AddScripts()函数中调用了他。而AddScripts是在ScriptMgr.cpp的ScriptsInit()中调用。ScriptsInit的调用关系有点曲折。由src/game/ScriptCalls.cpp中的LoadScriptingModule中调用,但也不是直接调用,先创建一个ScriptSet,然后加载各个回调函数,加载成功之后,再调用库中的回调函数ScriptInit,汗,有点头晕了。

后面LoadScriptModule由World.SetInitialWorldSettings调用,而SetInitialWorldSettings由Master.Run调用。将这个过程翻转一下,就是脚本被初始化的过程。

写好之后,还必须在Item_template里面增加一个Item,并且绑定他们的ScriptName为你自己的脚本名字,如 "item_only_for_flight"。