package item import ( "strings" "thehouseoficarus/internal/behavior" ) type EquipSlot string const ( SlotHead EquipSlot = "head" SlotNeck EquipSlot = "neck" SlotTorso EquipSlot = "torso" SlotLegs EquipSlot = "legs" SlotHands EquipSlot = "hands" SlotFeet EquipSlot = "feet" SlotBack EquipSlot = "back" SlotAmmo EquipSlot = "ammo" SlotMainHand EquipSlot = "main_hand" SlotOffHand EquipSlot = "off_hand" SlotRing EquipSlot = "ring" ) type EquipmentType string const ( EquipMeleeWeapon EquipmentType = "melee_weapon" EquipRangedWeapon EquipmentType = "ranged_weapon" EquipScienceWeapon EquipmentType = "tech_weapon" EquipArmor EquipmentType = "armor" EquipTool EquipmentType = "tool" EquipAmmo EquipmentType = "ammo" ) func (et EquipmentType) IsWeapon() bool { return et == EquipMeleeWeapon || et == EquipRangedWeapon || et == EquipScienceWeapon } type AttackBonuses struct { Stab int `yaml:"stab,omitempty"` Slash int `yaml:"slash,omitempty"` Crush int `yaml:"crush,omitempty"` Ranged int `yaml:"ranged,omitempty"` Science int `yaml:"science,omitempty"` } type DefenseBonuses struct { Stab int `yaml:"stab,omitempty"` Slash int `yaml:"slash,omitempty"` Crush int `yaml:"crush,omitempty"` Ranged int `yaml:"ranged,omitempty"` Science int `yaml:"science,omitempty"` } type OtherBonuses struct { Strength int `yaml:"strength,omitempty"` RangedStrength int `yaml:"ranged_strength,omitempty"` Science int `yaml:"science,omitempty"` Technology int `yaml:"technology,omitempty"` } type EquipmentDef struct { Type EquipmentType `yaml:"type"` Slot EquipSlot `yaml:"slot,omitempty"` AttackType string `yaml:"attack_type,omitempty"` Speed float64 `yaml:"speed,omitempty"` Junk string `yaml:"junk,omitempty"` Attack *AttackBonuses `yaml:"attack,omitempty"` Defense *DefenseBonuses `yaml:"defense,omitempty"` Other *OtherBonuses `yaml:"other,omitempty"` } type ToolDef struct { Type string `yaml:"type"` Speed float64 `yaml:"speed,omitempty"` } type ItemDef struct { ID string `yaml:"id"` Name string `yaml:"name"` Color string `yaml:"color"` Description string `yaml:"description"` Value int `yaml:"value"` Stackable bool `yaml:"stackable"` Recoverable bool `yaml:"recoverable"` Equipment *EquipmentDef `yaml:"equipment,omitempty"` Tool *ToolDef `yaml:"tool,omitempty"` Requirements map[string]int `yaml:"requirements,omitempty"` MaxQuality int `yaml:"max_quality"` Craft CraftList `yaml:"craft,omitempty"` Search []behavior.Trigger `yaml:"search,omitempty"` HealValue int `yaml:"heal_value"` EatMessage string `yaml:"eat_message"` FarmPatchType string `yaml:"farm_patch_type"` FarmLevel int `yaml:"farm_level"` FarmPlantXP int `yaml:"farm_plant_xp"` FarmHarvestXP int `yaml:"farm_harvest_xp"` FarmStages int `yaml:"farm_stages"` FarmProduct string `yaml:"farm_product"` FarmMinYield int `yaml:"farm_min_yield"` FarmMaxYield int `yaml:"farm_max_yield"` PotionEffect string `yaml:"potion_effect"` PotionBonus int `yaml:"potion_bonus"` PotionDuration float64 `yaml:"potion_duration"` BurnTicks float64 `yaml:"burn_ticks"` FireLevel int `yaml:"fire_level"` FireXP int `yaml:"fire_xp"` } func (d *ItemDef) EquipmentType() EquipmentType { if d.Equipment != nil { return d.Equipment.Type } return "" } func (d *ItemDef) EquipSlot() EquipSlot { if d.Equipment != nil { return d.Equipment.Slot } return "" } func (d *ItemDef) Speed() float64 { if d.Equipment != nil { return d.Equipment.Speed } return 0 } func (d *ItemDef) AttackType() string { if d.Equipment != nil { return d.Equipment.AttackType } return "" } func (d *ItemDef) ToolType() string { if d.Tool != nil { return d.Tool.Type } return "" } func (d *ItemDef) ToolSpeed() float64 { if d.Tool != nil { return d.Tool.Speed } return 0 } func (d *ItemDef) ProvidesJunk() string { if d.Equipment != nil { return d.Equipment.Junk } return "" } type ItemStats struct { StabAttack int SlashAttack int CrushAttack int ScienceAttack int RangedAttack int StabDefense int SlashDefense int CrushDefense int ScienceDefense int RangedDefense int StrengthBonus int RangedStrength int ScienceDamage int TechnologyBonus int } func (d *ItemDef) Stats() ItemStats { var s ItemStats if d.Equipment != nil { if d.Equipment.Attack != nil { s.StabAttack = d.Equipment.Attack.Stab s.SlashAttack = d.Equipment.Attack.Slash s.CrushAttack = d.Equipment.Attack.Crush s.RangedAttack = d.Equipment.Attack.Ranged s.ScienceAttack = d.Equipment.Attack.Science } if d.Equipment.Defense != nil { s.StabDefense = d.Equipment.Defense.Stab s.SlashDefense = d.Equipment.Defense.Slash s.CrushDefense = d.Equipment.Defense.Crush s.RangedDefense = d.Equipment.Defense.Ranged s.ScienceDefense = d.Equipment.Defense.Science } if d.Equipment.Other != nil { s.StrengthBonus = d.Equipment.Other.Strength s.RangedStrength = d.Equipment.Other.RangedStrength s.ScienceDamage = d.Equipment.Other.Science s.TechnologyBonus = d.Equipment.Other.Technology } } return s } type CraftList []CraftDef func (d *ItemDef) FirstCraft() *CraftDef { if len(d.Craft) == 0 { return nil } return &d.Craft[0] } func (d *ItemDef) FindCraft(fn func(CraftDef) bool) *CraftDef { for i := range d.Craft { if fn(d.Craft[i]) { return &d.Craft[i] } } return nil } func (d *ItemDef) MatchingCrafts(fn func(CraftDef) bool) []*CraftDef { var result []*CraftDef for i := range d.Craft { if fn(d.Craft[i]) { result = append(result, &d.Craft[i]) } } return result } type IngredientEntry struct { Items []string `yaml:"items"` Quantity int `yaml:"quantity"` Byproducts []string `yaml:"byproducts"` } type CraftStep struct { Delay float64 `yaml:"delay"` Message string `yaml:"message"` } type SuccessFormula struct { Base float64 `yaml:"base"` PerLevel float64 `yaml:"per_level"` Cap float64 `yaml:"cap"` } type CraftDef struct { Type string `yaml:"type"` Subtype string `yaml:"subtype,omitempty"` Level int `yaml:"level"` XP int `yaml:"xp"` TicksPerCycle float64 `yaml:"ticks_per_cycle"` Station []string `yaml:"station"` Tool string `yaml:"tool"` Ingredients []IngredientEntry `yaml:"ingredients"` OutputQty int `yaml:"output_qty"` Fail string `yaml:"fail"` SuccessMessage string `yaml:"success_message"` FailMessage string `yaml:"fail_message"` StartMessage string `yaml:"start_message"` EndMessage string `yaml:"end_message"` Steps []CraftStep `yaml:"steps"` Success *SuccessFormula `yaml:"success"` } func (c *CraftDef) EffectiveSkill() string { return c.Type } func (d *ItemDef) MatchesName(input string) bool { lower := strings.ToLower(strings.TrimSpace(input)) if lower == "" { return false } if strings.ToLower(d.Name) == lower { return true } return behavior.WordPrefixMatch(lower, d.Name) }