001  (ns cc.journeyman.the-great-game.buildings.module
002  
003    "A module of a building; essentially something like a portacabin, which can be
004     assembled together with other modules to make a complete building.
005   
006     Modules need to include
007  
008     1. Ground floor modules, having external doors;
009     2. Craft modules -- workshops -- which will normally be ground floor (except
010        weavers) and may have the constraint that no upper floor module can cover them;
011     3. Upper floor modules, having NO external doors (but linking internal doors);
012     4. Roof modules
013     
014     **Role** must be one of:
015     
016     1. `:primary` a ground floor main entrance module
017     2. `:secondary` a module which can be upper or ground floor
018     3. `:upper` a module which can only be on an upper floor, for example one
019        with a projecting gallery, balcony or overhang.
020     
021     Other values for `role` will emerge.
022     
023     **Exits** must be a sequence of keywords taken from the following list:
024     
025     1. `:left` an exit in the centre of the left wall
026     2. `:left-front` an exit in the centre of the left half of the front wall
027     3. `:front` an exit in the centre of the front wall
028     4. `:right-front` an exit in the centre of the right half of the front wall
029     5. `:right` an exit in the centre of the right wall
030     6. `:right-back` an exit in the centre of the right half of the back wall
031     7. `:left-back` an exit in the centre of the back wall
032        
033     A module placed on an upper floor must have no exit which opens beyond the 
034     footprint of the floor below - no doors into mid air! However, it is allowable 
035     (and indeed is necessary) to allow doors into roof spaces if the adjacent
036     module on the same floor does not yet exist, since otherwise it would be 
037     impossible to access a new room which might later be built there.
038     
039     **Load** must be a small integer indicating both the weight of the module and 
040     the total amount of weight it can support. So for example a stone-built module
041     might have a `load` value of 4, a brick built one of 3, and a half-timbered one 
042     of 2, and a tent of 0. This means a stone ground floor module could support one 
043     further floor of stone or brick, or two further floors of half timbered 
044     construction; while a brick built ground floor could support a single brick or 
045     half-timbered upper floor but not a stone one, and a half-timbered ground floor
046     could only support a half timbered upper floor.
047     
048     There also needs to be an undercroft or platform module, such that the area of 
049     the top of the platform is identical with the footprint of the building, and 
050     the altitude of the top of the platform is equal to the altitude of the 
051     terrain at the heighest corner of the building; so that the actual 
052     building doesn't float in the air, and also so that none of the doors or windows
053     are partly underground.
054  
055     Each module needs to wrap an actual 3d model created in Blender or whatever, 
056     and have a list of optional **textures** with which that model can be rendered. 
057     So an upper floor bedroom module might have the following renders:
058  
059     1. Bare masonry - constrained to upland or plateau terrain, and to coastal culture
060     2. Painted masonry - constrained to upland or plateau terrain, and to coastal culture
061     3. Half-timbered - not available on plateau terrain
062     4. Weatherboarded - constrained to forest terrain
063     5. Brick - constrained to arable or arid terrain
064  
065     of course these are only examples, and also, it's entirely possible to have
066     for example multiple different weatherboard renders for the same module. 
067     There needs to be a way of rendering what can be built above what: for
068     example, you can't have a masonry clad module over a half timbered one, 
069     but you can have a half-timbered one over a masonry one.")
070  
071  (defrecord BuildingModule
072    [model
073     ^Double length
074     ^Double width
075     ^Double height
076     ^Integer load 
077     ^clojure.lang.Keyword role
078     ^clojure.lang.IPersistentCollection textures
079     ^clojure.lang.IPersistentCollection exits
080     ]
081    )