生活技能系统

《永生》生活技能系统

1 生活功能挂接

MonsterAttribute.tab中 :生活技能学习配置:1|2 啦,即:

54    葵月       1     -1    1|14|15|16|17  1|14|15|16|17  0|1|10      1|2

2 客户端点击NPC

à Client:

 UBI_CCSDefaultDialogPacket

 

à Server:

 CSDefaultDialogHandler -> 调用脚本

  --sceneId表示场景号, selfid玩家,targetIdNPC

  function x000001_OnDefaultEvent( sceneId, selfHighId, selfLowId,targeHighId, targeLowId)

       BeginAddEvent(sceneId)

        AddEvent( sceneId, -1, 2, string4)

        AddEvent( sceneId, -1, 13, string5)

       EndAddEvent(sceneId)

       DispatchEventList(sceneId, selfHighId, selfLowId, targeHighId, targeLowId )

       return1

 end

通过读MonsterAttribute.tab中配置的生活技能学习配置(1|2),

之后检索表:DTT_LIFE_SKILL_LEARN,  //生活技能学习表LifeSkillLearn.tab

生活技能商店ID   生活技能商店名称

INT STRING

1     学习采矿

2     学习锻造

NPC_EVENT npcEvent;

npcEvent.m_NpcEventType = NPC_EVENT_LIFE_SKILL;

npcEvent.m_nID = 1 | 2;

npcEvent.m_Name = 学习采矿 | 学习锻造;

其中DispatchEventList中又会发包:SCNPCEventListPacket

 

à Client:

显示对话框上的列表选项:

//NPC一级对话事件列表

UBI_VOID WINAPIUBI_CPacketExecute::SCNPCEventListExecute(UBI_CPacket* pPacket)

{

       pNPCDialogData->SetNPCGuid(pSCNPCEventListPacket->GetNPCGUID().m_ullValue);

       pNPCDialogData->SetDialogTipID(pSCNPCEventListPacket->GetDialogTipID());

       for(UBI_INTi=0; i<pSCNPCEventListPacket->GetEventListCount(); i++)

       {

              pNPCDialogData->SetEventList(pSCNPCEventListPacket->GetNPCEvent(i),i);

       }

}

这样就保存在了NPC_EVENT NpcDialogData::m_EventList[MAX_NPCEVENTLIST_ COUNT]事件列表中,之后显示界面:pNPCDialogData->OpenNPCDialogInterface();

函数里面做:

local nEventCount =NPCDialogData:GetDialogEventCount();

if(nEventCount > 0) then

 NPCDialog_Event_Count = nEventCount

 for i = 0, nEventCount-1 do

  local strname, eventtype, nStatus = NPCDialogData:GetDialogEvent(i);

if(strname ~=nil) then                  NPCDialog_ComplexWindow_Main:AddOptionElement(strname,"1",tostring(i),   tostring(nStatus));

  end

 end

end

这里的:UBI_ComplexWindow::L_AddOptionElement中调用:

CEGUI::CEGUIComplexWindow* pWindow =static_cast<CEGUI::CEGUIComplexWindow*> (m_pWindow);

pWindow->AddChildElement_Option(strOut0,strOut1,strOut2,strOut3);

CEGUIComplexWindow::AddChildElement_Option中又调用:

_snprintf(szTempName, 32,"__option__%02d#%d,%d", nIndex, atoi(strExtra1.c_str()), atoi(strExtra2.c_str()));

%2d位置上对应:option按钮的编号

%d,%d位置上分别对应:"1", tostring(i) //iDialogEvent序号(01....17

 

//第一步:注册事件

pNewChild->d_Button->subscribeEvent(PushButton::EventClicked,Event::Subscriber(&CEGUIComplexWindow::handleOptionClicked, this));

//第二步:事件的触发与响应

boolCEGUIComplexWindow::handleOptionClicked(const EventArgs& e)

{

  WindowEventArgs arg( ((const WindowEventArgs&) e).window);

  fireEvent(EventOptionClicked,arg, EventNamespace); //触发

//这里CEGUIComplexWindow::EventOptionClicked就是:((utf8*)"OptionClicked" );

}

而在XML配置如下:

<WindowType="SH_ComplexWindow" Name="NPCDialog_ComplexWindow_Main">

<PropertyName="UnifiedMaxSize" Value="{{1,0},{1,0}}" />

<PropertyName="UnifiedAreaRect" Value="{{0.0783644,0},{0.157161,0}, {0.920033,0},       {0.891289,0}}" />

<Event Name="OptionClicked"Function="NPCDialogOptionClicked()"/>

而fireEvent内部会执行:

bool ScriptFunctor::operator()(constEventArgs& e) const

{

ScriptModule*scriptModule = System::getSingleton().getScriptingModule();

if (scriptModule)

{return scriptModule->executeScriptedEventHandler(scriptFunctionName, e); }

}

就会执行:UBI_UI_ScriptModule::executeScriptedEventHandler(),

其内部会调用:UBI_LayoutWnd::DoUIEvent,即执行:

UBI_ScriptSystem::GetSingleton().GetLuaState()->GetGlobals().SetString

("param0",pWindow->getName().c_str());

