aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/game/action_production.go139
-rw-r--r--internal/game/cmd_cook.go21
-rw-r--r--internal/game/cmd_drop.go10
-rw-r--r--internal/game/cmd_eat.go5
-rw-r--r--internal/game/cmd_get.go10
-rw-r--r--internal/game/cmd_search.go5
-rw-r--r--internal/game/cmd_smelt.go21
-rw-r--r--internal/game/cmd_smith.go66
-rw-r--r--internal/game/cmd_use.go53
-rw-r--r--internal/game/utils.go14
10 files changed, 204 insertions, 140 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)
}
diff --git a/internal/game/cmd_cook.go b/internal/game/cmd_cook.go
index ce33ccd..b27b293 100644
--- a/internal/game/cmd_cook.go
+++ b/internal/game/cmd_cook.go
@@ -40,10 +40,7 @@ func (g *Game) doCook(sess *net.Session, input string) {
unique := uniqueItemNames(matches)
if len(unique) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range unique {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matches)
return
}
@@ -71,11 +68,11 @@ func (g *Game) doCook(sess *net.Session, input string) {
sess.PendingMenu = recipeMenuData(recipes)
sess.State = net.StateRecipeChoice
- sess.WriteLine(fmt.Sprintf("\nWhat would you like to cook on the %s?", stationName))
- for i, r := range recipes {
- sess.WriteLine(fmt.Sprintf(" %d) %s", i+1, g.recipeName(sess, &r)))
+ var names []string
+ for _, r := range recipes {
+ names = append(names, g.recipeName(sess, &r))
}
- sess.WriteLine(fmt.Sprintf(" %d) Nothing", len(recipes)+1))
+ g.showMenuTable(sess, fmt.Sprintf("What would you like to cook on the %s?", stationName), names)
}
func (g *Game) showCookMenu(sess *net.Session, p *player.Player, allRecipes []action.RecipeDef, stationDefID, stationName string) {
@@ -110,11 +107,11 @@ func (g *Game) showCookMenu(sess *net.Session, p *player.Player, allRecipes []ac
}
sess.State = net.StateRecipeChoice
- sess.WriteLine(fmt.Sprintf("\nWhat would you like to cook on the %s?", stationName))
- for i, e := range entries {
- sess.WriteLine(fmt.Sprintf(" %d) %s", i+1, e.ItemName))
+ var names []string
+ for _, e := range entries {
+ names = append(names, e.ItemName)
}
- sess.WriteLine(fmt.Sprintf(" %d) Nothing", len(entries)+1))
+ g.showMenuTable(sess, fmt.Sprintf("What would you like to cook on the %s?", stationName), names)
sess.PendingMenu = entryMenuData(entries)
}
diff --git a/internal/game/cmd_drop.go b/internal/game/cmd_drop.go
index 702d1db..1fd99b4 100644
--- a/internal/game/cmd_drop.go
+++ b/internal/game/cmd_drop.go
@@ -39,10 +39,7 @@ func (g *Game) doDropAllNamed(sess *net.Session, input string) {
unique := uniqueItemNames(matches)
if len(unique) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range unique {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matches)
return
}
@@ -102,10 +99,7 @@ func (g *Game) doDrop(sess *net.Session, input string) {
unique := uniqueItemNames(matches)
if len(unique) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range unique {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matches)
return
}
diff --git a/internal/game/cmd_eat.go b/internal/game/cmd_eat.go
index 9d4bfd0..6a74979 100644
--- a/internal/game/cmd_eat.go
+++ b/internal/game/cmd_eat.go
@@ -28,10 +28,7 @@ func (g *Game) doEat(sess *net.Session, input string) {
unique := uniqueItemNames(matches)
if len(unique) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range unique {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matches)
return
}
diff --git a/internal/game/cmd_get.go b/internal/game/cmd_get.go
index 8237ec9..6f08892 100644
--- a/internal/game/cmd_get.go
+++ b/internal/game/cmd_get.go
@@ -27,10 +27,7 @@ func (g *Game) doGet(sess *net.Session, input string) {
if len(matches) > 1 {
unique := uniqueItemNames(matches)
if len(unique) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range unique {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matches)
return
}
}
@@ -149,10 +146,7 @@ func (g *Game) doGetAllNamed(sess *net.Session, input string) {
if len(matches) > 1 {
unique := uniqueItemNames(matches)
if len(unique) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range unique {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matches)
return
}
}
diff --git a/internal/game/cmd_search.go b/internal/game/cmd_search.go
index d4d2e72..cf37c90 100644
--- a/internal/game/cmd_search.go
+++ b/internal/game/cmd_search.go
@@ -26,10 +26,7 @@ func (g *Game) doSearch(sess *net.Session, input string) {
unique := uniqueItemNames(matches)
if len(unique) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range unique {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matches)
return
}
diff --git a/internal/game/cmd_smelt.go b/internal/game/cmd_smelt.go
index e0889f6..1cd5436 100644
--- a/internal/game/cmd_smelt.go
+++ b/internal/game/cmd_smelt.go
@@ -37,10 +37,7 @@ func (g *Game) doSmelt(sess *net.Session, input string) {
unique := uniqueItemNames(matches)
if len(unique) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range unique {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matches)
return
}
@@ -69,11 +66,11 @@ func (g *Game) doSmelt(sess *net.Session, input string) {
sess.PendingMenu = recipeMenuData(recipes)
sess.State = net.StateRecipeChoice
- sess.WriteLine("\nWhat would you like to smelt?")
- for i, r := range recipes {
- sess.WriteLine(fmt.Sprintf(" %d) %s", i+1, g.recipeName(sess, &r)))
+ var names []string
+ for _, r := range recipes {
+ names = append(names, g.recipeName(sess, &r))
}
- sess.WriteLine(fmt.Sprintf(" %d) Nothing", len(recipes)+1))
+ g.showMenuTable(sess, "What would you like to smelt?", names)
}
func (g *Game) showSmeltMenu(sess *net.Session, p *player.Player, allRecipes []action.RecipeDef, stationDefID, stationName string) {
@@ -102,10 +99,10 @@ func (g *Game) showSmeltMenu(sess *net.Session, p *player.Player, allRecipes []a
}
sess.State = net.StateRecipeChoice
- sess.WriteLine("\nWhat would you like to smelt?")
- for i, e := range entries {
- sess.WriteLine(fmt.Sprintf(" %d) %s", i+1, e.ItemName))
+ var names []string
+ for _, e := range entries {
+ names = append(names, e.ItemName)
}
- sess.WriteLine(fmt.Sprintf(" %d) Nothing", len(entries)+1))
+ g.showMenuTable(sess, "What would you like to smelt?", names)
sess.PendingMenu = entryMenuData(entries)
}
diff --git a/internal/game/cmd_smith.go b/internal/game/cmd_smith.go
index 30dcddc..7fc14d2 100644
--- a/internal/game/cmd_smith.go
+++ b/internal/game/cmd_smith.go
@@ -3,6 +3,7 @@ package game
import (
"fmt"
"sort"
+ "strconv"
"strings"
"thehouseoficarus/internal/action"
@@ -10,6 +11,7 @@ import (
"thehouseoficarus/internal/net"
"thehouseoficarus/internal/object"
"thehouseoficarus/internal/player"
+ "thehouseoficarus/internal/world"
)
func (g *Game) doSmith(sess *net.Session, input string) {
@@ -41,10 +43,7 @@ func (g *Game) doSmith(sess *net.Session, input string) {
}
unique := uniqueItemNames(matches)
if len(unique) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range unique {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matches)
return
}
barID := matches[0].ID
@@ -69,16 +68,16 @@ func (g *Game) doSmith(sess *net.Session, input string) {
sess.PendingMenu = barMenuData(barTypes)
sess.State = net.StateRecipeChoice
- sess.WriteLine("\nWhich bars would you like to smith?")
- for i, barID := range barTypes {
+ var names []string
+ for _, barID := range barTypes {
def, _ := g.ItemStore.Load(barID)
name := barID
if def != nil {
name = g.itemColorize(sess, def, def.Name)
}
- sess.WriteLine(fmt.Sprintf(" %d) %s", i+1, name))
+ names = append(names, name)
}
- sess.WriteLine(fmt.Sprintf(" %d) Nothing", len(barTypes)+1))
+ g.showMenuTable(sess, "Which bars would you like to smith?", names)
}
func (g *Game) showSmithTable(sess *net.Session, p *player.Player, barID string, allRecipes []action.RecipeDef) {
@@ -111,22 +110,31 @@ func (g *Game) showSmithTable(sess *net.Session, p *player.Player, barID string,
tbl := &Table{
Title: titleCase(barName) + " Smithing",
- Columns: []string{"Product", "Inputs", "Level Req."},
+ Columns: []string{"#", "Product", "Inputs", "Level Req."},
}
- for _, r := range recipes {
+ for i, r := range recipes {
outDef, _ := g.ItemStore.Load(r.Output)
productName := r.Output
if outDef != nil {
productName = outDef.Name
}
+ outputQty := r.OutputQty
+ if outputQty <= 0 {
+ outputQty = 1
+ }
+ if outDef != nil && outDef.Stackable && outputQty > 1 {
+ productName = fmt.Sprintf("%s x%d", productName, outputQty)
+ }
+
bars := barsRequired(r, barID)
inputStr := "1 bar"
if bars > 1 {
inputStr = fmt.Sprintf("%d bars", bars)
}
levelStr := fmt.Sprint(r.Level)
+ numStr := fmt.Sprintf("%d", i+1)
canMake := barCount >= bars && skillLevel >= r.Level
if canMake {
@@ -135,9 +143,10 @@ func (g *Game) showSmithTable(sess *net.Session, p *player.Player, barID string,
productName = color.Render(mode, dimSpec, productName)
inputStr = color.Render(mode, dimSpec, inputStr)
levelStr = color.Render(mode, dimSpec, levelStr)
+ numStr = color.Render(mode, dimSpec, numStr)
}
- tbl.Rows = append(tbl.Rows, []string{productName, inputStr, levelStr})
+ tbl.Rows = append(tbl.Rows, []string{numStr, productName, inputStr, levelStr})
}
unicode := p.OptionBool("unicode")
@@ -190,6 +199,10 @@ func (g *Game) handleSmithProduct(sess *net.Session, input string) {
}
}
+ sort.Slice(recipes, func(i, j int) bool {
+ return recipes[i].Level < recipes[j].Level
+ })
+
var targetRecipe *action.RecipeDef
var count int
@@ -216,18 +229,29 @@ func (g *Game) handleSmithProduct(sess *net.Session, input string) {
} else {
qty, productName := parseQty(input)
count = qty
- productName = strings.ToLower(strings.TrimSpace(productName))
+ productName = strings.TrimSpace(productName)
- for i := range recipes {
- outDef, _ := g.ItemStore.Load(recipes[i].Output)
- name := recipes[i].Output
- if outDef != nil {
- name = outDef.Name
+ if idx, err := strconv.Atoi(productName); err == nil && idx > 0 && idx <= len(recipes) {
+ targetRecipe = &recipes[idx-1]
+ } else {
+ matchCount := 0
+ for i := range recipes {
+ outDef, _ := g.ItemStore.Load(recipes[i].Output)
+ name := recipes[i].Output
+ if outDef != nil {
+ name = outDef.Name
+ }
+ if world.WordPrefixMatch(productName, name) {
+ if matchCount == 0 {
+ targetRecipe = &recipes[i]
+ }
+ matchCount++
+ }
}
- lower := strings.ToLower(name)
- if lower == productName || strings.HasPrefix(lower, productName) {
- targetRecipe = &recipes[i]
- break
+ if matchCount > 1 {
+ sess.WriteLine("That's ambiguous.")
+ g.reprompt(sess)
+ return
}
}
diff --git a/internal/game/cmd_use.go b/internal/game/cmd_use.go
index cb521f3..7c7bca0 100644
--- a/internal/game/cmd_use.go
+++ b/internal/game/cmd_use.go
@@ -56,10 +56,7 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName,
uniqueA := uniqueItemNames(matchesA)
if len(uniqueA) > 1 {
- sess.WriteLine("Which one?")
- for _, name := range uniqueA {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
- }
+ g.showWhichOne(sess, matchesA)
return
}
@@ -102,14 +99,14 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName,
g.promptHowMany(sess, filtered[0].ID)
return
}
- sess.PendingMenu = recipeMenuData(filtered)
- sess.State = net.StateRecipeChoice
- sess.WriteLine("\nWhat would you like to smelt?")
- for i, r := range filtered {
- sess.WriteLine(fmt.Sprintf(" %d) %s", i+1, g.recipeName(sess, &r)))
- }
- sess.WriteLine(fmt.Sprintf(" %d) Nothing", len(filtered)+1))
- return
+ sess.PendingMenu = recipeMenuData(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
}
if recipes[0].Type == "smithing" {
if !g.hasToolType(p, "hammer") {
@@ -124,13 +121,14 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName,
g.promptHowMany(sess, recipes[0].ID)
return
}
- sess.PendingMenu = recipeMenuData(recipes)
- sess.State = net.StateRecipeChoice
- sess.WriteLine(fmt.Sprintf("\nWhat would you like to make with %s on the %s?", itemAName, def.Name))
- for i, r := range recipes {
- sess.WriteLine(fmt.Sprintf(" %d) %s", i+1, g.recipeName(sess, &r)))
- }
- return
+ sess.PendingMenu = recipeMenuData(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
}
for _, ui := range def.UseInteractions {
@@ -158,8 +156,14 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName,
uniqueB := uniqueItemNames(matchesB)
if len(uniqueB) > 1 {
sess.WriteLine("Which '" + itemBName + "'?")
- for _, name := range uniqueB {
- sess.WriteLine(fmt.Sprintf(" - %s", name))
+ seen := make(map[string]bool)
+ for _, m := range matchesB {
+ if seen[m.Name] {
+ continue
+ }
+ seen[m.Name] = true
+ def, _ := g.ItemStore.Load(m.ID)
+ sess.WriteLine(fmt.Sprintf(" - %s", g.itemColorize(sess, def, m.Name)))
}
return
}
@@ -174,10 +178,11 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName,
if len(matched) > 1 {
sess.PendingMenu = combineMenuData(matched)
sess.State = net.StateRecipeChoice
- sess.WriteLine("\nWhat would you like to make?")
- for i, def := range matched {
- sess.WriteLine(fmt.Sprintf(" %d) %s", i+1, g.itemColorize(sess, def, def.Name)))
+ var names []string
+ for _, def := range matched {
+ names = append(names, g.itemColorize(sess, def, def.Name))
}
+ g.showMenuTable(sess, "What would you like to make?", names)
return
}
diff --git a/internal/game/utils.go b/internal/game/utils.go
index 2379fc2..55e48c6 100644
--- a/internal/game/utils.go
+++ b/internal/game/utils.go
@@ -60,6 +60,20 @@ func uniqueItemNames(matches []itemMatch) []string {
return out
}
+func (g *Game) showWhichOne(sess *net.Session, matches []itemMatch) {
+ sess.WriteLine("Which one?")
+ seen := make(map[string]bool)
+ for _, m := range matches {
+ if seen[m.Name] {
+ continue
+ }
+ seen[m.Name] = true
+ def, _ := g.ItemStore.Load(m.ID)
+ coloredName := g.itemColorize(sess, def, m.Name)
+ sess.WriteLine(fmt.Sprintf(" - %s", coloredName))
+ }
+}
+
func randInt(max int) int {
if max <= 0 {
return 0