1 ;; Sets a quest to be complete, with notification if it is in progress
2 ;; Note that if you set the quest to be complete before you assign it,
3 ;; then the assignment notification will say that it has been immediately
4 ;; completed, avoiding spamming the player with multiple notifications
6 (define (quest-complete quest)
7 (if (and (quest-assigned? quest) use-quest-pane)
8 (kern-log-msg "^c+mQuest completed:^c-\n^c+m" (qst-title quest) "^c-")
13 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14 ;; internal utility methods
16 (define (quest-data-add-child parent quest)
17 (let ((childlist (quest-data-getvalue parent 'qchildren)))
18 (if (not (in-list? quest childlist))
19 (quest-data-update parent 'qchildren
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 ;; quest assignment callbacks for use in quest definition
30 ;; causes a notification on assignment
31 (define (quest-assign-notify quest target)
32 (let ((notifytext (if (qst-complete? quest)
33 "^c+mQuest completed:^c-\n^c+m"
34 "^c+mNew quest:^c-\n^c+m"
37 (kern-log-msg notifytext (qst-title quest) "^c-")
42 ;; ensures parent/subquest relation once quest is assigned
43 (define (quest-assign-subquest quest target)
44 (let ((parent (quest-tbl-get quest 'qparent)))
45 (if (not (null? parent))
46 (quest-data-add-child parent (qst-tag quest))
51 ;; allows quest to proceed without any other action
52 (define (quest-assign-silent quest target)
56 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
57 ;; quest display callbacks for use in quest definition
59 ;; doesnt actually do anything
60 (define (quest-status-from-payload quest)
64 ;; doesnt actually do anything
65 (define (quest-status-inprogress quest)
69 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
70 ;; Interacting with the Quest Data Table
72 ;; The quest data table is a global storage location for fixed, plot
73 ;; based quests that are created once and then activated at the
76 ;; Anything procedurally generated on the fly would need
77 ;; to interface directly with the quest-sys module.
80 ;; retrieves a quest from the quest data table
81 (define (quest-data-get tag)
82 (println "quest-data-get:" tag)
83 (let* ((questdata (tbl-get (gob (kern-get-player)) 'questdata))
85 (tbl-get questdata tag)
89 ;; retrieves a value from a quest payload tbl, given the key for the quest
91 (define (quest-data-getvalue quest tag)
92 (let* ((qpayload (car (qst-payload (quest-data-get quest)))))
93 (tbl-get qpayload tag)
97 ;; assigns a quest from the quest data table, while ensuring it is not
98 ;; given out repeatedly
99 (define (quest-data-assign-once tag)
100 (let ((questentry (quest-data-get tag)))
101 (if (not (quest-assigned? questentry))
102 (quest-assign questentry)
106 ;; checks if a quest from the quest data table has been assigned
107 (define (quest-data-assigned? tag)
108 (quest-assigned? (quest-data-get tag))
111 ;; assuming quest in the QDT uses a tbl for payload, updates a key/value pair
112 (define (quest-data-update tag key value)
113 (let* ((qpayload (car (qst-payload (quest-data-get tag))))
114 (updatehook (tbl-get qpayload 'on-update))
116 (if (not (equal? (tbl-get qpayload key) value))
118 (tbl-set! qpayload key value)
119 (if (not (null? updatehook))
122 (qst-bump! (quest-data-get tag))
126 ;; updates as per quest-data-update, but additionally triggers a passed in function
127 (define (quest-data-update-with tag key value callback)
128 (println "quest-data-update-with")
130 (quest (quest-data-get tag))
131 (qpayload (car (qst-payload quest)))
133 (println "quest:" quest)
134 (println "qpayload:" qpayload)
135 (if (is-tbl? qpayload)
137 (updatehook (tbl-get qpayload 'on-update))
139 (println "updatehook" updatehook)
140 (if (not (equal? (tbl-get qpayload key) value))
142 (tbl-set! qpayload key value)
144 (if (not (null? updatehook))
147 (qst-bump! (quest-data-get tag))
155 ;; sets the description for a quest in the QDT
156 (define (quest-data-descr! tag descr)
157 (qst-set-descr! (quest-data-get tag) descr)
160 ;; sets the icon for a quest in the QDT
161 (define (quest-data-icon! tag icon)
162 (qst-set-icon! (quest-data-get tag) icon)
165 ;; sets a quest in the QDT to be complete, giving a notification if appropriate
166 ;; see the notes for quest-complete, above
167 (define (quest-data-complete tag)
168 (quest-complete (quest-data-get tag))
171 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
172 ;; callbacks for quest-data-update-with
174 ;; if appropriate, notifies the player about a change in quest state
175 ;; can be chained to further functions
176 (define (quest-notify subfunction)
177 (println "quest-notify")
179 (if (and (quest-assigned? quest) use-quest-pane)
180 (kern-log-msg "^c+mQuest updated:^c-\n^c+m" (qst-title quest) "^c-")
182 (if (not (null? subfunction))
186 ;; grants the player a given amount of experience, using or adding to the bonus xp
188 (define (grant-xp-fn amount)
190 (let* ((qpayload (car (qst-payload quest)))
191 (bonusxp (tbl-get qpayload 'bonus-xp))
192 (bonusxp (if (null? bonusxp)
194 (totalxp (+ bonusxp amount))
196 (if (quest-assigned? quest)
198 (kern-char-add-experience (car (kern-party-get-members (kern-get-player))) totalxp)
199 (tbl-set! qpayload 'bonus-xp 0)
201 (tbl-set! qpayload 'bonus-xp totalxp)
206 ;; shares amongst the players party a given amount of experience,
207 ;; using or adding to the bonus xp as appropriate
208 (define (grant-party-xp-fn amount)
210 (let* ((qpayload (car (qst-payload quest)))
211 (bonusxp (tbl-get qpayload 'bonus-xp))
212 (bonusxp (if (null? bonusxp)
214 (totalxp (+ bonusxp amount))
215 (party (kern-party-get-members (kern-get-player)))
216 (xp-each (ceiling (/ totalxp (length party))))
218 (if (quest-assigned? quest)
220 (map (lambda (kchar) (kern-char-add-experience kchar xp-each)) party)
221 (tbl-set! qpayload 'bonus-xp 0)
223 (tbl-set! qpayload 'bonus-xp totalxp)
228 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
229 ;; Reconcile active and pregenned quests at game load to simplify
232 ;; internal methods- will run automatically
234 (kern-add-hook 'new_game_start_hook 'reconcile-quests)
235 (kern-add-hook 'new_game_start_hook 'refresh-quests)
237 (define (reconcile-quests kplayer)
240 (kern-get-player)) 'quests))
243 (kern-get-player)) 'questdata))
247 (let ((tag (qst-tag quest)))
248 (if (and (not (null? tag))
249 (not (null? (tbl-get questdata tag))))
250 (tbl-set! questdata tag quest))
255 (define (refresh-quests)
256 (load "quests-data.scm")
260 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
263 ;; links a quest and subquest after they are already in-play
264 (define (quest-data-convert-subquest quest parent)
265 (quest-data-update quest 'qparent parent)
266 (quest-data-add-child parent quest)