Skip to content

Commit

Permalink
Update Lisa Frames
Browse files Browse the repository at this point in the history
  • Loading branch information
kurt22i authored and srliao committed May 17, 2022
1 parent ffbda63 commit 2f018d6
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 25 deletions.
35 changes: 20 additions & 15 deletions internal/characters/lisa/abil.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/genshinsim/gcsim/pkg/core"
)

var hitmarks = []int{26, 18, 17, 31}

func (c *char) Attack(p map[string]int) (int, int) {

f, a := c.ActionFrames(core.ActionAttack, p)
Expand All @@ -20,7 +22,8 @@ func (c *char) Attack(p map[string]int) (int, int) {
Mult: attack[c.NormalCounter][c.TalentLvlAttack()],
}

c.Core.Combat.QueueAttack(ai, core.NewDefSingleTarget(1, core.TargettableEnemy), 0, f-1)
//todo: Does it really snapshot immediately?
c.Core.Combat.QueueAttack(ai, core.NewDefSingleTarget(1, core.TargettableEnemy), 0, hitmarks[c.NormalCounter])

c.AdvanceNormalIndex()

Expand Down Expand Up @@ -57,11 +60,13 @@ func (c *char) ChargeAttack(p map[string]int) (int, int) {
done = true
}

c.Core.Combat.QueueAttack(ai, core.NewDefCircHit(0.1, false, core.TargettableEnemy), 0, f-1, cb)
c.Core.Combat.QueueAttack(ai, core.NewDefCircHit(0.1, false, core.TargettableEnemy), 0, f, cb)

return f, a
}

var skillHitmarks = []int{22, 117}

//p = 0 for no hold, p = 1 for hold
func (c *char) Skill(p map[string]int) (int, int) {
hold := p["hold"]
Expand Down Expand Up @@ -97,13 +102,13 @@ func (c *char) skillPress(p map[string]int) (int, int) {
done = true
}

c.Core.Combat.QueueAttack(ai, core.NewDefSingleTarget(1, core.TargettableEnemy), 0, f-1, cb)
c.Core.Combat.QueueAttack(ai, core.NewDefSingleTarget(1, core.TargettableEnemy), 0, skillHitmarks[0], cb)

if c.Core.Rand.Float64() < 0.5 {
c.QueueParticle("Lisa", 1, core.Electro, f+100)
}

c.SetCD(core.ActionSkill, 60)
c.SetCDWithDelay(core.ActionSkill, 60, 17)
return f, a
}

Expand Down Expand Up @@ -146,16 +151,16 @@ func (c *char) skillHold(p map[string]int) (int, int) {

//[8:31 PM] ArchedNosi | Lisa Unleashed: yeah 4-5 50/50 with Hold
//[9:13 PM] ArchedNosi | Lisa Unleashed: @gimmeabreak actually wait, xd i noticed i misread my sheet, Lisa Hold E always gens 5 orbs
c.Core.Combat.QueueAttack(ai, core.NewDefCircHit(3, false, core.TargettableEnemy), 0, f, c1cb)
c.Core.Combat.QueueAttack(ai, core.NewDefCircHit(3, false, core.TargettableEnemy), 0, skillHitmarks[1], c1cb)

// count := 4
// if c.Core.Rand.Float64() < 0.5 {
// count = 5
// }
c.QueueParticle("Lisa", 5, core.Electro, f+100)

// c.CD[def.SkillCD] = c.Core.F + 960 //16seconds
c.SetCD(core.ActionSkill, 960)
// c.CD[def.SkillCD] = c.Core.F + 960 //16seconds, starts after 114 frames
c.SetCDWithDelay(core.ActionSkill, 960, 114)
return f, a
}

