diff options
-rw-r--r-- | Changelog-Renewal.txt | 1 | ||||
-rw-r--r-- | db/Changelog.txt | 2 | ||||
-rw-r--r-- | db/item_stack.txt | 27 | ||||
-rw-r--r-- | src/map/itemdb.c | 41 | ||||
-rw-r--r-- | src/map/itemdb.h | 8 | ||||
-rw-r--r-- | src/map/pc.c | 26 | ||||
-rw-r--r-- | src/map/storage.c | 14 |
7 files changed, 113 insertions, 6 deletions
diff --git a/Changelog-Renewal.txt b/Changelog-Renewal.txt index 4d0faaaf6..858f42379 100644 --- a/Changelog-Renewal.txt +++ b/Changelog-Renewal.txt @@ -1,6 +1,7 @@ Date Added 2010/12/27 + * Added item stacking limit database (item_stack.txt) required for runes and other 3rd class related skill items. [Ai4rei] * Merged fixes from trunk for script command 'checkweight' (r14631) and skill-based item production (r14633). [Ai4rei] 2010/12/26 * Merged changes from trunk (r14496:14630). [Ai4rei] diff --git a/db/Changelog.txt b/db/Changelog.txt index 2e974a3da..9403e42f4 100644 --- a/db/Changelog.txt +++ b/db/Changelog.txt @@ -8,6 +8,8 @@ 1475 Equestrian's Spear: NEED INFO. 13005 Angelic Wing Dagger: NEED INFO. ======================= +2010/12/27 + * Rev. 14634 Added item stacking limitation database 'item_stack.txt'. [Ai4rei] 2010/12/16 * Rev. 14596 Added missing pet db documentation for fields 'attack_rate', 'defence_attack_rate', 'change_target_rate', 'pet_script' and 'loyal_script' based on the one provided by frenzmu06 (bugreport:4636, follow up to r13752). [Ai4rei] 2010/12/13 diff --git a/db/item_stack.txt b/db/item_stack.txt new file mode 100644 index 000000000..b2932b56b --- /dev/null +++ b/db/item_stack.txt @@ -0,0 +1,27 @@ +// Item Stacking Restriction File +// Prevents an item to be stacked more than x times in given +// inventory types. Generally used by 3rd class related skill items. +// Format: <item id>,<stack limit amount>,<type> +// Type mask values: +// &1: Character inventory restriction +// &2: Character cart restriction +// &4: Account storage restriction +// &8: Guild storage restriction +// Example: +// 512,4,12 // Will not allow more than 4 Apples in storages. +// Note: +// Stack limit of 0 will disable a restriction. + +// Rune Knight +12725,20,1 // Nauthiz Rune +12726,20,1 // Raido Rune +12727,20,1 // Berkana Rune +12728,20,1 // Isa Rune +12729,20,1 // Othila Rune +12730,20,1 // Uruz Rune +12731,20,1 // Thurisaz Rune +12732,20,1 // Wyrd Rune +12733,20,1 // Hagalaz Rune + +// Arch Bishop +12333,3,1 // Ancilla diff --git a/src/map/itemdb.c b/src/map/itemdb.c index ce10f4f39..6455d10b6 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -724,6 +724,46 @@ static int itemdb_read_itemdelay(void) return 0; } +/*================================================================== + * Reads item stacking restrictions + *----------------------------------------------------------------*/ +static bool itemdb_read_stack(char* fields[], int columns, int current) +{// <item id>,<stack limit amount>,<type> + unsigned short nameid, amount; + unsigned int type; + struct item_data* id; + + nameid = (unsigned short)strtoul(fields[0], NULL, 10); + + if( ( id = itemdb_exists(nameid) ) == NULL ) + { + ShowWarning("itemdb_read_stack: Unknown item id '%hu'.\n", nameid); + return false; + } + + if( !itemdb_isstackable2(id) ) + { + ShowWarning("itemdb_read_stack: Item id '%hu' is not stackable.\n", nameid); + return false; + } + + amount = (unsigned short)strtoul(fields[1], NULL, 10); + type = strtoul(fields[2], NULL, 10); + + if( !amount ) + {// ignore + return true; + } + + id->stack.amount = amount; + id->stack.inventory = (type&1)!=0; + id->stack.cart = (type&2)!=0; + id->stack.storage = (type&4)!=0; + id->stack.guildstorage = (type&8)!=0; + + return true; +} + /*====================================== * Applies gender restrictions according to settings. [Skotlex] *======================================*/ @@ -1040,6 +1080,7 @@ static void itemdb_read(void) itemdb_read_noequip(); itemdb_read_itemtrade(); itemdb_read_itemdelay(); + sv_readdb(db_path, "item_stack.txt", ',', 3, 3, -1, &itemdb_read_stack); } /*========================================== diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 3fb14b2d4..bc1d5b3b0 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -77,6 +77,14 @@ struct item_data { unsigned trade_restriction : 7; //Item restrictions mask [Skotlex] unsigned autoequip: 1; } flag; + struct + {// item stacking limitation + unsigned short amount; + unsigned int inventory:1; + unsigned int cart:1; + unsigned int storage:1; + unsigned int guildstorage:1; + } stack; short gm_lv_trade_override; //GM-level to override trade_restriction }; diff --git a/src/map/pc.c b/src/map/pc.c index 94121eba9..a444c7bba 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -3200,18 +3200,25 @@ int pc_modifysellvalue(struct map_session_data *sd,int orig_value) int pc_checkadditem(struct map_session_data *sd,int nameid,int amount) { int i; + struct item_data* data; nullpo_ret(sd); if(amount > MAX_AMOUNT) return ADDITEM_OVERAMOUNT; - if(!itemdb_isstackable(nameid)) + data = itemdb_search(nameid); + + if(!itemdb_isstackable2(data)) return ADDITEM_NEW; + if( data->stack.inventory && amount > data->stack.amount ) + return ADDITEM_OVERAMOUNT; + for(i=0;i<MAX_INVENTORY;i++){ + // FIXME: This does not consider the checked item's cards, thus could check a wrong slot for stackability. if(sd->status.inventory[i].nameid==nameid){ - if(sd->status.inventory[i].amount+amount > MAX_AMOUNT) + if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) ) return ADDITEM_OVERAMOUNT; return ADDITEM_EXIST; } @@ -3349,6 +3356,12 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount) return 5; data = itemdb_search(item_data->nameid); + + if( data->stack.inventory && amount > data->stack.amount ) + {// item stack limitation + return 5; + } + w = data->weight*amount; if(sd->weight + w > sd->max_weight) return 2; @@ -3361,7 +3374,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount) { if( sd->status.inventory[i].nameid == item_data->nameid && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 ) { - if( amount > MAX_AMOUNT - sd->status.inventory[i].amount ) + if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) ) return 5; sd->status.inventory[i].amount += amount; clif_additem(sd,i,amount,0); @@ -3787,6 +3800,11 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun return 1; data = itemdb_search(item_data->nameid); + if( data->stack.cart && amount > data->stack.amount ) + {// item stack limitation + return 1; + } + if( !itemdb_cancartstore(item_data, pc_isGM(sd)) ) { // Check item trade restrictions [Skotlex] clif_displaymessage (sd->fd, msg_txt(264)); @@ -3807,7 +3825,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun if( i < MAX_CART ) {// item already in cart, stack it - if(sd->status.cart[i].amount+amount > MAX_AMOUNT) + if( amount > MAX_AMOUNT - sd->status.cart[i].amount || ( data->stack.cart && amount > data->stack.amount - sd->status.cart[i].amount ) ) return 1; // no room sd->status.cart[i].amount+=amount; diff --git a/src/map/storage.c b/src/map/storage.c index eb64d3eb4..9aa34d3e0 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -138,6 +138,11 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data, data = itemdb_search(item_data->nameid); + if( data->stack.storage && amount > data->stack.amount ) + {// item stack limitation + return 1; + } + if( !itemdb_canstore(item_data, pc_isGM(sd)) ) { //Check if item is storable. [Skotlex] clif_displaymessage (sd->fd, msg_txt(264)); @@ -150,7 +155,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data, { if( compare_item(&stor->items[i], item_data) ) {// existing items found, stack them - if( amount > MAX_AMOUNT - stor->items[i].amount ) + 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); @@ -398,6 +403,11 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto if(item_data->nameid <= 0 || amount <= 0) return 1; + if( data->stack.guildstorage && amount > data->stack.amount ) + {// item stack limitation + return 1; + } + if( !itemdb_canguildstore(item_data, pc_isGM(sd)) || item_data->expire_time ) { //Check if item is storable. [Skotlex] clif_displaymessage (sd->fd, msg_txt(264)); @@ -407,7 +417,7 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto if(itemdb_isstackable2(data)){ //Stackable for(i=0;i<MAX_GUILD_STORAGE;i++){ if(compare_item(&stor->items[i], item_data)) { - if(stor->items[i].amount+amount > MAX_AMOUNT) + if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.guildstorage && amount > data->stack.amount - stor->items[i].amount ) ) return 1; stor->items[i].amount+=amount; clif_storageitemadded(sd,&stor->items[i],i,amount); |