From 3c0bb6cec420f251ffbc45eaf9196e11fc72dfa1 Mon Sep 17 00:00:00 2001 From: skotlex Date: Thu, 18 May 2006 16:55:07 +0000 Subject: - Rewrote/cleaned up several functions in storage.c - Optimized pc_additem comparisons to account for items with more than four slots. - Updated clif.c to enable retrieval of items from cart/storage while trading. Exception is retrieving items from the cart while vending. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6642 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/clif.c | 14 +- src/map/pc.c | 44 +++---- src/map/storage.c | 383 +++++++++++++++++++++++++++++------------------------- 3 files changed, 227 insertions(+), 214 deletions(-) (limited to 'src/map') diff --git a/src/map/clif.c b/src/map/clif.c index 95d7c9ceb..1a52a33d1 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9432,9 +9432,6 @@ void clif_parse_PutItemToCart(int fd,struct map_session_data *sd) void clif_parse_GetItemFromCart(int fd,struct map_session_data *sd) { RFIFOHEAD(fd); - - if (clif_trading(sd)) - return; pc_getitemfromcart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4)); } @@ -9951,7 +9948,7 @@ void clif_parse_MoveToKafra(int fd, struct map_session_data *sd) { item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2; item_amount = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]); - if (item_index < 0 || item_index >= MAX_INVENTORY) + if (item_index < 0 || item_index >= MAX_INVENTORY || item_amount < 1) return; if (sd->state.storage_flag == 1) @@ -9968,9 +9965,6 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd) { int item_index, item_amount; RFIFOHEAD(fd); - if (clif_trading(sd)) - return; - item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-1; item_amount = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]); @@ -9987,7 +9981,7 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd) { void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) { RFIFOHEAD(fd); - if (clif_trading(sd)) + if(sd->vender_id) return; if (sd->state.storage_flag == 1) @@ -10003,7 +9997,7 @@ void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) { void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) { RFIFOHEAD(fd); - if (clif_trading(sd)) + if (sd->vender_id) return; if (sd->state.storage_flag == 1) storage_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); @@ -10152,8 +10146,6 @@ void clif_parse_VendingListReq(int fd, struct map_session_data *sd) { */ void clif_parse_PurchaseReq(int fd, struct map_session_data *sd) { RFIFOHEAD(fd); - if (clif_trading(sd)) - return; vending_purchasereq(sd, RFIFOW(fd,2), RFIFOL(fd,4), RFIFOP(fd,8)); } diff --git a/src/map/pc.c b/src/map/pc.c index 1a3a88486..1797bb36b 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -2384,30 +2384,30 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount) { struct item_data *data; int i; - long w; + int w; nullpo_retr(1, sd); nullpo_retr(1, item_data); if(item_data->nameid <= 0 || amount <= 0) return 1; + if(amount > MAX_AMOUNT) + return 5; + data = itemdb_search(item_data->nameid); w = data->weight*amount; - if(w + (long)sd->weight > (long)sd->max_weight || w + (long)sd->weight < 0) //Weight overflow check? + if(w > sd->max_weight - sd->weight) return 2; i = MAX_INVENTORY; - if (!itemdb_isequip2(data)){ - // 装 備品ではないので、既所有品なら個数のみ変化させる + if (!itemdb_isequip2(data)){ //Stackable for (i = 0; i < MAX_INVENTORY; i++) if(sd->status.inventory[i].nameid == item_data->nameid && - sd->status.inventory[i].card[0] == item_data->card[0] && - sd->status.inventory[i].card[1] == item_data->card[1] && - sd->status.inventory[i].card[2] == item_data->card[2] && - sd->status.inventory[i].card[3] == item_data->card[3]) + memcmp(&sd->status.inventory[i].card,&item_data->card, + sizeof(item_data->card))==0) { - if (amount < 0 || amount > MAX_AMOUNT || sd->status.inventory[i].amount + amount > MAX_AMOUNT) + if (amount > MAX_AMOUNT - sd->status.inventory[i].amount) return 5; sd->status.inventory[i].amount += amount; clif_additem(sd,i,amount,0); @@ -2415,22 +2415,18 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount) } } if (i >= MAX_INVENTORY){ - // 装 備品か未所有品だったので空き欄へ追加 i = pc_search_inventory(sd,0); - if(i >= 0) { - // clear equips field first, just in case - if (item_data->equip != 0) - item_data->equip = 0; - memcpy(&sd->status.inventory[i], item_data, sizeof(sd->status.inventory[0])); - sd->status.inventory[i].amount = amount; - sd->inventory_data[i] = data; - clif_additem(sd,i,amount,0); - } - else return 4; - } - sd->weight += (int)w; + if(i<0) return 4; + // clear equips field first, just in case + if (item_data->equip) + item_data->equip = 0; + memcpy(&sd->status.inventory[i], item_data, sizeof(item_data)); + sd->status.inventory[i].amount = amount; + sd->inventory_data[i] = data; + clif_additem(sd,i,amount,0); + } + sd->weight += w; clif_updatestatus(sd,SP_WEIGHT); - return 0; } @@ -2857,7 +2853,7 @@ int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount) item_data=&sd->status.cart[idx]; - if( item_data->nameid==0 || amount < 1 || item_data->amountvender_id ) + if(item_data->nameid==0 || amount < 1 || item_data->amountvender_id ) return 1; if((flag = pc_additem(sd,item_data,amount)) == 0) return pc_cart_delitem(sd,idx,amount,0); diff --git a/src/map/storage.c b/src/map/storage.c index db5f097ee..0184d2978 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -123,52 +123,51 @@ int storage_delete(int account_id) */ int storage_storageopen(struct map_session_data *sd) { -//#ifdef TXT_ONLY struct storage *stor; -//#endif nullpo_retr(0, sd); if(sd->state.finalsave) //Refuse to open storage when you had your last save done. return 1; + + if(sd->state.storage_flag) + return 1; //Already open? - if( pc_can_give_items(pc_isGM(sd)) ) { //check is this GM level is allowed to put items to storage + if(pc_can_give_items(pc_isGM(sd))) + { //check is this GM level is allowed to put items to storage clif_displaymessage(sd->fd, msg_txt(246)); return 1; } -//Storage loading always from sql idea from Komurka [Skotlex] - removed as it opens exploits when server lags. -//#ifdef TXT_ONLY - if((stor = idb_get(storage_db,sd->status.account_id)) != NULL) { - if (stor->storage_status == 0 && sd->state.storage_flag == 0) { - stor->storage_status = 1; - sd->state.storage_flag = 1; - clif_storageitemlist(sd,stor); - clif_storageequiplist(sd,stor); - clif_updatestorageamount(sd,stor); - return 0; - } - } else -//#endif + + if((stor = idb_get(storage_db,sd->status.account_id)) == NULL) + { //Request storage. intif_request_storage(sd->status.account_id); - - return 1; + return 1; + } + + if (stor->storage_status) + return 1; //Already open/player already has it open... + + stor->storage_status = 1; + sd->state.storage_flag = 1; + clif_storageitemlist(sd,stor); + clif_storageequiplist(sd,stor); + clif_updatestorageamount(sd,stor); + return 0; } /*========================================== - * カプラ倉庫へアイテム追加 + * Internal add-item function. *------------------------------------------ */ -int storage_additem(struct map_session_data *sd,struct storage *stor,struct item *item_data,int amount) +static int storage_additem(struct map_session_data *sd,struct storage *stor,struct item *item_data,int amount) { struct item_data *data; int i; - nullpo_retr(1, sd); - nullpo_retr(1, stor); - nullpo_retr(1, item_data); - if(item_data->nameid <= 0 || amount <= 0) return 1; - nullpo_retr(1, data = itemdb_search(item_data->nameid)); + + data = itemdb_search(item_data->nameid); if (!itemdb_canstore(item_data->nameid, pc_isGM(sd))) { //Check if item is storable. [Skotlex] @@ -176,46 +175,38 @@ int storage_additem(struct map_session_data *sd,struct storage *stor,struct item return 1; } - i=MAX_STORAGE; - if(!itemdb_isequip2(data)){ - // 装備品ではないので、既所有品なら個数のみ変化させる + if(!itemdb_isequip2(data)){ //Stackable for(i=0;istorage_[i], item_data)) { - if(stor->storage_[i].amount+amount > MAX_AMOUNT) + if(amount > MAX_AMOUNT - stor->storage_[i].amount) return 1; stor->storage_[i].amount+=amount; clif_storageitemadded(sd,stor,i,amount); - break; + stor->dirty = 1; + return 0; } } } - if(i>=MAX_STORAGE){ - // 装備品か未所有品だったので空き欄へ追加 - for(i=0;istorage_[i].nameid==0){ - memcpy(&stor->storage_[i],item_data,sizeof(stor->storage_[0])); - stor->storage_[i].amount=amount; - stor->storage_amount++; - clif_storageitemadded(sd,stor,i,amount); - clif_updatestorageamount(sd,stor); - break; - } - } - if(i>=MAX_STORAGE) - return 1; - } + //Add item + for(i=0;istorage_[i].nameid;i++); + + if(i>=MAX_STORAGE) + return 1; + memcpy(&stor->storage_[i],item_data,sizeof(stor->storage_[0])); + stor->storage_[i].amount=amount; + stor->storage_amount++; + clif_storageitemadded(sd,stor,i,amount); + clif_updatestorageamount(sd,stor); stor->dirty = 1; return 0; } /*========================================== - * カプラ倉庫アイテムを減らす + * Internal del-item function *------------------------------------------ */ -int storage_delitem(struct map_session_data *sd,struct storage *stor,int n,int amount) +static int storage_delitem(struct map_session_data *sd,struct storage *stor,int n,int amount) { - nullpo_retr(1, sd); - nullpo_retr(1, stor); if(stor->storage_[n].nameid==0 || stor->storage_[n].amountstatus.account_id)); - if( (stor->storage_amount <= MAX_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open - if(index>=0 && indexstatus.inventory[index].amount) && (amount > 0) ) { //valid amount -// log_tostorage(sd, index, 0); - if(storage_additem(sd,stor,&sd->status.inventory[index],amount)==0) - // remove item from inventory - pc_delitem(sd,index,amount,0); - } // valid amount - }// valid index - }// storage not full & storage open + if((stor->storage_amount > MAX_STORAGE) || !stor->storage_status) + return 0; // storage full / storage closed - return 0; + if(index<0 || index>=MAX_INVENTORY) + return 0; + + if(sd->status.inventory[index].nameid <= 0) + return 0; //No item on that spot + + if(amount < 1 || amount < sd->status.inventory[index].amount) + return 0; + +// log_tostorage(sd, index, 0); + if(storage_additem(sd,stor,&sd->status.inventory[index],amount)==0) + // remove item from inventory + pc_delitem(sd,index,amount,0); + + return 1; } /*========================================== - * カプラ倉庫から出す + * Retrieve an item from the storage. *------------------------------------------ */ int storage_storageget(struct map_session_data *sd,int index,int amount) @@ -268,22 +265,25 @@ int storage_storageget(struct map_session_data *sd,int index,int amount) nullpo_retr(0, sd); nullpo_retr(0, stor=account2storage2(sd->status.account_id)); - if(stor->storage_status == 1) { // storage open - if(index>=0 && indexstorage_[index].amount) && (amount > 0) ) { //valid amount - if((flag = pc_additem(sd,&stor->storage_[index],amount)) == 0) - storage_delitem(sd,stor,index,amount); - //else //taken out because it can dupe items if the above fails somehow :) [Kevin] - //clif_additem(sd,0,0,flag); -// log_fromstorage(sd, index, 0); - } // valid amount - }// valid index - }// storage open + + if(index<0 || index>=MAX_STORAGE) + return 0; - return 0; + if(stor->storage_[index].nameid <= 0) + return 0; //Nothing there + + if(amount < 1 || amount > stor->storage_[index].amount) + return 0; + + if((flag = pc_additem(sd,&stor->storage_[index],amount)) == 0) + storage_delitem(sd,stor,index,amount); + else + clif_additem(sd,0,0,flag); +// log_fromstorage(sd, index, 0); + return 1; } /*========================================== - * カプラ倉庫へカートから入れる + * Move an item from cart to storage. *------------------------------------------ */ int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount) @@ -293,20 +293,26 @@ int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount) nullpo_retr(0, sd); nullpo_retr(0, stor=account2storage2(sd->status.account_id)); - if( (stor->storage_amount <= MAX_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open - if(index>=0 && indexstatus.cart[index].amount) && (amount > 0) ) { //valid amount - if(storage_additem(sd,stor,&sd->status.cart[index],amount)==0) - pc_cart_delitem(sd,index,amount,0); - } // valid amount - }// valid index - }// storage not full & storage open + if(stor->storage_amount > MAX_STORAGE || !stor->storage_status) + return 0; // storage full / storage closed - return 0; + if(index< 0 || index>=MAX_CART) + return 0; + + if(sd->status.cart[index].nameid <= 0) + return 0; //No item there. + + if(amount < 1 || amount > sd->status.cart[index].amount) + return 0; + + if(storage_additem(sd,stor,&sd->status.cart[index],amount)==0) + pc_cart_delitem(sd,index,amount,0); + + return 1; } /*========================================== - * カプラ倉庫からカートへ出す + * Get from Storage to the Cart *------------------------------------------ */ int storage_storagegettocart(struct map_session_data *sd,int index,int amount) @@ -316,17 +322,22 @@ int storage_storagegettocart(struct map_session_data *sd,int index,int amount) nullpo_retr(0, sd); nullpo_retr(0, stor=account2storage2(sd->status.account_id)); - if(stor->storage_status == 1) { // storage open - if(index>=0 && indexstorage_[index].amount) && (amount > 0) ) { //valid amount - if(pc_cart_additem(sd,&stor->storage_[index],amount)==0){ - storage_delitem(sd,stor,index,amount); - } - } // valid amount - }// valid index - }// storage open + if(!stor->storage_status) + return 0; + + if(index< 0 || index>=MAX_STORAGE) + return 0; + + if(stor->storage_[index].nameid <= 0) + return 0; //Nothing there. + + if(amount < 1 || amount > stor->storage_[index].amount) + return 0; + + if(pc_cart_additem(sd,&stor->storage_[index],amount)==0) + storage_delitem(sd,stor,index,amount); - return 0; + return 1; } @@ -342,15 +353,16 @@ int storage_storageclose(struct map_session_data *sd) nullpo_retr(0, stor=account2storage2(sd->status.account_id)); clif_storageclose(sd); - chrif_save(sd, 0); //This will invoke the storage save function as well. [Skotlex] + if (stor->storage_status) + chrif_save(sd,0); //This will invoke the storage save function as well. [Skotlex] stor->storage_status=0; - sd->state.storage_flag = 0; + sd->state.storage_flag=0; return 0; } /*========================================== - * ログアウト時開いているカプラ倉庫の保存 + * When quitting the game. *------------------------------------------ */ int storage_storage_quit(struct map_session_data *sd, int flag) @@ -447,26 +459,26 @@ int storage_guild_storageopen(struct map_session_data *sd) if(sd->state.finalsave) //Refuse to open storage when you had your last save done. return 1; + if(sd->state.storage_flag) + return 1; //Can't open both storages at a time. + if( pc_can_give_items(pc_isGM(sd)) ) { //check is this GM level can open guild storage and store items [Lupus] clif_displaymessage(sd->fd, msg_txt(246)); return 1; } - if((gstor = guild2storage2(sd->status.guild_id)) != NULL) { - if(gstor->storage_status) - return 1; - if(sd->state.storage_flag) - return 1; //Can't open both storages at a time. - gstor->storage_status = 1; - sd->state.storage_flag = 2; - clif_guildstorageitemlist(sd,gstor); - clif_guildstorageequiplist(sd,gstor); - clif_updateguildstorageamount(sd,gstor); + if((gstor = guild2storage2(sd->status.guild_id)) == NULL) { + intif_request_guild_storage(sd->status.account_id,sd->status.guild_id); return 0; } - else - intif_request_guild_storage(sd->status.account_id,sd->status.guild_id); - + if(gstor->storage_status) + return 1; + + gstor->storage_status = 1; + sd->state.storage_flag = 2; + clif_guildstorageitemlist(sd,gstor); + clif_guildstorageequiplist(sd,gstor); + clif_updateguildstorageamount(sd,gstor); return 0; } @@ -489,34 +501,29 @@ int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor return 1; } - i=MAX_GUILD_STORAGE; - if(!itemdb_isequip2(data)){ - // 装備品ではないので、既所有品なら個数のみ変化させる + if(!itemdb_isequip2(data)){ //Stackable for(i=0;istorage_[i], item_data)) { if(stor->storage_[i].amount+amount > MAX_AMOUNT) return 1; stor->storage_[i].amount+=amount; clif_guildstorageitemadded(sd,stor,i,amount); - break; - } - } - } - if(i>=MAX_GUILD_STORAGE){ - // 装備品か未所有品だったので空き欄へ追加 - for(i=0;istorage_[i].nameid==0){ - memcpy(&stor->storage_[i],item_data,sizeof(stor->storage_[0])); - stor->storage_[i].amount=amount; - stor->storage_amount++; - clif_guildstorageitemadded(sd,stor,i,amount); - clif_updateguildstorageamount(sd,stor); - break; + stor->dirty = 1; + return 0; } } - if(i>=MAX_GUILD_STORAGE) - return 1; } + //Add item + for(i=0;istorage_[i].nameid;i++); + + if(i>=MAX_GUILD_STORAGE) + return 1; + + memcpy(&stor->storage_[i],item_data,sizeof(stor->storage_[0])); + stor->storage_[i].amount=amount; + stor->storage_amount++; + clif_guildstorageitemadded(sd,stor,i,amount); + clif_updateguildstorageamount(sd,stor); stor->dirty = 1; return 0; } @@ -545,21 +552,25 @@ int storage_guild_storageadd(struct map_session_data *sd,int index,int amount) struct guild_storage *stor; nullpo_retr(0, sd); + nullpo_retr(0, stor=guild2storage2(sd->status.guild_id)); + + if (!stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE) + return 0; + + if(index<0 || index>=MAX_INVENTORY) + return 0; - if((stor=guild2storage2(sd->status.guild_id)) != NULL) { - if( (stor->storage_amount <= MAX_GUILD_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open - if(index>=0 && indexstatus.inventory[index].amount) && (amount > 0) ) { //valid amount -// log_tostorage(sd, index, 1); - if(guild_storage_additem(sd,stor,&sd->status.inventory[index],amount)==0) - // remove item from inventory - pc_delitem(sd,index,amount,0); - } // valid amount - }// valid index - }// storage not full & storage open - } + if(sd->status.inventory[index].nameid <= 0) + return 0; + + if(amount < 1 || amount > sd->status.inventory[index].amount) + return 0; - return 0; +// log_tostorage(sd, index, 1); + if(guild_storage_additem(sd,stor,&sd->status.inventory[index],amount)==0) + pc_delitem(sd,index,amount,0); + + return 1; } int storage_guild_storageget(struct map_session_data *sd,int index,int amount) @@ -568,20 +579,25 @@ int storage_guild_storageget(struct map_session_data *sd,int index,int amount) int flag; nullpo_retr(0, sd); + nullpo_retr(0, stor=guild2storage2(sd->status.guild_id)); - if((stor=guild2storage2(sd->status.guild_id)) != NULL) { - if(stor->storage_status == 1) { // storage open - if(index>=0 && indexstorage_[index].amount) && (amount > 0) ) { //valid amount - if((flag = pc_additem(sd,&stor->storage_[index],amount)) == 0) - guild_storage_delitem(sd,stor,index,amount); - else - clif_additem(sd,0,0,flag); -// log_fromstorage(sd, index, 1); - } // valid amount - }// valid index - }// storage open - } + if(!stor->storage_status) + return 0; + + if(index<0 || index>=MAX_GUILD_STORAGE) + return 0; + + if(stor->storage_[index].nameid <= 0) + return 0; + + if(amount < 1 || amount > stor->storage_[index].amount) + return 0; + + if((flag = pc_additem(sd,&stor->storage_[index],amount)) == 0) + guild_storage_delitem(sd,stor,index,amount); + else + clif_additem(sd,0,0,flag); +// log_fromstorage(sd, index, 1); return 0; } @@ -591,19 +607,24 @@ int storage_guild_storageaddfromcart(struct map_session_data *sd,int index,int a struct guild_storage *stor; nullpo_retr(0, sd); + nullpo_retr(0, stor=guild2storage2(sd->status.guild_id)); - if((stor=guild2storage2(sd->status.guild_id)) != NULL) { - if( (stor->storage_amount <= MAX_GUILD_STORAGE) && (stor->storage_status == 1) ) { // storage not full & storage open - if(index>=0 && indexstatus.cart[index].amount) && (amount > 0) ) { //valid amount - if(guild_storage_additem(sd,stor,&sd->status.cart[index],amount)==0) - pc_cart_delitem(sd,index,amount,0); - } // valid amount - }// valid index - }// storage not full & storage open - } + if(!stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE) + return 0; - return 0; + if(index<0 || index>=MAX_CART) + return 0; + + if(sd->status.cart[index].nameid <= 0) + return 0; + + if(amount < 1 || amount > sd->status.cart[index].amount) + return 0; + + if(guild_storage_additem(sd,stor,&sd->status.cart[index],amount)==0) + pc_cart_delitem(sd,index,amount,0); + + return 1; } int storage_guild_storagegettocart(struct map_session_data *sd,int index,int amount) @@ -611,20 +632,24 @@ int storage_guild_storagegettocart(struct map_session_data *sd,int index,int amo struct guild_storage *stor; nullpo_retr(0, sd); + nullpo_retr(0, stor=guild2storage2(sd->status.guild_id)); - if((stor=guild2storage2(sd->status.guild_id)) != NULL) { - if(stor->storage_status == 1) { // storage open - if(index>=0 && indexstorage_[index].amount) && (amount > 0) ) { //valid amount - if(pc_cart_additem(sd,&stor->storage_[index],amount)==0){ - guild_storage_delitem(sd,stor,index,amount); - } - } // valid amount - }// valid index - }// storage open - } + if(!stor->storage_status) + return 0; - return 0; + if(index<0 || index>=MAX_GUILD_STORAGE) + return 0; + + if(stor->storage_[index].nameid<=0) + return 0; + + if(amount < 1 || amount > stor->storage_[index].amount) + return 0; + + if(pc_cart_additem(sd,&stor->storage_[index],amount)==0) + guild_storage_delitem(sd,stor,index,amount); + + return 1; } int storage_guild_storagesave(int account_id, int guild_id) -- cgit v1.2.3-70-g09d2