Skip to content

Commit 196f017

Browse files
authored
Merge pull request #1339 from NicksWorld/geldfix
Fix permanence of ungeld
2 parents d61fc69 + f2e10c3 commit 196f017

2 files changed

Lines changed: 60 additions & 40 deletions

File tree

changelog.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ Template for new versions:
4141
- `control-panel`: fix setting numeric preferences from the commandline
4242
- `gui/quickfort`: fix build mode evluation rules to allow placement of various furniture and constructions on tiles with stair shapes or without orthagonal floor.
4343
- `emigration`: save-and-reload no longer resets the emigration cycle timeout, making gameplay more consistent
44-
- `rejuvenate`: ``--age`` no longer throws the error ``attempt to compare string with number``
44+
- `geld`, `ungeld`: fix gelding/ungelding being undone for units who are historical figures when reloading a game
45+
- `rejuvenate`: fix error when specifying ``--age`` parameter
4546

4647
## Misc Improvements
4748
- `control-panel`: Add realistic-melting tweak to control-panel registry

geld.lua

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
utils = require('utils')
1+
local utils = require('utils')
22

33
local validArgs = utils.invert({
44
'unit',
55
'toggle',
66
'ungeld',
77
'help',
8-
'find',
98
})
109
local args = utils.processArgs({...}, validArgs)
1110

12-
unit=nil
11+
local unit = nil
1312

1413
if args.help then
1514
print(dfhack.script_help())
@@ -21,7 +20,7 @@ if args.unit then
2120
if id then
2221
unit = df.unit.find(id)
2322
else
24-
qerror("Invalid ID provided.")
23+
qerror("Invalid unit ID provided.")
2524
end
2625
else
2726
unit = dfhack.gui.getSelectedUnit()
@@ -32,55 +31,75 @@ if not unit then
3231
end
3332

3433
if unit.sex == df.pronoun_type.she then
35-
qerror("Cannot geld female animals")
36-
return
34+
qerror("Cannot geld female animals.")
3735
end
3836

39-
function FindBodyPart(unit,newstate)
40-
bfound = false
41-
for i,wound in ipairs(unit.body.wounds) do
42-
for j,part in ipairs(wound.parts) do
43-
if unit.body.wounds[i].parts[j].flags2.gelded ~= newstate then
44-
bfound = true
45-
if newstate ~= nil then
46-
unit.body.wounds[i].parts[j].flags2.gelded = newstate
47-
end
48-
end
37+
-- Find the geldable body part id, returns -1 on failure
38+
local function FindBodyPartId(unit)
39+
for i,part in ipairs(unit.body.body_plan.body_parts) do
40+
if part.flags.GELDABLE then
41+
return i
4942
end
5043
end
51-
return bfound
44+
return -1
5245
end
5346

54-
function AddParts(unit)
55-
for i,wound in ipairs(unit.body.wounds) do
56-
if wound.id == 1 and #wound.parts == 0 then
57-
utils.insert_or_update(unit.body.wounds[i].parts,{ new = true, body_part_id = 1 }, 'body_part_id')
58-
end
47+
-- Sets the gelded status of a unit, returns false on failure
48+
local function SetGelded(unit, state)
49+
-- Gelded status is set in a number of places:
50+
-- unit.flags3
51+
-- unit.body.wounds
52+
-- unit.body.components.body_part_status
53+
54+
local part_id = FindBodyPartId(unit)
55+
if part_id == -1 then
56+
print("Could not find a geldable body part.")
57+
return false
5958
end
60-
end
6159

62-
function Geld(unit)
63-
unit.flags3.gelded = true
64-
if not FindBodyPart(unit,true) then
65-
utils.insert_or_update(unit.body.wounds,{ new = true, id = unit.body.wound_next_id }, 'id')
60+
unit.flags3.gelded = state
61+
62+
if state then
63+
-- Create new wound
64+
local _,wound,_ = utils.insert_or_update(unit.body.wounds, { new = true, id = unit.body.wound_next_id }, 'id')
6665
unit.body.wound_next_id = unit.body.wound_next_id + 1
67-
AddParts(unit)
68-
if not FindBodyPart(unit,true) then
69-
error("could not find body part")
66+
local _,part,_ = utils.insert_or_update(wound.parts, { new = true, body_part_id = part_id}, 'body_part_id')
67+
part.flags2.gelded = true
68+
else
69+
-- Remove gelding from any existing wounds
70+
for _,wound in ipairs(unit.body.wounds) do
71+
for _,part in ipairs(wound.parts) do
72+
part.flags2.gelded = false
73+
end
7074
end
7175
end
72-
print(string.format("unit %s gelded.",unit.id))
76+
77+
if state then
78+
-- Set part status to gelded
79+
unit.body.components.body_part_status[part_id].gelded = true
80+
else
81+
-- Remove gelded status from all parts
82+
for _,part in ipairs(unit.body.components.body_part_status) do
83+
part.gelded = false
84+
end
85+
end
86+
return true
7387
end
7488

75-
function Ungeld(unit)
76-
unit.flags3.gelded = false
77-
FindBodyPart(unit,false)
78-
print(string.format("unit %s ungelded.",unit.id))
89+
local function Geld(unit)
90+
if SetGelded(unit, true) then
91+
print(string.format("Unit %s gelded.", unit.id))
92+
else
93+
print(string.format("Failed to geld unit %s.", unit.id))
94+
end
7995
end
8096

81-
if args.find then
82-
print(FindBodyPart(unit) and "found" or "not found")
83-
return
97+
local function Ungeld(unit)
98+
if SetGelded(unit, false) then
99+
print(string.format("Unit %s ungelded.", unit.id))
100+
else
101+
print(string.format("Failed to ungeld unit %s.", unit.id))
102+
end
84103
end
85104

86105
local oldstate = dfhack.units.isGelded(unit)
@@ -101,5 +120,5 @@ if newstate ~= oldstate then
101120
Ungeld(unit)
102121
end
103122
else
104-
qerror(string.format("unit %s is already %s", unit.id, oldstate and "gelded" or "ungelded"))
123+
qerror(string.format("Unit %s is already %s.", unit.id, oldstate and "gelded" or "ungelded"))
105124
end

0 commit comments

Comments
 (0)