diff --git a/db/pre-re/skill_db.yml b/db/pre-re/skill_db.yml index 97e73f84da3..c54ab9e12f0 100644 --- a/db/pre-re/skill_db.yml +++ b/db/pre-re/skill_db.yml @@ -796,8 +796,8 @@ Body: Element: Earth CastCancel: true CastTime: 1000 - Duration1: 20000 - Duration2: 5000 + Duration1: 5000 + Duration2: 20000 Requires: SpCost: - Level: 1 @@ -5663,8 +5663,8 @@ Body: Hit: Single HitCount: 1 Element: Weapon - Duration1: 20000 - Duration2: 100 + Duration1: 100 + Duration2: 20000 Status: StoneWait - Id: 181 Name: NPC_CURSEATTACK @@ -15911,8 +15911,8 @@ Body: Area: 11 - Level: 5 Area: 14 - Duration1: 20000 - Duration2: 100 + Duration1: 100 + Duration2: 20000 Status: StoneWait - Id: 667 Name: NPC_WIDECONFUSE @@ -29647,7 +29647,8 @@ Body: HitCount: 1 CastCancel: true AfterCastActDelay: 1000 - Duration1: 10000 + Duration1: 100 + Duration2: 10000 Requires: SpCost: 30 Unit: diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index 33dd37a1f55..4cecf72fc0a 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -780,8 +780,8 @@ Body: Element: Earth CastCancel: true CastTime: 800 - Duration1: 17000 - Duration2: 5000 + Duration1: 5000 + Duration2: 17000 FixedCastTime: 200 Requires: SpCost: @@ -5933,8 +5933,8 @@ Body: Hit: Single HitCount: 1 Element: Weapon - Duration1: 17000 - Duration2: 100 + Duration1: 100 + Duration2: 17000 Status: StoneWait - Id: 181 Name: NPC_CURSEATTACK @@ -16310,8 +16310,8 @@ Body: Area: 11 - Level: 5 Area: 14 - Duration1: 17000 - Duration2: 100 + Duration1: 100 + Duration2: 17000 Status: StoneWait - Id: 667 Name: NPC_WIDECONFUSE @@ -19231,7 +19231,8 @@ Body: CastCancel: true CastTime: 2000 AfterCastActDelay: 2000 - Duration1: + Duration1: 100 + Duration2: - Level: 1 Time: 7000 - Level: 2 @@ -19242,7 +19243,6 @@ Body: Time: 13000 - Level: 5 Time: 15000 - Duration2: 100 Requires: SpCost: - Level: 1 @@ -32011,8 +32011,8 @@ Body: HitCount: 1 CastCancel: true AfterCastActDelay: 1000 - Duration1: 10000 - Duration2: 5000 + Duration1: 100 + Duration2: 10000 Requires: SpCost: 30 Unit: diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 00dca06b090..002ed65ba7b 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -1272,9 +1272,6 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 #endif ) { // Trigger status effects - enum sc_type type; - unsigned int time; - for (const auto &it : sd->addeff) { rate = it.rate; if( attack_type&BF_LONG ) // Any ranged physical attack takes status arrows into account (Grimtooth...) [DracoRPG] @@ -1299,58 +1296,24 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 continue; //Range Failed. } - type = it.sc; - time = it.duration; - - int32 val1 = 7, val2, val3; - - if (type == SC_STONEWAIT) { - val2 = src->id; - val3 = skill_get_time(status_db.getSkill(type), 7); - } else { - val2 = 0; - if (type == SC_BURNING) - val3 = src->id; - else - val3 = 0; - } - if (it.flag&ATF_TARGET) - status_change_start(src,bl,type,rate,val1,val2,val3,0,time,SCSTART_NONE); + sc_start(src, bl, it.sc, rate, 7, it.duration, 100); if (it.flag&ATF_SELF) - status_change_start(src,src,type,rate,val1,val2,val3,0,time,SCSTART_NONE); + sc_start(src, src, it.sc, rate, 7, it.duration, 100); } } if( skill_id ) { // Trigger status effects on skills - enum sc_type type; - unsigned int time; - for (const auto &it : sd->addeff_onskill) { if (skill_id != it.skill_id || !it.rate) continue; - type = it.sc; - time = it.duration; - - int32 val1 = 7, val2, val3; - - if (type == SC_STONEWAIT) { - val2 = src->id; - val3 = skill_get_time(status_db.getSkill(type), 7); - } else { - val2 = 0; - if (type == SC_BURNING) - val3 = src->id; - else - val3 = 0; - } if (it.target&ATF_TARGET) - status_change_start(src,bl,type,it.rate,val1,val2,val3,0,time,SCSTART_NONE); + sc_start(src, bl, it.sc, rate, 7, it.duration, 100); if (it.target&ATF_SELF) - status_change_start(src,src,type,it.rate,val1,val2,val3,0,time,SCSTART_NONE); + sc_start(src, src, it.sc, rate, 7, it.duration, 100); } //"While the damage can be blocked by Pneuma, the chance to break armor remains", irowiki. [Cydh] if (dmg_lv == ATK_BLOCK && skill_id == AM_ACIDTERROR) { @@ -1648,7 +1611,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; case NPC_PETRIFYATTACK: - sc_start4(src,bl,SC_STONEWAIT,(20*skill_lv),skill_lv,src->id,skill_get_time(skill_id,skill_lv),0,skill_get_time2(skill_id,skill_lv)); + sc_start2(src,bl,SC_STONEWAIT,(20*skill_lv),skill_lv,src->id,skill_get_time2(skill_id,skill_lv),skill_get_time(skill_id, skill_lv)); break; case NPC_CURSEATTACK: sc_start(src,bl,SC_CURSE,(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv)); @@ -2527,9 +2490,6 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * dstsd = BL_CAST(BL_PC, bl); if(dstsd && attack_type&BF_WEAPON) { //Counter effects. - enum sc_type type; - unsigned int time; - for (const auto &it : dstsd->addeff_atked) { rate = it.rate; if (attack_type&BF_LONG) @@ -2542,27 +2502,12 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * (it.flag&ATF_SHORT && !(attack_type&BF_SHORT))) continue; //Range Failed. } - type = it.sc; - time = it.duration; - - int32 val1 = 7, val2, val3; - - if (type == SC_STONEWAIT) { - val2 = src->id; - val3 = skill_get_time(status_db.getSkill(type), 7); - } else { - val2 = 0; - if (type == SC_BURNING) - val3 = src->id; - else - val3 = 0; - } if (it.flag&ATF_TARGET && src != bl) - status_change_start(src,src,type,rate,val1,val2,val3,0,time,SCSTART_NONE); + sc_start(src, src, it.sc, rate, 7, it.duration, 100); if (it.flag&ATF_SELF && !status_isdead(bl)) - status_change_start(src,bl,type,rate,val1,val2,val3,0,time,SCSTART_NONE); + sc_start(src, bl, it.sc, rate, 7, it.duration, 100); } } @@ -4892,7 +4837,7 @@ static int skill_tarotcard(struct block_list* src, struct block_list *target, ui int time = ((rand_eff == 0) ? skill_get_time2(skill_id, skill_lv) : skill_get_time2(status_db.getSkill(sc[rand_eff]), 1)); if (sc[rand_eff] == SC_STONEWAIT) - sc_start4(src, target, SC_STONEWAIT, 100, skill_lv, src->id, skill_get_time(status_db.getSkill(SC_STONEWAIT), 1), 0, time); + sc_start2(src, target, SC_STONEWAIT, 100, skill_lv, src->id, time, skill_get_time(status_db.getSkill(SC_STONEWAIT), 1)); else sc_start(src, target, sc[rand_eff], 100, skill_lv, time); break; @@ -8769,10 +8714,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (sd && sd->sc.data[SC_PETROLOGY_OPTION]) brate = sd->sc.data[SC_PETROLOGY_OPTION]->val3; - if (sc_start4(src,bl,type,(skill_lv*4+20)+brate, - skill_lv, src->id, skill_get_time(skill_id, skill_lv), 0, - skill_get_time2(skill_id,skill_lv))) - clif_skill_nodamage(src,bl,skill_id,skill_lv,1); + if (sc_start2(src, bl, type, (skill_lv * 4 + 20) + brate, skill_lv, src->id, skill_get_time2(skill_id, skill_lv), skill_get_time(skill_id, skill_lv))) + clif_skill_nodamage(src, bl, skill_id, skill_lv, 1); else if(sd) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); // Level 6-10 doesn't consume a red gem if it fails [celest] @@ -10358,7 +10301,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui sc_start4(src,bl,type,100,skill_lv,1000,src->id,0,skill_get_time2(skill_id,skill_lv)); break; case SC_STONEWAIT: - sc_start4(src,bl,type,100,skill_lv,src->id,skill_get_time(skill_id, skill_lv), 0, skill_get_time2(skill_id,skill_lv)); + sc_start2(src,bl,type,100,skill_lv,src->id,skill_get_time2(skill_id,skill_lv),skill_get_time(skill_id, skill_lv)); break; default: sc_start2(src,bl,type,100,skill_lv,src->id,skill_get_time2(skill_id,skill_lv)); @@ -10808,12 +10751,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( bl->id == skill_area_temp[1] ) break; // Already work on this target - status_change_start(src,bl,type,10000,skill_lv,src->id,skill_get_time(skill_id, skill_lv),0,skill_get_time2(skill_id,skill_lv), SCSTART_NOTICKDEF); + status_change_start(src,bl,type,10000,skill_lv,src->id,0,0,skill_get_time2(skill_id,skill_lv), SCSTART_NOTICKDEF, skill_get_time(skill_id, skill_lv)); } else { int rate = 45 + 5 * skill_lv + ( sd? sd->status.job_level : 50 ) / 4; // IroWiki says Rate should be reduced by target stats, but currently unknown if( rnd()%100 < rate ) { // Success on First Target - if( status_change_start(src,bl,type,10000,skill_lv,src->id,skill_get_time(skill_id, skill_lv),0,skill_get_time2(skill_id,skill_lv), SCSTART_NOTICKDEF) ) { + if( status_change_start(src,bl,type,10000,skill_lv,src->id,0,0,skill_get_time2(skill_id,skill_lv), SCSTART_NOTICKDEF, skill_get_time(skill_id, skill_lv)) ) { clif_skill_nodamage(src,bl,skill_id,skill_lv,1); skill_area_temp[1] = bl->id; map_foreachinallrange(skill_area_sub,bl,skill_get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id); @@ -15912,42 +15855,42 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t_t case UNT_ZENKAI_WATER: switch (rnd()%2 + 1) { case 1: - sc_start(ss, bl, SC_FREEZE, sg->val1*5, sg->skill_lv, skill_get_time(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_FREEZE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv)); break; case 2: - sc_start(ss, bl, SC_FREEZING, sg->val1*5, sg->skill_lv, skill_get_time(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_FREEZING, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv)); break; } break; case UNT_ZENKAI_LAND: switch (rnd()%2 + 1) { case 1: - sc_start4(ss, bl, SC_STONEWAIT, sg->val1*5, sg->skill_lv, ss->id, skill_get_time(sg->skill_id, sg->skill_lv), 0, skill_get_time2(sg->skill_id, sg->skill_lv)); + sc_start2(ss, bl, SC_STONEWAIT, sg->val1*5, sg->skill_lv, ss->id, skill_get_time2(sg->skill_id, sg->skill_lv), skill_get_time(sg->skill_id, sg->skill_lv)); break; case 2: - sc_start2(ss, bl, SC_POISON, sg->val1*5, sg->skill_lv, ss->id, skill_get_time(sg->skill_id, sg->skill_lv)); + sc_start2(ss, bl, SC_POISON, sg->val1*5, sg->skill_lv, ss->id, skill_get_time2(sg->skill_id, sg->skill_lv)); break; } break; case UNT_ZENKAI_FIRE: - sc_start4(ss, bl, SC_BURNING, sg->val1*5, sg->skill_lv, 1000, ss->id, 0, skill_get_time(sg->skill_id, sg->skill_lv)); + sc_start4(ss, bl, SC_BURNING, sg->val1*5, sg->skill_lv, 1000, ss->id, 0, skill_get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_ZENKAI_WIND: switch (rnd()%3 + 1) { case 1: - sc_start(ss, bl, SC_SLEEP, sg->val1*5, sg->skill_lv, skill_get_time(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_SLEEP, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv)); break; case 2: - sc_start(ss, bl, SC_SILENCE, sg->val1*5, sg->skill_lv, skill_get_time(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_SILENCE, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv)); break; case 3: - sc_start(ss, bl, SC_DEEPSLEEP, sg->val1*5, sg->skill_lv, skill_get_time(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_DEEPSLEEP, sg->val1*5, sg->skill_lv, skill_get_time2(sg->skill_id, sg->skill_lv)); break; } break; } } else - sc_start2(ss, bl,type,100,sg->val1,sg->val2,skill_get_time(sg->skill_id, sg->skill_lv)); + sc_start2(ss, bl,type,100,sg->val1,sg->val2,skill_get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_POISON_MIST: diff --git a/src/map/status.cpp b/src/map/status.cpp index d3a5e80b83b..38a33086149 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -8803,7 +8803,7 @@ t_tick status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_ tick_def2 = -2000; #endif break; - case SC_STONE: + case SC_STONEWAIT: #ifndef RENEWAL sc_def = status->mdef*100; sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10; @@ -9200,11 +9200,12 @@ void status_display_remove(struct block_list *bl, enum sc_type type) { * @param type: Status change (SC_*) * @param rate: Initial percentage rate of affecting bl (0~10000) * @param val1~4: Depends on type of status change - * @param tick: Initial duration that the status change affects bl + * @param duration: Initial duration that the status change affects bl * @param flag: Value which determines what parts to calculate. See e_status_change_start_flags + * @param delay: Delay in milliseconds before the SC is applied * @return adjusted duration based on flag values */ -int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,t_tick duration,unsigned char flag) { +int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,t_tick duration,unsigned char flag, int32 delay) { struct map_session_data *sd = NULL; struct status_change* sc; struct status_change_entry* sce; @@ -9298,6 +9299,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty return 0; break; case SC_STONE: + case SC_STONEWAIT: case SC_FREEZE: // Undead are immune to Freeze/Stone if (undead_flag && !(flag&SCSTART_NOAVOID)) @@ -10126,7 +10128,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty break; case SC_STONEWAIT: - val3 -= tick; // Petrify time - Incubation time + val3 = max(1, tick - delay); // Petrify time + tick = delay; break; case SC_DPOISON: @@ -13025,8 +13028,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const npc_touch_area_allnpc(sd,bl->m,bl->x,bl->y); // Trigger on-touch event. // Needed to be here to make sure OPT1_STONEWAIT has been cleared from the target - if (type == SC_STONEWAIT && sce->val4 > -1) - sc_start2(bl, bl, SC_STONE, 100, sce->val1, sce->val2, sce->val3); + if (type == SC_STONEWAIT) + status_change_start(bl, bl, SC_STONE, 100, sce->val1, sce->val2, 0, 0, sce->val3, SCSTART_NOAVOID); ers_free(sc_data_ers, sce); return 1; diff --git a/src/map/status.hpp b/src/map/status.hpp index dd1e92d311f..6f7840bf9d5 100644 --- a/src/map/status.hpp +++ b/src/map/status.hpp @@ -3218,12 +3218,17 @@ int status_isdead(struct block_list *bl); int status_isimmune(struct block_list *bl); t_tick status_get_sc_def(struct block_list *src,struct block_list *bl, enum sc_type type, int rate, t_tick tick, unsigned char flag); +int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,t_tick duration,unsigned char flag, int32 delay = 0); //Short version, receives rate in 1->100 range, and does not uses a flag setting. -#define sc_start(src, bl, type, rate, val1, tick) status_change_start(src,bl,type,100*(rate),val1,0,0,0,tick,SCSTART_NONE) -#define sc_start2(src, bl, type, rate, val1, val2, tick) status_change_start(src,bl,type,100*(rate),val1,val2,0,0,tick,SCSTART_NONE) -#define sc_start4(src, bl, type, rate, val1, val2, val3, val4, tick) status_change_start(src,bl,type,100*(rate),val1,val2,val3,val4,tick,SCSTART_NONE) - -int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,t_tick duration,unsigned char flag); +static int sc_start(block_list *src, block_list *bl, sc_type type, int32 rate, int32 val1, t_tick duration, int32 delay = 0) { + return status_change_start(src, bl, type, 100 * rate, val1, 0, 0, 0, duration, SCSTART_NONE, delay); +} +static int sc_start2(block_list *src, block_list *bl, sc_type type, int32 rate, int32 val1, int32 val2, t_tick duration, int32 delay = 0) { + return status_change_start(src, bl, type, 100 * rate, val1, val2, 0, 0, duration, SCSTART_NONE, delay); +} +static int sc_start4(block_list *src, block_list *bl, sc_type type, int32 rate, int32 val1, int32 val2, int32 val3, int32 val4, t_tick duration, int32 delay = 0) { + return status_change_start(src, bl, type, 100 * rate, val1, val2, val3, val4, duration, SCSTART_NONE, delay); +} int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line); #define status_change_end(bl,type,tid) status_change_end_(bl,type,tid,__FILE__,__LINE__) TIMER_FUNC(status_change_timer);