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
This commit is contained in:
Playtester 2024-04-20 15:41:24 +02:00 committed by GitHub
parent cd7341930e
commit 3cbdcf999f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 43 additions and 36 deletions

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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;

View File

@ -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);