diff --git a/desktop/src-common/advent/screens/scene.clj b/desktop/src-common/advent/screens/scene.clj index d7620cf5..633f77d7 100644 --- a/desktop/src-common/advent/screens/scene.clj +++ b/desktop/src-common/advent/screens/scene.clj @@ -2,6 +2,7 @@ (:require [play-clj.core :refer :all] [play-clj.ui :refer :all] [play-clj.utils :refer :all] + [play-clj.entities :as entities] [play-clj.g2d :refer :all] [clojure.zip :as zip] [clojure.pprint] @@ -20,29 +21,18 @@ (def +screen-width+ 320) (def +screen-height+ 240) -(defprotocol IMouseIn - (mouse-in? [this location])) - -(defprotocol ICursorOverridable - (cursor-override [this])) - -(defprotocol IInteractable - (get-script [this cursor location])) (def default-interaction - (reify - IInteractable - (get-script [_ cursor [x y]] - (if (= :main cursor) - (actions/get-script entities - (actions/walk-to entities :ego [x y] true)) - (actions/get-script entities - (actions/talk entities :ego "I don't know what to do with that.")))))) + {:get-script (fn [cursor [x y]] (if (= :main cursor) + (actions/get-script entities + (actions/walk-to entities :ego [x y] true)) + (actions/get-script entities + (actions/talk entities :ego "I don't know what to do with that."))))}) (defn find-override [screen entities [x y]] - (first (filter #(and (mouse-in? % [x y]) - (satisfies? ICursorOverridable %)) + (first (filter #(and ((:mouse-in? %) entities x y) + (:cursor %)) (get-in entities [:background :interactions])))) (defn open-inventory [screen entities] @@ -55,8 +45,12 @@ (if ((:mouse-in? (:inventory entities)) x y) (open-inventory screen entities) - (let [interaction (first (filter #(mouse-in? % [x y]) + (let [interaction (first (filter #((:mouse-in? %) entities x y) (get-in entities [:background :interactions]))) + interacting-entity (first (filter #(and (:mouse-in? %) + (:get-script %) + ((:mouse-in? %) entities x y)) + (vals (get-in entities [:background :entities])))) current-action (get-in entities [:actions :current]) ;; TODO - hacky way of resetting queue @@ -71,8 +65,10 @@ (if current-action entities ((or (when interaction - (get-script interaction (get-in entities [:cursor :current]) [x y])) - (get-script default-interaction (get-in entities [:cursor :current]) [x y])) entities)) + ((:get-script interaction) (get-in entities [:cursor :current]) [x y])) + (when interacting-entity + ((:get-script interacting-entity) (get-in entities [:cursor :current]) [x y])) + ((:get-script default-interaction) (get-in entities [:cursor :current]) [x y])) entities)) entities)))) (defn flip [anim] @@ -141,22 +137,29 @@ (input! :set-cursor-image (utils/cursor "cursor.png" (or override current)) 0 0)) (assoc-in entities [:cursor :last] (or override current))) -(defn make-background [& {:keys [collision interactions] :as params}] +(defn make-background [& {:keys [collision interactions entities] :as params}] (let [interactions-as-list (for [[id spec] interactions] - (reify - IMouseIn - (mouse-in? [_ location] - (apply (apply zone/box (:box spec)) location)) - IInteractable - (get-script [_ cursor location] - (if (= :main cursor) - (:script spec) - (get-in spec [:scripts cursor]))) - ICursorOverridable - (cursor-override [this] (:cursor spec))) - )] + (merge spec {:mouse-in? (fn [_ x y] + ((apply zone/box (:box spec)) x y)) + :get-script (fn [cursor [x y]] + (if (= :main cursor) + (:script spec) + (get-in spec [:scripts cursor])))})) + entities (into {} (for [[id entity] entities] + [id (merge entity + {:mouse-in? (fn [entities x y] + (let [{entity-x :x entity-y :y region :object} (get-in entities [:background :entities id]) + width (.getRegionWidth region) + height (.getRegionHeight region)] + ((zone/box entity-x entity-y (+ entity-x width) (+ entity-y height)) x y)))} + (when (:script entity) + {:get-script (fn [cursor [x y]] + (if (= :main cursor) + (:script entity) + (get-in entity [:scripts cursor])))}))]))] (merge params {:collision (advent.pathfind/map-from-resource collision) - :interactions interactions-as-list}))) + :interactions interactions-as-list + :entities entities}))) (defn do-dialogue [entities & pairs] @@ -314,19 +317,6 @@ (actions/talk entities :ego (str "It's the coolest sword I've ever seen!")) (actions/walk-to entities :ego [290 66]) (actions/talk entities :ego "Maybe I can pull it out."))} - :sheep {:box [38 160 71 181] - :script (actions/get-script - entities - (if ((get-in @entities [:state :inventory]) :wool) - (actions/talk entities :ego "The sheep has given me enough wool.") - (do (actions/give entities :wool) - (actions/talk entities :ego "I guess her wool is shedding.")))) - :scripts {:wool (actions/get-script entities - (actions/talk entities :ego "She doesn't need it back.")) - :carrot (actions/get-script entities - (actions/walk-to entities :ego [132 140]) - (actions/talk entities :ego "Come on girl, get the carrot!") - (actions/walk-straight-to entities :sheep [100 150]))}} :right-dir {:box [300 131 320 224] :script (actions/get-script entities @@ -351,7 +341,20 @@ (assoc (texture "overdirt.png") :x 0 :y 0 :baseline 240) (assoc (texture "background-trees.png") :x 0 :y 0 :baseline 44)] :entities {:sheep (actions/start-animation screen - (assoc (animation->texture screen sheep) :x 38 :y 160 :baseline 160) + (assoc (animation->texture screen sheep) :x 38 :y 160 :baseline 160 + :box [38 160 71 181] + :script (actions/get-script + entities + (if ((get-in @entities [:state :inventory]) :wool) + (actions/talk entities :ego "The sheep has given me enough wool.") + (do (actions/give entities :wool) + (actions/talk entities :ego "I guess her wool is shedding.")))) + :scripts {:wool (actions/get-script entities + (actions/talk entities :ego "She doesn't need it back.")) + :carrot (actions/get-script entities + (actions/walk-to entities :ego [132 140]) + (actions/talk entities :ego "Come on girl, get the carrot!") + (actions/walk-straight-to entities :sheep [100 150]))}) sheep)} :collision "outsidehouse/collision.png" :scale-fn (scaler-fn-with-baseline 110 0.10 1.00)) @@ -504,7 +507,7 @@ (when (get-in entities [:state :active?]) (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})] (if-let [mouse-override (find-override screen entities [x y])] - (assoc-in entities [:cursor :override] (cursor-override mouse-override)) + (assoc-in entities [:cursor :override] (:cursor mouse-override)) (assoc-in entities [:cursor :override] nil))))) :on-touch-down (fn [screen [entities]]