Skip to content

Commit 0457a90

Browse files
committed
Merge branch 'develop' into testing
2 parents 23b230d + 5f192a4 commit 0457a90

8 files changed

Lines changed: 79 additions & 23 deletions

File tree

docs/dev/overlay-dev-guide.rst

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,21 @@ beyond your everyday `widgets.Widget <widget>`:
7272
screen, but the returned screen can instantiate and configure any new views
7373
that it wants to. See the `hotkeys` DFHack logo widget for an example.
7474

75+
The ``overlay_trigger()`` function enables the activation of overlay widgets
76+
via the command line interface (CLI) or keybindings.
77+
For example, executing ``overlay trigger notes.map_notes add Kitchen``::
78+
79+
function MyOverlayWidget:overlay_trigger(arg1, arg2)
80+
if arg1 == 'add' then
81+
-- Add a new note to the map
82+
self:addSomething(arg2)
83+
elseif arg1 == 'delete' then
84+
self:deleteSomething(arg2)
85+
end
86+
end
87+
88+
This allows for dynamic updates to UI overlays directly from the CLI.
89+
7590
If the widget can take up a variable amount of space on the screen, and you want
7691
the widget to adjust its position according to the size of its contents, you can
7792
modify ``self.frame.w`` and ``self.frame.h`` at any time -- in ``init()`` or in
@@ -207,7 +222,7 @@ If you need to improve performance, here are some potential options:
207222
and change the start offset every time you scan.
208223

209224
2. Reduce the frequency of state updates by moving calcuations to
210-
``overlay_onupdate`` and setting the valud of the
225+
``overlay_onupdate`` and setting the value of the
211226
``overlay_onupdate_max_freq_seconds`` attribute appropriately
212227

213228
3. Move hotspots into C++ code, either in a new core library function or in a

docs/plugins/overlay.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ Examples
4949
``overlay trigger hotkeys.menu``
5050
Trigger the `hotkeys` menu widget so that it shows its popup menu. This is
5151
what is run when you hit :kbd:`Ctrl`:kbd:`Shift`:kbd:`C`.
52+
``overlay trigger notes.map_notes add Kitchen``
53+
Trigger the `notes` overlay widget so that it shows its new note popup
54+
with given title.
5255

5356
Widget position
5457
---------------

