diff options
-rw-r--r-- | Changelog-Trunk.txt | 2 | ||||
-rw-r--r-- | src/map/guild.c | 113 | ||||
-rw-r--r-- | src/map/homunculus.c | 351 | ||||
-rw-r--r-- | src/map/itemdb.c | 211 | ||||
-rw-r--r-- | src/map/mercenary.c | 214 |
5 files changed, 350 insertions, 541 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index b4949d061..4549e41ca 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -1,6 +1,8 @@ Date Added 2010/12/29 + * Made remaining csv databases (guild, castle, homunculus, itemdb, mercenary) use sv_readdb, where applicable (follow up to r14524, r14526 and r14532). [Ai4rei] + - Few databases remain unchanged, which have either a custom layout or are otherwise incompatible with sv_readdb. * Collection of random insignificant changes. [Ai4rei] - Added progress indication on map-server shutdown when objects are removed from maps, as it takes significant amount of time to complete. - Moved ers_free in db_obj_vclear, so that the node pointer is not used for comparison after it has been freed. diff --git a/src/map/guild.c b/src/map/guild.c index f90fc8946..7b20808d6 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -103,46 +103,34 @@ int guild_checkskill(struct guild *g,int id) /*========================================== * guild_skill_tree.txt reading - from jA [Komurka] *------------------------------------------*/ -int guild_read_guildskill_tree_db(void) -{ - int i,k,id=0,ln=0; - FILE *fp; - char line[1024],*p; +static bool guild_read_guildskill_tree_db(char* split[], int columns, int current) +{// <skill id>,<max lv>,<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5> + int k, id, skillid; - memset(guild_skill_tree,0,sizeof(guild_skill_tree)); - sprintf(line, "%s/guild_skill_tree.txt", db_path); - if( (fp=fopen(line,"r"))==NULL){ - ShowError("can't read %s\n", line); - return -1; + skillid = atoi(split[0]); + id = skillid - GD_SKILLBASE; + + if( id < 0 || id >= MAX_GUILDSKILL ) + { + ShowWarning("guild_read_guildskill_tree_db: Invalid skill id %d.\n", skillid); + return false; + } + + guild_skill_tree[id].id = skillid; + guild_skill_tree[id].max = atoi(split[1]); + + if( guild_skill_tree[id].id == GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[id].max == 0 ) + {// enable guild's glory when required for emblems + guild_skill_tree[id].max = 1; } - while(fgets(line, sizeof(line), fp)) + + for( k = 0; k < 5; k++ ) { - char *split[50]; - if(line[0]=='/' && line[1]=='/') - continue; - for(i=0,p=line;i<12 && p;i++){ - split[i]=p; - p=strchr(p,','); - if(p) *p++=0; - } - if(i<12) - continue; - id = atoi(split[0]) - GD_SKILLBASE; - if(id<0 || id>=MAX_GUILDSKILL) - continue; - guild_skill_tree[id].id=atoi(split[0]); - guild_skill_tree[id].max=atoi(split[1]); - if (guild_skill_tree[id].id==GD_GLORYGUILD && battle_config.require_glory_guild && guild_skill_tree[id].max==0) guild_skill_tree[id].max=1; - for(k=0;k<5;k++){ - guild_skill_tree[id].need[k].id=atoi(split[k*2+2]); - guild_skill_tree[id].need[k].lv=atoi(split[k*2+3]); - } - ln++; + guild_skill_tree[id].need[k].id = atoi(split[k*2+2]); + guild_skill_tree[id].need[k].lv = atoi(split[k*2+3]); } - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"guild_skill_tree.txt"); - return 0; + return true; } /*========================================== @@ -168,51 +156,21 @@ int guild_check_skill_require(struct guild *g,int id) return 1; } -static int guild_read_castledb(void) -{ - FILE *fp; - char line[1024]; - int j,ln=0; - char *str[32],*p; +static bool guild_read_castledb(char* str[], int columns, int current) +{// <castle id>,<map name>,<castle name>,<castle event>[,<reserved/unused switch flag>] struct guild_castle *gc; - sprintf(line, "%s/castle_db.txt", db_path); - if( (fp=fopen(line,"r"))==NULL){ - ShowError("can't read %s\n", line); - return -1; - } - - while(fgets(line, sizeof(line), fp)) - { - if(line[0]=='/' && line[1]=='/') - continue; - memset(str,0,sizeof(str)); - for(j=0,p=line;j<6 && p;j++){ - str[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - if (j < 4) //Insufficient data for castle. [Skotlex] - { - ShowError("castle_db.txt: invalid line '%s'\n", line); - continue; - } - - gc=(struct guild_castle *)aCalloc(1,sizeof(struct guild_castle)); - gc->castle_id=atoi(str[0]); - gc->mapindex = mapindex_name2id(str[1]); - safestrncpy(gc->castle_name,str[2],NAME_LENGTH); - safestrncpy(gc->castle_event,str[3],NAME_LENGTH); + CREATE(gc, struct guild_castle, 1); + gc->castle_id = atoi(str[0]); + gc->mapindex = mapindex_name2id(str[1]); + safestrncpy(gc->castle_name, str[2], sizeof(gc->castle_name)); + safestrncpy(gc->castle_event, str[3], sizeof(gc->castle_event)); - idb_put(castle_db,gc->castle_id,gc); + idb_put(castle_db,gc->castle_id,gc); - //intif_guild_castle_info(gc->castle_id); + //intif_guild_castle_info(gc->castle_id); - ln++; - } - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"castle_db.txt"); - return 0; + return true; } /// lookup: guild id -> guild* @@ -1969,9 +1927,10 @@ void do_init_guild(void) expcache_ers = ers_new(sizeof(struct guild_expcache)); guild_castleinfoevent_db=idb_alloc(DB_OPT_BASE); - guild_read_castledb(); + sv_readdb(db_path, "castle_db.txt", ',', 4, 5, -1, &guild_read_castledb); - guild_read_guildskill_tree_db(); //guild skill tree [Komurka] + memset(guild_skill_tree,0,sizeof(guild_skill_tree)); + sv_readdb(db_path, "guild_skill_tree.txt", ',', 12, 12, -1, &guild_read_guildskill_tree_db); //guild skill tree [Komurka] add_timer_func_list(guild_payexp_timer,"guild_payexp_timer"); add_timer_func_list(guild_send_xy_timer, "guild_send_xy_timer"); diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 0fbd7cbff..4c5717319 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -8,6 +8,7 @@ #include "../common/nullpo.h" #include "../common/mmo.h" #include "../common/showmsg.h" +#include "../common/strlib.h" #include "../common/utils.h" #include "log.h" @@ -876,226 +877,190 @@ int merc_hom_shuffle(struct homun_data *hd) return 1; } +static bool read_homunculusdb_sub(char* str[], int columns, int current) +{ + int classid; + struct s_homunculus_db *db; + + //Base Class,Evo Class + classid = atoi(str[0]); + if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX) + { + ShowError("read_homunculusdb : Invalid class %d\n", classid); + return false; + } + db = &homunculus_db[current]; + db->base_class = classid; + classid = atoi(str[1]); + if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX) + { + db->base_class = 0; + ShowError("read_homunculusdb : Invalid class %d\n", classid); + return false; + } + db->evo_class = classid; + //Name, Food, Hungry Delay, Base Size, Evo Size, Race, Element, ASPD + strncpy(db->name,str[2],NAME_LENGTH-1); + db->foodID = atoi(str[3]); + db->hungryDelay = atoi(str[4]); + db->base_size = atoi(str[5]); + db->evo_size = atoi(str[6]); + db->race = atoi(str[7]); + db->element = atoi(str[8]); + db->baseASPD = atoi(str[9]); + //base HP, SP, str, agi, vit, int, dex, luk + db->base.HP = atoi(str[10]); + db->base.SP = atoi(str[11]); + db->base.str = atoi(str[12]); + db->base.agi = atoi(str[13]); + db->base.vit = atoi(str[14]); + db->base.int_= atoi(str[15]); + db->base.dex = atoi(str[16]); + db->base.luk = atoi(str[17]); + //Growth Min/Max HP, SP, str, agi, vit, int, dex, luk + db->gmin.HP = atoi(str[18]); + db->gmax.HP = atoi(str[19]); + db->gmin.SP = atoi(str[20]); + db->gmax.SP = atoi(str[21]); + db->gmin.str = atoi(str[22]); + db->gmax.str = atoi(str[23]); + db->gmin.agi = atoi(str[24]); + db->gmax.agi = atoi(str[25]); + db->gmin.vit = atoi(str[26]); + db->gmax.vit = atoi(str[27]); + db->gmin.int_= atoi(str[28]); + db->gmax.int_= atoi(str[29]); + db->gmin.dex = atoi(str[30]); + db->gmax.dex = atoi(str[31]); + db->gmin.luk = atoi(str[32]); + db->gmax.luk = atoi(str[33]); + //Evolution Min/Max HP, SP, str, agi, vit, int, dex, luk + db->emin.HP = atoi(str[34]); + db->emax.HP = atoi(str[35]); + db->emin.SP = atoi(str[36]); + db->emax.SP = atoi(str[37]); + db->emin.str = atoi(str[38]); + db->emax.str = atoi(str[39]); + db->emin.agi = atoi(str[40]); + db->emax.agi = atoi(str[41]); + db->emin.vit = atoi(str[42]); + db->emax.vit = atoi(str[43]); + db->emin.int_= atoi(str[44]); + db->emax.int_= atoi(str[45]); + db->emin.dex = atoi(str[46]); + db->emax.dex = atoi(str[47]); + db->emin.luk = atoi(str[48]); + db->emax.luk = atoi(str[49]); + + //Check that the min/max values really are below the other one. + if(db->gmin.HP > db->gmax.HP) + db->gmin.HP = db->gmax.HP; + if(db->gmin.SP > db->gmax.SP) + db->gmin.SP = db->gmax.SP; + if(db->gmin.str > db->gmax.str) + db->gmin.str = db->gmax.str; + if(db->gmin.agi > db->gmax.agi) + db->gmin.agi = db->gmax.agi; + if(db->gmin.vit > db->gmax.vit) + db->gmin.vit = db->gmax.vit; + if(db->gmin.int_> db->gmax.int_) + db->gmin.int_= db->gmax.int_; + if(db->gmin.dex > db->gmax.dex) + db->gmin.dex = db->gmax.dex; + if(db->gmin.luk > db->gmax.luk) + db->gmin.luk = db->gmax.luk; + + if(db->emin.HP > db->emax.HP) + db->emin.HP = db->emax.HP; + if(db->emin.SP > db->emax.SP) + db->emin.SP = db->emax.SP; + if(db->emin.str > db->emax.str) + db->emin.str = db->emax.str; + if(db->emin.agi > db->emax.agi) + db->emin.agi = db->emax.agi; + if(db->emin.vit > db->emax.vit) + db->emin.vit = db->emax.vit; + if(db->emin.int_> db->emax.int_) + db->emin.int_= db->emax.int_; + if(db->emin.dex > db->emax.dex) + db->emin.dex = db->emax.dex; + if(db->emin.luk > db->emax.luk) + db->emin.luk = db->emax.luk; + + return true; +} + int read_homunculusdb(void) { - FILE *fp; - char line[1024], *p; - int i, k, classid; - int j = 0; + int i; const char *filename[]={"homunculus_db.txt","homunculus_db2.txt"}; - char *str[50]; - struct s_homunculus_db *db; memset(homunculus_db,0,sizeof(homunculus_db)); - for(i = 0; i<2; i++) + for(i = 0; i<ARRAYLENGTH(filename); i++) { - sprintf(line, "%s/%s", db_path, filename[i]); - fp = fopen(line,"r"); - if(!fp){ - if(i != 0) - continue; - ShowError("read_homunculusdb : can't read %s\n", line); - return -1; - } + char path[256]; - while(fgets(line, sizeof(line), fp) && j < MAX_HOMUNCULUS_CLASS) + if( i > 0 ) { - if(line[0] == '/' && line[1] == '/') - continue; + sprintf(path, "%s/%s", db_path, filename[i]); - k = 0; - p = strtok (line,","); - while (p != NULL && k < 50) - { - str[k++] = p; - p = strtok (NULL, ","); - } - if (k < 50 ) - { - ShowError("read_homunculusdb : Incorrect number of columns at %s, homunculus %d. Read %d columns, 50 are needed.\n", filename[i], j+1, k); - continue; - } - - //Base Class,Evo Class - classid = atoi(str[0]); - if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX) - { - ShowError("read_homunculusdb : Invalid class %d (%s)\n", classid, filename[i]); - continue; - } - db = &homunculus_db[j]; - db->base_class = classid; - classid = atoi(str[1]); - if (classid < HM_CLASS_BASE || classid > HM_CLASS_MAX) + if( !exists(path) ) { - db->base_class = 0; - ShowError("read_homunculusdb : Invalid class %d (%s)\n", classid, filename[i]); continue; } - db->evo_class = classid; - //Name, Food, Hungry Delay, Base Size, Evo Size, Race, Element, ASPD - strncpy(db->name,str[2],NAME_LENGTH-1); - db->foodID = atoi(str[3]); - db->hungryDelay = atoi(str[4]); - db->base_size = atoi(str[5]); - db->evo_size = atoi(str[6]); - db->race = atoi(str[7]); - db->element = atoi(str[8]); - db->baseASPD = atoi(str[9]); - //base HP, SP, str, agi, vit, int, dex, luk - db->base.HP = atoi(str[10]); - db->base.SP = atoi(str[11]); - db->base.str = atoi(str[12]); - db->base.agi = atoi(str[13]); - db->base.vit = atoi(str[14]); - db->base.int_= atoi(str[15]); - db->base.dex = atoi(str[16]); - db->base.luk = atoi(str[17]); - //Growth Min/Max HP, SP, str, agi, vit, int, dex, luk - db->gmin.HP = atoi(str[18]); - db->gmax.HP = atoi(str[19]); - db->gmin.SP = atoi(str[20]); - db->gmax.SP = atoi(str[21]); - db->gmin.str = atoi(str[22]); - db->gmax.str = atoi(str[23]); - db->gmin.agi = atoi(str[24]); - db->gmax.agi = atoi(str[25]); - db->gmin.vit = atoi(str[26]); - db->gmax.vit = atoi(str[27]); - db->gmin.int_= atoi(str[28]); - db->gmax.int_= atoi(str[29]); - db->gmin.dex = atoi(str[30]); - db->gmax.dex = atoi(str[31]); - db->gmin.luk = atoi(str[32]); - db->gmax.luk = atoi(str[33]); - //Evolution Min/Max HP, SP, str, agi, vit, int, dex, luk - db->emin.HP = atoi(str[34]); - db->emax.HP = atoi(str[35]); - db->emin.SP = atoi(str[36]); - db->emax.SP = atoi(str[37]); - db->emin.str = atoi(str[38]); - db->emax.str = atoi(str[39]); - db->emin.agi = atoi(str[40]); - db->emax.agi = atoi(str[41]); - db->emin.vit = atoi(str[42]); - db->emax.vit = atoi(str[43]); - db->emin.int_= atoi(str[44]); - db->emax.int_= atoi(str[45]); - db->emin.dex = atoi(str[46]); - db->emax.dex = atoi(str[47]); - db->emin.luk = atoi(str[48]); - db->emax.luk = atoi(str[49]); - - //Check that the min/max values really are below the other one. - if(db->gmin.HP > db->gmax.HP) - db->gmin.HP = db->gmax.HP; - if(db->gmin.SP > db->gmax.SP) - db->gmin.SP = db->gmax.SP; - if(db->gmin.str > db->gmax.str) - db->gmin.str = db->gmax.str; - if(db->gmin.agi > db->gmax.agi) - db->gmin.agi = db->gmax.agi; - if(db->gmin.vit > db->gmax.vit) - db->gmin.vit = db->gmax.vit; - if(db->gmin.int_> db->gmax.int_) - db->gmin.int_= db->gmax.int_; - if(db->gmin.dex > db->gmax.dex) - db->gmin.dex = db->gmax.dex; - if(db->gmin.luk > db->gmax.luk) - db->gmin.luk = db->gmax.luk; - - if(db->emin.HP > db->emax.HP) - db->emin.HP = db->emax.HP; - if(db->emin.SP > db->emax.SP) - db->emin.SP = db->emax.SP; - if(db->emin.str > db->emax.str) - db->emin.str = db->emax.str; - if(db->emin.agi > db->emax.agi) - db->emin.agi = db->emax.agi; - if(db->emin.vit > db->emax.vit) - db->emin.vit = db->emax.vit; - if(db->emin.int_> db->emax.int_) - db->emin.int_= db->emax.int_; - if(db->emin.dex > db->emax.dex) - db->emin.dex = db->emax.dex; - if(db->emin.luk > db->emax.luk) - db->emin.luk = db->emax.luk; - - j++; } - if (j > MAX_HOMUNCULUS_CLASS) - ShowWarning("read_homunculusdb: Reached max number of homunculus [%d]. Remaining homunculus were not read.\n ", MAX_HOMUNCULUS_CLASS); - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' homunculus in '"CL_WHITE"db/%s"CL_RESET"'.\n",j,filename[i]); + + sv_readdb(db_path, filename[i], ',', 50, 50, MAX_HOMUNCULUS_CLASS, &read_homunculusdb_sub); } + return 0; } -int read_homunculus_skilldb(void) -{ - FILE *fp; - char line[1024], *p; +static bool read_homunculus_skilldb_sub(char* split[], int columns, int current) +{// <hom class>,<skill id>,<max level>[,<job level>],<req id1>,<req lv1>,<req id2>,<req lv2>,<req id3>,<req lv3>,<req id4>,<req lv4>,<req id5>,<req lv5> int k, classid; - int j = 0; - char *split[15]; + int j; + int minJobLevelPresent = 0; - memset(hskill_tree,0,sizeof(hskill_tree)); - sprintf(line, "%s/homun_skill_tree.txt", db_path); - fp=fopen(line,"r"); - if(fp==NULL){ - ShowError("can't read %s\n", line); - return 1; - } + if( columns == 14 ) + minJobLevelPresent = 1; // MinJobLvl has been added - while(fgets(line, sizeof(line), fp)) + // check for bounds [celest] + classid = atoi(split[0]) - HM_CLASS_BASE; + if ( classid >= MAX_HOMUNCULUS_CLASS ) { - int minJobLevelPresent = 0; - - if(line[0]=='/' && line[1]=='/') - continue; - - k = 0; - p = strtok(line,","); - while (p != NULL && k < 15) - { - split[k++] = p; - p = strtok(NULL, ","); - } - - if(k < 13) - continue; - - if (k == 14) - minJobLevelPresent = 1; // MinJobLvl has been added + ShowWarning("read_homunculus_skilldb: Invalud homunculus class %d.\n", atoi(split[0])); + return false; + } - // check for bounds [celest] - classid = atoi(split[0]) - HM_CLASS_BASE; - if ( classid >= MAX_HOMUNCULUS_CLASS ) - continue; + k = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex] + // Search an empty line or a line with the same skill_id (stored in j) + ARR_FIND( 0, MAX_SKILL_TREE, j, !hskill_tree[classid][j].id || hskill_tree[classid][j].id == k ); + if (j == MAX_SKILL_TREE) + { + ShowWarning("Unable to load skill %d into homunculus %d's tree. Maximum number of skills per class has been reached.\n", k, classid); + return false; + } - k = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex] - // Search an empty line or a line with the same skill_id (stored in j) - for(j = 0; j < MAX_SKILL_TREE && hskill_tree[classid][j].id && hskill_tree[classid][j].id != k; j++); + hskill_tree[classid][j].id = k; + hskill_tree[classid][j].max = atoi(split[2]); + if (minJobLevelPresent) + hskill_tree[classid][j].joblv = atoi(split[3]); - if (j == MAX_SKILL_TREE) - { - ShowWarning("Unable to load skill %d into homunculus %d's tree. Maximum number of skills per class has been reached.\n", k, classid); - continue; - } + for( k = 0; k < MAX_PC_SKILL_REQUIRE; k++ ) + { + hskill_tree[classid][j].need[k].id = atoi(split[3+k*2+minJobLevelPresent]); + hskill_tree[classid][j].need[k].lv = atoi(split[3+k*2+minJobLevelPresent+1]); + } - hskill_tree[classid][j].id=k; - hskill_tree[classid][j].max=atoi(split[2]); - if (minJobLevelPresent) - hskill_tree[classid][j].joblv=atoi(split[3]); + return true; +} - for(k=0;k<MAX_PC_SKILL_REQUIRE;k++){ - hskill_tree[classid][j].need[k].id=atoi(split[3+k*2+minJobLevelPresent]); - hskill_tree[classid][j].need[k].lv=atoi(split[3+k*2+minJobLevelPresent+1]); - } - } +int read_homunculus_skilldb(void) +{ + memset(hskill_tree,0,sizeof(hskill_tree)); + sv_readdb(db_path, "homun_skill_tree.txt", ',', 13, 14, -1, &read_homunculus_skilldb_sub); - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","homun_skill_tree.txt"); return 0; } diff --git a/src/map/itemdb.c b/src/map/itemdb.c index ce10f4f39..98f9a90d1 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -471,46 +471,32 @@ int itemdb_isidentified(int nameid) /*========================================== * アイテム使用可能フラグのオーバーライド *------------------------------------------*/ -static int itemdb_read_itemavail (void) -{ - FILE *fp; - int nameid, j, k, ln = 0; - char line[1024], *str[10], *p; +static bool itemdb_read_itemavail(char* str[], int columns, int current) +{// <nameid>,<sprite> + int nameid, sprite; struct item_data *id; - sprintf(line, "%s/item_avail.txt", db_path); - if ((fp = fopen(line,"r")) == NULL) { - ShowError("can't read %s\n", line); - return -1; - } + nameid = atoi(str[0]); - while(fgets(line, sizeof(line), fp)) + if( ( id = itemdb_exists(nameid) ) == NULL ) { - if (line[0] == '/' && line[1] == '/') - continue; - memset(str, 0, sizeof(str)); - for (j = 0, p = line; j < 2 && p; j++) { - str[j] = p; - p = strchr(p, ','); - if(p) *p++ = 0; - } + ShowWarning("itemdb_read_itemavail: Invalid item id %d.\n", nameid); + return false; + } - if (j < 2 || str[0] == NULL || - (nameid = atoi(str[0])) < 0 || !(id = itemdb_exists(nameid))) - continue; + sprite = atoi(str[1]); - k = atoi(str[1]); - if (k > 0) { - id->flag.available = 1; - id->view_id = k; - } else - id->flag.available = 0; - ln++; + if( sprite > 0 ) + { + id->flag.available = 1; + id->view_id = sprite; + } + else + { + id->flag.available = 0; } - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, "item_avail.txt"); - return 0; + return true; } /*========================================== @@ -591,137 +577,90 @@ static void itemdb_read_itemgroup(void) /*========================================== * 装備制限ファイル読み出し *------------------------------------------*/ -static int itemdb_read_noequip(void) -{ - FILE *fp; - char line[1024]; - int ln=0; - int nameid,j; - char *str[32],*p; +static bool itemdb_read_noequip(char* str[], int columns, int current) +{// <nameid>,<mode> + int nameid; struct item_data *id; - sprintf(line, "%s/item_noequip.txt", db_path); - if( (fp=fopen(line,"r"))==NULL ){ - ShowError("can't read %s\n", line); - return -1; - } - while(fgets(line, sizeof(line), fp)) - { - if(line[0]=='/' && line[1]=='/') - continue; - memset(str,0,sizeof(str)); - for(j=0,p=line;j<2 && p;j++){ - str[j]=p; - p=strchr(p,','); - if(p) *p++=0; - } - if(str[0]==NULL) - continue; - - nameid=atoi(str[0]); - if(nameid<=0 || !(id=itemdb_exists(nameid))) - continue; + nameid = atoi(str[0]); - id->flag.no_equip |= atoi(str[1]); + if( ( id = itemdb_exists(nameid) ) == NULL ) + { + ShowWarning("itemdb_read_noequip: Invalid item id %d.\n", nameid); + return false; + } - ln++; + id->flag.no_equip |= atoi(str[1]); - } - fclose(fp); - if (ln > 0) { - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"item_noequip.txt"); - } - return 0; + return true; } /*========================================== * Reads item trade restrictions [Skotlex] *------------------------------------------*/ -static int itemdb_read_itemtrade(void) -{ - FILE *fp; - int nameid, j, flag, gmlv, ln = 0; - char line[1024], *str[10], *p; +static bool itemdb_read_itemtrade(char* str[], int columns, int current) +{// <nameid>,<mask>,<gm level> + int nameid, flag, gmlv; struct item_data *id; - sprintf(line, "%s/item_trade.txt", db_path); - if ((fp = fopen(line,"r")) == NULL) { - ShowError("can't read %s\n", line); - return -1; - } + nameid = atoi(str[0]); - while(fgets(line, sizeof(line), fp)) + if( ( id = itemdb_exists(nameid) ) == NULL ) { - if (line[0] == '/' && line[1] == '/') - continue; - memset(str, 0, sizeof(str)); - for (j = 0, p = line; j < 3 && p; j++) { - str[j] = p; - p = strchr(p, ','); - if(p) *p++ = 0; - } + //ShowWarning("itemdb_read_itemtrade: Invalid item id %d.\n", nameid); + //return false; + // FIXME: item_trade.txt contains items, which are commented in item database. + return true; + } - if (j < 3 || str[0] == NULL || - (nameid = atoi(str[0])) < 0 || !(id = itemdb_exists(nameid))) - continue; + flag = atoi(str[1]); + gmlv = atoi(str[2]); - flag = atoi(str[1]); - gmlv = atoi(str[2]); - - if (flag > 0 && flag < 128 && gmlv > 0) { //Check range - id->flag.trade_restriction = flag; - id->gm_lv_trade_override = gmlv; - ln++; - } + if( flag < 0 || flag >= 128 ) + {//Check range + ShowWarning("itemdb_read_itemtrade: Invalid trading mask %d for item id %d.\n", flag, nameid); + return false; } - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, "item_trade.txt"); - return 0; + if( gmlv < 1 ) + { + ShowWarning("itemdb_read_itemtrade: Invalid override GM level %d for item id %d.\n", gmlv, nameid); + return false; + } + + id->flag.trade_restriction = flag; + id->gm_lv_trade_override = gmlv; + + return true; } /*========================================== * Reads item delay amounts [Paradox924X] *------------------------------------------*/ -static int itemdb_read_itemdelay(void) -{ - FILE *fp; - int nameid, j, item_delays = 0; - char line[1024], *str[10], *p; +static bool itemdb_read_itemdelay(char* str[], int columns, int current) +{// <nameid>,<delay> + int nameid, delay; struct item_data *id; - sprintf(line, "%s/item_delay.txt", db_path); - if ((fp = fopen(line,"r")) == NULL) { - ShowError("can't read %s\n", line); - return -1; - } + nameid = atoi(str[0]); - while(fgets(line, sizeof(line), fp)) + if( ( id = itemdb_exists(nameid) ) == NULL ) { - if (line[0] == '/' && line[1] == '/') - continue; - if (item_delays == MAX_ITEMDELAYS) { - ShowError("itemdb_read_itemdelay: Too many entries specified in %s/item_delay.txt! Increase MAX_ITEMDELAYS in itemdb.h!\n", db_path); - break; - } - memset(str, 0, sizeof(str)); - for (j = 0, p = line; j < 2 && p; j++) { - str[j] = p; - p = strchr(p, ','); - if(p) *p++ = 0; - } + ShowWarning("itemdb_read_itemdelay: Invalid item id %d.\n", nameid); + return false; + } - if (j < 2 || str[0] == NULL || - (nameid = atoi(str[0])) < 0 || !(id = itemdb_exists(nameid))) - continue; + delay = atoi(str[1]); - id->delay = atoi(str[1]); - item_delays++; + if( delay < 0 ) + { + ShowWarning("itemdb_read_itemdelay: Invalid delay %d for item id %d.\n", id->delay, nameid); + return false; } - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", item_delays, "item_delay.txt"); - return 0; + id->delay = delay; + + return true; } /*====================================== @@ -1036,10 +975,10 @@ static void itemdb_read(void) itemdb_readdb(); itemdb_read_itemgroup(); - itemdb_read_itemavail(); - itemdb_read_noequip(); - itemdb_read_itemtrade(); - itemdb_read_itemdelay(); + sv_readdb(db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail); + sv_readdb(db_path, "item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip); + sv_readdb(db_path, "item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade); + sv_readdb(db_path, "item_delay.txt", ',', 2, 2, MAX_ITEMDELAYS, &itemdb_read_itemdelay); } /*========================================== diff --git a/src/map/mercenary.c b/src/map/mercenary.c index 79bec2da6..2cf729e80 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -8,6 +8,7 @@ #include "../common/nullpo.h" #include "../common/mmo.h" #include "../common/showmsg.h" +#include "../common/strlib.h" #include "../common/utils.h" #include "log.h" @@ -402,162 +403,105 @@ int mercenary_checkskill(struct mercenary_data *md, int skill_id) return 0; } -int read_mercenarydb(void) +static bool read_mercenarydb_sub(char* str[], int columns, int current) { - FILE *fp; - char line[1024], *p; - char *str[26]; - int i, j = 0, k = 0, ele; + int ele; struct s_mercenary_db *db; struct status_data *status; - sprintf(line, "%s/%s", db_path, "mercenary_db.txt"); - memset(mercenary_db,0,sizeof(mercenary_db)); - - fp = fopen(line, "r"); - if( !fp ) + db = &mercenary_db[current]; + db->class_ = atoi(str[0]); + strncpy(db->sprite, str[1], NAME_LENGTH); + strncpy(db->name, str[2], NAME_LENGTH); + db->lv = atoi(str[3]); + + status = &db->status; + db->vd.class_ = db->class_; + + status->max_hp = atoi(str[4]); + status->max_sp = atoi(str[5]); + status->rhw.range = atoi(str[6]); + status->rhw.atk = atoi(str[7]); + status->rhw.atk2 = status->rhw.atk + atoi(str[8]); + status->def = atoi(str[9]); + status->mdef = atoi(str[10]); + status->str = atoi(str[11]); + status->agi = atoi(str[12]); + status->vit = atoi(str[13]); + status->int_ = atoi(str[14]); + status->dex = atoi(str[15]); + status->luk = atoi(str[16]); + db->range2 = atoi(str[17]); + db->range3 = atoi(str[18]); + status->size = atoi(str[19]); + status->race = atoi(str[20]); + + ele = atoi(str[21]); + status->def_ele = ele%10; + status->ele_lv = ele/20; + if( status->def_ele >= ELE_MAX ) { - ShowError("read_mercenarydb : can't read mercenary_db.txt\n"); - return -1; + ShowWarning("Mercenary %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1); + status->def_ele = ELE_NEUTRAL; } - - while( fgets(line, sizeof(line), fp) && j < MAX_MERCENARY_CLASS ) + if( status->ele_lv < 1 || status->ele_lv > 4 ) { - k++; - if( line[0] == '/' && line[1] == '/' ) - continue; - - i = 0; - p = strtok(line, ","); - while( p != NULL && i < 26 ) - { - str[i++] = p; - p = strtok(NULL, ","); - } - if( i < 26 ) - { - ShowError("read_mercenarydb : Incorrect number of columns at mercenary_db.txt line %d.\n", k); - continue; - } - - db = &mercenary_db[j]; - db->class_ = atoi(str[0]); - strncpy(db->sprite, str[1], NAME_LENGTH); - strncpy(db->name, str[2], NAME_LENGTH); - db->lv = atoi(str[3]); - - status = &db->status; - db->vd.class_ = db->class_; - - status->max_hp = atoi(str[4]); - status->max_sp = atoi(str[5]); - status->rhw.range = atoi(str[6]); - status->rhw.atk = atoi(str[7]); - status->rhw.atk2 = status->rhw.atk + atoi(str[8]); - status->def = atoi(str[9]); - status->mdef = atoi(str[10]); - status->str = atoi(str[11]); - status->agi = atoi(str[12]); - status->vit = atoi(str[13]); - status->int_ = atoi(str[14]); - status->dex = atoi(str[15]); - status->luk = atoi(str[16]); - db->range2 = atoi(str[17]); - db->range3 = atoi(str[18]); - status->size = atoi(str[19]); - status->race = atoi(str[20]); - - ele = atoi(str[21]); - status->def_ele = ele%10; - status->ele_lv = ele/20; - if( status->def_ele >= ELE_MAX ) - { - ShowWarning("Mercenary %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1); - status->def_ele = ELE_NEUTRAL; - } - if( status->ele_lv < 1 || status->ele_lv > 4 ) - { - ShowWarning("Mercenary %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv); - status->ele_lv = 1; - } - - status->aspd_rate = 1000; - status->speed = atoi(str[22]); - status->adelay = atoi(str[23]); - status->amotion = atoi(str[24]); - status->dmotion = atoi(str[25]); - - j++; + ShowWarning("Mercenary %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv); + status->ele_lv = 1; } - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' mercenaries in '"CL_WHITE"db/mercenary_db.txt"CL_RESET"'.\n",j); + status->aspd_rate = 1000; + status->speed = atoi(str[22]); + status->adelay = atoi(str[23]); + status->amotion = atoi(str[24]); + status->dmotion = atoi(str[25]); - return 0; + return true; } -int read_mercenary_skilldb(void) +int read_mercenarydb(void) { - FILE *fp; - char line[1024], *p; - char *str[3]; + memset(mercenary_db,0,sizeof(mercenary_db)); + sv_readdb(db_path, "mercenary_db.txt", ',', 26, 26, MAX_MERCENARY_CLASS, &read_mercenarydb_sub); + + return 0; +} + +static bool read_mercenary_skilldb_sub(char* str[], int columns, int current) +{// <merc id>,<skill id>,<skill level> struct s_mercenary_db *db; - int i, j = 0, k = 0, class_; + int i, class_; int skillid, skilllv; - sprintf(line, "%s/%s", db_path, "mercenary_skill_db.txt"); - fp = fopen(line, "r"); - if( !fp ) + class_ = atoi(str[0]); + ARR_FIND(0, MAX_MERCENARY_CLASS, i, class_ == mercenary_db[i].class_); + if( i == MAX_MERCENARY_CLASS ) { - ShowError("read_mercenary_skilldb : can't read mercenary_skill_db.txt\n"); - return -1; + ShowError("read_mercenary_skilldb : Class %d not found in mercenary_db for skill entry.\n", class_); + return false; } - - while( fgets(line, sizeof(line), fp) ) + + skillid = atoi(str[1]); + if( skillid < MC_SKILLBASE || skillid >= MC_SKILLBASE + MAX_MERCSKILL ) { - k++; - if( line[0] == '/' && line[1] == '/' ) - continue; - - i = 0; - p = strtok(line, ","); - while( p != NULL && i < 3 ) - { - str[i++] = p; - p = strtok(NULL, ","); - } - if( i < 3 ) - { - ShowError("read_mercenary_skilldb : Incorrect number of columns at mercenary_skill_db.txt line %d.\n", k); - continue; - } - - class_ = atoi(str[0]); - ARR_FIND(0, MAX_MERCENARY_CLASS, i, class_ == mercenary_db[i].class_); - if( i == MAX_MERCENARY_CLASS ) - { - ShowError("read_mercenary_skilldb : Class not found in mercenary_db for skill entry, line %d.\n", k); - continue; - } - - skillid = atoi(str[1]); - if( skillid < MC_SKILLBASE || skillid >= MC_SKILLBASE + MAX_MERCSKILL ) - { - ShowError("read_mercenary_skilldb : Skill out of range, line %d.\n", k); - continue; - } - - db = &mercenary_db[i]; - skilllv = atoi(str[2]); - - i = skillid - MC_SKILLBASE; - db->skill[i].id = skillid; - db->skill[i].lv = skilllv; - j++; + ShowError("read_mercenary_skilldb : Skill %d out of range.\n", skillid); + return false; } - fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"db/mercenary_skill_db.txt"CL_RESET"'.\n",j); + db = &mercenary_db[i]; + skilllv = atoi(str[2]); + + i = skillid - MC_SKILLBASE; + db->skill[i].id = skillid; + db->skill[i].lv = skilllv; + + return true; +} + +int read_mercenary_skilldb(void) +{ + sv_readdb(db_path, "mercenary_skill_db.txt", ',', 3, 3, -1, &read_mercenary_skilldb_sub); + return 0; } |