310 lines
7.1 KiB
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
|
|
}
|