Skip to content

Commit

Permalink
refactor some char events into callbacks (#1286)
Browse files Browse the repository at this point in the history
* refactor ayato c6 into a callback

* refactor beidou c4 into a callback

* refactor chongyun c4 into a callback

* refactor cyno c2 and c6 into a callback

* refactor dori c6 into a callback

* refactor eula stack gain into a callback
- convert stack gain icd into a status

* refactor keqing c2 into a callback

* refactor klee a4 into a callback

* refactor kokomi q heal, c2/c4/c6 into a callback

* refactor mona c6 ca reset into a callback

* refactor nahida c6 into a callback

* refactor rosaria c1, c4 and c6

* refactor shenhe c4 reset into a callback

* refactor xinyan c1 and c4

* refactor yanfei a4 into a callback

* refactor yoimiya a1 and c2

* adjust eula burst stack cb
  • Loading branch information
k0l11 authored Feb 15, 2023
1 parent 5444dc8 commit 6ef74fb
Show file tree
Hide file tree
Showing 69 changed files with 520 additions and 527 deletions.
1 change: 1 addition & 0 deletions internal/characters/ayato/attack.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func (c *char) SoukaiKanka(p map[string]int) action.ActionInfo {
shunsuikenHitmark,
c.particleCB,
c.skillStacks,
c.makeC6CB(),
)

defer c.AdvanceNormalIndex()
Expand Down
6 changes: 1 addition & 5 deletions internal/characters/ayato/ayato.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type char struct {
stacks int
stacksMax int
shunsuikenCounter int
c6ready bool
c6Ready bool
}

const (
Expand All @@ -37,7 +37,6 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ profile.CharacterProfile)
c.NormalHitNum = normalHitNum

c.shunsuikenCounter = 3
c.c6ready = false

c.stacksMax = 4
if c.Base.Cons >= 2 {
Expand All @@ -58,9 +57,6 @@ func (c *char) Init() error {
if c.Base.Cons >= 2 {
c.c2()
}
if c.Base.Cons >= 6 {
c.c6()
}
return nil
}

Expand Down
33 changes: 18 additions & 15 deletions internal/characters/ayato/cons.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package ayato
import (
"github.com/genshinsim/gcsim/pkg/core/attributes"
"github.com/genshinsim/gcsim/pkg/core/combat"
"github.com/genshinsim/gcsim/pkg/core/event"
"github.com/genshinsim/gcsim/pkg/core/glog"
"github.com/genshinsim/gcsim/pkg/core/player/character"
"github.com/genshinsim/gcsim/pkg/enemy"
Expand Down Expand Up @@ -45,18 +44,26 @@ func (c *char) c2() {
})
}

func (c *char) c6() {
c.Core.Events.Subscribe(event.OnEnemyDamage, func(args ...interface{}) bool {
if c.Core.Player.Active() != c.Index {
return false
// After using Kamisato Art: Kyouka, Ayato's next Shunsuiken attack will create
// 2 extra Shunsuiken strikes when they hit opponents, each one dealing 450% of Ayato's ATK as DMG.
// Both these Shunsuiken attacks will not be affected by Namisen.
func (c *char) makeC6CB() combat.AttackCBFunc {
if c.Base.Cons < 6 || !c.c6Ready {
return nil
}
return func(a combat.AttackCB) {
if a.Target.Type() != combat.TargettableEnemy {
return
}
if !c.c6ready {
return false
if c.Core.Player.Active() != c.Index {
return
}
atk := args[1].(*combat.AttackEvent)
if atk.Info.AttackTag != combat.AttackTagNormal {
return false
if !c.c6Ready {
return
}
c.c6Ready = false

c.Core.Log.NewEvent("ayato c6 proc'd", glog.LogCharacterEvent, c.Index)
ai := combat.AttackInfo{
Abil: "Ayato C6",
ActorIndex: c.Index,
Expand All @@ -80,9 +87,5 @@ func (c *char) c6() {
20+i*2,
)
}

c.Core.Log.NewEvent("ayato c6 proc'd", glog.LogCharacterEvent, c.Index)
c.c6ready = false
return false
}, "ayato-c6")
}
}
2 changes: 1 addition & 1 deletion internal/characters/ayato/skill.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (c *char) Skill(p map[string]int) action.ActionInfo {
c.AddStatus(SkillBuffKey, 6*60, true)
// figure out atk buff
if c.Base.Cons >= 6 {
c.c6ready = true
c.c6Ready = true
}
c.SetCD(action.ActionSkill, 12*60)

Expand Down
2 changes: 1 addition & 1 deletion internal/characters/beidou/attack.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (c *char) Attack(p map[string]int) action.ActionInfo {
attackHitboxes[c.NormalCounter][1],
)
}
c.Core.QueueAttack(ai, ap, attackHitmarks[c.NormalCounter], attackHitmarks[c.NormalCounter])
c.Core.QueueAttack(ai, ap, attackHitmarks[c.NormalCounter], attackHitmarks[c.NormalCounter], c.makeC4Callback())

defer c.AdvanceNormalIndex()

Expand Down
2 changes: 1 addition & 1 deletion internal/characters/beidou/beidou.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ profile.CharacterProfile)
func (c *char) Init() error {
c.burstProc()
if c.Base.Cons >= 4 {
c.c4()
c.c4Init()
}
return nil
}
37 changes: 20 additions & 17 deletions internal/characters/beidou/cons.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import (
"github.com/genshinsim/gcsim/pkg/core/player"
)

const c4key = "beidou-c4"
const c4Key = "beidou-c4"

func (c *char) c4() {
// Upon being attacked, Beidou's Normal Attacks gain an additional instance of 20% Electro DMG for 10s.
func (c *char) c4Init() {
c.Core.Events.Subscribe(event.OnPlayerHPDrain, func(args ...interface{}) bool {
di := args[0].(player.DrainInfo)
if !di.External {
Expand All @@ -22,23 +23,26 @@ func (c *char) c4() {
if c.Core.Player.Active() != c.Index {
return false
}
c.Core.Status.Add("beidouc4", 600)
c.Core.Status.Add(c4Key, 600)
c.Core.Log.NewEvent("c4 triggered on damage", glog.LogCharacterEvent, c.Index).
Write("expiry", c.Core.F+600)
return false
}, "beidouc4")
}, c4Key)
}

c.Core.Events.Subscribe(event.OnEnemyDamage, func(args ...interface{}) bool {
t := args[0].(combat.Target)
ae := args[1].(*combat.AttackEvent)
if ae.Info.ActorIndex != c.Index {
return false
}
if ae.Info.AttackTag != combat.AttackTagNormal && ae.Info.AttackTag != combat.AttackTagExtra {
return false
// TODO: this should also be added to her CA
// Beidou's Normal Attacks gain an additional instance of 20% Electro DMG for 10s.
func (c *char) makeC4Callback() combat.AttackCBFunc {
if c.Base.Cons < 4 {
return nil
}
return func(a combat.AttackCB) {
trg := a.Target
if trg.Type() != combat.TargettableEnemy {
return
}
if !c.StatusIsActive(c4key) {
return false
if !c.StatusIsActive(c4Key) {
return
}

c.Core.Log.NewEvent("c4 proc'd on attack", glog.LogCharacterEvent, c.Index).
Expand All @@ -54,7 +58,6 @@ func (c *char) c4() {
Durability: 25,
Mult: 0.2,
}
c.Core.QueueAttack(ai, combat.NewSingleTargetHit(t.Key()), 0, 1)
return false
}, "beidou-c4")
c.Core.QueueAttack(ai, combat.NewSingleTargetHit(trg.Key()), 0, 1)
}
}
4 changes: 3 additions & 1 deletion internal/characters/chongyun/attack.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ func (c *char) Attack(p map[string]int) action.ActionInfo {
attackHitboxes[c.NormalCounter][1],
)
}
c.Core.QueueAttack(ai, ap, attackHitmarks[c.NormalCounter], attackHitmarks[c.NormalCounter])
c4CB := c.makeC4Callback()
c.Core.QueueAttack(ai, ap, attackHitmarks[c.NormalCounter], attackHitmarks[c.NormalCounter], c4CB)

if c.Base.Cons >= 1 && c.NormalCounter == 3 {
ai := combat.AttackInfo{
Expand All @@ -84,6 +85,7 @@ func (c *char) Attack(p map[string]int) action.ActionInfo {
),
attackHitmarks[c.NormalCounter]+i*5,
attackHitmarks[c.NormalCounter]+i*5,
c4CB,
)
}
}
Expand Down
4 changes: 4 additions & 0 deletions internal/characters/chongyun/burst.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@ func (c *char) Burst(p map[string]int) action.ActionInfo {
Mult: burst[c.TalentLvlBurst()],
}

c4CB := c.makeC4Callback()

// Spirit Blade 1-3
for _, hitmark := range burstHitmarks {
c.Core.QueueAttack(
ai,
combat.NewCircleHitOnTarget(c.Core.Combat.PrimaryTarget(), nil, 3.5),
hitmark,
hitmark,
c4CB,
)
}

Expand All @@ -51,6 +54,7 @@ func (c *char) Burst(p map[string]int) action.ActionInfo {
combat.NewCircleHitOnTarget(c.Core.Combat.PrimaryTarget(), nil, 3.5),
burstHitmarkC6,
burstHitmarkC6,
c4CB,
)
}

Expand Down
3 changes: 0 additions & 3 deletions internal/characters/chongyun/chongyun.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ profile.CharacterProfile)

func (c *char) Init() error {
c.onSwapHook()
if c.Base.Cons >= 4 {
c.c4()
}
if c.Base.Cons >= 6 && c.Core.Combat.DamageMode {
c.c6()
}
Expand Down
40 changes: 18 additions & 22 deletions internal/characters/chongyun/cons.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,41 @@
package chongyun

import (
"github.com/genshinsim/gcsim/pkg/core"
"github.com/genshinsim/gcsim/pkg/core/attributes"
"github.com/genshinsim/gcsim/pkg/core/combat"
"github.com/genshinsim/gcsim/pkg/core/event"
"github.com/genshinsim/gcsim/pkg/core/glog"
"github.com/genshinsim/gcsim/pkg/core/player/character"
"github.com/genshinsim/gcsim/pkg/enemy"
"github.com/genshinsim/gcsim/pkg/modifier"
)

func (c *char) c4() {
const icdKey = "chongyun-c4-icd"
c.Core.Events.Subscribe(event.OnEnemyDamage, func(args ...interface{}) bool {
atk := args[1].(*combat.AttackEvent)
t, ok := args[0].(core.Reactable)
const c4ICDKey = "chongyun-c4-icd"

// Chongyun regenerates 1 Energy every time he hits an opponent affected by Cryo.
// This effect can only occur once every 2s.
func (c *char) makeC4Callback() combat.AttackCBFunc {
if c.Base.Cons < 4 {
return nil
}
return func(a combat.AttackCB) {
e, ok := a.Target.(*enemy.Enemy)
if !ok {
return false
}
if atk.Info.ActorIndex != c.Index {
return false
return
}
if c.Core.Player.Active() != c.Index {
return false
return
}
if c.StatusIsActive(icdKey) {
return false
if !e.AuraContains(attributes.Cryo) {
return
}
if !t.AuraContains(attributes.Cryo) {
return false
if c.StatusIsActive(c4ICDKey) {
return
}

c.AddStatus(c4ICDKey, 2*60, true)
c.AddEnergy("chongyun-c4", 2)

c.Core.Log.NewEvent("chongyun c4 recovering 2 energy", glog.LogCharacterEvent, c.Index).
Write("final energy", c.Energy)
c.AddStatus(icdKey, 120, true)

return false
}, "chongyun-c4")
}
}

func (c *char) c6() {
Expand Down
6 changes: 4 additions & 2 deletions internal/characters/chongyun/skill.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ func (c *char) Skill(p map[string]int) action.ActionInfo {
CanBeDefenseHalted: false,
}
c.skillArea = combat.NewCircleHitOnTarget(c.Core.Combat.Player(), combat.Point{Y: 1.5}, 8)
c4CB := c.makeC4Callback()
c.Core.QueueAttack(
ai,
combat.NewCircleHitOnTarget(c.skillArea.Shape.Pos(), nil, 2.5),
0,
skillHitmark,
c.particleCB,
c4CB,
)

ai = combat.AttackInfo{
Expand All @@ -69,7 +71,7 @@ func (c *char) Skill(p map[string]int) action.ActionInfo {
Durability: 25,
Mult: skill[c.TalentLvlSkill()],
}
cb := func(a combat.AttackCB) {
a4CB := func(a combat.AttackCB) {
e, ok := a.Target.(*enemy.Enemy)
if !ok {
return
Expand Down Expand Up @@ -106,7 +108,7 @@ func (c *char) Skill(p map[string]int) action.ActionInfo {
Info: ai,
Snapshot: snap,
}
c.a4Snap.Callbacks = append(c.a4Snap.Callbacks, cb)
c.a4Snap.Callbacks = append(c.a4Snap.Callbacks, a4CB, c4CB)

// A4 delayed damage + cryo resist shred
// TODO: assuming this is NOT affected by hitlag since it should be tied to deployable?
Expand Down
15 changes: 13 additions & 2 deletions internal/characters/cyno/attack.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ func (c *char) Attack(p map[string]int) action.ActionInfo {
if c.StatusIsActive(BurstKey) {
return c.attackB(p) // go to burst mode attacks
}
c2CB := c.makeC2CB()
c6CB := c.makeC6CB()
for i, mult := range attack[c.NormalCounter] {
ai := combat.AttackInfo{
ActorIndex: c.Index,
Expand Down Expand Up @@ -72,7 +74,14 @@ func (c *char) Attack(p map[string]int) action.ActionInfo {
attackHitboxes[c.NormalCounter][1],
)
}
c.Core.QueueAttack(ai, ap, attackHitmarks[c.NormalCounter][i], attackHitmarks[c.NormalCounter][i])
c.Core.QueueAttack(
ai,
ap,
attackHitmarks[c.NormalCounter][i],
attackHitmarks[c.NormalCounter][i],
c2CB,
c6CB,
)
}

defer c.AdvanceNormalIndex()
Expand Down Expand Up @@ -118,6 +127,8 @@ func init() {
func (c *char) attackB(p map[string]int) action.ActionInfo {
c.tryBurstPPSlide(attackBHitmarks[c.normalBCounter][len(attackBHitmarks[c.normalBCounter])-1])

c2CB := c.makeC2CB()
c6CB := c.makeC6CB()
for i, mult := range attackB[c.normalBCounter] {
ai := combat.AttackInfo{
ActorIndex: c.Index,
Expand Down Expand Up @@ -152,7 +163,7 @@ func (c *char) attackB(p map[string]int) action.ActionInfo {
)
}
c.QueueCharTask(func() {
c.Core.QueueAttack(ai, ap, 0, 0)
c.Core.QueueAttack(ai, ap, 0, 0, c2CB, c6CB)
}, attackBHitmarks[c.normalBCounter][i])
}

Expand Down
5 changes: 1 addition & 4 deletions internal/characters/cyno/burst.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ func (c *char) Burst(p map[string]int) action.ActionInfo {
if c.Base.Cons >= 1 {
c.c1()
}
if c.Base.Cons >= 6 { // constellation 6 giving 4 stacks on burst
c.c6Stacks = 4
c.AddStatus(c6Key, 480, true) // 8s*60
}
c.c6Init()

return action.ActionInfo{
Frames: frames.NewAbilFunc(burstFrames),
Expand Down
Loading

0 comments on commit 6ef74fb

Please sign in to comment.