001  (ns cc.journeyman.the-great-game.buildings.rectangular
                
                002    "Build buildings with a generally rectangular floow plan.
                
                003     
                
                004     ## Motivations
                
                005     
                
                006     Right, the idea behind this namespace is many fold.
                
                007  
                
                008     1. To establish the broad principle of genetic buildings, by creating a
                
                009        function which reproducibly creates reproducible buildings at specified
                
                010        locations, such that different buildings are credibly varied but a
                
                011        building at a specified location is always (modulo economic change) the
                
                012        same.
                
                013     2. Create good rectangular buildings, and investigate whether a single 
                
                014        function can be used to create buildings of more than one family (e.g.
                
                015        can it produce flat roofed, north African style, mud brick houses as
                
                016        well as pitch roofed, half timbered northern European houses?)
                
                017     3. Establish whether, in my current state of fairly severe mental illness,
                
                018        I can actually produce any usable code at all.
                
                019  
                
                020     ## Key factors in the creation of a building
                
                021  
                
                022     ### Holding
                
                023  
                
                024     Every building is on a holding, and, indeed, what I mean by 'building' here
                
                025     may well turn out to be 'the collection of all the permanent structures on
                
                026     a holding. A holding is a polygonal area of the map which does not 
                
                027     intersect with any other holding, but for the time being we'll make the 
                
                028     simplifying assumption that every holding is a rectangular strip, and that
                
                029     'urban' holdings are of a reasonably standard width (see Viking-period 
                
                030     York) and length. Rural holdings (farms, ?wood lots) may be much larger.
                
                031  
                
                032     ### Terrain
                
                033  
                
                034     A building is made of the stuff of the place. In a forest, buildings will 
                
                035     tend to be wooden; in a terrain with rocky outcrops -- normally found on 
                
                036     steep slopes -- stone. On the flat lands where there's river mud, of brick,
                
                037     cob, or wattle and daub. So to build a building we need to know the 
                
                038     terrain. Terrain can be inferred from location but in practice this will 
                
                039     be computationally expensive, so we'll pass terrain in as an argument to
                
                040     the build function.
                
                041  
                
                042     For the time being we'll pass it in simply as a keyword from a defined set
                
                043     of keywords; later it may be a more sophisticated data structure.
                
                044  
                
                045     ### Culture
                
                046  
                
                047     People of different cultures build distinctively different buildings, even
                
                048     when using the same materials. So, in our world, a Japanese wooden house 
                
                049     looks quite different from an Anglo Saxon stave house which looks quite 
                
                050     different from a Canadian log cabin, even though the materials are much the
                
                051     same and the tools available to build with are not much different.
                
                052  
                
                053     Culture can affect not just the overall shape of a building but also its 
                
                054     finish and surface detail. For example, in many places in England, stone
                
                055     buildings are typically left bare; in rural Scotland, typically painted 
                
                056     white or in pastel shades; in Ireland, often quite vivid colours.
                
                057  
                
                058     People may also show religious or cultural symbols on their buildings.
                
                059   
                
                060     For all these reasons, we need to know the culture of the occupant when
                
                061     creating a building. Again, this will initially be passed in as a keyword.
                
                062  
                
                063     ### Craft
                
                064  
                
                065     People in the game world have a craft, and some crafts will require 
                
                066     different features in the building. In the broadly late-bronze-age-to
                
                067     medieval period within which the game is set, residence and  workplace
                
                068     are for most people pretty much the same.
                
                069  
                
                070     So a baker needs an oven, a smith a forge, and so on. All crafts who do
                
                071     some degree retail trade will want a shop front as part of the ground 
                
                072     floor of their dwelling. Merchants and bankers will probably have houses
                
                073     that are a bit more showy than others.
                
                074  
                
                075     Whether the 'genetic buildings' idea will ever really produce suitable
                
                076     buildings for aristons I don't know; it seems more likely that significant
                
                077     strongholds (of which there will be relatively few) should all be hand
                
                078     modelled rather than procedurally generated."
                
                079    (:require [cc.journeyman.the-great-game.holdings.holding :refer [ProtoHolding]]
                
                080              [cc.journeyman.the-great-game.location.location :refer [ProtoLocation]])
                
                081    (:import [org.apache.commons.math3.random MersenneTwister]))
                
                082  
                
                083   
                
                084  (def ^:dynamic *terrain-types* 
                
                085    "Types of terrain which affect building families. TODO: This is a placeholder;
                
                086     a more sophisticated model will be needed."
                
                087    #{:arable :arid :forest :plateau :upland})
                
                088  
                
                089  (def ^:dynamic *cultures*
                
                090    "Cultures which affect building families. TODO: placeholder"
                
                091    #{:ariston :coastal :steppe-clans :western-clans :wild-herd})
                
                092  
                
                093  (def ^:dynamic *crafts*
                
                094    "Crafts which affect building types in the game. See 
                
                095     `Populating a game world`. TODO: placeholder"
                
                096    #{:baker :banker :butcher :chancellor :innkeeper :lawyer :magus :merchant :miller :priest :scholar :smith :weaver})
                
                097  
                
                098  (def ^:dynamic *building-families* 
                
                099    "Families of buildings.
                
                100     
                
                101     Each family has
                
                102     
                
                103     * terrain types to which it is appropriate;
                
                104     * crafts to which it is appropriate;
                
                105     * cultures to which it is appropriate. 
                
                106     
                
                107     Each generated building will be of one family, and will comprise modules 
                
                108     taken only from that family."
                
                109    {:pitched-rectangular {:terrains #{:arable :forest :upland}
                
                110                           :crafts *crafts*
                
                111                           :cultures #{:coastal :western-clans}
                
                112                           :modules []}
                
                113     :flatroof-rectangular {:terrains #{:arid :plateau}
                
                114                            :crafts *crafts*
                
                115                            :cultures #{:coastal}
                
                116                            :modules []}})
                
                117  
                
                118  ;; TODO: So, modules need to contain
                
                119  ;;
                
                120  ;; 1. Ground floor modules, having external doors;
                
                121  ;; 2. Craft modules -- workshops -- which will normally be ground floor (except
                
                122  ;; weavers) and may have the constraint that no upper floor module can cover them;
                
                123  ;; 3. Upper floor modules, having NO external doors (but linking internal doors);
                
                124  ;; 4. Roof modules
                
                125  ;; 
                
                126  ;; There also needs to be an undercroft or platform module, such that the area of 
                
                127  ;; the top of the platform is identical with the footprint of the building, and 
                
                128  ;; the altitude of the top of the platform is equal to the altitude of the 
                
                129  ;; terrain at the heighest corner of the building; so that the actual 
                
                130  ;; building doesn't float in the air, and also so that none of the doors or windows
                
                131  ;; are partly underground.
                
                132  ;;
                
                133  ;; Each module needs to wrap an actual 3d model created in Blender or whatever, 
                
                134  ;; and have a list of optional textures with which that model can be rendered. 
                
                135  ;; So an upper floor bedroom module might have the following renders:
                
                136  ;;
                
                137  ;; 1. Bare masonry - constrained to upland or plateau terrain, and to coastal culture
                
                138  ;; 2. Painted masonry - constrained to upland or plateau terrain, and to coastal culture
                
                139  ;; 3. Half-timbered - not available on plateau terrain
                
                140  ;; 4. Weatherboarded - constrained to forest terrain
                
                141  ;; 5. Brick - constrained to arable or arid terrain
                
                142  ;;
                
                143  ;; of course these are only examples, and also, it's entirely possible to have
                
                144  ;; for example multiple different weatherboard renders for the same module. 
                
                145  ;; There needs to be a way of rendering what can be built above what: for
                
                146  ;; example, you can't have a masonry clad module over a half timbered one, 
                
                147  ;; but you can have a half-timbered one over a masonry one
                
                148  
                
                149  (defn building-family
                
                150    "A building family is essentially a collection of models of building modules
                
                151     which can be assembled to create buildings of a particular structural and
                
                152     architectural style."
                
                153    [terrain culture craft gene]
                
                154    (let [candidates (filter #(and
                
                155                               ((:terrains %) terrain)
                
                156                               ((:crafts %) craft)
                
                157                               ((:cultures %) culture))
                
                158                             (vals *building-families*))]
                
                159      (nth candidates (mod (Math/abs (.nextInt gene)) (count candidates)))))
                
                160  
                
                161  (building-family :arable :coastal :baker (MersenneTwister. 5))
                
                162  
                
                163  (defn build! 
                
                164    "Builds a building, and returns a data structure which represents it. In 
                
                165     building the building, it adds a model of the building to the representation
                
                166     of the world, so it does have a side effect."
                
                167    [holding terrain culture craft size]
                
                168    (if (satisfies? ProtoHolding holding)
                
                169    (let [location (.building-origin holding)
                
                170          gene (MersenneTwister. (int (+ (* (.easting location) 1000000) (.northing location))))
                
                171          family (building-family terrain culture craft gene)]
                
                172    (if 
                
                173     (and (instance? ProtoLocation location) (:orientation location))
                
                174      :stuff
                
                175      :nonsense
                
                176      ))
                
                177      :froboz))
                
                178  
                
                179  ;; (def ol (cc.journeyman.the-great-game.location.location/OrientedLocation. 123.45 543.76 12.34 0.00 {}))
                
                180