aboutsummaryrefslogtreecommitdiff
path: root/internal/game/action_production.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/action_production.go')
-rw-r--r--internal/game/action_production.go139
1 files changed, 92 insertions, 47 deletions
diff --git a/internal/game/action_production.go b/internal/game/action_production.go
index c0b76f3..0b8ca45 100644
--- a/internal/game/action_production.go
+++ b/internal/game/action_production.go
@@ -11,6 +11,7 @@ import (
"thehouseoficarus/internal/net"
"thehouseoficarus/internal/object"
"thehouseoficarus/internal/player"
+ "thehouseoficarus/internal/world"
)
type recipeEntry struct {
@@ -40,6 +41,19 @@ func (g *Game) promptHowMany(sess *net.Session, recipeID string) {
sess.Write("How many (return for all)?: ")
}
+func (g *Game) showMenuTable(sess *net.Session, title string, names []string) {
+ p := sess.Player.(*player.Player)
+ tbl := &Table{Title: title}
+ for i, name := range names {
+ tbl.Rows = append(tbl.Rows, []string{fmt.Sprintf("%d", i+1), name})
+ }
+ unicode := p.OptionBool("unicode")
+ sess.WriteLine("")
+ for _, line := range tbl.Render(unicode) {
+ sess.WriteLine(line)
+ }
+}
+
func (g *Game) handleHowMany(sess *net.Session, input string) {
p := sess.Player.(*player.Player)
recipeID := sess.PendingRecipeID
@@ -120,35 +134,18 @@ func (g *Game) startProduction(sess *net.Session, p *player.Player, recipe *acti
skillLevel := p.Level(player.SkillName(recipe.Skill))
if skillLevel < recipe.Level {
sess.WriteLine(fmt.Sprintf("You need level %d %s to do that.", recipe.Level, recipe.Skill))
+ g.reprompt(sess)
return
}
}
if !recipe.HasAllItemsQty(p.CountItem) {
sess.WriteLine("You don't have the required materials.")
+ g.reprompt(sess)
return
}
- outputQty := recipe.OutputQty
- if outputQty <= 0 {
- outputQty = 1
- }
-
- canPlace := false
outDef, _ := g.ItemStore.Load(recipe.Output)
- if outDef != nil && outDef.Stackable {
- for i := 0; i < 28; i++ {
- slot := p.InvSlot(i)
- if slot != nil && slot.ItemID == recipe.Output {
- canPlace = true
- break
- }
- }
- }
- if !canPlace && p.FirstFreeSlot() == -1 {
- sess.WriteLine("Your inventory is too full!")
- return
- }
wait := recipe.Wait
if wait <= 0 {
@@ -297,13 +294,13 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool {
}
}
if !placed {
+ recipe.ConsumeAll(p.HasItem, p.RemoveItem)
freeSlot := p.FirstFreeSlot()
if freeSlot == -1 {
sess.WriteLine("Your inventory is too full!")
g.CancelAction(p)
return false
}
- recipe.ConsumeAll(p.HasItem, p.RemoveItem)
p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: recipe.Output, Quantity: outputQty})
}
@@ -413,55 +410,103 @@ func (g *Game) canContinueProduction(p *player.Player, recipe *action.RecipeDef)
func (g *Game) handleRecipeChoice(sess *net.Session, input string) {
input = strings.TrimSpace(input)
- if input == "" {
+
+ menuData := sess.PendingMenu
+ if len(menuData) == 0 {
+ sess.State = net.StateGame
+ g.reprompt(sess)
return
}
- choice, err := strconv.Atoi(input)
- if err != nil {
- sess.State = net.StateGame
+ if input == "" {
sess.PendingMenu = nil
+ sess.State = net.StateGame
sess.WriteLine("Never mind.")
g.reprompt(sess)
return
}
- if len(sess.PendingMenu) > 0 {
- menuData := sess.PendingMenu
+ if choice, err := strconv.Atoi(input); err == nil {
sess.PendingMenu = nil
- if choice <= 0 || choice > len(menuData)+1 {
- sess.WriteLine("Invalid choice.")
- return
- }
sess.State = net.StateGame
- if choice == len(menuData)+1 {
+ if choice <= 0 || choice > len(menuData) {
sess.WriteLine("Never mind.")
g.reprompt(sess)
return
}
- entry := menuData[choice-1]
+ g.dispatchMenuEntry(sess, menuData[choice-1])
+ return
+ }
- if cid, ok := entry["combine_item"]; ok {
- g.promptHowMany(sess, "combine_"+cid)
- return
+ lower := strings.ToLower(input)
+ matchIdx := -1
+ for i, entry := range menuData {
+ name := g.menuEntryName(entry)
+ if name == "" {
+ continue
}
-
- if barID, ok := entry["bar_id"]; ok {
- p := sess.Player.(*player.Player)
- allRecipes, _ := g.RecipeStore.LoadAll()
- g.showSmithTable(sess, p, barID, allRecipes)
- return
+ if strings.ToLower(name) == lower || world.WordPrefixMatch(input, name) {
+ if matchIdx >= 0 {
+ sess.WriteLine("That's ambiguous.")
+ return
+ }
+ matchIdx = i
}
+ }
+ if matchIdx >= 0 {
+ sess.PendingMenu = nil
+ sess.State = net.StateGame
+ g.dispatchMenuEntry(sess, menuData[matchIdx])
+ return
+ }
- if rid, ok := entry["recipe_id"]; ok {
- g.promptHowMany(sess, rid)
- return
+ sess.PendingMenu = nil
+ sess.State = net.StateGame
+ sess.WriteLine("Never mind.")
+ g.reprompt(sess)
+}
+
+func (g *Game) menuEntryName(entry map[string]string) string {
+ if rid, ok := entry["recipe_id"]; ok {
+ all, _ := g.RecipeStore.LoadAll()
+ for _, r := range all {
+ if r.ID == rid {
+ if def, err := g.ItemStore.Load(r.Output); err == nil {
+ return def.Name
+ }
+ return r.Output
+ }
+ }
+ }
+ if barID, ok := entry["bar_id"]; ok {
+ if def, _ := g.ItemStore.Load(barID); def != nil {
+ return def.Name
+ }
+ return barID
+ }
+ if cid, ok := entry["combine_item"]; ok {
+ if def, _ := g.ItemStore.Load(cid); def != nil {
+ return def.Name
}
+ return cid
+ }
+ return ""
+}
- g.reprompt(sess)
+func (g *Game) dispatchMenuEntry(sess *net.Session, entry map[string]string) {
+ if cid, ok := entry["combine_item"]; ok {
+ g.promptHowMany(sess, "combine_"+cid)
+ return
+ }
+ if barID, ok := entry["bar_id"]; ok {
+ p := sess.Player.(*player.Player)
+ allRecipes, _ := g.RecipeStore.LoadAll()
+ g.showSmithTable(sess, p, barID, allRecipes)
+ return
+ }
+ if rid, ok := entry["recipe_id"]; ok {
+ g.promptHowMany(sess, rid)
return
}
-
- sess.State = net.StateGame
g.reprompt(sess)
}