diff options
author | Ibrahim Hossam <ibrahem.h.basyone@gmail.com> | 2015-07-06 21:38:11 +0200 |
---|---|---|
committer | Ibrahim Hossam <ibrahem.h.basyone@gmail.com> | 2015-07-08 03:26:34 +0200 |
commit | 856b6f1feb25ca74d716a4c22fff650e0ff065a0 (patch) | |
tree | c3035ea753ff2c79c1e969056a120998e4f2dd2c /src/map | |
parent | 0177783215ae97d08109f7af91a20b78b6a0df90 (diff) | |
download | hercules-856b6f1feb25ca74d716a4c22fff650e0ff065a0.tar.gz hercules-856b6f1feb25ca74d716a4c22fff650e0ff065a0.tar.bz2 hercules-856b6f1feb25ca74d716a4c22fff650e0ff065a0.tar.xz hercules-856b6f1feb25ca74d716a4c22fff650e0ff065a0.zip |
Update Unique ID system to match official now it cover all cash items include stackable ones.
Implement ForceSerial option in Package Item Database to force serial for
any item.
Implement ForceSerial option in item database to force serial for any item.
Implement Merge Client interface to merge stackable items with serial numbers ( check npc/other/item_merge.txt ).
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/clif.c | 157 | ||||
-rw-r--r-- | src/map/clif.h | 21 | ||||
-rw-r--r-- | src/map/itemdb.c | 64 | ||||
-rw-r--r-- | src/map/itemdb.h | 3 | ||||
-rw-r--r-- | src/map/packets.h | 2 | ||||
-rw-r--r-- | src/map/pc.c | 7 | ||||
-rw-r--r-- | src/map/script.c | 12 | ||||
-rw-r--r-- | src/map/storage.c | 4 |
8 files changed, 245 insertions, 25 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index d9b20e570..f01b59fda 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -18123,6 +18123,157 @@ void clif_roulette_generate_ack(struct map_session_data *sd, unsigned char resul clif->send(&p,sizeof(p), &sd->bl, SELF); } +/** +* Stackable items merger +**/ +void clif_openmergeitem(int fd, struct map_session_data *sd) +{ + int i = 0, n = 0, j = 0; + struct merge_item merge_items[MAX_INVENTORY]; + struct merge_item *merge_items_[MAX_INVENTORY] = {0}; + + memset(&merge_items,'\0',sizeof(merge_items)); + + for (i = 0; i < MAX_INVENTORY; i++) { + struct item *item_data = &sd->status.inventory[i]; + + if (item_data->nameid == 0 || !itemdb->isstackable(item_data->nameid)) + continue; + + merge_items[n].nameid = item_data->nameid; + merge_items[n].position = i + 2; + n++; + + + } + + qsort(merge_items,n,sizeof(struct merge_item),clif->comparemergeitem); + + for (i = 0, j = 0; i < n; i++) { + if (i > 0 && merge_items[i].nameid == merge_items[i-1].nameid) + { + merge_items_[j] = &merge_items[i]; + j++; + continue; + } + + if (i < n - 1 && merge_items[i].nameid == merge_items[i+1].nameid) + { + merge_items_[j] = &merge_items[i]; + j++; + continue; + } + } + + WFIFOHEAD(fd,2*j+4); + WFIFOW(fd,0) = 0x96d; + WFIFOW(fd,2) = 2*j+4; + for ( i = 0; i < j; i++ ) + WFIFOW(fd,i*2+4) = merge_items_[i]->position; + WFIFOSET(fd,2*j+4); +} + +int clif_comparemergeitem(const void *a, const void *b) +{ + const struct merge_item *a_ = a; + const struct merge_item *b_ = b; + + if (a_->nameid == b_->nameid) + return 0; + return a_->nameid > b_->nameid ? -1 : 1; +} + +void clif_ackmergeitems(int fd, struct map_session_data *sd) +{ + int i = 0, n = 0, length = 0, count = 0; + int16 nameid = 0, indexes[MAX_INVENTORY] = {0}, amounts[MAX_INVENTORY] = {0}; + struct item item_data; + + length = (RFIFOW(fd,2) - 4)/2; + + if (length >= MAX_INVENTORY || length < 2) { + WFIFOHEAD(fd,7); + WFIFOW(fd,0) = 0x96f; + WFIFOW(fd,2) = 0; + WFIFOW(fd,4) = 0; + WFIFOB(fd,6) = MERGEITEM_FAILD; + WFIFOSET(fd,7); + return; + } + + for (i = 0, n = 0; i < length; i++) { + int16 idx = RFIFOW(fd,i*2+4) - 2; + struct item *it = NULL; + + if (idx < 0 || idx >= MAX_INVENTORY) + continue; + + it = &sd->status.inventory[idx]; + + if (it->nameid == 0 || !itemdb->isstackable(it->nameid)) + continue; + + if (nameid == 0) + nameid = it->nameid; + + if (nameid != it->nameid) + continue; + + count += it->amount; + indexes[n] = idx; + amounts[n] = it->amount; + n++; + } + + + if (n < 2 || count == 0) { + WFIFOHEAD(fd,7); + WFIFOW(fd,0) = 0x96f; + WFIFOW(fd,2) = 0; + WFIFOW(fd,4) = 0; + WFIFOB(fd,6) = MERGEITEM_FAILD; + WFIFOSET(fd,7); + return; + } + + if (count > MAX_AMOUNT) { + WFIFOHEAD(fd,7); + WFIFOW(fd,0) = 0x96f; + WFIFOW(fd,2) = 0; + WFIFOW(fd,4) = 0; + WFIFOB(fd,6) = MERGEITEM_MAXCOUNTFAILD; + WFIFOSET(fd,7); + return; + } + + for (i = 0; i < n; i++) + pc->delitem(sd,indexes[i],amounts[i],0,DELITEM_NORMAL,LOG_TYPE_NPC); + + + memset(&item_data,'\0',sizeof(item_data)); + + item_data.nameid = nameid; + item_data.identify = 1; + item_data.unique_id = itemdb->unique_id(sd); + pc->additem(sd,&item_data,count,LOG_TYPE_NPC); + + ARR_FIND(0,MAX_INVENTORY,i,item_data.unique_id == sd->status.inventory[i].unique_id); + + WFIFOHEAD(fd,7); + WFIFOW(fd,0) = 0x96f; + WFIFOW(fd,2) = i+2; + WFIFOW(fd,4) = count; + WFIFOB(fd,6) = MERGEITEM_SUCCESS; + WFIFOSET(fd,7); + +} + +void clif_cancelmergeitem (int fd, struct map_session_data *sd) +{ + //Track The merge item cancelation ? + return; +} + /* */ unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { if( sd ) { @@ -18912,6 +19063,12 @@ void clif_defaults(void) { /* */ clif->parse_roulette_db = clif_parse_roulette_db; clif->roulette_generate_ack = clif_roulette_generate_ack; + /* Merge Items */ + clif->openmergeitem = clif_openmergeitem; + clif->cancelmergeitem = clif_cancelmergeitem; + clif->comparemergeitem = clif_comparemergeitem; + clif->ackmergeitems = clif_ackmergeitems; + /*------------------------ *- Parse Incoming Packet *------------------------*/ diff --git a/src/map/clif.h b/src/map/clif.h index 66dd13304..c827406ca 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -522,6 +522,16 @@ enum delitem_reason { DELITEM_ANALYSIS = 7, /// Consumed by Four Spirit Analysis (SO_EL_ANALYSIS) skill }; +/* +* Merge items reasons +*/ + +enum mergeitem_reason { + MERGEITEM_SUCCESS = 0x0, + MERGEITEM_FAILD = 0x1, + MERGEITEM_MAXCOUNTFAILD = 0x2, +}; + /** * Structures **/ @@ -542,6 +552,11 @@ struct cdelayed_damage { struct block_list bl; }; +struct merge_item { + int16 position; + int16 nameid; +}; + /** * Vars **/ @@ -1062,6 +1077,12 @@ struct clif_interface { /* */ bool (*parse_roulette_db) (void); void (*roulette_generate_ack) (struct map_session_data *sd, unsigned char result, short stage, short prizeIdx, short bonusItemID); + /* Merge Items */ + void (*openmergeitem) (int fd, struct map_session_data *sd); + void (*cancelmergeitem) (int fd, struct map_session_data *sd); + int (*comparemergeitem) (const void *a, const void *b); + void (*ackmergeitems) (int fd, struct map_session_data *sd); + /*------------------------ *- Parse Incoming Packet *------------------------*/ diff --git a/src/map/itemdb.c b/src/map/itemdb.c index b02da1e0d..4ebe282a2 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -199,6 +199,9 @@ void itemdb_package_item(struct map_session_data *sd, struct item_package *packa if( package->must_items[i].announce ) clif->package_announce(sd,package->must_items[i].id,package->id); + if ( package->must_items[i].force_serial ) + it.unique_id = itemdb->unique_id(sd); + get_count = itemdb->isstackable(package->must_items[i].id) ? package->must_items[i].qty : 1; it.amount = get_count == 1 ? 1 : get_count; @@ -719,7 +722,7 @@ void itemdb_write_cached_packages(const char *config_filename) { //now we loop into must for(c = 0; c < must_qty; c++) { struct item_package_must_entry *entry = &itemdb->packages[i].must_items[c]; - unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0; + unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0, force_serial = entry->force_serial == 1 ? 1 : 0; //first 2 byte = item id hwrite(&entry->id,sizeof(entry->id),1,file); //next 2 byte = qty @@ -729,7 +732,9 @@ void itemdb_write_cached_packages(const char *config_filename) { //next 1 byte = announce (1:0) hwrite(&announce,sizeof(announce),1,file); //next 1 byte = named (1:0) - hwrite(&named,sizeof(announce),1,file); + hwrite(&named,sizeof(named),1,file); + //next 1 byte = ForceSerial (1:0) + hwrite(&force_serial,sizeof(force_serial),1,file); } //now we loop into random groups for(c = 0; c < random_qty; c++) { @@ -741,7 +746,7 @@ void itemdb_write_cached_packages(const char *config_filename) { //now we loop into the group's list for(h = 0; h < group_qty; h++) { struct item_package_rand_entry *entry = &itemdb->packages[i].random_groups[c].random_list[h]; - unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0; + unsigned char announce = entry->announce == 1 ? 1 : 0, named = entry->named == 1 ? 1 : 0, force_serial = entry->force_serial == 1 ? 1 : 0; //first 2 byte = item id hwrite(&entry->id,sizeof(entry->id),1,file); //next 2 byte = qty @@ -753,7 +758,9 @@ void itemdb_write_cached_packages(const char *config_filename) { //next 1 byte = announce (1:0) hwrite(&announce,sizeof(announce),1,file); //next 1 byte = named (1:0) - hwrite(&named,sizeof(announce),1,file); + hwrite(&named,sizeof(named),1,file); + //next 1 byte = ForceSerial (1:0) + hwrite(&force_serial,sizeof(force_serial),1,file); } } } @@ -807,7 +814,7 @@ bool itemdb_read_cached_packages(const char *config_filename) { for(c = 0; c < package->must_qty; c++) { struct item_package_must_entry *entry = &itemdb->packages[i].must_items[c]; unsigned short mid = 0, qty = 0, hours = 0; - unsigned char announce = 0, named = 0; + unsigned char announce = 0, named = 0, force_serial = 0; struct item_data *data; //first 2 byte = item id hread(&mid,sizeof(mid),1,file); @@ -818,8 +825,10 @@ bool itemdb_read_cached_packages(const char *config_filename) { //next 1 byte = announce (1:0) hread(&announce,sizeof(announce),1,file); //next 1 byte = named (1:0) - hread(&named,sizeof(announce),1,file); - + hread(&named,sizeof(named),1,file); + //next 1 byte = ForceSerial (1:0) + hread(&force_serial,sizeof(force_serial),1,file); + if( !(data = itemdb->exists(mid)) ) ShowWarning("itemdb_read_cached_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id)); @@ -828,6 +837,7 @@ bool itemdb_read_cached_packages(const char *config_filename) { entry->qty = qty; entry->announce = announce ? 1 : 0; entry->named = named ? 1 : 0; + entry->force_serial = force_serial ? 1 : 0; } } if( package->random_qty ) { @@ -847,7 +857,7 @@ bool itemdb_read_cached_packages(const char *config_filename) { for(h = 0; h < group_qty; h++) { struct item_package_rand_entry *entry = &itemdb->packages[i].random_groups[c].random_list[h]; unsigned short mid = 0, qty = 0, hours = 0, rate = 0; - unsigned char announce = 0, named = 0; + unsigned char announce = 0, named = 0, force_serial = 0; struct item_data *data; if( prev ) prev->next = entry; @@ -863,8 +873,10 @@ bool itemdb_read_cached_packages(const char *config_filename) { //next 1 byte = announce (1:0) hread(&announce,sizeof(announce),1,file); //next 1 byte = named (1:0) - hread(&named,sizeof(announce),1,file); - + hread(&named,sizeof(named),1,file); + //next 1 byte = ForceSerial (1:0) + hread(&force_serial,sizeof(force_serial),1,file); + if( !(data = itemdb->exists(mid)) ) ShowWarning("itemdb_read_cached_packages: unknown item '%d' in package '%s'!\n",mid,itemdb_name(package->id)); @@ -874,7 +886,7 @@ bool itemdb_read_cached_packages(const char *config_filename) { entry->qty = qty; entry->announce = announce ? 1 : 0; entry->named = named ? 1 : 0; - + entry->force_serial = force_serial ? 1 : 0; prev = entry; } if( prev ) @@ -1020,7 +1032,7 @@ void itemdb_read_packages(void) { c = 0; while( (it = libconfig->setting_get_elem(itg,c++)) ) { int icount = 1, expire = 0, rate = 10000, gid = 0; - bool announce = false, named = false; + bool announce = false, named = false, force_serial = false; itname = config_setting_name(it); @@ -1049,6 +1061,9 @@ void itemdb_read_packages(void) { if( ( t = libconfig->setting_get_member(it, "Named")) && libconfig->setting_get_bool(t) ) named = true; + if( ( t = libconfig->setting_get_member(it, "ForceSerial")) && libconfig->setting_get_bool(t) ) + force_serial = true; + if( !( t = libconfig->setting_get_member(it, "Random") ) ) { ShowWarning("itemdb_read_packages: missing 'Random' field for item '%s' in package '%s', defaulting to must!\n",itname,config_setting_name(itg)); gid = 0; @@ -1061,6 +1076,7 @@ void itemdb_read_packages(void) { itemdb->packages[count].must_items[m].hours = expire; itemdb->packages[count].must_items[m].announce = announce == true ? 1 : 0; itemdb->packages[count].must_items[m].named = named == true ? 1 : 0; + itemdb->packages[count].must_items[m].force_serial = force_serial == true ? 1 : 0; m++; } else { int gidx = gid - 1; @@ -1078,6 +1094,7 @@ void itemdb_read_packages(void) { itemdb->packages[count].random_groups[gidx].random_list[r].hours = expire; itemdb->packages[count].random_groups[gidx].random_list[r].announce = announce == true ? 1 : 0; itemdb->packages[count].random_groups[gidx].random_list[r].named = named == true ? 1 : 0; + itemdb->packages[count].random_groups[gidx].random_list[r].force_serial = force_serial == true ? 1 : 0; itemdb->packages[count].random_groups[gidx].random_qty += 1; prev[gidx] = &itemdb->packages[count].random_groups[gidx].random_list[r]; @@ -1583,14 +1600,15 @@ int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) { SQL->GetData(handle, 19, &data, NULL); id.flag.no_refine = data && atoi(data) ? 0 : 1; SQL->GetData(handle, 20, &data, NULL); id.look = data ? atoi(data) : 0; SQL->GetData(handle, 21, &data, NULL); id.flag.bindonequip = data && atoi(data) ? 1 : 0; - SQL->GetData(handle, 22, &data, NULL); id.flag.buyingstore = data && atoi(data) ? 1 : 0; - SQL->GetData(handle, 23, &data, NULL); id.delay = data ? atoi(data) : 0; - SQL->GetData(handle, 24, &data, NULL); id.flag.trade_restriction = data ? atoi(data) : ITR_NONE; - SQL->GetData(handle, 25, &data, NULL); id.gm_lv_trade_override = data ? atoi(data) : 0; - SQL->GetData(handle, 26, &data, NULL); id.item_usage.flag = data ? atoi(data) : INR_NONE; - SQL->GetData(handle, 27, &data, NULL); id.item_usage.override = data ? atoi(data) : 0; - SQL->GetData(handle, 28, &data, NULL); id.stack.amount = data ? atoi(data) : 0; - SQL->GetData(handle, 29, &data, NULL); + SQL->GetData(handle, 22, &data, NULL); id.flag.force_serial = data && atoi(data) ? 1 : 0; + SQL->GetData(handle, 23, &data, NULL); id.flag.buyingstore = data && atoi(data) ? 1 : 0; + SQL->GetData(handle, 24, &data, NULL); id.delay = data ? atoi(data) : 0; + SQL->GetData(handle, 25, &data, NULL); id.flag.trade_restriction = data ? atoi(data) : ITR_NONE; + SQL->GetData(handle, 26, &data, NULL); id.gm_lv_trade_override = data ? atoi(data) : 0; + SQL->GetData(handle, 27, &data, NULL); id.item_usage.flag = data ? atoi(data) : INR_NONE; + SQL->GetData(handle, 28, &data, NULL); id.item_usage.override = data ? atoi(data) : 0; + SQL->GetData(handle, 29, &data, NULL); id.stack.amount = data ? atoi(data) : 0; + SQL->GetData(handle, 30, &data, NULL); if (data) { int stack_flag = atoi(data); id.stack.inventory = (stack_flag&1)!=0; @@ -1657,6 +1675,7 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source) * BindOnEquip: (true or false) * BuyingStore: (true or false) * Delay: Delay to use item + * ForceSerial: (true or false) * Trade: { * override: Group to override * nodrop: (true or false) @@ -1790,6 +1809,9 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source) if( (t = libconfig->setting_get_member(it, "BindOnEquip")) ) id.flag.bindonequip = libconfig->setting_get_bool(t) ? 1 : 0; + + if( (t = libconfig->setting_get_member(it, "ForceSerial")) ) + id.flag.force_serial = libconfig->setting_get_bool(t) ? 1 : 0; if ( (t = libconfig->setting_get_member(it, "BuyingStore")) ) id.flag.buyingstore = libconfig->setting_get_bool(t) ? 1 : 0; @@ -1992,7 +2014,7 @@ int itemdb_readdb_sql(const char *tablename) { " `matk`, `defence`, `range`, `slots`," " `equip_jobs`, `equip_upper`, `equip_genders`, `equip_locations`," " `weapon_level`, `equip_level_min`, `equip_level_max`, `refineable`," - " `view`, `bindonequip`, `buyingstore`, `delay`," + " `view`, `bindonequip`, `forceserial`, `buyingstore`, `delay`," " `trade_flag`, `trade_group`, `nouse_flag`, `nouse_group`," " `stack_amount`, `stack_flag`, `sprite`, `script`," " `equip_script`, `unequip_script`" diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 624080c3a..e50ebfd3d 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -398,6 +398,7 @@ struct item_package_rand_entry { unsigned short hours; unsigned int announce : 1; unsigned int named : 1; + unsigned int force_serial: 1; struct item_package_rand_entry *next; }; @@ -407,6 +408,7 @@ struct item_package_must_entry { unsigned short hours; unsigned int announce : 1; unsigned int named : 1; + unsigned int force_serial : 1; }; struct item_package_rand_group { @@ -466,6 +468,7 @@ struct item_data { unsigned buyingstore : 1; unsigned bindonequip : 1; unsigned keepafteruse : 1; + unsigned force_serial : 1; } flag; struct {// item stacking limitation unsigned short amount; diff --git a/src/map/packets.h b/src/map/packets.h index 53278f66e..6623c091c 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -448,6 +448,8 @@ packet(0x020a,10); //packet(0x020b,-1); //packet(0x020c,-1); packet(0x020d,-1); +packet(0x974,2,clif->cancelmergeitem); +packet(0x96e,-1,clif->ackmergeitems); //2004-07-05aSakexe #if PACKETVER >= 20040705 diff --git a/src/map/pc.c b/src/map/pc.c index 9e9f993d0..4dac559e2 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4448,6 +4448,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l if( sd->status.inventory[i].nameid == item_data->nameid && sd->status.inventory[i].bound == item_data->bound && sd->status.inventory[i].expire_time == 0 && + sd->status.inventory[i].unique_id == item_data->unique_id && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 ) { if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) ) return 5; @@ -4475,8 +4476,8 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l clif->additem(sd,i,amount,0); } - if( !itemdb->isstackable2(data) && !item_data->unique_id ) - sd->status.inventory[i].unique_id = itemdb->unique_id(sd); + if( ( !itemdb->isstackable2(data) || data->flag.force_serial || data->type == IT_CASH) && !item_data->unique_id ) + sd->status.inventory[i].unique_id = itemdb->unique_id(sd); logs->pick_pc(sd, log_type, amount, &sd->status.inventory[i],sd->inventory_data[i]); @@ -5028,7 +5029,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun sd->status.cart[i].card[2] == item_data->card[2] && sd->status.cart[i].card[3] == item_data->card[3] ); }; - if( i < MAX_CART ) + if( i < MAX_CART && item_data->unique_id == sd->status.cart[i].unique_id) {// item already in cart, stack it if( amount > MAX_AMOUNT - sd->status.cart[i].amount || ( data->stack.cart && amount > data->stack.amount - sd->status.cart[i].amount ) ) return 2; // no room diff --git a/src/map/script.c b/src/map/script.c index 47ac151ed..f2fce3a8f 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -19691,6 +19691,17 @@ BUILDIN(showscript) { return true; } +BUILDIN(mergeitem) +{ + struct map_session_data *sd = script->rid2sd(st); + + if (sd == NULL) + return true; + + clif->openmergeitem(sd->fd, sd); + + return true; +} /** place holder for the translation macro **/ BUILDIN(_) { return true; @@ -20329,6 +20340,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(channelmes, "ss"), BUILDIN_DEF(showscript, "s?"), + BUILDIN_DEF(mergeitem,""), BUILDIN_DEF(_,"s"), }; int i, len = ARRAYLENGTH(BUILDIN); diff --git a/src/map/storage.c b/src/map/storage.c index 0a22b9ec6..95194bc47 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -109,7 +109,8 @@ int compare_item(struct item *a, struct item *b) a->refine == b->refine && a->attribute == b->attribute && a->expire_time == b->expire_time && - a->bound == b->bound ) + a->bound == b->bound && + a->unique_id == b->unique_id) { int i; for (i = 0; i < MAX_SLOTS && (a->card[i] == b->card[i]); i++); @@ -155,6 +156,7 @@ int storage_additem(struct map_session_data* sd, struct item* item_data, int amo {// existing items found, stack them if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.storage && amount > data->stack.amount - stor->items[i].amount ) ) return 1; + stor->items[i].amount += amount; clif->storageitemadded(sd,&stor->items[i],i,amount); return 0; |