From 988f83cd463304f1656c8acb89a41dea0d13813e Mon Sep 17 00:00:00 2001 From: Ben Gardner Date: Tue, 5 Dec 2023 19:01:03 -0600 Subject: [PATCH] snapshot --- control.lua | 3 ++ locale/en/config.cfg | 1 + src/NetworkChestGui.lua | 84 +++++++++++++++++++++++++++---- src/prototypes/network-chests.lua | 8 +-- src/service_queue.lua | 35 +++++++++++-- 5 files changed, 115 insertions(+), 16 deletions(-) diff --git a/control.lua b/control.lua index 85cf9f8..101e4d6 100644 --- a/control.lua +++ b/control.lua @@ -1,5 +1,8 @@ if script.active_mods["gvv"] then require("__gvv__.gvv")() end +-- declare global +clog = require("src.log_console").log + -- need to register for on_tick() first require "src.GlobalState" diff --git a/locale/en/config.cfg b/locale/en/config.cfg index 5f0f0ff..431e8e9 100644 --- a/locale/en/config.cfg +++ b/locale/en/config.cfg @@ -24,6 +24,7 @@ network-limit-sensor=Network Limit Sensor network-chest=A chest used to access the network. network-loader=A loader. network-sensor=Reads the network item content for the circuit network. +network-chest-provider=Periodically moves contents to the network. Does not respect limits. [controls] in_confirm_dialog=Confirm Dialog diff --git a/src/NetworkChestGui.lua b/src/NetworkChestGui.lua index bff7524..45f5380 100644 --- a/src/NetworkChestGui.lua +++ b/src/NetworkChestGui.lua @@ -56,6 +56,7 @@ function M.on_gui_opened(player, chest_entity) M.log_chest_state(chest_entity, chest_info) +--[[ if #requests == 0 then M.add_autochest_element(chest_entity, chest_info, requests_scroll) else @@ -63,7 +64,7 @@ M.log_chest_state(chest_entity, chest_info) M.add_request_element(request, requests_scroll) end end - +]] -- edit window local edit_flow = requests_flow.add({ type = "flow", @@ -139,12 +140,14 @@ M.log_chest_state(chest_entity, chest_info) M.refresh_request_panel(ui.network_chest) end + function M.refresh_request_panel(network_chest) network_chest.requests_scroll.clear() if #network_chest.requests == 0 then M.add_autochest_element(network_chest.chest_entity, network_chest.chest_info, network_chest.requests_scroll) else + M.balance_requests(network_chest.requests) for _, request in ipairs(network_chest.requests) do M.add_request_element(request, network_chest.requests_scroll) end @@ -772,6 +775,60 @@ function Modal.try_to_auto(player_index) ]] end +--[[ +Round-robin, adding one slot per request until either the buffer +amount is satisfied or we run out of slots. +]] +function M.balance_requests(requests) + local old_req = {} -- consume 'buffer' from this one + local new_req = {} -- add 'buffer' to this one + for _, rr in pairs(requests) do + local prot = game.item_prototypes[rr.item] + old_req[rr.item] = { type=rr.type, item=rr.item, buffer=rr.buffer, stack_size=prot.stack_size } + new_req[rr.item] = { type=rr.type, item=rr.item, buffer=0, stack_size=prot.stack_size } + end + clog("balance before: %s", serpent.line(requests)) + local used_slots = 0 + while used_slots < Constants.NUM_INVENTORY_SLOTS do + local added = false + for _, rr in pairs(old_req) do + if used_slots >= Constants.NUM_INVENTORY_SLOTS then + break + end + local nn = new_req[rr.item] + --clog("process: [%s/%s] %s => %s", used_slots, Constants.NUM_INVENTORY_SLOTS, serpent.line(rr), serpent.line(nn)) + if rr.type == "take" then + if rr.buffer > 0 then + used_slots = used_slots + 1 + local amt = math.min(rr.buffer, rr.stack_size) + rr.buffer = rr.buffer - amt + nn.buffer = nn.buffer + amt + added = true + end + else -- "give" -- requires 1+buffer + if rr.buffer >= 0 then + used_slots = used_slots + 1 + nn.buffer = nn.buffer + math.min(rr.buffer, rr.stack_size) + rr.buffer = rr.buffer - rr.stack_size + added = true + end + end + end + if not added or used_slots == Constants.NUM_INVENTORY_SLOTS then + break + end + end + for _, rr in pairs(requests) do + local xx = new_req[rr.item] + rr.buffer = xx.buffer + end + clog("balance after: used=[%s]", used_slots) + for _, rr in pairs(requests) do + local nn = old_req[rr.item] + clog(" - [%s] item=%s buffer=%s [%s]", rr.type, rr.item, rr.buffer, math.ceil(rr.buffer / nn.stack_size)) + end +end + function Modal.try_to_confirm(player_index) local player = game.get_player(player_index) local ui = GlobalState.get_ui_state(player_index) @@ -802,11 +859,14 @@ function Modal.try_to_confirm(player_index) if ( modal_type == "add" or modal_type == "edit" and request.id ~= request_id - ) and request.item == item then + ) and request.item == item + then + clog("request for %s exists in %s", item, serpent.line(request)) return end end +--[[ -- make sure request size does not exceed chest size local used_slots = 0 for _, request in ipairs(chest_ui.requests) do @@ -814,12 +874,15 @@ function Modal.try_to_confirm(player_index) local slots = math.max(1, math.ceil(request.buffer / stack_size)) used_slots = used_slots + slots end - assert(used_slots <= Constants.NUM_INVENTORY_SLOTS) + if (used_slots > Constants.NUM_INVENTORY_SLOTS) then + clog("used_slots %s > max %s : req=%s", used_slots, Constants.NUM_INVENTORY_SLOTS, serpent.line(chest_ui.requests)) + end local new_inv_slots = math.ceil(buffer / game.item_prototypes[item].stack_size) - if used_slots + new_inv_slots > Constants.NUM_INVENTORY_SLOTS then - return - end + --if used_slots + new_inv_slots > Constants.NUM_INVENTORY_SLOTS then + -- return + --end +]] if modal_type == "add" then local request = { @@ -830,7 +893,7 @@ function Modal.try_to_confirm(player_index) limit = limit, } table.insert(chest_ui.requests, request) - M.add_request_element(request, chest_ui.requests_scroll) + --M.add_request_element(request, chest_ui.requests_scroll) elseif modal_type == "edit" then local request = M.get_request_by_id(player, request_id @@ -841,10 +904,12 @@ function Modal.try_to_confirm(player_index) request.buffer = buffer request.limit = limit end - local request_elem = chest_ui.requests_scroll[request_id] - M.update_request_element(request, request_elem) + --local request_elem = chest_ui.requests_scroll[request_id] + --M.update_request_element(request, request_elem) end + --M.balance_requests(chest_ui.requests) + M.refresh_request_panel(chest_ui) ui.close_type = "confirm_request" @@ -906,6 +971,7 @@ function M.on_chest_request_update(event, element) limit = limit, } table.insert(chest_ui.requests, request) + M.balance_requests(chest_ui.requests) M.refresh_request_panel(chest_ui) end diff --git a/src/prototypes/network-chests.lua b/src/prototypes/network-chests.lua index a50c86a..2a8afe7 100644 --- a/src/prototypes/network-chests.lua +++ b/src/prototypes/network-chests.lua @@ -25,9 +25,11 @@ local function add_chest(variant) entity.icon = Paths.graphics .. "/icons/network-chest-" .. variant .. ".png" -- update inventory - entity.inventory_size = 39 -- constants.NUM_INVENTORY_SLOTS - entity.inventory_type = "with_filters_and_bar" - + entity.inventory_size = 40 -- constants.NUM_INVENTORY_SLOTS + -- no filters + -- entity.inventory_type = "with_filters_and_bar" + entity.inventory_type = "with_bar" + entity.enable_inventory_bar = false -- create the item local item = table.deepcopy(data.raw["item"][override_item_name]) diff --git a/src/service_queue.lua b/src/service_queue.lua index 5071848..a06dfbb 100644 --- a/src/service_queue.lua +++ b/src/service_queue.lua @@ -430,9 +430,9 @@ end --[[ This is the handler for the "new" provider-only chest. -Sends everything to the network. No bars, filter, etc. +Sends everything to the network. No bars, filter, limit, etc. ]] -local function update_network_chest_provider(info) +local function update_network_chest_provider_old(info) -- default to bulk if there is nothing to transfer or the network is full local status = GlobalState.UPDATE_STATUS.UPDATE_BULK @@ -468,6 +468,31 @@ local function update_network_chest_provider(info) return status end +local function update_network_chest_provider(info) + local inv = info.entity.get_output_inventory() + local contents = inv.get_contents() + local n_empty = inv.count_empty_stacks(false, false) + + inv.clear() + + -- move everything we can to the network + for item, count in pairs(contents) do + if count > 0 then + GlobalState.increment_item_count(item, count) + end + end + + if n_empty == 0 then + return GlobalState.UPDATE_STATUS.UPDATE_PRI_INC * 5 + elseif n_empty < 2 then + return GlobalState.UPDATE_STATUS.UPDATE_PRI_INC + elseif n_empty > 4 then + return GlobalState.UPDATE_STATUS.UPDATE_PRI_DEC + else + return GlobalState.UPDATE_STATUS.UPDATE_PRI_SAME + end +end + --[[ This is the handler for the "new" requester-only chest. Fills the chest with one item (filter slot 1), respecting the bar. @@ -602,6 +627,7 @@ local function paste_network_chest(dst_info, source) end end +--[[ local function paste_network_chest_provider(dst_info, source) local dest = dst_info.entity if source.type == "assembling-machine" then @@ -646,6 +672,7 @@ local function paste_network_chest_provider(dst_info, source) end end end +]] ------------------------------------------------------------------------------- @@ -854,11 +881,11 @@ GlobalState.register_service_task("network-chest", { clone=clone_network_chest, tag="requests", }) --- provider has no extra data. just filters and a bar, which is already managed. +-- provider has no extra data, filters or bar. GlobalState.register_service_task("network-chest-provider", { service=service_network_chest_provider, create=create_network_chest, - paste=paste_network_chest_provider, + -- paste=paste_network_chest_provider, }) GlobalState.register_service_task("network-chest-requester", { service=service_network_chest_requester,