DFHack / dfhack

Memory hacking library for Dwarf Fortress and a set of tools that use it
Other
1.86k stars 471 forks source link

plugin idea: tallow handling (like seedwatch) #295

Open rh73 opened 10 years ago

rh73 commented 10 years ago

Like with seedwatch, it would be nice to have a plugin which periodically checks the stocks for new sorts of tallow and forbids them in the kitchen settings. At least, until a configurable minimum number of soap bars are in the stocks/hospitals.

It would make sense for drinks as well, allowing to cook them when they are abundant, and forbid once the amount goes below a threshold.

All this (seeds, plants, drinks, tallow) is relatively similar in function, so it could/should be handled by the same plugin. Configuring the threshold(s) could be done with the lua-UI stuff; see workflow, autobutcher etc.

myk002 commented 10 years ago

:+1:

BenLubar commented 8 years ago

We have ban-cooking, which I added in 2015. It supports:

ban-cooking booze  - bans cooking of drinks
ban-cooking honey  - bans cooking of honey bee honey
ban-cooking tallow - bans cooking of tallow
ban-cooking oil    - bans cooking of oil
ban-cooking seeds  - bans cooking of plants that have seeds (tree seeds don't count)

And as of today:

ban-cooking brew   - bans cooking of plants that can be brewed into alcohol
ban-cooking mill   - bans cooking of plants that can be milled into powder
ban-cooking thread - bans cooking of plants that can be turned into thread
ban-cooking milk   - bans cooking of creature liquids that can be turned into cheese

It doesn't unban the cooking when there's a lot of that ingredient, but it might be useful for you or anyone who might stumble upon this ticket in the future.

tewhalen commented 3 years ago

I spent a little time today and worked out a script (based on the logic in ban-cooking) that bans/unbans brewing based on a threshold of brewed drinks, in order to encourage more variety. I can't say it's pretty, but it seems to work.

-- Permit/Forbid brewing based on a threshold of drinks
-- in order to encourage drink variety
--[====[

multibrew
==============
Adjust the brewing exclusions based on a threshold of number of drinks

]====]
local utils = require 'utils'

local validArgs = utils.invert({ 'threshold', })
local args = utils.processArgs({...}, validArgs)

local threshold = 30
if args.threshold then threshold = tonumber(args.threshold) end

local function count_drinks_by_mat()
    local drink_tally = {}
    for i,drink in ipairs(df.global.world.items.other.DRINK) do
        v = drink_tally[drink.mat_index] or {0,0}
        drink_tally[drink.mat_index] = {drink.mat_type, v[2]+ drink.stack_size}
    end
    return drink_tally
end

local function pause_brewing(item_type, item_subtype, mat_type, mat_index)
    -- returns true if this is already paused or is successfully paused
    if dfhack.kitchen.findExclusion(df.kitchen_exc_type.Brew, item_type, item_subtype, mat_type, mat_index  ) ~= -1 then
        return true
    else
        return dfhack.kitchen.addExclusion(df.kitchen_exc_type.Brew, item_type, item_subtype, mat_type, mat_index  )
    end
end

local function restart_brewing(item_type, item_subtype, mat_type, mat_index)
    -- returns true if exclusion successfully removed
  return dfhack.kitchen.removeExclusion(df.kitchen_exc_type.Brew, item_type, item_subtype, mat_type, mat_index  )
end

local drink_tally= count_drinks_by_mat()

for mat_index,plant in pairs(df.global.world.raws.plants.all) do
    if plant.material_defs.type["drink"] ~= -1 then
        -- iterate through all the plants that can be brewed
        local count = drink_tally[mat_index] or {0,0}
        for j, material in pairs(plant.material) do
            if material.id == "STRUCTURAL" and utils.linear_index(material.reaction_product.id,"DRINK_MAT","value") then
                local item_type = df.item_type.PLANT
                local item_subtype = -1
                local mat_type = 419 + j -- Plant base = 419 (For some reason?!?)
                if count[2] >= threshold then
                    if pause_brewing( item_type, item_subtype, mat_type, mat_index  ) then
                        print("paused " .. plant.name .. " with " .. count[2] .. " drinks")
                    end
                elseif count[2] < threshold then
                    if restart_brewing( item_type, item_subtype, mat_type, mat_index  ) then
                        print("unpaused " .. plant.name .. " with " .. count[2] .." drinks")
                    end
                end

            end
        end
        for r, growth in pairs(plant.growths) do
            local growth_material = dfhack.matinfo.decode(growth).material
            if utils.linear_index(growth_material.reaction_product.id,"DRINK_MAT","value") then
                local item_type = df.item_type.PLANT_GROWTH
                local item_subtype = r

                for j, plant_material in pairs(plant.material) do
                    if plant_material.id == growth_material.id then
                        local mat_type = 419 + j -- Plant base = 419 (For some reason?!?)
                        if count[2] >= threshold then
                            if pause_brewing( item_type, item_subtype, mat_type, mat_index  ) then
                                print("paused " .. plant.name .. " with " .. count[2] .. " drinks")
                            end
                        elseif count[2] < threshold then
                            if restart_brewing( item_type, item_subtype, mat_type, mat_index  ) then
                                print("unpaused " .. plant.name .. " with " .. count[2] .." drinks")
                            end
                        end
                    end
                end
            end
        end
    end
end