diff options
author | Kevin <Kevin@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-04-27 07:18:21 +0000 |
---|---|---|
committer | Kevin <Kevin@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-04-27 07:18:21 +0000 |
commit | 677598256feaad3bcef53805ad8c70e744a9b7d3 (patch) | |
tree | 3a4b061dc62ac53fbd80c1434990a47dca0d54d9 /src/map | |
parent | ab60cf06afb586b106991b4b9848dd9c107ddec2 (diff) | |
download | hercules-677598256feaad3bcef53805ad8c70e744a9b7d3.tar.gz hercules-677598256feaad3bcef53805ad8c70e744a9b7d3.tar.bz2 hercules-677598256feaad3bcef53805ad8c70e744a9b7d3.tar.xz hercules-677598256feaad3bcef53805ad8c70e744a9b7d3.zip |
Some major changes to @reloaditemdb to allow unloading of any item while map server is running.
- Delete any item from inventory/cart/open storages that went missing during the reload.
- Delete item from any shop that has this item.
- Refresh item screen for anyone who has a shop open.
- Delete mob db drop table references.
- Delete item from storage during load if it isn't in the item db.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12661 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/clif.c | 31 | ||||
-rw-r--r-- | src/map/itemdb.c | 156 | ||||
-rw-r--r-- | src/map/mob.h | 5 | ||||
-rw-r--r-- | src/map/npc.c | 13 | ||||
-rw-r--r-- | src/map/npc.h | 2 | ||||
-rw-r--r-- | src/map/pc.c | 5 | ||||
-rw-r--r-- | src/map/storage.c | 2 | ||||
-rw-r--r-- | src/map/storage.h | 2 |
8 files changed, 188 insertions, 28 deletions
diff --git a/src/map/clif.c b/src/map/clif.c index 55e9b1776..66a01b867 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1894,20 +1894,27 @@ void clif_storagelist(struct map_session_data *sd,struct storage *stor) if(stor->storage_[i].nameid<=0) continue; id = itemdb_search(stor->storage_[i].nameid); - if(!itemdb_isstackable2(id)) - { //Equippable - WBUFW(bufe,ne*20+4)=i+1; - clif_item_sub(bufe, ne*20+6, &stor->storage_[i], id, id->equip); - clif_addcards(WBUFP(bufe, ne*20+16), &stor->storage_[i]); - ne++; - } else { //Stackable - WBUFW(buf,n*s+4)=i+1; - clif_item_sub(buf, n*s+6, &stor->storage_[i], id,-1); + if(!id) + { + //Item not found, was probably deleted and then map server reloaded/item db reloaded + storage_delitem(sd, stor, i, stor->storage_[i].amount); + return; + } + else + if(!itemdb_isstackable2(id)) + { //Equippable + WBUFW(bufe,ne*20+4)=i+1; + clif_item_sub(bufe, ne*20+6, &stor->storage_[i], id, id->equip); + clif_addcards(WBUFP(bufe, ne*20+16), &stor->storage_[i]); + ne++; + } else { //Stackable + WBUFW(buf,n*s+4)=i+1; + clif_item_sub(buf, n*s+6, &stor->storage_[i], id,-1); #if PACKETVER >= 5 - clif_addcards(WBUFP(buf,n*s+14), &stor->storage_[i]); + clif_addcards(WBUFP(buf,n*s+14), &stor->storage_[i]); #endif - n++; - } + n++; + } } if(n){ #if PACKETVER < 5 diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 442508775..6cfbbca97 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -10,6 +10,10 @@ #include "battle.h" // struct battle_config #include "script.h" // item script processing #include "pc.h" // W_MUSICAL, W_WHIP +#include "storage.h" +#include "npc.h" +#include "clif.h" +#include "mob.h" #include <stdio.h> #include <stdlib.h> @@ -1008,6 +1012,22 @@ static void destroy_item_data(struct item_data* self, int free_self) aFree(self); } +/*========================================== + * Looks for an item, returns NULL if not found + *------------------------------------------*/ +struct item_data* itemdb_search2(int nameid) +{ + if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) ) + { + DBKey key; + if( itemdb_array[nameid] ) + return itemdb_array[nameid]; + key.i = nameid; + return NULL; + } + return (struct item_data*)idb_get(itemdb_other,nameid); +} + static int itemdb_final_sub(DBKey key,void *data,va_list ap) { struct item_data *id = (struct item_data *)data; @@ -1018,32 +1038,142 @@ static int itemdb_final_sub(DBKey key,void *data,va_list ap) return 0; } -static int itemdb_reload_sub(DBKey key,void *data,va_list ap) +int itemdb_reload_check_npc(DBKey key,void * data,va_list ap) { - struct item_data *id = (struct item_data *)data; + struct npc_data * nd = (struct npc_data *)data; + int offset = 0, i = 0; - if( id != &dummy_item && id->flag.db2) - destroy_item_data(id, 1); + if(nd->subtype != SHOP && nd->subtype != CASHSHOP) + return 0; + + while(i < nd->u.shop.count) + { + + if(itemdb_search2(nd->u.shop.shop_item[i].nameid) == NULL) + { + + nd->u.shop.count--; + + //Shift array to left, overwriting old data + for(offset = i; offset+1 < nd->u.shop.count; offset++); + { + nd->u.shop.shop_item[offset].nameid = nd->u.shop.shop_item[offset+1].nameid; + nd->u.shop.shop_item[offset].value = nd->u.shop.shop_item[offset+1].value; + } + + } + //increment counter if we didn't delete something + else + i++; + + } + + //Resize array + RECREATE(nd->u.shop.shop_item, struct npc_item_list, nd->u.shop.count); return 0; } -void itemdb_reload(void) +static int itemdb_reload_check(DBKey key,void *data,va_list ap) { - int i; + struct map_session_data *sd = (struct map_session_data *)data; + struct storage * stor; + struct item_data * id; + struct npc_data * nd; - for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i ) - if( itemdb_array[i] ) - if( itemdb_array[i]->flag.db2 ) + if(sd->npc_shopid) + { + nd = (struct npc_data*)map_id2bl(sd->npc_shopid); + clif_buylist(sd, nd); + } + + //First, handle all items in inventories/equiped, cart, and storage + for(i = 0; i < MAX_INVENTORY; i++) + { + if(!sd->status.inventory[i].nameid) + continue; + + id = itemdb_search2(sd->status.inventory[i].nameid); + if(id == NULL) + { + sd->inventory_data[i] = NULL; + pc_delitem(sd, i, sd->status.inventory[i].amount, 4); + } + else + { + sd->inventory_data[i] = id; + } + } + + //Delete nonexistant items from cart + for(i = 0; i < MAX_CART; i++) + { + if(!sd->status.cart[i].nameid) + continue; + + id = itemdb_search2(sd->status.cart[i].nameid); + if(id == NULL) + { + sd->inventory_data[i] = NULL; + pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0); + } + } + + //Delete storage + if(stor = account2storage2(sd->status.account_id)) + { + //If storage isn't found, it will be deleted whenever storage is loaded again + if(stor) + { + for(i = 0; i < MAX_STORAGE; i++) { - destroy_item_data(itemdb_array[i], 1); - memset(itemdb_array[i], 0, sizeof(struct item_data)); + if(!sd->status.inventory[i].nameid) + continue; + + if(itemdb_search2(sd->status.inventory[i].nameid) == NULL) + storage_delitem(sd, stor, i, stor->storage_[i].amount); } + } + } - itemdb_other->clear(itemdb_other, itemdb_reload_sub); + return 0; +} - itemdb_read(); +//Cleanup mob db drop tables +void itemdb_foreach_mobdb(void) +{ + int i = 0, j = 0; + struct item_data * id; + s_mob_db * mdb; + + for(i=0; i < MAX_MOB_DB; i++) + { + mdb = mob_db(i); + if(mdb == mob_dummy) + continue; + for(j=0; j < MAX_MOB_DROP; j++) + { + id = itemdb_search2(mdb->dropitem[j].nameid); + if(id == NULL) + { + mdb->dropitem[j].nameid = 0; + mdb->dropitem[j].p = 0; + } + } + } +} + +void itemdb_reload(void) +{ + + do_final_itemdb(); + do_init_itemdb(); + + //Update ALL items on the server + map_foreachpc(itemdb_reload_check); + npc_foreach(itemdb_reload_check_npc); + itemdb_foreach_mobdb(); } void do_final_itemdb(void) diff --git a/src/map/mob.h b/src/map/mob.h index f01b4fff1..44fae102e 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -83,6 +83,11 @@ struct mob_db { struct spawn_info spawn[10]; }; +typedef struct mob_db s_mob_db; +extern struct mob_db *mob_db_data[MAX_MOB_DB+1]; +struct mob_db *mob_db(int index); +extern struct mob_db *mob_dummy; + struct mob_data { struct block_list bl; struct unit_data ud; diff --git a/src/map/npc.c b/src/map/npc.c index 98dd2d609..f1ff119da 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -150,6 +150,19 @@ struct npc_data* npc_name2id(const char* name) return (struct npc_data *) strdb_get(npcname_db, name); } + +/*========================================== + * Run function for each npc + *------------------------------------------*/ + +void npc_foreach(int (*func)(DBKey, void*, va_list), ...) +{ + va_list ap; + va_start(ap, func); + npcname_db->vforeach(npcname_db, func, ap); + va_end(ap); +} + /*========================================== * イベントキューのイベント処理 *------------------------------------------*/ diff --git a/src/map/npc.h b/src/map/npc.h index f75ede9c5..93fb3fa60 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -146,6 +146,8 @@ int npc_script_event(struct map_session_data* sd, enum npce_event type); int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int points); +void npc_foreach(int (*func)(DBKey,void*,va_list), ...); + extern struct npc_data* fake_nd; #endif /* _NPC_H_ */ diff --git a/src/map/pc.c b/src/map/pc.c index 29dfd1b30..7d268a0f5 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -2965,11 +2965,12 @@ int pc_delitem(struct map_session_data *sd,int n,int amount,int type) { nullpo_retr(1, sd); - if(sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || sd->inventory_data[n] == NULL) + if(sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || (sd->inventory_data[n] == NULL && ~type&4)) return 1; sd->status.inventory[n].amount -= amount; - sd->weight -= sd->inventory_data[n]->weight*amount ; + if(~type&4) + sd->weight -= sd->inventory_data[n]->weight*amount ; if(sd->status.inventory[n].amount<=0){ if(sd->status.inventory[n].equip) pc_unequipitem(sd,n,3); diff --git a/src/map/storage.c b/src/map/storage.c index c2e4bf5f7..f43ee7f04 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -224,7 +224,7 @@ static int storage_additem(struct map_session_data *sd,struct storage *stor,stru /*========================================== * Internal del-item function *------------------------------------------*/ -static int storage_delitem(struct map_session_data *sd,struct storage *stor,int n,int amount) +int storage_delitem(struct map_session_data *sd,struct storage *stor,int n,int amount) { if(stor->storage_[n].nameid==0 || stor->storage_[n].amount<amount) diff --git a/src/map/storage.h b/src/map/storage.h index 6764d4956..fa33e2050 100644 --- a/src/map/storage.h +++ b/src/map/storage.h @@ -11,9 +11,11 @@ struct item; //#include "map.h" struct map_session_data; +struct storage *account2storage2(int account_id); int storage_storageopen(struct map_session_data *sd); int storage_storageadd(struct map_session_data *sd,int index,int amount); int storage_storageget(struct map_session_data *sd,int index,int amount); +int storage_delitem(struct map_session_data *sd,struct storage *stor,int n,int amount); int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount); int storage_storagegettocart(struct map_session_data *sd,int index,int amount); int storage_storageclose(struct map_session_data *sd); |