diff options
Diffstat (limited to 'internal/game/cmd_craft.go')
| -rw-r--r-- | internal/game/cmd_craft.go | 185 |
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 |
