From 4dea0ce059567051d9c4cf441ad9c52afaad9f90 Mon Sep 17 00:00:00 2001 From: Matoba004 Date: Wed, 11 Feb 2026 03:42:46 +0100 Subject: [PATCH 1/2] initial commit --- internal/characters/albedo/albedo.go | 7 ++++++- internal/characters/fischl/fischl.go | 5 +++++ internal/characters/klee/klee.go | 7 ++++++- internal/characters/mona/mona.go | 7 ++++++- internal/characters/razor/razor.go | 7 ++++++- internal/characters/sucrose/sucrose.go | 7 ++++++- internal/characters/venti/venti.go | 7 ++++++- pkg/core/player/character/character.go | 1 + pkg/core/player/player.go | 11 +++++++++++ 9 files changed, 53 insertions(+), 6 deletions(-) diff --git a/internal/characters/albedo/albedo.go b/internal/characters/albedo/albedo.go index ec16097718..4a8ecdc468 100644 --- a/internal/characters/albedo/albedo.go +++ b/internal/characters/albedo/albedo.go @@ -25,7 +25,7 @@ type char struct { c2stacks int } -func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) error { +func NewChar(s *core.Core, w *character.CharWrapper, p info.CharacterProfile) error { c := char{} c.Character = tmpl.NewWithWrapper(s, w) @@ -34,6 +34,11 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) er c.SkillCon = 3 c.BurstCon = 5 + isHexerei, ok := p.Params["is_hexerei"] + if ok && isHexerei != 0 { + c.Hexerei = 1 + } + w.Character = &c return nil diff --git a/internal/characters/fischl/fischl.go b/internal/characters/fischl/fischl.go index 3dd87239dc..cbd340f72e 100644 --- a/internal/characters/fischl/fischl.go +++ b/internal/characters/fischl/fischl.go @@ -46,6 +46,11 @@ func NewChar(s *core.Core, w *character.CharWrapper, p info.CharacterProfile) er c.ozTravel = travel } + isHexerei, ok := p.Params["is_hexerei"] + if ok && isHexerei != 0 { + c.Hexerei = 1 + } + w.Character = &c return nil diff --git a/internal/characters/klee/klee.go b/internal/characters/klee/klee.go index 97847b60a8..1b5cc31999 100644 --- a/internal/characters/klee/klee.go +++ b/internal/characters/klee/klee.go @@ -18,7 +18,7 @@ type char struct { c1Chance float64 } -func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) error { +func NewChar(s *core.Core, w *character.CharWrapper, p info.CharacterProfile) error { c := char{} c.Character = tmpl.NewWithWrapper(s, w) @@ -29,6 +29,11 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) er c.SetNumCharges(action.ActionSkill, 2) + isHexerei, ok := p.Params["is_hexerei"] + if ok && isHexerei != 0 { + c.Hexerei = 1 + } + w.Character = &c return nil diff --git a/internal/characters/mona/mona.go b/internal/characters/mona/mona.go index 70e6075bed..7a1a418c04 100644 --- a/internal/characters/mona/mona.go +++ b/internal/characters/mona/mona.go @@ -24,7 +24,7 @@ type char struct { c6Stacks int } -func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) error { +func NewChar(s *core.Core, w *character.CharWrapper, p info.CharacterProfile) error { c := char{} c.Character = tmpl.NewWithWrapper(s, w) @@ -33,6 +33,11 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) er c.BurstCon = 3 c.SkillCon = 5 + isHexerei, ok := p.Params["is_hexerei"] + if ok && isHexerei != 0 { + c.Hexerei = 1 + } + w.Character = &c return nil diff --git a/internal/characters/razor/razor.go b/internal/characters/razor/razor.go index 118de892ae..70783c2b98 100644 --- a/internal/characters/razor/razor.go +++ b/internal/characters/razor/razor.go @@ -21,7 +21,7 @@ type char struct { c2bonus []float64 } -func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) error { +func NewChar(s *core.Core, w *character.CharWrapper, p info.CharacterProfile) error { c := char{} c.Character = tmpl.NewWithWrapper(s, w) @@ -30,6 +30,11 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) er c.SkillCon = 5 c.NormalHitNum = normalHitNum + isHexerei, ok := p.Params["is_hexerei"] + if ok && isHexerei != 0 { + c.Hexerei = 1 + } + w.Character = &c return nil diff --git a/internal/characters/sucrose/sucrose.go b/internal/characters/sucrose/sucrose.go index fec788a0d7..6407153ad4 100644 --- a/internal/characters/sucrose/sucrose.go +++ b/internal/characters/sucrose/sucrose.go @@ -24,7 +24,7 @@ type char struct { c6buff []float64 } -func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) error { +func NewChar(s *core.Core, w *character.CharWrapper, p info.CharacterProfile) error { c := char{} c.Character = tmpl.NewWithWrapper(s, w) @@ -37,6 +37,11 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) er c.SetNumCharges(action.ActionSkill, 2) } + isHexerei, ok := p.Params["is_hexerei"] + if ok && isHexerei != 0 { + c.Hexerei = 1 + } + w.Character = &c return nil diff --git a/internal/characters/venti/venti.go b/internal/characters/venti/venti.go index 6e7b7ffbc7..8bc86b10bf 100644 --- a/internal/characters/venti/venti.go +++ b/internal/characters/venti/venti.go @@ -23,7 +23,7 @@ type char struct { c4bonus []float64 } -func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) error { +func NewChar(s *core.Core, w *character.CharWrapper, p info.CharacterProfile) error { c := char{} c.Character = tmpl.NewWithWrapper(s, w) @@ -32,6 +32,11 @@ func NewChar(s *core.Core, w *character.CharWrapper, _ info.CharacterProfile) er c.BurstCon = 3 c.SkillCon = 5 + isHexerei, ok := p.Params["is_hexerei"] + if ok && isHexerei != 0 { + c.Hexerei = 1 + } + w.Character = &c return nil diff --git a/pkg/core/player/character/character.go b/pkg/core/player/character/character.go index b227a92c06..1763c04a0d 100644 --- a/pkg/core/player/character/character.go +++ b/pkg/core/player/character/character.go @@ -100,6 +100,7 @@ type CharWrapper struct { BurstCon int HasArkhe bool Moonsign int + Hexerei int Equip struct { Weapon info.Weapon diff --git a/pkg/core/player/player.go b/pkg/core/player/player.go index bc5b9e3b46..38e41626fb 100644 --- a/pkg/core/player/player.go +++ b/pkg/core/player/player.go @@ -406,3 +406,14 @@ func (h *Handler) GetMoonsignLevel() int { } return count } + +func (h *Handler) GetHexereiCount() int { + count := 0 + for _, char := range h.chars { + if char.Hexerei > 0 { + count++ + } + } + + return count +} From 6e8bef69b4eb40336fe850aa5bfba8710128c391 Mon Sep 17 00:00:00 2001 From: Matoba004 Date: Wed, 11 Feb 2026 11:42:01 +0100 Subject: [PATCH 2/2] added fischl hexerei buffs --- internal/characters/fischl/asc.go | 105 +++++++++++++++++++++++++++ internal/characters/fischl/cons.go | 57 +++++++++++++++ internal/characters/fischl/fischl.go | 1 + 3 files changed, 163 insertions(+) diff --git a/internal/characters/fischl/asc.go b/internal/characters/fischl/asc.go index a934f47508..39a8ba8bcd 100644 --- a/internal/characters/fischl/asc.go +++ b/internal/characters/fischl/asc.go @@ -6,7 +6,9 @@ import ( "github.com/genshinsim/gcsim/pkg/core/combat" "github.com/genshinsim/gcsim/pkg/core/event" "github.com/genshinsim/gcsim/pkg/core/info" + "github.com/genshinsim/gcsim/pkg/core/player/character" "github.com/genshinsim/gcsim/pkg/enemy" + "github.com/genshinsim/gcsim/pkg/modifier" ) const a4IcdKey = "fischl-a4-icd" @@ -74,3 +76,106 @@ func (c *char) a4() { c.Core.Events.Subscribe(event.OnQuicken, a4cbNoGadget, "fischl-a4") c.Core.Events.Subscribe(event.OnAggravate, a4cbNoGadget, "fischl-a4") } + +func (c *char) witchesEveRite() { + // if is hexerei + if c.Hexerei != 1 { + return + } + + if c.Core.Player.GetHexereiCount() < 2 { + return + } + + olF := func(args ...any) { + m := make([]float64, attributes.EndStatType) + m[attributes.ATKP] = 0.225 + + c.AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag("fischl-hex-overload", 10*60), + AffectedStat: attributes.ATKP, + Amount: func() []float64 { + return m + }, + }) + + c.Core.Player.ActiveChar().AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag("fischl-hex-overload", 10*60), + AffectedStat: attributes.ATKP, + Amount: func() []float64 { + return m + }, + }) + } + + ecF := func(args ...any) { + m := make([]float64, attributes.EndStatType) + m[attributes.EM] = 90 + + c.AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag("fischl-hex-electrocharged", 10*60), + AffectedStat: attributes.EM, + Amount: func() []float64 { + return m + }, + }) + + c.Core.Player.ActiveChar().AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag("fischl-hex-electrocharged", 10*60), + AffectedStat: attributes.EM, + Amount: func() []float64 { + return m + }, + }) + } + + updateBuffForActive := func(args ...any) { + // swap should update buff for new active char and remove from old active char + prev := args[0].(int) + next := args[1].(int) + + statMods := []string{"fischl-hex-overload", "fischl-hex-electrocharged", "fischl-hex-overload-c6", "fischl-hex-electrocharged-c6"} + + for _, mod := range statMods { + if c.StatModIsActive(mod) { + if prev != c.Index() { + c.Core.Player.Chars()[prev].DeleteStatMod(mod) + } + m := make([]float64, attributes.EndStatType) + + if mod == "fischl-hex-overload" || mod == "fischl-hex-overload-c6" { + m[attributes.ATKP] = 0.225 + } else { + m[attributes.EM] = 90 + } + + c.Core.Player.Chars()[next].AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag(mod, 10*60), + Amount: func() []float64 { + return m + }, + }) + } + } + + if c.StatModIsActive("fischl-hex-electrocharged") { + if prev != c.Index() { + c.Core.Player.Chars()[prev].DeleteStatMod("fischl-hex-electrocharged") + } + m := make([]float64, attributes.EndStatType) + m[attributes.EM] = 90 + + c.Core.Player.Chars()[next].AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag("fischl-hex-electrocharged", 10*60), + AffectedStat: attributes.EM, + Amount: func() []float64 { + return m + }, + }) + } + } + + c.Core.Events.Subscribe(event.OnOverload, olF, "fischl-hex-overload") + c.Core.Events.Subscribe(event.OnElectroCharged, ecF, "fischl-hex-electrocharged") + c.Core.Events.Subscribe(event.OnCharacterSwap, updateBuffForActive, "fischl-hex-update-buff") +} diff --git a/internal/characters/fischl/cons.go b/internal/characters/fischl/cons.go index 3f0a61db79..19ccb4d236 100644 --- a/internal/characters/fischl/cons.go +++ b/internal/characters/fischl/cons.go @@ -5,6 +5,8 @@ import ( "github.com/genshinsim/gcsim/pkg/core/attributes" "github.com/genshinsim/gcsim/pkg/core/combat" "github.com/genshinsim/gcsim/pkg/core/info" + "github.com/genshinsim/gcsim/pkg/core/player/character" + "github.com/genshinsim/gcsim/pkg/modifier" ) func (c *char) c6Wave() { @@ -33,4 +35,59 @@ func (c *char) c6Wave() { ), c.ozTravel, ) + + c.c6Hexerei() +} + +func (c *char) c6Hexerei() { + if c.Hexerei != 1 { + return + } + + if c.Core.Player.GetHexereiCount() < 2 { + return + } + if c.StatModIsActive("fischl-hex-overload") { + duration := c.StatusDuration("fischl-hex-overload") + m := make([]float64, attributes.EndStatType) + m[attributes.ATKP] = 0.225 + + c.AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag("fischl-hex-overload-c6", duration), + AffectedStat: attributes.ATKP, + Amount: func() []float64 { + return m + }, + }) + + c.Core.Player.ActiveChar().AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag("fischl-hex-overload-c6", duration), + AffectedStat: attributes.EM, + Amount: func() []float64 { + return m + }, + }) + } + + if c.StatModIsActive("fischl-hex-electrocharged") { + duration := c.StatusDuration("fischl-hex-electrocharged") + m := make([]float64, attributes.EndStatType) + m[attributes.EM] = 90 + + c.AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag("fischl-hex-electrocharged-c6", duration), + AffectedStat: attributes.EM, + Amount: func() []float64 { + return m + }, + }) + + c.Core.Player.ActiveChar().AddStatMod(character.StatMod{ + Base: modifier.NewBaseWithHitlag("fischl-hex-electrocharged-c6", duration), + AffectedStat: attributes.EM, + Amount: func() []float64 { + return m + }, + }) + } } diff --git a/internal/characters/fischl/fischl.go b/internal/characters/fischl/fischl.go index cbd340f72e..5ccfa53976 100644 --- a/internal/characters/fischl/fischl.go +++ b/internal/characters/fischl/fischl.go @@ -58,6 +58,7 @@ func NewChar(s *core.Core, w *character.CharWrapper, p info.CharacterProfile) er func (c *char) Init() error { c.a4() + c.witchesEveRite() if c.Base.Cons >= 6 { w, err := minazuki.New(