|  |  | @ -379,13 +379,6 @@ static bool isSupportedJob(df::job *job) | 
			
		
	
		
		
			
				
					
					|  |  |  |             job->job_type == job_type::CollectSand); |  |  |  |             job->job_type == job_type::CollectSand); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void enumLiveJobs(std::map<int, df::job*> &rv) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     df::job_list_link *p = world->job_list.next; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (; p; p = p->next) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         rv[p->item->id] = p->item; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static bool isOptionEnabled(unsigned flag) |  |  |  | static bool isOptionEnabled(unsigned flag) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return config.isValid() && (config.ival(0) & flag) != 0; |  |  |  |     return config.isValid() && (config.ival(0) & flag) != 0; | 
			
		
	
	
		
		
			
				
					|  |  | @ -828,71 +821,6 @@ static void link_job_constraint(ProtectedJob *pj, df::item_type itype, int16_t i | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void compute_custom_job(ProtectedJob *pj, df::job *job) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (pj->reaction_id < 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         pj->reaction_id = linear_index(df::reaction::get_vector(), |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                                        &df::reaction::code, job->reaction_name); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     df::reaction *r = df::reaction::find(pj->reaction_id); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!r) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (size_t i = 0; i < r->products.size(); i++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         using namespace df::enums::reaction_product_item_flags; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         VIRTUAL_CAST_VAR(prod, df::reaction_product_itemst, r->products[i]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!prod || (prod->item_type < (df::item_type)0 && !prod->flags.is_set(CRAFTS))) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         MaterialInfo mat(prod); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         df::dfhack_material_category mat_mask(0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         bool get_mat_prod = prod->flags.is_set(GET_MATERIAL_PRODUCT); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (get_mat_prod || prod->flags.is_set(GET_MATERIAL_SAME)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int reagent_idx = linear_index(r->reagents, &df::reaction_reagent::code, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                                            prod->get_material.reagent_code); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (reagent_idx < 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             int item_idx = linear_index(job->job_items, &df::job_item::reagent_index, reagent_idx); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (item_idx >= 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mat.decode(job->job_items[item_idx]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 VIRTUAL_CAST_VAR(src, df::reaction_reagent_itemst, r->reagents[reagent_idx]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (!src) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 mat.decode(src); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (get_mat_prod) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 std::string code = prod->get_material.product_code; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (mat.isValid()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     int idx = linear_index(mat.material->reaction_product.id, code); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (idx < 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         continue; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     mat.decode(mat.material->reaction_product.material, idx); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if (code == "SOAP_MAT") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                         mat_mask.bits.soap = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         link_job_constraint(pj, prod->item_type, prod->item_subtype, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                             mat_mask, mat.type, mat.index, prod->flags.is_set(CRAFTS));  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static void guess_job_material(df::job *job, MaterialInfo &mat, df::dfhack_material_category &mat_mask) |  |  |  | static void guess_job_material(df::job *job, MaterialInfo &mat, df::dfhack_material_category &mat_mask) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     using namespace df::enums::job_type; |  |  |  |     using namespace df::enums::job_type; | 
			
		
	
	
		
		
			
				
					|  |  | @ -934,100 +862,24 @@ static void guess_job_material(df::job *job, MaterialInfo &mat, df::dfhack_mater | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void compute_job_outputs(color_ostream &out, ProtectedJob *pj) |  |  |  | static int cbEnumJobOutputs(lua_State *L) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     using namespace df::enums::job_type; |  |  |  |     auto pj = (ProtectedJob*)lua_touserdata(L, lua_upvalueindex(1)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Custom reactions handled in another function
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     df::job *job = pj->job_copy; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (job->job_type == CustomReaction) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         compute_custom_job(pj, job); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Item type & subtype
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     df::item_type itype = ENUM_ATTR(job_type, item, job->job_type); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     int16_t isubtype = job->item_subtype; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (itype == item_type::NONE && job->job_type != MakeCrafts) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Item material & material category
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     MaterialInfo mat; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     df::dfhack_material_category mat_mask; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     guess_job_material(job, mat, mat_mask); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Job-specific code
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     switch (job->job_type) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     case SmeltOre: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mat.inorganic) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             std::vector<int16_t> &ores = mat.inorganic->metal_ore.mat_index; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             for (size_t i = 0; i < ores.size(); i++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 link_job_constraint(pj, item_type::BAR, -1, 0, 0, ores[i]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     case ExtractMetalStrands: |  |  |  |     lua_settop(L, 6); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if (mat.inorganic) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             std::vector<int16_t> &threads = mat.inorganic->thread_metal.mat_index; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             for (size_t i = 0; i < threads.size(); i++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 link_job_constraint(pj, item_type::THREAD, -1, 0, 0, threads[i]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     case PrepareMeal: |  |  |  |     df::dfhack_material_category mat_mask(0); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if (job->mat_type != -1) |  |  |  |     if (!lua_isnil(L, 3)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |         Lua::CheckDFAssign(L, &mat_mask, 3); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             std::vector<df::itemdef_foodst*> &food = df::itemdef_foodst::get_vector(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             for (size_t i = 0; i < food.size(); i++) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (food[i]->level == job->mat_type) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                     link_job_constraint(pj, item_type::FOOD, i, 0, -1, -1); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     case MakeCrafts: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         link_job_constraint(pj, item_type::NONE, -1, mat_mask, mat.type, mat.index, true); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #define PLANT_PROCESS_MAT(flag, tag) \ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mat.plant && mat.plant->flags.is_set(plant_raw_flags::flag)) \ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             mat.decode(mat.plant->material_defs.type_##tag, \ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                        mat.plant->material_defs.idx_##tag); \ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         else mat.decode(-1); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     case BrewDrink: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         PLANT_PROCESS_MAT(DRINK, drink); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     case MillPlants: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         PLANT_PROCESS_MAT(MILL, mill); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     case ProcessPlants: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         PLANT_PROCESS_MAT(THREAD, thread); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     case ProcessPlantsBag: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         PLANT_PROCESS_MAT(LEAVES, leaves); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     case ProcessPlantsBarrel: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         PLANT_PROCESS_MAT(EXTRACT_BARREL, extract_barrel); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     case ProcessPlantsVial: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         PLANT_PROCESS_MAT(EXTRACT_VIAL, extract_vial); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     case ExtractFromPlants: |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         PLANT_PROCESS_MAT(EXTRACT_STILL_VIAL, extract_still_vial); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #undef PLANT_PROCESS_MAT |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     default: |  |  |  |     link_job_constraint( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         pj, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |         (df::item_type)luaL_optint(L, 1, -1), luaL_optint(L, 2, -1), | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         mat_mask, luaL_optint(L, 4, -1), luaL_optint(L, 5, -1), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         lua_toboolean(L, 6) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     link_job_constraint(pj, itype, isubtype, mat_mask, mat.type, mat.index); |  |  |  |     return 0; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void map_job_constraints(color_ostream &out) |  |  |  | static void map_job_constraints(color_ostream &out) | 
			
		
	
	
		
		
			
				
					|  |  | @ -1040,19 +892,32 @@ static void map_job_constraints(color_ostream &out) | 
			
		
	
		
		
			
				
					
					|  |  |  |         constraints[i]->is_active = false; |  |  |  |         constraints[i]->is_active = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     auto L = Lua::Core::State; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Lua::StackUnwinder frame(L); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     bool ok = Lua::PushModulePublic(out, L, "plugins.workflow", "doEnumJobOutputs"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (!ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         out.printerr("The workflow lua module is not available.\n"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (TKnownJobs::const_iterator it = known_jobs.begin(); it != known_jobs.end(); ++it) |  |  |  |     for (TKnownJobs::const_iterator it = known_jobs.begin(); it != known_jobs.end(); ++it) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         ProtectedJob *pj = it->second; |  |  |  |         ProtectedJob *pj = it->second; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         pj->constraints.clear(); |  |  |  |         pj->constraints.clear(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!pj->isLive()) |  |  |  |         if (!ok || !pj->isLive()) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             continue; |  |  |  |             continue; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!melt_active && pj->actual_job->job_type == job_type::MeltMetalObject) |  |  |  |         if (!melt_active && pj->actual_job->job_type == job_type::MeltMetalObject) | 
			
		
	
		
		
			
				
					
					|  |  |  |             melt_active = pj->isResumed(); |  |  |  |             melt_active = pj->isResumed(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         compute_job_outputs(out, pj); |  |  |  |         // Call the lua module
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         lua_pushvalue(L, -1); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         lua_pushlightuserdata(L, pj); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         lua_pushcclosure(L, cbEnumJobOutputs, 1); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         Lua::PushDFObject(L, pj->job_copy); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         Lua::SafeCall(out, L, 2, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | 
 |