From 205782938d22ef40eb9532fb5354fd952040f540 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Fri, 28 Jun 2024 18:59:21 +0300 Subject: [PATCH 1/8] makeown - fix army controller, enemy status slot and adjust professions (for now, added THIEF for goblin snatchers) --- makeown.lua | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/makeown.lua b/makeown.lua index cbfe3433aa..a212cde718 100644 --- a/makeown.lua +++ b/makeown.lua @@ -2,6 +2,11 @@ local utils = require('utils') +-- List of professions to convert From-To +local convert_professions = {} +convert_professions[df.profession.MERCHANT] = df.profession.TRADER +convert_professions[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 +81,41 @@ 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.profession2 = df.profession.STANDARD end + if convert_professions[unit.profession2] then unit.profession2 = df.profession.STANDARD end +end + +local function fix_army(unit) + -- Disassociate them from their army controller + 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 + + 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) @@ -205,6 +243,7 @@ function make_own(unit) dfhack.units.makeown(unit) fix_unit(unit) + fix_army(unit) fix_histfig(unit) fix_clothing_ownership(unit) From dcd26bb67513b372b4bec346c7e0af00b732a2dc Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Fri, 28 Jun 2024 19:13:19 +0300 Subject: [PATCH 2/8] Clear enemy-of-civ/group status on makeown-ed units --- makeown.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/makeown.lua b/makeown.lua index a212cde718..cb8faf2117 100644 --- a/makeown.lua +++ b/makeown.lua @@ -231,6 +231,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 From e41d38107d556f95b28bd4be2e4ee3e53fa533ca Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Fri, 28 Jun 2024 21:03:03 +0300 Subject: [PATCH 3/8] Flip the giants LARGE_PREDATOR caste flag off! --- makeown.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/makeown.lua b/makeown.lua index cb8faf2117..19c460e1b3 100644 --- a/makeown.lua +++ b/makeown.lua @@ -262,6 +262,8 @@ function make_own(unit) else unit.flags1.tame = true unit.training_level = df.animal_training_level.Domesticated + -- No more "vengeful" spam when civilizing Giants! + unit.enemy.caste_flags.LARGE_PREDATOR = false; end end From 5f57e531653e7abfea3b3b8f791b3c3d73896c41 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Wed, 3 Jul 2024 01:06:29 +0300 Subject: [PATCH 4/8] Revert "Flip the giants LARGE_PREDATOR caste flag off!" This reverts commit e41d38107d556f95b28bd4be2e4ee3e53fa533ca. --- makeown.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/makeown.lua b/makeown.lua index 19c460e1b3..cb8faf2117 100644 --- a/makeown.lua +++ b/makeown.lua @@ -262,8 +262,6 @@ function make_own(unit) else unit.flags1.tame = true unit.training_level = df.animal_training_level.Domesticated - -- No more "vengeful" spam when civilizing Giants! - unit.enemy.caste_flags.LARGE_PREDATOR = false; end end From 80502c9ee856021fa6c2043d5b201f9d0547864e Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 3 Jul 2024 01:11:58 +0300 Subject: [PATCH 5/8] Apply suggestions from code review Co-authored-by: Myk --- makeown.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/makeown.lua b/makeown.lua index cb8faf2117..564d95a194 100644 --- a/makeown.lua +++ b/makeown.lua @@ -3,9 +3,10 @@ local utils = require('utils') -- List of professions to convert From-To -local convert_professions = {} -convert_professions[df.profession.MERCHANT] = df.profession.TRADER -convert_professions[df.profession.THIEF] = df.profession.STANDARD +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 @@ -81,8 +82,8 @@ local function fix_unit(unit) unit.civ_id = df.global.plotinfo.civ_id; - if convert_professions[unit.profession] then unit.profession2 = df.profession.STANDARD end - if convert_professions[unit.profession2] then unit.profession2 = df.profession.STANDARD 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) From f81bcdce8a366af6e8e41899dffd8b22ba8fbeef Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Wed, 3 Jul 2024 01:20:40 +0300 Subject: [PATCH 6/8] fixUnitEnemyStatus as a module script yeeeeee --- fix/loyaltycascade.lua | 25 +++++-------------------- makeown.lua | 4 ++++ 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/fix/loyaltycascade.lua b/fix/loyaltycascade.lua index a3b7090880..0f17f3a263 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.fixUnitEnemyStatus(unit) end return false diff --git a/makeown.lua b/makeown.lua index 564d95a194..b3d481435d 100644 --- a/makeown.lua +++ b/makeown.lua @@ -95,7 +95,11 @@ local function fix_army(unit) unit.enemy.army_controller_id = -1 unit.enemy.army_controller = nil end + fixUnitEnemyStatus(unit) +end +-- Also used by the script fix/loyaltycascade +function fixUnitEnemyStatus(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 From b6f50f67755ec59bf7120be8a2613aa49b8690d3 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Wed, 3 Jul 2024 01:24:40 +0300 Subject: [PATCH 7/8] docs --- changelog.txt | 1 + 1 file changed, 1 insertion(+) 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 From 33cc4fc1709fb05b48ea8192fdb6288580cfe184 Mon Sep 17 00:00:00 2001 From: Alex Noir Date: Tue, 16 Jul 2024 13:48:17 +0300 Subject: [PATCH 8/8] Implement suggestions --- fix/loyaltycascade.lua | 2 +- makeown.lua | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fix/loyaltycascade.lua b/fix/loyaltycascade.lua index 0f17f3a263..27ebbe0f04 100644 --- a/fix/loyaltycascade.lua +++ b/fix/loyaltycascade.lua @@ -76,7 +76,7 @@ local function fixUnit(unit) end if fixed then - makeown.fixUnitEnemyStatus(unit) + makeown.clearUnitEnemyStatus(unit) end return false diff --git a/makeown.lua b/makeown.lua index b3d481435d..998916293e 100644 --- a/makeown.lua +++ b/makeown.lua @@ -88,6 +88,7 @@ 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 @@ -95,11 +96,11 @@ local function fix_army(unit) unit.enemy.army_controller_id = -1 unit.enemy.army_controller = nil end - fixUnitEnemyStatus(unit) + clearUnitEnemyStatus(unit) end -- Also used by the script fix/loyaltycascade -function fixUnitEnemyStatus(unit) +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