From 1205395a5c8c13c55fd35e7f1f03b492dece12d5 Mon Sep 17 00:00:00 2001 From: k0l11 Date: Wed, 10 Aug 2022 13:07:45 +0200 Subject: [PATCH 1/2] yanfei frames update - adjust q burst buff name --- internal/characters/yanfei/asc.go | 6 +++--- internal/characters/yanfei/attack.go | 14 ++++++++++---- internal/characters/yanfei/burst.go | 17 +++++++++++------ internal/characters/yanfei/charge.go | 27 +++++++++++++++++++-------- internal/characters/yanfei/skill.go | 13 +++++++++---- internal/characters/yanfei/yanfei.go | 4 ++-- 6 files changed, 54 insertions(+), 27 deletions(-) diff --git a/internal/characters/yanfei/asc.go b/internal/characters/yanfei/asc.go index 4339513de..b6c8db898 100644 --- a/internal/characters/yanfei/asc.go +++ b/internal/characters/yanfei/asc.go @@ -13,12 +13,12 @@ import ( // repeatedly triggered it will overwrite the oldest bonus first. The Pyro DMG // bonus from Proviso is applied before charged attack damage is calculated. func (c *char) a1(stacks int) { - c.a1buff[attributes.PyroP] = float64(stacks) * 0.05 + c.a1Buff[attributes.PyroP] = float64(stacks) * 0.05 c.AddStatMod(character.StatMod{ Base: modifier.NewBaseWithHitlag("yanfei-a1", 360), AffectedStat: attributes.PyroP, Amount: func() ([]float64, bool) { - return c.a1buff, true + return c.a1Buff, true }, }) } @@ -52,7 +52,7 @@ func (c *char) a4() { HitlagFactor: 0.05, CanBeDefenseHalted: true, } - c.Core.QueueAttack(ai, combat.NewCircleHit(c.Core.Combat.Player(), 0.1, false, combat.TargettableEnemy), 1, 1) + c.Core.QueueAttack(ai, combat.NewCircleHit(c.Core.Combat.Player(), 0.1, false, combat.TargettableEnemy), 10, 10) return false }, "yanfei-a4") diff --git a/internal/characters/yanfei/attack.go b/internal/characters/yanfei/attack.go index 65b07879e..8c5467343 100644 --- a/internal/characters/yanfei/attack.go +++ b/internal/characters/yanfei/attack.go @@ -11,7 +11,7 @@ import ( ) var attackFrames [][]int -var attackHitmarks = []int{13, 28, 49} +var attackHitmarks = []int{12, 16, 37} const ( normalHitNum = 3 @@ -21,9 +21,15 @@ const ( func init() { attackFrames = make([][]int, normalHitNum) - attackFrames[0] = frames.InitNormalCancelSlice(attackHitmarks[0], 13) - attackFrames[1] = frames.InitNormalCancelSlice(attackHitmarks[1], 28) - attackFrames[2] = frames.InitNormalCancelSlice(attackHitmarks[2], 49) + attackFrames[0] = frames.InitNormalCancelSlice(attackHitmarks[0], 26) // N1 -> N2 + attackFrames[0][action.ActionCharge] = 21 // N1 -> CA + + attackFrames[1] = frames.InitNormalCancelSlice(attackHitmarks[1], 28) // N2 -> N3 + attackFrames[1][action.ActionCharge] = 16 // N2 -> CA + + attackFrames[2] = frames.InitNormalCancelSlice(attackHitmarks[2], 73) // N3 -> N1 + attackFrames[2][action.ActionCharge] = 42 // N3 -> CA + } // Standard attack function with seal handling diff --git a/internal/characters/yanfei/burst.go b/internal/characters/yanfei/burst.go index a64d5450e..f9968330f 100644 --- a/internal/characters/yanfei/burst.go +++ b/internal/characters/yanfei/burst.go @@ -13,12 +13,17 @@ import ( var burstFrames []int const ( - burstHitmark = 65 - burstBuffKey = "yanfei-burst" + burstHitmark = 24 + burstBuffKey = "yanfei-q" ) func init() { - burstFrames = frames.InitAbilSlice(65) + burstFrames = frames.InitAbilSlice(58) // Q -> N1 + burstFrames[action.ActionCharge] = 47 // Q -> CA + burstFrames[action.ActionSkill] = 55 // Q -> E + burstFrames[action.ActionDash] = 33 // Q -> D + burstFrames[action.ActionJump] = 32 // Q -> J + burstFrames[action.ActionSwap] = 46 // Q -> Swap } // Burst - Deals burst damage and adds status for charge attack bonus @@ -72,13 +77,13 @@ func (c *char) Burst(p map[string]int) action.ActionInfo { c.c4() - c.SetCDWithDelay(action.ActionBurst, 20*60, 8) - c.ConsumeEnergy(8) + c.SetCD(action.ActionBurst, 20*60) + c.ConsumeEnergy(5) return action.ActionInfo{ Frames: frames.NewAbilFunc(burstFrames), AnimationLength: burstFrames[action.InvalidAction], - CanQueueAfter: burstHitmark, + CanQueueAfter: burstFrames[action.ActionJump], // earliest cancel State: action.BurstState, } } diff --git a/internal/characters/yanfei/charge.go b/internal/characters/yanfei/charge.go index 7f68d5f38..6fe6a2c99 100644 --- a/internal/characters/yanfei/charge.go +++ b/internal/characters/yanfei/charge.go @@ -10,12 +10,16 @@ import ( var chargeFrames []int -const chargeHitmark = 66 +const chargeHitmark = 63 func init() { - chargeFrames = frames.InitAbilSlice(66) - chargeFrames[action.ActionDash] = chargeHitmark - chargeFrames[action.ActionJump] = chargeHitmark + chargeFrames = frames.InitAbilSlice(79) // CA -> N1 + chargeFrames[action.ActionCharge] = 78 // CA -> CA + chargeFrames[action.ActionSkill] = chargeHitmark // CA -> E + chargeFrames[action.ActionBurst] = chargeHitmark // CA -> Q + chargeFrames[action.ActionDash] = 51 // CA -> D + chargeFrames[action.ActionJump] = 49 // CA -> J + chargeFrames[action.ActionSwap] = 59 // CA -> Swap } // Charge attack function - handles seal use @@ -40,8 +44,15 @@ func (c *char) ChargeAttack(p map[string]int) action.ActionInfo { Durability: 25, Mult: charge[c.sealCount][c.TalentLvlAttack()], } + + // add windup if we're in idle or swap only + windup := 16 + if c.Core.Player.CurrentState() == action.Idle || c.Core.Player.CurrentState() == action.SwapState { + windup = 0 + } + // TODO: Not sure of snapshot timing - c.Core.QueueAttack(ai, combat.NewCircleHit(c.Core.Combat.Player(), 2, false, combat.TargettableEnemy), chargeHitmark, chargeHitmark) + c.Core.QueueAttack(ai, combat.NewCircleHit(c.Core.Combat.Player(), 2, false, combat.TargettableEnemy), chargeHitmark-windup, chargeHitmark-windup) c.Core.Log.NewEvent("yanfei charge attack consumed seals", glog.LogCharacterEvent, c.Index). Write("current_seals", c.sealCount) @@ -53,9 +64,9 @@ func (c *char) ChargeAttack(p map[string]int) action.ActionInfo { }, 1) return action.ActionInfo{ - Frames: frames.NewAbilFunc(chargeFrames), - AnimationLength: chargeFrames[action.InvalidAction], - CanQueueAfter: chargeHitmark, + Frames: func(next action.Action) int { return chargeFrames[next] - windup }, + AnimationLength: chargeFrames[action.InvalidAction] - windup, + CanQueueAfter: chargeFrames[action.ActionJump] - windup, // earliest cancel is before hitmark State: action.ChargeAttackState, } } diff --git a/internal/characters/yanfei/skill.go b/internal/characters/yanfei/skill.go index af31182c5..800bc9a4c 100644 --- a/internal/characters/yanfei/skill.go +++ b/internal/characters/yanfei/skill.go @@ -10,10 +10,15 @@ import ( var skillFrames []int -const skillHitmark = 46 +const skillHitmark = 32 func init() { - skillFrames = frames.InitAbilSlice(46) + skillFrames = frames.InitAbilSlice(46) // E -> N1 + skillFrames[action.ActionCharge] = 35 // E -> CA + skillFrames[action.ActionBurst] = 43 // E -> Q + skillFrames[action.ActionDash] = 29 // E -> D + skillFrames[action.ActionJump] = 34 // E -> J + skillFrames[action.ActionSwap] = 44 // E -> Swap } // Yanfei skill - Straightforward as it has little interactions with the rest of her kit @@ -50,12 +55,12 @@ func (c *char) Skill(p map[string]int) action.ActionInfo { c.Core.QueueParticle("yanfei", 3, attributes.Pyro, skillHitmark+c.Core.Flags.ParticleDelay) - c.SetCD(action.ActionSkill, 540) + c.SetCDWithDelay(action.ActionSkill, 540, 28) return action.ActionInfo{ Frames: frames.NewAbilFunc(skillFrames), AnimationLength: skillFrames[action.InvalidAction], - CanQueueAfter: skillHitmark, + CanQueueAfter: skillFrames[action.ActionDash], // earliest cancel is before skillHitmark State: action.SkillState, } } diff --git a/internal/characters/yanfei/yanfei.go b/internal/characters/yanfei/yanfei.go index fb1c7fb60..b409edca9 100644 --- a/internal/characters/yanfei/yanfei.go +++ b/internal/characters/yanfei/yanfei.go @@ -21,7 +21,7 @@ type char struct { sealStamReduction float64 sealCount int burstBuff []float64 - a1buff []float64 + a1Buff []float64 } func NewChar(s *core.Core, w *character.CharWrapper, _ character.CharacterProfile) error { @@ -52,7 +52,7 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ character.CharacterProfil } func (c *char) Init() error { - c.a1buff = make([]float64, attributes.EndStatType) + c.a1Buff = make([]float64, attributes.EndStatType) c.burstBuff = make([]float64, attributes.EndStatType) c.burstBuff[attributes.DmgP] = burstBonus[c.TalentLvlBurst()] c.a4() From b47b0fc6dcaeecb8def5c67a4dd598d20087f6e1 Mon Sep 17 00:00:00 2001 From: k0l11 Date: Wed, 10 Aug 2022 13:17:49 +0200 Subject: [PATCH 2/2] fix yanfei a4 hitlag in multitarget --- internal/characters/yanfei/asc.go | 5 ++++- internal/characters/yanfei/charge.go | 3 +++ internal/characters/yanfei/yanfei.go | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/characters/yanfei/asc.go b/internal/characters/yanfei/asc.go index b6c8db898..af0bdfe87 100644 --- a/internal/characters/yanfei/asc.go +++ b/internal/characters/yanfei/asc.go @@ -39,6 +39,9 @@ func (c *char) a4() { if atk.Info.AttackTag != combat.AttackTagExtra && !crit { return false } + // make it so a4 only applies hitlag once per A4 proc and not everytime an enemy gets hit + defhalt := !c.a4HitlagApplied + c.a4HitlagApplied = true ai := combat.AttackInfo{ ActorIndex: c.Index, @@ -50,7 +53,7 @@ func (c *char) a4() { Durability: 25, Mult: 0.8, HitlagFactor: 0.05, - CanBeDefenseHalted: true, + CanBeDefenseHalted: defhalt, } c.Core.QueueAttack(ai, combat.NewCircleHit(c.Core.Combat.Player(), 0.1, false, combat.TargettableEnemy), 10, 10) diff --git a/internal/characters/yanfei/charge.go b/internal/characters/yanfei/charge.go index 6fe6a2c99..a9e4ad815 100644 --- a/internal/characters/yanfei/charge.go +++ b/internal/characters/yanfei/charge.go @@ -63,6 +63,9 @@ func (c *char) ChargeAttack(p map[string]int) action.ActionInfo { c.DeleteStatus(sealBuffKey) }, 1) + // needed for a4 hitlag handling + c.a4HitlagApplied = false + return action.ActionInfo{ Frames: func(next action.Action) int { return chargeFrames[next] - windup }, AnimationLength: chargeFrames[action.InvalidAction] - windup, diff --git a/internal/characters/yanfei/yanfei.go b/internal/characters/yanfei/yanfei.go index b409edca9..ae02bcda1 100644 --- a/internal/characters/yanfei/yanfei.go +++ b/internal/characters/yanfei/yanfei.go @@ -22,6 +22,7 @@ type char struct { sealCount int burstBuff []float64 a1Buff []float64 + a4HitlagApplied bool } func NewChar(s *core.Core, w *character.CharWrapper, _ character.CharacterProfile) error {