(ns advent.actions (:require [play-clj.core :refer :all] [play-clj.ui :refer :all] [play-clj.utils :refer :all] [play-clj.g2d :refer :all] [clojure.pprint] [clojure.string :as s] [advent.pathfind] [advent.actions :as actions] [advent.screens.dialogue :as dialogue] [clojure.core.async :refer [put! ! >!! chan go thread take! alts!!]]) (:import [com.badlogic.gdx.graphics Pixmap Pixmap$Filter Texture Texture$TextureFilter] [com.badlogic.gdx.graphics.g2d TextureRegion])) (defprotocol IAction (begin [this screen entities]) (done? [this screen entities]) (continue [this screen entities]) (terminate [this screen entities])) (defmacro get-script [& forms] `(fn [action-channel#] (thread ~@forms (put! action-channel# :end)))) (defn jump-to [screen entities entity [x y]] (let [scale-fn (-> entities :background :scale-fn) entity (assoc entity :x x :y y :baseline (- 240 y))] (if (:scaled entity) (assoc entity :scale-x (scale-fn y) :scale-y (scale-fn y)) entity))) (defn walk-to [[target-x target-y] target-id] (fn [screen entities] (let [{from-x :x from-y :y :keys [left right anim] :as target-entity} (entities target-id)] (let [delta-x (- target-x from-x) delta-y (- target-y from-y) mag (Math/sqrt (+ (* delta-x delta-x) (* delta-y delta-y))) moved-x (* 1.5 (/ delta-x mag)) moved-y (* 1.5 (/ delta-y mag))] (if (< mag 1) (assoc entities target-id (assoc target-entity :actions (rest (:actions target-entity)) :anim nil)) (assoc entities target-id (assoc (jump-to screen entities target-entity [(+ moved-x from-x) (+ moved-y from-y)]) :anim (if (< moved-x 0) left right)))))))) (defn stop [screen entities target-id] (update-in entities [target-id] #(merge % {:anim nil} (when (:anim %) (texture (animation! (:anim %) :get-key-frame 0.25)))))) (defn walk-to [entities target-id [x y]] (let [c (chan) entity (entities target-id) path (take-nth 5 (advent.pathfind/visit-all (:collision (:background entities)) [(int (:x entity)) (int (:y entity))] [(int x) (int y)]))] (doseq [[target-x target-y] path] (put! (get-in entities [:actions :channel]) (reify IAction (begin [this screen entities] (let [{from-x :x from-y :y :keys [left right anim]} (entities target-id)] (let [delta-x (- target-x from-x)] (assoc-in entities [target-id :anim] (if (< delta-x 0) left right))))) (continue [this screen entities] (let [{from-x :x from-y :y :keys [left right anim] :as target-entity} (entities target-id)] (let [delta-x (- target-x from-x) delta-y (- target-y from-y) mag (Math/sqrt (+ (* delta-x delta-x) (* delta-y delta-y))) moved-x (* 1.5 (/ delta-x mag)) moved-y (* 1.5 (/ delta-y mag))] (assoc entities target-id (jump-to screen entities target-entity [(+ moved-x from-x) (+ moved-y from-y)]))))) (done? [this screen entities] (let [{from-x :x from-y :y :keys [left right anim] :as target-entity} (entities target-id)] (let [delta-x (- target-x from-x) delta-y (- target-y from-y) mag (Math/sqrt (+ (* delta-x delta-x) (* delta-y delta-y)))] (< mag 1)))) (terminate [this screen entities] (put! c entities) (stop screen entities target-id))))) ( (- (:total-time screen) @initial-time) (get-text-duration text))) (terminate [this screen entities] (put! c entities) (run! dialogue/talking-screen :stop-talk :target-id target-id) (stop screen entities target-id)))) (