Merge branch 'develop' into seedwatch

develop
Su 2021-01-29 11:34:57 +00:00 committed by GitHub
commit 545fcf6745
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 716 additions and 184 deletions

@ -34,6 +34,7 @@ tinythread_ Zlib \(c\) 2010, Marcus Geelnard
tinyxml_ Zlib \(c\) 2000-2006, Lee Thomason
UTF-8-decoder_ MIT \(c\) 2008-2010, Bjoern Hoehrmann
xlsxio_ MIT \(c\) 2016-2020, Brecht Sanders
alt-getopt_ MIT \(c\) 2009 Aleksey Cheusov
=============== ============= =================================================
.. _DFHack: https://github.com/DFHack/dfhack
@ -52,6 +53,7 @@ xlsxio_ MIT \(c\) 2016-2020, Brecht Sanders
.. _tinyxml: http://www.sourceforge.net/projects/tinyxml
.. _UTF-8-decoder: http://bjoern.hoehrmann.de/utf-8/decoder/dfa
.. _xlsxio: https://github.com/brechtsanders/xlsxio
.. _alt-getopt: https://github.com/LuaDist/alt-getopt
.. _CC-BY-SA: http://creativecommons.org/licenses/by/3.0/deed.en_US

@ -11,7 +11,7 @@ It can be difficult applying a set of blueprints that you did not write yourself
- The suites level has fancy rooms for your nobles.
- The apartments level(s) has small but well-furnished bedrooms for your other dwarves.
""
"Run each level's ""help"" blueprint (e.g. /surface_help) for more details."
"Run each level's ""help"" blueprint (e.g. /surface_help) for more details, or run /checklist for a list of all commands you need to run, in order."
""
"Dreamfort has a central staircase-based design. For all Dreamfort levels, place the cursor on the center staircase tile when you apply the blueprints. The first surface blueprint will designate a column of staircases that you can use as a guide."
""
@ -25,6 +25,50 @@ It can be difficult applying a set of blueprints that you did not write yourself
You are welcome to copy those spreadsheets and make your own modifications!
"#dreamfort.csv is generated with the following command:
for fname in dreamfort*.xlsx; do xlsx2csv -a -p '' $fname; done | sed 's/,*$//'"
#notes label(checklist)
Here is the recommended order for Dreamfort commands. See walkthroughs for details.
""
-- Find a good starting spot on the surface --
quickfort run library/dreamfort.csv -n /surface4
quickfort undo library/dreamfort.csv -n /surface4
""
"-- Surface, industry, and farming --"
quickfort run library/dreamfort.csv -n /surface1
quickfort run library/dreamfort.csv -n /industry1
quickfort run library/dreamfort.csv -n /surface2
quickfort orders library/dreamfort.csv -n /industry2
quickfort orders library/dreamfort.csv -n /farming2
quickfort orders library/dreamfort.csv -n /surface4
quickfort orders library/dreamfort.csv -n /surface5
quickfort orders library/dreamfort.csv -n /surface6
quickfort run library/dreamfort.csv -n /surface3
quickfort run library/dreamfort.csv -n /industry2
quickfort run library/dreamfort.csv -n /farming1
quickfort run library/dreamfort.csv -n /surface4
quickfort run library/dreamfort.csv -n /farming2
quickfort run library/dreamfort.csv -n /farming3
orders import automation
quickfort run library/dreamfort.csv -n /surface5
quickfort run library/dreamfort.csv -n /surface6
""
-- Everything else --
quickfort orders library/dreamfort.csv -n /services2
quickfort orders library/dreamfort.csv -n /guildhall2
quickfort orders library/dreamfort.csv -n /suites2
quickfort run library/dreamfort.csv -n /services1
quickfort run library/dreamfort.csv -n /services2
quickfort run library/dreamfort.csv -n /services3
quickfort run library/dreamfort.csv -n /guildhall1
quickfort run library/dreamfort.csv -n /guildhall2
quickfort run library/dreamfort.csv -n /suites1
quickfort run library/dreamfort.csv -n /suites2
quickfort run library/dreamfort.csv -n /apartments1_stack
""
-- Repeat for each apartments level --
quickfort orders library/dreamfort.csv -n /apartments2
quickfort run library/dreamfort.csv -n /apartments2
quickfort run library/dreamfort.csv -n /apartments3
burial -pets
#notes label(surface_help)
"Sets up a large, protected entrance to your fort in a flat area on the surface."
""
@ -64,6 +108,7 @@ Once the area is clear of trees, continue with /surface2.) clear trees and set u
stair_guide/surface_stair_guide
clear_small/surface_clear_small
zones/surface_zones
name_zones/surface_name_zones
""
"#meta label(surface2) start(staircase center) message(This would be a good time to queue manager orders for /surface4, /surface5, and /surface6. If you want a consistent color for your walls, remember to set the rock material in the buildingplan UI and in the manager orders for blocks.
Once the whole area is clear of trees, continue with /surface3.) set up starting workshops/stockpiles and clear a larger area"
@ -89,6 +134,7 @@ query_buildings/surface_query_buildings
build_scaffolding/surface_scaffolding
#<
build_roof/surface_roof
build_roof2/surface_roof2
#dig label(surface_stair_guide) hidden() use the meta blueprints for normal application
j
#>
@ -96,29 +142,29 @@ i
#>
i
#>
i
i7
#>
i
i7
#>
i
i7
#>
i
i7
#>
i
i7
#>
i
i7
#>
i
i7
#>
i
i7
#>
i
i7
#>
i
i7
#>
i
i7
#>
i
i7
#dig label(surface_clear_small) start(23; 25) hidden() use the meta blueprints for normal application
@ -144,7 +190,7 @@ i
,,,,,,`,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,`
,,,,,,`,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,`
,,,,,,`,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,`
,,,,,,`,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,j,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,`
,,,,,,`,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,`
,,,,,,`,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,`
,,,,,,`,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,`
,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,,`,,`,`,`,`,,`,`,`,`,`,`,`,`,`,`
@ -218,7 +264,57 @@ i
#build label(surface_build_start) start(23; 25) hidden() use the meta blueprints for normal application
#query label(surface_name_zones) start(23; 25) hidden() use the meta blueprints for normal application
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,"{namezone name=""main pasture""}",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,"{namezone name=""nestbox1""}","{namezone name=""nestbox2""}","{namezone name=""nestbox3""}","{namezone name=""nestbox4""}","{namezone name=""nestbox5""}","{namezone name=""nestbox6""}","{namezone name=""nestbox7""}","{namezone name=""nestbox8""}","{namezone name=""nestbox9""}","{namezone name=""nestbox10""}","{namezone name=""nestbox11""}","{namezone name=""nestbox12""}",,,,,,,,"{namezone name=""nestbox13""}","{namezone name=""nestbox14""}","{namezone name=""nestbox15""}","{namezone name=""nestbox16""}","{namezone name=""nestbox17""}","{namezone name=""nestbox18""}","{namezone name=""nestbox19""}","{namezone name=""nestbox20""}","{namezone name=""nestbox21""}","{namezone name=""nestbox22""}","{namezone name=""nestbox23""}","{namezone name=""nestbox24""}",`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,,,,,,,,,,,,,`,"{namezone name=""guard dogs""}",,,,,`,"{namezone name=""taming area""}",,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,`,`,`,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,`,`,`,,`,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,`,`,`,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,,,,,`,,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,,`,,`,`,`,`,,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,,,,,,,,`,`,,`,`,`,`,`,`,`,`,`,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,`,`,,,,,,,,`,`
,,,,,,,,,,,,,,,,,`,`,,,,,,,,`,`
,,,,,,,,,,,,,,,,,`,`,,,,,,,,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,`,,,,,,,,`
,,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`
#build label(surface_build_start) start(23; 25) hidden() message(use autofarm to manage farm crop selection) use the meta blueprints for normal application
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
@ -331,6 +427,7 @@ i
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,"{givename name=""starting food""}",,,,"{givename name=""starting wood""}",,,,"{givename name=""starting booze""}",,,,,"{givename name=""starting stone""}",,,,"{givename name=""starting misc""}",,,,"{givename name=""starting textile""}",,,,,,,`
,,,,,,`,,,,forbidbooze,,,,,,,,booze,,,,,otherstone,,,,,,,,,,,,,,,`
,,,,,,`,,,,nocontainers,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
@ -339,11 +436,10 @@ i
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,,,,,,,,,,,,,`,,,,,,`,forbidcages,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,`,`,`,,,forbidtraps,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,`,`,`,,`,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,,,,,`,"{givename name=""prison/training area""}",,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,`,`,`,,,forbidcages,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,`,`,`,,`,forbidtraps,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,`,`,`,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,,,,,`,,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,,`,,`,`,`,`,,`,`,`,`,`,`,`,`,`,`
@ -668,7 +764,7 @@ p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,
#build label(surface_buildings) start(23; 25) hidden() message(Remember to connect the levers to the gates once they are built.) use the meta blueprints for normal application
"#build label(surface_buildings) start(23; 25) hidden() message(Remember to connect the levers to the gates once they are built. Also, you can deconstruct the temporary trade depot in the pasture now.) use the meta blueprints for normal application"
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
@ -741,29 +837,29 @@ p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,,,,,,,,,,,,,`,,,,,,`,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,"{givename name=""trade depo gate""}",,"{givename name=""inner main gate""}",,"{givename name=""barracks gate""}",`,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,`,`,`,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,`,`,`,,`,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,`,`,`,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,,,,,`,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,"{givename name=""left outer gate""}","{givename name=""left inner gate""}","{givename name=""outer main gate""}","{givename name=""right inner gate""}","{givename name=""right outer gate""}",`,,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,,`,,`,`,`,`,,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,,,,,,,,`,`,,`,`,`,`,`,`,`,`,`,`
,,,,,,`,,,,,,,,,,,,`,,,,"{givename name=""inner main gate""}",,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,"{givename name=""trade depo gate""}",,,,,,,,"{givename name=""barracks gate""}",,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,"{givename name=""left outer gate""}",,,,,,,,,,,,"{givename name=""left inner gate""}",,,,,,,,"{givename name=""right inner gate""}",,,,,,,,,,,,"{givename name=""right outer gate""}"
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,`,,,,,,,,`
,,,,,,,,,,,,,,,,,,`,,,,,,,,`
,,,,,,,,,,,,,,,,,,,,,,"{givename name=""outer main gate""}"
@ -821,6 +917,56 @@ p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,
#build label(surface_roof) start(23; 25) hidden() use the meta blueprints for normal application
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,,,,,,,,,,,,,`,,,,,,`,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,,,,,`,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,`,,,,,,`,,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,Cf,`,`,`,`,Cf,`,Cf,`,`,`,`,Cf,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,Cf,`,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,`,Cf,`,`,`,`,`,`,`,`,`,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf
,,,,,,,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf
,,,,,,,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,Cd,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,,,,,,,,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
#build label(surface_roof2) start(23; 25) hidden() use the meta blueprints for normal application
# this is split up into two blueprints to guarantee that buildingplan matches items to the lower tiles first
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
@ -846,23 +992,23 @@ p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,`,`,`,`,`,`,`,`,`,Cf,`,`,`,`,Cf,`,Cf,`,`,`,`,Cf,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,Cf,`,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,`,Cf,`,`,`,`,`,`,`,`,`,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf
,,,,,,,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf
,,,,,,,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf,Cf
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,Cd,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,,,,,,,,,,,,,`,Cf,Cf,Cf,Cf,Cf,Cf,Cf,`
,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,,`,,`,`,`,`,,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,,,,,,,,`,`,,`,`,`,`,`,`,`,`,`,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,,,,,,,,,,,,`,,,,,,,,`,,,,,,,,,,,,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,~,`,,,,,,,,`
,,,,,,,,,,,,,,,,,,`,,,,,,,,`
@ -1088,13 +1234,13 @@ query_stockpiles/farming_query_stockpiles
- if the industry level is already built, configure the jugs, pots, and bags stockpiles to take from the ""Goods"" quantum stockpile on the industry level) use the meta blueprints for normal application"
,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,,`,,`,,forbidplants,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,`,`,`,`,`,`,`,"{givename name=""seeds feeder""}",`,`,,`,,`,,forbidplants,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,forbidtallow,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,forbiddye,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,seeds,linksonly,`,`,`,`,`,`,seeds,give2left,nocontainers,`,`,`,`,,forbidunpreparedfish,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,potash,nocontainers,`,`,`,`,`,`,`,`,`,,`,`,`,,forbidmiscliquid,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,seeds,linksonly,"{givename name=""seeds""}",`,`,`,`,`,seeds,give2left,nocontainers,`,`,`,`,,forbidunpreparedfish,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,potash,nocontainers,"{givename name=""potash""}",`,`,`,`,`,`,`,`,,`,`,`,,forbidmiscliquid,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,`,,,`,,,`,,,,`,`,`,`,forbidpreparedfood,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,plants,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,plants,"{givename name=""plants""}",`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,"{givename name=""cookable food""}",`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
@ -1105,28 +1251,28 @@ query_stockpiles/farming_query_stockpiles
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,,,,`,,,,`,,,,`,`,`,,,`,,,,`
,,,,,,,,bags,nocontainers,`,`,`,`,`,pots,`,`,`,`,,`,`,`,,`,`,`,,`,`,`
,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,jugs,nocontainers,`,`,`,`,`,`,`,`,`,`,,`,,`,,`,`,`,,`,`,`
,,,,,,,,bags,nocontainers,"{givename name=""bags""}",`,`,`,`,pots,`,`,`,`,,`,`,`,,`,`,`,,`,`,`
,,,,,,,,`,`,`,`,`,`,`,"{givename name=""pots""}",`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,jugs,nocontainers,"{givename name=""jugs""}",`,`,`,`,`,`,`,`,`,,`,,`,,`,`,`,,`,`,`
,,,,,,,,,`,,,,`,,,,`,,,,`,`,`,,,`,,,,`
,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,,`,`,`,`,`,`,`,`
,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,,,`,`,`,,,,,`,,,,,`
,,,,,,,,,`,`,`,,preparedfood,`,`,`,`,`,`,,`,,`,,rawhides,`,`,`,`,,unpreparedfish,`,`,`
,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,nocontainers,`,`,`
,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,,`,`,`,`
,,,,,,,,,`,`,`,,preparedfood,"{givename name=""prepared food""}",`,`,`,`,`,,`,,`,,rawhides,`,`,`,`,,unpreparedfish,`,`,`
,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,`,`,`,"{givename name=""rawhides""}",`,`,`,`,`,nocontainers,`,`,`
,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,,"{givename name=""unprepared fish""}",`,`,`
,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,`,`,,,,,`,,,,,`
,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,`,`,,give2up,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,`,`,,give2up,"{givename name=""refuse and corpses""}",`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,`,`,,booze,`,`,`,`,`,`,,`,`,`,,forbidcraftrefuse,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,`,`,,booze,"{givename name=""booze""}",`,`,`,`,`,,`,`,`,,forbidcraftrefuse,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,,,bodyparts,linksonly,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,,,`,`,`,`,give2left,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,,,"{givename name=""trash dumper feeder""}",`,`,`,give2left,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,,,,"{quantumstopfromnorth name=""Trash Dumper""}",,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,,,,quantum,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,,,,,,,,,,,,,,,,,,,"{quantum name=""trash quantum""}",,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
#query label(farming3) start(23; 25 staircase center) message(Check to ensure the office got assigned to your manager.) configure rooms
@ -1220,7 +1366,7 @@ Industry Walkthrough:
""
"4) If you want to automatically melt goblinite and other low-quality weapons and armor, mark the south-east stockpiles for auto-melt."
""
"5) Run ""orders import automation"" to use the provided automation.json to take care of your fort's basic needs."
"5) Run ""orders import automation"" to use the provided automation.json to take care of your fort's basic needs, such as food, booze, military supplies, and raw material processing."
"#dig label(industry1) start(18; 18; staircase center) message(This would be a good time to queue manager orders for /industry2. Once the area is dug out, continue with /industry2.)"
@ -1306,7 +1452,7 @@ query/industry_query
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,e,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,c,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,se(3x3),,,`,`,`,`,`,`,`,`,`,`,`,`
,,f,`,`,`,`,`,`,`,`,`,`,`,`,`,~,~,~,`,`,`,`,`,`,`,`,`,`,`,`,`,b(1x6)
@ -1315,7 +1461,7 @@ query/industry_query
,,f,`,`,`,`,`,`,`,`,`,`,`,,,`,,`,,,`,`,`,`,`,`,`,`,`,`,`,`
,,f,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`
,,f,`,`,`,`,`,`,`,afngwS(3x3),,,`,`,`,,,,`,`,`,sbpdz(3x3),,,`,`,`,`,`,`,`,`
,,f,`,`,`,`,`,f,`,~,~,~,`,,`,,`,,`,,`,~,~,~,`,b,`,`,`,`,`,`
,,f,`,`,`,`,`,c,`,~,~,~,`,,`,,`,,`,,`,~,~,~,`,c,`,`,`,`,`,`
,,f,`,`,`,`,`,`,`,~,~,~,`,`,`,,,,`,`,`,~,~,~,`,`,`,`,`,`,`,b(1x6)
,,f,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`
,,f,`,`,`,`,`,`,`,`,`,`,`,,,`,,`,,,`,`,`,`,`,`,`,`,`,`,`,`
@ -1340,33 +1486,33 @@ query/industry_query
- now that your industry is set up, run ""orders import automation"" to automate your fort's basic needs (download automation.json from https://drive.google.com/file/d/17WcN5mK-rnADOm2B_JFpPnByYgkYjxhb/view?usp=sharing and put it in your dfhack-config/orders/ directory)"
,,,,,,,,,,,roughgems,nocontainers,`,`,`,`,t{Down 6}&,`,`,`,`,`,`
,,,,,,,,,,,roughgems,nocontainers,"{givename name=""rough gems for moods""}",`,`,`,t{Down 6}&,`,`,`,`,`,`
,,,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,{quantum}g{Up}{Left 5}&,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,"{quantumstopfromsouth name=""Stoneworker quantum""}",`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,otherstone,,,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,"{quantum name=""stoneworker quantum""}g{Up}{Left 5}&",`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,"{quantumstopfromsouth name=""Stoneworker quantum""}{givename name=""stoneworker dumper""}",`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,otherstone,,"{givename name=""stoneworker feeder""}",`,`,`,`,`,`,`,`,`,`,`,`
,,miscliquid,`,`,`,`,`,`,`,`,`,`,`,`,`,~,nocontainers,~,`,`,`,`,`,`,`,`,`,`,`,`,`,steelbars
,,nocontainers,`,`,`,`,`,`,`,`,`,`,`,`,`,~,~,~,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,nocontainers,`,`,`,`,`,`,`,`,`,`,`,`,`,~,~,~,`,`,`,`,`,`,`,`,`,`,`,`,`,"{givename name=""steel""}"
,,"{givename name=""non-quantum liquids""}",`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,,,`,,`,,,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,{cages}{permittraps},,,`,`,`,,,,`,`,`,forbidotherstone,,,`,`,`,`,`,`,`,t{Left 6}{Down}&
,,`,`,`,`,`,`,{quantum}g{Up 10}{Right 4}&,"{quantumstopfromeast name=""Goods/Wood quantum""}",~,nocontainers,~,`,,`,,`,,`,,`,~,nocontainers,~,"{quantumstopfromwest name=""Metalworker quantum""}",quantum,`,`,`,`,`,`
,,`,`,`,`,`,`,"{quantum name=""goods/wood quantum""}g{Up 10}{Right 4}&","{quantumstopfromeast name=""Goods/Wood quantum""}{givename name=""goods/wood dumper""}",~,nocontainers,"{givename name=""goods/wood feeder""}",`,,`,,`,,`,,`,"{givename name=""metalworker feeder""}",nocontainers,~,"{quantumstopfromwest name=""Metalworker quantum""}{givename name=""metalworker dumper""}","{quantum name=""metalworker quantum""}",`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,{tallow}{permitdye},,,`,`,`,,,,`,`,`,forbidpotash,,,`,`,`,`,`,`,`,t{Left 6}{Up}&
,,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,,,`,,`,,,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,craftrefuse,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,craftrefuse,,"{givename name=""cloth/bones feeder""}",`,`,`,`,`,`,`,`,`,`,`,`,`,"{givename name=""coal""}"
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,~,nocontainers,~,`,`,`,`,`,`,`,`,`,`,`,`,`,coal
,,,,`,`,`,`,`,`,`,`,`,`,`,`,~,~,~,`,`,`,`,`,nocontainers,`,t{Up 7}&,~,~,~,~
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,"{quantumstopfromnorth name=""Clothier/Bones quantum""}",`,`,`,`,`,`,{ironweapons}{permitsteelweapons}{forbidmasterworkweapons}{forbidartifactweapons}
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,quantum,`,`,`,`,`,`,{ironarmor}{permitsteelarmor},forbidmasterworkarmor,forbidartifactarmor,~,~,~,~
,,,,`,`,`,`,`,`,`,`,`,`,`,`,~,~,~,`,`,`,`,`,nocontainers,"{givename name=""meltable iron/steel""}",t{Up 7}&,~,~,~,~
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,"{quantumstopfromnorth name=""Clothier/Bones quantum""}{givename name=""cloth/bones dumper""}",`,`,`,`,`,`,{ironweapons}{permitsteelweapons}{forbidmasterworkweapons}{forbidartifactweapons}
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,"{quantum name=""cloth/bones quantum""}",`,`,`,`,`,`,{ironarmor}{permitsteelarmor},forbidmasterworkarmor,forbidartifactarmor,~,~,~,~
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,nocontainers,give2up,t{Up 11}&,~,~,~,~
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,nocontainers,give2up,t{Up 11}&,"{givename name=""meltables""}",~,~,~
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,{metalweapons}{forbidmasterworkweapons}{forbidartifactweapons}
,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,metalarmor,forbidmasterworkarmor,forbidartifactarmor,~,~,~,~
,,,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`
@ -1516,6 +1662,7 @@ Services Walkthough:
build/services_build
place/services_place
zone/services_zone
name_zones/services_name_zones
query_stockpiles/services_query_stockpiles
#build label(services_build) start(23; 22) hidden() use the meta blueprints for normal application
@ -1646,6 +1793,40 @@ query_stockpiles/services_query_stockpiles
,,`,`,`,`,`,`,,`,`,`,`,`,`
#query label(services_name_zones) start(23; 22) hidden() use the meta blueprints for normal application
,,`,`,`,,,`,`,`,,,`,`,`
,,`,`,`,,,`,`,`,,,`,`,`
,,`,`,`,,,`,`,`,,,`,`,`
,,,`,,,,,`,,,,,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`,,,,"{namezone name=""hospital""}",`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,,,,,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,"{namezone name=""bath1""}",`,`,`,`,`,`,`,`,`,"{namezone name=""bath2""}",`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,~,`,,`,`,`,`,`,,`,~,`,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,~,`,`,`,`,`,`,`,`,`,~,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,"{namezone name=""garbage dump""}",,,,,,,,`,`,`,`,`,`,`,`,`
,,,,,,`,`,,`,`,,,,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,,`,`,`,`,`,`,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,,`,`,`,`,`,`
,,`,`,`,`,`,`,,`,`,`,`,`,`
,,`,`,`,`,`,`,,`,`,`,`,`,`
,,`,`,`,`,`,`,,`,`,`,`,`,`
"#query label(services_query_stockpiles) start(23; 22) hidden() message(remember to configure the soap stockpiles to take from the ""Metalworker"" quantum stockpile on the industry level (where all bars are stored)) use the meta blueprints for normal application"
@ -1663,17 +1844,17 @@ query_stockpiles/services_query_stockpiles
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,booze,`,`,booze,`,`,booze,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,preparedfood,t{Down 10}{Left 12}&,t{Down 10}{Left 10}&,preparedfood,t{Down 10}{Left 20}&,t{Down 10}{Left 10}&,preparedfood,t{Down 10}{Left 20}&,t{Down 10}{Left 12}&,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,"{booze}{givename name=""booze""}",`,`,"{booze}{givename name=""booze""}",`,`,"{booze}{givename name=""booze""}",,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,"{preparedfood}{givename name=""prepared food""}",t{Down 10}{Left 12}&,t{Down 10}{Left 10}&,"{preparedfood}{givename name=""prepared food""}",t{Down 10}{Left 20}&,t{Down 10}{Left 10}&,"{preparedfood}{givename name=""prepared food""}",t{Down 10}{Left 20}&,t{Down 10}{Left 12}&,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,,,,,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,soap,`,`,,`,`,`,`,`,,soap,`,`,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,nocontainers,`,`,`,`,`,`,`,`,`,nocontainers,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,"{givename name=""soap1""}",`,`,,`,`,`,`,`,,"{givename name=""soap2""}",`,`,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,,,,,,,,`,`,`,`,`,`,`,`,`
,,,,,,`,`,,`,`,,,,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,preparedfood,`,`,`,`,`,,booze,`,`,`,`,`,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,preparedfood,"{givename name=""prepared food""}",`,`,`,`,,booze,"{givename name=""booze""}",`,`,`,`,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,,`,`,`,`,`,`
,,`,`,`,`,`,`,,`,`,`,`,`,`
,,`,`,`,`,`,`,,`,`,`,`,`,`
@ -1697,8 +1878,8 @@ query_stockpiles/services_query_stockpiles
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,`,r--&j,`,`,r--&j,`,`,r--&j,`,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,r{+ 11}&h,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,`,"r--&j{givename name=""jail1""}",`,`,"r--&j{givename name=""jail2""}",`,`,"r--&j{givename name=""jail3""}",`,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,"r{+ 11}&h{givename name=""grand hall""}",`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,,,,,,,`,,,,,,,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`
,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`
@ -1832,6 +2013,7 @@ Suites for nobles and apartments for the teeming masses
Features:
- Well-appointed suites to satisfy most nobles
- Apartments with beds and storage to keep dwarves happy
- Apartments also serve as burial chambers since dwarves like looking at urns
- Meta blueprint included for designating 6 levels of apartments for a full 200+ dwarves
""
Suites Walkthrough:

