chuyiwen_gmsv/magic/magic_base.c
2017-01-18 17:09:08 +09:00

512 lines
13 KiB
C

#include "version.h"
#include <stdio.h>
#include <string.h>
#include "common.h"
#include "buf.h"
#include "configfile.h"
#include "magic_base.h"
#include "magic.h"
static Magic *MAGIC_magic;
static int MAGIC_magicnum;
#ifdef _ATTACK_MAGIC
AttMagic *ATTMAGIC_magic;
int ATTMAGIC_magicnum;
#endif
typedef struct tagMagic_MagicFunctionTable
{
char *functionname; /* 呪術設定ファイルに書く関数の名前 */
MAGIC_CALLFUNC func; /* 実際に呼び出される関数 */
int hash; /* hash */
}MAGIC_MagicFunctionTable;
/* 呪術を増やしたらここに登録する事 */
static MAGIC_MagicFunctionTable MAGIC_functbl[] = {
{ "MAGIC_Recovery", MAGIC_Recovery, 0},
{ "MAGIC_OtherRecovery", MAGIC_OtherRecovery, 0},
{ "MAGIC_FieldAttChange", MAGIC_FieldAttChange, 0},
{ "MAGIC_StatusChange", MAGIC_StatusChange, 0},
{ "MAGIC_MagicDef", MAGIC_MagicDef, 0},
{ "MAGIC_StatusRecovery", MAGIC_StatusRecovery, 0},
{ "MAGIC_Ressurect", MAGIC_Ressurect, 0},
{ "MAGIC_AttReverse", MAGIC_AttReverse, 0},
{ "MAGIC_ResAndDef", MAGIC_ResAndDef, 0},
#ifdef _ATTACK_MAGIC
{ "MAGIC_AttMagic" , MAGIC_AttMagic , 0 },
#endif
#ifdef _OTHER_MAGICSTAUTS
{ "MAGIC_MagicStatusChange", MAGIC_MagicStatusChange, 0},
#endif
#ifdef _ITEM_METAMO
{ "MAGIC_Metamo", MAGIC_Metamo, 0},
#endif
#ifdef _ITEM_ATTSKILLMAGIC
//{ "MAGIC_AttSkill", MAGIC_AttSkill, 0},
#endif
#ifdef _MAGIC_WEAKEN // vincent 精灵:虚弱
{ "MAGIC_Weaken", MAGIC_Weaken, 0},
#endif
#ifdef _MAGIC_DEEPPOISON // vincent 精灵:剧毒
{ "MAGIC_StatusChange2", MAGIC_StatusChange2,0},
#endif
#ifdef _MAGIC_BARRIER // vincent 精灵:魔障
{ "MAGIC_Barrier", MAGIC_Barrier, 0},
#endif
#ifdef _MAGIC_NOCAST // vincent 精灵:沉默
{ "MAGIC_Nocast", MAGIC_Nocast, 0},
#endif
#ifdef _MAGIC_TOCALL // 奔龙阵
{ "MAGIC_ToCallDragon", MAGIC_ToCallDragon, 0},
#endif
};
/*----------------------------------------------------------------------*/
/* 基本チェック,アクセス関係 */
/*----------------------------------------------------------------------*/
INLINE BOOL MAGIC_CHECKINDEX( int index )
{
if( MAGIC_magicnum<=index || index<0 )return FALSE;
return TRUE;
}
/*----------------------------------------------------------------------*/
static INLINE BOOL MAGIC_CHECKINTDATAINDEX( int index)
{
if( MAGIC_DATAINTNUM <= index || index < 0 ) return FALSE;
return TRUE;
}
/*----------------------------------------------------------------------*/
static INLINE BOOL MAGIC_CHECKCHARDATAINDEX( int index)
{
if( MAGIC_DATACHARNUM <= index || index < 0 ) return FALSE;
return TRUE;
}
/*----------------------------------------------------------------------*/
INLINE int MAGIC_getInt( int index, MAGIC_DATAINT element)
{
return MAGIC_magic[index].data[element];
}
/*----------------------------------------------------------------------*/
INLINE int MAGIC_setInt( int index, MAGIC_DATAINT element, int data)
{
int buf;
buf = MAGIC_magic[index].data[element];
MAGIC_magic[index].data[element]=data;
return buf;
}
/*----------------------------------------------------------------------*/
INLINE char* MAGIC_getChar( int index, MAGIC_DATACHAR element)
{
if( !MAGIC_CHECKINDEX( index)) return "\0";
if( !MAGIC_CHECKCHARDATAINDEX( element)) return "\0";
return MAGIC_magic[index].string[element].string;
}
/*----------------------------------------------------------------------*/
INLINE BOOL MAGIC_setChar( int index ,MAGIC_DATACHAR element, char* new )
{
if(!MAGIC_CHECKINDEX(index))return FALSE;
if(!MAGIC_CHECKCHARDATAINDEX(element))return FALSE;
strcpysafe( MAGIC_magic[index].string[element].string,
sizeof(MAGIC_magic[index].string[element].string),
new );
return TRUE;
}
/*----------------------------------------------------------------------
* 魔法の数を知る。
*---------------------------------------------------------------------*/
int MAGIC_getMagicNum( void)
{
return MAGIC_magicnum;
}
/*----------------------------------------------------------------------
* 魔法の設定ファイルを読む
*---------------------------------------------------------------------*/
BOOL MAGIC_initMagic( char *filename)
{
FILE* f;
char line[256];
int linenum=0;
int magic_readlen=0;
int i,j;
int max_magicid =0;
char token[256];
f = fopen(filename,"r");
if( f == NULL ){
print( "文件打开失败\n");
return FALSE;
}
MAGIC_magicnum=0;
/* まず有効な行が何行あるかどうか調べる */
while( fgets( line, sizeof( line ), f ) ){
linenum ++;
if( line[0] == '#' )continue; /* comment */
if( line[0] == '\n' )continue; /* none */
chomp( line );
#ifdef _MAGIC_OPTIMUM // Robin 取出最大MAGIC ID
if( getStringFromIndexWithDelim( line, ",", MAGIC_DATACHARNUM+MAGIC_ID+1,
token, sizeof(token)) == FALSE )
continue;
max_magicid = max( atoi( token), max_magicid);
#endif
MAGIC_magicnum++;
}
#ifdef _MAGIC_OPTIMUM
print("有效魔法:%d 最大魔法:%d ...", MAGIC_magicnum, max_magicid);
MAGIC_magicnum = max_magicid +1;
#endif
if( fseek( f, 0, SEEK_SET ) == -1 ){
fprint( "搜索错误\n" );
fclose(f);
return FALSE;
}
MAGIC_magic = allocateMemory( sizeof(struct tagMagic)
* MAGIC_magicnum );
if( MAGIC_magic == NULL ){
fprint( "无法分配内存 %d\n" ,
sizeof(struct tagMagic)*MAGIC_magicnum);
fclose( f );
return FALSE;
}
/* 初期化*/
for( i = 0; i < MAGIC_magicnum; i ++ ) {
for( j = 0; j < MAGIC_DATAINTNUM; j ++ ) {
MAGIC_setInt( i,j,-1);
}
for( j = 0; j < MAGIC_DATACHARNUM; j ++ ) {
MAGIC_setChar( i,j,"");
}
}
/* また読み直す */
linenum = 0;
while( fgets( line, sizeof( line ), f ) ){
linenum ++;
if( line[0] == '#' )continue; /* comment */
if( line[0] == '\n' )continue; /* none */
chomp( line );
/* 行を整形する */
/* まず tab を " " に置き換える */
replaceString( line, '\t' , ' ' );
/* 先頭のスペースを取る。*/
{
char buf[256];
for( i = 0; i < strlen( line); i ++) {
if( line[i] != ' ' ) {
break;
}
strcpy( buf, &line[i]);
}
if( i != 0 ) {
strcpy( line, buf);
}
}
{
char token[256];
int ret;
#ifdef _MAGIC_OPTIMUM
if( getStringFromIndexWithDelim( line, ",", MAGIC_DATACHARNUM+MAGIC_ID+1,
token, sizeof(token)) == FALSE )
continue;
magic_readlen = atoi( token);
#endif
for( i = 0; i < MAGIC_DATACHARNUM; i ++ ) {
/* 文字列用トークンを見る */
ret = getStringFromIndexWithDelim( line,",",
i + 1,
token,sizeof(token));
if( ret==FALSE ){
fprint("文件语法错误:%s 第%d行\n",filename,linenum);
break;
}
MAGIC_setChar( magic_readlen, i, token);
}
/* 4つ目以降は数値データ */
#define MAGIC_STARTINTNUM 5
for( i = MAGIC_STARTINTNUM; i < MAGIC_DATAINTNUM+MAGIC_STARTINTNUM; i ++ ) {
ret = getStringFromIndexWithDelim( line,",",i,token,
sizeof(token));
#ifdef _ATTACK_MAGIC
if( FALSE == ret )
break;
if( 0 != strlen( token ) )
{
MAGIC_setInt( magic_readlen , i - MAGIC_STARTINTNUM , atoi( token ) );
}
#else
if( ret==FALSE ){
fprint("文件语法错误:%s 第%d行\n",filename,linenum);
break;
}
if( strlen( token) != 0 ) {
MAGIC_setInt( magic_readlen, i - MAGIC_STARTINTNUM, atoi( token));
}
#endif
}
#ifdef _ATTACK_MAGIC
if( i != MAGIC_STARTINTNUM + MAGIC_IDX && i != MAGIC_DATAINTNUM + MAGIC_STARTINTNUM )
continue;
#else
if( i < MAGIC_DATAINTNUM+MAGIC_STARTINTNUM )
continue;
#endif
/* ちょっと不細工だけどこうする */
if( MAGIC_getInt( magic_readlen, MAGIC_TARGET_DEADFLG) == 1 ) {
MAGIC_setInt( magic_readlen, MAGIC_TARGET,
MAGIC_getInt( magic_readlen, MAGIC_TARGET)+100);
}
magic_readlen ++;
}
}
fclose(f);
MAGIC_magicnum = magic_readlen;
print( "有效魔法数是 %d...", MAGIC_magicnum );
/* hash の登録 */
for( i = 0; i < arraysizeof( MAGIC_functbl); i ++ ) {
MAGIC_functbl[i].hash = hashpjw( MAGIC_functbl[i].functionname);
}
return TRUE;
}
/*------------------------------------------------------------------------
* Magicの設定ファイル読み直し
*-----------------------------------------------------------------------*/
BOOL MAGIC_reinitMagic( void )
{
freeMemory( MAGIC_magic);
return( MAGIC_initMagic( getMagicfile()));
}
#ifdef _ATTACK_MAGIC
/*------------------------------------------------------------------------
* AttMagic的初始化
*-----------------------------------------------------------------------*/
BOOL ATTMAGIC_initMagic( char *filename )
{
FILE *file;
// Open file
if( NULL == ( file = fopen( filename , "r" ) ) )
{
ATTMAGIC_magicnum = 0;
ATTMAGIC_magic = NULL;
return TRUE;
}
fseek( file , 0 , SEEK_END );
// Calculate the number of attack magics
ATTMAGIC_magicnum = ftell( file ) / sizeof( struct tagAttMagic );
if( ATTMAGIC_magicnum % 2 )
{
fprint( "打开文件失败\n" );
fclose( file );
return FALSE;
}
fseek( file , 0 , SEEK_SET );
// Allocate memory to attack magics
ATTMAGIC_magic = allocateMemory( sizeof( struct tagAttMagic ) * ATTMAGIC_magicnum );
if( NULL == ATTMAGIC_magic )
{
fprint( "无法分配内存 %d\n" , sizeof( struct tagAttMagic ) * ATTMAGIC_magicnum );
fclose( file );
return FALSE;
}
// Read attack magics information
memset( ATTMAGIC_magic , 0 , sizeof( struct tagAttMagic ) * ATTMAGIC_magicnum );
fread( ATTMAGIC_magic , 1 , sizeof( struct tagAttMagic ) * ATTMAGIC_magicnum , file );
fclose( file );
ATTMAGIC_magicnum = ATTMAGIC_magicnum / 2;
print( "有效的攻击魔法数 %d\n" , ATTMAGIC_magicnum );
return TRUE;
}
/*------------------------------------------------------------------------
* AttMagic的再度初始化
*-----------------------------------------------------------------------*/
BOOL ATTMAGIC_reinitMagic( void )
{
freeMemory( ATTMAGIC_magic );
ATTMAGIC_magicnum = 0;
return ATTMAGIC_initMagic( getAttMagicfileName() );
// return ATTMAGIC_initMagic( getMagicfile() );
}
#endif
/*------------------------------------------------------------------------
* MAGIC_IDから添字を知る関数
* 返り値
* 成功: 添字
* 失敗: -1
*-----------------------------------------------------------------------*/
int MAGIC_getMagicArray( int magicid)
{
#ifdef _MAGIC_OPTIMUM
if( magicid >= 0 && magicid < MAGIC_magicnum)
return magicid;
#else
int i;
for( i = 0; i < MAGIC_magicnum; i ++ ) {
if( MAGIC_magic[i].data[MAGIC_ID] == magicid ) {
return i;
}
}
#endif
return -1;
}
/*------------------------------------------------------------
* 呪術の関数名からポインターを返す
* 引数
* name char* 呪術の名前
* 返り値
* 関数へのポインタ。ない場合にはNULL
------------------------------------------------------------*/
MAGIC_CALLFUNC MAGIC_getMagicFuncPointer(char* name)
{
int i;
int hash; //ttom
//ttom 12/18/2000
if(name==NULL) return NULL;
//ttom
//int hash = hashpjw( name );
hash=hashpjw(name);
for( i = 0 ; i< arraysizeof( MAGIC_functbl) ; i++ ) {
if( MAGIC_functbl[i].hash == hash ) {
if( strcmp( MAGIC_functbl[i].functionname, name ) == 0 ) {
return MAGIC_functbl[i].func;
}
}
}
return NULL;
}
// Nuke start (08/23)
/*
台湾 Nuke さんのチェック。
魔法の効果範囲をチェックする。
Check the validity of the target of a magic.
Return value:
0: Valid
-1: Invalid
*/
int MAGIC_isTargetValid( int magicid, int toindex)
{
int marray;
marray= MAGIC_getMagicArray( magicid);
#ifdef _ATTACK_MAGIC
if( toindex >= 0 && toindex <= 19 )
return 0;
// One side of players
if( 20 == toindex || 21 == toindex )
{
if( MAGIC_TARGET_WHOLEOTHERSIDE == MAGIC_magic[marray].data[MAGIC_TARGET] || MAGIC_TARGET_ALL_ROWS == MAGIC_magic[marray].data[MAGIC_TARGET] )
return 0;
else
return -1;
}
// All players
if( 22 == toindex )
{
if( MAGIC_TARGET_ALL == MAGIC_magic[marray].data[MAGIC_TARGET] )
return 0;
else
return -1;
}
// One row
if( 23 == toindex || 24 == toindex || 25 == toindex || 26 == toindex )
{
if( MAGIC_TARGET_ONE_ROW == MAGIC_magic[marray].data[MAGIC_TARGET] )
return 0;
else
return -1;
}
#else
// Single player
if ((toindex >= 0x0) && (toindex <= 0x13)) return 0;
// All players
if (toindex == 0x16) {
if (MAGIC_magic[marray].data[MAGIC_TARGET] == MAGIC_TARGET_ALL)
return 0; else return -1;
}
// One side of players
if ((toindex == 0x14) || (toindex == 0x15)) {
if (MAGIC_magic[marray].data[MAGIC_TARGET] == MAGIC_TARGET_WHOLEOTHERSIDE)
return 0; else return -1;
}
#endif
// Others: Error
return -1;
}
// Nuke end