From 062982a887e3f8766dc8cdc82dfce34249f129e6 Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 14:38:13 -0500 Subject: [PATCH 01/10] Added support for drills with multiple resource types When checking a drill for remaining resources, check for resources matching any of that drill's compatible types. --- autodeconstruct.lua | 68 ++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index bf1dd41..4a265ea 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -1,21 +1,38 @@ require "util" autodeconstruct = {} -local function find_resources(surface, position, range, resource_category) - local resource_category = resource_category or 'basic-solid' - local top_left = {x = position.x - range, y = position.y - range} - local bottom_right = {x = position.x + range, y = position.y + range} - - local resources = surface.find_entities_filtered{area={top_left, bottom_right}, type='resource'} - local categorized = {} - - for _, resource in pairs(resources) do - if resource.prototype.resource_category == resource_category then - table.insert(categorized, resource) +local function map_to_string(t) + local s = "{" + for k,_ in pairs(t) do + s = s..tostring(k).."," + end + s = s.."}" + return s +end + + +local function has_resources(drill) + local resource_categories = drill.prototype.resource_categories + local position = drill.position + local range = drill.prototype.mining_drill_radius + if resource_categories then + local top_left = {x = position.x - range, y = position.y - range} + local bottom_right = {x = position.x + range, y = position.y + range} + + local resources = drill.surface.find_entities_filtered{area={top_left, bottom_right}, type='resource'} + if global.debug then msg_all("found "..#resources.." resources near "..util.positiontostr(drill.position)..", checking for types "..map_to_string(resource_categories)) end + + for _, resource in pairs(resources) do + if resource_categories[resource.prototype.resource_category] and + resource.amount > 0 then + if global.debug then msg_all("drill still mining "..resource.name.." at "..util.positiontostr(resource.position)) end + return true + else + if global.debug then msg_all("drill can't mine "..resource.name.." at "..util.positiontostr(resource.position)) end + end end end - - return categorized + return false end local function find_all_entities(entity_type) @@ -84,14 +101,14 @@ local function find_drills(entity) local bottom_right = {x = position.x + global.max_radius, y = position.y + global.max_radius} local entities = {} - local targeting = {} - + local entities = surface.find_entities_filtered{area={top_left, bottom_right}, type='mining-drill'} if global.debug then msg_all({"autodeconstruct-debug", "found " .. #entities .. " drills"}) end - for i = 1, #entities do - if math.abs(entities[i].position.x - position.x) < entities[i].prototype.mining_drill_radius and math.abs(entities[i].position.y - position.y) < entities[i].prototype.mining_drill_radius then - autodeconstruct.check_drill(entities[i]) + for _, e in pairs(entities) do + if (math.abs(e.position.x - position.x) < e.prototype.mining_drill_radius and + math.abs(e.position.y - position.y) < e.prototype.mining_drill_radius) then + autodeconstruct.check_drill(e) end end end @@ -112,7 +129,7 @@ function autodeconstruct.init_globals() end function autodeconstruct.on_resource_depleted(event) - if event.entity.prototype.resource_category ~= 'basic-solid' or event.entity.prototype.infinite_resource ~= false then + if event.entity.prototype.infinite_resource then if global.debug then msg_all({"autodeconstruct-debug", "on_resource_depleted", game.tick .. " amount " .. event.entity.amount .. " resource_category " .. event.entity.prototype.resource_category .. " infinite_resource " .. (event.entity.prototype.infinite_resource == true and "true" or "false" )}) end return end @@ -126,20 +143,15 @@ function autodeconstruct.check_drill(drill) end local mining_drill_radius = drill.prototype.mining_drill_radius + if mining_drill_radius == nil then return end if mining_drill_radius > global.max_radius then global.max_radius = mining_drill_radius end - if mining_drill_radius == nil then return end - - local resources = find_resources(drill.surface, drill.position, mining_drill_radius, 'basic-solid') - for i = 1, #resources do - if resources[i].amount > 0 then return end + if not has_resources(drill) then + if global.debug then msg_all({"autodeconstruct-debug", util.positiontostr(drill.position) .. " found no compatible resources, deconstructing"}) end + autodeconstruct.order_deconstruction(drill) end - - if global.debug then msg_all({"autodeconstruct-debug", util.positiontostr(drill.position) .. " found no resources, deconstructing"}) end - - autodeconstruct.order_deconstruction(drill) end function autodeconstruct.on_cancelled_deconstruction(event) From ac81f23efaf6eba30ba65bf5e9666f65c4ef63ba Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 15:15:18 -0500 Subject: [PATCH 02/10] Remove empty fluid miners when setting changed Re-scan for depleted miners when fluid miner setting is newly enabled. Improve debug prints for resource types. --- autodeconstruct.lua | 11 +++++++---- control.lua | 8 ++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index 4a265ea..073b3e7 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -23,10 +23,13 @@ local function has_resources(drill) if global.debug then msg_all("found "..#resources.." resources near "..util.positiontostr(drill.position)..", checking for types "..map_to_string(resource_categories)) end for _, resource in pairs(resources) do - if resource_categories[resource.prototype.resource_category] and - resource.amount > 0 then - if global.debug then msg_all("drill still mining "..resource.name.." at "..util.positiontostr(resource.position)) end - return true + if resource_categories[resource.prototype.resource_category] then + if resource.amount > 0 then + if global.debug then msg_all("drill still mining "..resource.name.." at "..util.positiontostr(resource.position)) end + return true + else + if global.debug then msg_all("drill finished mining "..resource.name.." at "..util.positiontostr(resource.position)) end + end else if global.debug then msg_all("drill can't mine "..resource.name.." at "..util.positiontostr(resource.position)) end end diff --git a/control.lua b/control.lua index f3ddf18..fcef56d 100644 --- a/control.lua +++ b/control.lua @@ -29,6 +29,14 @@ script.on_configuration_changed(function() if err then msg_all({"autodeconstruct-err-generic", err}) end end) +script.on_event(defines.events.on_runtime_mod_setting_changed, function(event) + if (event.setting == "autodeconstruct-remove-fluid-drills" and + settings.global['autodeconstruct-remove-fluid-drills'].value == true) then + local _, err = pcall(autodeconstruct.init_globals) + if err then msg_all({"autodeconstruct-err-generic", err}) end + end +end) + script.on_event(defines.events.on_cancelled_deconstruction, function(event) local _, err = pcall(autodeconstruct.on_cancelled_deconstruction, event) if err then msg_all({"autodeconstruct-err-specific", "on_cancelled_deconstruction", err}) end From fc8bf2750124ce00df951a4e2d02bad73d9269d2 Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 15:41:15 -0500 Subject: [PATCH 03/10] Moved max_radius calculation to init_globals * Calculate max_radius based on all prototypes in the game, rather than checking every single entity when it is built to see if it has a larger radius. * Add filter to on_deconstruction_cancelled event. --- autodeconstruct.lua | 25 ++++++++++++++----------- control.lua | 21 +++++++-------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index 073b3e7..64ad1a8 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -123,9 +123,20 @@ local function debug_message_with_position(entity, msg) end function autodeconstruct.init_globals() + -- Find largest-range miner in the game global.max_radius = 0.99 + local drill_prototypes = game.get_filtered_entity_prototypes{{filter="type",type="mining-drill"}} + for _,p in drill_prototypes do + if p.mining_drill_radius then + if p.mining_drill_radius > global.max_radius then + global.max_radius = p.mining_drill_radius + if global.debug then msg_all({"autodeconstruct-debug", "init_globals", "global.max_radius updated to " .. global.max_radius}) end + end + end + end + + -- Look for existing depleted miners based on current settings local drill_entities = find_all_entities('mining-drill') - for _, drill_entity in pairs(drill_entities) do autodeconstruct.check_drill(drill_entity) end @@ -158,21 +169,13 @@ function autodeconstruct.check_drill(drill) end function autodeconstruct.on_cancelled_deconstruction(event) - if event.player_index ~= nil or event.entity.type ~= 'mining-drill' then return end + if event.player_index ~= nil then return end if global.debug then msg_all({"autodeconstruct-debug", "on_cancelled_deconstruction", util.positiontostr(event.entity.position) .. " deconstruction timed out, checking again"}) end - + -- If another mod cancelled deconstruction of a miner, check this miner again autodeconstruct.check_drill(event.entity) end -function autodeconstruct.on_built_entity(event) - if event.created_entity.type ~= 'mining-drill' then return end - if event.created_entity.prototype.mining_drill_radius > global.max_radius then - global.max_radius = event.created_entity.prototype.mining_drill_radius - if global.debug then msg_all({"autodeconstruct-debug", "on_built_entity", "global.max_radius updated to " .. global.max_radius}) end - end -end - function autodeconstruct.deconstruct_target(drill) local target = find_target(drill) diff --git a/control.lua b/control.lua index fcef56d..bc77cdf 100644 --- a/control.lua +++ b/control.lua @@ -37,22 +37,15 @@ script.on_event(defines.events.on_runtime_mod_setting_changed, function(event) end end) -script.on_event(defines.events.on_cancelled_deconstruction, function(event) - local _, err = pcall(autodeconstruct.on_cancelled_deconstruction, event) - if err then msg_all({"autodeconstruct-err-specific", "on_cancelled_deconstruction", err}) end -end) +script.on_event(defines.events.on_cancelled_deconstruction, + function(event) + local _, err = pcall(autodeconstruct.on_cancelled_deconstruction, event) + if err then msg_all({"autodeconstruct-err-specific", "on_cancelled_deconstruction", err}) end + end, + {{filter="type", type="mining-drill"}} +) script.on_event(defines.events.on_resource_depleted, function(event) local _, err = pcall(autodeconstruct.on_resource_depleted, event) if err then msg_all({"autodeconstruct-err-specific", "on_resource_depleted", err}) end end) - -script.on_event(defines.events.on_robot_built_entity, function(event) - local _, err = pcall(autodeconstruct.on_built_entity, event) - if err then msg_all({"autodeconstruct-err-specific", "on_robot_built_entity", err}) end -end) - -script.on_event(defines.events.on_built_entity, function(event) - local _, err = pcall(autodeconstruct.on_built_entity, event) - if err then msg_all({"autodeconstruct-err-specific", "on_built_entity", err}) end -end) From 710f9f14cee3a0930dbbb1dd3f178a7eeb55fae2 Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 15:41:15 -0500 Subject: [PATCH 04/10] Moved max_radius calculation to init_globals * Calculate max_radius based on all prototypes in the game, rather than checking every single entity when it is built to see if it has a larger radius. * Add filter to on_deconstruction_cancelled event. --- autodeconstruct.lua | 25 ++++++++++++++----------- control.lua | 21 +++++++-------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index 073b3e7..1f3d635 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -123,9 +123,20 @@ local function debug_message_with_position(entity, msg) end function autodeconstruct.init_globals() + -- Find largest-range miner in the game global.max_radius = 0.99 + local drill_prototypes = game.get_filtered_entity_prototypes{{filter="type",type="mining-drill"}} + for _,p in pairs(drill_prototypes) do + if p.mining_drill_radius then + if p.mining_drill_radius > global.max_radius then + global.max_radius = p.mining_drill_radius + if global.debug then msg_all({"autodeconstruct-debug", "init_globals", "global.max_radius updated to " .. global.max_radius}) end + end + end + end + + -- Look for existing depleted miners based on current settings local drill_entities = find_all_entities('mining-drill') - for _, drill_entity in pairs(drill_entities) do autodeconstruct.check_drill(drill_entity) end @@ -158,21 +169,13 @@ function autodeconstruct.check_drill(drill) end function autodeconstruct.on_cancelled_deconstruction(event) - if event.player_index ~= nil or event.entity.type ~= 'mining-drill' then return end + if event.player_index ~= nil then return end if global.debug then msg_all({"autodeconstruct-debug", "on_cancelled_deconstruction", util.positiontostr(event.entity.position) .. " deconstruction timed out, checking again"}) end - + -- If another mod cancelled deconstruction of a miner, check this miner again autodeconstruct.check_drill(event.entity) end -function autodeconstruct.on_built_entity(event) - if event.created_entity.type ~= 'mining-drill' then return end - if event.created_entity.prototype.mining_drill_radius > global.max_radius then - global.max_radius = event.created_entity.prototype.mining_drill_radius - if global.debug then msg_all({"autodeconstruct-debug", "on_built_entity", "global.max_radius updated to " .. global.max_radius}) end - end -end - function autodeconstruct.deconstruct_target(drill) local target = find_target(drill) diff --git a/control.lua b/control.lua index fcef56d..bc77cdf 100644 --- a/control.lua +++ b/control.lua @@ -37,22 +37,15 @@ script.on_event(defines.events.on_runtime_mod_setting_changed, function(event) end end) -script.on_event(defines.events.on_cancelled_deconstruction, function(event) - local _, err = pcall(autodeconstruct.on_cancelled_deconstruction, event) - if err then msg_all({"autodeconstruct-err-specific", "on_cancelled_deconstruction", err}) end -end) +script.on_event(defines.events.on_cancelled_deconstruction, + function(event) + local _, err = pcall(autodeconstruct.on_cancelled_deconstruction, event) + if err then msg_all({"autodeconstruct-err-specific", "on_cancelled_deconstruction", err}) end + end, + {{filter="type", type="mining-drill"}} +) script.on_event(defines.events.on_resource_depleted, function(event) local _, err = pcall(autodeconstruct.on_resource_depleted, event) if err then msg_all({"autodeconstruct-err-specific", "on_resource_depleted", err}) end end) - -script.on_event(defines.events.on_robot_built_entity, function(event) - local _, err = pcall(autodeconstruct.on_built_entity, event) - if err then msg_all({"autodeconstruct-err-specific", "on_robot_built_entity", err}) end -end) - -script.on_event(defines.events.on_built_entity, function(event) - local _, err = pcall(autodeconstruct.on_built_entity, event) - if err then msg_all({"autodeconstruct-err-specific", "on_built_entity", err}) end -end) From a598338d8e20c672b7281d7c86125761afd82939 Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 18:41:54 -0500 Subject: [PATCH 05/10] Improved pipe rotation logic Change pipe placement to utilize the direction-specific connection coordinates contained in the prototype data, rather than assuming symmetrical rotation. --- autodeconstruct.lua | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index 1f3d635..16364aa 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -214,21 +214,9 @@ local function range(from,to,step) return t end -local function rotate(v,dir) - if dir == defines.direction.east then - return {x = -v.y, y = v.x} - elseif dir == defines.direction.south then - return {x = -v.x, y = -v.y} - elseif dir == defines.direction.west then - return {x = v.y, y = -v.x} - end - return v -end - function autodeconstruct.build_pipe(drillData, pipeType, pipeTarget) --log("pipeTarget"..serpent.block(pipeTarget, {comment = false, numformat = '%1.8g', compact = true } ).."; drillData.position" .. serpent.block(drillData.position, {comment = false, numformat = '%1.8g', compact = true } )) - pipeTarget = rotate(pipeTarget,drillData.direction) - for _,x in pairs(range(drillData.position.x, drillData.position.x + pipeTarget.x, 1)) do + for _, x in pairs(range(drillData.position.x, drillData.position.x + pipeTarget.x, 1)) do for _, y in pairs(range(drillData.position.y, drillData.position.y + pipeTarget.y, 1)) do drillData.surface.create_entity{name="entity-ghost", player = drillData.owner, position = {x = x, y = y}, force=drillData.force, inner_name=pipeType} end @@ -248,6 +236,7 @@ function autodeconstruct.build_pipes(drill) owner = drill.last_user, surface = drill.surface } + --Space Exploration Compatibility check for space-surfaces local pipeType = "pipe" if game.active_mods["space-exploration"] then @@ -257,13 +246,23 @@ function autodeconstruct.build_pipes(drill) pipeType = "se-space-pipe" end end + + -- Connection position index is different from entity.direction + local conn_index = 1 -- north + if drillData.direction == defines.direction.east then + conn_index = 2 + elseif drillData.direction == defines.direction.south then + conn_index = 3 + elseif drillData.direction == defines.direction.west then + conn_index = 4 + end + -- fluidbox_prototype.pipe_connections contains a array with various connection points, it seems the one we need is always the 1st local fluidbox_prototype = drill.fluidbox.get_prototype(1) if fluidbox_prototype.pipe_connections and #fluidbox_prototype.pipe_connections > 0 then - for k, conn in pairs(fluidbox_prototype.pipe_connections) do - if conn.positions and #conn.positions > 0 then - autodeconstruct.build_pipe(drillData, pipeType, conn.positions[1]) - end + for _, conn in pairs(fluidbox_prototype.pipe_connections) do + -- get the relative positions of the pipe connections for this drill's rotation + autodeconstruct.build_pipe(drillData, pipeType, conn.positions[conn_index]) end end end From c84bb81a4ef6b0edad9d70c453622306f61cdb6a Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 18:55:26 -0500 Subject: [PATCH 06/10] Update autodeconstruct.lua * Removed unneeded validity checks for a fluidbox we know exists. * Only build pipes if this miner has more than one connection. (If a row depletes uniformly from the very end, no pipes are ever needed.) --- autodeconstruct.lua | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index 16364aa..bb661c0 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -247,6 +247,9 @@ function autodeconstruct.build_pipes(drill) end end + -- Drills only have one fluidbox, get the first + local fluidbox_prototype = drill.fluidbox.get_prototype(1) + -- Connection position index is different from entity.direction local conn_index = 1 -- north if drillData.direction == defines.direction.east then @@ -257,13 +260,9 @@ function autodeconstruct.build_pipes(drill) conn_index = 4 end - -- fluidbox_prototype.pipe_connections contains a array with various connection points, it seems the one we need is always the 1st - local fluidbox_prototype = drill.fluidbox.get_prototype(1) - if fluidbox_prototype.pipe_connections and #fluidbox_prototype.pipe_connections > 0 then - for _, conn in pairs(fluidbox_prototype.pipe_connections) do - -- get the relative positions of the pipe connections for this drill's rotation - autodeconstruct.build_pipe(drillData, pipeType, conn.positions[conn_index]) - end + for _, conn in pairs(fluidbox_prototype.pipe_connections) do + -- place pipes to this connection point for the given rotation + autodeconstruct.build_pipe(drillData, pipeType, conn.positions[conn_index]) end end @@ -276,7 +275,7 @@ function autodeconstruct.order_deconstruction(drill) local has_fluid = false if drill.fluidbox and #drill.fluidbox > 0 then has_fluid = true - if settings.global['autodeconstruct-remove-fluid-drills'].value ~= true then + if not settings.global['autodeconstruct-remove-fluid-drills'].value then debug_message_with_position(drill, "has a non-empty fluidbox and fluid deconstruction is not enabled, skipping") return @@ -316,8 +315,12 @@ function autodeconstruct.order_deconstruction(drill) if drill.order_deconstruction(drill.force, drill.last_user) then debug_message_with_position(drill, "marked for deconstruction") if has_fluid and settings.global['autodeconstruct-build-pipes'].value then - debug_message_with_position(drill, "adding pipe blueprints") - autodeconstruct.build_pipes(drill) + if #drill.fluidbox.get_connections(1) > 1 then + debug_message_with_position(drill, "adding pipe blueprints") + autodeconstruct.build_pipes(drill) + else + debug_message_with_position(drill, "skipping pipe blueprints, only one connection") + end end else msg_all({"autodeconstruct-err-specific", "drill.order_deconstruction", util.positiontostr(drill.position) .. " " .. drill.name .. " failed to order deconstruction" }) From afd3aa7bdc70dce03d2265db5ee23cd29cdf17b3 Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 21:21:51 -0500 Subject: [PATCH 07/10] Fixed chests being deconstructed while still in use * Fixed a logic error when checking if another miner is still using a chest. * Simplified the search code to find entities targeting the chest. * Fixed a crash if an inserter is nearby the chest but not targeting the chest. --- autodeconstruct.lua | 49 +++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index bb661c0..b08316d 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -59,10 +59,10 @@ local function find_target(entity) return entity.drop_target else local entities = entity.surface.find_entities_filtered{position=entity.drop_position} - - if global.debug then msg_all({"autodeconstruct-debug", "found " .. entities[1].name .. " at " .. util.positiontostr(entities[1].position)}) end - - return entities[1] + if #entities > 0 then + if global.debug then msg_all({"autodeconstruct-debug", "found " .. entities[1].name .. " at " .. util.positiontostr(entities[1].position)}) end + return entities[1] + end end end @@ -74,17 +74,9 @@ local function find_targeting(entity) local bottom_right = {x = position.x + range, y = position.y + range} local surface = entity.surface - local entities = {} local targeting = {} - local entities = surface.find_entities_filtered{area={top_left, bottom_right}, type='mining-drill'} - for i = 1, #entities do - if find_target(entities[i]) == entity then - targeting[#targeting + 1] = entities[i] - end - end - - local entities = surface.find_entities_filtered{area={top_left, bottom_right}, type='inserter'} + local entities = surface.find_entities_filtered{area={top_left, bottom_right}, type={'mining-drill', 'inserter'}} for i = 1, #entities do if find_target(entities[i]) == entity then targeting[#targeting + 1] = entities[i] @@ -103,8 +95,6 @@ local function find_drills(entity) local top_left = {x = position.x - global.max_radius, y = position.y - global.max_radius} local bottom_right = {x = position.x + global.max_radius, y = position.y + global.max_radius} - local entities = {} - local entities = surface.find_entities_filtered{area={top_left, bottom_right}, type='mining-drill'} if global.debug then msg_all({"autodeconstruct-debug", "found " .. #entities .. " drills"}) end @@ -184,19 +174,26 @@ function autodeconstruct.deconstruct_target(drill) local targeting = find_targeting(target) if targeting ~= nil then + + local chest_is_idle = true for i = 1, #targeting do - if not targeting[i].to_be_deconstructed(targeting[i].force) and targeting[i] ~= drill then break end + if not targeting[i].to_be_deconstructed(targeting[i].force) and targeting[i] ~= drill then + chest_is_idle = false + break + end end - - -- we are the only one targeting - if target.to_be_deconstructed(target.force) then - target.cancel_deconstruction(target.force) - end - - if target.order_deconstruction(target.force, target.last_user) then - debug_message_with_position(target, "marked for deconstruction") - else - msg_all({"autodeconstruct-err-specific", "target.order_deconstruction", util.positiontostr(target.position) .. " failed to order deconstruction on " .. target.name}) + + if chest_is_idle then + -- we are the only one targeting + if target.to_be_deconstructed(target.force) then + target.cancel_deconstruction(target.force) + end + + if target.order_deconstruction(target.force, target.last_user) then + debug_message_with_position(target, "marked for deconstruction") + else + msg_all({"autodeconstruct-err-specific", "target.order_deconstruction", util.positiontostr(target.position) .. " failed to order deconstruction on " .. target.name}) + end end end end From 944750891b71f50fa8d8ab1174705903232bc957 Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 21:33:15 -0500 Subject: [PATCH 08/10] Add deconstructing inserters feeding fuel to burner miners * For burner miners, checks for inserters targeting the miner and deconstructs them too. Note: Only case not covered is if an inserter is *taking* fuel from this miner in a daisy chain, in which case you might not want it to be deconstructed at all. --- autodeconstruct.lua | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index b08316d..a043cda 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -66,7 +66,7 @@ local function find_target(entity) end end -local function find_targeting(entity) +local function find_targeting(entity, types) local range = global.max_radius local position = entity.position @@ -76,7 +76,7 @@ local function find_targeting(entity) local surface = entity.surface local targeting = {} - local entities = surface.find_entities_filtered{area={top_left, bottom_right}, type={'mining-drill', 'inserter'}} + local entities = surface.find_entities_filtered{area={top_left, bottom_right}, type=types} for i = 1, #entities do if find_target(entities[i]) == entity then targeting[#targeting + 1] = entities[i] @@ -171,7 +171,7 @@ function autodeconstruct.deconstruct_target(drill) if target ~= nil and target.minable and target.prototype.selectable_in_game then if target.type == "logistic-container" or target.type == "container" then - local targeting = find_targeting(target) + local targeting = find_targeting(target, {'mining-drill', 'inserter'}) if targeting ~= nil then @@ -311,6 +311,7 @@ function autodeconstruct.order_deconstruction(drill) if drill.order_deconstruction(drill.force, drill.last_user) then debug_message_with_position(drill, "marked for deconstruction") + -- Handle pipes if has_fluid and settings.global['autodeconstruct-build-pipes'].value then if #drill.fluidbox.get_connections(1) > 1 then debug_message_with_position(drill, "adding pipe blueprints") @@ -319,6 +320,13 @@ function autodeconstruct.order_deconstruction(drill) debug_message_with_position(drill, "skipping pipe blueprints, only one connection") end end + -- Check for inserters providing fuel to this miner + if drill.burner then + local targeting = find_targeting(drill, {'inserter'}) + for _,e in pairs(targeting) do + e.order_deconstruction(e.force, e.last_user) + end + end else msg_all({"autodeconstruct-err-specific", "drill.order_deconstruction", util.positiontostr(drill.position) .. " " .. drill.name .. " failed to order deconstruction" }) end From 8e06e05e69801c206511a9df63fb1ff3b66d1bba Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 22:48:15 -0500 Subject: [PATCH 09/10] Added partial pipe construction * Added logic so that pipes are only built to connections in use. (This will fail if connected to a very rectangular entity or if there are more than one pipe connection on one side of the miner.) * Added logic to not deconstruct a burner miner that is a source for an inserter moving fuel around. --- autodeconstruct.lua | 101 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 12 deletions(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index a043cda..1693e14 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -88,6 +88,28 @@ local function find_targeting(entity, types) return targeting end +local function find_extracting(entity) + local range = global.max_radius + local position = entity.position + + local top_left = {x = position.x - range, y = position.y - range} + local bottom_right = {x = position.x + range, y = position.y + range} + + local surface = entity.surface + local extracting = {} + + local entities = surface.find_entities_filtered{area={top_left, bottom_right}, type="inserter"} + for i = 1, #entities do + if entities[i].pickup_target == entity then + extracting[#extracting + 1] = entities[i] + end + end + + if global.debug then msg_all({"autodeconstruct-debug", "found " .. #extracting .. " extracting"}) end + + return extracting +end + local function find_drills(entity) local position = entity.position local surface = entity.surface @@ -246,21 +268,70 @@ function autodeconstruct.build_pipes(drill) -- Drills only have one fluidbox, get the first local fluidbox_prototype = drill.fluidbox.get_prototype(1) + local neighbours = drill.neighbours[1] - -- Connection position index is different from entity.direction - local conn_index = 1 -- north - if drillData.direction == defines.direction.east then - conn_index = 2 - elseif drillData.direction == defines.direction.south then - conn_index = 3 - elseif drillData.direction == defines.direction.west then - conn_index = 4 - end + if neighbours then + + -- Connection position index is different from entity.direction + local conn_index = 1 -- north + if drillData.direction == defines.direction.east then + conn_index = 2 + elseif drillData.direction == defines.direction.south then + conn_index = 3 + elseif drillData.direction == defines.direction.west then + conn_index = 4 + end - for _, conn in pairs(fluidbox_prototype.pipe_connections) do - -- place pipes to this connection point for the given rotation - autodeconstruct.build_pipe(drillData, pipeType, conn.positions[conn_index]) + local connectors = {} + for _, conn in pairs(fluidbox_prototype.pipe_connections) do + connectors[#connectors + 1] = conn.positions[conn_index] + end + + for _,neighbour in pairs(neighbours) do + -- see if this neighbour is up, down, left, or right + -- whichever distance is greatest is what side it's on, if it's generally square + local xd = neighbour.position.x - drill.position.x + local yd = neighbour.position.y - drill.position.y + if math.abs(xd) > math.abs(yd) then + if xd > 0 then + -- to the east + for _, conn in pairs(connectors) do + if conn.x > 0 then + autodeconstruct.build_pipe(drillData, pipeType, conn) + break + end + end + else + -- to the west + for _, conn in pairs(connectors) do + if conn.x < 0 then + autodeconstruct.build_pipe(drillData, pipeType, conn) + break + end + end + end + else + if yd > 0 then + -- to the north + for _, conn in pairs(connectors) do + if conn.y > 0 then + autodeconstruct.build_pipe(drillData, pipeType, conn) + break + end + end + else + -- to the south + for _, conn in pairs(connectors) do + if conn.y < 0 then + autodeconstruct.build_pipe(drillData, pipeType, conn) + break + end + end + end + end + end end + end function autodeconstruct.order_deconstruction(drill) @@ -302,7 +373,13 @@ function autodeconstruct.order_deconstruction(drill) return end + + if drill.burner and #find_extracting(drill)>0 then + debug_message_with_position(drill, "is part of inserter chain, skipping") + return + end + -- end guards if settings.global['autodeconstruct-remove-target'].value then From 818d0ac13ec894e5cf53aabb6bb302721d1f660c Mon Sep 17 00:00:00 2001 From: robot256 Date: Sat, 20 Nov 2021 22:50:50 -0500 Subject: [PATCH 10/10] Update comment --- autodeconstruct.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/autodeconstruct.lua b/autodeconstruct.lua index 1693e14..9f14f4a 100644 --- a/autodeconstruct.lua +++ b/autodeconstruct.lua @@ -244,7 +244,6 @@ end function autodeconstruct.build_pipes(drill) -- future improvement: a mod setting for the pipeType to allow modded pipes - -- future improvement: it would be nice if it could detect which directions were connected and only connect those local drillData = { position = { x = drill.position.x,