Добавлен мод blueprint-sandboxes Добавляет метку версии в zzzparanoidal (#72)
144 lines
4.7 KiB
Lua
144 lines
4.7 KiB
Lua
-- Equipment-related methods
|
|
local Equipment = {}
|
|
|
|
-- Initializes an Inventory for the default equipment Blueprint(s)
|
|
function Equipment.Init(default)
|
|
local equipment = game.create_inventory(1)
|
|
Equipment.Set(equipment, default)
|
|
return equipment
|
|
end
|
|
|
|
-- Updates the default equipment Blueprint(s)
|
|
function Equipment.Set(equipment, default)
|
|
equipment[1].import_stack(default)
|
|
end
|
|
|
|
--[[
|
|
Before 1.1.87, there was a bug that did not correctly forcefully generate
|
|
chunks for surfaces with the Lab Tiles setting, which required us to
|
|
fix those tiles after generation but before placing the Blueprint.
|
|
This but was fixed in 1.1.87, however, it introduced another bug where
|
|
building a blueprint then did not immediately work on those tiles,
|
|
but building entities seemed to. So, the workaround is to delay the blueprint
|
|
building, so we do some work when the surface is generated, then the rest
|
|
as soon as possible (aligning to generated chunks seems faster (in ticks)
|
|
than waiting any number of specific ticks).
|
|
]]
|
|
function Equipment.Place(stack, surface, forceName)
|
|
if stack.is_blueprint then
|
|
log("Beginning Equipment Placement")
|
|
Equipment.Prepare(stack, surface)
|
|
|
|
global.equipmentInProgress[surface.name] = {
|
|
stack = stack,
|
|
surface = surface,
|
|
forceName = forceName,
|
|
retries = 100,
|
|
}
|
|
Equipment.BuildBlueprint(stack, surface, forceName)
|
|
else
|
|
global.equipmentInProgress[surface.name] = nil
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- Prepares a Surface for an Equipment Blueprint
|
|
function Equipment.Prepare(stack, surface)
|
|
-- We need to know how many Chunks must be generated to fit this Blueprint
|
|
local radius = 0
|
|
local function updateRadius(thing)
|
|
local x = math.abs(thing.position.x)
|
|
local y = math.abs(thing.position.y)
|
|
radius = math.max(radius, x, y)
|
|
end
|
|
local entities = stack.get_blueprint_entities()
|
|
local tiles = stack.get_blueprint_tiles()
|
|
if entities then
|
|
for _, thing in pairs(entities) do
|
|
updateRadius(thing)
|
|
end
|
|
end
|
|
if tiles then
|
|
for _, thing in pairs(tiles) do
|
|
updateRadius(thing)
|
|
end
|
|
end
|
|
|
|
-- Then, we can forcefully generate the necessary Chunks
|
|
local chunkRadius = 1 + math.ceil(radius / 32)
|
|
log("Requesting Chunks for Blueprint Placement: " .. chunkRadius)
|
|
surface.request_to_generate_chunks({ x = 0, y = 0 }, chunkRadius)
|
|
surface.force_generate_chunk_requests()
|
|
log("Chunks allegedly generated")
|
|
end
|
|
|
|
-- Applies an Equipment Blueprint to a Surface
|
|
function Equipment.IsReadyForBlueprint(stack, surface)
|
|
local entities = stack.get_blueprint_entities()
|
|
local tiles = stack.get_blueprint_tiles()
|
|
local function is_chunk_generated(thing)
|
|
return surface.is_chunk_generated({
|
|
thing.position.x / 32,
|
|
thing.position.y / 32,
|
|
})
|
|
end
|
|
if entities then
|
|
for _, thing in pairs(entities) do
|
|
if not is_chunk_generated(thing) then
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
if tiles then
|
|
for _, thing in pairs(tiles) do
|
|
if not is_chunk_generated(thing) then
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- Applies an Equipment Blueprint to a Surface
|
|
function Equipment.BuildBlueprint(stack, surface, forceName)
|
|
local equipmentData = global.equipmentInProgress[surface.name]
|
|
|
|
-- First, let's check if the Chunks are ready for us
|
|
if not Equipment.IsReadyForBlueprint(stack, surface) then
|
|
equipmentData.retries = equipmentData.retries - 1
|
|
return false
|
|
end
|
|
|
|
-- Then, place the Tiles ourselves since it might prevent placing the Blueprint
|
|
local tiles = stack.get_blueprint_tiles()
|
|
if tiles then
|
|
surface.set_tiles(tiles, true, true, true, true)
|
|
end
|
|
|
|
-- Finally, we can place the Blueprint
|
|
local ghosts = stack.build_blueprint({
|
|
surface = surface.name,
|
|
force = forceName,
|
|
position = { 0, 0 },
|
|
skip_fog_of_war = true,
|
|
raise_built = true,
|
|
})
|
|
|
|
-- But that may have not been successful, despite our attempts to ensure it!
|
|
if #ghosts > 0 then
|
|
log("Some ghosts created, ending repeated attempts; assuming Blueprint is placed")
|
|
global.equipmentInProgress[surface.name] = nil
|
|
return true
|
|
elseif equipmentData.retries <= 0 then
|
|
log("No ghosts created, but we've exceeded retry limit, ending repeated attempts")
|
|
surface.print("Failed to place Equipment Blueprint after too many retries")
|
|
global.equipmentInProgress[surface.name] = nil
|
|
return false
|
|
else
|
|
equipmentData.retries = equipmentData.retries - 1
|
|
return false
|
|
end
|
|
end
|
|
|
|
return Equipment
|