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 {})