1;;----------------------------------------------------------------------------
2;; Gob
3;;
4;; Quest flags, etc, go here.
5;;----------------------------------------------------------------------------
6(define (roland-mk free? joined? greeted?) (list free? joined? greeted?))
7(define (roland-is-free? knpc) (car (kobj-gob-data knpc)))
8(define (roland-joined? knpc) (cadr (kobj-gob-data knpc)))
9(define (roland-greeted? knpc) (caddr (kobj-gob-data knpc)))
10(define (roland-set-free! knpc) (set-car! (kobj-gob-data knpc) #t))
11(define (roland-set-joined! knpc) (set-car! (cdr (kobj-gob-data knpc)) #t))
12(define (roland-set-greeted! knpc) (set-car! (cddr (kobj-gob-data knpc)) #t))
13
14(define roland-greetings
15  (list
16   "Well met!"
17   "Hail, Wanderer!"
18   ))
19
20;;----------------------------------------------------------------------------
21;; Custom AI
22;;
23;; This AI controls Roland until he is freed. It constantly tries to pathfind
24;; to the prison exit. Once it gets outside the cell it sets the "freed" flag
25;; and resorts to the default kernel AI.
26;;----------------------------------------------------------------------------
27(define (roland-exit-point knpc)
28  (mk-loc (kobj-place knpc)
29          (rect-x slimey-cavern-prison-cell-exit)
30          (rect-y slimey-cavern-prison-cell-exit)))
31
32(define (roland-ai knpc)
33  (define (out-of-cell?)
34    (not (loc-in-rect? (kern-obj-get-location knpc)
35                       slimey-cavern-prison-cell)))
36  (define (try-to-escape)
37    (kern-log-enable #f)
38    (pathfind knpc (roland-exit-point knpc))
39    (kern-log-enable #t))
40  (define (set-free)
41    (roland-set-free! knpc)
42    (kern-char-set-ai knpc nil)
43    (kern-being-set-base-faction knpc faction-men)
44    )
45  (or (roland-greeted? knpc)
46      (and (any-player-party-member-visible? knpc)
47           (begin
48             (taunt knpc nil roland-greetings)
49             (roland-set-greeted! knpc))))
50  (if (out-of-cell?)
51      (set-free knpc)
52      (try-to-escape)))
53
54;; Note: (can-pathfind? ...) will pathfind through the locked door nowadays, so
55;; it cannot be relied on. Let's just let Roland try to get out and he'll know
56;; he's free.
57(define (roland-is-or-can-be-free? knpc)
58  (roland-is-free? knpc))
59
60(define (roland-join-player knpc)
61  (or (roland-joined? knpc)
62      (begin
63        (join-player knpc)
64        (roland-set-joined! knpc #t))))
65
66;;----------------------------------------------------------------------------
67;; Conv
68;;
69;; Roland is a knight errant, serving Lord Froederick.
70;; He is currently imprisoned by bandits in a cell in the slimy cave.
71;; Roland is a potential party member.
72;;----------------------------------------------------------------------------
73(define (roland-join knpc kpc)
74  (if (is-player-party-member? knpc)
75      (say knpc "Yes, I am still with you. Lead on!")
76      (if (roland-joined? knpc)
77          (begin
78            (say knpc "I am honored to rejoin you.")
79            (join-player knpc)
80            (kern-conv-end)
81            )
82          (if (roland-is-or-can-be-free? knpc)
83              ;; yes - will the player accept his continued allegiance to
84              ;; Froederick?
85              (begin
86                (say knpc "I thank you for freeing me! I owe you my life, and will gladly join you. What say you?")
87                (if (yes? kpc)
88                    (begin
89                      (say knpc "I am honored! Those vile rogues took my "
90                           "iron chest which contains my equipment. It should be "
91                           "around here somewhere.")
92                      (roland-join-player knpc))
93                    (say knpc "[sadly] As you will.")))
94              (say knpc "I am locked in this cell! Free me from this dishonour, "
95                   "and you will gain an ally.")
96              ))))
97
98(define roland-conv
99  (ifc basic-conv
100       ;; default if the only "keyword" which may (indeed must!) be longer than
101       ;; 4 characters. The 4-char limit arises from the kernel's practice of
102       ;; truncating all player queries to the first four characters. Default,
103       ;; on the other hand, is a feature of the ifc mechanism (see ifc.scm).
104       (method 'default
105               (lambda (knpc kpc)
106                 (say knpc "I'm afraid I can't help you with that.")))
107       (method 'hail
108               (lambda (knpc kpc)
109                 (if (roland-joined? knpc)
110                     (say knpc "I will aid thee any way I can.")
111                     (roland-join knpc kpc))))
112
113       (method 'bye (lambda (knpc kpc) (say knpc "Farewell.")))
114       (method 'job
115               (lambda (knpc kpc)
116                 (say knpc "I am a knight errant.")))
117       (method 'name (lambda (knpc kpc) (say knpc "I am Roland.")))
118       (method 'join roland-join)
119
120       (method 'cell
121               (lambda (knpc kpc)
122                 (say knpc "Use picklocks on a locked door to open it. Or, cast "
123                      "an unlock spell.")))
124       (method 'clov
125               (lambda (knpc kpc)
126                 (say knpc "I was with him the day he fell in battle. "
127                      "The enemy ambushed us, and I was knocked senseless. "
128                      "I dreamt that a hideous beast dragged the King down into Tartos. "
129                      "When I awoke I was in a camp hospital.")))
130       (method 'free
131               (lambda (knpc kpc)
132                 (say knpc "I was waylaid and kidnapped by the bandits in this "
133                      "cave. They've locked me in this cell to hold me for "
134                      "ransom.")))
135       (method 'pick
136               (lambda (knpc kpc)
137                 (say knpc "Bandits and thieves usually carry picklocks.")))
138       (method 'spel
139               (lambda (knpc kpc)
140                 (say knpc "You should ask a Wizard about spells.")))
141       (method 'trig
142               (lambda (knpc kpc)
143                 (say knpc "I know Trigave is a small town, a crossroad of "
144                      "the north, with much history.")))
145       (method 'knig
146               (lambda (knpc kpc)
147                 (say knpc "I was a squire of King Clovis in the Goblin Wars. "
148                      "When the wars ended, I took to wandering.")
149                 ))
150       ))
151
152;;----------------------------------------------------------------------------
153;; First-time constructor
154;;----------------------------------------------------------------------------
155(define (mk-roland)
156  (bind
157    (kern-mk-char
158     'ch_roland          ; tag
159     "Roland"            ; name
160     sp_human            ; species
161     oc_warrior          ; occ
162     s_knight            ; sprite
163     faction-prisoner    ; starting alignment
164     6 0 6               ; str/int/dex
165     pc-hp-off           ; hp bonus
166     pc-hp-gain          ; hp per-level bonus
167     0                   ; mp off
168     0                   ; mp gain
169     max-health          ; hp
170     -1                  ; xp
171     max-health          ; mp
172     0                   ; ap
173     3                   ; lvl
174     #f                  ; dead
175     'roland-conv        ; conv
176     nil                 ; sched
177     'roland-ai          ; special ai
178     nil                 ; container
179     nil                 ; readied
180     )
181    (roland-mk #f #f #f)))
182