(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 entities :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)))))))))))