Can't render this file because it has a wrong number of fields in line 171.

@ -24,6 +24,7 @@ Bearskie Bearskie
belal jimhester
Ben Lubar BenLubar
Ben Rosser TC01
Benjamin Seiller bseiller RedDwarfStepper
billw2012 billw2012
BrickViking brickviking
brndd brndd burneddi

@ -716,6 +716,8 @@ to always have one or two doors/beds/tables/chairs/etc available, and place
as many as you like. The plugins then take over and fulfill the orders,
with minimal space dedicated to stockpiles.
.. _buildingplan-filters:
Item filtering
--------------
@ -723,11 +725,11 @@ While placing a building, you can set filters for what materials you want the bu
out of, what quality you want the component items to be, and whether you want the items to
be decorated.
If a building type takes more than one item to construct, use
:kbd:`Ctrl`:kbd:`Left` and :kbd:`Ctrl`:kbd:`Right` to select the item that you
want to set filters for. Any filters that you set will be used for all buildings
of the selected type from that point onward (until you set a new filter or clear
the current one).
If a building type takes more than one item to construct, use :kbd:`Ctrl`:kbd:`Left` and
:kbd:`Ctrl`:kbd:`Right` to select the item that you want to set filters for. Any filters that
you set will be used for all buildings of the selected type placed from that point onward
(until you set a new filter or clear the current one). Buildings placed before the filters
were changed will keep the filter values that were set when the building was placed.
For example, you can be sure that all your constructed walls are the same color by setting
a filter to accept only certain types of stone.
@ -745,6 +747,51 @@ Note that Quickfort mode is only for compatibility with the legacy Python Quickf
DFHack `quickfort` script does not need Quickfort mode to be enabled. The `quickfort` script
will successfully integrate with buildingplan as long as the buildingplan plugin is enabled.
.. _buildingplan-settings:
Global settings
---------------
The buildingplan plugin has several global settings that can be set from the UI (:kbd:`G`
from any building placement screen, for example: :kbd:`b`:kbd:`a`:kbd:`G`). These settings
can also be set from the ``DFHack#`` prompt once a map is loaded (or from your
``onMapLoad.init`` file) with the syntax::
buildingplan set <setting> <true|false>
and displayed with::
buildingplan set
The available settings are:
+----------------+---------+-----------+---------------------------------------+
| Setting | Default | Persisted | Description |
+================+=========+===========+=======================================+
| all_enabled | false | no | Enable planning mode for all building |
| | | | types. |
+----------------+---------+-----------+---------------------------------------+
| blocks | true | yes | Allow blocks, boulders, logs, or bars |
+----------------+---------+ | to be matched for generic "building |
| boulders | true | | material" items |
+----------------+---------+ | |
| logs | true | | |
+----------------+---------+ | |
| bars | false | | |
+----------------+---------+-----------+---------------------------------------+
| quickfort_mode | false | no | Enable compatibility mode for the |
| | | | legacy Python Quickfort (not required |
| | | | for DFHack quickfort) |
+----------------+---------+-----------+---------------------------------------+
For example, to ensure you only use blocks when a "building material" item is required, you
could add this to your ``onMapLoad.init`` file::
on-new-fortress buildingplan set boulders false; buildingplan set logs false
Persisted settings (i.e. ``blocks``, ``boulders``, ``logs``, and ``bars``) are saved with
your game, so you only need to set them to the values you want once.
.. _confirm:
confirm

