From 470bc5bd99b793e46305310b5fbeb3068eba45f1 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Sat, 20 Jun 2026 23:43:35 -0400 Subject: refactor: removed separate crafting recipes and combined them into item YAML --- internal/object/item.go | 109 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 5 deletions(-) (limited to 'internal/object') diff --git a/internal/object/item.go b/internal/object/item.go index 8ec1565..241cc0b 100644 --- a/internal/object/item.go +++ b/internal/object/item.go @@ -1,11 +1,33 @@ package object import ( + "fmt" "strings" - "thehouseoficarus/internal/action" + "gopkg.in/yaml.v3" ) +func WordPrefixMatch(input, name string) bool { + inputWords := strings.Fields(strings.ToLower(input)) + if len(inputWords) == 0 { + return false + } + nameWords := strings.Fields(strings.ToLower(name)) + for _, iw := range inputWords { + found := false + for _, nw := range nameWords { + if strings.HasPrefix(nw, iw) || strings.HasPrefix(iw, nw) { + found = true + break + } + } + if !found { + return false + } + } + return true +} + type EquipSlot string const ( @@ -56,8 +78,7 @@ type ItemDef struct { SearchMessage string `yaml:"search_message"` HealValue int `yaml:"heal_value"` EatMessage string `yaml:"eat_message"` - MadeFrom []MadeFromEntry `yaml:"made_from,omitempty"` - Ticks float64 `yaml:"ticks"` + Craft CraftList `yaml:"craft,omitempty"` ProvidesJunk string `yaml:"provides_junk,omitempty"` FarmPatchType string `yaml:"farm_patch_type"` FarmLevel int `yaml:"farm_level"` @@ -72,12 +93,90 @@ type ItemDef struct { PotionDuration float64 `yaml:"potion_duration"` } -type MadeFromEntry struct { +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"` + 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"` @@ -105,5 +204,5 @@ func (d *ItemDef) MatchesName(input string) bool { if strings.ToLower(d.Name) == lower { return true } - return action.WordPrefixMatch(lower, d.Name) + return WordPrefixMatch(lower, d.Name) } -- cgit v1.2.3