Rehashed Item_delay.txt (bugreport:5487)
- Before you could only have MAX_ITEMDELAYS (10) items with delays. Now: you can have up to MAX_ITEMDELAYS (10) concurrent delays. and of course you can always increase MAX_ITEMDELAYS in src/map/itemdb.h as much as you may need. - Item delays are no longer lost on logout, they're persistent until server restarts. - When a item use is denied due to delay still up a message now tells the user why he can't use the item (before would leave the user wondering wtf was going on. it had no response) git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@15762 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
b3b6616733
commit
f8ddb21f74
@ -1038,7 +1038,7 @@ static void itemdb_read(void)
|
||||
sv_readdb(db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail);
|
||||
sv_readdb(db_path, "item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip);
|
||||
sv_readdb(db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade);
|
||||
sv_readdb(db_path, "item_delay.txt", ',', 2, 2, MAX_ITEMDELAYS, &itemdb_read_itemdelay);
|
||||
sv_readdb(db_path, "item_delay.txt", ',', 2, 2, -1, &itemdb_read_itemdelay);
|
||||
sv_readdb(db_path, "item_buyingstore.txt", ',', 1, 1, -1, &itemdb_read_buyingstore);
|
||||
}
|
||||
|
||||
|
@ -1671,6 +1671,9 @@ int map_quit(struct map_session_data *sd)
|
||||
|
||||
if( sd->bg_id )
|
||||
bg_team_leave(sd,1);
|
||||
|
||||
pc_itemcd_do(sd,false);
|
||||
|
||||
npc_script_event(sd, NPCE_LOGOUT);
|
||||
|
||||
//Unit_free handles clearing the player related data,
|
||||
|
99
src/map/pc.c
99
src/map/pc.c
@ -73,6 +73,19 @@ const struct sg_data sg_info[MAX_PC_FEELHATE] = {
|
||||
{ SG_STAR_ANGER, SG_STAR_BLESS, SG_STAR_COMFORT, "PC_FEEL_STAR", "PC_HATE_MOB_STAR", is_day_of_star }
|
||||
};
|
||||
|
||||
/**
|
||||
* Item Cool Down Delay Saving
|
||||
* Struct item_cd is not a member of struct map_session_data
|
||||
* to keep cooldowns in memory between player log-ins.
|
||||
* All cooldowns are reset when server is restarted.
|
||||
**/
|
||||
DBMap* itemcd_db = NULL; // char_id -> struct skill_cd
|
||||
struct item_cd {
|
||||
unsigned int tick[MAX_ITEMDELAYS];//tick
|
||||
short nameid[MAX_ITEMDELAYS];//skill id
|
||||
};
|
||||
|
||||
|
||||
//Converts a class to its array index for CLASS_COUNT defined arrays.
|
||||
//Note that it does not do a validity check for speed purposes, where parsing
|
||||
//player input make sure to use a pcdb_checkid first!
|
||||
@ -1072,6 +1085,11 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
|
||||
**/
|
||||
skill_cooldown_load(sd);
|
||||
|
||||
/**
|
||||
* Check if player have any item cooldowns on
|
||||
**/
|
||||
pc_itemcd_do(sd,true);
|
||||
|
||||
// Request all registries (auth is considered completed whence they arrive)
|
||||
intif_request_registry(sd,7);
|
||||
return true;
|
||||
@ -3995,23 +4013,36 @@ int pc_useitem(struct map_session_data *sd,int n)
|
||||
|
||||
if( sd->inventory_data[n]->delay > 0 ) { // Check if there is a delay on this item [Paradox924X]
|
||||
ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid || !sd->item_delay[i].nameid);
|
||||
if( i < MAX_ITEMDELAYS )
|
||||
{
|
||||
if( sd->item_delay[i].nameid )
|
||||
{// found
|
||||
if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 )
|
||||
if( i < MAX_ITEMDELAYS ) {
|
||||
if( sd->item_delay[i].nameid ) {// found
|
||||
if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) {
|
||||
int e_tick = DIFF_TICK(sd->item_delay[i].tick, tick)/1000;
|
||||
char e_msg[100];
|
||||
if( e_tick > 99 )
|
||||
sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %.1f minutes.",
|
||||
itemdb_jname(sd->status.inventory[n].nameid),
|
||||
(double)e_tick / 60);
|
||||
else
|
||||
sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %d seconds.",
|
||||
itemdb_jname(sd->status.inventory[n].nameid),
|
||||
e_tick);
|
||||
clif_colormes(sd,COLOR_RED,e_msg);
|
||||
return 0; // Delay has not expired yet
|
||||
}
|
||||
else
|
||||
{// not yet used item (all slots are initially empty)
|
||||
}
|
||||
} else {// not yet used item (all slots are initially empty)
|
||||
sd->item_delay[i].nameid = nameid;
|
||||
}
|
||||
sd->item_delay[i].tick = tick + sd->inventory_data[n]->delay;
|
||||
}
|
||||
else
|
||||
{// should not happen
|
||||
} else {// should not happen
|
||||
ShowError("pc_useitem: Exceeded item delay array capacity! (nameid=%d, char_id=%d)\n", nameid, sd->status.char_id);
|
||||
}
|
||||
//clean up used delays so we can give room for more
|
||||
for(i = 0; i < MAX_ITEMDELAYS; i++) {
|
||||
if( DIFF_TICK(sd->item_delay[i].tick, tick) <= 0 ) {
|
||||
sd->item_delay[i].tick = 0;
|
||||
sd->item_delay[i].nameid = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sd->itemid = sd->status.inventory[n].nameid;
|
||||
@ -8700,18 +8731,54 @@ int pc_read_motd(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pc_itemcd_do(struct map_session_data *sd, bool load) {
|
||||
int i,cursor = 0;
|
||||
struct item_cd* cd = NULL;
|
||||
|
||||
if( load ) {
|
||||
if( !(cd = idb_get(itemcd_db, sd->status.char_id)) ) {
|
||||
// no skill cooldown is associated with this character
|
||||
return;
|
||||
}
|
||||
for(i = 0; i < MAX_ITEMDELAYS; i++) {
|
||||
if( cd->nameid[i] && DIFF_TICK(gettick(),cd->tick[i]) < 0 ) {
|
||||
sd->item_delay[cursor].tick = cd->tick[i];
|
||||
sd->item_delay[cursor].nameid = cd->nameid[i];
|
||||
cursor++;
|
||||
}
|
||||
}
|
||||
idb_remove(itemcd_db,sd->status.char_id);
|
||||
} else {
|
||||
if( !(cd = idb_get(itemcd_db,sd->status.char_id)) ) {
|
||||
// create a new skill cooldown object for map storage
|
||||
CREATE( cd, struct item_cd, 1 );
|
||||
idb_put( itemcd_db, sd->status.char_id, cd );
|
||||
}
|
||||
for(i = 0; i < MAX_ITEMDELAYS; i++) {
|
||||
if( sd->item_delay[i].nameid && DIFF_TICK(gettick(),sd->item_delay[i].tick) < 0 ) {
|
||||
cd->tick[cursor] = sd->item_delay[i].tick;
|
||||
cd->nameid[cursor] = sd->item_delay[i].nameid;
|
||||
cursor++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*==========================================
|
||||
* pc? ŒW<EFBFBD>‰Šú‰»
|
||||
*------------------------------------------*/
|
||||
void do_final_pc(void)
|
||||
{
|
||||
void do_final_pc(void) {
|
||||
|
||||
db_destroy(itemcd_db);
|
||||
|
||||
do_final_pc_groups();
|
||||
return;
|
||||
}
|
||||
|
||||
int do_init_pc(void)
|
||||
{
|
||||
int do_init_pc(void) {
|
||||
|
||||
itemcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
|
||||
pc_readdb();
|
||||
pc_read_motd(); // Read MOTD [Valaris]
|
||||
|
||||
|
@ -218,7 +218,7 @@ struct map_session_data {
|
||||
unsigned int ks_floodprotect_tick; // [Kill Steal Protection]
|
||||
|
||||
struct {
|
||||
int nameid;
|
||||
short nameid;
|
||||
unsigned int tick;
|
||||
} item_delay[MAX_ITEMDELAYS]; // [Paradox924X]
|
||||
|
||||
@ -897,4 +897,8 @@ void pc_overheat(struct map_session_data *sd, int val);
|
||||
* Royal Guard
|
||||
**/
|
||||
int pc_banding(struct map_session_data *sd, short skill_lv);
|
||||
/**
|
||||
* Item Cooldown persistency
|
||||
**/
|
||||
void pc_itemcd_do(struct map_session_data *sd, bool load);
|
||||
#endif /* _PC_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user