Skip to content

Commit 2f1873d

Browse files
emigrate nobles (#1382)
* Add emigrate-nobles.lua and rst * Add logic for finding noble's sites * Add monarch handling logic * Add emigration logic * Add announcement * Add options handling * Add documentation * Attempt to fix units stuck in social activities * Fix title underline * Simplify logic * Update docs/emigrate-nobles.rst Co-authored-by: Myk <[email protected]> * Update docs/emigrate-nobles.rst Co-authored-by: Myk <[email protected]> * Update docs/emigrate-nobles.rst Co-authored-by: Myk <[email protected]> * Update docs/emigrate-nobles.rst * Add functionality to remove from squad * Remove squad removal logic * Remove unused function * Move emigrate-nobles into emigration * Move emigrate-nobles.rst into emigration.rst * Update docs/emigration.rst Co-authored-by: Myk <[email protected]> * Update internal/emigration/emigrate-nobles.lua Co-authored-by: Myk <[email protected]> * Remove module globals * Fix pair iteration * Refactor logic * Refactor emigration logic * Fix stupid typo * Fix stupid typo * Fix import error * Add support for current unit * Disable cancelling special jobs * Add mandate removal logic * Add check for fort admins * Add signposts for navigation * Change isAdministrator * Add support for other civ monarchs, change print messages * Add support for evicting noble mayors * Add symbol dropping logic * Update TODO * Update docs/emigration.rst * Fix bad mayor assignment logic * Update for new structures, add missing event * Fix incorrect history event * Update styling of new links and events * Update changelog.txt * doc edits --------- Co-authored-by: Myk <[email protected]>
1 parent e0c645f commit 2f1873d

File tree

5 files changed

+657
-93
lines changed

5 files changed

+657
-93
lines changed

changelog.txt

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Template for new versions:
4242
## New Features
4343
- `advtools`: new ``advtools.fastcombat`` overlay (enabled by default) allows you to skip combat animations and the announcement "More" button by mashing the movement keys
4444
- `gui/journal`: now working in adventure mode
45+
- `emigration`: new ``nobles`` command for sending "freeloader" barons back to the sites that they rule over
4546

4647
## Fixes
4748
- `position`: support for adv mode look cursor

docs/emigration.rst

+35
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,44 @@ even in the company of a visiting elven bard!
1616
The check is made monthly. A happy dwarf (i.e. with negative stress) will never
1717
emigrate.
1818

19+
The tool also supports ``nobles``, a manually-invoked command that makes nobles
20+
emigrate to their rightful land of rule. No more freeloaders making inane demands!
21+
Nobles assigned to squads or to fort administrator positions will not be emigrated.
22+
Remove their assignments before retrying. Nobles holding elected positions
23+
(i.e. mayors) may be emigrated, but will be marked with a ``*`` icon when listed.
24+
1925
Usage
2026
-----
2127

2228
::
2329

2430
enable emigration
31+
emigration nobles [--list]
32+
emigration nobles [<target>]
33+
34+
Examples
35+
--------
36+
37+
``emigration nobles``
38+
Emigrate the selected noble if it does not rule your fortress.
39+
If no unit is selected, list all nobles that do not rule your fortress.
40+
``emigration nobles --list``
41+
List all nobles that do not rule your fortress. Nobles that cannot be emigrated
42+
(see above) will have a ``!`` indicator while nobles holding elected positions
43+
will have a ``*`` indicator.
44+
``emigration nobles --all``
45+
Emigrate all nobles that do not rule your fortress.
46+
``emigration nobles --unit 34534``
47+
Emigrate a noble matching the specified unit ID that does not rule your fortress.
48+
49+
Options
50+
-------
51+
52+
These options are exclusive to the ``emigration nobles`` command.
53+
54+
``-l``, ``--list``
55+
List all nobles that do not rule your fortress
56+
``-a``, ``--all``
57+
Emigrate all nobles do not rule your fortress
58+
``-u``, ``--unit <id>``
59+
Emigrate noble matching specified unit ID that does not rule your fortress

emigration.lua

+18-93
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
local utils = require('utils')
55

6+
local nobles = reqscript('internal/emigration/emigrate-nobles')
7+
local unit_link_utils = reqscript('internal/emigration/unit-link-utils')
8+
69
local GLOBAL_KEY = 'emigration' -- used for state change hooks and persistence
710

811
local function get_default_state()
@@ -37,121 +40,40 @@ function desert(u,method,civ)
3740
local line = dfhack.units.getReadableName(u) .. " has "
3841
if method == 'merchant' then
3942
line = line.."joined the merchants"
40-
u.flags1.merchant = true
41-
u.civ_id = civ
43+
unit_link_utils.markUnitForEmigration(u, civ, false)
4244
else
4345
line = line.."abandoned the settlement in search of a better life."
44-
u.civ_id = civ
45-
u.flags1.forest = true
46-
u.flags2.visitor = true
47-
u.animal.leave_countdown = 2
46+
unit_link_utils.markUnitForEmigration(u, civ, true)
4847
end
49-
local hf_id = u.hist_figure_id
48+
5049
local hf = df.historical_figure.find(u.hist_figure_id)
5150
local fort_ent = df.global.plotinfo.main.fortress_entity
5251
local civ_ent = df.historical_entity.find(hf.civ_id)
5352
local newent_id = -1
5453
local newsite_id = -1
5554

56-
-- free owned rooms
57-
for i = #u.owned_buildings-1, 0, -1 do
58-
local temp_bld = df.building.find(u.owned_buildings[i].id)
59-
dfhack.buildings.setOwner(temp_bld, nil)
60-
end
61-
62-
-- remove from workshop profiles
63-
for _, bld in ipairs(df.global.world.buildings.other.WORKSHOP_ANY) do
64-
for k, v in ipairs(bld.profile.permitted_workers) do
65-
if v == u.id then
66-
bld.profile.permitted_workers:erase(k)
67-
break
68-
end
69-
end
70-
end
71-
for _, bld in ipairs(df.global.world.buildings.other.FURNACE_ANY) do
72-
for k, v in ipairs(bld.profile.permitted_workers) do
73-
if v == u.id then
74-
bld.profile.permitted_workers:erase(k)
75-
break
76-
end
77-
end
78-
end
79-
80-
-- disassociate from work details
81-
for _, detail in ipairs(df.global.plotinfo.labor_info.work_details) do
82-
for k, v in ipairs(detail.assigned_units) do
83-
if v == u.id then
84-
detail.assigned_units:erase(k)
85-
break
86-
end
87-
end
88-
end
89-
90-
-- unburrow
91-
for _, burrow in ipairs(df.global.plotinfo.burrows.list) do
92-
dfhack.burrows.setAssignedUnit(burrow, u, false)
93-
end
94-
95-
-- erase the unit from the fortress entity
96-
for k,v in ipairs(fort_ent.histfig_ids) do
97-
if v == hf_id then
98-
df.global.plotinfo.main.fortress_entity.histfig_ids:erase(k)
99-
break
100-
end
101-
end
102-
for k,v in ipairs(fort_ent.hist_figures) do
103-
if v.id == hf_id then
104-
df.global.plotinfo.main.fortress_entity.hist_figures:erase(k)
105-
break
106-
end
107-
end
108-
for k,v in ipairs(fort_ent.nemesis) do
109-
if v.figure.id == hf_id then
110-
df.global.plotinfo.main.fortress_entity.nemesis:erase(k)
111-
df.global.plotinfo.main.fortress_entity.nemesis_ids:erase(k)
112-
break
113-
end
114-
end
115-
116-
-- remove the old entity link and create new one to indicate former membership
117-
hf.entity_links:insert("#", {new = df.histfig_entity_link_former_memberst, entity_id = fort_ent.id, link_strength = 100})
118-
for k,v in ipairs(hf.entity_links) do
119-
if v._type == df.histfig_entity_link_memberst and v.entity_id == fort_ent.id then
120-
hf.entity_links:erase(k)
121-
break
122-
end
123-
end
55+
unit_link_utils.removeUnitAssociations(u)
56+
unit_link_utils.removeHistFigFromEntity(hf, fort_ent)
12457

12558
-- try to find a new entity for the unit to join
126-
for k,v in ipairs(civ_ent.entity_links) do
127-
if v.type == df.entity_entity_link_type.CHILD and v.target ~= fort_ent.id then
128-
newent_id = v.target
59+
for _,entity_link in ipairs(civ_ent.entity_links) do
60+
if entity_link.type == df.entity_entity_link_type.CHILD and entity_link.target ~= fort_ent.id then
61+
newent_id = entity_link.target
12962
break
13063
end
13164
end
13265

13366
if newent_id > -1 then
134-
hf.entity_links:insert("#", {new = df.histfig_entity_link_memberst, entity_id = newent_id, link_strength = 100})
135-
13667
-- try to find a new site for the unit to join
137-
for k,v in ipairs(df.global.world.entities.all[hf.civ_id].site_links) do
68+
for _,site_link in ipairs(df.global.world.entities.all[hf.civ_id].site_links) do
13869
local site_id = df.global.plotinfo.site_id
139-
if v.type == df.entity_site_link_type.Claim and v.target ~= site_id then
140-
newsite_id = v.target
70+
if site_link.type == df.entity_site_link_type.Claim and site_link.target ~= site_id then
71+
newsite_id = site_link.target
14172
break
14273
end
14374
end
14475
local newent = df.historical_entity.find(newent_id)
145-
newent.histfig_ids:insert('#', hf_id)
146-
newent.hist_figures:insert('#', hf)
147-
local hf_event_id = df.global.hist_event_next_id
148-
df.global.hist_event_next_id = df.global.hist_event_next_id+1
149-
df.global.world.history.events:insert("#", {new = df.history_event_add_hf_entity_linkst, year = df.global.cur_year, seconds = df.global.cur_year_tick, id = hf_event_id, civ = newent_id, histfig = hf_id, link_type = 0})
150-
if newsite_id > -1 then
151-
local hf_event_id = df.global.hist_event_next_id
152-
df.global.hist_event_next_id = df.global.hist_event_next_id+1
153-
df.global.world.history.events:insert("#", {new = df.history_event_change_hf_statest, year = df.global.cur_year, seconds = df.global.cur_year_tick, id = hf_event_id, hfid = hf_id, state = 1, reason = -1, site = newsite_id})
154-
end
76+
unit_link_utils.addHistFigToSite(hf, newsite_id, newent)
15577
end
15678
print(dfhack.df2console(line))
15779
dfhack.gui.showAnnouncement(line, COLOR_WHITE)
@@ -251,6 +173,9 @@ if args[1] == "enable" then
251173
state.enabled = true
252174
elseif args[1] == "disable" then
253175
state.enabled = false
176+
elseif args[1] == "nobles" then
177+
table.remove(args, 1)
178+
nobles.run(args)
254179
else
255180
print('emigration is ' .. (state.enabled and 'enabled' or 'not enabled'))
256181
return

0 commit comments

Comments
 (0)