6314c70fbcdc88e162b55af1c62d0e9373989aab
[mudsync.git] / mudsync / command.scm
1 ;;; Mudsync --- Live hackable MUD
2 ;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org>
3 ;;;
4 ;;; This file is part of Mudsync.
5 ;;;
6 ;;; Mudsync is free software; you can redistribute it and/or modify it
7 ;;; under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 3 of the License, or
9 ;;; (at your option) any later version.
10 ;;;
11 ;;; Mudsync is distributed in the hope that it will be useful, but
12 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ;;; General Public License for more details.
15 ;;;
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with Mudsync.  If not, see <http://www.gnu.org/licenses/>.
18
19 (define-module (mudsync command)
20   #:use-module (mudsync parser)
21   #:use-module (8sync actors)
22   #:use-module (8sync rmeta-slot)
23   #:use-module (srfi srfi-1)
24   #:use-module (srfi srfi-9)
25   #:use-module (ice-9 control)
26   #:use-module (ice-9 match)
27
28   #:export (command?
29             command-verbs
30             command-matcher
31             command-should-handle
32             command-action
33             command-priority
34
35             build-commands
36
37             direct-command
38             prep-indir-command
39             prep-direct-command
40             loose-direct-command
41             loose-prep-command
42             empty-command
43             direct-greedy-command
44             greedy-command
45             player-gather-command-handlers
46             find-command-winner))
47
48 ;;; Commands
49 ;;; ========
50
51 (define %low-priority 0)
52 (define %default-priority 1)
53 (define %high-priority 2)
54
55 ;; ;;; Avoiding some annoying issues crossing the continuation barrier
56 ;; ;;; and the "@@" special form
57 ;; (define (make-command verbs matcher should-handle action priority)
58 ;;   (list '*command* verbs matcher should-handle action priority))
59
60 ;; (define command-verbs second)
61 ;; (define command-matcher third)
62 ;; (define command-should-handle fourth)
63 ;; (define command-action fifth)
64 ;; (define command-priority sixth)
65
66 (define-record-type <command>
67   (make-command verbs matcher should-handle action priority obvious?)
68   command?
69   (verbs command-verbs)
70   (matcher command-matcher)
71   (should-handle command-should-handle)
72   (action command-action)
73   (priority command-priority)
74   (obvious? command-obvious?))
75
76 (define-syntax %build-command
77   (syntax-rules ()
78     ((_ (verb ...) ((cmd-proc action-sym args ...) ...))
79      (list (cons verb
80                  (list (cmd-proc (list verb ...)
81                                  (quote action-sym)
82                                  args ...)
83                        ...))
84            ...))
85     ((_ verb ((cmd-proc action-sym args ...) ...))
86      (list (cons verb
87                  (list (cmd-proc (list verb)
88                                  (quote action-sym)
89                                  args ...)
90                        ...))))))
91
92 (define-syntax-rule (build-commands (verb-or-verbs cmd-defs ...) ...)
93   (wrap-rmeta-slot
94    (append (%build-command verb-or-verbs cmd-defs ...) ...)))
95
96
97 (define* (direct-command verbs action #:key (obvious? #t))
98   (make-command verbs
99                 cmatch-direct-obj
100                 ;; @@: Should we allow fancier matching than this?
101                 ;;   Let the actor itself pass along this whole method?
102                 (lambda* (goes-by #:key direct-obj)
103                   (member direct-obj goes-by))
104                 action
105                 %default-priority
106                 obvious?))
107
108 (define* (loose-direct-command verbs action #:key (obvious? #t))
109   (make-command verbs
110                 cmatch-direct-obj
111                 ;; @@: Should we allow fancier matching than this?
112                 ;;   Let the actor itself pass along this whole method?
113                 (const #t)
114                 action
115                 %default-priority
116                 obvious?))
117
118
119 (define* (prep-indir-command verbs action #:optional prepositions
120                              #:key (obvious? #t))
121   (make-command verbs
122                 cmatch-indir-obj
123                 (lambda* (goes-by #:key direct-obj indir-obj preposition)
124                   (if prepositions
125                       (and
126                        (member indir-obj goes-by)
127                        (member preposition prepositions))
128                       (member indir-obj goes-by)))
129                 action
130                 %high-priority
131                 obvious?))
132
133 (define* (prep-direct-command verbs action #:optional prepositions
134                               #:key (obvious? #t))
135   (make-command verbs
136                 cmatch-indir-obj
137                 (lambda* (goes-by #:key direct-obj indir-obj preposition)
138                   (if prepositions
139                       (and
140                        (member  direct-obj goes-by)
141                        (member preposition prepositions))
142                       (member direct-obj goes-by)))
143                 action
144                 %high-priority
145                 obvious?))
146
147 (define* (loose-prep-command verbs action #:optional prepositions
148                              #:key (obvious? #t))
149   (make-command verbs
150                 cmatch-indir-obj
151                 (const #t)
152                 action
153                 %high-priority
154                 obvious?))
155
156
157 (define* (empty-command verbs action
158                         #:key (obvious? #t))
159   (make-command verbs
160                 cmatch-empty
161                 (const #t)
162                 action
163                 %low-priority
164                 obvious?))
165
166 (define* (greedy-command verbs action
167                          #:key (obvious? #t))
168   (make-command verbs
169                 cmatch-greedy
170                 (const #t)
171                 action
172                 %low-priority
173                 obvious?))
174
175 (define* (direct-greedy-command verbs action
176                                 #:key (obvious? #t))
177   "greedy commands but which match the direct object"
178   (make-command verbs
179                 cmatch-direct-obj-greedy
180                 (lambda* (goes-by #:key direct-obj rest)
181                   (member direct-obj goes-by))
182                 action
183                 %low-priority
184                 obvious?))
185
186 ;; @@: We should probably ONLY allow these to go to users!
187 (define* (custom-command verbs matcher should-handle action
188                          #:optional (priority %default-priority)
189                          #:key (obvious? #t))
190   "Full-grained customizable command."
191   (make-command verbs matcher should-handle action priority obvious?))