aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_move.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/cmd_move.go')
-rw-r--r--internal/game/cmd_move.go35
1 files changed, 29 insertions, 6 deletions
diff --git a/internal/game/cmd_move.go b/internal/game/cmd_move.go
index 2f27eed..d05146a 100644
--- a/internal/game/cmd_move.go
+++ b/internal/game/cmd_move.go
@@ -4,11 +4,13 @@ import (
"fmt"
"strings"
+ "thehouseoficarus/internal/behavior"
"thehouseoficarus/internal/engine"
"thehouseoficarus/internal/item"
"thehouseoficarus/internal/net"
"thehouseoficarus/internal/object"
"thehouseoficarus/internal/player"
+ "thehouseoficarus/internal/world"
)
func (g *Game) doMove(sess *net.Session, dir string, multiplier float64) {
@@ -67,8 +69,11 @@ func (g *Game) doMove(sess *net.Session, dir string, multiplier float64) {
}
}
- p.MovePendingGlobalFlags = exitDef.SetGlobalFlags
- p.MovePendingPlayerFlags = exitDef.SetPlayerFlags
+ // Stash the first on_traverse interaction whose condition passes — it will
+ // fire in completeMove once the player arrives. ExitDef.Condition (above,
+ // evaluated by exitDisplayState) gates whether the exit is passable at
+ // all; each on_traverse entry has its own additional Condition gate.
+ p.MovePendingInteraction = g.matchExitInteraction(sess, p, exitDef)
inCombat := g.Combat.Get(p.Name) != nil
@@ -96,6 +101,21 @@ func (g *Game) doMove(sess *net.Session, dir string, multiplier float64) {
}
}
+// matchExitInteraction returns the first on_traverse Interaction on exitDef
+// whose Condition (if any) passes for this player, or nil if the exit has no
+// on_traverse entries. The matched interaction's Action fires (with its optional
+// Message) once the player arrives in the target room.
+func (g *Game) matchExitInteraction(sess *net.Session, p *player.Player, exitDef world.ExitDef) *behavior.Interaction {
+ for i := range exitDef.OnTraverse {
+ it := &exitDef.OnTraverse[i]
+ if it.Condition != nil && !g.checkCondition(sess, it.Condition) {
+ continue
+ }
+ return it
+ }
+ return nil
+}
+
var gracefulItems = map[string]bool{
"graceful_hat": true,
"graceful_torso": true,
@@ -132,8 +152,7 @@ func (g *Game) moveTicks(p *player.Player, multiplier float64) int {
func (g *Game) completeMove(sess *net.Session, p *player.Player) {
exitDir := p.MoveDirection
targetID := p.MoveTarget
- pendingGlobalFlags := p.MovePendingGlobalFlags
- pendingPlayerFlags := p.MovePendingPlayerFlags
+ pendingInteraction := p.MovePendingInteraction
p.ClearMoveState()
@@ -163,8 +182,12 @@ func (g *Game) completeMove(sess *net.Session, p *player.Player) {
if p.EnterSeqRoom != 0 && p.EnterSeqRoom == oldRoom {
p.EnterSeqRoom = 0
}
- if len(pendingGlobalFlags) > 0 || len(pendingPlayerFlags) > 0 {
- g.applyFlagMutations(p, pendingGlobalFlags, pendingPlayerFlags)
+ // Fire the on_traverse interaction (if any matched at classification
+ // time) AFTER p.RoomID is set to the new room, so effect fields like
+ // aps_node / teleport operate on the destination as their reference frame.
+ if pendingInteraction != nil {
+ g.writePlayerMessage(sess, pendingInteraction.Message, p.Name, nil)
+ g.applyStepAction(sess, p, pendingInteraction.Action, p.RoomID, scopePlayer, nil)
}
g.AccountStore.SaveCharacter(p)