diff options
Diffstat (limited to 'internal/game/cmd_use.go')
| -rw-r--r-- | internal/game/cmd_use.go | 151 |
1 files changed, 142 insertions, 9 deletions
diff --git a/internal/game/cmd_use.go b/internal/game/cmd_use.go index 95a7b5b..fbe5945 100644 --- a/internal/game/cmd_use.go +++ b/internal/game/cmd_use.go @@ -16,8 +16,8 @@ func (g *Game) doUse(sess *net.Session, input string) { return } - p := sess.Player.(*player.Player) - g.CancelAction(p) + p := sess.Player + g.cancelAction(p) if g.tryRecharge(sess, p, input) { return @@ -50,11 +50,144 @@ func (g *Game) doUse(sess *net.Session, input string) { } if len(strings.Fields(input)) >= 2 { + if g.useRoomObject(sess, p, input) { + return + } g.doUseItemOnTarget(sess, p, strings.Fields(input)[0], strings.Join(strings.Fields(input)[1:], " ")) return } - g.StartAction(sess, "use", input) + if g.useRoomObject(sess, p, input) { + return + } + + g.startAction(sess, "use", input) +} + +func (g *Game) useRoomObject(sess *net.Session, p *player.Player, input string) bool { + objInstances := g.World.FindObjInstances(p.RoomID, input) + if len(objInstances) == 0 { + return false + } + objSt := &objInstances[0] + def, _ := g.ObjectStore.Load(objSt.DefID) + if def == nil { + return false + } + recipes := g.stationRecipes(p, objSt.DefID) + if len(recipes) > 0 { + g.showStationRecipeMenu(sess, p, recipes, def.Name) + return true + } + bt := def.BehaviorType() + if bt != "" { + g.startAction(sess, bt, def.Name) + return true + } + for _, ui := range def.UseInteractions { + if ui.Item != "" { + continue + } + if ui.Condition != nil && !g.checkCondition(sess, ui.Condition) { + continue + } + if ui.Message != "" { + sess.WriteLine(ui.Message) + } + if ui.Action != nil { + g.applyNodeAction(sess, ui.Action) + } + p.ActionState = &ActionState{Type: ActionUsing, TargetName: def.Name} + if g.Hub != nil { + for _, other := range g.Hub.PlayersInRoom(p.RoomID) { + if other != sess && other.Player != nil { + other.WriteLine(g.colorize(other, "broadcast", fmt.Sprintf("\n%s uses the %s.", p.Name, def.Name))) + } + } + } + return true + } + if len(def.UseInteractions) > 0 { + sess.WriteLine(fmt.Sprintf("Use what on the %s?", def.Name)) + return true + } + sess.WriteLine(fmt.Sprintf("You can't use the %s.", def.Name)) + 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 { + continue + } + if !r.HasAllItemsQty(p.CountItem) { + continue + } + skillName := player.SkillName(r.EffectiveSkill()) + if p.Level(skillName) < r.Level { + continue + } + if r.Tool != "" && !g.hasToolType(p, r.Tool) { + continue + } + if stationDefID == "anvil" && !g.hasToolType(p, "hammer") { + continue + } + results = append(results, r) + } + return results +} + +func (g *Game) showStationRecipeMenu(sess *net.Session, p *player.Player, recipes []action.RecipeDef, stationName string) { + if len(recipes) == 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) + return + } + needTypes := false + for i := range recipes { + for j := i + 1; j < len(recipes); j++ { + if recipes[i].Type != recipes[j].Type { + needTypes = true + break + } + } + if needTypes { + break + } + } + menu := recipeMenuData(recipeDefIDs(recipes)) + sess.PendingMenu = menu + sess.State = net.StateRecipeChoice + var names []string + for _, r := range recipes { + name := g.recipeName(sess, &r) + if needTypes { + typeLabel := strings.ToUpper(r.Type[:1]) + r.Type[1:] + names = append(names, fmt.Sprintf("%s (%s)", name, typeLabel)) + } else { + names = append(names, name) + } + } + g.showMenuTable(sess, fmt.Sprintf("What would you like to make at the %s?", stationName), names) } func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, itemBName string) { @@ -79,7 +212,7 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, objSt := &objInstances[0] def, _ := g.ObjectStore.Load(objSt.DefID) if def == nil { - g.StartAction(sess, "use", itemBName) + g.startAction(sess, "use", itemBName) return } @@ -109,7 +242,7 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, g.promptHowMany(sess, filtered[0].ID) return } - sess.PendingMenu = recipeMenuData(filtered) + sess.PendingMenu = recipeMenuData(recipeDefIDs(filtered)) sess.State = net.StateRecipeChoice var names []string for _, r := range filtered { @@ -131,7 +264,7 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, g.promptHowMany(sess, recipes[0].ID) return } - sess.PendingMenu = recipeMenuData(recipes) + sess.PendingMenu = recipeMenuData(recipeDefIDs(recipes)) sess.State = net.StateRecipeChoice var names []string for _, r := range recipes { @@ -157,7 +290,7 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, return } - g.StartAction(sess, "use", itemBName) + g.startAction(sess, "use", itemBName) return } @@ -213,12 +346,12 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, if len(craftRecipes) > 0 { var available []action.RecipeDef for _, r := range craftRecipes { - if g.canDoCraftRecipe(p, &r) { + if g.canDoGenericRecipe(p, &r, player.Crafting) { available = append(available, r) } } if len(available) == 1 { - g.startCraftRecipe(sess, p, &available[0], 0) + g.startGenericRecipe(sess, p, &available[0], 0, "last_craft") return } if len(available) > 1 { |
