diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index ab7d6434e..ebd82ce19 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -1998,6 +1998,11 @@ Low-level building creation functions: Destroys the building, or queues a deconstruction job. Returns *true* if the building was destroyed and deallocated immediately. +* ``dfhack.buildings.notifyCivzoneModified(building)`` + + Rebuilds the civzone <-> overlapping building association mapping. + Call after changing extents or modifying size in some fashion + * ``dfhack.buildings.markedForRemoval(building)`` Returns *true* if the building is marked for removal (with :kbd:`x`), *false* diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 9f3d590dd..84612f790 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2239,6 +2239,7 @@ static const LuaWrapper::FunctionReg dfhack_buildings_module[] = { WRAPM(Buildings, constructWithItems), WRAPM(Buildings, constructWithFilters), WRAPM(Buildings, deconstruct), + WRAPM(Buildings, notifyCivzoneModified), WRAPM(Buildings, markedForRemoval), WRAPM(Buildings, getRoomDescription), WRAPM(Buildings, isActivityZone), diff --git a/library/include/modules/Buildings.h b/library/include/modules/Buildings.h index aa539c02a..f4e8f37be 100644 --- a/library/include/modules/Buildings.h +++ b/library/include/modules/Buildings.h @@ -202,6 +202,11 @@ DFHACK_EXPORT bool deconstruct(df::building *bld); */ DFHACK_EXPORT bool markedForRemoval(df::building *bld); +/** + * Rebuilds a civzones building associations after it has been modified +*/ +DFHACK_EXPORT void notifyCivzoneModified(df::building* bld); + void updateBuildings(color_ostream& out, void* ptr); void clearBuildings(color_ostream& out); diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index 600be91d7..6e7190f9c 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -114,36 +114,18 @@ static df::building_extents_type *getExtentTile(df::building_extents &extent, df return &extent.extents[dx + dy*extent.width]; } -void add_building_to_all_zones(df::building* bld); - -static void buildings_fixzones() -{ - auto& vec = world->buildings.other[buildings_other_id::IN_PLAY]; - - bool changed = false; - - for (size_t i = 0; i < vec.size(); i++) - { - df::building* bld = vec[i]; - - add_building_to_all_zones(bld); - } -} - /* * 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; -static bool buildings_do_fixzones = false; void buildings_onStateChange(color_ostream &out, state_change_event event) { switch (event) { case SC_MAP_LOADED: buildings_do_onupdate = true; - buildings_do_fixzones = true; break; case SC_MAP_UNLOADED: buildings_do_onupdate = false; @@ -155,12 +137,6 @@ void buildings_onStateChange(color_ostream &out, state_change_event event) void buildings_onUpdate(color_ostream &out) { - if (buildings_do_fixzones) - { - buildings_fixzones(); - buildings_do_fixzones = false; - } - buildings_do_onupdate = false; df::job_list_link *link = world->jobs.list.next; @@ -1450,6 +1426,16 @@ bool Buildings::markedForRemoval(df::building *bld) return false; } +void Buildings::notifyCivzoneModified(df::building* bld) +{ + if (bld->getType() != building_type::Civzone) + return; + + //remove zone here needs to be the slow method + remove_zone_from_all_buildings(bld); + add_zone_to_all_buildings(bld); +} + void Buildings::clearBuildings(color_ostream& out) { corner1.clear(); corner2.clear();