local _ENV = mkmodule('dfhack.workshops') local utils = require 'utils' input_filter_defaults = { item_type = -1, item_subtype = -1, mat_type = -1, mat_index = -1, flags1 = {}, -- Instead of noting those that allow artifacts, mark those that forbid them. -- Leaves actually enabling artifacts to the discretion of the API user, -- which is the right thing because unlike the game UI these filters are -- used in a way that does not give the user a chance to choose manually. flags2 = { allow_artifact = true }, flags3 = {}, flags4 = 0, flags5 = 0, reaction_class = '', has_material_reaction_product = '', metal_ore = -1, min_dimension = -1, has_tool_use = -1, quantity = 1 } local fuel={item_type=df.item_type.BAR,mat_type=df.builtin_mats.COAL} jobs_furnace={ [df.furnace_type.Smelter]={ { name="Melt metal object", items={fuel,{flags2={allow_melt_dump=true}}},--also maybe melt_designated job_fields={job_type=df.job_type.MeltMetalObject} } }, [df.furnace_type.MagmaSmelter]={ { name="Melt metal object", items={{flags2={allow_melt_dump=true}}},--also maybe melt_designated job_fields={job_type=df.job_type.MeltMetalObject} } }, --[[ [df.furnace_type.MetalsmithsForge]={ unpack(concat(furnaces,mechanism,anvil,crafts,coins,flask)) }, ]] --MetalsmithsForge, --MagmaForge --[[ forges: weapons and ammo-> from raws... armor -> raws furniture -> builtins? siege eq-> builtin (only balista head) trap eq -> from raws+ mechanisms other object-> anvil, crafts, goblets,toys,instruments,nestbox... (raws?) flask, coins,stud with iron metal clothing-> raws??? ]] [df.furnace_type.GlassFurnace]={ { name="collect sand", items={}, job_fields={job_type=df.job_type.CollectSand} }, --glass crafts x3 }, [df.furnace_type.WoodFurnace]={ defaults={item_type=df.item_type.WOOD,vector_id=df.job_item_vector_id.WOOD}, { name="make charcoal", items={{}}, job_fields={job_type=df.job_type.MakeCharcoal} }, { name="make ash", items={{}}, job_fields={job_type=df.job_type.MakeAsh} } }, [df.furnace_type.Kiln]={ { name="collect clay", items={}, job_fields={job_type=df.job_type.CollectClay} } }, } jobs_workshop={ [df.workshop_type.Jewelers]={ { name="cut gems", items={{item_type=df.item_type.ROUGH,flags1={unrotten=true}}}, job_fields={job_type=df.job_type.CutGems} }, { name="encrust finished goods with gems", items={{item_type=df.item_type.SMALLGEM},{flags1={improvable=true,finished_goods=true}}}, job_fields={job_type=df.job_type.EncrustWithGems} }, { name="encrust ammo with gems", items={{item_type=df.item_type.SMALLGEM},{flags1={improvable=true,ammo=true}}}, job_fields={job_type=df.job_type.EncrustWithGems} }, { name="encrust furniture with gems", items={{item_type=df.item_type.SMALLGEM},{flags1={improvable=true,furniture=true}}}, job_fields={job_type=df.job_type.EncrustWithGems} }, }, [df.workshop_type.Fishery]={ { name="prepare raw fish", items={{item_type=df.item_type.FISH_RAW,flags1={unrotten=true}}}, job_fields={job_type=df.job_type.PrepareRawFish} }, { name="extract from raw fish", items={{flags1={unrotten=true,extract_bearing_fish=true}},{item_type=df.item_type.FLASK,flags1={empty=true,glass=true}}}, job_fields={job_type=df.job_type.ExtractFromRawFish} }, { name="catch live fish", items={}, job_fields={job_type=df.job_type.CatchLiveFish} }, -- no items? }, [df.workshop_type.Masons]={ defaults={item_type=df.item_type.BOULDER,item_subtype=-1,vector_id=df.job_item_vector_id.BOULDER, mat_type=0,mat_index=-1,flags3={hard=true}},--flags2={non_economic=true}, { name="construct armor stand", items={{}}, job_fields={job_type=df.job_type.ConstructArmorStand} }, { name="construct blocks", items={{}}, job_fields={job_type=df.job_type.ConstructBlocks} }, { name="construct throne", items={{}}, job_fields={job_type=df.job_type.ConstructThrone} }, { name="construct coffin", items={{}}, job_fields={job_type=df.job_type.ConstructCoffin} }, { name="construct door", items={{}}, job_fields={job_type=df.job_type.ConstructDoor} }, { name="construct floodgate", items={{}}, job_fields={job_type=df.job_type.ConstructFloodgate} }, { name="construct hatch cover", items={{}}, job_fields={job_type=df.job_type.ConstructHatchCover} }, { name="construct grate", items={{}}, job_fields={job_type=df.job_type.ConstructGrate} }, { name="construct cabinet", items={{}}, job_fields={job_type=df.job_type.ConstructCabinet} }, { name="construct chest", items={{}}, job_fields={job_type=df.job_type.ConstructChest} }, { name="construct statue", items={{}}, job_fields={job_type=df.job_type.ConstructStatue} }, { name="construct slab", items={{}}, job_fields={job_type=df.job_type.ConstructSlab} }, { name="construct table", items={{}}, job_fields={job_type=df.job_type.ConstructTable} }, { name="construct weapon rack", items={{}}, job_fields={job_type=df.job_type.ConstructWeaponRack} }, { name="construct quern", items={{}}, job_fields={job_type=df.job_type.ConstructQuern} }, { name="construct millstone", items={{}}, job_fields={job_type=df.job_type.ConstructMillstone} }, }, [df.workshop_type.Carpenters]={ --training weapons, wooden shields defaults={item_type=df.item_type.WOOD,vector_id=df.job_item_vector_id.WOOD}, { name="make barrel", items={{}}, job_fields={job_type=df.job_type.MakeBarrel} }, { name="make bucket", items={{}}, job_fields={job_type=df.job_type.MakeBucket} }, { name="make animal trap", items={{}}, job_fields={job_type=df.job_type.MakeAnimalTrap} }, { name="make cage", items={{}}, job_fields={job_type=df.job_type.MakeCage} }, { name="construct bed", items={{}}, job_fields={job_type=df.job_type.ConstructBed} }, { name="construct bin", items={{}}, job_fields={job_type=df.job_type.ConstructBin} }, { name="construct armor stand", items={{}}, job_fields={job_type=df.job_type.ConstructArmorStand} }, { name="construct blocks", items={{}}, job_fields={job_type=df.job_type.ConstructBlocks} }, { name="construct throne", items={{}}, job_fields={job_type=df.job_type.ConstructThrone} }, { name="construct coffin", items={{}}, job_fields={job_type=df.job_type.ConstructCoffin} }, { name="construct door", items={{}}, job_fields={job_type=df.job_type.ConstructDoor} }, { name="construct floodgate", items={{}}, job_fields={job_type=df.job_type.ConstructFloodgate} }, { name="construct hatch cover", items={{}}, job_fields={job_type=df.job_type.ConstructHatchCover} }, { name="construct grate", items={{}}, job_fields={job_type=df.job_type.ConstructGrate} }, { name="construct cabinet", items={{}}, job_fields={job_type=df.job_type.ConstructCabinet} }, { name="construct chest", items={{}}, job_fields={job_type=df.job_type.ConstructChest} }, { name="construct statue", items={{}}, job_fields={job_type=df.job_type.ConstructStatue} }, { name="construct table", items={{}}, job_fields={job_type=df.job_type.ConstructTable} }, { name="construct weapon rack", items={{}}, job_fields={job_type=df.job_type.ConstructWeaponRack} }, { name="construct splint", items={{}}, job_fields={job_type=df.job_type.ConstructSplint} }, { name="construct crutch", items={{}}, job_fields={job_type=df.job_type.ConstructCrutch} }, }, [df.workshop_type.Kitchen]={ --mat_type=2,3,4 defaults={flags1={unrotten=true}}, { name="prepare easy meal", items={{flags1={solid=true,cookable=true}},{flags1={cookable=true}}}, job_fields={job_type=df.job_type.PrepareMeal,mat_type=2} }, { name="prepare fine meal", items={{flags1={solid=true,cookable=true}},{flags1={cookable=true}},{flags1={cookable=true}}}, job_fields={job_type=df.job_type.PrepareMeal,mat_type=3} }, { name="prepare lavish meal", items={{flags1={solid=true,cookable=true}},{flags1={cookable=true}},{flags1={cookable=true}},{flags1={cookable=true}}}, job_fields={job_type=df.job_type.PrepareMeal,mat_type=4} }, }, [df.workshop_type.Butchers]={ { name="butcher an animal", items={{flags1={butcherable=true,unrotten=true,nearby=true}}}, job_fields={job_type=df.job_type.ButcherAnimal} }, { name="extract from land animal", items={{flags1={extract_bearing_vermin=true,unrotten=true}},{item_type=df.item_type.FLASK,flags1={empty=true,glass=true}}}, job_fields={job_type=df.job_type.ExtractFromLandAnimal} }, { name="catch live land animal", items={}, job_fields={job_type=df.job_type.CatchLiveLandAnimal} }, }, [df.workshop_type.Mechanics]={ { name="construct mechanisms", items={{item_type=df.item_type.BOULDER,item_subtype=-1,vector_id=df.job_item_vector_id.BOULDER, mat_type=0,mat_index=-1,quantity=1, flags3={hard=true}}}, job_fields={job_type=df.job_type.ConstructMechanisms} }, { name="construct traction bench", items={{item_type=df.item_type.TABLE},{item_type=df.item_type.MECHANISM},{item_type=df.item_type.CHAIN}}, job_fields={job_type=df.job_type.ConstructTractionBench} }, }, [df.workshop_type.Loom]={ { name="weave plant thread cloth", items={{item_type=df.item_type.THREAD,quantity=15000,min_dimension=15000,flags1={collected=true},flags2={plant=true}}}, job_fields={job_type=df.job_type.WeaveCloth} }, { name="weave silk thread cloth", items={{item_type=df.item_type.THREAD,quantity=15000,min_dimension=15000,flags1={collected=true},flags2={silk=true}}}, job_fields={job_type=df.job_type.WeaveCloth} }, { name="weave yarn cloth", items={{item_type=df.item_type.THREAD,quantity=15000,min_dimension=15000,flags1={collected=true},flags2={yarn=true}}}, job_fields={job_type=df.job_type.WeaveCloth} }, { name="weave inorganic cloth", items={{item_type=df.item_type.THREAD,quantity=15000,min_dimension=15000,flags1={collected=true},mat_type=0}}, job_fields={job_type=df.job_type.WeaveCloth} }, { name="collect webs", items={{item_type=df.item_type.THREAD,quantity=10,min_dimension=10,flags1={undisturbed=true}}}, job_fields={job_type=df.job_type.CollectWebs} }, }, [df.workshop_type.Leatherworks]={ defaults={item_type=SKIN_TANNED}, { name="construct leather bag", items={{}}, job_fields={job_type=df.job_type.ConstructChest} }, { name="construct waterskin", items={{}}, job_fields={job_type=df.job_type.MakeFlask} }, { name="construct backpack", items={{}}, job_fields={job_type=df.job_type.MakeBackpack} }, { name="construct quiver", items={{}}, job_fields={job_type=df.job_type.MakeQuiver} }, { name="sew leather image", items={{item_type=-1,flags1={empty=true},flags2={sewn_imageless=true}},{}}, job_fields={job_type=df.job_type.SewImage} }, }, [df.workshop_type.Dyers]={ { name="dye thread", items={{item_type=df.item_type.THREAD,quantity=15000,min_dimension=15000,flags1={collected=true},flags2={dyeable=true}}, {flags1={unrotten=true},flags2={dye=true}}}, job_fields={job_type=df.job_type.DyeThread} }, { name="dye cloth", items={{item_type=df.item_type.CLOTH,quantity=10000,min_dimension=10000,flags2={dyeable=true}}, {flags1={unrotten=true},flags2={dye=true}}}, job_fields={job_type=df.job_type.DyeThread} }, }, [df.workshop_type.Siege]={ { name="construct balista parts", items={{item_type=df.item_type.WOOD}}, job_fields={job_type=df.job_type.ConstructBallistaParts} }, { name="construct catapult parts", items={{item_type=df.item_type.WOOD}}, job_fields={job_type=df.job_type.ConstructCatapultParts} }, { name="assemble balista arrow", items={{item_type=df.item_type.WOOD}}, job_fields={job_type=df.job_type.AssembleSiegeAmmo} }, { name="assemble tipped balista arrow", items={{item_type=df.item_type.WOOD},{item_type=df.item_type.BALLISTAARROWHEAD}}, job_fields={job_type=df.job_type.AssembleSiegeAmmo} }, }, } local function matchIds(bid1,wid1,cid1,bid2,wid2,cid2) if bid1~=-1 and bid2~=-1 and bid1~=bid2 then return false end if wid1~=-1 and wid2~=-1 and wid1~=wid2 then return false end if cid1~=-1 and cid2~=-1 and cid1~=cid2 then return false end return true end local function scanRawsReaction(buildingId,workshopId,customId) local ret={} for idx,reaction in ipairs(df.global.world.raws.reactions.reactions) do for k,v in pairs(reaction.building.type) do if matchIds(buildingId,workshopId,customId,v,reaction.building.subtype[k],reaction.building.custom[k]) then table.insert(ret,reaction) end end end return ret end local function reagentToJobItem(reagent,react_id,reagentId) local ret_item ret_item=utils.clone_with_default(reagent, input_filter_defaults) ret_item.reaction_id=react_id ret_item.reagent_index=reagentId return ret_item end local function addReactionJobs(ret,bid,wid,cid) local reactions=scanRawsReaction(bid,wid or -1,cid or -1) for idx,react in pairs(reactions) do local job={name=react.name, items={},job_fields={job_type=df.job_type.CustomReaction,reaction_name=react.code} } for reagentId,reagent in pairs(react.reagents) do table.insert(job.items,reagentToJobItem(reagent,idx,reagentId)) end if react.flags.FUEL then table.insert(job.items,fuel) end table.insert(ret,job) end end local function scanRawsOres() local ret={} for idx,ore in ipairs(df.global.world.raws.inorganics) do if #ore.metal_ore.mat_index~=0 then ret[idx]=ore end end return ret end local function addSmeltJobs(ret,use_fuel) local ores=scanRawsOres() for idx,ore in pairs(ores) do print("adding:",ore.material.state_name.Solid) printall(ore) local job={name="smelt "..ore.material.state_name.Solid,job_fields={job_type=df.job_type.SmeltOre,mat_type=df.builtin_mats.INORGANIC,mat_index=idx},items={ {item_type=df.item_type.BOULDER,mat_type=df.builtin_mats.INORGANIC,mat_index=idx,vector_id=df.job_item_vector_id.BOULDER}}} if use_fuel then table.insert(job.items,fuel) end table.insert(ret,job) end return ret end function getJobs(buildingId,workshopId,customId) local ret={} local c_jobs if buildingId==df.building_type.Workshop then c_jobs=jobs_workshop[workshopId] elseif buildingId==df.building_type.Furnace then c_jobs=jobs_furnace[workshopId] if workshopId == df.furnace_type.Smelter or workshopId == df.furnace_type.MagmaSmelter then c_jobs=utils.clone(c_jobs,true) addSmeltJobs(c_jobs,workshopId == df.furnace_type.Smelter) end else return nil end if c_jobs==nil then c_jobs={} else c_jobs=utils.clone(c_jobs,true) end addReactionJobs(c_jobs,buildingId,workshopId,customId) for jobId,contents in pairs(c_jobs) do if jobId~="defaults" then local entry={} entry.name=contents.name local lclDefaults=utils.clone(input_filter_defaults,true) if c_jobs.defaults ~=nil then utils.assign(lclDefaults,c_jobs.defaults) end entry.items={} for k,item in pairs(contents.items) do entry.items[k]=utils.clone(lclDefaults,true) utils.assign(entry.items[k],item) end if contents.job_fields~=nil then entry.job_fields={} utils.assign(entry.job_fields,contents.job_fields) end ret[jobId]=entry end end --get jobs, add in from raws return ret end return _ENV