Diễn Đàn Game - Forum Game Private | GamePrivate.Biz

Xin Chào

Diễn Đàn Game - Forum Game Private | GamePrivate.Biz

Xin Chào

    [Võ Lâm]Hướng Dẫn Code Hàm Say Có Hình Npc

      New Mem
      guiuuelr

      Tổng số bài gửi : 2

      Giới tính : Male

      Gold : 8

      Cảm Ơn : 0

      Ngày Tham Gia : 2013-12-01

      Post by guiuuelr 01/12/13, 03:15 pm

      Dear All!
      Hôm nay mình xin hướng dẫn source newbie làm bảng Say2 (nói chuyện có hình).

      [Võ Lâm]Hướng Dẫn Code Hàm Say Có Hình Npc Say2_zps63719e63
      Đầu tiên thì các bạn cần thiết lập file ini trong thư mục Ui\UI3\ cho phù hợp với source của các bạn.
      Tiếp theo tạo ra 2 file UiMsgSel2.h và và UiMsgSel2.cpp bằng cách copy từ file gốc UiMsgSel.h và UiMsgSel.cpp, replace cụm từ uimsgsel bằng uimsgsel2.
      Bây giờ tiến hành làm:
      1.File \JX\swrod3\SwordOnline\Sources\Core\Src\GameDataDe f.h
      Gần struct KUiQuestionAndAnswer thêm:




      Code:
      struct KUiNpcSpr { char ImageFile[128]; unsigned short MaxFrame; };
      2. File \JX\swrod3\SwordOnline\Headers\KProtocol.h
      Tìm struct PLAYER_SCRIPTACTION_SYNC thêm 1 biến m_Select




      Code:
      typedef struct { BYTE ProtocolType; WORD m_wProtocolLong; BYTE m_nOperateType; //操作类型 BYTE m_bUIId, m_bOptionNum, m_bParam1, m_bParam2, m_Select;// chỉ thêm 1 biến ở dòng này int m_nParam; int m_nBufferLen; char m_pContent[MAX_SCIRPTACTION_BUFFERNUM]; //带控制符 } PLAYER_SCRIPTACTION_SYNC;
      3.File \JX\swrod3\SwordOnline\Sources\Core\Src\ScriptFuns .cpp
      Tìm và thêm 1 hàm vào gần hàm Say như thế này:




      Code:
      {"Say", LuaSelectUI}, {"Say2", LuaSaySPR},
      Tạo hàm LuaSaySPR y chang hàm LuaSelectUI
      Tại hàm LuaSelectUI Tìm và thêm biến mới tạo lúc nãy vào như thế này:




      Code:
      PLAYER_SCRIPTACTION_SYNC UiInfo; UiInfo.m_bUIId = UI_SELECTDIALOG; UiInfo.m_bParam1 = nDataType;//主信息的类型,字符串(0)或数字(1) UiInfo.m_bOptionNum = nOptionNum; UiInfo.m_nOperateType = SCRIPTACTION_UISHOW; UiInfo.m_Select = 0; //Từ nay 0 là Say, 1 là Say2
      Tương tự tại hàm LuaSaySPR mới tạo:




      Code:
      PLAYER_SCRIPTACTION_SYNC UiInfo; UiInfo.m_bUIId = UI_SELECTDIALOG; UiInfo.m_bParam1 = nDataType;//主信息的类型,字符串(0)或数字(1) UiInfo.m_bOptionNum = nOptionNum; UiInfo.m_nOperateType = SCRIPTACTION_UISHOW; UiInfo.m_Select = 1; //Say2
      Vậy là đã có 1 hàm lua mới rồi, bây giờ mình bắt đầu xử lý hàm đó.
      4.File \JX\swrod3\SwordOnline\Sources\Core\Src\KPlayer.h
      Tìm chỗ nào có public: thì thêm biến vào:



      Code:
      #ifndef _SERVER int m_nImageNpcID; //id npc #endif
      5.File \JX\swrod3\SwordOnline\Sources\Core\Src\KPlayer.cp p
      Hàm void KPlayer::Release()





      Code:
      void KPlayer::Release() { #ifndef _SERVER m_RunStatus = 0; m_dwNextLevelLeadExp = 0; m_nLeftSkillID = 0; m_nLeftSkillLevel = 0; m_nRightSkillID = 0; m_nRightSkillLevel = 0; m_nSendMoveFrames = defMAX_PLAYER_SEND_MOVE_FRAME; m_MouseDown[0] = FALSE; m_MouseDown[1] = FALSE; m_nImageNpcID = 0; //khởi tạo #endif 
      Tìm và sửa cái hàm này




      Code:
      void KPlayer::FindSelectNpc(int x, int y, int nRelation) { int nNpcIdx = 0; nNpcIdx = NpcSet.SearchNpcAt(x, y, nRelation, 40); if (nNpcIdx) { m_nPeapleIdx = nNpcIdx; m_nImageNpcID = nNpcIdx; // chỉ thêm có dòng này thui } else m_nPeapleIdx = 0; }
      Tiếp theo tìm hàm này void KPlayer::OnScriptAction(PLAYER_SCRIPTACTION_SYNC * pMsg) sẽ thấy ngay case UI_SELECTDIALOG, thêm vào 1 ít code như sau, mình chỉ thêm mấy dòng có chú thích và đoạn ***** mà thôi:




      Code:
      case UI_SELECTDIALOG://通知客户端显示选择窗口 { KUiQuestionAndAnswer *pQuest = NULL; KUiNpcSpr *pImage = NULL; // thêm dòng này if (pScriptAction->m_nBufferLen <= 0) break; if (pScriptAction->m_bOptionNum <= 0) pQuest = (KUiQuestionAndAnswer *)malloc(sizeof(KUiQuestionAndAnswer)); else pQuest = (KUiQuestionAndAnswer *)malloc(sizeof(KUiQuestionAndAnswer) + sizeof(KUiAnswer) * (pScriptAction->m_bOptionNum - 1)); pImage = (KUiNpcSpr *)malloc(sizeof(KUiNpcSpr)); // thêm dòng này char strContent[1024]; char * pAnswer = NULL; pQuest->AnswerCount = 0; //主信息为字符串 if (pScriptAction->m_bParam1 == 0) { g_StrCpyLen(strContent, pScriptAction->m_pContent, pScriptAction->m_nBufferLen + 1); pAnswer = strstr(strContent, "|"); if (!pAnswer) { pScriptAction->m_bOptionNum = 0; pQuest->AnswerCount = 0; } else *pAnswer++ = 0; g_StrCpyLen(pQuest->Question, strContent, sizeof(pQuest->Question)); pQuest->QuestionLen = TEncodeText(pQuest->Question, strlen(pQuest->Question)); } //主信息为数字标识 else { g_StrCpyLen(pQuest->Question, g_GetStringRes(*(int *)pScriptAction->m_pContent, szString, 1000), sizeof(pQuest->Question)); pQuest->QuestionLen = TEncodeText(pQuest->Question, strlen(pQuest->Question)); g_StrCpyLen(strContent, pScriptAction->m_pContent + sizeof(int), pScriptAction->m_nBufferLen - sizeof(int) + 1); pAnswer = strContent + 1; } for (int i = 0; i < pScriptAction->m_bOptionNum; i ++) { char * pNewAnswer = strstr(pAnswer, "|"); if (pNewAnswer) { *pNewAnswer = 0; strcpy(pQuest->Answer[i].AnswerText, pAnswer); pQuest->Answer[i].AnswerLen = -1; pAnswer = pNewAnswer + 1; } else { strcpy(pQuest->Answer[i].AnswerText, pAnswer); pQuest->Answer[i].AnswerLen = -1; pQuest->AnswerCount = i + 1; break; } } g_bUISelIntelActiveWithServer = pScriptAction->m_bParam2; g_bUISelLastSelCount = pQuest->AnswerCount; /*******************************************Code by thienthanden2*******************************************************/ if (m_nImageNpcID) { char szBuffer[128]; for (int i = 0; i < 16; i++) { Npc[m_nImageNpcID].GetNpcRes()->m_pcResNode->GetFileName(i, 3, 0, "", szBuffer, sizeof(szBuffer)); if (szBuffer[0]) { strcpy(pImage->ImageFile, szBuffer); pImage->MaxFrame = (Npc[m_nImageNpcID].GetNpcRes()->m_pcResNode->GetTotalFrames(i, 3, 0, 16))/ (Npc[m_nImageNpcID].GetNpcRes()->m_pcResNode->GetTotalDirs(i, 3, 0, 16)); goto Next; } } for (int j = 0; j < 16; j++) { Npc[m_nImageNpcID].GetNpcRes()->m_pcResNode->GetFileName(j, 0, 0, "", szBuffer, sizeof(szBuffer)); if (szBuffer[0]) { strcpy(pImage->ImageFile, szBuffer); pImage->MaxFrame = (Npc[m_nImageNpcID].GetNpcRes()->m_pcResNode->GetTotalFrames(j, 0, 0, 16))/ (Npc[m_nImageNpcID].GetNpcRes()->m_pcResNode->GetTotalDirs(j, 0, 0, 16)); goto Next; } } } Next: if (pScriptAction->m_Select == 1 && m_nImageNpcID) CoreDataChanged(GDCNI_QUESTION_CHOOSE,(unsigned int) pQuest, (int) pImage); else CoreDataChanged(GDCNI_QUESTION_CHOOSE,(unsigned int) pQuest, 0); free(pImage); pImage = NULL; /******************************************Kết thúc********************************************************/ free(pQuest); pQuest = NULL; } break;
      6.File \JX\swrod3\SwordOnline\Sources\S3Client\Ui\GameSpa ceChangedNotify.cpp
      inlude thêm vào:





      Code:
      #include "UiCase/UiMsgSel.h" #include "UiCase/UiMsgSel2.h"//tìm cái kia và inlude cái này kế bên
      Tìm case GDCNI_QUESTION_CHOOSE và sửa lại:




      Code:
      case GDCNI_QUESTION_CHOOSE: { if (nParam) KUiMsgSel2::OpenWindow((KUiQuestionAndAnswer*)uParam, (KUiNpcSpr*)nParam); else KUiMsgSel::OpenWindow((KUiQuestionAndAnswer*)uParam); }break;
      7.File \JX\swrod3\SwordOnline\Sources\S3Client\Ui\Elem\Wn dImage.h
      Khai báo thêm 1 hàm void SetMaxFrame(int nMaxFrame);
      8.File \JX\swrod3\SwordOnline\Sources\S3Client\Ui\Elem\Wn dImage.cpp
      Nãy mới tạo hàm thì giờ xử lý hàm:




      Code:
      void KWndImage::SetMaxFrame(int nMaxFrame) { m_Image.nNumFrames = nMaxFrame; }
      9.1.Giai đoạn cuối File UiMsgSel2.h mới tạo ở đầu trang
      Sửa lại thông số cho hàm static KUiMsgSel2* OpenWindow(KUiQuestionAndAnswer* pContent, KUiNpcSpr* pImage); //thêm param thứ 2
      Khai báo thêm 1 biến chứa hình ảnh npc:





      Code:
      KWndImage m_NpcSpr;
      9.2. File UiMsgSel2.cpp mới tạo
      Sửa lại hàm openwindow và 1 số thứ:




      Code:
      #define SCHEME_INI "Say2Fun.ini" //Sửa đường dẫn file ini cho phù hợp với source của các bạn, file ini do các bạn tạo ra từ file ini có sẵn của hàm Say
      Code:
      KUiMsgSel2* KUiMsgSel2::OpenWindow(KUiQuestionAndAnswer* pContent, KUiNpcSpr *pImage) { if (m_pSelf == NULL) { m_pSelf = new KUiMsgSel2; if (m_pSelf) { m_pSelf->Initialize(); m_pSelf->m_NpcSpr.SetImage(ISI_T_SPR,pImage->ImageFile,true); int nWidth, nHeight; m_pSelf->m_NpcSpr.GetSize(&nWidth, &nHeight); m_pSelf->m_NpcSpr.SetPosition(80 -nWidth/2, 80 -nHeight/2); m_pSelf->m_NpcSpr.SetMaxFrame(pImage->MaxFrame); } } if (m_pSelf) { m_pSelf->m_NpcSpr.SetImage(ISI_T_SPR,pImage->ImageFile,true); int nWidth, nHeight; m_pSelf->m_NpcSpr.GetSize(&nWidth, &nHeight); m_pSelf->m_NpcSpr.SetPosition(80 -nWidth/2, 80 -nHeight/2); m_pSelf->m_NpcSpr.SetMaxFrame(pImage->MaxFrame); UiSoundPlay(UI_SI_WND_OPENCLOSE); m_pSelf->BringToTop(); m_pSelf->Show(pContent); } return m_pSelf; } int KUiMsgSel2::Initialize() { AddChild(&m_NpcSpr); // dòng thêm AddChild(&m_MsgScrollList); AddChild(&m_InfoText); m_Style &= ~WND_S_VISIBLE; Wnd_AddWindow(this, WL_TOPMOST); char Scheme[256]; g_UiBase.GetCurSchemePath(Scheme, 256); LoadScheme(Scheme); return true; } void KUiMsgSel2::LoadScheme(const char* pScheme) { if (m_pSelf == NULL) return; char Buff[128]; KIniFile Ini; sprintf(Buff, "%s\\"SCHEME_INI, pScheme); if (Ini.Load(Buff)) { m_pSelf->Init(&Ini, "Main"); m_pSelf->m_MsgScrollList.Init(&Ini, "Select"); m_pSelf->m_InfoText.Init(&Ini, "InfoText"); m_pSelf->m_NpcSpr.Init(&Ini, "NpcSpr"); // dòng này là khởi tạo theo file ini, khỏi cũng được } } void KUiMsgSel2::Breathe() { if (m_NpcSpr.IsVisible()) m_NpcSpr.NextFrame(); //thêm if (m_bAutoUp) { if (IR_IsTimePassed(200, m_uLastScrollTime)) { ChangeCurSel(false); m_uLastScrollTime = IR_GetCurrentTime(); } } if (m_bAutoDown) { if (IR_IsTimePassed(200, m_uLastScrollTime)) { ChangeCurSel(true); m_uLastScrollTime = IR_GetCurrentTime(); } } }
      He he đến đây các bạn đã hoàn thành, build core và client lại. Bây giờ các bạn có thể Say2 với bất cứ Npc nào rồi. Vẫn còn 1 thanh cuộn các bạn phải thêm vào ở infotext nếu muốn giống VNG. Cũng rất đơn giản, chỉ cần xem các Ui có thanh cuộn và làm theo. Chúc các bạn thành công!
      Tut By Gamerur.com