aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_close.go
blob: 217ae9a793c49080ba6a342428719970c33a9a6e (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
package game

import (
	"fmt"
	"os"

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

func (g *Game) executeClose(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 {
		sess.WriteLine("Close which direction?")
		return
	}

	dir := g.World.ResolveExit(args[0])
	if dir == "" {
		sess.WriteLine("Invalid direction. Use n/s/e/w/ne/nw/se/sw/u/d.")
		return
	}

	curRoom, err := g.World.LoadRoom(p.RoomID)
	if err != nil {
		sess.WriteLine("Error loading current room.")
		return
	}

	curPath, ok := g.World.GetRoomPath(p.RoomID)
	if !ok {
		sess.WriteLine("Error: can't find current room file.")
		return
	}

	exitDef, ok := curRoom.Exits[dir]
	if !ok {
		sess.WriteLine(fmt.Sprintf("There is no exit to the %s from here.", dir))
		return
	}

	targetID := exitDef.Room
	targetRoom, err := g.World.LoadRoom(targetID)
	targetName := fmt.Sprintf("#%d", targetID)
	if err == nil {
		targetName = fmt.Sprintf("#%d (%s)", targetID, targetRoom.Name)
	}

	delete(curRoom.Exits, dir)
	curData, err := yaml.Marshal(curRoom)
	if err != nil {
		sess.WriteLine("Error updating current room YAML.")
		return
	}
	if err := os.WriteFile(curPath, curData, 0644); err != nil {
		sess.WriteLine("Error writing current room file.")
		return
	}

	reciprocalRemoved := false
	if targetRoom != nil {
		oppositeDir := world.OppositeExit[dir]
		if targetExit, tok := targetRoom.Exits[oppositeDir]; tok && targetExit.Room == p.RoomID {
			delete(targetRoom.Exits, oppositeDir)
			targetPath, tok2 := g.World.GetRoomPath(targetID)
			if tok2 {
				targetData, terr := yaml.Marshal(targetRoom)
				if terr == nil {
					if werr := os.WriteFile(targetPath, targetData, 0644); werr == nil {
						reciprocalRemoved = true
					}
				}
			}
		}
	}

	msg := fmt.Sprintf("Closed exit %s to %s.", dir, targetName)
	if reciprocalRemoved {
		msg += fmt.Sprintf(" Removed reciprocal exit from %s as well.", targetName)
	}
	sess.WriteLine(msg)
}