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
< User:Fleeting Frames
Revision as of 14:31, 27 July 2020 by Fleeting Frames (talk | contribs) (Initial writeup)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

<source lang="lua"> 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 () </source