From 157007f0f443c785b760d17c6a970ec6fbc177a1 Mon Sep 17 00:00:00 2001 From: Nicholas McDaniel Date: Mon, 25 Nov 2024 22:53:13 -0500 Subject: [PATCH 1/2] Update geld to set body_part_status, cleanup implementation --- changelog.txt | 1 + geld.lua | 96 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 60 insertions(+), 37 deletions(-) diff --git a/changelog.txt b/changelog.txt index fc7ee69c1..6e7850901 100644 --- a/changelog.txt +++ b/changelog.txt @@ -41,6 +41,7 @@ Template for new versions: - `control-panel`: fix setting numeric preferences from the commandline - `gui/quickfort`: fix build mode evluation rules to allow placement of various furniture and constructions on tiles with stair shapes or without orthagonal floor. - `emigration`: save-and-reload no longer resets the emigration cycle timeout, making gameplay more consistent +- `geld`/`ungeld`: fix permanence of gelding/ungelding status ## Misc Improvements - `control-panel`: Add realistic-melting tweak to control-panel registry diff --git a/geld.lua b/geld.lua index ff5044449..aada87249 100644 --- a/geld.lua +++ b/geld.lua @@ -5,11 +5,10 @@ local validArgs = utils.invert({ 'toggle', 'ungeld', 'help', - 'find', }) local args = utils.processArgs({...}, validArgs) -unit=nil +local unit = nil if args.help then print(dfhack.script_help()) @@ -21,7 +20,8 @@ if args.unit then if id then unit = df.unit.find(id) else - qerror("Invalid ID provided.") + qerror("Invalid unit ID provided.") + return end else unit = dfhack.gui.getSelectedUnit() @@ -29,58 +29,80 @@ end if not unit then qerror("Invalid unit selection.") + return end if unit.sex == df.pronoun_type.she then - qerror("Cannot geld female animals") + qerror("Cannot geld female animals.") return end -function FindBodyPart(unit,newstate) - bfound = false - for i,wound in ipairs(unit.body.wounds) do - for j,part in ipairs(wound.parts) do - if unit.body.wounds[i].parts[j].flags2.gelded ~= newstate then - bfound = true - if newstate ~= nil then - unit.body.wounds[i].parts[j].flags2.gelded = newstate - end - end +-- Find the geldable body part id, returns -1 on failure +local function FindBodyPartId(unit) + for i,part in ipairs(unit.body.body_plan.body_parts) do + if part.flags.GELDABLE then + return i end end - return bfound + return -1 end -function AddParts(unit) - for i,wound in ipairs(unit.body.wounds) do - if wound.id == 1 and #wound.parts == 0 then - utils.insert_or_update(unit.body.wounds[i].parts,{ new = true, body_part_id = 1 }, 'body_part_id') - end +-- Sets the gelded status of a unit, returns false on failure +local function SetGelded(unit, state) + -- Gelded status is set in a number of places: + -- unit.flags3 + -- unit.body.wounds + -- unit.body.components.body_part_status + + local part_id = FindBodyPartId(unit) + if part_id == -1 then + print("Could not find a geldable body part.") + return false end -end -function Geld(unit) - unit.flags3.gelded = true - if not FindBodyPart(unit,true) then - utils.insert_or_update(unit.body.wounds,{ new = true, id = unit.body.wound_next_id }, 'id') + unit.flags3.gelded = state + + if state then + -- Create new wound + local _,wound,_ = utils.insert_or_update(unit.body.wounds, { new = true, id = unit.body.wound_next_id }, 'id') unit.body.wound_next_id = unit.body.wound_next_id + 1 - AddParts(unit) - if not FindBodyPart(unit,true) then - error("could not find body part") + local _,part,_ = utils.insert_or_update(wound.parts, { new = true, body_part_id = part_id}, 'body_part_id') + part.flags2.gelded = true + else + -- Remove gelding from any existing wounds + for _,wound in ipairs(unit.body.wounds) do + for _,part in ipairs(wound.parts) do + part.flags2.gelded = false + end end end - print(string.format("unit %s gelded.",unit.id)) + + if state then + -- Set part status to gelded + unit.body.components.body_part_status[part_id].gelded = true + else + -- Remove gelded status from all parts + for _,part in ipairs(unit.body.components.body_part_status) do + part.gelded = false + end + end + return true end -function Ungeld(unit) - unit.flags3.gelded = false - FindBodyPart(unit,false) - print(string.format("unit %s ungelded.",unit.id)) +local function Geld(unit) + if SetGelded(unit, true) then + print(string.format("Unit %s gelded.", unit.id)) + else + print(string.format("Failed to geld unit %s.", unit.id)) + end end -if args.find then - print(FindBodyPart(unit) and "found" or "not found") - return +local function Ungeld(unit) + if SetGelded(unit, false) then + print(string.format("Unit %s ungelded.", unit.id)) + else + print(string.format("Failed to ungeld unit %s.", unit.id)) + end end local oldstate = dfhack.units.isGelded(unit) @@ -101,5 +123,5 @@ if newstate ~= oldstate then Ungeld(unit) end else - qerror(string.format("unit %s is already %s", unit.id, oldstate and "gelded" or "ungelded")) + qerror(string.format("Unit %s is already %s.", unit.id, oldstate and "gelded" or "ungelded")) end From 4062ac8b1d038a119f7a8cdbc2479eea62d173c6 Mon Sep 17 00:00:00 2001 From: Nicholas McDaniel Date: Thu, 28 Nov 2024 10:53:25 -0500 Subject: [PATCH 2/2] Minor cleanup --- geld.lua | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/geld.lua b/geld.lua index aada87249..7b55cdb50 100644 --- a/geld.lua +++ b/geld.lua @@ -1,4 +1,4 @@ -utils = require('utils') +local utils = require('utils') local validArgs = utils.invert({ 'unit', @@ -21,7 +21,6 @@ if args.unit then unit = df.unit.find(id) else qerror("Invalid unit ID provided.") - return end else unit = dfhack.gui.getSelectedUnit() @@ -29,12 +28,10 @@ end if not unit then qerror("Invalid unit selection.") - return end if unit.sex == df.pronoun_type.she then qerror("Cannot geld female animals.") - return end -- Find the geldable body part id, returns -1 on failure