瀏覽代碼

Official status change base durations for Silence and Stone (fixes #990)
* The renewal default duration for Silence is now 20s (30s in pre-re)
* Items, NPC_SILENCEATTACK and NPC_WIDESILENCE and monster Lex Divina use the default silence duration
* Incubation time for Stone is now subtracted from the Stone duration
* Incubation time is now 100ms for all Stone skills except Stone Curse (5 seconds)
* The Stone timer is now more exact and now deal 1% HP damage exactly every 5 seconds, even if it's on the last tick
* Fixed Sienna Execrate missing its skill animation

Playtester 9 年之前
父節點
當前提交
b3b3e9cc71
共有 3 個文件被更改,包括 31 次插入24 次删除
  1. 2 2
      db/re/skill_cast_db.txt
  2. 16 9
      src/map/skill.c
  3. 13 13
      src/map/status.c

+ 2 - 2
db/re/skill_cast_db.txt

@@ -296,7 +296,7 @@
 //-- NPC_BLINDATTACK
 177,0,0,0,0,20000,0,0
 //-- NPC_SILENCEATTACK
-178,0,0,0,0,30000,0,0
+178,0,0,0,0,20000,0,0
 //-- NPC_STUNATTACK
 179,0,0,0,0,5000,0,0
 //-- NPC_PETRIFYATTACK
@@ -981,7 +981,7 @@
 //-- NPC_HELLJUDGEMENT
 662,0,0,0,0,30000,0,-1
 //-- NPC_WIDESILENCE
-663,0,0,0,0,30000,0,-1
+663,0,0,0,0,20000,0,-1
 //-- NPC_WIDEFREEZE
 664,0,0,0,0,30000,0,-1
 //-- NPC_WIDEBLEEDING

+ 16 - 9
src/map/skill.c

@@ -3906,6 +3906,12 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
 						skl->x+range,skl->y+range,BL_CHAR,src,skl->skill_id,skl->skill_lv,tick);
 					break;
 				case PR_LEXDIVINA:
+					if (src->type == BL_MOB) {
+						// Monsters use the default duration when casting Lex Divina
+						sc_start(src, target, status_skill2sc(skl->skill_id), skl->type, skl->skill_lv, skill_get_time2(status_sc2skill(status_skill2sc(skl->skill_id)), 1));
+						break;
+					}
+					// Fall through
 				case PR_STRECOVERY:
 				case BS_HAMMERFALL:
 					sc_start(src, target, status_skill2sc(skl->skill_id), skl->type, skl->skill_lv, skill_get_time2(skl->skill_id, skl->skill_lv));
@@ -7045,12 +7051,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			if (sd && &sd->sc && sd->sc.data[SC_PETROLOGY_OPTION])
 				brate = sd->sc.data[SC_PETROLOGY_OPTION]->val3;
 
-			if (tsc && tsc->data[SC_STONE]) {
-				status_change_end(bl, SC_STONE, INVALID_TIMER);
+			if (tsc && tsc->data[type]) {
+				status_change_end(bl, type, INVALID_TIMER);
 				if (sd) clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 				break;
 			}
-			if (sc_start4(src,bl,SC_STONE,(skill_lv*4+20)+brate,
+			if (sc_start4(src,bl,type,(skill_lv*4+20)+brate,
 				skill_lv, src->id, 0, skill_get_time(skill_id, skill_lv),
 				skill_get_time2(skill_id,skill_lv)))
 					clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -9208,22 +9214,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			if( bl->id == skill_area_temp[1] )
 				break; // Already work on this target
 
-			if( tsc && tsc->data[SC_STONE] )
-				status_change_end(bl,SC_STONE,INVALID_TIMER);
+			if( tsc && tsc->data[type] )
+				status_change_end(bl,type,INVALID_TIMER);
 			else
-				status_change_start(src,bl,SC_STONE,10000,skill_lv,src->id,0,1000,skill_get_time(skill_id, skill_lv),SCSTART_NOTICKDEF);
+				status_change_start(src,bl,type,10000,skill_lv,src->id,0,0,skill_get_time(skill_id, skill_lv),SCSTART_NOTICKDEF);
 		} else {
 			int rate = 45 + 5 * skill_lv + ( sd? sd->status.job_level : 50 ) / 4;
 			// IroWiki says Rate should be reduced by target stats, but currently unknown
 			if( rnd()%100 < rate ) { // Success on First Target
-				if( !tsc->data[SC_STONE] )
-					rate = status_change_start(src,bl,SC_STONE,10000,skill_lv,src->id,0,1000,skill_get_time(skill_id, skill_lv),SCSTART_NOTICKDEF);
+				if( !tsc->data[type] )
+					rate = status_change_start(src,bl,type,10000,skill_lv,src->id,0,0,skill_get_time(skill_id, skill_lv),SCSTART_NOTICKDEF);
 				else {
 					rate = 1;
-					status_change_end(bl,SC_STONE,INVALID_TIMER);
+					status_change_end(bl,type,INVALID_TIMER);
 				}
 
 				if( rate ) {
+					clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 					skill_area_temp[1] = bl->id;
 					map_foreachinrange(skill_area_sub,bl,skill_get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
 				}

+ 13 - 13
src/map/status.c

@@ -8935,10 +8935,10 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			break;
 
 		case SC_STONE:
-			val3 = tick/1000; // Petrified HP-damage iterations.
+			val4 = max(val4, 100); // Incubation time
+			val3 = (tick-val4)/100; // Petrified timer iterations
 			if(val3 < 1) val3 = 1;
-			tick = val4; // Petrifying time.
-			tick = max(tick, 1000); // Min time
+			tick = val4;
 			calc_flag = 0; // Actual status changes take effect on petrified state.
 			break;
 
@@ -11838,21 +11838,21 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
 			status_change_end(bl, SC_AETERNA, INVALID_TIMER);
 			sc->opt1 = OPT1_STONE;
 			clif_changeoption(bl);
-			sc_timer_next(1000+tick,status_change_timer, bl->id, data );
+			sc_timer_next(100+tick,status_change_timer, bl->id, data );
 			status_calc_bl(bl, StatusChangeFlagTable[type]);
 			return 0;
 		}
-		if(--(sce->val3) > 0) {
-			if(++(sce->val4)%5 == 0 && status->hp > status->max_hp/4) {
-				if (sce->val2 && bl->type == BL_MOB) {
-					struct block_list *src = map_id2bl(sce->val2);
+		if (++(sce->val4)%50 == 0 && status->hp > status->max_hp/4) {
+			if (sce->val2 && bl->type == BL_MOB) {
+				struct block_list *src = map_id2bl(sce->val2);
 
-					if (src)
-						mob_log_damage((TBL_MOB*)bl, src, apply_rate(status->hp, 1));
-				}
-				status_percent_damage(NULL, bl, 1, 0, false);
+				if (src)
+					mob_log_damage((TBL_MOB*)bl, src, apply_rate(status->hp, 1));
 			}
-			sc_timer_next(1000+tick,status_change_timer, bl->id, data );
+			status_percent_damage(NULL, bl, 1, 0, false);
+		}
+		if(--(sce->val3) > 0) {
+			sc_timer_next(100+tick,status_change_timer, bl->id, data );
 			return 0;
 		}
 		break;