118 lines
2.8 KiB
Go
118 lines
2.8 KiB
Go
package monsters
|
|
|
|
import (
|
|
"dk/internal/database"
|
|
"fmt"
|
|
|
|
"zombiezen.com/go/sqlite"
|
|
)
|
|
|
|
// Builder provides a fluent interface for creating monsters
|
|
type Builder struct {
|
|
monster *Monster
|
|
db *database.DB
|
|
}
|
|
|
|
// NewBuilder creates a new monster builder
|
|
func NewBuilder(db *database.DB) *Builder {
|
|
return &Builder{
|
|
monster: &Monster{db: db},
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
// WithName sets the monster name
|
|
func (b *Builder) WithName(name string) *Builder {
|
|
b.monster.Name = name
|
|
return b
|
|
}
|
|
|
|
// WithMaxHP sets the monster's maximum hit points
|
|
func (b *Builder) WithMaxHP(maxHP int) *Builder {
|
|
b.monster.MaxHP = maxHP
|
|
return b
|
|
}
|
|
|
|
// WithMaxDmg sets the monster's maximum damage
|
|
func (b *Builder) WithMaxDmg(maxDmg int) *Builder {
|
|
b.monster.MaxDmg = maxDmg
|
|
return b
|
|
}
|
|
|
|
// WithArmor sets the monster's armor value
|
|
func (b *Builder) WithArmor(armor int) *Builder {
|
|
b.monster.Armor = armor
|
|
return b
|
|
}
|
|
|
|
// WithLevel sets the monster's level
|
|
func (b *Builder) WithLevel(level int) *Builder {
|
|
b.monster.Level = level
|
|
return b
|
|
}
|
|
|
|
// WithMaxExp sets the monster's maximum experience reward
|
|
func (b *Builder) WithMaxExp(maxExp int) *Builder {
|
|
b.monster.MaxExp = maxExp
|
|
return b
|
|
}
|
|
|
|
// WithMaxGold sets the monster's maximum gold reward
|
|
func (b *Builder) WithMaxGold(maxGold int) *Builder {
|
|
b.monster.MaxGold = maxGold
|
|
return b
|
|
}
|
|
|
|
// WithImmunity sets the monster's immunity type
|
|
func (b *Builder) WithImmunity(immunity int) *Builder {
|
|
b.monster.Immune = immunity
|
|
return b
|
|
}
|
|
|
|
// Create saves the monster to the database and returns it
|
|
func (b *Builder) Create() (*Monster, error) {
|
|
// Use a transaction to ensure we can get the ID
|
|
var monster *Monster
|
|
err := b.db.Transaction(func(tx *database.Tx) error {
|
|
query := `INSERT INTO monsters (name, max_hp, max_dmg, armor, level, max_exp, max_gold, immune)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
|
|
|
if err := tx.Exec(query, b.monster.Name, b.monster.MaxHP, b.monster.MaxDmg, b.monster.Armor,
|
|
b.monster.Level, b.monster.MaxExp, b.monster.MaxGold, b.monster.Immune); err != nil {
|
|
return fmt.Errorf("failed to insert monster: %w", err)
|
|
}
|
|
|
|
// Get the last inserted ID within the same transaction
|
|
var lastID int
|
|
err := tx.Query("SELECT last_insert_rowid()", func(stmt *sqlite.Stmt) error {
|
|
lastID = stmt.ColumnInt(0)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get last insert ID: %w", err)
|
|
}
|
|
|
|
// Create the monster with the ID
|
|
monster = &Monster{
|
|
ID: lastID,
|
|
Name: b.monster.Name,
|
|
MaxHP: b.monster.MaxHP,
|
|
MaxDmg: b.monster.MaxDmg,
|
|
Armor: b.monster.Armor,
|
|
Level: b.monster.Level,
|
|
MaxExp: b.monster.MaxExp,
|
|
MaxGold: b.monster.MaxGold,
|
|
Immune: b.monster.Immune,
|
|
db: b.db,
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create monster: %w", err)
|
|
}
|
|
|
|
return monster, nil
|
|
}
|