diff options
| author | historia <[not public]> | 2026-06-20 23:43:35 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-20 23:43:35 -0400 |
| commit | 470bc5bd99b793e46305310b5fbeb3068eba45f1 (patch) | |
| tree | ff268fab1a8e7699cd6404e6e86c2d4bd1c6f2f6 /internal/game/cmd_use.go | |
| parent | 010fa439399581391fcd509d2058191ff4fa74b3 (diff) | |
| download | thehouseoficarus-470bc5bd99b793e46305310b5fbeb3068eba45f1.tar.gz | |
refactor: removed separate crafting recipes and combined them into item YAML
Diffstat (limited to 'internal/game/cmd_use.go')
| -rw-r--r-- | internal/game/cmd_use.go | 264 |
1 files changed, 110 insertions, 154 deletions
diff --git a/internal/game/cmd_use.go b/internal/game/cmd_use.go index e653c93..640e28b 100644 --- a/internal/game/cmd_use.go +++ b/internal/game/cmd_use.go @@ -4,7 +4,6 @@ import ( "fmt" "strings" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/net" "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" @@ -116,57 +115,42 @@ func (g *Game) useRoomObject(sess *net.Session, p *player.Player, input string) return true } -func (g *Game) stationRecipes(p *player.Player, stationDefID string) []action.RecipeDef { - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - return nil - } - var results []action.RecipeDef - for _, r := range allRecipes { - if len(r.Station) == 0 { - continue - } - stationMatch := false - for _, sid := range r.Station { - if sid == stationDefID { - stationMatch = true - break - } - } - if !stationMatch { +func (g *Game) stationRecipes(p *player.Player, stationDefID string) []*object.ItemDef { + items := g.CraftIndex.ByStation(stationDefID) + var results []*object.ItemDef + for _, item := range items { + c := item.FirstCraft() + if !craftHasAllItemsQty(c, p.CountItem) { continue } - if !r.HasAllItemsQty(p.CountItem) { + skillName := player.SkillName(c.EffectiveSkill()) + if p.Level(skillName) < c.Level { continue } - skillName := player.SkillName(r.EffectiveSkill()) - if p.Level(skillName) < r.Level { - continue - } - if r.Tool != "" && !g.hasToolType(p, r.Tool) { + if c.Tool != "" && !g.hasToolType(p, c.Tool) { continue } if stationDefID == "anvil" && !g.hasToolType(p, "hammer") { continue } - results = append(results, r) + results = append(results, item) } return results } -func (g *Game) showRecipeMenu(sess *net.Session, p *player.Player, recipes []action.RecipeDef, stationName string) { - if len(recipes) == 0 { +func (g *Game) showRecipeMenu(sess *net.Session, p *player.Player, items []*object.ItemDef, stationName string) { + if len(items) == 0 { sess.WriteLine(fmt.Sprintf("You don't have anything you can make at the %s.", stationName)) return } - if len(recipes) == 1 { - g.promptHowMany(sess, recipes[0].ID) + if len(items) == 1 { + g.promptHowMany(sess, items[0].ID) return } needTypes := false - for i := range recipes { - for j := i + 1; j < len(recipes); j++ { - if recipes[i].Type != recipes[j].Type { + for i := range items { + for j := i + 1; j < len(items); j++ { + if len(items[i].Craft) > 0 && len(items[j].Craft) > 0 && items[i].FirstCraft().Type != items[j].FirstCraft().Type { needTypes = true break } @@ -175,17 +159,23 @@ func (g *Game) showRecipeMenu(sess *net.Session, p *player.Player, recipes []act break } } - menu := recipeMenuData(recipeDefIDs(recipes)) + menu := itemMenuData(itemIDs(items)) sess.PendingMenu = menu sess.State = net.StateRecipeChoice var names []string - for _, r := range recipes { - name := g.recipeName(sess, &r) + for _, item := range items { + cType := "" + if len(item.Craft) > 0 { + cType = item.FirstCraft().Type + } + if cType == "" { + cType = "combine" + } + typeLabel := strings.ToUpper(cType[:1]) + cType[1:] if needTypes { - typeLabel := strings.ToUpper(r.Type[:1]) + r.Type[1:] - names = append(names, fmt.Sprintf("%s (%s)", name, typeLabel)) + names = append(names, fmt.Sprintf("%s (%s)", g.itemName(sess, item), typeLabel)) } else { - names = append(names, name) + names = append(names, g.itemName(sess, item)) } } g.showMenuTable(sess, fmt.Sprintf("What would you like to make at the %s?", stationName), names) @@ -217,23 +207,28 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, return } - stationIDs := []string{def.ID} - recipes, err := g.RecipeStore.FindByStation(itemAID, stationIDs, "") - if err == nil && len(recipes) > 0 { - if recipes[0].Type == "smelting" { - filtered := recipes[:0:0] - for _, r := range recipes { - if r.Type != "smelting" { + recipes := g.CraftIndex.FindByStationInput(def.ID, itemAID) + + if len(recipes) > 0 { + cType := "" + if len(recipes[0].Craft) > 0 { + cType = recipes[0].FirstCraft().Type + } + if cType == "smelting" { + var filtered []*object.ItemDef + for _, item := range recipes { + c := item.FirstCraft() + if c.Type != "smelting" { continue } - if !r.HasAllItemsQty(p.CountItem) { + if !craftHasAllItemsQty(c, p.CountItem) { continue } - skillLevel := p.Level(player.SkillName(r.EffectiveSkill())) - if skillLevel < r.Level { + skillLevel := p.Level(player.SkillName(c.EffectiveSkill())) + if skillLevel < c.Level { continue } - filtered = append(filtered, r) + filtered = append(filtered, item) } if len(filtered) == 0 { sess.WriteLine("You can't smelt that here.") @@ -243,36 +238,35 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, g.promptHowMany(sess, filtered[0].ID) return } - sess.PendingMenu = recipeMenuData(recipeDefIDs(filtered)) - sess.State = net.StateRecipeChoice - var names []string - for _, r := range filtered { - names = append(names, g.recipeName(sess, &r)) - } - g.showMenuTable(sess, "What would you like to smelt?", names) - return + sess.PendingMenu = itemMenuData(itemIDs(filtered)) + sess.State = net.StateRecipeChoice + var names []string + for _, item := range filtered { + names = append(names, g.itemName(sess, item)) + } + g.showMenuTable(sess, "What would you like to smelt?", names) + return } - if recipes[0].Type == "smithing" { + if cType == "smithing" { if !g.hasToolType(p, "hammer") { sess.WriteLine("You need a hammer to smith.") return } - allRecipes, _ := g.RecipeStore.LoadAll() - g.showSmithTable(sess, p, itemAID, allRecipes) + g.showSmithTable(sess, p, itemAID) return } if len(recipes) == 1 { g.promptHowMany(sess, recipes[0].ID) return } - sess.PendingMenu = recipeMenuData(recipeDefIDs(recipes)) - sess.State = net.StateRecipeChoice - var names []string - for _, r := range recipes { - names = append(names, g.recipeName(sess, &r)) - } - g.showMenuTable(sess, fmt.Sprintf("What would you like to make with %s on the %s?", itemAName, def.Name), names) - return + sess.PendingMenu = itemMenuData(itemIDs(recipes)) + sess.State = net.StateRecipeChoice + var names []string + for _, item := range recipes { + names = append(names, g.itemName(sess, item)) + } + g.showMenuTable(sess, fmt.Sprintf("What would you like to make with %s on the %s?", itemAName, def.Name), names) + return } for _, ui := range def.UseInteractions { @@ -314,29 +308,19 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, itemBID := matchesB[0].ID - craftRecipes := g.findCraftRecipes(p, itemAID, itemBID) - fletchRecipes := g.findFletchRecipes(p, itemAID, itemBID) + craftItems := g.findCraftItems(p, itemAID, itemBID) + fletchItems := g.findFletchItems(p, itemAID, itemBID) - if len(craftRecipes) > 0 && len(fletchRecipes) > 0 { + if len(craftItems) > 0 && len(fletchItems) > 0 { var menu []map[string]string var names []string - for _, r := range craftRecipes { - menu = append(menu, map[string]string{"recipe_id": r.ID}) - outDef, _ := g.ItemStore.Load(r.Output) - name := r.Output - if outDef != nil { - name = outDef.Name - } - names = append(names, fmt.Sprintf("%s (Crafting)", name)) + for _, item := range craftItems { + menu = append(menu, map[string]string{"item_id": item.ID}) + names = append(names, fmt.Sprintf("%s (Crafting)", item.Name)) } - for _, r := range fletchRecipes { - menu = append(menu, map[string]string{"fletch_recipe_id": r.ID}) - outDef, _ := g.ItemStore.Load(r.Output) - name := r.Output - if outDef != nil { - name = outDef.Name - } - names = append(names, fmt.Sprintf("%s (Fletching)", name)) + for _, item := range fletchItems { + menu = append(menu, map[string]string{"item_id": item.ID}) + names = append(names, fmt.Sprintf("%s (Fletching)", item.Name)) } sess.PendingMenu = menu sess.State = net.StateRecipeChoice @@ -344,15 +328,15 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, return } - if len(craftRecipes) > 0 { - var available []action.RecipeDef - for _, r := range craftRecipes { - if g.canDoRecipe(p, &r, player.Crafting) { - available = append(available, r) + if len(craftItems) > 0 { + var available []*object.ItemDef + for _, item := range craftItems { + if g.canDoItem(p, item, player.Crafting) { + available = append(available, item) } } if len(available) == 1 { - g.startRecipe(sess, p, &available[0], 0, "last_craft") + g.startItem(sess, p, available[0], 0, "last_craft") return } if len(available) > 1 { @@ -361,15 +345,15 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, } } - if len(fletchRecipes) > 0 { - var available []action.RecipeDef - for _, r := range fletchRecipes { - if g.canDoFletchRecipe(p, &r) { - available = append(available, r) + if len(fletchItems) > 0 { + var available []*object.ItemDef + for _, item := range fletchItems { + if g.canDoFletchItem(p, item) { + available = append(available, item) } } if len(available) == 1 { - g.startFletchAction(sess, p, &available[0], 0) + g.startFletchAction(sess, p, available[0], 0) return } if len(available) > 1 { @@ -378,22 +362,33 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, } } - matched := g.findCombineResults(sess, p, itemAID, itemBID) - if len(matched) == 1 { - g.promptHowMany(sess, "combine_"+matched[0].ID) + matched := g.CraftIndex.FindByTwoInputs(itemAID, itemBID) + var matchable []*object.ItemDef + for _, item := range matched { + if craftHasAllItemsQty(item.FirstCraft(), p.CountItem) { + matchable = append(matchable, item) + } + } + if len(matchable) == 1 { + g.promptHowMany(sess, matchable[0].ID) return } - if len(matched) > 1 { - sess.PendingMenu = combineMenuData(matched) + if len(matchable) > 1 { + sess.PendingMenu = itemMenuData(itemIDs(matchable)) sess.State = net.StateRecipeChoice var names []string - for _, def := range matched { - names = append(names, g.itemColorize(sess, def, def.Name)) + for _, item := range matchable { + names = append(names, g.itemName(sess, item)) } g.showMenuTable(sess, "What would you like to make?", names) return } + if g.isGrimyHerb(itemAID) && itemBID == "vial_of_water" { + sess.WriteLine("Don't put a grimy herb in there! Clean it first!") + return + } + sess.WriteLine("You can't combine those items.") return } @@ -401,55 +396,16 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, sess.WriteLine(fmt.Sprintf("There's no '%s' here to use that on.", itemBName)) } -func (g *Game) findCombineResults(sess *net.Session, p *player.Player, itemAID, itemBID string) []*object.ItemDef { - items, err := g.ItemStore.LoadAll() - if err != nil { - return nil - } - var matched []*object.ItemDef - for _, def := range items { - if len(def.MadeFrom) == 0 { - continue - } - aEntry := -1 - bEntry := -1 - for ei, entry := range def.MadeFrom { - for _, id := range entry.Items { - if id == itemAID && aEntry < 0 { - aEntry = ei - } - if id == itemBID && bEntry < 0 { - bEntry = ei +func (g *Game) isGrimyHerb(itemID string) bool { + items := g.CraftIndex.ByType("clean") + for _, item := range items { + for _, e := range item.FirstCraft().Consume { + for _, id := range e.Items { + if id == itemID { + return true } } } - if aEntry >= 0 && bEntry >= 0 && aEntry != bEntry && madeFromAvailable(p, def.MadeFrom) { - matched = append(matched, def) - } } - return matched -} - -func combineMenuData(defs []*object.ItemDef) []map[string]string { - out := make([]map[string]string, len(defs)) - for i, d := range defs { - out[i] = map[string]string{"combine_item": d.ID} - } - return out -} - -func madeFromAvailable(p *player.Player, madeFrom []object.MadeFromEntry) bool { - for _, entry := range madeFrom { - found := false - for _, id := range entry.Items { - if p.HasItem(id) { - found = true - break - } - } - if !found { - return false - } - } - return true + return false } |
