Przeglądaj źródła

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!
Aleos 5 lat temu
rodzic
commit
e4e593fbbe
4 zmienionych plików z 37 dodań i 18 usunięć
  1. 1 0
      src/map/script_constants.hpp
  2. 7 7
      src/map/skill.cpp
  3. 28 11
      src/map/status.cpp
  4. 1 0
      src/map/status.hpp

+ 1 - 0
src/map/script_constants.hpp

@@ -1586,6 +1586,7 @@
 	export_constant(SC_SOUNDOFDESTRUCTION);
 	export_constant(SC_LUXANIMA);
 	export_constant(SC_REUSE_LIMIT_LUXANIMA);
+	export_constant(SC_ENSEMBLEFATIGUE);
 #ifdef RENEWAL
 	export_constant(SC_EXTREMITYFIST2);
 #endif

+ 7 - 7
src/map/skill.cpp

@@ -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_lv_dance = skill_lv;
 
-	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));
+	if (skill_get_inf2(skill_id, INF2_ISENSEMBLE))
 		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);
 }
@@ -7836,9 +7832,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 
 	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);
-			status_change_end(bl, SC_LONGING, INVALID_TIMER);
+			status_change_end(bl, SC_ENSEMBLEFATIGUE, INVALID_TIMER);
 		}
 		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);
 						tsd->skill_id_dance = skill_id;
 						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;

+ 28 - 11
src/map/status.cpp

@@ -650,9 +650,7 @@ void initChangeTables(void)
 #endif
 	add_sc( WS_CARTTERMINATION	, SC_STUN		);
 	set_sc( WS_OVERTHRUSTMAX	, SC_MAXOVERTHRUST	, EFST_OVERTHRUSTMAX, SCB_NONE );
-#ifdef RENEWAL
-	set_sc( CG_SPECIALSINGER	, SC_LONGING		, EFST_ENSEMBLEFATIGUE	, SCB_NONE );
-#else
+#ifndef RENEWAL
 	set_sc( CG_LONGINGFREEDOM	, SC_LONGING		, EFST_LONGING		, SCB_SPEED|SCB_ASPD );
 #endif
 	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_ADD_ATK_DAMAGE] = EFST_ADD_ATK_DAMAGE;
 	StatusIconChangeTable[SC_ADD_MATK_DAMAGE] = EFST_ADD_MATK_DAMAGE;
+	StatusIconChangeTable[SC_ENSEMBLEFATIGUE] = EFST_ENSEMBLEFATIGUE;
 
 	// Battleground Queue
 	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;
 
 	StatusChangeFlagTable[SC_ANCILLA] |= SCB_REGEN;
+	StatusChangeFlagTable[SC_ENSEMBLEFATIGUE] |= SCB_SPEED|SCB_ASPD;
 
 #ifdef RENEWAL
 	// renewal EDP increases your weapon atk
@@ -1665,9 +1665,6 @@ void initChangeTables(void)
 	StatusChangeStateTable[SC_VACUUM_EXTREME]		|= SCS_NOMOVE;
 	StatusChangeStateTable[SC_SUHIDE]				|= SCS_NOMOVE;
 	StatusChangeStateTable[SC_SV_ROOTTWIST]			|= SCS_NOMOVE;
-#ifdef RENEWAL
-	StatusChangeStateTable[SC_LONGING]				|= SCS_NOMOVE;
-#endif
 	StatusChangeStateTable[SC_GRAVITYCONTROL]		|= SCS_NOMOVE;
 
 	/* StatusChangeState (SCS_) NOPICKUPITEMS */
@@ -1693,6 +1690,7 @@ void initChangeTables(void)
 #ifdef RENEWAL
 	StatusChangeStateTable[SC_BASILICA_CELL]		|= SCS_NOCAST;
 	StatusChangeStateTable[SC_ROKISWEIL]			|= SCS_NOCAST;
+	StatusChangeStateTable[SC_ENSEMBLEFATIGUE]		|= SCS_NOCAST;
 #endif
 	StatusChangeStateTable[SC__BLOODYLUST]			|= 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_GRAVITYCONTROL] && skill_block_check(src, SC_GRAVITYCONTROL, 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;
 
@@ -7322,12 +7323,15 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
 			val = sc->data[SC_CHASEWALK]->val3;
 		else {
 			val = 0;
-#ifndef RENEWAL
-			// Longing for Freedom cancels song/dance penalty
+			// Longing for Freedom/Special Singer 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] )
 				val = max( val, 50 - 10 * sc->data[SC_LONGING]->val1 );
-			else
 #endif
+			else
 			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)) );
 
@@ -7529,7 +7533,10 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, b
 	} else {
 		if (sc->data[SC_DONTFORGETME])
 			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])
 			bonus -= sc->data[SC_LONGING]->val2 / 10;
 #endif
@@ -7729,7 +7736,10 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
 
 	if(sc->data[SC_DONTFORGETME])
 		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])
 		aspd_rate += sc->data[SC_LONGING]->val2;
 #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.
 			break;
 #else
+		case SC_ENSEMBLEFATIGUE:
+			val2 = 30; // Speed and ASPD penalty
+			break;
 		case SC_RICHMANKIM:
 			val2 = 10 + 10 * val1; // Exp increase bonus
 			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)
 					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);
+#endif
 			}
 			break;
 		case SC_NOCHAT:

+ 1 - 0
src/map/status.hpp

@@ -932,6 +932,7 @@ enum sc_type : int16 {
 
 	SC_LUXANIMA,
 	SC_REUSE_LIMIT_LUXANIMA,
+	SC_ENSEMBLEFATIGUE,
 
 #ifdef RENEWAL
 	SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled