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://svn.code.sf.net/p/rathena/svn/trunk@12661 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
2eabb3d1f7
commit
26a70ed737
@ -3,6 +3,15 @@ Date Added
|
|||||||
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
||||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||||
|
|
||||||
|
2008/04/27
|
||||||
|
* 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. [Kevin]
|
||||||
2008/04/26
|
2008/04/26
|
||||||
* Added script function hasquest. [Kevin]
|
* Added script function hasquest. [Kevin]
|
||||||
* Fixed OnGuildBreak. [Kevin]
|
* Fixed OnGuildBreak. [Kevin]
|
||||||
|
@ -1894,20 +1894,27 @@ void clif_storagelist(struct map_session_data *sd,struct storage *stor)
|
|||||||
if(stor->storage_[i].nameid<=0)
|
if(stor->storage_[i].nameid<=0)
|
||||||
continue;
|
continue;
|
||||||
id = itemdb_search(stor->storage_[i].nameid);
|
id = itemdb_search(stor->storage_[i].nameid);
|
||||||
if(!itemdb_isstackable2(id))
|
if(!id)
|
||||||
{ //Equippable
|
{
|
||||||
WBUFW(bufe,ne*20+4)=i+1;
|
//Item not found, was probably deleted and then map server reloaded/item db reloaded
|
||||||
clif_item_sub(bufe, ne*20+6, &stor->storage_[i], id, id->equip);
|
storage_delitem(sd, stor, i, stor->storage_[i].amount);
|
||||||
clif_addcards(WBUFP(bufe, ne*20+16), &stor->storage_[i]);
|
return;
|
||||||
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]);
|
|
||||||
#endif
|
|
||||||
n++;
|
|
||||||
}
|
}
|
||||||
|
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]);
|
||||||
|
#endif
|
||||||
|
n++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(n){
|
if(n){
|
||||||
#if PACKETVER < 5
|
#if PACKETVER < 5
|
||||||
|
162
src/map/itemdb.c
162
src/map/itemdb.c
@ -10,6 +10,10 @@
|
|||||||
#include "battle.h" // struct battle_config
|
#include "battle.h" // struct battle_config
|
||||||
#include "script.h" // item script processing
|
#include "script.h" // item script processing
|
||||||
#include "pc.h" // W_MUSICAL, W_WHIP
|
#include "pc.h" // W_MUSICAL, W_WHIP
|
||||||
|
#include "storage.h"
|
||||||
|
#include "npc.h"
|
||||||
|
#include "clif.h"
|
||||||
|
#include "mob.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -1008,6 +1012,22 @@ static void destroy_item_data(struct item_data* self, int free_self)
|
|||||||
aFree(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)
|
static int itemdb_final_sub(DBKey key,void *data,va_list ap)
|
||||||
{
|
{
|
||||||
struct item_data *id = (struct item_data *)data;
|
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;
|
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)
|
if(nd->subtype != SHOP && nd->subtype != CASHSHOP)
|
||||||
destroy_item_data(id, 1);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//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)
|
void itemdb_reload(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
int i;
|
do_final_itemdb();
|
||||||
|
do_init_itemdb();
|
||||||
|
|
||||||
for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
|
//Update ALL items on the server
|
||||||
if( itemdb_array[i] )
|
map_foreachpc(itemdb_reload_check);
|
||||||
if( itemdb_array[i]->flag.db2 )
|
npc_foreach(itemdb_reload_check_npc);
|
||||||
{
|
itemdb_foreach_mobdb();
|
||||||
destroy_item_data(itemdb_array[i], 1);
|
|
||||||
memset(itemdb_array[i], 0, sizeof(struct item_data));
|
|
||||||
}
|
|
||||||
|
|
||||||
itemdb_other->clear(itemdb_other, itemdb_reload_sub);
|
|
||||||
|
|
||||||
itemdb_read();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_final_itemdb(void)
|
void do_final_itemdb(void)
|
||||||
|
@ -83,6 +83,11 @@ struct mob_db {
|
|||||||
struct spawn_info spawn[10];
|
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 mob_data {
|
||||||
struct block_list bl;
|
struct block_list bl;
|
||||||
struct unit_data ud;
|
struct unit_data ud;
|
||||||
|
@ -150,6 +150,19 @@ struct npc_data* npc_name2id(const char* name)
|
|||||||
return (struct npc_data *) strdb_get(npcname_db, 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);
|
||||||
|
}
|
||||||
|
|
||||||
/*==========================================
|
/*==========================================
|
||||||
* イベントキューのイベント処理
|
* イベントキューのイベント処理
|
||||||
*------------------------------------------*/
|
*------------------------------------------*/
|
||||||
|
@ -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);
|
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;
|
extern struct npc_data* fake_nd;
|
||||||
|
|
||||||
#endif /* _NPC_H_ */
|
#endif /* _NPC_H_ */
|
||||||
|
@ -2965,11 +2965,12 @@ int pc_delitem(struct map_session_data *sd,int n,int amount,int type)
|
|||||||
{
|
{
|
||||||
nullpo_retr(1, sd);
|
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;
|
return 1;
|
||||||
|
|
||||||
sd->status.inventory[n].amount -= amount;
|
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].amount<=0){
|
||||||
if(sd->status.inventory[n].equip)
|
if(sd->status.inventory[n].equip)
|
||||||
pc_unequipitem(sd,n,3);
|
pc_unequipitem(sd,n,3);
|
||||||
|
@ -224,7 +224,7 @@ static int storage_additem(struct map_session_data *sd,struct storage *stor,stru
|
|||||||
/*==========================================
|
/*==========================================
|
||||||
* Internal del-item function
|
* 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)
|
if(stor->storage_[n].nameid==0 || stor->storage_[n].amount<amount)
|
||||||
|
@ -11,9 +11,11 @@ struct item;
|
|||||||
//#include "map.h"
|
//#include "map.h"
|
||||||
struct map_session_data;
|
struct map_session_data;
|
||||||
|
|
||||||
|
struct storage *account2storage2(int account_id);
|
||||||
int storage_storageopen(struct map_session_data *sd);
|
int storage_storageopen(struct map_session_data *sd);
|
||||||
int storage_storageadd(struct map_session_data *sd,int index,int amount);
|
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_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_storageaddfromcart(struct map_session_data *sd,int index,int amount);
|
||||||
int storage_storagegettocart(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);
|
int storage_storageclose(struct map_session_data *sd);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user