Исправлен мод heroturrets
Добавлен мод blueprint-sandboxes Добавляет метку версии в zzzparanoidal (#72)
This commit is contained in:
143
blueprint-sandboxes/scripts/equipment.lua
Normal file
143
blueprint-sandboxes/scripts/equipment.lua
Normal file
@@ -0,0 +1,143 @@
|
||||
-- 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
|
||||
Reference in New Issue
Block a user