Browse Source

Ankle Snare Status Rework (#8263)

- SC_ANKLE no longer has a natural resistance and minimum duration
- Glacier Fist, Clashing Spiral and Tarot Card of Fate now grant SC_ANKLE instead of SC_STOP (cannot teleport while under SC_ANKLE effect)
- Grand Cross now gives SC_ANKLE to self during the spell duration
- Ankle Snare now has a minimum duration of 3000+30*baselevel milliseconds
- Ankle Snare will no longer activate on bosses in renewal
- Fixed Ankle Snare stopping bosses in pre-renewal even if you didn't enable the config setting for it
- Glacier Fist now has a minimum duration of 1500+15*baselevel milliseconds rather than it being the maximum duration
- You can now define Glacier Fist's effective base duration in the YML file without worrying about it being halved in the source code (it is still getting reduced by Agi)
- Fixed some integer overflow issues
- Fixes #8253
Playtester 1 năm trước cách đây
mục cha
commit
3cbdcf999f
6 tập tin đã thay đổi với 43 bổ sung36 xóa
  1. 8 8
      db/pre-re/skill_db.yml
  2. 0 1
      db/pre-re/status.yml
  3. 8 8
      db/re/skill_db.yml
  4. 0 1
      db/re/status.yml
  5. 26 8
      src/map/skill.cpp
  6. 1 10
      src/map/status.cpp

+ 8 - 8
db/pre-re/skill_db.yml

@@ -10002,15 +10002,15 @@ Body:
     Element: Weapon
     Duration1:
       - Level: 1
-        Time: 4000
+        Time: 2000
       - Level: 2
-        Time: 8000
+        Time: 4000
       - Level: 3
-        Time: 12000
+        Time: 6000
       - Level: 4
-        Time: 16000
+        Time: 8000
       - Level: 5
-        Time: 24000
+        Time: 10000
     CastDelayFlags:
       IgnoreStatus: true
     Requires:
@@ -10026,7 +10026,7 @@ Body:
         - Level: 5
           Amount: 12
       SpiritSphereCost: 1
-    Status: Stop
+    Status: Ankle
   - Id: 372
     Name: CH_CHAINCRUSH
     Description: Chain Crush Combo
@@ -10847,7 +10847,7 @@ Body:
       Weapon:
         1hSpear: true
         2hSpear: true
-    Status: Stop
+    Status: Ankle
   - Id: 398
     Name: LK_HEADCRUSH
     Description: Traumatic Blow
@@ -32799,7 +32799,7 @@ Body:
           Amount: 27
         - Level: 5
           Amount: 30
-    Status: Stop
+    Status: Ankle
   - Id: 8219
     Name: ML_DEFENDER
     Description: Defending_Aura

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

@@ -769,7 +769,6 @@ Body:
       NoBanishingBuster: true
       NoClearance: true
       RemoveOnChangeMap: true
-    MinDuration: 5000
   - Status: Keeping
     DurationLookup: NPC_KEEPING
     CalcFlags:

+ 8 - 8
db/re/skill_db.yml

@@ -10250,15 +10250,15 @@ Body:
     Element: Weapon
     Duration1:
       - Level: 1
-        Time: 4000
+        Time: 2000
       - Level: 2
-        Time: 8000
+        Time: 4000
       - Level: 3
-        Time: 12000
+        Time: 6000
       - Level: 4
-        Time: 16000
+        Time: 8000
       - Level: 5
-        Time: 24000
+        Time: 10000
     CastDelayFlags:
       IgnoreStatus: true
     Requires:
@@ -10274,7 +10274,7 @@ Body:
         - Level: 5
           Amount: 12
       SpiritSphereCost: 1
-    Status: Stop
+    Status: Ankle
   - Id: 372
     Name: CH_CHAINCRUSH
     Description: Chain Crush Combo
@@ -11103,7 +11103,7 @@ Body:
         2hSword: true
         1hSpear: true
         2hSpear: true
-    Status: Stop
+    Status: Ankle
   - Id: 398
     Name: LK_HEADCRUSH
     Description: Traumatic Blow
@@ -46266,7 +46266,7 @@ Body:
           Amount: 27
         - Level: 5
           Amount: 30
-    Status: Stop
+    Status: Ankle
   - Id: 8219
     Name: ML_DEFENDER
     Description: Defending_Aura

+ 0 - 1
db/re/status.yml

@@ -786,7 +786,6 @@ Body:
       NoBanishingBuster: true
       NoClearance: true
       RemoveOnChangeMap: true
-    MinDuration: 5000
   - Status: Keeping
     DurationLookup: NPC_KEEPING
     CalcFlags:

+ 26 - 8
src/map/skill.cpp

@@ -1690,13 +1690,13 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl, uint
 		break;
 
 	case CH_TIGERFIST: {
-		uint16 basetime = skill_get_time(skill_id, skill_lv);
-		uint16 mintime = 30 * (status_get_lv(src) + 100);
+		t_tick basetime = skill_get_time(skill_id, skill_lv);
+		t_tick mintime = 15 * (status_get_lv(src) + 100);
 
-		if (status_get_class_(bl) == CLASS_BOSS)
+		if (status_bl_has_mode(bl, MD_STATUSIMMUNE))
 			basetime /= 5;
-		basetime = min((basetime * status_get_agi(bl)) / -200 + basetime, mintime) / 2;
-		sc_start(src, bl, SC_STOP, (1 + skill_lv) * 10, 0, basetime);
+		basetime = std::max((basetime * status_get_agi(bl)) / -200 + basetime, mintime);
+		sc_start(src, bl, SC_ANKLE, (1 + skill_lv) * 10, 0, basetime);
 	}
 		break;
 
@@ -1704,7 +1704,7 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl, uint
 	case ML_SPIRALPIERCE:
 	case HN_SPIRAL_PIERCE_MAX:
 		if( dstsd || ( dstmd && !status_bl_has_mode(bl,MD_STATUSIMMUNE) ) ) //Does not work on status immune
-			sc_start(src,bl,SC_STOP,100,0,skill_get_time2(skill_id,skill_lv));
+			sc_start(src,bl,SC_ANKLE,100,0,skill_get_time2(skill_id,skill_lv));
 		break;
 
 	case ST_REJECTSWORD:
@@ -5051,9 +5051,9 @@ static int skill_tarotcard(struct block_list* src, struct block_list *target, ui
 		skill_tarotcard(src, target, skill_id, skill_lv, tick);
 		break;
 	}
-	case 8: // THE HANGED MAN - stop, freeze or stoned
+	case 8: // THE HANGED MAN - ankle, freeze or stoned
 	{
-		enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONEWAIT };
+		enum sc_type sc[] = { SC_ANKLE, SC_FREEZE, SC_STONEWAIT };
 		uint8 rand_eff = rnd() % 3;
 		int time = ((rand_eff == 0) ? skill_get_time2(skill_id, skill_lv) : skill_get_time2(status_db.getSkill(sc[rand_eff]), 1));
 
@@ -13434,6 +13434,9 @@ TIMER_FUNC(skill_castend_id){
 						break;
 				}
 				sc_start2(src, src, type, 100, 0, 1, skill_get_time(ud->skill_id, ud->skill_lv));
+				// During Grand Cross you are in ankle state (cannot move or teleport)
+				if (ud->skill_id == CR_GRANDCROSS)
+					sc_start(src, src, SC_ANKLE, 100, 0, skill_get_time(ud->skill_id, ud->skill_lv));
 				break;
 			}
 			}
