From 374c1f17108a255b5189051ed6dab4393631d105 Mon Sep 17 00:00:00 2001 From: kdovtdc Date: Sat, 24 Aug 2024 22:14:34 +0200 Subject: [PATCH 1/7] Implement Tingyun * init + skeleton + data * implement stats, attack, skill, traces, talent, E1, E2, E4 TO-DO: * ult, E6, technique * check if logic for talent is functional and whether can be improved or not --- internal/character/tingyun/attack.go | 34 +++++ internal/character/tingyun/data.go | 164 ++++++++++++++++++++++++ internal/character/tingyun/eidolon.go | 58 +++++++++ internal/character/tingyun/skill.go | 128 ++++++++++++++++++ internal/character/tingyun/stats.go | 104 +++++++++++++++ internal/character/tingyun/talent.go | 37 ++++++ internal/character/tingyun/technique.go | 10 ++ internal/character/tingyun/tingyun.go | 56 ++++++++ internal/character/tingyun/trace.go | 61 +++++++++ internal/character/tingyun/ult.go | 10 ++ pkg/key/character.go | 1 + pkg/simulation/imports.go | 1 + 12 files changed, 664 insertions(+) create mode 100644 internal/character/tingyun/attack.go create mode 100644 internal/character/tingyun/data.go create mode 100644 internal/character/tingyun/eidolon.go create mode 100644 internal/character/tingyun/skill.go create mode 100644 internal/character/tingyun/stats.go create mode 100644 internal/character/tingyun/talent.go create mode 100644 internal/character/tingyun/technique.go create mode 100644 internal/character/tingyun/tingyun.go create mode 100644 internal/character/tingyun/trace.go create mode 100644 internal/character/tingyun/ult.go diff --git a/internal/character/tingyun/attack.go b/internal/character/tingyun/attack.go new file mode 100644 index 00000000..28da087d --- /dev/null +++ b/internal/character/tingyun/attack.go @@ -0,0 +1,34 @@ +package tingyun + +import ( + "github.com/simimpact/srsim/pkg/engine/info" + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" +) + +const Normal key.Attack = "tingyun-normal" + +func (c *char) Attack(target key.TargetID, state info.ActionState) { + // A4 implemented the same way as game with add and remove + c.engine.AddModifier(c.id, info.Modifier{ + Name: A4, + Source: c.id, + }) + + c.engine.Attack(info.Attack{ + Key: Normal, + AttackType: model.AttackType_NORMAL, + DamageType: model.DamageType_FIRE, + BaseDamage: info.DamageMap{ + model.DamageFormula_BY_ATK: basic[c.info.AttackLevelIndex()], + }, + Targets: []key.TargetID{target}, + Source: c.id, + EnergyGain: 20, + StanceDamage: 30, + }) + + c.engine.RemoveModifier(c.id, A4) + + c.engine.EndAttack() +} diff --git a/internal/character/tingyun/data.go b/internal/character/tingyun/data.go new file mode 100644 index 00000000..9f83931a --- /dev/null +++ b/internal/character/tingyun/data.go @@ -0,0 +1,164 @@ +// Code generated by "charstat"; DO NOT EDIT. + +package tingyun + +import ( + "github.com/simimpact/srsim/pkg/engine/prop" + "github.com/simimpact/srsim/pkg/engine/target/character" +) + +var promotions = []character.PromotionData{ + { + MaxLevel: 20, + ATKBase: 72, + ATKAdd: 3.6, + DEFBase: 54, + DEFAdd: 2.7, + HPBase: 115.2, + HPAdd: 5.76, + SPD: 112, + CritChance: 0.05, + CritDMG: 0.5, + Aggro: 100, + }, + { + MaxLevel: 30, + ATKBase: 100.8, + ATKAdd: 3.6, + DEFBase: 75.6, + DEFAdd: 2.7, + HPBase: 161.28, + HPAdd: 5.76, + SPD: 112, + CritChance: 0.05, + CritDMG: 0.5, + Aggro: 100, + }, + { + MaxLevel: 40, + ATKBase: 129.6, + ATKAdd: 3.6, + DEFBase: 97.2, + DEFAdd: 2.7, + HPBase: 207.36, + HPAdd: 5.76, + SPD: 112, + CritChance: 0.05, + CritDMG: 0.5, + Aggro: 100, + }, + { + MaxLevel: 50, + ATKBase: 158.4, + ATKAdd: 3.6, + DEFBase: 118.8, + DEFAdd: 2.7, + HPBase: 253.44, + HPAdd: 5.76, + SPD: 112, + CritChance: 0.05, + CritDMG: 0.5, + Aggro: 100, + }, + { + MaxLevel: 60, + ATKBase: 187.2, + ATKAdd: 3.6, + DEFBase: 140.4, + DEFAdd: 2.7, + HPBase: 299.52, + HPAdd: 5.76, + SPD: 112, + CritChance: 0.05, + CritDMG: 0.5, + Aggro: 100, + }, + { + MaxLevel: 70, + ATKBase: 216, + ATKAdd: 3.6, + DEFBase: 162, + DEFAdd: 2.7, + HPBase: 345.6, + HPAdd: 5.76, + SPD: 112, + CritChance: 0.05, + CritDMG: 0.5, + Aggro: 100, + }, + { + MaxLevel: 80, + ATKBase: 244.8, + ATKAdd: 3.6, + DEFBase: 183.6, + DEFAdd: 2.7, + HPBase: 391.68, + HPAdd: 5.76, + SPD: 112, + CritChance: 0.05, + CritDMG: 0.5, + Aggro: 100, + }, +} + +var traces = character.TraceMap{ + "101": { + Ascension: 2, + }, + "102": { + Ascension: 4, + }, + "103": { + Ascension: 6, + }, + "201": { + Stat: prop.ATKPercent, + Amount: 0.04, + Level: 1, + }, + "202": { + Stat: prop.DEFPercent, + Amount: 0.05, + Ascension: 2, + }, + "203": { + Stat: prop.ATKPercent, + Amount: 0.04, + Ascension: 3, + }, + "204": { + Stat: prop.ThunderDamagePercent, + Amount: 0.032, + Ascension: 3, + }, + "205": { + Stat: prop.ATKPercent, + Amount: 0.06, + Ascension: 4, + }, + "206": { + Stat: prop.DEFPercent, + Amount: 0.075, + Ascension: 5, + }, + "207": { + Stat: prop.ATKPercent, + Amount: 0.06, + Ascension: 5, + }, + "208": { + Stat: prop.ThunderDamagePercent, + Amount: 0.048, + Ascension: 6, + }, + "209": { + Stat: prop.DEFPercent, + Amount: 0.1, + Level: 75, + }, + "210": { + Stat: prop.ATKPercent, + Amount: 0.08, + Level: 80, + }, +} \ No newline at end of file diff --git a/internal/character/tingyun/eidolon.go b/internal/character/tingyun/eidolon.go new file mode 100644 index 00000000..609c2215 --- /dev/null +++ b/internal/character/tingyun/eidolon.go @@ -0,0 +1,58 @@ +package tingyun + +import ( + "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 ( + E1 = "tingyun-e1" + E2 = "tingyun-e2" +) + +func init() { + modifier.Register(E1, modifier.Config{ + StatusType: model.StatusType_STATUS_BUFF, + Stacking: modifier.ReplaceBySource, + TickMoment: modifier.ModifierPhase1End, + }) +} + +func doE1OnUlt(mod *modifier.Instance, e event.ActionEnd) { + st := mod.State().(skillState) + // bypass + if st.tingEidolon < 1 { + return + } + if e.AttackType == model.AttackType_ULT { + mod.Engine().AddModifier(mod.Owner(), info.Modifier{ + Name: E1, + Source: mod.Source(), + Stats: info.PropMap{prop.SPDPercent: 0.2}, + }) + } +} + +func doE2(mod *modifier.Instance, target key.TargetID) { + st := mod.State().(*skillState) + // bypass + if st.tingEidolon < 2 || st.e2flag { + return + } + mod.Engine().ModifyEnergy(info.ModifyAttribute{ + Key: E2, + Target: mod.Owner(), + Source: mod.Source(), + }) + st.e2flag = true +} + +// not fully correct, this should trigger with OnAllowAction instead of OnPhase1 +func removeE2CD(mod *modifier.Instance) { + st := mod.State().(*skillState) + st.e2flag = false +} diff --git a/internal/character/tingyun/skill.go b/internal/character/tingyun/skill.go new file mode 100644 index 00000000..9ef7fc4a --- /dev/null +++ b/internal/character/tingyun/skill.go @@ -0,0 +1,128 @@ +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, + 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) +} diff --git a/internal/character/tingyun/stats.go b/internal/character/tingyun/stats.go new file mode 100644 index 00000000..c2b7e79e --- /dev/null +++ b/internal/character/tingyun/stats.go @@ -0,0 +1,104 @@ +package tingyun + +var ( + basic = []float64{ + 0.5, + 0.6, + 0.7, + 0.8, + 0.9, + 1.0, + 1.1, + 1.2, + 1.3, + } + skillPursued = []float64{ + 0.2, + 0.22, + 0.24, + 0.26, + 0.28, + 0.3, + 0.325, + 0.35, + 0.375, + 0.4, + 0.42, + 0.44, + 0.46, + 0.48, + 0.5, + } + + skillAllyAtk = []float64{ + 0.25, + 0.275, + 0.3, + 0.325, + 0.35, + 0.375, + 0.40625, + 0.4375, + 0.46875, + 0.5, + 0.525, + 0.55, + 0.575, + 0.6, + 0.625, + } + + skillTingAtk = []float64{ + 0.15, + 0.16, + 0.17, + 0.18, + 0.19, + 0.2, + 0.2125, + 0.225, + 0.2375, + 0.25, + 0.26, + 0.27, + 0.28, + 0.29, + 0.3, + } + + ult = []float64{ + 0.2, + 0.23, + 0.26, + 0.29, + 0.32, + 0.35, + 0.3875, + 0.425, + 0.4625, + 0.5, + 0.53, + 0.56, + 0.59, + 0.62, + 0.65, + } + + talent = []float64{ + 0.3, + 0.33, + 0.36, + 0.39, + 0.42, + 0.45, + 0.4875, + 0.525, + 0.5625, + 0.6, + 0.63, + 0.66, + 0.69, + 0.72, + 0.75, + } +) diff --git a/internal/character/tingyun/talent.go b/internal/character/tingyun/talent.go new file mode 100644 index 00000000..1dc77bfd --- /dev/null +++ b/internal/character/tingyun/talent.go @@ -0,0 +1,37 @@ +package tingyun + +import ( + "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/model" +) + +const ( + IsTingyun = "tingyun-is-tingyun" + TingyunNormalMonitor = "tingyun-normal-monitor" + ProcTalent = "tingyun-benediction-proc-talent" +) + +func init() { + modifier.Register(TingyunNormalMonitor, modifier.Config{ + Listeners: modifier.Listeners{ + OnAfterAttack: doProcTalent, // Talent's Pursued + }, + }) + modifier.Register(IsTingyun, modifier.Config{}) +} + +func doProcTalent(mod *modifier.Instance, e event.AttackEnd) { + if e.AttackType == model.AttackType_NORMAL && mod.Engine().HasModifier(mod.Owner(), IsTingyun) { + st := mod.State().(*skillState) + mod.Engine().Attack(info.Attack{ + Key: ProcTalent, + Targets: e.Targets, + Source: mod.Owner(), + AttackType: model.AttackType_PURSUED, + DamageType: model.DamageType_THUNDER, + BaseDamage: info.DamageMap{model.DamageFormula_BY_ATK: st.talentPursuedMltp}, + }) + } +} diff --git a/internal/character/tingyun/technique.go b/internal/character/tingyun/technique.go new file mode 100644 index 00000000..5e317db9 --- /dev/null +++ b/internal/character/tingyun/technique.go @@ -0,0 +1,10 @@ +package tingyun + +import ( + "github.com/simimpact/srsim/pkg/engine/info" + "github.com/simimpact/srsim/pkg/key" +) + +func (c *char) Technique(target key.TargetID, state info.ActionState) { + +} diff --git a/internal/character/tingyun/tingyun.go b/internal/character/tingyun/tingyun.go new file mode 100644 index 00000000..1e0207f7 --- /dev/null +++ b/internal/character/tingyun/tingyun.go @@ -0,0 +1,56 @@ +package tingyun + +import ( + "github.com/simimpact/srsim/pkg/engine" + "github.com/simimpact/srsim/pkg/engine/info" + "github.com/simimpact/srsim/pkg/engine/target/character" + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" +) + +func init() { + character.Register(key.Tingyun, character.Config{ + Create: NewInstance, + Rarity: 4, + Element: model.DamageType_THUNDER, + Path: model.Path_HARMONY, + MaxEnergy: 130, + Promotions: promotions, + Traces: traces, + SkillInfo: character.SkillInfo{ + Attack: character.Attack{ + SPAdd: 1, + TargetType: model.TargetType_ENEMIES, + }, + Skill: character.Skill{ + SPNeed: 1, + TargetType: model.TargetType_ALLIES, + }, + Ult: character.Ult{ + TargetType: model.TargetType_ALLIES, + }, + Technique: character.Technique{ + TargetType: model.TargetType_SELF, + IsAttack: false, + }, + }, + }) +} + +type char struct { + engine engine.Engine + id key.TargetID + info info.Character +} + +func NewInstance(engine engine.Engine, id key.TargetID, charInfo info.Character) info.CharInstance { + c := &char{ + engine: engine, + id: id, + info: charInfo, + } + + c.initTraces() + + return c +} diff --git a/internal/character/tingyun/trace.go b/internal/character/tingyun/trace.go new file mode 100644 index 00000000..d5298c13 --- /dev/null +++ b/internal/character/tingyun/trace.go @@ -0,0 +1,61 @@ +package tingyun + +import ( + "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/model" +) + +const ( + A2 = "tingyun-a2" + A4 = "tingyun-a4" + A6 = "tingyun-a6" +) + +func init() { + modifier.Register(A2, modifier.Config{ + StatusType: model.StatusType_STATUS_BUFF, + Stacking: modifier.ReplaceBySource, + Duration: 1, + TickMoment: modifier.ModifierPhase1End, + }) + + modifier.Register(A4, modifier.Config{ + Listeners: modifier.Listeners{ + OnBeforeHit: addA4, + }, + }) + + modifier.Register(A6, modifier.Config{ + Listeners: modifier.Listeners{ + OnPhase1: addA6, + }, + }) +} + +func (c *char) initTraces() { + if c.info.Traces["103"] { + c.engine.AddModifier(c.id, info.Modifier{ + Name: A6, + Source: c.id, + }) + } +} + +func addA4(mod *modifier.Instance, e event.HitStart) { + ting, _ := mod.Engine().CharacterInfo(mod.Owner()) + if ting.Traces["102"] { + e.Hit.Attacker.AddProperty(A4, prop.AllDamagePercent, 0.4) + } +} + +func addA6(mod *modifier.Instance) { + mod.Engine().ModifyEnergy(info.ModifyAttribute{ + Key: A6, + Target: mod.Owner(), + Source: mod.Owner(), + Amount: 5.0, + }) +} diff --git a/internal/character/tingyun/ult.go b/internal/character/tingyun/ult.go new file mode 100644 index 00000000..258895f6 --- /dev/null +++ b/internal/character/tingyun/ult.go @@ -0,0 +1,10 @@ +package tingyun + +import ( + "github.com/simimpact/srsim/pkg/engine/info" + "github.com/simimpact/srsim/pkg/key" +) + +func (c *char) Ult(target key.TargetID, state info.ActionState) { + +} diff --git a/pkg/key/character.go b/pkg/key/character.go index 9adb5360..1ec1a61b 100644 --- a/pkg/key/character.go +++ b/pkg/key/character.go @@ -16,6 +16,7 @@ const ( Pela Character = "pela" Qingque Character = "qingque" SilverWolf Character = "silverwolf" + Tingyun Character = "tingyun" DummyCharacter Character = "dummy_character" Sampo Character = "sampo" Serval Character = "serval" diff --git a/pkg/simulation/imports.go b/pkg/simulation/imports.go index 3408e437..77e8cd2b 100644 --- a/pkg/simulation/imports.go +++ b/pkg/simulation/imports.go @@ -21,6 +21,7 @@ import ( _ "github.com/simimpact/srsim/internal/character/serval" _ "github.com/simimpact/srsim/internal/character/silverwolf" _ "github.com/simimpact/srsim/internal/character/sushang" + _ "github.com/simimpact/srsim/internal/character/tingyun" _ "github.com/simimpact/srsim/internal/enemy/dummy" _ "github.com/simimpact/srsim/internal/global" _ "github.com/simimpact/srsim/internal/lightcone/abundance/cornucopia" From d2b055cfc0d4ae0e74162f5c377bb970c624d28b Mon Sep 17 00:00:00 2001 From: kdovtdc Date: Sun, 25 Aug 2024 18:11:02 +0200 Subject: [PATCH 2/7] Implement Tingyun Ult, E6, Technique --- internal/character/tingyun/technique.go | 10 +++++- internal/character/tingyun/ult.go | 41 ++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/internal/character/tingyun/technique.go b/internal/character/tingyun/technique.go index 5e317db9..ecb8bbf4 100644 --- a/internal/character/tingyun/technique.go +++ b/internal/character/tingyun/technique.go @@ -5,6 +5,14 @@ import ( "github.com/simimpact/srsim/pkg/key" ) +const Technique key.Reason = "tingyun-technique" + func (c *char) Technique(target key.TargetID, state info.ActionState) { - + // Technique can be used multiple times in succession to gain the Energy the same amount of times + c.engine.ModifyEnergy(info.ModifyAttribute{ + Key: Technique, + Target: c.id, + Source: c.id, + Amount: 50.0, + }) } diff --git a/internal/character/tingyun/ult.go b/internal/character/tingyun/ult.go index 258895f6..eb250f14 100644 --- a/internal/character/tingyun/ult.go +++ b/internal/character/tingyun/ult.go @@ -2,9 +2,48 @@ package tingyun import ( "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 ( + Ult = "tingyun-ult" + UltBuff = "tingyun-ult-buff" +) + +func init() { + modifier.Register(UltBuff, modifier.Config{ + StatusType: model.StatusType_STATUS_BUFF, + Stacking: modifier.ReplaceBySource, + Duration: 2, + }) +} + func (c *char) Ult(target key.TargetID, state info.ActionState) { - + energyAmount := 50.0 + if c.info.Eidolon >= 6 { + energyAmount += 10.0 + } + c.engine.ModifyEnergyFixed(info.ModifyAttribute{ + Key: Technique, + Target: target, + Source: c.id, + Amount: energyAmount, + }) + + c.engine.AddModifier(target, info.Modifier{ + Name: UltBuff, + Source: c.id, + Stats: info.PropMap{prop.AllDamagePercent: ult[c.info.UltLevelIndex()]}, + TickImmediately: true, + }) + + c.engine.ModifyEnergy(info.ModifyAttribute{ + Key: Ult, + Target: c.id, + Source: c.id, + Amount: 5.0, + }) } From 1bb5e4a4fed576382d181219c0f6872a6c0e471c Mon Sep 17 00:00:00 2001 From: kdovtdc Date: Tue, 17 Sep 2024 00:53:12 +0200 Subject: [PATCH 3/7] fix missing amount in e2 --- internal/character/tingyun/eidolon.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/character/tingyun/eidolon.go b/internal/character/tingyun/eidolon.go index 609c2215..8f0c7f86 100644 --- a/internal/character/tingyun/eidolon.go +++ b/internal/character/tingyun/eidolon.go @@ -47,6 +47,7 @@ func doE2(mod *modifier.Instance, target key.TargetID) { Key: E2, Target: mod.Owner(), Source: mod.Source(), + Amount: 5.0, }) st.e2flag = true } From ffc0a163f5e28ca7c5a3f270949a8355e4504c0f Mon Sep 17 00:00:00 2001 From: kdovtdc Date: Tue, 17 Sep 2024 16:58:36 +0200 Subject: [PATCH 4/7] fix attack * swap order of `EndAttack` and `RemoveModifier` --- internal/character/tingyun/attack.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/character/tingyun/attack.go b/internal/character/tingyun/attack.go index 28da087d..77bcd0d2 100644 --- a/internal/character/tingyun/attack.go +++ b/internal/character/tingyun/attack.go @@ -28,7 +28,7 @@ func (c *char) Attack(target key.TargetID, state info.ActionState) { StanceDamage: 30, }) - c.engine.RemoveModifier(c.id, A4) - c.engine.EndAttack() + + c.engine.RemoveModifier(c.id, A4) } From 34b2cb5379e9161129034ce7347b5d735d88335c Mon Sep 17 00:00:00 2001 From: kdovtdc Date: Sun, 29 Sep 2024 15:58:03 +0200 Subject: [PATCH 5/7] Add missing modifier application during init --- internal/character/tingyun/talent.go | 7 +++++++ internal/character/tingyun/tingyun.go | 1 + 2 files changed, 8 insertions(+) diff --git a/internal/character/tingyun/talent.go b/internal/character/tingyun/talent.go index 1dc77bfd..ecf87d50 100644 --- a/internal/character/tingyun/talent.go +++ b/internal/character/tingyun/talent.go @@ -22,6 +22,13 @@ func init() { modifier.Register(IsTingyun, modifier.Config{}) } +func (c *char) initTalent() { + c.engine.AddModifier(c.id, info.Modifier{ + Name: IsTingyun, + Source: c.id, + }) +} + func doProcTalent(mod *modifier.Instance, e event.AttackEnd) { if e.AttackType == model.AttackType_NORMAL && mod.Engine().HasModifier(mod.Owner(), IsTingyun) { st := mod.State().(*skillState) diff --git a/internal/character/tingyun/tingyun.go b/internal/character/tingyun/tingyun.go index 1e0207f7..d921ee69 100644 --- a/internal/character/tingyun/tingyun.go +++ b/internal/character/tingyun/tingyun.go @@ -51,6 +51,7 @@ func NewInstance(engine engine.Engine, id key.TargetID, charInfo info.Character) } c.initTraces() + c.initTalent() return c } From 4ce08832be66e5b82c88bad3ba96013b7a1678d2 Mon Sep 17 00:00:00 2001 From: kdovtdc Date: Tue, 22 Oct 2024 23:49:16 +0200 Subject: [PATCH 6/7] Fix pointer logic --- internal/character/tingyun/eidolon.go | 2 +- internal/character/tingyun/skill.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/character/tingyun/eidolon.go b/internal/character/tingyun/eidolon.go index 8f0c7f86..401996f8 100644 --- a/internal/character/tingyun/eidolon.go +++ b/internal/character/tingyun/eidolon.go @@ -23,7 +23,7 @@ func init() { } func doE1OnUlt(mod *modifier.Instance, e event.ActionEnd) { - st := mod.State().(skillState) + st := mod.State().(*skillState) // bypass if st.tingEidolon < 1 { return diff --git a/internal/character/tingyun/skill.go b/internal/character/tingyun/skill.go index 9ef7fc4a..849f3d75 100644 --- a/internal/character/tingyun/skill.go +++ b/internal/character/tingyun/skill.go @@ -87,7 +87,7 @@ func (c *char) Skill(target key.TargetID, state info.ActionState) { c.engine.AddModifier(target, info.Modifier{ Name: Benediction, Source: c.id, - State: skillState{ + State: &skillState{ tingEidolon: c.info.Eidolon, e2flag: false, skillPursuedMltp: skillPursued[c.info.SkillLevelIndex()], From ab5bbc6c5b3335460d3aeab13e2d81e7b32eb7cf Mon Sep 17 00:00:00 2001 From: kdovtdc Date: Sun, 24 Nov 2024 18:24:07 +0100 Subject: [PATCH 7/7] Update with `CanDispel` field --- internal/character/tingyun/eidolon.go | 1 + internal/character/tingyun/skill.go | 1 + internal/character/tingyun/trace.go | 1 + internal/character/tingyun/ult.go | 1 + 4 files changed, 4 insertions(+) diff --git a/internal/character/tingyun/eidolon.go b/internal/character/tingyun/eidolon.go index 401996f8..43fe60a9 100644 --- a/internal/character/tingyun/eidolon.go +++ b/internal/character/tingyun/eidolon.go @@ -18,6 +18,7 @@ func init() { modifier.Register(E1, modifier.Config{ StatusType: model.StatusType_STATUS_BUFF, Stacking: modifier.ReplaceBySource, + CanDispel: true, TickMoment: modifier.ModifierPhase1End, }) } diff --git a/internal/character/tingyun/skill.go b/internal/character/tingyun/skill.go index 849f3d75..beade123 100644 --- a/internal/character/tingyun/skill.go +++ b/internal/character/tingyun/skill.go @@ -27,6 +27,7 @@ type skillState struct { func init() { modifier.Register(AtkBuff, modifier.Config{ StatusType: model.StatusType_STATUS_BUFF, + CanDispel: true, Listeners: modifier.Listeners{ OnRemove: removeBenedictionSelf, }, diff --git a/internal/character/tingyun/trace.go b/internal/character/tingyun/trace.go index d5298c13..dcf8c436 100644 --- a/internal/character/tingyun/trace.go +++ b/internal/character/tingyun/trace.go @@ -18,6 +18,7 @@ func init() { modifier.Register(A2, modifier.Config{ StatusType: model.StatusType_STATUS_BUFF, Stacking: modifier.ReplaceBySource, + CanDispel: true, Duration: 1, TickMoment: modifier.ModifierPhase1End, }) diff --git a/internal/character/tingyun/ult.go b/internal/character/tingyun/ult.go index eb250f14..51ef8978 100644 --- a/internal/character/tingyun/ult.go +++ b/internal/character/tingyun/ult.go @@ -17,6 +17,7 @@ func init() { modifier.Register(UltBuff, modifier.Config{ StatusType: model.StatusType_STATUS_BUFF, Stacking: modifier.ReplaceBySource, + CanDispel: true, Duration: 2, }) }