aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_craft.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-20 23:43:35 -0400
committerhistoria <[not public]>2026-06-20 23:43:35 -0400
commit470bc5bd99b793e46305310b5fbeb3068eba45f1 (patch)
treeff268fab1a8e7699cd6404e6e86c2d4bd1c6f2f6 /internal/game/cmd_craft.go
parent010fa439399581391fcd509d2058191ff4fa74b3 (diff)
downloadthehouseoficarus-470bc5bd99b793e46305310b5fbeb3068eba45f1.tar.gz
refactor: removed separate crafting recipes and combined them into item YAML
Diffstat (limited to 'internal/game/cmd_craft.go')
-rw-r--r--internal/game/cmd_craft.go185
1 files changed, 98 insertions, 87 deletions
diff --git a/internal/game/cmd_craft.go b/internal/game/cmd_craft.go
index d061a9c..3290daa 100644
--- a/internal/game/cmd_craft.go
+++ b/internal/game/cmd_craft.go
@@ -3,8 +3,8 @@ package game
import (
"strings"
- "thehouseoficarus/internal/action"
"thehouseoficarus/internal/net"
+ "thehouseoficarus/internal/object"
"thehouseoficarus/internal/player"
)
@@ -28,35 +28,27 @@ func (g *Game) doStationSkill(sess *net.Session, input string, recipeType string
p := sess.Player
g.cancelAction(p)
- allRecipes, err := g.RecipeStore.LoadAll()
- if err != nil {
- sess.WriteLine("Error loading recipes.")
- return
- }
+ items := g.CraftIndex.ByType(recipeType)
- var recipes []action.RecipeDef
- for _, r := range allRecipes {
- if r.Type != recipeType {
- continue
- }
- if !g.recipeVisible(p, &r) {
+ var filtered []*object.ItemDef
+ for _, item := range items {
+ if !g.itemVisible(p, item) {
continue
}
- recipes = append(recipes, r)
+ filtered = append(filtered, item)
}
if input != "" {
- g.doWithInput(sess, p, recipes, input, skill, flagKey, label, verbCap)
+ g.doWithInput(sess, p, filtered, input, skill, flagKey, label, verbCap)
return
}
- lastRecipeID, _ := p.Flags[flagKey].(string)
- if lastRecipeID != "" {
- for i := range recipes {
- if recipes[i].ID == lastRecipeID {
- r := &recipes[i]
- if g.canDoRecipe(p, r, skill) {
- g.startRecipe(sess, p, r, 0, flagKey)
+ lastItemID, _ := p.Flags[flagKey].(string)
+ if lastItemID != "" {
+ for _, item := range filtered {
+ if item.ID == lastItemID {
+ if g.canDoItem(p, item, skill) {
+ g.startItem(sess, p, item, 0, flagKey)
return
}
break
@@ -64,34 +56,33 @@ func (g *Game) doStationSkill(sess *net.Session, input string, recipeType string
}
}
- available := g.availableRecipes(p, recipes)
+ available := g.availableItems(p, filtered)
if len(available) == 0 {
+ if recipeType == "pharmacy" && g.hasGrimyHerbs(p) {
+ sess.WriteLine("Mix what? Grimy herbs? Clean those first!")
+ return
+ }
sess.WriteLine("You don't have any materials to " + verbPast + ".")
return
}
optionKey := verbPast + "_all"
if p.OptionBool(optionKey) && len(available) == 1 {
- g.startRecipe(sess, p, &available[0], 0, flagKey)
+ g.startItem(sess, p, available[0], 0, flagKey)
return
}
g.showProductionTable(sess, p, available, label, recipeType, flagKey, verbCap, false)
}
-func (g *Game) doWithInput(sess *net.Session, p *player.Player, recipes []action.RecipeDef, input string, skill player.SkillName, flagKey, label, verbCap string) {
+func (g *Game) doWithInput(sess *net.Session, p *player.Player, items []*object.ItemDef, input string, skill player.SkillName, flagKey, label, verbCap string) {
qty, productName := parseQty(input)
productName = strings.TrimSpace(productName)
- var matched []action.RecipeDef
- for _, r := range recipes {
- outDef, _ := g.ItemStore.Load(r.Output)
- name := r.Output
- if outDef != nil {
- name = outDef.Name
- }
- if action.WordPrefixMatch(productName, name) {
- matched = append(matched, r)
+ var matched []*object.ItemDef
+ for _, item := range items {
+ if object.WordPrefixMatch(productName, item.Name) {
+ matched = append(matched, item)
}
}
@@ -100,10 +91,10 @@ func (g *Game) doWithInput(sess *net.Session, p *player.Player, recipes []action
return
}
- var available []action.RecipeDef
- for _, r := range matched {
- if g.canDoRecipe(p, &r, skill) {
- available = append(available, r)
+ var available []*object.ItemDef
+ for _, item := range matched {
+ if g.canDoItem(p, item, skill) {
+ available = append(available, item)
}
}
@@ -113,68 +104,85 @@ func (g *Game) doWithInput(sess *net.Session, p *player.Player, recipes []action
}
if len(available) == 1 {
- g.startRecipe(sess, p, &available[0], qty, flagKey)
+ g.startItem(sess, p, available[0], qty, flagKey)
return
}
g.showProductionTable(sess, p, available, label, label, flagKey, verbCap, false)
}
-func (g *Game) recipeVisible(p *player.Player, r *action.RecipeDef) bool {
- if len(r.Station) > 0 {
- stID, _ := g.findStation(p.RoomID, r.Station)
- if stID == "" {
+func (g *Game) itemVisible(p *player.Player, item *object.ItemDef) bool {
+ return item.FindCraft(func(c object.CraftDef) bool {
+ if len(c.Station) > 0 {
+ stID, _ := g.findStation(p.RoomID, c.Station)
+ if stID == "" {
+ return false
+ }
+ }
+ if c.Tool != "" && !g.hasToolType(p, c.Tool) {
return false
}
- }
- if r.Tool != "" && !g.hasToolType(p, r.Tool) {
- return false
- }
- return true
+ return true
+ }) != nil
}
-func (g *Game) canDoRecipe(p *player.Player, r *action.RecipeDef, skill player.SkillName) bool {
- if p.Level(skill) < r.Level {
- return false
- }
- if !r.HasAllItemsQty(p.CountItem) {
- return false
- }
- if len(r.Station) > 0 {
- stID, _ := g.findStation(p.RoomID, r.Station)
- if stID == "" {
+func (g *Game) canDoItem(p *player.Player, item *object.ItemDef, skill player.SkillName) bool {
+ m := item.FindCraft(func(c object.CraftDef) bool {
+ if p.Level(skill) < c.Level {
return false
}
- }
- if r.Tool != "" && !g.hasToolType(p, r.Tool) {
- return false
- }
- return true
+ if !craftHasAllItemsQty(&c, p.CountItem) {
+ return false
+ }
+ if len(c.Station) > 0 {
+ stID, _ := g.findStation(p.RoomID, c.Station)
+ if stID == "" {
+ return false
+ }
+ }
+ if c.Tool != "" && !g.hasToolType(p, c.Tool) {
+ return false
+ }
+ return true
+ })
+ return m != nil
}
-func (g *Game) availableRecipes(p *player.Player, allRecipes []action.RecipeDef) []action.RecipeDef {
- var result []action.RecipeDef
- for _, r := range allRecipes {
- if r.HasAllItemsQty(p.CountItem) {
- result = append(result, r)
+func (g *Game) availableItems(p *player.Player, allItems []*object.ItemDef) []*object.ItemDef {
+ var result []*object.ItemDef
+ for _, item := range allItems {
+ m := item.FindCraft(func(c object.CraftDef) bool {
+ return craftHasAllItemsQty(&c, p.CountItem)
+ })
+ if m != nil {
+ result = append(result, item)
}
}
return result
}
-func (g *Game) startRecipe(sess *net.Session, p *player.Player, recipe *action.RecipeDef, count int, flagKey string) {
+func (g *Game) startItem(sess *net.Session, p *player.Player, item *object.ItemDef, count int, flagKey string) {
p.EnsureFlags()
- p.Flags[flagKey] = recipe.ID
+ p.Flags[flagKey] = item.ID
g.AccountStore.SaveCharacter(p)
- g.startProductionFromRecipe(sess, p, recipe, count)
+ g.startProductionFromItem(sess, p, item, count)
}
-func (g *Game) findCraftRecipes(p *player.Player, itemAID, itemBID string) []action.RecipeDef {
- allRecipes, err := g.RecipeStore.LoadAll()
- if err != nil {
- return nil
+func (g *Game) hasGrimyHerbs(p *player.Player) bool {
+ items := g.CraftIndex.ByType("clean")
+ for _, item := range items {
+ if item.FindCraft(func(c object.CraftDef) bool {
+ return craftHasAllItems(&c, p.HasItem)
+ }) != nil {
+ return true
+ }
}
+ return false
+}
+
+func (g *Game) findCraftItems(p *player.Player, itemAID, itemBID string) []*object.ItemDef {
+ items := g.CraftIndex.ByType("crafting")
toolTypeA := ""
toolTypeB := ""
@@ -185,19 +193,22 @@ func (g *Game) findCraftRecipes(p *player.Player, itemAID, itemBID string) []act
toolTypeB = defB.ToolType
}
- var matched []action.RecipeDef
- for _, r := range allRecipes {
- if r.Type != "crafting" {
- continue
- }
- if r.Tool == "" {
- continue
- }
-
- if r.Tool == toolTypeA && r.MatchesEntry(itemBID) {
- matched = append(matched, r)
- } else if r.Tool == toolTypeB && r.MatchesEntry(itemAID) {
- matched = append(matched, r)
+ var matched []*object.ItemDef
+ for _, item := range items {
+ match := item.FindCraft(func(c object.CraftDef) bool {
+ if c.Tool == "" {
+ return false
+ }
+ if c.Tool == toolTypeA && craftMatchesEntry(&c, itemBID) {
+ return true
+ }
+ if c.Tool == toolTypeB && craftMatchesEntry(&c, itemAID) {
+ return true
+ }
+ return false
+ })
+ if match != nil {
+ matched = append(matched, item)
}
}
return matched