This commit is contained in:
Aleksei-bird 2025-07-13 14:57:26 +03:00
commit edfa234e56
20 changed files with 1005 additions and 0 deletions

View File

@ -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!

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -0,0 +1 @@
-- data.raw.recipe["logistic-chest-requester"].ingredients

View File

@ -0,0 +1,2 @@
require('prototypes.robot-recall')
require('prototypes.robot-redistribute')

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -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."
}

View File

@ -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__

View File

@ -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}

View File

@ -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}

View File

@ -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
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File