www.pudn.com > GameEngine_src.rar > CNpcDlg.cpp


// CNpcDlg.cpp: implementation of the CNpcDlg class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "CNpcDlg.h" 
#include "normal.h" 
#include "CDInput.h" 
#include  
#include  
#include  
#include "normal.h" 
 
using std::string; 
 
extern PEASYDRAW	g_pEasyDraw; 
extern CDIMouse		theMouse; 
 
struct DLG_FILE_HEAD 
{ 
	int		dlgFileType;		//文件标识 
	int		dlgPageNum;			//对话框中页面中的数量 
	int		dlgESOffset;		//ES在文件中的偏移 
	char	dlgBKName[32]; 
	char	dlgHeadName[32]; 
}; 
 
const DLG_FILE = 'DLG'; 
 
struct DLG_PAGE_INFO 
{ 
	int ButtonNum;			//一个页面中按钮的数量 
	char NpcWordName[32];	//页面中NPC话语的图像文件名 
}; 
 
struct DLG_BUTTON_INFO 
{ 
	int  CmdOffset;			//按钮脚本在命令池中的偏移 
	int	 CmdNum;			//按钮中命令的数量 
	char ButtonName[32];	//按钮图像文件 
	RECT ButtonRect;		//按钮RECT 
}; 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
CNpcDlg::CNpcDlg() 
{ 
	m_CurPage = 0; 
	m_CurButton = 0; 
	m_DlgBKSurface = NULL; 
	m_NpcHeadSurface = NULL; 
} 
 
