Add a workaround for Planepacked bug in buildings constructed via API.

Buildings hanging in the air cause constructWithFilters to
exhibit the same behavior as a moody dwarf in a burrow excluding
the workshop, i.e. endlessly collecting the same type of reagent.

http://www.bay12games.com/dwarves/mantisbt/view.php?id=1416

The workaround monitors jobs and reclassifies the reagents on the fly.
develop
Alexander Gavrilov 2012-05-17 20:38:27 +04:00
parent e9ef9b87b5
commit f37f708b37
2 changed files with 68 additions and 0 deletions

@ -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);

@ -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::vector<df::job_item
bld->mat_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;
}