Skip to content

Commit

Permalink
Merge pull request #814 from shizukayuki/revamp-conditionals
Browse files Browse the repository at this point in the history
Refactor conditionals
  • Loading branch information
srliao authored Aug 20, 2022
2 parents 5394250 + 3950cb2 commit 20b610d
Show file tree
Hide file tree
Showing 29 changed files with 300 additions and 629 deletions.
15 changes: 5 additions & 10 deletions internal/characters/albedo/albedo.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,13 @@ func (c *char) Init() error {
return nil
}

func (c *char) Condition(k string) int64 {
switch k {
case "skill":
fallthrough
func (c *char) Condition(fields []string) (any, error) {
switch fields[0] {
case "elevator":
if c.skillActive {
return 1
}
return 0
return c.skillActive, nil
case "c2stacks":
return int64(c.c2stacks)
return c.c2stacks, nil
default:
return 0
return c.Character.Condition(fields)
}
}
8 changes: 4 additions & 4 deletions internal/characters/aloy/aloy.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ func (c *char) Init() error {
return nil
}

func (c *char) Condition(k string) int64 {
switch k {
func (c *char) Condition(fields []string) (any, error) {
switch fields[0] {
case "coil":
return int64(c.coils)
return c.coils, nil
default:
return 0
return c.Character.Condition(fields)
}
}
12 changes: 6 additions & 6 deletions internal/characters/fischl/fischl.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,16 @@ func (c *char) Init() error {
return nil
}

func (c *char) Condition(k string) int64 {
switch k {
func (c *char) Condition(fields []string) (any, error) {
switch fields[0] {
case "oz":
if c.ozActiveUntil <= c.Core.F {
return 0
return false, nil
}
return int64(c.ozActiveUntil - c.Core.F)
return (c.ozActiveUntil - c.Core.F), nil
case "oz-source":
return int64(c.ozSource)
return c.ozSource, nil
default:
return 0
return c.Character.Condition(fields)
}
}
10 changes: 5 additions & 5 deletions internal/characters/ningguang/ningguang.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ func (c *char) ActionStam(a action.Action, p map[string]int) float64 {
return c.Character.ActionStam(a, p)
}

func (c *char) Condition(field string) int64 {
switch field {
func (c *char) Condition(fields []string) (any, error) {
switch fields[0] {
case "jadeCount":
return int64(c.jadeCount)
return c.jadeCount, nil
case "prevAttack":
return int64(c.prevAttack)
return c.prevAttack, nil
default:
return 0
return c.Character.Condition(fields)
}
}
4 changes: 0 additions & 4 deletions internal/template/character/cooldown.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ func (c *Character) SetCD(a action.Action, dur int) {
if c.AvailableCDCharge[a] < 0 {
panic("unexpected charges less than 0")
}
//TODO: remove these tags; add special syntax just to check for charges instead of using tags
if c.Tags["skill_charge"] > 0 {
c.Tags["skill_charge"]--
}
c.Core.Log.NewEventBuildMsg(glog.LogCooldownEvent, c.Index, a.String(), " cooldown triggered").
Write("type", a.String()).
Write("expiry", c.Cooldown(a)).
Expand Down
10 changes: 10 additions & 0 deletions internal/template/character/default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package character

import (
"fmt"
"strings"
)

func (c *Character) Condition(fields []string) (any, error) {
return false, fmt.Errorf("invalid character condition: .%v.%v", c.Base.Key.String(), strings.Join(fields, "."))
}
103 changes: 103 additions & 0 deletions pkg/conditional/character.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package conditional

import (
"fmt"

"github.com/genshinsim/gcsim/pkg/core"
"github.com/genshinsim/gcsim/pkg/core/action"
"github.com/genshinsim/gcsim/pkg/core/attributes"
"github.com/genshinsim/gcsim/pkg/core/keys"
"github.com/genshinsim/gcsim/pkg/core/player/character"
)

func evalCharacter(c *core.Core, key keys.Char, fields []string) (any, error) {
if err := fieldsCheck(fields, 2, "character"); err != nil {
return 0, err
}
char, ok := c.Player.ByKey(key)
if !ok {
return 0, fmt.Errorf("character %v not in team when evaluating condition", key)
}

// special case for ability conditions. since fields are swapped
// .kokomi.<abil>.<cond>
typ := fields[1]
act := action.StringToAction(typ)
if act != action.InvalidAction {
if err := fieldsCheck(fields, 3, "character ability"); err != nil {
return 0, err
}
return evalCharacterAbil(c, char, act, fields[2])
}

switch typ {
case "cons":
return char.Base.Cons, nil
case "energy":
return char.Energy, nil
case "energymax":
return char.EnergyMax, nil
case "normal":
return char.NextNormalCounter(), nil
case "onfield":
return c.Player.Active() == char.Index, nil
case "weapon":
return int(char.Weapon.Key), nil
case "status":
if err := fieldsCheck(fields, 3, "character "+typ); err != nil {
return 0, err
}
return char.StatusIsActive(fields[2]), nil
case "mods":
if err := fieldsCheck(fields, 3, "character "+typ); err != nil {
return 0, err
}
return char.StatModIsActive(fields[2]), nil
case "infusion":
if err := fieldsCheck(fields, 3, "character "+typ); err != nil {
return 0, err
}
return c.Player.WeaponInfuseIsActive(char.Index, fields[2]), nil
case "tags":
if err := fieldsCheck(fields, 3, "character "+typ); err != nil {
return 0, err
}
return char.Tag(fields[2]), nil
case "stats":
if err := fieldsCheck(fields, 3, "character "+typ); err != nil {
return 0, err
}
return evalCharacterStats(char, fields[2])
default: // .kokomi.*
return char.Condition(fields[1:])
}

}

func evalCharacterStats(char *character.CharWrapper, stat string) (float64, error) {
key := attributes.StrToStatType(stat)
if key == -1 {
return 0, fmt.Errorf("invalid stat key %v in character stat condition", stat)
}
return char.Stat(key), nil
}

func evalCharacterAbil(c *core.Core, char *character.CharWrapper, act action.Action, typ string) (any, error) {
switch typ {
case "cd":
if act == action.ActionSwap {
return c.Player.SwapCD, nil
}
return char.Cooldown(act), nil
case "charge":
return char.Charges(act), nil
case "ready":
if act == action.ActionSwap {
return c.Player.SwapCD == 0 || c.Player.Active() == char.Index, nil
}
//TODO: nil map may cause problems here??
return char.ActionReady(act, nil), nil
default:
return 0, fmt.Errorf("bad character ability condition: invalid type %v", typ)
}
}
22 changes: 0 additions & 22 deletions pkg/conditional/charcustom.go

This file was deleted.

35 changes: 0 additions & 35 deletions pkg/conditional/charmods.go

This file was deleted.

56 changes: 23 additions & 33 deletions pkg/conditional/conditional.go
Original file line number Diff line number Diff line change
@@ -1,52 +1,42 @@
package conditional

import (
"strings"
"fmt"

"github.com/genshinsim/gcsim/pkg/core"
"github.com/genshinsim/gcsim/pkg/shortcut"
)

func Eval(c *core.Core, fields []string) int64 {
func fieldsCheck(fields []string, expecting int, category string) error {
if len(fields) < expecting {
return fmt.Errorf("bad %v condition; invalid num of fields; expecting at least %v; got %v", category, expecting, len(fields))
}
return nil
}

func Eval(c *core.Core, fields []string) (any, error) {
switch fields[0] {
case ".debuff":
case "debuff":
return evalDebuff(c, fields)
case ".element":
case "element":
return evalElement(c, fields)
case ".cd":
return evalCD(c, fields)
case ".energy":
return evalEnergy(c, fields)
case ".status":
return evalStatus(c, fields)
case ".tags":
return evalTags(c, fields)
case ".stam":
return evalStam(c, fields)
case ".ready":
return evalReady(c, fields)
case ".mods":
return evalCharMods(c, fields)
case ".infusion":
return evalInfusion(c, fields)
case ".construct":
case "status":
if err := fieldsCheck(fields, 2, "status"); err != nil {
return 0, err
}
return c.Status.Duration(fields[1]), nil
case "stam":
return c.Player.Stam, nil
case "construct":
return evalConstruct(c, fields)
case ".normal":
return evalNormalCounter(c, fields)
case ".onfield":
return evalOnField(c, fields)
case ".weapon":
return evalWeapon(c, fields)
case ".keys":
case "keys":
return evalKeys(c, fields)
case ".cons":
return evalConstellation(c, fields)
default:
//check if it's a char name; if so check char custom eval func
name := strings.TrimPrefix(fields[0], ".")
name := fields[0]
if key, ok := shortcut.CharNameToKey[name]; ok {
return evalCharCustom(c, key, fields)
return evalCharacter(c, key, fields)
}
return 0
return 0, fmt.Errorf("invalid character %v in character condition", name)
}
}
31 changes: 0 additions & 31 deletions pkg/conditional/cons.go

This file was deleted.

Loading

0 comments on commit 20b610d

Please sign in to comment.