437 lines
34 KiB
Clojure
437 lines
34 KiB
Clojure
(ns advent.screens.rooms.inside-jail
|
|
(:require [clojure.core.async :refer [chan]]
|
|
[advent.screens.rooms :as rooms]
|
|
[advent.screens.rooms.common :as common]
|
|
[advent.actions :as actions]
|
|
[advent.screens.items :as items]
|
|
[advent.utils :as utils]
|
|
[advent.pathfind]
|
|
[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 remove-lock [entities]
|
|
(-> entities
|
|
(utils/remove-interaction :lock)
|
|
(assoc-in [:room :collision] (get-in entities [:room :collision-free]))))
|
|
|
|
(defn open-lock [entities]
|
|
(actions/walk-to entities :ego [174 80] :face :right)
|
|
(actions/play-animation entities :ego :reach)
|
|
(actions/talk entities :ego "Yes, that's it!")
|
|
(actions/walk-straight-to entities :moveable-bars [65 77])
|
|
(actions/update-entities entities #(remove-lock %))
|
|
(actions/update-state entities #(assoc % :opened-bars? true)))
|
|
|
|
(defn chest-full? [entities]
|
|
(seq (get-in @entities [:state :chest-contents])))
|
|
|
|
(defn touch-chest [entities]
|
|
(cond
|
|
(not (chest-full? entities))
|
|
(do (actions/walk-to entities :ego [192 66] :face :right)
|
|
(actions/play-animation entities :ego :reach-start :stop? false)
|
|
(actions/play-animation entities :chest-top :open)
|
|
(actions/play-animation entities :ego :reach-stop)
|
|
(actions/do-dialogue entities :ego "It's empty now.")
|
|
(actions/play-animation entities :ego :reach-start :stop? false)
|
|
(actions/play-animation entities :chest-top :close)
|
|
(actions/play-animation entities :ego :reach-stop))
|
|
|
|
(get-in @entities [:state :opened-bars?])
|
|
(do (actions/walk-to entities :ego [192 66] :face :right)
|
|
(actions/play-animation entities :ego :reach-start :stop? false)
|
|
(actions/play-animation entities :chest-top :open)
|
|
(actions/play-animation entities :ego :reach-stop)
|
|
(actions/do-dialogue entities
|
|
:ego "Hey!"
|
|
:ego "All my possessions are in here!")
|
|
(actions/update-state entities #(-> %
|
|
(assoc :inventory (concat (:inventory %) (:chest-contents %)))
|
|
(assoc :chest-contents [])))
|
|
(when (not (actions/has-obtained? entities :rope))
|
|
(actions/give entities :rope)
|
|
(actions/do-dialogue entities :ego "Looks like there's some rope in here too."))
|
|
(actions/play-animation entities :ego :reach-start :stop? false)
|
|
(actions/play-animation entities :chest-top :close)
|
|
(actions/play-animation entities :ego :reach-stop)
|
|
)
|
|
|
|
:else
|
|
(do (actions/walk-to entities :ego [179 81] :face :right)
|
|
(actions/play-animation entities :ego :reach)
|
|
(actions/do-dialogue entities :ego "I can't reach it!")
|
|
(when (not (get-in @entities [:state :warden-sleeping?]))
|
|
(actions/do-dialogue entities :warden "Quit yer yappin'!"
|
|
:warden "You're not escaping while I'm on watch, so just give it up.")))))
|
|
|
|
|
|
(defn do-warden-dialogue [entities]
|
|
(actions/do-dialogue entities :ego "Hey, who are you? Why am I in this cell?"
|
|
:warden "You're under arrest for theft of property."
|
|
:ego "Under arrest? Theft of property?"
|
|
:ego "I didn't steal the Sword of Blergh, I fulfilled the prophecy."
|
|
:warden "Slow down there, chap."
|
|
:warden "You're not under arrest for theft of the sword."
|
|
:warden "You're under arrest for stealing the Duke of Remington's ladder."
|
|
:ego "But I'm the good guy!\nThe game is named after me!"
|
|
:warden "Sorry chap. The law's the law."
|
|
)
|
|
(actions/present-choices entities
|
|
{:choices ["But I'm just a kid."
|
|
{:run #(actions/respond entities %
|
|
:warden "The Duke of Remington is a very stern chap."
|
|
:warden "He doesn't bend the rules, even for young thieves.")
|
|
:choices actions/previous-choices}
|
|
"Took, son of Luke, son of Puke lended me that ladder!"
|
|
{:run #(actions/respond entities %
|
|
:warden "It wasn't his to give."
|
|
:warden "In fact, he's off to the gallows come dawn."
|
|
:ego "Oh boy.")
|
|
:choices actions/previous-choices}
|
|
"But I was going to teach Bloodclot a lesson!"
|
|
{:run #(actions/respond entities %
|
|
:warden "Sure you were. If he even exists."
|
|
:ego "He does! He's going to come destroy the town first thing in the morning!"
|
|
:warden "Uh huh."
|
|
:warden "As if I have heard the 'bad guy is coming to destroy the town' 1000 times already."
|
|
:warden "You could try coming up with something creative, chap."
|
|
:ego "Creative?"
|
|
:warden "Yeah, like, 'My mother is in the hospital.'"
|
|
:warden "Or, 'I have a highly contagious case of the lizard-pox.'")
|
|
:choices actions/previous-choices}
|
|
"But the whole town will die if I don't do something!"
|
|
{:run #(actions/respond entities %
|
|
:warden "The whole town will have a thief on the loose if I don't keep you here."
|
|
:warden "We don't want that either, do we?"
|
|
:ego "This is life and death we're talking about here!"
|
|
:warden "And this is my job. A chap's got to do his job, am I right?"
|
|
:warden "You've got to steal, and I've got to lock you up."
|
|
:warden "It's how it works.")
|
|
:choices actions/previous-choices}
|
|
"Nevermind."
|
|
{:run #(do (actions/respond entities %
|
|
:warden "This conversation has got me very tired."
|
|
:warden "Be a good chap and let me rest.")
|
|
(actions/play-animation entities :warden :fall-asleep :stop? false)
|
|
(actions/begin-animation entities :warden :sleep)
|
|
(actions/update-state entities (fn [s] (assoc s :warden-sleeping? true))))}]}))
|
|
|
|
(defn get-key [ entities]
|
|
(actions/walk-to entities :ego [71 82] :face :left)
|
|
(actions/play-animation entities :ego :squat)
|
|
(let [had-key-before? (actions/has-obtained? entities :key)]
|
|
(if had-key-before?
|
|
(do
|
|
(actions/do-dialogue entities :ego "He's got the key clutched in his hand!")
|
|
(actions/play-animation entities :ego :squat)
|
|
(actions/give entities :key))
|
|
(do
|
|
(actions/do-dialogue entities :ego "He's got something clutched in his hand!")
|
|
(actions/play-animation entities :ego :squat)
|
|
(actions/do-dialogue entities :ego "What's this?"
|
|
:ego "Hello hello!"
|
|
:ego "It's the key!")
|
|
(actions/give entities :key)
|
|
(actions/do-dialogue entities :ego "Come on! It's that easy to escape?"
|
|
:ego "We're not going to at least do that dog and bone scenario?"
|
|
:ego "I get to just take the key and leave?"
|
|
:ego "Seems like a pretty sorry excuse for a puzzle.")))))
|
|
|
|
(defn tie-up-warden [entities message]
|
|
(if (get-in @entities [:state :opened-bars?])
|
|
(do
|
|
(actions/play-animation entities :ego :idea)
|
|
(actions/do-dialogue entities
|
|
:ego "I know!"
|
|
:ego message)
|
|
(actions/walk-to entities :ego [91 61] :face :left)
|
|
(actions/play-animation entities :ego :reach)
|
|
(actions/do-dialogue entities
|
|
:warden "Hey! What do you think you're doing?"
|
|
:warden "Back in the slammer you go.")
|
|
(common/go-to-jail entities))
|
|
(actions/talk entities :ego "What am I supposed to do while in this cell?")))
|
|
|
|
(defn search-hay [entities]
|
|
(actions/walk-to entities :ego [144 86] :face :right)
|
|
(let [hay-searches (get-in @entities [:state :hay-searches] 0)]
|
|
(condp = hay-searches
|
|
0 (do
|
|
(actions/talk entities :ego "Maybe there's a needle or something in here.")
|
|
(actions/play-animation entities :ego :squat)
|
|
(actions/talk entities :ego "No. Nothing at all!"))
|
|
1 (do
|
|
(actions/talk entities :ego "Maybe I missed something. I'll check again.")
|
|
(actions/play-animation entities :ego :squat)
|
|
(actions/talk entities :ego "Nope. Still nothing."))
|
|
|
|
2 (do (actions/talk entities :ego "There's got to be something in here!")
|
|
(actions/play-animation entities :ego :squat)
|
|
(actions/talk entities :ego "Nope. Still nothing."))
|
|
|
|
(do (actions/talk entities :ego "One more try.")
|
|
(actions/play-animation entities :ego :squat)
|
|
(actions/play-animation entities :ego :sigh)
|
|
(actions/do-dialogue entities
|
|
:ego "You know, in some games, you have to try multiple times."
|
|
:ego "But I have a feeling each time you click on this hay, I'm going to find nothing."
|
|
:ego "Maybe you should give it a rest.")))
|
|
(actions/update-state entities #(assoc % :hay-searches (inc hay-searches)))))
|
|
|
|
|
|
(defn leave [entities]
|
|
(if (get-in @entities [:state :opened-bars?])
|
|
(do
|
|
(actions/walk-to entities :ego [279 57])
|
|
(if (chest-full? entities)
|
|
(actions/talk entities :ego "I probably shouldn't leave without my belongings.")
|
|
(do (actions/transition-background entities :outside-jail [50 46] :face :right)
|
|
(if (get-in @entities [:state :dropped-ball?])
|
|
(actions/do-dialogue entities :ego "Yes I made it!"
|
|
:ego "But what now?"
|
|
:ego "I have till sunrise before Bloodclot comes and destroys the town."
|
|
:ego "Maybe Gandarf can help me!")
|
|
(do
|
|
(actions/do-dialogue entities :ego "Yes I made it!"
|
|
:guard "Hmm?"
|
|
:guard "Halt! Thou art under arrest!"
|
|
:guard "Thou wilst be putteth back into thy cell.")
|
|
(actions/play-animation entities :ego :sigh)
|
|
|
|
(common/go-to-jail entities)
|
|
(actions/do-dialogue entities :ego "Dang! I was so close to freedom, I could taste it!"))))))
|
|
(actions/talk entities :ego "Do you really think I can walk down those steps while I'm locked up?")))
|
|
|
|
|
|
|
|
(defn make [screen]
|
|
(let [warden-sheet (texture! (texture "inside-jail/warden.png") :split 43 58)
|
|
warden-talk (animation 0.2 (for [i [1 0 1 0 1 0 1 0 0 0 2 0]]
|
|
(aget warden-sheet 0 i)))
|
|
warden-stand (animation 0.1 (for [i (flatten [(repeat 30 0) 2 (repeat 20 0) 2])]
|
|
(aget warden-sheet 0 i)))
|
|
warden-fall-asleep (animation 0.1 (for [i (flatten [(repeat 5 0) 2 2 (repeat 10 0) 2 2 2 (repeat 10 0) 2 2 2])]
|
|
(aget warden-sheet 0 i)))
|
|
warden-sleep (animation 0.25 (for [i (flatten [ 3 4 3 4 3 4 3 4 3 4 5 5 2 2 2 2 2 2])]
|
|
(aget warden-sheet 0 i)))
|
|
candle (utils/make-anim "inside-jail/candle.png" [20 25] 0.1 (range 4))
|
|
candle-aura (utils/make-anim (texture "inside-house/candle-aura.png") [27 27] 0.2 [0 1 2 3 2 1])]
|
|
(rooms/make :music :inside-antique
|
|
:interactions {
|
|
:lock {:box [172 102 190 124]
|
|
:script (actions/get-script entities
|
|
(actions/walk-to entities :ego [174 80] :face :right)
|
|
(actions/play-animation entities :ego :reach)
|
|
(actions/talk entities :ego "There's no helping it. It's locked."))
|
|
:scripts {:key (actions/get-script entities (open-lock entities))}}
|
|
:window {:box [98 110 118 140]
|
|
:script (actions/get-script entities
|
|
(actions/walk-to entities :ego [102 88] :face :right)
|
|
(actions/do-dialogue entities
|
|
:ego "What a peaceful night."
|
|
:ego "Oh my sweet Georgia McGorgeous. How will I ever save you now?")
|
|
(actions/in-love entities)
|
|
(actions/do-dialogue entities
|
|
:ego "I have to find a way out of here!"))
|
|
:scripts {:crowbar (actions/get-script entities
|
|
(if (get-in @entities [:state :bent-bars?])
|
|
(actions/do-dialogue entities :ego "They're bent as far as they can go.")
|
|
(do (actions/walk-to entities :ego [102 88] :face :right)
|
|
(actions/play-animation entities :ego :reach)
|
|
(actions/remove-entity entities :closed-window)
|
|
(actions/update-state entities #(assoc % :bent-bars? true))
|
|
(actions/do-dialogue entities :ego "Now we're getting somewhere."))))
|
|
:ball-n-chain (actions/get-script entities (if (get-in @entities [:state :bent-bars?])
|
|
(do (actions/walk-to entities :ego [102 88] :face :right)
|
|
(actions/play-animation entities :ego :reach)
|
|
(actions/update-state entities #(assoc % :dropped-ball? true))
|
|
(actions/do-dialogue entities :ego "Geronimo!!"
|
|
:ego "*crash*!")
|
|
(Thread/sleep 200)
|
|
(actions/begin-animation entities :warden :stand)
|
|
(Thread/sleep 300)
|
|
(actions/do-dialogue entities
|
|
:warden "Charlie, is that you chap?"
|
|
:warden "What're you doing digging through my trash can?")
|
|
(Thread/sleep 300)
|
|
(actions/play-animation entities :warden :fall-asleep :stop? false)
|
|
(actions/begin-animation entities :warden :sleep)
|
|
(actions/remove-item entities :ball-n-chain)
|
|
(actions/talk entities :ego "Phew! That was close!"))
|
|
(actions/do-dialogue entities :ego "I don't know what to do with that.")))
|
|
:sword (actions/get-script entities (actions/talk entities :ego "I wouldn't want to accidentally break the Sword of Blergh."))
|
|
:rope (actions/get-script entities (cond
|
|
(get-in @entities [:state :dropped-ball?])
|
|
(do (actions/walk-to entities :ego [102 88] :face :right)
|
|
(actions/do-dialogue entities :ego "Here goes.")
|
|
(actions/play-animation entities :ego :reach)
|
|
(actions/do-dialogue entities
|
|
:ego "Wait a second."
|
|
:ego "That guard is out cold."
|
|
:ego "Why risk breaking my neck now?"))
|
|
|
|
(get-in @entities [:state :bent-bars?])
|
|
(do (actions/walk-to entities :ego [102 88] :face :right)
|
|
(actions/do-dialogue entities :ego "Here goes.")
|
|
(actions/play-animation entities :ego :reach)
|
|
(actions/do-dialogue entities
|
|
:ego "Uh oh. There's a guard right beneath the window."
|
|
:ego "I had better not, or else I'd get caught."))
|
|
|
|
:else
|
|
(actions/do-dialogue entities :ego "Good thinking."
|
|
:ego "But I can't fit out that window."
|
|
:ego "And the bars are made of steel!")))
|
|
:key (actions/get-script entities (actions/walk-to entities :ego [102 88] :face :right)
|
|
(actions/do-dialogue entities :ego "Here goes."
|
|
:ego "Wait..."
|
|
:ego "The door locks without a key."
|
|
:ego "If I get caught, I won't be able to get out."))}}
|
|
:hay {:box [130 86 177 102]
|
|
:script (actions/get-script entities
|
|
(search-hay entities))
|
|
:scripts {:default (actions/get-script entities
|
|
(actions/talk entities :ego "Finding it again will be like finding a needle in a haystack!"))
|
|
|
|
:key (actions/get-script entities
|
|
(actions/do-dialogue entities :ego "I'm trying to escape."
|
|
:ego "Not help the next bloke who gets trapped here."))}}
|
|
:chest {:box [194 62 228 99]
|
|
:script (actions/get-script entities (touch-chest entities))}
|
|
:door {:box [257 62 301 152]
|
|
:cursor :down
|
|
:script (actions/get-script entities (leave entities))}}
|
|
:layers [(assoc (texture "inside-jail/background.png") :x 0 :y 0 :baseline 0 :night-profile :none)
|
|
(assoc (texture "inside-jail/bars.png") :x 0 :y 0 :baseline 165 :night-profile :none)
|
|
(assoc (texture "inside-jail/glow.png") :x 0 :y 0 :baseline 240 :additive? true :opacity 0.35 :night-profile :none)
|
|
(assoc (texture "inside-jail/fg.png") :x 0 :y 5 :baseline 241 :parallax 1.5 :night-profile :none)]
|
|
:hotspots [{:box [121 40 258 44]
|
|
:fn (fn [screen entities]
|
|
|
|
(let [is-walking? (#{(get-in entities [:room :entities :ego :left :walk])
|
|
(get-in entities [:room :entities :ego :right :walk])} (get-in entities [:room :entities :ego :anim]))]
|
|
(if is-walking?
|
|
(let [entities (-> entities
|
|
(update-in [:actions] #(assoc % :channel (chan) :current nil :started? false :script-running? false))
|
|
(update-in [:room :entities :ego] #(actions/start-animation screen % :stand)))]
|
|
((actions/get-script entities
|
|
(actions/stop-walking entities :ego)
|
|
(actions/do-dialogue entities
|
|
:ego "*creak*"
|
|
:ego "Oops!"
|
|
:warden "Hey! What are you doing?"
|
|
:warden "Get back in jail.")
|
|
(common/go-to-jail entities)
|
|
(actions/do-dialogue entities :warden "Now don't let me catch you trying to escape again.")
|
|
(actions/play-animation entities :warden :fall-asleep :stop? false)
|
|
(actions/begin-animation entities :warden :sleep)) entities)
|
|
entities)
|
|
entities)))}]
|
|
:entities {:warden (assoc (texture "inside-jail/warden.png" )
|
|
:x 40 :y 60 :baseline 166
|
|
:stand warden-stand
|
|
:talk warden-talk
|
|
:sleep warden-sleep
|
|
:fall-asleep warden-fall-asleep
|
|
:anim warden-stand
|
|
:anim-start 0
|
|
:night-profile :none
|
|
:inhale (sound "inside-jail/inhale.ogg")
|
|
:exhale (sound "inside-jail/exhale.ogg")
|
|
:talk-color (color 0.9 0.3 0.9 1.0)
|
|
:anim-sound-frames {warden-stand {31 [:blink 0.15]
|
|
51 [:blink 0.15]}
|
|
warden-talk {10 [:blink 0.15]}
|
|
warden-fall-asleep {7 [:blink 0.15]
|
|
18 [:blink 0.15]}
|
|
warden-sleep {0 [:inhale 1.0]
|
|
2 [:exhale 1.0]}}
|
|
:script (actions/get-script entities
|
|
(cond
|
|
(actions/has-item? entities :key) (actions/talk entities :ego "Shh! It's best not to wake him now.")
|
|
(get-in @entities [:state :warden-fast-asleep?]) (get-key entities)
|
|
(get-in @entities [:state :warden-sleeping?]) (do (actions/walk-to entities :ego [103 82])
|
|
(actions/do-dialogue entities
|
|
:ego "You-hoo! Mr. Warden?"
|
|
:ego "I guess he's really fast asleep!")
|
|
(actions/update-state entities #(assoc % :warden-fast-asleep? true)))
|
|
|
|
:else (do (actions/walk-to entities :ego [103 82])
|
|
(do-warden-dialogue entities))))
|
|
:scripts {:sword (actions/get-script entities (actions/do-dialogue entities
|
|
:ego "That's pretty gruesome."
|
|
:ego "I can't kill him just for doing his job."))
|
|
:rope (actions/get-script entities (tie-up-warden entities "I'll tie him up."))
|
|
:ball-n-chain (actions/get-script entities (tie-up-warden entities "I'll lock him up."))})
|
|
:chest-top (assoc (texture "inside-jail/chest-top.png")
|
|
:x 193 :y (- 240 165) :baseline 166
|
|
:origin-x 0 :origin-y 0
|
|
:night-profile :none
|
|
:open (animation 0.8 [(texture "inside-jail/chest-top-open.png")])
|
|
:close (animation 0.8 [(texture "inside-jail/chest-top.png")]))
|
|
:ball-n-chain (assoc (texture "inside-jail/ball-n-chain.png")
|
|
:x 80 :y 80 :baseline 160
|
|
:night-profile :none
|
|
:script (actions/get-script entities
|
|
(actions/walk-to entities :ego [103 83] :face :left)
|
|
(actions/play-animation entities :ego :squat)
|
|
(actions/remove-entity entities :ball-n-chain)
|
|
(actions/give entities :ball-n-chain)))
|
|
:moveable-bars (assoc (texture "inside-jail/moveable-bars.png")
|
|
:night-profile :none
|
|
:x 132 :y 77 :baseline 163)
|
|
:candle (assoc (animation->texture screen candle)
|
|
:x 207 :y 118 :baseline 2
|
|
:anim candle
|
|
:anim-start 0
|
|
:night-profile :none)
|
|
:candle-aura (assoc (animation->texture screen candle-aura) :x 215 :y 130 :baseline 2
|
|
:additive? true :origin-x 13 :origin-y 13 :opacity 0.5 :anim candle-aura :anim-start 0 :night-profile :none
|
|
:script (actions/get-script entities (actions/talk entities :ego "Just a candle."))
|
|
:scripts {:default (actions/get-script entities (actions/talk entities :ego "I might catch the place on fire."))})
|
|
:candle-smoke (doto (assoc (particle-effect "inside-jail/candle") :x 215 :y 130
|
|
:baseline 200)
|
|
(particle-effect! :set-position 215 130))
|
|
:crowbar (assoc (texture "inside-jail/crowbar.png")
|
|
:x 304 :y 65 :baseline 175
|
|
:night-profile :none
|
|
:script (actions/get-script entities
|
|
(if (get-in @entities [:state :opened-bars?])
|
|
(do (actions/walk-to entities :ego [295 55] :face :right)
|
|
(actions/play-animation entities :ego :reach)
|
|
(actions/remove-entity entities :crowbar )
|
|
(actions/give entities :crowbar)
|
|
(actions/talk entities :ego "It's a crowbar."))
|
|
(actions/talk entities :ego "I can't reach it."))))
|
|
:closed-window (assoc (texture "inside-jail/window.png")
|
|
:night-profile :none
|
|
:x 99 :y 111 :baseline 128)}
|
|
:collision "inside-jail/collision-locked.png"
|
|
:collision-free (advent.pathfind/map-from-resource "inside-jail/collision-free.png")
|
|
:scale-fn (utils/scaler-fn-with-baseline 0 0.50 1.5)
|
|
:start-pos [130 85]
|
|
:apply-state (fn [_ entities]
|
|
(utils/fast-forward-particle (get-in entities [:room :entities :candle-smoke]))
|
|
(as-> entities entities
|
|
(if (actions/has-obtained? entities :ball-n-chain)
|
|
(update-in entities [:room :entities] #(dissoc % :ball-n-chain))
|
|
entities)
|
|
(if (actions/has-obtained? entities :crowbar)
|
|
(update-in entities [:room :entities] #(dissoc % :crowbar))
|
|
entities)
|
|
(if (get-in entities [:state :warden-sleeping?])
|
|
(update-in entities [:room :entities :warden] #(actions/start-animation % :sleep))
|
|
entities)
|
|
(if (get-in entities [:state :opened-bars?])
|
|
(update-in (remove-lock entities)
|
|
[:room :entities :moveable-bars]
|
|
#(assoc % :x 65 :y 77))
|
|
entities)
|
|
(if (get-in entities [:state :bent-bars?])
|
|
(update-in entities [:room :entities] #(dissoc % :closed-window))
|
|
entities))))))
|