From 6b4bb61343f4c08e881228e569c95507e0250a1a Mon Sep 17 00:00:00 2001 From: shennetsind Date: Tue, 13 Dec 2011 04:10:54 +0000 Subject: added cool down saving, bugreport:3976 thanks to Epoque for his concept on how to handle the cool down data git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@15085 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/pc.c | 6 +++++- src/map/skill.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/map/skill.h | 4 ++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/map/pc.c b/src/map/pc.c index e6ef6ff83..214cf81a7 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -955,7 +955,11 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim strcpy(tmpstr, msg_txt(500)); // Actually, it's the night... clif_wis_message(sd->fd, wisp_server_name, tmpstr, strlen(tmpstr)+1); } - + /** + * Check if player have any cool downs on + **/ + skill_cooldown_load(sd); + // Request all registries (auth is considered completed whence they arrive) intif_request_registry(sd,7); return true; diff --git a/src/map/skill.c b/src/map/skill.c index 1847ffb86..56deef186 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -55,6 +55,18 @@ static struct eri *skill_timer_ers = NULL; //For handling skill_timerskills [Sko DBMap* skillunit_db = NULL; // int id -> struct skill_unit* DBMap* skilldb_name2id = NULL; + +/** + * Skill Cool Down Delay Saving + **/ +DBMap* skillcd_db = NULL; +struct skill_cd { + int duration[MAX_SKILL_TREE];//milliseconds + short skidx[MAX_SKILL_TREE];//the skill index entries belong to + short nameid[MAX_SKILL_TREE];//skill id + unsigned char cursor; +}; + struct s_skill_db skill_db[MAX_SKILL_DB]; struct s_skill_produce_db skill_produce_db[MAX_SKILL_PRODUCE_DB]; struct s_skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB]; @@ -13360,16 +13372,45 @@ int skill_spellbook (struct map_session_data *sd, int nameid) { int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) { struct map_session_data *sd = map_id2sd(id); + struct skill_cd * cd = NULL; + if (data <= 0 || data >= MAX_SKILL) return 0; if (!sd) return 0; if (sd->blockskill[data] != (0x1|(tid&0xFE))) return 0; + + if( ( cd = idb_get(skillcd_db,sd->status.char_id) ) ) { + int i,cursor; + ARR_FIND( 0, cd->cursor+1, cursor, cd->skidx[cursor] == data ); + cd->duration[cursor] = 0; + cd->skidx[cursor] = 0; + cd->nameid[cursor] = 0; + // compact the cool down list + for( i = 0, cursor = 0; i < cd->cursor; i++ ) { + if( cd->duration[i] == 0 ) + continue; + if( cursor != i ) { + cd->duration[cursor] = cd->duration[i]; + cd->skidx[cursor] = cd->skidx[i]; + cd->nameid[cursor] = cd->nameid[i]; + } + cursor++; + } + if( cursor == 0 ) { + idb_remove(skillcd_db,sd->status.char_id); + aFree(cd); + } else + cd->cursor = cursor; + } + sd->blockskill[data] = 0; return 1; } int skill_blockpc_start(struct map_session_data *sd, int skillid, int tick) { + struct skill_cd * cd = NULL; + int oskillid = skillid; nullpo_retr (-1, sd); skillid = skill_get_index(skillid); @@ -13384,6 +13425,15 @@ int skill_blockpc_start(struct map_session_data *sd, int skillid, int tick) if( battle_config.display_status_timers ) clif_skill_cooldown(sd, skillid, tick); + if( !( cd = idb_get(skillcd_db,sd->status.char_id) ) ) { + CREATE(cd,struct skill_cd,1); + idb_put(skillcd_db, sd->status.char_id, cd); + } + cd->duration[cd->cursor] = tick; + cd->skidx[cd->cursor] = skillid; + cd->nameid[cd->cursor] = oskillid; + cd->cursor++; + sd->blockskill[skillid] = 0x1|(0xFE&add_timer(gettick()+tick,skill_blockpc_end,sd->bl.id,skillid)); return 0; } @@ -13822,7 +13872,17 @@ int skill_stasis_check(struct block_list *bl, int src_id, int skillid) return 0; // Can Cast anything else like Weapon Skills } - +void skill_cooldown_load(struct map_session_data * sd) { + struct skill_cd * cd = NULL; + int i; + if( !( cd = idb_get(skillcd_db,sd->status.char_id) ) ) + return;//nothing for us here + + for( i = 0; i < cd->cursor; i++ ) { + skill_blockpc_start(sd, cd->nameid[i], cd->duration[i]); + } + return; +} /*========================================== * DB reading. * skill_db.txt @@ -14224,6 +14284,7 @@ int do_init_skill (void) group_db = idb_alloc(DB_OPT_BASE); skillunit_db = idb_alloc(DB_OPT_BASE); + skillcd_db = idb_alloc(DB_OPT_BASE); skill_unit_ers = ers_new(sizeof(struct skill_unit_group)); skill_timer_ers = ers_new(sizeof(struct skill_timerskill)); @@ -14243,6 +14304,7 @@ int do_final_skill(void) db_destroy(skilldb_name2id); db_destroy(group_db); db_destroy(skillunit_db); + db_destroy(skillcd_db); ers_destroy(skill_unit_ers); ers_destroy(skill_timer_ers); return 0; diff --git a/src/map/skill.h b/src/map/skill.h index 4670fbbf5..b4e0f209e 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -1555,6 +1555,10 @@ enum { UNT_MAX = 0x190 }; +/** + * Skill Cool Downs - load from pc.c when the character logs in + **/ +void skill_cooldown_load(struct map_session_data * sd); /** * Warlock **/ -- cgit v1.2.3-70-g09d2