216 lines
10 KiB
Clojure
216 lines
10 KiB
Clojure
(ns advent.screens.inventory
|
|
(:require [play-clj.core :refer :all]
|
|
[play-clj.ui :refer :all]
|
|
[play-clj.utils :refer :all]
|
|
[play-clj.g2d :refer :all]
|
|
[clojure.tools.logging :as log]
|
|
|
|
[advent.pathfind]
|
|
[advent.actions :as actions]
|
|
[advent.zone :as zone]
|
|
[advent.tween :as tween]
|
|
[advent.utils :as utils])
|
|
(:import [com.badlogic.gdx.graphics Pixmap Pixmap$Filter Texture Texture$TextureFilter]
|
|
[com.badlogic.gdx.graphics.g2d TextureRegion]
|
|
[com.badlogic.gdx.utils.viewport FitViewport]
|
|
[com.badlogic.gdx.utils Align]
|
|
[com.badlogic.gdx Application Audio Files Game Gdx Graphics Input
|
|
InputMultiplexer InputProcessor Net Preferences Screen]))
|
|
(println "loading " *ns*)
|
|
|
|
(defn interactable? [entities]
|
|
(and (:shown? entities) (= 1.0 (:opacity entities))))
|
|
|
|
|
|
(defn close [screen {:keys [selected-item] :as entities} script-started? dragged-out?]
|
|
(log/info "closing inventory")
|
|
(screen! @(resolve 'advent.screens.scene/scene) :on-reactivate { :came-from-inventory? dragged-out?})
|
|
(screen! @(resolve 'advent.screens.scene/hud) :on-reactivate { :script-started? script-started? :item selected-item})
|
|
(-> entities
|
|
(assoc-in [:tweens :fade-out] (tween/tween :fade-out screen [:opacity] 1.0 0.0 0.2 :ease tween/ease-out-cubic
|
|
:finish #(assoc % :shown? false :hovered-item nil :selected-item nil)))))
|
|
|
|
(defn mouse-down [screen entities options]
|
|
(when (interactable? entities)
|
|
(let [[x y] (utils/unproject screen options)
|
|
selected-entity (first (filter #((:box %) x y) (vals (:items entities))))]
|
|
(assoc entities :selected-item (:item selected-entity)
|
|
:down-time (:total-time screen)))))
|
|
|
|
(defn mouse-outside-inventory? [[x y]]
|
|
(or (< x 140)
|
|
(> x 1140)
|
|
(< y 320)
|
|
(> y 880)))
|
|
|
|
(defn mouse-drag [screen {:keys [selected-item] :as entities} options]
|
|
(when (interactable? entities)
|
|
(let [[x y] (utils/unproject screen options)
|
|
hovered-entity (first (filter #((:box %) x y) (vals (:items entities))))]
|
|
(cond
|
|
(and selected-item (mouse-outside-inventory? [x y]))
|
|
(close screen entities false true)
|
|
|
|
selected-item
|
|
(-> entities
|
|
(assoc-in [:items selected-item :x] x)
|
|
(assoc-in [:items selected-item :y] y)
|
|
(assoc :dragged? true)
|
|
(assoc :hovered-item (:item hovered-entity)))
|
|
:else
|
|
(assoc entities :hovered-item (:item hovered-entity) :dragged? true)))))
|
|
|
|
|
|
(defn mouse-move [screen entities options]
|
|
(let [[x y] (utils/unproject screen options)
|
|
hovered-entity (first (filter #((:box %) x y) (vals (:items entities))))]
|
|
(assoc entities :hovered-item (:item hovered-entity))))
|
|
|
|
(defn left-click [screen {:keys [selected-item hovered-item dragged?] :as entities} options]
|
|
(let [room-entities (-> @(resolve 'advent.screens.scene/scene)
|
|
:entities
|
|
deref)]
|
|
|
|
(log/info "chose inventory item" selected-item)
|
|
(println selected-item hovered-item dragged?)
|
|
(cond (not selected-item)
|
|
(close screen entities false false)
|
|
|
|
(and
|
|
(> (- (:total-time screen) (:down-time entities)) 0.5)
|
|
(= selected-item hovered-item)
|
|
dragged?)
|
|
(dissoc entities :selected-item :hovered-item :dragged?)
|
|
|
|
(and (or (not hovered-item) (= selected-item hovered-item)))
|
|
(do (screen! @(resolve 'advent.screens.scene/scene) :on-chose-item { :item selected-item})
|
|
(close screen entities false false))
|
|
:else
|
|
(when-let [interaction-script (or ((or (:scripts selected-item) (constantly nil)) (:value hovered-item))
|
|
(actions/get-script entities (actions/talk entities :ego "I'm not sure how those go together.")))]
|
|
(interaction-script room-entities)
|
|
(close screen entities true false)))))
|
|
|
|
(defn right-click [screen {:keys [selected-item] :as entities} options]
|
|
(let [
|
|
room-entities (-> @(resolve 'advent.screens.scene/scene)
|
|
:entities
|
|
deref
|
|
)
|
|
ego (get-in room-entities [:room :entities :ego])]
|
|
(when selected-item
|
|
(((:get-script ego) selected-item [0 0]) room-entities)
|
|
(close screen entities true false))))
|
|
|
|
(defn update-hovered-text [screen {:keys [hovered-text hovered-item selected-item] :as entities}]
|
|
(cond
|
|
(and hovered-item selected-item (not= hovered-item selected-item))
|
|
(label! (:hovered-text entities) :set-text (str "Use " (:name selected-item) " with " (:name hovered-item)))
|
|
|
|
hovered-item
|
|
(label! (:hovered-text entities) :set-text (:name hovered-item))
|
|
|
|
:else
|
|
(label! (:hovered-text entities) :set-text "")))
|
|
|
|
(defscreen inventory-screen
|
|
:on-show
|
|
(fn [screen entities options]
|
|
(let [[screen atlas] (utils/acquire-atlas screen "packed/global.atlas")
|
|
screen (utils/setup-viewport screen 1280 960)
|
|
hovered-text (assoc (label "" (style :label (utils/get-font "ego/font.fnt") (color :white)) :set-font-scale 0.25) :x 0 :y 850 :width 1280 )]
|
|
(label! hovered-text :set-alignment Align/bottom)
|
|
(utils/add-actor-to-stage screen hovered-text)
|
|
{:overlay (assoc (utils/atlas->texture atlas "inventory-overlay" ) :x 0 :y 0 :scale-x 4 :scale-y 4 :origin-x 0 :origin-y 0 :opacity 0.0)
|
|
:fade (assoc (utils/atlas->texture atlas "black.png")
|
|
:scale-x 80
|
|
:scale-y 80
|
|
:opacity 0.7
|
|
:origin-x 0
|
|
:origin-y 0)
|
|
:all-items (texture! (texture (pixmap "cursor.png")) :split 18 16)
|
|
:items []
|
|
:shown? false
|
|
:hovered-item nil
|
|
:opacity 0.0
|
|
:tweens {}
|
|
:hovered-text hovered-text}))
|
|
|
|
:on-render
|
|
(fn [{:keys [^FitViewport viewport] :as screen} {:keys [shown? tweens] :as entities} options]
|
|
|
|
(.apply viewport)
|
|
(let [entities (utils/apply-tweens screen entities tweens)
|
|
opacity (get-in entities [:opacity])
|
|
entities (-> entities
|
|
(assoc-in [:overlay :opacity] opacity)
|
|
(assoc-in [:fade :opacity] (* 0.6 opacity))
|
|
(assoc-in [:hovered-text :opacity] opacity)
|
|
(update-in [:items] (fn [items]
|
|
(reduce-kv (fn [c k i]
|
|
(assoc c k (assoc i :opacity opacity)))
|
|
|
|
items items))))]
|
|
|
|
(when shown?
|
|
(doto (:hovered-text entities)
|
|
(label! :set-color (color 1 1 1 opacity)))
|
|
(render! screen [(:fade entities) (:overlay entities)])
|
|
(render! screen (vals (:items entities)))
|
|
(render! screen [(get-in entities [:items (:selected-item entities)])])
|
|
(update-hovered-text screen entities)
|
|
|
|
(render! screen [(:hovered-text entities)]))
|
|
entities))
|
|
|
|
:show-screen (fn [screen entities {:keys [items]}]
|
|
(log/info "showing inventory")
|
|
(when-not (:shown? entities)
|
|
|
|
(label! (entities :hovered-text) :set-text "")
|
|
(-> entities
|
|
(assoc-in [:hovered-text :text] "")
|
|
(assoc :shown? true
|
|
:opacity 0.0
|
|
:items (into {} (for [[item index] (map vector items (range))
|
|
:let [row (int (/ index (Math/floor (/ 8 utils/ui-scale))))
|
|
column (mod index (Math/floor (/ 8 utils/ui-scale)))
|
|
base-x (* 79 4)
|
|
base-y (* 180 4)
|
|
item-width (* utils/ui-scale 4 18)
|
|
padding (/ item-width 4)
|
|
item-height (* utils/ui-scale 4 16)
|
|
padding-height (/ item-height 4)
|
|
x (+ base-x (* column (+ padding item-width)))
|
|
y (- base-y (* row (+ padding item-width)))
|
|
offset-x (+ x (/ item-width 2))
|
|
offset-y (+ y (/ item-width 2))
|
|
padded-width (/ (+ item-width padding padding) 2)
|
|
padded-height (/ (+ item-height padding-height padding-height) 2)
|
|
#_#_padding (* 4 padding)]]
|
|
[item (assoc (texture (aget (:all-items entities) 0 (.indexOf utils/+all-cursors+ (:cursor item))))
|
|
:x (+ x (/ padding 2)) :y y
|
|
:scale-x (* utils/ui-scale 4)
|
|
:scale-y (* utils/ui-scale 4)
|
|
:origin-x 9
|
|
:origin-y 8
|
|
:item item
|
|
:box (zone/box (- x padded-width) (- y padded-height) (+ x padded-width) (+ y padded-height)))])))
|
|
(assoc-in [:tweens :fade-in] (tween/tween :fade-in screen [:opacity] 0.0 1.0 0.2 :ease tween/ease-out-cubic)))))
|
|
|
|
:on-mouse-moved mouse-move
|
|
:on-touch-dragged mouse-drag
|
|
:on-touch-down mouse-down
|
|
|
|
:on-touch-up (fn [screen entities options]
|
|
(when (interactable? entities)
|
|
(if (= (button-code :left) (:button options))
|
|
(left-click screen entities options)
|
|
(right-click screen entities options))))
|
|
|
|
:on-resize (fn [{:keys [^FitViewport viewport] :as screen} entities {:keys [width height]}]
|
|
(.update viewport width height true))
|
|
:on-hide (fn [screen entities options]
|
|
(utils/release-resources screen)))
|
|
|