horsegen: generate skills
This commit is contained in:
@@ -3,4 +3,4 @@
|
||||
Models, data, algorithms, and tools for Umamusume: Pretty Derby.
|
||||
|
||||
Data is generated from the game's local database.
|
||||
Algorithms come from either Erzzy and Kireina's reference document or Crazyfellow's parenting and gene guide.
|
||||
Algorithms come from Erzzy and Kireina's reference, KuromiAK's race mechanics reference, and Crazyfellow's parenting and gene guide.
|
||||
|
||||
@@ -130,6 +130,53 @@ race sparks with skills always give +1, skill sparks always give +1-5, unique sp
|
||||
- support card skill hints are defined in single_mode_hint_gain
|
||||
- skill_set is NOT trainee skills, seems to be npcs
|
||||
|
||||
skill categories:
|
||||
- 0 passive
|
||||
- 1 early race
|
||||
- 2 mid-race
|
||||
- 3 late race or last spurt
|
||||
- 4 anytime
|
||||
- 5 unique
|
||||
|
||||
unique_skill_id_1 is for inherited uniques, points to non-inherited version.
|
||||
unique_skill_id_2 is same but points to 1\*/2\* version.
|
||||
|
||||
exp_type appears to be whether the skill gains levels, i.e. own unique.
|
||||
|
||||
ability time and cooldown time are given in tenths of milliseconds, i.e. divide by 10000 to get seconds.
|
||||
|
||||
ability types:
|
||||
- 1 speed bonus => ability_value / 10000 is flat gain
|
||||
- 2 stamina bonus
|
||||
- 3 power bonus
|
||||
- 4 guts bonus
|
||||
- 5 wit bonus
|
||||
- 6 runaway => ability_value = 0
|
||||
- 8 vision => ability_value / 10000 is amount (what are the units? what does vision do??)
|
||||
- 9 heal or stam debuff => ability_value / 10000 is hp modify
|
||||
- 10 starting gate delay (focus, concentration, gatekept) => ability_value / 10000 is multiplier
|
||||
- 13 frenzy => ability_value / 10000 is rush time modifier (add?)
|
||||
- 21 current speed => ability_value / 10000 is multiplier modifier
|
||||
- 27 target speed => ''
|
||||
- 28 lane change speed => ''
|
||||
- 31 accel => ''
|
||||
- 35 force lane change? it's only on dodging danger/sixth sense with a value of 5000 on both, gametora says "change lane (50% of the track)"
|
||||
|
||||
target types:
|
||||
- 0 none (second and third abilities on skills that only have one)
|
||||
- 1 self
|
||||
- 4 others in view
|
||||
- 9 others ahead, target_value is number of targets (18 for all)
|
||||
- 10 others behind, target_value is number of targets
|
||||
- 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
|
||||
|
||||
ability_value_usage can be 1 for plain or 2-6 for aoharu stat skill stat scaling
|
||||
|
||||
seems to be activate_lot = 1 means wit check, 0 means guaranteed
|
||||
|
||||
# races
|
||||
|
||||
- group 1, grade: g1 100, g2 200, g3 300, op 400, pre-op 700
|
||||
|
||||
1025
horse/skill-group.kk
Normal file
1025
horse/skill-group.kk
Normal file
File diff suppressed because it is too large
Load Diff
2301
horse/skill.kk
2301
horse/skill.kk
File diff suppressed because it is too large
Load Diff
@@ -61,25 +61,37 @@ func ExecCharacterKK(t *template.Template, w io.Writer, c []NamedID[Character],
|
||||
return t.ExecuteTemplate(w, "koka-character", &data)
|
||||
}
|
||||
|
||||
func ExecSkillKK(t *template.Template, w io.Writer, g []NamedID[SkillGroup]) error {
|
||||
func ExecSkillKK(t *template.Template, w io.Writer, g []NamedID[SkillGroup], s []Skill) error {
|
||||
data := struct {
|
||||
Groups []NamedID[SkillGroup]
|
||||
}{g}
|
||||
Skills []Skill
|
||||
}{g, s}
|
||||
return t.ExecuteTemplate(w, "koka-skill", &data)
|
||||
}
|
||||
|
||||
const replaceDash = " ,!?/+();#○◎☆♡'&=♪∀゚∴"
|
||||
func ExecSkillGroupKK(t *template.Template, w io.Writer, g []NamedID[SkillGroup], s []Skill) error {
|
||||
data := struct {
|
||||
Groups []NamedID[SkillGroup]
|
||||
Skills []Skill
|
||||
}{g, s}
|
||||
return t.ExecuteTemplate(w, "koka-skill-group", &data)
|
||||
}
|
||||
|
||||
const replaceDash = " ,!?/+();#○☆♡'&=♪∀゚∴"
|
||||
|
||||
var (
|
||||
kkReplace = func() *strings.Replacer {
|
||||
r := []string{
|
||||
"Triple 7s", "Triple-Sevens", // hard to replace with the right thing automatically
|
||||
"1,500,000 CC", "Million-CC",
|
||||
"1,500,000 CC", "One-Million-CC",
|
||||
"15,000,000 CC", "Fifteen-Million-CC",
|
||||
"1st", "First",
|
||||
".", "",
|
||||
"'s", "s",
|
||||
"ó", "o",
|
||||
"∞", "Infinity",
|
||||
"×", "x",
|
||||
"◎", "Lv2",
|
||||
}
|
||||
for _, c := range replaceDash {
|
||||
r = append(r, string(c), "-")
|
||||
|
||||
133
horsegen/load.go
133
horsegen/load.go
@@ -20,6 +20,9 @@ var characterAffinity3SQL string
|
||||
//go:embed skill-group.sql
|
||||
var skillGroupSQL string
|
||||
|
||||
//go:embed skill.sql
|
||||
var skillSQL string
|
||||
|
||||
type (
|
||||
Character struct{}
|
||||
SkillGroup struct{}
|
||||
@@ -174,3 +177,133 @@ func SkillGroups(ctx context.Context, db *sqlitex.Pool) ([]NamedID[SkillGroup],
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
type Skill struct {
|
||||
ID int
|
||||
Name string
|
||||
Description string
|
||||
GroupID int
|
||||
GroupName string
|
||||
Rarity int
|
||||
GroupRate int
|
||||
GradeValue int
|
||||
WitCheck bool
|
||||
Activations [2]SkillActivation
|
||||
IconID int
|
||||
Index int
|
||||
}
|
||||
|
||||
type SkillActivation struct {
|
||||
Precondition string
|
||||
Condition string
|
||||
Duration float64
|
||||
Cooldown float64
|
||||
Abilities [3]SkillAbility
|
||||
}
|
||||
|
||||
type SkillAbility struct {
|
||||
Type int
|
||||
ValueUsage int
|
||||
Value float64
|
||||
Target int
|
||||
TargetValue int
|
||||
}
|
||||
|
||||
func Skills(ctx context.Context, db *sqlitex.Pool) ([]Skill, error) {
|
||||
conn, err := db.Take(ctx)
|
||||
defer db.Put(conn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't get connection for skills: %w", err)
|
||||
}
|
||||
stmt, _, err := conn.PrepareTransient(skillSQL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't prepare statement for skills: %w", err)
|
||||
}
|
||||
defer stmt.Finalize()
|
||||
|
||||
var r []Skill
|
||||
for {
|
||||
ok, err := stmt.Step()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error stepping skills: %w", err)
|
||||
}
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
s := Skill{
|
||||
ID: stmt.ColumnInt(0),
|
||||
Name: stmt.ColumnText(1),
|
||||
Description: stmt.ColumnText(2),
|
||||
GroupID: stmt.ColumnInt(3),
|
||||
GroupName: stmt.ColumnText(4),
|
||||
Rarity: stmt.ColumnInt(5),
|
||||
GroupRate: stmt.ColumnInt(6),
|
||||
GradeValue: stmt.ColumnInt(7),
|
||||
WitCheck: stmt.ColumnInt(8) != 0,
|
||||
Activations: [2]SkillActivation{
|
||||
{
|
||||
Precondition: stmt.ColumnText(9),
|
||||
Condition: stmt.ColumnText(10),
|
||||
Duration: stmt.ColumnFloat(11),
|
||||
Cooldown: stmt.ColumnFloat(12),
|
||||
Abilities: [3]SkillAbility{
|
||||
{
|
||||
Type: stmt.ColumnInt(13),
|
||||
ValueUsage: stmt.ColumnInt(14),
|
||||
Value: stmt.ColumnFloat(15),
|
||||
Target: stmt.ColumnInt(16),
|
||||
TargetValue: stmt.ColumnInt(17),
|
||||
},
|
||||
{
|
||||
Type: stmt.ColumnInt(18),
|
||||
ValueUsage: stmt.ColumnInt(19),
|
||||
Value: stmt.ColumnFloat(20),
|
||||
Target: stmt.ColumnInt(21),
|
||||
TargetValue: stmt.ColumnInt(22),
|
||||
},
|
||||
{
|
||||
Type: stmt.ColumnInt(23),
|
||||
ValueUsage: stmt.ColumnInt(24),
|
||||
Value: stmt.ColumnFloat(25),
|
||||
Target: stmt.ColumnInt(26),
|
||||
TargetValue: stmt.ColumnInt(27),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Precondition: stmt.ColumnText(28),
|
||||
Condition: stmt.ColumnText(29),
|
||||
Duration: stmt.ColumnFloat(30),
|
||||
Cooldown: stmt.ColumnFloat(31),
|
||||
Abilities: [3]SkillAbility{
|
||||
{
|
||||
Type: stmt.ColumnInt(32),
|
||||
ValueUsage: stmt.ColumnInt(33),
|
||||
Value: stmt.ColumnFloat(34),
|
||||
Target: stmt.ColumnInt(35),
|
||||
TargetValue: stmt.ColumnInt(36),
|
||||
},
|
||||
{
|
||||
Type: stmt.ColumnInt(37),
|
||||
ValueUsage: stmt.ColumnInt(38),
|
||||
Value: stmt.ColumnFloat(39),
|
||||
Target: stmt.ColumnInt(40),
|
||||
TargetValue: stmt.ColumnInt(41),
|
||||
},
|
||||
{
|
||||
Type: stmt.ColumnInt(42),
|
||||
ValueUsage: stmt.ColumnInt(43),
|
||||
Value: stmt.ColumnFloat(44),
|
||||
Target: stmt.ColumnInt(45),
|
||||
TargetValue: stmt.ColumnInt(46),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IconID: stmt.ColumnInt(47),
|
||||
Index: stmt.ColumnInt(48),
|
||||
}
|
||||
r = append(r, s)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ func main() {
|
||||
pairs []AffinityRelation
|
||||
trios []AffinityRelation
|
||||
sg []NamedID[SkillGroup]
|
||||
skills []Skill
|
||||
)
|
||||
eg.Go(func() error {
|
||||
slog.Info("get characters")
|
||||
@@ -72,6 +73,12 @@ func main() {
|
||||
sg = r
|
||||
return err
|
||||
})
|
||||
eg.Go(func() error {
|
||||
slog.Info("get skills")
|
||||
r, err := Skills(ctx, db)
|
||||
skills = r
|
||||
return err
|
||||
})
|
||||
if err := eg.Wait(); err != nil {
|
||||
slog.Error("load", slog.Any("err", err))
|
||||
os.Exit(1)
|
||||
@@ -92,7 +99,15 @@ func main() {
|
||||
return err
|
||||
}
|
||||
slog.Info("write skills")
|
||||
return ExecSkillKK(t, sf, sg)
|
||||
return ExecSkillKK(t, sf, sg, skills)
|
||||
})
|
||||
eg.Go(func() error {
|
||||
sf, err := os.Create(filepath.Join(out, "skill-group.kk"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
slog.Info("write skill groups")
|
||||
return ExecSkillGroupKK(t, sf, sg, skills)
|
||||
})
|
||||
if err := eg.Wait(); err != nil {
|
||||
slog.Error("generate", slog.Any("err", err))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{{ define "koka-skill" -}}
|
||||
module horse/skill
|
||||
{{- define "koka-skill-group" -}}
|
||||
module horse/skill-group
|
||||
|
||||
// Automatically generated with the horsegen tool; DO NOT EDIT
|
||||
// Automatically generated with horsegen; DO NOT EDIT
|
||||
|
||||
// Skill groups.
|
||||
// A skill group may contain white, circle, double-circle, gold, and purple skills
|
||||
@@ -27,7 +27,7 @@ pub fip(1) fun skill-group/from-id(^id: int): maybe<skill-group>
|
||||
{{- end }}
|
||||
_ -> Nothing
|
||||
|
||||
// Get names for skill groups.
|
||||
// Get the name for a skill group.
|
||||
// Skill group names are the name of the base skill in the group.
|
||||
pub fun skill-group/show(sg: skill-group): string
|
||||
match sg
|
||||
@@ -45,4 +45,291 @@ pub fip fun skill-group/order2(a: skill-group, b: skill-group): order2<skill-gro
|
||||
pub fun skill-group/(==)(a: skill-group, b: skill-group): bool
|
||||
a.group-id == b.group-id
|
||||
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "koka-skill" -}}
|
||||
module horse/skill
|
||||
|
||||
import std/num/float64
|
||||
pub import horse/skill-group
|
||||
|
||||
// Skills instances.
|
||||
pub type skill
|
||||
{{- range $s := $.Skills }}
|
||||
{{ kkenum $s.Name }}
|
||||
{{- end }}
|
||||
|
||||
// Map a skill to its ID.
|
||||
pub fip fun skill/skill-id(^s: skill): int
|
||||
match s
|
||||
{{- range $s := $.Skills }}
|
||||
{{ kkenum $s.Name }} -> {{ $s.ID }}
|
||||
{{- end }}
|
||||
|
||||
// Get the skill for an ID.
|
||||
pub fip(1) fun skill/from-id(^id: int): maybe<skill>
|
||||
match id
|
||||
{{- range $s := $.Skills }}
|
||||
{{ $s.ID }} -> Just( {{- kkenum $s.Name -}} )
|
||||
{{- end }}
|
||||
_ -> Nothing
|
||||
|
||||
// Get the name of a skill.
|
||||
pub fun skill/show(s: skill): string
|
||||
match s
|
||||
{{- range $s := $.Skills }}
|
||||
{{ kkenum $s.Name }} -> {{ printf "%q" $s.Name }}
|
||||
{{- end }}
|
||||
|
||||
// Compare two skills by ID order.
|
||||
pub fip fun skill/order2(a: skill, b: skill): order2<skill>
|
||||
match cmp(a.skill-id, b.skill-id)
|
||||
Lt -> Lt2(a, b)
|
||||
Eq -> Eq2(a)
|
||||
Gt -> Gt2(a, b)
|
||||
|
||||
pub fun skill/(==)(a: skill, b: skill): bool
|
||||
a.skill-id == b.skill-id
|
||||
|
||||
// Get complete skill info.
|
||||
pub fun skill/detail(^s: skill): skill-detail
|
||||
match s
|
||||
{{- range $s := $.Skills }}
|
||||
{{ kkenum $s.Name }} -> {{ template "kk-render-skill-detail" $s }}
|
||||
{{- end }}
|
||||
|
||||
// Details about a skill.
|
||||
pub struct skill-detail
|
||||
skill-id: int
|
||||
name: string
|
||||
description: string
|
||||
group: skill-group
|
||||
rarity: rarity
|
||||
group-rate: int
|
||||
grade-value: int
|
||||
wit-check: bool
|
||||
activations: list<activation>
|
||||
icon-id: int
|
||||
|
||||
// Automatically generated.
|
||||
// Shows a string representation of the `skill-detail` type.
|
||||
pub fun skill-detail/show(this : skill-detail) : e string
|
||||
match this
|
||||
Skill-detail(skill-id, name, description, group, rarity, group-rate, grade-value, wit-check, activations, icon-id) -> "Skill-detail(skill-id: " ++ skill-id.show ++ ", name: " ++ name.show ++ ", description: " ++ description.show ++ ", group: " ++ group.show ++ ", rarity: " ++ rarity.show ++ ", group-rate: " ++ group-rate.show ++ ", grade-value: " ++ grade-value.show ++ ", wit-check: " ++ wit-check.show ++ ", activations: " ++ activations.show ++ ", icon-id: " ++ icon-id.show ++ ")"
|
||||
|
||||
// Skill rarity.
|
||||
pub type rarity
|
||||
Common // white
|
||||
Rare // gold
|
||||
Unique-Low // 1*/2* unique
|
||||
Unique-Upgraded // 3*+ unique on a trainee upgraded from 1*/2*
|
||||
Unique // base 3* unique
|
||||
|
||||
pub fun rarity/show(r: rarity): string
|
||||
match r
|
||||
Common -> "Common"
|
||||
Rare -> "Rare"
|
||||
Unique-Low -> "Unique (1☆/2☆)"
|
||||
Unique-Upgraded -> "Unique (3☆+ from 1☆/2☆ upgraded)"
|
||||
Unique -> "Unique (3☆+)"
|
||||
|
||||
// Condition and precondition logic.
|
||||
pub alias condition = string
|
||||
|
||||
// Activation conditions and effects.
|
||||
// A skill has one or two activations.
|
||||
pub struct activation
|
||||
precondition: condition
|
||||
condition: condition
|
||||
duration: float64 // seconds
|
||||
cooldown: float64 // seconds
|
||||
abilities: list<ability> // one to three elements
|
||||
|
||||
pub fun activation/show(a: activation): string
|
||||
match a
|
||||
Activation("", condition, -1.0, _, abilities) -> condition ++ " -> " ++ abilities.show
|
||||
Activation("", condition, duration, cooldown, abilities) | cooldown >= 500.0 -> condition ++ " -> " ++ abilities.show ++ " for " ++ duration.show ++ "s"
|
||||
Activation("", condition, duration, cooldown, abilities) -> condition ++ " -> " ++ abilities.show ++ " for " ++ duration.show ++ "s on " ++ cooldown.show ++ "s cooldown"
|
||||
Activation(precondition, condition, -1.0, _, abilities)-> precondition ++ " -> " ++ condition ++ " -> " ++ abilities.show
|
||||
Activation(precondition, condition, duration, cooldown, abilities) | cooldown >= 500.0 -> precondition ++ " -> " ++ condition ++ " -> " ++ abilities.show ++ " for " ++ duration.show ++ "s"
|
||||
Activation(precondition, condition, duration, cooldown, abilities) -> precondition ++ "-> " ++ condition ++ " -> " ++ abilities.show ++ " for " ++ duration.show ++ "s on " ++ cooldown.show ++ "s cooldown"
|
||||
|
||||
// Effects of activating a skill.
|
||||
pub struct ability
|
||||
ability-type: ability-type
|
||||
value-usage: value-usage
|
||||
target: target
|
||||
|
||||
pub fun ability/show(a: ability): string
|
||||
match a
|
||||
Ability(t, Direct, Self) -> t.show
|
||||
Ability(t, Direct, target) -> t.show ++ " " ++ target.show
|
||||
Ability(t, v, Self) -> t.show ++ " scaling by " ++ v.show
|
||||
Ability(t, v, target) -> t.show ++ " " ++ target.show ++ " scaling by " ++ v.show
|
||||
|
||||
// Target of a skill activation effect.
|
||||
pub type ability-type
|
||||
Passive-Speed(bonus: float64)
|
||||
Passive-Stamina(bonus: float64)
|
||||
Passive-Power(bonus: float64)
|
||||
Passive-Guts(bonus: float64)
|
||||
Passive-Wit(bonus: float64)
|
||||
Runaway
|
||||
Vision(bonus: float64)
|
||||
HP(rate: float64)
|
||||
Gate-Delay(rate: float64)
|
||||
Frenzy(add: float64)
|
||||
Current-Speed(rate: float64)
|
||||
Target-Speed(rate: float64)
|
||||
Lane-Speed(rate: float64)
|
||||
Accel(rate: float64)
|
||||
Lane-Change(rate: float64)
|
||||
|
||||
pub fun ability-type/show(a: ability-type): string
|
||||
match a
|
||||
Passive-Speed(bonus) -> "passive " ++ bonus.show ++ " Speed"
|
||||
Passive-Stamina(bonus) -> "passive " ++ bonus.show ++ " Stamina"
|
||||
Passive-Power(bonus) -> "passive " ++ bonus.show ++ " Power"
|
||||
Passive-Guts(bonus) -> "passive " ++ bonus.show ++ " Guts"
|
||||
Passive-Wit(bonus) -> "passive " ++ bonus.show ++ " Wit"
|
||||
Runaway -> "enable Great Escape style"
|
||||
Vision(bonus) -> bonus.show ++ " vision"
|
||||
HP(rate) | rate >= 0.0 -> show(rate * 100.0) ++ "% HP recovery"
|
||||
HP(rate) -> show(rate * 100.0) ++ "% HP loss"
|
||||
Gate-Delay(rate) -> rate.show ++ "× gate delay"
|
||||
Frenzy(add) -> add.show ++ "s longer Rushed"
|
||||
Current-Speed(rate) -> show(rate * 100.0) ++ "% current speed"
|
||||
Target-Speed(rate) -> show(rate * 100.0) ++ "% target speed"
|
||||
Lane-Speed(rate) -> show(rate * 100.0) ++ "% lane speed"
|
||||
Accel(rate) -> show(rate * 100.0) ++ "% acceleration"
|
||||
Lane-Change(rate) -> rate.show ++ " course width movement"
|
||||
|
||||
// Special scaling for skill activation effects.
|
||||
pub type value-usage
|
||||
Direct
|
||||
Team-Speed
|
||||
Team-Stamina
|
||||
Team-Power
|
||||
Team-Guts
|
||||
Team-Wit
|
||||
Multiply-Random
|
||||
|
||||
pub fun value-usage/show(v: value-usage): string
|
||||
match v
|
||||
Direct -> "no scaling"
|
||||
Team-Speed -> "team's Speed"
|
||||
Team-Stamina -> "team's Stamina"
|
||||
Team-Power -> "team's Power"
|
||||
Team-Guts -> "team's Guts"
|
||||
Team-Wit -> "team's Wit"
|
||||
Multiply-Random -> "random multiplier (0× to 0.04×)"
|
||||
|
||||
// Who a skill activation targets.
|
||||
pub type target
|
||||
Self
|
||||
In-View
|
||||
Ahead(limit: int)
|
||||
Behind(limit: int)
|
||||
Style(style: style)
|
||||
Rushing-Ahead(limit: int)
|
||||
Rushing-Behind(limit: int)
|
||||
Rushing-Style(style: style)
|
||||
|
||||
pub fun target/show(t: target): string
|
||||
match t
|
||||
Self -> "self"
|
||||
In-View -> "others in field of view"
|
||||
Ahead(limit) | limit >= 18 -> "others ahead"
|
||||
Ahead(limit) -> "next " ++ limit.show ++ " others ahead"
|
||||
Behind(limit) | limit >= 18 -> "others behind"
|
||||
Behind(limit) -> "next " ++ limit.show ++ " others behind"
|
||||
Style(Front-Runner) -> "other Front Runners"
|
||||
Style(Pace-Chaser) -> "other Pace Chasers"
|
||||
Style(Late-Surger) -> "other Late Surgers"
|
||||
Style(End-Closer) -> "other End Closers"
|
||||
Rushing-Ahead(limit) | limit >= 18 -> "others rushing ahead"
|
||||
Rushing-Ahead(limit) -> "next " ++ limit.show ++ " others rushing ahead"
|
||||
Rushing-Behind(limit) | limit >= 18 -> "others rushing behind"
|
||||
Rushing-Behind(limit) -> "next " ++ limit.show ++ " others rushing behind"
|
||||
Rushing-Style(Front-Runner) -> "rushing Front Runners"
|
||||
Rushing-Style(Pace-Chaser) -> "rushing Pace Chasers"
|
||||
Rushing-Style(Late-Surger) -> "rushing Late Surgers"
|
||||
Rushing-Style(End-Closer) -> "rushing End Closers"
|
||||
|
||||
// Running style for skill targets.
|
||||
// TODO(zeph): there is definitely a better place for this to live
|
||||
pub type style
|
||||
Front-Runner
|
||||
Pace-Chaser
|
||||
Late-Surger
|
||||
End-Closer
|
||||
|
||||
{{- end -}}
|
||||
|
||||
{{ define "kk-render-skill-detail" }}
|
||||
{{- /* Call with Skill structure as argument. */ -}}
|
||||
Skill-detail(skill-id = {{ $.ID -}}
|
||||
, name = {{ printf "%q" $.Name -}}
|
||||
, description = {{ printf "%q" $.Description -}}
|
||||
, group = {{ kkenum $.GroupName -}}
|
||||
, rarity = {{ if eq $.Rarity 1 }}Common{{ else if eq $.Rarity 2 }}Rare{{ else if eq $.Rarity 3 }}Unique-Low{{ else if eq $.Rarity 4 }}Unique-Upgraded{{ else if eq $.Rarity 5 }}Unique{{ else }}??? $.Rarity={{ $.Rarity }}{{ end -}}
|
||||
, group-rate = {{ $.GroupRate -}}
|
||||
, grade-value = {{ $.GradeValue -}}
|
||||
, wit-check = {{ if $.WitCheck }}True{{ else }}False{{ end -}}
|
||||
, activations = [
|
||||
{{- range $a := $.Activations -}}
|
||||
{{- if ne $a.Condition "" -}}
|
||||
Activation(precondition = {{ printf "%q" $a.Precondition -}}
|
||||
, condition = {{ printf "%q" $a.Condition -}}
|
||||
, duration = {{ printf "%f" $a.Duration -}}
|
||||
, cooldown = {{ printf "%f" $a.Cooldown -}}
|
||||
, abilities = [
|
||||
{{- range $abil := $a.Abilities -}}
|
||||
{{- if ne $abil.Type 0 -}}
|
||||
Ability(ability-type =
|
||||
{{- if eq $abil.Type 1 -}}Passive-Speed({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 2 -}}Passive-Stamina({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 3 -}}Passive-Power({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 4 -}}Passive-Guts({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 5 -}}Passive-Wit({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 6 -}}Runaway
|
||||
{{- else if eq $abil.Type 8 -}}Vision({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 9 -}}HP({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 10 -}}Gate-Delay({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 13 -}}Frenzy({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 21 -}}Current-Speed({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 27 -}}Target-Speed({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 28 -}}Lane-Speed({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 31 -}}Accel({{ printf "%f" $abil.Value }})
|
||||
{{- else if eq $abil.Type 35 -}}Lane-Change({{ printf "%f" $abil.Value }})
|
||||
{{- else -}}??? $abil.Type={{$abil.Type}}
|
||||
{{- end -}}
|
||||
, value-usage =
|
||||
{{- if eq $abil.ValueUsage 1 -}}Direct
|
||||
{{- else if eq $abil.ValueUsage 3 -}}Team-Speed
|
||||
{{- else if eq $abil.ValueUsage 4 -}}Team-Stamina
|
||||
{{- else if eq $abil.ValueUsage 5 -}}Team-Power
|
||||
{{- else if eq $abil.ValueUsage 6 -}}Team-Guts
|
||||
{{- else if eq $abil.ValueUsage 7 -}}Team-Wit
|
||||
{{- else if eq $abil.ValueUsage 8 -}}Multiply-Random
|
||||
{{- else -}}??? $abil.ValueUsage={{ $abil.ValueUsage }}
|
||||
{{- end -}}
|
||||
, target =
|
||||
{{- if eq $abil.Target 1 -}}Self
|
||||
{{- else if eq $abil.Target 4 -}}In-View
|
||||
{{- else if eq $abil.Target 9 -}}Ahead({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 10 -}}Behind({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 18 -}}Style({{ if eq $abil.TargetValue 1 }}Front-Runner{{ else if eq $abil.TargetValue 2 }}Pace-Chaser{{ else if eq $abil.TargetValue 3 }}Late-Surger{{ else if eq $abil.TargetValue 4 }}End-Closer{{ else }}??? $abil.TargetValue={{ $abil.TargetValue }}{{ end }})
|
||||
{{- else if eq $abil.Target 19 -}}Rushing-Ahead({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 20 -}}Rushing-Behind({{ $abil.TargetValue }})
|
||||
{{- else if eq $abil.Target 21 -}}Rushing-Style({{ if eq $abil.TargetValue 1 }}Front-Runner{{ else if eq $abil.TargetValue 2 }}Pace-Chaser{{ else if eq $abil.TargetValue 3 }}Late-Surger{{ else if eq $abil.TargetValue 4 }}End-Closer{{ else }}??? $abil.TargetValue={{ $abil.TargetValue }}{{ end }})
|
||||
{{- end -}}
|
||||
),
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
]),
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
], icon-id = {{ $.IconID -}}
|
||||
)
|
||||
{{- end -}}
|
||||
|
||||
69
horsegen/skill.sql
Normal file
69
horsegen/skill.sql
Normal file
@@ -0,0 +1,69 @@
|
||||
WITH skill_names AS (
|
||||
SELECT
|
||||
n."index" AS "id",
|
||||
n."text" AS "name",
|
||||
d."text" AS "description"
|
||||
FROM text_data n
|
||||
JOIN text_data d ON n."index" = d."index" AND n."category" = 47 AND d."category" = 48
|
||||
), skill_groups AS (
|
||||
SELECT
|
||||
group_id,
|
||||
name
|
||||
FROM skill_data d
|
||||
JOIN skill_names n ON d.id = n.id
|
||||
WHERE group_rate = 1
|
||||
)
|
||||
SELECT
|
||||
d.id,
|
||||
n.name,
|
||||
n.description,
|
||||
d.group_id,
|
||||
g.name,
|
||||
d.rarity,
|
||||
d.group_rate,
|
||||
d.grade_value,
|
||||
d.activate_lot,
|
||||
d.precondition_1,
|
||||
d.condition_1,
|
||||
IIF(d.float_ability_time_1 <= 0, CAST(d.float_ability_time_1 AS REAL), d.float_ability_time_1 / 1e4) AS float_ability_time_1,
|
||||
IIF(d.float_cooldown_time_1 <= 0, CAST(d.float_cooldown_time_1 AS REAL), d.float_cooldown_time_1 / 1e4) AS float_cooldown_time_1,
|
||||
d.ability_type_1_1,
|
||||
d.ability_value_usage_1_1,
|
||||
d.float_ability_value_1_1 / 1e4 AS float_ability_value_1_1,
|
||||
d.target_type_1_1,
|
||||
d.target_value_1_1,
|
||||
d.ability_type_1_2,
|
||||
d.ability_value_usage_1_2,
|
||||
d.float_ability_value_1_2 / 1e4 AS float_ability_value_1_2,
|
||||
d.target_type_1_2,
|
||||
d.target_value_1_2,
|
||||
d.ability_type_1_3,
|
||||
d.ability_value_usage_1_3,
|
||||
d.float_ability_value_1_3 / 1e4 AS float_ability_value_1_3,
|
||||
d.target_type_1_3,
|
||||
d.target_value_1_3,
|
||||
d.precondition_2,
|
||||
d.condition_2,
|
||||
IIF(d.float_ability_time_2 <= 0, CAST(d.float_ability_time_2 AS REAL), d.float_ability_time_2 / 1e4) AS float_ability_time_2,
|
||||
IIF(d.float_cooldown_time_2 <= 0, CAST(d.float_cooldown_time_2 AS REAL), d.float_cooldown_time_2 / 1e4) AS float_cooldown_time_2,
|
||||
d.ability_type_2_1,
|
||||
d.ability_value_usage_2_1,
|
||||
d.float_ability_value_2_1 / 1e4 AS float_ability_value_2_1,
|
||||
d.target_type_2_1,
|
||||
d.target_value_2_1,
|
||||
d.ability_type_2_2,
|
||||
d.ability_value_usage_2_2,
|
||||
d.float_ability_value_2_2 / 1e4 AS float_ability_value_2_2,
|
||||
d.target_type_2_2,
|
||||
d.target_value_2_2,
|
||||
d.ability_type_2_3,
|
||||
d.ability_value_usage_2_3,
|
||||
d.float_ability_value_2_3 / 1e4 AS float_ability_value_2_3,
|
||||
d.target_type_2_3,
|
||||
d.target_value_2_3,
|
||||
d.icon_id,
|
||||
ROW_NUMBER() OVER (ORDER BY d.id) - 1 AS "index"
|
||||
FROM skill_data d
|
||||
JOIN skill_names n ON d.id = n.id
|
||||
JOIN skill_groups g ON d.group_id = g.group_id
|
||||
ORDER BY d.id
|
||||
Reference in New Issue
Block a user