Files
horse/mdb/spark.go

94 lines
2.2 KiB
Go

package mdb
import (
"context"
_ "embed"
"zombiezen.com/go/sqlite/sqlitex"
"git.sunturtle.xyz/zephyr/horse"
)
var (
//go:embed sql/spark.sql
sparkSQL string
//go:embed sql/spark-effect.sql
sparkEffectSQL string
)
func Sparks(ctx context.Context, db *sqlitex.Pool) ([]horse.Spark, error) {
// We don't use func load here because we have multiple queries to run.
conn, err := db.Take(ctx)
defer db.Put(conn)
if err != nil {
return nil, err
}
var sp []horse.Spark
{
stmt := conn.Prep(sparkSQL)
for {
ok, err := stmt.Step()
if err != nil {
return nil, err
}
if !ok {
break
}
sp = append(sp, horse.Spark{
ID: horse.SparkID(stmt.ColumnInt(0)),
Name: stmt.ColumnText(1),
Description: stmt.ColumnText(2),
Group: horse.SparkGroupID(stmt.ColumnInt(3)),
Rarity: horse.SparkRarity(stmt.ColumnInt(4)),
Type: horse.SparkType(stmt.ColumnInt(5)),
// Effects filled in later, but we can start with space.
// The vast majority of sparks are skill sparks,
// which have five rolls.
Effects: make([][]horse.SparkEffect, 0, 5),
})
}
}
stmt := conn.Prep(sparkEffectSQL)
cur := sp
last := 0
for {
ok, err := stmt.Step()
if err != nil {
return nil, err
}
if !ok {
break
}
// We sort sparks by group ID first, so we can add effects in a single pass.
group := stmt.ColumnInt(0)
for len(cur) > 0 && cur[0].Group != horse.SparkGroupID(group) {
cur = cur[1:]
last = 0 // reset whenever we change group IDs
}
effect := stmt.ColumnInt(1)
if effect != last {
// This effect is a separate roll from the previous one.
// Create a new slot for the effects to go into.
for i := range cur {
if cur[i].Group != horse.SparkGroupID(group) {
break
}
cur[i].Effects = append(cur[i].Effects, make([]horse.SparkEffect, 0, 1))
}
last = effect
}
for i := range cur {
if cur[i].Group != horse.SparkGroupID(group) {
break
}
e := horse.SparkEffect{
Target: horse.SparkTarget(stmt.ColumnInt(2)),
Value1: stmt.ColumnInt32(3),
Value2: stmt.ColumnInt32(4),
}
cur[i].Effects[len(cur[i].Effects)-1] = append(cur[i].Effects[len(cur[i].Effects)-1], e)
}
}
return sp, nil
}