Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

emigrate nobles #1382

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
973b5e8
Add emigrate-nobles.lua and rst
ong-yinggao98 Jan 26, 2025
7a8f07e
Add logic for finding noble's sites
ong-yinggao98 Jan 27, 2025
414111e
Add monarch handling logic
ong-yinggao98 Jan 28, 2025
16f5939
Add emigration logic
ong-yinggao98 Jan 28, 2025
c110f25
Add announcement
ong-yinggao98 Jan 28, 2025
2d6e588
Add options handling
ong-yinggao98 Jan 29, 2025
fe549d9
Add documentation
ong-yinggao98 Jan 29, 2025
9777b1a
Attempt to fix units stuck in social activities
ong-yinggao98 Jan 29, 2025
16544b2
Fix title underline
ong-yinggao98 Jan 30, 2025
537af8e
Simplify logic
ong-yinggao98 Jan 30, 2025
ebc3976
Update docs/emigrate-nobles.rst
ong-yinggao98 Jan 30, 2025
4272ee7
Update docs/emigrate-nobles.rst
ong-yinggao98 Jan 30, 2025
8de561e
Update docs/emigrate-nobles.rst
ong-yinggao98 Jan 30, 2025
18a28d5
Update docs/emigrate-nobles.rst
ong-yinggao98 Jan 30, 2025
3b40700
Add functionality to remove from squad
ong-yinggao98 Jan 30, 2025
c521f5f
Remove squad removal logic
ong-yinggao98 Feb 7, 2025
fdb1698
Remove unused function
ong-yinggao98 Feb 7, 2025
c4ac1d6
Move emigrate-nobles into emigration
ong-yinggao98 Feb 7, 2025
b2ad9d1
Move emigrate-nobles.rst into emigration.rst
ong-yinggao98 Feb 7, 2025
07e6330
Update docs/emigration.rst
ong-yinggao98 Feb 8, 2025
39dac77
Update internal/emigration/emigrate-nobles.lua
ong-yinggao98 Feb 8, 2025
a6d65e4
Remove module globals
ong-yinggao98 Feb 8, 2025
b1cefb2
Fix pair iteration
ong-yinggao98 Feb 8, 2025
ecd42a5
Refactor logic
ong-yinggao98 Feb 8, 2025
ec335cb
Refactor emigration logic
ong-yinggao98 Feb 8, 2025
32afe4e
Fix stupid typo
ong-yinggao98 Feb 8, 2025
4fefcfb
Fix stupid typo
ong-yinggao98 Feb 8, 2025
4419093
Fix import error
ong-yinggao98 Feb 8, 2025
2b42b13
Add support for current unit
ong-yinggao98 Feb 8, 2025
64c5b64
Disable cancelling special jobs
ong-yinggao98 Feb 8, 2025
16ff909
Add mandate removal logic
ong-yinggao98 Feb 9, 2025
1fa7b04
Add check for fort admins
ong-yinggao98 Feb 9, 2025
5501751
Add signposts for navigation
ong-yinggao98 Feb 9, 2025
dd2718e
Change isAdministrator
ong-yinggao98 Feb 9, 2025
23728b8
Add support for other civ monarchs, change print messages
ong-yinggao98 Feb 9, 2025
161207e
Add support for evicting noble mayors
ong-yinggao98 Feb 10, 2025
fb8d15e
Add symbol dropping logic
ong-yinggao98 Feb 10, 2025
5569bb0
Update TODO
ong-yinggao98 Feb 10, 2025
16b4fe9
Update docs/emigration.rst
ong-yinggao98 Feb 10, 2025
bce191d
Fix bad mayor assignment logic
ong-yinggao98 Feb 10, 2025
3c71aeb
Update for new structures, add missing event
ong-yinggao98 Feb 11, 2025
bd58a05
Fix incorrect history event
ong-yinggao98 Feb 11, 2025
a69dc66
Update styling of new links and events
ong-yinggao98 Feb 11, 2025
5049178
Merge branch 'master' into noble-emigration
myk002 Feb 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions docs/emigration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,44 @@ even in the company of a visiting elven bard!
The check is made monthly. A happy dwarf (i.e. with negative stress) will never
emigrate.

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

Usage
-----

::

enable emigration
emigration nobles [--list]
emigration nobles [<target>]

Examples
--------

``emigration nobles``
Emigrate the selected noble if it does not rule your fortress.
If no unit is selected, list all nobles that do not rule your fortress.
``emigration nobles --list``
List all nobles that do not rule your fortress. Nobles that cannot be emigrated
(see above) will have a ``!`` indicator while nobles holding elected positions
will have a ``*`` indicator.
``emigration nobles --all``
Emigrate all nobles that do not rule your fortress.
``emigration nobles --unit 34534``
Emigrate a noble matching the specified unit ID that does not rule your fortress.

Options
-------

These options are exclusive to the ``emigration nobles`` command.

``-l``, ``--list``
List all nobles that do not rule your fortress
``-a``, ``--all``
Emigrate all nobles do not rule your fortress
``-u``, ``--unit <id>``
Emigrate noble matching specified unit ID that does not rule your fortress
111 changes: 18 additions & 93 deletions emigration.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

local utils = require('utils')

local nobles = reqscript('internal/emigration/emigrate-nobles')
local unit_link_utils = reqscript('internal/emigration/unit-link-utils')

