horsegen: generate sparks
This commit is contained in:
@@ -138,6 +138,22 @@ func ExecScenario(t *template.Template, region string, kk, g io.Writer, scen []S
|
||||
return err
|
||||
}
|
||||
|
||||
func ExecSparks(t *template.Template, region string, kk, g io.Writer, sparks []Spark, effects map[int]map[int][]SparkEffect) error {
|
||||
data := struct {
|
||||
Region string
|
||||
Sparks []Spark
|
||||
SparkEffects map[int]map[int][]SparkEffect
|
||||
}{region, sparks, effects}
|
||||
var err error
|
||||
if kk != nil {
|
||||
err = errors.Join(err, t.ExecuteTemplate(kk, "koka-spark", &data))
|
||||
}
|
||||
if g != nil {
|
||||
err = errors.Join(err, t.ExecuteTemplate(g, "go-spark", &data))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
const wordSeps = " ,!?/-+();#○☆♡'=♪∀゚∴"
|
||||
|
||||
var (
|
||||
|
||||
@@ -32,6 +32,12 @@ var saddleSQL string
|
||||
//go:embed scenario.sql
|
||||
var scenarioSQL string
|
||||
|
||||
//go:embed spark.sql
|
||||
var sparkSQL string
|
||||
|
||||
//go:embed spark-effect.sql
|
||||
var sparkEffectSQL string
|
||||
|
||||
type (
|
||||
Character struct{}
|
||||
SkillGroup struct{}
|
||||
@@ -447,3 +453,88 @@ func Scenarios(ctx context.Context, db *sqlitex.Pool) ([]Scenario, error) {
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
type Spark struct {
|
||||
ID int
|
||||
Name string
|
||||
Description string
|
||||
Group int
|
||||
Rarity int
|
||||
Type int
|
||||
}
|
||||
|
||||
type SparkEffect struct {
|
||||
Target int
|
||||
Value1 int
|
||||
Value2 int
|
||||
}
|
||||
|
||||
func Sparks(ctx context.Context, db *sqlitex.Pool) ([]Spark, error) {
|
||||
conn, err := db.Take(ctx)
|
||||
defer db.Put(conn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't get connection for sparks: %w", err)
|
||||
}
|
||||
stmt, _, err := conn.PrepareTransient(sparkSQL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't prepare statement for sparks: %w", err)
|
||||
}
|
||||
defer stmt.Finalize()
|
||||
|
||||
var r []Spark
|
||||
for {
|
||||
ok, err := stmt.Step()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error stepping sparks: %w", err)
|
||||
}
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
s := Spark{
|
||||
ID: stmt.ColumnInt(0),
|
||||
Name: stmt.ColumnText(1),
|
||||
Description: stmt.ColumnText(2),
|
||||
Group: stmt.ColumnInt(3),
|
||||
Rarity: stmt.ColumnInt(4),
|
||||
Type: stmt.ColumnInt(5),
|
||||
}
|
||||
r = append(r, s)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func SparkEffects(ctx context.Context, db *sqlitex.Pool) (map[int]map[int][]SparkEffect, error) {
|
||||
conn, err := db.Take(ctx)
|
||||
defer db.Put(conn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't get connection for spark effects: %w", err)
|
||||
}
|
||||
stmt, _, err := conn.PrepareTransient(sparkEffectSQL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't prepare statement for spark effects: %w", err)
|
||||
}
|
||||
defer stmt.Finalize()
|
||||
|
||||
r := make(map[int]map[int][]SparkEffect)
|
||||
for {
|
||||
ok, err := stmt.Step()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error stepping spark effects: %w", err)
|
||||
}
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
group := stmt.ColumnInt(0)
|
||||
eff := stmt.ColumnInt(1)
|
||||
s := SparkEffect{
|
||||
Target: stmt.ColumnInt(2),
|
||||
Value1: stmt.ColumnInt(3),
|
||||
Value2: stmt.ColumnInt(4),
|
||||
}
|
||||
if r[group] == nil {
|
||||
r[group] = make(map[int][]SparkEffect)
|
||||
}
|
||||
r[group][eff] = append(r[group][eff], s)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@@ -45,14 +45,16 @@ func main() {
|
||||
|
||||
eg, ctx := errgroup.WithContext(pctx)
|
||||
var (
|
||||
charas []NamedID[Character]
|
||||
pairs []AffinityRelation
|
||||
trios []AffinityRelation
|
||||
sg []NamedID[SkillGroup]
|
||||
skills []Skill
|
||||
races []Race
|
||||
saddles []Saddle
|
||||
scens []Scenario
|
||||
charas []NamedID[Character]
|
||||
pairs []AffinityRelation
|
||||
trios []AffinityRelation
|
||||
sg []NamedID[SkillGroup]
|
||||
skills []Skill
|
||||
races []Race
|
||||
saddles []Saddle
|
||||
scens []Scenario
|
||||
sparks []Spark
|
||||
sparkeff map[int]map[int][]SparkEffect
|
||||
)
|
||||
eg.Go(func() error {
|
||||
slog.Info("get characters")
|
||||
@@ -102,6 +104,18 @@ func main() {
|
||||
scens = r
|
||||
return err
|
||||
})
|
||||
eg.Go(func() error {
|
||||
slog.Info("get sparks")
|
||||
r, err := Sparks(ctx, db)
|
||||
sparks = r
|
||||
return err
|
||||
})
|
||||
eg.Go(func() error {
|
||||
slog.Info("get spark effects")
|
||||
r, err := SparkEffects(ctx, db)
|
||||
sparkeff = r
|
||||
return err
|
||||
})
|
||||
if err := eg.Wait(); err != nil {
|
||||
slog.Error("load", slog.Any("err", err))
|
||||
os.Exit(1)
|
||||
@@ -173,6 +187,18 @@ func main() {
|
||||
slog.Info("write scenarios")
|
||||
return ExecScenario(t, region, kf, gf, scens)
|
||||
})
|
||||
eg.Go(func() error {
|
||||
kf, err := os.Create(filepath.Join(out, region, "spark.kk"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gf, err := os.Create(filepath.Join(out, region, "spark.go"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
slog.Info("write sparks")
|
||||
return ExecSparks(t, region, kf, gf, sparks, sparkeff)
|
||||
})
|
||||
if err := eg.Wait(); err != nil {
|
||||
slog.Error("generate", slog.Any("err", err))
|
||||
os.Exit(1)
|
||||
|
||||
9
horsegen/spark-effect.sql
Normal file
9
horsegen/spark-effect.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
SELECT
|
||||
factor_group_id,
|
||||
effect_id,
|
||||
target_type,
|
||||
value_1,
|
||||
value_2
|
||||
FROM succession_factor_effect
|
||||
WHERE factor_group_id NOT IN (40001) -- exclude Carnival Bonus
|
||||
ORDER BY factor_group_id, effect_id, target_type
|
||||
35
horsegen/spark.go.template
Normal file
35
horsegen/spark.go.template
Normal file
@@ -0,0 +1,35 @@
|
||||
{{- define "go-spark" -}}
|
||||
package {{ $.Region }}
|
||||
|
||||
// Automatically generated with horsegen; DO NOT EDIT
|
||||
|
||||
import . "git.sunturtle.xyz/zephyr/horse/horse"
|
||||
|
||||
const (
|
||||
{{- range $s := $.Sparks }}
|
||||
Spark{{ goenum $s.Name }}Lv{{ $s.Rarity }} SparkID = {{ $s.ID }} // {{ $s.Name }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
var AllSparks = map[SparkID]Spark{
|
||||
{{- range $s := $.Sparks }}
|
||||
Spark{{ goenum $s.Name }}Lv{{ $s.Rarity }}: {
|
||||
ID: {{ $s.ID }},
|
||||
Name: {{ printf "%q" $s.Name }},
|
||||
Description: {{ printf "%q" $s.Description }},
|
||||
Group: {{ $s.Group }},
|
||||
Rarity: {{ $s.Rarity }},
|
||||
Type: {{ $s.Type }},
|
||||
Effects: [][]SparkEffect{
|
||||
{{- range $r := index $.SparkEffects $s.Group }}
|
||||
{
|
||||
{{- range $e := $r -}}
|
||||
{ {{- $e.Target }}, {{ $e.Value1 }}, {{ $e.Value2 -}} },
|
||||
{{- end -}}
|
||||
},
|
||||
{{- end }}
|
||||
},
|
||||
},
|
||||
{{- end }}
|
||||
}
|
||||
{{ end }}
|
||||
131
horsegen/spark.kk.template
Normal file
131
horsegen/spark.kk.template
Normal file
@@ -0,0 +1,131 @@
|
||||
{{- define "koka-spark" -}}
|
||||
module horse/{{ $.Region }}/spark
|
||||
|
||||
// Automatically generated with horsegen; DO NOT EDIT
|
||||
|
||||
import horse/game-id
|
||||
pub import horse/spark
|
||||
|
||||
// Enumeration of all sparks for type-safe programming.
|
||||
pub type spark
|
||||
{{- range $s := $.Sparks }}
|
||||
{{ kkenum $s.Name }}-Lv{{ $s.Rarity }}
|
||||
{{- end }}
|
||||
|
||||
// Get the ID for a spark.
|
||||
pub fun spark-id(s: spark): spark-id
|
||||
match s
|
||||
{{- range $s := $.Sparks }}
|
||||
{{ kkenum $s.Name }}-Lv{{ $s.Rarity }} -> Spark-id({{ $s.ID }})
|
||||
{{- end }}
|
||||
|
||||
// List of all sparks in ID order for easy iterating.
|
||||
pub val all = [
|
||||
{{- range $s := $.Sparks }}
|
||||
{{ kkenum $s.Name }}-Lv{{ $s.Rarity }},
|
||||
{{- end }}
|
||||
]
|
||||
|
||||
// Get the name for a spark.
|
||||
// The name does not indicate the spark level.
|
||||
// If no spark matches the ID, the result contains the numeric ID.
|
||||
pub fun show(s: spark-id): string
|
||||
match s.game-id
|
||||
{{- range $s := $.Sparks }}
|
||||
{{ $s.ID }} -> {{ printf "%q" $s.Name }}
|
||||
{{- end }}
|
||||
x -> "spark " ++ x.show
|
||||
|
||||
// Get the description for a spark.
|
||||
// The description does not indicate the spark level.
|
||||
// If no spark matches the ID, the result contains the numeric ID.
|
||||
pub fun description(s: spark-id): string
|
||||
match s.game-id
|
||||
{{- range $s := $.Sparks }}
|
||||
{{ $s.ID }} -> {{ printf "%q" $s.Description }}
|
||||
{{- end }}
|
||||
x -> "spark " ++ x.show
|
||||
|
||||
// Get the spark group ID of a spark.
|
||||
// If no spark matches the ID, the result is an invalid ID.
|
||||
pub fun spark-group(s: spark-id): spark-group-id
|
||||
match s.game-id
|
||||
{{- range $s := $.Sparks }}
|
||||
{{ $s.ID }} -> Spark-group-id({{ $s.Group }})
|
||||
{{- end }}
|
||||
_ -> Spark-group-id(0)
|
||||
|
||||
// Get the rarity (level or star count) of a spark.
|
||||
// If no spark matches the ID, the result is One.
|
||||
pub fun rarity(s: spark-id): rarity
|
||||
match s.game-id
|
||||
{{- range $s := $.Sparks }}
|
||||
{{ $s.ID }} -> {{ if eq $s.Rarity 1 }}One{{ else if eq $s.Rarity 2 }}Two{{ else if eq $s.Rarity 3 }}Three{{ else }}??? $s.Rarity={{ $s.Rarity }}{{ end }}
|
||||
{{- end }}
|
||||
_ -> One
|
||||
|
||||
// Get the type of a spark.
|
||||
// If no spark matches the ID, the result is Stat.
|
||||
pub fun spark-type(s: spark-id): spark-type
|
||||
match s.game-id
|
||||
{{- range $s := $.Sparks }}
|
||||
{{ $s.ID }} -> {{ if eq $s.Type 1 }}Stat
|
||||
{{- else if eq $s.Type 2 }}Aptitude
|
||||
{{- else if eq $s.Type 5 }}Race
|
||||
{{- else if eq $s.Type 4 }}Skill
|
||||
{{- else if eq $s.Type 6 }}Scenario
|
||||
{{- else if eq $s.Type 7 }}Carnival-Bonus
|
||||
{{- else if eq $s.Type 10 }}Surface
|
||||
{{- else if eq $s.Type 8 }}Distance
|
||||
{{- else if eq $s.Type 11 }}Style
|
||||
{{- else if eq $s.Type 9 }}Hidden
|
||||
{{- else if eq $s.Type 3 }}Unique
|
||||
{{- else }}??? $s.Type={{ $s.Type }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
_ -> Stat
|
||||
|
||||
// Get the list of all effects a spark can apply during inheritance.
|
||||
// When a spark procs, a random element is chosen from the list yielded by this
|
||||
// function according to a hidden distribution, then all effects in that are applied.
|
||||
// If no spark matches the ID, the result is the empty list.
|
||||
pub fun effects(s: spark-id): list<list<spark-effect>>
|
||||
match s.game-id
|
||||
{{- range $s := $.Sparks }}
|
||||
{{ $s.ID }} -> [
|
||||
{{- range $r := index $.SparkEffects $s.Group }}
|
||||
[
|
||||
{{- range $e := $r -}}
|
||||
{{- if eq $e.Target 1 -}}Stat-Up(Speed, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 2 -}}Stat-Up(Stamina, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 3 -}}Stat-Up(Power, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 4 -}}Stat-Up(Guts, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 5 -}}Stat-Up(Wit, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 6 -}}SP-Up({{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 7 -}}Random-Stat-Up({{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 11 -}}Aptitude-Up(Turf, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 12 -}}Aptitude-Up(Dirt, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 21 -}}Aptitude-Up(Front-Runner, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 22 -}}Aptitude-Up(Pace-Chaser, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 23 -}}Aptitude-Up(Late-Surger, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 24 -}}Aptitude-Up(End-Closer, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 31 -}}Aptitude-Up(Sprint, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 32 -}}Aptitude-Up(Mile, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 33 -}}Aptitude-Up(Medium, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 34 -}}Aptitude-Up(Long, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 41 -}}Skill-Hint(Skill-id({{ $e.Value1 }}), {{ $e.Value2 }}),
|
||||
{{- else if eq $e.Target 51 -}}Carnival-Bonus {{/*- skipped, but doesn't hurt to put it here -*/}}
|
||||
{{- else if eq $e.Target 61 -}}Stat-Cap-Up(Speed, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 62 -}}Stat-Cap-Up(Stamina, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 63 -}}Stat-Cap-Up(Power, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 64 -}}Stat-Cap-Up(Guts, {{ $e.Value1 }}),
|
||||
{{- else if eq $e.Target 65 -}}Stat-Cap-Up(Wit, {{ $e.Value1 }}),
|
||||
{{- else -}}
|
||||
??? $e.Target={{- $e.Target -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
],
|
||||
{{- end }}
|
||||
]
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
20
horsegen/spark.sql
Normal file
20
horsegen/spark.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
WITH spark AS (
|
||||
SELECT
|
||||
n."index" AS "id",
|
||||
n."text" AS "name",
|
||||
d."text" AS "description"
|
||||
FROM text_data n
|
||||
LEFT JOIN text_data d ON n."index" = d."index" AND d."category" = 172
|
||||
WHERE n.category = 147
|
||||
)
|
||||
SELECT
|
||||
sf.factor_id,
|
||||
spark.name,
|
||||
spark.description,
|
||||
sf.factor_group_id,
|
||||
sf.rarity,
|
||||
sf.factor_type
|
||||
FROM spark
|
||||
JOIN succession_factor sf ON spark.id = sf.factor_id
|
||||
WHERE sf.factor_type != 7 -- exclude Carnival Bonus
|
||||
ORDER BY sf.factor_id
|
||||
Reference in New Issue
Block a user