163 lines
3.4 KiB
Go

package monsters
import (
"fmt"
"dk/internal/database"
)
// Monster represents a monster in the game
type Monster struct {
ID int
Name string
MaxHP int
MaxDmg int
Armor int
Level int
MaxExp int
MaxGold int
Immune int
}
// Immunity constants
const (
ImmuneNone = 0
ImmuneHurt = 1
ImmuneSleep = 2
)
// New creates a new Monster with sensible defaults
func New() *Monster {
return &Monster{
Name: "",
MaxHP: 10,
MaxDmg: 5,
Armor: 0,
Level: 1,
MaxExp: 10,
MaxGold: 5,
Immune: ImmuneNone,
}
}
// Validate checks if monster has valid values
func (m *Monster) Validate() error {
if m.Name == "" {
return fmt.Errorf("monster name cannot be empty")
}
if m.MaxHP < 1 {
return fmt.Errorf("monster MaxHP must be at least 1")
}
if m.Level < 1 {
return fmt.Errorf("monster Level must be at least 1")
}
if m.Immune < ImmuneNone || m.Immune > ImmuneSleep {
return fmt.Errorf("invalid immunity type: %d", m.Immune)
}
return nil
}
// CRUD operations
func (m *Monster) Delete() error {
return database.Exec("DELETE FROM monsters WHERE id = %d", m.ID)
}
func (m *Monster) Insert() error {
id, err := database.Insert("monsters", m, "ID")
if err != nil {
return err
}
m.ID = int(id)
return nil
}
// Query functions
func Find(id int) (*Monster, error) {
var monster Monster
err := database.Get(&monster, "SELECT * FROM monsters WHERE id = %d", id)
if err != nil {
return nil, fmt.Errorf("monster with ID %d not found", id)
}
return &monster, nil
}
func All() ([]*Monster, error) {
var monsters []*Monster
err := database.Select(&monsters, "SELECT * FROM monsters ORDER BY level ASC, id ASC")
return monsters, err
}
func ByLevel(level int) ([]*Monster, error) {
var monsters []*Monster
err := database.Select(&monsters, "SELECT * FROM monsters WHERE level = %d ORDER BY id ASC", level)
return monsters, err
}
func ByLevelRange(minLevel, maxLevel int) ([]*Monster, error) {
var monsters []*Monster
err := database.Select(&monsters, "SELECT * FROM monsters WHERE level >= %d AND level <= %d ORDER BY level ASC, id ASC", minLevel, maxLevel)
return monsters, err
}
func ByImmunity(immunityType int) ([]*Monster, error) {
var monsters []*Monster
err := database.Select(&monsters, "SELECT * FROM monsters WHERE immune = %d ORDER BY level ASC, id ASC", immunityType)
return monsters, err
}
func ByName(name string) (*Monster, error) {
var monster Monster
err := database.Get(&monster, "SELECT * FROM monsters WHERE name = %s COLLATE NOCASE", name)
if err != nil {
return nil, fmt.Errorf("monster with name '%s' not found", name)
}
return &monster, nil
}
// Helper methods
func (m *Monster) IsHurtImmune() bool {
return m.Immune == ImmuneHurt
}
func (m *Monster) IsSleepImmune() bool {
return m.Immune == ImmuneSleep
}
func (m *Monster) HasImmunity() bool {
return m.Immune != ImmuneNone
}
func (m *Monster) ImmunityName() string {
switch m.Immune {
case ImmuneNone:
return "None"
case ImmuneHurt:
return "Hurt Spells"
case ImmuneSleep:
return "Sleep Spells"
default:
return "Unknown"
}
}
func (m *Monster) DifficultyRating() float64 {
if m.Level == 0 {
return 0
}
return float64(m.MaxHP+m.MaxDmg+m.Armor) / float64(m.Level)
}
func (m *Monster) ExpPerHP() float64 {
if m.MaxHP == 0 {
return 0
}
return float64(m.MaxExp) / float64(m.MaxHP)
}
func (m *Monster) GoldPerHP() float64 {
if m.MaxHP == 0 {
return 0
}
return float64(m.MaxGold) / float64(m.MaxHP)
}