package spells import ( "fmt" "dk/internal/database" ) // Spell represents a spell in the game type Spell struct { ID int Name string MP int Attribute int Type int } // SpellType constants for spell types const ( TypeHealing = 1 TypeHurt = 2 TypeSleep = 3 TypeAttackBoost = 4 TypeDefenseBoost = 5 ) // New creates a new Spell with sensible defaults func New() *Spell { return &Spell{ Name: "", MP: 5, Attribute: 10, Type: TypeHealing, } } // Validate checks if spell has valid values func (s *Spell) Validate() error { if s.Name == "" { return fmt.Errorf("spell name cannot be empty") } if s.MP < 0 { return fmt.Errorf("spell MP cannot be negative") } if s.Attribute < 0 { return fmt.Errorf("spell Attribute cannot be negative") } if s.Type < TypeHealing || s.Type > TypeDefenseBoost { return fmt.Errorf("invalid spell type: %d", s.Type) } return nil } // CRUD operations func (s *Spell) Delete() error { return database.Exec("DELETE FROM spells WHERE id = %d", s.ID) } func (s *Spell) Insert() error { id, err := database.Insert("spells", s, "ID") if err != nil { return err } s.ID = int(id) return nil } // Query functions func Find(id int) (*Spell, error) { var spell Spell err := database.Get(&spell, "SELECT * FROM spells WHERE id = %d", id) if err != nil { return nil, fmt.Errorf("spell with ID %d not found", id) } return &spell, nil } func All() ([]*Spell, error) { var spells []*Spell err := database.Select(&spells, "SELECT * FROM spells ORDER BY type ASC, mp ASC, id ASC") return spells, err } func ByType(spellType int) ([]*Spell, error) { var spells []*Spell err := database.Select(&spells, "SELECT * FROM spells WHERE type = %d ORDER BY mp ASC, id ASC", spellType) return spells, err } func ByMaxMP(maxMP int) ([]*Spell, error) { var spells []*Spell err := database.Select(&spells, "SELECT * FROM spells WHERE mp <= %d ORDER BY type ASC, mp ASC, id ASC", maxMP) return spells, err } func ByTypeAndMaxMP(spellType, maxMP int) ([]*Spell, error) { var spells []*Spell err := database.Select(&spells, "SELECT * FROM spells WHERE type = %d AND mp <= %d ORDER BY mp ASC, id ASC", spellType, maxMP) return spells, err } func ByName(name string) (*Spell, error) { var spell Spell err := database.Get(&spell, "SELECT * FROM spells WHERE name = %s COLLATE NOCASE", name) if err != nil { return nil, fmt.Errorf("spell with name '%s' not found", name) } return &spell, nil } // Helper methods func (s *Spell) IsHealing() bool { return s.Type == TypeHealing } func (s *Spell) IsHurt() bool { return s.Type == TypeHurt } func (s *Spell) IsSleep() bool { return s.Type == TypeSleep } func (s *Spell) IsAttackBoost() bool { return s.Type == TypeAttackBoost } func (s *Spell) IsDefenseBoost() bool { return s.Type == TypeDefenseBoost } func (s *Spell) TypeName() string { switch s.Type { case TypeHealing: return "Healing" case TypeHurt: return "Hurt" case TypeSleep: return "Sleep" case TypeAttackBoost: return "Attack Boost" case TypeDefenseBoost: return "Defense Boost" default: return "Unknown" } } func (s *Spell) CanCast(availableMP int) bool { return availableMP >= s.MP } func (s *Spell) Efficiency() float64 { if s.MP == 0 { return 0 } return float64(s.Attribute) / float64(s.MP) } func (s *Spell) IsOffensive() bool { return s.Type == TypeHurt || s.Type == TypeSleep } func (s *Spell) IsSupport() bool { return s.Type == TypeHealing || s.Type == TypeAttackBoost || s.Type == TypeDefenseBoost }