horsegen: generate scenarios since sparks use them

This commit is contained in:
2026-02-10 21:04:12 -05:00
parent c00d3d0186
commit 8fb29a953c
12 changed files with 243 additions and 129 deletions

View File

@@ -123,6 +123,21 @@ func ExecSaddle(t *template.Template, region string, kk, g io.Writer, saddles []
return err
}
func ExecScenario(t *template.Template, region string, kk, g io.Writer, scen []Scenario) error {
data := struct {
Region string
Scenarios []Scenario
}{region, scen}
var err error
if kk != nil {
err = errors.Join(err, t.ExecuteTemplate(kk, "koka-scenario", &data))
}
if g != nil {
err = errors.Join(err, t.ExecuteTemplate(g, "go-scenario", &data))
}
return err
}
const wordSeps = " ,!?/-+();#○☆♡'=♪∀゚∴"
var (

View File

@@ -29,6 +29,9 @@ var raceSQL string
//go:embed saddle.sql
var saddleSQL string
//go:embed scenario.sql
var scenarioSQL string
type (
Character struct{}
SkillGroup struct{}
@@ -407,3 +410,40 @@ func Saddles(ctx context.Context, db *sqlitex.Pool) ([]Saddle, error) {
}
return r, nil
}
type Scenario struct {
ID int
Name string
Title string
}
func Scenarios(ctx context.Context, db *sqlitex.Pool) ([]Scenario, error) {
conn, err := db.Take(ctx)
defer db.Put(conn)
if err != nil {
return nil, fmt.Errorf("couldn't get connection for scenario: %w", err)
}
stmt, _, err := conn.PrepareTransient(scenarioSQL)
if err != nil {
return nil, fmt.Errorf("couldn't prepare statement for scenario: %w", err)
}
defer stmt.Finalize()
var r []Scenario
for {
ok, err := stmt.Step()
if err != nil {
return nil, fmt.Errorf("error stepping scenarios: %w", err)
}
if !ok {
break
}
s := Scenario{
ID: stmt.ColumnInt(0),
Name: stmt.ColumnText(1),
Title: stmt.ColumnText(2),
}
r = append(r, s)
}
return r, nil
}

View File

@@ -52,6 +52,7 @@ func main() {
skills []Skill
races []Race
saddles []Saddle
scens []Scenario
)
eg.Go(func() error {
slog.Info("get characters")
@@ -91,8 +92,14 @@ func main() {
})
eg.Go(func() error {
slog.Info("get saddles")
s, err := Saddles(ctx, db)
saddles = s
r, err := Saddles(ctx, db)
saddles = r
return err
})
eg.Go(func() error {
slog.Info("get scenarios")
r, err := Scenarios(ctx, db)
scens = r
return err
})
if err := eg.Wait(); err != nil {
@@ -154,6 +161,18 @@ func main() {
slog.Info("write saddles")
return ExecSaddle(t, region, kf, gf, saddles)
})
eg.Go(func() error {
kf, err := os.Create(filepath.Join(out, region, "scenario.kk"))
if err != nil {
return err
}
gf, err := os.Create(filepath.Join(out, region, "scenario.go"))
if err != nil {
return err
}
slog.Info("write scenarios")
return ExecScenario(t, region, kf, gf, scens)
})
if err := eg.Wait(); err != nil {
slog.Error("generate", slog.Any("err", err))
os.Exit(1)

View File

@@ -0,0 +1,23 @@
{{- define "go-scenario" -}}
package {{ $.Region }}
// Automatically generated with horsegen; DO NOT EDIT
import . "git.sunturtle.xyz/zephyr/horse/horse"
const (
{{- range $s := $.Scenarios }}
Scenario{{ goenum $s.Name }} ScenarioID = {{ $s.ID }} // {{ $s.Name }}
{{- end }}
)
var AllScenarios = map[ScenarioID]Scenario{
{{- range $s := $.Scenarios }}
Scenario{{ goenum $s.Name }}: {
ID: {{ $s.ID }},
Name: {{ printf "%q" $s.Name }},
Title: {{ printf "%q" $s.Title }},
},
{{- end }}
}
{{ end }}

View File

@@ -0,0 +1,45 @@
{{- define "koka-scenario" -}}
module horse/{{ $.Region }}/scenario
// Automatically generated with horsegen; DO NOT EDIT
import horse/game-id
// Enumeration of all scenarios for type-safe programming.
pub type scenario
{{- range $s := $.Scenarios }}
{{ kkenum $s.Name }}
{{- end }}
// Get the scenario ID for a scenario.
pub fun scenario-id(s: scenario): scenario-id
match s
{{- range $s := $.Scenarios }}
{{ kkenum $s.Name }} -> Scenario-id({{ $s.ID }})
{{- end }}
// List of all scenarios in ID order for easy iterating.
pub val all = [
{{- range $s := $.Scenarios }}
{{ kkenum $s.Name }},
{{- end }}
]
// Get the name for a scenario.
// If no scenario matches the ID, the result contains the numeric ID.
pub fun show(s: scenario-id): string
match s.game-id
{{- range $s := $.Scenarios }}
{{ $s.ID }} -> {{ printf "%q" $s.Name }}
{{- end }}
x -> "scenario " ++ x.show
// Get the full title for a scenario, e.g. "The Beginning: URA Finale".
// If no scenario matches the ID, the result contains the numeric ID.
pub fun title(s: scenario-id): string
match s.game-id
{{- range $s := $.Scenarios }}
{{ $s.ID }} -> {{ printf "%q" $s.Title }}
{{- end }}
x -> "scenario " ++ x.show
{{ end }}

17
horsegen/scenario.sql Normal file
View File

@@ -0,0 +1,17 @@
WITH scenario_name AS (
SELECT "index" AS id, "text" AS name
FROM text_data
WHERE category = 237
), scenario_title AS (
SELECT "index" AS id, "text" AS title
FROM text_data
WHERE category = 119
)
SELECT
sc.id,
n.name,
t.title
FROM single_mode_scenario sc
JOIN scenario_name n ON sc.id = n.id
JOIN scenario_title t ON sc.id = t.id
ORDER BY sc.id