diff --git a/src/common/random.cpp b/src/common/random.cpp index 5aa42d23f0..643a11bc8b 100644 --- a/src/common/random.cpp +++ b/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; +} diff --git a/src/common/random.hpp b/src/common/random.hpp index 4b51b87096..fadbfc7e47 100644 --- a/src/common/random.hpp +++ b/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 */ diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 1c884ed4f0..b195369367 100755 --- a/src/map/pc.cpp +++ b/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); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index ca856cc505..8ce6a63e45 100755 --- a/src/map/skill.cpp +++ b/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: diff --git a/src/map/status.cpp b/src/map/status.cpp index 56d9b3e530..8c79ade399 100644 --- a/src/map/status.cpp +++ b/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{