616 lines
22 KiB
Lua
616 lines
22 KiB
Lua
------------------------------------------------------------------------------
|
|
---Description of the module.
|
|
---@class Model
|
|
local Model = {
|
|
---single-line comment
|
|
classname = "HMModel",
|
|
version = "0.9.35",
|
|
beacon_combo = 4,
|
|
beacon_factory = 0.5,
|
|
beacon_factory_constant = 3
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get models
|
|
---@param bypass boolean
|
|
---@return table
|
|
function Model.getModels(bypass)
|
|
local display_all_sheet = User.getModGlobalSetting("display_all_sheet")
|
|
local first_id = nil
|
|
local models = {}
|
|
if Model.countModel() > 0 then
|
|
for _,model in pairs(global.models) do
|
|
if Player.isAdmin() and ( display_all_sheet or model.owner == "admin" or bypass ) then
|
|
models[model.id] = model
|
|
if first_id == nil then first_id = model.id end
|
|
elseif model.owner == Player.native().name or (model.share ~= nil and model.share > 0) then
|
|
models[model.id] = model
|
|
if first_id == nil then first_id = model.id end
|
|
end
|
|
end
|
|
end
|
|
return models
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get models
|
|
---@param bypass boolean
|
|
---@return table
|
|
function Model.getModelsByOwner(bypass)
|
|
local models = Model.getModels(bypass)
|
|
local models_by_owner = {}
|
|
for _, model in pairs(models) do
|
|
if models_by_owner[model.owner] == nil then models_by_owner[model.owner] = {} end
|
|
table.insert(models_by_owner[model.owner], model)
|
|
end
|
|
return models_by_owner
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get models
|
|
---@return table
|
|
function Model.getModelsOwner()
|
|
local models = Model.getModels()
|
|
local models_owner = {}
|
|
for _, model in pairs(models) do
|
|
if model.owner == Player.native().name then
|
|
table.insert(models_owner, model)
|
|
end
|
|
end
|
|
return models_owner
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get block order
|
|
---@param block table
|
|
---@return table
|
|
function Model.getBlockOrder(block)
|
|
local order = {"products", "ingredients"}
|
|
if block.by_product == false then order = {"ingredients", "products"} end
|
|
return order
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get rules
|
|
---@return table
|
|
function Model.getRules()
|
|
if global.rules == nil then
|
|
Model.resetRules()
|
|
end
|
|
return global.rules
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Reset rules
|
|
function Model.resetRules()
|
|
global.rules = {}
|
|
table.insert(global.rules, {index=0, mod="base", name="production-crafting", category="extraction-machine", type="entity-subgroup", value="extraction-machine", excluded = false})
|
|
table.insert(global.rules, {index=1, mod="base", name="production-crafting", category="extraction-machine", type="entity-type", value="mining-drill", excluded = false})
|
|
table.insert(global.rules, {index=2, mod="base", name="production-crafting", category="energy", type="entity-subgroup", value="energy", excluded = false})
|
|
table.insert(global.rules, {index=3, mod="base", name="production-crafting", category="technology", type="entity-type", value="lab", excluded = false})
|
|
table.insert(global.rules, {index=4, mod="base", name="module-limitation", category="extraction-machine", type="entity-type", value="mining-drill", excluded = true})
|
|
table.insert(global.rules, {index=5, mod="base", name="module-limitation", category="technology", type="entity-type", value="lab", excluded = true})
|
|
table.insert(global.rules, {index=6, mod="ShinyIcons", name="production-crafting", category="extraction-machine", type="entity-subgroup", value="shinyminer1", excluded = false})
|
|
table.insert(global.rules, {index=7, mod="ShinyIcons", name="production-crafting", category="extraction-machine", type="entity-subgroup", value="shinyminer2", excluded = false})
|
|
table.insert(global.rules, {index=8, mod="DyWorld", name="production-crafting", category="extraction-machine", type="entity-subgroup", value="dyworld-extraction-burner", excluded = false})
|
|
table.insert(global.rules, {index=9, mod="DyWorld", name="production-crafting", category="extraction-machine", type="entity-subgroup", value="dyworld-drills-electric", excluded = false})
|
|
table.insert(global.rules, {index=10, mod="DyWorld", name="production-crafting", category="extraction-machine", type="entity-subgroup", value="dyworld-drills-burner", excluded = false})
|
|
table.insert(global.rules, {index=11, mod="DyWorld", name="production-crafting", category="standard", type="entity-name", value="assembling-machine-1", excluded = true})
|
|
table.insert(global.rules, {index=12, mod="DyWorld", name="production-crafting", category="standard", type="entity-name", value="assembling-machine-2", excluded = true})
|
|
table.insert(global.rules, {index=13, mod="DyWorld", name="production-crafting", category="standard", type="entity-name", value="assembling-machine-3", excluded = true})
|
|
table.insert(global.rules, {index=14, mod="DyWorld", name="production-crafting", category="extraction-machine", type="entity-group", value="production", excluded = true})
|
|
table.insert(global.rules, {index=15, mod="Transport_Drones", name="production-crafting", category="standard", type="entity-name", value="supply-depot", excluded = true})
|
|
table.insert(global.rules, {index=16, mod="Transport_Drones", name="production-crafting", category="standard", type="entity-name", value="request-depot", excluded = true})
|
|
table.insert(global.rules, {index=17, mod="Transport_Drones", name="production-crafting", category="standard", type="entity-name", value="buffer-depot", excluded = true})
|
|
end
|
|
|
|
|
|
---Return effects on a table
|
|
---@return ModuleEffectsData
|
|
function Model.newEffects()
|
|
return { speed = 0, productivity = 0, consumption = 0, pollution = 0 }
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get and initialize the model
|
|
---@return table
|
|
function Model.newModel()
|
|
if global.model_id == nil then global.model_id = 1 end
|
|
if global.models == nil then global.models = {} end
|
|
local owner = Player.native().name
|
|
if owner == nil or owner == "" then owner = "admin" end
|
|
global.model_id = global.model_id + 1
|
|
local model = {}
|
|
model.id = "model_"..global.model_id
|
|
model.owner = owner
|
|
model.blocks = {}
|
|
model.ingredients = {}
|
|
model.resources = {}
|
|
model.time = 1
|
|
model.version = Model.version
|
|
model.index = table.size(global.models)
|
|
Model.appendParameters(model)
|
|
global.models[model.id] = model
|
|
return model
|
|
end
|
|
|
|
---Append parameters
|
|
---@param model ModelData
|
|
function Model.appendParameters(model)
|
|
if model ~= nil then
|
|
if model.parameters == nil then
|
|
model.parameters = {}
|
|
end
|
|
if model.parameters.effects == nil then
|
|
model.parameters.effects = Model.newEffects()
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get model
|
|
---@return table
|
|
function Model.getModelById(model_id)
|
|
if model_id ~= nil and global.models ~= nil then
|
|
return global.models[model_id]
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get parameter objects
|
|
---@param parameter table --{name=parameter.name, model=model.id, block=block.id, recipe=recipe.id}
|
|
---@return ModelData, BlockData, RecipeData
|
|
function Model.getParameterObjects(parameter)
|
|
if parameter ~= nil then
|
|
if global.models == nil then
|
|
---initialisation
|
|
global.models = {}
|
|
local model = Model.newModel()
|
|
User.setParameter(parameter.name, {name=parameter.name, model=model.id})
|
|
return model
|
|
end
|
|
if parameter.model ~= nil and global.models[parameter.model] ~= nil then
|
|
local model = global.models[parameter.model]
|
|
local block, recipe
|
|
if model ~= nil and parameter.block ~= nil and model.blocks ~= nil then
|
|
block = model.blocks[parameter.block]
|
|
if block ~= nil and parameter.recipe ~= nil and block.recipes ~= nil then
|
|
recipe = block.recipes[parameter.recipe]
|
|
end
|
|
end
|
|
return model, block, recipe
|
|
else
|
|
---initialisation parameter
|
|
local model = Model.getLastModel()
|
|
if model == nil then model = Model.newModel() end
|
|
User.setParameter(parameter.name, {name=parameter.name, model=model.id})
|
|
return model
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get last model
|
|
---@return table
|
|
function Model.getLastModel()
|
|
local last_model = nil
|
|
local models = Model.getModels()
|
|
for _,model in pairs(models) do
|
|
last_model = model
|
|
end
|
|
return last_model
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Create model Production Block
|
|
---@param model table
|
|
---@param recipe table
|
|
---@return table
|
|
function Model.newBlock(model, recipe)
|
|
if model.block_id == nil then model.block_id = 0 end
|
|
model.block_id = model.block_id + 1
|
|
|
|
local inputModel = {}
|
|
inputModel.id = "block_"..model.block_id
|
|
inputModel.name = recipe.name
|
|
inputModel.owner = Player.native().name
|
|
inputModel.count = 1
|
|
inputModel.power = 0
|
|
inputModel.ingredients = {}
|
|
inputModel.products = {}
|
|
inputModel.recipes = {}
|
|
|
|
return inputModel
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Create model Beacon
|
|
---@param name string
|
|
---@param count number
|
|
---@return table
|
|
function Model.newBeacon(name, count)
|
|
local beaconModel = {}
|
|
beaconModel.name = name or "beacon"
|
|
beaconModel.type = "entity"
|
|
beaconModel.count = count or 0
|
|
beaconModel.energy = 0
|
|
beaconModel.combo = User.getPreferenceSetting("beacon_affecting_one")
|
|
beaconModel.per_factory = User.getPreferenceSetting("beacon_by_factory")
|
|
beaconModel.per_factory_constant = User.getPreferenceSetting("beacon_constant")
|
|
---limit infini = 0
|
|
beaconModel.limit = 0
|
|
---modules
|
|
beaconModel.modules = {}
|
|
return beaconModel
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Create model Factory
|
|
---@param name string
|
|
---@param count number
|
|
---@return table
|
|
function Model.newFactory(name, count)
|
|
local factoryModel = {}
|
|
factoryModel.name = name or "assembling-machine-1"
|
|
factoryModel.type = "entity"
|
|
factoryModel.count = count or 0
|
|
factoryModel.energy = 0
|
|
factoryModel.speed = 0
|
|
---limit infini = 0
|
|
factoryModel.limit = 0
|
|
---modules
|
|
factoryModel.modules = {}
|
|
return factoryModel
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Create model Ingredient
|
|
---@param name string
|
|
---@param type string
|
|
---@param count number
|
|
---@return table
|
|
function Model.newIngredient(name, type, count)
|
|
if count == nil then count = 0 end
|
|
|
|
local ingredientModel = {}
|
|
ingredientModel.index = 1
|
|
ingredientModel.name = name
|
|
ingredientModel.type = type
|
|
ingredientModel.count = count
|
|
|
|
return ingredientModel
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Create model Rule
|
|
---@param mod string
|
|
---@param name string
|
|
---@param category string
|
|
---@param type string
|
|
---@param value string
|
|
---@param excluded boolean
|
|
---@param index number
|
|
---@return Table
|
|
function Model.newRule(mod, name, category, type, value, excluded, index)
|
|
local rule_model = {}
|
|
rule_model.mod = mod
|
|
rule_model.name = name
|
|
rule_model.category = category
|
|
rule_model.type = type
|
|
rule_model.value = value
|
|
rule_model.excluded = excluded
|
|
rule_model.index = index
|
|
return rule_model
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Count modules model
|
|
---@param element table
|
|
---@return number
|
|
function Model.countModulesModel(element)
|
|
local count = 0
|
|
if element ~= nil and element.modules ~= nil then
|
|
for _, value in pairs(element.modules) do
|
|
count = count + value
|
|
end
|
|
end
|
|
return count
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Create model Recipe
|
|
---@param model table
|
|
---@param name string
|
|
---@param type string
|
|
---@return table
|
|
function Model.newRecipe(model, name, type)
|
|
if model.recipe_id == nil then model.recipe_id = 0 end
|
|
model.recipe_id = model.recipe_id + 1
|
|
|
|
local recipeModel = {}
|
|
recipeModel.id = "R"..model.recipe_id
|
|
recipeModel.index = 1
|
|
recipeModel.name = name
|
|
recipeModel.type = type or "recipe"
|
|
recipeModel.count = 0
|
|
recipeModel.production = 1
|
|
recipeModel.factory = Model.newFactory()
|
|
recipeModel.beacons = {}
|
|
table.insert(recipeModel.beacons, Model.newBeacon())
|
|
|
|
return recipeModel
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Create model Resource
|
|
---@param model table
|
|
---@param name string
|
|
---@param type string
|
|
---@param count number
|
|
---@return table
|
|
function Model.newResource(model, name, type, count)
|
|
if model.resource_id == nil then model.resource_id = 0 end
|
|
model.resource_id = model.resource_id + 1
|
|
|
|
if count == nil then count = 1 end
|
|
|
|
local resourceModel = {}
|
|
resourceModel.id = model.resource_id
|
|
resourceModel.index = 1
|
|
resourceModel.type = type
|
|
resourceModel.name = name
|
|
resourceModel.count = count
|
|
|
|
return resourceModel
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Count in list
|
|
---@return number
|
|
function Model.countModel()
|
|
return table.size(global.models)
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Set the beacon
|
|
---@param recipe table
|
|
---@param name string
|
|
---@param combo number
|
|
---@param per_factory number
|
|
---@param per_factory_constant number
|
|
---@return BeaconData
|
|
function Model.addBeacon(recipe, name, combo, per_factory, per_factory_constant)
|
|
if recipe ~= nil then
|
|
local beacon_prototype = EntityPrototype(name)
|
|
if beacon_prototype:native() ~= nil then
|
|
local beacon = Model.newBeacon(name, 0)
|
|
beacon.combo = combo or User.getPreferenceSetting("beacon_affecting_one")
|
|
beacon.per_factory = per_factory or User.getPreferenceSetting("beacon_by_factory")
|
|
beacon.per_factory_constant = per_factory_constant or User.getPreferenceSetting("beacon_constant")
|
|
if recipe.beacons == nil then recipe.beacons = {} end
|
|
table.insert(recipe.beacons, beacon)
|
|
return beacon
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Set the beacon
|
|
---@param recipe table
|
|
---@param index number
|
|
---@param name string
|
|
---@param combo number
|
|
---@param per_factory number
|
|
---@param per_factory_constant number
|
|
function Model.setBeacon(recipe, index, name, combo, per_factory, per_factory_constant)
|
|
if recipe ~= nil and recipe.beacons ~= nil then
|
|
local beacon_prototype = EntityPrototype(name)
|
|
if beacon_prototype:native() ~= nil then
|
|
local beacon = {}
|
|
local beacon = Model.newBeacon(name, 0)
|
|
beacon.combo = combo or User.getPreferenceSetting("beacon_affecting_one")
|
|
beacon.per_factory = per_factory or User.getPreferenceSetting("beacon_by_factory")
|
|
beacon.per_factory_constant = per_factory_constant or User.getPreferenceSetting("beacon_constant")
|
|
if recipe.beacons[index] ~= nil then
|
|
recipe.beacons[index] = beacon
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Set a factory
|
|
---@param recipe table
|
|
---@param factory_name string
|
|
---@param factory_fuel table
|
|
function Model.setFactory(recipe, factory_name, factory_fuel)
|
|
if recipe ~= nil then
|
|
local factory_prototype = EntityPrototype(factory_name)
|
|
if factory_prototype:native() ~= nil then
|
|
recipe.factory.name = factory_name
|
|
recipe.factory.fuel = factory_fuel
|
|
if Model.countModulesModel(recipe.factory) >= factory_prototype:getModuleInventorySize() then
|
|
recipe.factory.modules = {}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Return first recipe of block
|
|
---@param recipes table
|
|
---@return table
|
|
function Model.firstRecipe(recipes)
|
|
for _, recipe in spairs(recipes,function(t,a,b) return t[b].index > t[a].index end) do
|
|
return recipe
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Return last recipe of block
|
|
---@param recipes table
|
|
---@return table
|
|
function Model.lastRecipe(recipes)
|
|
for _, recipe in spairs(recipes,function(t,a,b) return t[b].index < t[a].index end) do
|
|
return recipe
|
|
end
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get and initialize the default
|
|
---@return table
|
|
function Model.getDefault()
|
|
local default = User.get("default")
|
|
if default.recipes == nil then default.recipes = {} end
|
|
return default
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get the default recipe
|
|
---@param key string --recipe name
|
|
---@return table
|
|
function Model.getDefaultRecipe(key)
|
|
local default = Model.getDefault()
|
|
if default.recipes[key] == nil then
|
|
default.recipes[key] = {
|
|
name = key,
|
|
factory = nil,
|
|
beacon = nil
|
|
}
|
|
end
|
|
return default.recipes[key]
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get speed of the factory
|
|
---@param key string --factory name
|
|
---@return number
|
|
function Model.getSpeedFactory(key)
|
|
local entity_prototype = EntityPrototype(key)
|
|
local crafting_speed = entity_prototype:getCraftingSpeed()
|
|
if crafting_speed ~= 0 then return crafting_speed end
|
|
local mining_speed = entity_prototype:getMiningSpeed()
|
|
if mining_speed ~= 0 then return mining_speed end
|
|
return 1
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get the factory of prototype
|
|
---@param recipe_prototype table
|
|
---@return string
|
|
function Model.getDefaultPrototypeFactory(recipe_prototype)
|
|
local category = recipe_prototype:getCategory()
|
|
if category ~= nil then
|
|
local factories = {}
|
|
if recipe_prototype:getType() == "boiler" then
|
|
factories = Player.getBoilersForRecipe(recipe_prototype)
|
|
elseif recipe_prototype:getType() == "fluid" then
|
|
factories = Player.getProductionsCrafting("fluid", recipe_prototype:native())
|
|
else
|
|
factories = Player.getProductionsCrafting(category, recipe_prototype:native())
|
|
end
|
|
local default_factory_level = User.getPreferenceSetting("default_factory_level")
|
|
local factory_level = 1
|
|
if default_factory_level == "fast" then
|
|
factory_level = 100
|
|
else
|
|
factory_level = tonumber(default_factory_level)
|
|
end
|
|
local level = 1
|
|
local lua_factory = nil
|
|
local last_factory = nil
|
|
for _, factory in spairs(factories, function(t,a,b) return Model.getSpeedFactory(t[b].name) > Model.getSpeedFactory(t[a].name) end) do
|
|
if level == factory_level then lua_factory = factory end
|
|
last_factory = factory
|
|
level = level + 1
|
|
end
|
|
if lua_factory ~= nil then return lua_factory.name end
|
|
if last_factory ~= nil then return last_factory.name end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
---Get the beacon of recipe
|
|
---@param key string --recipe name
|
|
---@return string
|
|
function Model.getDefaultRecipeBeacon(key)
|
|
local default = Model.getDefault()
|
|
if default.recipes[key] == nil then
|
|
return nil
|
|
end
|
|
return default.recipes[key].beacon
|
|
end
|
|
|
|
---Check if factory has module
|
|
---@param factory FactoryData
|
|
---@return boolean
|
|
function Model.factoryHasModule(factory)
|
|
if factory == nil then return false end
|
|
if factory.modules == nil then return false end
|
|
if factory.modules ~= nil and #factory.modules then return false end
|
|
return true
|
|
end
|
|
|
|
---Compare module priorities
|
|
---@param module_priorities1 {[uint] : ModulePriorityData}
|
|
---@param module_priorities2 {[uint] : ModulePriorityData}
|
|
function Model.compareModulePriorities(module_priorities1, module_priorities2)
|
|
if module_priorities1 == nil or module_priorities2 == nil then return false end
|
|
if #module_priorities1 ~= #module_priorities2 then return false end
|
|
for i = 1, #module_priorities1, 1 do
|
|
local module_priority1 = module_priorities1[i]
|
|
local module_priority2 = module_priorities2[i]
|
|
if module_priority1.name ~= module_priority2.name then return false end
|
|
if module_priority1.value ~= module_priority2.value then return false end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---Compare 2 factories
|
|
---@param factory1 FactoryData
|
|
---@param factory2 FactoryData
|
|
---@param with_priority boolean
|
|
---@return boolean
|
|
function Model.compareFactory(factory1, factory2, with_priority)
|
|
if factory1 == nil or factory2 == nil then return false end
|
|
if factory1.name ~= factory2.name then return false end
|
|
if factory1.fuel ~= factory2.fuel then return false end
|
|
if with_priority and Model.compareModulePriorities(factory1.module_priority, factory2.module_priority) == false then return false end
|
|
return true
|
|
end
|
|
|
|
---Compare 2 factories
|
|
---@param beacon1 BeaconData
|
|
---@param beacon2 BeaconData
|
|
---@param with_priority boolean
|
|
---@return boolean
|
|
function Model.compareBeacon(beacon1, beacon2, with_priority)
|
|
if beacon1 == nil or beacon2 == nil then return false end
|
|
if beacon1.name ~= beacon2.name then return false end
|
|
if beacon1.fuel ~= beacon2.fuel then return false end
|
|
if beacon1.combo ~= beacon2.combo then return false end
|
|
if beacon1.per_factory ~= beacon2.per_factory then return false end
|
|
if beacon1.per_factory_constant ~= beacon2.per_factory_constant then return false end
|
|
if with_priority and Model.compareModulePriorities(beacon1.module_priority, beacon2.module_priority) == false then return false end
|
|
return true
|
|
end
|
|
|
|
---Compare 2 factories
|
|
---@param beacons1 {[uint] : BeaconData}
|
|
---@param beacons2 {[uint] : BeaconData}
|
|
---@return boolean
|
|
function Model.compareBeacons(beacons1, beacons2)
|
|
if beacons1 == nil or beacons2 == nil then return false end
|
|
if #beacons1 ~= #beacons2 then return false end
|
|
for i = 1, #beacons1, 1 do
|
|
local beacon1 = beacons1[i]
|
|
local beacon2 = beacons2[i]
|
|
local with_priority = Model.factoryHasModule(beacon1) or Model.factoryHasModule(beacon2)
|
|
if Model.compareBeacon(beacon1, beacon2, with_priority) == false then return false end
|
|
end
|
|
return true
|
|
end
|
|
|
|
return Model
|