4 ;; A portal destination is simply a Scheme list of (place x y).
6 ;; Here are some convenience functions for:
7 ;; - creating a destination: portal-mk
8 ;; - inquiring the place: portal-place
9 ;; - inquiring the (x y): portal-coords
10 (define (portal-mk place x y) (list place x y))
11 (define (portal-place portal) (safe-eval (car portal)))
12 (define (portal-coords portal) (cons (portal-place portal) (cdr portal)))
15 ;; Function called when a portal is activated.
16 ;; Causes the stepper to be relocated to the portal destination.
17 (define (portal-step kportal kstepper)
18 (let ((portal (kobj-gob-data kportal)))
19 (kern-obj-relocate kstepper
20 (portal-coords portal)
23 ;; prompt-portal-step:
24 ;; Function called when a portal is activated.
25 ;; Prints two UI confirmation prompts, and on double-confirmation,
26 ;; relocates the stepper.
27 (define (prompt-portal-step kportal kstepper)
29 (kern-print "Are you SURE you want to step there?\n")
30 (if (kern-conv-get-yes-no? kstepper)
34 (kern-print "Are you REALLY REALLY SURE?\n")
35 (if (kern-conv-get-yes-no? kstepper)
40 (kern-print "Ok... you asked for it!\n")
41 (portal-step kportal kstepper))
42 (kern-print "Wise move.\n")))
43 (kern-print "Make up your mind.\n")))
47 ;; This is the interface for a "use (E)nter command" portal,
48 ;; which acts when the (E)nter command is invoked while standing upon the portal.
50 ;; By convention, small-scale places accessible from a large-scale wilderness
51 ;; place are generally of this type. It is thus possible to enter the
52 ;; (smaller, contained) place from any direction, or to walk through that
53 ;; tile in the wilderness without entering.
55 (method 'enter portal-step)))
57 (define bump-portal-ifc
58 ;; This is the interface for a pseudo-edge tile
59 ;; Marked impassable, but teleports you to the next area if yu bump into it
63 (kern-obj-set-pclass kobj pclass-wall)
65 (method 'bump portal-step)))
67 (define auto-portal-ifc
68 ;; This is the interface for an "automatic enter" portal,
69 ;; which acts immediately when stepped upon.
71 ;; By convention, this interface is used for most small-scale portals,
72 ;; magical gates, and for trapdoors and other "surprise" portals.
74 (method 'step portal-step)))
76 (define prompting-auto-portal-ifc
77 ;; This is the interface for a "prompting" portal,
78 ;; which prints a UI prompt for the user to confirm their intention to enter.
80 ;; By convention, this interface is used for non-surprise portals
81 ;; which present the appearance of not being able to readily return,
82 ;; such as holes in the floor (without a ladder or rope attched),
83 ;; or portals whose destination is (or appears to be) potentially hazardous,
84 ;; such as certain magical gates to unknown destinations.
86 (method 'step prompt-portal-step)))
89 ;; Portal objects for some common portal types:
90 ;; Instances of such objects are placed on the appropriate map on the
91 ;; "mechanisms" layer. These object "types" specify a name/label, sprite,
92 ;; and a portal "interface" behavior. Instances are created by "portal
93 ;; constructor" functions such as those below.
94 (mk-obj-type 't_ladder_down "ladder leading down" s_ladder_down layer-mechanism portal-ifc)
95 (mk-obj-type 't_ladder_up "ladder leading up" s_ladder_up layer-mechanism portal-ifc)
96 (mk-obj-type 't_trap_door "trap door" '() layer-mechanism auto-portal-ifc)
97 (mk-obj-type 't_bump_door nil '() layer-mechanism bump-portal-ifc)
98 (mk-obj-type 't_teleporter "teleporter" s_floor_plate layer-mechanism prompting-auto-portal-ifc)
99 (mk-obj-type 't_dungeon "dungeon" s_dungeon layer-mechanism auto-portal-ifc)
100 (mk-obj-type 't_ship_relic "ship relic" s_ship layer-mechanism auto-portal-ifc)
102 ;; mk-portal -- generic helper constructor
103 (define (mk-portal type place-tag x y)
104 (bind (kern-mk-obj type 1)
105 (portal-mk place-tag x y)))
107 ;; Portal constructor functions for some common portal types:
108 ;; These functions create an instance of a portal type,
109 ;; binding a destination (place-tag x y) to one of the "types" defined above.
110 (define (mk-ladder-down place-tag x y) (mk-portal t_ladder_down place-tag x y))
111 (define (mk-ladder-up place-tag x y) (mk-portal t_ladder_up place-tag x y))
112 (define (mk-trap-door place-tag x y) (mk-portal t_trap_door place-tag x y))
113 (define (mk-bump-door place-tag x y) (mk-portal t_bump_door place-tag x y))
114 (define (mk-teleporter place-tag x y) (mk-portal t_teleporter place-tag x y))
115 (define (mk-dungeon place-tag x y) (mk-portal t_dungeon place-tag x y))
116 (define (mk-ship-relic place-tag x y) (mk-portal t_ship_relic place-tag x y))
118 ;;----------------------------------------------------------------------------
119 ;; Special portal -- entrance to thief's cave near Bole. Invisible, but under
120 ;; reveal it shows the letter 'O'. When stepped on at midnight the player is
121 ;; transported to the Traps I dungeon.
122 ;;----------------------------------------------------------------------------
123 (define (thief-door-step kportal kchar)
124 (let ((time (kern-get-time)))
125 (if (and (>= (time-hour time) 0)
126 (< (time-hour time) 3))
127 (portal-step kportal kchar))))
129 (define thief-door-ifc
131 (method 'step thief-door-step)))
133 (mk-obj-type 't_thief_door "strange mark" s_O layer-mechanism thief-door-ifc)
135 (define (mk-thief-door place-tag x y)
136 (make-invisible (mk-portal t_thief_door place-tag x y)))
138 ;;----------------------------------------------------------------------------
139 ;; Secret Path -- visible only when Reveal is in effect
140 ;;----------------------------------------------------------------------------
141 (mk-obj-type 't_secret_path "secret path" s_cobblestone layer-none nil)
142 (define (mk-secret-path)
143 (make-invisible (kern-mk-obj t_secret_path 1)))
145 ;;----------------------------------------------------------------------------
146 ;; Clue Trigger -- make a mechanism which will provide a clue when stepped
147 ;; on. Technically not a portal, but it doesn't really fit anywhere else,
149 ;;----------------------------------------------------------------------------
150 (define (clue-mk msg) msg)
151 (define (clue-msg clue) clue)
152 (define (clue-trigger clue)
153 (apply kern-log-msg (clue-msg clue)))
155 (define (clue-step kmech kchar)
156 (clue-trigger (kobj-gob-data kmech)))
158 (define clue-step-ifc
160 (method 'step clue-step)))
162 (mk-obj-type 't_step_clue nil nil layer-mechanism clue-step-ifc)
164 (define (mk-step-clue . msg)
165 (bind (kern-mk-obj t_step_clue 1)
168 ;;----------------------------------------------------------------------------
169 ;; The riddle machine -- fills region with given terrain when answered
171 ;;----------------------------------------------------------------------------
172 (define (riddle-mk ans ter-tag x y w h pos? msg)
173 (list ans ter-tag x y w h pos? msg
177 (define (riddle-ans riddle) (car riddle))
178 (define (riddle-terrain riddle) (eval (cadr riddle)))
179 (define (riddle-x riddle) (caddr riddle))
180 (define (riddle-y riddle) (list-ref riddle 3))
181 (define (riddle-w riddle) (list-ref riddle 4))
182 (define (riddle-h riddle) (list-ref riddle 5))
183 (define (riddle-pos? riddle) (list-ref riddle 6))
184 (define (riddle-msg riddle) (list-ref riddle 7))
185 (define (riddle-rm-on-correct? riddle) (list-ref riddle 8))
186 (define (riddle-rm-on-wrong? riddle) (list-ref riddle 9))
187 (define (riddle-set-rm-on-correct! riddle val) (list-set-ref! riddle 8 val))
188 (define (riddle-set-rm-on-wrong! riddle val) (list-set-ref! riddle 9 val))
190 (define (riddle-trigger riddle kmech)
192 (fill-terrain (riddle-terrain riddle)
193 (loc-place (kern-obj-get-location kmech))
200 (define (riddle-step kmech kchar)
201 (if (is-player-party-member? kchar)
202 (let ((riddle (kobj-gob-data kmech)))
203 (kern-log-msg "*** STENTORIAN VOICE ***")
204 (apply kern-log-msg (riddle-msg riddle))
205 (let ((guess (kern-conv-get-reply kchar)))
206 (cond ((eq? guess (riddle-ans riddle))
207 (kern-log-msg "YOU MAY PASS")
208 (if (riddle-pos? riddle)
209 (riddle-trigger riddle kmech))
210 (if (riddle-rm-on-correct? riddle)
211 (kern-obj-remove kmech))
214 (kern-log-msg "WRONG!")
215 (if (not (riddle-pos? riddle))
216 (riddle-trigger riddle kmech))
217 (if (riddle-rm-on-wrong? riddle)
218 (kern-obj-remove kmech))
223 (define riddle-step-ifc
225 (method 'step riddle-step)))
227 (mk-obj-type 't_step_riddle nil nil layer-mechanism riddle-step-ifc)
229 (define (mk-riddle ans ter-tag x y w h pos? . msg)
230 (bind (kern-mk-obj t_step_riddle 1)
231 (riddle-mk ans ter-tag x y w h pos? msg)))