aboutsummaryrefslogtreecommitdiff
path: root/internal/game/act_room.go
blob: 792d8bd2d55d0925f8d774ba428207ca0d2cd62f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package game

import (
	"fmt"
	"strings"

	"thehouseoficarus/internal/net"
	"thehouseoficarus/internal/player"
)

// runEnterSteps evaluates a room's on_enter block for the player. The first
// trigger whose Condition passes wins; its Steps run as a scripted sequence
// (room-locked, so steps are skipped if the player immediately leaves).
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
	}
	g.runTrigger(sess, p, room.OnEnter, roomID, nil, true)
}

// runExitSteps evaluates a room's on_exit block for the player. It fires the
// first matching trigger as a non-room-locked sequence using the room being
// left as the reference room (broadcasts/spawn resolve to the old room). It is
// invoked before the player's RoomID is updated to the destination.
func (g *Game) runExitSteps(sess *net.Session, roomID int) {
	room, err := g.World.LoadRoom(roomID)
	if err != nil || len(room.OnExit) == 0 {
		return
	}
	p := sess.Player
	if p == nil {
		return
	}
	g.runTrigger(sess, p, room.OnExit, roomID, nil, false)
}

// applyFlagMutations sets global and player flags. It is the player-scoped
// flag step of applyStep, called once per step that carries set_global_flags
// and/or set_player_flags. scopeGlobal sets globals directly in applyStep
// instead (so world-scoped cascades don't reach back into this helper).
func (g *Game) applyFlagMutations(p *player.Player, setGlobalFlags, setPlayerFlags map[string]any) {
	g.GlobalFlags.SetAll(setGlobalFlags)
	if len(setPlayerFlags) > 0 {
		for k, v := range setPlayerFlags {
			g.setPlayerFlag(p, 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", msg))
			}
		}
	}
}