require("factsheet") adamo.opts.debugging = true adamo.opts.logging = true 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_mult 5 and 150kW, ~10-25 ore_mult is the range -- between stone and steel furnace power use local ore_mult = 1/adamo.geo.ore.impurity_ratio local time_mult = ore_mult/5 local flux_name = "adamo-chemical-calcite" local clinker_name = "adamo-chemical-clinker" local fluxxing_category = "adamo-chemical-firing" local fluxxing_subgroup = fluxxing_category 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_mult end local count_minerals = function(ore_count) return math.ceil(ore_count * adamo.geo.ore.impurity_ratio) end local flux_recipe = util.table.deepcopy(recipe) flux_recipe.name = flux_recipe.name.."-calcined" mult_recipe_energy(flux_recipe,time_mult/ore_mult*mult) mult_in_recipe(flux_recipe,mult) flux_recipe.category = fluxxing_category flux_recipe.subgroup = fluxxing_subgroup local ore_count = 0 for ore,plate in pairs(adamo.chem.fluxables) do if uses_ingredient(flux_recipe,plate) then io_manip(flux_recipe,plate,ore) end local x,this_ore_count,x = get_ingredient(flux_recipe,ore) ore_count = ore_count + (this_ore_count or 0) -- broken --if this_ore_count > 0 then -- add_ingredient( -- flux_recipe, -- ore, -- 1 -- ) --end end if ore_count == 0 then if uses_ingredient(flux_recipe,"stone") then x,stone_count,x = get_ingredient(flux_recipe,"stone") io_manip(flux_recipe,"stone",clinker_name,1/2) local flux_count = math.ceil(stone_count/2) add_ingredient(flux_recipe,flux_name,flux_count) return flux_recipe else return nil end end local flux_count = math.ceil(ore_count/ore_mult) local clinker_count = flux_count local mineral_count = flux_count local clinker_prob = 1/adamo.chem.ratio.lime_per_clinker local mineral_prob = 1 - clinker_prob add_ingredient(flux_recipe,flux_name,flux_count) add_result(flux_recipe,clinker_name,clinker_count,clinker_prob) for chemical,abundance in pairs(adamo.geo.ore.mineral_results) do if data.raw.item[chemical] then add_result( flux_recipe, chemical, mineral_count, abundance*mineral_prob ) end end return flux_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" fluorite_science_pack.category = "advanced-crafting" fluorite_science_pack.category = "crafting-with-fluid" fluorite_science_pack.category = "chemistry" mult_recipe_energy(fluorite_science_pack,1/2) replace_in_recipe( fluorite_science_pack, "sulfur", "adamo-chemical-hydrofluoric-acid", 10 ) mult_in_recipe( fluorite_science_pack, 1.5, "chemical-science-pack" ) mult_in_recipe( fluorite_science_pack, 1.5, "engine-unit" ) adamo.recipe.tint.apply(fluorite_science_pack) 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_recipes_to_tech( "adamo-chemical-fluorine-processing", { fluoride_battery_recipe.name, 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_in_recipe(new_recipe,binding_prod_mult) elseif new_category == "adamo-chemical-separation" then mult_recipe_energy(new_recipe,separation_time_mult) mult_in_recipe(new_recipe,separation_prod_mult) elseif new_category == "adamo-chemical-vaporworks" then mult_recipe_energy(new_recipe,vapor_time_mult) mult_in_recipe(new_recipe,vapor_prod_mult) end adamo.recipe.tint.apply(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_in_recipe( screen_recipe, 1/screening_efficiency, ingred_name ) mult_in_recipe( 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