From f90ae6b7c3f9a139b85f12237406994783435914 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Wed, 24 Sep 2014 13:25:07 -0700 Subject: [PATCH 01/18] first step at dialogue trees. --- desktop/resources/inside-house/background.png | Bin 49807 -> 44053 bytes desktop/resources/wizard/stand.png | Bin 0 -> 1815 bytes desktop/resources/wizard/talk.png | Bin 0 -> 2447 bytes desktop/resources/wizard/talk.pxa/0.pxi | Bin 0 -> 264123 bytes desktop/resources/wizard/talk.pxa/1.pxi | Bin 0 -> 264123 bytes desktop/resources/wizard/talk.pxa/2.pxi | Bin 0 -> 264123 bytes desktop/resources/wizard/talk.pxa/3.pxi | Bin 0 -> 264123 bytes .../resources/wizard/talk.pxa/CelData.plist | 22 ++++ desktop/src-common/advent/action_test.clj | 93 ---------------- desktop/src-common/advent/action_test2.clj | 99 ------------------ desktop/src-common/advent/actions.clj | 14 +++ desktop/src-common/advent/core.clj | 2 +- .../src-common/advent/screens/dialogue.clj | 36 ++++++- desktop/src-common/advent/screens/scene.clj | 47 +++++++-- 14 files changed, 113 insertions(+), 200 deletions(-) create mode 100644 desktop/resources/wizard/stand.png create mode 100644 desktop/resources/wizard/talk.png create mode 100644 desktop/resources/wizard/talk.pxa/0.pxi create mode 100644 desktop/resources/wizard/talk.pxa/1.pxi create mode 100644 desktop/resources/wizard/talk.pxa/2.pxi create mode 100644 desktop/resources/wizard/talk.pxa/3.pxi create mode 100644 desktop/resources/wizard/talk.pxa/CelData.plist delete mode 100644 desktop/src-common/advent/action_test.clj delete mode 100644 desktop/src-common/advent/action_test2.clj diff --git a/desktop/resources/inside-house/background.png b/desktop/resources/inside-house/background.png index e19da54ea5bc610b584cc62b1582250ba9d75f1b..b92cc869f7069ecdb55917fe1f353972640d2efc 100644 GIT binary patch literal 44053 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 literal 49807 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�ls=U$h*vnSKeVp<}x)}vcfM{TsSREla*0~F^WH%%<48aQGIRP@j;9A~eDjHYJ}4N=Hc58I?d%Kym>2Ui&~~@SD$gHk<`NeKoSTzm zx6<)y1Xe;rBdjki31^cqB8$cKR88%VZ<j;M^f!n7#=oT9a>Qz?Eevp~V`$<;%$# zm@6?BPr)1V)D{nLx1{!FCi4^-+1rS>blr8hsp~rl_g+Y_SB-mt-3ZVl-(Xu1^S{UF z48|%+<9zX9&1oTYPLw~zCC^wjnb7B;GjDFM;j#@`{>H+o1s-!esq>aO4o0Z?Ai2Nm z!JS$)ZX|%iTOA6zL<7!=mzog_0)ds&5rU zsdoZ(ntB859(vQSdW9jMVowQtY$M1k2P#vJk;5VBH)VoHc%DlzVoHld%N>M3S(#hN zupg%^V58#Q4{A4^_t|vk5xKLDzA6@QT2kcfTOX6qAEhM0f$eYYO|6A+*^^fHQ_AYc z(T24434$H80Qjrvj&E*Ty{r-tLZ&4=(ET?~jF0_jy{Gn*?NA`RMzC3@0O3BCPFXZ?Yl|^1UHGyuRS^{_OI;y@?(0Jv; ztbELAY`swUX`T#6uzEJ#As{PZmsk~5+>Uc}Wu+A0ZqmorDLIUw$xrsi>dW5b6fH*( z{^V>^J}Wr2HUr?FgGzRV?D()=W0+QB0Rwo@@RC?I`>hqZ9;Ub3s`0lMjf4)wQN)jo zsvS7#hy#PWI0R16`$ih57$telx0L9gLFotV)Z~upC-px?d4zPnUe#HyC_C}7e>j1o za2${&OX6|fX=PE0eUafAu)BP;$WhuT(DLZ6{{rvsp7-Q5=jABpT;?sZhbl%m`<^z9IGD15f!WJN!Nm@sJqsnD zrpUdrIXf?K^ZieIkf+lS}ssN2SvMk=s_>J9=#{P#! zNLzArjMmZ5m$=>>$v=G-P4u9?$_Kue@JtmuMwV6CCResI{`9mQYuq2+U1rPd>&wvy zh`eGY^#;AOB~|NeM!)l+!N6>o(()Dg9x^Ur8;0<A;g#U@NB4 zz{4|*(~V^ub{@KkP=6(L?63PE>wC0sz5i@9d(MIV6VWz~>@&kwYDDm*NYG8zaBN6Q zOfFvPYp!{T%Nvc1UkZpI#8g~7<262bDA-8*9xngDvwywW)Ek?}EA>OhRvJ-;3FC~5 z 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 diff --git a/desktop/resources/wizard/stand.png b/desktop/resources/wizard/stand.png new file mode 100644 index 0000000000000000000000000000000000000000..ce64fc19c62d322e18aeba8540bec627c4ce6a44 GIT binary patch literal 1815 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 z^~PAW6?(hItF7wDiT<0`^*^|CRadFY4*>!M2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk 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 literal 0 HcmV?d00001 diff --git a/desktop/resources/wizard/talk.pxa/3.pxi b/desktop/resources/wizard/talk.pxa/3.pxi new file mode 100644 index 0000000000000000000000000000000000000000..1a6bdecd64f55d0ca037a252492fdbb8bae6381e GIT binary patch literal 264123 zcmeI)YiwL+nFnw?p3*io%`{EZYiOWu3%eya*A`ePP12gu#xZr`OxkSB#6GnrnaqUo zB*D$LIzTCRDEC__)Zs1!d|kuefggD{tO3`087Rx0NSr zuWjzX>kV&w>pMU2;g5X${;hqr{nhFZ&s=y`@3YTdR6J+#xl2Z><>|OaY1hPtdhPbg z#BKW;$$?68aJX_uGSW9zEl*8tnP^nTw>{C4bV0f_y*#}leQvSmp{2d&UwG@_@QNoI z_rL{dPrB&Qi+e9w_MA(XKlgc;ZL9Aqk5!t}TPu6Z6UmlZd2h1qKxL}3tD2-s((}?n zdhVGIU%s^Wiho$KEl#s1nVvd)9;q%twtjEk?n@PReyndzeJ6j#6GWi!{jI9-^YHS^McN_*31r)QU{^|5j@^tOzb zo8^&1{Z}pTzjO2Au0od&0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7dX2MRp+;Dbjxu-TeSfWS!#WHsNKlRS;X2oUHnfxPbTzyE$? zK!@Es%_VTM0y|+%Yv0#4pK8bNPs}Q0{OdtUi108KsFY%&bNDB`x78A z{{^!8&!7K4JABLR{KAWCv+n|r{nxjS`WQd_2g;fP8yr^hPTQ5NJmrtM5HGy!*+Y1Ln{D zd<@8@moHiCJ3u?A_9f6E0(t$vytsSz=YQ(ILvEaA5_p;fvgdzR|JhiOec#W=fPCut z|1?264S{(kkk@`*|9Q=~PSyWByJ?z3;As-b>i?Q$x6D5OTgL$3|DPscry($p1+tpY zp6}T-PiyUG^Pd0n_y%ekfxkl_um5}u$lm+2b=fqpef9r$06UbxJQm2G`NymOY+ast z+yzY|K;R?==GK4y?w^kb>i;BR9Y&x71X|z!^IFfRt=l@FE1F1vK$`+{pa1!C>ogk= z+B~h@2@vQIf&4k&TJx>*+3y7CkgjMZ0Rn9bWY72f_kL72zUWAnfeRMRPW=wBHZko^ zpu+^R`p@e;f9_{vKtA7L-O*eE1lkbD>OZgbe5(H20JJNC4i@-p^`C9);I3&p0Rn%6 zK>pmHJ5~RG1D;(7bhyCWy3dyL_ks@Zn&uNAZ~}qWdY?NMoZwKK2@vRTf&5vY*M94A zhj&f$2@p7eKx@6veHS>vp*9mB(BT4k{b$p;>F};;J^=zJ5Xfu3b+^9r@A7|ttsv$J zoWcSlxBciT^?uI6GoP}23U^)C2t4Bj=GOb%irpg`*ofG0RjXF5FkL{6cTu7!^Z1xxV3MrTArG!mG>s4qqE7>j=|xLm9b`}UMn}I zXRaS84GwSKwL2MW#t}EZYUkkarv1(Gu4-~!qfwqdeB(_6+Xjbc=Zi~0?_y`?~2n4*koW1IOJMG()A0`|Hhm?I|=%hDw|2wK=PI43&b3Et@$lHP-Xwi}^!+*MrK80~H&n~br#AQQH;opL zdznw)^X9i?%{}hM6SW~6-uCv{t{!V@wD9)I#LPR663kuy$h+QsZ|{5F`@Z+@oM=?W zhbQa%tK%CR<%8R^#o1f2Bb(b=t2BozcO++|&r2^$`?7oU!Rp@4#bW=8RsBaltC#n$ zSQ|HJ+C2A-H3Ena!(#cNlrUVF`|{#EPNthsvi$~CKE z|5dBvHm_Y1D`M4}m8;if$A99JrJ>S>a_vBQYUY7~C+EX+aQLQVIvKyNF*aE_kTibq zsZVcd)a%W(JF4Q0$T^XVB9}#87+Dp$I#P~IM4FL9k-H=JMm`j|FY>9#XCj}Ad?E71 z$d@8tiTrEi8&yn%2 zLig@SJ#t6njgfmJ?~B|Qc_8wY$X6p@i+nxujmUQ*KZ^V$@|(yXBmdh~SkM*eiJTQ# z8o4TRW26+>7imPAkpq#}MdF$Z;+hNI8HsBy_(0@Ck&i?^7MY2BA@XmLe~&~P7DO8s zd@J&wk?%(yjr=0=tH}RHj&v1zmP9Uztc(mqc1HF@?uxuE@}5XsuP3h86W8nceB?`! z=vPmix98`P$GQs9p+e#GNSv#1X=F|0Ws#dBBayL47#41iOh&@8@Y=}Tk$WQ1uflsH v(VxP7k;9SiMIMTTU*X4*Uq}8g@_1L_wCvwyd + + + + + duration + 0.20000000298023224 + + + duration + 0.20000000298023224 + + + duration + 0.20000000298023224 + + + duration + 0.20000000298023224 + + + diff --git a/desktop/src-common/advent/action_test.clj b/desktop/src-common/advent/action_test.clj deleted file mode 100644 index 0abf0427..00000000 --- a/desktop/src-common/advent/action_test.clj +++ /dev/null @@ -1,93 +0,0 @@ -(ns advent.action-test) - -(defprotocol IAction - (begin [this state]) - (done? [this state]) - (continue [this state])) - - -(defmacro do-actions [name & forms] - `(vector ~@(for [form forms] - `(fn [~name] - ~form)))) - -(defn walk-to [who & targets ] - (for [[target-x target-y] targets] - (fn [state] - (reify - IAction - (begin [this state] (println "Starting Walking") state) - (continue [this {:keys [x y] :as state}] - (println "Continue Walking from" x y) - (Thread/sleep 500) - (assoc state :x (inc x) :y (inc y))) - (done? [this {:keys [x y]} ] - (and (= x target-x) - (= y target-y))))))) - -(defn talk [who text] - (reify - IAction - (begin [this state] - (println "Speaking:" text) - (assoc state :time 0)) - (continue [this state] - (Thread/sleep 200) - (assoc state :time (inc (:time state)))) - (done? [this {:keys [time]}] - (< 3 time)))) - -(defn give-item [item] - (reify - IAction - (begin [this state] - (println "Receiving item:" item) - (update-in state [:items] #(conj % item))) - (continue [this state] - state) - (done? [this state] - true))) - - -(defn walk-to [who & targets ] - (for [[target-x target-y] targets] - (fn [state] - (reify - IAction - (begin [this state] (println "Starting Walking to" target-x target-y) state) - (continue [this {:keys [x y] :as state}] - (println "Continue Walking from" x y) - (Thread/sleep 500) - (assoc state :x (inc x) :y (inc y))) - (done? [this {:keys [x y]} ] - (and (>= x target-x) - (>= y target-y))))))) - -(defn get-script [] - (let [random-loc (+ 3 (rand-int 10))] - (do-actions state - (if (= 1 (rand-int 2)) - (give-item :gold) - (give-item :candy)) - (walk-to :ego [3 3] [random-loc random-loc] ) - (if ((:items state) :gold) - (talk :ego "I have enough money to buy something") - (talk :ego "I'm broke."))))) - -(defn test-run [] - (let [state {:x 0 :y 0 :time 0 :items #{}} - actions (get-script)] - (loop [actions actions - state state - started? false] - (when (seq actions) - (let [step ((first actions) state)] - (if (sequential? step) - (recur (concat step (rest actions)) state false) - (let [state (if started? - state - (begin step state)) - state (continue step state)] - (if (done? step state) - (recur (rest actions) state false) - (recur actions state true))))))))) diff --git a/desktop/src-common/advent/action_test2.clj b/desktop/src-common/advent/action_test2.clj deleted file mode 100644 index 4fc7514b..00000000 --- a/desktop/src-common/advent/action_test2.clj +++ /dev/null @@ -1,99 +0,0 @@ -(ns advent.action-test2 - (:require [clojure.core.async :refer [put! ! chan go thread take! alts!!]])) - -(defprotocol IAction - (begin [this state]) - (done? [this state]) - (continue [this state]) - (terminate [this state])) - - - -(defn talk [action-channel who text] - (let [c (chan)] - (put! action-channel - (reify - IAction - (begin [this state] - (println "Speaking:" text) - (assoc state :time 0)) - (continue [this state] - (Thread/sleep 200) - (assoc state :time (inc (:time state)))) - (done? [this {:keys [time]}] - (< 3 time)) - (terminate [this state] - (put! c state) - state))) - (= x target-x) - (>= y target-y))) - (terminate [this state] - (put! c state) - state)))) - (screen screen {:x (:input-x screen) :y (:input-y screen)})] + (when (seq entities) + (when (< y (* 20 (count entities))) + (run! @(resolve 'advent.screens.scene/scene) :on-start-script :script (:result-script (entities (int (/ y 20))))) + {})))) + + :on-resize (fn [screen entities] + (size! screen 1280 960))) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 38cece3b..ff5745e3 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -155,18 +155,49 @@ (aget peddler-sheet 0 i))) peddler-stand (animation 0.2 (for [i (flatten [(repeat 5 0) 6])] (aget peddler-sheet 0 i))) - wizard (texture "wizard.png") - _ (texture! wizard :flip true false)] + wizard-sheet (texture! (texture "wizard/talk.png") :split 20 46) + wizard-stand (animation 0.2 (for [i (flatten [(repeat 10 0) 1])] + (aget wizard-sheet 0 i))) + wizard-talk (animation 0.2 (for [i [0 2 0 2 1 2 0 3 0 2 0 1 0 2]] + (aget wizard-sheet 0 i)))] {:inside-house (make-background :interactions {:down-dir {:box [151 0 320 20] :script (actions/get-script entities (actions/walk-to entities :ego [237 1]) (actions/transition-background entities :outside-house [262 88])) - :cursor :down}} + :cursor :down} + :wizard {:box [228 80 248 126] + :script (actions/get-script entities + (actions/talk entities :ego "Hello there Fangald!") + (actions/talk entities :wizard "Oh no, not you again!") + (actions/present-choices entities "You're not my friend, Mr. Fangald?" + (actions/get-script entities + (actions/talk entities :ego "You're not my friend, Mr. Fangald?") + (actions/talk entities :wizard "No, you are a rascally little boy who is nothing but a cheat!") + (actions/present-choices entities + "Oh, come on, I'm not that bad." + (actions/get-script entities + (actions/talk entities :ego "Oh, come on, I'm not that bad.") + (actions/talk entities :wizard "Yes you are. Shoo!")) + "I'm sorry." + (actions/get-script entities + (actions/talk entities :ego "I'm sorry") + (actions/talk entities :wizard "That's better. Now scram.")) + )) + "Yes, it's me!" + (actions/get-script entities + (actions/talk entities :ego "Yes, it's me!") + (actions/talk entities :wizard "Great, just great. Leave me alone."))))}} :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)] - :entities {:wizard (assoc wizard :x 228 :y 80 :baseline 160 :scale-x 1.75 :scale-y 1.75)} + :entities {:wizard (actions/start-animation screen (assoc (animation->texture screen wizard-stand) :x 228 :y 80 :baseline 160 :scale-x 1.75 :scale-y 1.75 + :left {:talk (flip wizard-talk) + :stand (flip wizard-stand)} + :right {:talk wizard-talk + :stand wizard-stand} + :facing :left) + :stand)} :collision "inside-house/collision.png" :scale-fn (scaler-fn-with-baseline 110 0.10 1.75)) :outside-house @@ -312,7 +343,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 :actions {:object nil @@ -361,4 +392,8 @@ (if (= (button-code :right) (:button screen)) (assoc-in entities [:cursor :current] :main) - (left-click screen entities)))) + (left-click screen entities))) + + :on-start-script (fn [{:keys [script]} [entities] ] + (script entities) + entities)) From 240af5dcf02f71b76f35b542924cf451f0c2051e Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Wed, 24 Sep 2014 18:39:07 -0700 Subject: [PATCH 02/18] dialogue tree improvements. --- desktop/src-common/advent/actions.clj | 19 ++--- .../src-common/advent/screens/dialogue.clj | 15 ++-- desktop/src-common/advent/screens/scene.clj | 75 +++++++++++-------- 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/desktop/src-common/advent/actions.clj b/desktop/src-common/advent/actions.clj index 6405fe36..a6dea3a8 100644 --- a/desktop/src-common/advent/actions.clj +++ b/desktop/src-common/advent/actions.clj @@ -10,7 +10,8 @@ [advent.screens.dialogue :as dialogue] [clojure.core.async :refer [put! ! >!! chan go thread take! alts!!]]) (:import [com.badlogic.gdx.graphics Pixmap Pixmap$Filter Texture Texture$TextureFilter] - [com.badlogic.gdx.graphics.g2d TextureRegion])) + [com.badlogic.gdx.graphics.g2d TextureRegion] + [com.badlogic.gdx Screen])) (defprotocol IAction (begin [this screen entities]) @@ -148,17 +149,17 @@ entities))))) (defn present-choices [entities & pairs] - (let [pairs (partition 2 pairs)] - (run-action entities - (begin [this screen entities] - (run! dialogue/choice-screen :on-present-choices :pairs pairs) - entities) + (run-action entities + (begin [this screen entities] + (run! dialogue/choice-screen :on-present-choices :pairs pairs) + (run! @(resolve 'advent.screens.scene/scene) :on-pause) + entities) - (continue [this screen entities] entities) + (continue [this screen entities] entities) - (done? [this screen entities] true) + (done? [this screen entities] true) - (terminate [this screen entities] entities)))) + (terminate [this screen entities] entities))) (defn give [entities target-id item] diff --git a/desktop/src-common/advent/screens/dialogue.clj b/desktop/src-common/advent/screens/dialogue.clj index 9ece19c4..9e486d43 100644 --- a/desktop/src-common/advent/screens/dialogue.clj +++ b/desktop/src-common/advent/screens/dialogue.clj @@ -5,10 +5,12 @@ [play-clj.g2d :refer :all] [clojure.pprint] [advent.pathfind] + [clojure.core.async :refer [put! ! >!! chan go thread take! alts!!]] #_[advent.screens.scene :as scene]) (:import [com.badlogic.gdx.graphics Pixmap Pixmap$Filter Texture Texture$TextureFilter] [com.badlogic.gdx.graphics.g2d TextureRegion] - [com.badlogic.gdx.scenes.scene2d.utils Align])) + [com.badlogic.gdx.scenes.scene2d.utils Align] + [com.badlogic.gdx Screen])) (defn ensure-on-screen [talk] (let [margin-width (* 0.05 (game :width)) @@ -34,7 +36,7 @@ (fn [{:keys [create-talk target-id text x y scale]} [entities]] (let [font (bitmap-font "ego/font.fnt" ) tr (bitmap-font! font :get-region) - scale (or (max scale 0.75) 1) + scale (or (min (max scale 0.75) 1) 1) width (/ (game :width) 1.5) tx (.getTexture tr) _ (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear) @@ -70,18 +72,17 @@ (let [font (bitmap-font "ego/font.fnt" ) tr (bitmap-font! font :get-region) scale 1 - width (/ (game :width) 1.5) tx (.getTexture tr) _ (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear)] (into entities (for [[[text result-script] i] (map vector pairs (range))] - (do (println result-script) - [i (assoc (label text (style :label font (color :white))) :x 0 :y (* 20 i) :result-script result-script)]))))) + [i (assoc (label text (style :label font (color :white))) :x 30 :y (* 30 i) :result-script result-script)])))) :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 (* 20 (count entities))) - (run! @(resolve 'advent.screens.scene/scene) :on-start-script :script (:result-script (entities (int (/ y 20))))) + (when (< y (* 30 (count entities))) + (run! @(resolve 'advent.screens.scene/scene) :on-resume) + (run! @(resolve 'advent.screens.scene/scene) :on-start-script :script (:result-script (entities (int (/ y 30))))) {})))) :on-resize (fn [screen entities] diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index ff5745e3..d5bc87c5 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -145,6 +145,17 @@ (merge params {:collision (advent.pathfind/map-from-resource collision) :interactions interactions-as-list}))) +(defn make-dialogue-tree [entities target-id tree] + (let [[e-line t-line options] tree + option-scripts (when options (for [option options] + [(first option) (actions/get-script entities + (make-dialogue-tree entities target-id option))]))] + (actions/talk entities :ego e-line) + (if (string? t-line) + (actions/talk entities target-id t-line) + (t-line)) + (apply actions/present-choices entities option-scripts))) + (defn backgrounds [screen] (let [sheep-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) sheep (animation 0.15 (for [i (flatten [(repeat 10 0) 1 2 3 4 5 6 7 4 5 6 7 8 9 10 (repeat 25 11) (repeat 15 12)])] @@ -168,26 +179,18 @@ :cursor :down} :wizard {:box [228 80 248 126] :script (actions/get-script entities - (actions/talk entities :ego "Hello there Fangald!") - (actions/talk entities :wizard "Oh no, not you again!") - (actions/present-choices entities "You're not my friend, Mr. Fangald?" - (actions/get-script entities - (actions/talk entities :ego "You're not my friend, Mr. Fangald?") - (actions/talk entities :wizard "No, you are a rascally little boy who is nothing but a cheat!") - (actions/present-choices entities - "Oh, come on, I'm not that bad." - (actions/get-script entities - (actions/talk entities :ego "Oh, come on, I'm not that bad.") - (actions/talk entities :wizard "Yes you are. Shoo!")) - "I'm sorry." - (actions/get-script entities - (actions/talk entities :ego "I'm sorry") - (actions/talk entities :wizard "That's better. Now scram.")) - )) - "Yes, it's me!" - (actions/get-script entities - (actions/talk entities :ego "Yes, it's me!") - (actions/talk entities :wizard "Great, just great. Leave me alone."))))}} + (make-dialogue-tree entities :wizard ["Hello there Mr. Fangald!" + "Oh no, not you again!" + [["You're not my friend, Mr. Fangald?" + "No, you are a rascally little boy who is nothing but a cheat!" + [["Oh come on, I'm not that bad." + "Yes you are. Shoo!"] + ["I'm sorry I stole your magic cowboy hat." + #(do (actions/talk entities :wizard "Go.") + (actions/talk entities :wizard "Away.") + (actions/transition-background entities :outside-house [262 88]))]]] + ["What do you mean, 'not you again'?" + "I mean get lost kid."]]]))}} :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)] @@ -343,9 +346,11 @@ (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 + :active? true} :actions {:object nil :channel (chan) :current nil @@ -358,7 +363,7 @@ [:entities :ego] (get-ego screen)) :inventory (assoc (texture "inventory.png") :x 278 :y 0 :baseline 9000 :mouse-in? (zone/box 278 0 320 42)) - :fps (assoc (label "0" (color :white) ) :x 5 :baseline 9000)})) + :fps (assoc (label "0" (color :white) ) :x 5 :baseline 0)})) :on-render (fn [screen [entities]] @@ -383,17 +388,25 @@ :on-mouse-moved (fn [screen [entities]] - (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})] - (if-let [mouse-override (find-override screen entities [x y])] - (assoc-in entities [:cursor :override] (cursor-override mouse-override)) - (assoc-in entities [:cursor :override] nil)))) + (when (get-in entities [:state :active?]) + (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})] + (if-let [mouse-override (find-override screen entities [x y])] + (assoc-in entities [:cursor :override] (cursor-override mouse-override)) + (assoc-in entities [:cursor :override] nil))))) :on-touch-down (fn [screen [entities]] - (if (= (button-code :right) - (:button screen)) - (assoc-in entities [:cursor :current] :main) - (left-click screen entities))) + (when (get-in entities [:state :active?]) + (if (= (button-code :right) + (:button screen)) + (assoc-in entities [:cursor :current] :main) + (left-click screen entities)))) - :on-start-script (fn [{:keys [script]} [entities] ] + :on-pause (fn [screen [entities]] + (assoc-in entities [:state :active?] false)) + + :on-resume (fn [screen [entities]] + (assoc-in entities [:state :active?] true)) + + :on-start-script (fn [{:keys [script]} [entities]] (script entities) entities)) From a5cd9fcea90e42e113ea9febfcd916cb679c482a Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Wed, 24 Sep 2014 23:11:20 -0700 Subject: [PATCH 03/18] more dialogue tree improvement. --- desktop/src-common/advent/actions.clj | 2 +- desktop/src-common/advent/screens/dialogue.clj | 11 ++++++++++- desktop/src-common/advent/screens/scene.clj | 11 ++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/desktop/src-common/advent/actions.clj b/desktop/src-common/advent/actions.clj index a6dea3a8..b03e80b7 100644 --- a/desktop/src-common/advent/actions.clj +++ b/desktop/src-common/advent/actions.clj @@ -152,7 +152,7 @@ (run-action entities (begin [this screen entities] (run! dialogue/choice-screen :on-present-choices :pairs pairs) - (run! @(resolve 'advent.screens.scene/scene) :on-pause) + (run! @(resolve 'advent.screens.scene/scene) :on-deactivate) entities) (continue [this screen entities] entities) diff --git a/desktop/src-common/advent/screens/dialogue.clj b/desktop/src-common/advent/screens/dialogue.clj index 9e486d43..42491218 100644 --- a/desktop/src-common/advent/screens/dialogue.clj +++ b/desktop/src-common/advent/screens/dialogue.clj @@ -81,9 +81,18 @@ (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-resume) + (run! @(resolve 'advent.screens.scene/scene) :on-reactivate) (run! @(resolve 'advent.screens.scene/scene) :on-start-script :script (:result-script (entities (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))] + (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)))))))) :on-resize (fn [screen entities] (size! screen 1280 960))) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index d5bc87c5..6abacfd1 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -154,7 +154,8 @@ (if (string? t-line) (actions/talk entities target-id t-line) (t-line)) - (apply actions/present-choices entities option-scripts))) + (when options + (apply actions/present-choices entities option-scripts)))) (defn backgrounds [screen] (let [sheep-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) @@ -401,11 +402,11 @@ (assoc-in entities [:cursor :current] :main) (left-click screen entities)))) - :on-pause (fn [screen [entities]] - (assoc-in entities [:state :active?] false)) + :on-deactivate (fn [screen [entities]] + (assoc-in entities [:state :active?] false)) - :on-resume (fn [screen [entities]] - (assoc-in entities [:state :active?] true)) + :on-reactivate (fn [screen [entities]] + (assoc-in entities [:state :active?] true)) :on-start-script (fn [{:keys [script]} [entities]] (script entities) From 51be2e0e1470562d6ae4f0d176baf05792b509cf Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Thu, 25 Sep 2014 17:07:39 -0700 Subject: [PATCH 04/18] a way of doing dialogue trees, but meh. --- desktop/src-common/advent/screens/scene.clj | 55 ++++++++++++--------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 6abacfd1..1a4611d1 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -145,17 +145,16 @@ (merge params {:collision (advent.pathfind/map-from-resource collision) :interactions interactions-as-list}))) -(defn make-dialogue-tree [entities target-id tree] - (let [[e-line t-line options] tree - option-scripts (when options (for [option options] - [(first option) (actions/get-script entities - (make-dialogue-tree entities target-id option))]))] - (actions/talk entities :ego e-line) - (if (string? t-line) - (actions/talk entities target-id t-line) - (t-line)) - (when options - (apply actions/present-choices entities option-scripts)))) +(defn run-dialogue-tree [entities command-pairs & [previous-line]] + (let [commands (partition 2 command-pairs)] + (doseq [[subject arg] commands] + (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)))])) + (if (= :line arg) + (actions/talk entities subject previous-line) + (actions/talk entities subject arg)))))) (defn backgrounds [screen] (let [sheep-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) @@ -180,18 +179,28 @@ :cursor :down} :wizard {:box [228 80 248 126] :script (actions/get-script entities - (make-dialogue-tree entities :wizard ["Hello there Mr. Fangald!" - "Oh no, not you again!" - [["You're not my friend, Mr. Fangald?" - "No, you are a rascally little boy who is nothing but a cheat!" - [["Oh come on, I'm not that bad." - "Yes you are. Shoo!"] - ["I'm sorry I stole your magic cowboy hat." - #(do (actions/talk entities :wizard "Go.") - (actions/talk entities :wizard "Away.") - (actions/transition-background entities :outside-house [262 88]))]]] - ["What do you mean, 'not you again'?" - "I mean get lost kid."]]]))}} + (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."]]]))}} :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)] From 27d992776a76b7035faf5af36d50b024bf6715af Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Fri, 26 Sep 2014 16:51:27 -0700 Subject: [PATCH 05/18] a better approach to dialogue treees. --- desktop/src-common/advent/actions.clj | 49 +++++++++++++++---- .../src-common/advent/screens/dialogue.clj | 13 ++--- desktop/src-common/advent/screens/scene.clj | 38 ++++++-------- 3 files changed, 61 insertions(+), 39 deletions(-) diff --git a/desktop/src-common/advent/actions.clj b/desktop/src-common/advent/actions.clj index b03e80b7..08f17413 100644 --- a/desktop/src-common/advent/actions.clj +++ b/desktop/src-common/advent/actions.clj @@ -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] diff --git a/desktop/src-common/advent/screens/dialogue.clj b/desktop/src-common/advent/screens/dialogue.clj index 42491218..5f9e4f86 100644 --- a/desktop/src-common/advent/screens/dialogue.clj +++ b/desktop/src-common/advent/screens/dialogue.clj @@ -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)))))))) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 1a4611d1..0d52d95f 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -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 From f5c6c593a71ed93e165b91df6eb9f7c518532e2d Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Fri, 26 Sep 2014 17:06:28 -0700 Subject: [PATCH 06/18] sample conversation. --- desktop/src-common/advent/screens/scene.clj | 25 ++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 0d52d95f..0230944f 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -3,6 +3,7 @@ [play-clj.ui :refer :all] [play-clj.utils :refer :all] [play-clj.g2d :refer :all] + [clojure.zip :as zip] [clojure.pprint] [advent.pathfind] [advent.actions :as actions] @@ -179,16 +180,20 @@ :cursor :down} :wizard {:box [228 80 248 126] :script (actions/get-script entities - (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 %)}}}) + (actions/present-choices entities {:choices {"Hello there Mr. Fangald" {:run #(do (actions/talk entities :ego %) + (actions/talk entities :wizard "Oh, no. Not you again!")) + :choices {"What do you mean, \"Not you again?\"" {:run #(do (actions/talk entities :ego %) + (actions/talk entities :wizard "I mean, you've wrecked my life and I never want to see you again.")) + :choices {"You mean the time I set your house on fire with a fire mint?" {:choices actions/previous-choices} + "You're still cross about my stealing your magic cowboy hat?" {:choices actions/previous-choices} + "Even an old hoot like you needs a kick in the pants every now and again." {:choices actions/previous-choices} + "Something else" {:choices actions/something-else}}} + "You're not happy to see me, Mr. Fangald?" {:run #(do (actions/talk entities :ego %) + (actions/talk entities :wizard "Of course not, you little cheat. You're nothing but a little cheat.")) + :choices #(-> % zip/left)} + "Something else" {:choices actions/something-else}}} + "Good bye, Mr. Fangald!" {:run #(do (actions/talk entities :ego %) + (actions/talk entities :wizard "Now scram!"))}}}) )}} :layers [(assoc (texture "inside-house/background.png") :x 0 :y 0 :baseline 0) From 9da703004a72f225ea6050cd54854e5e9972a449 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Sat, 27 Sep 2014 09:11:00 -0700 Subject: [PATCH 07/18] improvements on conversation tree. --- desktop/src-common/advent/screens/scene.clj | 79 ++++++++++++++------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 0230944f..55e93610 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -146,16 +146,55 @@ (merge params {:collision (advent.pathfind/map-from-resource collision) :interactions interactions-as-list}))) -(defn run-dialogue-tree [entities command-pairs & [previous-line]] - (let [commands (partition 2 command-pairs)] - (doseq [[subject arg] commands] - (if (= :choices subject) - (apply actions/present-choices entities (for [choice (partition 2 arg)] - [(first choice) (actions/get-script entities - (run-dialogue-tree entities (doto (second choice) println) (first choice)))])) - (if (= :line arg) - (actions/talk entities subject previous-line) - (actions/talk entities subject arg)))))) + +(defn do-dialogue [entities & pairs] + (loop [pairs (partition 2 pairs)] + (let [[[target line]] pairs + result (actions/talk entities target line)] + (if (seq (rest pairs)) + (recur (rest pairs)) + result)))) + +(defn respond [entities line & more] + (apply do-dialogue entities :ego line more)) + +(defn wizard-dialogue [entities] + { + :choices {"What do you mean, \"Not you again?\"" + {:run #(respond entities % :wizard "I mean, you've wrecked my life and I never want to see you again.") + :choices {"You mean the time I set your house on fire with a fire mint?" + {:run #(do + (respond entities % + :wizard "That was you!?" + :wizard "My house was nearly destroyed!" + :wizard "I spent weeks rebuilding my home!" + :wizard "Leave, now, or I'll turn you into a ..." + :wizard "... a ..." + :wizard "... a frog!" + :ego "Okay, okay! I'm leaving.") + (actions/transition-background entities :outside-house [262 88]) + (actions/talk entities :ego "I guess he's really upset with me."))} + "You're still cross about my stealing your magic cowboy hat?" + {:run #(do (respond entities % + :wizard "Of course I'm cross! It's irreplaceable!" + :wizard "That cowboy hat accented my facial physique." + :wizard "And complemented my skin color." + :wizard "And you little cheat stole it from me!" + :wizard "That's why I bought my MagiSafe 5000, to keep out intruders like you." + :wizard "Now leave.") + (actions/transition-background entities :outside-house [262 88]))} + "Even an old hoot like you needs a kick in the pants every now and again." + {:run #(respond entities % :wizard "What gives you the right to try to teach me a lesson?") + :choices {"My good looks?" {:choices actions/previous-choices} + "My good standing within the community?" {:choices actions/previous-choices} + "My respectful attitude?" {:choices actions/previous-choices}}}}} + "You're not happy to see me, Mr. Fangald?" + {:run #(respond entities % :wizard "Of course not, you little brat. You've made my life a living hell!") + :choices #(-> % zip/left)} + "Good bye, Mr. Fangald!" + {:run #(do + (respond entities % :wizard "Now scram!") + (actions/transition-background entities :outside-house [262 88]))}}}) (defn backgrounds [screen] (let [sheep-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) @@ -180,22 +219,8 @@ :cursor :down} :wizard {:box [228 80 248 126] :script (actions/get-script entities - (actions/present-choices entities {:choices {"Hello there Mr. Fangald" {:run #(do (actions/talk entities :ego %) - (actions/talk entities :wizard "Oh, no. Not you again!")) - :choices {"What do you mean, \"Not you again?\"" {:run #(do (actions/talk entities :ego %) - (actions/talk entities :wizard "I mean, you've wrecked my life and I never want to see you again.")) - :choices {"You mean the time I set your house on fire with a fire mint?" {:choices actions/previous-choices} - "You're still cross about my stealing your magic cowboy hat?" {:choices actions/previous-choices} - "Even an old hoot like you needs a kick in the pants every now and again." {:choices actions/previous-choices} - "Something else" {:choices actions/something-else}}} - "You're not happy to see me, Mr. Fangald?" {:run #(do (actions/talk entities :ego %) - (actions/talk entities :wizard "Of course not, you little cheat. You're nothing but a little cheat.")) - :choices #(-> % zip/left)} - "Something else" {:choices actions/something-else}}} - "Good bye, Mr. Fangald!" {:run #(do (actions/talk entities :ego %) - (actions/talk entities :wizard "Now scram!"))}}}) - - )}} + (do-dialogue entities :ego "Hello there Mr. Fangald!" :wizard "Oh no, not you again!") + (actions/present-choices entities (wizard-dialogue entities)))}} :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)] @@ -351,7 +376,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 From fd3b07bf123e10e8783132d0e96372621ec954e9 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Sat, 27 Sep 2014 10:19:20 -0700 Subject: [PATCH 08/18] ordered dialogue trees --- desktop/src-common/advent/actions.clj | 17 ++++++++++------- desktop/src-common/advent/screens/dialogue.clj | 4 ++-- desktop/src-common/advent/screens/scene.clj | 10 +++++----- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/desktop/src-common/advent/actions.clj b/desktop/src-common/advent/actions.clj index 08f17413..04adba77 100644 --- a/desktop/src-common/advent/actions.clj +++ b/desktop/src-common/advent/actions.clj @@ -163,30 +163,33 @@ (recur (inc so-far) (zip/right zipper))))) (defn make-zipper [tree] - (zip/zipper map? (comp vals :choices) (fn [n c] nil) tree)) + (zip/zipper map? (comp #(map second %) #(partition 2 %) :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)] + (let [selected-index (atom nil) + node (zip/node zipper) + dialogue-choices (partition 2 (:choices node))] (run-action entities (begin [this screen entities] - (run! dialogue/choice-screen :on-present-choices :choices (:choices node) :callback #(reset! selected-choice %)) + (run! dialogue/choice-screen :on-present-choices :choices dialogue-choices :callback #(reset! selected-index %)) (run! @(resolve 'advent.screens.scene/scene) :on-deactivate) entities) (continue [this screen entities] entities) - (done? [this screen entities] (not (nil? @selected-choice))) + (done? [this screen entities] (not (nil? @selected-index))) (terminate [this screen entities] (run! @(resolve 'advent.screens.scene/scene) :on-reactivate) entities)) - (let [zipper (nth-child zipper (-> node :choices keys (.indexOf @selected-choice))) + (let [zipper (nth-child zipper @selected-index) node (zip/node zipper)] (when-let [run (:run node)] - (run @selected-choice)) + (run (-> dialogue-choices + (nth @selected-index) + first))) (when-let [next-choices (:choices node)] (if (fn? next-choices) (recur (next-choices zipper)) diff --git a/desktop/src-common/advent/screens/dialogue.clj b/desktop/src-common/advent/screens/dialogue.clj index 5f9e4f86..e00fb9a6 100644 --- a/desktop/src-common/advent/screens/dialogue.clj +++ b/desktop/src-common/advent/screens/dialogue.clj @@ -75,7 +75,7 @@ tx (.getTexture tr) _ (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear)] (-> entities - (into (for [[text i] (map vector (keys choices) (range))] + (into (for [[[text] i] (map vector choices (range))] [i (assoc (label text (style :label font (color :white))) :x 30 :y (* 30 i))])) (assoc :state {:object nil :callback callback :choices choices})))) @@ -83,7 +83,7 @@ (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})] (when (seq entities) (when (< y (* 30 (count entities))) - ((get-in entities [:state :callback]) (nth (keys (get-in entities [:state :choices])) (int (/ y 30)))) + ((get-in entities [:state :callback]) (int (/ y 30))) {})))) :on-mouse-moved (fn [screen [entities]] diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 55e93610..9c6a7ce2 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -160,9 +160,9 @@ (defn wizard-dialogue [entities] { - :choices {"What do you mean, \"Not you again?\"" + :choices ["What do you mean, \"Not you again?\"" {:run #(respond entities % :wizard "I mean, you've wrecked my life and I never want to see you again.") - :choices {"You mean the time I set your house on fire with a fire mint?" + :choices ["You mean the time I set your house on fire with a fire mint?" {:run #(do (respond entities % :wizard "That was you!?" @@ -185,16 +185,16 @@ (actions/transition-background entities :outside-house [262 88]))} "Even an old hoot like you needs a kick in the pants every now and again." {:run #(respond entities % :wizard "What gives you the right to try to teach me a lesson?") - :choices {"My good looks?" {:choices actions/previous-choices} + :choices ["My good looks?" {:choices actions/previous-choices} "My good standing within the community?" {:choices actions/previous-choices} - "My respectful attitude?" {:choices actions/previous-choices}}}}} + "My respectful attitude?" {:choices actions/previous-choices}]}]} "You're not happy to see me, Mr. Fangald?" {:run #(respond entities % :wizard "Of course not, you little brat. You've made my life a living hell!") :choices #(-> % zip/left)} "Good bye, Mr. Fangald!" {:run #(do (respond entities % :wizard "Now scram!") - (actions/transition-background entities :outside-house [262 88]))}}}) + (actions/transition-background entities :outside-house [262 88]))}]}) (defn backgrounds [screen] (let [sheep-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) From fbbc7519a862f96c1dd0282e07a13eaa01abce77 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Sun, 28 Sep 2014 13:57:15 -0700 Subject: [PATCH 09/18] Wizard convincing puzzle. --- desktop/src-common/advent/screens/scene.clj | 63 +++++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 9c6a7ce2..c8cb77dd 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -159,8 +159,7 @@ (apply do-dialogue entities :ego line more)) (defn wizard-dialogue [entities] - { - :choices ["What do you mean, \"Not you again?\"" + {:choices ["What do you mean, \"Not you again?\"" {:run #(respond entities % :wizard "I mean, you've wrecked my life and I never want to see you again.") :choices ["You mean the time I set your house on fire with a fire mint?" {:run #(do @@ -185,9 +184,63 @@ (actions/transition-background entities :outside-house [262 88]))} "Even an old hoot like you needs a kick in the pants every now and again." {:run #(respond entities % :wizard "What gives you the right to try to teach me a lesson?") - :choices ["My good looks?" {:choices actions/previous-choices} - "My good standing within the community?" {:choices actions/previous-choices} - "My respectful attitude?" {:choices actions/previous-choices}]}]} + :choices ["My good looks?" + {:run #(do (respond entities % + :wizard "You know, handsome looks aren't all they're chocked up to be." + :wizard "Take me for example." + :wizard "When you have a bod like man, you can hardly go to the grocery store without being noticed." + :wizard "But no. Your looks, however good they may be, don't give you the right to teach me a lesson." + :wizard "Now please leave me in peace.") + (actions/transition-background entities :outside-house [262 88]))} + "My good standing within the community?" + {:run #(do (respond entities % + :wizard "Ha! Good standing?" + :wizard "You're the neighborhood cheat and everyone knows it." + :wizard "Now please leave me in peace.") + (actions/transition-background entities :outside-house [262 88]))} + "I'm going to be a knight! That counts for something doesn't it?" + {:run #(do (respond entities % + :wizard "You are, are you?" + :wizard "Pray tell, how do you, a mere wreckless youth, plan on becoming a knight?")) + :choices ["By pulling the Sword of Blergh from its stone!" + {:run #(respond entities % + :wizard "Well, well. It sounds I was wrong about you." + :wizard "Indeed, you are on the path of setting your destructive past behind you." + :wizard "But know this, the stone cannot be cheated easily." + :wizard "You must fulfill the age-old prophecy." + :wizard "'The Sword of Blergh with magic sting,' ..." + :wizard "... 'Shall yield to no earthly king.'" + :wizard "'To draw from hardened, weathered stone,' ..." + :wizard "... 'One must have valor, right to the bone.'" + :wizard "'Worthy in courage, wisdom and might,' ..." + :wizard "... 'only then with sword he'll fight.'" + :wizard "'But a hero should he prove not be,' ..." + :wizard "... 'Only ruin will fall on thee.'" + :wizard "'I'll fall neither for guile nor guise'..." + ) + :choices ["Is this almost over?" + {:run #(do (respond entities % + :wizard "Patience, boy." + :wizard "... 'Such a man will have great surprise.'" + :wizard "If this is truely your quest, boy, then I will help you in your quest. " + :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." + :ego "No cheating." + :ego "Check.") + (swap! entities (fn [e] (assoc-in e [:state :convinced-wizard?] true))))} + "*cough* *cough* *ahem*" + {:run #(do (respond entities % + :wizard "Excuse you." + :wizard "... 'Such a man will have great surprise.'" + :wizard "If this is truely your quest, boy, then I will help you in your quest. " + :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." + :ego "No cheating." + :ego "Check.") + (swap! entities (fn [e] (assoc-in e [:state :convinced-wizard?] true))))}]} + "By besting swamp, foe, and the occasional bizarre conversation tree." + {:run #(do (respond entities % + :wizard "While your goal sounds noble, no amount of bizarre conversation tree searching will earn my respect." + :wizard "Now please leave.") + (actions/transition-background entities :outside-house [262 88]))}]}]}]} "You're not happy to see me, Mr. Fangald?" {:run #(respond entities % :wizard "Of course not, you little brat. You've made my life a living hell!") :choices #(-> % zip/left)} From 4bd400dff3fa84f40bea084100f6c375f5c1c465 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Sun, 28 Sep 2014 14:52:05 -0700 Subject: [PATCH 10/18] first puzzle complete --- desktop/src-common/advent/actions.clj | 37 ++- .../src-common/advent/screens/dialogue.clj | 2 +- desktop/src-common/advent/screens/scene.clj | 212 +++++++++--------- 3 files changed, 142 insertions(+), 109 deletions(-) diff --git a/desktop/src-common/advent/actions.clj b/desktop/src-common/advent/actions.clj index 04adba77..26d6f68e 100644 --- a/desktop/src-common/advent/actions.clj +++ b/desktop/src-common/advent/actions.clj @@ -19,8 +19,10 @@ (done? [this screen entities]) (continue [this screen entities]) (terminate [this screen entities]) + (can-skip? [this screen entities]) (get-channel [this])) + (defmacro get-script [entities & forms] `(fn [starting-entities#] (let [~entities (atom starting-entities#)] @@ -114,7 +116,9 @@ (< (dist final-x final-y from-x from-y) 1))) (terminate [this screen entities] - (stop screen entities target-id))) + (stop screen entities target-id)) + (can-skip? [this screen entities] + false)) @entities))) (defn get-text-duration [text] @@ -147,7 +151,9 @@ (run! dialogue/talking-screen :stop-talk :target-id target-id) (if stop? (stop screen entities target-id) - entities))))) + entities)) + (can-skip? [this screen entities] + true)))) (defn something-else [zipper] (-> zipper zip/up zip/up)) @@ -182,7 +188,9 @@ (terminate [this screen entities] (run! @(resolve 'advent.screens.scene/scene) :on-reactivate) - entities)) + entities) + (can-skip? [this screen entities] + false)) (let [zipper (nth-child zipper @selected-index) node (zip/node zipper)] @@ -195,6 +203,16 @@ (recur (next-choices zipper)) (recur zipper))))))) +(defn update-state [entities f] + (run-action entities + (begin [this screen entities] + (update-in entities [:state] f )) + (continue [this screen entities] entities) + (done? [this screen entities] true) + (terminate [this screen entities] + entities) + (can-skip? [this screen entities] + false))) (defn give [entities target-id item] (run-action entities @@ -210,7 +228,9 @@ (done? [this screen entities] true) (terminate [this screen entities] - entities))) + entities) + (can-skip? [this screen entities] + false))) (defn transition-background [entities new-background [x y]] (run-action entities @@ -231,7 +251,9 @@ (>= (get-in entities [:transition :opacity]) 1.0)) (terminate [this screen entities] - entities)) + entities) + (can-skip? [this screen entities] + false)) (run-action entities (begin [this screen entities] (let [ego (get-in entities [:background :entities :ego]) @@ -248,4 +270,7 @@ (<= (get-in entities [:transition :opacity]) 0.0)) (terminate [this screen entities] - (dissoc entities :transition)))) + (dissoc entities :transition)) + + (can-skip? [this screen entities] + false))) diff --git a/desktop/src-common/advent/screens/dialogue.clj b/desktop/src-common/advent/screens/dialogue.clj index e00fb9a6..b0bfe9ad 100644 --- a/desktop/src-common/advent/screens/dialogue.clj +++ b/desktop/src-common/advent/screens/dialogue.clj @@ -82,7 +82,7 @@ :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))) + (when (< y (* 30 (dec (count entities)))) ((get-in entities [:state :callback]) (int (/ y 30))) {})))) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index c8cb77dd..2991da55 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -53,16 +53,22 @@ (let [interaction (first (filter #(mouse-in? % [x y]) (get-in entities [:background :interactions]))) + + current-action (get-in entities [:actions :current]) ;; TODO - hacky way of resetting queue - entities (if-let [current-action (get-in entities [:actions :current])] - (assoc (actions/terminate current-action screen entities) - :actions {:channel (chan) :current nil :started? false}) - entities) - script (or (when interaction - (get-script interaction [x y])) - (get-script default-interaction [x y]))] + entities (if (and current-action (actions/can-skip? current-action screen entities)) + (let [terminated-entities (actions/terminate current-action screen entities)] + (do (put! (actions/get-channel current-action) terminated-entities) + (-> terminated-entities + (assoc-in [:actions :current] nil) + (assoc-in [:actions :started?] false)))) + (assoc-in entities [:actions :channel] (chan)))] - (script entities) + (if current-action + entities + ((or (when interaction + (get-script interaction [x y])) + (get-script default-interaction [x y])) entities)) entities)))) (defn flip [anim] @@ -159,95 +165,97 @@ (apply do-dialogue entities :ego line more)) (defn wizard-dialogue [entities] - {:choices ["What do you mean, \"Not you again?\"" - {:run #(respond entities % :wizard "I mean, you've wrecked my life and I never want to see you again.") - :choices ["You mean the time I set your house on fire with a fire mint?" - {:run #(do - (respond entities % - :wizard "That was you!?" - :wizard "My house was nearly destroyed!" - :wizard "I spent weeks rebuilding my home!" - :wizard "Leave, now, or I'll turn you into a ..." - :wizard "... a ..." - :wizard "... a frog!" - :ego "Okay, okay! I'm leaving.") - (actions/transition-background entities :outside-house [262 88]) - (actions/talk entities :ego "I guess he's really upset with me."))} - "You're still cross about my stealing your magic cowboy hat?" - {:run #(do (respond entities % - :wizard "Of course I'm cross! It's irreplaceable!" - :wizard "That cowboy hat accented my facial physique." - :wizard "And complemented my skin color." - :wizard "And you little cheat stole it from me!" - :wizard "That's why I bought my MagiSafe 5000, to keep out intruders like you." - :wizard "Now leave.") - (actions/transition-background entities :outside-house [262 88]))} - "Even an old hoot like you needs a kick in the pants every now and again." - {:run #(respond entities % :wizard "What gives you the right to try to teach me a lesson?") - :choices ["My good looks?" - {:run #(do (respond entities % - :wizard "You know, handsome looks aren't all they're chocked up to be." - :wizard "Take me for example." - :wizard "When you have a bod like man, you can hardly go to the grocery store without being noticed." - :wizard "But no. Your looks, however good they may be, don't give you the right to teach me a lesson." - :wizard "Now please leave me in peace.") - (actions/transition-background entities :outside-house [262 88]))} - "My good standing within the community?" - {:run #(do (respond entities % - :wizard "Ha! Good standing?" - :wizard "You're the neighborhood cheat and everyone knows it." - :wizard "Now please leave me in peace.") - (actions/transition-background entities :outside-house [262 88]))} - "I'm going to be a knight! That counts for something doesn't it?" - {:run #(do (respond entities % - :wizard "You are, are you?" - :wizard "Pray tell, how do you, a mere wreckless youth, plan on becoming a knight?")) - :choices ["By pulling the Sword of Blergh from its stone!" - {:run #(respond entities % - :wizard "Well, well. It sounds I was wrong about you." - :wizard "Indeed, you are on the path of setting your destructive past behind you." - :wizard "But know this, the stone cannot be cheated easily." - :wizard "You must fulfill the age-old prophecy." - :wizard "'The Sword of Blergh with magic sting,' ..." - :wizard "... 'Shall yield to no earthly king.'" - :wizard "'To draw from hardened, weathered stone,' ..." - :wizard "... 'One must have valor, right to the bone.'" - :wizard "'Worthy in courage, wisdom and might,' ..." - :wizard "... 'only then with sword he'll fight.'" - :wizard "'But a hero should he prove not be,' ..." - :wizard "... 'Only ruin will fall on thee.'" - :wizard "'I'll fall neither for guile nor guise'..." - ) - :choices ["Is this almost over?" - {:run #(do (respond entities % - :wizard "Patience, boy." - :wizard "... 'Such a man will have great surprise.'" - :wizard "If this is truely your quest, boy, then I will help you in your quest. " - :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." - :ego "No cheating." - :ego "Check.") - (swap! entities (fn [e] (assoc-in e [:state :convinced-wizard?] true))))} - "*cough* *cough* *ahem*" - {:run #(do (respond entities % - :wizard "Excuse you." - :wizard "... 'Such a man will have great surprise.'" - :wizard "If this is truely your quest, boy, then I will help you in your quest. " - :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." - :ego "No cheating." - :ego "Check.") - (swap! entities (fn [e] (assoc-in e [:state :convinced-wizard?] true))))}]} - "By besting swamp, foe, and the occasional bizarre conversation tree." - {:run #(do (respond entities % - :wizard "While your goal sounds noble, no amount of bizarre conversation tree searching will earn my respect." - :wizard "Now please leave.") - (actions/transition-background entities :outside-house [262 88]))}]}]}]} - "You're not happy to see me, Mr. Fangald?" - {:run #(respond entities % :wizard "Of course not, you little brat. You've made my life a living hell!") - :choices #(-> % zip/left)} - "Good bye, Mr. Fangald!" - {:run #(do - (respond entities % :wizard "Now scram!") - (actions/transition-background entities :outside-house [262 88]))}]}) + (do-dialogue entities :ego "Hello there Mr. Fangald!" :wizard "Oh no, not you again!") + (actions/present-choices entities + {:choices ["What do you mean, \"Not you again?\"" + {:run #(respond entities % :wizard "I mean, you've wrecked my life and I never want to see you again.") + :choices ["You mean the time I set your house on fire with a fire mint?" + {:run #(do + (respond entities % + :wizard "That was you!?" + :wizard "My house was nearly destroyed!" + :wizard "I spent weeks rebuilding my home!" + :wizard "Leave, now, or I'll turn you into a ..." + :wizard "... a ..." + :wizard "... a frog!" + :ego "Okay, okay! I'm leaving.") + (actions/transition-background entities :outside-house [262 88]) + (actions/talk entities :ego "I guess he's really upset with me."))} + "You're still cross about my stealing your magic cowboy hat?" + {:run #(do (respond entities % + :wizard "Of course I'm cross! It's irreplaceable!" + :wizard "That cowboy hat accented my facial physique." + :wizard "And complemented my skin color." + :wizard "And you little cheat stole it from me!" + :wizard "That's why I bought my MagiSafe 5000, to keep out intruders like you." + :wizard "Now leave.") + (actions/transition-background entities :outside-house [262 88]))} + "Even an old hoot like you needs a kick in the pants every now and again." + {:run #(respond entities % :wizard "What gives you the right to try to teach me a lesson?") + :choices ["My good looks?" + {:run #(do (respond entities % + :wizard "You know, handsome looks aren't all they're chocked up to be." + :wizard "Take me for example." + :wizard "When you have a bod like man, you can hardly go to the grocery store without being noticed." + :wizard "But no. Your looks, however good they may be, don't give you the right to teach me a lesson." + :wizard "Now please leave me in peace.") + (actions/transition-background entities :outside-house [262 88]))} + "My good standing within the community?" + {:run #(do (respond entities % + :wizard "Ha! Good standing?" + :wizard "You're the neighborhood cheat and everyone knows it." + :wizard "Now please leave me in peace.") + (actions/transition-background entities :outside-house [262 88]))} + "I'm going to be a knight! That counts for something doesn't it?" + {:run #(do (respond entities % + :wizard "You are, are you?" + :wizard "Pray tell, how do you, a mere wreckless youth, plan on becoming a knight?")) + :choices ["By pulling the Sword of Blergh from its stone!" + {:run #(respond entities % + :wizard "Well, well. It sounds I was wrong about you." + :wizard "Indeed, you are on the path of setting your destructive past behind you." + :wizard "But know this, the stone cannot be cheated easily." + :wizard "You must fulfill the age-old prophecy." + :wizard "'The Sword of Blergh with magic sting,' ..." + :wizard "... 'Shall yield to no earthly king.'" + :wizard "'To draw from hardened, weathered stone,' ..." + :wizard "... 'One must have valor, right to the bone.'" + :wizard "'Worthy in courage, wisdom and might,' ..." + :wizard "... 'only then with sword he'll fight.'" + :wizard "'But a hero should he prove not be,' ..." + :wizard "... 'Only ruin will fall on he.'" + :wizard "'Should he use guile or guise'..." + ) + :choices ["Is this almost over?" + {:run #(do (actions/update-state (fn [state] (assoc state :convinced-wizard? true))) + (respond entities % + :wizard "Patience, boy." + :wizard "... 'Such a man will have great surprise.'" + :wizard "If this is truely your quest, boy, then I will help you in your quest. " + :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." + :ego "No cheating." + :ego "Check."))} + "*cough* *cough* *ahem*" + {:run #(do (actions/update-state entities (fn [state] (assoc state :convinced-wizard? true))) + (respond entities % + :wizard "Excuse you. Moving on..." + :wizard "... 'Such a man will have great surprise.'" + :wizard "If this is truely your quest, boy, then I will help you in your quest. " + :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." + :ego "No cheating." + :ego "Check."))}]} + "By besting swamp, foe, and the occasional bizarre conversation tree." + {:run #(do (respond entities % + :wizard "While your goal sounds noble, no amount of bizarre conversation tree searching will earn my respect." + :wizard "Now please leave.") + (actions/transition-background entities :outside-house [262 88]))}]}]}]} + "You're not happy to see me, Mr. Fangald?" + {:run #(respond entities % :wizard "Of course not, you little brat. You've made my life a living hell!") + :choices #(-> % zip/left)} + "Good bye, Mr. Fangald!" + {:run #(do + (respond entities % :wizard "Now scram!") + (actions/transition-background entities :outside-house [262 88]))}]})) (defn backgrounds [screen] (let [sheep-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) @@ -270,10 +278,7 @@ (actions/walk-to entities :ego [237 1]) (actions/transition-background entities :outside-house [262 88])) :cursor :down} - :wizard {:box [228 80 248 126] - :script (actions/get-script entities - (do-dialogue entities :ego "Hello there Mr. Fangald!" :wizard "Oh no, not you again!") - (actions/present-choices entities (wizard-dialogue entities)))}} + :wizard {:box [228 80 248 126]}} :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)] @@ -293,7 +298,10 @@ entities (actions/walk-to entities :ego [262 88]) (actions/talk entities :ego (str "Anyone home?")) - (actions/transition-background entities :inside-house [237 0]))} + (actions/transition-background entities :inside-house [237 0]) + (if (get-in @entities [:state :convinced-wizard?]) + (actions/talk entities :wizard (str "Oh, hello there boy.")) + (wizard-dialogue entities)))} :sword {:box [274 55 305 88] :script (actions/get-script entities From d235017423256439dab433bb3255f63dd320fe72 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Wed, 1 Oct 2014 13:26:56 -0700 Subject: [PATCH 11/18] lots of improvements. --- desktop/src-common/advent/actions.clj | 8 +-- .../src-common/advent/screens/inventory.clj | 62 +++++++++++++++---- desktop/src-common/advent/screens/scene.clj | 25 +++++--- desktop/src-common/advent/utils.clj | 8 +++ 4 files changed, 77 insertions(+), 26 deletions(-) diff --git a/desktop/src-common/advent/actions.clj b/desktop/src-common/advent/actions.clj index 26d6f68e..ca2cfb1a 100644 --- a/desktop/src-common/advent/actions.clj +++ b/desktop/src-common/advent/actions.clj @@ -67,7 +67,7 @@ ~@forms)) (reset! ~entities ( entities - (update-in [:background :entities target-id :inventory] #(conj % item)) + (update-in [:state :inventory] #(conj % item)) (assoc-in [:cursor :current] item))) (continue [this screen entities] entities) diff --git a/desktop/src-common/advent/screens/inventory.clj b/desktop/src-common/advent/screens/inventory.clj index f1b14a4c..9666307f 100644 --- a/desktop/src-common/advent/screens/inventory.clj +++ b/desktop/src-common/advent/screens/inventory.clj @@ -4,7 +4,9 @@ [play-clj.utils :refer :all] [play-clj.g2d :refer :all] [clojure.pprint] - [advent.pathfind]) + [advent.pathfind] + [advent.zone :as zone] + [advent.utils :as utils]) (:import [com.badlogic.gdx.graphics Pixmap Pixmap$Filter Texture Texture$TextureFilter] [com.badlogic.gdx.graphics.g2d TextureRegion] [com.badlogic.gdx.scenes.scene2d.utils Align] @@ -12,17 +14,24 @@ InputMultiplexer InputProcessor Net Preferences Screen])) + (defscreen inventory-screen :on-show (fn [screen entities] (update! screen :renderer (stage) :camera (orthographic)) - {:overlay (assoc (texture "inventory-overlay.png" ) :x 0 :y 0) - :fade (assoc (texture "black.png") - :scale-x 20 - :scale-y 20 - :opacity 0.7) - :shown? false - :start-showing? false}) + (let [highlighted-text (assoc (label "Hello" (style :label (utils/get-font "ego/font.fnt") (color :white))) :x 0 :y 850 :width 1280)] + (label! highlighted-text :set-alignment Align/center) + {:overlay (assoc (texture "inventory-overlay.png" ) :x 0 :y 0 :scale-x 4 :scale-y 4 :origin-x 0 :origin-y 0) + :fade (assoc (texture "black.png") + :scale-x 80 + :scale-y 80 + :opacity 0.7) + :all-items (texture! (texture "cursor.png") :split 16 16) + :items [] + :shown? false + :start-showing? false + :highlighted-item nil + :highlighted-text highlighted-text})) :on-render (fn [screen [entities]] @@ -33,18 +42,47 @@ entities)] (when (:shown? entities) - (render! screen [(:fade entities) (:overlay entities)])) + (render! screen [(:fade entities) (:overlay entities)]) + (render! screen (:items entities)) + (if-let [item (:highlighted-item entities)] + (label! (:highlighted-text entities) :set-text (name item)) + (label! (:highlighted-text entities) :set-text "")) + (render! screen [(:highlighted-text entities)])) entities)) - :show-screen (fn [screen [entities]] - (assoc entities :start-showing? true)) + :show-screen (fn [{items :items} [entities]] + (assoc entities :start-showing? true + :items (for [[item index] (map vector items (range)) + :let [x (+ (* 79 4) (* index (* 24 4))) + y (* 4 180) + item-width 16 + offset-x (+ x (/ item-width 2)) + offset-y (+ y (/ item-width 2)) + padding (/ item-width 2) + padding (* 4 padding)]] + (assoc (texture (aget (:all-items entities) 0 (.indexOf utils/+all-cursors+ item))) + :x x :y y + :scale-x 4 + :scale-y 4 + :item item + :box (zone/box (- offset-x padding) (- offset-y padding) (+ offset-x item-width padding) (+ offset-y item-width padding)))))) + + :on-mouse-moved (fn [screen [entities]] + (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)}) + selected-entity (first (filter #((:box %) x y) (:items entities)))] + (if selected-entity + (assoc entities :highlighted-item (:item selected-entity)) + (assoc entities :highlighted-item nil)))) :on-touch-down (fn [screen [entities]] (when (:shown? entities) + (run! @(resolve 'advent.screens.scene/scene) :on-reactivate) + (when-let [{:keys [highlighted-item]} entities] + (run! @(resolve 'advent.screens.scene/scene) :on-chose-item :item highlighted-item)) (-> entities (assoc :shown? false) (assoc :start-showing? false)))) :on-resize (fn [screen entities] - (size! screen 320 240) + (height! screen 960) entities)) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 2991da55..c70082c2 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -34,7 +34,7 @@ IInteractable (get-script [_ [x y]] (actions/get-script entities - (actions/walk-to entities :ego [x y]))))) + (actions/walk-to entities :ego [x y] true))))) (defn find-override [screen entities [x y]] @@ -43,7 +43,8 @@ (get-in entities [:background :interactions])))) (defn open-inventory [screen entities] - (run! inventory-screen :show-screen)) + (run! inventory-screen :show-screen :items (get-in entities [:state :inventory])) + (assoc-in entities [:state :active?] false)) (defn left-click [screen entities] @@ -103,7 +104,7 @@ :origin-x 9 :origin-y 0 :scaled true - :inventory #{} + :x 150 :y 95 :id "ego"}] (actions/start-animation screen @@ -227,7 +228,7 @@ :wizard "'Should he use guile or guise'..." ) :choices ["Is this almost over?" - {:run #(do (actions/update-state (fn [state] (assoc state :convinced-wizard? true))) + {:run #(do (actions/update-state entities (fn [state] (assoc state :convinced-wizard? true))) (respond entities % :wizard "Patience, boy." :wizard "... 'Such a man will have great surprise.'" @@ -311,9 +312,9 @@ :sheep {:box [38 160 71 181] :script (actions/get-script entities - (if ((get-in @entities [:background :entities :ego :inventory]) :wool) + (if ((get-in @entities [:state :inventory]) :wool) (actions/talk entities :ego "The sheep has given me enough wool.") - (do (actions/give entities :ego :wool) + (do (actions/give entities :wool) (actions/talk entities :ego "I guess his wool is shedding."))))} :right-dir {:box [300 131 320 224] :script (actions/get-script @@ -363,11 +364,11 @@ :mushrooms {:box [247 59 269 76] :script (actions/get-script entities - (if ((get-in @entities [:background :entities :ego :inventory]) :mushrooms) + (if ((get-in @entities [:state :inventory]) :mushrooms) (actions/talk entities :ego "I've already got a junk ton of mushrooms.") (do (actions/walk-to entities :ego [242 75]) - (actions/give entities :ego :mushrooms) + (actions/give entities :mushrooms) (actions/talk entities :ego "Perfectly ripe mushrooms!"))))} :window {:box [103 44 130 140] :script (actions/get-script @@ -437,11 +438,12 @@ (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 - :active? true} + :active? true + :inventory (sorted-set)} :actions {:object nil :channel (chan) :current nil @@ -498,6 +500,9 @@ :on-reactivate (fn [screen [entities]] (assoc-in entities [:state :active?] true)) + :on-chose-item (fn [{:keys [item]} [entities]] + (assoc-in entities [:cursor :current] item)) + :on-start-script (fn [{:keys [script]} [entities]] (script entities) entities)) diff --git a/desktop/src-common/advent/utils.clj b/desktop/src-common/advent/utils.clj index bc91bdd0..23c113c4 100644 --- a/desktop/src-common/advent/utils.clj +++ b/desktop/src-common/advent/utils.clj @@ -24,3 +24,11 @@ (pixmap! resized :draw-pixmap base-cursor (* index 16) 0 16 16 0 0 target-width target-height) resized )) + + +(defn get-font [filename] + (let [font (bitmap-font filename) + tr (bitmap-font! font :get-region) + tx (.getTexture tr)] + (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear) + font)) From 6c0acd1ae62f590c3969aefb595bbb4ff03c70a6 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Wed, 1 Oct 2014 20:42:26 -0700 Subject: [PATCH 12/18] item interactions. --- desktop/src-common/advent/screens/scene.clj | 25 +++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index c70082c2..2302adce 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -27,14 +27,17 @@ (cursor-override [this])) (defprotocol IInteractable - (get-script [this location])) + (get-script [this cursor location])) (def default-interaction (reify IInteractable - (get-script [_ [x y]] - (actions/get-script entities - (actions/walk-to entities :ego [x y] true))))) + (get-script [_ cursor [x y]] + (if (= :main cursor) + (actions/get-script entities + (actions/walk-to entities :ego [x y] true)) + (actions/get-script entities + (actions/talk entities :ego "I don't know what to do with that.")))))) (defn find-override [screen entities [x y]] @@ -68,8 +71,8 @@ (if current-action entities ((or (when interaction - (get-script interaction [x y])) - (get-script default-interaction [x y])) entities)) + (get-script interaction (get-in entities [:cursor :current]) [x y])) + (get-script default-interaction (get-in entities [:cursor :current]) [x y])) entities)) entities)))) (defn flip [anim] @@ -145,8 +148,10 @@ (mouse-in? [_ location] (apply (apply zone/box (:box spec)) location)) IInteractable - (get-script [_ location] - (:script spec)) + (get-script [_ cursor location] + (if (= :main cursor) + (:script spec) + (get-in spec [:scripts cursor]))) ICursorOverridable (cursor-override [this] (:cursor spec))) )] @@ -315,7 +320,9 @@ (if ((get-in @entities [:state :inventory]) :wool) (actions/talk entities :ego "The sheep has given me enough wool.") (do (actions/give entities :wool) - (actions/talk entities :ego "I guess his wool is shedding."))))} + (actions/talk entities :ego "I guess her wool is shedding.")))) + :scripts {:wool (actions/get-script entities + (actions/talk entities :ego "She doesn't need it back."))}} :right-dir {:box [300 131 320 224] :script (actions/get-script entities From a21d0cb6f353b60aaec439d520db9d0081b3f7c7 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Thu, 2 Oct 2014 12:26:29 -0700 Subject: [PATCH 13/18] the sheep can move closer to the player now. --- desktop/resources/cursor.png | Bin 2257 -> 2271 bytes .../resources/outside-castle/collision.png | Bin 5654 -> 5825 bytes desktop/resources/outsidehouse/collision.png | Bin 6350 -> 6350 bytes desktop/src-common/advent/actions.clj | 42 ++++++++++++++++++ desktop/src-common/advent/screens/scene.clj | 15 ++++++- desktop/src-common/advent/utils.clj | 2 +- 6 files changed, 57 insertions(+), 2 deletions(-) diff --git a/desktop/resources/cursor.png b/desktop/resources/cursor.png index b1f3bfa5783b9ecdbff8ced219e5316b1ca603f7..92337a7336cd9094471fd032daeff200c596976a 100644 GIT binary patch delta 1180 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
~0Pk$_bGh6uNP4H2Wz;!HS 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 delta 4590 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 W?Op9>Zk&KYkGYApafPAhwSNMgJff%o diff --git a/desktop/resources/outsidehouse/collision.png b/desktop/resources/outsidehouse/collision.png index c2c63c56ddb4242a8b92e4759f9e560c982aad1e..e1397b3e5e372deebd6fc89d4b0b0cc15d449585 100644 GIT binary patch delta 5282 zcmcIoX*ksHzn=N_rBP@Gll-D)28prDR+d3z=O@|Mkg`Q1e%Zc5ma(s6-=pl2Erdxz zSz8!ek)3R1Upvlq&UId%7yth`&#ULUpX+nopY6Fm_w)3L^@&wlf{;!Ruj(LaO`E>= ztf0CmDx?T=BQym2DwSNF3=YR>lf^pJc~A_(Y*I@f+hO=1;cHIUIunm=reJ%HGY$|CiX)5U>vbMC;H#RP1&U-2vO|)zTbY4;* zE^RT1AP6wv3c>e%zf zXx~txe(gN-C?DU1)lVYLL^y$0>5P*?gWjTIgK&vcJb_~MnHR=nWyQHlc=ZzxmHVpF zr^@S!D5uXG%#Rur-Gk^%E?$^2O(sOL_rD5GEeGKN^tXdb+Qd+)ZTa4D;=pn)x!}a3 z0u+JtV7x>z0&Tj*i=&=FV5nyz^aVg3lL*1-ZDkmI+u#FwgHVHSb6he7k&}XcoQ!Zp zjW#LgZH+}UX*kTt@o-fbcFD4lk9wx^fF%(FVnlC}(9k3@t#9mzg2lJ>oz?Zh!Hr0` z^M7Gsa3;_M?o{;XX3XlxxI4C>Orw+r3@&9_cc|1f)vb7)TRB%37zb#k?D;`3@H~bD zV<+{nAxVTR5NVV3*i>Gi<&SwY2v)-2;A_~7(R0zyDt_gLkupT2jF(K;Pg(lAQFRQ# zWGMDDuPZHeVTWOz?Vp_Rl4RtsVnF#-2?9g7Gux8tQnqVyWNF{o6o6RgvQez%VMP!y z2{1fW-KO08oaJ8Clymdv_RGp7v<-rH|D>rbS#0Qr9ZY8nLXDuZZF{SlZM~DTKa$_? z$?z!hE+$?9Z=Q5md;W{~!JKTf#6?H}?iRR{=1IeqA0w^39j@eoKpBiR*8>4!22R7l z;aglE0060e65#)UEvJ^B#e6bdZ??H6&b$x@1C}d`iuoH1X0RFpsxi*tFo?Od(5aU^ zNEwT=&1Y84|NHgA8{j0fcmhqlP{cC0sPOm7%!f0TS!TUZ%vbi$%Wy|#64DWvSsytm zolCGQvwjAne?-?OzP5RmlYBCiM8}vuV?)_K&I*%Yfpj@HoFI&j&0w zwTx7ksz!8)`aZbBOorV_Zua}EMP^}0erdNRfuVlKTPOt-I*<|gtB;;xF;um)G_7IT zSu(;`7Q!cYpMnc_rl$dj9yE@Hk))l%4ItJLbPt_yqPK$8E1zr5h0ku0Y+H^8`&Tyi zKYfA5_goa;{A%~Ef4Fu$xyS@DcN^H6qv70DhVi}ej(3o3pk4d<-`2Wpe-3xJE^@bu z_{~Nz;i;MS9Hkcm*@_F#)R?d^zTri_O4m|?(2YQi-NeC zu4?ly*PT8Fp>1>qG07O9_^zGmg<$ED+r@(xhDi4769;(*&(2Nv+p2O;lWG}WP3;`bMgIiESCI}qwgK7-t5dk zgBjf-{!fqosqtT=K(20nJ6U7>YCfxxFQ~#y-=#HR#j_$A2hEnppSq*(+w(OC98Y&j z&nf~?9@pL8=6%d`&OT+Q2h-@(28{30GCydx_-F2EoeOhg8tKFkenymZ}w26>da z@AoPz9+!u;FIop|wcb52nNDKsjFCLpWppG_Do4)UC{!SG;;yKW2i(QMvs5?o$ZMbgLCGoj$doxxp{qfmPadFx;_T)VOk3 z?Nl|6QNC|`Bjo;QX8{=|BwGiSAYS7M(jFU_!r2LQ-BtON)+Y~n?pqh*YC82?QIl-g z?NaW6e9#w}J_d-X5&`dj-6Y^~qz^j}$z4M;b? zPAqjSaG$q4ccp);nXmQDlfA-L7vZMEk1Io5>Q2O+lz@lEfkwez8NSf>Nax;hZi!3a zUwk$^Cfz@ug+Yt$hmNx;+``<78?Vf{$ z%W3*0Ec$TSwUYAo@A-GqT8IZOAqyQ-tuomQjC&%TS z#i#|ZmaM*SZF$o$r*k^Pd}2$=`*riq#Gemq+u;4{Bj{Wn!VPr|l)^uMUetY&+gxz0 zH#c@NdUWrgWo)(XhhdW{X)rmIdKa+^2nw|p4?lNnz3jV`l5u)fM)rCX$Mk6ti|P%o zTuP3tI}_Y&Z-fd#+xWddTLs^&56;7ftgusOaRUi3mD$6pGf*h2VN~e#UpJ_s5voPD zpfVk+lv%cwWJeNTb=@r`k}EBC0nbZX7Z8eKKd<=o7ik>@NFpbyQ;RL%!H2(UoY*S|ii(gv-LKJSM7uKFVBTJ0Ux={ydmo*g9 z@)`ZCq{75j>tZ1nd=AP6PgxS|tBNe~ENO6OZ5-uIg+5WZxHvcm?jcLe*d(6-!k_E z(;E%r6{vZvlFPoA7F7AU2QqtfHZzBx+ejIca){L9r4vHZ1A;ILmc}P)9H9R2=r3Uu z9IyxyC-Sh8pM1=a`w(&}{<}rc3Rk~3X=PAQt6d(-%YL=55@4!ZI!CWW>ZNGwK~(-y z#hDlLhh6df^;Frb;%bSY$(E#PU71of&=ZmP)(lHJG%Ge7kwMv*wnQ<*5r*0@xRFI> zLS7XhppjB#jwQj&i`hKrQKIK`4K8JaOu8>tPt?(>rl#_V9JvYyFK9*tob0?$2B|kM zlUC98W##^cXq`PFn+uXY(3To$0={kZDcsMAed6Zsawx&*L;zGzmHAd0%}6_L8GF-_ zE2IEKWnBbY#I4A~*GEF0z~k$Jz;aDx0UaEn%}OABiArC~bJ(K!<*D0v0CJ!yr!1=( z;74=RsI-iv{@Q`2XUvEaB47;Sjn8py^wC;TyfpHv_GG)XBII7N&c=8y&>x7+l&u}% z)Qn{Zhj^$$>*<^5o@R7bkeo)9&Ix;O;~lQrgKyuJ2IE;Wy#P77p#XaOz6px;TwXOZ z?PKDvG7X90OD7t`SAGA!$rSKV)k_5}8MWI)R`K+#;ikqcy$RkFtQeYg+#m!c2loj9 zE^k(~H2b04GpL+B+3rl*TXaf~tlYi{&xPo+j8i>a)Xy}1>GdI9`^C0~-x>G@F)t!r z>i$|_1J|We&71=hxReR4@Vz7Q!S1(9__y>Tp=nrdY8os>&QJ1}P}0me#X3e*g`?W6 zN6Gg{3^}TqZfVL?Tuwuu-yo^OR6KTc&Mdz}U8;O3bc|(7 zBeLSlvms!0Vsu-uvI8Udw~y^Wz?asm!&% zOFAKDrIpGh{tsF0OEMztvC1qHnHV$Hf^EuVrr9~Ju|)1|P$sG7!Ap6MVDBoQhWFkc zGk)hJ3eZJaFM{vK=M`o=G;d;kE*{M?Ibb767!X$cv$&dS5xQjJ?5oRxdngwz+|K(J)BMG5q5i-JX{!r2vmp;8bk##bPs-;bA9)u{0pnT16RtICdraSkbQ$s; z7<6ana;(L2;%ykqD_hDn+&$o-wgo9#HtK$Emp1}5&kKdS3$QEh$mXDaaQYl{*6}ET zudQ24%nVw_E+*c>vv79jl>of-Uz$A4<1qlEOyCP6o7MN}Kijw8&xdm0#H6q63|B!r z*y$LqoJJAep|1@xZaIVs;?U&=I))N-u1M-|r1d-1i{0(5unvX!$@$Lt*u}NWk&aF| zira>NhPIt4Hi^LI?42q5?kB%q|Jw4zhKPSmBQ9hLZ&<7mXQ~Vji>sViu|SXKm(;^Sks`osCi}XI=*)x zx^&Y*G8S6?A@RcNCWlY{S16OMN+}l%9DgK;vU9epSjkv&3pB@Lel1}|J*%9M(*sMj zTNL}m)>B`JAL1XBf@UdGaqEXZGswxr{-b*v?})8CVOBE|fCVU#c%Nq=0#tFBr@6-* zMs0RjU2Zt~I(JTFSI5ipy9Ry~Hqndv?#5!cE|ya@m9^=?eM z1rfd5ve{le<}X#3xA&+E32$^fwT9J?BShnB68KZMX9iA7LwAYa9@AX154Jl`A0#JW z0M46z%!njj{YWG&d6E;}SB}&RoM)N&2f@P<7tk+j9HDkkrL-_lROe4EuMAtpgV