@@ -16198,6 +16201,15 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t_t
 		case UNT_MANHOLE:
 			if( sg->val2 == 0 && tsc && ((sg->unit_id == UNT_ANKLESNARE && skill_id != SC_ESCAPE) || bl->id != sg->src_id) ) {
 				t_tick sec = skill_get_time2(sg->skill_id,sg->skill_lv);
+				if (sg->unit_id == UNT_ANKLESNARE) {
+					t_tick mintime = 30 * (status_get_lv(ss) + 100);
+#ifndef RENEWAL
+					// Bosses cannot activate Ankle Snare in renewal so we don't need this code
+					if (status_bl_has_mode(bl, MD_STATUSIMMUNE))
+						sec /= 5;
+#endif
+					sec = std::max((sec * status_get_agi(bl)) / -200 + sec, mintime);
+				}
 
 				if( status_change_start(ss, bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, SCSTART_NORATEDEF) ) {
 					const struct TimerData* td = tsc->getSCE(type)?get_timer(tsc->getSCE(type)->timer):NULL;
@@ -21243,6 +21255,12 @@ int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap)
 	if( !(skill->inf2[INF2_ISSONG] || skill->inf2[INF2_ISTRAP]) && !skill->inf2[INF2_IGNORELANDPROTECTOR] && group->skill_id != NC_NEUTRALBARRIER && (battle_config.land_protector_behavior ? map_getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) : map_getcell(unit->bl.m, unit->bl.x, unit->bl.y, CELL_CHKLANDPROTECTOR)) )
 		return 0; //AoE skills are ineffective. [Skotlex]
 
+#ifdef RENEWAL
+	// Ankle Snare can no longer trap bosses in renewal
+	if (group->unit_id == UNT_ANKLESNARE && status_bl_has_mode(bl, MD_STATUSIMMUNE))
+		return 0;
+#endif
+
 	if( battle_check_target(&unit->bl,bl,group->target_flag) <= 0 )
 		return 0;
 

+ 1 - 10
src/map/status.cpp

@@ -9605,11 +9605,6 @@ t_tick status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_
 				tick /= 2; // Half duration for players.
 			sc_def2 = status->mdef*100;
 			break;
-		case SC_ANKLE:
-			if(status_has_mode(status,MD_STATUSIMMUNE)) // Lasts 5 times less on bosses
-				tick /= 5;
-			sc_def = status->agi*50;
-			break;
 		case SC_JOINTBEAT:
 			tick_def2 = 1000 * ((status->luk / 2 + status->agi / 5) / 2); // (50 * LUK / 100 + 20 * AGI / 100) / 2
 			break;
@@ -11585,7 +11580,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 
 		/* General */
 		case SC_FEAR:
-			status_change_start(src,bl,SC_ANKLE,10000,val1,0,0,0,2000,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF);
+			sc_start(src, bl, SC_ANKLE, 100, 0, 2000);
 			break;
 
 		/* Rune Knight */
@@ -12849,10 +12844,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 	//SC that make stop walking
 	if (scdb->flag[SCF_STOPWALKING]) {
 		switch (type) {
-			case SC_ANKLE:
-				if (battle_config.skill_trap_type || !map_flag_gvg(bl->m))
-					unit_stop_walking(bl, 1);
-				break;
 			case SC__MANHOLE:
 				if (bl->type == BL_PC || !unit_blown_immune(bl,0x1))
 					unit_stop_walking(bl,1);