aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_registry.go
blob: be1c2761d42ce3407e3f24e4ad5836e4a5a95d70 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
package game

import (
	"fmt"
	"strings"

	"thehouseoficarus/internal/net"
)

type commandHandler func(g *Game, sess *net.Session, args []string, rawInput string)

type commandDef struct {
	handler commandHandler
	class   CommandClass
}

var commandRegistry = map[string]commandDef{
	"get":    {(*Game).executeGet, ClassActive},
	"take":   {(*Game).executeGet, ClassActive},
	"grab":   {(*Game).executeGet, ClassActive},
	"pick":   {(*Game).executeGet, ClassActive},
	"drop":   {(*Game).executeDrop, ClassActive},
	"attack": {(*Game).executeAttack, ClassActive},
	"kill":   {(*Game).executeAttack, ClassActive},
	"work":   {(*Game).executeWork, ClassActive},
	"style":  {(*Game).executeStyle, ClassInstant},
	"look":   {(*Game).executeLook, ClassInstant},
	"l":      {(*Game).executeLook, ClassInstant},
	"north":  {(*Game).executeMove, ClassActive},
	"n":      {(*Game).executeMove, ClassActive},
	"south":  {(*Game).executeMove, ClassActive},
	"s":      {(*Game).executeMove, ClassActive},
	"east":   {(*Game).executeMove, ClassActive},
	"e":      {(*Game).executeMove, ClassActive},
	"west":   {(*Game).executeMove, ClassActive},
	"w":      {(*Game).executeMove, ClassActive},
	"up":     {(*Game).executeMove, ClassActive},
	"u":      {(*Game).executeMove, ClassActive},
	"down":   {(*Game).executeMove, ClassActive},
	"d":      {(*Game).executeMove, ClassActive},
	"say":    {(*Game).executeSay, ClassInstant},
	"sc":     {(*Game).executeScore, ClassInstant},
	"score":  {(*Game).executeScore, ClassInstant},
	"skills": {(*Game).executeSkills, ClassInstant},
	"sk":     {(*Game).executeSkills, ClassInstant},
	"task":   {(*Game).executeTask, ClassInstant},
	"stats":  {(*Game).executeStats, ClassInstant},
	"tech":   {(*Game).executeTech, ClassInstant},
	"t":      {(*Game).executeTech, ClassInstant},
	"i":      {(*Game).executeInventory, ClassInstant},
	"inv":    {(*Game).executeInventory, ClassInstant},
	"inventory": {(*Game).executeInventory, ClassInstant},
	"quit":   {(*Game).executeQuit, ClassActive},
	"description": {(*Game).executeDescription, ClassInstant},
	"desc":   {(*Game).executeDescription, ClassInstant},
	"option": {(*Game).executeOption, ClassInstant},
	"options": {(*Game).executeOption, ClassInstant},
	"color":  {(*Game).executeColor, ClassInstant},
	"colors": {(*Game).executeColor, ClassInstant},
	"colortable": {(*Game).executeColortable, ClassInstant},
	"prompt": {(*Game).executePrompt, ClassInstant},
	"exits":  {(*Game).executeExits, ClassInstant},
	"map":    {(*Game).executeMap, ClassInstant},
	"symbol": {(*Game).executeSymbol, ClassInstant},
	"queued": {(*Game).executeQueued, ClassInstant},
	"help":   {(*Game).executeHelp, ClassInstant},
	"mine":   {(*Game).executeGather, ClassActive},
	"chop":   {(*Game).executeGather, ClassActive},
	"fish":   {(*Game).executeGather, ClassActive},
	"cut":    {(*Game).executeGather, ClassActive},
	"pull":   {(*Game).executeUse, ClassActive},
	"push":   {(*Game).executeUse, ClassActive},
	"use":    {(*Game).executeUse, ClassActive},
	"cook":   {(*Game).executeCook, ClassActive},
	"smelt":  {(*Game).executeSmelt, ClassActive},
	"smith":  {(*Game).executeSmith, ClassActive},
	"craft":  {(*Game).executeCraft, ClassActive},
	"eat":    {(*Game).executeEat, ClassFree},
	"drink":  {(*Game).executeDrink, ClassFree},
	"fletch": {(*Game).executeFletch, ClassFree},
	"clean":  {(*Game).executeClean, ClassFree},
	"mix":    {(*Game).executeMix, ClassActive},
	"id":     {(*Game).executeIdentify, ClassActive},
	"identify": {(*Game).executeIdentify, ClassActive},
	"autotrigger": {(*Game).executeAutotrigger, ClassInstant},
	"auto":      {(*Game).executeAutotrigger, ClassInstant},
	"mods":      {(*Game).executeMods, ClassInstant},
	"modlist":   {(*Game).executeMods, ClassInstant},
	"mod":       {(*Game).executeMods, ClassInstant},
	"modules":   {(*Game).executeMods, ClassInstant},
	"module":    {(*Game).executeMods, ClassInstant},
	"sneak":     {(*Game).executeSneak, ClassInstant},
	"trigger":   {(*Game).executeTrigger, ClassActive},
	"talk":   {(*Game).executeTalk, ClassActive},
	"speak":  {(*Game).executeTalk, ClassActive},
	"ask":    {(*Game).executeTalk, ClassActive},
	"burn":   {(*Game).executeBurn, ClassActive},
	"stoke":  {(*Game).executeStoke, ClassActive},
	"alias":  {(*Game).executeAlias, ClassInstant},
	"unalias": {(*Game).executeUnalias, ClassInstant},
	"search": {(*Game).executeSearch, ClassActive},
	"steal":  {(*Game).executeSteal, ClassActive},
	"thieve": {(*Game).executeSteal, ClassActive},
	"plant":  {(*Game).executePlant, ClassActive},
	"harvest": {(*Game).executeHarvest, ClassActive},
	"rake":   {(*Game).executeRake, ClassActive},
	"water":  {(*Game).executeWater, ClassActive},
	"cure":   {(*Game).executeCure, ClassActive},
	"inspect": {(*Game).executeInspect, ClassInstant},
	"walk":   {(*Game).executeWalk, ClassActive},
	"bank":   {(*Game).executeBank, ClassActive},
	"construct": {(*Game).executeConstruct, ClassActive},
	"make":   {(*Game).executeConstruct, ClassActive},
	"jack":   {(*Game).executeJack, ClassActive},
	"jackin": {(*Game).executeJack, ClassActive},
	"eq":     {(*Game).executeWear, ClassFree},
	"equipment": {(*Game).executeWear, ClassFree},
	"equip":  {(*Game).executeWear, ClassFree},
	"wear":   {(*Game).executeWear, ClassFree},
	"wield":  {(*Game).executeWear, ClassFree},
	"remove": {(*Game).executeRemove, ClassFree},
	"unwear": {(*Game).executeRemove, ClassFree},
	"unwield": {(*Game).executeRemove, ClassFree},
	"aps":      {(*Game).executeAps, ClassActive},
	"verbs":    {(*Game).executeVerbs, ClassInstant},
	"what":     {(*Game).executeVerbs, ClassInstant},
	"syntax":   {(*Game).executeVerbs, ClassInstant},
	"commands": {(*Game).executeVerbs, ClassInstant},
	"stop":     {(*Game).executeStop, ClassInstant},
	"hide":     {(*Game).executeHide, ClassActive},
	"safespot": {(*Game).executeHide, ClassActive},
	"unhide":   {(*Game).executeUnhide, ClassActive},
	"unsafespot": {(*Game).executeUnhide, ClassActive},
}

