From 7f4a7ba26f8cfd8f929ddc2402f774c7b7294c82 Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Fri, 23 May 2014 01:49:49 +0700 Subject: [PATCH 1/2] * Changed itemgroup from array to DBMap * Removed MAX_ITEMGROUP limit * Changed player bonus fixed array * Minor changes Signed-off-by: Cydh Ramdh --- db/re/item_db.txt | 2 +- db/re/item_misc.txt | 2 +- db/re/item_package.txt | 24 ++-- sql-files/item_db_re.sql | 2 +- src/map/cashshop.c | 5 +- src/map/itemdb.c | 258 ++++++++++++++++++++------------------- src/map/itemdb.h | 54 ++++---- src/map/pc.c | 109 ++++++++++++++++- src/map/pc.h | 18 ++- src/map/skill.c | 99 +++++++-------- src/map/status.c | 3 +- src/map/unit.c | 1 + 12 files changed, 351 insertions(+), 226 deletions(-) diff --git a/db/re/item_db.txt b/db/re/item_db.txt index 75765fbb73..9762561a11 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -2598,7 +2598,7 @@ 4567,Alphoccio_Card,Alphoccio Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; if(BaseJob==Job_Bard) { bonus bMaxHPrate,10; bonus bMaxSPrate,5;} },{},{} 4568,Celia_Card,Celia Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; skill "SA_ABRACADABRA",1; },{},{} 4569,Chen_Card,Chen Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; skill "MO_CALLSPIRITS",2; },{},{} -4570,Flamel_Card,Flamel Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; bonus2 bAddItemHealRate,70,200; },{},{} +4570,Flamel_Card,Flamel Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; bonus2 bAddItemHealRate,IG_Flamel_Card,200; },{},{} 4571,Gertie_Card,Gertie Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; skill "RG_CLOSECONFINE",1; },{},{} 4572,Randel_Card,Randel Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; skill "CR_AUTOGUARD",3; },{},{} 4573,Trentini_Card,Trentini Card,6,20,,10,,,,,,,,4,,,,,{ bonus bFlee,10; if(BaseJob==Job_Dancer) { bonus bMaxHPrate,10; bonus bMaxSPrate,5;} },{},{} diff --git a/db/re/item_misc.txt b/db/re/item_misc.txt index 638062423f..ee58c48791 100644 --- a/db/re/item_misc.txt +++ b/db/re/item_misc.txt @@ -706,7 +706,7 @@ 61,1473,1 // Wizardy_Staff 61,1474,1 // Gae_Bolg 61,1477,1 // Spectral_Spear -61,1478,1 // Ahlspiess, +61,1478,1 // Ahlspiess 61,1479,1 // Spectral_Spear_ 61,1480,1 // Gae_Bolg_ 61,1481,1 // Zephyrus_ diff --git a/db/re/item_package.txt b/db/re/item_package.txt index 7e19cf49cd..00d3956695 100644 --- a/db/re/item_package.txt +++ b/db/re/item_package.txt @@ -1149,24 +1149,24 @@ IG_Ox_Tail_Scroll,Eyes_Of_Ifrit,5,1,1,1,0,1 IG_Ox_Tail_Scroll,Majoruros_Horn,100,1,1,1,0,1 IG_Ox_Tail_Scroll,Sealed_D_Lord_Card,5,1,1,1,0,1 -IG_Buddah_Scroll,Mental_Potion,1,3,1,0,0,0 +IG_Buddah_Scroll,Mental_Potion,0,3,0,0,0,0 IG_Buddah_Scroll,Bubble_Gum_Box,1400,1,1,0,0,0 IG_Buddah_Scroll,Str_Dish_Box,1400,1,1,0,0,0 IG_Buddah_Scroll,Megaphone_Box,1400,1,1,0,0,0 -IG_Buddah_Scroll,Battle_Manual_Box,1352,1,,0,0,0,0 +IG_Buddah_Scroll,Battle_Manual_Box,1352,1,1,0,0,0,0 IG_Buddah_Scroll,Token_Of_Siegfried_Box,1250,1,1,0,0,0 IG_Buddah_Scroll,Shadow_Armor_S_Box10,1400,1,1,0,0,0 IG_Buddah_Scroll,Guyak_Pudding,1400,10,1,0,0,0 -IG_Buddah_Scroll,Poker_Card_In_Mouth,30,1,0,0,0,0 -IG_Buddah_Scroll,Sleeping_Kitty_Cat,100,1,0,0,0,0 -IG_Buddah_Scroll,18600,10,1,0,0,0,0 -IG_Buddah_Scroll,Guarantee_Weapon_5Up,70,1,0,0,0,0 -IG_Buddah_Scroll,Red_Hood,100,0,1,0,0,0 -IG_Buddah_Scroll,Spirit_Of_Chung_E,20,1,0,0,0,0 -IG_Buddah_Scroll,Guarantee_Weapon_9Up,5,1,0,0,0,0 -IG_Buddah_Scroll,Sealed_Samurai_Card,3,1,0,0,0,0 -IG_Buddah_Scroll,Kirin_Wing,10,1,0,0,0,0 -IG_Buddah_Scroll,Unbreak_Weap_Box,50,1,0,0,0,0 +IG_Buddah_Scroll,Poker_Card_In_Mouth,30,1,1,1,0,0 +IG_Buddah_Scroll,Sleeping_Kitty_Cat,100,1,1,1,0,0 +IG_Buddah_Scroll,18600,10,1,1,1,0,0 +IG_Buddah_Scroll,Guarantee_Weapon_5Up,70,1,1,1,0,0 +IG_Buddah_Scroll,Red_Hood,100,1,1,1,0,0 +IG_Buddah_Scroll,Spirit_Of_Chung_E,20,1,1,1,0,0 +IG_Buddah_Scroll,Guarantee_Weapon_9Up,5,1,1,1,0,0 +IG_Buddah_Scroll,Sealed_Samurai_Card,3,1,1,1,0,0 +IG_Buddah_Scroll,Kirin_Wing,10,1,1,1,0,0 +IG_Buddah_Scroll,Unbreak_Weap_Box,50,1,1,1,0,0 IG_Evil_Incarnation,Dead_Tree_Branch_Box2,224,1,1,0,0,1 IG_Evil_Incarnation,Guyak_Pudding,124,10,1,0,0,1 diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql index 83d1880ca6..0c3a16d198 100644 --- a/sql-files/item_db_re.sql +++ b/sql-files/item_db_re.sql @@ -2629,7 +2629,7 @@ REPLACE INTO `item_db_re` VALUES (4566,'Gypsy_Trentini_Card','Gypsy Trentini Car REPLACE INTO `item_db_re` VALUES (4567,'Alphoccio_Card','Alphoccio Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; if(BaseJob==Job_Bard) { bonus bMaxHPrate,10; bonus bMaxSPrate,5;}',NULL,NULL); REPLACE INTO `item_db_re` VALUES (4568,'Celia_Card','Celia Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; skill "SA_ABRACADABRA",1;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (4569,'Chen_Card','Chen Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; skill "MO_CALLSPIRITS",2;',NULL,NULL); -REPLACE INTO `item_db_re` VALUES (4570,'Flamel_Card','Flamel Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; bonus2 bAddItemHealRate,70,200;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (4570,'Flamel_Card','Flamel Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; bonus2 bAddItemHealRate,IG_Flamel_Card,200;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (4571,'Gertie_Card','Gertie Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; skill "RG_CLOSECONFINE",1;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (4572,'Randel_Card','Randel Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; skill "CR_AUTOGUARD",3;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (4573,'Trentini_Card','Trentini Card',6,20,NULL,10,NULL,NULL,NULL,NULL,NULL,NULL,NULL,4,NULL,NULL,NULL,NULL,'bonus bFlee,10; if(BaseJob==Job_Dancer) { bonus bMaxHPrate,10; bonus bMaxSPrate,5;}',NULL,NULL); diff --git a/src/map/cashshop.c b/src/map/cashshop.c index 3078031511..ac5f673b1e 100644 --- a/src/map/cashshop.c +++ b/src/map/cashshop.c @@ -67,6 +67,7 @@ static int cashshop_parse_dbrow( char** str, const char* source, int line ){ /* * Reads database from TXT format, * parses lines and sends them to parse_dbrow. + * TODO: Change to sv_readdb */ static void cashshop_read_db_txt( void ){ const char* filename[] = { DBPATH"item_cash_db.txt", DBIMPORT"/item_cash_db.txt" }; @@ -87,7 +88,7 @@ static void cashshop_read_db_txt( void ){ } while( fgets( line, sizeof( line ), fp ) ){ - char *str[3], *p; + char *str[2], *p; int i; lines++; @@ -130,7 +131,7 @@ static void cashshop_read_db_txt( void ){ fclose(fp); - ShowStatus( "Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi] ); + ShowStatus( "Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, path ); } } diff --git a/src/map/itemdb.c b/src/map/itemdb.c index ad68236bd2..8844dfc6fa 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -19,18 +19,20 @@ #include static struct item_data* itemdb_array[MAX_ITEMDB]; -static DBMap* itemdb_other;// int nameid -> struct item_data* - -static struct s_item_group_db itemgroup_db[MAX_ITEMGROUP]; - struct item_data dummy_item; //This is the default dummy item used for non-existant items. [Skotlex] +static DBMap* itemdb_other;// int nameid -> struct item_data* static DBMap *itemdb_combo; +static DBMap *itemdb_group; DBMap * itemdb_get_combodb(){ return itemdb_combo; } +DBMap * itemdb_get_groupdb() { + return itemdb_group; +} + /** * Search for item name * name = item alias, so we should find items aliases first. if not found then look for "jname" (full name) @@ -150,9 +152,10 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str) */ unsigned short itemdb_searchrandomid(uint16 group_id, uint8 sub_group) { + struct s_item_group_db *group = (struct s_item_group_db *) idb_get(itemdb_group, group_id); if (sub_group) sub_group -= 1; - if (!group_id || group_id >= MAX_ITEMGROUP || !&itemgroup_db[group_id]) { + if (!group) { ShowError("itemdb_searchrandomid: Invalid group id %d\n", group_id); return UNKNOWN_ITEM_ID; } @@ -160,8 +163,8 @@ unsigned short itemdb_searchrandomid(uint16 group_id, uint8 sub_group) ShowError("itemdb_searchrandomid: Invalid sub_group %d\n", sub_group+1); return UNKNOWN_ITEM_ID; } - if (&itemgroup_db[group_id].random[sub_group] && itemgroup_db[group_id].random[sub_group].data_qty) - return itemgroup_db[group_id].random[sub_group].data[rand()%itemgroup_db[group_id].random[sub_group].data_qty].nameid; + if (&group->random[sub_group] && group->random[sub_group].data_qty) + return group->random[sub_group].data[rand()%group->random[sub_group].data_qty].nameid; ShowError("itemdb_searchrandomid: No item entries for group id %d and sub group %d\n", group_id, sub_group+1); return UNKNOWN_ITEM_ID; @@ -177,9 +180,11 @@ unsigned short itemdb_searchrandomid(uint16 group_id, uint8 sub_group) */ uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, uint16 nameid) { uint16 i, amt = 1; + struct s_item_group_db *group = (struct s_item_group_db *) idb_get(itemdb_group, group_id); + if (sub_group) sub_group -= 1; - if (!group_id || group_id >= MAX_ITEMGROUP || !&itemgroup_db[group_id]) { + if (!group) { ShowError("itemdb_get_randgroupitem_count: Invalid group id %d\n", group_id); return amt; } @@ -187,11 +192,12 @@ uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, uint16 n ShowError("itemdb_get_randgroupitem_count: Invalid sub_group id %d\n", group_id+1); return amt; } - if (!(&itemgroup_db[group_id].random[sub_group]) || !itemgroup_db[group_id].random[sub_group].data_qty) + if (!(&group->random[sub_group]) || !group->random[sub_group].data_qty) return amt; - ARR_FIND(0,itemgroup_db[group_id].random[sub_group].data_qty,i,itemgroup_db[group_id].random[sub_group].data[i].nameid == nameid); - if (i < itemgroup_db[group_id].random[sub_group].data_qty) - amt = itemgroup_db[group_id].random[sub_group].data[i].amount; + for (i = 0; i < group->random[sub_group].data_qty; i++) { + if (group->random[sub_group].data[i].nameid == nameid) + return group->random[sub_group].data[i].amount; + } return amt; } @@ -201,37 +207,37 @@ uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, uint16 n * @param group_id: The group ID of item that obtained by player * @param *group: struct s_item_group from itemgroup_db[group_id].random[idx] or itemgroup_db[group_id].must[sub_group][idx] */ -static void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, uint16 group_id, struct s_item_group *group) { +static void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, struct s_item_group_entry *data) { uint16 i; struct item tmp; - nullpo_retv(group); + nullpo_retv(data); - memset(&tmp,0,sizeof(tmp)); + memset(&tmp, 0, sizeof(tmp)); - tmp.nameid = group->nameid; - tmp.amount = (itemdb_isstackable(group->nameid)) ? group->amount : 1; - tmp.bound = group->bound; + tmp.nameid = data->nameid; + tmp.amount = (itemdb_isstackable(data->nameid)) ? data->amount : 1; + tmp.bound = data->bound; tmp.identify = 1; - tmp.expire_time = (group->duration) ? (unsigned int)(time(NULL) + group->duration*60) : 0; - if (group->isNamed) { - tmp.card[0] = itemdb_isequip(group->nameid) ? CARD0_FORGE : CARD0_CREATE; + tmp.expire_time = (data->duration) ? (unsigned int)(time(NULL) + data->duration*60) : 0; + if (data->isNamed) { + tmp.card[0] = itemdb_isequip(data->nameid) ? CARD0_FORGE : CARD0_CREATE; tmp.card[1] = 0; tmp.card[2] = GetWord(sd->status.char_id, 0); tmp.card[3] = GetWord(sd->status.char_id, 1); } - //Do loop for non-stackable item - for (i = 0; i < group->amount; i++) { - int flag; - if ((flag = pc_additem(sd,&tmp,tmp.amount,LOG_TYPE_SCRIPT))) - clif_additem(sd,0,0,flag); - else if (!flag && group->isAnnounced) { ///TODO: Move this broadcast to proper behavior (it should on at different packet) + // Do loop for non-stackable item + for (i = 0; i < data->amount; i++) { + char flag; + if ((flag = pc_additem(sd, &tmp, tmp.amount, LOG_TYPE_SCRIPT))) + clif_additem(sd, 0, 0, flag); + else if (!flag && data->isAnnounced) { ///TODO: Move this broadcast to proper behavior (it should on at different packet) char output[CHAT_SIZE_MAX]; - sprintf(output,msg_txt(NULL,717),sd->status.name,itemdb_jname(group->nameid),itemdb_jname(sd->itemid)); - clif_broadcast(&sd->bl,output,strlen(output),BC_DEFAULT,ALL_CLIENT); + sprintf(output, msg_txt(NULL, 717), sd->status.name, itemdb_jname(data->nameid), itemdb_jname(sd->itemid)); + clif_broadcast(&sd->bl, output, strlen(output), BC_DEFAULT, ALL_CLIENT); //clif_broadcast_obtain_special_item(); } - if (itemdb_isstackable(group->nameid)) + if (itemdb_isstackable(data->nameid)) break; } } @@ -244,53 +250,36 @@ static void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, uint16 grou */ char itemdb_pc_get_itemgroup(uint16 group_id, struct map_session_data *sd) { uint16 i = 0; + struct s_item_group_db *group; nullpo_retr(1,sd); - if (!group_id || group_id >= MAX_ITEMGROUP) { + if (!(group = (struct s_item_group_db *) idb_get(itemdb_group, group_id))) { ShowError("itemdb_pc_get_itemgroup: Invalid group id '%d' specified.",group_id); return 2; } - //Get the 'must' item(s) - if (itemgroup_db[group_id].must_qty) - for (i = 0; i < itemgroup_db[group_id].must_qty; i++) - if (&itemgroup_db[group_id].must[i] && itemdb_exists(itemgroup_db[group_id].must[i].nameid)) - itemdb_pc_get_itemgroup_sub(sd,group_id,&itemgroup_db[group_id].must[i]); + // Get the 'must' item(s) + if (group->must_qty) { + for (i = 0; i < group->must_qty; i++) + if (&group->must[i]) + itemdb_pc_get_itemgroup_sub(sd,&group->must[i]); + } - //Get the 'random' item each random group + // Get the 'random' item each random group for (i = 0; i < MAX_ITEMGROUP_RANDGROUP; i++) { uint16 rand; - if (!(&itemgroup_db[group_id].random[i]) || !itemgroup_db[group_id].random[i].data_qty) //Skip empty random group + if (!(&group->random[i]) || !group->random[i].data_qty) //Skip empty random group continue; - rand = rnd()%itemgroup_db[group_id].random[i].data_qty; - //Woops, why is the data empty? Every check should be done when load the item group! So this is bad day for the player :P - if (!&itemgroup_db[group_id].random[i].data[rand] || !itemgroup_db[group_id].random[i].data[rand].nameid) { + rand = rnd()%group->random[i].data_qty; + if (!(&group->random[i].data[rand]) || !group->random[i].data[rand].nameid) continue; - } - if (itemdb_exists(itemgroup_db[group_id].random[i].data[rand].nameid)) - itemdb_pc_get_itemgroup_sub(sd,group_id,&itemgroup_db[group_id].random[i].data[rand]); + itemdb_pc_get_itemgroup_sub(sd,&group->random[i].data[rand]); } return 0; } -/*========================================== - * Calculates total item-group related bonuses for the given item - *------------------------------------------*/ -int itemdb_group_bonus(struct map_session_data* sd, int itemid) -{ - int bonus = 0, i, j; - for (i=0; i < MAX_ITEMGROUP; i++) { - if (!sd->itemgrouphealrate[i]) - continue; - ARR_FIND(0,itemgroup_db[i].random[0].data_qty,j,itemgroup_db[i].random[0].data[j].nameid == itemid ); - if( j < itemgroup_db[i].random[0].data_qty ) - bonus += sd->itemgrouphealrate[i]; - } - return bonus; -} - /// Searches for the item_data. /// Returns the item_data or NULL if it does not exist. struct item_data* itemdb_exists(int nameid) @@ -672,11 +661,13 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent) } while (fgets(line,sizeof(line),fp)) { - uint16 nameid; - int j, group_id, prob = 1, amt = 1, rand_group = 1, announced = 0, dur = 0, named = 0, bound = 0; - char *str[3], *p; + int group_id = -1; + unsigned int j, prob = 1; + uint16 nameid, amt = 1, dur = 0; + char *str[9], *p, rand_group = 1, announced = 0, named = 0, bound = 0; + struct s_item_group_random *random = NULL; + struct s_item_group_db *group = NULL; bool found = false; - struct s_item_group_random *random; ln++; if (line[0] == '/' && line[1] == '/') @@ -692,44 +683,45 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent) } } memset(str,0,sizeof(str)); - for (j = 0, p = line; j < 3 && p;j++) { + for (j = 0, p = line; j < 9 && p;j++) { str[j] = p; - if (j == 2) - sscanf(str[j],"%d,%d,%d,%d,%d,%d,%d",&prob,&amt,&rand_group,&announced,&dur,&named,&bound); p = strchr(p,','); if (p) *p++=0; } - if (str[0] == NULL) + if (str[0] == NULL) //Empty Group ID continue; if (j < 3) { - if (j > 1) //Or else it barks on blank lines... + if (j > 1) // Or else it barks on blank lines... ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln); continue; } - //Checking group_id + // Checking group_id trim(str[0]); if (ISDIGIT(str[0][0])) group_id = atoi(str[0]); - else //Try reads group id by const - script_get_constant(trim(str[0]),&group_id); - if (!group_id || group_id >= MAX_ITEMGROUP) { - ShowWarning("itemdb_read_itemgroup: Cannot save '%s' because invalid group id or group db is overflow in %s:%d\n", str[0], filename, ln); + else // Try reads group id by const + script_get_constant(trim(str[0]), &group_id); + + if (group_id < 0) { + ShowWarning("itemdb_read_itemgroup: Invlaid Group ID '%s' (%s:%d)\n", str[0], filename, ln); continue; } - //Checking sub group + // Checking sub group + prob = atoi(str[2]); + if (str[4] != NULL) rand_group = atoi(str[4]); if (rand_group < 0 || rand_group > MAX_ITEMGROUP_RANDGROUP) { - ShowWarning("itemdb_read_itemgroup: Invalid sub group %d for group '%s' in %s:%d\n", rand_group, str[0], filename, ln); + ShowWarning("itemdb_read_itemgroup: Invalid sub group '%d' for group '%s' in %s:%d\n", rand_group, str[0], filename, ln); continue; } - if (rand_group && prob < 1) { - ShowWarning("itemdb_read_itemgroup: Invalid probaility for group '%s' sub: %d in %s:%d\n", str[0], rand_group, filename, ln); + if (rand_group != 0 && prob < 1) { + ShowWarning("itemdb_read_itemgroup: Random item must has probability. Group '%s' in %s:%d\n", str[0], filename, ln); continue; } - //Checking item + // Checking item trim(str[1]); if (ISDIGIT(str[1][0]) && itemdb_exists((nameid = atoi(str[1])))) found = true; @@ -742,27 +734,40 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent) continue; } - amt = cap_value(amt,1,MAX_AMOUNT); - dur = cap_value(dur,0,UINT16_MAX); - bound = cap_value(bound,0,4); + if (str[3] != NULL) amt = cap_value(atoi(str[3]),1,MAX_AMOUNT); + if (str[5] != NULL) announced = atoi(str[5]); + if (str[6] != NULL) dur = cap_value(atoi(str[6]),0,UINT16_MAX); + if (str[7] != NULL) named = atoi(str[7]); + if (str[8] != NULL) bound = cap_value(atoi(str[8]),0,4); - //Must item (rand_group == 0), place it here + found = true; + if (!(group = (struct s_item_group_db *) idb_get(itemdb_group, group_id))) { + found = false; + CREATE(group, struct s_item_group_db, 1); + group->id = group_id; + } + + // Must item (rand_group == 0), place it here if (!rand_group) { - uint16 idx = itemgroup_db[group_id].must_qty; + uint16 idx = group->must_qty; if (!idx) - CREATE(itemgroup_db[group_id].must,struct s_item_group,1); + CREATE(group->must, struct s_item_group_entry, 1); else - RECREATE(itemgroup_db[group_id].must,struct s_item_group,idx+1); + RECREATE(group->must, struct s_item_group_entry, idx+1); - itemgroup_db[group_id].must[idx].nameid = nameid; - itemgroup_db[group_id].must[idx].amount = amt; - itemgroup_db[group_id].must[idx].isAnnounced = announced; - itemgroup_db[group_id].must[idx].duration = dur; - itemgroup_db[group_id].must[idx].isNamed = named; - itemgroup_db[group_id].must[idx].bound = bound; - itemgroup_db[group_id].must_qty++; - //If 'must' item isn't set as random item, skip the next process + group->must[idx].nameid = nameid; + group->must[idx].amount = amt; + group->must[idx].isAnnounced = announced; + group->must[idx].duration = dur; + group->must[idx].isNamed = named; + group->must[idx].bound = bound; + group->must_qty++; + // If 'must' item isn't set as random item, skip the next process if (!prob) { + if (!found) { + idb_put(itemdb_group, group->id, group); + itemdb_itemgroup_count++; + } entries++; continue; } @@ -771,15 +776,16 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent) else rand_group -= 1; - random = &itemgroup_db[group_id].random[rand_group]; + random = &group->random[rand_group]; - //Check, if the entry for this random group already created or not + // Check, if the entry for this random group already created or not if (!random->data_qty) { - CREATE(random->data,struct s_item_group,prob); + CREATE(random->data, struct s_item_group_entry, prob); random->data_qty = 0; } else - RECREATE(random->data,struct s_item_group,random->data_qty+prob); + RECREATE(random->data, struct s_item_group_entry, random->data_qty+prob); + //Now put the entry to its rand_group for (j = random->data_qty; j < random->data_qty+prob; j++) { random->data[j].nameid = nameid; @@ -790,6 +796,11 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent) random->data[j].bound = bound; } random->data_qty += prob; + + if (!found) { + idb_put(itemdb_group, group->id, group); + itemdb_itemgroup_count++; + } entries++; } fclose(fp); @@ -1590,7 +1601,7 @@ static void itemdb_read(void) { else itemdb_readdb(); - memset(&itemgroup_db, 0, sizeof(itemgroup_db)); + itemdb_itemgroup_count = 0; for(i=0; imust_qty) + aFree(group->must); + group->must_qty = 0; + for (j = 0; j < MAX_ITEMGROUP_RANDGROUP; j++) { + if (!group->random[j].data_qty || !(&group->random[j])) + continue; + aFree(group->random[j].data); + group->random[j].data_qty = 0; + } + aFree(group); + return 0; +} + /** * Reload Item DB */ @@ -1689,19 +1718,7 @@ void itemdb_reload(void) { if( itemdb_array[i] ) destroy_item_data(itemdb_array[i], true); - for (i = 0; i < MAX_ITEMGROUP; i++) { - uint8 j; - if (!(&itemgroup_db[i])) - continue; - if (itemgroup_db[i].must_qty) - aFree(itemgroup_db[i].must); - for (j = 0; j < MAX_ITEMGROUP_RANDGROUP; j++) { - if (!(&itemgroup_db[i].random[j]) || !itemgroup_db[i].random[j].data_qty) - continue; - aFree(itemgroup_db[i].random[j].data); - } - } - + itemdb_group->clear(itemdb_group, itemdb_group_free); itemdb_other->clear(itemdb_other, itemdb_final_sub); db_clear(itemdb_combo); @@ -1769,20 +1786,8 @@ void do_final_itemdb(void) { for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i ) if( itemdb_array[i] ) destroy_item_data(itemdb_array[i], true); - - for (i = 0; i < MAX_ITEMGROUP; i++) { - uint8 j; - if (!(&itemgroup_db[i])) - continue; - if (itemgroup_db[i].must_qty) - aFree(itemgroup_db[i].must); - for (j = 0; j < MAX_ITEMGROUP_RANDGROUP; j++) { - if (!(&itemgroup_db[i].random[j]) || !itemgroup_db[i].random[j].data_qty) - continue; - aFree(itemgroup_db[i].random[j].data); - } - } - + + itemdb_group->destroy(itemdb_group, itemdb_group_free); itemdb_other->destroy(itemdb_other, itemdb_final_sub); destroy_item_data(&dummy_item, false); db_destroy(itemdb_combo); @@ -1795,6 +1800,7 @@ void do_init_itemdb(void) { memset(itemdb_array, 0, sizeof(itemdb_array)); itemdb_other = idb_alloc(DB_OPT_BASE); itemdb_combo = idb_alloc(DB_OPT_BASE); + itemdb_group = idb_alloc(DB_OPT_BASE); create_dummy_data(); //Dummy data item. itemdb_read(); diff --git a/src/map/itemdb.h b/src/map/itemdb.h index d5c43a07cc..084695ccb4 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -23,8 +23,6 @@ #define IG_FINDINGORE 6 #define IG_POTION 37 -#define MAX_ITEMGROUP 420 ///The max. item group count (increase this when needed). TODO: Remove this limit and use dynamic size or DBMap if needed - #define MAX_ITEMGROUP_RANDGROUP 4 ///Max group for random item (increase this when needed). TODO: Remove this limit and use dynamic size if needed #define CARD0_FORGE 0x00FF @@ -318,6 +316,33 @@ struct item_combo { bool isRef;/* whether this struct is a reference or the master */ }; + +/// Struct of item group entry +struct s_item_group_entry { + uint16 nameid, /// Item ID + duration; /// Duration if item as rental item (in minutes) + uint16 amount; /// Amount of item will be obtained + bool isAnnounced, /// Broadcast if player get this item + isNamed; /// Named the item (if possible) + char bound; /// Makes the item as bound item (according to bound type) +}; + +/// Struct of random group +struct s_item_group_random { + struct s_item_group_entry *data; + uint16 data_qty; +}; + +/// Struct of item group that will be used for db +struct s_item_group_db { + uint16 id; + struct s_item_group_entry *must; + uint16 must_qty; + struct s_item_group_random random[MAX_ITEMGROUP_RANDGROUP]; //! TODO: Move this fixed array to dynamic size if needed. +}; + +static uint16 itemdb_itemgroup_count; /// Number of Item Groups + ///Main item data struct struct item_data { uint16 nameid; @@ -384,29 +409,6 @@ struct item_data { unsigned char combos_count; }; -/* Struct of item group entry */ -struct s_item_group { - uint16 nameid, ///item id - duration; ///duration if item as rental item (in minute) - uint16 amount; ///amount of item will be obtained - bool isAnnounced, ///broadcast if player get this item - isNamed; ///named the item (if possible) - char bound; ///makes the item as bound item (according to bound type) -}; - -/* Struct of random group */ -struct s_item_group_random { - struct s_item_group *data; - uint16 data_qty; -}; - -/* Struct of item group that will be used for db */ -struct s_item_group_db { - struct s_item_group *must; - uint16 must_qty; - struct s_item_group_random random[MAX_ITEMGROUP_RANDGROUP]; //! TODO: Move this fixed array to dynamic size if needed. -}; - struct item_data* itemdb_searchname(const char *name); int itemdb_searchname_array(struct item_data** data, int size, const char *str); struct item_data* itemdb_load(int nameid); @@ -440,7 +442,6 @@ struct item_data* itemdb_exists(int nameid); const char* itemdb_typename(enum item_types type); const char *itemdb_typename_ammo (enum e_item_ammo ammo); -int itemdb_group_bonus(struct map_session_data* sd, int itemid); unsigned short itemdb_searchrandomid(uint16 group_id, uint8 sub_group); #define itemdb_value_buy(n) itemdb_search(n)->value_buy @@ -479,6 +480,7 @@ char itemdb_pc_get_itemgroup(uint16 group_id, struct map_session_data *sd); uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, uint16 nameid); DBMap * itemdb_get_combodb(); +DBMap * itemdb_get_groupdb(); void itemdb_reload(void); diff --git a/src/map/pc.c b/src/map/pc.c index c11ec81285..206cef6322 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -66,6 +66,7 @@ int day_timer_tid = INVALID_TIMER; int night_timer_tid = INVALID_TIMER; struct eri *pc_sc_display_ers = NULL; +struct eri *pc_itemgrouphealrate_ers = NULL; int pc_expiration_tid = INVALID_TIMER; struct fame_list smith_fame_list[MAX_FAME_LIST]; @@ -2154,6 +2155,56 @@ int pc_bonus_subele(struct map_session_data* sd, unsigned char ele, short rate, return 0; } +/** Add item group heal rate bonus to player +* @param sd Player +* @param group_id Item Group ID +* @param rate +* @author Cydh +*/ +void pc_itemgrouphealrate(struct map_session_data *sd, uint16 group_id, short rate) { + struct s_pc_itemgrouphealrate *entry; + uint8 i; + + for (i = 0; i < sd->itemgrouphealrate_count; i++) { + if (sd->itemgrouphealrate[i]->group_id == group_id) + break; + } + + if (i != sd->itemgrouphealrate_count) { + sd->itemgrouphealrate[i]->rate += rate; + return; + } + + if (i >= UINT8_MAX) { + ShowError("pc_itemgrouphealrate_add: Reached max (%d) possible bonuses for this player %d\n", UINT8_MAX); + return; + } + + entry = ers_alloc(pc_itemgrouphealrate_ers, struct s_pc_itemgrouphealrate); + entry->group_id = group_id; + entry->rate = rate; + + RECREATE(sd->itemgrouphealrate, struct s_pc_itemgrouphealrate *, sd->itemgrouphealrate_count+1); + sd->itemgrouphealrate[sd->itemgrouphealrate_count++] = entry; +} + +/** Clear item group heal rate from player +* @param sd Player +* @author Cydh +*/ +void pc_itemgrouphealrate_clear(struct map_session_data *sd) { + if (!sd || !sd->itemgrouphealrate_count) + return; + else { + uint8 i; + for( i = 0; i < sd->itemgrouphealrate_count; i++ ) + ers_free(pc_itemgrouphealrate_ers, sd->itemgrouphealrate[i]); + sd->itemgrouphealrate_count = 0; + aFree(sd->itemgrouphealrate); + sd->itemgrouphealrate = NULL; + } +} + /*========================================== * Add a bonus(type) to player sd *------------------------------------------*/ @@ -3217,8 +3268,8 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) case SP_ADD_ITEM_HEAL_RATE: if(sd->state.lr_flag == 2) break; - if (type2 < MAX_ITEMGROUP) { //Group bonus - sd->itemgrouphealrate[type2] += val; + if (type2 < itemdb_itemgroup_count) { //Group bonus + pc_itemgrouphealrate(sd, type2, val); break; } //Standard item bonus. @@ -7616,7 +7667,7 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp) //All item bonuses. bonus += sd->bonus.itemhealrate2; //Item Group bonuses - bonus += bonus*itemdb_group_bonus(sd, itemid)/100; + bonus += bonus*pc_get_itemgroup_bonus(sd, itemid)/100; //Individual item bonuses. for(i = 0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid; i++) { @@ -10758,16 +10809,63 @@ short pc_maxparameter(struct map_session_data *sd, enum e_params param) { ((class_&JOBL_UPPER) ? battle_config.max_trans_parameter : battle_config.max_parameter))); } + +/** +* Calculates total item-group related bonuses for the given item +* @param sd Player +* @param nameid Item ID +* @return Heal rate +**/ +short pc_get_itemgroup_bonus(struct map_session_data* sd, uint16 nameid) { + short bonus = 0; + uint8 i; + + if (!sd->itemgrouphealrate_count) + return bonus; + for (i = 0; i < sd->itemgrouphealrate_count; i++) { + uint16 group_id = sd->itemgrouphealrate[i]->group_id, j; + struct s_item_group_db *group = (struct s_item_group_db *) idb_get(itemdb_get_groupdb(), group_id); + if (!group) + continue; + + for (j = 0; j < group->random[0].data_qty; j++) { + if (group->random[0].data[j].nameid == nameid) { + bonus += sd->itemgrouphealrate[i]->rate; + break; + } + } + } + return bonus; +} + +/** +* Calculates total item-group related bonuses for the given item group +* @param sd Player +* @param group_id Item Group ID +* @return Heal rate +**/ +short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id) { + short bonus = 0; + uint8 i; + + if (!sd->itemgrouphealrate_count) + return bonus; + for (i = 0; i < sd->itemgrouphealrate_count; i++) { + if (sd->itemgrouphealrate[i]->group_id == group_id) + return sd->itemgrouphealrate[i]->rate; + } + return bonus; +} + /*========================================== * pc Init/Terminate *------------------------------------------*/ void do_final_pc(void) { - db_destroy(itemcd_db); - do_final_pc_groups(); ers_destroy(pc_sc_display_ers); + ers_destroy(pc_itemgrouphealrate_ers); } void do_init_pc(void) { @@ -10808,4 +10906,5 @@ void do_init_pc(void) { do_init_pc_groups(); pc_sc_display_ers = ers_new(sizeof(struct sc_display_entry), "pc.c:pc_sc_display_ers", ERS_OPT_NONE); + pc_itemgrouphealrate_ers = ers_new(sizeof(struct s_pc_itemgrouphealrate), "pc.c:pc_itemgrouphealrate_ers", ERS_OPT_NONE); } diff --git a/src/map/pc.h b/src/map/pc.h index f9425990ea..c784604024 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -149,6 +149,12 @@ enum npc_timeout_type { NPCT_WAIT = 2, }; +/// Item Group heal rate struct +struct s_pc_itemgrouphealrate { + uint16 group_id; /// Item Group ID + short rate; /// Rate +}; + struct map_session_data { struct block_list bl; struct unit_data ud; @@ -323,7 +329,6 @@ struct map_session_data { int ignore_mdef_by_race[RC_MAX]; int ignore_mdef_by_class[CLASS_MAX]; int ignore_def_by_race[RC_MAX]; - int itemgrouphealrate[MAX_ITEMGROUP]; short sp_gain_race[RC_MAX]; short sp_gain_race_attack[RC_MAX]; short hp_gain_race_attack[RC_MAX]; @@ -595,13 +600,18 @@ struct map_session_data { int16 icon; int tid; } bonus_script[MAX_PC_BONUS_SCRIPT]; + + struct s_pc_itemgrouphealrate **itemgrouphealrate; /// List of Item Group Heal rate bonus + uint8 itemgrouphealrate_count; /// Number of rate bonuses /* Expiration Timer ID */ int expiration_tid; time_t expiration_time; }; -struct eri *pc_sc_display_ers; +struct eri *pc_sc_display_ers; /// Player's SC display table +struct eri *pc_itemgrouphealrate_ers; /// Player's Item Group Heal Rate table + /* Global Expiration Timer ID */ extern int pc_expiration_tid; @@ -1105,6 +1115,10 @@ void pc_bonus_script_clear(struct map_session_data *sd, uint16 flag); void pc_cell_basilica(struct map_session_data *sd); +void pc_itemgrouphealrate_clear(struct map_session_data *sd); +short pc_get_itemgroup_bonus(struct map_session_data* sd, uint16 nameid); +short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id); + #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_class, int type); #endif diff --git a/src/map/skill.c b/src/map/skill.c index a5543e292c..2617a8ab20 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6965,66 +6965,67 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } case AM_BERSERKPITCHER: - case AM_POTIONPITCHER: { - int i,hp = 0,sp = 0; - if( dstmd && dstmd->mob_id == MOBID_EMPERIUM ) { - map_freeblock_unlock(); - return 1; - } - if( sd ) { - int x,bonus=100; - struct skill_condition require = skill_get_requirement(sd, skill_id, skill_lv); - x = skill_lv%11 - 1; - i = pc_search_inventory(sd, require.itemid[x]); - if (i < 0 || require.itemid[x] <= 0) { - clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + case AM_POTIONPITCHER: + { + int i,hp = 0,sp = 0; + if( dstmd && dstmd->mob_id == MOBID_EMPERIUM ) { map_freeblock_unlock(); return 1; } - if (sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < require.amount[x]) { - clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - map_freeblock_unlock(); - return 1; - } - if( skill_id == AM_BERSERKPITCHER ) { - if( dstsd && dstsd->status.base_level < (unsigned int)sd->inventory_data[i]->elv ) { + if( sd ) { + int x,bonus=100; + struct skill_condition require = skill_get_requirement(sd, skill_id, skill_lv); + x = skill_lv%11 - 1; + i = pc_search_inventory(sd, require.itemid[x]); + if (i < 0 || require.itemid[x] <= 0) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map_freeblock_unlock(); return 1; } - } - potion_flag = 1; - potion_hp = potion_sp = potion_per_hp = potion_per_sp = 0; - potion_target = bl->id; - run_script(sd->inventory_data[i]->script,0,sd->bl.id,0); - potion_flag = potion_target = 0; - if( sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ALCHEMIST ) - bonus += sd->status.base_level; - if( potion_per_hp > 0 || potion_per_sp > 0 ) { - hp = tstatus->max_hp * potion_per_hp / 100; - hp = hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000; - if( dstsd ) { - sp = dstsd->status.max_sp * potion_per_sp / 100; - sp = sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000; + if (sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < require.amount[x]) { + clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + map_freeblock_unlock(); + return 1; } - } else { - if( potion_hp > 0 ) { - hp = potion_hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000; - hp = hp * (100 + (tstatus->vit<<1)) / 100; - if( dstsd ) - hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100; + if( skill_id == AM_BERSERKPITCHER ) { + if( dstsd && dstsd->status.base_level < (unsigned int)sd->inventory_data[i]->elv ) { + clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + map_freeblock_unlock(); + return 1; + } } - if( potion_sp > 0 ) { - sp = potion_sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000; - sp = sp * (100 + (tstatus->int_<<1)) / 100; - if( dstsd ) - sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10) / 100; + potion_flag = 1; + potion_hp = potion_sp = potion_per_hp = potion_per_sp = 0; + potion_target = bl->id; + run_script(sd->inventory_data[i]->script,0,sd->bl.id,0); + potion_flag = potion_target = 0; + if( sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ALCHEMIST ) + bonus += sd->status.base_level; + if( potion_per_hp > 0 || potion_per_sp > 0 ) { + hp = tstatus->max_hp * potion_per_hp / 100; + hp = hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000; + if( dstsd ) { + sp = dstsd->status.max_sp * potion_per_sp / 100; + sp = sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000; + } + } else { + if( potion_hp > 0 ) { + hp = potion_hp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000; + hp = hp * (100 + (tstatus->vit<<1)) / 100; + if( dstsd ) + hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100; + } + if( potion_sp > 0 ) { + sp = potion_sp * (100 + pc_checkskill(sd,AM_POTIONPITCHER)*10 + pc_checkskill(sd,AM_LEARNINGPOTION)*5)*bonus/10000; + sp = sp * (100 + (tstatus->int_<<1)) / 100; + if( dstsd ) + sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10) / 100; + } } - } - if (sd->itemgrouphealrate[IG_POTION]>0) { - hp += hp * sd->itemgrouphealrate[IG_POTION] / 100; - sp += sp * sd->itemgrouphealrate[IG_POTION] / 100; + if ((bonus = pc_get_itemgroup_bonus_group(sd, IG_POTION))) { + hp += hp * bonus / 100; + sp += sp * bonus / 100; } if( (i = pc_skillheal_bonus(sd, skill_id)) ) { diff --git a/src/map/status.c b/src/map/status.c index b02d29c215..d2aaf903ce 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2866,7 +2866,6 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) + sizeof(sd->ignore_def_by_race) + sizeof(sd->ignore_mdef_by_race) + sizeof(sd->ignore_mdef_by_class) - + sizeof(sd->itemgrouphealrate) + sizeof(sd->sp_gain_race) + sizeof(sd->sp_gain_race_attack) + sizeof(sd->hp_gain_race_attack) @@ -2938,6 +2937,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),true); pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),true); + pc_itemgrouphealrate_clear(sd); + npc_script_event(sd, NPCE_STATCALC); // Parse equipment diff --git a/src/map/unit.c b/src/map/unit.c index 27103473e6..1d3d26eb02 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -2664,6 +2664,7 @@ int unit_free(struct block_list *bl, clr_type clrtype) sd->quest_log = NULL; sd->num_quests = sd->avail_quests = 0; } + pc_itemgrouphealrate_clear(sd); break; } case BL_PET: From dc834fb39f89a25eeeeb1b9fb7db4697ebdafab9 Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Fri, 23 May 2014 10:51:56 +0700 Subject: [PATCH 2/2] Follow up 7f4a7ba Signed-off-by: Cydh Ramdh --- src/map/cashshop.c | 4 ++-- src/map/clif.c | 2 +- src/map/itemdb.c | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/map/cashshop.c b/src/map/cashshop.c index ac5f673b1e..830ddff7cf 100644 --- a/src/map/cashshop.c +++ b/src/map/cashshop.c @@ -88,7 +88,7 @@ static void cashshop_read_db_txt( void ){ } while( fgets( line, sizeof( line ), fp ) ){ - char *str[2], *p; + char *str[3], *p; int i; lines++; @@ -103,7 +103,7 @@ static void cashshop_read_db_txt( void ){ if( *p == '\0' ) continue; - for( i = 0; i < 2; ++i ){ + for( i = 0; i < 3; ++i ){ str[i] = p; p = strchr( p, ',' ); diff --git a/src/map/clif.c b/src/map/clif.c index 1c8dc46ea8..128b5fb9e8 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -17025,7 +17025,7 @@ void clif_ackworldinfo(struct map_session_data* sd) { WFIFOHEAD(fd,packet_len(0x979)); WFIFOW(fd,0)=0x979; //AID -> world name ? - safestrncpy((char*)WFIFOP(fd,2), '\0' /* World name */, 24); + safestrncpy((char*)WFIFOP(fd,2), "" /* World name */, 24); safestrncpy((char*)WFIFOP(fd,26), sd->status.name, NAME_LENGTH); WFIFOSET(fd,packet_len(0x979)); } diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 8844dfc6fa..a122734ce7 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -664,7 +664,8 @@ static void itemdb_read_itemgroup_sub(const char* filename, bool silent) int group_id = -1; unsigned int j, prob = 1; uint16 nameid, amt = 1, dur = 0; - char *str[9], *p, rand_group = 1, announced = 0, named = 0, bound = 0; + uint8 rand_group = 1; + char *str[9], *p, announced = 0, named = 0, bound = 0; struct s_item_group_random *random = NULL; struct s_item_group_db *group = NULL; bool found = false;