aboutsummaryrefslogtreecommitdiff
path: root/internal/game/action_room.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-25 15:40:48 -0400
committerhistoria <[not public]>2026-06-25 15:40:48 -0400
commitabd612c15799f604e671e83dc7c410ed2b44185f (patch)
tree0597ca92350de73aac2a7cf26b2f2d6595dac0cc /internal/game/action_room.go
parent2725e2927a1595c7b100d942d1f14146252adeb7 (diff)
downloadthehouseoficarus-abd612c15799f604e671e83dc7c410ed2b44185f.tar.gz
slop refactor
Diffstat (limited to 'internal/game/action_room.go')
-rw-r--r--internal/game/action_room.go220
1 files changed, 0 insertions, 220 deletions
diff --git a/internal/game/action_room.go b/internal/game/action_room.go
deleted file mode 100644
index 86c1737..0000000
--- a/internal/game/action_room.go
+++ /dev/null
@@ -1,220 +0,0 @@
-package game
-
-import (
- "fmt"
- "strings"
-
- "thehouseoficarus/internal/net"
- "thehouseoficarus/internal/player"
- "thehouseoficarus/internal/world"
-)
-
-// enterSeq is an in-flight on_enter cutscene for a single player. It is driven
-// one step at a time by EnterSeqTick.
-type enterSeq struct {
- sess *net.Session
- playerName string
- roomID int
- steps []world.EnterStep
- wait int
- started bool
-}
-
-// runEnterSteps evaluates a room's on_enter script for the player. Steps whose
-// condition fails are dropped. If none of the surviving steps are "timed"
-// (no delay, no flag mutation) the messages are printed synchronously, exactly
-// as before. Otherwise the surviving steps become a scheduled cutscene driven
-// by EnterSeqTick.
-func (g *Game) runEnterSteps(sess *net.Session, roomID int) {
- room, err := g.World.LoadRoom(roomID)
- if err != nil || len(room.OnEnter) == 0 {
- return
- }
- p := sess.Player
- if p == nil {
- return
- }
-
- var steps []world.EnterStep
- cutscene := false
- for _, step := range room.OnEnter {
- if step.Condition != nil && !g.checkCondition(sess, step.Condition) {
- continue
- }
- steps = append(steps, step)
- if step.IsTimed() {
- cutscene = true
- }
- }
- if len(steps) == 0 {
- return
- }
-
- if !cutscene {
- for _, step := range steps {
- if step.Message != "" {
- sess.WriteLine(step.Message)
- }
- }
- return
- }
-
- g.startEnterCutscene(sess, p, roomID, steps)
-}
-
-// startEnterCutscene registers a scheduled on_enter sequence and persists a
-// marker on the player so the cutscene can be resumed on reconnect if it is
-// interrupted (disconnect, server restart).
-func (g *Game) startEnterCutscene(sess *net.Session, p *player.Player, roomID int, steps []world.EnterStep) {
- g.cancelEnterSeq(p.Name)
- if p.CutsceneRoom != roomID {
- p.CutsceneRoom = roomID
- g.AccountStore.SaveCharacter(p)
- }
- g.enterMu.Lock()
- g.enterSeqs[p.Name] = &enterSeq{
- sess: sess,
- playerName: p.Name,
- roomID: roomID,
- steps: steps,
- wait: steps[0].Delay,
- }
- g.enterMu.Unlock()
-}
-
-// EnterSeqTick advances every in-flight cutscene by one tick. Sequences for a
-// player who is no longer connected are paused (left for resume); sequences are
-// removed from the map on completion or cancellation.
-func (g *Game) EnterSeqTick() {
- g.enterMu.Lock()
- seqs := make([]*enterSeq, 0, len(g.enterSeqs))
- for _, s := range g.enterSeqs {
- seqs = append(seqs, s)
- }
- g.enterMu.Unlock()
-
- for _, seq := range seqs {
- if !g.isCharLive(seq.playerName, seq.sess) {
- continue
- }
-
- var jobs []world.EnterStep
- done := false
-
- g.enterMu.Lock()
- if g.enterSeqs[seq.playerName] != seq {
- g.enterMu.Unlock()
- continue
- }
- seq.wait--
- for seq.wait <= 0 && len(seq.steps) > 0 {
- step := seq.steps[0]
- seq.steps = seq.steps[1:]
- jobs = append(jobs, step)
- if len(seq.steps) > 0 {
- seq.wait = seq.steps[0].Delay
- } else {
- seq.wait = 0
- }
- }
- if len(seq.steps) == 0 {
- done = true
- delete(g.enterSeqs, seq.playerName)
- }
- g.enterMu.Unlock()
-
- for _, step := range jobs {
- g.fireEnterStep(seq, step)
- }
- if done {
- g.completeEnterSeq(seq)
- }
- }
-}
-
-func (g *Game) fireEnterStep(seq *enterSeq, step world.EnterStep) {
- p := seq.sess.Player
- if p == nil || p.RoomID != seq.roomID {
- return
- }
- if step.Message != "" {
- // Break from the prompt on the first line only, so a multi-line
- // cutscene reads as tight consecutive lines.
- if !seq.started {
- seq.sess.WriteLine("\n" + step.Message)
- seq.started = true
- } else {
- seq.sess.WriteLine(step.Message)
- }
- }
- if len(step.SetFlags) > 0 || len(step.SetPlayerFlags) > 0 {
- g.applyFlagMutations(p, step.SetFlags, step.SetPlayerFlags)
- g.AccountStore.SaveCharacter(p)
- }
-}
-
-func (g *Game) completeEnterSeq(seq *enterSeq) {
- if !g.isCharLive(seq.playerName, seq.sess) {
- return
- }
- p := seq.sess.Player
- if p == nil {
- return
- }
- if p.CutsceneRoom == seq.roomID {
- p.CutsceneRoom = 0
- g.AccountStore.SaveCharacter(p)
- }
- g.writePrompt(seq.sess)
-}
-
-// cancelEnterSeq drops any in-flight cutscene for the player. It does not touch
-// the persisted CutsceneRoom marker, so a cutscene cancelled by disconnect can
-// still be resumed on reconnect.
-func (g *Game) cancelEnterSeq(name string) {
- g.enterMu.Lock()
- delete(g.enterSeqs, name)
- g.enterMu.Unlock()
-}
-
-func (g *Game) isCharLive(name string, sess *net.Session) bool {
- g.charsMu.Lock()
- defer g.charsMu.Unlock()
- return g.loggedInChars[name] == sess
-}
-
-// applyFlagMutations sets world and player flags, shared by on_enter steps and
-// exit traversal.
-func (g *Game) applyFlagMutations(p *player.Player, setFlags, setPlayerFlags map[string]any) {
- g.Flags.SetAll(setFlags)
- if len(setPlayerFlags) > 0 {
- p.EnsureFlags()
- for k, v := range setPlayerFlags {
- p.Flags[k] = v
- }
- }
-}
-
-func (g *Game) BroadcastRespawns() {
- respawns := g.World.FlushObjRespawns()
- for _, st := range respawns {
- def, err := g.ObjectStore.Load(st.DefID)
- if err != nil || !def.IsGatherable() {
- continue
- }
- cfg := def.Gather
- if cfg.RespawnBroadcast == "" {
- continue
- }
- name := def.Name
- if idx := st.Index + 1; len(g.World.FindObjInstances(st.RoomID, st.DefID)) > 1 {
- name += fmt.Sprintf(" [%d]", idx)
- }
- msg := strings.ReplaceAll(cfg.RespawnBroadcast, "{name}", name)
- if g.Hub != nil {
- for _, sess := range g.Hub.PlayersInRoom(st.RoomID) {
- sess.WriteLine(g.colorize(sess, "broadcast", fmt.Sprintf("\n%s", msg)))
- }
- }
- }
-}