📄 script.cpp
字号:
//********************************************
// 脚本 相关函数
// 创建于2000年5月8日
//********************************************
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include "gamelib\goldpoint.h"
#include "main.h"
#include "message.h"
#include "role.h"
#include "script.h"
//静态成员
int CScript::MAX_COMMAND=0;
CScript::stCommand *CScript::COMMAND=NULL;
int CScript::MAX_VARIABLE=0;
CScript::stVariable *CScript::VARIABLE=NULL;
char CScript::RecursionFile[8][MAX_PATH];
int CScript::RecursionPoint[8];
int CScript::RecursionLevel=0;
CScript::CScript()
{
Data=NULL;
}
//析构
CScript::~CScript()
{
_DELETE( Data );
}
//初始化
bool CScript::Init(char *CommandFileName, char *VariableFileName)
{
if( !LoadCommandList(CommandFileName) ) //读指令
return false;
if( !LoadVariableList(VariableFileName) ) //读全局变量
return false;
return true;
}
//读取指令列表
bool CScript::LoadCommandList(char *filename)
{
char* strTemp;
char *index="指令列表";
CIniSet Ini(filename);
MAX_COMMAND=Ini.GetContinueDataNum(index);
COMMAND=(stCommand *)realloc(COMMAND, sizeof(stCommand)*MAX_COMMAND);
for(int i=0; i<MAX_COMMAND; i++)
{
char* str = Ini.ReadData(index, i);
COMMAND[i].Id=atoi(str); //获得指令Id
free( str );
strTemp = Ini.ReadText(index, i);
strcpy( COMMAND[i].Name, strTemp ); //获得指令名字
free(strTemp);
}
return true;
}
//读取全局变量列表
bool CScript::LoadVariableList(char *filename)
{
char *index="全局变量列表";
CIniSet Ini(filename);
MAX_VARIABLE=Ini.GetContinueDataNum( "全局变量列表" );
VARIABLE=(stVariable *)realloc(VARIABLE, sizeof(stVariable)*MAX_VARIABLE);
for(int i=0; i<MAX_VARIABLE; i++)
{
char* str = Ini.ReadData(index, i);
strcpy( VARIABLE[i].Name, str); //获得变量名字
free( str );
VARIABLE[i].SValue=VARIABLE[i].Value=Ini.ReadInt(index, i); //获得变量值
}
return true;
}
//读取进度时候
void CScript::LoadVariable(FILE *fp)
{
int num;
fread(&num, 4, 1, fp);
if( num != MAX_VARIABLE )
{
_FREE( VARIABLE );
}
MAX_VARIABLE=num;
fread(VARIABLE, sizeof(stVariable), MAX_VARIABLE, fp);
}
//存储进度的时候
void CScript::SaveVariable(FILE *fp)
{
fwrite(&MAX_VARIABLE, 4, 1, fp);
fwrite(VARIABLE, sizeof(stVariable), MAX_VARIABLE, fp);
}
//释放
bool CScript::Release()
{
_FREE( COMMAND );
_FREE( VARIABLE );
return true;
}
//返回变量的值
int CScript::GetValue(char *Var)
{
for(int i=0; i<MAX_VARIABLE; i++)
{
if( stricmp(Var, VARIABLE[i].Name)==0 )
{
return VARIABLE[i].Value;
}
}
ShowMessage("Variable [%s] not define!", Var);
return ERROR_DATA; //无此值
}
//设置变量的值
int CScript::SetValue(char *Var, int num)
{
for(int i=0; i<MAX_VARIABLE; i++)
{
if( stricmp(Var, VARIABLE[i].Name)==0 )
{
VARIABLE[i].Value=num;
return 1;
}
}
ShowMessage("Variable [%s] not define!", Var);
return ERROR_DATA; //无此值
}
//改变变量的值(增加)
int CScript::AddValue(char *Var, int num)
{
for(int i=0; i<MAX_VARIABLE; i++)
{
if( stricmp(Var, VARIABLE[i].Name)==0 )
{
VARIABLE[i].Value+=num;
return 1;
}
}
return ERROR_DATA; //无此值
}
//恢复变量的原始值
void CScript::RestoreValue()
{
for(int i=0; i<MAX_VARIABLE; i++)
{
VARIABLE[i].Value=VARIABLE[i].SValue;
}
}
//打开文件并读入
bool CScript::Open(char *filename)
{
strcpy(FileName, filename);
_DELETE( Data );
DataLen=GetFileLength(FileName); //取得文件长度
if( DataLen == -1 )
{
ShowMessage("Can't found file %s", FileName);
return false;
}
Data=new char[DataLen];
//读数据
FILE *fp;
fp=fopen(filename, "rb");
fread(Data, DataLen, 1, fp);
fclose(fp);
//初始化指针
Point=0; //当前指针
Line=Word=0; //当前行列
bInString=false;
return true;
}
//读取一条指令
char *CScript::ReadCommand(int lp)
{
if( lp==-1 )
lp=Point;
//临时变量
char chr;
char *Ret;
int m=0;
Ret=(char *)malloc(DataLen-lp+1);
memset(Ret, 0, DataLen-lp+1);
for(int i=lp; i<DataLen; i++)
{
chr=Data[i];
//注释
if( Data[i] == '/' && Data[i+1] == '/' )//是注释,跳到下一行
{
i+=GotoNextLine(i)-1;
continue;
}
//指令开始
if( chr >= 'a' && chr <= 'z' || chr >= 'A' && chr <= 'Z' )
{
for(int j=i; j<DataLen; j++)
{
chr=Data[j];
if( chr == ';' || chr == '\t' ) //指令结束
{
Point=j; //移动当前指针
return Ret; //返回
}
if( chr == '\r' )
{
Point=j+1; //回车,将当前指针移动到回车的后一个字符
return Ret; //返回
}
Ret[m]=chr; //保存在Ret中
m++; //下一个
}
Point=DataLen-1; //在文件完的时候都没有结束的话,将当前指针移到最后
return Ret;
}
}
Point=DataLen-1; //没有找到指令语句
return Ret;
}
//获取指令名字
char *CScript::GetCommandName(char *CmdStr)
{
int Len=strlen(CmdStr);
int n=0;
char chr;
char *Ret;
Ret=(char *)malloc(Len);
memset(Ret, 0, Len);
for(int i=0; i<Len; i++)
{
chr=CmdStr[i];
//'('表示参数开始,而其他表示该指令没有参数,并且结束
if( chr == '(' || chr == ' ' || chr == '\t' || chr == '\r' || chr == ';' )
{
return Ret; //返回名字
}
Ret[n]=chr; //放到Ret
n++; //下一个
}
return Ret;
}
//取得整形参数
int CScript::GetIntParam(char *CmdStr, int num)
{
int Len=strlen(CmdStr);
int n=0;
char chr;
char *Ret;
Ret=(char *)malloc(Len);
memset(Ret, 0, Len);
//查找参数头
for(int i=0; i<Len; i++)
{
chr=CmdStr[i];
if( chr == '(' ) //参数开始
{
goto _Next;
}
}
//没有找到参数头'('
ShowMessage("Command [%s]'s Param %d not found!", CmdStr, num);
goto _Error;
_Next:
{
int ParamNum=0;
bInString=false;
for(int j=i; j<Len; j++)
{
chr=CmdStr[j];
//第几参数
if( chr == '\"' )
bInString=!bInString;//进入和跳出一个string参数,这里面的所以字符都不与考虑
//ParamNum不会被加加,除非跳出这个string参数
if( IsOperation(chr) )
ParamNum++; //是个分隔符,那么就是下一个参数的开始
//直接数值参数
//要的是这个参数并且是数字
if( ParamNum==num && ( (chr >= '0' && chr <= '9') || chr == '-' ) )
{
for(int k=j; k<Len; k++)
{
chr=CmdStr[k]; //得到这个字符
//如果不是数字也不是负号
if( (chr <'0' || chr > '9') && chr != '-' )
{
//转化成整数
int ret=atoi(Ret);
_FREE(Ret);
return ret;
}
//后面还有数字,放到一起,等到结束的时候转化
Ret[n]=chr;
n++;
}
goto _Error;
}
//变量数值参数
//用$开头的是全局变量
if( ParamNum==num && chr == '$' )
{
for(int k=j; k<Len; k++)
{
chr=CmdStr[k];
//如果是空格,')',或者是分隔符,就返回这个全局变量的值
if( chr == ' ' || chr == ')' || IsOperation(chr) )
{
int ret = GetValue(Ret);
_FREE(Ret);
return ret;
}
//继续
Ret[n]=chr;
n++;
}
ShowMessage("Command [%s]'s Param %d not found!", CmdStr, num);
goto _Error;
}
}
}
_Error:
_FREE(Ret);
return ERROR_DATA;
}
//取得字符串参数
char *CScript::GetStringParam(char *CmdStr, int num)
{
int Len=strlen(CmdStr);
int n=0;
char chr;
char *Ret;
Ret=(char *)malloc(Len);
memset(Ret, 0, Len);
//查找参数头
for(int i=0; i<Len; i++)
{
chr=CmdStr[i];
if( chr == '(' )
{
goto _Next;
}
}
goto _ERROR;
_Next:
{
int ParamNum=0;
bInString=false;
for(int j=i; j<Len; j++)
{
chr=CmdStr[j];
//第几参数
//和上面的函数一样的逻辑
if( chr == '\"' )
bInString=!bInString;
if( IsOperation(chr) )
ParamNum++;
//参数开始
//“开头
if( ParamNum==num && chr == '\"' )
{
//跳过"
for(int k=j+1; k<Len; k++)
{
chr=CmdStr[k];
//查找配对的"
if( chr == '\"' )
return Ret; //找到,返回这个参数,不包括""
Ret[n]=chr;
n++;
}
goto _ERROR;
}
}}
_ERROR:
ShowMessage("Command [%s]'s Param %d not found!", CmdStr, num);
return Ret;
}
//取得变量形参数
char *CScript::GetVariableParam(char *CmdStr, int num)
{
int Len=strlen(CmdStr);
int n=0;
char chr;
char *Ret;
Ret=(char *)malloc(Len);
memset(Ret, 0, Len);
//查找参数头
for(int i=0; i<Len; i++)
{
chr=CmdStr[i];
if( chr == '(' )
{
goto _Next;
}
}
goto _ERROR;
_Next:
{
int ParamNum=0;
bInString=false;
for(int j=i; j<Len; j++)
{
chr=CmdStr[j];
//第几参数
//……………… 一样
if( chr == '\"' )
bInString=!bInString;
if( IsOperation(chr) )
ParamNum++;
//变量数值参数
//以$开头…………看GetIntParam的注释
if( ParamNum==num && chr == '$' )
{
for(int k=j; k<Len; k++)
{
chr=CmdStr[k];
if( chr == ' ' || chr == ')' || IsOperation(chr) )
return Ret;
Ret[n]=chr;
n++;
}
goto _ERROR;
}
}
}
_ERROR:
ShowMessage("Command [%s]'s Param %d not found!", CmdStr, num);
return Ret;
}
//取得某个分隔符
char CScript::GetOperation(char *CmdStr, int num)
{
int Len=strlen(CmdStr);
int n=0;
char chr;
//查找参数头
for(int i=0; i<Len; i++)
{
chr=CmdStr[i];
if( chr == '(' )
{
goto _Next;
}
}
goto _ERROR;
_Next:
{
int ParamNum=0;
bInString=false;
for(int j=i; j<Len; j++)
{
chr=CmdStr[j];
//变量数值参数
//简单多了
if( ParamNum==num && IsOperation(chr) )
{
return chr;
}
//第几参数
//……没有语言了
if( chr == '\"' )
bInString=!bInString;
if( IsOperation(chr) )
ParamNum++;
}
}
_ERROR:
ShowMessage("Command [%s]'s Operation %d not found!", CmdStr, num);
return 0;
}
//某字符是否是分隔符
bool CScript::IsOperation(char chr)
{
//过滤掉string参数中的所有东东
//, = > < ! 都是分隔符
if( !bInString && ( chr == ',' || chr == '=' || chr == '>'
|| chr == '<' || chr == '!' ))
return true;
return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -