163 lines
3.4 KiB
Go
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)
|
|
}
|