diff --git a/robot-recall-fixed/README.md b/robot-recall-fixed/README.md new file mode 100644 index 00000000..0a13882d --- /dev/null +++ b/robot-recall-fixed/README.md @@ -0,0 +1,16 @@ +# robot-recall-fixed + +_n.b._: This mod was forked from [343N's robot-recall](https://mods.factorio.com/mod/robot-recall), to fix an issue with the module not loading due to a missing icon.item_size. + +This mod adds two items: + +__Robot Recall Station__ +A logistic container which lets you recall robots to it. Bots will 'teleport' there, in the same amount of time that it would take them to travel from their location. (You can't command robots to move places in world with mods, at least, not easily). This only recalls currently IDLE robots sitting in roboport inventories. Should work with any modded robots that work in roboports, tested with bobs and angels robots. + +__Robot Redeployment Station__ +A logistic container which automatically places any bots put in it. Bots will automatically move to any roboports in their vicinity. Robots will only be deployed, if at the time of deployment, there is space for it in the logistic network. This container does the equivalent of placing a bot manually as the player, on the position the container is at. + +Note: Recall progress was not saved in between sessions before version 0.1.6. That has now changed. As a result, a massive desync has also been fixed. This mod is now multiplayer safe and persistent between sessions (yay!) + +__Missing your Locale?__ +Feel free to go to the github repo and create a pull request with your own locale file and locale changes! \ No newline at end of file diff --git a/robot-recall-fixed/changelog.txt b/robot-recall-fixed/changelog.txt new file mode 100644 index 00000000..25a50cef --- /dev/null +++ b/robot-recall-fixed/changelog.txt @@ -0,0 +1,6 @@ +--------------------------------------------------------------------------------------------------- +Version: 0.2.16 +Date: 2022-06-17 + Changes: + - Forked from original by 343N + - Updated to fix incompatibility with AAI Warehousing diff --git a/robot-recall-fixed/control.lua b/robot-recall-fixed/control.lua new file mode 100644 index 00000000..2b10c7d2 --- /dev/null +++ b/robot-recall-fixed/control.lua @@ -0,0 +1,63 @@ +-- require('util') +require('control.robot-recall') +require('control.robot-redistribute') +-- require('') + +script.on_init(function(event) + global.teleportQueue = {} + global.teleportQueueEntryCount = 0 + global.hasChanged = false + global.openedGUIPlayers = {} + global.deploying = {} +end) + +script.on_configuration_changed(function(event) + if (event.mod_changes and event.mod_changes['robot-recall']) then + local old_ver = event.mod_changes['robot-recall'].old_version + if (old_ver) then + if (old_ver == "0.2.0" or string.find(old_ver, "0.1.")) then + global.teleportQueue = {} + global.teleportQueueEntryCount = 0 + end + + if (old_ver == "0.2.0" or old_ver == "0.2.1") then + global.deploying = {} + for _, surface in pairs(game.surfaces) do + local deploymentstations = + surface.find_entities_filtered( + {name = "robot-redistribute-chest"}) + for k, v in pairs(deploymentstations) do + global.deploying[v.unit_number] = + {ent = v, deploying = false} + end + end + end + if (new_ver == "0.2.1" or + new_ver == "0.2.2" or + new_ver == "0.2.3" or + string.find(old_ver, "0.1.")) then + local newTeleportQueue = {} + for k,e in pairs(global.teleportQueue) do + local newEl = e + if (newEl.source and newEl.source.valid) then + newEl.srcPos = newEl.source.position + newEl.surface = newEl.source.surface + end + if (newEl.destination and newEl.destination.valid) then + newEl.surface = newEl.destination.surface + newEl.destPos = newEl.destination.position + end + table.insert(newTeleportQueue, newEl) + end + global.teleportQueue = newTeleportQueue + global.teleportQueueEntryCount = table_size(newTeleportQueue) + end + end + end + + global.deploying = global.deploying or {} + global.teleportQueue = global.teleportQueue or {} + global.teleportQueueEntryCount = global.teleportQueueEntryCount or 0 + global.hasChanged = global.hasChanged or false + global.openedGUIPlayers = global.openedGUIPlayers or {} +end) diff --git a/robot-recall-fixed/control/robot-recall.lua b/robot-recall-fixed/control/robot-recall.lua new file mode 100644 index 00000000..4b2ff76e --- /dev/null +++ b/robot-recall-fixed/control/robot-recall.lua @@ -0,0 +1,573 @@ +function getAverage(items) + local count = 0 + local sum = 0 + for k, v in pairs(items) do + count = count + 1 + sum = sum + v + end + + return sum / count +end + +function getItemProtoFromName(n) return game.item_prototypes[n] end + +function setGUISize(element, w, h) + if (not element.style) then return end + if (w) then element.style.width = w end + if (h) then element.style.height = h end +end + +function getAllIdleRobotsInNetwork(logistic_network) + local robots = {} + if (logistic_network == nil) then return robots end + for k, cell in pairs(logistic_network.cells) do + local inv = cell.owner.get_inventory(defines.inventory.roboport_robot) + for i = 1, #inv do + local itemstack = inv[i] + if (itemstack.valid_for_read) then + if robots[itemstack.name] then + robots[itemstack.name].count = + robots[itemstack.name].count + itemstack.count + else + robots[itemstack.name] = + { + count = itemstack.count, + item = itemstack.prototype, + ent = itemstack.prototype.place_result + } + end + end + end + end + + return robots + +end + +function getDistanceBetweenVectors(a, b) + local x = a.x - b.x + local y = a.y - b.y + + return math.abs(math.sqrt((x * x) + (y * y))) +end + +function getBotsBeingRecalled(recall_chest) + local tbl = {} + for k, v in pairs(global.teleportQueue) do + if (tbl.destination == recall_chest) then + tbl[v.itemname] = + tbl[v.itemname] and tbl[v.itemname] + v.count or v.count + end + end + return tbl +end + +function addToTeleportQueue(source, destination, itemstack) + + local currentTick = game.tick + local destinationInv = destination.get_inventory(defines.inventory.chest) + local dist = + getDistanceBetweenVectors(source.position, destination.position) + + local robotEnt = itemstack.prototype.place_result + local unitsPerTick = (source["force"]["worker_robots_speed_modifier"] + 1) * robotEnt.speed * settings.global["recall-speed-modifier"].value + local can_insert = destinationInv.can_insert(itemstack) + + -- game.print("" .. itemstack.count .. " " .. itemstack.name .. + -- "to teleport queue") + + if (not can_insert) then return end + -- game.print("Can't recall, no space!") + local item_name = itemstack.prototype.name + local queueEntry = { + source = source, + srcPos = source.position, + destination = destination, + destPos = destination.position, + startTick = currentTick, + endTick = math.abs(currentTick + (dist / unitsPerTick)), + -- itemstack = itemstack, + itemname = item_name, + surface = destination.surface, + count = itemstack.count + } + table.insert(global.teleportQueue, queueEntry) + itemstack.clear() + global.teleportQueueEntryCount = global.teleportQueueEntryCount + 1 + -- local timeTo + +end + +function buildRecallGui(baseGUI, entity) + if (not entity) then return end + if (entity.name ~= 'robot-recall-chest') then return end + local logistic_network = entity.logistic_network + if (baseGUI['robot-recall-chest'] ~= nil) then + baseGUI['robot-recall-chest'].destroy() + end + + local recallFrame = baseGUI.add({ + type = "frame", + name = "robot-recall-chest", + direction = "vertical", + -- style="standalone_inner_frame_in_outer_frame" + }) + recallFrame.caption = {'robot-recall.chest-title'} + -- ply.opened = recallFrame + -- this is for vanilla at 1x scale + local INV_DIMENSIONS = {width = 874, height = 436, verticalOffset = -88} + local WIDTH = 300 + local HEIGHT = INV_DIMENSIONS.height + local recallScrollFlowFrame = recallFrame.add( + { + type = "frame", + name = "frame", + style = "inside_shallow_frame", + direction = "vertical" + }) + local recallScrollFlow = recallScrollFlowFrame.add { + type = "scroll-pane", + name = "scrollpane" + } + + setGUISize(recallFrame, WIDTH, HEIGHT) + setGUISize(recallScrollFlow, WIDTH - 20, HEIGHT - 50) + -- game.print(ply.gui) + local ply = game.players[baseGUI.player_index] + local res = ply.display_resolution + local scl = ply.display_scale + global.openedGUIPlayers[baseGUI.player_index] = + {ply = game.players[baseGUI.player_index], ent = entity} + recallFrame.location = { + (res.width / 2) - (INV_DIMENSIONS.width * scl * 0.5) - WIDTH * scl, + (res.height / 2) - (INV_DIMENSIONS.height / 2 * scl) + + (INV_DIMENSIONS.verticalOffset * scl) + } + + local robots = getAllIdleRobotsInNetwork(logistic_network) + updateRecallGuiList(baseGUI, robots, logistic_network) +end + +function updateRecallGuiListEntry(itemname, count, baseGui) + local scrollPane = baseGui['robot-recall-chest']['frame']['scrollpane'] + local ply = game.players[baseGui.player_index] + local flow = + baseGui['robot-recall-chest']['frame']['scrollpane'][itemname] or + scrollPane.add({type = "flow", name = itemname}) + local spritebutton = flow['spritebutton'] or flow.add( + { + type = "sprite-button", + tooltip = { + "robot-recall.recall-button-tooltip", getItemProtoFromName(itemname).localised_name + }, + name = "spritebutton" + }) + + if (spritebutton.sprite == "") then + spritebutton.sprite = "item/" .. itemname + end + + local progressbar = + baseGui['robot-recall-chest']['frame']['scrollpane'][itemname .. '-progressbar'] or + scrollPane.add({ + type = "progressbar", + name = itemname .. '-progressbar', + visible = false, + value = 0 + }) + + if (ply.opened and ply.opened.name == "robot-recall-chest") then + if (ply.opened.get_inventory(defines.inventory.chest).can_insert( + {name = itemname})) then + spritebutton.enabled = true + else + spritebutton.enabled = false + end + end + + local label = flow['label'] or flow.add({type = "label", name = "label"}) + label.caption = {"robot-recall.recall-count", getItemProtoFromName(itemname).localised_name, count} + label.style.single_line = false + +end + +function updateRecallGuiList(baseGui, robots, logistic_network) + local scrollPane = baseGui['robot-recall-chest']['frame']['scrollpane'] + local ply = game.players[baseGui.player_index] + if (logistic_network == nil or not logistic_network.valid) then + local label = scrollPane['no-network'] or scrollPane.add( + { + type = "label", + caption = {"robot-recall.chest-no-network", ":("}, + name = "no-network" + }) + label.style.horizontal_align = "center" + label.style.width = scrollPane.style.maximal_width - 10 + return + end + if (scrollPane['no-network'] and scrollPane['no-network'].valid) then + scrollPane['no-network'].destroy() + end + local count = 0 + local recalled = getBotsBeingRecalled() + for k, v in pairs(recalled) do + if (robots[k]) then + robots[k].count = robots[k].count + v + else + robots[k] = { + count = v, + item = getItemProtoFromName(k), + ent = getItemProtoFromName(k).place_result + } + end + end + for k, v in pairs(robots) do updateRecallGuiListEntry(k, v.count, baseGui) end + + local count = table_size(robots) + if (count * 2 ~= table_size(scrollPane)) then + for k, v in pairs(baseGui['robot-recall-chest']['frame']['scrollpane'] + .children) do + if (v.valid and v.type == "flow" and not robots[v.name]) then + local progress = + baseGui['robot-recall-chest']['frame']['scrollpane'][v.name .. + '-progressbar'] + v.destroy() + progress.destroy() + -- baseGui['robot-recall-chest']['frame']['scrollpane'][k..'-progressbar'].destroy() + end + end + end + + if (count == 0 and not scrollPane['no-robots-label']) then + local label = scrollPane.add({ + type = "label", + caption = {'robot-recall.chest-no-robot-in-roboport', ":("}, + name = "no-robots-label" + }) + -- baseGUI.style.height + label.style.single_line = false + label.style.horizontal_align = 'center' + label.style.width = scrollPane.style.maximal_width - 10 + return + elseif (count > 0 and scrollPane['no-robots-label'] and + scrollPane['no-robots-label'].valid) then + scrollPane['no-robots-label'].destroy() + end + -- if (scrollPane['no-robots-label']) then + -- game.print(scrollPane['no-robots-label'].valid) + -- end +end + +function updateRecallGuiListProgress(baseGui, robots, logistic_network) + if (not baseGui or not baseGui['robot-recall-chest']) then return end + + local scrollPane = baseGui['robot-recall-chest']['frame']['scrollpane'] + local ply = game.players[baseGui.player_index] + for _, element in pairs(scrollPane.children) do + if (element.type == "progressbar") then + local progressbar = element + local itemname = string.sub(element.name, 0, + -1 - string.len("-progressbar")) + local totalProgress = {} + for k, v in pairs(global.teleportQueue) do + -- if (global.teleportQueue.destination) then + -- end + + if (v.destination and v.destination.valid and ply.opened and + ply.opened.valid and v.destination.unit_number == + ply.opened.unit_number and v.itemname == itemname) then + local currentTick = game.tick - v.startTick + local finishTick = v.endTick - v.startTick + -- game.print("TELEPORT QUEUE LOl") + table.insert(totalProgress, currentTick / finishTick) + end + end + if (table_size(totalProgress) ~= 0) then + progressbar.visible = true + local newprog = getAverage(totalProgress) + progressbar.value = math.max(newprog, progressbar.value) + else + progressbar.visible = false + progressbar.value = 0 + -- local robots = getAllIdleRobotsInNetwork(ply.opened.ent) + -- updateRecallGuiList(v.ply.gui.screen, robots, v.ent.logistic_network) + end + + end + end + +end + +function createRobotRecallGUI(ent, ply, gui) + -- if (not (ent and ent.name == "robot-recall-chest")) then return end + if (gui['robot-recall-chest'] ~= nil) then + gui['robot-recall-chest'].destroy() + end + local recallFrame = gui.add({ + type = "frame", + name = "robot-recall-chest", + direction = "vertical" + }) + recallFrame.caption = {'robot-recall.chest-title'} + -- ply.opened = recallFrame + -- this is for vanilla at 1x scale + local INV_DIMENSIONS = {width = 874, height = 436, verticalOffset = -88} + local WIDTH = 300 + local HEIGHT = INV_DIMENSIONS.height + local recallScrollFlowFrame = recallFrame.add( + { + type = "frame", + name = "frame", + style = "inside_shallow_frame_with_padding", + direction = "vertical" + }) + local recallScrollFlow = recallScrollFlowFrame.add { + type = "scroll-pane", + name = "scrollpane" + } + + setGUISize(recallFrame, WIDTH, HEIGHT) + setGUISize(recallScrollFlow, WIDTH - 20, HEIGHT - 50) + -- game.print(ply.gui) + local res = ply.display_resolution + local scl = ply.display_scale + + recallFrame.location = { + (res.width / 2) - (INV_DIMENSIONS.width * scl * 0.5) - WIDTH * scl, + (res.height / 2) - (INV_DIMENSIONS.height / 2 * scl) + + (INV_DIMENSIONS.verticalOffset * scl) + } + + -- if (ent and ent.logistic_network) then + -- -- game.print(ent.logistic_network.robots) + -- -- recallFrame.direction = "vertical" + -- -- drawRobotRecallGui(recallScrollFlow, ent.logistic_network) + -- end +end + +function callRobotsToEntity(location_ent, logisticNetwork, robotItem) + + for k, cell in pairs(logisticNetwork.cells) do + local roboport = cell.owner + local inv = roboport.get_inventory(defines.inventory.roboport_robot) + for i = 1, #inv do + local itemstack = inv[i] + if (itemstack.valid_for_read) then + if (itemstack.prototype == robotItem) then + addToTeleportQueue(roboport, location_ent, itemstack) + end + end + end + end +end + +function updateTeleportJobs(event) + local warning = false + for k, e in ipairs(global.teleportQueue) do + -- if (not itemstack.valid) + if ((not e.destination or not e.destination.valid)) then + -- game.print("Source or destination not valid! Removing queue item!") + + local count + if (not warning) then + -- if (__DebugAdapter) then __DebugAdapter.print("Hello!") end + game.print("Robot Recall Chest cannot be found! Robots have been returned to their source position.") + warning = true + end + if (e.source.valid) then count = e.source.insert({name=e.itemname, count=e.count}) end + if (not count or count ~= e.count) then + count = count and (e.count - count) or e.count + e.surface.spill_item_stack(e.srcPos, {name=e.itemname, count=count}) + game.print(count .. " robots have been dropped at their source position, there is no room in the source.") + end + + + global.teleportQueue[k] = nil + global.teleportQueueEntryCount = global.teleportQueueEntryCount - 1 + + end + if (event.tick >= e.endTick) then + -- game.print("Teleport job finished!") + + -- if () then return end + local destinationInv = e.destination.get_inventory( + defines.inventory.roboport_robot) or + e.destination.get_inventory( + defines.inventory.chest) + local sourceInv = e.source.get_inventory( + defines.inventory.roboport_robot) or + e.source + .get_inventory(defines.inventory.chest) + + -- if (destinationInv.can_insert({name = e.itemname, count = e.count})) then + local amnt = destinationInv.insert({name = e.itemname, count = e.count}) + if (amnt ~= e.count) then + local initialRemainder = e.count - amnt + local remainder = e.count - amnt + remainder = remainder - sourceInv.insert({name = e.itemname, count = remainder}) + if (remainder ~= 0) then + game.print("Recall of " .. e.count .. " '" .. e.itemname .. + "' robots has (partially) failed. " .. remainder .. ' could not be recalled.') + if (e.destination.logistic_network and + e.destination.logistic_network.valid) then + for _, cell in + pairs(e.destination.logistic_network.cells) do + if (remainder ~= 0) then + local inv = + cell.owner.get_inventory( + defines.inventory.roboport_robot) + remainder = + remainder - + inv.insert({name = e.itemname, count = remainder}) + end + end + if (remainder ~= initialRemainder) then + -- game.print("Recall of " .. e.count .. " " .. e.itemname .. " has failed.") + game.print( + (initialRemainder - remainder) .. + " robots have been redeployed to roboports") + end + end + + if (remainder ~= 0) then + game.print(remainder .. " robots have been dropped in front of the recall station.") + local ent = + e.destination.surface.spill_item_stack(e.destination.position, + {name = e.itemname, count = remainder}) + -- game.print(ent.position) + + end + + end + + end + -- end + + -- for _, v in pairs(global.openedGUIPlayers) do + -- -- getAllIdleRobotsInNetwork(p.ply.opened) + -- -- local robots = getAllIdleRobotsInNetwork(v.ent.logistic_network) + -- -- updateRecallGuiList(v.ply.gui.screen, robots, v.ent.logistic_network) + -- end + table.remove(global.teleportQueue, k) + global.teleportQueueEntryCount = global.teleportQueueEntryCount - 1 + end + end +end + +function initRecallChest(event) end + +script.on_event({defines.events.on_built_entity}, function(event) + -- game.print("Hello!") + if (event.created_entity and event.created_entity.name == + "robot-recall-chest") then initRecallChest(event) end +end) + +script.on_event({defines.events.on_robot_built_entity}, function(event) + if (event.created_entity and event.created_entity.name == + "robot-recall-chest") then initRecallChest(event) end +end) + +script.on_event({defines.events.on_gui_opened}, function(event) + local ent = event.entity + local ply = game.players[event.player_index] + local gui = ply.gui.screen + buildRecallGui(gui, ent) + -- recallFrame.add({}) + + -- local closeButton = recallFrame.add({type="button",name="robot-recall-chest.close", caption="Close!"}) + +end) + +script.on_event({defines.events.on_gui_closed}, function(event) + local ent = event.entity + local ply = game.players[event.player_index] + local gui = ply.gui.screen + if (gui['robot-recall-chest'] ~= nil) then + if (global.openedGUIPlayers[event.player_index]) then + table.remove(global.openedGUIPlayers, event.player_index) + end + gui['robot-recall-chest'].destroy() + end + -- game.print('on_gui_close') +end) + +script.on_event({defines.events.on_gui_click}, function(event) + -- game.print(event) + local ply = game.players[event.player_index] + -- local items = game.item_prototypes + + if (event.element.type == "sprite-button" and ply.opened and ply.opened.name == + "robot-recall-chest") then + local itemname = event.element.parent.name + local item = game.item_prototypes[itemname] + -- game.print('recalling "' .. itemname .. '"') + callRobotsToEntity(ply.opened, ply.opened.logistic_network, item, + event.tick) + + end + + if (event.element.name == "robot-recall-chest.close") then + event.element.parent.destroy() + end +end) + +-- script.on_nth_tick(10, function(event) +-- if (event.tick % 5 == 0) then +-- for k, v in pairs(game.players) do +-- -- local = v.gui.screen +-- local gui = v.gui.screen +-- updateRecallGui(event, gui, v) +-- end +-- end +-- end) +-- script.on_event({defines.events.on_tick}, function(event) +-- if (global.teleportQueueEntryCount > 0) then +-- for k, v in pairs(global.openedGUIPlayers) do +-- -- local = v.gui.screen +-- local gui = v.ply.gui.screen +-- -- __DebugAdapter.print("Updating every tick!") +-- if (v.ent.logistic_network and v.ent.logistic_network.valid) then +-- local robots = getAllIdleRobotsInNetwork(v.ent.logistic_network) +-- updateRecallGuiList(v.ply.gui.screen, robots, +-- v.ent.logistic_network) +-- end +-- end +-- end +-- end) + +script.on_nth_tick(2, function(event) + if (not global.teleportQueueEntryCount or not global.teleportQueue) then return end + if (global.teleportQueueEntryCount == 0 and global.hasChanged) then + global.hasChanged = false + for k, v in pairs(global.openedGUIPlayers) do + updateRecallGuiListProgress(v.ply.gui.screen) + end + elseif (global.teleportQueueEntryCount > 0) then + global.hasChanged = true + for k, v in pairs(global.openedGUIPlayers) do + updateRecallGuiListProgress(v.ply.gui.screen) + end + end + +end) + +script.on_nth_tick(10, function(event) + -- if (not global.teleportQueueEntryCount + if (global.teleportQueueEntryCount and global.teleportQueueEntryCount > 0) then updateTeleportJobs(event) end +end) + +script.on_nth_tick(180, function(event) + for k, v in pairs(global.openedGUIPlayers) do + -- __DebugAdapter.print("Updating every 10 ticks!") + + -- local = v.gui.screen + local gui = v.ply.gui.screen + if (v.ent.logistic_network and v.ent.logistic_network.valid) then + local robots = getAllIdleRobotsInNetwork(v.ent.logistic_network) + updateRecallGuiList(v.ply.gui.screen, robots, v.ent.logistic_network) + end + end + -- end +end) + + diff --git a/robot-recall-fixed/control/robot-redistribute.lua b/robot-recall-fixed/control/robot-redistribute.lua new file mode 100644 index 00000000..b951d83f --- /dev/null +++ b/robot-recall-fixed/control/robot-redistribute.lua @@ -0,0 +1,79 @@ +script.on_nth_tick(15, function(event) + for k, v in pairs(global.deploying) do + if (v.deploying and v.ent.valid) then + local inv = v.ent.get_inventory(1) + if (not inv.is_empty()) then + local items = inv.get_contents() + for name, count in pairs(items) do + local placeresult = game.item_prototypes[name].place_result + if (placeresult.type == "logistic-robot" or placeresult.type == + "construction-robot") then + if (logisticNetworkHasItemSpace(v.ent.logistic_network, name)) then + v.ent.surface.create_entity( + { + name = placeresult.name, + position = v.ent.position, + force = v.ent.logistic_network.force + }) + inv.remove({name = name, count = 1}) + end + end + + end + end + end + end +end) + +script.on_event(defines.events.on_built_entity, function(event) + + if (event.created_entity.name == "robot-redistribute-chest") then + local entity = event.created_entity + global.deploying[entity.unit_number] = {ent = entity, deploying = false} + end + +end) + +script.on_event(defines.events.on_robot_built_entity, function(event) + + if (event.created_entity.name == "robot-redistribute-chest") then + local entity = event.created_entity + global.deploying[entity.unit_number] = {ent = entity, deploying = false} + end + +end) + +-- function canInsertIntoRoboport(itemname, logistic_network) +-- -- local roboport = +-- if (logistic_network and logistic_network.valid) then +-- for k, v in pairs(logistic_network.cells) do +-- local inv = cell.owner.get_inventory( +-- defines.inventory.roboport_robot) +-- if (inv and inv.can_insert({name = itemname, count = 1})) then +-- return true +-- end +-- end +-- end +-- return false +-- end + +function logisticNetworkHasItemSpace(logistic_network, itemname) + if (logistic_network and logistic_network.valid) then + for k, v in pairs(logistic_network.cells) do + local inv = v.owner.get_inventory(defines.inventory.roboport_robot) + if (inv and inv.can_insert({name = itemname, count = 1})) then + return true + end + end + end + return false +end + +script.on_nth_tick(60, function(event) + for k, v in pairs(global.deploying) do + if (v.ent and not v.ent.valid) then table.remove(global.deploying, k) + elseif (v.ent and not v.ent.get_inventory(1).is_empty()) then v.deploying = true + else v.deploying = false end + end + +end) diff --git a/robot-recall-fixed/data-final-fixes.lua b/robot-recall-fixed/data-final-fixes.lua new file mode 100644 index 00000000..5b2b4ac0 --- /dev/null +++ b/robot-recall-fixed/data-final-fixes.lua @@ -0,0 +1 @@ +-- data.raw.recipe["logistic-chest-requester"].ingredients \ No newline at end of file diff --git a/robot-recall-fixed/data.lua b/robot-recall-fixed/data.lua new file mode 100644 index 00000000..bcb27501 --- /dev/null +++ b/robot-recall-fixed/data.lua @@ -0,0 +1,2 @@ +require('prototypes.robot-recall') +require('prototypes.robot-redistribute') \ No newline at end of file diff --git a/robot-recall-fixed/graphics/entity/hr-robot-recall-chest.png b/robot-recall-fixed/graphics/entity/hr-robot-recall-chest.png new file mode 100644 index 00000000..4e5214c1 Binary files /dev/null and b/robot-recall-fixed/graphics/entity/hr-robot-recall-chest.png differ diff --git a/robot-recall-fixed/graphics/entity/hr-robot-redistribute-chest.png b/robot-recall-fixed/graphics/entity/hr-robot-redistribute-chest.png new file mode 100644 index 00000000..66df27a5 Binary files /dev/null and b/robot-recall-fixed/graphics/entity/hr-robot-redistribute-chest.png differ diff --git a/robot-recall-fixed/graphics/entity/robot-recall-chest.png b/robot-recall-fixed/graphics/entity/robot-recall-chest.png new file mode 100644 index 00000000..cb370c16 Binary files /dev/null and b/robot-recall-fixed/graphics/entity/robot-recall-chest.png differ diff --git a/robot-recall-fixed/graphics/entity/robot-redistribute-chest.png b/robot-recall-fixed/graphics/entity/robot-redistribute-chest.png new file mode 100644 index 00000000..d5d5b038 Binary files /dev/null and b/robot-recall-fixed/graphics/entity/robot-redistribute-chest.png differ diff --git a/robot-recall-fixed/graphics/icons/robot-recall-chest.png b/robot-recall-fixed/graphics/icons/robot-recall-chest.png new file mode 100644 index 00000000..5bc7b67b Binary files /dev/null and b/robot-recall-fixed/graphics/icons/robot-recall-chest.png differ diff --git a/robot-recall-fixed/graphics/icons/robot-redistribute-chest.png b/robot-recall-fixed/graphics/icons/robot-redistribute-chest.png new file mode 100644 index 00000000..a598c01c Binary files /dev/null and b/robot-recall-fixed/graphics/icons/robot-redistribute-chest.png differ diff --git a/robot-recall-fixed/info.json b/robot-recall-fixed/info.json new file mode 100644 index 00000000..4491fb77 --- /dev/null +++ b/robot-recall-fixed/info.json @@ -0,0 +1,9 @@ +{ + "name": "robot-recall-fixed", + "version": "0.2.17", + "title": "Robot Recall, fixed", + "author": "uliet", + "factorio_version": "1.1", + "dependencies": ["base >= 1.1.38", "! robot-recall"], + "description": "Lets you recall all robots in your network. Forked from 343N's 0.2.15 version." +} \ No newline at end of file diff --git a/robot-recall-fixed/locale/en/config.cfg b/robot-recall-fixed/locale/en/config.cfg new file mode 100644 index 00000000..30dd3986 --- /dev/null +++ b/robot-recall-fixed/locale/en/config.cfg @@ -0,0 +1,26 @@ +[entity-name] +robot-recall-chest=Robot Recall Station +robot-redistribute-chest=Robot Deployment Station + +[item-name] +robot-recall-chest=Robot Recall Station +robot-redistribute-chest=Robot Deployment Station + +[item-description] +robot-recall-chest=A station that lets you call any robots in your network to it (to be decommissioned) +robot-redistribute-chest=A station that deploys robots into your network + +[mod-setting-name] +recall-speed-modifier=Recall Station recall speed modifier +recall-chest-size=Recall Station inventory size + +[mod-setting-description] +recall-speed-modifier=Sets the speed at which robots are recalled. \nBase speed is 1 (2 is twice as fast, 0.5 is half speed). \nMin: 0.1, Max: 100, Default: 1. +recall-chest-size=Sets the recall station inventory size.\nMin: 1, Max: 320, Default: 40. + +[robot-recall] +chest-title=Recall Robots +recall-button-tooltip=Recall __1__ +chest-no-network=This is not apart of a logistics network! __1__ +chest-no-robot-in-roboport=There are no robots in this network's roboports! __1__ +recall-count=__1__\nCount: __2__ \ No newline at end of file diff --git a/robot-recall-fixed/prototypes/robot-recall.lua b/robot-recall-fixed/prototypes/robot-recall.lua new file mode 100644 index 00000000..3a59f5bd --- /dev/null +++ b/robot-recall-fixed/prototypes/robot-recall.lua @@ -0,0 +1,104 @@ +-- local entity = table.deepcopy(data.raw["logistic-container"]["logistic-chest-requester"]) + + +local entity = {} +local baseEnt = data.raw["logistic-container"]["logistic-chest-passive-provider"] + +entity.name = "robot-recall-chest" +entity.order = "logistic-container" +entity.minable = { mining_time = 0.1, result = "robot-recall-chest" } +entity.logistic_mode = "passive-provider" +entity.inventory_size = settings.startup["recall-chest-size"].value +entity.icon_size = 64 +entity.health = 350 +entity.icon_mipmaps = 4 +entity.icon = "__robot-recall-fixed__/graphics/icons/robot-recall-chest.png" +entity.open_sound = { filename = "__base__/sound/metallic-chest-open.ogg", volume=0.5 } +entity.close_sound = { filename = "__base__/sound/metallic-chest-close.ogg", volume = 0.5 } +entity.animation_sound = baseEnt.animation_sound +entity.vehicle_impact_sound = baseEnt.vehicle_impact_sound +entity.opened_duration = baseEnt.opened_duration +entity.collision_box = {{-0.35, -0.35}, {0.35, 0.35}} +entity.selection_box = {{-0.5, -0.5}, {0.5, 0.5}} +entity.damaged_trigger_effect = baseEnt.damaged_trigger_effect +entity.type = "logistic-container" +entity.animation = + { + layers = + { + { + filename = "__robot-recall-fixed__/graphics/entity/robot-recall-chest.png", + priority = "extra-high", + width = 34, + height = 38, + frame_count = 7, + shift = util.by_pixel(0, -2), + hr_version = + { + filename = "__robot-recall-fixed__/graphics/entity/hr-robot-recall-chest.png", + priority = "extra-high", + width = 66, + height = 74, + frame_count = 7, + shift = util.by_pixel(0, -2), + scale = 0.5 + } + }, + { + filename = "__base__/graphics/entity/logistic-chest/logistic-chest-shadow.png", + priority = "extra-high", + width = 48, + height = 24, + repeat_count = 7, + shift = util.by_pixel(8.5, 5.5), + draw_as_shadow = true, + hr_version = + { + filename = "__base__/graphics/entity/logistic-chest/hr-logistic-chest-shadow.png", + priority = "extra-high", + width = 96, + height = 44, + repeat_count = 7, + shift = util.by_pixel(8.5, 5), + draw_as_shadow = true, + scale = 0.5 + } + } + } + } + +entity.picture = entity.animation +entity.circuit_wire_connection_point = circuit_connector_definitions["chest"].points +entity.circuit_connector_sprites = circuit_connector_definitions["chest"].sprites +entity.circuit_wire_max_distance = default_circuit_wire_max_distance +entity.flags = {"placeable-player", "player-creation"} + + + + + +local item = table.deepcopy(data.raw.item["logistic-chest-requester"]) +item.name = "robot-recall-chest" +-- item.entity = "robot-recall-chest" +item.place_result = "robot-recall-chest" +item.icon_size = 64 +item.icons = { + { + icon = "__robot-recall-fixed__/graphics/icons/robot-recall-chest.png" + -- tint = { r = 0.5, g = 0.5, b = 0.5, a = 1} + }, +} + +local recipe = table.deepcopy(data.raw.recipe["logistic-chest-requester"]) +recipe.enabled = false; +recipe.name = "robot-recall-chest" +recipe.result = "robot-recall-chest" + +table.insert(data.raw["technology"]["construction-robotics"].effects, {type="unlock-recipe", recipe="robot-recall-chest"}) +table.insert(data.raw["technology"]["logistic-robotics"].effects, {type="unlock-recipe", recipe="robot-recall-chest"}) + + +if __DebugAdapter then + local variables = require("__debugadapter__/variables.lua") +end +data:extend{item, entity, recipe} \ No newline at end of file diff --git a/robot-recall-fixed/prototypes/robot-redistribute.lua b/robot-recall-fixed/prototypes/robot-redistribute.lua new file mode 100644 index 00000000..4d0f0149 --- /dev/null +++ b/robot-recall-fixed/prototypes/robot-redistribute.lua @@ -0,0 +1,107 @@ +-- local entity = table.deepcopy(data.raw["logistic-container"]["logistic-chest-requester"]) + + +local entity = {} +local baseEnt = data.raw["logistic-container"]["logistic-chest-passive-provider"] + +entity.name = "robot-redistribute-chest" +entity.order = "logistic-container" +entity.minable = { mining_time = 0.1, result = "robot-redistribute-chest" } +entity.logistic_mode = "requester" +entity.inventory_size = 40 +entity.logistic_slots_count = 40 +entity.icon_size = 64 +entity.health = 350 +entity.icon = "__robot-recall-fixed__/graphics/icons/robot-redistribute-chest.png" +entity.icon_mipmaps = 4 +entity.open_sound = { filename = "__base__/sound/metallic-chest-open.ogg", volume=0.5 } +entity.close_sound = { filename = "__base__/sound/metallic-chest-close.ogg", volume = 0.5 } +entity.animation_sound = baseEnt.animation_sound +entity.vehicle_impact_sound = baseEnt.vehicle_impact_sound +entity.opened_duration = baseEnt.opened_duration +entity.collision_box = {{-0.35, -0.35}, {0.35, 0.35}} +entity.selection_box = {{-0.5, -0.5}, {0.5, 0.5}} +entity.damaged_trigger_effect = baseEnt.damaged_trigger_effect +entity.type = "logistic-container" +entity.animation = + { + layers = + { + { + filename = "__robot-recall-fixed__/graphics/entity/robot-redistribute-chest.png", + priority = "extra-high", + width = 34, + height = 38, + frame_count = 7, + shift = util.by_pixel(0, -2), + hr_version = + { + filename = "__robot-recall-fixed__/graphics/entity/hr-robot-redistribute-chest.png", + priority = "extra-high", + width = 66, + height = 74, + frame_count = 7, + shift = util.by_pixel(0, -2), + scale = 0.5 + } + }, + { + filename = "__base__/graphics/entity/logistic-chest/logistic-chest-shadow.png", + priority = "extra-high", + width = 48, + height = 24, + repeat_count = 7, + shift = util.by_pixel(8.5, 5.5), + draw_as_shadow = true, + hr_version = + { + filename = "__base__/graphics/entity/logistic-chest/hr-logistic-chest-shadow.png", + priority = "extra-high", + width = 96, + height = 44, + repeat_count = 7, + shift = util.by_pixel(8.5, 5), + draw_as_shadow = true, + scale = 0.5 + } + } + } + } + +entity.picture = entity.animation +entity.circuit_wire_connection_point = circuit_connector_definitions["chest"].points +entity.circuit_connector_sprites = circuit_connector_definitions["chest"].sprites +entity.circuit_wire_max_distance = default_circuit_wire_max_distance +entity.flags = {"placeable-player", "player-creation"} + + + + + +local item = table.deepcopy(data.raw.item["logistic-chest-requester"]) +item.name = "robot-redistribute-chest" +-- item.entity = "robot-redistribute-chest" +item.place_result = "robot-redistribute-chest" +item.icon_size = 64 +item.icons = { + { + icon = "__robot-recall-fixed__/graphics/icons/robot-redistribute-chest.png" + -- tint = { r = 0.5, g = 0.5, b = 0.5, a = 1} + }, +} + +local recipe = table.deepcopy(data.raw.recipe["logistic-chest-requester"]) +recipe.enabled = false; +recipe.name = "robot-redistribute-chest" +recipe.result = "robot-redistribute-chest" + +table.insert(data.raw["technology"]["construction-robotics"].effects, {type="unlock-recipe", recipe="robot-redistribute-chest"}) +table.insert(data.raw["technology"]["logistic-robotics"].effects, {type="unlock-recipe", recipe="robot-redistribute-chest"}) + + +if __DebugAdapter then + local variables = require("__debugadapter__/variables.lua") + + -- prepare debug metatables here +end +data:extend{item, entity, recipe} \ No newline at end of file diff --git a/robot-recall-fixed/settings.lua b/robot-recall-fixed/settings.lua new file mode 100644 index 00000000..bdf58524 --- /dev/null +++ b/robot-recall-fixed/settings.lua @@ -0,0 +1,19 @@ +data:extend({ + { + name = "recall-speed-modifier", + type = "double-setting", + setting_type = "runtime-global", + default_value = 1, + minimum_value = 0.1, + maximum_value = 100 + }, + + { + name = "recall-chest-size", + type = "int-setting", + setting_type = "startup", + default_value = 40, + minimum_value = 1, + maximum_value = 320 + } +}) \ No newline at end of file diff --git a/robot-recall-fixed/thumbnail.png b/robot-recall-fixed/thumbnail.png new file mode 100644 index 00000000..a5dd634b Binary files /dev/null and b/robot-recall-fixed/thumbnail.png differ diff --git a/robot-recall-fixed/util.lua b/robot-recall-fixed/util.lua new file mode 100644 index 00000000..e69de29b