704 lines
28 KiB
Lua
704 lines
28 KiB
Lua
-------------------------------------------------------------------------------
|
|
---Description of the module.
|
|
---@class SolverMatrix
|
|
SolverMatrix = newclass(function(base)
|
|
end)
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Clone la matrice
|
|
---@param matrix Matrix
|
|
---@return Matrix
|
|
function SolverMatrix:clone(matrix)
|
|
local matrix_clone = table.deepcopy(matrix)
|
|
return matrix_clone
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Prepare la matrice
|
|
---@param matrix Matrix
|
|
---@return Matrix
|
|
function SolverMatrix:prepare(matrix)
|
|
local matrix_clone = self:clone(matrix)
|
|
self:prepare_z_and_objectives(matrix_clone, false)
|
|
return matrix_clone
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Prepare Z et objectives
|
|
---@param matrix Matrix
|
|
---@param reverse boolean reverse objective sign
|
|
function SolverMatrix:prepare_z_and_objectives(matrix, reverse)
|
|
local row = {}
|
|
local objective_values = {}
|
|
---ajoute la ligne Z avec Z=-input
|
|
for _, column in pairs(matrix.columns) do
|
|
local objective = matrix.objectives[column.key]
|
|
local objective_value = 0
|
|
if objective ~= nil then
|
|
objective_value = objective.value
|
|
end
|
|
if reverse then
|
|
objective_value = -objective_value
|
|
end
|
|
local value = 0 - objective_value
|
|
table.insert(row, value)
|
|
table.insert(objective_values, objective_value)
|
|
end
|
|
matrix.objective_values = objective_values
|
|
table.insert(matrix.rows, row)
|
|
end
|
|
-------------------------------------------------------------------------------
|
|
---Finalise la matrice
|
|
---@param matrix Matrix
|
|
---@return Matrix
|
|
function SolverMatrix:finalize(matrix)
|
|
---finalize la ligne Z reinject le input Z=Z+input
|
|
local zrow = matrix.rows[#matrix.rows]
|
|
for icol, column in pairs(matrix.columns) do
|
|
local objective = matrix.objective_values[icol] or 0
|
|
zrow[icol] = zrow[icol] + objective
|
|
end
|
|
return matrix
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Add runtime
|
|
---@param debug boolean
|
|
---@param runtime table
|
|
---@param name string
|
|
---@param matrix Matrix
|
|
---@param pivot? table
|
|
function SolverMatrix:add_runtime(debug, runtime, name, matrix, pivot)
|
|
if debug == true then
|
|
local clone = table.deepcopy(matrix)
|
|
table.insert(runtime, { name = name, matrix = clone, pivot = pivot })
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Ajoute la ligne State
|
|
---state = 0 => produit
|
|
---state = 1 => produit pilotant
|
|
---state = 2 => produit restant
|
|
---state = 3 => produit surplus
|
|
---@param matrix Matrix
|
|
---@return Matrix
|
|
function SolverMatrix:apply_state(matrix)
|
|
local states = {}
|
|
for irow, row in pairs(matrix.rows) do
|
|
if irow < #matrix.rows then
|
|
for icol, column in pairs(matrix.columns) do
|
|
local cell_value = row[icol] or 0
|
|
if states[icol] == nil then
|
|
table.insert(states, 0)
|
|
end
|
|
if cell_value < 0 then
|
|
states[icol] = 2
|
|
end
|
|
if cell_value > 0 and states[icol] ~= 2 then
|
|
states[icol] = 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local zrow = matrix.rows[#matrix.rows]
|
|
for icol, cell in pairs(zrow) do
|
|
if cell > 0 and states[icol] == 2 then
|
|
states[icol] = 3
|
|
end
|
|
end
|
|
matrix.states = states
|
|
return matrix
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Abstract Resoud la matrice
|
|
---@param matrix_base Matrix
|
|
---@param debug boolean
|
|
---@param by_factory boolean
|
|
---@param time number
|
|
---@return Matrix, table
|
|
function SolverMatrix:solve_matrix(matrix_base, debug, by_factory, time)
|
|
end
|
|
-------------------------------------------------------------------------------
|
|
---Return a matrix of block
|
|
---@param block table
|
|
---@param parameters ParametersData
|
|
---@param debug boolean
|
|
---@return table
|
|
function SolverMatrix:solve(block, parameters, debug)
|
|
local mC, runtimes
|
|
|
|
local ok, err = pcall(function()
|
|
local mA = SolverMatrix.get_block_matrix(block, parameters)
|
|
if mA ~= nil then
|
|
mC, runtimes = self:solve_matrix(mA, debug, block.by_factory, block.time)
|
|
end
|
|
end)
|
|
if not (ok) then
|
|
if block.solver == true and block.by_factory ~= true then
|
|
Player.print("Matrix solver can not find solution!")
|
|
else
|
|
Player.print("Algebraic solver can not find solution!")
|
|
end
|
|
if debug then
|
|
Player.print(err)
|
|
end
|
|
end
|
|
if debug then
|
|
block.runtimes = runtimes
|
|
else
|
|
block.runtimes = nil
|
|
end
|
|
|
|
if mC ~= nil then
|
|
---remove temperature convert lines
|
|
---necessary to retieve the right value
|
|
for i = #mC.headers, 1, -1 do
|
|
if mC.headers[i].name == "helmod-temperature-convert" then
|
|
table.remove(mC.rows, i)
|
|
table.remove(mC.headers, i)
|
|
table.remove(mC.parameters, i)
|
|
end
|
|
end
|
|
|
|
---ratio pour le calcul du nombre de block
|
|
local ratio = 1
|
|
---calcul ordonnee sur les recipes du block
|
|
local row_index = 1
|
|
local sorter = function(t, a, b) return t[b].index > t[a].index end
|
|
if block.by_product == false then
|
|
sorter = function(t, a, b) return t[b].index < t[a].index end
|
|
end
|
|
|
|
local recipes = block.recipes
|
|
for _, recipe in spairs(recipes, sorter) do
|
|
local parameters = mC.parameters[row_index]
|
|
if parameters.recipe_count > 0 then
|
|
recipe.count = parameters.recipe_count
|
|
recipe.production = parameters.recipe_production
|
|
else
|
|
recipe.count = 0
|
|
end
|
|
row_index = row_index + 1
|
|
---calcul dependant du recipe count
|
|
if recipe.type == "energy" then
|
|
ModelCompute.computeEnergyFactory(recipe)
|
|
else
|
|
ModelCompute.computeFactory(recipe)
|
|
end
|
|
|
|
block.power = block.power + recipe.energy_total
|
|
block.pollution_total = block.pollution_total + recipe.pollution_total
|
|
|
|
if type(recipe.factory.limit) == "number" and recipe.factory.limit > 0 then
|
|
local currentRatio = recipe.factory.limit / recipe.factory.count
|
|
if currentRatio < ratio then
|
|
ratio = currentRatio
|
|
---block number
|
|
block.count = recipe.factory.count / recipe.factory.limit
|
|
---subblock energy
|
|
if block.count ~= nil and block.count > 0 then
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if block.count <= 1 then
|
|
block.count = 1
|
|
block.limit_energy = nil
|
|
block.limit_pollution = nil
|
|
block.limit_building = nil
|
|
for _, recipe in spairs(recipes, function(t, a, b) return t[b].index > t[a].index end) do
|
|
recipe.factory.limit_count = nil
|
|
if recipe.beacons ~= nil then
|
|
for _, beacon in pairs(recipe.beacons) do
|
|
beacon.limit_count = nil
|
|
end
|
|
end
|
|
recipe.limit_energy = nil
|
|
recipe.limit_pollution = nil
|
|
end
|
|
else
|
|
block.limit_energy = block.power / block.count
|
|
block.limit_pollution = block.pollution_total / block.count
|
|
for _, recipe in spairs(recipes, function(t, a, b) return t[b].index > t[a].index end) do
|
|
recipe.factory.limit_count = recipe.factory.count / block.count
|
|
if recipe.beacons ~= nil then
|
|
for _, beacon in pairs(recipe.beacons) do
|
|
beacon.limit_count = beacon.count / block.count
|
|
end
|
|
end
|
|
recipe.limit_energy = recipe.energy_total / block.count
|
|
recipe.limit_pollution = recipe.pollution_total / block.count
|
|
end
|
|
end
|
|
---state = 0 => produit
|
|
---state = 1 => produit pilotant
|
|
---state = 2 => produit restant
|
|
---state = 3 => produit surplus
|
|
|
|
---finalisation du bloc
|
|
for icol, state in pairs(mC.states) do
|
|
if icol > 0 then
|
|
local rows = mC.rows
|
|
local zrow = rows[#mC.rows]
|
|
local Z = math.abs(zrow[icol])
|
|
local product_header = mC.columns[icol]
|
|
local product_key = product_header.key
|
|
local product = Product(product_header):clone()
|
|
product.count = Z
|
|
product.state = state
|
|
if block.by_product == false then
|
|
if state == 1 or state == 3 then
|
|
---element produit
|
|
if block.ingredients[product_key] ~= nil then
|
|
block.ingredients[product_key].count = block.ingredients[product_key].count +
|
|
product.count
|
|
block.ingredients[product_key].state = state
|
|
end
|
|
if block.products[product_key] ~= nil then
|
|
block.products[product_key].state = 0
|
|
end
|
|
else
|
|
---element ingredient
|
|
if block.products[product_key] ~= nil then
|
|
block.products[product_key].count = block.products[product_key].count + product.count
|
|
block.products[product_key].state = state
|
|
end
|
|
if block.ingredients[product_key] ~= nil then
|
|
block.ingredients[product_key].state = state
|
|
end
|
|
end
|
|
else
|
|
if state == 1 or state == 3 then
|
|
---element produit
|
|
if block.products[product_key] ~= nil then
|
|
block.products[product_key].count = block.products[product_key].count + product.count
|
|
block.products[product_key].state = state
|
|
end
|
|
if block.ingredients[product_key] ~= nil then
|
|
block.ingredients[product_key].state = 0
|
|
end
|
|
else
|
|
---element ingredient
|
|
if block.ingredients[product_key] ~= nil then
|
|
block.ingredients[product_key].count = block.ingredients[product_key].count +
|
|
product.count
|
|
block.ingredients[product_key].state = state
|
|
end
|
|
if block.products[product_key] ~= nil then
|
|
block.products[product_key].state = state
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return block
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Return a matrix of block
|
|
---@param block table
|
|
---@param parameters ParametersData
|
|
---@return table
|
|
function SolverMatrix.get_block_matrix(block, parameters)
|
|
local recipes = block.recipes
|
|
if recipes ~= nil then
|
|
local matrix = Matrix()
|
|
local col_index = {}
|
|
---begin loop recipes
|
|
local factor = 1
|
|
local sorter = function(t, a, b) return t[b].index > t[a].index end
|
|
if block.by_product == false then
|
|
factor = -factor
|
|
sorter = function(t, a, b) return t[b].index < t[a].index end
|
|
end
|
|
|
|
for _, recipe in spairs(recipes, sorter) do
|
|
recipe.base_time = block.time
|
|
ModelCompute.computeModuleEffects(recipe, parameters)
|
|
if recipe.type == "energy" then
|
|
ModelCompute.computeEnergyFactory(recipe)
|
|
else
|
|
ModelCompute.computeFactory(recipe)
|
|
end
|
|
|
|
|
|
local row_valid = false
|
|
local recipe_prototype = RecipePrototype(recipe)
|
|
local lua_recipe = recipe_prototype:native()
|
|
|
|
---la recette n'existe plus
|
|
if recipe_prototype:native() == nil then return end
|
|
|
|
---prepare le taux de production
|
|
local production = 1
|
|
if not (block.solver == true) and recipe.production ~= nil then production = recipe.production end
|
|
|
|
local rowParameters = MatrixRowParameters()
|
|
local row = MatrixRow(recipe.type, recipe.name, recipe.name .. "\nRecette")
|
|
|
|
rowParameters.base = row.header
|
|
if recipe.contraint ~= nil then
|
|
rowParameters.contraint = { type = recipe.contraint.type, name = recipe.contraint.name }
|
|
end
|
|
rowParameters.factory_count = recipe.factory.input or 0
|
|
rowParameters.factory_speed = recipe.factory.speed or 0
|
|
rowParameters.recipe_count = 0
|
|
rowParameters.recipe_production = production
|
|
rowParameters.recipe_energy = recipe_prototype:getEnergy(recipe.factory)
|
|
rowParameters.coefficient = 0
|
|
|
|
---preparation
|
|
local lua_products = {}
|
|
local lua_ingredients = {}
|
|
for i, lua_product in pairs(recipe_prototype:getProducts(recipe.factory)) do
|
|
local product = Product(lua_product)
|
|
local product_key = product:getTableKey()
|
|
local count = product:getAmount(recipe)
|
|
lua_products[product_key] = { name = lua_product.name, type = lua_product.type, count = count,
|
|
temperature = lua_product.temperature, minimum_temperature = lua_product.minimum_temperature,
|
|
maximum_temperature = lua_product.maximum_temperature }
|
|
end
|
|
for i, lua_ingredient in pairs(recipe_prototype:getIngredients(recipe.factory)) do
|
|
local ingredient = Product(lua_ingredient)
|
|
local ingredient_key = ingredient:getTableKey()
|
|
local count = ingredient:getAmount()
|
|
---si constant compte comme un produit (recipe rocket)
|
|
if lua_ingredient.constant then
|
|
count = ingredient:getAmount(recipe)
|
|
end
|
|
if lua_ingredients[ingredient_key] == nil then
|
|
lua_ingredients[ingredient_key] = { name = lua_ingredient.name, type = lua_ingredient.type,
|
|
count = count, temperature = lua_ingredient.temperature,
|
|
minimum_temperature = lua_ingredient.minimum_temperature,
|
|
maximum_temperature = lua_ingredient.maximum_temperature }
|
|
else
|
|
lua_ingredients[ingredient_key].count = lua_ingredients[ingredient_key].count + count
|
|
end
|
|
end
|
|
|
|
if not (block.by_product == false) then
|
|
---prepare header products
|
|
for name, lua_product in pairs(lua_products) do
|
|
local product = Product(lua_product)
|
|
local product_key = product:getTableKey()
|
|
local index = 1
|
|
if col_index[product_key] ~= nil then
|
|
index = col_index[product_key]
|
|
end
|
|
col_index[product_key] = index
|
|
|
|
local col_name = product_key .. index
|
|
|
|
local col_header = MatrixHeader()
|
|
col_header.sysname = col_name
|
|
col_header.tooltip = col_name .. "\nProduit"
|
|
col_header.index = index
|
|
col_header.key = product_key
|
|
col_header.is_ingredient = false
|
|
col_header.product = lua_product
|
|
|
|
local cell_value = lua_product.count * factor
|
|
row:add_value(col_header, cell_value)
|
|
|
|
if rowParameters.contraint ~= nil and rowParameters.contraint.name == name then
|
|
rowParameters.contraint.name = col_name
|
|
end
|
|
|
|
row_valid = true
|
|
end
|
|
---prepare header ingredients
|
|
for name, lua_ingredient in pairs(lua_ingredients) do
|
|
local ingredient = Product(lua_ingredient)
|
|
local ingredient_key = ingredient:getTableKey()
|
|
local index = 1
|
|
---cas normal de l'ingredient n'existant pas du cote produit
|
|
if col_index[ingredient_key] ~= nil and lua_products[ingredient_key] == nil then
|
|
index = col_index[ingredient_key]
|
|
end
|
|
---cas de l'ingredient existant du cote produit
|
|
if col_index[ingredient_key] ~= nil and lua_products[ingredient_key] ~= nil then
|
|
---cas de la valeur equivalente, on creer un nouveau element
|
|
if lua_products[ingredient_key].count == lua_ingredients[ingredient_key].count or recipe.type == "resource" or recipe.type == "energy" then
|
|
index = col_index[ingredient_key] + 1
|
|
else
|
|
index = col_index[ingredient_key]
|
|
end
|
|
end
|
|
col_index[ingredient_key] = index
|
|
|
|
local col_name = ingredient_key .. index
|
|
|
|
local col_header = MatrixHeader()
|
|
col_header.sysname = col_name
|
|
col_header.tooltip = col_name .. "\nIngredient"
|
|
col_header.index = index
|
|
col_header.key = ingredient_key
|
|
col_header.is_ingredient = true
|
|
col_header.product = lua_ingredient
|
|
|
|
local cell_value = row:get_value(col_header) or 0
|
|
cell_value = cell_value - lua_ingredients[ingredient_key].count * factor
|
|
row:add_value(col_header, cell_value)
|
|
|
|
row_valid = true
|
|
end
|
|
else
|
|
---prepare header ingredients
|
|
for name, lua_ingredient in pairs(lua_ingredients) do
|
|
local ingredient = Product(lua_ingredient)
|
|
local ingredient_key = ingredient:getTableKey()
|
|
local index = 1
|
|
---cas normal de l'ingredient n'existant pas du cote produit
|
|
if col_index[ingredient_key] ~= nil then
|
|
index = col_index[ingredient_key]
|
|
end
|
|
col_index[ingredient_key] = index
|
|
|
|
local col_name = ingredient_key .. index
|
|
|
|
local col_header = MatrixHeader()
|
|
col_header.sysname = col_name
|
|
col_header.tooltip = col_name .. "\nIngredient"
|
|
col_header.index = index
|
|
col_header.key = ingredient_key
|
|
col_header.is_ingredient = true
|
|
col_header.product = lua_ingredient
|
|
|
|
local cell_value = -lua_ingredient.count * factor
|
|
row:add_value(col_header, cell_value)
|
|
|
|
if rowParameters.contraint ~= nil and rowParameters.contraint.name == name then
|
|
rowParameters.contraint.name = col_name
|
|
end
|
|
row_valid = true
|
|
end
|
|
---prepare header products
|
|
for name, lua_product in pairs(lua_products) do
|
|
local product = Product(lua_product)
|
|
local product_key = product:getTableKey()
|
|
local index = 1
|
|
if col_index[product_key] ~= nil then
|
|
index = col_index[product_key]
|
|
end
|
|
---cas du produit existant du cote ingredient
|
|
if col_index[product_key] ~= nil and lua_ingredients[product_key] ~= nil then
|
|
---cas de la valeur equivalente, on creer un nouveau element
|
|
if lua_products[product_key].count == lua_ingredients[product_key].count or recipe.type == "resource" or recipe.type == "energy" then
|
|
index = col_index[product_key] + 1
|
|
else
|
|
index = col_index[product_key]
|
|
end
|
|
end
|
|
col_index[product_key] = index
|
|
|
|
local col_name = product_key .. index
|
|
|
|
local col_header = MatrixHeader()
|
|
col_header.sysname = col_name
|
|
col_header.tooltip = col_name .. "\nProduit"
|
|
col_header.index = index
|
|
col_header.key = product_key
|
|
col_header.is_ingredient = false
|
|
col_header.product = lua_product
|
|
|
|
local cell_value = row:get_value(col_header) or 0
|
|
cell_value = cell_value + lua_product.count * factor
|
|
row:add_value(col_header, cell_value)
|
|
|
|
row_valid = true
|
|
end
|
|
end
|
|
if row_valid then
|
|
matrix:add_row(row, rowParameters)
|
|
end
|
|
end
|
|
|
|
---end loop recipes
|
|
|
|
local objectives = {}
|
|
local input_ready = {}
|
|
local block_elements = block.products
|
|
if block.by_product == false then
|
|
block_elements = block.ingredients
|
|
end
|
|
for _, column in pairs(matrix.columns) do
|
|
if block_elements ~= nil and block_elements[column.key] ~= nil and not (input_ready[column.key]) and column.index == 1 then
|
|
local objective = {}
|
|
objective.value = block_elements[column.key].input or 0
|
|
objective.key = column.key
|
|
objectives[column.key] = objective
|
|
input_ready[column.key] = true
|
|
end
|
|
end
|
|
|
|
matrix = SolverMatrix.linkTemperatureFluid(matrix, block.by_product)
|
|
matrix.objectives = objectives
|
|
return matrix
|
|
end
|
|
return nil
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Link Temperature Fluid
|
|
---@param matrix table
|
|
---@param by_product boolean
|
|
---@return table
|
|
function SolverMatrix.linkTemperatureFluid(matrix, by_product)
|
|
---Create blank parameters
|
|
local template_parameters = MatrixRowParameters()
|
|
template_parameters.factory_count = 0
|
|
template_parameters.factory_speed = 1
|
|
template_parameters.recipe_count = 0
|
|
template_parameters.recipe_production = 1
|
|
template_parameters.recipe_energy = 1
|
|
template_parameters.coefficient = 0
|
|
|
|
---Create blank row
|
|
local template_row = {}
|
|
for _, column in pairs(matrix.columns) do
|
|
table.insert(template_row, 0)
|
|
end
|
|
|
|
local mA2 = Matrix()
|
|
local block_ingredient_fluids = {}
|
|
local block_product_fluids = {}
|
|
|
|
for irow, row in pairs(matrix.rows) do
|
|
local rowParameters = matrix.parameters[irow]
|
|
local rowHeader = matrix.headers[irow]
|
|
local rowMatrix = MatrixRow(rowHeader.type, rowHeader.name, rowHeader.tooltip)
|
|
rowMatrix.columns = matrix.columns
|
|
rowMatrix.columnIndex = matrix.columnIndex
|
|
rowMatrix.values = row
|
|
|
|
|
|
local ingredient_fluids = {}
|
|
local product_fluids = {}
|
|
|
|
for icol, column in pairs(matrix.columns) do
|
|
local cell_value = row[icol] or 0
|
|
local product = column.product
|
|
if (column.key ~= nil) and (product.type == "fluid") then
|
|
if cell_value > 0 then
|
|
block_product_fluids[product.name] = block_product_fluids[product.name] or {}
|
|
block_product_fluids[product.name][column.key] = column
|
|
product_fluids[column.key] = column
|
|
elseif cell_value < 0 then
|
|
ingredient_fluids[column.key] = column
|
|
end
|
|
end
|
|
end
|
|
|
|
---Convert any Z into product
|
|
for _, product_fluid in pairs(product_fluids) do
|
|
local product = product_fluid.product
|
|
local linked_fluids = block_ingredient_fluids[product.name] or {}
|
|
for _, linked_fluid in pairs(linked_fluids) do
|
|
if SolverMatrix.checkLinkedTemperatureFluid(product_fluid, linked_fluid, by_product) then
|
|
local parameters = MatrixRowParameters()
|
|
local new_row = MatrixRow("recipe", "helmod-temperature-convert", "")
|
|
new_row:add_value(product_fluid, -1)
|
|
new_row:add_value(linked_fluid, 1)
|
|
mA2:add_row(new_row, parameters)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Insert the row
|
|
mA2:add_row(rowMatrix, rowParameters)
|
|
|
|
---Convert any overflow product back into Z
|
|
for _, product_fluid in pairs(product_fluids) do
|
|
local product = product_fluid.product
|
|
local linked_fluids = block_ingredient_fluids[product.name] or {}
|
|
for _, linked_fluid in pairs(linked_fluids) do
|
|
if SolverMatrix.checkLinkedTemperatureFluid(product_fluid, linked_fluid, by_product) then
|
|
local parameters = MatrixRowParameters()
|
|
local new_row = MatrixRow("recipe", "helmod-temperature-convert", "")
|
|
new_row:add_value(product_fluid, 1)
|
|
new_row:add_value(linked_fluid, -1)
|
|
mA2:add_row(new_row, parameters)
|
|
end
|
|
end
|
|
end
|
|
|
|
---If an ingredient has already been made in this block
|
|
---Convert any Z into ingredient
|
|
---Convert any unmet ingredient back into Z
|
|
for _, ingredient_fluid in pairs(ingredient_fluids) do
|
|
local product = ingredient_fluid.product
|
|
block_ingredient_fluids[product.name] = block_ingredient_fluids[product.name] or {}
|
|
block_ingredient_fluids[product.name][ingredient_fluid.key] = ingredient_fluid
|
|
|
|
local linked_fluids = block_product_fluids[product.name] or {}
|
|
for _, linked_fluid in pairs(linked_fluids) do
|
|
if SolverMatrix.checkLinkedTemperatureFluid(linked_fluid, ingredient_fluid, by_product) then
|
|
local parameters = MatrixRowParameters()
|
|
local new_row = MatrixRow("recipe", "helmod-temperature-convert", "")
|
|
new_row:add_value(linked_fluid, -1)
|
|
new_row:add_value(ingredient_fluid, 1)
|
|
mA2:add_row(new_row, parameters)
|
|
|
|
local parameters = MatrixRowParameters()
|
|
local new_row = MatrixRow("recipe", "helmod-temperature-convert", "")
|
|
new_row:add_value(linked_fluid, 1)
|
|
new_row:add_value(ingredient_fluid, -1)
|
|
mA2:add_row(new_row, parameters)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return mA2
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Check Linked Temperature Fluid
|
|
---@param item1 table
|
|
---@param item2 table
|
|
---@param by_product boolean
|
|
---@return boolean
|
|
function SolverMatrix.checkLinkedTemperatureFluid(item1, item2, by_product)
|
|
local result = false
|
|
|
|
local product, ingredient
|
|
if by_product ~= false then
|
|
product = item1
|
|
ingredient = item2
|
|
else
|
|
product = item2
|
|
ingredient = item1
|
|
end
|
|
|
|
if product.key ~= ingredient.key then
|
|
local T = product.product.temperature
|
|
local T2 = ingredient.product.temperature
|
|
local T2min = ingredient.product.minimum_temperature
|
|
local T2max = ingredient.product.maximum_temperature
|
|
if T ~= nil or T2 ~= nil or T2min ~= nil or T2max ~= nil then
|
|
---traitement seulement si une temperature
|
|
if T2min == nil and T2max == nil then
|
|
---Temperature sans intervale
|
|
if T == nil or T2 == nil or T2 == T then
|
|
result = true
|
|
end
|
|
else
|
|
---Temperature avec intervale
|
|
---securise les valeurs
|
|
T = T or 25
|
|
T2min = T2min or -defines.constant.max_float
|
|
T2max = T2max or defines.constant.max_float
|
|
if T >= T2min and T <= T2max then
|
|
result = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return result
|
|
end |