Skip to content

Commit

Permalink
Merge pull request #4880 from myk002/myk_preserve_rooms
Browse files Browse the repository at this point in the history
new tool: preserve-rooms
  • Loading branch information
myk002 authored Aug 28, 2024
2 parents f11efe6 + 847ed96 commit 7b6c23b
Show file tree
Hide file tree
Showing 9 changed files with 882 additions and 9 deletions.
1 change: 1 addition & 0 deletions data/init/dfhack.tools.init
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ enable burrow
enable faststart
enable logistics
enable overlay
enable preserve-rooms

# aliases
alias add autounsuspend suspendmanager
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Template for new versions:
# Future

## New Tools
- `preserve-rooms`: manage room assignments for off-map units and noble roles. reserves rooms owned by traveling units and reinstates their ownership when they return to the site. also allows you to assign rooms to noble/administrator roles, and the rooms will be automatically assigned whenever the holder of the role changes

## New Features

Expand Down
82 changes: 82 additions & 0 deletions docs/plugins/preserve-rooms.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
preserve-rooms
==============

.. dfhack-tool::
:summary: Manage room assignments for off-map units and noble roles.
:tags: fort bugfix interface

When a citizen leaves the map for any reason, e.g. when going off on a raid,
they lose all their zone assignments. Any bedrooms, offices, dining rooms, or
tombs assigned to the citizen will become unassigned and may be claimed by
another unit while they are away.

A related issue occurs when a noble or administrative role changes hands,
either because you have reassigned them or because of an internal fort
election. Rooms you have assigned to the previous noble stay assigned to them,
and the new noble complains because their room requirements are not being met.

This tool mitigates both issues. It records when units leave the map and
reserves their assigned bedrooms, offices, etc. for them. The zones will be
disabled in their absence (so other units don't steal them), and will be
re-enabled and reassigned to them when they appear back on the map. If they die
away from the fort, the zone will become unreserved and available for reuse.

When you click on an assignable zone, you will also now have the option to
associate the room with a noble or administrative role. The room will be
automatically reassigned to whoever currently holds that position. If multiple
rooms of the same type are assigned to a position, then only one room of that
type will be assigned to each holder of that position (e.g. one room per baron
or militia captain).

Usage
-----

::

preserve-rooms [status]
preserve-rooms now
preserve-rooms enable|disable <feature>
preserve-rooms reset <feature>

Examples
--------

``preserve-rooms``
List the types of rooms that are assigned to each noble role and which of
those rooms are being automatically assigned to new holders of the
respective office.
``preserve-rooms now``
Do an immediate update of room assignments. The plugin does this routinely
in the background, but you can run it manually to update now.
``preserve-rooms disable track-missions``
Disable the ``track-missions`` feature for this fort.
``preserve-rooms reset track-roles``
Clear all configuration related to the ``track-roles`` feature (currently
assigned rooms are not unassigned).

Features
--------

``track-missions``
Reserve the rooms assigned to units that leave the map and reassign them
upon their return. This feature is enabled by default.
``track-roles``
Allow rooms to be associated with noble or adminstrative roles. Associated
rooms will be automatically assigned to the current holder of the specified
role. This feature is enabled by default.

Overlay
-------

The ``preserve-rooms.reserved`` overlay indicates whether a zone is disabled
because it is being reserved for a unit that left the map and is expected to
return. For unreserved rooms, it provides widgets to mark the zone as
associated with a specific noble or administrative role.

Notes
-----

This tool fixes rooms being unassigned when a unit leaves the map. This is a
different bug from the one fixed by `preserve-tombs`, which handles the case
where a tomb is unassigned upon a unit's death, preventing them from ever being
buried in their own tomb.
13 changes: 7 additions & 6 deletions library/modules/EventManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,19 +725,20 @@ static void manageNewUnitActiveEvent(color_ostream& out) {

multimap<Plugin*,EventHandler> copy(handlers[EventType::UNIT_NEW_ACTIVE].begin(), handlers[EventType::UNIT_NEW_ACTIVE].end());
// iterate event handler callbacks
vector<int32_t> new_active_unit_ids;
vector<int32_t> newly_active_unit_ids;
for (df::unit* unit : df::global::world->units.active) {
if (!activeUnits.count(unit->id)) {
activeUnits.emplace(unit->id);
new_active_unit_ids.emplace_back(unit->id);
}
if (!activeUnits.count(unit->id))
newly_active_unit_ids.emplace_back(unit->id);
}
for (int32_t unit_id : new_active_unit_ids) {
for (int32_t unit_id : newly_active_unit_ids) {
for (auto &[_,handle] : copy) {
DEBUG(log,out).print("calling handler for new unit event\n");
run_handler(out, EventType::UNIT_NEW_ACTIVE, handle, (void*) intptr_t(unit_id)); // intptr_t() avoids cast from smaller type warning
}
}
activeUnits.clear();
std::transform(df::global::world->units.active.begin(), df::global::world->units.active.end(),
std::inserter(activeUnits, activeUnits.end()), [](auto & unit){ return unit->id; });
}


Expand Down
1 change: 1 addition & 0 deletions plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ if(BUILD_SUPPORTED)
dfhack_plugin(pathable pathable.cpp LINK_LIBRARIES lua)
dfhack_plugin(pet-uncapper pet-uncapper.cpp)
dfhack_plugin(plant plant.cpp LINK_LIBRARIES lua)
dfhack_plugin(preserve-rooms preserve-rooms.cpp LINK_LIBRARIES lua)
dfhack_plugin(preserve-tombs preserve-tombs.cpp)
dfhack_plugin(probe probe.cpp LINK_LIBRARIES lua)
dfhack_plugin(prospector prospector.cpp LINK_LIBRARIES lua)
Expand Down
4 changes: 2 additions & 2 deletions plugins/logistics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ static int logistics_getStockpileData(lua_State *L) {

ProcessorStats melt_stats, trade_stats, dump_stats, train_stats, forbid_stats, claim_stats;

for (auto bld : df::global::world->buildings.other.STOCKPILE) {
for (auto bld : world->buildings.other.STOCKPILE) {
int32_t stockpile_number = bld->stockpile_number;
MeltStockProcessor melt_stock_processor(stockpile_number, false, melt_stats, false);
TradeStockProcessor trade_stock_processor(stockpile_number, false, trade_stats);
Expand Down Expand Up @@ -796,7 +796,7 @@ static int logistics_getGlobalCounts(lua_State *L) {
out = &Core::getInstance().getConsole();
DEBUG(control,*out).print("entering logistics_getGlobalCounts\n");

size_t num_melt = df::global::world->items.other.ANY_MELT_DESIGNATED.size();
size_t num_melt = world->items.other.ANY_MELT_DESIGNATED.size();

size_t num_trade = 0;
for (auto link = world->jobs.list.next; link; link = link->next) {
Expand Down
Loading

0 comments on commit 7b6c23b

Please sign in to comment.