251 lines
9.2 KiB
Lua
251 lines
9.2 KiB
Lua
-------------------------------------------------------------------------------
|
||
---Description of the module.
|
||
---@class Product
|
||
Product = newclass(Prototype,function(base, object)
|
||
Prototype.init(base, object)
|
||
base.classname = "HMProduct"
|
||
base.belt_ratio = 45/0.09375
|
||
end)
|
||
|
||
Product.classname = "HMProduct"
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Return localised name of Prototype
|
||
---@return string
|
||
function Product:getLocalisedName()
|
||
if self.lua_prototype ~= nil then
|
||
local localisedName = self.lua_prototype.name
|
||
if self.lua_prototype.type == 0 or self.lua_prototype.type == "item" then
|
||
local item = Player.getItemPrototype(self.lua_prototype.name)
|
||
if item ~= nil then
|
||
localisedName = item.localised_name
|
||
end
|
||
end
|
||
if self.lua_prototype.type == 1 or self.lua_prototype.type == "fluid" then
|
||
local item = Player.getFluidPrototype(self.lua_prototype.name)
|
||
if item ~= nil then
|
||
localisedName = item.localised_name
|
||
end
|
||
end
|
||
return localisedName
|
||
end
|
||
return "unknow"
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Return table key
|
||
---@return string
|
||
function Product:getTableKey()
|
||
if self.lua_prototype ~= nil then
|
||
if self.lua_prototype.type == 1 or self.lua_prototype.type == "fluid" then
|
||
local T = self.lua_prototype.temperature
|
||
if T ~= nil then
|
||
return string.format("%s#%s", self.lua_prototype.name,T)
|
||
end
|
||
local Tmin = self.lua_prototype.minimum_temperature
|
||
local Tmax = self.lua_prototype.maximum_temperature
|
||
if Tmin ~= nil or Tmax ~= nil then
|
||
Tmin = Tmin or -1e300
|
||
Tmax = Tmax or 1e300
|
||
if Tmin < -1e300 and Tmax < 1e300 then
|
||
return string.format("%s#inf#%s", self.lua_prototype.name, Tmax)
|
||
end
|
||
if Tmin > -1e300 and Tmax > 1e300 then
|
||
return string.format("%s#%s#inf", self.lua_prototype.name, Tmin)
|
||
end
|
||
if Tmin > -1e300 and Tmax < 1e300 then
|
||
return string.format("%s#%s#%s", self.lua_prototype.name, Tmin, Tmax)
|
||
end
|
||
end
|
||
end
|
||
return self.lua_prototype.name
|
||
end
|
||
return "unknow"
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Has Burnt Result
|
||
---@return boolean
|
||
function Product:hasBurntResult()
|
||
if self.lua_prototype ~= nil then
|
||
if self.lua_prototype.type == 0 or self.lua_prototype.type == "item" then
|
||
local item = Player.getItemPrototype(self.lua_prototype.name)
|
||
return item.burnt_result ~= nil
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Clone prototype model
|
||
---@return table
|
||
function Product:clone()
|
||
local prototype = {
|
||
type = self.lua_prototype.type,
|
||
name = self.lua_prototype.name,
|
||
amount = self:getElementAmount(),
|
||
state = self.lua_prototype.state,
|
||
temperature = self.lua_prototype.temperature,
|
||
minimum_temperature = self.lua_prototype.minimum_temperature,
|
||
maximum_temperature = self.lua_prototype.maximum_temperature,
|
||
burnt = self.lua_prototype.burnt,
|
||
constant = self.lua_prototype.constant
|
||
}
|
||
return prototype
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Get amount of element
|
||
---@see http://lua-api.factorio.com/latest/Concepts.html#Product
|
||
---@return number
|
||
function Product:getElementAmount()
|
||
local element = self.lua_prototype
|
||
if element == nil then return 0 end
|
||
|
||
if element.amount ~= nil then
|
||
---In 0.17, it seems probability can be used with just 'amount' and it
|
||
---doesn't need to use amount_min/amount_max
|
||
if element.probability ~= nil then
|
||
return element.amount * element.probability
|
||
else
|
||
return element.amount
|
||
end
|
||
end
|
||
|
||
if element.probability ~= nil and element.amount_min ~= nil and element.amount_max ~= nil then
|
||
return ((element.amount_min + element.amount_max) * element.probability / 2)
|
||
end
|
||
|
||
return 0
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Get amount of element for bonus
|
||
---@return number
|
||
function Product:getBonusAmount()
|
||
local element = self.lua_prototype
|
||
if element == nil then return 0 end
|
||
|
||
local catalyst_amount = element.catalyst_amount or 0
|
||
local probability = element.probability or 1
|
||
local amount = 0
|
||
---If amount not specified, amount_min, amount_max and probability must all be specified.
|
||
---Minimal amount of the item or fluid to give. Has no effect when amount is specified.
|
||
---Maximum amount of the item or fluid to give. Has no effect when amount is specified.
|
||
if element.probability ~= nil and element.amount_min ~= nil and element.amount_max ~= nil then
|
||
amount = (element.amount_min + element.amount_max) / 2
|
||
end
|
||
|
||
if element.amount ~= nil then
|
||
amount = element.amount
|
||
end
|
||
if amount >= catalyst_amount then
|
||
return (amount - catalyst_amount) * probability
|
||
end
|
||
return 0
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Get type of element (item or fluid)
|
||
---@return string
|
||
function Product:getType()
|
||
if self.lua_prototype.type == 1 or self.lua_prototype.type == "fluid" then return "fluid" end
|
||
return "item"
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Get amount of element
|
||
---@param recipe table
|
||
---@return number
|
||
function Product:getAmount(recipe)
|
||
local amount = self:getElementAmount()
|
||
local bonus_amount = self:getBonusAmount() ---if there are no catalyst amount = bonus_amount
|
||
if recipe == nil then
|
||
return amount
|
||
end
|
||
return amount + bonus_amount * self:getProductivityBonus(recipe)
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Count product
|
||
---@param model table
|
||
---@param recipe table
|
||
---@return number
|
||
function Product:countProduct(model, recipe)
|
||
local amount = self:getElementAmount()
|
||
local bonus_amount = self:getBonusAmount() ---if there are no catalyst amount = bonus_amount
|
||
return (amount + bonus_amount * self:getProductivityBonus(recipe) ) * recipe.count
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Count ingredient
|
||
---@param model table
|
||
---@param recipe table
|
||
---@return number
|
||
function Product:countIngredient(model, recipe)
|
||
local amount = self:getElementAmount()
|
||
return amount * recipe.count
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Count container
|
||
---@param count number
|
||
---@param container string
|
||
---@param time number
|
||
---@return number
|
||
function Product:countContainer(count, container, time)
|
||
if count == nil then return 0 end
|
||
if self.lua_prototype.type == 0 or self.lua_prototype.type == "item" then
|
||
local entity_prototype = EntityPrototype(container)
|
||
if entity_prototype:getType() == "inserter" then
|
||
local inserter_capacity = entity_prototype:getInserterCapacity()
|
||
local inserter_speed = entity_prototype:getInserterRotationSpeed()
|
||
---temps pour 360<36> t=360/360*inserter_speed
|
||
local inserter_time = 1 / inserter_speed
|
||
return count * inserter_time / (inserter_capacity * (time or 1))
|
||
elseif entity_prototype:getType() == "transport-belt" then
|
||
---ratio = item_per_s / speed_belt (blue belt)
|
||
local belt_speed = entity_prototype:getBeltSpeed()
|
||
return count / (belt_speed * self.belt_ratio * (time or 1))
|
||
elseif entity_prototype:getType() ~= "logistic-robot" then
|
||
local cargo_wagon_size = entity_prototype:getInventorySize(1)
|
||
if cargo_wagon_size == nil then return 0 end
|
||
if entity_prototype:getInventorySize(2) ~= nil and entity_prototype:getInventorySize(2) > entity_prototype:getInventorySize(1) then
|
||
cargo_wagon_size = entity_prototype:getInventorySize(2)
|
||
end
|
||
local stack_size = ItemPrototype(self.lua_prototype.name):stackSize()
|
||
if cargo_wagon_size * stack_size == 0 then return 0 end
|
||
return count / (cargo_wagon_size * stack_size)
|
||
else
|
||
local cargo_wagon_size = entity_prototype:native().max_payload_size + (Player.getForce().worker_robots_storage_bonus or 0 )
|
||
return count / cargo_wagon_size
|
||
end
|
||
end
|
||
if self.lua_prototype.type == 1 or self.lua_prototype.type == "fluid" then
|
||
local entity_prototype = EntityPrototype(container)
|
||
if entity_prototype:getType() == "pipe" then
|
||
local fluids_logistic_maximum_flow = User.getParameter("fluids_logistic_maximum_flow")
|
||
return count / (fluids_logistic_maximum_flow or defines.constant.logistic_flow_default)
|
||
else
|
||
local cargo_wagon_size = EntityPrototype(container):getFluidCapacity()
|
||
if cargo_wagon_size == 0 then return 0 end
|
||
return count / cargo_wagon_size
|
||
end
|
||
end
|
||
end
|
||
|
||
-------------------------------------------------------------------------------
|
||
---Get the productivity bonus of the recipe
|
||
---@param recipe table
|
||
---@return number
|
||
function Product:getProductivityBonus(recipe)
|
||
if recipe.isluaobject or recipe.factory == nil or recipe.factory.effects == nil then return 1 end
|
||
local productivity = recipe.factory.effects.productivity
|
||
local capped_time = recipe.time / recipe.factory.speed
|
||
local factory_speed = recipe.factory.speed_total or 1
|
||
local adjusted_time = recipe.time / factory_speed
|
||
local speed_adjustment = capped_time / adjusted_time
|
||
productivity = productivity * speed_adjustment
|
||
|
||
return productivity
|
||
end |