369 lines
22 KiB
Clojure
369 lines
22 KiB
Clojure
(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")
|
|
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 2
|
|
: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)
|
|
: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]
|
|
(-> 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))))))
|
|
|