190 lines
6.2 KiB
Lua
190 lines
6.2 KiB
Lua
---@class FPMachine
|
|
---@field proto FPMachinePrototype
|
|
---@field count number
|
|
---@field limit number?
|
|
---@field force_limit boolean
|
|
---@field fuel FPFuel?
|
|
---@field module_set FPModuleSet
|
|
---@field total_effects ModuleEffects
|
|
---@field effects_tooltip string
|
|
---@field valid boolean
|
|
---@field parent FPLine
|
|
---@field class "Machine"
|
|
|
|
-- Class representing a machine with its attached modules and fuel
|
|
Machine = {}
|
|
|
|
function Machine.init(proto, parent)
|
|
local machine = {
|
|
proto = proto,
|
|
count = 0,
|
|
limit = nil, -- will be set by the user
|
|
force_limit = true, -- ignored if limit is not set
|
|
fuel = nil, -- needs to be set by calling Machine.find_fuel afterwards
|
|
module_set = nil, -- set right below
|
|
total_effects = nil,
|
|
effects_tooltip = "",
|
|
valid = true,
|
|
parent = parent,
|
|
class = "Machine"
|
|
}
|
|
machine.module_set = ModuleSet.init(machine)
|
|
|
|
return machine
|
|
end
|
|
|
|
|
|
function Machine.normalize_fuel(self, player)
|
|
if self.proto.energy_type ~= "burner" then self.fuel = nil; return end
|
|
-- no need to continue if this machine doesn't have a burner
|
|
|
|
local burner = self.proto.burner
|
|
-- Check if fuel has a valid category for this machine, replace otherwise
|
|
if self.fuel and not burner.categories[self.fuel.proto.category] then self.fuel = nil end
|
|
|
|
-- If this machine has fuel already, don't replace it
|
|
if self.fuel == nil then
|
|
-- Use the first category of this machine's burner as the default one
|
|
local fuel_category_name, _ = next(burner.categories, nil)
|
|
local fuel_category_id = PROTOTYPE_MAPS.fuels[fuel_category_name].id
|
|
|
|
local default_fuel_proto = prototyper.defaults.get(player, "fuels", fuel_category_id)
|
|
self.fuel = Fuel.init(default_fuel_proto)
|
|
self.fuel.parent = self
|
|
end
|
|
end
|
|
|
|
function Machine.summarize_effects(self, mining_prod)
|
|
local effects = self.module_set.total_effects
|
|
|
|
effects["base_prod"] = self.proto.base_productivity or nil
|
|
effects["mining_prod"] = mining_prod or nil
|
|
|
|
self.total_effects = effects
|
|
self.effects_tooltip = util.gui.format_module_effects(effects, false)
|
|
|
|
Line.summarize_effects(self.parent)
|
|
end
|
|
|
|
function Machine.check_module_compatibility(self, module_proto)
|
|
local recipe = self.parent.recipe
|
|
|
|
if self.proto.module_limit == 0 then return false end
|
|
|
|
if next(module_proto.limitations) and recipe.proto.use_limitations
|
|
and not module_proto.limitations[recipe.proto.name] then
|
|
return false
|
|
end
|
|
|
|
local allowed_effects = self.proto.allowed_effects
|
|
if allowed_effects == nil then
|
|
return false
|
|
else
|
|
for effect_name, _ in pairs(module_proto.effects) do
|
|
if allowed_effects[effect_name] == false then
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
|
|
function Machine.paste(self, object)
|
|
if object.class == "Machine" then
|
|
-- See if the pasted machine also exists in this machine's category, and use it if compatible
|
|
local found_machine = prototyper.util.find_prototype("machines", object.proto.name, self.proto.category)
|
|
|
|
if found_machine and Line.is_machine_applicable(self.parent, found_machine) then
|
|
self.parent.machine = object
|
|
object.parent = self.parent
|
|
object.proto = found_machine -- make sure to set this to the right category machine
|
|
|
|
ModuleSet.normalize(object.module_set, {compatibility=true, effects=true})
|
|
Line.summarize_effects(object.parent)
|
|
return true, nil
|
|
else
|
|
return false, "incompatible"
|
|
end
|
|
elseif object.class == "Module" then
|
|
return ModuleSet.paste(self.module_set, object)
|
|
else
|
|
return false, "incompatible_class"
|
|
end
|
|
end
|
|
|
|
function Machine.clone(self)
|
|
local clone = Machine.unpack(Machine.pack(self))
|
|
clone.parent = self.parent
|
|
clone.count = self.count -- keep around to avoid recalc being needed
|
|
Machine.validate(clone)
|
|
return clone
|
|
end
|
|
|
|
|
|
function Machine.pack(self)
|
|
return {
|
|
proto = prototyper.util.simplify_prototype(self.proto, self.proto.category),
|
|
limit = self.limit,
|
|
force_limit = self.force_limit,
|
|
fuel = (self.fuel) and Fuel.pack(self.fuel) or nil,
|
|
module_set = ModuleSet.pack(self.module_set),
|
|
class = self.class
|
|
}
|
|
end
|
|
|
|
function Machine.unpack(packed_self)
|
|
local self = packed_self
|
|
|
|
self.fuel = (packed_self.fuel) and Fuel.unpack(packed_self.fuel) or nil
|
|
if self.fuel then self.fuel.parent = self end
|
|
|
|
self.module_set = ModuleSet.unpack(packed_self.module_set)
|
|
self.module_set.parent = self
|
|
|
|
return self
|
|
end
|
|
|
|
|
|
-- Needs validation: proto, fuel, module_set
|
|
function Machine.validate(self)
|
|
self.proto = prototyper.util.validate_prototype_object(self.proto, "category")
|
|
self.valid = (not self.proto.simplified)
|
|
|
|
local parent_line = self.parent
|
|
if self.valid and parent_line.valid and parent_line.recipe.valid then
|
|
self.valid = Line.is_machine_applicable(parent_line, self.proto)
|
|
end
|
|
|
|
-- If the machine changed to not use a burner, remove its fuel
|
|
if not self.proto.burner then self.fuel = nil end
|
|
if self.fuel then self.valid = Fuel.validate(self.fuel) and self.valid end
|
|
|
|
self.valid = ModuleSet.validate(self.module_set) and self.valid
|
|
|
|
return self.valid
|
|
end
|
|
|
|
-- Needs repair: proto, fuel, module_set
|
|
function Machine.repair(self, player)
|
|
-- If the prototype is still simplified, it couldn't be fixed by validate
|
|
-- A final possible fix is to replace this machine with the default for its category
|
|
if self.proto.simplified and not Line.change_machine_to_default(self.parent, player) then
|
|
return false -- if this happens, the whole line can not be salvaged
|
|
end
|
|
self.valid = true -- if it gets to this, change_machine was successful and the machine is valid
|
|
-- It just might need to cleanup some fuel and/or modules
|
|
|
|
if self.fuel and not self.fuel.valid and not Fuel.repair(self.fuel) then
|
|
-- If fuel is unrepairable, replace it with a default value
|
|
self.fuel = nil
|
|
Machine.normalize_fuel(self, player)
|
|
end
|
|
|
|
-- Remove invalid modules and normalize the remaining ones
|
|
ModuleSet.repair(self.module_set)
|
|
|
|
return true
|
|
end
|