thienthanden2
29-01-13, 06:41 AM
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).
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>
Đầ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:
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
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:
{"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:
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:
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:
#ifndef _SERVER
int m_nImageNpcID; //id npc
#endif
5.File \JX\swrod3\SwordOnline\Sources\Core\Src\KPlayer.cp p
Hàm void KPlayer::Release()
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
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:
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:
#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:
case GDCNI_QUESTION_CHOOSE:
{
if (nParam)
KUiMsgSel2::OpenWindow((KUiQuestionAndAnswer*)uPar am, (KUiNpcSpr*)nParam);
else KUiMsgSel::OpenWindow((KUiQuestionAndAnswer*)uPara m);
}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:
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:
KWndImage m_NpcSpr;
9.2. File UiMsgSel2.cpp mới tạo
Sửa lại hàm openwindow và 1 số thứ:
#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
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! :)>-
Hôm nay mình xin hướng dẫn source newbie làm bảng Say2 (nói chuyện có hình).
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>
Đầ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:
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
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:
{"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:
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:
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:
#ifndef _SERVER
int m_nImageNpcID; //id npc
#endif
5.File \JX\swrod3\SwordOnline\Sources\Core\Src\KPlayer.cp p
Hàm void KPlayer::Release()
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
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:
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:
#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:
case GDCNI_QUESTION_CHOOSE:
{
if (nParam)
KUiMsgSel2::OpenWindow((KUiQuestionAndAnswer*)uPar am, (KUiNpcSpr*)nParam);
else KUiMsgSel::OpenWindow((KUiQuestionAndAnswer*)uPara m);
}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:
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:
KWndImage m_NpcSpr;
9.2. File UiMsgSel2.cpp mới tạo
Sửa lại hàm openwindow và 1 số thứ:
#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
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! :)>-