Skip to content

Commit eec7afc

Browse files
committed
remove unit from current conflict activities
1 parent 43948f3 commit eec7afc

File tree

5 files changed

+40
-5
lines changed

5 files changed

+40
-5
lines changed

changelog.txt

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Template for new versions:
3333
## Fixes
3434

3535
## Misc Improvements
36+
- `fix/loyaltycascade`: now also breaks up brawls and other intra-fort conflicts that *look* like loyalty cascades
37+
- `makeown`: remove selected unit from any current conflicts so they don't just start attacking other citizens when you make them a citizen of your fort
3638

3739
## Removed
3840

docs/fix/loyaltycascade.rst

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ fix/loyaltycascade
66
:tags: fort bugfix units
77

88
This tool neutralizes loyalty cascades by fixing units who consider their own
9-
civilization to be the enemy.
9+
civilization to be the enemy. It will also halt all fighting on the map that
10+
involves your citizens, though "real" enemies will re-engage in combat after a
11+
short delay.
1012

1113
Usage
1214
-----

docs/makeown.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ makeown
66
:tags: fort armok units
77

88
Select a unit in the UI and run this tool to converts that unit to be a fortress
9-
citizen (if sentient). It also removes their foreign affiliation, if any.
9+
citizen (if sentient). It also removes their foreign affiliation, if any, and
10+
removes the unit from any current conflict they are engaged in.
1011

1112
This tool also fixes :bug:`10921`, where you request workers from your
1213
holdings, but they come with the "Merchant" profession and are unable to

fix/loyaltycascade.lua

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
-- Prevents a "loyalty cascade" (intra-fort civil war) when a citizen is killed.
2+
-- Also breaks up brawls and other conflicts.
23

34
local makeown = reqscript('makeown')
45

@@ -76,7 +77,7 @@ local function fixUnit(unit)
7677
makeown.clear_enemy_status(unit)
7778
end
7879

79-
return false
80+
return makeown.remove_from_conflict(unit) or fixed
8081
end
8182

8283
local count = 0
@@ -87,7 +88,7 @@ for _, unit in pairs(dfhack.units.getCitizens()) do
8788
end
8889

8990
if count > 0 then
90-
print(('Fixed %s units from a loyalty cascade.'):format(count))
91+
print(('Fixed %s units with loyalty issues.'):format(count))
9192
else
9293
print('No loyalty cascade found.')
9394
end

makeown.lua

+30-1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,35 @@ function clear_enemy_status(unit)
8181
if status_cache.next_slot > status_slot then
8282
status_cache.next_slot = status_slot
8383
end
84+
85+
return true
86+
end
87+
88+
function remove_from_conflict(unit)
89+
-- Remove the unit from any conflict activity
90+
-- They will prompty re-engage if there is an actual enemy around
91+
local to_remove = {}
92+
for act_idx,act_id in ipairs(unit.activities) do
93+
local act = df.activity_entry.find(act_id)
94+
if not act or act.type ~= df.activity_entry_type.Conflict then goto continue end
95+
for _,ev in ipairs(act.events) do
96+
if ev:getType() ~= df.activity_event_type.Conflict then goto next_ev end
97+
for _,side in ipairs(ev.sides) do
98+
utils.erase_sorted(side.histfig_ids, unit.hist_figure_id)
99+
utils.erase_sorted(side.unit_ids, unit.id)
100+
end
101+
::next_ev::
102+
end
103+
table.insert(to_remove, 1, act_idx)
104+
::continue::
105+
end
106+
107+
for _,act_idx in ipairs(to_remove) do
108+
unit.activities:erase(act_idx)
109+
end
110+
111+
-- return whether we removed unit from any conflicts
112+
return #to_remove > 0
84113
end
85114

86115
local prof_map = {
@@ -162,7 +191,7 @@ local function fix_unit(unit)
162191
end
163192

164193
clear_enemy_status(unit)
165-
194+
remove_from_conflict(unit)
166195
cancel_hostile_jobs(unit.job.current_job)
167196
end
168197

0 commit comments

Comments
 (0)