aboutsummaryrefslogtreecommitdiff
path: root/internal/item/item.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-25 15:40:48 -0400
committerhistoria <[not public]>2026-06-25 15:40:48 -0400
commitabd612c15799f604e671e83dc7c410ed2b44185f (patch)
tree0597ca92350de73aac2a7cf26b2f2d6595dac0cc /internal/item/item.go
parent2725e2927a1595c7b100d942d1f14146252adeb7 (diff)
downloadthehouseoficarus-abd612c15799f604e671e83dc7c410ed2b44185f.tar.gz
slop refactor
Diffstat (limited to 'internal/item/item.go')
-rw-r--r--internal/item/item.go191
1 files changed, 191 insertions, 0 deletions
diff --git a/internal/item/item.go b/internal/item/item.go
new file mode 100644
index 0000000..890fa8d
--- /dev/null
+++ b/internal/item/item.go
@@ -0,0 +1,191 @@
+package item
+
+import (
+ "fmt"
+ "strings"
+
+ "gopkg.in/yaml.v3"
+ "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 WeaponType string
+
+const (
+ WeaponMelee WeaponType = "melee"
+ WeaponRanged WeaponType = "ranged"
+ WeaponScience WeaponType = "science"
+)
+
+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"`
+ EquipSlot EquipSlot `yaml:"equip_slot"`
+ WeaponType WeaponType `yaml:"weapon_type"`
+ AttackType string `yaml:"attack_type"`
+ Stats ItemStats `yaml:"stats"`
+ Speed float64 `yaml:"speed"`
+ Requirements map[string]int `yaml:"requirements,omitempty"`
+ ToolType string `yaml:"tool_type"`
+ ToolSpeed float64 `yaml:"tool_speed"`
+ BurnTicks float64 `yaml:"burn_ticks"`
+ FireLevel int `yaml:"fire_level"`
+ FireXP int `yaml:"fire_xp"`
+ Quality int `yaml:"quality"`
+ MaxQuality int `yaml:"max_quality"`
+ SearchTable string `yaml:"search_table"`
+ SearchMiscTable string `yaml:"search_misc_table"`
+ SearchTicks float64 `yaml:"search_ticks"`
+ SearchMessage string `yaml:"search_message"`
+ HealValue int `yaml:"heal_value"`
+ EatMessage string `yaml:"eat_message"`
+ Craft CraftList `yaml:"craft,omitempty"`
+ ProvidesJunk string `yaml:"provides_junk,omitempty"`
+ 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"`
+ Recoverable bool `yaml:"recoverable"`
+}
+
+type CraftList []CraftDef
+
+func (cl *CraftList) UnmarshalYAML(value *yaml.Node) error {
+ switch value.Kind {
+ case yaml.SequenceNode:
+ return value.Decode((*[]CraftDef)(cl))
+ case yaml.MappingNode:
+ var single CraftDef
+ if err := value.Decode(&single); err != nil {
+ return err
+ }
+ *cl = []CraftDef{single}
+ return nil
+ }
+ return fmt.Errorf("craft: expected mapping or sequence")
+}
+
+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 ConsumeEntry struct {
+ Items []string `yaml:"items"`
+ Quantity int `yaml:"quantity"`
+ Byproducts []string `yaml:"byproducts"`
+}
+
+type CraftStep struct {
+ Tick float64 `yaml:"tick"`
+ 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"`
+ Skill string `yaml:"skill"`
+ Level int `yaml:"level"`
+ XP int `yaml:"xp"`
+ Wait float64 `yaml:"wait"`
+ Station []string `yaml:"station"`
+ Tool string `yaml:"tool"`
+ Consume []ConsumeEntry `yaml:"consume"`
+ OutputQty int `yaml:"output_qty"`
+ Fail string `yaml:"fail"`
+ Message string `yaml:"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 {
+ if c.Skill != "" {
+ return c.Skill
+ }
+ return c.Type
+}
+
+type ItemStats struct {
+ StabAttack int `yaml:"stab_attack"`
+ SlashAttack int `yaml:"slash_attack"`
+ CrushAttack int `yaml:"crush_attack"`
+ ScienceAttack int `yaml:"science_attack"`
+ RangedAttack int `yaml:"ranged_attack"`
+
+ StabDefense int `yaml:"stab_defense"`
+ SlashDefense int `yaml:"slash_defense"`
+ CrushDefense int `yaml:"crush_defense"`
+ ScienceDefense int `yaml:"science_defense"`
+ RangedDefense int `yaml:"ranged_defense"`
+
+ StrengthBonus int `yaml:"strength_bonus"`
+ RangedStrength int `yaml:"ranged_strength"`
+ ScienceDamage int `yaml:"science_damage"`
+ TechnologyBonus int `yaml:"technology_bonus"`
+}
+
+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)
+}