summaryrefslogtreecommitdiff
path: root/src/map/skill.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/skill.c')
-rw-r--r--src/map/skill.c62
1 files changed, 60 insertions, 2 deletions
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;