mangos传送宝石原理和具体参考代码
为了理解宝石的原理,我们先来理解一下与NPC进行谈话时出现菜单的原理
为了方便,我们用 C来表示客户端,也就是玩家的窗口。用S来表示服务端。
用---箭头符号来表示发送的消息。
一个完整的显示菜单的过程如下:
用户点击一个NPC:
C----S 显示一个某某NPC的菜单 S----C 显示菜单内容
用户选择一项菜:
C----S 选择了某菜单 S----C 执行选择菜单的功能
这些功能是客户端天然支持的:
为了实现用宝石来触发菜单,摆在我们面前的问题有两个
1、如何触发显示菜单的消息?
2、如何处理玩家选择菜单后的消息?
为了解决第一个问题,经过研究,我们会发现:
当物品类型为任务物品的时候,客户端会向服务端发送消息
当物品类型为可使用物品的时候,也会发送
当物品类型为可阅读物品的时候,也会发送
所以,现在我们可以收到客户端发来的消息了。
以任务物品为例,定义一个物品,类型为任务物品(当然也可以是其他类型的)。再随便定义一个任务ID.
这样,用户右键点这个物品的时候服务端就可以收到消息。
在任务物品的处理函数是这个
void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data )
在这里面加上处理
如果任务是物品触发的,如果物品Id是你定义的那个。就显示一个菜单。
if(qst_giver->GetEntry() == 你定义的那个物品ID)
{
GossipMenu *Menu;
objmgr.CreateGossipMenuForPlayer(&Menu, Plr->GetGUID(), 1, Plr);
Menu->AddItem(0,"1 申明", 29);
Menu->AddItem(0,"2 主城传送", 27);
Menu->AddItem(0,"3 副本传送", 28);
Menu->AddItem(0,"4 战场传送", 34);
Menu->AddItem(0,"5 会员服务", 3);
Menu->SendTo(Plr);
return;
}
GossipMenu这个类是专门用来生成菜单的,
AddItem(0,"1 申明", 29)函数的第一个参数表示菜单项编号。
第二个参数就是显示给玩家的字符,
第三个参数就是玩家点击该菜单后客户端会发送给服务端的编号.
最后Menu->SendTo(Plr)是把该菜单发送给玩家。
这样,我们就可以给玩家显示主菜单
接下来,玩家选择菜单的处理
玩家选择菜单处理是在void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data )
中完成的。
这个函数本身是用来处理npc的菜单选择处理的。
我们在其中增加判断如果玩家的guid和npc的guid相等,我们就认为这是一个宝石菜单
在这里面处理吧消息吧。
if (guid == _player->GetGUID())
{
uint32 IntId = 1;
GossipMenuItem item = _player->CurrentGossipMenu->GetItem(option);
IntId = item.IntId;
switch(IntId)
{
case 0:
{
GossipMenu *Menu;
objmgr.CreateGossipMenuForPlayer(&Menu, Plr->GetGUID(), 1, Plr);
Menu->AddItem(0,"1 申明", 29);
Menu->AddItem(0,"2 主城传送", 27);
Menu->AddItem(0,"3 副本传送", 28);
Menu->AddItem(0,"4 战场传送", 34);
Menu->AddItem(0,"5 会员服务", 3);
Menu->SendTo(Plr);
break;
}
case 2:
{
GossipMenu *Menu;
objmgr.CreateGossipMenuForPlayer(&Menu, Plr->GetGUID(), 1, Plr);
Menu->AddItem(0,"1 部落", 29);
Menu->AddItem(0,"2 联盟", 27);
Menu->AddItem(0,"3 外域", 28);
Menu->AddItem(0,"4 等等", 34);
break;
}
//.....扩展更多
}
return;
} 商业版发布站程序下载:发布站程序下载: