-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathskill.go
More file actions
129 lines (113 loc) · 3.68 KB
/
skill.go
File metadata and controls
129 lines (113 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package tingyun
import (
"math"
"github.com/simimpact/srsim/pkg/engine/event"
"github.com/simimpact/srsim/pkg/engine/info"
"github.com/simimpact/srsim/pkg/engine/modifier"
"github.com/simimpact/srsim/pkg/engine/prop"
"github.com/simimpact/srsim/pkg/key"
"github.com/simimpact/srsim/pkg/model"
)
const (
AtkBuff = "tingyun-atk-buff"
Benediction = "tingyun-benediction"
ProcSkill = "tingyun-benediction-proc-skill"
)
type skillState struct {
tingEidolon int
e2flag bool
skillPursuedMltp float64
talentPursuedMltp float64
}
func init() {
modifier.Register(AtkBuff, modifier.Config{
StatusType: model.StatusType_STATUS_BUFF,
CanDispel: true,
Listeners: modifier.Listeners{
OnRemove: removeBenedictionSelf,
},
})
modifier.Register(Benediction, modifier.Config{
Listeners: modifier.Listeners{
OnAfterAction: doE1OnUlt, // E1
OnPhase1: removeE2CD, // E2 cooldown
OnTriggerDeath: doE2, // E2
OnRemove: removeAtkBuffSelf, // remove on destroy
OnAfterAttack: doProcSkill, // Skill's Pursued
},
})
}
func (c *char) Skill(target key.TargetID, state info.ActionState) {
// check A2
if c.info.Traces["101"] {
c.engine.AddModifier(c.id, info.Modifier{
Name: A2,
Source: c.id,
Stats: info.PropMap{prop.SPDPercent: 0.2},
})
}
// calculate Atk Buff
allyAtk := c.engine.Stats(target).GetProperty(prop.ATKBase)
allyAtk *= skillAllyAtk[c.info.SkillLevelIndex()]
tingAtk := c.engine.Stats(target).ATK()
tingAtk *= skillTingAtk[c.info.SkillLevelIndex()]
atkAmount := math.Min(allyAtk, tingAtk)
// remove Atk Buff from all allies
//// Assuming removing a modifier triggers OnDestroy:
//// This Atk Buff modifier has an OnDestroy listener that removes Benediction on the Owner when triggered,
//// which itself has an OnDestroy listener that removes the Atk Buff on the Owner.
for _, trg := range c.engine.Characters() {
c.engine.RemoveModifier(trg, AtkBuff)
}
// add new Atk Buff to target based on E1 (Spd Buff on ally Ult)
c.engine.AddModifier(target, info.Modifier{
Name: AtkBuff,
Source: c.id,
Stats: info.PropMap{prop.ATKFlat: atkAmount},
})
// remove Benediction from all allies
//// Because of the removal earlier, there should be no Benediction on any ally at this point,
//// so the OnDestroy cannot be triggered and the Atk Buff on the Owner won't be removed.
//// Essentially, this is a redundant step.
for _, trg := range c.engine.Characters() {
c.engine.RemoveModifier(trg, Benediction)
}
// add Benediction, with effects based on Tingyun's Eidolon
c.engine.AddModifier(target, info.Modifier{
Name: Benediction,
Source: c.id,
State: &skillState{
tingEidolon: c.info.Eidolon,
e2flag: false,
skillPursuedMltp: skillPursued[c.info.SkillLevelIndex()],
talentPursuedMltp: talent[c.info.TalentLevelIndex()],
},
})
c.engine.Events().AttackEnd.Subscribe(func(event event.AttackEnd) {
c.engine.AddModifier(target, info.Modifier{
Name: TingyunNormalMonitor,
Source: c.id,
})
})
}
func doProcSkill(mod *modifier.Instance, e event.AttackEnd) {
st := mod.State().(*skillState)
trg := mod.Engine().Retarget(info.Retarget{
Targets: e.Targets,
Max: 1,
})
mod.Engine().Attack(info.Attack{
Key: ProcSkill,
Targets: trg,
Source: mod.Owner(),
AttackType: model.AttackType_PURSUED,
DamageType: model.DamageType_THUNDER,
BaseDamage: info.DamageMap{model.DamageFormula_BY_ATK: st.skillPursuedMltp},
})
}
func removeBenedictionSelf(mod *modifier.Instance) {
mod.Engine().RemoveModifier(mod.Owner(), Benediction)
}
func removeAtkBuffSelf(mod *modifier.Instance) {
mod.Engine().RemoveModifier(mod.Owner(), AtkBuff)
}