local GLOBAL_KEY = 'emigration' -- used for state change hooks and persistence

local function get_default_state()
Expand Down Expand Up @@ -37,121 +40,40 @@ function desert(u,method,civ)
local line = dfhack.units.getReadableName(u) .. " has "
if method == 'merchant' then
line = line.."joined the merchants"
u.flags1.merchant = true
u.civ_id = civ
unit_link_utils.markUnitForEmigration(u, civ, false)
else
line = line.."abandoned the settlement in search of a better life."
u.civ_id = civ
u.flags1.forest = true
u.flags2.visitor = true
u.animal.leave_countdown = 2
unit_link_utils.markUnitForEmigration(u, civ, true)
end
local hf_id = u.hist_figure_id

local hf = df.historical_figure.find(u.hist_figure_id)
local fort_ent = df.global.plotinfo.main.fortress_entity
local civ_ent = df.historical_entity.find(hf.civ_id)
local newent_id = -1
local newsite_id = -1

-- free owned rooms
for i = #u.owned_buildings-1, 0, -1 do
local temp_bld = df.building.find(u.owned_buildings[i].id)
dfhack.buildings.setOwner(temp_bld, nil)
end

-- remove from workshop profiles
for _, bld in ipairs(df.global.world.buildings.other.WORKSHOP_ANY) do
for k, v in ipairs(bld.profile.permitted_workers) do
if v == u.id then
bld.profile.permitted_workers:erase(k)
break
end
end
end
for _, bld in ipairs(df.global.world.buildings.other.FURNACE_ANY) do
for k, v in ipairs(bld.profile.permitted_workers) do
if v == u.id then
bld.profile.permitted_workers:erase(k)
break
end
end
end

-- disassociate from work details
for _, detail in ipairs(df.global.plotinfo.labor_info.work_details) do
for k, v in ipairs(detail.assigned_units) do
if v == u.id then
detail.assigned_units:erase(k)
break
end
end
end

-- unburrow
for _, burrow in ipairs(df.global.plotinfo.burrows.list) do
dfhack.burrows.setAssignedUnit(burrow, u, false)
end

-- erase the unit from the fortress entity
for k,v in ipairs(fort_ent.histfig_ids) do
if v == hf_id then
df.global.plotinfo.main.fortress_entity.histfig_ids:erase(k)
break
end
end
for k,v in ipairs(fort_ent.hist_figures) do
if v.id == hf_id then
df.global.plotinfo.main.fortress_entity.hist_figures:erase(k)
break
end
end
for k,v in ipairs(fort_ent.nemesis) do
if v.figure.id == hf_id then
df.global.plotinfo.main.fortress_entity.nemesis:erase(k)
df.global.plotinfo.main.fortress_entity.nemesis_ids:erase(k)
break
end
end

-- remove the old entity link and create new one to indicate former membership
hf.entity_links:insert("#", {new = df.histfig_entity_link_former_memberst, entity_id = fort_ent.id, link_strength = 100})
for k,v in ipairs(hf.entity_links) do
if v._type == df.histfig_entity_link_memberst and v.entity_id == fort_ent.id then
hf.entity_links:erase(k)
break
end
end
unit_link_utils.removeUnitAssociations(u)
unit_link_utils.removeHistFigFromEntity(hf, fort_ent)

-- try to find a new entity for the unit to join
for k,v in ipairs(civ_ent.entity_links) do
if v.type == df.entity_entity_link_type.CHILD and v.target ~= fort_ent.id then
newent_id = v.target
for _,entity_link in ipairs(civ_ent.entity_links) do
if entity_link.type == df.entity_entity_link_type.CHILD and entity_link.target ~= fort_ent.id then
newent_id = entity_link.target
break
end
end

if newent_id > -1 then
hf.entity_links:insert("#", {new = df.histfig_entity_link_memberst, entity_id = newent_id, link_strength = 100})

-- try to find a new site for the unit to join
for k,v in ipairs(df.global.world.entities.all[hf.civ_id].site_links) do
for _,site_link in ipairs(df.global.world.entities.all[hf.civ_id].site_links) do
local site_id = df.global.plotinfo.site_id
if v.type == df.entity_site_link_type.Claim and v.target ~= site_id then
newsite_id = v.target
if site_link.type == df.entity_site_link_type.Claim and site_link.target ~= site_id then
newsite_id = site_link.target
break
end
end
local newent = df.historical_entity.find(newent_id)
newent.histfig_ids:insert('#', hf_id)
newent.hist_figures:insert('#', hf)
local hf_event_id = df.global.hist_event_next_id
df.global.hist_event_next_id = df.global.hist_event_next_id+1
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})
if newsite_id > -1 then
local hf_event_id = df.global.hist_event_next_id
df.global.hist_event_next_id = df.global.hist_event_next_id+1
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})
end
unit_link_utils.addHistFigToSite(hf, newsite_id, newent)
end
print(dfhack.df2console(line))
dfhack.gui.showAnnouncement(line, COLOR_WHITE)
Expand Down Expand Up @@ -251,6 +173,9 @@ if args[1] == "enable" then
state.enabled = true
elseif args[1] == "disable" then
state.enabled = false
elseif args[1] == "nobles" then
table.remove(args, 1)
nobles.run(args)
else
print('emigration is ' .. (state.enabled and 'enabled' or 'not enabled'))
return
Expand Down
Loading