v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

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 ()