docs/plugins/preserve-rooms.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ This tool mitigates both issues. It records when units leave the map and
1919
reserves their assigned bedrooms, offices, etc. for them. The zones will be
2020
disabled in their absence (so other units don't steal them), and will be
2121
re-enabled and reassigned to them when they appear back on the map. If they die
22-
away from the fort, the zone will become unreserved and available for reuse.
22+
away from the fort, the zone will become unreserved and available for reuse. If
23+
they are captured and held prisoner, their room will continue to be reserved in
24+
their name in the (optimistic) hope of their safe return.
2325

2426
When you click on an assignable zone, you will also now have the option to
2527
associate the room with a noble or administrative role. The room will be

plugins/lua/orders.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ LaborRestrictionsOverlay.ATTRS{
448448
frame={w=57, h=15},
449449
}
450450

451-
local function can_set_labors()
451+
function can_set_labors()
452452
for _,fs in ipairs(dfhack.gui.getFocusStrings(dfhack.gui.getDFViewscreen(true))) do
453453
if fs:endswith('WORKER_ASSIGNMENT') then
454454
return false

plugins/lua/overlay.lua

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,11 @@ local function do_trigger(args, quiet)
383383
do_by_names_or_numbers(args[1], function(name, db_entry)
384384
local widget = db_entry.widget
385385
if widget.overlay_trigger then
386-
register_trigger_lock_screen(widget:overlay_trigger(), name)
386+
register_trigger_lock_screen(
387+
widget:overlay_trigger(table.unpack(args, 2)),
388+
name
389+
)
390+
387391
if not quiet then
388392
print(('triggered widget %s'):format(name))
389393
end

plugins/lua/preserve-rooms.lua

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ DEBUG = DEBUG or false
1515
--
1616

1717
-- updated on world load
18-
local code_lookup = {}
18+
code_lookup = code_lookup or {}
1919

2020
function assignToRole(code, bld)
2121
local group_codes = code_lookup[code:lower()]
@@ -111,7 +111,7 @@ ReservedWidget.ATTRS{
111111
version=2,
112112
}
113113

114-
local new_world_loaded = true
114+
new_world_loaded = true
115115

116116
local CONFLICTING_TOOLTIPS = utils.invert{
117117
df.main_hover_instruction.ZoneRepaint,
@@ -222,15 +222,19 @@ end
222222
local mi = df.global.game.main_interface
223223

224224
function ReservedWidget:onInput(keys)
225-
if not CONFLICTING_TOOLTIPS[mi.current_hover] and ReservedWidget.super.onInput(self, keys) then
226-
return true
227-
end
228225
if keys._MOUSE_L and
229226
(preserve_rooms_isReserved() or preserve_rooms_getRoleAssignment() ~= '')
230227
then
231228
if self.subviews.pause_mask:getMousePos() then return true end
232229
if self.subviews.add_mask:getMousePos() then return true end
233230
end
231+
if CONFLICTING_TOOLTIPS[mi.current_hover] then
232+
return false
233+
end
234+
if mi.entering_building_name and keys._STRING then
235+
return false
236+
end
237+
return ReservedWidget.super.onInput(self, keys)
234238
end
235239

236240
function ReservedWidget:render(dc)
@@ -276,7 +280,7 @@ local function add_options(options, choices, codes)
276280
end
277281

278282
-- updated on world load
279-
local codes = {}
283+
codes = codes or {}
280284

281285
function ReservedWidget:refresh_role_list()
282286
local options, choices = {{label='None', value={''}, pen=COLOR_YELLOW}}, {'None'}

plugins/preserve-rooms.cpp

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -358,26 +358,52 @@ static void assign_nobles(color_ostream &out) {
358358
}
359359
}
360360

361+
static bool scrub_id_from_entries(int32_t id, int32_t key, unordered_map<int32_t, vector<int32_t>> & entries) {
362+
auto it = entries.find(key);
363+
if (it == entries.end())
364+
return false;
365+
auto & entry_ids = it->second;
366+
vector_erase_at(entry_ids, linear_index(entry_ids, id));
367+
if (entry_ids.empty()) {
368+
entries.erase(it);
369+
return true;
370+
}
371+
return false;
372+
}
373+
374+
// clear the reservation for a zone
361375
static void clear_reservation(color_ostream &out, int32_t zone_id, df::building_civzonest * zone = NULL) {
362376
auto it = reserved_zones.find(zone_id);
363377
if (it == reserved_zones.end())
364378
return;
365-
for (auto hfid : it->second) {
366-
auto pending_it = pending_reassignment.find(hfid);
367-
if (pending_it != pending_reassignment.end()) {
368-
auto & zone_ids = pending_it->second;
369-
vector_erase_at(zone_ids, linear_index(zone_ids, zone_id));
370-
if (zone_ids.empty())
371-
pending_reassignment.erase(pending_it);
372-
}
373-
}
379+
for (int32_t hfid : it->second)
380+
scrub_id_from_entries(zone_id, hfid, pending_reassignment);
374381
reserved_zones.erase(zone_id);
375382
if (!zone)
376383
zone = virtual_cast<df::building_civzonest>(df::building::find(zone_id));
377384
if (zone)
378385
zone->spec_sub_flag.bits.active = true;
379386
}
380387

388+
// stop reserving zones for dead units
389+
static void scrub_reservations(color_ostream &out) {
390+
vector<int32_t> hfids_to_scrub;
391+
for (auto &[hfid, zone_ids] : pending_reassignment) {
392+
if (auto hf = df::historical_figure::find(hfid); hf && hf->died_year == -1)
393+
continue;
394+
DEBUG(cycle,out).print("removed reservation for dead or culled hfid %d\n", hfid);
395+
hfids_to_scrub.push_back(hfid);
396+
for (int32_t zone_id : zone_ids) {
397+
if (scrub_id_from_entries(hfid, zone_id, reserved_zones)) {
398+
if (auto zone = virtual_cast<df::building_civzonest>(df::building::find(zone_id)))
399+
zone->spec_sub_flag.bits.active = true;
400+
}
401+
}
402+
}
403+
for (int32_t hfid : hfids_to_scrub)
404+
pending_reassignment.erase(hfid);
405+
}
406+
381407
// handles when units disappear from their assignments compared to the last scan
382408
static void handle_missing_assignments(color_ostream &out,
383409
const unordered_set<int32_t> & active_unit_ids,
@@ -411,9 +437,9 @@ static void handle_missing_assignments(color_ostream &out,
411437
continue;
412438
// unit is off-map or is dead; if we can assign room to spouse then we don't need to reserve the room
413439
auto spouse_hf = df::historical_figure::find(spouse_hfid);
440+
auto spouse = spouse_hf ? df::unit::find(spouse_hf->unit_id) : nullptr;
414441
if (spouse_hf && share_with_spouse) {
415-
if (auto spouse = df::unit::find(spouse_hf->unit_id);
416-
spouse && Units::isActive(spouse) && !Units::isDead(spouse) && active_unit_ids.contains(spouse->id))
442+
if (spouse && Units::isActive(spouse) && !Units::isDead(spouse) && active_unit_ids.contains(spouse->id))
417443
{
418444
DEBUG(cycle,out).print("assigning zone %d (%s) to spouse %s\n",
419445
zone_id, ENUM_KEY_STR(civzone_type, zone->type).c_str(),
@@ -430,7 +456,7 @@ static void handle_missing_assignments(color_ostream &out,
430456
DF2CONSOLE(Units::getReadableName(unit)).c_str());
431457
pending_reassignment[hfid].push_back(zone_id);
432458
reserved_zones[zone_id].push_back(hfid);
433-
if (share_with_spouse && spouse_hfid > -1) {
459+
if (share_with_spouse && spouse) {
434460
DEBUG(cycle,out).print("registering spouse unit for reassignment to zone %d (%s): hfid=%d\n",
435461
zone_id, ENUM_KEY_STR(civzone_type, zone->type).c_str(), spouse_hfid);
436462
pending_reassignment[spouse_hfid].push_back(zone_id);
@@ -489,6 +515,8 @@ static void do_cycle(color_ostream &out) {
489515
DEBUG(cycle,out).print("tracking zone assignments: bedrooms: %zd, offices: %zd, dining halls: %zd, tombs: %zd\n",
490516
last_known_assignments_bedroom.size(), last_known_assignments_office.size(),
491517
last_known_assignments_dining.size(), last_known_assignments_tomb.size());
518+
519+
scrub_reservations(out);
492520
}
493521

494522
if (config.get_bool(CONFIG_TRACK_ROLES)) {

0 commit comments

Comments
 (0)