生活技能系統

《永生》生活技能系統

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中,客戶端也是如此。

 

發佈了22 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章