Skip to content

Commit

Permalink
add new bp weapons (genshinsim#1630)
Browse files Browse the repository at this point in the history
  • Loading branch information
imring authored Aug 17, 2023
1 parent 35bfe61 commit 540bd64
Show file tree
Hide file tree
Showing 23 changed files with 825 additions and 1 deletion.
3 changes: 3 additions & 0 deletions internal/weapons/bow/scionoftheblazingsun/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package_name: scionoftheblazingsun
genshin_id: 15424
key: scionoftheblazingsun
107 changes: 107 additions & 0 deletions internal/weapons/bow/scionoftheblazingsun/scionoftheblazingsun.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package scionoftheblazingsun

import (
"fmt"

"github.com/genshinsim/gcsim/pkg/core"
"github.com/genshinsim/gcsim/pkg/core/attacks"
"github.com/genshinsim/gcsim/pkg/core/attributes"
"github.com/genshinsim/gcsim/pkg/core/combat"
"github.com/genshinsim/gcsim/pkg/core/event"
"github.com/genshinsim/gcsim/pkg/core/keys"
"github.com/genshinsim/gcsim/pkg/core/player/character"
"github.com/genshinsim/gcsim/pkg/core/player/weapon"
"github.com/genshinsim/gcsim/pkg/enemy"
"github.com/genshinsim/gcsim/pkg/modifier"
)

const (
icdKey = "scion-icd"
debuffKey = "scion-heartsearer"
)

func init() {
core.RegisterWeaponFunc(keys.ScionOfTheBlazingSun, NewWeapon)
}

type Weapon struct {
Index int
}

func (w *Weapon) SetIndex(idx int) { w.Index = idx }
func (w *Weapon) Init() error { return nil }

// After a Charged Attack hits an opponent, a Sunfire Arrow will descend upon the opponent hit, dealing 60% ATK as DMG,
// and applying the Heartsearer effect to the opponent damaged by said Arrow for 10s. Opponents affected by Heartsearer
// take 28% more Charged Attack DMG from the wielder. A Sunfire Arrow can be triggered once every 10s.
func NewWeapon(c *core.Core, char *character.CharWrapper, p weapon.WeaponProfile) (weapon.Weapon, error) {
w := &Weapon{}
r := p.Refine

sunfireMult := 0.45 + float64(r)*0.15

m := make([]float64, attributes.EndStatType)
m[attributes.DmgP] = 0.21 + 0.07*float64(r)
char.AddAttackMod(character.AttackMod{
Base: modifier.NewBase("scion", -1),
Amount: func(atk *combat.AttackEvent, t combat.Target) ([]float64, bool) {
e, ok := t.(*enemy.Enemy)
if !ok {
return nil, false
}
if !e.StatusIsActive(debuffKey) {
return nil, false
}
if atk.Info.AttackTag != attacks.AttackTagExtra {
return nil, false
}

return m, true
},
})

c.Events.Subscribe(event.OnEnemyDamage, func(args ...interface{}) bool {
t, ok := args[0].(*enemy.Enemy)
if !ok {
return false
}
atk := args[1].(*combat.AttackEvent)
if atk.Info.ActorIndex != char.Index {
return false
}
if c.Player.Active() != char.Index {
return false
}
if char.StatusIsActive(icdKey) {
return false
}
if atk.Info.AttackTag != attacks.AttackTagExtra {
return false
}

ai := combat.AttackInfo{
ActorIndex: char.Index,
Abil: "Sunfire Arrow",
AttackTag: attacks.AttackTagWeaponSkill,
ICDTag: attacks.ICDTagNone,
ICDGroup: attacks.ICDGroupDefault,
StrikeType: attacks.StrikeTypePierce,
Element: attributes.Physical,
Durability: 100,
Mult: sunfireMult,
}
c.QueueAttack(ai, combat.NewCircleHitOnTarget(t, nil, 3.5), 0.25*60, 0.25*60, w.applyDebuff)
char.AddStatus(icdKey, 10*60, true)

return false
}, fmt.Sprintf("scion-%v", char.Base.Key.String()))
return w, nil
}

func (w *Weapon) applyDebuff(a combat.AttackCB) {
e, ok := a.Target.(*enemy.Enemy)
if !ok {
return
}
e.AddStatus(debuffKey, 10*60, true)
}
3 changes: 3 additions & 0 deletions internal/weapons/catalyst/sacrificialjade/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package_name: sacrificialjade
genshin_id: 14424
key: sacrificialjade
105 changes: 105 additions & 0 deletions internal/weapons/catalyst/sacrificialjade/sacrificialjade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package sacrificialjade

import (
"fmt"

"github.com/genshinsim/gcsim/pkg/core"
"github.com/genshinsim/gcsim/pkg/core/attributes"
"github.com/genshinsim/gcsim/pkg/core/event"
"github.com/genshinsim/gcsim/pkg/core/glog"
"github.com/genshinsim/gcsim/pkg/core/keys"
"github.com/genshinsim/gcsim/pkg/core/player/character"
"github.com/genshinsim/gcsim/pkg/core/player/weapon"
"github.com/genshinsim/gcsim/pkg/modifier"
)

func init() {
core.RegisterWeaponFunc(keys.SacrificialJade, NewWeapon)
}

type Weapon struct {
Index int
refine int
c *core.Core
char *character.CharWrapper
lastSwap int
buff []float64
}

func (w *Weapon) SetIndex(idx int) { w.Index = idx }

func (w *Weapon) Init() error {
if w.c.Player.Active() != w.char.Index {
w.lastSwap = w.c.F
w.c.Tasks.Add(w.getBuffs(w.lastSwap), 5*60)
}
return nil
}

// When not on the field for more than 5s, Max HP will be increased by 32% and Elemental Mastery will be increased by 40.
// These effects will be canceled after the wielder has been on the field for 10s.
func NewWeapon(c *core.Core, char *character.CharWrapper, p weapon.WeaponProfile) (weapon.Weapon, error) {
w := &Weapon{
refine: p.Refine,
c: c,
char: char,
lastSwap: -1,
buff: make([]float64, attributes.EndStatType),
}

w.char.AddStatMod(character.StatMod{
Base: modifier.NewBase("sacrificial-jade", -1),
AffectedStat: attributes.NoStat,
Amount: func() ([]float64, bool) {
return w.buff, true
},
})

c.Events.Subscribe(event.OnCharacterSwap, func(args ...interface{}) bool {
prev := args[0].(int)
next := args[1].(int)
if prev == char.Index {
w.lastSwap = c.F
w.c.Tasks.Add(w.getBuffs(w.lastSwap), 5*60)
return false
}
if next == char.Index {
w.lastSwap = c.F
w.c.Tasks.Add(w.clearBuffs(w.lastSwap), 10*60)
return false
}
return false
}, fmt.Sprintf("sacrificial-jade-%v", char.Base.Key.String()))

return w, nil
}

func (w *Weapon) getBuffs(src int) func() {
return func() {
if w.lastSwap != src {
return
}
if w.c.Player.Active() == w.char.Index {
return
}

w.buff[attributes.HPP] = 0.24 + 0.08*float64(w.refine)
w.buff[attributes.EM] = 30 + 10*float64(w.refine)
w.c.Log.NewEvent("sacrificial jade gained buffs", glog.LogWeaponEvent, w.char.Index)
}
}

func (w *Weapon) clearBuffs(src int) func() {
return func() {
if w.lastSwap != src {
return
}
if w.c.Player.Active() != w.char.Index {
return
}

w.buff[attributes.HPP] = 0
w.buff[attributes.EM] = 0
w.c.Log.NewEvent("sacrificial jade lost buffs", glog.LogWeaponEvent, w.char.Index)
}
}
3 changes: 3 additions & 0 deletions internal/weapons/claymore/talkingstick/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package_name: talkingstick
genshin_id: 12424
key: talkingstick
15 changes: 15 additions & 0 deletions internal/weapons/claymore/talkingstick/talkingstick.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package talkingstick

import (
"github.com/genshinsim/gcsim/internal/weapons/common"
"github.com/genshinsim/gcsim/pkg/core"
"github.com/genshinsim/gcsim/pkg/core/keys"
)

// ATK will be increased by 16% for 15s after being affected by Pyro. This effect can be triggered once every 12s.
// All Elemental DMG Bonus will be increased by 12% for 15s after being affected by Hydro, Cryo, Electro, or Dendro.
// This effect can be triggered once every 12s.
// TODO: https://github.com/genshinsim/gcsim/issues/850
func init() {
core.RegisterWeaponFunc(keys.TalkingStick, common.NewNoEffect)
}
57 changes: 57 additions & 0 deletions internal/weapons/spear/balladofthefjords/balladofthefjords.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package balladofthefjords

import (
"github.com/genshinsim/gcsim/pkg/core"
"github.com/genshinsim/gcsim/pkg/core/attributes"
"github.com/genshinsim/gcsim/pkg/core/keys"
"github.com/genshinsim/gcsim/pkg/core/player/character"
"github.com/genshinsim/gcsim/pkg/core/player/weapon"
"github.com/genshinsim/gcsim/pkg/modifier"
)

func init() {
core.RegisterWeaponFunc(keys.BalladOfTheFjords, NewWeapon)
}

type Weapon struct {
Index int
refine int
c *core.Core
char *character.CharWrapper
}

func (w *Weapon) SetIndex(idx int) { w.Index = idx }

func (w *Weapon) Init() error {
partyEleTypes := make(map[attributes.Element]bool)
for _, char := range w.c.Player.Chars() {
partyEleTypes[char.Base.Element] = true
}
count := len(partyEleTypes)
if count < 3 {
return nil
}

em := 90 + 30*float64(w.refine)
m := make([]float64, attributes.EndStatType)
m[attributes.EM] = float64(count) * em
w.char.AddStatMod(character.StatMod{
Base: modifier.NewBase("balladofthefjords", -1),
AffectedStat: attributes.EM,
Amount: func() ([]float64, bool) {
return m, true
},
})

return nil
}

// When there are at least 3 different Elemental Types in your party, Elemental Mastery will be increased by 120.
func NewWeapon(c *core.Core, char *character.CharWrapper, p weapon.WeaponProfile) (weapon.Weapon, error) {
w := &Weapon{
refine: p.Refine,
c: c,
char: char,
}
return w, nil
}
3 changes: 3 additions & 0 deletions internal/weapons/spear/balladofthefjords/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package_name: balladofthefjords
genshin_id: 13424
key: balladofthefjords
3 changes: 3 additions & 0 deletions internal/weapons/sword/wolffang/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package_name: wolffang
genshin_id: 11424
key: wolffang
Loading

0 comments on commit 540bd64

Please sign in to comment.