Aleksei-bird 7c9c708c92 Первый фикс
Пачки некоторых позиций увеличены
2024-03-01 20:54:33 +03:00

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