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

Share
    New Mem
    avatar

    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 on 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).


    Đầ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