From baa897bc78ef9ba796e70345124e140eb97927fd Mon Sep 17 00:00:00 2001 From: Tom Cook Date: Mon, 26 Dec 2022 22:18:01 +0000 Subject: [PATCH 1/3] Add option to output recipe ingredients for all inputs. --- crafting_combinator/config.lua | 19 +-- crafting_combinator/locale/en/en.cfg | 3 +- crafting_combinator/script/rc.lua | 145 +++++++++++------- .../script/recipe-selector.lua | 53 +++++-- 4 files changed, 147 insertions(+), 73 deletions(-) diff --git a/crafting_combinator/config.lua b/crafting_combinator/config.lua index 9512f34..b2cc355 100644 --- a/crafting_combinator/config.lua +++ b/crafting_combinator/config.lua @@ -12,7 +12,7 @@ return { GROUP_NAME = 'crafting_combinator:virtual-recipes', RECIPE_SUBGROUP_PREFIX = 'crafting_combinator:virtual-recipe-subgroup:', UNSORTED_RECIPE_SUBGROUP = 'crafting_combinator:virtual-recipe-subgroup:unsorted', - + CC_DEFAULT_SETTINGS = { chest_position = 1, -- 1 = Behind, 2 = Left, 3 = Right mode = 'w', @@ -30,32 +30,33 @@ return { divide_by_output = false, differ_output = false, time_multiplier = 10, + all_inputs = false, }, - + ASSEMBLER_DISTANCE = 1, ASSEMBLER_SEARCH_DISTANCE = 2, CHEST_DISTANCE = 1, CHEST_SEARCH_DISTANCE = 2, INSERTER_SEARCH_RADIUS = 3, - + REFRESH_RATE_CC = 60, REFRESH_RATE_RC = 60, - + INSERTER_EMPTY_DELAY = 60, - + MODULE_CHEST_SIZE = 100, - + RC_SLOT_COUNT = 40, -- This is the number of extra slots on top of the max ingredient count RC_SLOT_RESERVE = 5, -- 5 is arbitrary, but large enough - + -- Recipes matching any of these strings will not get a virtual recipe RECIPES_TO_IGNORE = { 'angels%-void', }, - + FLYING_TEXT_INTERVAL = 180, - + MACHINE_STATUS_SIGNALS = { working = 'signal-green', no_power = 'signal-red', diff --git a/crafting_combinator/locale/en/en.cfg b/crafting_combinator/locale/en/en.cfg index 5926cd4..ef32cf0 100644 --- a/crafting_combinator/locale/en/en.cfg +++ b/crafting_combinator/locale/en/en.cfg @@ -60,7 +60,8 @@ multiply-by-input=Multiply results by input count multiply-by-input:tooltip=Take each resulting signal and multiply it by the strength of the chosen input signal before outputting it divide-by-output=Divide results by product/ingredient count divide-by-output:tooltip=Take the resulting recipe signals and divide their strength by how much of the searched-for item or fluid it produces or consumes, effectively outputting how many times the recipe needs to be crafted to obtain or process the given number of an item. This only works in usage and recipe mode with 'Multiply results by input count' enabled -time-multiplier=Time multiplier: +time-multiplier=Time multiplier: +all-inputs=Calculate for all input signals differ-output=Vary the strength of output signals differ-output:tooltip=Set the strengths of the output signals to be each a different number. This can not be used with either of 'Multiply results by input count' and 'Divide results by product count' open-module-chest=Open module chest diff --git a/crafting_combinator/script/rc.lua b/crafting_combinator/script/rc.lua index e392aab..82f309b 100644 --- a/crafting_combinator/script/rc.lua +++ b/crafting_combinator/script/rc.lua @@ -16,6 +16,7 @@ _M.settings_parser = settings_parser { divide_by_output = {'o', 'bool'}, differ_output = {'d', 'bool'}, time_multiplier = {'t', 'number'}, + all_inputs = {'a', 'bool'}, } @@ -78,7 +79,7 @@ function _M.create(entity) last_name = false, last_count = false, }, combinator_mt) - + entity.connect_neighbour { wire = defines.wire_type.red, target_entity = combinator.output_proxy, @@ -91,7 +92,7 @@ function _M.create(entity) } combinator.output_proxy.destructible = false combinator.control_behavior = combinator.output_proxy.get_or_create_control_behavior() - + global.rc.data[entity.unit_number] = combinator table.insert(global.rc.ordered, combinator) end @@ -99,11 +100,11 @@ end function _M.destroy(entity) local unit_number = entity.unit_number local combinator = global.rc.data[unit_number] - + combinator.output_proxy.destroy() settings_parser.destroy(entity) signals.cache.drop(entity) - + global.rc.data[unit_number] = nil for k, v in pairs(global.rc.ordered) do if v.entity.unit_number == unit_number then @@ -119,7 +120,7 @@ function _M:update(forced) self.last_name = false self.last_count = false end - + if self.settings.mode == 'rec' or self.settings.mode == 'use' then self:find_recipe() elseif self.settings.mode == 'mac' then self:find_machines(forced) else self:find_ingredients_and_products(forced); end @@ -144,15 +145,17 @@ function _M:find_recipe() self.settings.mode == 'rec' and 'products' or 'ingredients', self.last_signal, self.settings.multiply_by_input and self.last_count or nil ) - + + log(serpent.block(recipes)) + if not changed then return; end self.last_signal = signal self.last_count = count - + local params = make_params(table_size(recipes)) local index = 1 local slots = _M.get_rc_slot_count() - + count = self.settings.multiply_by_input and count or 1 local round = self.settings.mode == 'use' and math.floor or math.ceil for i, recipe in pairs(recipes) do @@ -169,52 +172,85 @@ function _M:find_recipe() slots = slots - 1 end end - + self.control_behavior.parameters = params end function _M:find_ingredients_and_products() - local changed, recipe, input_count = recipe_selector.get_recipe( - self.entity, - defines.circuit_connector_id.combinator_input, - self.last_name, - self.settings.multiply_by_input and self.last_count or nil - ) - - if not changed then return; end - - self.last_name = recipe and recipe.name - self.last_count = input_count - - if recipe and (recipe.hidden or not recipe.enabled) then recipe = nil; end - + local changed, recipes, input_count, input_signal + if self.settings.all_inputs then + changed, recipes, last_signals = recipe_selector.get_all_recipes( + self.entity, + defines.circuit_connector_id.combinator_input, + nil +-- self.last_signals + ) + if not changed then return ; end + self.last_signals = last_signals + else + local changed, recipe, input_count = recipe_selector.get_recipe( + self.entity, + defines.circuit_connector_id.combinator_input, + self.last_name, + self.settings.multiply_by_input and self.last_count or nil + ) + if recipe and (recipe.hidden or not recipe.enabled) then recipe = nil; end + recipes={{recipe=recipe}} + + if not changed then return; end + + self.last_name = recipe and recipe.name + self.last_count = input_count + self.last_signal = input_signal + end + local params = {} - - if recipe then - local crafting_multiplier = self.settings.multiply_by_input and input_count or 1 - for i, ing in pairs( - self.settings.mode == 'prod' and recipe.products or - self.settings.mode == 'ing' and recipe.ingredients or {} - ) do - local amount = math.ceil( - tonumber(ing.amount or ing.amount_min or ing.amount_max) * crafting_multiplier - * (tonumber(ing.probability) or 1) - ) - - params[i] = { - signal = {type = ing.type, name = ing.name}, - count = self.settings.differ_output and i or util.simulate_overflow(amount), - index = i, - } + + local ingredients = {} + local time_signal = 0 + + local crafting_multiplier = self.settings.multiply_by_input and input_count or 1 + for i, c_recipe in pairs(recipes) do + local recipe = c_recipe.recipe + log(string.format("Loop recipe: %s, %d", serpent.block(recipe.name), recipe.energy)) + if recipe and recipe.energy then + for i, ing in pairs( + self.settings.mode == 'prod' and recipe.products or + self.settings.mode == 'ing' and recipe.ingredients or {} + ) do + local amount = math.ceil( + tonumber(ing.amount or ing.amount_min or ing.amount_max) * crafting_multiplier + * (tonumber(ing.probability) or 1) + ) + + if ing.type == "item" then + ingredients[ing.name] = (ingredients[ing.name] or 0) + (self.settings.differ_output and i or util.simulate_overflow(amount)) + end + end end - - table.insert(params, { - signal = {type = 'virtual', name = config.TIME_SIGNAL_NAME}, - count = util.simulate_overflow(math.floor(tonumber(recipe.energy) * self.settings.time_multiplier * crafting_multiplier)), - index = _M.get_rc_slot_count(), - }) + time_signal = time_signal + ( + util.simulate_overflow(math.floor(tonumber(recipe.energy) * + (self.settings.time_multiplier or 1) + * crafting_multiplier)) + ) + end + + local i = 1 + for name, count in pairs(ingredients) do + params[i] = { + signal = {type="item", name=name}, + count = count, + index = i + } + i = i + 1 end - + + table.insert(params, { + signal = {type = 'virtual', name = config.TIME_SIGNAL_NAME}, + count = time_signal, + index = _M.get_rc_slot_count(), + }) + self.control_behavior.parameters = params end @@ -226,14 +262,14 @@ function _M:find_machines() self.last_name, self.settings.multiply_by_input and self.last_count or nil ) - + if not changed then return; end - + self.last_name = recipe and recipe.name self.last_count = input_count - + if recipe and (recipe.hidden or not recipe.enabled) then recipe = nil; end - + if _M.item_map == nil then _M.build_machine_cache(); end local params = {} @@ -275,9 +311,10 @@ function _M:open(player_index) gui.checkbox('divide-by-output', self.settings.divide_by_output, {tooltip=true}), gui.checkbox('differ-output', self.settings.differ_output, {tooltip=true}), gui.number_picker('time-multiplier', self.settings.time_multiplier), + gui.checkbox('all-inputs', self.settings.all_inputs, {tooltip=true}), } }):open(player_index) - + self:update_disabled_checkboxes(root) end @@ -293,9 +330,9 @@ function _M:on_checked_changed(name, state, element) end end if category == 'misc' then self.settings[name] = state; end - + self:update_disabled_checkboxes(gui.get_root(element)) - + self.settings_parser:update(self.entity, self.settings) self:update(true) end diff --git a/crafting_combinator/script/recipe-selector.lua b/crafting_combinator/script/recipe-selector.lua index 1ac6351..ac203d8 100644 --- a/crafting_combinator/script/recipe-selector.lua +++ b/crafting_combinator/script/recipe-selector.lua @@ -6,12 +6,12 @@ local _M = {} function _M.get_recipe(entity, circuit_id, last_name, last_count) local highest = signals.get_highest(entity, circuit_id, last_count ~= nil) - + if not highest then if last_name == nil then return false; end return true, nil, 0 end - + if last_name == highest.signal.name and (last_count == nil or last_count == highest.count) then return false; end return true, entity.force.recipes[highest.signal.name], highest.count end @@ -27,27 +27,62 @@ local get_recipes_cache = { fluid = {}, }, } + +function _M.get_all_recipes(entity, circuit_id, last_signals) + local all_signals = signals.get_merged_signals(entity, circuit_id) + if last_signals then + local changed = false + for k, v in pairs(all_signals) do + local equiv = last_signals[k] + if equiv.signal.name ~= v.signal.name or equiv.count ~= v.count then + changed = true + end + end + if not changed then + return false + end + end + + + local recipes = {} + + for i, signal in pairs(all_signals) do + log(string.format("Collected signal: %s, %s", serpent.block(signal), signal.signal.name)) + local recipe = entity.force.recipes[signal.signal.name] + log(string.format("Collected recipe: %s", serpent.block(recipe))) + table.insert(recipes, {count=signal.count, recipe=recipe}) + end + return true, recipes, all_signals +end + function _M.get_recipes(entity, circuit_id, mode, last_signal, last_count) local highest = signals.get_highest(entity, circuit_id, last_count ~= nil) - + log(serpent.block(highest)) + if not highest or highest.signal.type == 'virtual' then - if last_signal == nil then return false; end + if last_signal == nil then + log("Returning false 1") + return false + end return true, {}, 0, nil end - + if last_signal and last_signal.name == highest.signal.name and last_signal.type == highest.signal.type and (last_count == nil or last_count == highest.count) - then return false; end - + then + log("Returning false 2") + return false + end + local cache = get_recipes_cache[mode][highest.signal.type] local force_index = entity.force.index cache[force_index] = cache[force_index] or {} if cache[force_index][highest.signal.name] then return true, cache[force_index][highest.signal.name], highest.count, highest.signal end - + local results = {} for name, recipe in pairs(entity.force.recipes) do for _, product in pairs(recipe[mode]) do @@ -59,7 +94,7 @@ function _M.get_recipes(entity, circuit_id, mode, last_signal, last_count) end end end - + cache[force_index][highest.signal.name] = results return true, results, highest.count, highest.signal end From 96b84ccd70810ead99158167a623472233b66bd2 Mon Sep 17 00:00:00 2001 From: Tom Cook Date: Fri, 6 Jan 2023 10:01:28 +0000 Subject: [PATCH 2/3] Add "read required ingredients" option to the recipe combinator. --- crafting_combinator/locale/en/en.cfg | 1 + crafting_combinator/script/cc.lua | 93 ++++++++++++++++++---------- crafting_combinator/script/rc.lua | 45 ++++++++------ 3 files changed, 85 insertions(+), 54 deletions(-) diff --git a/crafting_combinator/locale/en/en.cfg b/crafting_combinator/locale/en/en.cfg index ef32cf0..c971c32 100644 --- a/crafting_combinator/locale/en/en.cfg +++ b/crafting_combinator/locale/en/en.cfg @@ -56,6 +56,7 @@ empty-inserters=Empty inserters' hands (prevents jamming) read-recipe=Read the current recipe read-speed=Read the machine's crafting speed read-machine-status=Read machine status +read-required-ingredients=Read required ingredients multiply-by-input=Multiply results by input count multiply-by-input:tooltip=Take each resulting signal and multiply it by the strength of the chosen input signal before outputting it divide-by-output=Divide results by product/ingredient count diff --git a/crafting_combinator/script/cc.lua b/crafting_combinator/script/cc.lua index 3319a1c..33657b0 100644 --- a/crafting_combinator/script/cc.lua +++ b/crafting_combinator/script/cc.lua @@ -38,6 +38,7 @@ _M.settings_parser = settings_parser { read_recipe = {'r', 'bool'}, read_speed = {'s', 'bool'}, read_machine_status = {'st', 'bool'}, + read_required_ingredients = {'ri', 'bool'}, wait_for_output_to_clear = {'wo', 'bool'}, } @@ -75,15 +76,15 @@ function _M.create(entity) enabled = true, last_recipe = false, }, combinator_mt) - + combinator.module_chest.destructible = false combinator.inventories.module_chest = combinator.module_chest.get_inventory(defines.inventory.chest) - + global.cc.data[entity.unit_number] = combinator table.insert(global.cc.ordered, combinator) combinator:find_assembler() combinator:find_chest() - + -- Other combinators can use the module chest as overflow output, so let them know it's there _M.update_chests(entity.surface, combinator.module_chest) end @@ -116,7 +117,7 @@ end function _M.destroy(entity, player_index) local unit_number = entity.unit_number local combinator = global.cc.data[unit_number] - + if player_index then local inventory = combinator.inventories.module_chest if not inventory.is_empty() then @@ -129,20 +130,20 @@ function _M.destroy(entity, player_index) stack.count = stack.count - r -- Clone the entity as replacement and tell the player the inventory is full game.get_player(player_index).print{'inventory-restriction.player-inventory-full', stack.prototype.localised_name} - + -- Replace the entity if a player was trying to pick it up local old_entity = combinator.entity local old_cb = combinator.control_behavior combinator.entity = old_entity.clone{position = old_entity.position} combinator.control_behavior = combinator.entity.get_or_create_control_behavior() - + global.cc.data[unit_number] = nil global.cc.data[combinator.entity.unit_number] = combinator - + for _, connection in pairs(old_entity.circuit_connection_definitions) do combinator.entity.connect_neighbour(connection) end - + old_entity.destroy() return true -- Inidcate that the original entity was destroyed else stack.clear(); end @@ -150,13 +151,13 @@ function _M.destroy(entity, player_index) end end end - + -- Notify other combinators that the chest was destroyed _M.update_chests(entity.surface, combinator.module_chest, true) if player_index then combinator.module_chest.destroy(); end settings_parser.destroy(entity) signals.cache.drop(entity) - + global.cc.data[unit_number] = nil for k, v in pairs(global.cc.ordered) do if v.entity.unit_number == unit_number then @@ -186,7 +187,7 @@ function _M:update() local params = {} if self.enabled and self.assembler and self.assembler.valid then self.assembler.active = true - + if self.settings.mode == 'w' then self:set_recipe() end @@ -194,9 +195,10 @@ function _M:update() if self.settings.read_recipe then self:read_recipe(params); end if self.settings.read_speed then self:read_speed(params); end if self.settings.read_machine_status then self:read_machine_status(params); end + if self.settings.read_required_ingredients then self:read_required_ingredients(params); end end end - + self.control_behavior.parameters = params end @@ -207,7 +209,7 @@ function _M:open(player_index) gui.button('open-module-chest'), gui.dropdown('chest-position', CHEST_POSITION_NAMES, self.settings.chest_position, {tooltip=true}), }, - + gui.section { name = 'mode', gui.radio('w', self.settings.mode, {locale='mode-write', tooltip=true}), @@ -223,9 +225,10 @@ function _M:open(player_index) gui.checkbox('read-recipe', self.settings.read_recipe), gui.checkbox('read-speed', self.settings.read_speed), gui.checkbox('read-machine-status', self.settings.read_machine_status), + gui.checkbox('read-required-ingredients', self.settings.read_required_ingredients) } }):open(player_index) - + self:update_disabled_checkboxes(root) end @@ -244,9 +247,9 @@ function _M:on_checked_changed(name, state, element) if name == 'craft_until_zero' and self.settings.craft_until_zero then self.last_recipe = nil end - + self:update_disabled_checkboxes(gui.get_root(element)) - + self.settings_parser:update(self.entity, self.settings) end @@ -259,6 +262,7 @@ function _M:update_disabled_checkboxes(root) self:disable_checkbox(root, 'misc:read-recipe', 'r') self:disable_checkbox(root, 'misc:read-speed', 'r') self:disable_checkbox(root, 'misc:read-machine-status', 'r') + self:disable_checkbox(root, 'misc:read-required-ingredients', 'r') end function _M:disable_checkbox(root, name, mode) @@ -313,6 +317,27 @@ function _M:read_machine_status(params) }) end +function _M:read_required_ingredients(params) + local recipe = self.assembler.get_recipe() + if recipe then + local inventory = self.assembler.get_inventory(defines.inventory.assembling_machine_input) + local signal_index = 4 + for ii, ing in pairs(recipe.ingredients) do + local count = ing.amount - inventory.get_item_count(ing.name) + if count > 0 then + local signal = { + signal = { type='item', name=ing.name }, + count = count, + index = #params + 1 + } + table.insert(params, signal) + signal_index = signal_index + 1 + log(string.format("Outputting signal %s", serpent.block(signal))) + end + end + end +end + function _M:set_recipe() local changed, recipe if self.settings.craft_until_zero then @@ -327,11 +352,11 @@ function _M:set_recipe() if changed then self.last_recipe = recipe else recipe = self.last_recipe; end end - + if recipe and (recipe.hidden or not recipe.enabled) then recipe = nil; end - + local a_recipe = self.assembler.get_recipe() - + -- Move items if necessary if a_recipe and ((not recipe) or recipe ~= a_recipe) then local success, error = self:move_items() @@ -339,32 +364,32 @@ function _M:set_recipe() if self.settings.empty_inserters then success, error = self:empty_inserters() if not success then return self:on_chest_full(error); end - + local tick = game.tick + config.INSERTER_EMPTY_DELAY global.cc.inserter_empty_queue[tick] = global.cc.inserter_empty_queue[tick] or {} table.insert(global.cc.inserter_empty_queue[tick], self) end - + -- Clear fluidboxes if self.settings.discard_fluids then for i=1, #self.assembler.fluidbox do self.assembler.fluidbox[i] = nil; end end end - + if recipe ~= a_recipe then -- Move modules if necessary if recipe then self:move_modules(recipe); end - + -- Finally attempt to switch the recipe self.assembler.set_recipe(recipe) local new_recipe = self.assembler.get_recipe() if new_recipe and new_recipe ~= recipe then self.assembler.set_recipe(nil); end --TODO: Some notification? end - + -- Move modules and items back into the machine self:insert_modules() self:insert_items() - + return true end @@ -385,7 +410,7 @@ function _M:insert_modules() local inventory = self.inventories.module_chest if inventory.is_empty() then return; end local target = self.inventories.assembler.modules - + for i = 1, #inventory do local stack = inventory[i] if stack.valid_for_read then @@ -400,7 +425,7 @@ function _M:insert_items() local inventory = self.inventories.chest if not inventory or not inventory.valid or inventory.is_empty() then return; end local target = self.inventories.assembler.input - + for i = 1, #inventory do local stack = inventory[i] if stack.valid_for_read then @@ -415,11 +440,11 @@ function _M:move_items() if self.settings.wait_for_output_to_clear and not self.inventories.assembler.output.is_empty() then return false, 'waiting-for-output' end - + if self.settings.discard_items then return true; end - + local target = self:get_chest_inventory() - + -- Compensate for half-finished crafts -- Do this first to avoid losing a lot of items if self.assembler.crafting_progress > 0 then @@ -434,7 +459,7 @@ function _M:move_items() self.assembler.crafting_progress = 0 if not success then return false, 'chest-full'; end end - + -- Clear the assembler inventories -- This may become somewhat problematic if the input items can be moved, but the output can't, since inserters will -- continue to replace the items that were removed. I guess that's up to the player to deal with tho... @@ -452,7 +477,7 @@ function _M:move_items() end end end - + return true end @@ -472,7 +497,7 @@ end function _M:empty_inserters() local target = self:get_chest_inventory() - + for _, inserter in pairs(self.assembler.surface.find_entities_filtered { area = util.area(self.assembler.prototype.selection_box):expand(config.INSERTER_SEARCH_RADIUS) + self.assembler.position, type = 'inserter', @@ -501,7 +526,7 @@ function _M:find_assembler(assembler_to_ignore) if self.assembler and (self.assembler == assembler_to_ignore or self.assembler.prototype.fixed_recipe) then self.assembler = nil end - + if self.assembler then self.inventories.assembler = { output = self.assembler.get_inventory(defines.inventory.assembling_machine_output), diff --git a/crafting_combinator/script/rc.lua b/crafting_combinator/script/rc.lua index 82f309b..6b2a5d5 100644 --- a/crafting_combinator/script/rc.lua +++ b/crafting_combinator/script/rc.lua @@ -195,7 +195,7 @@ function _M:find_ingredients_and_products() self.settings.multiply_by_input and self.last_count or nil ) if recipe and (recipe.hidden or not recipe.enabled) then recipe = nil; end - recipes={{recipe=recipe}} + recipes={{recipe=recipe, count=input_count}} if not changed then return; end @@ -209,30 +209,35 @@ function _M:find_ingredients_and_products() local ingredients = {} local time_signal = 0 - local crafting_multiplier = self.settings.multiply_by_input and input_count or 1 for i, c_recipe in pairs(recipes) do + local crafting_multiplier = self.settings.multiply_by_input and c_recipe.count or 1 local recipe = c_recipe.recipe - log(string.format("Loop recipe: %s, %d", serpent.block(recipe.name), recipe.energy)) - if recipe and recipe.energy then - for i, ing in pairs( - self.settings.mode == 'prod' and recipe.products or - self.settings.mode == 'ing' and recipe.ingredients or {} - ) do - local amount = math.ceil( - tonumber(ing.amount or ing.amount_min or ing.amount_max) * crafting_multiplier - * (tonumber(ing.probability) or 1) - ) - - if ing.type == "item" then - ingredients[ing.name] = (ingredients[ing.name] or 0) + (self.settings.differ_output and i or util.simulate_overflow(amount)) + if recipe then + log(string.format("Recipe: %s", serpent.block(recipe))) + log(string.format("Loop recipe: %s, %d", serpent.block(recipe.name), recipe.energy)) + if recipe and recipe.energy then + for i, ing in pairs( + self.settings.mode == 'prod' and recipe.products or + self.settings.mode == 'ing' and recipe.ingredients or {} + ) do + log(string.format("Ingredient %s with amount %d and multiplier %d", + ing.name, ing.amount, crafting_multiplier)) + local amount = math.ceil( + tonumber(ing.amount or ing.amount_min or ing.amount_max) * crafting_multiplier + * (tonumber(ing.probability) or 1) + ) + + if ing.type == "item" then + ingredients[ing.name] = (ingredients[ing.name] or 0) + (self.settings.differ_output and i or util.simulate_overflow(amount)) + end end end + time_signal = time_signal + ( + util.simulate_overflow(math.floor(tonumber(recipe.energy) * + (self.settings.time_multiplier or 1) + * crafting_multiplier)) + ) end - time_signal = time_signal + ( - util.simulate_overflow(math.floor(tonumber(recipe.energy) * - (self.settings.time_multiplier or 1) - * crafting_multiplier)) - ) end local i = 1 From 1d9a2b453ab4c041c39e29a0ee2e0b516bd9ff29 Mon Sep 17 00:00:00 2001 From: Tom Cook Date: Sat, 14 Jan 2023 12:28:10 +0000 Subject: [PATCH 3/3] Debugging. --- crafting_combinator/data.lua | 31 ++++++++++++++----- crafting_combinator/script/cc.lua | 23 ++++++++------ crafting_combinator/script/rc.lua | 6 ---- .../script/recipe-selector.lua | 19 +++++++----- crafting_combinator/script/signals.lua | 26 ++++++++-------- 5 files changed, 61 insertions(+), 44 deletions(-) diff --git a/crafting_combinator/data.lua b/crafting_combinator/data.lua index 344ed71..bb83dee 100644 --- a/crafting_combinator/data.lua +++ b/crafting_combinator/data.lua @@ -8,7 +8,7 @@ local cc = table.deepcopy(data.raw['constant-combinator']['constant-combinator'] cc.name = config.CC_NAME cc.icon = '__crafting_combinator__/graphics/icon-crafting-combinator.png' cc.icon_size = 32 -cc.item_slot_count = 3 +cc.item_slot_count = 40 cc.minable.result = cc.name table.insert(cc.flags, 'not-deconstructable') @@ -93,7 +93,7 @@ data:extend { inventory_size = config.MODULE_CHEST_SIZE, picture = trans, minable = {mining_time = 0.2, result = cc.name}, - + -- Disguise the chest as the combinator itself, so it looks right in deconstruction planner filters localised_name = {'entity-name.crafting_combinator:crafting-combinator'}, icons = icons.of(cc), @@ -119,15 +119,15 @@ data:extend { sprite = trans, icon = '__base__/graphics/icons/blueprint.png', icon_size = 32, - + minable = { result = config.SETTINGS_ENTITY_NAME, mining_time = 0, }, - + energy_source = { type = 'void' }, energy_usage_per_tick = '1W', - + instruments = {}, maximum_polyphony = 0, }, @@ -146,7 +146,7 @@ data:extend { }, activity_led_sprites = trans, activity_led_light_offsets = {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, - + circuit_wire_connection_points = {con_point, con_point, con_point, con_point}, draw_circuit_wires = false, }, @@ -158,13 +158,13 @@ data:extend { circuit_wire_max_distance = 3, circuit_wire_connection_points = {con_point, con_point, con_point, con_point}, draw_circuit_wires = false, - + picture_on = trans, picture_off = trans, energy_source = {type = 'void'}, energy_usage_per_tick = '1W', }, - + { type = 'item-group', name = config.GROUP_NAME, @@ -201,3 +201,18 @@ data:extend { icon_size = 32, }, } + +data:extend { + { + type = "recipe", + name = "resin", + category = "crafting-machine", + subgroup = "bob-resource", + energy_required = 1, + ingredients = { + { "wood", 1 }, + }, + result = "resin", + allow_decomposition = false, + }, +} diff --git a/crafting_combinator/script/cc.lua b/crafting_combinator/script/cc.lua index 33657b0..ae0ee28 100644 --- a/crafting_combinator/script/cc.lua +++ b/crafting_combinator/script/cc.lua @@ -199,6 +199,7 @@ function _M:update() end end + log(string.format("CC Output params: %s", serpent.block(params))) self.control_behavior.parameters = params end @@ -323,16 +324,18 @@ function _M:read_required_ingredients(params) local inventory = self.assembler.get_inventory(defines.inventory.assembling_machine_input) local signal_index = 4 for ii, ing in pairs(recipe.ingredients) do - local count = ing.amount - inventory.get_item_count(ing.name) - if count > 0 then - local signal = { - signal = { type='item', name=ing.name }, - count = count, - index = #params + 1 - } - table.insert(params, signal) - signal_index = signal_index + 1 - log(string.format("Outputting signal %s", serpent.block(signal))) + log(string.format("Requirement: %s", serpent.block(ing))) + if ing.type == "item" then + local count = ing.amount - inventory.get_item_count(ing.name) + if count > 0 then + local signal = { + signal = { type='item', name=ing.name }, + count = count, + index = #params + 1 + } + table.insert(params, signal) + signal_index = signal_index + 1 + end end end end diff --git a/crafting_combinator/script/rc.lua b/crafting_combinator/script/rc.lua index 6b2a5d5..6928b03 100644 --- a/crafting_combinator/script/rc.lua +++ b/crafting_combinator/script/rc.lua @@ -146,8 +146,6 @@ function _M:find_recipe() self.last_signal, self.settings.multiply_by_input and self.last_count or nil ) - log(serpent.block(recipes)) - if not changed then return; end self.last_signal = signal self.last_count = count @@ -213,15 +211,11 @@ function _M:find_ingredients_and_products() local crafting_multiplier = self.settings.multiply_by_input and c_recipe.count or 1 local recipe = c_recipe.recipe if recipe then - log(string.format("Recipe: %s", serpent.block(recipe))) - log(string.format("Loop recipe: %s, %d", serpent.block(recipe.name), recipe.energy)) if recipe and recipe.energy then for i, ing in pairs( self.settings.mode == 'prod' and recipe.products or self.settings.mode == 'ing' and recipe.ingredients or {} ) do - log(string.format("Ingredient %s with amount %d and multiplier %d", - ing.name, ing.amount, crafting_multiplier)) local amount = math.ceil( tonumber(ing.amount or ing.amount_min or ing.amount_max) * crafting_multiplier * (tonumber(ing.probability) or 1) diff --git a/crafting_combinator/script/recipe-selector.lua b/crafting_combinator/script/recipe-selector.lua index ac203d8..f24717b 100644 --- a/crafting_combinator/script/recipe-selector.lua +++ b/crafting_combinator/script/recipe-selector.lua @@ -8,11 +8,21 @@ function _M.get_recipe(entity, circuit_id, last_name, last_count) local highest = signals.get_highest(entity, circuit_id, last_count ~= nil) if not highest then - if last_name == nil then return false; end + if last_name == nil then + return false + end return true, nil, 0 end - if last_name == highest.signal.name and (last_count == nil or last_count == highest.count) then return false; end + local name = highest.signal.name + if name ~= "solder" and name ~= "basic-electronic-components" and name ~= "basic-circuit-board" then + log(string.format("Highest: %s", serpent.block(highest))) + end + + if last_name == highest.signal.name and (last_count == nil or last_count == highest.count) then + return false + end + return true, entity.force.recipes[highest.signal.name], highest.count end @@ -47,9 +57,7 @@ function _M.get_all_recipes(entity, circuit_id, last_signals) local recipes = {} for i, signal in pairs(all_signals) do - log(string.format("Collected signal: %s, %s", serpent.block(signal), signal.signal.name)) local recipe = entity.force.recipes[signal.signal.name] - log(string.format("Collected recipe: %s", serpent.block(recipe))) table.insert(recipes, {count=signal.count, recipe=recipe}) end return true, recipes, all_signals @@ -57,11 +65,9 @@ end function _M.get_recipes(entity, circuit_id, mode, last_signal, last_count) local highest = signals.get_highest(entity, circuit_id, last_count ~= nil) - log(serpent.block(highest)) if not highest or highest.signal.type == 'virtual' then if last_signal == nil then - log("Returning false 1") return false end return true, {}, 0, nil @@ -72,7 +78,6 @@ function _M.get_recipes(entity, circuit_id, mode, last_signal, last_count) and last_signal.type == highest.signal.type and (last_count == nil or last_count == highest.count) then - log("Returning false 2") return false end diff --git a/crafting_combinator/script/signals.lua b/crafting_combinator/script/signals.lua index f4afeaf..68fabdb 100644 --- a/crafting_combinator/script/signals.lua +++ b/crafting_combinator/script/signals.lua @@ -17,7 +17,7 @@ local cache_mt = { } self.__cache_entities[key] = entity entity.destructible = false - + self.__entity.connect_neighbour { wire = defines.wire_type.red, target_entity = entity, @@ -28,11 +28,11 @@ local cache_mt = { target_entity = entity, source_circuit_id = self.__circuit_id or nil, } - + self[key] = { __cb = entity.get_or_create_control_behavior(), } - + return self[key] end, } @@ -99,14 +99,14 @@ end function _M.get_highest(entity, circuit_id, update_count) local cache = _M.cache.get(entity, circuit_id) - + if cache.highest.valid and not cache.highest.__cb.disabled and (not cache.highest.value or not cache.highest_present.__cb.disabled) then if update_count and cache.highest.value and cache.highest_count.__cb.disabled then local count = _M.get_merged_signal(entity, cache.highest.value.signal, circuit_id) - + cache.highest.value.count = count cache.highest_count.__cb.circuit_condition = {condition = { comparator = '=', @@ -116,14 +116,14 @@ function _M.get_highest(entity, circuit_id, update_count) end return cache.highest.value end - + local highest = nil for _, signal in pairs(_M.get_merged_signals(entity, circuit_id)) do if highest == nil or signal.count > highest.count then highest = signal; end end - + cache.highest.valid = true - + if highest then cache.highest.value = highest cache.highest.__cb.circuit_condition = {condition = { @@ -131,13 +131,13 @@ function _M.get_highest(entity, circuit_id, update_count) first_signal = _M.EVERYTHING, second_signal = highest.signal, }} - + cache.highest_present.__cb.circuit_condition = {condition = { comparator = '≠', first_signal = highest.signal, constant = 0, }} - + cache.highest_count.__cb.circuit_condition = {condition = { comparator = '=', first_signal = highest.signal, @@ -151,7 +151,7 @@ function _M.get_highest(entity, circuit_id, update_count) constant = 0, }} end - + return highest end @@ -159,7 +159,7 @@ end function _M.watch_highest_presence(entity, circuit_id) local highest = _M.get_highest(entity, circuit_id) local cache = _M.cache.get(entity, circuit_id) - + if not highest then cache.signal_present.valid = false else @@ -170,7 +170,7 @@ function _M.watch_highest_presence(entity, circuit_id) constant = 0, }} end - + return highest end function _M.signal_present(entity, circuit_id)