📄 cscript.cpp
字号:
//--------------------------------------------------------------------------------------------------------
// 游戏脚本模块
//CScript.cpp
//游戏引擎中的脚本部分
//作者:吴振华(kylinx)(中国科大01级11系)
//E-mail:game-diy@163.com
//创建于:2003/6/28 by Kylinx
//--------------------------------------------------------------------------------------------------------
#include<stdio.h>
#include"CScript.h"
#include"CError.h"
#include"CMessage.h"
#include"CGame.h"
#include"CGraph.h"
#include"CMoveRole.h"
#include"CMacro.h"
#include"CRole.h"
#include"CTalk.h"
////////////////////////////////////////////////////////////////////////////////////////////
//构造
////////////////////////////////////////////////////////////////////////////////////////////
CScriptData::CScriptData()
{
m_pLog=NULL;
m_aFlag=NULL;
}
////////////////////////////////////////////////////////////////////////////////////////////
//析构
////////////////////////////////////////////////////////////////////////////////////////////
CScriptData::~CScriptData()
{
Release();
}
BOOL CScriptData::SaveFlagToFile(FILE*fp)
{
LOA_ASSERT(fp);
if(!m_aFlag)
return false;
fwrite(m_aFlag,sizeof(int)*m_nFlagCount,1,fp);
return true;
}
BOOL CScriptData::LoadFlagFromFile(FILE*fp)
{
LOA_ASSERT(fp);
if(!m_aFlag)
return false;
fread(m_aFlag,sizeof(int)*m_nFlagCount,1,fp);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
//释放
////////////////////////////////////////////////////////////////////////////////////////////
void CScriptData::Release()
{
if(m_aFlag)
{
delete [] m_aFlag;
m_aFlag=NULL;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
//初始化脚本数据库
////////////////////////////////////////////////////////////////////////////////////////////
BOOL CScriptData::InitScriptVariable(CLog*pLog,int Size)
{
LOA_ASSERT(pLog);
m_pLog=pLog;
Release();
this->m_nFlagCount=Size;
if(m_nFlagCount<=0)
return false;
m_aFlag=new int[m_nFlagCount];
if(!m_aFlag)
{
if(m_pLog)
m_pLog->WriteMessage("New Game Flag Failed! out of memory!\n");
return false;
}
for(int i=0;i<m_nFlagCount;i++)
m_aFlag[i]=LOA_FLAG_CLOSE;
m_pLog->WriteMessage("Init Script Variable...OK!\n");
return true;
}
BOOL CScriptData::SetFlag(int index,int flagstate)
{
if(index<0 || index>=m_nFlagCount)
return false;
m_aFlag[index]=flagstate;
return true;
}
BOOL CScriptData::IsFlagEquel(int index,int flagstate)
{
if(index<0 || index>=m_nFlagCount)
return false;
if(m_aFlag[index]==flagstate)
return true;
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////
CScript::CScript()
{
m_pLog=NULL;
m_pBuffer=NULL;
m_pBufEnd=NULL;
m_pScriptData=NULL;
m_pMsgQueue=NULL;
m_pMoveRole=NULL;
}
CScript::~CScript()
{
Release();
}
BOOL CScript::InitScript(const char*szFile)
{
LOA_ASSERT(szFile);
OFSTRUCT ofs;
HFILE hf=OpenFile(szFile,&ofs,GENERIC_READ);
if(-1==hf)
{
m_pLog->WriteMessage("Open Script File<%s> Failed!\n",szFile);
return false;
}
m_dwSize=::GetFileSize((HANDLE)hf,NULL);
if(0xffffffff==m_dwSize)
{
m_pLog->WriteMessage("Get File<%s> Size Failed!\n",szFile);
_lclose(hf);
return false;
}
_lclose(hf);
m_pBuffer=new char[m_dwSize];
if(!m_pBuffer)
{
m_pLog->WriteMessage("New Script Buffer Failed! Size=%d\n",m_dwSize);
return false;
}
FILE*fp=fopen(szFile,"r");
fread(m_pBuffer,m_dwSize,1,fp);
fclose(fp);
m_pBufEnd=m_pBuffer+m_dwSize;
m_pBufCur=m_pBuffer;
m_pMoveRole=new CMoveRole();
strncpy(m_szScriptFile,szFile,128);
return true;
}
void CScript::Release()
{
if(m_pBuffer)
{
delete [] m_pBuffer;
m_pBuffer=NULL;
}
m_pBufCur=NULL;
m_pBufEnd=NULL;
m_dwSize=0;
if(m_pMsgQueue)
{
m_pMsgQueue->ClearAllMessage();
delete m_pMsgQueue;
m_pMsgQueue=NULL;
}
if(m_pMoveRole)
{
delete m_pMoveRole;
m_pMoveRole=NULL;
}
}
BOOL CScript::GotoNextLine(char* &pBufCur)
{
while(pBufCur<=m_pBufEnd)
{
if(*pBufCur=='\n')
{
pBufCur++; //跳过回车
return true;
}
pBufCur++;
}
return false;
}
BOOL CScript::GetNextIndexPositon(char* &pBufCur)
{
while(pBufCur<=m_pBufEnd)
{
if(*pBufCur=='#')
{
pBufCur++; //跳过#
return true;
}
pBufCur++;
}
return false;
}
BOOL CScript::IsNum(char c)
{
if(c>='0' && c<='9')
return true;
return false;
}
BOOL CScript::IsChar(char c)
{
if((c>='a' && c<='z') || ( c>='A' && c<='Z'))
return true;
return false;
}
BOOL CScript::GetInt(char*&pBufCur,int&iValue)
{
char str[32];
memset(str,0,32);
int i=0;
while(pBufCur<=m_pBufEnd)
{
if(IsNum(*pBufCur))
{
if(i<32)
{
str[i++]=*pBufCur;
}
pBufCur++;
}
else
{
if(strcmp(str,"")==0)
return false;
sscanf(str,"%d",&iValue);
return true;
}
}
return false;
}
BOOL CScript::GetString(char* &pBufCur,ScriptStr&str)
{
memset(str,0,1024);
int i=0;
while(pBufCur<=m_pBufEnd)
{
if(*pBufCur=='"')
{
pBufCur++; //跳过"号
break;
}
if(i<1024)
{
str[i++]=*pBufCur; //拷贝字符串到str中,最多1024个字符
}
pBufCur++;
}
return true;
}
BOOL CScript::GetFunction(char*&pBufCur,ScriptStr&str)
{
memset(str,0,1024);
int i=0;
while(pBufCur<=m_pBufEnd)
{
if(*pBufCur=='(')
{
pBufCur++; //跳过(号
break;
}
if(i<1024)
{
str[i++]=*pBufCur; //拷贝字符串到str中,最多1024个字符
}
pBufCur++;
}
return true;
}
BOOL CScript::GetIndex(char*&pBufCur,ScriptStr&str)
{
memset(str,0,1024);
int i=0;
while(pBufCur<=m_pBufEnd)
{
if(*pBufCur=='#')
{
pBufCur++; //跳过#
break;
}
if(i<1024)
{
str[i++]=*pBufCur;
}
pBufCur++;
}
return true;
}
BOOL CScript::ExecuteScript(CGame*pGame,CLog*pLog,CScriptData*pScriptData,const char*szFile)
{
LOA_ASSERT(pGame);
LOA_ASSERT(pLog);
LOA_ASSERT(pScriptData);
LOA_ASSERT(szFile);
m_pGame=pGame;
m_pLog=pLog;
Release();
m_pMsgQueue=new CMessage();
m_pMsgQueue->InitMessageQueue(pGame->GetLog());
m_pScriptData=pScriptData;
ScriptStr str;
if(!InitScript(szFile))
{
Release();
return false;
}
m_bComplete=false;
while(m_pBufCur<=m_pBufEnd)
{
//--------------------------------跳过注释---------------------------------------------
if(*m_pBufCur=='/') //如果是"/"
{
if(m_pBufCur+1>m_pBufEnd) //如果到了文件末尾
{
Release();
return false;
}
if(*(m_pBufCur+1)=='/') //如果是//
{
if(!GotoNextLine(m_pBufCur))
{
Release();
return false;
}
continue;
}
else
{
m_pBufCur++;
continue;
}
}
//-------------------------------------------------------------------------------------
//--------------------------------跳过空格,回车,和tab--------------------------------
if(*m_pBufCur==' ' || *m_pBufCur=='\t' || *m_pBufCur=='\n')
{
m_pBufCur++;
continue;
}
//-------------------------------------------------------------------------------------
//--------------------------------跳过索引标号-----------------------------------------
if(*m_pBufCur=='#')
{
if(!GotoNextLine(m_pBufCur))
{
Release();
return false;
}
continue;
}
//-------------------------------------------------------------------------------------
//--------------------------------得到数据---------------------------------------------
if(IsChar(*m_pBufCur))
{
GetFunction(m_pBufCur,str);
strlwr(str);
int iRev=ExecuteFunction(str);
if(0==iRev)
{
Release();
return false;
}
else if(iRev==-1)
{
Release();
return -1;
}
else
{
if(m_bComplete)
{
while(m_pMsgQueue->GetMessageCount()>0)
{
m_pMsgQueue->ExecuteMessage();
}
Release();
return true;
}
if(!GotoNextLine(m_pBufCur))
{
Release();
return true;
}
continue;
}
}
else
{
m_pBufCur++;
}
}
Release();
return true;
}
BOOL CScript::ExecuteFunction(const char*szFunction)
{
LOA_ASSERT(szFunction);
int iv1,iv2,iv3,iv4,iv5;
ScriptStr str;
STMessage msg;
msg.cParam=(void*)m_pGame;
//-----------------------------------------------------------------------------------------
//return;指令
if(strcmp(szFunction,"return")==0) //从脚本结束
{
m_bComplete=true;
return true;
}
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
//LoadScript(char*szFile);
//ex:LoadScript("script\script.ini");
else if(strcmp(szFunction,"loadscript")==0) //laodScript指令
{
WaitForNextChar(m_pBufCur);
GetString(m_pBufCur,str); //得到文件名字
CScript script;
script.ExecuteScript(m_pGame,m_pGame->GetLog(),
m_pGame->GetScriptData(),str);
/*
msg.ID=LOA_MSG_LOADSCRIPT;
msg.pParam1=new char[64];
msg.dwNewFlag=LOA_MSG_NEW_P1PARAM_A; //说明参数pParam申请了内存,为以后引擎可以识别而释放之
strncpy((char*)msg.pParam1,str,64);
m_pMsgQueue->AddMessage(msg);
*/
return true;
}
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
//SetPlayerDir(int dir);
// dir==0 下
// 1 左
// 2 上
// 3 右
else if(strcmp(szFunction,"setplayerdir")==0) //SetPlayerDir指令(int dir)
{
WaitForNextNum(m_pBufCur);
if(!GetInt(m_pBufCur,iv1))
{
m_pLog->WriteMessage("Get Command<SetPlayerDir>'s Param1 failed!\n");
return false;
}
if(iv1>=0 && iv1<=3)
{
m_pGame->GetPlayer()->pRole->nDirection=iv1;
}
return true;
}
//-----------------------------------------------------------------------------------------
//SetNpcDir(int idInGame,int dir)
else if(strcmp(szFunction,"setnpcdir")==0)
{
WaitForNextNum(m_pBufCur);
GetInt(m_pBufCur,iv1);
m_pBufCur++;
WaitForNextNum(m_pBufCur);
GetInt(m_pBufCur,iv2);
if(iv2>=0 && iv2<=3)
{
if(iv1==0)
{
DWORD dwTempAddr=m_pGame->GetNpcList()->GetCurAddress();
m_pGame->GetNpcList()->ResetToHead();
STRenderRole*pNpc;
while(m_pGame->GetNpcList()->GetAndMovePointToNext(pNpc))
{
pNpc->pRole->nDirection=iv2;
}
m_pGame->GetNpcList()->SetCurAddress(dwTempAddr);
}
else
{
STRenderRole*pNpc;
if(m_pGame->GetNpcList()->FindData(iv1,pNpc))
{
pNpc->pRole->nDirection=iv2;
}
}
}
return true;
}
//SetNpcScript(int id,char*szScript);
else if(strcmp(szFunction,"setnpcscript")==0)
{
WaitForNextNum(m_pBufCur);
GetInt(m_pBufCur,iv1);
m_pBufCur++;
WaitForNextChar(m_pBufCur);
GetString(m_pBufCur,str);
STRenderRole*pNpc;
if(m_pGame->GetNpcList()->FindData(iv1,pNpc))
{
strncpy(pNpc->pRole->szNpcScriptFile,str,128);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -