Files
gitea-docker/desktop/src-common/advent/screens/rooms/space.clj
2016-02-22 08:23:58 -08:00

371 lines
30 KiB
Clojure

(ns advent.screens.rooms.space
(:require [advent.screens.rooms :as rooms]
[advent.screens.rooms.common :as common]
[advent.screens.rooms.held :as held]
[advent.saves :as saves]
[advent.actions :as actions]
[advent.screens.items :as items]
[advent.utils :as utils]
[advent.tween :as tween]
[clojure.zip :as zip]
[clojure.set :as set]
[clojure.string :as str]
[play-clj.core :refer :all]
[play-clj.ui :refer :all]
[play-clj.utils :refer :all]
[play-clj.math :refer :all]
[play-clj.g2d :refer :all]))
(defn taunt [screen entities]
(when (and (not (get-in entities [:fg-actions :script-running?]))
(get-in entities [:state :active?])
(not (get-in entities [:state :blergh-dead?]))
(not (actions/has-item? entities :magic-slingshot)))
((actions/get-script entities (actions/do-dialogue entities :bloodclot-head (rand-nth ["Come over here, so I can eat you!"
"The taste of children makes my tummy rumble!"
"Come here and fight me like a good little morsel!"
"Georgia McGorgeous will be so impressed with how quickly I eat you!"
"Come on, I'm hungry!"
"First I'll eat you, then I'll eat Georgia McGorgeous!"]))) entities))
nil)
(defn shock [screen entities]
(when (and (not (get-in entities [:fg-actions :script-running?]))
(get-in entities [:state :active?])
(not (get-in entities [:state :blergh-dead?]))
(actions/has-item? entities :magic-slingshot))
((actions/get-script entities
(actions/play-sound entities :shock-short 0.25 :wait? false)
(actions/play-animation entities :bloodclot-head :shoot :stop? false)
(actions/update-entity entities :lightning #(assoc % :opacity 1.0))
(actions/begin-animation entities :bloodclot-head :keep-shoot)
(Thread/sleep 2000)
(actions/update-entity entities :lightning #(assoc % :opacity 0.0))
(actions/do-dialogue entities :bloodclot-head "Dang! Come a little closer!"))
entities))
nil)
(defn start-swing-if-necessary [screen e]
(if (and (not= (:anim e) :swing)
(> (:x e) 190))
(actions/start-animation screen e :swing)
e))
(defn start-fade-if-necessary [e screen]
(if (and (nil? (get-in e [:tweens :flash]))
(< (get-in e [:room :entities :ego :y]) 100))
(assoc-in e [:tweens :flash] (tween/tween :flash screen [:white-fade :opacity] 0.0 1.0 0.5 :ease tween/ease-in-cubic))
e))
(defn bloodclot-disappear [entities]
(actions/run-action entities
(begin [this screen entities]
(particle-effect! (get-in entities [:room :entities :appear]) :reset)
(particle-effect! (get-in entities [:room :entities :appear]) :start)
(utils/play-sound! screen entities :disappear (constantly 0.7))
(-> entities
(assoc-in [:tweens :bloodclot-head-appear]
(tween/tween :bloodclot-head-appear screen [:room :entities :bloodclot-head :opacity] 1.0 0.0 1.0 :ease tween/ease-in-cubic))
(assoc-in [:tweens :bloodclot-appear]
(tween/tween :bloodclot-appear screen [:room :entities :bloodclot :opacity] 1.0 0.0 1.0 :ease tween/ease-in-cubic))))
(continue [this screen entities]
entities)
(done? [this screen entities]
(= 0.0 (get-in entities [:room :entities :bloodclot :opacity])))
(terminate [this screen entities]
entities)
(skip-type [this screen entities]
:none)))
(defn swing-at-blergh [entities]
(let [jump-path (bezier (map #(apply vector-2* %) [[35 45] [110 145] [195 180]]))
swing-path (bezier (map #(apply vector-2* %) [[195 180] [205 45]]))
jump-dist (utils/dist 35 45 205 45)
speed 190.0
jump-duration (/ jump-dist speed)
swing-dist (utils/dist 195 180 205 45)
swing-duration (/ swing-dist (* speed 1.5))]
(actions/run-action entities
(begin [this screen entities]
(utils/play-sound! screen entities :jump (constantly 0.9))
(-> entities
(assoc-in [:room :entities :cloud] (assoc (utils/get-texture "space/cloud.png")
:x (- (get-in entities [:room :entities :ego :x]) 10)
:y (get-in entities [:room :entities :ego :y])
:origin-x 7
:origin-y 7
:scale-x 0.5
:scale-y 0.5
:opacity 0.5
:baseline 240))
(assoc-in [:tweens :cloud-up] (tween/tween :cloud-up screen [:room :entities :cloud :y]
(get-in entities [:room :entities :ego :y])
(+ (get-in entities [:room :entities :ego :y]) 20)
1.0))
(assoc-in [:tweens :cloud-fade] (tween/tween :cloud-fade screen [:room :entities :cloud :opacity]
0.5
0.0
1.0))
(assoc-in [:tweens :cloud-grow] (tween/tween :cloud-grow screen [:room :entities :cloud :scale-y]
0.5
2.5
1.0))
(assoc-in [:tweens :cloud-grow-2] (tween/tween :cloud-grow-2 screen [:room :entities :cloud :scale-x]
0.5
2.5
1.0))
(update-in [:room :entities :ego]
#(actions/start-animation screen % :jump))
(assoc-in [:tweens :jump-pos] (tween/tween :jump-pos screen [:room :entities :ego :move-pct] 0.0 1.0 jump-duration :ease tween/ease-in-quadratic))))
(continue [this screen entities]
(let [v (vector-2 0 0)
a (bezier! jump-path :value-at v (get-in entities [:room :entities :ego :move-pct] 0.0))]
(update-in entities [:room :entities :ego] #(assoc % :x (vector-2! v :x) :y (vector-2! v :y)))))
(done? [this screen entities]
(= (get-in entities [:room :entities :ego :move-pct]) 1.0))
(terminate [this screen entities]
(assoc-in entities [:room :entities :ego :move-pct] 0.0))
(skip-type [this screen entities]
:none))
(actions/run-action entities
(begin [this screen entities]
(utils/play-sound! screen entities :swing-sword (constantly 0.9))
(-> entities
(update-in [:room :entities :ego]
#(actions/start-animation screen % :swing))
(assoc-in [:tweens :swing-pos] (tween/tween :swing-pos screen [:room :entities :ego :move-pct] 0.0 1.0 swing-duration :ease tween/ease-in-dectic))))
(continue [this screen entities]
(let [v (vector-2 0 0)
a (bezier! swing-path :value-at v (get-in entities [:room :entities :ego :move-pct] 0.0))]
(-> entities
(start-fade-if-necessary screen)
(update-in [:room :entities :ego] #(assoc % :x (vector-2! v :x) :y (vector-2! v :y))))))
(done? [this screen entities]
(= (get-in entities [:room :entities :ego :move-pct]) 1.0))
(terminate [this screen entities]
(-> entities
(assoc-in [:room :entities :ego :move-pct] 0.0)
(update-in [:room :entities :ego] #(actions/start-animation screen % :pant))))
(skip-type [this screen entities]
:none))
(actions/run-action entities
(begin [this screen entities]
(assoc-in entities [:tweens :flash] (tween/tween :flash screen [:white-fade :opacity] 1.0 0.0 3.0 :ease tween/ease-in-quadratic)))
(continue [this screen entities]
entities)
(done? [this screen entities]
(nil? (get-in entities [:tweens :flash])))
(terminate [this screen entities]
entities)
(skip-type [this screen entities]
:none))))
(defn grunt-vol [entities]
(* 0.3 (get-in entities [:room :entities :bloodclot :opacity])))
(defn make [screen]
(let [bloodclot-head-talk-anim (utils/make-anim-seq "space/bloodclot-head-talk" [82 75] 0.05 [0 0 1 1 2 2 1 1 0 0 1 1 2 2 1 1 0 0 3 4 4 4 3 0 0 1 1 2 2 1 1 0 0 0 0 5 5 5 6 6 6 7 7 7])
bloodclot-head-stand-anim (utils/make-anim-seq "space/bloodclot-head-talk" [82 75] 0.05 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 4 3])
bloodclot-head-shoot-anim (utils/make-anim-seq "space/bloodclot-head-talk" [82 75] 0.05 [8 9 8 9 8 9 8 9 8 9 8 9 8 9 8 9 8 9 8 9 10 11 10 11 10 11 10 11 10 11 10 11])
bloodclot-head-keep-shoot-anim (utils/make-anim-seq "space/bloodclot-head-talk" [82 75] 0.05 [12 13])
blergh-stand-anim (utils/make-anim "space/bloodclot-stand.png" [106 165] 0.9 [0 1])
bloodclot-explode (utils/make-anim-seq "space/bloodclot-explode" [106 165] 0.075 [0 0 0 0 0 0 0 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 4 4 4 5 5 5 5 5 5 5 5 5 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 8 8 8 7 7 7 7 8 8 8 8 8 7 7 7 7 8 8 7 7 7 7 8 8 8 7 8 8 8 8 8 8 8 8 9 8 8 8 8 9 9 8 8 8 8 8 8 8 9 9 9 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 10 9 10 10 8 9 9 9 9 9 10 10 10 10 9 9 9 9 9 9 9 9 9 9 10 10 10 10 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 13 14 15 16 17 18 19 20 21 22])
bullet (utils/make-anim "space/bullet.png" [24 24] 0.0075 [0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 3 3 3 4 4 5 5 6 5 4 7])
effect (particle-effect "particles/appear")
blowup-effect (particle-effect "particles/blowup")
lightning-effect (particle-effect "particles/lightning")
grow-explode (particle-effect "particles/grow-explode")]
(rooms/make :music :fight
:name "Duel"
:sounds {:shock (utils/load-sound "space/shock.ogg")
:shock-short (utils/load-sound "space/shock-short.ogg")
:jump (utils/load-sound "space/jump.ogg")
:swing-sword (utils/load-sound "space/swingsword.ogg")}
:interactions
{}
:layers [(assoc (utils/get-texture "space/background.png") :x 0 :y 0 :baseline 0)]
:timers {:taunt [10.0 8.0 taunt]
:shock [5.0 15.0 shock]}
:entities {:appear (assoc effect
:x 240 :y 50
:baseline 200)
:later (assoc (utils/get-texture "space/later.png")
:x 0 :y 0
:baseline 240
:opacity 0.0)
:grow-explode (assoc grow-explode
:x 240 :y 130
:baseline 200)
:blowup (assoc blowup-effect
:x 225 :y 175
:baseline 241)
:lightning (assoc lightning-effect
:x 225 :y 160
:baseline 240
:opacity 0.0)
:bloodclot-head (assoc (animation->texture screen bloodclot-head-stand-anim)
:x 195 :y 138 :baseline 195
:opacity 0.0
:anim bloodclot-head-stand-anim
:talk bloodclot-head-talk-anim
:keep-shoot bloodclot-head-keep-shoot-anim
:shoot bloodclot-head-shoot-anim
:anim-start 0
:stand bloodclot-head-stand-anim
:talk-color (color 0.95 0.4 0.2 1.0))
:bloodclot (assoc (animation->texture screen blergh-stand-anim)
:x 180 :y 50 :baseline 190
:stand blergh-stand-anim
:inhale-sound (utils/load-sound "space/bloodclot-inhale.ogg")
:exhale-sound (utils/load-sound "space/bloodclot-exhale.ogg")
:explode-sound (utils/load-sound "space/bloodclot-explode.ogg")
:anim-sound-frames {blergh-stand-anim {0 [:inhale-sound grunt-vol]
1 [:exhale-sound grunt-vol]}
bloodclot-explode {35 [:grow-sound (constantly 0.5)]
181 [:explode-sound (constantly 0.5)]}}
:opacity 0.0
:anim blergh-stand-anim
:anim-start 0
:explode bloodclot-explode
:script (actions/get-script entities
(actions/do-dialogue entities
:bloodclot-head "No time to talk."
:bloodclot-head "It's lunch time."))
:scripts {:spear (actions/get-script entities
(actions/do-dialogue entities :ego "I don't want to get too close while he still has his lightning gem."
:ego "Plus, this spear wouldn't do any damage to him."))
:kiss (actions/get-script entities
(actions/do-dialogue entities
:ego "No way!"
:ego "I can't kiss that green creep!"))
:trophy (actions/get-script entities
(actions/do-dialogue entities
:ego "Showing Bloodclot a trophy for wisdom doesn't seem very wise."))
:medal (actions/get-script entities
(actions/do-dialogue :ego "His little finger could've beaten me in an arm wrestling match!"))
:crowbar (actions/get-script entities
(actions/do-dialogue entities :ego "I don't want to get too close while he still has his lightning gem."
:ego "And this crowbar's too heavy for me to swing."))
:sword (actions/get-script entities
(if (actions/has-item? entities :magic-slingshot)
(if (get-in @entities [:state :broke-jewel?])
(do
(swing-at-blergh entities)
(actions/do-dialogue entities
:bloodclot-head "Ha ha ha! Still a weakling, I see."
:bloodclot-head "But you'll not best me!")
(actions/play-animation entities :ego :scared :continue? true)
(Thread/sleep 500)
(actions/walk-straight-to entities :ego [35 45] :override-dir :right :speed 3.0))
(actions/do-dialogue entities :ego "I don't want to get too close while he still has his lightning gem!"))
(do
(actions/update-entity entities :ego (fn [e]
(dissoc e :stand-override :talk-override)))
(actions/update-entity entities :ego #(assoc % :get-script (:original-get-script %)))
(swing-at-blergh entities)
(actions/do-dialogue entities :bloodclot-head "Ha ha ha! Is that the best you can do?"
:bloodclot-head "Take this!")
(actions/play-sound entities :shock 0.7 :wait? false)
(actions/play-animation entities :bloodclot-head :shoot :stop? false)
(actions/begin-animation entities :bloodclot-head :keep-shoot)
(actions/update-entity entities :lightning #(assoc % :opacity 1.0))
(actions/play-animation entities :ego :shock :stop? false)
(actions/begin-animation entities :bloodclot-head :stand)
(actions/update-entity entities :lightning #(assoc % :opacity 0.0))
(actions/play-animation entities :ego :burnt :stop? false)
(actions/play-animation entities :ego :passed-out :continue? true)
(actions/do-dialogue entities :bloodclot-head "Oh shucks. I overcooked him."
:bloodclot-head "No matter."
:bloodclot-head "Tomorrow, I will return with my legion of goblins."
:bloodclot-head "And THEN the feast will begin."
:bloodclot-head "Starting with his precious Georgia McGorgeous.")
(bloodclot-disappear entities)
(common/go-to-jail entities 5.0)
(actions/do-dialogue entities :ego "Hey!" :ego "What's going on? I was just about to teach Bloodclot a lesson!")
(utils/save-chapter @entities :chapter-3))))
:magic-slingshot (actions/get-script entities
(actions/do-dialogue entities
:ego "Hey, Bloodclot!"
:ego "Eat this!")
(actions/play-animation entities :ego :shoot)
(actions/add-entity entities :bullet (get-in @entities [:room :bullet]))
(actions/walk-straight-to entities :bullet [213 166] :update-baseline? false :speed 15.0)
(particle-effect! (get-in @entities [:room :entities :blowup]) :reset)
(particle-effect! (get-in @entities [:room :entities :blowup]) :start)
(actions/add-entity entities :broken-jewel (get-in @entities [:room :broken-jewel]))
(actions/remove-entity entities :bullet)
(actions/update-state entities #(assoc % :broke-jewel? true))
(Thread/sleep 5000)
(actions/do-dialogue entities
:bloodclot-head "Argh! My lightning gem!"
:bloodclot-head "No matter. I will rip you apart with my bare hands!")
(actions/pause-camera entities)
(actions/transition-background entities :held [113 120])
(actions/do-dialogue entities :bloodclot-head "Time to die, runt."
:bloodclot-head "No one injures Bloodclot and lives to talk about it!"
:ego "Let me down and fight me fair and square!"
:bloodclot-head "I'm three times as mighty as you."
:bloodclot-head "I'd rather have you as a tasty morsel.")
(held/bloodclot-choices entities))
:default (actions/get-script entities (actions/talk entities :ego "No time for that!"))})}
:bullet (assoc (animation->texture screen bullet)
:x 37 :y 85 :baseline 241
:walk bullet)
:broken-jewel (assoc (utils/get-texture "space/broken-jewel.png")
:x 225 :y 170 :baseline 240)
:collision "space/collision.png"
:scale-fn (constantly 1.5)
:start-pos [35 45]
:apply-state (fn [screen e]
(as-> e e
(if (get-in e [:state :broke-jewel?])
(assoc-in e [:room :entities :broken-jewel] (get-in e [:room :broken-jewel]))
e)
(if (get-in e [:state :seen-bloodclot?])
(assoc-in e [:room :entities :bloodclot :opacity ] 1.0)
e)
(if (get-in e [:state :seen-bloodclot?])
(assoc-in e [:room :entities :bloodclot-head :opacity ] 1.0)
e)
(if (and (not (actions/has-obtained? e :slingshot))
(get-in e [:state :seen-bloodclot?]))
(update-in e [:room :entities :ego] #(actions/start-animation screen % :scared))
e)
(assoc-in e [:state :seen-bloodclot?] true)
(assoc-in e [:room :entities :ego :original-get-script]
(get-in e [:room :entities :ego :get-script]))
(assoc-in e [:room :entities :ego :get-script]
(fn [cursor [x y]]
(actions/get-script entities
(if (actions/has-obtained? entities :slingshot)
(actions/talk entities :ego "No time for that!")
(do
(actions/talk entities :ego "No time for that!" :anim :scared-talk :stop? false)
(actions/begin-animation entities :ego :scared)))))))))))