diff --git a/data/blueprints/library/dreamfort.csv b/data/blueprints/library/dreamfort.csv index 2eb98607f..8924df3c6 100644 --- a/data/blueprints/library/dreamfort.csv +++ b/data/blueprints/library/dreamfort.csv @@ -2,26 +2,28 @@ Welcome to the Dreamfort Walkthrough! It can be difficult applying a set of blueprints that you did not write yourself. This walkthrough will guide you through the high-level steps of building Dreamfort. "" -"The final fort will have a walled-in area on the surface for livestock, trading, and military. Be sure to bring some blocks with you for the initial set of workshops! One z-level down is the farming level, with related workshops and vents up to the surface for miasma control. The farming level also has a miniature dining hall and dormitory for use until you get the services and apartment levels set up." +"The final fort will have a walled-in area on the surface for livestock, trading, and military. Be sure to bring some blocks with you for the initial set of workshops! One z-level down is the farming level, with related workshops and vents up to the surface for miasma control. The farming level also has a miniature dining hall and dormitory for use until you get the services and beds levels set up." "" "Beyond those two, the other layers can be built in any order, at any z-level, according to your preference and the layout peculiarities of your embark site:" "- The industry level has a compact, but complete set of workshops and stockpiles (minus what is already provided on the farming level)" "- The services level has dining, hospital, and justice services, including a well system. This level is 4 z-levels deep." -"- The guildhall level has many rooms for building libraries, temples, and guildhalls" +"- The guildhall level has many empty rooms for building libraries, temples, and guildhalls" - The suites level has fancy rooms for your nobles - The apartments level(s) has small but well-furnished bedrooms for your other dwarves "" +"Run the ""help"" blueprints for each level for more details." +"" "Dreamfort has a central staircase-based design. Choose a tile for your staircase on the surface in a nice, flat area. For all blueprints, the cursor will start on this tile on the z-level where you want to apply the blueprint." "" -"Blueprints that require manual steps (like 'assign animals to pasture') will leave a message telling you so after you apply them. Blueprints will also leave messages with hints when you might want to run ""quickfort orders"" on specific blueprints to start manufacturing needed items." +"Blueprints that require manual steps (like 'assign minecart to hauling route') will leave a message telling you so after you apply them. Blueprints will also leave messages with hints when you might want to run ""quickfort orders"" on specific blueprints to start manufacturing needed items." "" "Directly after embark, apply /surface1 on a flat area on the surface and /industry1 somewhere underground (but not immediately below the surface -- that will be for the farming level). Work your way through the steps for those levels: apply /surface2 when /surface1 is done, /industry2 when /industry1 is done, etc. Once you channel out parts of the surface with /surface3, you can start the farming sequence with /farming1. You can start the services, guildhall, suites, and apartments sequences as your fort needs those levels." "" -"This .csv file is generated from source .xlsx files. If you want to look at how these blueprints are put together, including full lists of their features, it will be easier to look at the .xlsx files than this giant .csv. You can view them online at: https://drive.google.com/drive/folders/1iS90EEVqUkxTeZiiukVj1pLloZqabKuP" +"This .csv file is generated from source .xlsx files. If you want to look at how these blueprints are put together, it will be easier to look at the online spreadsheets than this giant .csv. You can view them at: https://drive.google.com/drive/folders/1iS90EEVqUkxTeZiiukVj1pLloZqabKuP" You are welcome to copy those files 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(surface_readme) +#notes label(surface_help) "Sets up a large, protected entrance to your fort in a flat area on the surface." "" Features: @@ -46,7 +48,7 @@ Once the area is clear, continue with /surface2.) clear an area and set up pastu clear_small/surface_clear_small zones/surface_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 for the manager orders for blocks. +"#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, continue with /surface3.) set up starting workshops/stockpiles and clear a larger area. if you didn't bring blocks, temporarily turn off the buildings_use_blocks setting so you can use wood or boulders" build_start/surface_build_start place_start/surface_place_start @@ -54,14 +56,14 @@ query_start/surface_query_start clear/surface_clear pick/surface_pick "" -"#meta label(surface3) start(staircase center) message(Once the channels are dug out and you have around 650 blocks, continue with /surface4. You can also start digging out the sub-surface farming level once the channels are done.) channel to prevent miasma in the sub-surface farming level" +"#meta label(surface3) start(staircase center) message(Once the channels are dug out, continue with /surface4. You can also start digging out the sub-surface farming level once the channels are done.) channel to prevent miasma in the sub-surface farming level" dig/surface_channel "" -"#meta label(surface4) start(staircase center) message(Once floors and walls are built and you have completed the manager orders for /surface5, continue with /surface5.) cover up the holes with flooring and build walls" +"#meta label(surface4) start(staircase center) message(Once floors and walls are built, continue with /surface5.) cover up the holes with flooring and build walls" build_floors/surface_floors build_walls/surface_walls "" -"#meta label(surface5) start(staircase center) message(Once you have around 1,050 blocks, continue with /surface6) build gates, furniture, the trade depot, and traps" +"#meta label(surface5) start(staircase center) message(Once buildings have been constructed, continue with /surface6) build gates, furniture, the trade depot, and traps" build_bridges/surface_gates build_buildings/surface_buildings "" @@ -820,7 +822,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, -#notes label(farming_readme) +#notes label(farming_help) "Sets up farming, food storage, and related industries. Also provides post-embark necessities that can later be disassembed." "" Features: @@ -844,7 +846,7 @@ Screw Press Manual steps you have to take: Assign the office to your manager Assign a minecart to your quantum garbage stockpile hauling route -"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" +"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" "#dig label(farming1) start(23; 25; staircase center) message(This would be a good time to queue up manager orders for /farming2. Once the area is dug out, continue with /farming2.)" @@ -985,13 +987,13 @@ query_stockpiles/farming_query_stockpiles #place label(farming_place) start(23; 25) hidden() use the meta blueprints for normal application -,,,,,,,,,`,`,`,`,`,`,`,`,f(3x6),`,`,,`,,`,,f(14x16),`,`,`,`,`,`,`,`,`,`,`,`,` +,,,,,,,,,`,`,`,`,`,`,`,`,f(3x6),,,,`,,`,,f(14x16),,,,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,` -,,,,,,,,,f(8x1),`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` -,,,,,,,,,b(8x1),`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` +,,,,,,,,,f(8x1),,,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` +,,,,,,,,,b(8x1),,,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,,,`,,,`,,,`,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,` -,,,,,,f(14x10),`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` +,,,,,,f(14x10),,,,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` @@ -1002,7 +1004,7 @@ query_stockpiles/farming_query_stockpiles ,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,`,,,,`,,,,`,,,,`,`,`,,,`,,,,` -,,,,,,,,u,u,u,u,`,`,`,u(5x3),`,`,`,`,,`,`,`,,`,`,`,,`,`,` +,,,,,,,,u,u,u,u,`,`,`,u(5x3),,,`,`,,`,`,`,,`,`,`,,`,`,` ,,,,,,,,g,`,`,u,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,g,g,g,g,`,`,`,`,`,`,`,`,,`,,`,,`,`,`,,`,`,` ,,,,,,,,,`,,,,`,,,,`,,,,`,`,`,,,`,,,,` @@ -1010,20 +1012,20 @@ query_stockpiles/farming_query_stockpiles ,,,,,,,,,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,,`,`,`,`,`,`,`,` ,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,,,,,,,,,,,,,`,`,`,,,,,`,,,,,` -,,,,,,,,,`,`,`,,f(7x2),`,`,`,`,`,`,,`,,`,,r(2x3),`,`,`,`,,f(1x3),`,`,` +,,,,,,,,,`,`,`,,f(7x2),,,`,`,`,`,,`,,`,,r(2x3),,,`,`,,f(1x3),,,` ,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,,`,`,`,`,`,,`,`,`,` ,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,`,`,,,,,`,,,,,` -,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,`,`,,ry(14x10),`,`,`,`,`,`,`,`,`,`,`,`,` +,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,`,`,,ry(14x10),,,,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,` -,,,,,,,,,`,`,`,,f(7x2),`,`,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` +,,,,,,,,,`,`,`,,f(7x2),,,`,`,`,`,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,,`,,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,` -,,,,,,,,,,,,,,,,,,,,,ry(3x3),`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` +,,,,,,,,,,,,,,,,,,,,,ry(3x3),,,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,,,,,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,,,,,,,,,,,,,`,`,`,,`,`,`,`,`,`,`,`,`,`,`,`,`,` ,,,,,,,,,,,,,,,,,,,,,,`,,,`,`,`,`,`,`,`,`,`,`,`,`,`,` -,,,,,,,,,,,,,,,,,,,,,,ry(1x1),,,`,`,`,`,`,`,`,`,`,`,`,`,`,` +,,,,,,,,,,,,,,,,,,,,,,ry,,,`,`,`,`,`,`,`,`,`,`,`,`,`,` "#query label(farming_query_stockpiles) start(23; 25) hidden() message(remember to: @@ -1116,7 +1118,7 @@ query_stockpiles/farming_query_stockpiles ,,,,,,,,,,,,,,,,,,,,,,`,,,`,`,`,`,`,`,`,`,`,`,`,`,`,` -#notes label(industry_readme) +#notes label(industry_help) Sets up workshops for all non-farming industries "" Features: @@ -1303,7 +1305,7 @@ query/industry_query ,,,,,,,,,,,`,`,`,`,`,`,`,`,`,`,`,`,` -#notes label(services_readme) +#notes label(services_help) "Sets up public services (dining, hospital, etc.)" "" Features: @@ -1319,7 +1321,7 @@ Manual steps you have to take: "If you want to declare the dining room as a tavern, the bedrooms at the top can be assigned to the tavern as rented rooms." "Configure the soap stockpiles to take from the industry level ""Metalworker"" quantum stockpile (which holds all the bars)" "Convert the bath pit zones to pond zones when you are ready to fill them with 3-depth water. This is the only really fiddly bit, since you have to carefully disable the pond zone again when the final bucket to bring the water to an even 3-depth is on the way." -"Fill the cisterns with water, either with a bucket brigade or by plumbing flowing water. Fill so that there are two z-levels of 7-depth water. If you want to fill with buckets, designate a pond zone on the level below the main floor. If you feel adventurous and are experience with water pressure, you can instead route (depressurized!) water to the second-to-bottom level (the one above the up staircases)." +"Fill the cisterns with water, either with a bucket brigade or by plumbing flowing water. Fill so that there are two z-levels of 7-depth water. If you want to fill with buckets, designate a pond zone on the level below the main floor. If you feel adventurous and are experienced with water pressure, you can instead route (depressurized!) water to the second-to-bottom level (the one above the up staircases)." "#dig label(services1) start(23; 22; staircase center) message(This would be a good time to queue manager orders for /services2. Once the area is dug out, continue with /services2.)" @@ -1633,7 +1635,7 @@ query_stockpiles/services_query_stockpiles ,,`,`,`,`,`,`,,`,`,`,`,`,` -#notes label(guildhall_readme) +#notes label(guildhall_help) "Multiple 7x7 rooms for guildhalls, temples, libraries, etc." "" Features: @@ -1738,7 +1740,7 @@ Features: ,,`,`,`,`,`,`,`,,,,,,`,`,`,`,`,`,`,,,,,,,,`,`,`,`,`,`,`,,,,,,`,`,`,`,`,`,` -#notes label(beds_readme) +#notes label(beds_help) Suites for nobles and apartments for the teeming masses "" Features: diff --git a/docs/Plugins.rst b/docs/Plugins.rst index a690ddbf3..3cff80c9c 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -706,15 +706,44 @@ enabled materials, you should be able to place complex constructions more conven buildingplan ============ When active (via ``enable buildingplan``), this plugin adds a planning mode for -furniture placement. You can then place furniture and other buildings before -the required materials are available, and the job will be unsuspended when -the item is created. +building placement. You can then place furniture, constructions, and other buildings +before the required materials are available, and they will be created in a suspended +state. Buildingplan will periodically scan for appropriate items, and the jobs will +be unsuspended when the items are available. -Very useful when combined with `workflow` - you can set a constraint +This is very useful when combined with `workflow` - you can set a constraint 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, +as many as you like. The plugins then take over and fulfill the orders, with minimal space dedicated to stockpiles. +Item filtering +-------------- + +While placing a building, you can set filters for what materials you want the building made +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 Ctrl+Left and Ctrl+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). + +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. + +Quickfort mode +-------------- + +If you use the external Python Quickfort to apply building blueprints instead of the native +DFHack `quickfort` script, you must enable Quickfort mode. This temporarily enables +buildingplan for all building types and adds an extra blank screen after every building +placement. This "dummy" screen is needed for Python Quickfort to interact successfully with +Dwarf Fortress. + +Note that Quickfort mode is only for compatibility with the legacy Python Quickfort. The +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. + .. _confirm: confirm diff --git a/docs/changelog.txt b/docs/changelog.txt index 7f289c36d..dbe296c85 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -34,8 +34,17 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: # Future ## Fixes +- `buildingplan`: artifacts are now successfully matched when max quality is set to ``artifacts`` - `dwarfmonitor`: fixed a crash when opening the ``prefs`` screen if units have vague preferences +## Misc Improvements +- `buildingplan`: all buildings, furniture, and constructions are now supported (except for the few building types not supported by dfhack itself) +- `buildingplan`: now respects building job_item filters when matching items +- `buildingplan`: default filter setting for max quality changed from ``artifact`` to ``masterwork`` + +## API +- `buildingplan`: added Lua interface API + # 0.47.04-r3 ## New Plugins diff --git a/docs/guides/quickfort-user-guide.rst b/docs/guides/quickfort-user-guide.rst index 76485a985..bef85b161 100644 --- a/docs/guides/quickfort-user-guide.rst +++ b/docs/guides/quickfort-user-guide.rst @@ -69,7 +69,8 @@ Features - Build mode - - DFHack buildingplan integration + - DFHack buildingplan integration, so you can place buildings before + manufacturing all required source materials - Designate complete constructions at once, without having to wait for each tile to become supported before you can build it - Automatic expansion of building footprints to their minimum dimensions, so @@ -1022,32 +1023,49 @@ allowing for much easier viewing and editing. Buildingplan integration ------------------------ -Buildingplan is a DFHack plugin that keeps jobs in a suspended state until the -materials required for the job are available. This prevents a building -designation from being canceled when a dwarf picks up the job but can't find the -materials. - -For all types that buildingplan supports, quickfort using buildingplan to manage -construction. Buildings are still constructed immediately if you have the -materials, but you now have the freedom to apply build blueprints before you -manufacture all required materials, and the jobs will be fulfilled as the -materials become available. - -If a ``#build`` blueprint only refers to supported types, the buildingplan -integration pairs well with the `workflow` plugin, which can build items a few -at a time continuously as long as they are needed. For building types that are -not yet supported by buildingplan, a good pattern to follow is to first run -``quickfort orders`` on the ``#build`` blueprint to manufacture all the required -items, then apply the blueprint itself. - -See the `buildingplan documentation ` for more information. As of -this writing, buildingplan only supports basic furniture. +Buildingplan is a DFHack plugin that keeps building construction jobs in a +suspended state until the materials required for the job are available. This +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 always use buildingplan to manage everything designated in a +``#build`` blueprint. + +However, quickfort *does* use buildingplan's filters for each building type. For +example, you can use the buildingplan UI to set the 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 the buildingplan integration you now have the freedom +to apply ``#build`` blueprints before you manufacture the resources. The +construction jobs will be fulfilled as the materials become available. + +Since it can be difficult to figure out exactly what source materials you need +for a ``#build`` blueprint, quickfort supplies the ``orders`` command. It +enqueues manager orders for everything that the buildings in a ``#build`` +blueprint require. See the next section for more details on this. + +Alternately, if you know you only need a few types of items, the `workflow` +plugin can be configured to build those items continuously for as long as they +are needed. + +If the buildingplan plugin is not enabled, run ``quickfort orders`` first and +make sure all manager orders are fulfilled before applying a ``#build`` +blueprint. Generating manager orders ------------------------- Quickfort can generate manager orders to make sure you have the proper items in -stock to apply a ``#build`` blueprint. +stock for a ``#build`` blueprint. Many items can be manufactured from different source materials. Orders will always choose rock when it can, then wood, then cloth, then iron. You can always @@ -1066,7 +1084,9 @@ If you want your constructions to be in a consistent color, be sure to choose a rock type for all of your 'Make rock blocks' orders by selecting the order and hitting ``d``. You might want to set the rock type for other non-block orders to something different if you fear running out of the type of rock that you want to -use for blocks. +use for blocks. You should also set the `buildingplan` material filter for +construction building types to that type of rock as well so other random blocks +you might have lying around aren't used. There are a few building types that will generate extra manager orders for related materials: @@ -1105,23 +1125,16 @@ Tips and tricks Caveats and limitations ----------------------- -- Buildings will be designated regardless of whether you have the required - materials, but if materials are not available when the construction job is - picked up by a dwarf, the buildings will be canceled and the designations - will disappear. Until the buildingplan plugin can be extended to support all - building types, you should use ``quickfort orders`` to pre-manufacture all - the materials you need for a ``#build`` blueprint before you apply it. - - If you use the ``jugs`` alias in your ``#query``-mode blueprints, be aware that there is no way to differentiate jugs from other types of tools in the game. Therefore, ``jugs`` stockpiles will also take nest boxes and other tools. The only workaround is not to have other tools lying around in your fort. -- Likewise for bags. The game does not differentiate between empty and full - bags, so you'll get bags of gypsum power and sand in your bags stockpile - unless you avoid collecting sand and are careful to assign all your gypsum to - your hospital. +- Likewise for the ``bags`` alias. The game does not differentiate between + empty and full bags, so you'll get bags of gypsum power and sand in your bags + stockpile unless you avoid collecting sand and are careful to assign all your + gypsum to your hospital. - Weapon traps and upright spear/spike traps can currently only be built with a single weapon. @@ -1260,7 +1273,7 @@ sheet, like in surface's meta sheet. things to include in messages are: * The name of the next blueprint to apply and when to run it -* Whether quickfort orders should be run for an upcoming step +* Whether quickfort orders could be run for an upcoming step * Any manual actions that have to happen, like assigning minecarts to hauling routes or pasturing animals after creating zones diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index 976ade441..6d6d777f7 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -368,10 +368,19 @@ df::building *Buildings::allocInstance(df::coord pos, df::building_type type, in obj->bucket_z = bld->z; break; } + case building_type::Workshop: + { + if (VIRTUAL_CAST_VAR(obj, df::building_workshopst, bld)) + obj->profile.max_general_orders = 5; + break; + } case building_type::Furnace: { if (VIRTUAL_CAST_VAR(obj, df::building_furnacest, bld)) + { obj->melt_remainder.resize(df::inorganic_raw::get_vector().size(), 0); + obj->profile.max_general_orders = 5; + } break; } case building_type::Coffin: @@ -419,6 +428,12 @@ df::building *Buildings::allocInstance(df::coord pos, df::building_type type, in obj->gate_flags.bits.closed = true; break; } + case building_type::Bridge: + { + if (VIRTUAL_CAST_VAR(obj, df::building_bridgest, bld)) + obj->gate_flags.bits.closed = false; + break; + } default: break; } diff --git a/plugins/buildingplan-planner.cpp b/plugins/buildingplan-planner.cpp index dcdcfb777..0a714854c 100644 --- a/plugins/buildingplan-planner.cpp +++ b/plugins/buildingplan-planner.cpp @@ -495,7 +495,9 @@ void migrateV1ToV2() // remove the v1 record DFHack::World::DeletePersistentData(config); - debug("v1 record successfully migrated"); + debug("v1 %s(%d) record successfully migrated", + ENUM_KEY_STR(building_type, bld->getType()).c_str(), + bld->id); } } @@ -510,13 +512,14 @@ void Planner::reset() std::vector items; DFHack::World::GetPersistentData(&items, planned_building_persistence_key_v2); - debug("found data for %zu planned buildings", items.size()); + debug("found data for %zu planned building(s)", items.size()); for (auto i = items.begin(); i != items.end(); i++) { PlannedBuilding pb(*i); if (!pb.isValid()) { + debug("discarding invalid planned building"); pb.remove(); continue; } @@ -608,7 +611,7 @@ bool Planner::registerTasks(PlannedBuilding & pb) int32_t id = bld->id; tasks[vector_id][bucket].push(std::make_pair(id, job_item_idx)); debug("added task: %s/%s/%d,%d; " - "%zu vectors, %zu buckets, %zu tasks in bucket", + "%zu vector(s), %zu filter bucket(s), %zu task(s) in bucket", ENUM_KEY_STR(job_item_vector_id, vector_id).c_str(), bucket.c_str(), id, job_item_idx, tasks.size(), tasks[vector_id].size(), tasks[vector_id][bucket].size()); @@ -626,38 +629,7 @@ PlannedBuilding * Planner::getPlannedBuilding(df::building *bld) bool Planner::isPlannableBuilding(BuildingTypeKey key) { - if (getNumFilters(key) == 0) - return false; - - // restrict supported types to be the same as the previous implementation - switch(std::get<0>(key)) - { - case df::enums::building_type::Armorstand: - case df::enums::building_type::Bed: - case df::enums::building_type::Chair: - case df::enums::building_type::Coffin: - case df::enums::building_type::Door: - case df::enums::building_type::Floodgate: - case df::enums::building_type::Hatch: - case df::enums::building_type::GrateWall: - case df::enums::building_type::GrateFloor: - case df::enums::building_type::BarsVertical: - case df::enums::building_type::BarsFloor: - case df::enums::building_type::Cabinet: - case df::enums::building_type::Box: - case df::enums::building_type::Weaponrack: - case df::enums::building_type::Statue: - case df::enums::building_type::Slab: - case df::enums::building_type::Table: - case df::enums::building_type::WindowGlass: - case df::enums::building_type::AnimalTrap: - case df::enums::building_type::Chain: - case df::enums::building_type::Cage: - case df::enums::building_type::TractionBench: - return true; - default: - return false; - } + return getNumFilters(key) >= 1; } Planner::ItemFiltersWrapper Planner::getItemFilters(BuildingTypeKey key) @@ -831,7 +803,7 @@ void Planner::doCycle() auto & buckets = it->second; auto other_id = ENUM_ATTR(job_item_vector_id, other, it->first); auto item_vector = df::global::world->items.other[other_id]; - debug("matching %zu items in vector %s against %zu buckets", + debug("matching %zu item(s) in vector %s against %zu filter bucket(s)", item_vector.size(), ENUM_KEY_STR(job_item_vector_id, it->first).c_str(), buckets.size()); @@ -848,7 +820,7 @@ void Planner::doCycle() popInvalidTasks(task_queue); if (task_queue.empty()) { - debug("removing empty bucket: %s/%s; %zu buckets left", + debug("removing empty bucket: %s/%s; %zu bucket(s) left", ENUM_KEY_STR(job_item_vector_id, it->first).c_str(), bucket_it->first.c_str(), buckets.size() - 1); @@ -891,7 +863,7 @@ void Planner::doCycle() if (task_queue.empty()) { debug( - "removing empty item bucket: %s/%s; %zu remaining", + "removing empty item bucket: %s/%s; %zu left", ENUM_KEY_STR(job_item_vector_id, it->first).c_str(), bucket_it->first.c_str(), buckets.size() - 1); @@ -907,7 +879,7 @@ void Planner::doCycle() } if (buckets.empty()) { - debug("removing empty vector: %s; %zu vectors left", + debug("removing empty vector: %s; %zu vector(s) left", ENUM_KEY_STR(job_item_vector_id, it->first).c_str(), tasks.size() - 1); it = tasks.erase(it); @@ -915,7 +887,7 @@ void Planner::doCycle() else ++it; } - debug("cycle done; %zu registered buildings left", + debug("cycle done; %zu registered building(s) left", planned_buildings.size()); } diff --git a/plugins/lua/buildingplan.lua b/plugins/lua/buildingplan.lua index 49b80990f..2de7db7d2 100644 --- a/plugins/lua/buildingplan.lua +++ b/plugins/lua/buildingplan.lua @@ -79,18 +79,16 @@ function construct_building_from_ui_state() custom=uibs.custom_type, pos=pos, width=width, height=height, direction=direction} if err then error(err) end - -- TODO: assign fields for the types that need them. we can't pass them all - -- in to the call to constructBuilding since the unneeded fields will cause - -- errors - --local fields = { - -- friction=uibs.friction, - -- use_dump=uibs.use_dump, - -- dump_x_shift=uibs.dump_x_shift, - -- dump_y_shift=uibs.dump_y_shift, - -- speed=uibs.speed - --} - -- TODO: use quickfort's post_construction_fns? maybe move those functions - -- into the library so they get applied automatically + -- assign fields for the types that need them. we can't pass them all in to + -- the call to constructBuilding since attempting to assign unrelated + -- fields to building types that don't support them causes errors. + for k,v in pairs(bld) do + if k == 'friction' then bld.friction = uibs.friction end + if k == 'use_dump' then bld.use_dump = uibs.use_dump end + if k == 'dump_x_shift' then bld.dump_x_shift = uibs.dump_x_shift end + if k == 'dump_y_shift' then bld.dump_y_shift = uibs.dump_y_shift end + if k == 'speed' then bld.speed = uibs.speed end + end return bld end