Skip to content

Commit a6cdf8c

Browse files
authored
Merge pull request #1295 from myk002/myk_rejuvenate
[rejuvenate]: ensure histfig data stays consistent and respect age-related caste data per race
2 parents 64af1a4 + f8a4753 commit a6cdf8c

File tree

4 files changed

+82
-40
lines changed

4 files changed

+82
-40
lines changed

armoks-blessing.lua

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,9 @@
11
-- Adjust all attributes of all dwarves to an ideal
22
-- by vjek
33

4+
local rejuvenate = reqscript('rejuvenate')
45
local utils = require('utils')
56

6-
function rejuvenate(unit)
7-
if unit==nil then
8-
print ("No unit available! Aborting with extreme prejudice.")
9-
return
10-
end
11-
12-
local current_year=df.global.cur_year
13-
local newbirthyear=current_year - 20
14-
if unit.birth_year < newbirthyear then
15-
unit.birth_year=newbirthyear
16-
end
17-
if unit.old_year < current_year+100 then
18-
unit.old_year=current_year+100
19-
end
20-
21-
end
227
-- ---------------------------------------------------------------------------
238
function brainwash_unit(unit)
249
if unit==nil then
@@ -251,7 +236,7 @@ function adjust_all_dwarves(skillname)
251236
print("Adjusting "..dfhack.df2console(dfhack.TranslateName(dfhack.units.getVisibleName(v))))
252237
brainwash_unit(v)
253238
elevate_attributes(v)
254-
rejuvenate(v)
239+
rejuvenate.rejuvenate(v, true)
255240
if skillname then
256241
if df.job_skill_class[skillname] then
257242
LegendaryByClass(skillname,v)

changelog.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Template for new versions:
4545
- `deep-embark`: fix error when embarking where there is no land to stand on (e.g. when embarking in the ocean with `gui/embark-anywhere`)
4646
- `deep-embark`: fix failure to transport units and items when embarking where there is no room to spawn the starting wagon
4747
- `gui/create-item`, `modtools/create-item`: items of type "VERMIN", "PET", "REMANS", "FISH", "RAW FISH", and "EGG" no longer spawn creature item "nothing" and will now stack correctly
48+
- `rejuvenate`: don't set a lifespan limit for creatures that are immortal (e.g. elves, goblins)
49+
- `rejuvenate`: properly disconnect babies from mothers when aging babies up to adults
4850

4951
## Misc Improvements
5052
- `gui/sitemap`: show whether a unit is friendly, hostile, or wild

docs/rejuvenate.rst

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ rejuvenate
66
:tags: fort armok units
77

88
If your most valuable citizens are getting old, this tool can save them. It
9-
decreases the age of the selected dwarf to 20 years, or to the age specified.
10-
Age is only increased using the --force option.
9+
decreases the age of the selected dwarf to the minimum adult age, or to the age
10+
specified. Age can only be increased (e.g. when this tool is run on babies or
11+
children) if the ``--force`` option is specified.
1112

1213
Usage
1314
-----
@@ -20,23 +21,27 @@ Examples
2021
--------
2122

