Skip to content

Commit a8b2f21

Browse files
committed
prioritize high-value meals and don't go eating or drinking on a full stomach
1 parent 8a3b92b commit a8b2f21

2 files changed

Lines changed: 42 additions & 8 deletions

File tree

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Template for new versions:
3636
- `gui/journal`: fix typo which caused the table of contents to always be regenerated even when not needed
3737
- `gui/mod-manager`: gracefully handle mods with missing or broken ``info.txt`` files
3838
- `uniform-unstick`: resolve overlap with new buttons in 51.13
39+
- `immortal-cravings`: prioritize high-value meals and don't go eating or drinking on a full stomach
3940

4041
## Misc Improvements
4142

immortal-cravings.lua

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,27 @@ function distance(p1, p2)
1313
return math.max(math.abs(p1.x - p2.x), math.abs(p1.y - p2.y)) + math.abs(p1.z - p2.z)
1414
end
1515

16+
---find best item in an item vector (according to some metric)
17+
---@generic T : df.item
18+
---@param item_vector T[]
19+
---@param metric fun(item: T): number
20+
---@param is_good? fun(item: T): boolean
21+
---@return T?
22+
function findBest(item_vector, metric, is_good)
23+
local best = nil
24+
local mbest = -1
25+
for _,item in ipairs(item_vector) do
26+
if not item.flags.in_job and (not is_good or is_good(item)) then
27+
mitem = metric(item)
28+
if not best or mitem > mbest then
29+
best = item
30+
mbest = mitem
31+
end
32+
end
33+
end
34+
return best
35+
end
36+
1637
---find closest accessible item in an item vector
1738
---@generic T : df.item
1839
---@param pos df.coord
@@ -46,19 +67,28 @@ local function get_closest_drink(pos)
4667
return findClosest(pos, df.global.world.items.other.DRINK, is_good)
4768
end
4869

49-
---find some prepared meal
70+
---find highest-value accessible meal
5071
---@return df.item_foodst?
51-
local function get_closest_meal(pos)
72+
local function get_best_meal(pos)
73+
5274
---@param meal df.item_foodst
5375
local function is_good(meal)
54-
if meal.flags.rotten then
76+
local accessible = dfhack.maps.canWalkBetween(pos,xyz2pos(dfhack.items.getPosition(meal)))
77+
if meal.flags.rotten or not accessible then
5578
return false
5679
else
80+
-- check that meal is either on the ground or in food storage (and not in a backpack)
5781
local container = dfhack.items.getContainer(meal)
5882
return not container or container:isFoodStorage()
5983
end
6084
end
61-
return findClosest(pos, df.global.world.items.other.FOOD, is_good)
85+
86+
---@param meal df.item_foodst
87+
local function portion_value(meal)
88+
return dfhack.items.getValue(meal) / meal.stack_size
89+
end
90+
91+
return findBest(df.global.world.items.other.FOOD, portion_value, is_good)
6292
end
6393

6494
---create a Drink job for the given unit
@@ -86,7 +116,7 @@ end
86116
---create Eat job for the given unit
87117
---@param unit df.unit
88118
local function goEat(unit)
89-
local meal = get_closest_meal(unit.pos)
119+
local meal = get_best_meal(unit.pos)
90120
if not meal then
91121
-- print('no accessible meals found')
92122
return
@@ -181,12 +211,15 @@ local function main_loop()
181211
-- print('immortal-cravings watching:')
182212
watched = {}
183213
for _, unit in ipairs(dfhack.units.getCitizens()) do
184-
if not is_active_caste_flag(unit, 'NO_DRINK') and not is_active_caste_flag(unit, 'NO_EAT') then
214+
if
215+
not (is_active_caste_flag(unit, 'NO_DRINK') or is_active_caste_flag(unit, 'NO_EAT')) or
216+
unit.counters2.stomach_content > 0
217+
then
185218
goto next_unit
186219
end
187220
for _, need in ipairs(unit.status.current_soul.personality.needs) do
188-
if need.id == DrinkAlcohol and need.focus_level < threshold or
189-
need.id == EatGoodMeal and need.focus_level < threshold
221+
if need.id == DrinkAlcohol and need.focus_level < threshold or
222+
need.id == EatGoodMeal and need.focus_level < threshold
190223
then
191224
table.insert(watched, unit.id)
192225
-- print(' '..dfhack.df2console(dfhack.units.getReadableName(unit)))

0 commit comments

Comments
 (0)