mirror of
https://asciireactor.com/factorio/adamo-chemical.git
synced 2024-11-21 22:35:07 +00:00
618 lines
15 KiB
Lua
618 lines
15 KiB
Lua
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_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)
|
|
calcined_recipe.name = calcined_recipe.name.."-calcined"
|
|
mult_recipe_energy(
|
|
calcined_recipe,mult*time_norm/ore_norm
|
|
)
|
|
mult_recipe_io(calcined_recipe,mult)
|
|
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,iron_ore_count,toss =
|
|
get_ingredient(calcined_recipe,"iron-ore")
|
|
local toss,copper_ore_count,toss =
|
|
get_ingredient(calcined_recipe,"copper-ore")
|
|
local ore_count = (iron_ore_count or 0) + (copper_ore_count or 0)
|
|
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 |