aboutsummaryrefslogtreecommitdiff
path: root/internal/game/act_talk.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/act_talk.go')
-rw-r--r--internal/game/act_talk.go119
1 files changed, 85 insertions, 34 deletions
diff --git a/internal/game/act_talk.go b/internal/game/act_talk.go
index e9047b2..f54290a 100644
--- a/internal/game/act_talk.go
+++ b/internal/game/act_talk.go
@@ -6,6 +6,7 @@ import (
"strings"
"thehouseoficarus/internal/behavior"
+ "thehouseoficarus/internal/color"
"thehouseoficarus/internal/net"
"thehouseoficarus/internal/object"
"thehouseoficarus/internal/player"
@@ -52,51 +53,99 @@ func (g *Game) startTalk(sess *net.Session, p *player.Player, obj *object.Object
}
}
+func (g *Game) handleNodeAction(sess *net.Session, na *behavior.NodeAction) (intercepted bool) {
+ if na.Shop != nil {
+ g.applyNodeAction(sess, na)
+ g.enterShop(sess, na.Shop)
+ return true
+ }
+ g.applyNodeAction(sess, na)
+
+ if v, ok := g.Flags.Get("guard_hostile"); ok && v != nil {
+ g.Flags.Delete("guard_hostile")
+ p := sess.Player
+ if p != nil && p.Action != nil {
+ if td, ok := p.Action.Data.(*behavior.TalkData); ok && td.StealGuard {
+ guardMob := g.findGuardInRoom(p.RoomID, "guard")
+ if guardMob != nil {
+ sess.State = net.StateGame
+ g.cancelAction(p)
+ guardMob.Protected = false
+ g.startCombat(sess, p, guardMob)
+ }
+ return true
+ }
+ }
+ }
+ return false
+}
+
func (g *Game) showTalkNode(sess *net.Session, node behavior.TalkNode) {
- sess.WriteLine(fmt.Sprintf("%s", g.colorize(sess, "dialog", node.Message)))
+ p := sess.Player
+ td, _ := p.Action.Data.(*behavior.TalkData)
+
+ dialogSpec := g.resolveColor(sess, "dialog")
+ msg := node.Message.Pick()
+ if msg != "" {
+ sess.WriteLine(color.ExpandTagsDefault(g.colorMode(sess), dialogSpec, msg))
+ }
if node.Action != nil {
- if node.Action.Shop != nil {
- g.applyNodeAction(sess, node.Action)
- g.enterShop(sess, node.Action.Shop)
+ if g.handleNodeAction(sess, node.Action) {
+ return
+ }
+ }
+
+ cfg := td.Cfg
+ for {
+ visible := g.visibleOptions(sess, node.Options)
+ if len(visible) > 0 {
+ for i, opt := range visible {
+ sess.WriteLine(fmt.Sprintf(" %d. %s", i+1, opt.Text))
+ }
+ sess.State = net.StateTalk
+ sess.Write("\nChoice: ")
return
}
- g.applyNodeAction(sess, node.Action)
-
- if v, ok := g.Flags.Get("guard_hostile"); ok && v != nil {
- g.Flags.Delete("guard_hostile")
- p := sess.Player
- if p != nil && p.Action != nil {
- if td, ok := p.Action.Data.(*behavior.TalkData); ok && td.StealGuard {
- guardMob := g.findGuardInRoom(p.RoomID, "guard")
- if guardMob != nil {
- sess.State = net.StateGame
- g.cancelAction(p)
- guardMob.Protected = false
- g.startCombat(sess, p, guardMob)
- }
+
+ if node.Next != "" && cfg != nil {
+ next, ok := cfg.Nodes[node.Next]
+ if !ok {
+ break
+ }
+ if td != nil {
+ td.Node = node.Next
+ }
+ node = next
+
+ msg := node.Message.Pick()
+ if msg != "" {
+ sess.WriteLine(color.ExpandTagsDefault(g.colorMode(sess), dialogSpec, msg))
+ }
+
+ if node.Action != nil {
+ if g.handleNodeAction(sess, node.Action) {
return
}
}
+ } else {
+ break
}
}
- if len(node.Options) == 0 {
- sess.State = net.StateGame
- g.writePrompt(sess)
- return
- }
+ sess.State = net.StateGame
+ g.writePrompt(sess)
+}
- visible := 0
- for _, opt := range node.Options {
+func (g *Game) visibleOptions(sess *net.Session, options []behavior.TalkOption) []behavior.TalkOption {
+ var visible []behavior.TalkOption
+ for _, opt := range options {
if opt.Condition != nil && !g.checkCondition(sess, opt.Condition) {
continue
}
- visible++
- sess.WriteLine(fmt.Sprintf(" %d. %s", visible, opt.Text))
+ visible = append(visible, opt)
}
- sess.State = net.StateTalk
- sess.Write("\nChoice: ")
+ return visible
}
func (g *Game) handleTalkInput(sess *net.Session, input string) {
@@ -108,6 +157,9 @@ func (g *Game) handleTalkInput(sess *net.Session, input string) {
}
input = strings.TrimSpace(input)
+ if input == "" {
+ input = "1"
+ }
lower := strings.ToLower(input)
if lower == "bye" || lower == "exit" || lower == "end" || lower == "quit" {
g.cancelAction(p)
@@ -168,11 +220,10 @@ func (g *Game) handleTalkInput(sess *net.Session, input string) {
return
}
- if chosen.End {
- g.cancelAction(p)
- sess.State = net.StateGame
- g.writePrompt(sess)
- return
+ if chosen.Action != nil {
+ if g.handleNodeAction(sess, chosen.Action) {
+ return
+ }
}
if chosen.Goto != "" {