func classifyCommand(cmd string) CommandClass {
	if def, ok := commandRegistry[cmd]; ok {
		return def.class
	}
	if _, ok := verbAliases[cmd]; ok {
		return ClassActive
	}
	if obstacleVerbs[cmd] {
		return ClassActive
	}
	return ClassUnknown
}

func (g *Game) executeCommand(sess *net.Session, cmd string, args []string, rawInput string) {
	if def, ok := commandRegistry[cmd]; ok {
		def.handler(g, sess, args, rawInput)
		return
	}

	if obstacleVerbs[cmd] {
		g.doObstacle(sess, cmd)
		return
	}

	p := sess.Player
	if a, ok := verbAliases[cmd]; ok {
		g.cancelAction(p)
		switch a {
		case "gather":
			if len(args) == 0 {
				target := g.defaultTarget(p.RoomID, cmd)
				if target == "" {
					sess.WriteLine(fmt.Sprintf("%s what?", cmd))
					return
				}
				g.startAction(sess, cmd, target)
			} else {
				g.startAction(sess, cmd, strings.Join(args, " "))
			}
		case "talk":
			if len(args) == 0 {
				sess.WriteLine("Talk to whom?")
			} else {
				g.startAction(sess, "talk", strings.Join(args, " "))
			}
		}
		return
	}

	sess.WriteLine("Unknown command.")
}

func (g *Game) executeGather(sess *net.Session, args []string, rawInput string) {
	verb := strings.Fields(rawInput)[0]
	p := sess.Player
	g.cancelAction(p)
	if len(args) == 0 {
		target := g.defaultTarget(p.RoomID, verb)
		if target == "" {
			sess.WriteLine(fmt.Sprintf("%s what?", verb))
			return
		}
		g.startAction(sess, verb, target)
	} else {
		g.startAction(sess, verb, strings.Join(args, " "))
	}
}

func (g *Game) executeTalk(sess *net.Session, args []string, rawInput string) {
	p := sess.Player
	g.cancelAction(p)
	if len(args) == 0 {
		sess.WriteLine("Talk to whom?")
	} else {
		g.startAction(sess, "talk", strings.Join(args, " "))
	}
}