From 886e91b4eaedf28da3324d5c1c670f809a0d3986 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 6 Sep 2024 16:11:31 -0700 Subject: [PATCH] clean up algorithm so it only scans relevant items --- docs/fix/dry-buckets.rst | 4 ++++ fix/dry-buckets.lua | 44 ++++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/docs/fix/dry-buckets.rst b/docs/fix/dry-buckets.rst index 311e3e6c2e..9d3a7d4e0b 100644 --- a/docs/fix/dry-buckets.rst +++ b/docs/fix/dry-buckets.rst @@ -12,6 +12,10 @@ water from them. This tool also fixes over-full buckets that are blocking well operations. +If enabled in `gui/control-panel` (it is enabled by default), this fix is +periodically run automaticaly, so you should not normally need to run it +manually. + Usage ----- diff --git a/fix/dry-buckets.lua b/fix/dry-buckets.lua index 27834abb82..db98f0f719 100644 --- a/fix/dry-buckets.lua +++ b/fix/dry-buckets.lua @@ -1,35 +1,43 @@ local argparse = require("argparse") -local quiet = false - -local emptied = 0 -local in_building = 0 local water_type = dfhack.matinfo.find('WATER').type +local quiet = false argparse.processArgsGetopt({...}, { {'q', 'quiet', handler=function() quiet = true end}, }) -for _,item in ipairs(df.global.world.items.other.IN_PLAY) do - local container = dfhack.items.getContainer(item) - if container - and container:getType() == df.item_type.BUCKET - and not (container.flags.in_job) - and item:getMaterial() == water_type - and item:getType() == df.item_type.LIQUID_MISC - and not (item.flags.in_job) - then - if container.flags.in_building or item.flags.in_building then - in_building = in_building + 1 +local emptied = 0 +local in_building = 0 +for _,item in ipairs(df.global.world.items.other.BUCKET) do + if item.flags.in_job then goto continue end + local emptied_bucket = false + local freed_in_building = false + for _,contained_item in ipairs(dfhack.items.getContainedItems(item)) do + if not contained_item.flags.in_job and + contained_item:getMaterial() == water_type and + contained_item:getType() == df.item_type.LIQUID_MISC + then + if item.flags.in_building or contained_item.flags.in_building then + freed_in_building = true + end + -- ok to remove item while iterating since we're iterating through copy of the vector + dfhack.items.remove(contained_item) + emptied_bucket = true end - dfhack.items.remove(item) + end + if emptied_bucket then emptied = emptied + 1 end + if freed_in_building then + in_building = in_building + 1 + end + ::continue:: end if not quiet then - print('Emptied '..emptied..' buckets.') - if emptied > 0 then + print(('Emptied %d buckets.'):format(emptied)) + if in_building > 0 then print(('Unclogged %d wells.'):format(in_building)) end end