package items import ( "fmt" "dk/internal/database" ) // Item represents an item in the game type Item struct { ID int `db:"id"` Type int `db:"type"` Name string `db:"name"` Lore string `db:"lore"` Value int `db:"value"` Attack int `db:"attack"` Defense int `db:"defense"` Strength int `db:"strength"` Dexterity int `db:"dexterity"` MaxHP int `db:"max_hp"` MaxMP int `db:"max_mp"` ExpBonus int `db:"exp_bonus"` GoldBonus int `db:"gold_bonus"` Special string `db:"special"` } // ItemType constants for item types const ( TypeWeapon = 1 TypeArmor = 2 TypeShield = 3 TypeAccessory = 4 ) // New creates a new Item with sensible defaults func New() *Item { return &Item{ Type: TypeWeapon, Name: "", Lore: "", Value: 0, Attack: 0, Defense: 0, Strength: 0, Dexterity: 0, MaxHP: 0, MaxMP: 0, ExpBonus: 0, GoldBonus: 0, Special: "", } } // Validate checks if item has valid values func (i *Item) Validate() error { if i.Name == "" { return fmt.Errorf("item name cannot be empty") } if i.Type < TypeWeapon || i.Type > TypeAccessory { return fmt.Errorf("invalid item type: %d", i.Type) } if i.Value < 0 { return fmt.Errorf("item value cannot be negative") } return nil } // CRUD operations func (i *Item) Delete() error { return database.Exec("DELETE FROM items WHERE id = %d", i.ID) } func (i *Item) Insert() error { id, err := database.Insert("items", i, "id") if err != nil { return err } i.ID = int(id) return nil } func (i *Item) Update() error { fields := map[string]any{ "type": i.Type, "name": i.Name, "lore": i.Lore, "value": i.Value, "attack": i.Attack, "defense": i.Defense, "strength": i.Strength, "dexterity": i.Dexterity, "max_hp": i.MaxHP, "max_mp": i.MaxMP, "exp_bonus": i.ExpBonus, "gold_bonus": i.GoldBonus, "special": i.Special, } return database.Update("items", fields, "id", i.ID) } // Query functions func Find(id int) (*Item, error) { var item Item err := database.Get(&item, "SELECT * FROM items WHERE id = %d", id) if err != nil { return nil, fmt.Errorf("item with ID %d not found", id) } return &item, nil } func All() ([]*Item, error) { var items []*Item err := database.Select(&items, "SELECT * FROM items ORDER BY type ASC, value ASC, id ASC") return items, err } func ByType(itemType int) ([]*Item, error) { var items []*Item err := database.Select(&items, "SELECT * FROM items WHERE type = %d ORDER BY value ASC, id ASC", itemType) return items, err } func ByValueRange(minValue, maxValue int) ([]*Item, error) { var items []*Item err := database.Select(&items, "SELECT * FROM items WHERE value >= %d AND value <= %d ORDER BY value ASC, id ASC", minValue, maxValue) return items, err } // Helper methods func (i *Item) IsWeapon() bool { return i.Type == TypeWeapon } func (i *Item) IsArmor() bool { return i.Type == TypeArmor } func (i *Item) IsShield() bool { return i.Type == TypeShield } func (i *Item) IsAccessory() bool { return i.Type == TypeAccessory } func (i *Item) TypeName() string { switch i.Type { case TypeWeapon: return "Weapon" case TypeArmor: return "Armor" case TypeShield: return "Shield" case TypeAccessory: return "Accessory" default: return "Unknown" } } func (i *Item) HasSpecial() bool { return i.Special != "" } func (i *Item) IsEquippable() bool { return i.Type >= TypeWeapon && i.Type <= TypeShield } func (i *Item) IsSlottable() bool { return i.Type == TypeAccessory } func (i *Item) HasLore() bool { return i.Lore != "" } // Stat bonus methods func (i *Item) HasAttackBonus() bool { return i.Attack != 0 } func (i *Item) HasDefenseBonus() bool { return i.Defense != 0 } func (i *Item) HasStrengthBonus() bool { return i.Strength != 0 } func (i *Item) HasDexterityBonus() bool { return i.Dexterity != 0 } func (i *Item) HasHPBonus() bool { return i.MaxHP != 0 } func (i *Item) HasMPBonus() bool { return i.MaxMP != 0 } func (i *Item) HasExpBonus() bool { return i.ExpBonus != 0 } func (i *Item) HasGoldBonus() bool { return i.GoldBonus != 0 } // Returns true if the item provides any stat bonuses func (i *Item) HasStatBonuses() bool { return i.Attack != 0 || i.Defense != 0 || i.Strength != 0 || i.Dexterity != 0 || i.MaxHP != 0 || i.MaxMP != 0 || i.ExpBonus != 0 || i.GoldBonus != 0 } func (i *Item) GetStatBonuses() map[string]int { bonuses := make(map[string]int) if i.Attack != 0 { bonuses["Attack"] = i.Attack } if i.Defense != 0 { bonuses["Defense"] = i.Defense } if i.Strength != 0 { bonuses["Strength"] = i.Strength } if i.Dexterity != 0 { bonuses["Dexterity"] = i.Dexterity } if i.MaxHP != 0 { bonuses["Max HP"] = i.MaxHP } if i.MaxMP != 0 { bonuses["Max MP"] = i.MaxMP } if i.ExpBonus != 0 { bonuses["Exp Bonus"] = i.ExpBonus } if i.GoldBonus != 0 { bonuses["Gold Bonus"] = i.GoldBonus } return bonuses } // GetPrimaryStatBonus returns the main stat bonus for the item type func (i *Item) GetPrimaryStatBonus() int { switch i.Type { case TypeWeapon: return i.Attack case TypeArmor, TypeShield: return i.Defense case TypeAccessory: // For accessories, return the highest stat bonus max := 0 stats := []int{i.Attack, i.Defense, i.Strength, i.Dexterity, i.MaxHP, i.MaxMP} for _, stat := range stats { if abs(stat) > abs(max) { max = stat } } return max default: return 0 } } func abs(x int) int { if x < 0 { return -x } return x }