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.
|
||||
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
|
||||
* Added script function hasquest. [Kevin]
|
||||
* Fixed OnGuildBreak. [Kevin]
|
||||
|
@ -1894,6 +1894,13 @@ 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(!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;
|
||||
|
162
src/map/itemdb.c
162
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
int i;
|
||||
do_final_itemdb();
|
||||
do_init_itemdb();
|
||||
|
||||
for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
|
||||
if( itemdb_array[i] )
|
||||
if( itemdb_array[i]->flag.db2 )
|
||||
{
|
||||
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();
|
||||
//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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* イベントキューのイベント処理
|
||||
*------------------------------------------*/
|
||||
|
@ -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_ */
|
||||
|
@ -2965,10 +2965,11 @@ 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;
|
||||
if(~type&4)
|
||||
sd->weight -= sd->inventory_data[n]->weight*amount ;
|
||||
if(sd->status.inventory[n].amount<=0){
|
||||
if(sd->status.inventory[n].equip)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user