Skip to content

Commit

Permalink
Merge pull request #4884 from myk002/myk_preserve-rooms
Browse files Browse the repository at this point in the history
preserve-rooms: fix logic around restoring zone ownership
  • Loading branch information
myk002 authored Aug 29, 2024
2 parents 60e3214 + a1fd0e4 commit f81a880
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 25 deletions.
9 changes: 5 additions & 4 deletions library/modules/EventManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,9 +724,12 @@ static void manageNewUnitActiveEvent(color_ostream& out) {
return;

multimap<Plugin*,EventHandler> copy(handlers[EventType::UNIT_NEW_ACTIVE].begin(), handlers[EventType::UNIT_NEW_ACTIVE].end());
// iterate event handler callbacks
unordered_set<int32_t> next_activeUnits;
vector<int32_t> newly_active_unit_ids;
for (df::unit* unit : df::global::world->units.active) {
if (!Units::isActive(unit))
continue;
next_activeUnits.emplace(unit->id);
if (!activeUnits.count(unit->id))
newly_active_unit_ids.emplace_back(unit->id);
}
Expand All @@ -736,9 +739,7 @@ static void manageNewUnitActiveEvent(color_ostream& out) {
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; });
activeUnits = std::move(next_activeUnits);
}


Expand Down
4 changes: 3 additions & 1 deletion plugins/lua/preserve-rooms.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ local GLOBAL_KEY = 'preserve-rooms'
--

local function print_status()
local features = preserve_rooms_getState()
local features, stats = preserve_rooms_getState()
print('Features:')
for feature,enabled in pairs(features) do
print((' %20s: %s'):format(feature, enabled))
end
print()
print('Rooms reserved for traveling units:', stats.reservations)
end

local function do_set_feature(enabled, feature)
Expand Down
44 changes: 24 additions & 20 deletions plugins/preserve-rooms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,6 @@ DFhackCExport command_result plugin_save_site_data (color_ostream &out) {
return CR_OK;
}

DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) {
if (event == DFHack::SC_WORLD_UNLOADED) {
if (is_enabled) {
DEBUG(control,out).print("world unloaded; disabling %s\n", plugin_name);
is_enabled = false;
}
}
return CR_OK;
}

DFhackCExport command_result plugin_onupdate(color_ostream &out) {
if (!Core::getInstance().isMapLoaded() || !World::isFortressMode())
return CR_OK;
Expand Down Expand Up @@ -308,7 +298,7 @@ static void assign_nobles(color_ostream &out) {
continue;
Buildings::setOwner(zone, unit);
INFO(cycle,out).print("preserve-rooms: assigning %s to a %s-associated %s\n",
Units::getReadableName(unit).c_str(), code.c_str(),
DF2CONSOLE(Units::getReadableName(unit)).c_str(), code.c_str(),
ENUM_KEY_STR(civzone_type, zone->type).c_str());
break;
}
Expand Down Expand Up @@ -371,13 +361,14 @@ static void handle_missing_assignments(color_ostream &out,
if (!zone)
continue;
// unit is off-map or is dead; if we can assign room to spouse then we don't need to reserve the room
if (auto spouse_hf = df::historical_figure::find(spouse_hfid); spouse_hf && share_with_spouse) {
auto spouse_hf = df::historical_figure::find(spouse_hfid);
if (spouse_hf && share_with_spouse) {
if (auto spouse = df::unit::find(spouse_hf->unit_id);
spouse && Units::isActive(spouse) && !Units::isDead(spouse) && active_unit_ids.contains(spouse->id))
{
DEBUG(cycle,out).print("assigning zone %d (%s) to spouse %s\n",
zone_id, ENUM_KEY_STR(civzone_type, zone->type).c_str(),
Units::getReadableName(spouse).c_str());
DF2CONSOLE(Units::getReadableName(spouse)).c_str());
Buildings::setOwner(zone, spouse);
continue;
}
Expand All @@ -387,7 +378,7 @@ static void handle_missing_assignments(color_ostream &out,
// register the hf ids for reassignment and reserve the room
DEBUG(cycle,out).print("registering primary unit for reassignment to zone %d (%s): %d %s\n",
zone_id, ENUM_KEY_STR(civzone_type, zone->type).c_str(), unit->id,
Units::getReadableName(unit).c_str());
DF2CONSOLE(Units::getReadableName(unit)).c_str());
pending_reassignment[hfid].push_back(zone_id);
reserved_zones[zone_id].push_back(hfid);
if (share_with_spouse && spouse_hfid > -1) {
Expand All @@ -396,6 +387,12 @@ static void handle_missing_assignments(color_ostream &out,
pending_reassignment[spouse_hfid].push_back(zone_id);
reserved_zones[zone_id].push_back(spouse_hfid);
}
INFO(cycle,out).print("preserve-rooms: reserving %s for the return of %s%s%s\n",
toLower_cp437(ENUM_KEY_STR(civzone_type, zone->type)).c_str(),
DF2CONSOLE(Units::getReadableName(unit)).c_str(),
spouse_hf ? " or their spouse, " : "",
spouse_hf ? DF2CONSOLE(Units::getReadableName(spouse_hf)).c_str() : "");

zone->spec_sub_flag.bits.active = false;
}
}
Expand Down Expand Up @@ -481,22 +478,24 @@ static void on_new_active_unit(color_ostream& out, void* data) {
if (!unit || unit->hist_figure_id < 0)
return;
TRACE(event,out).print("unit %d (%s) arrived on map (hfid: %d, in pending: %d)\n",
unit->id, Units::getReadableName(unit).c_str(), unit->hist_figure_id,
unit->id, DF2CONSOLE(Units::getReadableName(unit)).c_str(), unit->hist_figure_id,
pending_reassignment.contains(unit->hist_figure_id));
auto hfid = unit->hist_figure_id;
auto it = pending_reassignment.find(hfid);
if (it == pending_reassignment.end())
return;
INFO(event,out).print("preserve-rooms: restoring room ownership for %s\n",
Units::getReadableName(unit).c_str());
DF2CONSOLE(Units::getReadableName(unit)).c_str());
for (auto zone_id : it->second) {
reserved_zones.erase(zone_id);
auto zone = virtual_cast<df::building_civzonest>(df::building::find(zone_id));
if (!zone || zone->assigned_unit || spouse_has_sharable_room(out, hfid, zone->type))
if (!zone)
continue;
DEBUG(event,out).print("assigning and activating zone %d\n", zone->id);
Buildings::setOwner(zone, unit);
zone->spec_sub_flag.bits.active = true;
if (zone->assigned_unit || spouse_has_sharable_room(out, hfid, zone->type))
continue;
DEBUG(event,out).print("reassigning zone %d\n", zone->id);
Buildings::setOwner(zone, unit);
}
pending_reassignment.erase(it);
}
Expand Down Expand Up @@ -615,7 +614,12 @@ static int preserve_rooms_getState(lua_State *L) {
features.emplace("track-roles", config.get_bool(CONFIG_TRACK_ROLES));
Lua::Push(L, features);

return 1;
unordered_map<string, size_t> stats;
stats.emplace("travelers", pending_reassignment.size());
stats.emplace("reservations", reserved_zones.size());
Lua::Push(L, stats);

return 2;
}

DFHACK_PLUGIN_LUA_FUNCTIONS{
Expand Down

0 comments on commit f81a880

Please sign in to comment.