package game import ( "strings" "thehouseoficarus/internal/behavior" "thehouseoficarus/internal/item" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" ) func (g *Game) executeFletch(sess *net.Session, args []string, rawInput string) { g.doFletch(sess, strings.Join(args, " ")) } var fletchLogItems = map[string]bool{ "logs": true, "oak_logs": true, "willow_logs": true, "maple_logs": true, "yew_logs": true, "magic_logs": true, } var fletchGemItems = map[string]bool{ "uncut_sapphire": true, "uncut_emerald": true, "uncut_ruby": true, "uncut_diamond": true, } func fletchNeedsKnife(def *item.ItemDef) bool { return def.FindCraft(func(c item.CraftDef) bool { if c.Tool == "knife" { return true } for _, e := range c.Ingredients { for _, id := range e.Items { if fletchLogItems[id] { if strings.Contains(def.ID, "shaft") || strings.Contains(def.ID, "bow") { return true } } } } return false }) != nil } func fletchNeedsChisel(def *item.ItemDef) bool { return def.FindCraft(func(c item.CraftDef) bool { if c.Tool == "chisel" { return true } for _, e := range c.Ingredients { for _, id := range e.Items { if fletchGemItems[id] { return true } } } return false }) != nil } func (g *Game) doFletch(sess *net.Session, input string) { p := sess.Player if g.Combat.Get(p.Name) != nil { sess.WriteLine("You can't do that during combat!") return } if p.Action != nil { p.Action = nil } items := g.CraftIndex.ByType("fletching") if input != "" { g.doFletchWithInput(sess, p, items, input) return } lastItemID, _ := p.Flags["last_fletch"].(string) if lastItemID != "" { for _, item := range items { if item.ID == lastItemID { if g.canDoFletchItem(p, item) { g.startFletchAction(sess, p, item, 0) return } break } } } available := g.availableFletchItems(p, items) if len(available) == 0 { sess.WriteLine("You don't have any materials to fletch.") return } if p.OptionBool("fletch_all") && len(available) == 1 { g.startFletchAction(sess, p, available[0], 0) return } g.showProductionTable(sess, p, available, "Fletching", "fletching", "last_fletch", "Fletch", true) } func (g *Game) doFletchWithInput(sess *net.Session, p *player.Player, items []*item.ItemDef, input string) { qty, productName := parseQty(input) productName = strings.TrimSpace(productName) var matched []*item.ItemDef for _, item := range items { if behavior.WordPrefixMatch(productName, item.Name) { matched = append(matched, item) } } if len(matched) == 0 { sess.WriteLine("You can't fletch that.") return } var available []*item.ItemDef for _, item := range matched { if g.canDoFletchItem(p, item) { available = append(available, item) } } if len(available) == 0 { sess.WriteLine("You don't have the materials for that.") return } if len(available) == 1 { g.startFletchAction(sess, p, available[0], qty) return } g.showProductionTable(sess, p, available, "Fletching", "fletching", "last_fletch", "Fletch", true) } func (g *Game) hasFletchTools(p *player.Player, item *item.ItemDef) bool { c := item.FirstCraft() if c.Tool != "" { return g.hasToolType(p, c.Tool) } if fletchNeedsKnife(item) && !g.hasToolType(p, "knife") { return false } if fletchNeedsChisel(item) && !g.hasToolType(p, "chisel") { return false } return true } func (g *Game) canDoFletchItem(p *player.Player, def *item.ItemDef) bool { return def.FindCraft(func(c item.CraftDef) bool { return p.Level(player.Fletching) >= c.Level && craftHasAllItemsQty(&c, p.CountItem) }) != nil && g.hasFletchTools(p, def) } func (g *Game) availableFletchItems(p *player.Player, allItems []*item.ItemDef) []*item.ItemDef { var result []*item.ItemDef for _, def := range allItems { match := def.FindCraft(func(c item.CraftDef) bool { return craftHasAllItemsQty(&c, p.CountItem) }) if match != nil && g.hasFletchTools(p, def) { result = append(result, def) } } return result } func (g *Game) findFletchItems(p *player.Player, itemAID, itemBID string) []*item.ItemDef { items := g.CraftIndex.ByType("fletching") toolTypeA := "" toolTypeB := "" if defA, _ := g.ItemStore.Load(itemAID); defA != nil { toolTypeA = defA.ToolType() } if defB, _ := g.ItemStore.Load(itemBID); defB != nil { toolTypeB = defB.ToolType() } isToolA := toolTypeA == "knife" || toolTypeA == "chisel" isToolB := toolTypeB == "knife" || toolTypeB == "chisel" var matched []*item.ItemDef for _, item := range items { c := item.FirstCraft() if c.Tool != "" { if c.Tool == toolTypeA && craftMatchesEntry(c, itemBID) { matched = append(matched, item) continue } if c.Tool == toolTypeB && craftMatchesEntry(c, itemAID) { matched = append(matched, item) continue } } aMatch := false bMatch := false for _, e := range c.Ingredients { for _, id := range e.Items { if id == itemAID { aMatch = true } if id == itemBID { bMatch = true } } } if aMatch && bMatch { matched = append(matched, item) continue } if isToolA && bMatch { if (fletchNeedsKnife(item) && toolTypeA == "knife") || (fletchNeedsChisel(item) && toolTypeA == "chisel") { matched = append(matched, item) continue } } if isToolB && aMatch { if (fletchNeedsKnife(item) && toolTypeB == "knife") || (fletchNeedsChisel(item) && toolTypeB == "chisel") { matched = append(matched, item) continue } } } return matched }