|
| 1 | +package pyro |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + |
| 6 | + "github.com/genshinsim/gcsim/internal/frames" |
| 7 | + "github.com/genshinsim/gcsim/pkg/core/action" |
| 8 | + "github.com/genshinsim/gcsim/pkg/core/attacks" |
| 9 | + "github.com/genshinsim/gcsim/pkg/core/attributes" |
| 10 | + "github.com/genshinsim/gcsim/pkg/core/combat" |
| 11 | + "github.com/genshinsim/gcsim/pkg/core/geometry" |
| 12 | +) |
| 13 | + |
| 14 | +var ( |
| 15 | + attackFrames [][][]int |
| 16 | + attackHitmarks = [][]int{{13, 13, 16, 30, 25}, {16, 10, 19, 23, 14}} |
| 17 | + attackHitlagHaltFrame = [][]float64{{0.03, 0.03, 0.06, 0.09, 0.12}, {0.03, 0.03, 0.06, 0.06, 0.10}} |
| 18 | + attackHitboxes = [][][]float64{{{1.4, 2.2}, {1.7}, {1.5, 2.2}, {1.7}, {1.75}}, {{1.6}, {1.4, 2.2}, {1.5}, {1.5}, {1.6}}} |
| 19 | + attackOffsets = [][]float64{{0, 0.6, 0.4, 0.6, 0.6}, {1, 0, 0.7, 0.7, 1}} |
| 20 | + attackFanAngles = [][]float64{{360, 180, 360, 360, 240}, {360, 360, 360, 360, 360}} |
| 21 | +) |
| 22 | + |
| 23 | +const normalHitNum = 5 |
| 24 | + |
| 25 | +func init() { |
| 26 | + attackFrames = make([][][]int, 2) |
| 27 | + |
| 28 | + // Male |
| 29 | + attackFrames[0] = make([][]int, normalHitNum) |
| 30 | + |
| 31 | + attackFrames[0][0] = frames.InitNormalCancelSlice(attackHitmarks[0][0], 28) // N1 -> CA |
| 32 | + attackFrames[0][0][action.ActionAttack] = 17 // N1 -> N2 |
| 33 | + |
| 34 | + attackFrames[0][1] = frames.InitNormalCancelSlice(attackHitmarks[0][1], 28) // N2 -> CA |
| 35 | + attackFrames[0][1][action.ActionAttack] = 26 // N2 -> N3 |
| 36 | + |
| 37 | + attackFrames[0][2] = frames.InitNormalCancelSlice(attackHitmarks[0][2], 36) // N3 -> CA |
| 38 | + attackFrames[0][2][action.ActionAttack] = 32 // N3 -> N4 |
| 39 | + |
| 40 | + attackFrames[0][3] = frames.InitNormalCancelSlice(attackHitmarks[0][3], 45) // N4 -> CA |
| 41 | + attackFrames[0][3][action.ActionAttack] = 39 // N4 -> N5 |
| 42 | + |
| 43 | + attackFrames[0][4] = frames.InitNormalCancelSlice(attackHitmarks[0][4], 69) // N5 -> N1 |
| 44 | + attackFrames[0][4][action.ActionCharge] = 500 // N5 -> CA, TODO: this action is illegal; need better way to handle it |
| 45 | + |
| 46 | + // Female |
| 47 | + attackFrames[1] = make([][]int, normalHitNum) |
| 48 | + |
| 49 | + attackFrames[1][0] = frames.InitNormalCancelSlice(attackHitmarks[1][0], 32) // N1 -> CA |
| 50 | + attackFrames[1][0][action.ActionAttack] = 24 // N1 -> N2 |
| 51 | + |
| 52 | + attackFrames[1][1] = frames.InitNormalCancelSlice(attackHitmarks[1][1], 23) // N2 -> CA |
| 53 | + attackFrames[1][1][action.ActionAttack] = 21 // N2 -> N3 |
| 54 | + |
| 55 | + attackFrames[1][2] = frames.InitNormalCancelSlice(attackHitmarks[1][2], 39) // N3 -> CA |
| 56 | + attackFrames[1][2][action.ActionAttack] = 27 // N3 -> N4 |
| 57 | + |
| 58 | + attackFrames[1][3] = frames.InitNormalCancelSlice(attackHitmarks[1][3], 45) // N4 -> CA |
| 59 | + attackFrames[1][3][action.ActionAttack] = 38 // N4 -> N5 |
| 60 | + |
| 61 | + attackFrames[1][4] = frames.InitNormalCancelSlice(attackHitmarks[1][4], 64) // N5 -> N1 |
| 62 | + attackFrames[1][4][action.ActionCharge] = 500 // N5 -> CA, TODO: this action is illegal; need better way to handle it |
| 63 | +} |
| 64 | + |
| 65 | +func (c *Traveler) Attack(p map[string]int) (action.Info, error) { |
| 66 | + ai := combat.AttackInfo{ |
| 67 | + ActorIndex: c.Index, |
| 68 | + Abil: fmt.Sprintf("Normal %v", c.NormalCounter), |
| 69 | + AttackTag: attacks.AttackTagNormal, |
| 70 | + ICDTag: attacks.ICDTagNormalAttack, |
| 71 | + ICDGroup: attacks.ICDGroupDefault, |
| 72 | + StrikeType: attacks.StrikeTypeSlash, |
| 73 | + Element: attributes.Physical, |
| 74 | + Durability: 25, |
| 75 | + Mult: attack[c.NormalCounter][c.TalentLvlAttack()], |
| 76 | + HitlagFactor: 0.01, |
| 77 | + HitlagHaltFrames: attackHitlagHaltFrame[c.gender][c.NormalCounter] * 60, |
| 78 | + CanBeDefenseHalted: true, |
| 79 | + } |
| 80 | + if c.Base.Cons >= 6 && c.nightsoulState.HasBlessing() { |
| 81 | + ai.Element = attributes.Pyro |
| 82 | + ai.IgnoreInfusion = true |
| 83 | + ai.AdditionalTags = []attacks.AdditionalTag{attacks.AdditionalTagNightsoul} |
| 84 | + } |
| 85 | + ap := combat.NewCircleHitOnTargetFanAngle( |
| 86 | + c.Core.Combat.Player(), |
| 87 | + geometry.Point{Y: attackOffsets[c.gender][c.NormalCounter]}, |
| 88 | + attackHitboxes[c.gender][c.NormalCounter][0], |
| 89 | + attackFanAngles[c.gender][c.NormalCounter], |
| 90 | + ) |
| 91 | + if (c.gender == 0 && (c.NormalCounter == 0 || c.NormalCounter == 2)) || |
| 92 | + (c.gender == 1 && c.NormalCounter == 1) { |
| 93 | + ap = combat.NewBoxHitOnTarget( |
| 94 | + c.Core.Combat.Player(), |
| 95 | + geometry.Point{Y: attackOffsets[c.gender][c.NormalCounter]}, |
| 96 | + attackHitboxes[c.gender][c.NormalCounter][0], |
| 97 | + attackHitboxes[c.gender][c.NormalCounter][1], |
| 98 | + ) |
| 99 | + } |
| 100 | + c.Core.QueueAttack( |
| 101 | + ai, |
| 102 | + ap, |
| 103 | + attackHitmarks[c.gender][c.NormalCounter], |
| 104 | + attackHitmarks[c.gender][c.NormalCounter], |
| 105 | + ) |
| 106 | + |
| 107 | + defer c.AdvanceNormalIndex() |
| 108 | + |
| 109 | + return action.Info{ |
| 110 | + Frames: frames.NewAttackFunc(c.Character, attackFrames[c.gender]), |
| 111 | + AnimationLength: attackFrames[c.gender][c.NormalCounter][action.InvalidAction], |
| 112 | + CanQueueAfter: attackHitmarks[c.gender][c.NormalCounter], |
| 113 | + State: action.NormalAttackState, |
| 114 | + }, nil |
| 115 | +} |
0 commit comments