Fixes Ensemble skills behavior (#5014)
* Fixes #4987. * Ensemble skills apply SC_ENSEMBLEFATIGUE which should disable skill casting and reduces movement speed/ASPD by 30%. * Applies SC_ENSEMBLEFATIGUE to both the caster and partner. Thanks to @LordWhiplash!
This commit is contained in:
parent
5d1edeb80b
commit
e4e593fbbe
@ -1586,6 +1586,7 @@
|
|||||||
export_constant(SC_SOUNDOFDESTRUCTION);
|
export_constant(SC_SOUNDOFDESTRUCTION);
|
||||||
export_constant(SC_LUXANIMA);
|
export_constant(SC_LUXANIMA);
|
||||||
export_constant(SC_REUSE_LIMIT_LUXANIMA);
|
export_constant(SC_REUSE_LIMIT_LUXANIMA);
|
||||||
|
export_constant(SC_ENSEMBLEFATIGUE);
|
||||||
#ifdef RENEWAL
|
#ifdef RENEWAL
|
||||||
export_constant(SC_EXTREMITYFIST2);
|
export_constant(SC_EXTREMITYFIST2);
|
||||||
#endif
|
#endif
|
||||||
|
@ -6449,12 +6449,8 @@ static int skill_castend_song(struct block_list* src, uint16 skill_id, uint16 sk
|
|||||||
sd->skill_id_dance = skill_id;
|
sd->skill_id_dance = skill_id;
|
||||||
sd->skill_lv_dance = skill_lv;
|
sd->skill_lv_dance = skill_lv;
|
||||||
|
|
||||||
if (skill_get_inf2(skill_id, INF2_ISENSEMBLE)) {
|
if (skill_get_inf2(skill_id, INF2_ISENSEMBLE))
|
||||||
sc_start(src, src, status_skill2sc(CG_SPECIALSINGER), 100, 1, skill_get_time(CG_SPECIALSINGER, skill_lv));
|
|
||||||
skill_check_pc_partner(sd, skill_id, &skill_lv, 3, 1);
|
skill_check_pc_partner(sd, skill_id, &skill_lv, 3, 1);
|
||||||
// todo, apply ensemble fatigue if it hits you + ensemble partner.. ??
|
|
||||||
// or maybe we do that in skill_check_pc_partner or something ??
|
|
||||||
}
|
|
||||||
|
|
||||||
return map_foreachinrange(skill_apply_songs, src, skill_get_splash(skill_id, skill_lv), splash_target(src), flag, src, skill_id, skill_lv, tick);
|
return map_foreachinrange(skill_apply_songs, src, skill_get_splash(skill_id, skill_lv), splash_target(src), flag, src, skill_id, skill_lv, tick);
|
||||||
}
|
}
|
||||||
@ -7836,9 +7832,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CG_SPECIALSINGER:
|
case CG_SPECIALSINGER:
|
||||||
if (tsc && tsc->data[SC_LONGING]) {
|
if (tsc && tsc->data[SC_ENSEMBLEFATIGUE]) {
|
||||||
clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
|
clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
|
||||||
status_change_end(bl, SC_LONGING, INVALID_TIMER);
|
status_change_end(bl, SC_ENSEMBLEFATIGUE, INVALID_TIMER);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -15330,6 +15326,10 @@ int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16
|
|||||||
clif_skill_nodamage(&tsd->bl, &sd->bl, skill_id, *skill_lv, 1);
|
clif_skill_nodamage(&tsd->bl, &sd->bl, skill_id, *skill_lv, 1);
|
||||||
tsd->skill_id_dance = skill_id;
|
tsd->skill_id_dance = skill_id;
|
||||||
tsd->skill_lv_dance = *skill_lv;
|
tsd->skill_lv_dance = *skill_lv;
|
||||||
|
#ifdef RENEWAL
|
||||||
|
sc_start(&sd->bl, &sd->bl, SC_ENSEMBLEFATIGUE, 100, 1, skill_get_time(CG_SPECIALSINGER, *skill_lv));
|
||||||
|
sc_start(&sd->bl, &tsd->bl, SC_ENSEMBLEFATIGUE, 100, 1, skill_get_time(CG_SPECIALSINGER, *skill_lv));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
|
@ -650,9 +650,7 @@ void initChangeTables(void)
|
|||||||
#endif
|
#endif
|
||||||
add_sc( WS_CARTTERMINATION , SC_STUN );
|
add_sc( WS_CARTTERMINATION , SC_STUN );
|
||||||
set_sc( WS_OVERTHRUSTMAX , SC_MAXOVERTHRUST , EFST_OVERTHRUSTMAX, SCB_NONE );
|
set_sc( WS_OVERTHRUSTMAX , SC_MAXOVERTHRUST , EFST_OVERTHRUSTMAX, SCB_NONE );
|
||||||
#ifdef RENEWAL
|
#ifndef RENEWAL
|
||||||
set_sc( CG_SPECIALSINGER , SC_LONGING , EFST_ENSEMBLEFATIGUE , SCB_NONE );
|
|
||||||
#else
|
|
||||||
set_sc( CG_LONGINGFREEDOM , SC_LONGING , EFST_LONGING , SCB_SPEED|SCB_ASPD );
|
set_sc( CG_LONGINGFREEDOM , SC_LONGING , EFST_LONGING , SCB_SPEED|SCB_ASPD );
|
||||||
#endif
|
#endif
|
||||||
set_sc( CG_HERMODE , SC_HERMODE , EFST_HERMODE , SCB_NONE );
|
set_sc( CG_HERMODE , SC_HERMODE , EFST_HERMODE , SCB_NONE );
|
||||||
@ -1386,6 +1384,7 @@ void initChangeTables(void)
|
|||||||
StatusIconChangeTable[SC_REF_T_POTION] = EFST_REF_T_POTION;
|
StatusIconChangeTable[SC_REF_T_POTION] = EFST_REF_T_POTION;
|
||||||
StatusIconChangeTable[SC_ADD_ATK_DAMAGE] = EFST_ADD_ATK_DAMAGE;
|
StatusIconChangeTable[SC_ADD_ATK_DAMAGE] = EFST_ADD_ATK_DAMAGE;
|
||||||
StatusIconChangeTable[SC_ADD_MATK_DAMAGE] = EFST_ADD_MATK_DAMAGE;
|
StatusIconChangeTable[SC_ADD_MATK_DAMAGE] = EFST_ADD_MATK_DAMAGE;
|
||||||
|
StatusIconChangeTable[SC_ENSEMBLEFATIGUE] = EFST_ENSEMBLEFATIGUE;
|
||||||
|
|
||||||
// Battleground Queue
|
// Battleground Queue
|
||||||
StatusIconChangeTable[SC_ENTRY_QUEUE_APPLY_DELAY] = EFST_ENTRY_QUEUE_APPLY_DELAY;
|
StatusIconChangeTable[SC_ENTRY_QUEUE_APPLY_DELAY] = EFST_ENTRY_QUEUE_APPLY_DELAY;
|
||||||
@ -1563,6 +1562,7 @@ void initChangeTables(void)
|
|||||||
StatusIconChangeTable[SC_USE_SKILL_SP_SHA] = EFST_USE_SKILL_SP_SHA;
|
StatusIconChangeTable[SC_USE_SKILL_SP_SHA] = EFST_USE_SKILL_SP_SHA;
|
||||||
|
|
||||||
StatusChangeFlagTable[SC_ANCILLA] |= SCB_REGEN;
|
StatusChangeFlagTable[SC_ANCILLA] |= SCB_REGEN;
|
||||||
|
StatusChangeFlagTable[SC_ENSEMBLEFATIGUE] |= SCB_SPEED|SCB_ASPD;
|
||||||
|
|
||||||
#ifdef RENEWAL
|
#ifdef RENEWAL
|
||||||
// renewal EDP increases your weapon atk
|
// renewal EDP increases your weapon atk
|
||||||
@ -1665,9 +1665,6 @@ void initChangeTables(void)
|
|||||||
StatusChangeStateTable[SC_VACUUM_EXTREME] |= SCS_NOMOVE;
|
StatusChangeStateTable[SC_VACUUM_EXTREME] |= SCS_NOMOVE;
|
||||||
StatusChangeStateTable[SC_SUHIDE] |= SCS_NOMOVE;
|
StatusChangeStateTable[SC_SUHIDE] |= SCS_NOMOVE;
|
||||||
StatusChangeStateTable[SC_SV_ROOTTWIST] |= SCS_NOMOVE;
|
StatusChangeStateTable[SC_SV_ROOTTWIST] |= SCS_NOMOVE;
|
||||||
#ifdef RENEWAL
|
|
||||||
StatusChangeStateTable[SC_LONGING] |= SCS_NOMOVE;
|
|
||||||
#endif
|
|
||||||
StatusChangeStateTable[SC_GRAVITYCONTROL] |= SCS_NOMOVE;
|
StatusChangeStateTable[SC_GRAVITYCONTROL] |= SCS_NOMOVE;
|
||||||
|
|
||||||
/* StatusChangeState (SCS_) NOPICKUPITEMS */
|
/* StatusChangeState (SCS_) NOPICKUPITEMS */
|
||||||
@ -1693,6 +1690,7 @@ void initChangeTables(void)
|
|||||||
#ifdef RENEWAL
|
#ifdef RENEWAL
|
||||||
StatusChangeStateTable[SC_BASILICA_CELL] |= SCS_NOCAST;
|
StatusChangeStateTable[SC_BASILICA_CELL] |= SCS_NOCAST;
|
||||||
StatusChangeStateTable[SC_ROKISWEIL] |= SCS_NOCAST;
|
StatusChangeStateTable[SC_ROKISWEIL] |= SCS_NOCAST;
|
||||||
|
StatusChangeStateTable[SC_ENSEMBLEFATIGUE] |= SCS_NOCAST;
|
||||||
#endif
|
#endif
|
||||||
StatusChangeStateTable[SC__BLOODYLUST] |= SCS_NOCAST;
|
StatusChangeStateTable[SC__BLOODYLUST] |= SCS_NOCAST;
|
||||||
StatusChangeStateTable[SC_DEATHBOUND] |= SCS_NOCAST;
|
StatusChangeStateTable[SC_DEATHBOUND] |= SCS_NOCAST;
|
||||||
@ -2468,6 +2466,9 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
|
|||||||
(sc->data[SC_NOVAEXPLOSING] && skill_block_check(src, SC_NOVAEXPLOSING, skill_id)) ||
|
(sc->data[SC_NOVAEXPLOSING] && skill_block_check(src, SC_NOVAEXPLOSING, skill_id)) ||
|
||||||
(sc->data[SC_GRAVITYCONTROL] && skill_block_check(src, SC_GRAVITYCONTROL, skill_id)) ||
|
(sc->data[SC_GRAVITYCONTROL] && skill_block_check(src, SC_GRAVITYCONTROL, skill_id)) ||
|
||||||
(sc->data[SC_KAGEHUMI] && skill_block_check(src, SC_KAGEHUMI, skill_id))
|
(sc->data[SC_KAGEHUMI] && skill_block_check(src, SC_KAGEHUMI, skill_id))
|
||||||
|
#ifdef RENEWAL
|
||||||
|
|| (sc->data[SC_ENSEMBLEFATIGUE] && skill_id != CG_SPECIALSINGER)
|
||||||
|
#endif
|
||||||
))
|
))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -7322,12 +7323,15 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
|
|||||||
val = sc->data[SC_CHASEWALK]->val3;
|
val = sc->data[SC_CHASEWALK]->val3;
|
||||||
else {
|
else {
|
||||||
val = 0;
|
val = 0;
|
||||||
#ifndef RENEWAL
|
// Longing for Freedom/Special Singer cancels song/dance penalty
|
||||||
// Longing for Freedom cancels song/dance penalty
|
#ifdef RENEWAL
|
||||||
|
if (sc->data[SC_ENSEMBLEFATIGUE])
|
||||||
|
val = max(val, sc->data[SC_ENSEMBLEFATIGUE]->val2);
|
||||||
|
#else
|
||||||
if( sc->data[SC_LONGING] )
|
if( sc->data[SC_LONGING] )
|
||||||
val = max( val, 50 - 10 * sc->data[SC_LONGING]->val1 );
|
val = max( val, 50 - 10 * sc->data[SC_LONGING]->val1 );
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
|
else
|
||||||
if( sd && sc->data[SC_DANCING] )
|
if( sd && sc->data[SC_DANCING] )
|
||||||
val = max( val, 500 - (40 + 10 * (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) * pc_checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON)) );
|
val = max( val, 500 - (40 + 10 * (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) * pc_checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON)) );
|
||||||
|
|
||||||
@ -7529,7 +7533,10 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, b
|
|||||||
} else {
|
} else {
|
||||||
if (sc->data[SC_DONTFORGETME])
|
if (sc->data[SC_DONTFORGETME])
|
||||||
bonus -= sc->data[SC_DONTFORGETME]->val2 / 10;
|
bonus -= sc->data[SC_DONTFORGETME]->val2 / 10;
|
||||||
#ifndef RENEWAL
|
#ifdef RENEWAL
|
||||||
|
if (sc->data[SC_ENSEMBLEFATIGUE])
|
||||||
|
bonus -= sc->data[SC_ENSEMBLEFATIGUE]->val2 / 10;
|
||||||
|
#else
|
||||||
if (sc->data[SC_LONGING])
|
if (sc->data[SC_LONGING])
|
||||||
bonus -= sc->data[SC_LONGING]->val2 / 10;
|
bonus -= sc->data[SC_LONGING]->val2 / 10;
|
||||||
#endif
|
#endif
|
||||||
@ -7729,7 +7736,10 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
|
|||||||
|
|
||||||
if(sc->data[SC_DONTFORGETME])
|
if(sc->data[SC_DONTFORGETME])
|
||||||
aspd_rate += sc->data[SC_DONTFORGETME]->val2;
|
aspd_rate += sc->data[SC_DONTFORGETME]->val2;
|
||||||
#ifndef RENEWAL
|
#ifdef RENEWAL
|
||||||
|
if (sc->data[SC_ENSEMBLEFATIGUE])
|
||||||
|
aspd_rate += sc->data[SC_ENSEMBLEFATIGUE]->val2;
|
||||||
|
#else
|
||||||
if(sc->data[SC_LONGING])
|
if(sc->data[SC_LONGING])
|
||||||
aspd_rate += sc->data[SC_LONGING]->val2;
|
aspd_rate += sc->data[SC_LONGING]->val2;
|
||||||
#endif
|
#endif
|
||||||
@ -10467,6 +10477,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
|||||||
val2 = 500-100*val1; // Aspd penalty.
|
val2 = 500-100*val1; // Aspd penalty.
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
|
case SC_ENSEMBLEFATIGUE:
|
||||||
|
val2 = 30; // Speed and ASPD penalty
|
||||||
|
break;
|
||||||
case SC_RICHMANKIM:
|
case SC_RICHMANKIM:
|
||||||
val2 = 10 + 10 * val1; // Exp increase bonus
|
val2 = 10 + 10 * val1; // Exp increase bonus
|
||||||
break;
|
break;
|
||||||
@ -13204,7 +13217,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
|
|||||||
if((sce->val1&0xFFFF) == CG_MOONLIT)
|
if((sce->val1&0xFFFF) == CG_MOONLIT)
|
||||||
clif_status_change(bl,EFST_MOON,0,0,0,0,0);
|
clif_status_change(bl,EFST_MOON,0,0,0,0,0);
|
||||||
|
|
||||||
|
#ifdef RENEWAL
|
||||||
|
status_change_end(bl, SC_ENSEMBLEFATIGUE, INVALID_TIMER);
|
||||||
|
#else
|
||||||
status_change_end(bl, SC_LONGING, INVALID_TIMER);
|
status_change_end(bl, SC_LONGING, INVALID_TIMER);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SC_NOCHAT:
|
case SC_NOCHAT:
|
||||||
|
@ -932,6 +932,7 @@ enum sc_type : int16 {
|
|||||||
|
|
||||||
SC_LUXANIMA,
|
SC_LUXANIMA,
|
||||||
SC_REUSE_LIMIT_LUXANIMA,
|
SC_REUSE_LIMIT_LUXANIMA,
|
||||||
|
SC_ENSEMBLEFATIGUE,
|
||||||
|
|
||||||
#ifdef RENEWAL
|
#ifdef RENEWAL
|
||||||
SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
|
SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
|
||||||
|
Loading…
x
Reference in New Issue
Block a user