aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_move.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-09 22:15:54 -0400
committerhistoria <[not public]>2026-07-09 22:15:54 -0400
commitecba7f726f70b37126d852c38c7e3eec7b04d730 (patch)
tree9129215c6e5015336fde1116395336d82bb952d1 /internal/game/cmd_move.go
parentb3d4c616f59ad2519f3a0b77e3b47d6571cd2486 (diff)
downloadthehouseoficarus-ecba7f726f70b37126d852c38c7e3eec7b04d730.tar.gz
feat: old standalone trigger systems completely unified into trigger->condition->action system
Diffstat (limited to 'internal/game/cmd_move.go')
-rw-r--r--internal/game/cmd_move.go45
1 files changed, 26 insertions, 19 deletions
diff --git a/internal/game/cmd_move.go b/internal/game/cmd_move.go
index 4391b1f..2967e79 100644
--- a/internal/game/cmd_move.go
+++ b/internal/game/cmd_move.go
@@ -73,7 +73,7 @@ func (g *Game) doMove(sess *net.Session, dir string, multiplier float64) {
// 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)
+ p.MovePendingTrigger = g.matchExitTrigger(sess, p, exitDef)
inCombat := g.Combat.Get(p.Name) != nil
@@ -101,17 +101,17 @@ 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 {
+// matchExitTrigger returns the first on_traverse Trigger on exitDef whose
+// Condition (and item filter, n/a for traverse) passes for this player, or nil
+// if the exit has no matching on_traverse entry. The matched trigger's Steps
+// run as a sequence once the player arrives in the target room.
+func (g *Game) matchExitTrigger(sess *net.Session, p *player.Player, exitDef world.ExitDef) *behavior.Trigger {
for i := range exitDef.OnTraverse {
- it := &exitDef.OnTraverse[i]
- if it.Condition != nil && !g.checkCondition(sess, it.Condition) {
+ t := &exitDef.OnTraverse[i]
+ if t.Condition != nil && !g.checkCondition(sess, t.Condition) {
continue
}
- return it
+ return t
}
return nil
}
@@ -152,7 +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
- pendingInteraction := p.MovePendingInteraction
+ pendingTrigger := p.MovePendingTrigger
p.ClearMoveState()
@@ -174,19 +174,26 @@ func (g *Game) completeMove(sess *net.Session, p *player.Player) {
}
}
}
+
+ // Interruptable: an unlocked in-flight verb sequence is cancelled by the
+ // move. (Locked sequences block movement entirely at the command router.)
+ g.cancelUnlockedSequences(p.Name)
+
+ // Fire the on_exit block of the room being left BEFORE updating RoomID, so
+ // the exit scene resolves against the old room.
+ if oldRoom != targetID {
+ g.runExitSteps(sess, oldRoom)
+ }
+
p.RoomID = targetID
p.HazardTimer = 0
p.Stats.RecordRoomVisit(targetID)
- g.cancelEnterSeq(p.Name)
- if p.EnterSeqRoom != 0 && p.EnterSeqRoom == oldRoom {
- p.EnterSeqRoom = 0
- }
- // 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.runInteraction(sess, p, pendingInteraction.Action, p.RoomID, scopePlayer, nil)
+ // Fire the on_traverse trigger (if any matched at classification time)
+ // AFTER p.RoomID is set to the new room, so effects like aps_node/teleport
+ // operate on the destination as their reference frame.
+ if pendingTrigger != nil {
+ g.runTrigger(sess, p, []behavior.Trigger{*pendingTrigger}, p.RoomID, nil, false)
}
g.AccountStore.SaveCharacter(p)