001  (ns walkmap.microworld
002    "An interface between walkmap and microworld, to allow use of microworld
003    functionality to model things like rainfall, soil fertility, settlement
004    and so on."
005    (:require [clojure.edn :as edn :only [read]]
006              [clojure.java.io :as io]
007              [clojure.string :as s]
008              [mw-cli.core :refer [process]]
009              [mw-engine.core :refer [run-world]]
010              [mw-engine.heightmap :as h]
011              [mw-engine.drainage :as d]
012              [mw-parser.bulk :as parser]
013              [taoensso.timbre :as l]
014              [walkmap.edge :as e]
015              [walkmap.polygon :as p :only [check-polygon polygon? rectangle]]
016              [walkmap.superstructure :refer [store]]
017              [walkmap.tag :as t :only [tag tags]]
018              [walkmap.utils :as u :only [check-kind-type check-kind-type-seq kind-type truncate]]
019              [walkmap.vertex :as v :only [vertex vertex?]]))
020  
021  ;; (def settlement-rules (parser/compile-file "resources/rules/settlement_rules.txt"))
022  
023  ;; (def w0 (h/apply-heightmap "../the-great-game/resources/maps/heightmap.png"))
024  ;; (def w1 (d/rain-world (d/flood-hollows w0)))
025  ;; (def w2 (drainage/flow-world-nr w1))
026  
027  ;; (def w3 (run-world w2 nil settlement-rules 100))
028  
029  ;; (with-open [w (clojure.java.io/writer "settlement_1.edn")]
030  ;;   (binding [*out* w]
031  ;;     (pr
032  ;;       (run-world w0 nil settlement-rules 100))))
033  
034  ;; (process
035  ;;   (h/apply-heightmap "resources/small_hill.png")
036  ;;   (parser/compile-file "resources/rules/settlement_rules.txt")
037  ;;   100
038  ;;   "small_hill.edn"
039  ;;   "small_hill.html")
040  
041  (defn cell->polygon
042    ([cell]
043     (cell->polygon cell (v/vertex 1 1 1)))
044    ([cell scale-vector]
045     (t/tag
046       (assoc
047         (merge
048           cell
049           (let [w (* (:x cell) (:x scale-vector))
050                 s (* (:y cell) (:y scale-vector))
051                 e (+ w (:x scale-vector))
052                 n (+ s (:y scale-vector))
053                 z (* (:altitude cell) (:z scale-vector))]
054           (p/rectangle
055             (v/vertex s w z)
056             (v/vertex n e z))))
057         :walkmap.id/id
058         (keyword (gensym "mw-cell")))
059       (:state cell))))
060  
061  (defn load-microworld-edn
062    "While it would be possible to call MicroWorld functions directly from
063    Walkmap, the fact is that running MicroWorld is so phenomenally
064    compute-heavy that it's much more sensible to do it in batch mode. So the
065    better plan is to be able to pull the output from MicroWorld - as an EDN
066    structure - into a walkmap superstructure."
067    ([filename]
068     (load-microworld-edn filename :mw))
069    ([filename map-kind]
070     (when-not
071       (keyword? map-kind)
072       (throw (IllegalArgumentException.
073                (u/truncate
074                  (str "Must be a keyword: " (or map-kind "nil")) 80))))
075     (load-microworld-edn filename map-kind nil))
076    ([filename mapkind superstucture]
077     (load-microworld-edn filename mapkind superstucture (v/vertex 1 1 1)))
078    ([filename map-kind superstructure scale-vertex]
079     (let [mw (try
080                (with-open [r (io/reader filename)]
081                  (edn/read (java.io.PushbackReader. r)))
082                (catch RuntimeException e
083                  (l/error "Error parsing edn file '%s': %s\n"
084                           filename (.getMessage e))))
085           polys (reduce
086                   concat
087                   (map (fn [row] (map cell->polygon row)) mw))]
088       (if (map? superstructure)
089         (reduce
090           #(store %2 %1)
091           superstructure
092           polys)
093         polys))))
094  
095  ;; (load-microworld-edn "../MicroWorld/mw-cli/isle_of_man.edn" nil {})