Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Template for new versions:

## Fixes

- `immortal-cravings`: also take care of immortal units with alcohol dependence

## Misc Improvements

## Removed
Expand Down
8 changes: 4 additions & 4 deletions docs/immortal-cravings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ immortal-cravings
:tags: fort gameplay

When enabled, this script watches your fort for units that have no physiological
need to eat or drink but still have personality needs that can only be satisfied
by eating or drinking (e.g. necromancers or goblins). This enables those units
to help themselves to a drink or a meal when they crave one and are not
otherwise occupied.
need to eat or drink but are still alcohol dependent or have personality needs
that can only be satisfied by eating or drinking (e.g. necromancers or goblins).
This enables those units to help themselves to a drink or a meal when they crave
one and are not otherwise occupied.

Usage
-----
Expand Down
42 changes: 31 additions & 11 deletions immortal-cravings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@

local repeatutil = require("repeat-util")

--- constants

local focus_threshold = -9000
local dependence_threshold = 33600 * 2

--- utility functions

local verbose = false
verbose = false
---conditional printing of debug messages
---@param message string
local function debug(message)
Expand Down Expand Up @@ -147,6 +152,19 @@ local function goEat(unit)
print(dfhack.df2console('immortal-cravings: %s is getting something to eat'):format(name))
end

---@param unit df.unit
---@param flag_name string
local function is_active_caste_flag(unit, flag_name)
return not unit.uwss_remove_caste_flag[flag_name] and
(unit.uwss_add_caste_flag[flag_name] or dfhack.units.casteFlagSet(unit.race, unit.caste, df.caste_raw_flags[flag_name]))
end

---@param unit df.unit
local function needs_alcohol(unit)
local mt = dfhack.units.getMiscTrait(unit, df.misc_trait_type.WantsDrink, false)
return mt and mt.value > dependence_threshold
end

--- script logic

local GLOBAL_KEY = 'immortal-cravings'
Expand Down Expand Up @@ -175,8 +193,6 @@ EatGoodMeal = df.need_type.EatGoodMeal
---@type integer[]
watched = watched or {}

local threshold = -9000

---unit loop: check for idle watched units and create eat/drink jobs for them
local function unit_loop()
debug(('immortal-cravings: running unit loop (%d watched units)'):format(#watched))
Expand All @@ -194,12 +210,18 @@ local function unit_loop()
debug("immortal-cravings: skipping busy"..dfhack.units.getReadableName(unit))
table.insert(kept, unit.id)
else
-- unit is available for jobs; satisfy one of its needs
-- unit is alcohol dependent and approaching withdrawal symptoms
if needs_alcohol(unit) then
goDrink(unit)
goto next_unit
end

-- otherwise satisfy a personality need
for _, need in ipairs(unit.status.current_soul.personality.needs) do
if need.id == DrinkAlcohol and need.focus_level < threshold then
if need.id == DrinkAlcohol and need.focus_level < focus_threshold then
goDrink(unit)
break
elseif need.id == EatGoodMeal and need.focus_level < threshold then
elseif need.id == EatGoodMeal and need.focus_level < focus_threshold then
goEat(unit)
break
end
Expand All @@ -214,10 +236,7 @@ local function unit_loop()
end
end

local function is_active_caste_flag(unit, flag_name)
return not unit.uwss_remove_caste_flag[flag_name] and
(unit.uwss_add_caste_flag[flag_name] or dfhack.units.casteFlagSet(unit.race, unit.caste, df.caste_raw_flags[flag_name]))
end


---main loop: look for citizens with personality needs for food/drink but w/o physiological need
local function main_loop()
Expand All @@ -227,7 +246,8 @@ local function main_loop()
if
(is_active_caste_flag(unit, 'NO_DRINK') or is_active_caste_flag(unit, 'NO_EAT')) and
unit.counters2.stomach_content == 0 and
dfhack.units.getFocusPenalty(unit, DrinkAlcohol, EatGoodMeal) < threshold
(dfhack.units.getFocusPenalty(unit, DrinkAlcohol, EatGoodMeal) < focus_threshold or
needs_alcohol(unit))
then
table.insert(watched, unit.id)
debug(' ' .. dfhack.df2console(dfhack.units.getReadableName(unit)))
Expand Down
Loading