aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_use.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/cmd_use.go')
-rw-r--r--internal/game/cmd_use.go151
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 {