Files
gitea-docker/desktop/src-common/advent/screens/rooms/inside_jail.clj
2015-08-19 06:35:40 -07:00

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))))))