summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt2
-rw-r--r--src/map/guild.c113
-rw-r--r--src/map/homunculus.c351
-rw-r--r--src/map/itemdb.c211
-rw-r--r--src/map/mercenary.c214
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;
}