aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_room.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/cmd_room.go')
-rw-r--r--internal/game/cmd_room.go48
1 files changed, 38 insertions, 10 deletions
diff --git a/internal/game/cmd_room.go b/internal/game/cmd_room.go
index b381cf3..33627eb 100644
--- a/internal/game/cmd_room.go
+++ b/internal/game/cmd_room.go
@@ -83,7 +83,7 @@ func (g *Game) roomSetName(sess *net.Session, args []string) {
return
}
text := strings.Join(args, " ")
- g.writeRoom(sess, func(room *world.Room) {
+ g.mutateRoom(sess, func(room *world.Room) {
room.Name = text
})
sess.WriteLine(fmt.Sprintf("Room name set to: %s", text))
@@ -94,10 +94,29 @@ func (g *Game) roomSetDesc(sess *net.Session, args []string) {
sess.WriteLine("Usage: room desc <text>")
return
}
+ room, _, err := g.loadRoomWrite(sess.Player)
+ if err != nil {
+ sess.WriteLine(fmt.Sprintf("Error loading room: %v", err))
+ return
+ }
+ // Replacing the list wholesale would destroy alternates; require a direct
+ // YAML edit when the room already has conditional or multiple variants.
+ if len(room.Description) > 1 {
+ sess.WriteLine("This room has multiple or conditional descriptions; edit the room YAML directly to keep them.")
+ return
+ }
+ for _, v := range room.Description {
+ if v.Condition != nil {
+ sess.WriteLine("This room has conditional descriptions; edit the room YAML directly to keep them.")
+ return
+ }
+ }
text := strings.Join(args, " ")
- g.writeRoom(sess, func(room *world.Room) {
+ if !g.mutateRoom(sess, func(room *world.Room) {
room.Description = behavior.DescList{{Text: text}}
- })
+ }) {
+ return
+ }
sess.WriteLine("Room description updated.")
}
@@ -121,7 +140,7 @@ func (g *Game) roomSetColor(sess *net.Session, args []string) {
return
}
}
- g.writeRoom(sess, func(room *world.Room) {
+ g.mutateRoom(sess, func(room *world.Room) {
room.Color = value
})
if value == "" {
@@ -176,21 +195,30 @@ func parseLocalObjArgs(rawInput, action string) (name string, aliases []string,
return name, nil, desc
}
-func (g *Game) writeRoom(sess *net.Session, fn func(*world.Room)) {
+// mutateRoom loads the player's current room, applies fn, writes it back, and
+// reconciles the live runtime state from the new file. Every successful
+// in-game room edit must go through it: a plain file write left the live room
+// unchanged (a removed mob kept standing, an added spawn never appeared) until
+// the next room entry or restart.
+//
+// It runs on the owner goroutine and returns false after reporting an error.
+func (g *Game) mutateRoom(sess *net.Session, fn func(*world.Room)) bool {
p := sess.Player
room, path, err := g.loadRoomWrite(p)
if err != nil {
sess.WriteLine(fmt.Sprintf("Error loading room: %v", err))
- return
+ return false
}
fn(room)
data, err := yaml.Marshal(room)
if err != nil {
- sess.WriteLine("Error marshaling room YAML.")
- return
+ sess.WriteLine(fmt.Sprintf("Error marshaling room YAML: %v", err))
+ return false
}
if err := writeRoomFile(path, data); err != nil {
- sess.WriteLine("Error writing room file.")
- return
+ sess.WriteLine(fmt.Sprintf("Error writing room file: %v", err))
+ return false
}
+ g.ReconcileRoom(p.RoomID)
+ return true
}