diff --git a/changelog.txt b/changelog.txt index f2343400c6..18c2b90191 100644 --- a/changelog.txt +++ b/changelog.txt @@ -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 diff --git a/fix/loyaltycascade.lua b/fix/loyaltycascade.lua index a3b7090880..27ebbe0f04 100644 --- a/fix/loyaltycascade.lua +++ b/fix/loyaltycascade.lua @@ -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 @@ -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 diff --git a/makeown.lua b/makeown.lua index cbfe3433aa..998916293e 100644 --- a/makeown.lua +++ b/makeown.lua @@ -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 @@ -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) @@ -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 @@ -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)