Issue information

Issue ID
#8427
Status
Confirmed
Severity
None
Started
Garr
Nov 6, 2014 20:41
Last Post
Haru
Dec 20, 2015 16:10
Confirmation
Yes (1)
No (0)

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.