Minor SC_STONEWAIT fixes (#6892)

* The SC_STONEWAIT status should not be applicable to the Undead element.
* Fixes the overall duration for SC_STONEWAIT and SC_STONE because of incorrect order of resistance application.
* Adds the delay parameter to sc_start functions since some statuses, if not most, have a delay of some sort before being applied to a target.
* Swaps the duration values for Stone Curse related skills.
Thanks to @Playtester!
This commit is contained in:
Aleos
2022-04-27 12:40:38 -04:00
committed by GitHub
parent ef6a682ca8
commit 3b9c28aa46
5 changed files with 59 additions and 107 deletions

View File

@@ -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: