mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
Refactor legacy addons into Clusterio format (#413)
* Refactor custom start * Refactor afk kick * Fix use of assert get player * Refactor chat popup * Refactor chat auto reply * Refactor help bubbles * Refactor damage popups * Refactor death markers * Refactor deconstruction log * Remove FAGC logging * Refactor discord alerts * Refactor insert pickup * Refactor inventory clear * Refactor extra logging * Refactor nuke protection * Refactor pollution grading * Refactor protection jail * Refactor report jail * Refactor mine depletion * Refactor degrading tiles * Refactor station auto name * Refactor spawn area * Refactor fast deconstruction * Bug Fixes
This commit is contained in:
231
exp_scenario/module/control/mine_depletion.lua
Normal file
231
exp_scenario/module/control/mine_depletion.lua
Normal file
@@ -0,0 +1,231 @@
|
||||
--[[-- Control - Mine Depletion
|
||||
Marks mining drills for deconstruction when resources deplete
|
||||
]]
|
||||
|
||||
local Async = require("modules/exp_util/async")
|
||||
local config = require("modules.exp_legacy.config.miner")
|
||||
|
||||
local floor = math.floor
|
||||
|
||||
--- Orders the deconstruction of an entity by its own force
|
||||
local order_deconstruction_async =
|
||||
Async.register(function(entity)
|
||||
--- @cast entity LuaEntity
|
||||
entity.order_deconstruction(entity.force)
|
||||
end)
|
||||
|
||||
--- Reliability get the drop target of an entity
|
||||
--- @param entity LuaEntity
|
||||
--- @return LuaEntity?
|
||||
local function get_drop_chest(entity)
|
||||
-- First check the direct drop target
|
||||
local target = entity.drop_target
|
||||
if target and (target.type == "container" or target.type == "logistic-container" or target.type == "infinity-container") then
|
||||
return target
|
||||
end
|
||||
|
||||
-- Then check all entities at the drop position
|
||||
local entities = entity.surface.find_entities_filtered{
|
||||
position = entity.drop_position,
|
||||
type = { "container", "logistic-container", "infinity-container" },
|
||||
}
|
||||
|
||||
return #entities > 0 and entities[1] or nil
|
||||
end
|
||||
|
||||
--- Check if an entity should has checked performed
|
||||
--- @param entity LuaEntity
|
||||
--- @return boolean
|
||||
local function prevent_deconstruction(entity)
|
||||
-- Already waiting to be deconstructed
|
||||
if not entity.valid or entity.to_be_deconstructed() then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Not minable, selectable, or deconstructive
|
||||
if not entity.minable or not entity.prototype.selectable_in_game or entity.has_flag("not-deconstructable") then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Is connected to the circuit network
|
||||
local red_write_connection = entity.get_wire_connector(defines.wire_connector_id.circuit_red, false)
|
||||
local green_write_connection = entity.get_wire_connector(defines.wire_connector_id.circuit_green, false)
|
||||
if red_write_connection and red_write_connection.connection_count > 0
|
||||
or green_write_connection and green_write_connection.connection_count > 0 then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Check if an output chest should be deconstructed
|
||||
--- @param entity LuaEntity
|
||||
local function try_deconstruct_output_chest(entity)
|
||||
-- Get a valid chest as the target
|
||||
local target = get_drop_chest(entity)
|
||||
if not target or prevent_deconstruction(target) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Get all adjacent mining drills and inserters
|
||||
local entities = target.surface.find_entities_filtered{
|
||||
type = { "mining-drill", "inserter" },
|
||||
to_be_deconstructed = false,
|
||||
area = {
|
||||
{ target.position.x - 1, target.position.y - 1 },
|
||||
{ target.position.x + 1, target.position.y + 1 }
|
||||
},
|
||||
}
|
||||
|
||||
-- Check if any other entity is using this chest
|
||||
for _, other in ipairs(entities) do
|
||||
if other ~= entity and get_drop_chest(other) == target then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Deconstruct the chest
|
||||
order_deconstruction_async:start_after(10, target)
|
||||
end
|
||||
|
||||
--- Check if a miner should be deconstructed
|
||||
--- @param entity LuaEntity
|
||||
local function try_deconstruct_miner(entity)
|
||||
-- Check if the miner should be deconstructed
|
||||
if prevent_deconstruction(entity) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if there are any resources remaining for the miner
|
||||
local surface = entity.surface
|
||||
local resources = surface.find_entities_filtered{
|
||||
type = "resource",
|
||||
area = entity.mining_area,
|
||||
}
|
||||
|
||||
for _, resource in ipairs(resources) do
|
||||
if resource.amount > 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Deconstruct the miner
|
||||
order_deconstruction_async:start_after(10, entity)
|
||||
|
||||
-- Try deconstruct the output chest
|
||||
if config.chest then
|
||||
try_deconstruct_output_chest(entity)
|
||||
end
|
||||
|
||||
-- Skip pipe build if not required
|
||||
if not config.fluid or #entity.fluidbox == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
-- Build pipes if the miner used fluid
|
||||
local position = entity.position
|
||||
local create_entity_position = { x = position.x, y = position.y }
|
||||
local create_entity_param = { name = "entity-ghost", inner_name = "pipe", force = entity.force, position = create_entity_position }
|
||||
local create_entity = surface.create_entity
|
||||
create_entity(create_entity_param)
|
||||
|
||||
-- Find all the entities to connect to
|
||||
local bounding_box = entity.bounding_box
|
||||
local search_area = {
|
||||
{ bounding_box.left_top.x - 1, bounding_box.left_top.y - 1 },
|
||||
{ bounding_box.right_bottom.x + 1, bounding_box.right_bottom.y + 1 },
|
||||
}
|
||||
|
||||
local entities = surface.find_entities_filtered{ area = search_area, type = { "mining-drill", "pipe", "pipe-to-ground", "infinity-pipe" } }
|
||||
local ghosts = surface.find_entities_filtered{ area = search_area, ghost_type = { "pipe", "pipe-to-ground", "infinity-pipe" } }
|
||||
table.insert_array(entities, ghosts)
|
||||
|
||||
-- Check which directions to add pipes in
|
||||
local pos_x, pos_y, neg_x, neg_y = false, false, false, false
|
||||
for _, other in ipairs(entities) do
|
||||
if (other.position.x > position.x) and (other.position.y == position.y) then
|
||||
pos_x = true
|
||||
elseif (other.position.x < position.x) and (other.position.y == position.y) then
|
||||
neg_x = true
|
||||
elseif (other.position.x == position.x) and (other.position.y > position.y) then
|
||||
pos_y = true
|
||||
elseif (other.position.x == position.x) and (other.position.y < position.y) then
|
||||
neg_y = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Build the pipes
|
||||
if pos_x then
|
||||
create_entity_position.y = floor(position.y)
|
||||
for x = position.x + 1, bounding_box.right_bottom.x do
|
||||
create_entity_position.x = x
|
||||
create_entity(create_entity_param)
|
||||
end
|
||||
end
|
||||
if neg_x then
|
||||
create_entity_position.y = floor(position.y)
|
||||
for x = floor(bounding_box.left_top.x), floor(position.x - 1) do
|
||||
create_entity_position.x = x
|
||||
create_entity(create_entity_param)
|
||||
end
|
||||
end
|
||||
if pos_y then
|
||||
create_entity_position.x = floor(position.x)
|
||||
for y = floor(position.y + 1), floor(bounding_box.right_bottom.y) do
|
||||
create_entity_position.y = y
|
||||
create_entity(create_entity_param)
|
||||
end
|
||||
end
|
||||
if neg_y then
|
||||
create_entity_position.x = floor(position.x)
|
||||
for y = floor(bounding_box.left_top.y), floor(position.y - 1) do
|
||||
create_entity_position.y = y
|
||||
create_entity(create_entity_param)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Get the max mining radius
|
||||
local max_mining_radius = 0
|
||||
for _, proto in pairs(prototypes.get_entity_filtered{ { filter = "type", type = "mining-drill" } }) do
|
||||
if proto.mining_drill_radius > max_mining_radius then
|
||||
max_mining_radius = proto.mining_drill_radius
|
||||
end
|
||||
end
|
||||
|
||||
--- Try deconstruct a miner when its resources deplete
|
||||
--- @param event EventData.on_resource_depleted
|
||||
local function on_resource_depleted(event)
|
||||
local resource = event.entity
|
||||
if resource.prototype.infinite_resource then
|
||||
return
|
||||
end
|
||||
|
||||
-- Find all mining drills within the area
|
||||
local position = resource.position
|
||||
local drills = resource.surface.find_entities_filtered{
|
||||
type = "mining-drill",
|
||||
area = {
|
||||
{ position.x - max_mining_radius, position.y - max_mining_radius },
|
||||
{ position.x + max_mining_radius, position.y + max_mining_radius },
|
||||
},
|
||||
}
|
||||
|
||||
-- Check which could have reached this resource
|
||||
for _, drill in pairs(drills) do
|
||||
local radius = drill.prototype.mining_drill_radius
|
||||
local dx = math.abs(drill.position.x - resource.position.x)
|
||||
local dy = math.abs(drill.position.y - resource.position.y)
|
||||
if dx <= radius and dy <= radius then
|
||||
try_deconstruct_miner(drill)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local e = defines.events
|
||||
|
||||
return {
|
||||
events = {
|
||||
[e.on_resource_depleted] = on_resource_depleted,
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user