summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/clif.c6
-rw-r--r--src/map/pc.c1
-rw-r--r--src/map/pc.h1
-rw-r--r--src/map/skill.c62
-rw-r--r--src/map/skill.h5
5 files changed, 72 insertions, 3 deletions
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
@@ -1571,6 +1571,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
**/
void skill_cooldown_load(struct map_session_data * sd);