Garr - Nov 6, 2014 20:41
Well, I always thought that like in mob_db/mob_db2 and all such files, entries from pet_db2 would overwrite entries on same monsters within pet_db, but it seems that's not happening. As far as I understood it just copies in all entries from pet_db and pet_db2 disregarding any similar mob IDs, and then the first entry (pet_db one) takes effect over pet_db2 one when it searches for pet index. Is there a chance we'll get same behaviour as the other db/db2 files?
I was able to implement that on my own, but I'm not sure if my way is at all efficient.
Garr - Nov 6, 2014 20:43
Just in case, my curent read_petdb:[code=auto:0]
int read_petdb()
{
char* filename[] = {"pet_db.txt","pet_db2.txt"};
FILE *fp;
int nameid,i,j,k,l;
// Remove any previous scripts in case reloaddb was invoked.
for( j = 0; j < MAX_PET_DB; j++ )
{
if( pet->db[j].pet_script )
{
script->free_code(pet->db[j].pet_script);
pet->db[j].pet_script = NULL;
}
if( pet->db[j].equip_script )
{
script->free_code(pet->db[j].equip_script);
pet->db[j].pet_script = NULL;
}
}
// clear database
memset(pet->db,0,sizeof(pet->db));
j = 0; // entry counter
for( i = 0; i < ARRAYLENGTH(filename); i++ ) {
char line[1024];
int lines, entries;
sprintf(line, "%s/%s", map->db_path, filename[i]);
fp=fopen(line,"r");
if( fp == NULL ) {
if( i == 0 )
ShowError("can't read %s\n",line);
continue;
}
lines = entries = 0;
while( fgets(line, sizeof(line), fp) && j < MAX_PET_DB ) {
char *str[22], *p;
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( k = 0; k < 20; ++k )
{
str[k] = p;
p = strchr(p,',');
if( p == NULL )
break; // comma not found
*p = '\0';
++p;
}
if( p == NULL )
{
ShowError("read_petdb: Insufficient columns in line %d, skipping.\n", lines);
continue;
}
// Pet Script
if( *p != '{' )
{
ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
continue;
}
str[20] = p;
p = strstr(p+1,"},");
if( p == NULL )
{
ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
continue;
}
p[1] = '\0';
p += 2;
// Equip Script
if( *p != '{' )
{
ShowError("read_petdb: Invalid format (Equip Script column) in line %d, skipping.\n", lines);
continue;
}
str[21] = p;
if( (nameid = atoi(str[0])) <= 0 )
continue;
if( !mob->db_checkid(nameid) )
{
ShowWarning("pet_db reading: Invalid mob-class %d, pet not read.\n", nameid);
continue;
}
k = -1;
ARR_FIND( 0, j, l, pet->db[l].class_ == nameid);
if ( l < j ) {
k = j;
j = l;
if( pet->db[j].pet_script ) {
script->free_code(pet->db[j].pet_script);
pet->db[j].pet_script = NULL;
}
if( pet->db[j].equip_script ) {
script->free_code(pet->db[j].equip_script);
pet->db[j].pet_script = NULL;
}
memset(&pet->db[j],0,sizeof(pet->db[j]));
}
pet->db[j].class_ = nameid;
safestrncpy(pet->db[j].name,str[1],NAME_LENGTH);
safestrncpy(pet->db[j].jname,str[2],NAME_LENGTH);
pet->db[j].itemID=atoi(str[3]);
pet->db[j].EggID=atoi(str[4]);
pet->db[j].AcceID=atoi(str[5]);
pet->db[j].FoodID=atoi(str[6]);
pet->db[j].fullness=atoi(str[7]);
pet->db[j].hungry_delay=atoi(str[8])*1000;
pet->db[j].r_hungry=atoi(str[9]);
if( pet->db[j].r_hungry <= 0 )
pet->db[j].r_hungry=1;
pet->db[j].r_full=atoi(str[10]);
pet->db[j].intimate=atoi(str[11]);
pet->db[j].die=atoi(str[12]);
pet->db[j].capture=atoi(str[13]);
pet->db[j].speed=atoi(str[14]);
pet->db[j].s_perfor=(char)atoi(str[15]);
pet->db[j].talk_convert_class=atoi(str[16]);
pet->db[j].attack_rate=atoi(str[17]);
pet->db[j].defence_attack_rate=atoi(str[18]);
pet->db[j].change_target_rate=atoi(str[19]);
pet->db[j].pet_script = NULL;
pet->db[j].equip_script = NULL;
if( *str[20] )
pet->db[j].pet_script = script->parse(str[20], filename[i], lines, 0, NULL);
if( *str[21] )
pet->db[j].equip_script = script->parse(str[21], filename[i], lines, 0, NULL);
if (k != -1) j = k; else j++;
entries++;
}
if( j >= MAX_PET_DB )
ShowWarning("read_petdb: Reached max number of pets [%d]. Remaining pets were not read.\n ", MAX_PET_DB);
fclose(fp);
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' pets in '"CL_WHITE"%s"CL_RESET"'.\n", entries, filename[i]);
}
return 0;
}
[/code]
This post has been edited by
Garr
on Nov 6, 2014 20:43
Dastgir - Nov 7, 2014 5:24
pet_db2.txt is for custom pets (not the pet_db.txt to be overwritten as I think)
would have to wait for haru/Ind to know what is the intended behaviour.
malufett - Nov 7, 2014 5:45
as the code says it will override the entry from 'pet_db.txt'...
this code will find the existing mob id..then the next will the overwriting of data entries..[code=auto:0]
ARR_FIND( 0, j, l, pet->db[l].class_ == nameid);[/code][code=auto:0]
if ( l < j ) { // found existing id
k = j; // temp variable
j = l; // set current entry to the found pet entry
[/code]
:meow:
Haru - Nov 7, 2014 6:03
I don't think it is intended to create two different pets with the same mob_id (especially if you look at the function search_petDB_index, it doesn't seem to expect multiple entries with the same mob id), so it would be better to overwrite entries based on the same mob, rather than creating new ones.
I think we need a more efficient way to do that, than how you suggested, though. Looping through the entire mob_db every time a new entry is inserted, doesn't seem too good.
This post has been edited by
Haru
on Nov 7, 2014 6:04
Garr - Nov 7, 2014 6:47
@malufett Yes, I know, as I said that's MY modified version to check for previously used same mob id. But as I said I don't think that code is in any way efficient, that's why I asked for help here. Unmodified looks currently like this:[code=auto:0]
int read_petdb()
{
char* filename[] = {"pet_db.txt","pet_db2.txt"};
FILE *fp;
int nameid,i,j,k;
// Remove any previous scripts in case reloaddb was invoked.
for( j = 0; j < MAX_PET_DB; j++ )
{
if( pet->db[j].pet_script )
{
script->free_code(pet->db[j].pet_script);
pet->db[j].pet_script = NULL;
}
if( pet->db[j].equip_script )
{
script->free_code(pet->db[j].equip_script);
pet->db[j].pet_script = NULL;
}
}
// clear database
memset(pet->db,0,sizeof(pet->db));
j = 0; // entry counter
for( i = 0; i < ARRAYLENGTH(filename); i++ ) {
char line[1024];
int lines, entries;
sprintf(line, "%s/%s", map->db_path, filename[i]);
fp=fopen(line,"r");
if( fp == NULL ) {
if( i == 0 )
ShowError("can't read %s\n",line);
continue;
}
lines = entries = 0;
while( fgets(line, sizeof(line), fp) && j < MAX_PET_DB ) {
char *str[22], *p;
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( k = 0; k < 20; ++k )
{
str[k] = p;
p = strchr(p,',');
if( p == NULL )
break; // comma not found
*p = '\0';
++p;
}
if( p == NULL )
{
ShowError("read_petdb: Insufficient columns in line %d, skipping.\n", lines);
continue;
}
// Pet Script
if( *p != '{' )
{
ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
continue;
}
str[20] = p;
p = strstr(p+1,"},");
if( p == NULL )
{
ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
continue;
}
p[1] = '\0';
p += 2;
// Equip Script
if( *p != '{' )
{
ShowError("read_petdb: Invalid format (Equip Script column) in line %d, skipping.\n", lines);
continue;
}
str[21] = p;
if( (nameid = atoi(str[0])) <= 0 )
continue;
if( !mob->db_checkid(nameid) )
{
ShowWarning("pet_db reading: Invalid mob-class %d, pet not read.\n", nameid);
continue;
}
pet->db[j].class_ = nameid;
safestrncpy(pet->db[j].name,str[1],NAME_LENGTH);
safestrncpy(pet->db[j].jname,str[2],NAME_LENGTH);
pet->db[j].itemID=atoi(str[3]);
pet->db[j].EggID=atoi(str[4]);
pet->db[j].AcceID=atoi(str[5]);
pet->db[j].FoodID=atoi(str[6]);
pet->db[j].fullness=atoi(str[7]);
pet->db[j].hungry_delay=atoi(str[8])*1000;
pet->db[j].r_hungry=atoi(str[9]);
if( pet->db[j].r_hungry <= 0 )
pet->db[j].r_hungry=1;
pet->db[j].r_full=atoi(str[10]);
pet->db[j].intimate=atoi(str[11]);
pet->db[j].die=atoi(str[12]);
pet->db[j].capture=atoi(str[13]);
pet->db[j].speed=atoi(str[14]);
pet->db[j].s_perfor=(char)atoi(str[15]);
pet->db[j].talk_convert_class=atoi(str[16]);
pet->db[j].attack_rate=atoi(str[17]);
pet->db[j].defence_attack_rate=atoi(str[18]);
pet->db[j].change_target_rate=atoi(str[19]);
pet->db[j].pet_script = NULL;
pet->db[j].equip_script = NULL;
if( *str[20] )
pet->db[j].pet_script = script->parse(str[20], filename[i], lines, 0, NULL);
if( *str[21] )
pet->db[j].equip_script = script->parse(str[21], filename[i], lines, 0, NULL);
j++;
entries++;
}
if( j >= MAX_PET_DB )
ShowWarning("read_petdb: Reached max number of pets [%d]. Remaining pets were not read.\n ", MAX_PET_DB);
fclose(fp);
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' pets in '"CL_WHITE"%s"CL_RESET"'.\n", entries, filename[i]);
}
return 0;
}
[/code]
@Haru Indeed, as it can create tonns of confusion. And I know it's not efficient at all, just nothing else came to mind for a quick fix :(
This post has been edited by
Garr
on Nov 7, 2014 6:51
Garr - Dec 6, 2014 12:46
bump
kyeme - Dec 13, 2015 5:16
Still not fixed?
I don't know how to search commit on github.
Dastgir - Dec 18, 2015 4:51
Not yet fixed
Haru - Dec 20, 2015 16:10
This will get fixed when we convert the Pet DB to libconfig.