User:Fleeting Frames/buy food needs

From Dwarf Fortress Wiki
Jump to navigation Jump to search

Usage: Open trading screen in trade depot with broker and caravan present, then run the script.

function buy_food_needs ()
  if df.global.gview.view.child.child == nil or
     df.global.gview.view.child.child._type ~= df.viewscreen_tradelistst or
     df.global.gview.view.child.child.child._type ~= df.viewscreen_tradegoodsst then
    dfhack.error ("This script must be run when the trade screen is open")
  end
 
  local preferences = {}
 
  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
            local found = false
           
            for l, pref in ipairs (preferences) do
              if pref.mattype == preference.mattype and
                 pref.matindex == preference.matindex and
                 pref.item_type == preference_item_type then
                found = true
                break
              end
            end
           
            if not found then
             table.insert (preferences, preference)
            end
          end
        end
      end
    end
  end
 
  for i, item in ipairs (df.global.gview.view.child.child.child.trader_items) do
    if item._type == df.item_cagest then  --  may contain food item_critterst, but at most one.
      local found = false
     
      if #item.general_refs > 2 then
        for k, ref in ipairs (item.general_refs) do
          if ref._type == df.general_ref_contains_unitst then
            local unit = df.unit.find (ref.unit_id)
       
            for l, preference in ipairs (preferences) do
              if preference.matindex == -1 then  --  It's an animal
                if unit.race == preference.mattype then
                  dfhack.println ("Buying caged " .. df.global.world.raws.creatures.all [preference.mattype].name [0])
                  df.global.gview.view.child.child.child.trader_selected [i] = 1
                  found = true
                  break
                end
               
              else
                local matinforet = dfhack.matinfo.decode (preference.mattype, preference.matindex)
               
                if matinforet.mode == "creature" and
                   df.global.world.raws.creatures.all [unit.race].creature_id == matinforet.creature.creature_id and
                   matinforet.material.id ~= "CHEESE" and
                   matinforet.material.id ~= "MILK" and
                   matinforet.material.id ~= "EGGSHELL" and  --  Are there any preferences for eggs at all?
                   matinforet.material.id ~= "EGG_WHITE" and
                   matinforet.material.id ~= "EGG_YOLK" then     
                  local pref
           
                  if matinforet.material.prefix == "" then
                    pref = matinforet.material.state_name.Solid
             
                  else
                    pref = matinforet.material.prefix .. " " .. matinforet.material.state_name.Solid
                  end
           
                  dfhack.println ("Buying caged " .. matinforet.creature.name [0] .. " for " .. pref)               
                  df.global.gview.view.child.child.child.trader_selected [i] = 1
                  found = true
                  break
                end
              end
            end
          end
         
          if found then
            break
          end
        end       
      end

    elseif item._type == df.item_liquid or  --  ###
           item._type == df.item_powder or  --  ###
           item._type == df.item_seedst or
           item._type == df.item_meatst or
           item._type == df.item_plantst or
           item._type == df.item_plant_growthst or
           item._type == df.item_cheesest or
           item._type == df.item_globst then
      for k, preference in ipairs (preferences) do
        local matinforet = dfhack.matinfo.decode (preference.mattype, preference.matindex)
         local matinfoitem = dfhack.matinfo.decode(item)
         local has_matching_product = false
         
         if preference.matindex ~= -1 and matinfoitem then
			for mati=0, #matinfoitem.material.reaction_product.material.mat_type - 1 do
				if matinfoitem.material.reaction_product.material.mat_type[mati] == preference.mattype and
					matinfoitem.material.reaction_product.material.mat_index[mati] == preference.matindex then
					has_matching_product = true
					break
				end
			end
         end
         
         
        if preference.matindex ~= -1 and (
           item.mat_type == preference.mattype and
           item.mat_index == preference.matindex 
           ) or has_matching_product
           then
          local pref
          pref = matinfoitem:toString(10015)
          if not pref then
            if matinfoitem.material.prefix == "" then
              pref = matinfoitem.material.state_name.Solid
            else
              pref = matinfoitem.material.prefix .. " " .. matinfoitem.material.state_name.Solid
            end
          end
          
          local pref2
          if has_matching_product then
            pref2 = matinforet:toString(10015)
            if not pref2 then
              if matinforet.material.prefix == "" then
                pref2 = matinforet.material.state_name.Solid
              else
                pref2 = matinforet.material.prefix .. " " .. matinforet.material.state_name.Solid
              end
            end
          end
           
          dfhack.println ("Buying " .. pref .. (has_matching_product and (" due preference for " .. pref2) or ""))
          df.global.gview.view.child.child.child.trader_selected [i] = 1
          break
        end
      end
           
    elseif item._type == df.item_fishst or
           item._type == df.item_fish_rawst then --  Which one? This or previous one?
      for k, preference in ipairs (preferences) do
        local matinforet = dfhack.matinfo.decode (preference.mattype, preference.matindex)
       
        if preference.item_type == df.item_type.FISH then
          if preference.matindex == -1 then
            if preference.mattype == item.race then
              dfhack.println ("Buying " .. df.global.world.raws.creatures.all [preference.mattype].name [0])
              df.global.gview.view.child.child.child.trader_selected [i] = 1
              break
            end
           
          elseif matinforet.mode == "creature" and  --  No fish producing milk or eggs, yet...
                 item.race == preference.mattype then
            local pref
           
            if matinforet.material.prefix == "" then
              pref = matinforet.material.state_name.Solid
           
            else
              pref = matinforet.material.prefix .. " " .. matinforet.material.state_name.Solid
            end
           
            dfhack.println ("Buying " .. pref)               
            df.global.gview.view.child.child.child.trader_selected [i] = 1
            break
          end
        end
      end
     
--    elseif --  item._type == item_foodst or  --  Cooked meals aren't sold (yet)
--           item._type == df.item_drinkst or  --  Should always be in a barrel
--           item._type == df.item_eggst then  --  Don't think there can be egg preferences due to eggs being 3 "creature" parts...               
         
    elseif item._type == df.item_barrelst or
           item._type == df.item_boxst then  -- for bags...
      if #item.general_refs > 2 then
        local found = false
       
        for k, ref in ipairs (item.general_refs) do
          if ref._type == df.general_ref_contains_itemst then
            local content = df.item.find (ref.item_id)
       
            for l, preference in ipairs (preferences) do
              local matinforet = dfhack.matinfo.decode (preference.mattype, preference.matindex)
         
              if preference.matindex ~= -1 and
                 content.mat_type == preference.mattype and
                 content.mat_index == preference.matindex then
                local pref

                found = true

                if preference.item_type == df.item_type.DRINK or
                   preference.item_type == df.item_type.LIQUID_MISC then
                  if matinforet.material.prefix == "" then
                    pref = matinforet.material.state_name.Liquid
             
                  else
                    pref = matinforet.material.prefix .. " " .. matinforet.material.state_name.Liquid
                  end
           
                  dfhack.println ("Buying barrel of " .. pref)               
                  df.global.gview.view.child.child.child.trader_selected [i] = 1
                 
                else
                  if matinforet.material.prefix == "" then
                    pref = matinforet.material.state_name.Solid
             
                   else
                    pref = matinforet.material.prefix .. " " .. matinforet.material.state_name.Solid
                  end
           
                  dfhack.println ("Buying bag with " .. pref)               
                  df.global.gview.view.child.child.child.trader_selected [i] = 1
                end
               
                break
              end
            end
          end
         
          if found then
            break
          end
        end       
      end
    end
  end
end

buy_food_needs ()