diff --git a/autocheese.lua b/autocheese.lua index 0e9fb5221..e9bdc146a 100644 --- a/autocheese.lua +++ b/autocheese.lua @@ -1,14 +1,12 @@ --@module = true -local ic = reqscript('idle-crafting') - ---make cheese using a specific barrel and workshop ---@param barrel df.item ---@param workshop df.building_workshopst ---@return df.job function makeCheese(barrel, workshop) ---@type df.job - local job = ic.make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.MakeCheese local jitem = df.job_item:new() @@ -22,29 +20,17 @@ function makeCheese(barrel, workshop) dfhack.error('could not attach item') end - ic.assignToWorkshop(job, workshop) + dfhack.job.assignToWorkshop(job, workshop) return job end - - ----unit is ready to take jobs +---checks that unit can path to workshop ---@param unit df.unit +---@param workshop df.building_workshopst ---@return boolean -function unitIsAvailable(unit) - if unit.job.current_job then - return false - elseif #unit.individual_drills > 0 then - return false - elseif unit.flags1.caged or unit.flags1.chained then - return false - elseif unit.military.squad_id ~= -1 then - local squad = df.squad.find(unit.military.squad_id) - -- this lookup should never fail - ---@diagnostic disable-next-line: need-check-nil - return #squad.orders == 0 and squad.activity == -1 - end - return true +function canAccessWorkshop(unit, workshop) + local workshop_position = xyz2pos(workshop.centerx, workshop.centery, workshop.z) + return dfhack.maps.canWalkBetween(unit.pos, workshop_position) end ---check if unit can perform labor at workshop @@ -54,8 +40,8 @@ end ---@return boolean function availableLaborer(unit, unit_labor, workshop) return unit.status.labors[unit_labor] - and unitIsAvailable(unit) - and ic.canAccessWorkshop(unit, workshop) + and dfhack.units.isJobAvailable(unit) + and canAccessWorkshop(unit, workshop) end ---find unit with a particular labor enabled diff --git a/changelog.txt b/changelog.txt index 5ecf8024e..6fc58b711 100644 --- a/changelog.txt +++ b/changelog.txt @@ -34,6 +34,9 @@ Template for new versions: ## Misc Improvements +- adapt Lua tools to use new API functionality for creating and assigning jobs +- `idle-crafting`: properly interrupt interruptible (i.e. "green") social activities + ## Removed # 52.03-r2 diff --git a/husbandry.lua b/husbandry.lua index cf8085746..9198013a1 100644 --- a/husbandry.lua +++ b/husbandry.lua @@ -4,9 +4,8 @@ local utils = require 'utils' local repeatutil = require("repeat-util") -local ic = reqscript('idle-crafting') -local verbose = true +local verbose = false ---conditional printing of debug messages ---@param message string local function debug(message) @@ -120,17 +119,17 @@ local function getAppropriateWorkshop(unit, collection) end local function shearCreature(unit, workshop) - local job = ic.make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.ShearCreature dfhack.job.addGeneralRef(job, df.general_ref_type.UNIT_SHEAREE, unit.id) - ic.assignToWorkshop(job, workshop) + dfhack.job.assignToWorkshop(job, workshop) end local function milkCreature(unit, workshop) - local job = ic.make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.MilkCreature dfhack.job.addGeneralRef(job, df.general_ref_type.UNIT_MILKEE, unit.id) - ic.assignToWorkshop(job, workshop) + dfhack.job.assignToWorkshop(job, workshop) end diff --git a/idle-crafting.lua b/idle-crafting.lua index 6744f02fd..e5d25751b 100644 --- a/idle-crafting.lua +++ b/idle-crafting.lua @@ -55,26 +55,12 @@ function weightedChoice(choices) return nil --never reached on well-formed input end ----create a new linked job ----@return df.job -function make_job() - local job = df.job:new() - dfhack.job.linkIntoWorld(job, true) - return job -end - -function assignToWorkshop(job, workshop) - job.pos = xyz2pos(workshop.centerx, workshop.centery, workshop.z) - dfhack.job.addGeneralRef(job, df.general_ref_type.BUILDING_HOLDER, workshop.id) - workshop.jobs:insert("#", job) -end - ---make totem at specified workshop ---@param unit df.unit ---@param workshop df.building_workshopst ---@return boolean function makeTotem(unit, workshop) - local job = make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.MakeTotem job.mat_type = -1 @@ -89,7 +75,7 @@ function makeTotem(unit, workshop) jitem.flags2.body_part = true job.job_items.elements:insert('#', jitem) - assignToWorkshop(job, workshop) + dfhack.job.assignToWorkshop(job, workshop) return dfhack.job.addWorker(job, unit) end @@ -98,7 +84,7 @@ end ---@param workshop df.building_workshopst ---@return boolean function makeHornCrafts(unit, workshop) - local job = make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.MakeCrafts job.mat_type = -1 job.material_category.horn = true @@ -114,7 +100,7 @@ function makeHornCrafts(unit, workshop) jitem.flags2.body_part = true job.job_items.elements:insert('#', jitem) - assignToWorkshop(job, workshop) + dfhack.job.assignToWorkshop(job, workshop) return dfhack.job.addWorker(job, unit) end @@ -123,7 +109,7 @@ end ---@param workshop df.building_workshopst ---@return boolean function makeBoneCraft(unit, workshop) - local job = make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.MakeCrafts job.mat_type = -1 job.material_category.bone = true @@ -139,7 +125,7 @@ function makeBoneCraft(unit, workshop) jitem.flags2.body_part = true job.job_items.elements:insert('#', jitem) - assignToWorkshop(job, workshop) + dfhack.job.assignToWorkshop(job, workshop) return dfhack.job.addWorker(job, unit) end @@ -148,7 +134,7 @@ end ---@param workshop df.building_workshopst ---@return boolean function makeShellCraft(unit, workshop) - local job = make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.MakeCrafts job.mat_type = -1 job.material_category.shell = true @@ -164,7 +150,7 @@ function makeShellCraft(unit, workshop) jitem.flags2.body_part = true job.job_items.elements:insert('#', jitem) - assignToWorkshop(job, workshop) + dfhack.job.assignToWorkshop(job, workshop) return dfhack.job.addWorker(job, unit) end @@ -173,7 +159,7 @@ end ---@param workshop df.building_workshopst ---@return boolean "" function makeRockCraft(unit, workshop) - local job = make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.MakeCrafts job.mat_type = 0 @@ -187,7 +173,7 @@ function makeRockCraft(unit, workshop) jitem.flags3.hard = true job.job_items.elements:insert('#', jitem) - assignToWorkshop(job, workshop) + dfhack.job.assignToWorkshop(job, workshop) return dfhack.job.addWorker(job, unit) end @@ -291,13 +277,8 @@ local STONE_CRAFT = df.unit_labor['STONE_CRAFT'] ---@param value_if_absent T ---@return number|T function getCraftingNeed(unit, value_if_absent) - local needs = unit.status.current_soul.personality.needs - for _, need in ipairs(needs) do - if need.id == CraftObject then - return -need.focus_level - end - end - return value_if_absent + local focus_penalty = dfhack.units.getFocusPenalty(unit, CraftObject) + return focus_penalty > 1000 and value_if_absent or -focus_penalty end local function stop() @@ -334,27 +315,6 @@ function canAccessWorkshop(unit, workshop) return dfhack.maps.canWalkBetween(unit.pos, workshop_position) end ----unit is ready to take jobs ----@param unit df.unit ----@return boolean -function unitIsAvailable(unit) - if unit.job.current_job then - return false - elseif #unit.specific_refs > 0 then -- activities such as "Conduct Meeting" - return false - elseif #unit.social_activities > 0 then - return false - elseif #unit.individual_drills > 0 then - return false - elseif unit.military.squad_id ~= -1 then - local squad = df.squad.find(unit.military.squad_id) - -- this lookup should never fail - ---@diagnostic disable-next-line: need-check-nil - return #squad.orders == 0 and squad.activity == -1 - end - return true -end - ---select crafting job based on available resources ---@param workshop df.building_workshopst ---@return (fun(unit:df.unit, workshop:df.building_workshopst):boolean)? @@ -397,7 +357,7 @@ local function processUnit(workshop, idx, unit_id) elseif not canAccessWorkshop(unit, workshop) then -- dfhack.print('-') return false - elseif not unitIsAvailable(unit) then + elseif not dfhack.units.isJobAvailable(unit) then -- dfhack.print('.') return false end diff --git a/immortal-cravings.lua b/immortal-cravings.lua index 21ae333ec..da9f90d76 100644 --- a/immortal-cravings.lua +++ b/immortal-cravings.lua @@ -1,7 +1,6 @@ --@enable = true --@module = true -local idle = reqscript('idle-crafting') local repeatutil = require("repeat-util") --- utility functions @@ -101,7 +100,7 @@ local function goDrink(unit) -- print('no accessible drink found') return end - local job = idle.make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.DrinkItem job.flags.special = true local dx, dy, dz = dfhack.items.getPosition(drink) @@ -134,7 +133,7 @@ local function goEat(unit) end dfhack.items.setOwner(meal, unit) - local job = idle.make_job() + local job = dfhack.job.createLinked() job.job_type = df.job_type.Eat job.flags.special = true local dx, dy, dz = dfhack.items.getPosition(meal) @@ -148,25 +147,6 @@ local function goEat(unit) print(dfhack.df2console('immortal-cravings: %s is getting something to eat'):format(name)) end ----unit is ready to take jobs (will interrupt social activities) ----@param unit df.unit ----@return boolean -function unitIsAvailable(unit) - if unit.job.current_job then - return false - elseif #unit.individual_drills > 0 then - return false - elseif unit.flags1.caged or unit.flags1.chained then - return false - elseif unit.military.squad_id ~= -1 then - local squad = df.squad.find(unit.military.squad_id) - -- this lookup should never fail - ---@diagnostic disable-next-line: need-check-nil - return #squad.orders == 0 and squad.activity == -1 - end - return true -end - --- script logic local GLOBAL_KEY = 'immortal-cravings' @@ -210,7 +190,7 @@ local function unit_loop() then goto next_unit end - if not unitIsAvailable(unit) then + if not dfhack.units.isJobAvailable(unit) then debug("immortal-cravings: skipping busy"..dfhack.units.getReadableName(unit)) table.insert(kept, unit.id) else @@ -245,21 +225,13 @@ local function main_loop() watched = {} for _, unit in ipairs(dfhack.units.getCitizens(false, false)) do if - not (is_active_caste_flag(unit, 'NO_DRINK') or is_active_caste_flag(unit, 'NO_EAT')) or - unit.counters2.stomach_content > 0 + (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 then - goto next_unit - end - for _, need in ipairs(unit.status.current_soul.personality.needs) do - if need.id == DrinkAlcohol and need.focus_level < threshold or - need.id == EatGoodMeal and need.focus_level < threshold - then - table.insert(watched, unit.id) - debug(' '..dfhack.df2console(dfhack.units.getReadableName(unit))) - goto next_unit - end + table.insert(watched, unit.id) + debug(' ' .. dfhack.df2console(dfhack.units.getReadableName(unit))) end - ::next_unit:: end if #watched > 0 then