moving between rooms nearly works
[mudsync.git] / mudsync / room.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 room)
20   #:use-module (mudsync command)
21   #:use-module (mudsync gameobj)
22   #:use-module (8sync systems actors)
23   #:use-module (8sync agenda)
24   #:use-module (oop goops)
25   #:use-module (srfi srfi-1)
26   #:export (<room>
27             room-actions
28             room-actions*
29
30             <exit>))
31
32 \f
33 ;;; Exits
34 ;;; =====
35
36 (define-class <exit> ()
37   ;; Used for wiring
38   (to-symbol #:accessor exit-to-symbol
39              #:init-keyword #:to-symbol)
40   ;; The actual address we use
41   (to-address #:accessor exit-to-address
42               #:init-keyword #:address)
43   ;; Name of the room (@@: Should this be names?)
44   (name #:accessor exit-name
45         #:init-keyword #:name)
46   (desc #:accessor exit-desc
47                #:init-keyword #:desc)
48
49   ;; *Note*: These two methods have an extra layer of indirection, but
50   ;;   it's for a good reason.
51   (visible-check #:init-value (const #t)
52                  #:init-keyword #:visible-check)
53   ;; By default all exits can be traversed
54   (traverse-check #:init-value (const #t)
55                   #:init-keyword #:traverse-check))
56
57 (define* (exit-can-traverse? exit actor
58                              #:optional (target-actor (actor-id actor)))
59   ((slot-ref exit 'traverse-check) exit actor target-actor))
60
61 (define* (exit-is-visible? exit actor
62                            #:optional (target-actor (actor-id actor)))
63   ((slot-ref exit 'traverse-check) exit actor target-actor))
64
65
66 \f
67 ;;; Rooms
68 ;;; =====
69
70 (define %room-contain-commands
71   (list
72    (loose-direct-command "look" 'cmd-look-at)
73    (empty-command "look" 'cmd-look-room)
74    (loose-direct-command "go" 'cmd-go)))
75
76 ;; TODO: Subclass from container?
77 (define-class <room> (<gameobj>)
78   ;; A list of <exit>
79   (exits #:init-value '()
80          #:init-keyword #:exits
81          #:getter room-exits)
82
83   (container-commands
84    #:init-value %room-contain-commands)
85
86   (message-handler
87    #:allocation #:each-subclass
88    ;; @@: Can remove this indirection once things settle
89    #:init-value (wrap-apply room-action-dispatch)))
90
91
92 (define room-actions
93   (build-actions
94    ;; desc == description
95    (wire-exits! (wrap-apply room-wire-exits!))
96    (cmd-go (wrap-apply room-cmd-go))))
97
98 (define room-actions*
99   (append room-actions gameobj-actions))
100
101 (define room-action-dispatch
102   (simple-dispatcher room-actions*))
103
104
105 (define (room-wire-exits! room message)
106   "Actually hook up the rooms' exit addresses to the rooms they
107 claim to point to."
108   (for-each
109    (lambda (exit)
110      (define new-exit
111        (<-wait room (gameobj-gm room) 'lookup-room
112                #:symbol (exit-to-symbol exit)))
113
114      (set! (exit-to-address exit) new-exit))
115
116    (room-exits room)))
117
118 (define-mhandler (room-cmd-go room message direct-obj)
119   (define exit
120     (find
121      (lambda (exit)
122        (equal? (exit-name exit) direct-obj))
123      (pk 'later-exits (room-exits room))))
124   (if exit
125       (<- room (message-from message) 'tell
126           #:text "Yeah you can go there...\n")
127       (<- room (message-from message) 'tell
128           #:text "I don't know where that is?\n")))
129