@ -36,6 +36,19 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Fixes
- `embark-assistant`: fixed order of factors when calculating min temperature
- `seedwatch`: don't turn off upon map load
- `embark-assistant`: improved performance of surveying
- `quickfort`: creating zones no longer causes eventual crashes
## Misc Improvements
- `buildingplan`: set global settings from the ``DFHack#`` prompt: e.g. ``buildingplan set boulders false``
- `buildingplan`: add 'enable all' option for buildingplan (so you don't have to enable all building types individually). this setting is not persisted (just like quickfort_mode is not persisted), but it can be set from onMapLoad.init
- `buildingplan`: modified ``Planning Mode`` status in the UI to show whether we're in quickfort mode, enable all mode, or whether just the building type is enabled.
## Misc Improvements
- `quickfort`: Dreamfort blueprint set improvements: add a streamlined checklist for all required dreamfort commands and give names to stockpiles, levers, bridges, and zones
## Lua
- ``processArgsGetopt()`` added to utils.lua, providing a callback interface for parameter parsing and getopt-like flexibility for parameter ordering and combination (see docs in ``library/lua/utils.lua`` and ``library/lua/3rdparty/alt_getopt.lua`` for details).
# 0.47.04-r4
@ -1169,4 +1182,3 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- The ``ui_menu_width`` global is now a 2-byte array; the second item is the former ``ui_area_map_width`` global, which is now removed
- The former ``announcements`` global is now a field in ``d_init``
- ``world`` fields formerly beginning with ``job_`` are now fields of ``world.jobs``, e.g. ``world.job_list`` is now ``world.jobs.list``

@ -842,6 +842,8 @@ Blueprint mode Description
meta Link sequences of blueprints together
notes Display long messages, such as help text or blueprint
walkthroughs
ignore Hide a section from quickfort, useful for scratch space or
personal notes
============== ===========
.. _quickfort-meta:
@ -1000,6 +1002,14 @@ The quotes around the ``#meta`` modeline allow newlines in a single cell's text.
Each line of the ``#notes`` "blueprint", however, is in a separate cell,
allowing for much easier viewing and editing.
Ignore blueprints
`````````````````
If you don't want some data to be visible to quickfort at all, use an
``#ignore`` blueprint. All lines until the next modeline in the file or sheet
will be completely ignored. This can be useful for personal notes, scratch
space, or temporarily "commented out" blueprints.
Buildingplan integration
------------------------
@ -1009,19 +1019,22 @@ prevents a building designation from being canceled when a dwarf picks up the
job but can't find the materials.
As long as the `buildingplan` plugin is enabled, quickfort will use it to manage
construction. The buildingplan plugin also has an "enabled" setting for each
building type, but that setting only applies to the buildingplan user interface;
quickfort will use buildingplan to manage everything designated in a ``#build``
blueprint regardless of the buildingplan UI settings.
However, quickfort *does* use buildingplan's filters for each building type. For
example, you can use the buildingplan UI to set the type of stone you want your
walls made out of. Or you can specify that all buildingplan-managed tables must
be of Masterful quality. The current filter settings are saved with planned
buildings when the ``#build`` blueprint is run. This means you can set the
filters the way you want for one blueprint, run the blueprint, and then freely
change them again for the next blueprint, even if the first set of buildings
haven't been built yet.
construction. The buildingplan plugin has an `"enabled" setting
<buildingplan-settings>` for each building type, but those settings only apply
to buildings created through the buildingplan user interface. In addition,
buildingplan has a "quickfort_mode" setting for compatibility with legacy Python
Quickfort. This setting has no effect on DFHack Quickfort, which will use
buildingplan to manage everything designated in a ``#build`` blueprint
regardless of the buildingplan UI settings.
However, quickfort *does* use `buildingplan's filters <buildingplan-filters>`
for each building type. For example, you can use the buildingplan UI to set the
type of stone you want your walls made out of. Or you can specify that all
buildingplan-managed tables must be of Masterful quality. The current filter
settings are saved with planned buildings when the ``#build`` blueprint is run.
This means you can set the filters the way you want for one blueprint, run the
blueprint, and then freely change them again for the next blueprint, even if the
first set of buildings haven't been built yet.
Note that buildings are still constructed immediately if you already have the
materials. However, with buildingplan you now have the freedom to apply

@ -0,0 +1,169 @@
-- Copyright (c) 2009 Aleksey Cheusov <vle@gmx.net>
--
-- Permission is hereby granted, free of charge, to any person obtaining
-- a copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, sublicense, and/or sell copies of the Software, and to
-- permit persons to whom the Software is furnished to do so, subject to
-- the following conditions:
--
-- The above copyright notice and this permission notice shall be
-- included in all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-- based on https://github.com/LuaDist/alt-getopt/blob/master/alt_getopt.lua
-- MIT licence
-- modified to support aggregation of non-options and to call qerror instead of
-- os.exit() on error. can be used directly or via the utils.processArgs2()
-- wrapper.
-- sh_opts should be in standard getopt format: a string of letters that
-- represent options, each followed by a colon if that option takes an argument.
-- e.g.: 'ak:hv' has three flags (options with no arguments): 'a', 'h', and 'v'
-- and one option that takes an argument: 'k'.
--
-- Options passed to the module to parse can be in any of the following formats:
-- -kVALUE, -k VALUE, --key=VALUE, --key VALUE
-- -abcd is equivalent to -a -b -c -d if none of them accept arguments.
-- -abckVALUE and -abck VALUE are also acceptable (where k is the only option
-- in the string that takes a value).
local _ENV = mkmodule('3rdparty.alt_getopt')
local function get_opt_map(opts)
local i = 1
local len = #opts
local options = {}
for short_opt, accept_arg in opts:gmatch('(%w)(:?)') do
options[short_opt] = #accept_arg
end
return options
end
local function err_unknown_opt(opt)
qerror(string.format('Unknown option "-%s%s"', #opt > 1 and '-' or '', opt))
end
-- resolve aliases into their canonical forms
local function canonicalize(options, opt)
if not options[opt] then
err_unknown_opt(opt)
end
while type(options[opt]) == 'string' do
opt = options[opt]
if not options[opt] then
err_unknown_opt(opt)
end
end
if type(options[opt]) ~= 'number' then
qerror(string.format(
'Option "%s" resolves to non-number for has_arg flag', opt))
end
return opt
end
local function has_arg(options, opt)
return options[canonicalize(options, opt)] == 1
end
-- returns vectors for opts, optargs, and nonoptions
function get_ordered_opts(args, sh_opts, long_opts)
local optind, count, opts, optargs, nonoptions = 1, 1, {}, {}, {}
local options = get_opt_map(sh_opts)
for k,v in pairs(long_opts) do
options[k] = v
end
while optind <= #args do
local a = args[optind]
if a == '--' then
optind = optind + 1
elseif a:sub(1, 2) == '--' then
local pos = a:find('=', 1, true)
if pos then
local opt = a:sub(3, pos-1)
if not has_arg(options, opt) then
qerror(string.format('Bad usage of option "%s"', a))
end
opts[count] = opt
optargs[count] = a:sub(pos+1)
else
local opt = a:sub(3)
opts[count] = opt
if has_arg(options, opt) then
if i == #args then
qerror(string.format(
'Missing value for option "%s"', a))
end
optargs[count] = args[optind+1]
optind = optind + 1
end
end
count = count + 1
elseif a:sub(1, 1) == '-' then
local j
for j=2,#a do
local opt = canonicalize(options, a:sub(j, j))
if not has_arg(options, opt) then
opts[count] = opt
count = count + 1
elseif j == #a then
if optind == #args then
qerror(string.format(
'Missing value for option "-%s"', opt))
end
opts[count] = opt
optargs[count] = args[optind+1]
optind = optind + 1
count = count + 1
else
opts[count] = opt
optargs[count] = a:sub(j+1)
count = count + 1
break
end
end
else
table.insert(nonoptions, args[optind])
end
optind = optind + 1
end
for i=optind,#args do
table.insert(nonoptions, args[i])
end
return opts, optargs, nonoptions
end
-- returns a map of options to their optargs (or 1 if the option doesn't take an
-- argument), and a vector for nonoptions
function get_opts(args, sh_opts, long_opts)
local ret = {}
local opts,optargs,nonoptions = get_ordered_opts(args, sh_opts, long_opts)
for i,v in ipairs(opts) do
if optarg[i] then
ret[v] = optarg[i]
else
ret[v] = 1
end
end
return ret, nonoptions
end
return _ENV

@ -1,6 +1,7 @@
local _ENV = mkmodule('utils')
local df = df
local getopt = require('3rdparty.alt_getopt')
-- Comparator function
function compare(a,b)
@ -613,6 +614,60 @@ function processArgs(args, validArgs)
return result
end
-- processes commandline options according to optionActions and returns all
-- argument strings that are not options. Options and non-option strings can
-- appear in any order, and single-letter options that do not take arguments
-- can be combined into a single option string (e.g. '-abc' is the same as
-- '-a -b -c' if options 'a' and 'b' do not take arguments.
--
-- optionActions is a vector with elements in the following format:
-- {shortOptionName, longOptionAlias, hasArg=boolean, handler=fn}
-- shortOptionName and handler are required. If the option takes an argument,
-- it will be passed to the handler function.
-- longOptionAlias is optional.
-- hasArgument defaults to false.
--
-- example usage:
--
-- local filename = nil
-- local open_readonly = false
-- local nonoptions = processArgsGetopt(args, {
-- {'r', handler=function() open_readonly = true end},
-- {'f', 'filename', hasArg=true,
-- handler=function(optarg) filename = optarg end}
-- })
--
-- when args is {'first', '-f', 'fname', 'second'} or, equivalently,
-- {'first', '--filename', 'fname', 'second'} (note the double dash in front of
-- the long option alias), then filename will be fname and nonoptions will
-- contain {'first', 'second'}.
function processArgsGetopt(args, optionActions)
local sh_opts, long_opts = '', {}
local handlers = {}
for _,optionAction in ipairs(optionActions) do
local sh_opt,long_opt = optionAction[1], optionAction[2]
if not sh_opt or type(sh_opt) ~= 'string' or #sh_opt ~= 1 then
error('optionAction missing option letter at index 1')
end
if not optionAction.handler then
error(string.format('handler missing for option "%s"', sh_opt))
end
sh_opts = sh_opts .. sh_opt
if optionAction.hasArg then sh_opts = sh_opts .. ':' end
handlers[sh_opt] = optionAction.handler
if long_opt then
long_opts[long_opt] = sh_opt
handlers[long_opt] = optionAction.handler
end
end
local opts, optargs, nonoptions =
getopt.get_ordered_opts(args, sh_opts, long_opts)
for i,v in ipairs(opts) do
handlers[v](optargs[i])
end
return nonoptions
end
function fillTable(table1,table2)
for k,v in pairs(table2) do
table1[k] = v

@ -881,7 +881,7 @@ static void linkRooms(df::building *bld)
for (size_t i = 0; i < vec.size(); i++)
{
auto room = vec[i];
if (!room->is_room || room->z != bld->z)
if (!room->is_room || room->z != bld->z || room == bld)
continue;
df::building_extents_type *pext = getExtentTile(room->room, df::coord2d(bld->x1, bld->y1));

@ -17,7 +17,7 @@
#include "buildingplan-lib.h"
DFHACK_PLUGIN("buildingplan");
#define PLUGIN_VERSION 2.0
#define PLUGIN_VERSION "2.0"
REQUIRE_GLOBAL(ui);
REQUIRE_GLOBAL(ui_build_selector);
REQUIRE_GLOBAL(world); // used in buildingplan library
@ -27,6 +27,7 @@ REQUIRE_GLOBAL(world); // used in buildingplan library
bool show_help = false;
bool quickfort_mode = false;
bool all_enabled = false;
bool in_dummy_screen = false;
std::unordered_map<BuildingTypeKey, bool, BuildingTypeKeyHash> planmode_enabled;
@ -284,7 +285,7 @@ void ViewscreenChooseMaterial::render()
//START Viewscreen Hook
static bool is_planmode_enabled(BuildingTypeKey key)
{
return planmode_enabled[key] || quickfort_mode;
return planmode_enabled[key] || quickfort_mode || all_enabled;
}
static std::string get_item_label(const BuildingTypeKey &key, int item_idx)
@ -387,6 +388,7 @@ static void show_global_settings_dialog()
lua_newtable(L);
int ctable = lua_gettop(L);
Lua::SetField(L, quickfort_mode, ctable, "quickfort_mode");
Lua::SetField(L, all_enabled, ctable, "all_enabled");
for (auto & setting : planner.getGlobalSettings())
{
@ -629,7 +631,8 @@ struct buildingplan_place_hook : public df::viewscreen_dwarfmodest
show_help = true;
}
if (input->count(interface_key::CUSTOM_SHIFT_P))
if (!quickfort_mode && !all_enabled
&& input->count(interface_key::CUSTOM_SHIFT_P))
{
planmode_enabled[key] = !planmode_enabled[key];
if (!is_planmode_enabled(key))
@ -765,8 +768,16 @@ struct buildingplan_place_hook : public df::viewscreen_dwarfmodest
OutputString(COLOR_WHITE, x, y, "Use Shift-Keys here", true, left_margin);
}
OutputToggleString(x, y, "Planning Mode", interface_key::CUSTOM_SHIFT_P,
planmode_enabled[key], true, left_margin, COLOR_WHITE, COLOR_LIGHTRED);
OutputHotkeyString(x, y, "Planning Mode", interface_key::CUSTOM_SHIFT_P);
OutputString(COLOR_WHITE, x, y, ": ");
if (quickfort_mode)
OutputString(COLOR_YELLOW, x, y, "Quickfort", true, left_margin);
else if (all_enabled)
OutputString(COLOR_YELLOW, x, y, "All", true, left_margin);
else if (planmode_enabled[key])
OutputString(COLOR_GREEN, x, y, "On", true, left_margin);
else
OutputString(COLOR_GREY, x, y, "Off", true, left_margin);
OutputHotkeyString(x, y, "Global Settings", interface_key::CUSTOM_SHIFT_G,
true, left_margin, COLOR_WHITE, COLOR_LIGHTRED);
@ -911,25 +922,87 @@ IMPLEMENT_VMETHOD_INTERPOSE(buildingplan_query_hook, render);
IMPLEMENT_VMETHOD_INTERPOSE(buildingplan_place_hook, render);
IMPLEMENT_VMETHOD_INTERPOSE(buildingplan_room_hook, render);
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
static bool setSetting(std::string name, bool value);
static bool isTrue(std::string val)
{
val = toLower(val);
return val == "on" || val == "true" || val == "y" || val == "yes"
|| val == "1";
}
static command_result buildingplan_cmd(color_ostream &out, vector <string> & parameters)
{
if (!parameters.empty())
if (parameters.empty())
return CR_OK;
std::string cmd = toLower(parameters[0]);
if (cmd.size() >= 1 && cmd[0] == 'v')
{
if (parameters.size() == 1 && toLower(parameters[0])[0] == 'v')
out.print("buildingplan version: %s\n", PLUGIN_VERSION);
}
else if (parameters.size() >= 2 && cmd == "debug")
{
out << "Building Plan" << endl << "Version: " << PLUGIN_VERSION << endl;
show_debugging = isTrue(parameters[1]);
out.print("buildingplan debugging: %s\n",
show_debugging ? "enabled" : "disabled");
}
else if (parameters.size() == 2 && toLower(parameters[0]) == "debug")
else if (cmd == "set")
{
if (!is_enabled)
{
show_debugging = (toLower(parameters[1]) == "on");
out << "Debugging " << ((show_debugging) ? "enabled" : "disabled") << endl;
out.printerr(
"ERROR: buildingplan must be enabled before you can"
" read or set buildingplan global settings.");
return CR_FAILURE;
}
if (!DFHack::Core::getInstance().isMapLoaded())
{
out.printerr(
"ERROR: A map must be loaded before you can read or set"
"buildingplan global settings. Try adding your"
"'buildingplan set' commands to the onMapLoad.init file.\n");
return CR_FAILURE;
}
return CR_OK;
if (parameters.size() == 1)
{
// display current settings
out.print("active settings:\n");
out.print(" all_enabled = %s\n", all_enabled ? "true" : "false");
for (auto & setting : planner.getGlobalSettings())
{
out.print(" %s = %s\n", setting.first.c_str(),
setting.second ? "true" : "false");
}
DFHACK_PLUGIN_IS_ENABLED(is_enabled);
out.print(" quickfort_mode = %s\n",
quickfort_mode ? "true" : "false");
}
else if (parameters.size() == 3)
{
// set a setting
std::string setting = toLower(parameters[1]);
bool val = isTrue(parameters[2]);
if (!setSetting(setting, val))
{
out.printerr("ERROR: invalid parameter: '%s'\n",
parameters[1].c_str());
}
}
else
{
out.printerr("ERROR: invalid syntax\n");
}
}
return CR_OK;
}
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
@ -1040,14 +1113,20 @@ static void scheduleCycle() {
cycle_requested = true;
}
static void setSetting(std::string name, bool value) {
static bool setSetting(std::string name, bool value) {
if (name == "quickfort_mode")
{
debug("setting quickfort_mode %d -> %d", quickfort_mode, value);
quickfort_mode = value;
return;
return true;
}
if (name == "all_enabled")
{
debug("setting all_enabled %d -> %d", all_enabled, value);
all_enabled = value;
return true;
}
planner.setGlobalSetting(name, value);
return planner.setGlobalSetting(name, value);
}
DFHACK_PLUGIN_LUA_FUNCTIONS {

@ -69,23 +69,28 @@ namespace embark_assist {
Heavily_Forested
};
struct mid_level_tile {
// only contains those attributes that are being handled during incursion processing
struct mid_level_tile_incursion_base {
uint8_t aquifer = Clear_Aquifer_Bits;
bool clay = false;
bool sand = false;
int8_t soil_depth;
int16_t elevation;
int8_t biome_offset;
tree_levels trees;
uint8_t savagery_level; // 0 - 2
uint8_t evilness_level; // 0 - 2
};
// contains all attributes (some by inheritance), used for regular survey/matching
struct mid_level_tile : public mid_level_tile_incursion_base {
bool flux = false;
bool coal = false;
int8_t soil_depth;
int8_t offset;
int16_t elevation;
river_sizes river_size = river_sizes::None;
int16_t river_elevation = 100;
int8_t adamantine_level; // -1 = none, 0 .. 3 = cavern 1 .. magma sea. Currently not used beyond present/absent.
int8_t magma_level; // -1 = none, 0 .. 3 = cavern 3 .. surface/volcano
int8_t biome_offset;
tree_levels trees;
uint8_t savagery_level; // 0 - 2
uint8_t evilness_level; // 0 - 2
std::vector<bool> metals;
std::vector<bool> economics;
std::vector<bool> minerals;
@ -141,10 +146,10 @@ namespace embark_assist {
std::vector<bool> minerals;
std::vector<int16_t> neighbors; // entity_raw indices
uint8_t necro_neighbors;
mid_level_tile north_row[16];
mid_level_tile south_row[16];
mid_level_tile west_column[16];
mid_level_tile east_column[16];
mid_level_tile_incursion_base north_row[16];
mid_level_tile_incursion_base south_row[16];
mid_level_tile_incursion_base west_column[16];
mid_level_tile_incursion_base east_column[16];
uint8_t north_corner_selection[16]; // 0 - 3. For some reason DF stores everything needed for incursion
uint8_t west_corner_selection[16]; // detection in 17:th row/colum data in the region details except
// this info, so we have to go to neighboring world tiles to fetch it.

@ -57,6 +57,12 @@ namespace embark_assist {
//===============================================================================
void embark_update() {
// not updating the embark overlay during an active find/match/survey phase
// which leads to better performance
if (state != nullptr && state->match_iterator.active) {
return;
}
auto screen = Gui::getViewscreenByType<df::viewscreen_choose_start_sitest>(0);
embark_assist::defs::mid_level_tiles mlt;
embark_assist::survey::initiate(&mlt);

@ -68,7 +68,7 @@ namespace embark_assist {
void process_embark_incursion(matcher_info *result,
embark_assist::defs::world_tile_data *survey_results,
embark_assist::defs::mid_level_tile *mlt, // Note this is a single tile, as opposed to most usages of this variable name.
embark_assist::defs::mid_level_tile_incursion_base *mlt, // Note this is a single tile, as opposed to most usages of this variable name.
embark_assist::defs::finders *finder,
int16_t elevation,
uint16_t x,
@ -2699,7 +2699,7 @@ namespace embark_assist {
void merge_incursion_into_world_tile(embark_assist::defs::region_tile_datum* current,
embark_assist::defs::region_tile_datum* target_tile,
embark_assist::defs::mid_level_tile* target_mlt) {
embark_assist::defs::mid_level_tile_incursion_base* target_mlt) {
df::world_data* world_data = world->world_data;
current->aquifer |= target_mlt->aquifer;
@ -3065,6 +3065,12 @@ uint16_t embark_assist::matcher::find(embark_assist::defs::match_iterators *iter
iterator->active = !(iterator->i > world->worldgen.worldgen_parms.dim_y / 16);
if (!iterator->active) {
// if the cursor was positioned in the lower right corner before the search it has to be moved to a neighbouring tile manually
// to force another call to embark_update when all (incursion) data is finally collected to make sure this specific world tile is properly reevaluated
// see the embark_update() in embark-assistant
if (iterator->x == world->worldgen.worldgen_parms.dim_x - 1 && iterator->y == world->worldgen.worldgen_parms.dim_y - 1) {
embark_assist::matcher::move_cursor(iterator->x - 1, iterator->y);
}
embark_assist::matcher::move_cursor(iterator->x, iterator->y);
if (!survey_results->at(0).at(0).survey_completed) { // Every world tile has gone through preliminary survey, so add possible incursion resources to each tile.

@ -455,7 +455,7 @@ namespace embark_assist {
void process_embark_incursion(embark_assist::defs::site_infos *site_info,
embark_assist::defs::world_tile_data *survey_results,
embark_assist::defs::mid_level_tile *mlt, // Note this is a single tile, as opposed to most usages of this variable name.
embark_assist::defs::mid_level_tile_incursion_base *mlt, // Note this is a single tile, as opposed to most usages of this variable name.
int16_t elevation,
uint16_t x,
uint16_t y) {
@ -996,7 +996,6 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
base_z = elevation - 1;
features = details->features[i][k];
std::map<int, int> layer_bottom, layer_top;
mlt->at(i).at(k).adamantine_level = -1;
mlt->at(i).at(k).magma_level = -1;
@ -1027,8 +1026,6 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
feature->min_z != -30000) {
auto layer = world_data->underground_regions[feature->layer];
layer_bottom[layer->layer_depth] = feature->min_z;
layer_top[layer->layer_depth] = feature->max_z;
base_z = std::min((int)base_z, (int)feature->min_z);
if (layer->type == df::world_underground_region::MagmaSea) {
@ -1381,51 +1378,16 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
tile->west_column[i].sand = mlt->at(0).at(i).sand;
tile->east_column[i].sand = mlt->at(15).at(i).sand;
tile->north_row[i].flux = mlt->at(i).at(0).flux; // Not used
tile->south_row[i].flux = mlt->at(i).at(15).flux;
tile->west_column[i].flux = mlt->at(0).at(i).flux;
tile->east_column[i].flux = mlt->at(15).at(i).flux;
tile->north_row[i].coal = mlt->at(i).at(0).coal; // Not used
tile->south_row[i].coal = mlt->at(i).at(15).coal;
tile->west_column[i].coal = mlt->at(0).at(i).coal;
tile->east_column[i].coal = mlt->at(15).at(i).coal;
tile->north_row[i].soil_depth = mlt->at(i).at(0).soil_depth;
tile->south_row[i].soil_depth = mlt->at(i).at(15).soil_depth;
tile->west_column[i].soil_depth = mlt->at(0).at(i).soil_depth;
tile->east_column[i].soil_depth = mlt->at(15).at(i).soil_depth;
tile->north_row[i].offset = mlt->at(i).at(0).offset; // Not used
tile->south_row[i].offset = mlt->at(i).at(15).offset;
tile->west_column[i].offset = mlt->at(0).at(i).offset;
tile->east_column[i].offset = mlt->at(15).at(i).offset;
tile->north_row[i].elevation = mlt->at(i).at(0).elevation;
tile->south_row[i].elevation = mlt->at(i).at(15).elevation;
tile->west_column[i].elevation = mlt->at(0).at(i).elevation;
tile->east_column[i].elevation = mlt->at(15).at(i).elevation;
tile->north_row[i].river_size = mlt->at(i).at(0).river_size; // Not used
tile->south_row[i].river_size = mlt->at(i).at(15).river_size;
tile->west_column[i].river_size = mlt->at(0).at(i).river_size;
tile->east_column[i].river_size = mlt->at(15).at(i).river_size;
tile->north_row[i].river_elevation = mlt->at(i).at(0).river_elevation; // Not used
tile->south_row[i].river_elevation = mlt->at(i).at(15).river_elevation;
tile->west_column[i].river_elevation = mlt->at(0).at(i).river_elevation;
tile->east_column[i].river_elevation = mlt->at(15).at(i).river_elevation;
tile->north_row[i].adamantine_level = mlt->at(i).at(0).adamantine_level; // Not used
tile->south_row[i].adamantine_level = mlt->at(i).at(15).adamantine_level;
tile->west_column[i].adamantine_level = mlt->at(0).at(i).adamantine_level;
tile->east_column[i].adamantine_level = mlt->at(15).at(i).adamantine_level;
tile->north_row[i].magma_level = mlt->at(i).at(0).magma_level; // Not used
tile->south_row[i].magma_level = mlt->at(i).at(15).magma_level;
tile->west_column[i].magma_level = mlt->at(0).at(i).magma_level;
tile->east_column[i].magma_level = mlt->at(15).at(i).magma_level;
tile->north_row[i].biome_offset = mlt->at(i).at(0).biome_offset;
tile->south_row[i].biome_offset = mlt->at(i).at(15).biome_offset;
tile->west_column[i].biome_offset = mlt->at(0).at(i).biome_offset;
@ -1446,21 +1408,6 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
tile->west_column[i].evilness_level = mlt->at(0).at(i).evilness_level;
tile->east_column[i].evilness_level = mlt->at(15).at(i).evilness_level;
tile->north_row[i].metals.resize(0); // Not used
tile->south_row[i].metals.resize(0);
tile->west_column[i].metals.resize(0);
tile->east_column[i].metals.resize(0);
tile->north_row[i].economics.resize(0); // Not used
tile->south_row[i].economics.resize(0);
tile->west_column[i].economics.resize(0);
tile->east_column[i].economics.resize(0);
tile->north_row[i].minerals.resize(0); // Not used
tile->south_row[i].minerals.resize(0);
tile->west_column[i].minerals.resize(0);
tile->east_column[i].minerals.resize(0);
tile->north_corner_selection[i] = world_data->region_details[0]->edges.biome_corner[i][0];
tile->west_corner_selection[i] = world_data->region_details[0]->edges.biome_corner[0][i];
tile->north_row_biome_x[i] = world_data->region_details[0]->edges.biome_x[i][0];

@ -1,5 +1,4 @@
#pragma once
#include <map>
#include "DataDefs.h"
#include "df/coord2d.h"

@ -229,7 +229,16 @@ end
setting is not needed for DFHack quickfort.
--]]
function GlobalSettings:init()
self.subviews.label:setText{
self:make_setting_label_token('Enable all', 'CUSTOM_E', 'all_enabled', 12),
self:make_setting_value_token('all_enabled'), '\n',
' Enables buildingplan for all building types. Use this to avoid having\n',
' to manually enable buildingplan for each building type that you want\n',
' to plan. Note that DFHack quickfort will use buildingplan to manage\n',
' buildings regardless of whether buildingplan is "enabled" for the\n',
' building type.\n',
'\n',
'Allowed types for generic, fire-safe, and magma-safe building material:\n',
self:make_setting_label_token('Blocks', 'CUSTOM_B', 'blocks', 10),
self:make_setting_value_token('blocks'), '\n',

@ -1 +1 @@
Subproject commit 9d11d91e1991bedc3108f97c0b79389c88206594
Subproject commit e20fa9f5ca7707377477b3d9c032ec1f3a2e6414