diff --git a/db/pre-re/autospell_db.conf b/db/pre-re/autospell_db.conf index e5752a82a8c..cf328bb8977 100644 --- a/db/pre-re/autospell_db.conf +++ b/db/pre-re/autospell_db.conf @@ -44,6 +44,7 @@ autospell_db: ( SkillId: Skill ID/Name (constant string or int) SkillLevel: Highest usable level (int, defaults to 0) (can be grouped by AutoSpell Levels) (Level 0 would mean not usable in this AutoSpell level) + (Level "HALF_AUTOSPELL_LEVEL" uses half of casted autospell level) SpiritBoost: Use max level when under Sage Spirit? (boolean, defaults to false) }, **************************************************************************/ diff --git a/db/re/autospell_db.conf b/db/re/autospell_db.conf index e5752a82a8c..2e26a09611a 100644 --- a/db/re/autospell_db.conf +++ b/db/re/autospell_db.conf @@ -44,91 +44,89 @@ autospell_db: ( SkillId: Skill ID/Name (constant string or int) SkillLevel: Highest usable level (int, defaults to 0) (can be grouped by AutoSpell Levels) (Level 0 would mean not usable in this AutoSpell level) + (Level "HALF_AUTOSPELL_LEVEL" uses half of casted autospell level) SpiritBoost: Use max level when under Sage Spirit? (boolean, defaults to false) }, **************************************************************************/ -{ - SkillId: "MG_NAPALMBEAT" - SkillLevel: 3 - SpiritBoost: false -}, { SkillId: "MG_COLDBOLT" - SkillLevel: { - // Lv1: 0 - Lv2: 1 - Lv3: 2 - Lv4: 3 - Lv5: 3 - Lv6: 3 - Lv7: 3 - Lv8: 3 - Lv9: 3 - Lv10: 3 - } + SkillLevel: "HALF_AUTOSPELL_LEVEL" SpiritBoost: true }, { SkillId: "MG_FIREBOLT" - SkillLevel: { - // Lv1: 0 - Lv2: 1 - Lv3: 2 - Lv4: 3 - Lv5: 3 - Lv6: 3 - Lv7: 3 - Lv8: 3 - Lv9: 3 - Lv10: 3 - } + SkillLevel: "HALF_AUTOSPELL_LEVEL" SpiritBoost: true }, { SkillId: "MG_LIGHTNINGBOLT" - SkillLevel: { - // Lv1: 0 - Lv2: 1 - Lv3: 2 - Lv4: 3 - Lv5: 3 - Lv6: 3 - Lv7: 3 - Lv8: 3 - Lv9: 3 - Lv10: 3 - } + SkillLevel: "HALF_AUTOSPELL_LEVEL" SpiritBoost: true }, { SkillId: "MG_SOULSTRIKE" SkillLevel: { - // Lv1 .. Lv4: 0 - Lv5: 1 - Lv6: 2 - Lv7: 3 - Lv8: 3 - Lv9: 3 - Lv10: 3 + // Lv1 .. Lv3: 0 + Lv4: "HALF_AUTOSPELL_LEVEL" + Lv5: "HALF_AUTOSPELL_LEVEL" + Lv6: "HALF_AUTOSPELL_LEVEL" + Lv7: "HALF_AUTOSPELL_LEVEL" + Lv8: "HALF_AUTOSPELL_LEVEL" + Lv9: "HALF_AUTOSPELL_LEVEL" + Lv10: "HALF_AUTOSPELL_LEVEL" } SpiritBoost: false }, { SkillId: "MG_FIREBALL" SkillLevel: { - // Lv1 .. Lv7: 0 - Lv8: 1 - Lv9: 2 - Lv10: 2 + // Lv1 .. Lv3: 0 + Lv4: "HALF_AUTOSPELL_LEVEL" + Lv5: "HALF_AUTOSPELL_LEVEL" + Lv6: "HALF_AUTOSPELL_LEVEL" + Lv7: "HALF_AUTOSPELL_LEVEL" + Lv8: "HALF_AUTOSPELL_LEVEL" + Lv9: "HALF_AUTOSPELL_LEVEL" + Lv10: "HALF_AUTOSPELL_LEVEL" + } + SpiritBoost: false +}, +{ + SkillId: "WZ_EARTHSPIKE" + SkillLevel: { + // Lv1 .. Lv6: 0 + Lv7: "HALF_AUTOSPELL_LEVEL" + Lv8: "HALF_AUTOSPELL_LEVEL" + Lv9: "HALF_AUTOSPELL_LEVEL" + Lv10: "HALF_AUTOSPELL_LEVEL" } SpiritBoost: false }, { SkillId: "MG_FROSTDIVER" + SkillLevel: { + // Lv1 .. Lv6: 0 + Lv7: "HALF_AUTOSPELL_LEVEL" + Lv8: "HALF_AUTOSPELL_LEVEL" + Lv9: "HALF_AUTOSPELL_LEVEL" + Lv10: "HALF_AUTOSPELL_LEVEL" + } + SpiritBoost: false +}, +{ + SkillId: "MG_THUNDERSTORM" + SkillLevel: { + // Lv1 .. Lv9: 0 + Lv10: "HALF_AUTOSPELL_LEVEL" + } + SpiritBoost: false +}, +{ + SkillId: "WZ_HEAVENDRIVE" SkillLevel: { // Lv1 .. Lv9: 0 - Lv10: 1 + Lv10: "HALF_AUTOSPELL_LEVEL" } SpiritBoost: false }, diff --git a/src/map/battle.c b/src/map/battle.c index 4b01f41dd20..79a62d850de 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6839,12 +6839,21 @@ static enum damage_lv battle_weapon_attack(struct block_list *src, struct block_ int sp = 0; uint16 skill_id = sc->data[SC_AUTOSPELL]->val2; uint16 skill_lv = sc->data[SC_AUTOSPELL]->val3; - int i = rnd()%100; - if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_SAGE) +#ifndef RENEWAL + int i = rnd() % 100; + if (sc->data[SC_SOULLINK] != NULL && sc->data[SC_SOULLINK]->val2 == SL_SAGE) i = 0; //Max chance, no skill_lv reduction. [Skotlex] - if (i >= 50) skill_lv -= 2; - else if (i >= 15) skill_lv--; - if (skill_lv < 1) skill_lv = 1; + + if (i >= 50) + skill_lv -= 2; + else if (i >= 15) + skill_lv--; + if (skill_lv < 1) + skill_lv = 1; +#else + if (sd != NULL && skill_lv > pc->checkskill(sd, skill_id)) + skill_lv = pc->checkskill(sd, skill_id); +#endif sp = skill->get_sp(skill_id,skill_lv) * 2 / 3; if (status->charge(src, 0, sp)) { diff --git a/src/map/script.c b/src/map/script.c index a37fb0aa2d6..03eff031058 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -30155,6 +30155,9 @@ static void script_hardcoded_constants(void) script->set_constant("HOMINFO_RENAME", HOMINFO_RENAME, false, false); script->set_constant("HOMINFO_LEVEL", HOMINFO_LEVEL, false, false); + script->constdb_comment("autospell db constants"); + script->set_constant2("HALF_AUTOSPELL_LEVEL", HALF_AUTOSPELL_LEVEL, false, false); + script->constdb_comment("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); diff --git a/src/map/skill.c b/src/map/skill.c index ec4b8989eca..131672e5766 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -5318,7 +5318,7 @@ static int skill_castend_damage_id(struct block_list *src, struct block_list *bl } else { sc_start(src, src, SC_NO_SWITCH_WEAPON, 100, 1, skill->get_time(skill_id, skill_lv), skill_id); skill->area_temp[0] = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, BCT_ENEMY, skill->area_sub_count); - + // recursive invocation of skill->castend_damage_id() with flag|1 map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), skill->splash_target(src), src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill->castend_damage_id); } @@ -10145,7 +10145,7 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * int level = 0; if (sd != NULL) level = skill_id == AB_CLEMENTIA ? pc->checkskill(sd, AL_BLESSING) : pc->checkskill(sd, AL_INCAGI); - + if (sd == NULL || sd->status.party_id == 0 || flag & 1) { clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, level, skill->get_time(skill_id, skill_lv), skill_id)); } else if (sd != NULL) { @@ -17962,8 +17962,17 @@ static void skill_autospell_select_spell(struct block_list *bl, int skill_lv) if ((upper_idx - lower_idx) > 1) skill_idx += rnd() % (upper_idx - lower_idx); + // @TODO: Is this how AutoSpell works for non-players after rebalance? I made it the same as the player one... const struct s_autospell_db *sk = &skill->dbs->autospell_db[skill_idx]; - sc_start4(bl, bl, SC_AUTOSPELL, 100, skill_lv, sk->skill_id, sk->skill_lv[skill_lv - 1], 0, + int spell_level = sk->skill_lv[skill_lv - 1]; + if (spell_level == HALF_AUTOSPELL_LEVEL) { + spell_level = skill_lv / 2; + + if (spell_level == 0) + spell_level = 1; + } + + sc_start4(bl, bl, SC_AUTOSPELL, 100, skill_lv, sk->skill_id, spell_level, 0, skill->get_time(SA_AUTOSPELL, skill_lv), SA_AUTOSPELL); } @@ -17995,6 +18004,14 @@ static int skill_autospell_spell_selected(struct map_session_data *sd, uint16 sk return 0; // Don't have enough level to use int max_lv = sk->skill_lv[autospell_lv - 1]; + + if (max_lv == HALF_AUTOSPELL_LEVEL) { + max_lv = autospell_lv / 2; + + if (max_lv == 0) + max_lv = 1; + } + if (sk->spirit_boost && sd->sc.data[SC_SOULLINK] != NULL && sd->sc.data[SC_SOULLINK]->val2 == SL_SAGE) max_lv = skill->dbs->db[skill->get_index(skill_id)].max; // Soul Linker bonus. [Skotlex] @@ -24919,8 +24936,8 @@ static void skill_read_autospell_skill_level(struct config_setting_t *conf, stru snprintf(lv, sizeof(lv), "Lv%d", i + 1); int level; - if (libconfig->setting_lookup_int(t, lv, &level) == CONFIG_TRUE) { - if (level >= 0 && level <= MAX_SKILL_LEVEL) + if (map->setting_lookup_const(t, lv, &level) == CONFIG_TRUE) { + if ((level >= 0 && level <= MAX_SKILL_LEVEL) || level == HALF_AUTOSPELL_LEVEL) sk->skill_lv[i] = level; else ShowWarning("%s: Invalid SkillLevel %d specified in level %d for skill ID %d in %s! Minimum is 0, maximum is %d. Defaulting to 0...\n", @@ -24932,8 +24949,8 @@ static void skill_read_autospell_skill_level(struct config_setting_t *conf, stru } int level; - if (libconfig->setting_lookup_int(conf, "SkillLevel", &level) == CONFIG_TRUE) { - if (level >= 0 && level <= MAX_SKILL_LEVEL) + if (map->setting_lookup_const(conf, "SkillLevel", &level) == CONFIG_TRUE) { + if ((level >= 0 && level <= MAX_SKILL_LEVEL) || level == HALF_AUTOSPELL_LEVEL) skill->level_set_value(sk->skill_lv, level); else ShowWarning("%s: Invalid SkillLevel %d specified for skill ID %d in %s! Minimum is 0, maximum is %d. Defaulting to 0...\n", diff --git a/src/map/skill.h b/src/map/skill.h index 5002617d1b1..ed8abf13d18 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -77,7 +77,7 @@ struct status_change_entry; #define MAX_SKILL_SPELLBOOK_DB 17 #define MAX_SKILL_MAGICMUSHROOM_DB 23 -#define MAX_AUTOSPELL_DB 7 +#define MAX_AUTOSPELL_DB 9 //Walk intervals at which chase-skills are attempted to be triggered. #define WALK_SKILL_INTERVAL 5 @@ -85,6 +85,9 @@ struct status_change_entry; // Max Crimson Marker targets (RL_C_MARKER) #define MAX_SKILL_CRIMSON_MARKER 3 +// Autospell db special level/constant for "use half of casted level" +#define HALF_AUTOSPELL_LEVEL -1 + /** * Enumerations **/ @@ -143,7 +146,7 @@ enum e_skill_inf2 { INF2_HIDDEN_TRAP = 0x00080000, ///< Traps that are hidden (based on trap_visiblity battle conf) INF2_IS_COMBO_SKILL = 0x00100000, ///< Sets whether a skill can be used in combos or not INF2_NO_STASIS = 0x00200000, - INF2_NO_KAGEHUMI = 0x00400000, + INF2_NO_KAGEHUMI = 0x00400000, INF2_RANGE_VULTURE = 0x00800000, ///< Range is modified by AC_VULTURE INF2_RANGE_SNAKEEYE = 0x01000000, ///< Range is modified by GS_SNAKEEYE INF2_RANGE_SHADOWJUMP = 0x02000000, ///< Range is modified by NJ_SHADOWJUMP @@ -1815,7 +1818,7 @@ enum skill_enabled_npc_flags { struct s_autospell_db { int autospell_level; //< Minimum AutoSpell level to show this skill int skill_id; //< Skill Id - int skill_lv[MAX_SKILL_LEVEL]; //< Maximum usable skill level at each AutoSpell level + int skill_lv[MAX_SKILL_LEVEL]; //< Maximum usable skill level at each AutoSpell level (also accepts HALF_AUTOSPELL_LEVEL as level) bool spirit_boost; //< Whether Sage's Spirit boosts this skill to maximum level }; diff --git a/src/map/status.c b/src/map/status.c index a6a4e96a9fc..3099b29e66f 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -7701,8 +7701,12 @@ static int status_change_start_sub(struct block_list *src, struct block_list *bl case SC_AUTOSPELL: //Val1 Skill LV of Autospell //Val2 Skill ID to cast - //Val3 Max Lv to cast - val4 = 5 + val1*2; //Chance of casting + //Val3 Max Lv to cast (pre-re) / Lv to cast (zero) +#ifndef RENEWAL + val4 = 5 + val1 * 2; // Chance of casting +#else + val4 = 2 * val1; // Chance of casting +#endif break; case SC_VOLCANO: #ifndef RENEWAL