1059 lines
39 KiB
Lua

------------------------------------------------------------------------------
---Description of the module.
---@class ModelBuilder
local ModelBuilder = {
---single-line comment
classname = "HMModelBuilder"
}
-------------------------------------------------------------------------------
---Add a recipe into production block
---@param model table
---@param block table
---@param recipe_name string
---@param recipe_type string
---@param index number
---@return table, table
function ModelBuilder.addRecipeIntoProductionBlock(model, block, recipe_name, recipe_type, index)
local recipe_prototype = RecipePrototype(recipe_name, recipe_type)
local lua_recipe = recipe_prototype:native()
if lua_recipe ~= nil then
local block_types = true
---ajoute le bloc si il n'existe pas
if block == nil then
local modelBlock = Model.newBlock(model, lua_recipe)
local block_index = table.size(model.blocks)
modelBlock.index = block_index
modelBlock.unlinked = false
block = modelBlock
model.blocks[modelBlock.id] = modelBlock
---check si le block est independant
ModelCompute.checkUnlinkedBlock(model, modelBlock)
block_types = false
end
---ajoute le recipe si il n'existe pas
local ModelRecipe = Model.newRecipe(model, lua_recipe.name, recipe_type)
local icon_name, icon_type = recipe_prototype:getIcon()
if not (block_types) then
block.type = icon_type
end
if index == nil then
local recipe_index = table.size(block.recipes)
ModelRecipe.index = recipe_index
else
ModelRecipe.index = index
for _, recipe in pairs(block.recipes) do
if recipe.index >= index then
recipe.index = recipe.index + 1
end
end
end
if ModelRecipe.index == 0 then
---change block name
block.name = icon_name
block.type = icon_type
end
ModelRecipe.count = 1
if recipe_type ~= "energy" then
local default_factory = User.getDefaultFactory(ModelRecipe)
if default_factory ~= nil then
Model.setFactory(ModelRecipe, default_factory.name, default_factory.fuel)
ModelBuilder.setFactoryModulePriority(ModelRecipe, default_factory.module_priority)
else
local default_factory_name = Model.getDefaultPrototypeFactory(recipe_prototype)
if default_factory_name ~= nil then
Model.setFactory(ModelRecipe, default_factory_name)
end
end
local default_beacons = User.getDefaultBeacons(ModelRecipe)
if default_beacons ~= nil then
for _, default_beacon in pairs(default_beacons) do
local beacon = Model.addBeacon(ModelRecipe, default_beacon.name, default_beacon.combo, default_beacon.per_factory, default_beacon.per_factory_constant)
ModelBuilder.setBeaconModulePriority(beacon, ModelRecipe, default_beacon.module_priority)
end
end
else
Model.setFactory(ModelRecipe, recipe_name)
end
local recipe_products
local recipe_ingredients
local block_products
local block_ingredients
if block.by_product == false then
recipe_products = recipe_prototype:getIngredients(ModelRecipe.factory)
recipe_ingredients = recipe_prototype:getProducts()
block_products = block.ingredients
block_ingredients = block.products
else
recipe_products = recipe_prototype:getProducts()
recipe_ingredients = recipe_prototype:getIngredients(ModelRecipe.factory)
block_products = block.products
block_ingredients = block.ingredients
end
---ajoute les produits du block
for _, lua_product in pairs(recipe_products) do
local product = Product(lua_product):clone()
local element_key = Product(lua_product):getTableKey()
if block_products[element_key] == nil then
if block_ingredients[element_key] ~= nil then
product.state = 2
else
product.state = 1
end
block_products[element_key] = product
end
end
---ajoute les ingredients du block
for _, lua_ingredient in pairs(recipe_ingredients) do
local ingredient = Product(lua_ingredient):clone()
local element_key = Product(lua_ingredient):getTableKey()
if block_ingredients[element_key] == nil then
block_ingredients[element_key] = ingredient
if block_products[element_key] ~= nil and block_products[element_key].state == 1 then
block_products[element_key].state = 2
end
end
end
block.recipes[ModelRecipe.id] = ModelRecipe
return block, ModelRecipe
end
end
-------------------------------------------------------------------------------
---Remove a model
---@param model table
---@param block table
---@param recipe table
---@param with_below boolean
function ModelBuilder.convertRecipeToblock(model, block, recipe, with_below)
local new_block = Model.newBlock(model, recipe)
local block_index = table.size(model.blocks)
new_block.index = block_index
new_block.type = block.type
new_block.unlinked = block.by_factory and true or false
new_block.by_factory = block.by_factory
new_block.by_product = block.by_product
new_block.by_limit = block.by_limit
model.blocks[new_block.id] = new_block
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 start_index = recipe.index
for _, block_recipe in spairs(block.recipes, sorter) do
if
(block_recipe.index == start_index)
or ((block.by_product == false) == (block_recipe.index < start_index))
then
---clean block
block.recipes[block_recipe.id] = nil
---add recipe
block_recipe.index = table.size(new_block.recipes)
new_block.recipes[block_recipe.id] = block_recipe
if with_below ~= true then
break
end
end
end
local block_products, block_ingredients = ModelCompute.prepareBlock(new_block)
new_block.products = block_products
new_block.ingredients = block_ingredients
---check si le block est independant
ModelCompute.checkUnlinkedBlock(model, new_block)
end
-------------------------------------------------------------------------------
---Remove a model
---@param model_id string
function ModelBuilder.removeModel(model_id)
global.models[model_id] = nil
end
-------------------------------------------------------------------------------
---Update recipe production
---@param recipe table
---@param production number
function ModelBuilder.updateRecipeProduction(recipe, production)
if recipe ~= nil then
recipe.production = production
end
end
-------------------------------------------------------------------------------
---Update a factory number
---@param recipe table
---@param value any
function ModelBuilder.updateFactoryNumber(recipe, value)
if recipe ~= nil then
if value == 0 then
recipe.factory.input = nil
else
recipe.factory.input = value
end
end
end
-------------------------------------------------------------------------------
---Update a factory limit
---@param recipe table
---@param value any
function ModelBuilder.updateFactoryLimit(recipe, value)
if recipe ~= nil then
if value == 0 then
recipe.factory.limit = nil
else
recipe.factory.limit = value
end
end
end
-------------------------------------------------------------------------------
---Update block matrix solver
---@param block table
---@param value any
function ModelBuilder.updateBlockMatrixSolver(block, value)
if block ~= nil then
block.solver = value
end
end
-------------------------------------------------------------------------------
---Update recipe matrix solver
---@param block table
---@param recipe table
function ModelBuilder.updateMatrixSolver(block, recipe)
if block ~= nil then
local recipes = block.recipes
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 apply = false
local matrix_solver = 0
for _, current_recipe in spairs(recipes, sorter) do
if apply == true and current_recipe.matrix_solver == matrix_solver then
apply = false
end
if apply == true and current_recipe.matrix_solver ~= matrix_solver then
current_recipe.matrix_solver = matrix_solver
end
if current_recipe.id == recipe.id then
if current_recipe.matrix_solver == 0 then
matrix_solver = 1
else
matrix_solver = 0
end
current_recipe.matrix_solver = matrix_solver
apply = true
end
end
end
end
-------------------------------------------------------------------------------
---Update a factory
---@param recipe RecipeData
---@param fuel string | FuelData
function ModelBuilder.updateFuelFactory(recipe, fuel)
if recipe ~= nil and fuel ~= nil then
recipe.factory.fuel = fuel
end
end
-------------------------------------------------------------------------------
---Convert factory modules to a prority module
---@param factory table
---@return table
function ModelBuilder.convertModuleToPriority(factory)
local module_priority = {}
for name, value in pairs(factory.modules or {}) do
table.insert(module_priority, { name = name, value = value })
end
return module_priority
end
-------------------------------------------------------------------------------
---Add a module to prority module
---@param factory table
---@param module_name string
---@param module_max number
---@return table
function ModelBuilder.addModulePriority(factory, module_name, module_max)
local module_priority = ModelBuilder.convertModuleToPriority(factory)
local factory_prototype = EntityPrototype(factory)
if Model.countModulesModel(factory) < factory_prototype:getModuleInventorySize() then
local count = 1
if module_max then
count = factory_prototype:getModuleInventorySize() - Model.countModulesModel(factory)
end
local success = false
---parcours la priorite
for i, priority in pairs(module_priority) do
if priority.name == module_name then
priority.value = priority.value + count
success = true
end
end
if success == false then
table.insert(module_priority, { name = module_name, value = count })
end
end
return module_priority
end
-------------------------------------------------------------------------------
---Remove module priority
---@param factory table
---@param module_name string
---@param module_max number
---@return table
function ModelBuilder.removeModulePriority(factory, module_name, module_max)
local module_priority = ModelBuilder.convertModuleToPriority(factory)
---parcours la priorite
local index = nil
for i, priority in pairs(module_priority) do
if priority.name == module_name then
if priority.value > 1 and not (module_max) then
priority.value = priority.value - 1
else
index = i
end
end
end
if index ~= nil then
table.remove(module_priority, index)
end
return module_priority
end
-------------------------------------------------------------------------------
---Add a module in factory
---@param recipe RecipeData
---@param module_name string
---@param module_max number
function ModelBuilder.addFactoryModule(recipe, module_name, module_max)
local module = ItemPrototype(module_name)
if recipe ~= nil and module:native() ~= nil then
if Player.checkFactoryLimitationModule(module:native(), recipe) == true then
local module_priority = ModelBuilder.addModulePriority(recipe.factory, module_name, module_max or false)
ModelBuilder.setFactoryModulePriority(recipe, module_priority)
end
end
end
-------------------------------------------------------------------------------
---Set a module in factory
---@param recipe RecipeData
---@param module_name string
---@param module_value number
---@return boolean
function ModelBuilder.setFactoryModule(recipe, module_name, module_value)
if recipe ~= nil then
return ModelBuilder.setModuleModel(recipe.factory, module_name, module_value)
end
return false
end
-------------------------------------------------------------------------------
---Set a module priority
---@param element table
---@param module_priority table
function ModelBuilder.setModulePriority(element, module_priority)
if element ~= nil then
for i, priority in pairs(module_priority) do
if i == 1 then
ModelBuilder.setModuleModel(element, priority.name, priority.value)
else
ModelBuilder.appendModuleModel(element, priority.name, priority.value)
end
end
end
end
-------------------------------------------------------------------------------
---Set a module priority in factory
---@param recipe RecipeData
---@param module_priority table
function ModelBuilder.setFactoryModulePriority(recipe, module_priority)
if recipe ~= nil then
recipe.factory.modules = {}
if module_priority == nil then
recipe.factory.module_priority = nil
else
recipe.factory.module_priority = table.clone(module_priority)
local first = true
for i, priority in pairs(module_priority) do
local module = ItemPrototype(priority.name)
if Player.checkFactoryLimitationModule(module:native(), recipe) == true then
if first then
ModelBuilder.setModuleModel(recipe.factory, priority.name, priority.value)
first = false
else
ModelBuilder.appendModuleModel(recipe.factory, priority.name, priority.value)
end
end
end
end
end
end
-------------------------------------------------------------------------------
---Apply a module priority in factory
---@param recipe RecipeData
function ModelBuilder.applyFactoryModulePriority(recipe)
if recipe ~= nil then
local module_priority = recipe.factory.module_priority
if module_priority == nil then
recipe.factory.modules = {}
else
local first = true
for i, priority in pairs(module_priority) do
local module = ItemPrototype(priority.name)
if Player.checkFactoryLimitationModule(module:native(), recipe) == true then
if first then
ModelBuilder.setModuleModel(recipe.factory, priority.name, priority.value)
first = false
else
ModelBuilder.appendModuleModel(recipe.factory, priority.name, priority.value)
end
end
end
end
end
end
---Set a module priority in beacons
---@param recipe RecipeData
---@param modules_priority {[uint] : {[uint] : ModulePriorityData}}
function ModelBuilder.setBeaconsModulesPriority(recipe, modules_priority)
if recipe ~= nil then
local beacons = recipe.beacons
for index, beacon in ipairs(beacons) do
local module_priority = modules_priority[index]
ModelBuilder.setBeaconModulePriority(beacon, recipe, module_priority)
end
end
end
-------------------------------------------------------------------------------
---Set a module priority in beacon
---@param beacon FactoryData
---@param recipe RecipeData
---@param module_priority {[uint] : ModulePriorityData}
function ModelBuilder.setBeaconModulePriority(beacon, recipe, module_priority)
if beacon ~= nil then
beacon.modules = {}
if module_priority == nil then
beacon.module_priority = nil
else
beacon.module_priority = table.clone(module_priority)
local first = true
for _, priority in pairs(module_priority) do
local module = ItemPrototype(priority.name)
if Player.checkBeaconLimitationModule(beacon, recipe, module:native()) == true then
if first then
ModelBuilder.setModuleModel(beacon, priority.name, priority.value)
first = false
else
ModelBuilder.appendModuleModel(beacon, priority.name, priority.value)
end
end
end
end
end
end
-------------------------------------------------------------------------------
---Set factory block
---@param block table
---@param current_recipe RecipeData
function ModelBuilder.setFactoryBlock(block, current_recipe)
if current_recipe ~= nil then
local factory_prototype = EntityPrototype(current_recipe.factory.name)
local factory_ingredient_count = factory_prototype:getIngredientCount()
for _, recipe in pairs(block.recipes) do
local prototype_recipe = RecipePrototype(recipe)
local recipe_ingredient_count = prototype_recipe:getIngredientCount()
--- check ingredient limitation
if factory_ingredient_count < recipe_ingredient_count then
-- Skip
elseif prototype_recipe:getCategory() == RecipePrototype(current_recipe):getCategory() then
Model.setFactory(recipe, current_recipe.factory.name, current_recipe.factory.fuel)
ModelBuilder.setFactoryModulePriority(recipe, current_recipe.factory.module_priority)
end
end
end
end
-------------------------------------------------------------------------------
---Set factory line
---@param model table
---@param current_recipe RecipeData
function ModelBuilder.setFactoryLine(model, current_recipe)
if current_recipe ~= nil then
for _, block in pairs(model.blocks) do
ModelBuilder.setFactoryBlock(block, current_recipe)
end
end
end
-------------------------------------------------------------------------------
---Set factory module block
---@param block table
---@param current_recipe RecipeData
function ModelBuilder.setFactoryModuleBlock(block, current_recipe)
if current_recipe ~= nil then
for key, recipe in pairs(block.recipes) do
local prototype_recipe = RecipePrototype(recipe)
if prototype_recipe:getCategory() == RecipePrototype(current_recipe):getCategory() then
ModelBuilder.setFactoryModulePriority(recipe, current_recipe.factory.module_priority)
end
end
end
end
-------------------------------------------------------------------------------
---Set factory module line
---@param model table
---@param current_recipe RecipeData
function ModelBuilder.setFactoryModuleLine(model, current_recipe)
if current_recipe ~= nil then
for _, block in pairs(model.blocks) do
ModelBuilder.setFactoryModuleBlock(block, current_recipe)
end
end
end
-------------------------------------------------------------------------------
---Set beacon block
---@param block table
---@param current_recipe RecipeData
function ModelBuilder.setBeaconBlock(block, current_recipe)
if current_recipe ~= nil then
for key, recipe in pairs(block.recipes) do
if recipe ~= current_recipe then
local prototype_recipe = RecipePrototype(recipe)
if prototype_recipe:getCategory() == RecipePrototype(current_recipe):getCategory() then
recipe.beacons = {}
if current_recipe.beacons ~= nil then
for key, current_beacon in pairs(current_recipe.beacons) do
local beacon = Model.addBeacon(recipe, current_beacon.name, current_beacon.combo,current_beacon.per_factory, current_beacon.per_factory_constant)
ModelBuilder.setBeaconModulePriority(beacon, current_recipe, current_beacon.module_priority)
end
end
end
end
end
end
end
-------------------------------------------------------------------------------
---Set beacon line
---@param model table
---@param current_recipe RecipeData
function ModelBuilder.setBeaconLine(model, current_recipe)
if current_recipe ~= nil then
for _, block in pairs(model.blocks) do
ModelBuilder.setBeaconBlock(block, current_recipe)
end
end
end
-------------------------------------------------------------------------------
---Set beacon module block
---@param block table
---@param current_recipe RecipeData
function ModelBuilder.setBeaconModuleBlock(block, current_recipe)
if current_recipe ~= nil then
for key, recipe in pairs(block.recipes) do
if recipe ~= current_recipe and recipe.beacons ~= nil then
local prototype_recipe = RecipePrototype(recipe)
if prototype_recipe:getCategory() == RecipePrototype(current_recipe):getCategory()
and #recipe.beacons == #current_recipe.beacons then
for index, current_beacon in pairs(current_recipe.beacons) do
local beacon = recipe.beacons[index]
ModelBuilder.setBeaconModulePriority(beacon, current_recipe, current_beacon.module_priority)
end
end
end
end
end
end
-------------------------------------------------------------------------------
---Set beacon module line
---@param model table
---@param current_recipe RecipeData
function ModelBuilder.setBeaconModuleLine(model, current_recipe)
if current_recipe ~= nil then
for _, block in pairs(model.blocks) do
ModelBuilder.setBeaconModuleBlock(block, current_recipe)
end
end
end
-------------------------------------------------------------------------------
---Remove a module from factory
---@param recipe RecipeData
---@param module_name string
---@param module_max number
function ModelBuilder.removeFactoryModule(recipe, module_name, module_max)
local module = ItemPrototype(module_name)
if recipe ~= nil and module:native() ~= nil then
local module_priority = ModelBuilder.removeModulePriority(recipe.factory, module_name, module_max or false)
ModelBuilder.setFactoryModulePriority(recipe, module_priority)
end
end
-------------------------------------------------------------------------------
---Remove a production block
---@param model table
---@param block table
function ModelBuilder.removeProductionBlock(model, block)
if block ~= nil then
model.blocks[block.id] = nil
table.reindex_list(model.blocks)
for _, block in pairs(model.blocks) do
if block.index == 0 then
block.unlinked = true
break
end
end
end
end
-------------------------------------------------------------------------------
---Remove a production recipe
---@param block table
---@param recipe RecipeData
function ModelBuilder.removeProductionRecipe(block, recipe)
if block ~= nil and block.recipes[recipe.id] ~= nil then
block.recipes[recipe.id] = nil
table.reindex_list(block.recipes)
---change block name
local first_recipe = Model.firstRecipe(block.recipes)
if first_recipe ~= nil then
local recipe_prototype = RecipePrototype(first_recipe)
local icon_name, icon_type = recipe_prototype:getIcon()
block.name = icon_name
block.type = icon_type
else
block.name = ""
end
end
end
-------------------------------------------------------------------------------
---Past model
---@param into_model table
---@param into_block table
---@param from_model table
---@param from_block table
function ModelBuilder.pastModel(into_model, into_block, from_model, from_block)
if from_model ~= nil then
if from_block ~= nil then
ModelBuilder.copyBlock(into_model, into_block, from_model, from_block)
else
ModelBuilder.copyModel(into_model, from_model)
end
end
end
-------------------------------------------------------------------------------
---Copy model
---@param into_model table
---@param from_model table
function ModelBuilder.copyModel(into_model, from_model)
if from_model ~= nil then
if from_model.parameters ~= nil then
into_model.parameters = table.deepcopy(from_model.parameters)
end
for _, from_block in spairs(from_model.blocks, function(t, a, b) return t[b].index > t[a].index end) do
ModelBuilder.copyBlock(into_model, nil, from_model, from_block)
end
end
end
-------------------------------------------------------------------------------
---Copy block
---@param into_model table
---@param into_block table
---@param from_model table
---@param from_block table
function ModelBuilder.copyBlock(into_model, into_block, from_model, from_block)
if from_model ~= nil and from_block ~= nil then
local from_recipe_ids = {}
for recipe_id, recipe in spairs(from_block.recipes, function(t, a, b) return t[b].index > t[a].index end) do
table.insert(from_recipe_ids, recipe_id)
end
local recipe_index = #from_recipe_ids
for _, recipe_id in ipairs(from_recipe_ids) do
local recipe = from_block.recipes[recipe_id]
local recipe_prototype = RecipePrototype(recipe)
if recipe_prototype:native() ~= nil then
---ajoute le bloc si il n'existe pas
if into_block == nil then
into_block = Model.newBlock(into_model, recipe_prototype:native())
local index = table.size(into_model.blocks)
into_block.index = index
if index == 0 then
into_block.unlinked = true
else
into_block.unlinked = from_block.unlinked
end
into_block.solver = from_block.solver
into_block.by_product = from_block.by_product
into_block.type = from_block.type
---copy input
if from_block.products ~= nil then
into_block.products = table.deepcopy(from_block.products)
end
if from_block.ingredients ~= nil then
into_block.ingredients = table.deepcopy(from_block.ingredients)
end
into_model.blocks[into_block.id] = into_block
end
local recipe_model = Model.newRecipe(into_model, recipe.name, recipe_prototype:getType())
recipe_model.index = recipe_index
recipe_model.production = recipe.production or 1
recipe_model.factory = ModelBuilder.cloneFactory(recipe.factory)
if recipe.beacons ~= nil then
recipe_model.beacons = {}
for _, beacon in pairs(recipe.beacons) do
table.insert(recipe_model.beacons, ModelBuilder.cloneBeacon(beacon))
end
end
if recipe.contraint ~= nil then
recipe_model.contraint = table.deepcopy(recipe.contraint)
end
into_block.recipes[recipe_model.id] = recipe_model
recipe_index = recipe_index + 1
end
end
if into_block ~= nil then
table.reindex_list(into_block.recipes)
if from_block.products_linked ~= nil then
into_block.products_linked = table.deepcopy(from_block.products_linked)
end
end
end
end
---Clone factory
---@param factory FactoryData
---@return FactoryData
function ModelBuilder.cloneFactory(factory)
local new_factory = Model.newFactory(factory.name)
new_factory.limit = factory.limit
new_factory.fuel = factory.fuel
new_factory.input = factory.input
new_factory.modules = {}
if factory.modules ~= nil then
for name, value in pairs(factory.modules) do
new_factory.modules[name] = value
end
end
if factory.module_priority ~= nil then
new_factory.module_priority = table.clone(factory.module_priority)
end
return new_factory
end
---Clone beacon
---@param beacon FactoryData
---@return FactoryData
function ModelBuilder.cloneBeacon(beacon)
local new_beacon = Model.newBeacon(beacon.name)
new_beacon.combo = beacon.combo
new_beacon.per_factory = beacon.per_factory
new_beacon.per_factory_constant = beacon.per_factory_constant
new_beacon.modules = {}
if beacon.modules ~= nil then
for name, value in pairs(beacon.modules) do
new_beacon.modules[name] = value
end
end
if beacon.module_priority ~= nil then
new_beacon.module_priority = table.clone(beacon.module_priority)
end
return new_beacon
end
-------------------------------------------------------------------------------
---Set module model
---@param factory FactoryData
---@param module_name string
---@param module_value number
---@return boolean
function ModelBuilder.setModuleModel(factory, module_name, module_value)
local element_prototype = EntityPrototype(factory)
if factory.modules ~= nil and factory.modules[module_name] == module_value then return false end
factory.modules = {}
factory.modules[module_name] = 0
if module_value <= element_prototype:getModuleInventorySize() then
factory.modules[module_name] = module_value
else
factory.modules[module_name] = element_prototype:getModuleInventorySize()
end
return true
end
-------------------------------------------------------------------------------
---Append module model
---@param factory FactoryData
---@param module_name string
---@param module_value number
---@return boolean
function ModelBuilder.appendModuleModel(factory, module_name, module_value)
local factory_prototype = EntityPrototype(factory)
if factory.modules ~= nil and factory.modules[module_name] == module_value then return false end
local count_modules = Model.countModulesModel(factory)
if count_modules >= factory_prototype:getModuleInventorySize() then
return false
elseif (count_modules + module_value) <= factory_prototype:getModuleInventorySize() then
factory.modules[module_name] = module_value
else
factory.modules[module_name] = 0
local delta = factory_prototype:getModuleInventorySize() - Model.countModulesModel(factory)
factory.modules[module_name] = delta
end
return true
end
-------------------------------------------------------------------------------
---Return current beacon if not exist initialise
---@param recipe RecipeData
---@return BeaconData
function ModelBuilder.getCurrentBeacon(recipe)
if recipe.beacons == nil or #recipe.beacons == 0 then
recipe.beacons = {}
if recipe.beacon ~= nil then
table.insert(recipe.beacons, recipe.beacon)
else
local new_beacon = Model.newBeacon()
table.insert(recipe.beacons, new_beacon)
end
end
local beacons = recipe.beacons
local current_beacon_selection = User.getParameter("current_beacon_selection") or 1
local beacon = nil
if #beacons >= current_beacon_selection then
beacon = beacons[current_beacon_selection]
else
User.setParameter("current_beacon_selection", 1)
beacon = beacons[1]
end
return beacon
end
-------------------------------------------------------------------------------
---Update a beacon
---@param beacon BeaconData
---@param recipe RecipeData
---@param options table
function ModelBuilder.updateBeacon(beacon, recipe, options)
if recipe ~= nil then
if options.combo ~= nil then
beacon.combo = options.combo
end
if options.per_factory ~= nil then
beacon.per_factory = options.per_factory
end
if options.per_factory_constant ~= nil then
beacon.per_factory_constant = options.per_factory_constant
end
end
end
-------------------------------------------------------------------------------
---Add a module in beacon
---@param beacon BeaconData
---@param recipe RecipeData
---@param module_name string
---@param module_max number
function ModelBuilder.addBeaconModule(beacon, recipe, module_name, module_max)
local module = ItemPrototype(module_name)
if recipe ~= nil and module:native() ~= nil then
if Player.checkFactoryLimitationModule(module:native(), recipe) == true then
local module_priority = ModelBuilder.addModulePriority(beacon, module_name, module_max or false)
ModelBuilder.setBeaconModulePriority(beacon, recipe, module_priority)
end
end
end
-------------------------------------------------------------------------------
---Remove a module in beacon
---@param beacon BeaconData
---@param recipe RecipeData
---@param module_name string
---@param module_max number
function ModelBuilder.removeBeaconModule(beacon, recipe, module_name, module_max)
local module = ItemPrototype(module_name)
if recipe ~= nil and module:native() ~= nil then
local module_priority = ModelBuilder.removeModulePriority(beacon, module_name, module_max or false)
ModelBuilder.setBeaconModulePriority(beacon, recipe, module_priority)
end
end
-------------------------------------------------------------------------------
---Unlink a production block
---@param block table
function ModelBuilder.unlinkProductionBlock(block)
if block ~= nil then
block.unlinked = not (block.unlinked)
if not block.unlinked then
for i, ingredient in pairs(block.ingredients) do
ingredient.input = 0
ingredient.count = 0
end
for i, product in pairs(block.products) do
product.input = 0
product.count = 0
end
end
end
end
-------------------------------------------------------------------------------
---Update a product
---@param block table
---@param product_name string
---@param quantity number
function ModelBuilder.updateProduct(block, product_name, quantity)
if block ~= nil then
local block_elements = block.products
if block.by_product == false then
block_elements = block.ingredients
end
if block_elements ~= nil and block_elements[product_name] ~= nil then
block_elements[product_name].input = quantity
end
end
end
-------------------------------------------------------------------------------
---Update a production block option
---@param block table
---@param option string
---@param value any
function ModelBuilder.updateProductionBlockOption(block, option, value)
if block ~= nil then
block[option] = value
---reset states
for _, product in pairs(block.products) do
product.state = 1
end
for _, ingredient in pairs(block.ingredients) do
ingredient.state = 1
end
end
end
-------------------------------------------------------------------------------
---Up a production block
---@param model table
---@param block table
---@param step number
function ModelBuilder.upProductionBlock(model, block, step)
if model ~= nil and block ~= nil then
table.up_indexed_list(model.blocks, block.index, step)
if block.index == 0 then
block.unlinked = true
end
end
end
-------------------------------------------------------------------------------
---Down a production block
---@param model table
---@param block table
---@param step number
function ModelBuilder.downProductionBlock(model, block, step)
if model ~= nil and block ~= nil then
table.down_indexed_list(model.blocks, block.index, step)
for _, block in pairs(model.blocks) do
if block.index == 0 then
block.unlinked = true
break
end
end
end
end
-------------------------------------------------------------------------------
---Up a production recipe
---@param block table
---@param recipe RecipeData
---@param step number
function ModelBuilder.upProductionRecipe(block, recipe, step)
if block ~= nil and block.recipes ~= nil and recipe ~= nil then
table.up_indexed_list(block.recipes, recipe.index, step)
---change block name
local first_recipe = Model.firstRecipe(block.recipes)
if first_recipe ~= nil then
local recipe_prototype = RecipePrototype(first_recipe)
local icon_name, icon_type = recipe_prototype:getIcon()
block.name = icon_name
block.type = icon_type
end
end
end
-------------------------------------------------------------------------------
---Down a production recipe
---@param block table
---@param recipe RecipeData
---@param step number
function ModelBuilder.downProductionRecipe(block, recipe, step)
if block ~= nil and block.recipes ~= nil and recipe ~= nil then
table.down_indexed_list(block.recipes, recipe.index, step)
---change block name
local first_recipe = Model.firstRecipe(block.recipes)
if first_recipe ~= nil then
local recipe_prototype = RecipePrototype(first_recipe)
local icon_name, icon_type = recipe_prototype:getIcon()
block.name = icon_name
block.type = icon_type
end
end
end
-------------------------------------------------------------------------------
---Update recipe contraint
---@param recipe RecipeData
---@param contraint table
function ModelBuilder.updateRecipeContraint(recipe, contraint)
if recipe ~= nil then
if recipe.contraint ~= nil and recipe.contraint.name == contraint.name and recipe.contraint.type == contraint.type then
recipe.contraint = nil
else
recipe.contraint = contraint
end
end
end
-------------------------------------------------------------------------------
---Update recipe Neighbour Bonus
---@param recipe table
---@param value number
function ModelBuilder.updateRecipeNeighbourBonus(recipe, value)
if recipe ~= nil then
recipe.factory.neighbour_bonus = value
end
end
return ModelBuilder