^;$v!9qG9BNY^buagszB`cBd-?=nph6dJ>j50+XpipgcG!HA#j%kCg{#kH97jT!dkc=+d# zxgyQP`Rs|b{h1Fxy%o;+i*{xm^*vK*s;=XvmdS9Gfq@o5XQOo@5h_oHp-&#fE3Ogi?&jC!PBs`@K~%2nOR_iPDak=6 zqd|=Ad8%U@dhK0ALfd(GXjLH%8<@n(=)S=au`mXfUR|J`u9`#uMz(@FZ6HJ?tdfJMYvv5I{DaJNT*VaEgO5!!M!Z+B|L?J7J!jo-HG;R laXINaH-^7et`&uRC_Onl-5{)U|_4OQKn70Nb2{{aKcJSqSH delta 5266 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 YC0q%1Tv{%#19rC5aGENGSiIlA08BkUvH$=8 diff --git a/desktop/src-common/advent/actions.clj b/desktop/src-common/advent/actions.clj index ca2cfb1a..1c61d877 100644 --- a/desktop/src-common/advent/actions.clj +++ b/desktop/src-common/advent/actions.clj @@ -67,6 +67,48 @@ ~@forms)) (reset! ~entities ( entities + (assoc-in [:background :entities target-id :x] final-x) + (assoc-in [:background :entities target-id :y] final-y)) + (update-in entities [:background :entities target-id] + #(start-animation screen + (assoc (jump-to screen entities % [(+ moved-x from-x) (+ moved-y from-y)]) + :facing (cond (< delta-x 0) :left + (> delta-x 0) :right + :else (:facing %))) + :walk + )))))) + + (done? [this screen entities] + (let [{from-x :x from-y :y :keys [left right anim] :as target-entity} (get-in entities [:background :entities target-id])] + (< (dist final-x final-y from-x from-y) 1))) + + (terminate [this screen entities] + (stop screen entities target-id)) + (can-skip? [this screen entities] + false)))) + (defn walk-to [entities target-id [final-x final-y] & [can-skip?]] (let [{start-x :x start-y :y} (get-in @entities [:background :entities target-id]) final-x (int final-x) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 2302adce..d7620cf5 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -322,7 +322,11 @@ (do (actions/give entities :wool) (actions/talk entities :ego "I guess her wool is shedding.")))) :scripts {:wool (actions/get-script entities - (actions/talk entities :ego "She doesn't need it back."))}} + (actions/talk entities :ego "She doesn't need it back.")) + :carrot (actions/get-script entities + (actions/walk-to entities :ego [132 140]) + (actions/talk entities :ego "Come on girl, get the carrot!") + (actions/walk-straight-to entities :sheep [100 150]))}} :right-dir {:box [300 131 320 224] :script (actions/get-script entities @@ -410,6 +414,15 @@ (actions/walk-to entities :ego [310 80]) (actions/transition-background entities :outside-house [0 80])) :cursor :right} + :garden {:box [103 170 178 200] + :script (actions/get-script + entities + (if ((get-in @entities [:state :inventory]) :carrot) + (actions/talk entities :ego "If I steal any more, I might get caught.") + (do + (actions/walk-to entities :ego [128 180]) + (actions/talk entities :ego "Hey! Carrots. No one will notice one missing.") + (actions/give entities :carrot))))} :peddler {:box [110 90 128 146] :script (actions/get-script entities diff --git a/desktop/src-common/advent/utils.clj b/desktop/src-common/advent/utils.clj index 23c113c4..b3c27dfa 100644 --- a/desktop/src-common/advent/utils.clj +++ b/desktop/src-common/advent/utils.clj @@ -11,7 +11,7 @@ (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})] (println (:input-x screen) (:input-y screen) "->" x y))) -(def +all-cursors+ [:main :wool :mushrooms :talk :right :down :left :up]) +(def +all-cursors+ [:main :wool :mushrooms :carrot :right :down :left :up]) (defn cursor [filename which] (let [scale 2 From f2d915a3f0ecd2091751629906a67d803244c1cf Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Fri, 3 Oct 2014 16:19:01 -0700 Subject: [PATCH 14/18] handles moving entities, needs a lot of refactoring. --- desktop/src-common/advent/screens/scene.clj | 103 ++++++++++---------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index d7620cf5..633f77d7 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -2,6 +2,7 @@ (:require [play-clj.core :refer :all] [play-clj.ui :refer :all] [play-clj.utils :refer :all] + [play-clj.entities :as entities] [play-clj.g2d :refer :all] [clojure.zip :as zip] [clojure.pprint] @@ -20,29 +21,18 @@ (def +screen-width+ 320) (def +screen-height+ 240) -(defprotocol IMouseIn - (mouse-in? [this location])) - -(defprotocol ICursorOverridable - (cursor-override [this])) - -(defprotocol IInteractable - (get-script [this cursor location])) (def default-interaction - (reify - IInteractable - (get-script [_ cursor [x y]] - (if (= :main cursor) - (actions/get-script entities - (actions/walk-to entities :ego [x y] true)) - (actions/get-script entities - (actions/talk entities :ego "I don't know what to do with that.")))))) + {:get-script (fn [cursor [x y]] (if (= :main cursor) + (actions/get-script entities + (actions/walk-to entities :ego [x y] true)) + (actions/get-script entities + (actions/talk entities :ego "I don't know what to do with that."))))}) (defn find-override [screen entities [x y]] - (first (filter #(and (mouse-in? % [x y]) - (satisfies? ICursorOverridable %)) + (first (filter #(and ((:mouse-in? %) entities x y) + (:cursor %)) (get-in entities [:background :interactions])))) (defn open-inventory [screen entities] @@ -55,8 +45,12 @@ (if ((:mouse-in? (:inventory entities)) x y) (open-inventory screen entities) - (let [interaction (first (filter #(mouse-in? % [x y]) + (let [interaction (first (filter #((:mouse-in? %) entities x y) (get-in entities [:background :interactions]))) + interacting-entity (first (filter #(and (:mouse-in? %) + (:get-script %) + ((:mouse-in? %) entities x y)) + (vals (get-in entities [:background :entities])))) current-action (get-in entities [:actions :current]) ;; TODO - hacky way of resetting queue @@ -71,8 +65,10 @@ (if current-action entities ((or (when interaction - (get-script interaction (get-in entities [:cursor :current]) [x y])) - (get-script default-interaction (get-in entities [:cursor :current]) [x y])) entities)) + ((:get-script interaction) (get-in entities [:cursor :current]) [x y])) + (when interacting-entity + ((:get-script interacting-entity) (get-in entities [:cursor :current]) [x y])) + ((:get-script default-interaction) (get-in entities [:cursor :current]) [x y])) entities)) entities)))) (defn flip [anim] @@ -141,22 +137,29 @@ (input! :set-cursor-image (utils/cursor "cursor.png" (or override current)) 0 0)) (assoc-in entities [:cursor :last] (or override current))) -(defn make-background [& {:keys [collision interactions] :as params}] +(defn make-background [& {:keys [collision interactions entities] :as params}] (let [interactions-as-list (for [[id spec] interactions] - (reify - IMouseIn - (mouse-in? [_ location] - (apply (apply zone/box (:box spec)) location)) - IInteractable - (get-script [_ cursor location] - (if (= :main cursor) - (:script spec) - (get-in spec [:scripts cursor]))) - ICursorOverridable - (cursor-override [this] (:cursor spec))) - )] + (merge spec {:mouse-in? (fn [_ x y] + ((apply zone/box (:box spec)) x y)) + :get-script (fn [cursor [x y]] + (if (= :main cursor) + (:script spec) + (get-in spec [:scripts cursor])))})) + entities (into {} (for [[id entity] entities] + [id (merge entity + {:mouse-in? (fn [entities x y] + (let [{entity-x :x entity-y :y region :object} (get-in entities [:background :entities id]) + width (.getRegionWidth region) + height (.getRegionHeight region)] + ((zone/box entity-x entity-y (+ entity-x width) (+ entity-y height)) x y)))} + (when (:script entity) + {:get-script (fn [cursor [x y]] + (if (= :main cursor) + (:script entity) + (get-in entity [:scripts cursor])))}))]))] (merge params {:collision (advent.pathfind/map-from-resource collision) - :interactions interactions-as-list}))) + :interactions interactions-as-list + :entities entities}))) (defn do-dialogue [entities & pairs] @@ -314,19 +317,6 @@ (actions/talk entities :ego (str "It's the coolest sword I've ever seen!")) (actions/walk-to entities :ego [290 66]) (actions/talk entities :ego "Maybe I can pull it out."))} - :sheep {:box [38 160 71 181] - :script (actions/get-script - entities - (if ((get-in @entities [:state :inventory]) :wool) - (actions/talk entities :ego "The sheep has given me enough wool.") - (do (actions/give entities :wool) - (actions/talk entities :ego "I guess her wool is shedding.")))) - :scripts {:wool (actions/get-script entities - (actions/talk entities :ego "She doesn't need it back.")) - :carrot (actions/get-script entities - (actions/walk-to entities :ego [132 140]) - (actions/talk entities :ego "Come on girl, get the carrot!") - (actions/walk-straight-to entities :sheep [100 150]))}} :right-dir {:box [300 131 320 224] :script (actions/get-script entities @@ -351,7 +341,20 @@ (assoc (texture "overdirt.png") :x 0 :y 0 :baseline 240) (assoc (texture "background-trees.png") :x 0 :y 0 :baseline 44)] :entities {:sheep (actions/start-animation screen - (assoc (animation->texture screen sheep) :x 38 :y 160 :baseline 160) + (assoc (animation->texture screen sheep) :x 38 :y 160 :baseline 160 + :box [38 160 71 181] + :script (actions/get-script + entities + (if ((get-in @entities [:state :inventory]) :wool) + (actions/talk entities :ego "The sheep has given me enough wool.") + (do (actions/give entities :wool) + (actions/talk entities :ego "I guess her wool is shedding.")))) + :scripts {:wool (actions/get-script entities + (actions/talk entities :ego "She doesn't need it back.")) + :carrot (actions/get-script entities + (actions/walk-to entities :ego [132 140]) + (actions/talk entities :ego "Come on girl, get the carrot!") + (actions/walk-straight-to entities :sheep [100 150]))}) sheep)} :collision "outsidehouse/collision.png" :scale-fn (scaler-fn-with-baseline 110 0.10 1.00)) @@ -504,7 +507,7 @@ (when (get-in entities [:state :active?]) (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})] (if-let [mouse-override (find-override screen entities [x y])] - (assoc-in entities [:cursor :override] (cursor-override mouse-override)) + (assoc-in entities [:cursor :override] (:cursor mouse-override)) (assoc-in entities [:cursor :override] nil))))) :on-touch-down (fn [screen [entities]] From d672c7ab39a18d1b778e67e0e869d7557e3efe8a Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Fri, 3 Oct 2014 18:41:34 -0700 Subject: [PATCH 15/18] minor fixes. --- desktop/src-common/advent/screens/inventory.clj | 5 +++-- desktop/src-common/advent/screens/scene.clj | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/desktop/src-common/advent/screens/inventory.clj b/desktop/src-common/advent/screens/inventory.clj index 9666307f..bc04b0fc 100644 --- a/desktop/src-common/advent/screens/inventory.clj +++ b/desktop/src-common/advent/screens/inventory.clj @@ -77,8 +77,9 @@ :on-touch-down (fn [screen [entities]] (when (:shown? entities) (run! @(resolve 'advent.screens.scene/scene) :on-reactivate) - (when-let [{:keys [highlighted-item]} entities] - (run! @(resolve 'advent.screens.scene/scene) :on-chose-item :item highlighted-item)) + (let [{:keys [highlighted-item]} entities] + (when highlighted-item + (run! @(resolve 'advent.screens.scene/scene) :on-chose-item :item highlighted-item))) (-> entities (assoc :shown? false) (assoc :start-showing? false)))) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 633f77d7..5ad1c2fe 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -461,7 +461,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 From 098891dd4291d7859b6b24f6100bbc361728f44e Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Fri, 3 Oct 2014 20:00:09 -0700 Subject: [PATCH 16/18] first step in large refactoring to extract rooms. --- desktop/src-common/advent/actions.clj | 57 +-- desktop/src-common/advent/screens/rooms.clj | 28 ++ .../advent/screens/rooms/behind_house.clj | 47 +++ .../advent/screens/rooms/cat_tree.clj | 24 ++ .../advent/screens/rooms/inside_house.clj | 34 ++ .../advent/screens/rooms/outside_castle.clj | 57 +++ .../advent/screens/rooms/outside_house.clj | 163 ++++++++ desktop/src-common/advent/screens/scene.clj | 378 ++---------------- desktop/src-common/advent/utils.clj | 20 + 9 files changed, 433 insertions(+), 375 deletions(-) create mode 100644 desktop/src-common/advent/screens/rooms.clj create mode 100644 desktop/src-common/advent/screens/rooms/behind_house.clj create mode 100644 desktop/src-common/advent/screens/rooms/cat_tree.clj create mode 100644 desktop/src-common/advent/screens/rooms/inside_house.clj create mode 100644 desktop/src-common/advent/screens/rooms/outside_castle.clj create mode 100644 desktop/src-common/advent/screens/rooms/outside_house.clj diff --git a/desktop/src-common/advent/actions.clj b/desktop/src-common/advent/actions.clj index 1c61d877..09a4a271 100644 --- a/desktop/src-common/advent/actions.clj +++ b/desktop/src-common/advent/actions.clj @@ -30,7 +30,7 @@ (defn jump-to [screen entities entity [x y]] - (let [scale-fn (-> entities :background :scale-fn) + (let [scale-fn (-> entities :room :scale-fn) entity (assoc entity :x x :y y :baseline (- 240 y))] @@ -50,7 +50,7 @@ entity))) (defn stop [screen entities target-id] - (update-in entities [:background :entities target-id] #(start-animation screen % :stand))) + (update-in entities [:room :entities target-id] #(start-animation screen % :stand))) (defn dist [x1 y1 x2 y2] @@ -68,7 +68,7 @@ (reset! ~entities ( entities - (assoc-in [:background :entities target-id :x] final-x) - (assoc-in [:background :entities target-id :y] final-y)) - (update-in entities [:background :entities target-id] + (assoc-in [:room :entities target-id :x] final-x) + (assoc-in [:room :entities target-id :y] final-y)) + (update-in entities [:room :entities target-id] #(start-animation screen (assoc (jump-to screen entities % [(+ moved-x from-x) (+ moved-y from-y)]) :facing (cond (< delta-x 0) :left @@ -101,7 +101,7 @@ )))))) (done? [this screen entities] - (let [{from-x :x from-y :y :keys [left right anim] :as target-entity} (get-in entities [:background :entities target-id])] + (let [{from-x :x from-y :y :keys [left right anim] :as target-entity} (get-in entities [:room :entities target-id])] (< (dist final-x final-y from-x from-y) 1))) (terminate [this screen entities] @@ -110,11 +110,11 @@ false)))) (defn walk-to [entities target-id [final-x final-y] & [can-skip?]] - (let [{start-x :x start-y :y} (get-in @entities [:background :entities target-id]) + (let [{start-x :x start-y :y} (get-in @entities [:room :entities target-id]) final-x (int final-x) final-y (int final-y) path (vec (take-nth 5 (advent.pathfind/visit-all - (:collision (:background @entities)) + (:collision (:room @entities)) [(int start-x) (int start-y)] [final-x final-y]))) path (if (seq path) @@ -127,7 +127,7 @@ entities) (continue [this screen entities] - (let [{from-x :x from-y :y :keys [left right scale-x] :as target-entity} (get-in entities [:background :entities target-id]) + (let [{from-x :x from-y :y :keys [left right scale-x] :as target-entity} (get-in entities [:room :entities target-id]) [[target-x target-y] remainder] @targets-left] (let [delta-x (- target-x from-x) delta-y (- target-y from-y) @@ -142,9 +142,9 @@ (if (< distance speed) (do (swap! targets-left rest) (-> entities - (assoc-in [:background :entities target-id :x] target-x) - (assoc-in [:background :entities target-id :y] target-y))) - (update-in entities [:background :entities target-id] + (assoc-in [:room :entities target-id :x] target-x) + (assoc-in [:room :entities target-id :y] target-y))) + (update-in entities [:room :entities target-id] #(start-animation screen (assoc (jump-to screen entities % [(+ moved-x from-x) (+ moved-y from-y)]) :facing (cond (< delta-x 0) :left @@ -154,7 +154,7 @@ )))))) (done? [this screen entities] - (let [{from-x :x from-y :y :keys [left right anim] :as target-entity} (get-in entities [:background :entities target-id])] + (let [{from-x :x from-y :y :keys [left right anim] :as target-entity} (get-in entities [:room :entities target-id])] (< (dist final-x final-y from-x from-y) 1))) (terminate [this screen entities] @@ -172,15 +172,15 @@ (run-action entities (begin [this screen entities] (let [_ (swap! initial-time #(or % (:total-time screen))) - target-y (get-in entities [:background :entities target-id :y]) - scale-fn (get-in entities [:background :scale-fn]) + target-y (get-in entities [:room :entities target-id :y]) + scale-fn (get-in entities [:room :scale-fn]) scale (scale-fn target-y) height (* scale 36)] (run! dialogue/talking-screen :on-talk :text text - :x (get-in entities [:background :entities target-id :x]) :y (+ (get-in entities [:background :entities target-id :y]) height) + :x (get-in entities [:room :entities target-id :x]) :y (+ (get-in entities [:room :entities target-id :y]) height) :target-id target-id :scale scale) - (update-in entities [:background :entities target-id ] #(start-animation screen % :talk)))) + (update-in entities [:room :entities target-id ] #(start-animation screen % :talk)))) (continue [this screen entities] entities) @@ -298,12 +298,12 @@ false)) (run-action entities (begin [this screen entities] - (let [ego (get-in entities [:background :entities :ego]) + (let [ego (get-in entities [:room :entities :ego]) entities (-> entities - (assoc-in [:background] (get-in entities [:backgrounds new-background])) - (assoc-in [:background :entities :ego] ego))] + (assoc-in [:room] (get-in entities [:rooms new-background])) + (assoc-in [:room :entities :ego] ego))] (-> entities - (update-in [:background :entities :ego] #(jump-to screen entities % [x y]))))) + (update-in [:room :entities :ego] #(jump-to screen entities % [x y]))))) (continue [this screen entities] (update-in entities [:transition :opacity] - 0.075)) @@ -316,3 +316,14 @@ (can-skip? [this screen entities] false))) + +(defn do-dialogue [entities & pairs] + (loop [pairs (partition 2 pairs)] + (let [[[target line]] pairs + result (actions/talk entities target line)] + (if (seq (rest pairs)) + (recur (rest pairs)) + result)))) + +(defn respond [entities line & more] + (apply do-dialogue entities :ego line more)) diff --git a/desktop/src-common/advent/screens/rooms.clj b/desktop/src-common/advent/screens/rooms.clj new file mode 100644 index 00000000..4ebc4c0f --- /dev/null +++ b/desktop/src-common/advent/screens/rooms.clj @@ -0,0 +1,28 @@ +(ns advent.screens.rooms + (:require [advent.zone :as zone])) + +(defn make [& {:keys [collision interactions entities] :as params}] + (let [interactions-as-list (for [[id spec] interactions] + (merge spec {:mouse-in? (fn [_ x y] + ((apply zone/box (:box spec)) x y)) + :get-script (fn [cursor [x y]] + (if (= :main cursor) + (:script spec) + (get-in spec [:scripts cursor])))})) + entities (into {} (for [[id entity] entities] + [id (merge entity + {:mouse-in? (fn [entities x y] + (let [{entity-x :x entity-y :y region :object} (get-in entities [:room :entities id]) + width (.getRegionWidth region) + height (.getRegionHeight region)] + ((zone/box entity-x entity-y (+ entity-x width) (+ entity-y height)) x y)))} + (when (:script entity) + {:get-script (fn [cursor [x y]] + (if (= :main cursor) + (:script entity) + (get-in entity [:scripts cursor])))}))]))] + (merge params {:collision (advent.pathfind/map-from-resource collision) + :interactions interactions-as-list + :entities entities}))) + + diff --git a/desktop/src-common/advent/screens/rooms/behind_house.clj b/desktop/src-common/advent/screens/rooms/behind_house.clj new file mode 100644 index 00000000..586c61e3 --- /dev/null +++ b/desktop/src-common/advent/screens/rooms/behind_house.clj @@ -0,0 +1,47 @@ +(ns advent.screens.rooms.behind-house + (:require [advent.screens.rooms :as rooms] + [advent.actions :as actions] + [advent.utils :as utils] + [clojure.zip :as zip] + [play-clj.core :refer :all] + [play-clj.ui :refer :all] + [play-clj.utils :refer :all] + [play-clj.g2d :refer :all])) + +(defn make [screen] + (rooms/make :interactions + {:left-dir {:box [0 131 20 224] + :script (actions/get-script + entities + (actions/walk-to entities :ego [122 140]) + (actions/transition-background entities :outside-house [244 150]) + (actions/walk-to entities :ego [195 140])) + :cursor :left} + :crack {:box [68 100 73 114] + :script (actions/get-script + entities + (actions/walk-to entities :ego [70 80]) + (actions/talk entities :ego "I can see Fangald, the wizard inside.") + (actions/talk entities :ego "It looks like he's opening his Magi-safe.") + (actions/talk entities :ego "[todo: sounds play.]") + (actions/talk entities :ego "A lot of good it'll do me to know his password while he's still there."))} + :mushrooms {:box [247 59 269 76] + :script (actions/get-script + entities + (if ((get-in @entities [:state :inventory]) :mushrooms) + (actions/talk entities :ego "I've already got a junk ton of mushrooms.") + (do + (actions/walk-to entities :ego [242 75]) + (actions/give entities :mushrooms) + (actions/talk entities :ego "Perfectly ripe mushrooms!"))))} + :window {:box [103 44 130 140] + :script (actions/get-script + entities + (actions/walk-to entities :ego [128 100]) + (actions/talk entities :ego "I can see Fangald moving around in there but it's hard to see at this angle."))}} + :layers [(assoc (texture "behindhouse/background.png") :x 0 :y 0 :baseline 0) + (assoc (texture "behindhouse/house.png") :x 0 :y 0 :baseline 122) + (assoc (texture "behindhouse/brush.png") :x 0 :y 0 :baseline 240)] + :entities {} + :collision "behindhouse/collision.png" + :scale-fn (utils/scaler-fn-with-baseline 110 0.10 1.00))) diff --git a/desktop/src-common/advent/screens/rooms/cat_tree.clj b/desktop/src-common/advent/screens/rooms/cat_tree.clj new file mode 100644 index 00000000..f07be0ea --- /dev/null +++ b/desktop/src-common/advent/screens/rooms/cat_tree.clj @@ -0,0 +1,24 @@ +(ns advent.screens.rooms.cat-tree + (:require [advent.screens.rooms :as rooms] + [advent.actions :as actions] + [advent.utils :as utils] + [clojure.zip :as zip] + [play-clj.core :refer :all] + [play-clj.ui :refer :all] + [play-clj.utils :refer :all] + [play-clj.g2d :refer :all])) + +(defn make [screen] + (rooms/make :interactions + {:down-dir {:box [150 0 270 20] + :script (actions/get-script entities + (actions/walk-to entities :ego [203 1]) + (actions/transition-background entities :outside-house [137 204]) + (actions/walk-to entities :ego [195 140])) + :cursor :down}} + :layers [(assoc (texture "cat-tree/background.png") :x 0 :y 0 :baseline 0) + (assoc (texture "cat-tree/tree-and-rock.png") :x 0 :y 0 :baseline 161) + (assoc (texture "cat-tree/sillhoute.png") :x 0 :y 0 :baseline 240)] + :entities {} + :collision "cat-tree/collision.png" + :scale-fn (utils/scaler-fn-with-baseline 110 0.10 1.20))) diff --git a/desktop/src-common/advent/screens/rooms/inside_house.clj b/desktop/src-common/advent/screens/rooms/inside_house.clj new file mode 100644 index 00000000..7b198fc5 --- /dev/null +++ b/desktop/src-common/advent/screens/rooms/inside_house.clj @@ -0,0 +1,34 @@ +(ns advent.screens.rooms.inside-house + (:require [advent.screens.rooms :as rooms] + [advent.actions :as actions] + [advent.utils :as utils] + [clojure.zip :as zip] + [play-clj.core :refer :all] + [play-clj.ui :refer :all] + [play-clj.utils :refer :all] + [play-clj.g2d :refer :all])) + +(defn make [screen] + (let [wizard-sheet (texture! (texture "wizard/talk.png") :split 20 46) + wizard-stand (animation 0.2 (for [i (flatten [(repeat 10 0) 1])] + (aget wizard-sheet 0 i))) + wizard-talk (animation 0.2 (for [i [0 2 0 2 1 2 0 3 0 2 0 1 0 2]] + (aget wizard-sheet 0 i)))] + (rooms/make :interactions {:down-dir {:box [151 0 320 20] + :script (actions/get-script entities + (actions/walk-to entities :ego [237 1]) + (actions/transition-background entities :outside-house [262 88])) + :cursor :down} + :wizard {:box [228 80 248 126]}} + :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)] + :entities {:wizard (actions/start-animation screen (assoc (animation->texture screen wizard-stand) :x 228 :y 80 :baseline 160 :scale-x 1.75 :scale-y 1.75 + :left {:talk (utils/flip wizard-talk) + :stand (utils/flip wizard-stand)} + :right {:talk wizard-talk + :stand wizard-stand} + :facing :left) + :stand)} + :collision "inside-house/collision.png" + :scale-fn (utils/scaler-fn-with-baseline 110 0.10 1.75)))) diff --git a/desktop/src-common/advent/screens/rooms/outside_castle.clj b/desktop/src-common/advent/screens/rooms/outside_castle.clj new file mode 100644 index 00000000..9c26ad1c --- /dev/null +++ b/desktop/src-common/advent/screens/rooms/outside_castle.clj @@ -0,0 +1,57 @@ +(ns advent.screens.rooms.outside-castle + (:require [advent.screens.rooms :as rooms] + [advent.actions :as actions] + [advent.utils :as utils] + [clojure.zip :as zip] + [play-clj.core :refer :all] + [play-clj.ui :refer :all] + [play-clj.utils :refer :all] + [play-clj.g2d :refer :all])) + +(defn make [screen] + (let [peddler-sheet (texture! (texture "outside-castle/peddler-talk.png" ) :split 18 36) + peddler-talk (animation 0.18 (for [i (flatten [2 3 2 3 2 3 6 1 0 1 0 1 0 1 0 1 2 3 2 3 2 3 6 4 5 4 5 4 5 4 5])] + (aget peddler-sheet 0 i))) + peddler-stand (animation 0.2 (for [i (flatten [(repeat 5 0) 6])] + (aget peddler-sheet 0 i)))] + (rooms/make :interactions + {:right-dir {:box [300 40 320 140] + :script (actions/get-script + entities + (actions/walk-to entities :ego [310 80]) + (actions/transition-background entities :outside-house [0 80])) + :cursor :right} + :garden {:box [103 170 178 200] + :script (actions/get-script + entities + (if ((get-in @entities [:state :inventory]) :carrot) + (actions/talk entities :ego "If I steal any more, I might get caught.") + (do + (actions/walk-to entities :ego [128 180]) + (actions/talk entities :ego "Hey! Carrots. No one will notice one missing.") + (actions/give entities :carrot))))} + :peddler {:box [110 90 128 146] + :script (actions/get-script + entities + (actions/walk-to entities :ego [191 90]) + (actions/talk entities :ego "Hello there, peddler.") + (actions/talk entities :peddler "Good day sir! Care to see any of my wares?" :stop? false) + (actions/talk entities :peddler "I have only the choicest of wares.") + (actions/talk entities :ego "What 'wares' are you selling?") + (actions/talk entities :peddler "I have the choicest of all types of wares..." :stop? false) + (actions/talk entities :peddler "...I'm well stocked on used earplugs..." :stop? false) + (actions/talk entities :peddler "...glass eyes, motivational tapes... " :stop? false) + (actions/talk entities :peddler "...and useful books like this:" :stop? false) + (actions/talk entities :peddler "'Checkers Mastery in Less Than 10 Seconds'") + (actions/talk entities :ego "I sure am interested on that book on checkers.") + (actions/talk entities :peddler "An excellent selection! It is the choicest of checkers book you'll ever find." :stop? false) + (actions/talk entities :peddler "This book will only set you back 75 sheckels.") + (actions/talk entities :ego "But I haven't got any money!") + (actions/talk entities :peddler "Then you won't have the choicest of checkers books."))}} + :layers [(assoc (texture "outside-castle/background.png") :x 0 :y 0 :baseline 0)] + :entities {:peddler (actions/start-animation screen + (assoc (texture "outside-castle/peddler.png") :x 110 :y 90 :baseline 150 :anim nil + :talk peddler-talk :stand peddler-stand) + :stand)} + :collision "outside-castle/collision.png" + :scale-fn (utils/scaler-fn-with-baseline 110 0.10 1.00)))) diff --git a/desktop/src-common/advent/screens/rooms/outside_house.clj b/desktop/src-common/advent/screens/rooms/outside_house.clj new file mode 100644 index 00000000..9710dc10 --- /dev/null +++ b/desktop/src-common/advent/screens/rooms/outside_house.clj @@ -0,0 +1,163 @@ +(ns advent.screens.rooms.outside-house + (:require [advent.screens.rooms :as rooms] + [advent.actions :as actions] + [advent.utils :as utils] + [clojure.zip :as zip] + [play-clj.core :refer :all] + [play-clj.ui :refer :all] + [play-clj.utils :refer :all] + [play-clj.g2d :refer :all])) + +(defn wizard-dialogue [entities] + (actions/do-dialogue entities :ego "Hello there Mr. Fangald!" :wizard "Oh no, not you again!") + (actions/present-choices entities + {:choices ["What do you mean, \"Not you again?\"" + {:run #(actions/respond entities % :wizard "I mean, you've wrecked my life and I never want to see you again.") + :choices ["You mean the time I set your house on fire with a fire mint?" + {:run #(do + (actions/respond entities % + :wizard "That was you!?" + :wizard "My house was nearly destroyed!" + :wizard "I spent weeks rebuilding my home!" + :wizard "Leave, now, or I'll turn you into a ..." + :wizard "... a ..." + :wizard "... a frog!" + :ego "Okay, okay! I'm leaving.") + (actions/transition-background entities :outside-house [262 88]) + (actions/talk entities :ego "I guess he's really upset with me."))} + "You're still cross about my stealing your magic cowboy hat?" + {:run #(do (actions/respond entities % + :wizard "Of course I'm cross! It's irreplaceable!" + :wizard "That cowboy hat accented my facial physique." + :wizard "And complemented my skin color." + :wizard "And you little cheat stole it from me!" + :wizard "That's why I bought my MagiSafe 5000, to keep out intruders like you." + :wizard "Now leave.") + (actions/transition-background entities :outside-house [262 88]))} + "Even an old hoot like you needs a kick in the pants every now and again." + {:run #(actions/respond entities % :wizard "What gives you the right to try to teach me a lesson?") + :choices ["My good looks?" + {:run #(do (actions/respond entities % + :wizard "You know, handsome looks aren't all they're chocked up to be." + :wizard "Take me for example." + :wizard "When you have a bod like man, you can hardly go to the grocery store without being noticed." + :wizard "But no. Your looks, however good they may be, don't give you the right to teach me a lesson." + :wizard "Now please leave me in peace.") + (actions/transition-background entities :outside-house [262 88]))} + "My good standing within the community?" + {:run #(do (actions/respond entities % + :wizard "Ha! Good standing?" + :wizard "You're the neighborhood cheat and everyone knows it." + :wizard "Now please leave me in peace.") + (actions/transition-background entities :outside-house [262 88]))} + "I'm going to be a knight! That counts for something doesn't it?" + {:run #(do (actions/respond entities % + :wizard "You are, are you?" + :wizard "Pray tell, how do you, a mere wreckless youth, plan on becoming a knight?")) + :choices ["By pulling the Sword of Blergh from its stone!" + {:run #(actions/respond entities % + :wizard "Well, well. It sounds I was wrong about you." + :wizard "Indeed, you are on the path of setting your destructive past behind you." + :wizard "But know this, the stone cannot be cheated easily." + :wizard "You must fulfill the age-old prophecy." + :wizard "'The Sword of Blergh with magic sting,' ..." + :wizard "... 'Shall yield to no earthly king.'" + :wizard "'To draw from hardened, weathered stone,' ..." + :wizard "... 'One must have valor, right to the bone.'" + :wizard "'Worthy in courage, wisdom and might,' ..." + :wizard "... 'only then with sword he'll fight.'" + :wizard "'But a hero should he prove not be,' ..." + :wizard "... 'Only ruin will fall on he.'" + :wizard "'Should he use guile or guise'..." + ) + :choices ["Is this almost over?" + {:run #(do (actions/update-state entities (fn [state] (assoc state :convinced-wizard? true))) + (actions/respond entities % + :wizard "Patience, boy." + :wizard "... 'Such a man will have great surprise.'" + :wizard "If this is truely your quest, boy, then I will help you in your quest. " + :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." + :ego "No cheating." + :ego "Check."))} + "*cough* *cough* *ahem*" + {:run #(do (actions/update-state entities (fn [state] (assoc state :convinced-wizard? true))) + (actions/respond entities % + :wizard "Excuse you. Moving on..." + :wizard "... 'Such a man will have great surprise.'" + :wizard "If this is truely your quest, boy, then I will help you in your quest. " + :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." + :ego "No cheating." + :ego "Check."))}]} + "By besting swamp, foe, and the occasional bizarre conversation tree." + {:run #(do (actions/respond entities % + :wizard "While your goal sounds noble, no amount of bizarre conversation tree searching will earn my respect." + :wizard "Now please leave.") + (actions/transition-background entities :outside-house [262 88]))}]}]}]} + "You're not happy to see me, Mr. Fangald?" + {:run #(actions/respond entities % :wizard "Of course not, you little brat. You've made my life a living hell!") + :choices #(-> % zip/left)} + "Good bye, Mr. Fangald!" + {:run #(do + (actions/respond entities % :wizard "Now scram!") + (actions/transition-background entities :outside-house [262 88]))}]})) +(defn make [screen] + (let [sheep-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) + sheep (animation 0.15 (for [i (flatten [(repeat 10 0) 1 2 3 4 5 6 7 4 5 6 7 8 9 10 (repeat 25 11) (repeat 15 12)])] + (aget sheep-sheet 0 i)))] + (rooms/make :interactions + {:door {:box [258 100 281 160] + :script (actions/get-script + entities + (actions/walk-to entities :ego [262 88]) + (actions/talk entities :ego (str "Anyone home?")) + (actions/transition-background entities :inside-house [237 0]) + (if (get-in @entities [:state :convinced-wizard?]) + (actions/talk entities :wizard (str "Oh, hello there boy.")) + (wizard-dialogue entities)))} + :sword {:box [274 55 305 88] + :script (actions/get-script + entities + (actions/talk entities :ego (str "It's the coolest sword I've ever seen!")) + (actions/walk-to entities :ego [290 66]) + (actions/talk entities :ego "Maybe I can pull it out."))} + :right-dir {:box [300 131 320 224] + :script (actions/get-script + entities + (actions/walk-to entities :ego [244 150]) + (actions/transition-background entities :behind-house [122 140]) + (actions/walk-to entities :ego [172 122])) + :cursor :right} + :up-dir {:box [60 180 224 240] + :script (actions/get-script + entities + (actions/walk-to entities :ego [137 204]) + (actions/transition-background entities :cat-tree [203 1])) + :cursor :up} + :left-dir {:box [0 40 20 140] + :script (actions/get-script + entities + (actions/walk-to entities :ego [0 80]) + (actions/transition-background entities :outside-castle [310 80])) + :cursor :left}} + :layers [(assoc (texture "bg5.png") :x 0 :y 0 :baseline 0) + (assoc (texture "house.png") :x 0 :y 0 :baseline 122) + (assoc (texture "overdirt.png") :x 0 :y 0 :baseline 240) + (assoc (texture "background-trees.png") :x 0 :y 0 :baseline 44)] + :entities {:sheep (actions/start-animation screen + (assoc (animation->texture screen sheep) :x 38 :y 160 :baseline 160 + :box [38 160 71 181] + :script (actions/get-script + entities + (if ((get-in @entities [:state :inventory]) :wool) + (actions/talk entities :ego "The sheep has given me enough wool.") + (do (actions/give entities :wool) + (actions/talk entities :ego "I guess her wool is shedding.")))) + :scripts {:wool (actions/get-script entities + (actions/talk entities :ego "She doesn't need it back.")) + :carrot (actions/get-script entities + (actions/walk-to entities :ego [132 140]) + (actions/talk entities :ego "Come on girl, get the carrot!") + (actions/walk-straight-to entities :sheep [100 150]))}) + sheep)} + :collision "outsidehouse/collision.png" + :scale-fn (utils/scaler-fn-with-baseline 110 0.10 1.00)))) diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index 5ad1c2fe..22da29e4 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -10,6 +10,12 @@ [advent.actions :as actions] [advent.zone :as zone] [advent.utils :as utils] + [advent.screens.rooms :as rooms] + [advent.screens.rooms.outside-house :as rooms.outside-house] + [advent.screens.rooms.inside-house :as rooms.inside-house] + [advent.screens.rooms.behind-house :as rooms.behind-house] + [advent.screens.rooms.outside-castle :as rooms.outside-castle] + [advent.screens.rooms.cat-tree :as rooms.cat-tree] [advent.screens.dialogue :refer [talking-screen]] [advent.screens.inventory :refer [inventory-screen]] [clojure.core.async :refer [put! ! chan go thread take! alts!!]]) @@ -18,22 +24,18 @@ [java.lang Object] [com.badlogic.gdx Gdx])) -(def +screen-width+ 320) -(def +screen-height+ 240) - - (def default-interaction {:get-script (fn [cursor [x y]] (if (= :main cursor) - (actions/get-script entities - (actions/walk-to entities :ego [x y] true)) - (actions/get-script entities - (actions/talk entities :ego "I don't know what to do with that."))))}) + (actions/get-script entities + (actions/walk-to entities :ego [x y] true)) + (actions/get-script entities + (actions/talk entities :ego "I don't know what to do with that."))))}) (defn find-override [screen entities [x y]] (first (filter #(and ((:mouse-in? %) entities x y) (:cursor %)) - (get-in entities [:background :interactions])))) + (get-in entities [:room :interactions])))) (defn open-inventory [screen entities] (run! inventory-screen :show-screen :items (get-in entities [:state :inventory])) @@ -46,11 +48,11 @@ (open-inventory screen entities) (let [interaction (first (filter #((:mouse-in? %) entities x y) - (get-in entities [:background :interactions]))) + (get-in entities [:room :interactions]))) interacting-entity (first (filter #(and (:mouse-in? %) (:get-script %) ((:mouse-in? %) entities x y)) - (vals (get-in entities [:background :entities])))) + (vals (get-in entities [:room :entities])))) current-action (get-in entities [:actions :current]) ;; TODO - hacky way of resetting queue @@ -71,14 +73,6 @@ ((:get-script default-interaction) (get-in entities [:cursor :current]) [x y])) entities)) entities)))) -(defn flip [anim] - (animation (animation! anim :get-frame-duration) - (for [src-frame (animation! anim :get-key-frames) - :let [frame (texture (texture! src-frame :get-texture))]] - (do - (texture! frame :set-region src-frame) - (texture! frame :flip true false) - frame)))) (defn get-ego [screen] (let [player-sheet (texture! (texture "player.png") :split 18 36) @@ -93,11 +87,9 @@ ego {:right {:walk walk-right :stand stand-anim :talk talk-anim} - :left {:walk (flip walk-right) - :stand (flip stand-anim) - :talk (flip talk-anim)} - - + :left {:walk (utils/flip walk-right) + :stand (utils/flip stand-anim) + :talk (utils/flip talk-anim)} :baseline 95 :facing :right :origin-x 9 @@ -123,13 +115,6 @@ (let [[current _] (alts!! [channel] :default nil)] (assoc entities :actions {:channel channel :current current :started? false})))) -(defn scaler-fn-with-baseline [baseline minimum-size & [maximum-size]] - (let [maximum-size (or maximum-size 1.0)] - (fn [y] - (if (< y baseline) maximum-size - (let [percent-complete (- 1.0 (/ (- y baseline) (- +screen-height+ baseline))) - range (+ (* percent-complete (- maximum-size minimum-size)) minimum-size)] - range))))) (defn update-cursor [screen {{:keys [current override last]} :cursor :as entities}] (when-not (= (or override current) @@ -137,321 +122,8 @@ (input! :set-cursor-image (utils/cursor "cursor.png" (or override current)) 0 0)) (assoc-in entities [:cursor :last] (or override current))) -(defn make-background [& {:keys [collision interactions entities] :as params}] - (let [interactions-as-list (for [[id spec] interactions] - (merge spec {:mouse-in? (fn [_ x y] - ((apply zone/box (:box spec)) x y)) - :get-script (fn [cursor [x y]] - (if (= :main cursor) - (:script spec) - (get-in spec [:scripts cursor])))})) - entities (into {} (for [[id entity] entities] - [id (merge entity - {:mouse-in? (fn [entities x y] - (let [{entity-x :x entity-y :y region :object} (get-in entities [:background :entities id]) - width (.getRegionWidth region) - height (.getRegionHeight region)] - ((zone/box entity-x entity-y (+ entity-x width) (+ entity-y height)) x y)))} - (when (:script entity) - {:get-script (fn [cursor [x y]] - (if (= :main cursor) - (:script entity) - (get-in entity [:scripts cursor])))}))]))] - (merge params {:collision (advent.pathfind/map-from-resource collision) - :interactions interactions-as-list - :entities entities}))) -(defn do-dialogue [entities & pairs] - (loop [pairs (partition 2 pairs)] - (let [[[target line]] pairs - result (actions/talk entities target line)] - (if (seq (rest pairs)) - (recur (rest pairs)) - result)))) - -(defn respond [entities line & more] - (apply do-dialogue entities :ego line more)) - -(defn wizard-dialogue [entities] - (do-dialogue entities :ego "Hello there Mr. Fangald!" :wizard "Oh no, not you again!") - (actions/present-choices entities - {:choices ["What do you mean, \"Not you again?\"" - {:run #(respond entities % :wizard "I mean, you've wrecked my life and I never want to see you again.") - :choices ["You mean the time I set your house on fire with a fire mint?" - {:run #(do - (respond entities % - :wizard "That was you!?" - :wizard "My house was nearly destroyed!" - :wizard "I spent weeks rebuilding my home!" - :wizard "Leave, now, or I'll turn you into a ..." - :wizard "... a ..." - :wizard "... a frog!" - :ego "Okay, okay! I'm leaving.") - (actions/transition-background entities :outside-house [262 88]) - (actions/talk entities :ego "I guess he's really upset with me."))} - "You're still cross about my stealing your magic cowboy hat?" - {:run #(do (respond entities % - :wizard "Of course I'm cross! It's irreplaceable!" - :wizard "That cowboy hat accented my facial physique." - :wizard "And complemented my skin color." - :wizard "And you little cheat stole it from me!" - :wizard "That's why I bought my MagiSafe 5000, to keep out intruders like you." - :wizard "Now leave.") - (actions/transition-background entities :outside-house [262 88]))} - "Even an old hoot like you needs a kick in the pants every now and again." - {:run #(respond entities % :wizard "What gives you the right to try to teach me a lesson?") - :choices ["My good looks?" - {:run #(do (respond entities % - :wizard "You know, handsome looks aren't all they're chocked up to be." - :wizard "Take me for example." - :wizard "When you have a bod like man, you can hardly go to the grocery store without being noticed." - :wizard "But no. Your looks, however good they may be, don't give you the right to teach me a lesson." - :wizard "Now please leave me in peace.") - (actions/transition-background entities :outside-house [262 88]))} - "My good standing within the community?" - {:run #(do (respond entities % - :wizard "Ha! Good standing?" - :wizard "You're the neighborhood cheat and everyone knows it." - :wizard "Now please leave me in peace.") - (actions/transition-background entities :outside-house [262 88]))} - "I'm going to be a knight! That counts for something doesn't it?" - {:run #(do (respond entities % - :wizard "You are, are you?" - :wizard "Pray tell, how do you, a mere wreckless youth, plan on becoming a knight?")) - :choices ["By pulling the Sword of Blergh from its stone!" - {:run #(respond entities % - :wizard "Well, well. It sounds I was wrong about you." - :wizard "Indeed, you are on the path of setting your destructive past behind you." - :wizard "But know this, the stone cannot be cheated easily." - :wizard "You must fulfill the age-old prophecy." - :wizard "'The Sword of Blergh with magic sting,' ..." - :wizard "... 'Shall yield to no earthly king.'" - :wizard "'To draw from hardened, weathered stone,' ..." - :wizard "... 'One must have valor, right to the bone.'" - :wizard "'Worthy in courage, wisdom and might,' ..." - :wizard "... 'only then with sword he'll fight.'" - :wizard "'But a hero should he prove not be,' ..." - :wizard "... 'Only ruin will fall on he.'" - :wizard "'Should he use guile or guise'..." - ) - :choices ["Is this almost over?" - {:run #(do (actions/update-state entities (fn [state] (assoc state :convinced-wizard? true))) - (respond entities % - :wizard "Patience, boy." - :wizard "... 'Such a man will have great surprise.'" - :wizard "If this is truely your quest, boy, then I will help you in your quest. " - :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." - :ego "No cheating." - :ego "Check."))} - "*cough* *cough* *ahem*" - {:run #(do (actions/update-state entities (fn [state] (assoc state :convinced-wizard? true))) - (respond entities % - :wizard "Excuse you. Moving on..." - :wizard "... 'Such a man will have great surprise.'" - :wizard "If this is truely your quest, boy, then I will help you in your quest. " - :wizard "But heed the warning from the prophecy: No cheat can pull the Sword of Blergh." - :ego "No cheating." - :ego "Check."))}]} - "By besting swamp, foe, and the occasional bizarre conversation tree." - {:run #(do (respond entities % - :wizard "While your goal sounds noble, no amount of bizarre conversation tree searching will earn my respect." - :wizard "Now please leave.") - (actions/transition-background entities :outside-house [262 88]))}]}]}]} - "You're not happy to see me, Mr. Fangald?" - {:run #(respond entities % :wizard "Of course not, you little brat. You've made my life a living hell!") - :choices #(-> % zip/left)} - "Good bye, Mr. Fangald!" - {:run #(do - (respond entities % :wizard "Now scram!") - (actions/transition-background entities :outside-house [262 88]))}]})) - -(defn backgrounds [screen] - (let [sheep-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) - sheep (animation 0.15 (for [i (flatten [(repeat 10 0) 1 2 3 4 5 6 7 4 5 6 7 8 9 10 (repeat 25 11) (repeat 15 12)])] - (aget sheep-sheet 0 i))) - - peddler-sheet (texture! (texture "outside-castle/peddler-talk.png" ) :split 18 36) - peddler-talk (animation 0.18 (for [i (flatten [2 3 2 3 2 3 6 1 0 1 0 1 0 1 0 1 2 3 2 3 2 3 6 4 5 4 5 4 5 4 5])] - (aget peddler-sheet 0 i))) - peddler-stand (animation 0.2 (for [i (flatten [(repeat 5 0) 6])] - (aget peddler-sheet 0 i))) - wizard-sheet (texture! (texture "wizard/talk.png") :split 20 46) - wizard-stand (animation 0.2 (for [i (flatten [(repeat 10 0) 1])] - (aget wizard-sheet 0 i))) - wizard-talk (animation 0.2 (for [i [0 2 0 2 1 2 0 3 0 2 0 1 0 2]] - (aget wizard-sheet 0 i)))] - {:inside-house - (make-background :interactions {:down-dir {:box [151 0 320 20] - :script (actions/get-script entities - (actions/walk-to entities :ego [237 1]) - (actions/transition-background entities :outside-house [262 88])) - :cursor :down} - :wizard {:box [228 80 248 126]}} - :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)] - :entities {:wizard (actions/start-animation screen (assoc (animation->texture screen wizard-stand) :x 228 :y 80 :baseline 160 :scale-x 1.75 :scale-y 1.75 - :left {:talk (flip wizard-talk) - :stand (flip wizard-stand)} - :right {:talk wizard-talk - :stand wizard-stand} - :facing :left) - :stand)} - :collision "inside-house/collision.png" - :scale-fn (scaler-fn-with-baseline 110 0.10 1.75)) - :outside-house - (make-background :interactions - {:door {:box [258 100 281 160] - :script (actions/get-script - entities - (actions/walk-to entities :ego [262 88]) - (actions/talk entities :ego (str "Anyone home?")) - (actions/transition-background entities :inside-house [237 0]) - (if (get-in @entities [:state :convinced-wizard?]) - (actions/talk entities :wizard (str "Oh, hello there boy.")) - (wizard-dialogue entities)))} - :sword {:box [274 55 305 88] - :script (actions/get-script - entities - (actions/talk entities :ego (str "It's the coolest sword I've ever seen!")) - (actions/walk-to entities :ego [290 66]) - (actions/talk entities :ego "Maybe I can pull it out."))} - :right-dir {:box [300 131 320 224] - :script (actions/get-script - entities - (actions/walk-to entities :ego [244 150]) - (actions/transition-background entities :behind-house [122 140]) - (actions/walk-to entities :ego [172 122])) - :cursor :right} - :up-dir {:box [60 180 224 240] - :script (actions/get-script - entities - (actions/walk-to entities :ego [137 204]) - (actions/transition-background entities :cat-tree [203 1])) - :cursor :up} - :left-dir {:box [0 40 20 140] - :script (actions/get-script - entities - (actions/walk-to entities :ego [0 80]) - (actions/transition-background entities :outside-castle [310 80])) - :cursor :left}} - :layers [(assoc (texture "bg5.png") :x 0 :y 0 :baseline 0) - (assoc (texture "house.png") :x 0 :y 0 :baseline 122) - (assoc (texture "overdirt.png") :x 0 :y 0 :baseline 240) - (assoc (texture "background-trees.png") :x 0 :y 0 :baseline 44)] - :entities {:sheep (actions/start-animation screen - (assoc (animation->texture screen sheep) :x 38 :y 160 :baseline 160 - :box [38 160 71 181] - :script (actions/get-script - entities - (if ((get-in @entities [:state :inventory]) :wool) - (actions/talk entities :ego "The sheep has given me enough wool.") - (do (actions/give entities :wool) - (actions/talk entities :ego "I guess her wool is shedding.")))) - :scripts {:wool (actions/get-script entities - (actions/talk entities :ego "She doesn't need it back.")) - :carrot (actions/get-script entities - (actions/walk-to entities :ego [132 140]) - (actions/talk entities :ego "Come on girl, get the carrot!") - (actions/walk-straight-to entities :sheep [100 150]))}) - sheep)} - :collision "outsidehouse/collision.png" - :scale-fn (scaler-fn-with-baseline 110 0.10 1.00)) - :behind-house - (make-background :interactions - {:left-dir {:box [0 131 20 224] - :script (actions/get-script - entities - (actions/walk-to entities :ego [122 140]) - (actions/transition-background entities :outside-house [244 150]) - (actions/walk-to entities :ego [195 140])) - :cursor :left} - :crack {:box [68 100 73 114] - :script (actions/get-script - entities - (actions/walk-to entities :ego [70 80]) - (actions/talk entities :ego "I can see Fangald, the wizard inside.") - (actions/talk entities :ego "It looks like he's opening his Magi-safe.") - (actions/talk entities :ego "[todo: sounds play.]") - (actions/talk entities :ego "A lot of good it'll do me to know his password while he's still there."))} - :mushrooms {:box [247 59 269 76] - :script (actions/get-script - entities - (if ((get-in @entities [:state :inventory]) :mushrooms) - (actions/talk entities :ego "I've already got a junk ton of mushrooms.") - (do - (actions/walk-to entities :ego [242 75]) - (actions/give entities :mushrooms) - (actions/talk entities :ego "Perfectly ripe mushrooms!"))))} - :window {:box [103 44 130 140] - :script (actions/get-script - entities - (actions/walk-to entities :ego [128 100]) - (actions/talk entities :ego "I can see Fangald moving around in there but it's hard to see at this angle."))}} - :layers [(assoc (texture "behindhouse/background.png") :x 0 :y 0 :baseline 0) - (assoc (texture "behindhouse/house.png") :x 0 :y 0 :baseline 122) - (assoc (texture "behindhouse/brush.png") :x 0 :y 0 :baseline 240)] - :entities {} - :collision "behindhouse/collision.png" - :scale-fn (scaler-fn-with-baseline 110 0.10 1.00)) - :cat-tree - (make-background :interactions - {:down-dir {:box [150 0 270 20] - :script (actions/get-script entities - (actions/walk-to entities :ego [203 1]) - (actions/transition-background entities :outside-house [137 204]) - (actions/walk-to entities :ego [195 140])) - :cursor :down}} - :layers [(assoc (texture "cat-tree/background.png") :x 0 :y 0 :baseline 0) - (assoc (texture "cat-tree/tree-and-rock.png") :x 0 :y 0 :baseline 161) - (assoc (texture "cat-tree/sillhoute.png") :x 0 :y 0 :baseline 240)] - :entities {} - :collision "cat-tree/collision.png" - :scale-fn (scaler-fn-with-baseline 110 0.10 1.20)) - :outside-castle - (make-background :interactions - {:right-dir {:box [300 40 320 140] - :script (actions/get-script - entities - (actions/walk-to entities :ego [310 80]) - (actions/transition-background entities :outside-house [0 80])) - :cursor :right} - :garden {:box [103 170 178 200] - :script (actions/get-script - entities - (if ((get-in @entities [:state :inventory]) :carrot) - (actions/talk entities :ego "If I steal any more, I might get caught.") - (do - (actions/walk-to entities :ego [128 180]) - (actions/talk entities :ego "Hey! Carrots. No one will notice one missing.") - (actions/give entities :carrot))))} - :peddler {:box [110 90 128 146] - :script (actions/get-script - entities - (actions/walk-to entities :ego [191 90]) - (actions/talk entities :ego "Hello there, peddler.") - (actions/talk entities :peddler "Good day sir! Care to see any of my wares?" :stop? false) - (actions/talk entities :peddler "I have only the choicest of wares.") - (actions/talk entities :ego "What 'wares' are you selling?") - (actions/talk entities :peddler "I have the choicest of all types of wares..." :stop? false) - (actions/talk entities :peddler "...I'm well stocked on used earplugs..." :stop? false) - (actions/talk entities :peddler "...glass eyes, motivational tapes... " :stop? false) - (actions/talk entities :peddler "...and useful books like this:" :stop? false) - (actions/talk entities :peddler "'Checkers Mastery in Less Than 10 Seconds'") - (actions/talk entities :ego "I sure am interested on that book on checkers.") - (actions/talk entities :peddler "An excellent selection! It is the choicest of checkers book you'll ever find." :stop? false) - (actions/talk entities :peddler "This book will only set you back 75 sheckels.") - (actions/talk entities :ego "But I haven't got any money!") - (actions/talk entities :peddler "Then you won't have the choicest of checkers books."))}} - :layers [(assoc (texture "outside-castle/background.png") :x 0 :y 0 :baseline 0)] - :entities {:peddler (actions/start-animation screen - (assoc (texture "outside-castle/peddler.png") :x 110 :y 90 :baseline 150 :anim nil - :talk peddler-talk :stand peddler-stand) - :stand)} - :collision "outside-castle/collision.png" - :scale-fn (scaler-fn-with-baseline 110 0.10 1.00))})) - (defn animate [entity screen] (merge entity (animation->texture (update-in screen [:total-time] #(- % (:anim-start entity))) (:anim entity)))) @@ -460,10 +132,14 @@ (fn [screen entities] (update! screen :renderer (stage) :camera (orthographic)) (let [_ (input! :set-cursor-image (utils/cursor "cursor.png" :main) 0 0) - music (sound "town-music.mp3") + music (sound "town-music.mp3") _ (sound! music :loop 0.20) - backgrounds (backgrounds screen)] - {:backgrounds backgrounds + rooms {:inside-house (rooms.inside-house/make screen) + :outside-house (rooms.outside-house/make screen) + :behind-house (rooms.behind-house/make screen) + :cat-tree (rooms.cat-tree/make screen) + :outside-castle (rooms.outside-castle/make screen)}] + {:rooms rooms :state {:object nil :active? true :inventory (sorted-set)} @@ -475,7 +151,7 @@ :current :main :last :main :override nil} - :background (assoc-in (:outside-house backgrounds) + :room (assoc-in (:outside-house rooms) [:entities :ego] (get-ego screen)) :inventory (assoc (texture "inventory.png") :x 278 :y 0 :baseline 9000 :mouse-in? (zone/box 278 0 320 42)) @@ -484,17 +160,15 @@ :on-render (fn [screen [entities]] (clear!) - (.glEnable (.getGL20 Gdx/graphics) GL20/GL_BLEND) - #_(.glEnable (.getGL30 Gdx/graphics) GL30/GL_BLEND) (let [entities (update-cursor screen entities) entities (update-from-script screen entities) - entities (update-in entities [:background :entities] (fn [entities] + entities (update-in entities [:room :entities] (fn [entities] (into entities (for [[id entity] entities] (if (:anim entity) [id (animate entity screen)] [id entity]))))) - all-entities (concat (vals entities) (get-in entities [:background :layers]) (vals (get-in entities [:background :entities])))] + all-entities (concat (vals entities) (get-in entities [:room :layers]) (vals (get-in entities [:room :entities])))] (label! (:fps entities) :set-text (str (game :fps))) (render! screen (sort-by :baseline all-entities)) entities)) diff --git a/desktop/src-common/advent/utils.clj b/desktop/src-common/advent/utils.clj index b3c27dfa..937a4135 100644 --- a/desktop/src-common/advent/utils.clj +++ b/desktop/src-common/advent/utils.clj @@ -32,3 +32,23 @@ tx (.getTexture tr)] (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear) font)) + +(def +screen-width+ 320) +(def +screen-height+ 240) + +(defn scaler-fn-with-baseline [baseline minimum-size & [maximum-size]] + (let [maximum-size (or maximum-size 1.0)] + (fn [y] + (if (< y baseline) maximum-size + (let [percent-complete (- 1.0 (/ (- y baseline) (- +screen-height+ baseline))) + range (+ (* percent-complete (- maximum-size minimum-size)) minimum-size)] + range))))) + +(defn flip [anim] + (animation (animation! anim :get-frame-duration) + (for [src-frame (animation! anim :get-key-frames) + :let [frame (texture (texture! src-frame :get-texture))]] + (do + (texture! frame :set-region src-frame) + (texture! frame :flip true false) + frame)))) From 1b487edc2bc2462b410ae26223fbcf5b95605d04 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Fri, 3 Oct 2014 21:11:14 -0700 Subject: [PATCH 17/18] cleaning up dialogue a bit. --- desktop/src-common/advent/actions.clj | 3 +- .../advent/screens/rooms/outside_castle.clj | 29 ++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/desktop/src-common/advent/actions.clj b/desktop/src-common/advent/actions.clj index 09a4a271..781499fe 100644 --- a/desktop/src-common/advent/actions.clj +++ b/desktop/src-common/advent/actions.clj @@ -320,7 +320,8 @@ (defn do-dialogue [entities & pairs] (loop [pairs (partition 2 pairs)] (let [[[target line]] pairs - result (actions/talk entities target line)] + next-speaker-is-different (not= target (ffirst (next pairs))) + result (talk entities target line :stop? next-speaker-is-different)] (if (seq (rest pairs)) (recur (rest pairs)) result)))) diff --git a/desktop/src-common/advent/screens/rooms/outside_castle.clj b/desktop/src-common/advent/screens/rooms/outside_castle.clj index 9c26ad1c..501fc791 100644 --- a/desktop/src-common/advent/screens/rooms/outside_castle.clj +++ b/desktop/src-common/advent/screens/rooms/outside_castle.clj @@ -34,20 +34,21 @@ :script (actions/get-script entities (actions/walk-to entities :ego [191 90]) - (actions/talk entities :ego "Hello there, peddler.") - (actions/talk entities :peddler "Good day sir! Care to see any of my wares?" :stop? false) - (actions/talk entities :peddler "I have only the choicest of wares.") - (actions/talk entities :ego "What 'wares' are you selling?") - (actions/talk entities :peddler "I have the choicest of all types of wares..." :stop? false) - (actions/talk entities :peddler "...I'm well stocked on used earplugs..." :stop? false) - (actions/talk entities :peddler "...glass eyes, motivational tapes... " :stop? false) - (actions/talk entities :peddler "...and useful books like this:" :stop? false) - (actions/talk entities :peddler "'Checkers Mastery in Less Than 10 Seconds'") - (actions/talk entities :ego "I sure am interested on that book on checkers.") - (actions/talk entities :peddler "An excellent selection! It is the choicest of checkers book you'll ever find." :stop? false) - (actions/talk entities :peddler "This book will only set you back 75 sheckels.") - (actions/talk entities :ego "But I haven't got any money!") - (actions/talk entities :peddler "Then you won't have the choicest of checkers books."))}} + (actions/do-dialogue entities + :ego "Hello there, peddler." + :peddler "Good day sir! Care to see any of my wares?" + :peddler "I have only the choicest of wares." + :ego "What 'wares' are you selling?" + :peddler "I have the choicest of all types of wares..." + :peddler "...I'm well stocked on used earplugs..." + :peddler "...glass eyes, motivational tapes... " + :peddler "...and useful books like this:" + :peddler "'Checkers Mastery in Less Than 10 Seconds'" + :ego "I sure am interested on that book on checkers." + :peddler "An excellent selection! It is the choicest of checkers book you'll ever find." + :peddler "This book will only set you back 75 sheckels." + :ego "But I haven't got any money!" + :peddler "Then you won't have the choicest of checkers books."))}} :layers [(assoc (texture "outside-castle/background.png") :x 0 :y 0 :baseline 0)] :entities {:peddler (actions/start-animation screen (assoc (texture "outside-castle/peddler.png") :x 110 :y 90 :baseline 150 :anim nil From 64cb52060e5a4121a7c70879ffd1c6e4af451f61 Mon Sep 17 00:00:00 2001 From: Remington Covert Date: Sat, 4 Oct 2014 11:34:12 -0700 Subject: [PATCH 18/18] added sheep animations. --- desktop/resources/outsidehouse/sheep-walk.png | Bin 0 -> 2229 bytes .../outsidehouse/sheep-walk.pxa/0.pxi | Bin 0 -> 264124 bytes .../outsidehouse/sheep-walk.pxa/1.pxi | Bin 0 -> 264124 bytes .../outsidehouse/sheep-walk.pxa/2.pxi | Bin 0 -> 264124 bytes .../outsidehouse/sheep-walk.pxa/3.pxi | Bin 0 -> 264124 bytes .../outsidehouse/sheep-walk.pxa/4.pxi | Bin 0 -> 264124 bytes .../outsidehouse/sheep-walk.pxa/5.pxi | Bin 0 -> 264124 bytes .../outsidehouse/sheep-walk.pxa/CelData.plist | 30 ++++++++++++++++++ .../advent/screens/rooms/outside_house.clj | 19 +++++++---- 9 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 desktop/resources/outsidehouse/sheep-walk.png create mode 100644 desktop/resources/outsidehouse/sheep-walk.pxa/0.pxi create mode 100644 desktop/resources/outsidehouse/sheep-walk.pxa/1.pxi create mode 100644 desktop/resources/outsidehouse/sheep-walk.pxa/2.pxi create mode 100644 desktop/resources/outsidehouse/sheep-walk.pxa/3.pxi create mode 100644 desktop/resources/outsidehouse/sheep-walk.pxa/4.pxi create mode 100644 desktop/resources/outsidehouse/sheep-walk.pxa/5.pxi create mode 100644 desktop/resources/outsidehouse/sheep-walk.pxa/CelData.plist diff --git a/desktop/resources/outsidehouse/sheep-walk.png b/desktop/resources/outsidehouse/sheep-walk.png new file mode 100644 index 0000000000000000000000000000000000000000..16f136b502915d84bfeaddfd7bace3e3503fcc36 GIT binary patch literal 2229 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 literal 0 HcmV?d00001 diff --git a/desktop/resources/outsidehouse/sheep-walk.pxa/1.pxi b/desktop/resources/outsidehouse/sheep-walk.pxa/1.pxi new file mode 100644 index 0000000000000000000000000000000000000000..66a3bad51e5623be91e18d9a18eebeb34551522c GIT binary patch literal 264124 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 literal 0 HcmV?d00001 diff --git a/desktop/resources/outsidehouse/sheep-walk.pxa/2.pxi b/desktop/resources/outsidehouse/sheep-walk.pxa/2.pxi new file mode 100644 index 0000000000000000000000000000000000000000..7ee184c191a5e1988da3a21b6c12f194410b933f GIT binary patch literal 264124 zcmeI&e{7s}9l-H+y}^LOjHTa{v1J zY^k#+AG_Dqmy3PVs;cjN^n2+`PM$JjcK!Ps7B*h~;j6B`X8A{MSl#@w8(Z76J-s)V zcii^r+dqHz17CaS>)%*c-@Btw_{}M&o>qJM8B^0|PCILQTOm6b_sDGSUQz7blJCB$ zuaq0e=XSQ{cjemZI}6$V{+lzhK&U|@rU4DDEJGZtsyFJ%FknhiLF65Hw$&4hGoOR0n zc{6J-e(!?zxXiZPVE?{LE`3ijIXNjgdEfiyUzSWs(#e_0v~}ftA=kfdXTGc4)7F#A zclVUz=8Il$udGp#CB|H}8k=yPlnAaLRd9Bu7e|0mvOZAJt}3yfa-V}JHr z|D&aB6POqRhu7?DFC92AwnKl0KYY&r`MNU0kw5=i{}bc$HVOix1>Wk~9`}8tzdz!; zV)T7%6Cf}#1uAQ~GO}^k^qc*eKeF}@oj);WYE%RW98KVDt^YCK6Gyv;{R9Y1Oo4|V z=pX)X_J{u-pt7bbKi9{s?Kks!V$RU02oN}$KxO?O{tg&f^T$~KZ#Z}4J@I_Bd)QBa zz{C_7cm0oA(<8@6KacnC0+r(vbB0DmfWUYHZ*@(NUH>E38SftU5g;(}1jeq}(QEp6 zqaA&2WqagWmFMHV*Kq;_-hF}b*6PT*KGx_)&Z#_)K5yhZVDvuQ1PDw_fw#N<$D7r7 z*BtLW`v?$tcLm1#e{;wFOdmVK%JE~Z@$s%X_8MLjATTinj<)H>kh`W-$`0;Zb$wHNbL;SSdQN&qoU^8-BYoE4vyNP9 z-y}BJq~B>)Kl~!+VF?nnpHX%&f27aMQ+(n>s!b7t9vQ zxl(VooLipl+}2$x?&$66NY6gJx22RD$mez*Ik;(i-08^6j`WPmjyIf^RK>5ln$YW_$GOHs!tu@$ta$R*tMi}oM*cnG! zGQ-CPj~w~dErYvufAZF*aSsMfOJ?PcV!7D+I-2P%nbpPKF}pXmWR6_6Bb{z;Z40y& z#oltMSSaL5H#N83nCtH=_IBk;`#aCC%_X0TxnGc6*pZ%kT_Ib3{c!L2OhPy>kGqEJu=i7;g)>&&=(I9jNSjjm%e;Y?Y;Ni|CLSMrF>UwPjN?~ zYh@|BbA9FI@JF$+vbC-^UvACs%1ucwO6Df@mCxp@h3#w7>4pW34F?~K>KYa-i4Ul4 z_rm#g3vZ2~Jp4#oOQtE_J+!Ck&{jwK(%p-eH7;mqT(qR|iiRbPOBXF(v}}G|EQ=}8nbGWMZgg4H7%h#mQFm01c1L$a_e2jyd!ompC!%jhPe$L3o{FB1 zeh@ty{UrKX^o!`Z=(o|!(I2C~Mt_U`5&bjzcl1j1pQ@_rR1{;YJ~gV1&WNT()1#Tu zIZ=$cx-Pmnig8!RxT_aOmq*K@tD@!6%ILaiRdju{I$9HDqK`*iRjKN&Q8C&T-5%W& z-5>3V_C`-f-;aJAJrg|}{XF_z^m6o<=wH#RRjEl;QB8DOG&7nXt%@>HUsQ_9(Li)d z6!)AI_ndTh6!)C;K=ferQ1nPN6g?UJF#1sxW0(|UnDo==SJAJd7o$H!e~Mm<4pgOT zrbp*R3!|oJQ?xC*ExIeZH;Vh!#QkdGel_2To{C~#HF4dV-$#G1O2vdysgt9)R_elN zadc&LL(~>^Mq!xR67@u3nYuZ;Bf2w+d8O`)Vm_%o(Y`3goZ26~6op^v&rys!_1~)0 X3pL`~7un>+CP&2g(f%FH}#eNlkvo(Ed#Q&Rl6AU+l}&7dyA+y2=9^>a(S; z-h6CcS6?pnPphiF^U-goFF9q(jM???X;{>F`3J7L`kECVykSlAhi`0c&-V7+T;6fp zCvN}D-4A^Ep|5;(eSP1KLgAOEo_2ce8D~ySpEd35>1~DVVB90q*|W0Pw6+(f)}AwKV{_}m!-Ly*Zc>v> zeet~7^XFV}Vcpz|=Cv35vt9Y};QIXbY)@`oUv_)0eP@0k-&x2d(~}uVDmnYq1M_Fr zUi_|w?QxlHxxs<`mt6YJWODM3yL+^WkQk$HSoS7*UyRzlbTi2Z}XWRBPEU0U^ zb?vmORFxM20t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+z$k%(um0@d$fpNidFIIbk!?N_ATV(S zD(k<}{P}Z-o47MIGXexg3yiG&(d)nR92k9!_XG$`Jb^b_`_})&`&ygP_!bzwRu8`R z(!t|8{CoJ}WYF!_9>=^q_9yv25Ffjxk zeqdnu@9d8IbAZY-V2m~XpSDd55wjq0atR!_rbmAMkMRsR^1K-1*>G~HnJs~dA#mLK zudMCEYrnGIk8P~uE5}R>4YMF{atVyJo-5nlXiZnPAA8Ol9eZ*~nk|9xCop;~ztweo z>@(o4o;UtVPV`=m zCqUqTBQUa#Pvq(&&yA6D{9C^f2_FfJFM-PXA73LjS^@;#E&)Hg-!4hlA@Kht@chbE z*Iu`=zN?TO80gDx&t(q1%?)g7Ze5k{D(8!R+0x+9wN07k*0r5mb6w>)WA%qNH@B|Y zQOKCQ-0{)4V75@smHM*f+=^`1ww_XPM_+eG zdiIg6Ev4Mfd~Vm#otwAEosNFmk)Bc6aNJ=@Rs2_%oRiFXp|*2QS9fkp&xX#p!^&cz zSX$pz`87E|IX5{knSCI?wRT%!d(5`IH($;L)9^v9{n@VEibYlFnq*c?rPv<_4DT2! zHdRh36}GQwSa|u!Ygtt?t0O(FHQ0M|-E~Jt80YTX6?9?AE3+ zcLq&MX4Q^jx!CtQn&~Z>HO0PTHg9Ul9KCEuI^Epb7HBJredSWIP{@^TYHqzTH_%_~ z>&}%9bj_*FB_EHuUyxkbk)C>8AzOa^aPRnJM|#ZLJbve=K3y5^m^FsXNRYH zbf_`HE%~0I&mAH-cKZvT|H3`B_uhB^7dQ8m^4+by#T|w2Ri*5%4V6!azZ9D)@7DL_ z%dPp{xhcs-$-Jb#^0oO=Vf)&2x?y2s!=cyWx`u^I;|tWbXVHSXMYqOK9)6^)CDRmV z5AAI_{H`N?>7K>Q8y7Y-E?(MrMZ?m@Ws8?AUcR8NamnI^iyD?*v1n1_(k086H!dH( zz}Ftlv}9Ih`*vmrhW0fbc^{z7t=H!UbKTdJx_a|FbEW4VdwgA~SS%;iu`H%UXGOE4 zdC_H2W3(*FMmbmISD8^kKN?i;t4 za{c+-&er^{Tw8r-A=}rtrn{8yYCklRWI{4MnVVdc%ud%lH@)`k8S9%{=N}r}-gAZ+jsFL?@1;mCnYEEd*8fElSxTBIWw8Ewwy2I`qu8uca?kEdUE;h zo^o7#;f%eDl2ek&l~XMFz!if_FHcTQP8dpud7%eb7_eanF%5z}!K9&g(IPnCIHuuf{6YsrtM+8O-jGp^rKl{!9 z(NdNPj1Pg4Is5912M&zw(4XN)_W3`5uH519pa0GO@$r5e1%c55Z+31U@wm~?k9by$ zzK&%A1jeU8WiD4ncEmY-yr22QbN|r(tLz`HLndhQO-=gRlv9og_PqtD|RaJ+i=GLL*^z8Js*k^T1NBXRhy$+vh-|B0c*00Lud+V;x z4&+L6u3C2xA`V%zw!I}Yw05wqX?XF4%(~k3H*VOlvEvhQ!fc_OEA?i}xn_qt7S zh2_OUv9z|c@-;axIVU+cnYll|rFLs!Tik7XPrjTBrlFl$w`V(Z%NA6nYmympE5+@x z!_bDoVpHXiQeoSwhWVEbzm`-bGdj{!T7$hO*Hw3TgmG;D&e+nD8QL~*c+0nL9@w?} zleaV-abwW5WLE4bmW#cwp_$r}Syk*EvwA~I=J07d(&^^bwm@56>@Amyg+i`$V{_{b zxxVei-mY9}f9I^)T=J>7_w$nrI?|J`Eo95D9q#R)=|~^(GLPNy+0Rvmd&G@zG=^}v z^9w__dU&WY!p-^a!7m;p7`y)YFMav$+I#N3?<*U-OZl$Wp5l%|*NReh=eo*|LvO`~ z%F^22e7QBhD>o^*FqxCoSKgbi7PhTUryJ%sHXM8{tZSIRINqSP-3#W`Ex09y^3cO= zEt#e`dT>wEp{0)WCA$|cZJgiGxNvdfYgaOu3d#zhO~FKAeN`GN(Fix(|j z+PHM+1mAol(~?=9?d{L@4eo6kSq{+V*6VTuxvr~Aojv*fTOp8g; znbFK>PIPJ17%hpiQFm01c1O2IcSjFId!k39$D?mYPek91o{XM~eh@tq{UrKX^o!`( z=(o{J(I2C~Mt_U`5&bjzcl2`fpQ@_rR1{;YJ~gV1&WNT&Q={q8IZ=$cx-PmXig8!R zxT_aMmqkmXE2Cx6is;&CWprJ%Dq0<7qK`*iRjKMNQ8C&T-4@*)-52eN_C`-d-;aJA zJsmw0{XF_z^iuSf=wHz*RjCP8QB8DOG(DOZt&B3!_NWw#gejok4Dit@BN}U|Vxl$KIi=r!{>!Y@)GYZ4h z=BOtM%hXNL?a>`k+*j(}DDEe@Aq~4KDTDuva^uyD>pX2P+e1-n)Hsr1DS^YT&XW#?9DV3w`|LGmism| zWJ{er`PjX-pz z@~+!HarLc*xq-d|mt6YJWK!~u~IY}pHB~#ax^MzdBy50G%a!-3t zF5lf#j*BmvxqoqTYBHsAily(pa&Xxd$!W>ygYSEPQkR^OoS7*UJG14`TicZ_XWRES z&aZF0bX0n>S~ulXs?OMu5Obf#J13a{X8C10#>IO@P43CotaHxBgGQ_u7mIj1(BT_D6sA zTmK`aY!i6<1&&*w4VRjl6%v zePZObY!e_b@dPSsxiYG8*Yt^g-Vd++Bgap?nHmuR0^(>96PIeMF83kUq{zrVKSN?u5y77)b z8Ewpoz{xBydM%G$>*LM+=+6x!?iJ%5Yd--36H{R1`ajXNKRlDs_kiL3z7rtu{~<8E z{wr&_GUDNTz=@20w{GZ+7 zV=MQOi8(`~B0yj~fw9*Ac*nlce(V2@bUa63VhRj@e!tbx{jbjRR>$G>1PB~2@cfFE z*Iu`=p|g+8+#$Yl<1=K40Zw5`l{mh;8lY-wQd+U874+nO!ga-HRP#i|c&ZfRS+ ztDN0Z$X!z^Wd{zdy1sdROWV+PdQN(J9J8jiBYpPKqmG^Gz?y5DH?Gd+d+Tq=4&+L6 zuikKYK=G2b>(;kshV~A&HxF;VnAuRb@up3iHg|k9PM9r}bEV#FIk!C9xxKqo+|}FF zk)CyQZ)+*npU>?+_T=UraiwFw?MP3r?0DT_Nmcx+PtHkZzfiYjc4t>^YxjmNafKDd zLb0^2v+^}LKRGu!FPU{PzpZY2VMok%eNVoe3#Ori+ID6;bITW2rE8O!F_q%ZIAG|B z!D4geC8ffS)r|`-AAT&YN@jMXr?v%qPp+%}*a+jb{k!9t*38gz1IM2E`Yi){_I~Wv z<}sfPn%2z9UBz;-_c)qqt(n!u-ch?ZwPuc;wj-TxX=@L(6~*3isaPoFN;kE%-I(j! zS?uk~l@4~!uFEAKkGWrvT-cGGa$O-?K7P1&e6k}w=4Bqg^HZO$40p^Y|I--4;jYgP zP4(DNV}x7t-GiSyOfY)?3!neOJ$3iqcmEeRcbD>AZ9TF}nyzSE(zJBZ;zi5m*EcO*v|wT5k}DQ2Y+AB-*|Mf( zLnrv!qnXysifnIxwr_BM^U>`9ZE3qcH<0VPrqtP!@6VNwQ0~%f>FB%Bv(XQuA4flpo{N4J zy&U~6`cw4h=&#Y=qJKoMME|U+s!l~Qw(8TOy6DVkYBVjH5uF>wn5*lfi=!BKb&R`u zaddgKEV?RM9<7Y7i&jO~N2{YXQ6~CG)K!(L-WC<3J<;vaJ<%Te~kVfy;_y3sfuc&)1w*D{Ag8_iFQV%s2uf2w?uKxnz&}o-BDb#=7H$J z=%MJ5XfS#*`d;+?D8^6|W2pI2^z-N!(TmYWqlHm(v^m-y-4@*y z-5bUAYU6sfalP7aMo&dCui7|o?Qf#LRHb4 + + + + + duration + 0.10000000149011612 + + + duration + 0.10000000149011612 + + + duration + 0.10000000149011612 + + + duration + 0.10000000149011612 + + + duration + 0.10000000149011612 + + + duration + 0.10000000149011612 + + + diff --git a/desktop/src-common/advent/screens/rooms/outside_house.clj b/desktop/src-common/advent/screens/rooms/outside_house.clj index 9710dc10..fc3dc26d 100644 --- a/desktop/src-common/advent/screens/rooms/outside_house.clj +++ b/desktop/src-common/advent/screens/rooms/outside_house.clj @@ -101,9 +101,12 @@ (actions/respond entities % :wizard "Now scram!") (actions/transition-background entities :outside-house [262 88]))}]})) (defn make [screen] - (let [sheep-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) - sheep (animation 0.15 (for [i (flatten [(repeat 10 0) 1 2 3 4 5 6 7 4 5 6 7 8 9 10 (repeat 25 11) (repeat 15 12)])] - (aget sheep-sheet 0 i)))] + (let [sheep-stand-sheet (texture! (texture "outsidehouse/sheep-anim.png") :split 33 21) + sheep-walk-sheet (texture! (texture "outsidehouse/sheep-walk.png") :split 33 21) + sheep-stand (animation 0.15 (for [i (flatten [(repeat 10 0) 1 2 3 4 5 6 7 4 5 6 7 8 9 10 (repeat 25 11) (repeat 15 12)])] + (aget sheep-stand-sheet 0 i))) + sheep-walk (animation 0.15 (for [i (range 6)] + (aget sheep-walk-sheet 0 i)))] (rooms/make :interactions {:door {:box [258 100 281 160] :script (actions/get-script @@ -144,7 +147,7 @@ (assoc (texture "overdirt.png") :x 0 :y 0 :baseline 240) (assoc (texture "background-trees.png") :x 0 :y 0 :baseline 44)] :entities {:sheep (actions/start-animation screen - (assoc (animation->texture screen sheep) :x 38 :y 160 :baseline 160 + (assoc (animation->texture screen sheep-stand) :x 38 :y 160 :baseline 160 :box [38 160 71 181] :script (actions/get-script entities @@ -157,7 +160,11 @@ :carrot (actions/get-script entities (actions/walk-to entities :ego [132 140]) (actions/talk entities :ego "Come on girl, get the carrot!") - (actions/walk-straight-to entities :sheep [100 150]))}) - sheep)} + (actions/walk-straight-to entities :sheep [95 150]))} + :left {:walk (utils/flip sheep-walk) + :stand (utils/flip sheep-stand)} + :right {:walk sheep-walk + :stand sheep-stand}) + sheep-stand)} :collision "outsidehouse/collision.png" :scale-fn (utils/scaler-fn-with-baseline 110 0.10 1.00))))