Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Template for new versions:
- `gui/pathable`: new "Depot" mode that shows whether wagons can path to your trade depot
- `advtools`: automatically add a conversation option to "ask whereabouts of" for all your relationships (before, you could only ask whereabouts of people involved in rumors)
- `gui/design`: all-new visually-driven UI for much improved usability
- `makeown`: goblin snatchers and giants can now be makeown-ed more reliably

## Fixes
- `assign-profile`: fix handling of ``unit`` option for setting target unit id
Expand Down
25 changes: 5 additions & 20 deletions fix/loyaltycascade.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
--@module = true
-- Prevents a "loyalty cascade" (intra-fort civil war) when a citizen is killed.

-- Checks if a unit is a former member of a given entity as well as it's
-- current enemy.
local makeown = reqscript('makeown')

local function getUnitRenegade(unit, entity_id)
local unit_entity_links = df.historical_figure.find(unit.hist_figure_id).entity_links
local former_index = nil
Expand Down Expand Up @@ -72,26 +75,8 @@ local function fixUnit(unit)
fixed = true
end

if fixed and unit.enemy.enemy_status_slot ~= -1 then
local status_cache = df.global.world.enemy_status_cache
local status_slot = unit.enemy.enemy_status_slot

unit.enemy.enemy_status_slot = -1
status_cache.slot_used[status_slot] = false

for index, _ in pairs(status_cache.rel_map[status_slot]) do
status_cache.rel_map[status_slot][index] = -1
end

for index, _ in pairs(status_cache.rel_map) do
status_cache.rel_map[index][status_slot] = -1
end

-- TODO: what if there were status slots taken above status_slot?
-- does everything need to be moved down by one?
if status_cache.next_slot > status_slot then
status_cache.next_slot = status_slot
end
if fixed then
makeown.clearUnitEnemyStatus(unit)
end

return false
Expand Down
57 changes: 55 additions & 2 deletions makeown.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

local utils = require('utils')

-- List of professions to convert From-To
local convert_professions = {
[df.profession.MERCHANT]=df.profession.TRADER,
[df.profession.THIEF]=df.profession.STANDARD,
}

local function get_translation(race_id)
local race_name = df.global.world.raws.creatures.all[race_id].creature_id
for _,translation in ipairs(df.global.world.raws.language.translations) do
Expand Down Expand Up @@ -76,8 +82,46 @@ local function fix_unit(unit)

unit.civ_id = df.global.plotinfo.civ_id;

if unit.profession == df.profession.MERCHANT then unit.profession = df.profession.TRADER end
if unit.profession2 == df.profession.MERCHANT then unit.profession2 = df.profession.TRADER end
if convert_professions[unit.profession] then unit.profession = convert_professions[unit.profession] end
if convert_professions[unit.profession2] then unit.profession2 = convert_professions[unit.profession2] end
end

local function fix_army(unit)
-- Disassociate them from their army controller
-- TODO: Check of there is a membership list in the army itself that we need to scrub
if unit.enemy.army_controller then
if unit.enemy.army_controller.commander_hf == unit.hist_figure_id then
unit.enemy.army_controller.commander_hf = -1
end
unit.enemy.army_controller_id = -1
unit.enemy.army_controller = nil
end
clearUnitEnemyStatus(unit)
end

-- Also used by the script fix/loyaltycascade
function clearUnitEnemyStatus(unit)
if unit.enemy.enemy_status_slot ~= -1 then
local status_cache = df.global.world.enemy_status_cache
local status_slot = unit.enemy.enemy_status_slot

unit.enemy.enemy_status_slot = -1
status_cache.slot_used[status_slot] = false

for index, _ in pairs(status_cache.rel_map[status_slot]) do
status_cache.rel_map[status_slot][index] = -1
end

for index, _ in pairs(status_cache.rel_map) do
status_cache.rel_map[index][status_slot] = -1
end

-- TODO: what if there were status slots taken above status_slot?
-- does everything need to be moved down by one?
if status_cache.next_slot > status_slot then
status_cache.next_slot = status_slot
end
end
end

local function add_to_entity(hf, eid)
Expand Down Expand Up @@ -193,6 +237,14 @@ local function fix_histfig(unit)
entity_link(hf, eid, true, false, k)
::continue::
end
-- If you're makeown-ing an enemy of your civilization or group, people will feel vengeful without this
if df.histfig_entity_link_enemyst:is_instance(el) then
local eid = el.entity_id
if eid == civ_id or eid == group_id then
hf.entity_links:erase(k)
el:delete()
end
end
end

-- add them to our civ/site if they aren't already
Expand All @@ -205,6 +257,7 @@ function make_own(unit)
dfhack.units.makeown(unit)

fix_unit(unit)
fix_army(unit)
fix_histfig(unit)
fix_clothing_ownership(unit)

Expand Down