Browse Source

Fixed SL_HIGH (#6699)

Added a central random function for chance calculation
Added a missing status change end for SC_SPIRIT on jobchange
Lemongrass3110 3 years ago
parent
commit
0449f39015
5 changed files with 27 additions and 21 deletions
  1. 4 0
      src/common/random.cpp
  2. 1 0
      src/common/random.hpp
  3. 3 0
      src/map/pc.cpp
  4. 9 20
      src/map/skill.cpp
  5. 10 1
      src/map/status.cpp

+ 4 - 0
src/common/random.cpp

@@ -42,3 +42,7 @@ int32 rnd_value( int32 min, int32 max ){
 
 	return min + (int32)( rnd_uniform() * ( max - min + 1 ) );
 }
+
+bool rnd_chance( uint16 chance, uint16 base ){
+	return rnd_value( 0, base ) < chance;
+}

+ 1 - 0
src/common/random.hpp

@@ -10,5 +10,6 @@ void rnd_init(void);
 
 int32 rnd(void);// [0, SINT32_MAX]
 int32 rnd_value(int32 min, int32 max);// [min, max]
+bool rnd_chance( uint16 chance, uint16 base );
 
 #endif /* RANDOM_HPP */

+ 3 - 0
src/map/pc.cpp

@@ -10258,6 +10258,9 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)
 		status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER);
 	if (sd->sc.data[SC_SOULATTACK] && !pc_checkskill(sd, SU_SOULATTACK))
 		status_change_end(&sd->bl, SC_SOULATTACK, INVALID_TIMER);
+	if( sd->sc.data[SC_SPIRIT] ){
+		status_change_end( &sd->bl, SC_SPIRIT, INVALID_TIMER );
+	}
 
 	if(sd->status.manner < 0)
 		clif_changestatus(sd,SP_MANNER,sd->status.manner);

+ 9 - 20
src/map/skill.cpp

@@ -9968,15 +9968,17 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 	case SL_STAR:
 	case SL_SUPERNOVICE:
 	case SL_WIZARD:
-		if (skill_id == SL_SUPERNOVICE && dstsd && dstsd->die_counter && !(rnd()%100))
-		{	//Erase death count 1% of the casts
-			pc_setparam(dstsd, SP_PCDIECOUNTER, 0);
-			clif_specialeffect(bl, EF_ANGEL2, AREA);
-			//SC_SPIRIT invokes status_calc_pc for us.
-		}
-
+	case SL_HIGH:
 		if( sc_start2( src, bl, type, 100, skill_lv, skill_id, skill_get_time( skill_id, skill_lv ) ) ){
 			clif_skill_nodamage( src, bl, skill_id, skill_lv, 1 );
+
+			// 1% chance to erase death count on successful cast
+			if( skill_id == SL_SUPERNOVICE && dstsd && dstsd->die_counter && rnd_chance( 1, 100 )  ){
+				pc_setparam( dstsd, SP_PCDIECOUNTER, 0 );
+				clif_specialeffect( bl, EF_ANGEL2, AREA );
+				status_calc_pc( dstsd, SCO_NONE );
+			}
+
 			sc_start( src, src, SC_SMA, 100, skill_lv, skill_get_time( SL_SMA, skill_lv ) );
 		}else{
 			if( sd ){
@@ -9984,19 +9986,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			}
 		}
 		break;
-	case SL_HIGH:
-		if (sd && tsc && (tsc->data[SC_SOULGOLEM] || tsc->data[SC_SOULSHADOW] || tsc->data[SC_SOULFALCON] || tsc->data[SC_SOULFAIRY])) { // Soul links from Soul Linker and Soul Reaper skills don't stack.
-			clif_skill_fail(sd, skill_id, USESKILL_FAIL,0);
-			break;
-		}
-		if (sd && !(dstsd && (dstsd->class_&JOBL_UPPER) && !(dstsd->class_&JOBL_2) && dstsd->status.base_level < 70)) {
-			clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
-			break;
-		}
-		clif_skill_nodamage(src,bl,skill_id,skill_lv,
-			sc_start4(src,bl,type,100,skill_lv,skill_id,0,0,skill_get_time(skill_id,skill_lv)));
-		sc_start(src,src,SC_SMA,100,skill_lv,skill_get_time(SL_SMA,skill_lv));
-		break;
 	case SP_SOULGOLEM:
 	case SP_SOULSHADOW:
 	case SP_SOULFALCON:

+ 10 - 1
src/map/status.cpp

@@ -9475,6 +9475,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		case SC_SPIRIT:
 			if( sd ){
 				uint64 target_class = 0;
+				uint64 mask = MAPID_UPPERMASK;
 
 				switch( val2 ){
 					case SL_ALCHEMIST:
@@ -9522,12 +9523,20 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 					case SL_WIZARD:
 						target_class = MAPID_WIZARD;
 						break;
+					case SL_HIGH:
+						if( sd->status.base_level < 70 ){
+							return 0;
+						}
+
+						mask |= JOBL_UPPER;
+						target_class = MAPID_NOVICE_HIGH;
+						break;
 					default:
 						ShowError( "Unknown skill id %d for SC_SPIRIT.\n", val2 );
 						return 0;
 				}
 
-				if( !( ( sd->class_ & MAPID_UPPERMASK ) == target_class ) ){
+				if( ( sd->class_ & mask ) != target_class ){
 					return 0;
 				}
 			}else{