Cleaned up mob_readskilldb() a bit (moved row processing to its own function).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13359 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
ultramage 2008-11-08 01:31:08 +00:00
parent cd70b692e7
commit 2016dd0599

View File

@ -3787,15 +3787,12 @@ static int mob_read_randommonster(void)
} }
/*========================================== /*==========================================
* mob_skill_db.txt reading * processes one mob_skill_db entry
* @param last_mob_id ensures that only one error message per mob id is printed
*------------------------------------------*/ *------------------------------------------*/
static int mob_readskilldb(void) static bool mob_parse_row_mobskilldb(char** str, const char* source, int line, int* last_mob_id)
{ {
FILE *fp; static const struct {
char line[1024];
int i,tmp, count;
const struct {
char str[32]; char str[32];
enum MobSkillState id; enum MobSkillState id;
} cond1[] = { } cond1[] = {
@ -3863,62 +3860,26 @@ static int mob_readskilldb(void)
{ "around", MST_AROUND }, { "around", MST_AROUND },
}; };
int x;
const char* filename[] = { "mob_skill_db.txt","mob_skill_db2.txt" };
if( battle_config.mob_skill_rate == 0 ) {
ShowStatus("Mob skill use disabled. Not reading mob skills.\n");
return 0;
}
for( x = 0; x < ARRAYLENGTH(filename); ++x )
{
int last_mob_id = 0;
count = 0;
sprintf(line, "%s/%s", db_path, filename[x]);
fp=fopen(line,"r");
if(fp==NULL){
if(x==0)
ShowError("can't read %s\n",line);
continue;
}
while(fgets(line, sizeof(line), fp))
{
char *sp[20],*p;
int mob_id;
struct mob_skill *ms, gms; struct mob_skill *ms, gms;
int j=0; int mob_id;
int i, j, tmp;
count++; mob_id = atoi(str[0]);
if(line[0] == '/' && line[1] == '/')
continue;
memset(sp,0,sizeof(sp));
for(i=0,p=line;i<18 && p;i++){
sp[i]=p;
if((p=strchr(p,','))!=NULL)
*p++=0;
}
if(i == 0 || (mob_id=atoi(sp[0]))== 0)
continue;
if(i < 18) {
ShowError("mob_skill: Insufficient number of fields for skill at %s, line %d\n", filename[x], count);
continue;
}
if (mob_id > 0 && mob_db(mob_id) == mob_dummy) if (mob_id > 0 && mob_db(mob_id) == mob_dummy)
{ {
if (mob_id != last_mob_id) { if (mob_id != *last_mob_id) {
ShowError("mob_skill: Non existant Mob id %d at %s, line %d\n", mob_id, filename[x], count); ShowError("mob_skill: Non existant Mob id %d at %s, line %d\n", mob_id, source, line);
last_mob_id = mob_id; *last_mob_id = mob_id;
} }
continue; return false;
} }
if( strcmp(sp[1],"clear")==0 ){ if( strcmp(str[1],"clear")==0 ){
if (mob_id < 0) if (mob_id < 0)
continue; return false;
memset(mob_db_data[mob_id]->skill,0,sizeof(struct mob_skill)); memset(mob_db_data[mob_id]->skill,0,sizeof(struct mob_skill));
mob_db_data[mob_id]->maxskill=0; mob_db_data[mob_id]->maxskill=0;
continue; return true;
} }
if (mob_id < 0) if (mob_id < 0)
@ -3927,63 +3888,64 @@ static int mob_readskilldb(void)
ms = &gms; ms = &gms;
} else { } else {
ARR_FIND( 0, MAX_MOBSKILL, i, (ms = &mob_db_data[mob_id]->skill[i])->skill_id == 0 ); ARR_FIND( 0, MAX_MOBSKILL, i, (ms = &mob_db_data[mob_id]->skill[i])->skill_id == 0 );
if( i == MAX_MOBSKILL ) { if( i == MAX_MOBSKILL )
if (mob_id != last_mob_id) { {
ShowError("mob_skill: readdb: too many skills! Line %d in %d[%s]\n", count,mob_id,mob_db_data[mob_id]->sprite); if (mob_id != *last_mob_id) {
last_mob_id = mob_id; ShowError("mob_skill: readdb: too many skills! Line %d in %d[%s]\n", line, mob_id, mob_db_data[mob_id]->sprite);
*last_mob_id = mob_id;
} }
continue; return false;
} }
} }
//State //State
ARR_FIND( 0, ARRAYLENGTH(state), j, strcmp(sp[2],state[j].str) == 0 ); ARR_FIND( 0, ARRAYLENGTH(state), j, strcmp(str[2],state[j].str) == 0 );
if( j < ARRAYLENGTH(state) ) if( j < ARRAYLENGTH(state) )
ms->state = state[j].id; ms->state = state[j].id;
else { else {
ShowWarning("mob_skill: Unrecognized state %s at %s, line %d\n", sp[2], filename[x], count); ShowWarning("mob_skill: Unrecognized state %s at %s, line %d\n", str[2], source, line);
ms->state = MSS_ANY; ms->state = MSS_ANY;
} }
//Skill ID //Skill ID
j=atoi(sp[3]); j=atoi(str[3]);
if (j<=0 || j>MAX_SKILL_DB) //fixed Lupus if (j<=0 || j>MAX_SKILL_DB) //fixed Lupus
{ {
if (mob_id < 0) if (mob_id < 0)
ShowError("Invalid Skill ID (%d) for all mobs\n", j); ShowError("Invalid Skill ID (%d) for all mobs\n", j);
else else
ShowError("Invalid Skill ID (%d) for mob %d (%s)\n", j, mob_id, mob_db_data[mob_id]->sprite); ShowError("Invalid Skill ID (%d) for mob %d (%s)\n", j, mob_id, mob_db_data[mob_id]->sprite);
continue; return false;
} }
ms->skill_id=j; ms->skill_id=j;
//Skill lvl //Skill lvl
j= atoi(sp[4])<=0 ? 1 : atoi(sp[4]); j= atoi(str[4])<=0 ? 1 : atoi(str[4]);
ms->skill_lv= j>battle_config.mob_max_skilllvl ? battle_config.mob_max_skilllvl : j; //we strip max skill level ms->skill_lv= j>battle_config.mob_max_skilllvl ? battle_config.mob_max_skilllvl : j; //we strip max skill level
//Apply battle_config modifiers to rate (permillage) and delay [Skotlex] //Apply battle_config modifiers to rate (permillage) and delay [Skotlex]
tmp = atoi(sp[5]); tmp = atoi(str[5]);
if (battle_config.mob_skill_rate != 100) if (battle_config.mob_skill_rate != 100)
tmp = tmp*battle_config.mob_skill_rate/100; tmp = tmp*battle_config.mob_skill_rate/100;
if (tmp > 10000) if (tmp > 10000)
ms->permillage= 10000; ms->permillage= 10000;
else else
ms->permillage= tmp; ms->permillage= tmp;
ms->casttime=atoi(sp[6]); ms->casttime=atoi(str[6]);
ms->delay=atoi(sp[7]); ms->delay=atoi(str[7]);
if (battle_config.mob_skill_delay != 100) if (battle_config.mob_skill_delay != 100)
ms->delay = ms->delay*battle_config.mob_skill_delay/100; ms->delay = ms->delay*battle_config.mob_skill_delay/100;
if (ms->delay < 0) //time overflow? if (ms->delay < 0) //time overflow?
ms->delay = INT_MAX; ms->delay = INT_MAX;
ms->cancel=atoi(sp[8]); ms->cancel=atoi(str[8]);
if( strcmp(sp[8],"yes")==0 ) ms->cancel=1; if( strcmp(str[8],"yes")==0 ) ms->cancel=1;
//Target //Target
ARR_FIND( 0, ARRAYLENGTH(target), j, strcmp(sp[9],target[j].str) == 0 ); ARR_FIND( 0, ARRAYLENGTH(target), j, strcmp(str[9],target[j].str) == 0 );
if( j < ARRAYLENGTH(target) ) if( j < ARRAYLENGTH(target) )
ms->target = target[j].id; ms->target = target[j].id;
else { else {
ShowWarning("mob_skill: Unrecognized target %s at %s, line %d\n", sp[9], filename[x], count); ShowWarning("mob_skill: Unrecognized target %s at %s, line %d\n", str[9], source, line);
ms->target = MST_TARGET; ms->target = MST_TARGET;
} }
@ -4005,27 +3967,27 @@ static int mob_readskilldb(void)
} }
//Cond1 //Cond1
ARR_FIND( 0, ARRAYLENGTH(cond1), j, strcmp(sp[10],cond1[j].str) == 0 ); ARR_FIND( 0, ARRAYLENGTH(cond1), j, strcmp(str[10],cond1[j].str) == 0 );
if( j < ARRAYLENGTH(cond1) ) if( j < ARRAYLENGTH(cond1) )
ms->cond1 = cond1[j].id; ms->cond1 = cond1[j].id;
else { else {
ShowWarning("mob_skill: Unrecognized condition 1 %s at %s, line %d\n", sp[10], filename[x], count); ShowWarning("mob_skill: Unrecognized condition 1 %s at %s, line %d\n", str[10], source, line);
ms->cond1 = -1; ms->cond1 = -1;
} }
//Cond2 //Cond2
// numeric value // numeric value
ms->cond2 = atoi(sp[11]); ms->cond2 = atoi(str[11]);
// or special constant // or special constant
ARR_FIND( 0, ARRAYLENGTH(cond2), j, strcmp(sp[11],cond2[j].str) == 0 ); ARR_FIND( 0, ARRAYLENGTH(cond2), j, strcmp(str[11],cond2[j].str) == 0 );
if( j < ARRAYLENGTH(cond2) ) if( j < ARRAYLENGTH(cond2) )
ms->cond2 = cond2[j].id; ms->cond2 = cond2[j].id;
ms->val[0]=(int)strtol(sp[12],NULL,0); ms->val[0]=(int)strtol(str[12],NULL,0);
ms->val[1]=(int)strtol(sp[13],NULL,0); ms->val[1]=(int)strtol(str[13],NULL,0);
ms->val[2]=(int)strtol(sp[14],NULL,0); ms->val[2]=(int)strtol(str[14],NULL,0);
ms->val[3]=(int)strtol(sp[15],NULL,0); ms->val[3]=(int)strtol(str[15],NULL,0);
ms->val[4]=(int)strtol(sp[16],NULL,0); ms->val[4]=(int)strtol(str[16],NULL,0);
if(ms->skill_id == NPC_EMOTION && mob_id>0 && if(ms->skill_id == NPC_EMOTION && mob_id>0 &&
ms->val[1] == mob_db(mob_id)->status.mode) ms->val[1] == mob_db(mob_id)->status.mode)
@ -4042,8 +4004,8 @@ static int mob_readskilldb(void)
ms->val[1] = 0; //Do not "set" it. ms->val[1] = 0; //Do not "set" it.
} }
if(sp[17] != NULL && strlen(sp[17])>2) if(str[17] != NULL && strlen(str[17])>2)
ms->emotion=atoi(sp[17]); ms->emotion=atoi(str[17]);
else else
ms->emotion=-1; ms->emotion=-1;
if (mob_id < 0) if (mob_id < 0)
@ -4061,9 +4023,7 @@ static int mob_readskilldb(void)
if (!(mob_id&1)) //Skill not for normal enemies. if (!(mob_id&1)) //Skill not for normal enemies.
continue; continue;
for(j=0;j<MAX_MOBSKILL;j++) ARR_FIND( 0, MAX_MOBSKILL, j, mob_db_data[i]->skill[j].skill_id == 0 );
if( mob_db_data[i]->skill[j].skill_id == 0)
break;
if(j==MAX_MOBSKILL) if(j==MAX_MOBSKILL)
continue; continue;
@ -4072,9 +4032,79 @@ static int mob_readskilldb(void)
} }
} else //Skill set on a single mob. } else //Skill set on a single mob.
mob_db_data[mob_id]->maxskill=i+1; mob_db_data[mob_id]->maxskill=i+1;
return true;
}
/*==========================================
* mob_skill_db.txt reading
*------------------------------------------*/
static int mob_readskilldb(void)
{
const char* filename[] = { "mob_skill_db.txt", "mob_skill_db2.txt" };
int fi;
if( battle_config.mob_skill_rate == 0 )
{
ShowStatus("Mob skill use disabled. Not reading mob skills.\n");
return 0;
}
for( fi = 0; fi < ARRAYLENGTH(filename); ++fi )
{
uint32 lines = 0, count = 0;
char line[1024];
int i;
int tmp = 0;
char path[256];
FILE *fp;
sprintf(path, "%s/%s", db_path, filename[fi]);
fp = fopen(path, "r");
if( fp == NULL )
{
ShowWarning("mob_readskilldb: File not found \"%s\", skipping.\n", path);
continue;
}
// process rows one by one
while(fgets(line, sizeof(line), fp))
{
char *str[20], *p, *np;
int j=0;
lines++;
if(line[0] == '/' && line[1] == '/')
continue;
memset(str, 0, sizeof(str));
p = line;
while( ISSPACE(*p) )
++p;
if( *p == '\0' )
continue;// empty line
for(i = 0; i < 18; i++)
{
str[i] = p;
if((np = strchr(p, ',')) != NULL) {
*np = '\0'; p = np + 1;
}
}
if( i < 18 )
{
ShowError("mob_readskilldb: Insufficient number of fields for skill at %s, line %d\n", filename[fi], lines);
continue;
}
if( !mob_parse_row_mobskilldb(str, path, lines, &tmp) )
continue;
count++;
} }
fclose(fp); fclose(fp);
ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",filename[x]); ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n", filename[fi]);
} }
return 0; return 0;
} }