CNpcDlg::~CNpcDlg() 
{ 
	Free(); 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CNpcDlg::Init() 
{ 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CNpcDlg::Free() 
{ 
	for ( int i = 0; i < m_PageList.GetLength(); ++i ) 
	{ 
		CDynamicArray &ButtonList = m_PageList[i].m_ButtonList; 
 
		for ( int j = 0; j < ButtonList.GetLength(); ++j ) 
		{ 
			g_pEasyDraw->DeleteSurface( ButtonList[j].m_ButtonSurface ); 
		} 
 
		g_pEasyDraw->DeleteSurface( m_PageList[i].m_NpcWordSurface ); 
	} 
	if ( m_DlgBKSurface ) 
	{ 
		g_pEasyDraw->DeleteSurface( m_DlgBKSurface ); 
		g_pEasyDraw->DeleteSurface( m_NpcHeadSurface ); 
		m_DlgBKSurface = NULL; 
		m_NpcHeadSurface = NULL; 
	} 
	m_PageList.Free(); 
} 
/* 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CNpcDlg::LoadDlg( char *filename, bool isFromFile ) 
{ 
	if ( isFromFile ) 
	{ 
		FILE *fp = fopen( filename, "rb" ); 
		if ( fp == NULL )	return false; 
 
		DLG_FILE_HEAD dfh; 
		fread( &dfh, sizeof(dfh), 1, fp ); 
		if ( dfh.dlgFileType != DLG_FILE ) 
		{ 
			fclose(fp); 
			return false; 
		} 
 
		char sz[64]; 
		strcpy( sz, "..\\data\\npc_dlg\\" ); 
		strcat( sz, dfh.dlgBKName ); 
		m_DlgBKSurface = g_pEasyDraw->CreateSurface( sz, 0, 0 ); 
		assert( m_DlgBKSurface != NULL ); 
 
		strcpy( sz, "..\\data\\npc_dlg\\" ); 
		strcat( sz, dfh.dlgHeadName ); 
		m_NpcHeadSurface = g_pEasyDraw->CreateSurface( sz, 0, 0 ); 
		assert( m_NpcHeadSurface != NULL ); 
 
		m_CmdPool.LoadESFromFile( fp, dfh.dlgESOffset );			//load script 
		fseek( fp, sizeof(dfh),	SEEK_SET ); 
 
		for ( int i = 0; i < dfh.dlgPageNum; ++i ) 
		{ 
			DLG_PAGE_INFO page_info; 
			fread( &page_info, sizeof(DLG_PAGE_INFO), 1, fp ); 
			 
			DLG_PAGE *pPage = m_PageList.CreateOneElement(); 
 
			strcpy( sz, "..\\data\\npc_dlg\\" ); 
			strcat( sz, page_info.NpcWordName ); 
			pPage->m_NpcWordSurface = g_pEasyDraw->CreateSurface( sz, 0, 0 ); 
			assert( pPage->m_NpcWordSurface != NULL ); 
 
			for ( int j = 0; j < page_info.ButtonNum; ++j ) 
			{ 
				DLG_BUTTON_INFO button_info; 
				fread( &button_info, sizeof(button_info), 1, fp ); 
 
				DLG_BUTTON *pButton = pPage->m_ButtonList.CreateOneElement(); 
 
				strcpy( sz, "..\\data\\npc_dlg\\" ); 
				strcat( sz, button_info.ButtonName ); 
				pButton->m_ButtonSurface = g_pEasyDraw->CreateSurface( sz, 0, 0 ); 
				assert( pButton->m_ButtonSurface != NULL ); 
 
				pButton->m_ButtonRect	= button_info.ButtonRect; 
				pButton->m_CmdNum		= button_info.CmdNum; 
				pButton->m_CmdOffset	= button_info.CmdOffset; 
			} 
		} 
	} 
	else 
	{ 
		char *buf = filename; 
		DLG_FILE_HEAD dfh = READ_MEMORY( buf, DLG_FILE_HEAD ); 
		if ( dfh.dlgFileType != DLG_FILE ) 
			return false; 
 
		char sz[64]; 
		strcpy( sz, "..\\data\\npc_dlg\\" ); 
		strcat( sz, dfh.dlgBKName ); 
		m_DlgBKSurface = g_pEasyDraw->CreateSurface( sz, 0, 0 ); 
		assert( m_DlgBKSurface != NULL ); 
 
		strcpy( sz, "..\\data\\npc_dlg\\" ); 
		strcat( sz, dfh.dlgHeadName ); 
		m_NpcHeadSurface = g_pEasyDraw->CreateSurface( sz, 0, 0 ); 
		assert( m_NpcHeadSurface != NULL ); 
 
		m_CmdPool.LoadESFromMemory( buf, dfh.dlgESOffset ); 
		buf += sizeof(DLG_FILE_HEAD); 
 
		for ( int i = 0; i < dfh.dlgPageNum; ++i ) 
		{ 
			DLG_PAGE_INFO page_info = READ_MEMORY( buf, DLG_PAGE_INFO ); 
			buf += sizeof(DLG_PAGE_INFO); 
			 
			DLG_PAGE *pPage = m_PageList.CreateOneElement(); 
 
			strcpy( sz, "..\\data\\npc_dlg\\" ); 
			strcat( sz, page_info.NpcWordName ); 
			pPage->m_NpcWordSurface = g_pEasyDraw->CreateSurface( sz, 0, 0 ); 
			assert( pPage->m_NpcWordSurface != NULL ); 
 
			for ( int j = 0; j < page_info.ButtonNum; ++j ) 
			{ 
				DLG_BUTTON_INFO button_info = READ_MEMORY( buf, DLG_BUTTON_INFO ); 
				buf += sizeof(DLG_BUTTON_INFO); 
 
				DLG_BUTTON *pButton = pPage->m_ButtonList.CreateOneElement(); 
 
				strcpy( sz, "..\\data\\npc_dlg\\" ); 
				strcat( sz, button_info.ButtonName ); 
				pButton->m_ButtonSurface = g_pEasyDraw->CreateSurface( sz, 0, 0 ); 
				assert( pButton->m_ButtonSurface != NULL ); 
 
				pButton->m_ButtonRect	= button_info.ButtonRect; 
				pButton->m_CmdNum		= button_info.CmdNum; 
				pButton->m_CmdOffset	= button_info.CmdOffset; 
			} 
		} 
	} 
 
	return true; 
}*/ 
 
////////////////////////////////////////////////////////////////////// 
//从EPK文件中读取dlg文件 
//dlg文件结构:文件头+页数据(每一页包括按钮数据)+脚本 
////////////////////////////////////////////////////////////////////// 
bool CNpcDlg::LoadDlgFromEPK( CEPKFile &epk, const char *dlgName ) 
{ 
	BYTE *buf = epk.Read( dlgName ); 
	debug_assert( buf != NULL ); 
 
	DLG_FILE_HEAD dfh = READ_MEMORY( buf, DLG_FILE_HEAD );	//读取dlg文件头 
	buf += sizeof(dfh); 
	CDynamicArray surfNameArray; 
	string name; 
 
	for ( int i = 0; i < dfh.dlgPageNum; ++i ) 
	{	//读取页面信息 
		DLG_PAGE_INFO pageInfo = READ_MEMORY( buf, DLG_PAGE_INFO ); 
		buf += sizeof(DLG_PAGE_INFO); 
		DLG_PAGE *pPage = m_PageList.CreateOneElement();	//创建页面对象 
 
		name = pageInfo.NpcWordName; 
		pPage->m_IndexOfSurface = surfNameArray.GetLength(); 
		surfNameArray.Add( name ); 
 
		for ( int j = 0; j < pageInfo.ButtonNum; ++j ) 
		{ 
			DLG_BUTTON_INFO buttonInfo = READ_MEMORY( buf, DLG_BUTTON_INFO ); 
			buf += sizeof(buttonInfo); 
			DLG_BUTTON *pButton = pPage->m_ButtonList.CreateOneElement(); 
			pButton->m_ButtonRect	= buttonInfo.ButtonRect; 
			pButton->m_CmdNum		= buttonInfo.CmdNum; 
			pButton->m_CmdOffset	= buttonInfo.CmdOffset; 
 
			name = buttonInfo.ButtonName; 
			pButton->m_IndexOfSurface = surfNameArray.GetLength(); 
			surfNameArray.Add( name ); 
 
		} 
	} 
 
	m_CmdPool.LoadESFromMemory( (char*)buf, 0 ); 
 
	//读取各个页面: 
	buf = epk.Read( dfh.dlgBKName );				//载入背景ECP 
	debug_assert( buf != NULL ); 
	m_DlgBKSurface = g_pEasyDraw->CreateSurfaceFromMemory( buf ); 
 
	buf = epk.Read( dfh.dlgHeadName );				//载入NPC头像页面 
	debug_assert( buf != NULL ); 
	m_NpcHeadSurface = g_pEasyDraw->CreateSurfaceFromMemory( buf ); 
 
	CDynamicArray surfArray; 
	for ( i = 0; i < surfNameArray.GetLength(); ++i ) 
	{ 
		buf = epk.Read( surfNameArray[i].c_str() );	//载入所有对话和按钮页面 
		debug_assert( buf != NULL ); 
		PSURFACE surf = g_pEasyDraw->CreateSurfaceFromMemory( buf ); 
		surfArray.Add( surf ); 
	} 
 
	for ( i = 0; i < m_PageList.GetLength(); ++i ) 
	{ 
		DLG_PAGE &page = m_PageList[i]; 
		page.m_NpcWordSurface = surfArray[page.m_IndexOfSurface]; 
 
		for ( int j = 0; j < page.m_ButtonList.GetLength(); ++j ) 
		{ 
			DLG_BUTTON &button = page.m_ButtonList[j]; 
			button.m_ButtonSurface = surfArray[button.m_IndexOfSurface]; 
		} 
	} 
 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
//处理鼠标信息 
////////////////////////////////////////////////////////////////////// 
void CNpcDlg::HandleMouseMsg() 
{ 
	int mx = theMouse.GetX(); 
	int my = theMouse.GetY(); 
 
	if ( m_CurPage > 0 && m_CurPage <= m_PageList.GetLength() ) 
	{ 
		//draw back ground picture in center 
		int x = g_pEasyDraw->GetDeviceWidth() >> 1;		//width / 2 
		int y = g_pEasyDraw->GetDeviceHeight() >> 1; 
 
		m_Render.x = x - (m_DlgBKSurface->GetWidth() >> 1); 
		m_Render.y = y - (m_DlgBKSurface->GetHeight() >> 1); 
 
		//判断鼠标是否在按钮上面 
		m_CurButton = 0; 
		CDynamicArray &ButtonList = m_PageList[m_CurPage-1].m_ButtonList; 
		for ( int i = 0; i < ButtonList.GetLength(); ++i ) 
		{ 
			DLG_BUTTON &button = ButtonList[i]; 
			if ( mx > button.m_ButtonRect.left+m_Render.x && mx < button.m_ButtonRect.right+m_Render.x ) 
			{ 
				if ( my > button.m_ButtonRect.top+m_Render.y && my < button.m_ButtonRect.bottom+m_Render.y ) 
				{ 
					m_CurButton = i+1; 
 
					if ( theMouse.IsLRelease() ) 
					{ 
						DLG_BUTTON &button = m_PageList[m_CurPage-1].m_ButtonList[m_CurButton-1]; 
						m_CmdPool.SetObj( this ); 
						m_CmdPool.RunCmd( button.m_CmdOffset, button.m_CmdNum ); 
					} 
				} 
			} 
		} 
	} 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CNpcDlg::Draw() 
{ 
	if ( m_CurPage > 0 && m_CurPage <= m_PageList.GetLength() ) 
	{ 
		m_DlgBKSurface->DrawSurface( m_Render.x, m_Render.y, 0 ); 
 
		//draw npc head 
		m_NpcHeadSurface->DrawSurface( m_Render.x+73, m_Render.y+45, 0 ); 
 
		//draw npc word 
		m_PageList[m_CurPage-1].m_NpcWordSurface->DrawSurface( m_Render.x+180, m_Render.y+45, 0 ); 
 
		//draw button 
		CDynamicArray &ButtonList = m_PageList[m_CurPage-1].m_ButtonList; 
		for ( int i = 0; i < ButtonList.GetLength(); ++i ) 
		{ 
			DLG_BUTTON &button = ButtonList[i]; 
			button.m_ButtonSurface->DrawSurface(button.m_ButtonRect.left+m_Render.x, button.m_ButtonRect.top+m_Render.y, 0); 
		} 
 
		//draw button be selected 
		if ( m_CurButton > 0 && m_CurButton <= ButtonList.GetLength() ) 
		{ 
			DLG_BUTTON &button = ButtonList[m_CurButton-1]; 
			button.m_ButtonSurface->DrawContour(button.m_ButtonRect.left+m_Render.x, button.m_ButtonRect.top+m_Render.y ); 
		} 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CNpcDlg::GoToPage( int page_num ) 
{ 
	if ( page_num >= 0 && page_num <= m_PageList.GetLength() ) 
	{ 
		m_CurPage = page_num; 
		m_CurButton = 0; 
	} 
} 
 
//****************************************NPC对话框管理器的实现************************************** 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
CNpcDlgMgr::CNpcDlgMgr() 
{ 
	m_CurDlgIndex = 0; 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
CNpcDlgMgr::~CNpcDlgMgr() 
{ 
 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CNpcDlgMgr::Init() 
{ 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CNpcDlgMgr::Free() 
{ 
	m_NpcDlgList.Free(); 
	m_NpcDlgNameList.Free(); //因为只有少数关卡有NPC对话框,所以此处free 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CNpcDlgMgr::OnFreeLvl() 
{ 
	m_NpcDlgList.Free(); 
	m_NpcDlgNameList.Free(); //因为只有少数关卡有NPC对话框,所以此处free 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CNpcDlgMgr::OnLoadMap( char *dlgName ) 
{ 
	string str = dlgName; 
	m_NpcDlgNameList.Add( str ); 
} 
 
////////////////////////////////////////////////////////////////////// 
//按DLG文件载入列表,载入所有DLG文件 
////////////////////////////////////////////////////////////////////// 
bool CNpcDlgMgr::OnLoadLvl() 
{ 
	CEPKFile epk; 
	if ( false == epk.Open( "..\\data\\dlg.epk", EPK_IN ) ) 
	{ 
		assert( false ); 
		return false; 
	} 
 
	for ( int i = 0; i < m_NpcDlgNameList.GetLength(); ++i ) 
	{ 
		CNpcDlg *pDlg = m_NpcDlgList.CreateOneElement(); 
		pDlg->LoadDlgFromEPK( epk, m_NpcDlgNameList[i].c_str() ); 
	} 
 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CNpcDlgMgr::OnInitLvl() 
{ 
	m_CurDlgIndex = 0; 
	return true; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
bool CNpcDlgMgr::OpenDlg( char *dlg_name ) 
{ 
	string sz = dlg_name; 
	int i = m_NpcDlgNameList.Find( sz ); 
	m_CurDlgIndex = 0; 
	if ( i >= 0 ) 
	{ 
		m_CurDlgIndex = i+1; 
		m_NpcDlgList[m_CurDlgIndex-1].GoToPage(1); 
				 
		return true; 
	} 
	else 
		assert(false); 
	return false; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CNpcDlgMgr::CloseDlg() 
{ 
	m_NpcDlgList[m_CurDlgIndex-1].GoToPage(0); 
	m_CurDlgIndex = 0; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
int CNpcDlgMgr::HandleMouseMsg() 
{ 
	if ( m_CurDlgIndex > 0 ) 
	{ 
		m_NpcDlgList[m_CurDlgIndex-1].HandleMouseMsg(); 
		return 1; 
	} 
	return 0; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 
////////////////////////////////////////////////////////////////////// 
void CNpcDlgMgr::Draw() 
{ 
	if ( m_CurDlgIndex > 0 ) 
	{ 
		m_NpcDlgList[m_CurDlgIndex-1].Draw(); 
	} 
}