summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2020-04-20 21:17:25 +0200
committerHaru <haru@dotalux.com>2020-05-04 02:10:25 +0200
commitbfa423fea55aa5659506cf85e6c418346804ac89 (patch)
treeefd3809adcc899e92de16df032b12d34ca7e177e /src
parent595dae284856bcf442274b39b63cce8746687c13 (diff)
downloadhercules-bfa423fea55aa5659506cf85e6c418346804ac89.tar.gz
hercules-bfa423fea55aa5659506cf85e6c418346804ac89.tar.bz2
hercules-bfa423fea55aa5659506cf85e6c418346804ac89.tar.xz
hercules-bfa423fea55aa5659506cf85e6c418346804ac89.zip
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 <haru@dotalux.com>
Diffstat (limited to 'src')
-rw-r--r--src/map/pc.c49
-rw-r--r--src/map/skill.c32
-rw-r--r--src/map/skill.h1
3 files changed, 58 insertions, 24 deletions
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