(ns advent.screens.rooms.castle-gate (:require [advent.screens.rooms :as rooms] [advent.actions :as actions] [advent.screens.items :as items] [advent.screens.rooms.common :as common] [advent.utils :as utils] [advent.screens.dialogue :as dialogue] [advent.steam :as steam] [advent.tween :as tween] [clojure.zip :as zip] [play-clj.core :refer :all] [play-clj.ui :refer :all] [play-clj.math :refer :all] [play-clj.utils :refer :all] [play-clj.g2d :refer :all])) (defn make-night [entities] entities) (defn make-coin-flip [screen] (let [coin-flip (utils/make-anim "castle-gate/coinflip.png" [10 10] 0.05 (range 5))] (assoc (animation->texture screen coin-flip) :x 212 :y 114 :baseline 151 :opacity 0.0 :origin-x 5 :origin-y 5 :night-profile :none :update-fn (partial utils/update-path-location 0.5) :script (actions/get-script entities (when (get-in @entities [:state :has-dropped-coin?]) (actions/walk-to entities :ego [196 46] :face :left) (actions/play-animation entities :ego :squat) (actions/remove-entity entities :coin-flip) (actions/give entities :money))) :walk coin-flip :coinflip coin-flip))) (defn make-goon-1 [screen] (let [stand (utils/make-anim "castle-gate/goon-1.png" [13 33] 0.21 [0 0 0 0 0 0 0 0 0 1])] (assoc (animation->texture screen stand) :x 244 :y 102 :baseline 138 :scale-x 1.4 :scale-y 1.4 :night-profile :sprite :anim stand :anim-start 0 :stand stand))) (defn make-goon-2 [screen] (let [stand (utils/make-anim "castle-gate/goon-2.png" [12 32] 0.175 [0 0 0 0 0 0 0 0 0 0 0 0 0 1]) talk (utils/make-anim "castle-gate/goon-2-talk.png" [12 32] 0.175 (range 2)) flip (utils/make-anim "castle-gate/goon-2-flip.png" [12 32] 0.05 [1 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]) search (utils/make-anim "castle-gate/goon-2-search.png" [24 32] 0.3 [0 1 2 3 2 3 2 1 4 5 6 5 6 7 6 7 6 7 6 1 0]) walk (utils/flip (utils/make-anim "castle-gate/goon-2-walk.png" [24 34] 0.075 (range 7)))] (assoc (animation->texture screen stand) :x 214 :y 102 :baseline 151 :scale-x 1.4 :scale-y 1.4 :origin-x 6 :origin-y 0 :anim stand :talk talk :flip flip :walk walk :search search :flip-sound (utils/load-sound "castle-gate/flip.ogg") :anim-sound-frames {flip {1 [:flip-sound 0.4]}} :anim-merges {search {:origin-x 12 :origin-y 0} talk {:origin-x 6 :origin-y 0} walk {:origin-x 12 :origin-y 3} :default {:origin-x 6 :origin-y 0}} :update-fn (fn [s es e] (if (and (= (:flip e) (:anim e)) (animation! (:flip e) :is-animation-finished (- (:total-time s) (:anim-start e)))) (actions/start-animation s e :stand) e)) :script (actions/get-script entities (if (get-in @entities [:tweens :coin-y]) (do (actions/update-entities entities (fn [entities] (assoc-in entities [:room :entities :coin-flip :opacity] 1.0))) (actions/talk entities :ego "Hey, Bubba!" :wait false) (actions/update-entities entities (fn [entities] (-> entities (update-in [:tweens] dissoc :coin-y) (assoc-in [:room :entities :coin-flip :opacity] 1.0)))) (actions/walk-straight-to entities :coin-flip [212 90] :update-baseline? false :speed 3.0) (screen! dialogue/talking-screen :stop-talk {}) (actions/do-stop entities :ego) (actions/walk-straight-to entities :coin-flip [210 105] :update-baseline? false :speed 1.0) (Thread/sleep 50) (actions/walk-straight-to entities :coin-flip [205 75] :update-baseline? false :speed 1.5) (actions/walk-straight-to entities :coin-flip [202 83] :update-baseline? false :speed 1.0) (Thread/sleep 50) (actions/walk-straight-to entities :coin-flip [195 65] :update-baseline? false :speed 0.5) (actions/walk-straight-to entities :coin-flip [192 70] :update-baseline? false :speed 0.5) (Thread/sleep 50) (actions/walk-straight-to entities :coin-flip [185 44] :update-baseline? false :speed 0.5) (actions/update-state entities (fn [s] (assoc s :has-dropped-coin? true))) (actions/talk entities :goon-2 "You made me lose my coin, Dipstick!" :anim :search) (actions/talk entities :ego "Umm, sorry!")) (do (actions/do-dialogue entities :ego "Hey, Bubba!" :goon-2 "Beat it, Dipstick.")))) :scripts {:money (actions/get-script entities (actions/do-dialogue entities :ego "I don't want to give it back!")) :default (actions/get-script entities (actions/do-dialogue entities :goon-2 "Beat it, Dipstick."))} :night-profile :sprite :anim-start 0 :stand stand))) (defn attempt-walking-through-gate [entities] (actions/walk-to entities :ego [157 83] :skip-type :end) (actions/walk-straight-to entities :ego [100 83]) (actions/transition-background entities :inside-castle [280 145]) (actions/walk-to entities :ego [245 90] :skip-type :end)) (defn flip-coin [screen entities] (if (and (= 0 (rand-int 2)) (not (get-in entities [:state :has-dropped-coin?])) (not (get-in entities [:state :bubba-gone?])) (= (get-in entities [:room :entities :goon-2 :anim]) (get-in entities [:room :entities :goon-2 :stand]))) (-> entities (update-in [:room :entities :coin-flip] (fn [cf] (-> (actions/start-animation screen cf :coinflip) (assoc :opacity 1.0)))) (assoc-in [:tweens :coin-y] (tween/tween :coin-y screen [:room :entities :coin-flip :y] 112 175 0.5 :ease tween/ease-out-cubic :finish (fn [e] (assoc-in e [:tweens :coin-y] (tween/tween :coin-y (assoc screen :total-time (+ 0.5 (:total-time screen))) [:room :entities :coin-flip :y] 174 118 0.5 :ease tween/ease-in-cubic :finish (fn [e] (assoc-in e [:room :entities :coin-flip :opacity] 0.0))))))) (update-in [:room :entities :goon-2] (fn [g] (-> (actions/start-animation screen g :flip))))) entities)) (defn look-at-note [entities] (actions/walk-to entities :ego [126 65] :face :left) (if (get-in @entities [:state :has-voted?]) (actions/do-dialogue entities :ego "It's a notice for a town vote." :ego "Let's see..." :ego "It looks like Took's going to get a pardon! 35 to 34!") (actions/do-dialogue entities :ego "It's a notice for a town vote." :ego "\"Took, son of Luke, son of Puke abandoned his post and duties," :ego "... and let a hoodlum steal the Duke's ladder." :ego "Vote 'Yea' by signing below to pardon him of his crime." :ego "And vote 'Nay' to exact due justice.\"" :ego "Let's see..." :ego "It looks like it's perfect tie! 34 to 34!")) (actions/update-state entities #(assoc % :has-read-voting-sheet? true))) (defn sign-note [entities] (actions/walk-to entities :ego [126 65] :face :left) (cond (not (get-in @entities [:state :has-read-voting-sheet?])) (do (actions/do-dialogue entities :ego "Let me read it first.") (look-at-note entities) (recur entities)) (get-in @entities [:state :has-voted?]) (actions/do-dialogue entities :ego "Looks like I've already voted.") :else (do (actions/do-dialogue entities :ego "It'd be a shame to have Took punished on my account!" :ego "I'll vote to give him a pardon.") (actions/play-animation entities :ego :reach) (actions/do-dialogue entities :ego "There, now the vote is 35 to 34!") (actions/update-state entities #(assoc % :has-voted? true)) (steam/set-achievement "PARDON")))) (defn make-note [] {:box [97 102 111 132] :script (actions/get-script entities (look-at-note entities)) :scripts {:charcoal (actions/get-script entities (sign-note entities))}}) (defn make [screen] (let [throw-walkie (utils/make-anim-seq "castle-gate/throw-walkie" [205 136] 0.1 (flatten [(repeat 55 0) (range 9) (repeat 55 8)])) walkie-visible (animation 1.0 [(utils/get-texture "castle-gate/throw-walkie-9.png")]) walkie-invisible (animation 1.0 [(utils/get-texture "castle-gate/throw-walkie-1.png")])] (rooms/make :music {:day :town-2 :night :night} :name "Castle gate" :timers {:taunt [1.0 6.0 flip-coin]} :interactions {:right-dir {:box [280 40 320 83] :script (actions/get-script entities (actions/walk-to entities :ego [301 46] :face :right :skip-type :end) (actions/walk-straight-to entities :ego [340 40]) (actions/transition-background entities :outside-castle [82 180]) (actions/update-state entities #(assoc % :bubba-gone? false)) (actions/walk-to entities :ego [129 148] :skip-type :end)) :cursor :right} :left-dir {:box [115 93 169 212] :script (actions/get-script entities (attempt-walking-through-gate entities)) :cursor :left} :window {:box [192 157 215 215] :script (actions/get-script entities (actions/talk entities :ego "That's a big window!")) :scripts {:walkie-talkies (actions/get-script entities (actions/play-animation entities :ego :idea) (actions/walk-to entities :ego [285 71]) (actions/walk-straight-to entities :ego [308 105] :face :left) (actions/add-entity entities :walkie-talkies (actions/start-animation (get-in @entities [:room :walkie-talkies]) :walkie-invisible)) (actions/begin-animation entities :walkie-talkies :throw-walkie) (actions/play-animation entities :ego :throw) (actions/remove-item entities :walkie-talkies) (actions/begin-animation entities :walkie-talkies :stand) (Thread/sleep 2000) (actions/walk-straight-to entities :ego [285 71]))}} :note (make-note)} :layers {:day [(assoc (utils/get-texture "castle-gate/background.png") :x 0 :y 0 :baseline 0) (assoc (utils/get-texture "castle-gate/overlay.png") :x 0 :y 0 :baseline 240)] :night [(assoc (utils/get-texture "castle-gate/background.png") :x 0 :y 0 :baseline 0) (assoc (utils/get-texture "castle-gate/overlay.png") :x 0 :y 0 :baseline 240)]} :entities {:frankie (common/make-frankie screen) :goon-1 (make-goon-1 screen) :goon-2 (make-goon-2 screen) :outside-particles (common/make-outside-particles) :coin-flip (make-coin-flip screen) } :walkie-talkies (rooms/make-entity :walkie-talkies (assoc (animation->texture screen walkie-visible) :x 104 :y 88 :baseline 130 :night-profile :sprite :throw-walkie throw-walkie :stand walkie-visible :walkie-invisible walkie-invisible :anim-start 0 :anim walkie-visible)) :collision "castle-gate/collision.png" :scale-fn (utils/scaler-fn-with-baseline 110 0.10 1.30) :apply-state (fn [_ entities] (utils/fast-forward-particle (get-in entities [:room :entities :outside-particles])) (as-> entities entities (if (= :night (get-in entities [:state :time])) (make-night entities) entities) (if (and (not (actions/has-item? entities :walkie-talkies)) (actions/has-obtained? entities :walkie-talkies)) (assoc-in entities [:room :entities :walkie-talkies] (get-in entities [:room :walkie-talkies])) entities) (if (and (not (actions/has-obtained? entities :money)) (get-in entities [:state :has-dropped-coin?])) (do (update-in entities [:room :entities :coin-flip] assoc :x 185 :y 44 :opacity 1.0)) entities) (if (actions/has-obtained? entities :money) (update-in entities [:room :entities] dissoc :coin-flip) entities) (if (get-in entities [:state :bubba-gone?]) (update-in entities [:room :entities] dissoc :coin-flip :goon-2) entities ))) :start-pos [300 45])))