From e4400c5f1e84c18d2126f2cb502ae10685977cbb Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Sat, 20 Jun 2026 03:20:01 -0400 Subject: refactor: combined all station crafting --- internal/action/recipe.go | 107 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 8 deletions(-) (limited to 'internal/action') diff --git a/internal/action/recipe.go b/internal/action/recipe.go index 5a69195..8779d53 100644 --- a/internal/action/recipe.go +++ b/internal/action/recipe.go @@ -1,6 +1,8 @@ package action import ( + "fmt" + "os" "path/filepath" "gopkg.in/yaml.v3" @@ -30,13 +32,68 @@ type RecipeDef struct { Success *SuccessFormula `yaml:"success"` } +type consolidatedRecipeDef struct { + Type string `yaml:"type"` + Skill string `yaml:"skill"` + Station []string `yaml:"station"` + Tool string `yaml:"tool"` + Wait float64 `yaml:"wait"` + Consume []ConsumeEntry `yaml:"consume"` + Products []recipeProduct `yaml:"products"` +} + +type recipeProduct struct { + ID string `yaml:"id"` + Output string `yaml:"output"` + OutputQty int `yaml:"output_qty"` + Level int `yaml:"level"` + XP int `yaml:"xp"` + Consume []ConsumeEntry `yaml:"consume"` + Message string `yaml:"message"` + FailMessage string `yaml:"fail_message"` + Fail string `yaml:"fail"` + Success *SuccessFormula `yaml:"success"` +} + type RecipeStore struct { dataDir string cache map[string][]RecipeDef + byID map[string]*RecipeDef } func NewRecipeStore(dataDir string) *RecipeStore { - return &RecipeStore{dataDir: dataDir, cache: make(map[string][]RecipeDef)} + return &RecipeStore{ + dataDir: dataDir, + cache: make(map[string][]RecipeDef), + byID: make(map[string]*RecipeDef), + } +} + +func (s *RecipeStore) GetByID(recipeID string) *RecipeDef { + if r, ok := s.byID[recipeID]; ok { + return r + } + s.ensureLoaded() + if r, ok := s.byID[recipeID]; ok { + return r + } + return nil +} + +func (s *RecipeStore) ensureLoaded() { + if _, ok := s.cache["_all"]; ok { + return + } + all, err := s.loadAllRaw() + if err != nil { + return + } + s.cache["_all"] = all + for i := range all { + if all[i].ID != "" { + s.byID[all[i].ID] = &all[i] + } + } } func (s *RecipeStore) LoadAll() ([]RecipeDef, error) { @@ -53,13 +110,10 @@ func (s *RecipeStore) LoadByType(recipeType string) ([]RecipeDef, error) { return result, nil } - all, err := s.loadAllRaw() - if err != nil { - return nil, err - } + s.ensureLoaded() + all := s.cache["_all"] if recipeType == "_all" { - s.cache[recipeType] = all result := make([]RecipeDef, len(all)) copy(result, all) return result, nil @@ -82,15 +136,52 @@ func (s *RecipeStore) loadAllRaw() ([]RecipeDef, error) { var recipes []RecipeDef WalkYAMLDir(dir, func(path, id string, data []byte) error { var r RecipeDef - if err := yaml.Unmarshal(data, &r); err != nil { + if err := yaml.Unmarshal(data, &r); err == nil && r.Type != "" { + recipes = append(recipes, r) return nil } - recipes = append(recipes, r) + + var cr consolidatedRecipeDef + if err := yaml.Unmarshal(data, &cr); err != nil { + fmt.Fprintf(os.Stderr, "recipe parse error %s: %v\n", path, err) + return nil + } + if cr.Type == "" || len(cr.Products) == 0 { + return nil + } + + for _, p := range cr.Products { + recipes = append(recipes, s.expandProduct(cr, p)) + } return nil }) return recipes, nil } +func (s *RecipeStore) expandProduct(cr consolidatedRecipeDef, p recipeProduct) RecipeDef { + r := RecipeDef{ + ID: p.ID, + Output: p.Output, + OutputQty: p.OutputQty, + Type: cr.Type, + Skill: cr.Skill, + Level: p.Level, + XP: p.XP, + Station: cr.Station, + Tool: cr.Tool, + Wait: cr.Wait, + Consume: p.Consume, + Message: p.Message, + FailMessage: p.FailMessage, + Fail: p.Fail, + Success: p.Success, + } + if len(r.Consume) == 0 { + r.Consume = cr.Consume + } + return r +} + func (r *RecipeDef) MatchesEntry(itemID string) bool { for _, e := range r.Consume { for _, id := range e.Items { -- cgit v1.2.3