aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_room_object.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/cmd_room_object.go')
-rw-r--r--internal/game/cmd_room_object.go235
1 files changed, 235 insertions, 0 deletions
diff --git a/internal/game/cmd_room_object.go b/internal/game/cmd_room_object.go
new file mode 100644
index 0000000..f682d62
--- /dev/null
+++ b/internal/game/cmd_room_object.go
@@ -0,0 +1,235 @@
+package game
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ "gopkg.in/yaml.v3"
+ "thehouseoficarus/internal/behavior"
+ "thehouseoficarus/internal/net"
+ "thehouseoficarus/internal/object"
+ "thehouseoficarus/internal/world"
+)
+
+func (g *Game) roomObject(sess *net.Session, action string, args []string) {
+ switch action {
+ case "addobj":
+ g.roomAddObj(sess, args)
+ case "remobj":
+ g.roomRemObj(sess, args)
+ case "addlocalobj":
+ g.roomAddLocalObj(sess, args)
+ case "remlocalobj":
+ g.roomRemLocalObj(sess, args)
+ case "hide":
+ g.roomHide(sess, args)
+ case "unhide":
+ g.roomUnhide(sess, args)
+ }
+}
+
+func (g *Game) roomAddObj(sess *net.Session, args []string) {
+ if len(args) == 0 {
+ sess.WriteLine("Usage: room addobj <object_id>")
+ return
+ }
+ objID := args[0]
+ if _, err := g.ObjectStore.Load(objID); err != nil {
+ sess.WriteLine(fmt.Sprintf("Object '%s' not found in data/objects/.", objID))
+ return
+ }
+ p := sess.Player
+ room, _, err := g.loadRoomWrite(p)
+ if err != nil {
+ sess.WriteLine(fmt.Sprintf("Error loading room: %v", err))
+ return
+ }
+ for _, obj := range room.Objects {
+ if obj.ID == objID && obj.Local == nil {
+ sess.WriteLine(fmt.Sprintf("Object '%s' is already in this room.", objID))
+ return
+ }
+ }
+ room.Objects = append(room.Objects, world.RoomObject{ID: objID})
+ g.writeRoom(sess, func(r *world.Room) { *r = *room })
+ sess.WriteLine(fmt.Sprintf("Added object '%s' to room.", objID))
+}
+
+func (g *Game) roomRemObj(sess *net.Session, args []string) {
+ if len(args) == 0 {
+ sess.WriteLine("Usage: room remobj <object_id>")
+ return
+ }
+ objID := args[0]
+ p := sess.Player
+ room, _, err := g.loadRoomWrite(p)
+ if err != nil {
+ sess.WriteLine(fmt.Sprintf("Error loading room: %v", err))
+ return
+ }
+ found := false
+ filtered := room.Objects[:0]
+ for _, obj := range room.Objects {
+ if obj.ID == objID && obj.Local == nil {
+ found = true
+ } else {
+ filtered = append(filtered, obj)
+ }
+ }
+ if !found {
+ sess.WriteLine(fmt.Sprintf("Referenced object '%s' not found in this room.", objID))
+ return
+ }
+ room.Objects = filtered
+ g.writeRoom(sess, func(r *world.Room) { *r = *room })
+ sess.WriteLine(fmt.Sprintf("Removed object '%s' from room.", objID))
+}
+
+func (g *Game) roomAddLocalObj(sess *net.Session, args []string) {
+ if len(args) < 2 {
+ sess.WriteLine("Usage: room addlocalobj <name> <description>")
+ return
+ }
+ name := args[0]
+ desc := strings.Join(args[1:], " ")
+
+ normName := world.NormalizeObjectName(name)
+ if normName == "" {
+ sess.WriteLine("Invalid object name.")
+ return
+ }
+
+ p := sess.Player
+ room, _, err := g.loadRoomWrite(p)
+ if err != nil {
+ sess.WriteLine(fmt.Sprintf("Error loading room: %v", err))
+ return
+ }
+
+ for _, obj := range room.Objects {
+ if obj.Local != nil && world.NormalizeObjectName(obj.Local.Name) == normName {
+ sess.WriteLine(fmt.Sprintf("A local object named '%s' already exists in this room.", name))
+ return
+ }
+ }
+
+ room.Objects = append(room.Objects, world.RoomObject{
+ ID: normName,
+ Local: &object.ObjectDef{
+ Name: name,
+ Description: behavior.DescList{{Text: desc}},
+ Aliases: []string{name},
+ },
+ })
+
+ path, _ := g.World.GetRoomPath(p.RoomID)
+ data, _ := yaml.Marshal(room)
+ os.WriteFile(path, data, 0644)
+ sess.WriteLine(fmt.Sprintf("Added local object '%s' to room.", name))
+}
+
+func (g *Game) roomRemLocalObj(sess *net.Session, args []string) {
+ if len(args) == 0 {
+ sess.WriteLine("Usage: room remlocalobj <name>")
+ return
+ }
+ name := args[0]
+ normName := world.NormalizeObjectName(name)
+
+ p := sess.Player
+ room, _, err := g.loadRoomWrite(p)
+ if err != nil {
+ sess.WriteLine(fmt.Sprintf("Error loading room: %v", err))
+ return
+ }
+
+ found := false
+ filtered := room.Objects[:0]
+ for _, obj := range room.Objects {
+ if obj.Local != nil && world.NormalizeObjectName(obj.Local.Name) == normName {
+ found = true
+ } else {
+ filtered = append(filtered, obj)
+ }
+ }
+ if !found {
+ sess.WriteLine(fmt.Sprintf("No local object named '%s' found in this room.", name))
+ return
+ }
+ room.Objects = filtered
+
+ path, _ := g.World.GetRoomPath(p.RoomID)
+ data, _ := yaml.Marshal(room)
+ os.WriteFile(path, data, 0644)
+ sess.WriteLine(fmt.Sprintf("Removed local object '%s' from room.", name))
+}
+
+func (g *Game) roomHide(sess *net.Session, args []string) {
+ if len(args) == 0 {
+ sess.WriteLine("Usage: room hide <name_or_object_id>")
+ return
+ }
+ g.roomToggleHidden(sess, args[0], true)
+}
+
+func (g *Game) roomUnhide(sess *net.Session, args []string) {
+ if len(args) == 0 {
+ sess.WriteLine("Usage: room unhide <name_or_object_id>")
+ return
+ }
+ g.roomToggleHidden(sess, args[0], false)
+}
+
+func (g *Game) roomToggleHidden(sess *net.Session, input string, hidden bool) {
+ p := sess.Player
+ room, _, err := g.loadRoomWrite(p)
+ if err != nil {
+ sess.WriteLine(fmt.Sprintf("Error loading room: %v", err))
+ return
+ }
+
+ norm := world.NormalizeObjectName(input)
+ var count int
+
+ for i := range room.Objects {
+ obj := &room.Objects[i]
+ if obj.Local != nil {
+ if world.NormalizeObjectName(obj.Local.Name) == norm {
+ obj.Local.Hidden = hidden
+ count++
+ }
+ continue
+ }
+ if strings.EqualFold(obj.ID, input) {
+ obj.HiddenOverride = hidden
+ count++
+ continue
+ }
+ if def, err := g.ObjectStore.Load(obj.ID); err == nil {
+ if world.NormalizeObjectName(def.Name) == norm {
+ obj.HiddenOverride = hidden
+ count++
+ }
+ }
+ }
+
+ if count == 0 {
+ label := "hide"
+ if !hidden {
+ label = "unhide"
+ }
+ sess.WriteLine(fmt.Sprintf("No objects matching '%s' found for %s.", input, label))
+ return
+ }
+
+ path, _ := g.World.GetRoomPath(p.RoomID)
+ data, _ := yaml.Marshal(room)
+ os.WriteFile(path, data, 0644)
+
+ action := "Hidden"
+ if !hidden {
+ action = "Unhidden"
+ }
+ sess.WriteLine(fmt.Sprintf("%s %d object(s) matching '%s'.", action, count, input))
+}