m_pScriptEnv->DoString(szEventHandle);

即:先设置全局变量“param0”的值,之后执行响应函数,即执行NPCDialogOptionClicked()

3 客户端点击按钮选项

àClient:

这样,点击对话框上的按钮,就会执行NPCDialogOptionClicked()。

此函数中要判断点击的是列表中的哪个按钮,解析param0即可

local clickedname = param0;

local pos1, pos2 =string.find(clickedname, "#");

local pos3, pos4 =string.find(clickedname, ",");

strType =tonumber(string.sub(clickedname, pos2+1, pos3-1 ));

strIndex =tonumber(string.sub(clickedname, pos4+1));

得到的strIndex即是npcEvent序号,注意不是npcEvent.m_nID。

NPCDialogData:ClickEventButton(strIndex,0);

函数内部执行:

UBI_CNPCDialogData::ClickEventButton()

{

//得到脚本参数

UBI_INT nPosition = args[2].GetInteger();

UBI_SHORT nNPCDialogType =args[3].GetInteger();

客户端如果点击的按钮是:关于“生活技能”的,那么执行:

switch(m_EventList[nPosition].m_NpcEventType)

{

//生活技能

case NPC_EVENT_LIFE_SKILL:

 {

  UBI_CCSAskNpcEventInfoPacketpacket;

  packet.SetTargetGUID(UBI_GUID(pNPCObject->GetGuid()));                     

  packet.SetNpcEventType((UBI_CHAR)m_EventList[nPosition].m_NpcEventType);

  packet.SetNpcEventID(m_EventList[nPosition].m_nID);

  SendPacket(&packet);

 }

 break;

}

 

à Server:

//感觉没啥用,因为这些信息都是Client发过来的,怎么又发了回去?

服务器会判断客户端点击的是哪个NPC的身上的哪个event。

UBI_CPacketHandler::CSAskNpcEventInfoHandler()

{

      switch(pAskNpcEventInfoPacket->GetNpcEventType())

       {

       caseNPC_EVENT_LIFE_SKILL:               //生活技能

                     {

                            UBI_CSCNpcEventInfoPacketNpcEventInfoPacket;

                            NpcEventInfoPacket.SetNPCGUID(npcGuid);

NpcEventInfoPacket.SetEventType(pAskNpcEventInfoPacket   ->GetNpcEventType());

              //UBI_CSCNpcEventInfoPacket内没有ID,所以通过AddEvent来传递技能学习ID

                            NPCEVENT_INFOnpcEvent;

                            npcEvent.m_nID= pAskNpcEventInfoPacket->GetNpcEventID();

                            NpcEventInfoPacket.AddEvent(npcEvent);

                            pObjectHuman->SendStackPacket(&NpcEventInfoPacket);

                            break;

                     }

       }

}

4 显示二级对话框、点击“学习”

à Client:

//接下来就显示NPC二级对话事件列表

UBI_CPacketExecute::SCNpcEventInfoExecute(UBI_CPacket*pPacket)

{

        switch((NPC_EVENT_TYPE)pSCNpcEventInfoPacket->GetEventType())

        {

              // 生活技能学习

              caseNPC_EVENT_LIFE_SKILL:

        {

                     //获取技能学习数据

            UBI_CLearnLifeSkillData*pLearnLifeSkillData = pDataPoolManager->GetLearnLifeSkillData();

            if (UBI_NULL ==pLearnLifeSkillData)

            {

                return;

            }

                     NPCEVENT_INFO* pInfo= pSCNpcEventInfoPacket->GetEvent(0);

            if (UBI_NULL == pInfo)

            {

                return;

            }

     读取表格LifeSkillLearn.tab中的第pInfo->m_nID号对应行的生活技能学习数据,然后

         pLearnLifeSkillData->Update(pInfo->m_nID);

         (1) 读取第1页对应的生活技能,放到:vector<UBI_INT>m_SkillIDs中,

         (2) 读取第1页对应的配方,放到:vector<UBI_INT> m_PatternIDs中。

         界面显示,

     pLearnLifeSkillData->Show();

     之后根据m_SkillIDs中的技能ID,去表LifeSkill.tab中查找技能名称,加载ListBox某行上(对应技能数组索引);

     根据m_PatternIDs中的配方ID,去表LifeSkillPattern.tab中查找配方名称,加载ListBox+5000行上(对应配方数组索引+5000);

     这样,当选择列表框时候,选择“习得”,就能根据别选择列表的索引,进而得到ID。【LearnLifeSkillData:GetPatternID(patternIndex);】

     之后给服务器发学习包:

     (1) UBI_CCSLearnLifeSkillPacketpacket;

              packet.SetSkillID(skillID);

              packet.SetPatternID(-1);

     (2) UBI_CCSLearnLifeSkillPacketpacket;

              packet.SetSkillID(-1);

              packet.SetPatternID(patternID);

       }

        }

}

 

à Server:

学习配方LearnLifeSkillPattern时候,先得到对应的需求技能ID及其等级,

判断HasLearnedLifeSkill(requireSkillID)技能以及GetLifeSkillLevel(requireSkillID)技能等级。

学会的生活技能、配方等保存在m_LifeSkills中,客户端也是如此。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值