Quellcode durchsuchen

Fixes Longing for Freedom making players stuck (#7957)

Fixes #7777

Fixes Longing for Freedom making players not be able to walk after songs have ended.
Remove the movement restriction from Longing for Freedom when it becomes active with an Ensemble skill.
Fixed partners moving out of song
Fixed normal attacks while in SC_LONGING

Thanks to @XanKriegor1!

Co-authored-by: Playtester <3785983+Playtester@users.noreply.github.com>
Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
Aleos vor 1 Monat
Ursprung
Commit
c8fdc58176
3 geänderte Dateien mit 43 neuen und 3 gelöschten Zeilen
  1. 8 0
      db/pre-re/status.yml
  2. 4 1
      src/map/skill.cpp
  3. 31 2
      src/map/status.cpp

+ 8 - 0
db/pre-re/status.yml

@@ -1706,6 +1706,11 @@ Body:
     CalcFlags:
       Speed: true
       Aspd: true
+    States:
+      NoMove: true
+      NoMoveCond: true
+      NoAttack: true
+      NoAttackCond: true
   - Status: Hermode
     Icon: EFST_HERMODE
     DurationLookup: CG_HERMODE
@@ -1770,6 +1775,8 @@ Body:
     States:
       NoMove: true
       NoMoveCond: true
+      NoAttack: true
+      NoAttackCond: true
     CalcFlags:
       Speed: true
       Regen: true
@@ -1781,6 +1788,7 @@ Body:
       RemoveOnChangeMap: true
       RequireWeapon: true
       OverlapIgnoreLevel: true
+      StopAttacking: true
     EndOnEnd:
       Longing: true
   - Status: Elementalchange

+ 4 - 1
src/map/skill.cpp

@@ -22624,7 +22624,10 @@ int32 skill_unit_move_sub(struct block_list* bl, va_list ap)
 
 	//Target-type check.
 	if( !(group->bl_flag&target->type && battle_check_target(&unit->bl,target,group->target_flag) > 0) ) {
-		if( group->src_id == target->id && group->state.song_dance&0x2 ) { //Ensemble check to see if they went out/in of the area [Skotlex]
+		status_change* tsc = status_get_sc( target );
+
+		// Ensemble check to see if the caster or the partner went out/in of the area
+		if( group->state.song_dance&0x2 && ( group->src_id == target->id || ( tsc != nullptr && tsc->getSCE( SC_DANCING ) != nullptr && group->src_id == tsc->getSCE( SC_DANCING )->val4 ) ) ){
 			if( flag&1 ) {
 				if( flag&2 ) { //Clear this skill id.
 					util::vector_erase_if_exists(skill_unit_cell, skill_id);

+ 31 - 2
src/map/status.cpp

@@ -2124,7 +2124,8 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
 			}
 		}
 
-		if (sc->getSCE(SC_DANCING) && flag!=2) {
+		// Only do skill specific checks here, normal attacks should have been checked already (additionally the skill db lookup would fail)
+		if( sc->getSCE( SC_DANCING ) != nullptr && flag != 2 && skill_id != 0 ){
 			std::shared_ptr<s_skill_db> skill = skill_db.find(skill_id);
 
 			if (!skill)
@@ -5627,6 +5628,10 @@ void status_calc_state( block_list& bl, status_change& sc, std::shared_ptr<s_sta
 					}
 					break;
 
+				case SC_LONGING:
+					// Does not do anything. SC_LONGING is just defined with SCS_NOMOVECOND to trigger a recalculation with the conditions under SC_DANCING above
+					break;
+
 				case SC_CRYSTALIZE:
 					if( bl.type != BL_MOB ){
 						restriction = true;
@@ -5681,7 +5686,31 @@ void status_calc_state( block_list& bl, status_change& sc, std::shared_ptr<s_sta
 
 	// Can't attack
 	if( scdb->state[SCS_NOATTACK] ){
-		status_calc_state_sub( bl, sc, start, scdb, sc.cant.attack, SCS_NOATTACK, SCS_NOATTACKCOND, func_not_impl );
+		status_calc_state_sub( bl, sc, start, scdb, sc.cant.attack, SCS_NOATTACK, SCS_NOATTACKCOND, []( block_list& bl, status_change& sc, bool& restriction, const sc_type type, const status_change_entry& sce ) -> bool {
+			// Check the specific conditions
+			switch( type ){
+				case SC_DANCING:
+					if( sce.val4 != 0 ){
+#ifndef RENEWAL
+						// In Pre-Renewal you can attack when SC_LONGING is active
+						if( sc.getSCE( SC_LONGING ) != nullptr ){
+							break;
+						}
+#endif
+						restriction = true;
+					}
+					break;
+
+				case SC_LONGING:
+					// Does not do anything. SC_LONGING is just defined with SCS_NOATTACKCOND to trigger a recalculation with the conditions under SC_DANCING above
+					break;
+
+				default:
+					return false;
+			}
+
+			return true;
+		} );
 	}
 
 	// Can't warp