aboutsummaryrefslogtreecommitdiff
path: root/internal/action
diff options
context:
space:
mode:
Diffstat (limited to 'internal/action')
-rw-r--r--internal/action/recipe.go107
1 files changed, 99 insertions, 8 deletions
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 {