Expand All @@ -178,7 +183,7 @@ func (c *char) Burst(p map[string]int) (int, int) {
c.Core.Combat.QueueAttack(ai, core.NewDefSingleTarget(targ, core.TargettableEnemy), f, f, a4cb)

//duration is 15 seconds, tick every .5 sec
//30 zaps once every 30 frame, starting at f
//30 zaps once every 30 frame, starting at 119

ai = core.AttackInfo{
ActorIndex: c.Index,
Expand All @@ -191,7 +196,7 @@ func (c *char) Burst(p map[string]int) (int, int) {
Mult: burst[c.TalentLvlBurst()],
}

for i := 30; i <= 900; i += 30 {
for i := 119; i <= 119+900; i += 30 { //first tick at 119

var cb core.AttackCBFunc
if c.Base.Cons >= 4 {
Expand All @@ -209,12 +214,12 @@ func (c *char) Burst(p map[string]int) (int, int) {

}
}
c.Core.Combat.QueueAttack(ai, core.NewDefSingleTarget(1, core.TargettableEnemy), f-1, f+i, cb, a4cb)
c.Core.Combat.QueueAttack(ai, core.NewDefSingleTarget(1, core.TargettableEnemy), f-1, i, cb, a4cb)
}

//add a status for this just in case someone cares
c.AddTask(func() {
c.Core.Status.AddStatus("lisaburst", 900)
c.Core.Status.AddStatus("lisaburst", 119+900)
}, "lisa burst status", f)

//on lisa c4
Expand All @@ -225,11 +230,11 @@ func (c *char) Burst(p map[string]int) (int, int) {
//[8:11 PM] gimmeabreak: i guess single target it does nothing then?
//[8:12 PM] ArchedNosi | Lisa Unleashed: yeah single does nothing

//burst cd starts 52 frames after executed
//energy consumed the same time as the initial hit (64 frames)
c.ConsumeEnergy(64)
//burst cd starts 53 frames after executed
//energy usually consumed after 63 frames
c.ConsumeEnergy(63)
// c.CD[def.BurstCD] = c.Core.F + 1200
c.SetCDWithDelay(core.ActionBurst, 1200, 52)
c.SetCDWithDelay(core.ActionBurst, 1200, 53)
return f, a
}

Expand Down
101 changes: 92 additions & 9 deletions internal/characters/lisa/frames.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,115 @@ func (c *char) ActionFrames(a core.ActionType, p map[string]int) (int, int) {
switch a {
case core.ActionAttack:
f := 0
a := 0
switch c.NormalCounter {
//TODO: need to add atkspd mod
case 0:
f = 25
f = 15
a = 30
case 1:
f = 46 - 25
f = 12
a = 20
case 2:
f = 70 - 46
f = 17
a = 34
case 3:
f = 114 - 70
f = 31
a = 57
}
f = int(float64(f) / (1 + c.Stat(core.AtkSpd)))
return f, f
return f, a
case core.ActionCharge:
return 95, 95
return 70, 91
case core.ActionSkill:
hold := p["hold"]
if hold == 0 {
return 21, 21 //no hold
return 20, 38 //no hold
}
//yes hold
return 116, 116
return 114, 141
case core.ActionBurst:
return 64, 64
return 56, 86
case core.ActionDash:
return 22, 22
case core.ActionJump:
return 33, 33
default:
c.Core.Log.NewEventBuildMsg(core.LogActionEvent, c.Index, "unknown action (invalid frames): ", a.String())
return 0, 0
}
}

func (c *char) InitCancelFrames() {

//normal cancels
c.SetNormalCancelFrames(0, core.ActionAttack, 30-15) //n1 -> next attack
c.SetNormalCancelFrames(0, core.ActionCharge, 15-15) //n1 -> charge
c.SetNormalCancelFrames(0, core.ActionSkill, 26-15) //only CA can be done before hitmark
c.SetNormalCancelFrames(0, core.ActionBurst, 26-15)
c.SetNormalCancelFrames(0, core.ActionDash, 26-15)
c.SetNormalCancelFrames(0, core.ActionJump, 26-15)
c.SetNormalCancelFrames(0, core.ActionSwap, 26-15)

c.SetNormalCancelFrames(1, core.ActionAttack, 20-12) //n2 -> next attack
c.SetNormalCancelFrames(1, core.ActionCharge, 12-12) //n2 -> charge
c.SetNormalCancelFrames(1, core.ActionSkill, 18-12) //only CA can be done before hitmark
c.SetNormalCancelFrames(1, core.ActionBurst, 18-12)
c.SetNormalCancelFrames(1, core.ActionDash, 18-12)
c.SetNormalCancelFrames(1, core.ActionJump, 18-12)
c.SetNormalCancelFrames(1, core.ActionSwap, 18-12)

c.SetNormalCancelFrames(2, core.ActionAttack, 34-17) //n3 -> n4
c.SetNormalCancelFrames(2, core.ActionCharge, 26-17) //n3 -> charge
//CA is after hitmark this time, so no need for the rest

c.SetNormalCancelFrames(3, core.ActionAttack, 57-31) //n4 -> n1
//Missing N4->CA - it's extremely long though.

c.SetAbilCancelFrames(core.ActionCharge, core.ActionAttack, 86-70) //charge -> n1
c.SetAbilCancelFrames(core.ActionCharge, core.ActionCharge, 90-70) //charge -> charge
c.SetAbilCancelFrames(core.ActionCharge, core.ActionSkill, 94-70) //charge -> skill
c.SetAbilCancelFrames(core.ActionCharge, core.ActionBurst, 93-70) //charge -> burst
c.SetAbilCancelFrames(core.ActionCharge, core.ActionSwap, 90-70) //charge -> swap

c.SetAbilCancelFrames(core.ActionBurst, core.ActionAttack, 86-56) //burst -> n1
c.SetAbilCancelFrames(core.ActionBurst, core.ActionCharge, 86-56) //burst -> charge
c.SetAbilCancelFrames(core.ActionBurst, core.ActionSkill, 87-56) //burst -> skill
c.SetAbilCancelFrames(core.ActionBurst, core.ActionDash, 88-56) //burst -> dash
c.SetAbilCancelFrames(core.ActionBurst, core.ActionJump, 57-56) //burst -> jump
c.SetAbilCancelFrames(core.ActionBurst, core.ActionSwap, 56-56) //burst -> swap

c.SetAbilCancelFrames(core.ActionSkill, core.ActionAttack, 37-20)
c.SetAbilCancelFrames(core.ActionSkill, core.ActionCharge, 38-20)
c.SetAbilCancelFrames(core.ActionSkill, core.ActionBurst, 40-20)
c.SetAbilCancelFrames(core.ActionSkill, core.ActionDash, 35-20)
c.SetAbilCancelFrames(core.ActionSkill, core.ActionJump, 20-20)
c.SetAbilCancelFrames(core.ActionSkill, core.ActionSwap, 23-20)
}

func (c *char) ActionInterruptableDelay(next core.ActionType, p map[string]int) int {
// Provide a custom override for Lisa's Hold E
if c.Core.LastAction.Typ == core.ActionSkill &&
c.Core.LastAction.Param["hold"] == 1 {
return SkillHoldFrames(next)
}
//otherwise use default implementation
return c.Tmpl.ActionInterruptableDelay(next, p)
}

func SkillHoldFrames(next core.ActionType) int {
switch next {
case core.ActionAttack:
return 143 - 114
case core.ActionCharge:
return 125 - 114
case core.ActionBurst:
return 138 - 114
case core.ActionDash:
return 116 - 114
case core.ActionJump:
return 117 - 114
default:
return 114 - 114
}
}
1 change: 1 addition & 0 deletions internal/characters/lisa/lisa.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func NewChar(s *core.Core, p core.CharacterProfile) (core.Character, error) {

func (c *char) Init() {
c.Tmpl.Init()
c.InitCancelFrames()

c.skillHoldMult()

Expand Down
2 changes: 1 addition & 1 deletion internal/characters/lisa/lisa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestCD(t *testing.T) {
t.Error(err)
t.FailNow()
}
err = testhelper.TestSkillCDSingleCharge(c, x, 60)
err = testhelper.TestSkillCDSingleCharge(c, x, 60+17) //17 frames for CD to start
if err != nil {
t.Error(err)
}
Expand Down

0 comments on commit 2f018d6

Please sign in to comment.