From 3238a7ff626d448d6291e33e94e473c728d0d0b7 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Sun, 18 Mar 2012 03:35:00 +0000 Subject: Added Official behavior to non-ensamble songs: they no longer go off if you warp within the same map. bugreport:4547 Dev Note: I didn't put it under session data cause only bard/gypsy classes use it, I found it to a be a waste. I'm not very comfortable with the dbmap either, however, so if you got any idea on how to make it more efficient lets talk :3 git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@15708 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/clif.c | 6 +++++- src/map/pc.c | 1 + src/map/pc.h | 1 + src/map/skill.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/map/skill.h | 5 +++++ 5 files changed, 72 insertions(+), 3 deletions(-) (limited to 'src/map') diff --git a/src/map/clif.c b/src/map/clif.c index 6196d347d..279f58d5e 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -8947,6 +8947,8 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) clif_changemap(sd, sd->mapindex, sd->bl.x, sd->bl.y); return; } + + sd->state.warping = 0; // look #if PACKETVER < 4 @@ -9216,9 +9218,11 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) // If player is dead, and is spawned (such as @refresh) send death packet. [Valaris] if(pc_isdead(sd)) clif_clearunit_area(&sd->bl, CLR_DEAD); + else { + skill_usave_trigger(sd); // Uncomment if you want to make player face in the same direction he was facing right before warping. [Skotlex] -// else // clif_changed_dir(&sd->bl, SELF); + } // Trigger skill effects if you appear standing on them if(!battle_config.pc_invincible_time) diff --git a/src/map/pc.c b/src/map/pc.c index 276ccf73a..cdf3bef52 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4372,6 +4372,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y } sd->state.changemap = (sd->mapindex != mapindex); + sd->state.warping = 1; if( sd->state.changemap ) { // Misc map-changing settings sd->state.pmap = sd->bl.m; diff --git a/src/map/pc.h b/src/map/pc.h index 8c70984e0..e3d810378 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -145,6 +145,7 @@ struct map_session_data { unsigned short autobonus; //flag to indicate if an autobonus is activated. [Inkfish] struct guild *gmaster_flag; unsigned int prevend : 1;//used to flag wheather you've spent 40sp to open the vending or not. + unsigned int warping : 1;//states whether you're in the middle of a warp processing } state; struct { unsigned char no_weapon_damage, no_magic_damage, no_misc_damage; diff --git a/src/map/skill.c b/src/map/skill.c index 325a3de33..b3d08a74c 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -71,6 +71,14 @@ struct skill_cd { unsigned char cursor; }; +/** + * Skill Unit Persistency during endack routes (mostly for songs see bugreport:4574) + **/ +DBMap* skillusave_db = NULL; // char_id -> struct skill_usave +struct skill_usave { + int skill_num, skill_lv; +}; + 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]; @@ -10487,7 +10495,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in sc = status_get_sc(bl); type = status_skill2sc(sg->skill_id); sce = (sc && type != -1)?sc->data[type]:NULL; - + if( bl->prev==NULL || (status_isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB) ) //Need to delete the trap if the source died. return 0; @@ -13375,7 +13383,7 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li struct block_list* src; struct unit_data *ud; int i,j; - + if( group == NULL ) { ShowDebug("skill_delunitgroup: group is NULL (source=%s:%d, %s)! Please report this! (#3504)\n", file, line, func); @@ -13388,6 +13396,24 @@ int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int li ShowError("skill_delunitgroup: Group's source not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id); return 0; } + + if( !status_isdead(src) && ((TBL_PC*)src)->state.warping && !((TBL_PC*)src)->state.changemap ) { + switch( group->skill_id ) { + case BA_DISSONANCE: + case BA_POEMBRAGI: + case BA_WHISTLE: + case BA_ASSASSINCROSS: + case BA_APPLEIDUN: + case DC_UGLYDANCE: + case DC_HUMMING: + case DC_DONTFORGETME: + case DC_FORTUNEKISS: + case DC_SERVICEFORYOU: + skill_usave_add(((TBL_PC*)src), group->skill_id, group->skill_lv); + break; + } + } + if (skill_get_unit_flag(group->skill_id)&(UF_DANCE|UF_SONG|UF_ENSEMBLE)) { struct status_change* sc = status_get_sc(src); @@ -14856,7 +14882,37 @@ int skill_blockmerc_start(struct mercenary_data *md, int skillid, int tick) md->blockskill[skillid] = 1; return add_timer(gettick() + tick, skill_blockmerc_end, md->bl.id, skillid); } +/** + * Adds a new skill unit entry for this player to recast after map load + **/ +void skill_usave_add(struct map_session_data * sd, int skill_num, int skill_lv) { + struct skill_usave * sus = NULL; + + if( idb_exists(skillusave_db,sd->status.char_id) ) { + idb_remove(skillusave_db,sd->status.char_id); + } + + CREATE( sus, struct skill_usave, 1 ); + idb_put( skillusave_db, sd->status.char_id, sus ); + + sus->skill_num = skill_num; + sus->skill_lv = skill_lv; + + return; +} +void skill_usave_trigger(struct map_session_data *sd) { + struct skill_usave * sus = NULL; + if( ! (sus = idb_get(skillusave_db,sd->status.char_id)) ) { + return; + } + + skill_unitsetting(&sd->bl,sus->skill_num,sus->skill_lv,sd->bl.x,sd->bl.y,0); + + idb_remove(skillusave_db,sd->status.char_id); + + return; +} /* * */ @@ -15699,6 +15755,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_RELEASE_DATA); + skillusave_db = idb_alloc(DB_OPT_RELEASE_DATA); skill_unit_ers = ers_new(sizeof(struct skill_unit_group)); skill_timer_ers = ers_new(sizeof(struct skill_timerskill)); @@ -15719,6 +15776,7 @@ int do_final_skill(void) db_destroy(group_db); db_destroy(skillunit_db); db_destroy(skillcd_db); + db_destroy(skillusave_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 fa792540e..48867021c 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -1570,6 +1570,11 @@ enum { UNT_MAX = 0x190 }; +/** + * Skill Unit Save + **/ +void skill_usave_add(struct map_session_data * sd, int skill_num, int skill_lv); +void skill_usave_trigger(struct map_session_data *sd); /** * Skill Cool Downs - load from pc.c when the character logs in **/ -- cgit v1.2.3-70-g09d2