horsegen: also generate go
This commit is contained in:
66
abilitytype_string.go
Normal file
66
abilitytype_string.go
Normal file
@@ -0,0 +1,66 @@
|
||||
// Code generated by "stringer -type AbilityType -trimprefix Ability"; DO NOT EDIT.
|
||||
|
||||
package horse
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[AbilityPassiveSpeed-1]
|
||||
_ = x[AbilityPassiveStamina-2]
|
||||
_ = x[AbilityPassivePower-3]
|
||||
_ = x[AbilityPassiveGuts-4]
|
||||
_ = x[AbilityPassiveWit-5]
|
||||
_ = x[AbilityGreatEscape-6]
|
||||
_ = x[AbilityVision-8]
|
||||
_ = x[AbilityHP-9]
|
||||
_ = x[AbilityGateDelay-10]
|
||||
_ = x[AbilityFrenzy-13]
|
||||
_ = x[AbilityCurrentSpeed-21]
|
||||
_ = x[AbilityTargetSpeed-27]
|
||||
_ = x[AbilityLaneSpeed-28]
|
||||
_ = x[AbilityAccel-31]
|
||||
_ = x[AbilityLaneChange-35]
|
||||
}
|
||||
|
||||
const (
|
||||
_AbilityType_name_0 = "PassiveSpeedPassiveStaminaPassivePowerPassiveGutsPassiveWitGreatEscape"
|
||||
_AbilityType_name_1 = "VisionHPGateDelay"
|
||||
_AbilityType_name_2 = "Frenzy"
|
||||
_AbilityType_name_3 = "CurrentSpeed"
|
||||
_AbilityType_name_4 = "TargetSpeedLaneSpeed"
|
||||
_AbilityType_name_5 = "Accel"
|
||||
_AbilityType_name_6 = "LaneChange"
|
||||
)
|
||||
|
||||
var (
|
||||
_AbilityType_index_0 = [...]uint8{0, 12, 26, 38, 49, 59, 70}
|
||||
_AbilityType_index_1 = [...]uint8{0, 6, 8, 17}
|
||||
_AbilityType_index_4 = [...]uint8{0, 11, 20}
|
||||
)
|
||||
|
||||
func (i AbilityType) String() string {
|
||||
switch {
|
||||
case 1 <= i && i <= 6:
|
||||
i -= 1
|
||||
return _AbilityType_name_0[_AbilityType_index_0[i]:_AbilityType_index_0[i+1]]
|
||||
case 8 <= i && i <= 10:
|
||||
i -= 8
|
||||
return _AbilityType_name_1[_AbilityType_index_1[i]:_AbilityType_index_1[i+1]]
|
||||
case i == 13:
|
||||
return _AbilityType_name_2
|
||||
case i == 21:
|
||||
return _AbilityType_name_3
|
||||
case 27 <= i && i <= 28:
|
||||
i -= 27
|
||||
return _AbilityType_name_4[_AbilityType_index_4[i]:_AbilityType_index_4[i+1]]
|
||||
case i == 31:
|
||||
return _AbilityType_name_5
|
||||
case i == 35:
|
||||
return _AbilityType_name_6
|
||||
default:
|
||||
return "AbilityType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
}
|
||||
264
character.go
Normal file
264
character.go
Normal file
File diff suppressed because one or more lines are too long
@@ -166,13 +166,20 @@ ability types:
|
||||
target types:
|
||||
- 0 none (second and third abilities on skills that only have one)
|
||||
- 1 self
|
||||
- 2 others who have sympathy? only on autumn neo universe's rare green skill which triggers everyone's sympathy, and there's no target value
|
||||
- 4 others in view
|
||||
- 7 frontmost? only on daiichi ruby's unique, has a target value of 5 but the description says 先頭から4人まで
|
||||
- 9 others ahead, target_value is number of targets (18 for all)
|
||||
- 10 others behind, target_value is number of targets
|
||||
- 11 all teammates
|
||||
- 18 others in style, target_value is style (1=front, 2=pace, 3=late, 4=end)
|
||||
- 19 rushing others ahead
|
||||
- 20 rushing others behind
|
||||
- 21 rushing others in style, target_value is style
|
||||
- 22 specific character, target value is character id
|
||||
- 23 other who triggered the skill
|
||||
|
||||
TODO target types only in jp: 2, 7, 11, 22, 23
|
||||
|
||||
ability_value_usage can be 1 for plain or 2-6 for aoharu stat skill stat scaling
|
||||
|
||||
|
||||
145
horsegen/character.go.template
Normal file
145
horsegen/character.go.template
Normal file
@@ -0,0 +1,145 @@
|
||||
{{ define "go-character" -}}
|
||||
package horse
|
||||
|
||||
// Automatically generated with horsegen; DO NOT EDIT
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Character struct {
|
||||
ID int16
|
||||
Name string
|
||||
}
|
||||
|
||||
var characterIDs = []int16{
|
||||
{{- range $c := $.Characters }}
|
||||
{{ $c.ID }}, // {{ $c.Name }}
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
var characterNames = []string{
|
||||
{{- range $c := $.Characters }}
|
||||
{{ printf "%q" $c.Name }},
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
var characterNameToID = map[string]int16{
|
||||
{{- range $c := $.Characters }}
|
||||
{{ printf "%q" $c.Name }}: {{ $c.ID }},
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func characterIndex(id int16) (int, bool) {
|
||||
return slices.BinarySearch(characterIDs, id)
|
||||
}
|
||||
|
||||
func CharacterForID(id int16) Character {
|
||||
i, ok := characterIndex(id)
|
||||
if !ok {
|
||||
return Character{}
|
||||
}
|
||||
return Character{
|
||||
ID: id,
|
||||
Name: characterNames[i],
|
||||
}
|
||||
}
|
||||
|
||||
func CharacterForName(name string) Character {
|
||||
id, ok := characterNameToID[name]
|
||||
if !ok {
|
||||
return Character{}
|
||||
}
|
||||
return Character{
|
||||
ID: id,
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Character) MarshalJSON() ([]byte, error) {
|
||||
// Only marshal legal or empty characters.
|
||||
if c.ID == 0 {
|
||||
return []byte{'0'}, nil
|
||||
}
|
||||
i, ok := characterIndex(c.ID)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("marshaling character %q with invalid ID %d", c.Name, c.ID)
|
||||
}
|
||||
if characterNames[i] != c.Name {
|
||||
return nil, fmt.Errorf("marshaling character with ID %d: name is %q but should be %q", c.ID, c.Name, characterNames[i])
|
||||
}
|
||||
return strconv.AppendInt(nil, int64(c.ID), 10), nil
|
||||
}
|
||||
|
||||
func (c *Character) UnmarshalJSON(b []byte) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
id, err := strconv.ParseInt(string(b), 10, 16)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshaling invalid character ID %q: %w", b, err)
|
||||
}
|
||||
if id == 0 {
|
||||
*c = Character{}
|
||||
return nil
|
||||
}
|
||||
i, ok := characterIndex(int16(id))
|
||||
if !ok {
|
||||
return fmt.Errorf("unmarshaling unrecognized character ID %d", id)
|
||||
}
|
||||
*c = Character{
|
||||
ID: int16(id),
|
||||
Name: characterNames[i],
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var pairAffinity = []int8{
|
||||
{{- range $a := $.Characters -}}
|
||||
{{- range $b := $.Characters -}}
|
||||
{{- index $.PairMaps $a.ID $b.ID -}},
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
}
|
||||
|
||||
var trioAffinity = []int8{
|
||||
{{- range $a := $.Characters -}}
|
||||
{{- range $b := $.Characters -}}
|
||||
{{- range $c := $.Characters -}}
|
||||
{{- index $.TrioMaps $a.ID $b.ID $c.ID -}},
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
}
|
||||
|
||||
func PairAffinity(a, b Character) int {
|
||||
i, ok := characterIndex(a.ID)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
j, ok := characterIndex(b.ID)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
return int(pairAffinity[i*{{ $.Count }} + j])
|
||||
}
|
||||
|
||||
func TrioAffinity(a, b, c Character) int {
|
||||
i, ok := characterIndex(a.ID)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
j, ok := characterIndex(b.ID)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
k, ok := characterIndex(c.ID)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
return int(trioAffinity[i*{{ $.Count }}*{{ $.Count }} + j*{{ $.Count }} + k])
|
||||
}
|
||||
|
||||
{{ end }}
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
@@ -10,7 +11,7 @@ import (
|
||||
"unicode"
|
||||
)
|
||||
|
||||
//go:embed character.kk.template skill.kk.template
|
||||
//go:embed character.kk.template skill.kk.template character.go.template skill.go.template
|
||||
var templates embed.FS
|
||||
|
||||
// LoadTemplates sets up templates to render game data to source code.
|
||||
@@ -18,12 +19,14 @@ func LoadTemplates() (*template.Template, error) {
|
||||
t := template.New("root")
|
||||
t.Funcs(template.FuncMap{
|
||||
"kkenum": kkenum,
|
||||
"goenum": goenum,
|
||||
})
|
||||
return t.ParseFS(templates, "*")
|
||||
}
|
||||
|
||||
// ExecCharacterKK renders the Koka character module to w.
|
||||
func ExecCharacterKK(t *template.Template, w io.Writer, c []NamedID[Character], pairs, trios []AffinityRelation) error {
|
||||
// ExecCharacter renders the Koka character module to kk and the Go character file to g.
|
||||
// If either is nil, it is skipped.
|
||||
func ExecCharacter(t *template.Template, kk, g io.Writer, c []NamedID[Character], pairs, trios []AffinityRelation) error {
|
||||
if len(pairs) != len(c)*len(c) {
|
||||
return fmt.Errorf("there are %d pairs but there must be %d for %d characters", len(pairs), len(c)*len(c), len(c))
|
||||
}
|
||||
@@ -58,13 +61,20 @@ func ExecCharacterKK(t *template.Template, w io.Writer, c []NamedID[Character],
|
||||
Count int
|
||||
MaxID int
|
||||
}{c, pairs, trios, pm, tm, len(c), maxid}
|
||||
return t.ExecuteTemplate(w, "koka-character", &data)
|
||||
var err error
|
||||
if kk != nil {
|
||||
err = errors.Join(t.ExecuteTemplate(kk, "koka-character", &data))
|
||||
}
|
||||
if g != nil {
|
||||
err = errors.Join(t.ExecuteTemplate(g, "go-character", &data))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func ExecSkillKK(t *template.Template, w io.Writer, g []NamedID[SkillGroup], s []Skill) error {
|
||||
m := make(map[int][]Skill, len(g))
|
||||
u := make(map[int]int, len(g))
|
||||
for _, t := range s {
|
||||
func ExecSkill(t *template.Template, kk, g io.Writer, groups []NamedID[SkillGroup], skills []Skill) error {
|
||||
m := make(map[int][]Skill, len(groups))
|
||||
u := make(map[int]int, len(groups))
|
||||
for _, t := range skills {
|
||||
m[t.GroupID] = append(m[t.GroupID], t)
|
||||
if t.Rarity >= 4 {
|
||||
// Add inheritable uniques to u so we can add inherited versions to groups.
|
||||
@@ -72,7 +82,7 @@ func ExecSkillKK(t *template.Template, w io.Writer, g []NamedID[SkillGroup], s [
|
||||
}
|
||||
}
|
||||
// Now that u is set up, iterate through again and add in inherited skills.
|
||||
for _, t := range s {
|
||||
for _, t := range skills {
|
||||
if t.InheritID != 0 {
|
||||
m[u[t.InheritID]] = append(m[u[t.InheritID]], t)
|
||||
}
|
||||
@@ -81,8 +91,15 @@ func ExecSkillKK(t *template.Template, w io.Writer, g []NamedID[SkillGroup], s [
|
||||
Groups []NamedID[SkillGroup]
|
||||
Skills []Skill
|
||||
Related map[int][]Skill
|
||||
}{g, s, m}
|
||||
return t.ExecuteTemplate(w, "koka-skill", &data)
|
||||
}{groups, skills, m}
|
||||
var err error
|
||||
if kk != nil {
|
||||
err = errors.Join(t.ExecuteTemplate(kk, "koka-skill", &data))
|
||||
}
|
||||
if g != nil {
|
||||
err = errors.Join(t.ExecuteTemplate(g, "go-skill-data", &data))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func ExecSkillGroupKK(t *template.Template, w io.Writer, g []NamedID[SkillGroup], s []Skill) error {
|
||||
@@ -93,7 +110,7 @@ func ExecSkillGroupKK(t *template.Template, w io.Writer, g []NamedID[SkillGroup]
|
||||
return t.ExecuteTemplate(w, "koka-skill-group", &data)
|
||||
}
|
||||
|
||||
const replaceDash = " ,!?/+();#○☆♡'=♪∀゚∴"
|
||||
const wordSeps = " ,!?/-+();#○☆♡'=♪∀゚∴"
|
||||
|
||||
var (
|
||||
kkReplace = func() *strings.Replacer {
|
||||
@@ -111,13 +128,33 @@ var (
|
||||
"×", "x",
|
||||
"◎", "Lv2",
|
||||
}
|
||||
for _, c := range replaceDash {
|
||||
for _, c := range wordSeps {
|
||||
r = append(r, string(c), "-")
|
||||
}
|
||||
return strings.NewReplacer(r...)
|
||||
}()
|
||||
kkMultidash = regexp.MustCompile(`-+`)
|
||||
kkDashNonletter = regexp.MustCompile(`-[^A-Za-z]`)
|
||||
|
||||
goReplace = func() *strings.Replacer {
|
||||
r := []string{
|
||||
"Triple 7s", "TripleSevens",
|
||||
"1,500,000 CC", "OneMillionCC",
|
||||
"15,000,000 CC", "FifteenMillionCC",
|
||||
"1st", "First",
|
||||
"♡ 3D Nail Art", "NailArt",
|
||||
".", "",
|
||||
"&", "And",
|
||||
"'s", "s",
|
||||
"∞", "Infinity",
|
||||
"×", "X",
|
||||
"◎", "Lv2",
|
||||
}
|
||||
for _, c := range wordSeps {
|
||||
r = append(r, string(c), "")
|
||||
}
|
||||
return strings.NewReplacer(r...)
|
||||
}()
|
||||
)
|
||||
|
||||
func kkenum(name string) string {
|
||||
@@ -144,3 +181,14 @@ func kkenum(name string) string {
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func goenum(name string) string {
|
||||
// go names are a bit more lax, so we need fewer checks
|
||||
orig := name
|
||||
name = goReplace.Replace(name)
|
||||
if len(name) == 0 {
|
||||
panic(fmt.Errorf("%q became empty as Go enum variant", orig))
|
||||
}
|
||||
name = strings.ToUpper(name[:1]) + name[1:]
|
||||
return name
|
||||
}
|
||||
|
||||
@@ -15,11 +15,12 @@ import (
|
||||
|
||||
func main() {
|
||||
var (
|
||||
mdb string
|
||||
out string
|
||||
mdb string
|
||||
kkOut, goOut string
|
||||
)
|
||||
flag.StringVar(&mdb, "mdb", os.ExpandEnv(`$USERPROFILE\AppData\LocalLow\Cygames\Umamusume\master\master.mdb`), "`path` to Umamusume master.mdb")
|
||||
flag.StringVar(&out, "kk", `.\horse`, "existing `dir`ectory for output Koka files")
|
||||
flag.StringVar(&kkOut, "kk", `.\horse`, "existing `dir`ectory for output Koka files")
|
||||
flag.StringVar(&goOut, "go", `.`, "existing `dir`ectory for output Go files")
|
||||
flag.Parse()
|
||||
|
||||
pctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||
@@ -86,23 +87,28 @@ func main() {
|
||||
|
||||
eg, ctx = errgroup.WithContext(pctx)
|
||||
eg.Go(func() error {
|
||||
cf, err := os.Create(filepath.Join(out, "character.kk"))
|
||||
cf, err := os.Create(filepath.Join(kkOut, "character.kk"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gf, err := os.Create(filepath.Join(goOut, "character.go"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
slog.Info("write characters")
|
||||
return ExecCharacterKK(t, cf, charas, pairs, trios)
|
||||
return ExecCharacter(t, cf, gf, charas, pairs, trios)
|
||||
})
|
||||
eg.Go(func() error {
|
||||
sf, err := os.Create(filepath.Join(out, "skill.kk"))
|
||||
sf, err := os.Create(filepath.Join(kkOut, "skill.kk"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gf, err := os.Create(filepath.Join(goOut, "skill_data.go"))
|
||||
slog.Info("write skills")
|
||||
return ExecSkillKK(t, sf, sg, skills)
|
||||
return ExecSkill(t, sf, gf, sg, skills)
|
||||
})
|
||||
eg.Go(func() error {
|
||||
sf, err := os.Create(filepath.Join(out, "skill-group.kk"))
|
||||
sf, err := os.Create(filepath.Join(kkOut, "skill-group.kk"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
70
horsegen/skill.go.template
Normal file
70
horsegen/skill.go.template
Normal file
@@ -0,0 +1,70 @@
|
||||
{{- define "go-skill-data" -}}
|
||||
package horse
|
||||
|
||||
// Automatically generated with horsegen; DO NOT EDIT
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type SkillID -trimprefix Skill -linecomment
|
||||
const (
|
||||
{{- range $s := $.Skills }}
|
||||
Skill{{ goenum $s.Name }}{{ if ne $s.InheritID 0 }}Inherit{{ end }} SkillID = {{ $s.ID }} // {{ $s.Name }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
var AllSkills = map[SkillID]Skill{
|
||||
{{- range $s := $.Skills }}
|
||||
Skill{{ goenum $s.Name }}{{ if ne $s.InheritID 0 }}Inherit{{ end }}: {
|
||||
{{ $s.ID }},
|
||||
{{ printf "%q" $s.Name }},
|
||||
{{ printf "%q" $s.Description }},
|
||||
{{ $s.GroupID }},
|
||||
{{ $s.Rarity }},
|
||||
{{ $s.GroupRate }},
|
||||
{{ $s.GradeValue }},
|
||||
{{ $s.WitCheck }},
|
||||
[]Activation{
|
||||
{{- range $a := $s.Activations }}
|
||||
{{- if ne $a.Condition "" }}
|
||||
{
|
||||
{{ printf "%q" $a.Precondition }},
|
||||
{{ printf "%q" $a.Condition }},
|
||||
{{ $a.Duration }},
|
||||
{{ $a.Cooldown }},
|
||||
[]Ability{
|
||||
{{- range $abil := $a.Abilities }}
|
||||
{{- if ne $abil.Type 0 }}
|
||||
{
|
||||
{{ if eq $abil.Type 1 -}}AbilityPassiveSpeed,
|
||||
{{ else if eq $abil.Type 2 -}}AbilityPassiveStamina,
|
||||
{{ else if eq $abil.Type 3 -}}AbilityPassivePower,
|
||||
{{ else if eq $abil.Type 4 -}}AbilityPassiveGuts,
|
||||
{{ else if eq $abil.Type 5 -}}AbilityPassiveWit,
|
||||
{{ else if eq $abil.Type 6 -}}AbilityGreatEscape,
|
||||
{{ else if eq $abil.Type 8 -}}AbilityVision,
|
||||
{{ else if eq $abil.Type 9 -}}AbilityHP,
|
||||
{{ else if eq $abil.Type 10 -}}AbilityGateDelay,
|
||||
{{ else if eq $abil.Type 13 -}}AbilityFrenzy,
|
||||
{{ else if eq $abil.Type 21 -}}AbilityCurrentSpeed,
|
||||
{{ else if eq $abil.Type 27 -}}AbilityTargetSpeed,
|
||||
{{ else if eq $abil.Type 28 -}}AbilityLaneSpeed,
|
||||
{{ else if eq $abil.Type 31 -}}AbilityAccel,
|
||||
{{ else if eq $abil.Type 35 -}}AbilityLaneChange,
|
||||
{{ else }}??? $abil.Type={{$abil.Type}}
|
||||
{{ end -}}
|
||||
{{ $abil.ValueUsage }},
|
||||
{{ $abil.Value }},
|
||||
{{ $abil.Target }},
|
||||
{{ $abil.TargetValue }},
|
||||
},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
},
|
||||
},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
},
|
||||
{{ $s.SPCost }},
|
||||
{{ $s.IconID }},
|
||||
},
|
||||
{{- end }}
|
||||
}
|
||||
{{ end }}
|
||||
57
skill.go
Normal file
57
skill.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package horse
|
||||
|
||||
type SkillID int32
|
||||
|
||||
// Skill is the internal data about a skill.
|
||||
type Skill struct {
|
||||
ID SkillID
|
||||
Name string
|
||||
Description string
|
||||
Group int32
|
||||
Rarity int8
|
||||
GroupRate int8
|
||||
GradeValue int32
|
||||
WitCheck bool
|
||||
Activations []Activation
|
||||
SPCost int
|
||||
IconID int
|
||||
}
|
||||
|
||||
// Activation is the parameters controlling when a skill activates.
|
||||
type Activation struct {
|
||||
Precondition string
|
||||
Condition string
|
||||
Duration int // 1e4 scale
|
||||
Cooldown int // 1e4 scale
|
||||
Abilities []Ability
|
||||
}
|
||||
|
||||
// Ability is an individual effect applied by a skill.
|
||||
type Ability struct {
|
||||
Type AbilityType
|
||||
ValueUsage int8
|
||||
Value int32
|
||||
Target int8
|
||||
TargetValue int32
|
||||
}
|
||||
|
||||
type AbilityType int8
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type AbilityType -trimprefix Ability
|
||||
const (
|
||||
AbilityPassiveSpeed AbilityType = 1
|
||||
AbilityPassiveStamina AbilityType = 2
|
||||
AbilityPassivePower AbilityType = 3
|
||||
AbilityPassiveGuts AbilityType = 4
|
||||
AbilityPassiveWit AbilityType = 5
|
||||
AbilityGreatEscape AbilityType = 6
|
||||
AbilityVision AbilityType = 8
|
||||
AbilityHP AbilityType = 9
|
||||
AbilityGateDelay AbilityType = 10
|
||||
AbilityFrenzy AbilityType = 13
|
||||
AbilityCurrentSpeed AbilityType = 21
|
||||
AbilityTargetSpeed AbilityType = 27
|
||||
AbilityLaneSpeed AbilityType = 28
|
||||
AbilityAccel AbilityType = 31
|
||||
AbilityLaneChange AbilityType = 35
|
||||
)
|
||||
15217
skill_data.go
Normal file
15217
skill_data.go
Normal file
File diff suppressed because it is too large
Load Diff
995
skillid_string.go
Normal file
995
skillid_string.go
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user