From bfa423fea55aa5659506cf85e6c418346804ac89 Mon Sep 17 00:00:00 2001 From: Haru Date: Mon, 20 Apr 2020 21:17:25 +0200 Subject: Refactor the Bard/Dancer Soul Link temporary skill granting code The code no longer relies on invalid assumptions about the mapping between skill IDs and indices Fixes #2670 Signed-off-by: Haru --- src/map/pc.c | 49 +++++++++++++++++++++++++------------------------ src/map/skill.c | 32 ++++++++++++++++++++++++++++++++ src/map/skill.h | 1 + 3 files changed, 58 insertions(+), 24 deletions(-) (limited to 'src/map') diff --git a/src/map/pc.c b/src/map/pc.c index a8ed4430e..599317dee 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1627,31 +1627,32 @@ static int pc_calc_skilltree(struct map_session_data *sd) sd->status.skill[i].flag = SKILL_FLAG_PERMANENT; } - if( sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER && skill->dbs->db[i].nameid >= DC_HUMMING && skill->dbs->db[i].nameid <= DC_SERVICEFORYOU ) - { //Enable Bard/Dancer spirit linked skills. - if (sd->status.sex) { - // Link dancer skills to bard. - if (i < 8) { - Assert_report(i >= 8); - continue; - } - if (sd->status.skill[i-8].lv < 10) - continue; - sd->status.skill[i].id = skill->dbs->db[i].nameid; - sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill - sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill - } else { - // Link bard skills to dancer. - if (i < 8) { - Assert_report(i >= 8); - continue; - } - if (sd->status.skill[i].lv < 10) - continue; - sd->status.skill[i-8].id = skill->dbs->db[i-8].nameid; - sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill - sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill + if (sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER + && ((skill->dbs->db[i].nameid >= BA_WHISTLE && skill->dbs->db[i].nameid <= BA_APPLEIDUN) + || (skill->dbs->db[i].nameid >= DC_HUMMING && skill->dbs->db[i].nameid <= DC_SERVICEFORYOU)) + ) { + //Enable Bard/Dancer spirit linked skills. + int linked_nameid = skill->get_linked_song_dance_id(skill->dbs->db[i].nameid); + if (linked_nameid == 0) { + Assert_report("Linked bard/dance skill not found"); + continue; } + int copy_from_index; + int copy_to_index; + if (sd->status.sex == SEX_MALE && skill->dbs->db[i].nameid >= BA_WHISTLE && skill->dbs->db[i].nameid <= BA_APPLEIDUN) { + copy_from_index = i; + copy_to_index = skill->get_index(linked_nameid); + } else { + copy_from_index = skill->get_index(linked_nameid); + copy_to_index = i; + } + if (copy_from_index < copy_to_index) + continue; // Copy only after the source skill has been filled into the tree + if (sd->status.skill[copy_from_index].lv < 10) + continue; // Copy only if the linked skill has been mastered + sd->status.skill[copy_to_index].id = skill->dbs->db[copy_to_index].nameid; + sd->status.skill[copy_to_index].lv = sd->status.skill[copy_from_index].lv; // Set the level to the same as the linking skill + sd->status.skill[copy_to_index].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill } } diff --git a/src/map/skill.c b/src/map/skill.c index 0fcd5fd0c..2fae7e7f9 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -10938,6 +10938,37 @@ static int skill_count_wos(struct block_list *bl, va_list ap) return 0; } +/** + * Returns the linked song/dance skill ID, if any (for the Bard/Dancer Soul Link). + * + * @param skill_id The skill ID to look up + * + * @return The linked song or dance's skill ID if any + * @retval 0 if the given skill_id doesn't have a linked skill ID + */ +static int skill_get_linked_song_dance_id(int skill_id) +{ + switch (skill_id) { + case BA_WHISTLE: + return DC_HUMMING; + case BA_ASSASSINCROSS: + return DC_DONTFORGETME; + case BA_POEMBRAGI: + return DC_FORTUNEKISS; + case BA_APPLEIDUN: + return DC_SERVICEFORYOU; + case DC_HUMMING: + return BA_WHISTLE; + case DC_DONTFORGETME: + return BA_ASSASSINCROSS; + case DC_FORTUNEKISS: + return BA_POEMBRAGI; + case DC_SERVICEFORYOU: + return BA_APPLEIDUN; + } + return 0; +} + /*========================================== * *------------------------------------------*/ @@ -21812,4 +21843,5 @@ void skill_defaults(void) skill->splash_target = skill_splash_target; skill->check_npc_chaospanic = skill_check_npc_chaospanic; skill->count_wos = skill_count_wos; + skill->get_linked_song_dance_id = skill_get_linked_song_dance_id; } diff --git a/src/map/skill.h b/src/map/skill.h index 65195dc75..4dbbaf147 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -2200,6 +2200,7 @@ struct skill_interface { int (*splash_target) (struct block_list* bl); int (*check_npc_chaospanic) (struct block_list *bl, va_list args); int (*count_wos) (struct block_list *bl, va_list ap); + int (*get_linked_song_dance_id) (int skill_id); }; #ifdef HERCULES_CORE -- cgit v1.2.3-60-g2f50