User:Fleeting Frames/order takeout

From Dwarf Fortress Wiki
Jump to navigation Jump to search

Save as order_takeout.lua into /hack/scripts folder, run with order_takeout when diplomat gives you "menu" on what to order. Each run adds 1, rolls over to 0. Add "verbose" as an argument to print receipt.

--Finds foods somebody wants to eat when diplomat is taking orders and bumps their priority.
local args = {...}

--AutomagicTables from lua wiki by ThomasWrensch and RiciLake, copied wholesale
do 
  local auto, assign

  function auto(tab, key)
    return setmetatable({}, {
            __index = auto,
            __newindex = assign,
            parent = tab,
            key = key
    })
  end

  local meta = {__index = auto}

  -- The if statement below prevents the table from being
  -- created if the value assigned is nil. This is, I think,
  -- technically correct but it might be desirable to use
  -- assignment to nil to force a table into existence.

  function assign(tab, key, val)
  if val ~= nil then
    local oldmt = getmetatable(tab)
    oldmt.parent[oldmt.key] = tab
    setmetatable(tab, meta)
    tab[key] = val
  end
  end

  function AutomagicTable()
    return setmetatable({}, meta)
  end
end

function removeMagic(automagictable)
  setmetatable(automagictable,nil)
  for i,t in pairs(automagictable) do
    if type(t)=="table" then removeMagic(t) end
  end
end

function order_takeout ()
  local scr = dfhack.gui.getCurViewscreen()
  if scr._type ~= df.viewscreen_topicmeeting_takerequestsst then
    dfhack.error ("This script must be run when the trade order screen is open")
  end
 
  local preferences = {}
  
  local entity_resources = df.global.world.entities.all[scr.meeting.civ_id].resources

    --[=[
        .misc_mat
            .meat
                .mat_type
                .mat_index
            .extracts
                -"-
            .powders
                -"-
            .cheese
                -"-
            .booze
                -"-
        .fish_races --equal to mat_type, mat_index must be -1 to be importable (normally mat_index is race ans mat_type is sub-material)
        .fish_castes
        .egg_races
        .seeds --mat_type varies
        .plants --plants
            .mat_type = 419 always
            .mat_index = variable
        .shrub_fruit_plants --garden vegetables mat_index
        .shrub_fruit_growths --420+nr = mat_type
 --]=]
  local entity_resources_table = AutomagicTable()
  
  local function add_resources(category,resource, mat_index_ovr)
    if not category or not resource then qerror("wut") end
    for index, mat_type in pairs(mat_index_ovr and resource or resource.mat_type) do
      entity_resources_table[mat_type][mat_index_ovr or resource.mat_index[index]] = function() return category, index end
    end
  end
  local valid_categories={
  "Meat",
  "Fish",
  "Plants",
  "FruitsNuts",--absent on humans
  "GardenVegetables",
  "Drinks",
  "Cheese",
  "Extracts",
  "Powders",
  "Fish",
  "Eggs",
  "Seeds"
  }
  
  add_resources("Meat", entity_resources.misc_mat.meat)
  add_resources("Extracts", entity_resources.misc_mat.extracts)
  add_resources("Powders", entity_resources.misc_mat.powders)
  add_resources("Cheese", entity_resources.misc_mat.cheese)
  add_resources("Drinks", entity_resources.misc_mat.booze)
  add_resources("Fish", entity_resources.fish_races, -1)
  --add_resources("Eggs", entity_resources.egg_races, ??) --egg mat_index = race, mat_type = only eggshell counts?? - 0/1500 dwarves want to eat egg anyway
  add_resources("Seeds", entity_resources.seeds)
  add_resources("Plants", entity_resources.plants)
  for index, mat_index in pairs(entity_resources.shrub_fruit_plants) do
    entity_resources_table[entity_resources.shrub_fruit_growths[index]+420][mat_index] = function() return "GardenVegetables", index end
  end
 
  for i, unit in ipairs (df.global.world.units.all) do
    if dfhack.units.isCitizen (unit) and
       dfhack.units.isAlive (unit) and
       unit.status.current_soul then
      for k, preference in ipairs (unit.status.current_soul.preferences) do
        if preference.active then
          if preference.type == df.unit_preference.T_type.LikeFood then
            if preferences[preference.mattype] then
              preferences[preference.mattype][preference.matindex] = true
            else
              preferences[preference.mattype]= {[preference.matindex] = true}
            end
          end
        end
      end
    end
  end
  
  local function order(category,index)
    scr.meeting.sell_requests.priority[category][index] = (scr.meeting.sell_requests.priority[category][index] + 1) % 4
  end
  
  removeMagic(entity_resources_table)
  
  for mat_type, indextable in pairs(preferences) do
    for mat_index, _ in pairs(indextable) do
      if entity_resources_table[mat_type] and entity_resources_table[mat_type][mat_index] then
        if args[1] == "verbose" then print(entity_resources_table[mat_type][mat_index]()) end
        order(entity_resources_table[mat_type][mat_index]())
      end
    end
  end
  
end

order_takeout ()