a better approach to dialogue treees.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
[play-clj.g2d :refer :all]
|
||||
[clojure.pprint]
|
||||
[clojure.string :as s]
|
||||
[clojure.zip :as zip]
|
||||
[advent.pathfind]
|
||||
[advent.actions :as actions]
|
||||
[advent.screens.dialogue :as dialogue]
|
||||
@@ -148,18 +149,48 @@
|
||||
(stop screen entities target-id)
|
||||
entities)))))
|
||||
|
||||
(defn present-choices [entities & pairs]
|
||||
(run-action entities
|
||||
(begin [this screen entities]
|
||||
(run! dialogue/choice-screen :on-present-choices :pairs pairs)
|
||||
(run! @(resolve 'advent.screens.scene/scene) :on-deactivate)
|
||||
entities)
|
||||
(defn something-else [zipper]
|
||||
(-> zipper zip/up zip/up))
|
||||
|
||||
(continue [this screen entities] entities)
|
||||
(defn previous-choices [zipper]
|
||||
(-> zipper zip/up))
|
||||
|
||||
(done? [this screen entities] true)
|
||||
(defn nth-child [zipper i]
|
||||
(loop [so-far 0
|
||||
zipper (zip/down zipper)]
|
||||
(if (= so-far i)
|
||||
zipper
|
||||
(recur (inc so-far) (zip/right zipper)))))
|
||||
|
||||
(terminate [this screen entities] entities)))
|
||||
(defn make-zipper [tree]
|
||||
(zip/zipper map? (comp vals :choices) (fn [n c] nil) tree))
|
||||
|
||||
(defn present-choices [entities choices]
|
||||
(loop [zipper (make-zipper choices)]
|
||||
(let [selected-choice (atom nil)
|
||||
node (zip/node zipper)]
|
||||
(run-action entities
|
||||
(begin [this screen entities]
|
||||
(run! dialogue/choice-screen :on-present-choices :choices (:choices node) :callback #(reset! selected-choice %))
|
||||
(run! @(resolve 'advent.screens.scene/scene) :on-deactivate)
|
||||
entities)
|
||||
|
||||
(continue [this screen entities] entities)
|
||||
|
||||
(done? [this screen entities] (not (nil? @selected-choice)))
|
||||
|
||||
(terminate [this screen entities]
|
||||
(run! @(resolve 'advent.screens.scene/scene) :on-reactivate)
|
||||
entities))
|
||||
|
||||
(let [zipper (nth-child zipper (-> node :choices keys (.indexOf @selected-choice)))
|
||||
node (zip/node zipper)]
|
||||
(when-let [run (:run node)]
|
||||
(run @selected-choice))
|
||||
(when-let [next-choices (:choices node)]
|
||||
(if (fn? next-choices)
|
||||
(recur (next-choices zipper))
|
||||
(recur zipper)))))))
|
||||
|
||||
|
||||
(defn give [entities target-id item]
|
||||
|
||||
@@ -68,28 +68,29 @@
|
||||
entities)
|
||||
|
||||
:on-present-choices
|
||||
(fn [{:keys [pairs]} [entities]]
|
||||
(fn [{:keys [choices callback]} [entities]]
|
||||
(let [font (bitmap-font "ego/font.fnt" )
|
||||
tr (bitmap-font! font :get-region)
|
||||
scale 1
|
||||
tx (.getTexture tr)
|
||||
_ (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear)]
|
||||
(into entities (for [[[text result-script] i] (map vector pairs (range))]
|
||||
[i (assoc (label text (style :label font (color :white))) :x 30 :y (* 30 i) :result-script result-script)]))))
|
||||
(-> entities
|
||||
(into (for [[text i] (map vector (keys choices) (range))]
|
||||
[i (assoc (label text (style :label font (color :white))) :x 30 :y (* 30 i))]))
|
||||
(assoc :state {:object nil :callback callback :choices choices}))))
|
||||
|
||||
:on-touch-down (fn [screen [entities]]
|
||||
(let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})]
|
||||
(when (seq entities)
|
||||
(when (< y (* 30 (count entities)))
|
||||
(run! @(resolve 'advent.screens.scene/scene) :on-reactivate)
|
||||
(run! @(resolve 'advent.screens.scene/scene) :on-start-script :script (:result-script (entities (int (/ y 30)))))
|
||||
((get-in entities [:state :callback]) (nth (keys (get-in entities [:state :choices])) (int (/ y 30))))
|
||||
{}))))
|
||||
|
||||
:on-mouse-moved (fn [screen [entities]]
|
||||
(let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})
|
||||
font (bitmap-font "ego/font.fnt" )]
|
||||
(when (seq entities)
|
||||
(doseq [index (range (count entities))]
|
||||
(doseq [index (range (dec (count entities)))]
|
||||
(if (< (* index 30) y (* (inc index) 30))
|
||||
(label! (entities index) :set-style (style :label font (color :yellow)))
|
||||
(label! (entities index) :set-style (style :label font (color :white))))))))
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
(if (= :choices subject)
|
||||
(apply actions/present-choices entities (for [choice (partition 2 arg)]
|
||||
[(first choice) (actions/get-script entities
|
||||
(run-dialogue-tree entities (second choice) (first choice)))]))
|
||||
(run-dialogue-tree entities (doto (second choice) println) (first choice)))]))
|
||||
(if (= :line arg)
|
||||
(actions/talk entities subject previous-line)
|
||||
(actions/talk entities subject arg))))))
|
||||
@@ -179,28 +179,18 @@
|
||||
:cursor :down}
|
||||
:wizard {:box [228 80 248 126]
|
||||
:script (actions/get-script entities
|
||||
(run-dialogue-tree entities [:ego "Hello there Mr. Fangald!"
|
||||
:wizard "Oh no, not you again!"
|
||||
:choices ["You're not happy to see me?" [:ego :line
|
||||
:wizard "Of course not!"
|
||||
:wizard "Not after all the hell you've put me through."
|
||||
:choices ["You mean the time I set your rabbit loose?" [:ego :line
|
||||
:wizard "Fluffy was my best rabbit!"]
|
||||
"You're not still sore about my stealing your magic cowboy hat." [:ego :line
|
||||
:ego "Are you?"
|
||||
:wizard "That cowboy hat was one of a kind!"
|
||||
:wizard "Truly unique."
|
||||
:wizard "It accented my unique facial physique."
|
||||
:wizard "And now it's gone forever."
|
||||
:wizard "Leave me to die in peace."]
|
||||
"You mean the time I set your house on fire with a fire mint?" [:ego :line
|
||||
:wizard "That was you? I spent a fortune cleaning up the mess you made!"
|
||||
:wizard "You ruined my life work!"]
|
||||
|
||||
"An old hoot like you needs a kick the pants every now and again!" [:ego :line
|
||||
:wizard "Maybe so, but not from a cheating little boy like you!"]]]
|
||||
"What do you mean, 'not you again'?" [:ego :line
|
||||
:wizard "I mean get lost kid."]]]))}}
|
||||
(actions/present-choices entities {:choices {"Hello there" {:run #(do (actions/talk entities :ego %)
|
||||
(actions/talk entities :wizard "Oh, hello."))
|
||||
:choices {"How are you doing?" {:run #(do (actions/talk entities :ego %)
|
||||
(actions/talk entities :wizard "I'm ok."))
|
||||
:choices actions/previous-choices}
|
||||
"Any news?" {:run #(do (actions/talk entities :ego %)
|
||||
(actions/talk entities :wizard "Not really"))
|
||||
:choices actions/previous-choices}
|
||||
"Something Else" {:choices actions/something-else}}}
|
||||
"Good bye" {:run #(actions/talk entities :ego %)}}})
|
||||
|
||||
)}}
|
||||
:layers [(assoc (texture "inside-house/background.png") :x 0 :y 0 :baseline 0)
|
||||
(assoc (texture "inside-house/desk.png") :x 0 :y 0 :baseline 200)
|
||||
(assoc (texture "inside-house/sillhoute.png") :x 0 :y 0 :baseline 240)]
|
||||
@@ -356,7 +346,7 @@
|
||||
(update! screen :renderer (stage) :camera (orthographic))
|
||||
(let [_ (input! :set-cursor-image (utils/cursor "cursor.png" :main) 0 0)
|
||||
music (sound "town-music.mp3")
|
||||
_ (sound! music :loop 0.20)
|
||||
;; _ (sound! music :loop 0.20)
|
||||
backgrounds (backgrounds screen)]
|
||||
{:backgrounds backgrounds
|
||||
:state {:object nil
|
||||
|
||||
Reference in New Issue
Block a user