⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 script.cpp

📁 圣剑二完整的游戏代码。附作者写的三篇文章。游戏的开发过程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//********************************************
//	脚本 相关函数
//  创建于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 + -