diff --git a/library/Core.cpp b/library/Core.cpp index 1d2a76026..e8c43b7f5 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -71,6 +71,7 @@ using namespace DFHack; using namespace tthread; using namespace df::enums; using df::global::init; +using df::global::world; // FIXME: A lot of code in one file, all doing different things... there's something fishy about it. @@ -1113,8 +1114,18 @@ int Core::Update() return 0; }; +extern bool buildings_do_onupdate; +void buildings_onStateChange(color_ostream &out, state_change_event event); +void buildings_onUpdate(color_ostream &out); + +static int buildings_timer = 0; + void Core::onUpdate(color_ostream &out) { + // convert building reagents + if (buildings_do_onupdate && (++buildings_timer & 1)) + buildings_onUpdate(out); + // notify all the plugins that a game tick is finished plug_mgr->OnUpdate(out); @@ -1124,6 +1135,8 @@ void Core::onUpdate(color_ostream &out) void Core::onStateChange(color_ostream &out, state_change_event event) { + buildings_onStateChange(out, event); + plug_mgr->OnStateChange(out, event); Lua::Core::onStateChange(out, event); diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index d2b3e3527..e0afc56ed 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -87,6 +87,58 @@ static uint8_t *getExtentTile(df::building_extents &extent, df::coord2d tile) return &extent.extents[dx + dy*extent.width]; } +/* + * A monitor to work around this bug, in its application to buildings: + * + * http://www.bay12games.com/dwarves/mantisbt/view.php?id=1416 + */ +bool buildings_do_onupdate = false; + +void buildings_onStateChange(color_ostream &out, state_change_event event) +{ + switch (event) { + case SC_MAP_LOADED: + buildings_do_onupdate = true; + break; + case SC_MAP_UNLOADED: + buildings_do_onupdate = false; + break; + default: + break; + } +} + +void buildings_onUpdate(color_ostream &out) +{ + buildings_do_onupdate = false; + + df::job_list_link *link = world->job_list.next; + for (; link; link = link->next) { + df::job *job = link->item; + + if (job->job_type != job_type::ConstructBuilding) + continue; + if (job->job_items.empty()) + continue; + + buildings_do_onupdate = true; + + for (size_t i = 0; i < job->items.size(); i++) + { + df::job_item_ref *iref = job->items[i]; + if (iref->role != df::job_item_ref::Reagent) + continue; + df::job_item *item = vector_get(job->job_items, iref->job_item_idx); + if (!item) + continue; + // Convert Reagent to Hauled, while decrementing quantity + item->quantity = std::max(0, item->quantity-1); + iref->role = df::job_item_ref::Hauled; + iref->job_item_idx = -1; + } + } +} + uint32_t Buildings::getNumBuildings() { return world->buildings.all.size(); @@ -906,6 +958,8 @@ bool Buildings::constructWithFilters(df::building *bld, std::vectormat_index = items[i]->mat_index; } + buildings_do_onupdate = true; + createDesign(bld, rough); return true; } @@ -969,3 +1023,4 @@ bool Buildings::deconstruct(df::building *bld) return true; } +