From 0323aa37c8c74642796328672335c12401b1aa12 Mon Sep 17 00:00:00 2001 From: Aleos Date: Thu, 24 Mar 2022 12:50:02 -0400 Subject: [PATCH] Adds INF2_ISTOGGLEABLE skill flag (#6737) * Adds the INF2_ISTOGGLEABLE skill flag which is used to enable or disable a skill's status. When toggled off the skill doesn't consume HP/SP. Thanks to @Lemongrass3110! --- db/pre-re/skill_db.yml | 28 +++++++++++++++ db/re/skill_db.yml | 48 +++++++++++++++++++++++++ doc/skill_db.txt | 1 + src/map/script_constants.hpp | 1 + src/map/skill.cpp | 70 ++++++++++-------------------------- src/map/skill.hpp | 4 ++- 6 files changed, 100 insertions(+), 52 deletions(-) diff --git a/db/pre-re/skill_db.yml b/db/pre-re/skill_db.yml index 5ddcff8039..4b0bc099eb 100644 --- a/db/pre-re/skill_db.yml +++ b/db/pre-re/skill_db.yml @@ -1977,6 +1977,7 @@ Body: IgnoreKagehumi: true AllowOnMado: true IgnoreWugBite: true + Toggleable: true Range: 1 Hit: Single HitCount: 1 @@ -4097,6 +4098,7 @@ Body: NoDamage: true Flags: AllowOnMado: true + Toggleable: true Hit: Single HitCount: 1 Duration1: @@ -4729,6 +4731,7 @@ Body: Flags: IgnoreKagehumi: true IgnoreWugBite: true + Toggleable: true Hit: Single HitCount: 1 Duration1: @@ -5078,6 +5081,7 @@ Body: NoDamage: true Flags: IsQuest: true + Toggleable: true Hit: Single HitCount: 1 Duration1: 600000 @@ -6757,6 +6761,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Duration1: 300000 @@ -9952,6 +9958,8 @@ Body: DamageFlags: NoDamage: true IgnoreFlee: true + Flags: + Toggleable: true Hit: Single HitCount: 1 CastCancel: true @@ -10632,6 +10640,7 @@ Body: NoDamage: true Flags: IgnoreKagehumi: true + Toggleable: true Hit: Single HitCount: 1 CastTime: 1200 @@ -11256,6 +11265,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Knockback: 4 @@ -11307,6 +11318,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Requires: @@ -11352,6 +11365,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Requires: @@ -11395,6 +11410,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Requires: @@ -11441,6 +11458,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Requires: @@ -11876,6 +11895,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 AfterCastActDelay: 1000 @@ -14080,6 +14101,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Element: Weapon @@ -16955,6 +16978,7 @@ Body: NoDamage: true Flags: IsQuest: true + Toggleable: true Hit: Single Knockback: 2 Duration1: 300000 @@ -32850,6 +32874,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 AfterCastActDelay: 800 @@ -32865,6 +32891,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Duration1: 300000 diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index c4fca09386..76abbc201a 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -1980,6 +1980,7 @@ Body: AllowWhenHidden: true IgnoreKagehumi: true IgnoreWugBite: true + Toggleable: true Range: 1 Hit: Single HitCount: 1 @@ -4322,6 +4323,7 @@ Body: NoDamage: true Flags: AllowOnMado: true + Toggleable: true Hit: Single HitCount: 1 Duration1: @@ -4974,6 +4976,7 @@ Body: Flags: IgnoreKagehumi: true IgnoreWugBite: true + Toggleable: true Hit: Single HitCount: 1 Duration1: @@ -5341,6 +5344,7 @@ Body: NoDamage: true Flags: IsQuest: true + Toggleable: true Hit: Single HitCount: 1 Duration1: 600000 @@ -7127,6 +7131,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Duration1: 300000 @@ -7408,6 +7414,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 AfterCastActDelay: 800 @@ -10232,6 +10240,8 @@ Body: DamageFlags: NoDamage: true IgnoreFlee: true + Flags: + Toggleable: true Hit: Single HitCount: 1 CastCancel: true @@ -10899,6 +10909,7 @@ Body: NoDamage: true Flags: IgnoreKagehumi: true + Toggleable: true Hit: Single HitCount: 1 CastTime: 500 @@ -11528,6 +11539,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Knockback: 4 @@ -11601,6 +11614,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Requires: @@ -11646,6 +11661,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Requires: @@ -11689,6 +11706,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Requires: @@ -11735,6 +11754,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Requires: @@ -12175,6 +12196,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Duration1: 600000 @@ -14395,6 +14418,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Element: Weapon @@ -17930,6 +17955,7 @@ Body: NoDamage: true Flags: IsQuest: true + Toggleable: true Hit: Single Duration1: 900000 Duration2: 5000 @@ -20349,6 +20375,7 @@ Body: Flags: IgnoreKagehumi: true IgnoreWugBite: true + Toggleable: true Hit: Single HitCount: 1 AfterCastActDelay: 2000 @@ -21564,6 +21591,7 @@ Body: Flags: AllowOnWarg: true IncreaseDanceWithWugDamage: true + Toggleable: true Hit: Single HitCount: 1 Element: Weapon @@ -21698,6 +21726,7 @@ Body: Flags: IgnoreKagehumi: true IgnoreWugBite: true + Toggleable: true Hit: Single HitCount: 1 Duration1: 10000 @@ -30068,6 +30097,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 CastCancel: true @@ -30145,6 +30176,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 CastCancel: true @@ -30300,6 +30333,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 CastCancel: true @@ -30507,6 +30542,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 CastCancel: true @@ -31204,6 +31241,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 CastCancel: true @@ -31291,6 +31330,7 @@ Body: TargetType: Self Flags: AllowWhenHidden: true + Toggleable: true Hit: Single HitCount: 1 Duration1: 200000 @@ -36212,6 +36252,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 CastCancel: true @@ -36228,6 +36270,8 @@ Body: DamageFlags: NoDamage: true Splash: true + Flags: + Toggleable: true Hit: Single HitCount: 1 SplashArea: 10 @@ -43012,6 +43056,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 AfterCastActDelay: 800 @@ -43028,6 +43074,8 @@ Body: TargetType: Self DamageFlags: NoDamage: true + Flags: + Toggleable: true Hit: Single HitCount: 1 Duration1: 300000 diff --git a/doc/skill_db.txt b/doc/skill_db.txt index 17dfb3d70c..6b6461b975 100644 --- a/doc/skill_db.txt +++ b/doc/skill_db.txt @@ -103,6 +103,7 @@ IgnoreAutoGuard - Not blocked by SC_AUTOGUARD (When TargetType is Weapon only IgnoreCicada - Not blocked by SC_UTSUSEMI or SC_BUNSINJYUTSU (When TargetType is Weapon only). ShowScale - Shows AoE area while casting IgnoreGtb - Not blocked by Golden Thief Bug card. +Toggleable - Skill can be toggled on and off. When toggled off the skill doesn't consume HP/SP. --------------------------------------- diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index 516d7ba9e8..f6f29bcf11 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -8394,6 +8394,7 @@ export_constant(INF2_IGNORECICADA); export_constant(INF2_SHOWSCALE); export_constant(INF2_IGNOREGTB); + export_constant(INF2_TOGGLEABLE); /* skill no near npc flags */ export_constant(SKILL_NONEAR_WARPPORTAL); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 9291aa68a1..f186c9ac84 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -16693,7 +16693,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i return false; //Checks if disabling skill - in which case no SP requirements are necessary - if( sc && skill_disable_check(sc,skill_id)) + if( sc && skill_disable_check(*sc,skill_id)) return true; std::bitset inf2 = skill_db.find(skill_id)->inf2; @@ -18032,7 +18032,7 @@ struct s_skill_condition skill_get_requirement(struct map_session_data* sd, uint sc = NULL; //Checks if disabling skill - in which case no SP requirements are necessary - if( sc && skill_disable_check(sc,skill_id) ) + if( sc && skill_disable_check(*sc,skill_id) ) return req; skill_lv = cap_value(skill_lv, 1, MAX_SKILL_LEVEL); @@ -22917,61 +22917,29 @@ int skill_block_check(struct block_list *bl, sc_type type , uint16 skill_id) { return 0; } -/* Determines whether a skill is currently active or not - * Used for purposes of cancelling SP usage when disabling a skill +/** + * Determines whether a skill is currently active or not. Used for purposes of cancelling HP/SP usage when disabling a skill. + * @param sc: Status changes active on target + * @param skill_id: Skill to toggle + * @return True on success or false otherwise */ -int skill_disable_check(struct status_change *sc, uint16 skill_id) -{ - enum sc_type type = skill_get_sc(skill_id); +bool skill_disable_check(status_change &sc, uint16 skill_id) { + std::shared_ptr skill = skill_db.find(skill_id); - if (type <= SC_NONE || type >= SC_MAX) - return 0; - switch( skill_id ) { //HP & SP Consumption Check - case BS_MAXIMIZE: - case NV_TRICKDEAD: - case TF_HIDING: - case AS_CLOAKING: - case GC_CLOAKINGEXCEED: - case ST_CHASEWALK: - case CR_DEFENDER: - case CR_SHRINK: - case CR_AUTOGUARD: - case ML_DEFENDER: - case ML_AUTOGUARD: - case PA_GOSPEL: - case GS_GATLINGFEVER: - case TK_READYCOUNTER: - case TK_READYDOWN: - case TK_READYSTORM: - case TK_READYTURN: - case TK_RUN: - case SG_FUSION: - case KO_YAMIKUMO: - case RA_WUGDASH: - case RA_CAMOUFLAGE: - case SJ_LUNARSTANCE: - case SJ_STARSTANCE: - case SJ_UNIVERSESTANCE: - case SJ_SUNSTANCE: - case SP_SOULCOLLECT: - case IG_GUARD_STANCE: - case IG_ATTACK_STANCE: - if( sc->data[type] ) - return 1; - break; + if (skill == nullptr || skill->sc <= SC_NONE || skill->sc >= SC_MAX) + return false; + if (skill->inf2[INF2_TOGGLEABLE]) { + if (sc.data[skill->sc]) + return true; // These 2 skills contain a master and are not correctly pulled using skill_get_sc - case NC_NEUTRALBARRIER: - if( sc->data[SC_NEUTRALBARRIER_MASTER] ) - return 1; - break; - case NC_STEALTHFIELD: - if( sc->data[SC_STEALTHFIELD_MASTER] ) - return 1; - break; + if (skill->nameid == NC_NEUTRALBARRIER && sc.data[SC_NEUTRALBARRIER_MASTER]) + return true; + if (skill->nameid == NC_STEALTHFIELD && sc.data[SC_STEALTHFIELD_MASTER]) + return true; } - return 0; + return false; } int skill_get_elemental_type( uint16 skill_id , uint16 skill_lv ) { diff --git a/src/map/skill.hpp b/src/map/skill.hpp index 27316cbc56..04742e12f2 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -26,6 +26,7 @@ struct homun_data; struct skill_unit; struct s_skill_unit_group; struct status_change_entry; +struct status_change; #define MAX_SKILL_PRODUCE_DB 300 /// Max Produce DB #define MAX_PRODUCE_RESOURCE 12 /// Max Produce requirements @@ -108,6 +109,7 @@ enum e_skill_inf2 : uint8 { INF2_IGNORECICADA, // Skill is not blocked by SC_UTSUSEMI or SC_BUNSINJYUTSU (physical-skill only) INF2_SHOWSCALE, // Skill shows AoE area while casting INF2_IGNOREGTB, // Skill ignores effect of GTB + INF2_TOGGLEABLE, // Skill can be toggled on and off (won't consume HP/SP when toggled off) INF2_MAX, }; @@ -612,7 +614,7 @@ bool skill_check_condition_castend(struct map_session_data *sd, uint16 skill_id, int skill_check_condition_char_sub (struct block_list *bl, va_list ap); void skill_consume_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type); struct s_skill_condition skill_get_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv); -int skill_disable_check(struct status_change *sc, uint16 skill_id); +bool skill_disable_check(status_change &sc, uint16 skill_id); bool skill_pos_maxcount_check(struct block_list *src, int16 x, int16 y, uint16 skill_id, uint16 skill_lv, enum bl_type type, bool display_failure); int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16 *skill_lv, int range, int cast_flag);