From bee2c27d786ddb8b7e92590655a8c40d48d05d6c Mon Sep 17 00:00:00 2001 From: eppc0330 <47050704+eppc0330@users.noreply.github.com> Date: Mon, 13 Mar 2023 14:25:02 +0900 Subject: [PATCH] Implement NPC_ALL_STAT_DOWN (#7637) --- db/re/skill_db.yml | 12 ++++++++++++ db/re/status.yml | 13 +++++++++++++ src/map/script_constants.hpp | 1 + src/map/skill.cpp | 6 ++++++ src/map/status.cpp | 24 ++++++++++++++++++++++++ src/map/status.hpp | 1 + 6 files changed, 57 insertions(+) diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index 7b57d015d3..41c116068b 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -17907,6 +17907,18 @@ Body: NoReiteration: true NoOverlap: true Status: PropertyWalk + - Id: 751 + Name: NPC_ALL_STAT_DOWN + Description: Decrease All Stats + MaxLevel: 5 + TargetType: Attack + DamageFlags: + NoDamage: true + Flags: + IsNpc: true + Range: 9 + Duration1: 10000 + Status: ALL_STAT_DOWN - Id: 752 Name: NPC_GRADUAL_GRAVITY Description: Increased Gravity diff --git a/db/re/status.yml b/db/re/status.yml index 16ccd4797a..a231b3b6df 100644 --- a/db/re/status.yml +++ b/db/re/status.yml @@ -8556,3 +8556,16 @@ Body: DisplayPc: true NoDispell: true NoClearance: true + - Status: ALL_STAT_DOWN + Icon: EFST_ALL_STAT_DOWN + DurationLookup: NPC_ALL_STAT_DOWN + CalcFlags: + Str: true + Agi: true + Vit: true + Int: true + Dex: true + Luk: true + Flags: + NoDispell: true + NoClearance: true diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index 5ba824c51d..116476db33 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -1873,6 +1873,7 @@ export_constant(SC_GOLDENE_TONE); export_constant(SC_TEMPERING); export_constant(SC_GRADUAL_GRAVITY); + export_constant(SC_ALL_STAT_DOWN); #ifdef RENEWAL export_constant(SC_EXTREMITYFIST2); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 21c72b5e97..93df2365ce 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -7822,6 +7822,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui clif_skill_nodamage(src, bl, skill_id, skill_lv, 1); break; + case NPC_ALL_STAT_DOWN: + status_change_start(src, bl, type, 10000, skill_lv, 0, 0, 0, skill_get_time(skill_id, skill_lv), SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF); + clif_skill_nodamage(src, bl, skill_id, skill_lv, 1); + clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, DMG_SINGLE); + break; + #ifdef RENEWAL // EDP also give +25% WATK poison pseudo element to user. case ASC_EDP: diff --git a/src/map/status.cpp b/src/map/status.cpp index 02c2bfb025..a7b3e7340f 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -6412,7 +6412,10 @@ static unsigned short status_calc_str(struct block_list *bl, status_change *sc, str += sc->getSCE(SC_ALMIGHTY)->val1; if (sc->getSCE(SC_ULTIMATECOOK)) str += sc->getSCE(SC_ULTIMATECOOK)->val1; + if (sc->getSCE(SC_ALL_STAT_DOWN)) + str -= sc->getSCE(SC_ALL_STAT_DOWN)->val2; + //TODO: Stat points should be able to be decreased below 0 return (unsigned short)cap_value(str,0,USHRT_MAX); } @@ -6496,7 +6499,10 @@ static unsigned short status_calc_agi(struct block_list *bl, status_change *sc, agi += sc->getSCE(SC_ALMIGHTY)->val1; if (sc->getSCE(SC_ULTIMATECOOK)) agi += sc->getSCE(SC_ULTIMATECOOK)->val1; + if (sc->getSCE(SC_ALL_STAT_DOWN)) + agi -= sc->getSCE(SC_ALL_STAT_DOWN)->val2; + //TODO: Stat points should be able to be decreased below 0 return (unsigned short)cap_value(agi,0,USHRT_MAX); } @@ -6572,7 +6578,10 @@ static unsigned short status_calc_vit(struct block_list *bl, status_change *sc, vit += sc->getSCE(SC_ULTIMATECOOK)->val1; if (sc->getSCE(SC_CUP_OF_BOZA)) vit += 10; + if (sc->getSCE(SC_ALL_STAT_DOWN)) + vit -= sc->getSCE(SC_ALL_STAT_DOWN)->val2; + //TODO: Stat points should be able to be decreased below 0 return (unsigned short)cap_value(vit,0,USHRT_MAX); } @@ -6661,7 +6670,10 @@ static unsigned short status_calc_int(struct block_list *bl, status_change *sc, int_ += sc->getSCE(SC_ALMIGHTY)->val1; if (sc->getSCE(SC_ULTIMATECOOK)) int_ += sc->getSCE(SC_ULTIMATECOOK)->val1; + if (sc->getSCE(SC_ALL_STAT_DOWN)) + int_ -= sc->getSCE(SC_ALL_STAT_DOWN)->val2; + //TODO: Stat points should be able to be decreased below 0 return (unsigned short)cap_value(int_,0,USHRT_MAX); } @@ -6747,7 +6759,10 @@ static unsigned short status_calc_dex(struct block_list *bl, status_change *sc, dex += sc->getSCE(SC_ALMIGHTY)->val1; if (sc->getSCE(SC_ULTIMATECOOK)) dex += sc->getSCE(SC_ULTIMATECOOK)->val1; + if (sc->getSCE(SC_ALL_STAT_DOWN)) + dex -= sc->getSCE(SC_ALL_STAT_DOWN)->val2; + //TODO: Stat points should be able to be decreased below 0 return (unsigned short)cap_value(dex,0,USHRT_MAX); } @@ -6821,7 +6836,10 @@ static unsigned short status_calc_luk(struct block_list *bl, status_change *sc, luk += sc->getSCE(SC_ULTIMATECOOK)->val1; if (sc->getSCE(SC_MYSTICPOWDER)) luk += 10; + if (sc->getSCE(SC_ALL_STAT_DOWN)) + luk -= sc->getSCE(SC_ALL_STAT_DOWN)->val2; + //TODO: Stat points should be able to be decreased below 0 return (unsigned short)cap_value(luk,0,USHRT_MAX); } @@ -10895,6 +10913,12 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty tick_time = status_get_sc_interval(type); val4 = tick - tick_time; // Remaining time break; + case SC_ALL_STAT_DOWN: + val2 = 20 * val1; + if( val1 < skill_get_max( NPC_ALL_STAT_DOWN ) ){ + val2 -= 10; + } + break; case SC_BOSSMAPINFO: if( sd != NULL ) { struct mob_data *boss_md = map_getmob_boss(bl->m); // Search for Boss on this Map diff --git a/src/map/status.hpp b/src/map/status.hpp index 899f3b2591..0f2599db4d 100644 --- a/src/map/status.hpp +++ b/src/map/status.hpp @@ -1264,6 +1264,7 @@ enum sc_type : int16 { SC_TEMPERING, SC_GRADUAL_GRAVITY, + SC_ALL_STAT_DOWN, #ifdef RENEWAL SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled