require("factsheet") local binding_time_mult = 1 local binding_prod_mult = 5 local separation_time_mult = 1/2 local separation_prod_mult = 2 local vapor_time_mult = 2 local vapor_prod_mult = 5 local screening_efficiency = 0.8 chem_category_list = { "crafting-with-fluid", "chemistry", "drugs", "drugs-et-et", "drugs-to-et", "drugs-et-to", "drugs-to-to", "drugs-tre-tre", "agitation", "advanced-agitation", "drugged-science", "gold-mining", "super-gold-mining" } function is_chem_category(category) if type(category) ~= "string" then return false end for _,category_name in pairs(chem_category_list) do if category == category_name then return true end end return false end smelting_category_list = { "smelting" } function is_smelting_category(category) if type(category) ~= "string" then return false end for _,category_name in pairs(smelting_category_list) do if category == category_name then return true end end return false end manufacturing_names = { "steel-plate", "belt", "inserter", "rounds", "barrel" } manufacturing_subgroups = { "intermediate-product", "science-pack", } catalyst_names = { "iron-plate", "copper-plate", } function manufacturing_needed_for(ingredient) if type(ingredient) ~= "table" then return false end local itemname = ingredient.name or ingredient[1] for _,matchname in pairs(manufacturing_names) do if itemname:match(matchname) or itemname == matchname then return true end end if type(data.raw.item[itemname]) == "table" then if data.raw.item[itemname].normal or data.raw.item[itemname].expensive then for _,subgroup in pairs(manufacturing_subgroups) do if ( data.raw.item[itemname].normal.subgroup or data.raw.item[itemname].expensive.subgroup ) == subgroup then return true end end end for _,subgroup in pairs(manufacturing_subgroups) do if data.raw.item[itemname].subgroup == subgroup then return true end end end return false end function is_plate(io_type) local io_type = io_prototype_or_bust(io_type) if not io_type then return end return (io_type.name or io_type[1]):match("plate") end function is_catalyst(io_type) local io_type = io_prototype_or_bust(io_type) if not io_type then return end if io_type.catalyst_amount then if io_type.catalyst_amount > 0 then return true else return false end end local itemname = io_type.name or io_type[1] for _,matchname in pairs(catalyst_names) do if itemname:match(matchname) or itemname == matchname then return true end end return false end function chemical_category( name, solid_input_count, solid_output_count, fluid_input_count, fluid_output_count, catalyst_inputs, catalyst_outputs, takes_water, outputs_water, uses_carbonation ) local solid_output_count = solid_output_count - catalyst_outputs local solid_input_count = solid_input_count - catalyst_inputs if uses_carbonation then solid_input_count = solid_input_count - 1 end if fluid_input_count == 0 and fluid_output_count == 0 then if solid_input_count < solid_output_count then return "adamo-chemical-separation" elseif solid_input_count == solid_output_count then return "adamo-chemical-manufacturing" elseif solid_output_count == 1 and solid_input_count > 1 then return "adamo-chemical-firing" else return "adamo-chemical-manufacturing" end end if solid_output_count == 0 and solid_input_count == 0 then return "adamo-chemical-vaporworks" end -- from this point everything has fluids and solids if takes_water and fluid_input_count == 1 and solid_input_count == 0 then return "adamo-chemical-vaporworks" end if solid_input_count > solid_output_count and fluid_input_count > 0 and fluid_output_count > 0 and fluid_input_count >= solid_input_count then return "adamo-chemical-disassociation" end if takes_water then fluid_input_count = fluid_input_count - 1 end -- water is incidental for these if fluid_input_count == 0 and fluid_output_count == 0 then if solid_input_count < solid_output_count then return "adamo-chemical-separation" end end if solid_input_count == solid_output_count then if fluid_input_count < fluid_output_count then return "adamo-chemical-recovery" elseif fluid_input_count == fluid_output_count then if fluid_input_count > 0 then return "adamo-chemical-displacement" end return "adamo-chemical-binding" elseif fluid_input_count > fluid_output_count then return "adamo-chemical-activation" end end if takes_water then fluid_input_count = fluid_input_count + 1 end if fluid_input_count > 0 --and fluid_output_count >= 0 implied and solid_output_count > 0 and solid_output_count < (fluid_output_count + 2) then if solid_input_count < solid_output_count or ( ( solid_input_count - fluid_input_count + fluid_output_count ) < solid_output_count ) then return "adamo-chemical-deposition" end if solid_input_count > solid_output_count and fluid_output_count == 0 then return "adamo-chemical-binding" end end return "adamo-chemical-manufacturing" end -- Calcination smelting should give back some resources. -- at time_norm 5 and 150kW, ~10-25 ore_norm is the range -- between stone and steel furnace power use local ore_norm = 10 local time_norm = 4 local calcinate_recipe = function(recipe,mult) local recipe = recipe_or_bust(recipe) if not recipe then return nil end if type(mult) ~= "number" or mult <= 0 then mult = ore_norm end local calcined_recipe = util.table.deepcopy(recipe) mult_recipe_energy( calcined_recipe,mult*time_norm/ore_norm ) mult_recipe_io(calcined_recipe,mult) calcined_recipe.name = calcined_recipe.name.."-calcined" calcined_recipe.category = "adamo-chemical-firing" calcined_recipe.subgroup = "adamo-chemical-firing" if uses_ingredient(recipe,"iron-plate") then replace_in_recipe_io( calcined_recipe, "iron-plate", "iron-ore" ) end if uses_ingredient(recipe,"copper-plate") then replace_in_recipe_io( calcined_recipe, "copper-plate", "copper-ore" ) end local toss,ore_count,toss = get_ingredient(calcined_recipe,"iron-ore") if ore_count == 0 then toss,ore_count,toss = get_ingredient(calcined_recipe,"copper-ore") end if ore_count == 0 then toss,stone_count,toss = get_ingredient(calcined_recipe,"stone") if stone_count > 0 then replace_in_recipe_io( calcined_recipe, "stone", "adamo-chemical-clinker", 1/2 ) add_ingredient( calcined_recipe,"adamo-chemical-calcite", math.ceil(stone_count/2) ) return calcined_recipe else return nil end end local mineral_count = ore_count/20 local flux_input = math.ceil(mineral_count*2) local clinker_ratio = 1/3 -- to match gypsum local clinker_output = clinker_ratio*flux_input local clinker_count = clinker_ratio*flux_input local clinker_prob = nil if clinker_output > 1 then clinker_count = math.ceil(clinker_output) clinker_prob = clinker_count/clinker_output end add_ingredient( calcined_recipe,"adamo-chemical-calcite", flux_input ) add_result( calcined_recipe,"adamo-chemical-fluorite", mineral_count, (fluorite_ratio) ) if data.raw.item["SiSi-quartz"] then add_result( calcined_recipe,"SiSi-quartz", mineral_count, quartz_ratio ) end if data.raw.item["adamo-chemical-quartz"] then add_result( calcined_recipe,"adamo-chemical-quartz", mineral_count, quartz_ratio ) end add_result( calcined_recipe,"sulfur", mineral_count, (1 - fluorite_ratio - quartz_ratio) ) add_result( calcined_recipe,"adamo-chemical-clinker", clinker_count, clinker_prob ) return calcined_recipe end -- Generate chemical engineering recipes. -- Should be able to use hydrofluoric acid to clean chips, make batteries, do science. local processing_unit_from_hf_recipe = util.table.deepcopy(data.raw.recipe["processing-unit"]) processing_unit_from_hf_recipe.name = "adamo-chemical-processing-unit" for _,ingredient in pairs(processing_unit_from_hf_recipe.normal.ingredients) do if ingredient.type and ingredient.name == "sulfuric-acid" then ingredient.name = "adamo-chemical-hydrofluoric-acid" end end for _,ingredient in pairs(processing_unit_from_hf_recipe.expensive.ingredients) do if ingredient.type and ingredient.name == "sulfuric-acid" then ingredient.name = "adamo-chemical-hydrofluoric-acid" end end local fluoride_battery_recipe = util.table.deepcopy(data.raw.recipe["battery"]) fluoride_battery_recipe.name = "adamo-chemical-fluoride-battery" fluoride_battery_recipe.normal.result_count = 1 fluoride_battery_recipe.normal.ingredients = {{ name = "copper-plate", type = "item", amount = 1, catalyst_amount = 0 },{ "adamo-chemical-calcite",1 },{ "solid-fuel",1 },{ name = "adamo-chemical-hydrofluoric-acid", type = "fluid", amount = 10 }} fluoride_battery_recipe.expensive.result_count = 1 fluoride_battery_recipe.expensive.ingredients = {{ name = "copper-plate", type = "item", amount = 2, catalyst_amount = 0 },{ "adamo-chemical-calcite",2 },{ "solid-fuel",2 },{ name = "adamo-chemical-hydrofluoric-acid", type = "fluid", amount = 20 }} local fluorite_science_pack = util.table.deepcopy( data.raw.recipe["chemical-science-pack"] ) fluorite_science_pack .name = "chemical-science-pack-from-fluorite" mult_recipe_energy(fluorite_science_pack,1/2) replace_recipe_io( fluorite_science_pack, "sulfur", "adamo-chemical-fluorite", 1 ) mult_recipe_io( fluorite_science_pack, 1.5, "chemical-science-pack" ) mult_recipe_io( fluorite_science_pack, 1.5, "engine-unit" ) data:extend({ processing_unit_from_hf_recipe, fluoride_battery_recipe, fluorite_science_pack }) add_recipe_to_tech( "advanced-electronics-2", processing_unit_from_hf_recipe.name ) add_recipe_to_tech( "adamo-chemical-fluorine-processing", fluoride_battery_recipe.name ) add_recipe_to_tech( "chemical-science-pack", fluorite_science_pack.name ) set_productivity_recipes({ fluoride_battery_recipe.name, processing_unit_from_hf_recipe.name, fluorite_science_pack.name }) -- Now make copies of everything. for _,recipe in pairs(data.raw.recipe) do local category = get_recipe_category(recipe) local main_result = get_main_result(recipe) local new_category local solid_input_count = 0 local fluid_input_count = 0 local solid_output_count = 0 local fluid_output_count = 0 local uses_plates = false local catalyst_inputs = 0 local catalyst_outputs = 0 local takes_water = false local outputs_water = false local uses_carbonation = false local uses_manufacturing = false if is_smelting_category(category) and has_ingredients(recipe) and has_results(recipe) then local calcined_recipe = calcinate_recipe(recipe) if calcined_recipe then mirror_recipe_in_techs( recipe, calcined_recipe ) if is_productivity_recipe(recipe) then set_productivity_recipe(calcined_recipe) end data:extend({calcined_recipe}) end end if is_chem_category(category) and has_ingredients(recipe) and has_results(recipe) then for k,ingredient in pairs( recipe.ingredients or recipe.expensive.ingredients or recipe.normal.ingredients ) do if ingredient.type ~= "fluid" then if manufacturing_needed_for(ingredient) then uses_manufacturing = true end if is_plate(ingredient) then uses_plates = true end if is_catalyst(ingredient) then catalyst_inputs = catalyst_inputs + 1 end if (ingredient.name or ingredient[1]) == "solid-fuel" then uses_carbonation = true end solid_input_count = solid_input_count + 1 elseif ingredient.name == "water" then takes_water = true fluid_input_count = fluid_input_count + 1 else fluid_input_count = fluid_input_count + 1 end end if type(recipe.results) == "table" or ( recipe.expensive and type(recipe.expensive.results) == "table" ) or ( recipe.normal and type(recipe.normal.results) == "table" ) then for k,result in pairs( recipe.results or recipe.expensive.results or recipe.normal.results ) do if result.type ~= "fluid" then solid_output_count = solid_output_count + 1 if is_catalyst(result) then catalyst_outputs = catalyst_outputs + 1 end else if result.name == "water" then outputs_water = true end fluid_output_count = fluid_output_count + 1 end end elseif recipe.result then solid_output_count = 1 elseif recipe.normal.result then solid_output_count = 1 elseif recipe.expensive.result then solid_output_count = 1 end -- Assign new recipe type. if uses_manufacturing then new_category = "adamo-chemical-manufacturing" elseif 2*catalyst_inputs > (fluid_input_count + solid_input_count) then new_category = "adamo-chemical-manufacturing" else new_category = chemical_category( recipe.name, solid_input_count, solid_output_count, fluid_input_count, fluid_output_count, catalyst_inputs, catalyst_outputs, takes_water, outputs_water, uses_carbonation ) if new_category == "adamo-chemical-binding" and not adamochemical.mixer then new_category = "adamo-chemical-manufacturing" end end if not ( new_category == "adamo-chemical-manufacturing" and category == "crafting-with-fluid" ) then local new_recipe = util.table.deepcopy(recipe) format_ingredients(new_recipe) format_results(new_recipe) new_recipe.name = "adamo-cc-"..recipe.name if main_result then set_main_product(new_recipe,main_result) end new_recipe.category = new_category new_recipe.subgroup = new_category if new_category == "adamo-chemical-binding" then mult_recipe_energy(new_recipe,binding_time_mult) mult_recipe_io(new_recipe,binding_prod_mult) elseif new_category == "adamo-chemical-separation" then mult_recipe_energy(new_recipe,separation_time_mult) mult_recipe_io(new_recipe,separation_prod_mult) elseif new_category == "adamo-chemical-vaporworks" then mult_recipe_energy(new_recipe,vapor_time_mult) mult_recipe_io(new_recipe,vapor_prod_mult) end fill_recipe_tint(new_recipe) new_recipe.always_show_products = true new_recipe.show_amount_in_title = true data:extend({new_recipe}) if is_productivity_recipe(recipe) then set_productivity_recipe(new_recipe) end mirror_recipe_in_techs(recipe,new_recipe) end end end -- Screeners should screen. if data.raw["recipe-category"]["screening"] then for _,recipe in pairs(data.raw.recipe) do if recipe.category == "adamo-chemical-separation" then local screen_recipe = util.table.deepcopy(recipe) screen_recipe.name = screen_recipe.name .."-by-screening" screen_recipe.category = "screening" screen_recipe.hide_from_player_crafting = true screen_recipe.order = screen_recipe.order if uses_ingredient(screen_recipe,"water") then remove_ingredient(screen_recipe,"water") for _,ingred_name in pairs( get_io_names(screen_recipe) ) do mult_recipe_io( screen_recipe, 1/screening_efficiency, ingred_name ) mult_recipe_io( screen_recipe, separation_time_mult ) mult_recipe_energy( screen_recipe, separation_time_mult ) end end data:extend({screen_recipe}) mirror_recipe_in_techs(recipe,screen_recipe) if is_productivity_recipe(recipe) then set_productivity_recipe(screen_recipe) end end end end