(ns advent.screens.rooms.tongue-fight (: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])) (println "loading " *ns*) (defn cause-damage [entities screen is-player-wound?] (println "test" is-player-wound?) (if is-player-wound? (update-in entities [:room :tongue-hearts] dec) (let [remaining-hearts (dec (get-in entities [:room :ego-hearts]))] (-> entities (assoc-in [:tweens :ego-heart-scale-x] (tween/tween :ego-heart-scale-x screen [:room :entities [:ego-heart remaining-hearts] :scale-x] 1 0.0 0.2 :ease tween/ease-in-cubic)) (assoc-in [:tweens :ego-heart-scale-y] (tween/tween :ego-heart-scale-y screen [:room :entities [:ego-heart remaining-hearts] :scale-y] 1 0.0 0.2 :ease tween/ease-in-cubic)) (assoc-in [:room :ego-hearts] remaining-hearts))))) (defn show-heart [entities screen is-player-wound?] (let [[x y] (if is-player-wound? [256 163] [146 185])] (-> entities (update-in [:room :entities :heart] #(assoc % :opacity 1 :x x :y y)) (update-in [:room :entities :heart] #(actions/start-animation screen % :beat)) (assoc-in [:tweens :heart-y] (tween/tween :heart-y screen [:room :entities :heart :y] y (+ y 10) 1.0 :ease tween/ease-out-cubic)) (assoc-in [:tweens :heart-opacity] (tween/tween :heart-opacity screen [:room :entities :heart :opacity] 1.0 0.0 1.2 :ease tween/ease-linear)) (cause-damage screen is-player-wound?)))) (defn stop-swing-if-necessary [screen {{{{:keys [anim anim-start] {:keys [tongue-swing]} :left } :ego} :entities} :room :as entities}] (if (and (= tongue-swing anim) (animation! anim :is-animation-finished (- (:total-time screen) anim-start))) (update-in entities [:room :entities :ego] #(actions/start-animation screen % :tongue-idle)) entities)) (defn trigger-tongue [screen {{{{:keys [state started anim anim-start] :as tongue} :tongue {ego-anim :anim ego-anim-start :anim-start {ego-windup :tongue-windup} :left } :ego } :entities :keys [ego-hearts tongue-hearts]} :room :as entities}] (if tongue (let [time-in-state (- (:total-time screen) (or started (:total-time screen))) tongue-finished? (animation! anim :is-animation-finished (- (:total-time screen) anim-start)) ego-finished? (animation! ego-anim :is-animation-finished (- (:total-time screen) ego-anim-start)) is-player-wound? (= ego-anim ego-windup) entities (stop-swing-if-necessary screen entities)] (cond (and (not (get-in entities [:fg-actions :script-running?])) (get-in entities [:state :active?]) (= 0 ego-hearts)) (do ((actions/get-script entities (common/do-win entities false)) entities) entities) (and (not (get-in entities [:fg-actions :script-running?])) (get-in entities [:state :active?]) (= 0 tongue-hearts)) (do ((actions/get-script entities (common/do-win entities true)) entities) entities) (and (= state :attack) tongue-finished?) (-> entities (update-in [:room :entities :tongue] #(actions/start-animation screen % :idle)) (update-in [:room :entities :ego] #(actions/start-animation screen % :tongue-idle)) (update-in [:room :entities :tongue] assoc :state :idle :started (:total-time screen)) (update-in [:room :entities :heart] #(actions/start-animation screen % :idle))) (and (= state :windup) tongue-finished? (or (not is-player-wound?) ego-finished?)) (-> entities (update-in [:room :entities :tongue] #(if is-player-wound? (actions/start-animation screen % :attack-hit) (actions/start-animation screen % :attack))) (update-in [:room :entities :tongue] assoc :state :attack :started (:total-time screen) ) (update-in [:room :entities :ego] #(if is-player-wound? (actions/start-animation screen % :tongue-swing) (actions/start-animation screen % :tongue-hit))) (show-heart screen is-player-wound?)) (and (= state :idle) is-player-wound? ego-finished?) (update-in entities [:room :entities :ego] #(actions/start-animation screen % :tongue-swing)) ;; reset timer if you wind up while the tongue is idle (and (= state :idle) is-player-wound?) (assoc-in entities [:room :entities :tongue :started] (:total-time screen)) (and (= state :idle) (= 1 (rand-int (* 60 2))) (> time-in-state 2.0) (not is-player-wound?)) (-> entities (update-in [:room :entities :tongue] #(actions/start-animation screen % :windup)) (update-in [:room :entities :tongue] assoc :state :windup :started (:total-time screen))) (not started) (assoc-in entities [:room :entities :tongue :started] (:total-time screen)) :else entities )) entities)) (defn make [screen atlas global-atlas] (let [hair-0 (utils/make-anim-seq atlas "hair-0" [7 8] 0.12 (range 4)) hair-1 (utils/make-anim-seq atlas "hair-1" [23 16] 0.13 [0 1 2 1]) hair-2 (utils/make-anim-seq atlas "hair-2" [47 66] 0.15 [0 1 2 1]) hair-3 (utils/make-anim-seq atlas "hair-3" [7 8] 0.12 [0 1 2 1]) hair-4 (utils/make-anim-seq atlas "hair-4" [12 28] 0.12 [0 1 2 1]) hair-5 (utils/make-anim-seq atlas "hair-5" [8 10] 0.12 [0 1 2 1]) hair-6 (utils/make-anim-seq atlas "hair-6" [4 6] 0.16 [0 1 2 1]) hair-7 (utils/make-anim-seq atlas "hair-7" [5 7] 0.16 [0 1 2 1]) hair-8 (utils/make-anim-seq atlas "hair-8" [6 6] 0.16 [0 1 2 1]) hair-9 (utils/make-anim-seq atlas "hair-9" [12 18] 0.16 [0 1 2 1]) heart (utils/make-anim-seq atlas "heart" [24 24] 0.08 [3]) beat (utils/make-anim-seq atlas "heart" [24 24] 0.08 [0 1 0 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3]) black-blowup (particle-effect "particles/black-blowup") black-blowup-big (particle-effect "particles/black-blowup-big") tongue-idle (utils/make-anim-seq atlas "tongue-idle/tongue-idle" [135 145] 0.16 (range 5)) tongue-windup (utils/make-anim-seq atlas "tongue-windup" [135 145] 0.16 [0 1 2 3 2 1 2 3 2 1 0 ]) tongue-attack (utils/make-anim-seq atlas "tongue-attack" [135 145] 0.14 [ 2 3 4 5 6 0]) tongue-attack-hit (utils/make-anim-seq atlas "tongue-attack-hit" [135 145] 0.1 (range 7)) falling-bg (utils/make-anim-seq atlas "falling-bg" [128 128] 0.1 (range 6)) sword-spin (utils/make-anim-seq atlas "sword-spin" [300 238] 0.1 (range 6)) bloodclot-swallow-bottom (utils/make-anim-seq atlas "bloodclot-swallow-bottom" [116 83] 0.2 (concat [0 0 0 0 0 0] (range 3) (repeat 100 2))) bloodclot-swallow-top (utils/make-anim-seq atlas "bloodclot-swallow-top" [116 83] 0.2 (concat [0 0 0 0 0 0] (range 3) (repeat 100 2))) bloodclot-swallow-bottom-uhoh (utils/make-anim-seq atlas "bloodclot-swallow-bottom" [116 83] 0.3 [2 0 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3]) bloodclot-swallow-top-uhoh (utils/make-anim-seq atlas "bloodclot-swallow-top" [116 83] 0.3 [2 0 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3]) falling-ego (utils/make-anim-seq atlas "falling-ego" [40 72] 0.2 (range 4)) hearts (into {} (for [x (range 5)] [[:ego-heart x] (assoc (utils/atlas->texture atlas "heart" 0) :origin-y 12 :origin-x 12 :x (+ 22 (* 16 x)) :y 221 :baseline 321 :opacity 1)]))] (rooms/make :name "Tongue Fight" :interactions {} :layers [(assoc (utils/atlas->texture atlas "background") :x 0 :y 0 :baseline 0 :scale-x 1 :scale-y 1)] :update-fn trigger-tongue :ego-hearts 5 :tongue-hearts 5 :sounds {:swoosh (utils/load-sound "tongue-fight/swoosh.ogg") :big-swoosh (utils/load-sound "tongue-fight/big-swoosh.ogg") :impact (utils/load-sound "tongue-fight/impact.ogg") :explode-sound (utils/load-sound "space/bloodclot-explode.ogg") :swallow (utils/load-sound "tongue-fight/swallow.ogg") :falling-ego (utils/load-sound "tongue-fight/falling-ego.ogg")} :entities (into {:penultimate (assoc (utils/atlas->texture atlas "penultimate") :x 0 :y 0 :baseline 2 :scale-x 1 :scale-y 1 :opacity 0) :penultimate-wall (assoc (utils/atlas->texture atlas "penultimate-wall") :x 0 :y 0 :baseline 5 :scale-x 1 :scale-y 1 :opacity 0) :penultimate-black (assoc (utils/atlas->texture atlas "penultimate-black") :x 0 :y 0 :baseline 6 :scale-x 1 :scale-y 1 :opacity 0) :bloodclot-swallow-top (assoc (utils/atlas->texture atlas "bloodclot-swallow-top" 0) :x 167 :y 118 :baseline 3 :scale-x 1 :scale-y 1 :opacity 0 :swallow bloodclot-swallow-top :uhoh bloodclot-swallow-top-uhoh) :bloodclot-swallow-bottom (assoc (utils/atlas->texture atlas "bloodclot-swallow-bottom" 0) :x 167 :y 118 :baseline 5 :scale-x 1 :scale-y 1 :opacity 0 :swallow bloodclot-swallow-bottom :uhoh bloodclot-swallow-bottom-uhoh) :black-blowup (assoc black-blowup :x 222 :y 85 :baseline 241) :black-blowup-big (assoc black-blowup-big :x 222 :y 85 :baseline 241) :hair-0 (assoc (animation->texture screen hair-0) :x 35 :y 46 :width 6 :height 7 :baseline 1 :anim hair-0 :anim-start 0) :hair-1 (assoc (animation->texture screen hair-1) :x 113 :y 176 :width 23 :height 16 :baseline 1 :anim hair-1 :anim-start 0) :hair-2 (assoc (animation->texture screen hair-2) :x 243 :y 104 :width 47 :height 66 :baseline 1 :anim hair-2 :anim-start 0) :hair-3 (assoc (animation->texture screen hair-3) :x 121 :y 222 :width 7 :height 8 :baseline 1 :anim hair-3 :anim-start 0) :hair-4 (assoc (animation->texture screen hair-4) :x 71 :y 6 :width 12 :height 28 :baseline 1 :anim hair-4 :anim-start 0) :hair-5 (assoc (animation->texture screen hair-5) :x 100 :y 12 :width 8 :height 10 :baseline 1 :anim hair-5 :anim-start 0) :hair-6 (assoc (animation->texture screen hair-6) :x 113 :y 38 :width 4 :height 6 :baseline 1 :anim hair-6 :anim-start 0) :hair-7 (assoc (animation->texture screen hair-7) :x 125 :y 21 :width 5 :height 7 :baseline 1 :anim hair-7 :anim-start 0) :hair-8 (assoc (animation->texture screen hair-8) :x 145 :y 6 :width 6 :height 6 :baseline 1 :anim hair-8 :anim-start 0) :hair-9 (assoc (animation->texture screen hair-9) :x 23 :y 29 :width 12 :height 18 :baseline 1 :anim hair-9 :anim-start 0) :heart (assoc (animation->texture screen heart) :x 23 :y 29 :width 32 :height 32 :baseline 321 :opacity 0 :anim heart :idle heart :beat beat :anim-start 0) :falling-bg (assoc (animation->texture screen falling-bg) :x 0 :y 0 :width 320 :height 240 :baseline 320 :anim falling-bg :opacity 0 :anim-start 0) :belly-bottom (assoc (utils/atlas->texture atlas "belly-bottom") :x 0 :y 0 :baseline 321 :scale-x 1 :scale-y 1 :opacity 0) :falling-ego (assoc (animation->texture screen falling-ego) :x 160 :y 120 :scale-x 2 :scale-y 2 :origin-x 20 :origin-y 35 :baseline 321 :opacity 0 :anim falling-ego :anim-start 0) :sword-spin (assoc (animation->texture screen sword-spin) :x 160 :y 120 :origin-x 150 :origin-y 120 :width 300 :height 238 :baseline 321 :opacity 0 :anim sword-spin :anim-start 0) :tongue (assoc (animation->texture screen tongue-idle) :x 211 :y 40 :origin-x 23 :origin-y 10 :width 135 :height 145 :baseline 4 :anim tongue-idle :windup tongue-windup :idle tongue-idle :attack tongue-attack :hit-sound (utils/load-sound "georgia/kick.ogg") :slice-sound (utils/load-sound "tongue-fight/impact.ogg") :attack-hit tongue-attack-hit :anim-merges {tongue-idle {:origin-x 23 :origin-y 10} tongue-windup {:origin-x 23 :origin-y 10} tongue-attack {:origin-x 90 :origin-y 10} tongue-attack-hit {:origin-x 100 :origin-y 10}} :anim-sound-frames {tongue-attack {1 [:hit-sound (constantly 0.6)]} tongue-attack-hit {1 [:slice-sound (constantly 0.6)]}} :anim-start 0 :state :idle :script (actions/get-script entities (actions/begin-animation entities :ego :tongue-windup))) } hearts) :collision "space/collision.png" :scale-fn (constantly 1.0) :start-pos [141 110] :apply-state (fn [screen e] (screen! @(resolve 'advent.screens.scene/hud) :on-tongue-fight {}) (-> e (update-in [:room :entities :ego] #(actions/start-animation screen % :tongue-idle)) (assoc-in [:room :entities :ego :stand-override] :tongue-idle) (assoc-in [:room :entities :ego :baseline] 3) (assoc-in [:room :entities :ego :x] 141) (assoc-in [:room :entities :ego :y] 110))))))