Files
horse/horsegen/load.go

310 lines
7.1 KiB
Go

package main
import (
"context"
_ "embed"
"fmt"
"zombiezen.com/go/sqlite/sqlitex"
)
//go:embed character.sql
var characterSQL string
//go:embed character.affinity2.sql
var characterAffinity2SQL string
//go:embed character.affinity3.sql
var characterAffinity3SQL string
//go:embed skill-group.sql
var skillGroupSQL string
//go:embed skill.sql
var skillSQL string
type (
Character struct{}
SkillGroup struct{}
)
type NamedID[T any] struct {
// Disallow conversions between NamedID types.
_ [0]*T
ID int
Name string
// For internal use, the index of the identity, when it's needed.
// We don't show this in public API, but it lets us use vectors for lookups.
Index int
}
func Characters(ctx context.Context, db *sqlitex.Pool) ([]NamedID[Character], error) {
conn, err := db.Take(ctx)
defer db.Put(conn)
if err != nil {
return nil, fmt.Errorf("couldn't get connection for characters: %w", err)
}
stmt, _, err := conn.PrepareTransient(characterSQL)
if err != nil {
return nil, fmt.Errorf("couldn't prepare statement for characters: %w", err)
}
defer stmt.Finalize()
var r []NamedID[Character]
for {
ok, err := stmt.Step()
if err != nil {
return nil, fmt.Errorf("error stepping characters: %w", err)
}
if !ok {
break
}
c := NamedID[Character]{
ID: stmt.ColumnInt(0),
Name: stmt.ColumnText(1),
Index: stmt.ColumnInt(2),
}
r = append(r, c)
}
return r, nil
}
type AffinityRelation struct {
IDA int
NameA string
IDB int
NameB string
IDC int
NameC string
Affinity int
}
func CharacterPairs(ctx context.Context, db *sqlitex.Pool) ([]AffinityRelation, error) {
conn, err := db.Take(ctx)
defer db.Put(conn)
if err != nil {
return nil, fmt.Errorf("couldn't get connection for character pairs: %w", err)
}
stmt, _, err := conn.PrepareTransient(characterAffinity2SQL)
if err != nil {
return nil, fmt.Errorf("couldn't prepare statement for character pairs: %w", err)
}
defer stmt.Finalize()
var r []AffinityRelation
for {
ok, err := stmt.Step()
if err != nil {
return nil, fmt.Errorf("error stepping character pairs: %w", err)
}
if !ok {
break
}
p := AffinityRelation{
IDA: stmt.ColumnInt(0),
NameA: stmt.ColumnText(1),
IDB: stmt.ColumnInt(2),
NameB: stmt.ColumnText(3),
Affinity: stmt.ColumnInt(4),
}
r = append(r, p)
}
return r, nil
}
func CharacterTrios(ctx context.Context, db *sqlitex.Pool) ([]AffinityRelation, error) {
conn, err := db.Take(ctx)
defer db.Put(conn)
if err != nil {
return nil, fmt.Errorf("couldn't get connection for character trios: %w", err)
}
stmt, _, err := conn.PrepareTransient(characterAffinity3SQL)
if err != nil {
return nil, fmt.Errorf("couldn't prepare statement for character trios: %w", err)
}
defer stmt.Finalize()
var r []AffinityRelation
for {
ok, err := stmt.Step()
if err != nil {
return nil, fmt.Errorf("error stepping character trios: %w", err)
}
if !ok {
break
}
p := AffinityRelation{
IDA: stmt.ColumnInt(0),
NameA: stmt.ColumnText(1),
IDB: stmt.ColumnInt(2),
NameB: stmt.ColumnText(3),
IDC: stmt.ColumnInt(4),
NameC: stmt.ColumnText(5),
Affinity: stmt.ColumnInt(6),
}
r = append(r, p)
}
return r, nil
}
func SkillGroups(ctx context.Context, db *sqlitex.Pool) ([]NamedID[SkillGroup], error) {
conn, err := db.Take(ctx)
defer db.Put(conn)
if err != nil {
return nil, fmt.Errorf("couldn't get connection for skill groups: %w", err)
}
stmt, _, err := conn.PrepareTransient(skillGroupSQL)
if err != nil {
return nil, fmt.Errorf("couldn't prepare statement for skill groups: %w", err)
}
defer stmt.Finalize()
var r []NamedID[SkillGroup]
for {
ok, err := stmt.Step()
if err != nil {
return nil, fmt.Errorf("error stepping skill groups: %w", err)
}
if !ok {
break
}
g := NamedID[SkillGroup]{
ID: stmt.ColumnInt(0),
Name: stmt.ColumnText(1),
}
r = append(r, g)
}
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
}