aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_room.go
blob: 11f919ad5fc851f4b2aab43ffc6a7fa4adf274f4 (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package game

import (
	"fmt"
	"os"
	"strings"

	"gopkg.in/yaml.v3"
	"thehouseoficarus/internal/behavior"
	"thehouseoficarus/internal/net"
	"thehouseoficarus/internal/player"
	"thehouseoficarus/internal/world"
)

func (g *Game) executeRoom(sess *net.Session, args []string, rawInput string) {
	if !g.checkAdmin(sess) {
		sess.WriteLine("Unknown command.")
		return
	}
	p := sess.Player
	if p == nil {
		return
	}
	if len(args) == 0 {
		g.showRoomHelp(sess)
		return
	}

	action := strings.ToLower(args[0])
	rest := args[1:]

	switch action {
	case "name":
		g.roomSetName(sess, rest)
	case "desc":
		g.roomSetDesc(sess, rest)
	case "addobj", "remobj", "addlocalobj", "remlocalobj", "hide", "unhide":
		g.roomObject(sess, action, rest)
	case "addmob", "remmob":
		g.roomMob(sess, action, rest)
	case "addspawn", "remspawn":
		g.roomSpawn(sess, action, rest)
	default:
		sess.WriteLine(fmt.Sprintf("Unknown room action: %s", action))
		g.showRoomHelp(sess)
	}
}

func (g *Game) showRoomHelp(sess *net.Session) {
	sess.WriteLine("room actions:")
	sess.WriteLine("  room name <text>              — set room name")
	sess.WriteLine("  room desc <text>              — set room description")
	sess.WriteLine("  room addobj <object_id>       — add a referenced object")
	sess.WriteLine("  room remobj <object_id>       — remove a referenced object")
	sess.WriteLine("  room addlocalobj <name> <description> — add a local object")
	sess.WriteLine("  room remlocalobj <name>       — remove a local object")
	sess.WriteLine("  room hide <name_or_id>        — hide all matching objects")
	sess.WriteLine("  room unhide <name_or_id>      — unhide all matching objects")
	sess.WriteLine("  room addmob <mob_id>          — add a mob spawn")
	sess.WriteLine("  room remmob <mob_id>          — remove a mob spawn")
	sess.WriteLine("  room addspawn <item_id> [qty] [respawn_ticks] — add an item spawn")
	sess.WriteLine("  room remspawn <item_id>       — remove an item spawn")
}

func (g *Game) roomSetName(sess *net.Session, args []string) {
	if len(args) == 0 {
		sess.WriteLine("Usage: room name <text>")
		return
	}
	text := strings.Join(args, " ")
	g.writeRoom(sess, func(room *world.Room) {
		room.Name = text
	})
	sess.WriteLine(fmt.Sprintf("Room name set to: %s", text))
}

func (g *Game) roomSetDesc(sess *net.Session, args []string) {
	if len(args) == 0 {
		sess.WriteLine("Usage: room desc <text>")
		return
	}
	text := strings.Join(args, " ")
	g.writeRoom(sess, func(room *world.Room) {
		room.Description = behavior.DescList{{Text: text}}
	})
	sess.WriteLine("Room description updated.")
}

func (g *Game) loadRoomWrite(p *player.Player) (*world.Room, string, error) {
	path, ok := g.World.GetRoomPath(p.RoomID)
	if !ok {
		return nil, "", fmt.Errorf("room file not found")
	}
	room, err := g.World.LoadRoom(p.RoomID)
	if err != nil {
		return nil, "", err
	}
	return room, path, nil
}

func (g *Game) writeRoom(sess *net.Session, fn func(*world.Room)) {
	p := sess.Player
	room, path, err := g.loadRoomWrite(p)
	if err != nil {
		sess.WriteLine(fmt.Sprintf("Error loading room: %v", err))
		return
	}
	fn(room)
	data, err := yaml.Marshal(room)
	if err != nil {
		sess.WriteLine("Error marshaling room YAML.")
		return
	}
	if err := os.WriteFile(path, data, 0644); err != nil {
		sess.WriteLine("Error writing room file.")
		return
	}
}