Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tartaglia frame adjustment #667

Merged
merged 44 commits into from
Aug 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e4cac72
adjust tartaglia burst frames and hitmarks
skippi Aug 8, 2022
c7f211b
adjust tartaglia burst energy consumption delay
skippi Aug 8, 2022
dca29dc
fix tartaglia burst cooldown start delays
skippi Aug 8, 2022
8666f8e
fix tartaglia burst energy refund delay
skippi Aug 8, 2022
3efefe5
fix tartaglia melee charge frames
skippi Aug 8, 2022
43ee5bb
fix tartaglia melee attack frames
skippi Aug 8, 2022
e8c0b21
fix tartaglia range attack frames
skippi Aug 8, 2022
cbc560a
fix tartaglia aim frames
skippi Aug 8, 2022
6055ec8
fix tartaglia skill idle frames
skippi Aug 8, 2022
26fba99
add tartaglia skill walk frames
skippi Aug 8, 2022
e80d53e
add tartaglia skill dash frames
skippi Aug 8, 2022
c5c425d
fix tartaglia skill using normal ICD
skippi Aug 8, 2022
9c2ec42
add hitlag to childe melee attack
skippi Aug 8, 2022
533b126
add tartaglia charge weakspot hitlag
skippi Aug 9, 2022
a0d5d46
fix tartaglia skill CD delay after entering melee
skippi Aug 9, 2022
b3c2ed1
fix tartaglia skill deactivation CD delay
skippi Aug 9, 2022
8102b1c
simplify tartaglia skill frames
skippi Aug 9, 2022
7cbb274
rename runningFrames to lastMultiHit
skippi Aug 9, 2022
48eaf4c
move attack info outside of loop
skippi Aug 9, 2022
c6ddcf0
simplify tartaglia exit CD delay addition
skippi Aug 9, 2022
dab6329
fix tartaglia attack frame formatting
skippi Aug 9, 2022
eeca88c
fix tartaglia ranged attack init
skippi Aug 9, 2022
815fd6e
fix missing defense halt on tartaglia melee attack
skippi Aug 9, 2022
6d3637f
move childe melee CA hitlag to aimshot
skippi Aug 9, 2022
7467146
add minimum walk requirement to tartaglia skill
skippi Aug 9, 2022
4e72df6
fix bad animation length on tartaglia walk
skippi Aug 9, 2022
55247df
add hitlag to tartaglia riptide ICD/duration
skippi Aug 9, 2022
df3329e
Merge branch 'next' of https://github.com/genshinsim/gcsim into tarta…
skippi Aug 9, 2022
a19b6ec
add hitlag to tartaglia c4 ICD
skippi Aug 9, 2022
7773b88
format tartaglia riptide code
skippi Aug 9, 2022
17616a3
add hitlag to tartaglia riptide energy ICD
skippi Aug 9, 2022
2ec99ea
remove unused code
skippi Aug 9, 2022
1d621ca
Merge branch 'main' of https://github.com/genshinsim/gcsim into tarta…
skippi Aug 12, 2022
028ca20
fix tartaglia ranged attack ICD tag
skippi Aug 12, 2022
e0ed78e
Merge branch 'main' of https://github.com/genshinsim/gcsim into tarta…
skippi Aug 14, 2022
48fc65f
add tartaglia N6 -> CA action prevention
skippi Aug 14, 2022
5158277
refactor tartaglia N6 hitmark code
skippi Aug 14, 2022
f9df96d
fix tartaglia N6 using last multi-hit info for all hits
skippi Aug 14, 2022
3612653
refactor tartaglia charge hitmarks
skippi Aug 14, 2022
fc88270
format tartaglia riptide code
skippi Aug 14, 2022
920633c
fix tartaglia incorrect CanQueueAfter
skippi Aug 14, 2022
4de8dd7
refactor tartaglia skill cd delay
skippi Aug 14, 2022
55b87dd
add hitlag extension to tartaglia skill duration
skippi Aug 14, 2022
53c4095
add hitlag extension to tartaglia skill force disable
skippi Aug 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 21 additions & 17 deletions internal/characters/tartaglia/aimed.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ import (

var aimedFrames []int

const aimedHitmark = 84
const aimedHitmark = 86

func init() {
aimedFrames = frames.InitAbilSlice(84)
aimedFrames = frames.InitAbilSlice(94)
aimedFrames[action.ActionDash] = aimedHitmark
aimedFrames[action.ActionJump] = aimedHitmark
}

//Once fully charged, deal Hydro DMG and apply the Riptide status.
// Once fully charged, deal Hydro DMG and apply the Riptide status.
func (c *char) Aimed(p map[string]int) action.ActionInfo {
if c.Core.Status.Duration("tartagliamelee") > 0 {
if c.StatusIsActive(meleeKey) {
c.Core.Log.NewEvent("aim called when not in ranged stance", glog.LogActionEvent, c.Index).
Write("action", action.ActionAim)
return action.ActionInfo{
Expand All @@ -38,26 +38,30 @@ func (c *char) Aimed(p map[string]int) action.ActionInfo {
weakspot, ok := p["weakspot"]

ai := combat.AttackInfo{
ActorIndex: c.Index,
Abil: "Aim (Charged)",
AttackTag: combat.AttackTagExtra,
ICDTag: combat.ICDTagNone,
ICDGroup: combat.ICDGroupDefault,
StrikeType: combat.StrikeTypePierce,
Element: attributes.Hydro,
Durability: 25,
Mult: aim[c.TalentLvlAttack()],
HitWeakPoint: weakspot == 1,
ActorIndex: c.Index,
Abil: "Aim (Charged)",
AttackTag: combat.AttackTagExtra,
ICDTag: combat.ICDTagNone,
ICDGroup: combat.ICDGroupDefault,
StrikeType: combat.StrikeTypePierce,
Element: attributes.Hydro,
Durability: 25,
Mult: aim[c.TalentLvlAttack()],
HitWeakPoint: weakspot == 1,
HitlagHaltFrames: 0.12 * 60, // deployable hitlag, but only on weakspot
HitlagFactor: 0.01,
HitlagOnHeadshotOnly: true,
IsDeployable: true,
}

c.Core.QueueAttack(
ai,
combat.NewDefSingleTarget(c.Core.Combat.DefaultTarget, combat.TargettableEnemy),
aimedHitmark,
aimedHitmark+travel,
//TODO: what's the ordering on these 2 callbacks?
c.rtFlashCallback, //call back for triggering slash
c.aimedApplyRiptide, //call back for applying riptide
// TODO: what's the ordering on these 2 callbacks?
c.rtFlashCallback, // call back for triggering slash
c.aimedApplyRiptide, // call back for applying riptide
)

return action.ActionInfo{
Expand Down
119 changes: 81 additions & 38 deletions internal/characters/tartaglia/attack.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,38 @@ import (

const normalHitNum = 6

var attackFrames [][]int
var attackHitmarks = []int{17, 13, 34, 37, 22, 39}
var (
attackFrames [][]int
attackHitmarks = []int{17, 8, 15, 19, 11, 14}
)

func init() {
// attack (ranged) -> x
attackFrames = make([][]int, normalHitNum)

attackFrames[0] = frames.InitNormalCancelSlice(attackHitmarks[0], 17)
attackFrames[1] = frames.InitNormalCancelSlice(attackHitmarks[1], 13)
attackFrames[2] = frames.InitNormalCancelSlice(attackHitmarks[2], 34)
attackFrames[3] = frames.InitNormalCancelSlice(attackHitmarks[3], 37)
attackFrames[4] = frames.InitNormalCancelSlice(attackHitmarks[4], 22)
attackFrames[5] = frames.InitNormalCancelSlice(attackHitmarks[5], 39)
// N1 -> x
attackFrames[0] = frames.InitNormalCancelSlice(attackHitmarks[0], 26)

// N2 -> x
attackFrames[1] = frames.InitNormalCancelSlice(attackHitmarks[1], 27)

// N3 -> x
attackFrames[2] = frames.InitNormalCancelSlice(attackHitmarks[2], 33)

// N4 -> x
attackFrames[3] = frames.InitNormalCancelSlice(attackHitmarks[3], 32)

// N5 -> x
attackFrames[4] = frames.InitNormalCancelSlice(attackHitmarks[4], 33)

// N6 -> x
attackFrames[5] = frames.InitNormalCancelSlice(attackHitmarks[5], 66)
}

// Normal attack
// Perform up to 6 consecutive shots with a bow.
func (c *char) Attack(p map[string]int) action.ActionInfo {
if c.Core.Status.Duration("tartagliamelee") > 0 {
if c.StatusIsActive(meleeKey) {
return c.meleeAttack(p)
}

Expand All @@ -42,7 +55,7 @@ func (c *char) Attack(p map[string]int) action.ActionInfo {
ActorIndex: c.Index,
Abil: fmt.Sprintf("Normal %v", c.NormalCounter),
AttackTag: combat.AttackTagNormal,
ICDTag: combat.ICDTagNormalAttack,
ICDTag: combat.ICDTagNone,
ICDGroup: combat.ICDGroupDefault,
StrikeType: combat.StrikeTypePierce,
Element: attributes.Physical,
Expand All @@ -66,45 +79,75 @@ func (c *char) Attack(p map[string]int) action.ActionInfo {
}
}

var meleeFrames [][]int
var meleeHitmarks = [][]int{{7}, {13}, {28}, {32}, {36}, {48, 49}}
var (
meleeFrames [][]int
meleeHitmarks = [][]int{{8}, {6}, {16}, {7}, {7}, {4, 20}}
meleeHitlagHaltFrames = [][]float64{{0.03}, {0.03}, {0.06}, {0.06}, {0.06}, {0.03, 0.12}}
)

func init() {
// attack (melee) -> x
meleeFrames = make([][]int, normalHitNum)

meleeFrames[0] = frames.InitNormalCancelSlice(meleeHitmarks[0][0], 7)
meleeFrames[1] = frames.InitNormalCancelSlice(meleeHitmarks[1][0], 13)
meleeFrames[2] = frames.InitNormalCancelSlice(meleeHitmarks[2][0], 28)
meleeFrames[3] = frames.InitNormalCancelSlice(meleeHitmarks[3][0], 32)
meleeFrames[4] = frames.InitNormalCancelSlice(meleeHitmarks[4][0], 36)
meleeFrames[5] = frames.InitNormalCancelSlice(meleeHitmarks[5][1], 49)
// N1 -> x
meleeFrames[0] = frames.InitNormalCancelSlice(meleeHitmarks[0][0], 23)
meleeFrames[0][action.ActionAttack] = 10
meleeFrames[0][action.ActionCharge] = 23

// N2 -> x
meleeFrames[1] = frames.InitNormalCancelSlice(meleeHitmarks[1][0], 23)
meleeFrames[1][action.ActionAttack] = 11
meleeFrames[1][action.ActionCharge] = 23

// N3 -> x
meleeFrames[2] = frames.InitNormalCancelSlice(meleeHitmarks[2][0], 37)
meleeFrames[2][action.ActionAttack] = 32
meleeFrames[2][action.ActionCharge] = 37

// N4 -> x
meleeFrames[3] = frames.InitNormalCancelSlice(meleeHitmarks[3][0], 37)
meleeFrames[3][action.ActionAttack] = 33
meleeFrames[3][action.ActionCharge] = 37

// N5 -> x
meleeFrames[4] = frames.InitNormalCancelSlice(meleeHitmarks[4][0], 23)
meleeFrames[4][action.ActionAttack] = 22
meleeFrames[4][action.ActionCharge] = 23

// N6 -> x
meleeFrames[5] = frames.InitNormalCancelSlice(meleeHitmarks[5][0]+meleeHitmarks[5][1], 65)
meleeFrames[5][action.ActionAttack] = 65
skippi marked this conversation as resolved.
Show resolved Hide resolved
meleeFrames[5][action.ActionCharge] = 500 // illegal action
}

// Melee stance attack.
// Perform up to 6 consecutive Hydro strikes.
func (c *char) meleeAttack(p map[string]int) action.ActionInfo {
ai := combat.AttackInfo{
ActorIndex: c.Index,
Abil: fmt.Sprintf("Normal %v", c.NormalCounter),
AttackTag: combat.AttackTagNormal,
ICDTag: combat.ICDTagNormalAttack,
ICDGroup: combat.ICDGroupDefault,
StrikeType: combat.StrikeTypeSlash,
Element: attributes.Hydro,
Durability: 25,
}
for i, mult := range eAttack[c.NormalCounter] {
ai.Mult = mult[c.TalentLvlSkill()]
c.Core.QueueAttack(
ai,
combat.NewCircleHit(c.Core.Combat.Player(), .5, false, combat.TargettableEnemy),
meleeHitmarks[c.NormalCounter][i],
meleeHitmarks[c.NormalCounter][i],
//TODO: what's the ordering on these 2 callbacks?
c.meleeApplyRiptide, //call back for applying riptide
c.rtSlashCallback, //call back for triggering slash
)
ai := combat.AttackInfo{
ActorIndex: c.Index,
Abil: fmt.Sprintf("Normal %v", c.NormalCounter),
AttackTag: combat.AttackTagNormal,
ICDTag: combat.ICDTagNormalAttack,
ICDGroup: combat.ICDGroupDefault,
StrikeType: combat.StrikeTypeSlash,
Element: attributes.Hydro,
Durability: 25,
HitlagFactor: 0.01,
CanBeDefenseHalted: true,
Mult: mult[c.TalentLvlSkill()],
HitlagHaltFrames: meleeHitlagHaltFrames[c.NormalCounter][i] * 60,
}
c.QueueCharTask(func() {
c.Core.QueueAttack(
ai,
combat.NewCircleHit(c.Core.Combat.Player(), .5, false, combat.TargettableEnemy),
0,
0,
c.meleeApplyRiptide, // riptide can trigger on the same hit that applies
c.rtSlashCallback,
)
}, meleeHitmarks[c.NormalCounter][i])
}

defer c.AdvanceNormalIndex()
Expand Down
45 changes: 29 additions & 16 deletions internal/characters/tartaglia/burst.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,36 @@ import (
"github.com/genshinsim/gcsim/pkg/core/combat"
)

var burstMeleeFrames []int
var burstRangedFrames []int
var (
burstMeleeFrames []int
burstRangedFrames []int
)

const burstMeleeHitmark = 92
const burstRangedHitmark = 47
const (
burstMeleeHitmark = 69
burstRangedHitmark = 70
)

func init() {
// burst (melee) -> x
burstMeleeFrames = frames.InitAbilSlice(97)
burstMeleeFrames = frames.InitAbilSlice(102)
burstMeleeFrames[action.ActionAttack] = 101
burstMeleeFrames[action.ActionSkill] = 102
burstMeleeFrames[action.ActionDash] = 102
burstMeleeFrames[action.ActionJump] = 102
burstMeleeFrames[action.ActionSwap] = 100

// burst (ranged) -> x
burstRangedFrames = frames.InitAbilSlice(52)
burstRangedFrames = frames.InitAbilSlice(55)
burstRangedFrames[action.ActionAttack] = 53
burstRangedFrames[action.ActionDash] = 54
burstRangedFrames[action.ActionJump] = 53
burstRangedFrames[action.ActionSwap] = 52
}

//Performs a different attack depending on the stance in which it is cast.
//Ranged Stance: dealing AoE Hydro DMG. Apply Riptide status to enemies hit. Returns 20 Energy after use
//Melee Stance: dealing AoE Hydro DMG. Triggers Riptide Blast (clear riptide after triggering riptide blast)
// Performs a different attack depending on the stance in which it is cast.
// Ranged Stance: dealing AoE Hydro DMG. Apply Riptide status to enemies hit. Returns 20 Energy after use
// Melee Stance: dealing AoE Hydro DMG. Triggers Riptide Blast (clear riptide after triggering riptide blast)
func (c *char) Burst(p map[string]int) action.ActionInfo {
ai := combat.AttackInfo{
ActorIndex: c.Index,
Expand All @@ -41,7 +54,7 @@ func (c *char) Burst(p map[string]int) action.ActionInfo {
hitmark := burstRangedHitmark
cb := c.rangedBurstApplyRiptide

if c.Core.Status.Duration("tartagliamelee") > 0 {
if c.StatusIsActive(meleeKey) {
ai.Abil = "Melee Stance: Light of Obliteration"
ai.Mult = meleeBurst[c.TalentLvlBurst()]
cancels = burstMeleeFrames
Expand All @@ -53,17 +66,17 @@ func (c *char) Burst(p map[string]int) action.ActionInfo {
} else {
c.Core.Tasks.Add(func() {
c.AddEnergy("tartaglia-ranged-burst-refund", 20)
}, hitmark+9)
}, 4)
}

c.Core.QueueAttack(ai, combat.NewCircleHit(c.Core.Combat.Player(), 5, false, combat.TargettableEnemy), hitmark, hitmark, cb)

if c.Core.Status.Duration("tartagliamelee") > 0 {
c.ConsumeEnergy(75)
c.SetCDWithDelay(action.ActionBurst, 900, 75)
if c.StatusIsActive(meleeKey) {
c.ConsumeEnergy(71)
c.SetCDWithDelay(action.ActionBurst, 900, 66)
} else {
c.ConsumeEnergy(8)
c.SetCDWithDelay(action.ActionBurst, 900, 8)
c.ConsumeEnergy(3)
c.SetCDWithDelay(action.ActionBurst, 900, 0)
}

return action.ActionInfo{
Expand Down
21 changes: 13 additions & 8 deletions internal/characters/tartaglia/charge.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,25 @@ import (
"github.com/genshinsim/gcsim/pkg/core/glog"
)

var chargeFrames []int
var chargeHitmarks = []int{71, 73}
var (
chargeFrames []int
chargeHitmarks = []int{14, 27}
)

func init() {
chargeFrames = frames.InitAbilSlice(73)
chargeFrames[action.ActionDash] = chargeHitmarks[len(chargeHitmarks)-1]
chargeFrames[action.ActionJump] = chargeHitmarks[len(chargeHitmarks)-1]
chargeFrames = frames.InitAbilSlice(55)
chargeFrames[action.ActionSkill] = 29
chargeFrames[action.ActionBurst] = 29
chargeFrames[action.ActionDash] = 14
chargeFrames[action.ActionJump] = 15
chargeFrames[action.ActionSwap] = 52
}

// since E is aoe, so this should be considered aoe too
// hitWeakPoint: tartaglia can proc Prototype Cresent's Passive on Geovishap's weakspots.
// Evidence: https://youtu.be/oOfeu5pW0oE
func (c *char) ChargeAttack(p map[string]int) action.ActionInfo {
if c.Core.Status.Duration("tartagliamelee") == 0 {
if !c.StatusIsActive(meleeKey) {
c.Core.Log.NewEvent("charge called when not in melee stance", glog.LogActionEvent, c.Index).
Write("action", action.ActionCharge)
return action.ActionInfo{
Expand Down Expand Up @@ -56,8 +61,8 @@ func (c *char) ChargeAttack(p map[string]int) action.ActionInfo {
combat.NewCircleHit(c.Core.Combat.Player(), 1, false, combat.TargettableEnemy),
chargeHitmarks[i],
chargeHitmarks[i],
c.meleeApplyRiptide, //call back for applying riptide
c.rtSlashCallback, //call back for triggering slash
c.meleeApplyRiptide, // call back for applying riptide
c.rtSlashCallback, // call back for triggering slash
)
}

Expand Down
23 changes: 23 additions & 0 deletions internal/characters/tartaglia/dash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package tartaglia

import (
"github.com/genshinsim/gcsim/internal/frames"
"github.com/genshinsim/gcsim/pkg/core/action"
)

var dashFrames []int

func init() {
dashFrames = frames.InitAbilSlice(19)
dashFrames[action.ActionSkill] = 3
}

func (c *char) Dash(p map[string]int) action.ActionInfo {
c.Character.Dash(p)
return action.ActionInfo{
Frames: func(next action.Action) int { return dashFrames[next] },
AnimationLength: dashFrames[action.InvalidAction],
CanQueueAfter: dashFrames[action.ActionSkill], // fastest cancel
State: action.DashState,
}
}
Loading