2223
``rejuvenate``
23-
Set the age of the selected dwarf to 20 (if they're older).
24+
Set the age of the selected dwarf to 18 (if they're older than 18). The
25+
target age may be different if you have modded dwarves to become an adult
26+
at a different age, or if you have selected a unit that is not a dwarf.
2427
``rejuvenate --all``
25-
Set the age of all dwarves over 20 to 20.
28+
Set the ages of all adult citizens and residents to their minimum adult
29+
ages.
2630
``rejuvenate --all --force``
27-
Set the age of all dwarves (including babies) to 20.
31+
Set the ages of all citizens and residents (including children and babies)
32+
to their minimum adult ages.
2833
``rejuvenate --age 149 --force``
2934
Set the age of the selected dwarf to 149, even if they are younger.
3035

3136
Options
3237
-------
3338

3439
``--all``
35-
Rejuvenate all citizens, not just the selected one.
40+
Rejuvenate all citizens and residents instead of a selected unit.
3641
``--age <num>``
37-
Sets the target to the age specified. If this is not set, the target age is 20.
42+
Sets the target to the age specified. If this is not set, the target age defaults to the minimum adult age for the unit.
3843
``--force``
39-
Set age for units under the specified age to the specified age. Useful if there are too
40-
many babies around...
44+
Set age for units under the specified age to the specified age. Useful if
45+
there are too many babies around...
4146
``--dry-run``
4247
Only list units that would be changed; don't actually change ages.

rejuvenate.lua

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,93 @@
1-
-- set age of selected unit
2-
-- by vjek
31
--@ module = true
42

53
local utils = require('utils')
64

7-
function rejuvenate(unit, force, dry_run, age)
8-
local current_year = df.global.cur_year
9-
if not age then
10-
age = 20
5+
local DEFAULT_CHILD_AGE = 18
6+
local DEFAULT_OLD_AGE = 160
7+
local ANY_BABY = df.global.world.units.other.ANY_BABY
8+
9+
local function get_caste_misc(unit)
10+
local cre = df.creature_raw.find(unit.race)
11+
if not cre then return end
12+
if unit.caste < 0 or unit.caste >= #cre.caste then
13+
return
1114
end
15+
return cre.caste[unit.caste].misc
16+
end
17+
18+
local function get_adult_age(misc)
19+
return misc and misc.child_age or DEFAULT_CHILD_AGE
20+
end
21+
22+
local function get_rand_old_age(misc)
23+
return misc and math.random(misc.maxage_min, misc.maxage_max) or DEFAULT_OLD_AGE
24+
end
25+
26+
-- called by armoks-blessing
27+
function rejuvenate(unit, quiet, force, dry_run, age)
28+
local name = dfhack.df2console(dfhack.units.getReadableName(unit))
29+
local misc = get_caste_misc(unit)
30+
local adult_age = get_adult_age(misc)
31+
age = age or adult_age
32+
if age < adult_age then
33+
dfhack.printerr('cannot set age to child or baby range')
34+
return
35+
end
36+
local current_year = df.global.cur_year
1237
local new_birth_year = current_year - age
13-
local name = dfhack.df2console(dfhack.TranslateName(dfhack.units.getVisibleName(unit)))
38+
local new_old_year = unit.old_year < 0 and -1 or math.max(unit.old_year, new_birth_year + get_rand_old_age(misc))
1439
if unit.birth_year > new_birth_year and not force then
15-
print(name .. ' is under ' .. age .. ' years old. Use --force to force.')
40+
if not quiet then
41+
dfhack.printerr(name .. ' is under ' .. age .. ' years old. Use --force to force.')
42+
end
1643
return
1744
end
1845
if dry_run then
1946
print('would change: ' .. name)
2047
return
2148
end
49+
50+
local hf = df.historical_figure.find(unit.hist_figure_id)
2251
unit.birth_year = new_birth_year
23-
if unit.old_year < new_birth_year + 160 then
24-
unit.old_year = new_birth_year + 160
25-
end
52+
if hf then hf.born_year = new_birth_year end
53+
unit.old_year = new_old_year
54+
if hf then hf.old_year = new_old_year end
55+
2656
if unit.profession == df.profession.BABY or unit.profession == df.profession.CHILD then
57+
if unit.profession == df.profession.BABY then
58+
local idx = utils.linear_index(ANY_BABY, unit.id, 'id')
59+
if idx then
60+
ANY_BABY:erase(idx)
61+
end
62+
unit.flags1.rider = false
63+
unit.relationship_ids.RiderMount = -1
64+
unit.mount_type = df.rider_positions_type.STANDARD
65+
unit.profession2 = df.profession.STANDARD
66+
unit.idle_area_type = df.unit_station_type.MillBuilding
67+
unit.mood = -1
68+
69+
-- let the mom know she isn't carrying anyone anymore
70+
local mother = df.unit.find(unit.relationship_ids.Mother)
71+
if mother then mother.flags1.ridden = false end
72+
end
2773
unit.profession = df.profession.STANDARD
74+
unit.profession2 = df.profession.STANDARD
75+
if hf then hf.profession = df.profession.STANDARD end
76+
end
77+
if not quiet then
78+
print(name .. ' is now ' .. age .. ' years old and will live a normal lifespan henceforth')
2879
end
29-
print(name .. ' is now ' .. age .. ' years old and will live to at least 160')
3080
end
3181

32-
function main(args)
82+
local function main(args)
3383
local units = {} --as:df.unit[]
3484
if args.all then
3585
units = dfhack.units.getCitizens()
3686
else
3787
table.insert(units, dfhack.gui.getSelectedUnit(true) or qerror("Please select a unit in the UI."))
3888
end
3989
for _, u in ipairs(units) do
40-
rejuvenate(u, args.force, args['dry-run'], args.age)
90+
rejuvenate(u, false, args.force, args['dry-run'], args.age)
4191
end
4292
end
4393

0 commit comments

Comments
 (0)