Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions modfiles/backend/data/Factory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ local Product = require("backend.data.Product")
---@field archived boolean
---@field name string
---@field matrix_free_items FPItemPrototype[]?
---@field last_recipe_items FPItemPrototype[]?
---@field blueprints string[]
---@field notes string
---@field productivity_boni { string: ModuleEffectValue }
Expand All @@ -32,6 +33,7 @@ local function init(name)

name = name,
matrix_free_items = nil,
last_recipe_items = nil,
blueprints = {},
notes = "",
productivity_boni = {},
Expand Down Expand Up @@ -182,6 +184,7 @@ end
---@field class "Factory"
---@field name string
---@field matrix_free_items FPPackedPrototype[]?
---@field last_recipe_items FPPackedPrototype[]?
---@field blueprints string[]
---@field notes string
---@field productivity_boni { string: ModuleEffectValue }
Expand All @@ -194,6 +197,7 @@ function Factory:pack()
class = self.class,
name = self.name,
matrix_free_items = prototyper.util.simplify_prototypes(self.matrix_free_items, "type"),
last_recipe_items = prototyper.util.simplify_prototypes(self.last_recipe_items, "type"),
blueprints = self.blueprints,
notes = self.notes,
productivity_boni = self.productivity_boni,
Expand All @@ -209,6 +213,7 @@ local function unpack(packed_self)

-- Product prototypes will be automatically unpacked by the validation process
unpacked_self.matrix_free_items = packed_self.matrix_free_items
unpacked_self.last_recipe_items = packed_self.last_recipe_items
unpacked_self.blueprints = packed_self.blueprints
unpacked_self.notes = packed_self.notes
unpacked_self.productivity_boni = packed_self.productivity_boni
Expand Down
2 changes: 2 additions & 0 deletions modfiles/locale/en/config.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,8 @@ choose_unrestricted_items=Choose unrestricted items
choose_unrestricted_items_tt=Choose [font=default-bold]__1__[/font] unrestricted __2__ in total, so the matrix solver can determine a unique solution.\n\nThe left side lists the constrained items, while the right side contains the unrestricted ones. Click on any item to move it to the other side.\n\nUnrestricted items may become byproducts or ingredients, depending on the solver’s solution.
unrestricted_items_balanced=Unrestricted items balanced
unrestricted_items_balanced_tt=The current selection of unrestricted items is balanced.\n\nTo choose different unrestricted items, constrain one of the current ones first.
last_recipe_items=From last recipe
other_items=Other Items
turn_unrestricted=Switch [font=default-bold]__1__[/font] to be constrained
turn_constrained=Switch [font=default-bold]__1__[/font] to be unrestricted
solver_choice=Solver
Expand Down
22 changes: 22 additions & 0 deletions modfiles/ui/dialogs/recipe_dialog.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,31 @@ local function attempt_adding_line(player, recipe_id, modal_data)
util.messages.raise(player, "error", {"fp.error_no_compatible_machine"}, 1)
else
local floor = util.context.get(player, "Floor") --[[@as Floor]]
local factory = util.context.get(player, "Factory") --[[@as Factory]]
local relative_object = OBJECT_INDEX[modal_data.add_after_line_id] --[[@as LineObject]]
floor:insert(line, relative_object, "next") -- if not relative, insert uses last line

log("[FP] RecipeDialog: Creating suggestions for recipe: " .. recipe_proto.name)
local last_recipe_items = {}
for _, p in ipairs(recipe_proto.products) do
local item_proto = prototyper.util.find("items", p.name, p.type)
if item_proto then
table.insert(last_recipe_items, item_proto)
end
end
for _, i in ipairs(recipe_proto.ingredients) do
local item_proto = prototyper.util.find("items", i.name, i.type)
if item_proto then
table.insert(last_recipe_items, item_proto)
end
end
factory.last_recipe_items = last_recipe_items

log("[FP] RecipeDialog: Set " .. #last_recipe_items .. " items from last recipe for factory '" .. factory.name .. "'.")
local item_names = ""
for _, item in ipairs(last_recipe_items) do item_names = item_names .. item.name .. ", " end
log("[FP] RecipeDialog: Items are: " .. item_names)

local recipe_name = recipe_proto.localised_name
if not (recipe_proto.custom or player.force.recipes[recipe_proto.name].enabled) then
util.messages.raise(player, "warning", {"fp.warning_recipe_disabled", recipe_name}, 2)
Expand Down
46 changes: 43 additions & 3 deletions modfiles/ui/main/production_box.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ local function refresh_solver_frame(player)
solver_flow.clear()

local factory_data = solver.generate_factory_data(player, factory)

local matrix_metadata = matrix_engine.get_matrix_solver_metadata(factory_data)
if matrix_metadata.num_rows == 0 then return end -- skip if there are no active lines
local linear_dependence_data = matrix_engine.get_linear_dependence_data(factory_data, matrix_metadata)
Expand Down Expand Up @@ -68,16 +69,55 @@ local function refresh_solver_frame(player)
item_count = item_count + #matrix_metadata.free_items

if needs_choice then
local flow_constrained = solver_flow.add{type="flow", direction="horizontal"}
build_item_flow(flow_constrained, "constrained", linear_dependence_data.allowed_free_items)
item_count = item_count + #linear_dependence_data.allowed_free_items
log("[FP] SolverUI: Needs choice. Processing items.")
local last_recipe_items_to_display = {}
local other_items = {}
local allowed_free_items = linear_dependence_data.allowed_free_items

local function base_name(item)
if (item.base_name ~= nil) then return item.base_name
else return item.name
end
end

local last_recipe_map = {}
for _, item in ipairs(factory.last_recipe_items or {}) do
last_recipe_map[base_name(item)] = true
end

for _, item in ipairs(allowed_free_items) do
if last_recipe_map[base_name(item)] then
table.insert(last_recipe_items_to_display, item)
else
table.insert(other_items, item)
end
end
log("[FP] SolverUI: Separated into " .. #last_recipe_items_to_display .. " from last recipe and " .. #other_items .. " other items.")

if #last_recipe_items_to_display > 0 then
solver_flow.add{type="label", caption={"fp.last_recipe_items"}, style="bold_label"}
local flow_priority = solver_flow.add{type="flow", direction="horizontal"}
build_item_flow(flow_priority, "constrained", last_recipe_items_to_display)
item_count = item_count + #last_recipe_items_to_display
end

if #other_items > 0 then
if #last_recipe_items_to_display > 0 then
solver_flow.add{type="label", caption={"fp.other_items"}, style="bold_label"}
end
local flow_constrained = solver_flow.add{type="flow", direction="horizontal"}
build_item_flow(flow_constrained, "constrained", other_items)
item_count = item_count + #other_items
end
end

-- This is some total bullshit because extra_bottom_padding_when_activated doesn't work
local total_width = 180 + (4 * 12) + (item_count * 40)
local interface_width = util.globals.ui_state(player).main_dialog_dimensions.width
local box_width = interface_width - MAGIC_NUMBERS.list_width
solver_flow.style.bottom_padding = (total_width > box_width) and 16 or 4
else
log("[FP] SolverUI: Solver is balanced.")
end
end

Expand Down