1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2025-03-05 15:05:57 +02:00

Merge branch 'scenario/diggy' of github.com:iltar/RedMew into scenario/diggy

This commit is contained in:
Lynn 2018-10-08 17:43:16 +02:00
commit 788b473894
5 changed files with 91 additions and 393 deletions

View File

@ -67,7 +67,6 @@ local Config = {
['refined-concrete'] = 0.15,
['refined-hazard-concrete-left'] = 0.15,
['refined-hazard-concrete-right'] = 0.15,
['deepwater-green'] = 0.7,
},
cracking_sounds = {
'CRACK',

View File

@ -36,7 +36,6 @@ function Debug.print(message)
if (debug) then
game.print('[' .. global.message_count .. '] ' .. tostring(message))
log('[' .. global.message_count .. '] ' .. tostring(message))
game.write_file("desync", '[' .. global.message_count .. '] ' .. tostring(message) .. '\n', true)
end
end

View File

@ -32,10 +32,21 @@ local disc_value = 0
local ring_value = 0
local enable_stress_grid = 0
local stress_map_blur_add
local mask_disc_blur
local stress_map_check_stress_in_threshold
local support_beam_entities
local stress_map_blur_add = nil
local mask_disc_blur = nil
local stress_map_check_stress_in_threshold = nil
local support_beam_entities = nil
local on_surface_created = nil
local stress_threshold_causing_collapse = 0.9
global.stress_map_storage = {}
local stress_map_storage = global.stress_map_storage
global.new_tile_map = {}
local new_tile_map = global.new_tile_map
local defaultValue = 0
DiggyCaveCollapse.events = {
--[[--
@ -97,9 +108,10 @@ local function collapse(args)
local position = args.position
local surface = args.surface
local positions = {}
local tiles = {}
local entities = nil
mask_disc_blur(
position.x,
position.y,
position.x, position.y,
config.collapse_threshold_total_strength,
function(x, y, value)
stress_map_check_stress_in_threshold(
@ -112,7 +124,7 @@ local function collapse(args)
)
end
)
local tiles, entities = create_collapse_template(positions, surface)
tiles, entities = create_collapse_template(positions, surface)
Template.insert(surface, tiles, entities)
end
@ -140,13 +152,22 @@ local function spawn_cracking_sound_text(surface, position)
end
local function on_collapse_triggered(event)
spawn_cracking_sound_text(event.surface, event.position)
local position = event.position
local x = position.x
local y = position.y
local x_t = new_tile_map[x]
if x_t and x_t[y] then
Template.insert(event.surface, {}, {{position = position, name = 'sand-rock-big'}})
else
spawn_cracking_sound_text(event.surface, position)
Task.set_timeout(
config.collapse_delay,
on_collapse_timeout_finished,
{surface = event.surface, position = event.position}
{surface = event.surface, position = position}
)
end
end
local function on_built_tile(surface, new_tile, tiles)
local new_tile_strength = support_beam_entities[new_tile.name]
@ -167,7 +188,7 @@ local function on_robot_mined_tile(event)
for _, tile in pairs(event.tiles) do
local strength = support_beam_entities[tile.old_tile.name]
if strength then
stress_map_blur_add(event.robot.surface, tile.position, strength, 'on_robot_mined_tile')
stress_map_blur_add(event.robot.surface, tile.position, strength)
end
end
end
@ -178,7 +199,7 @@ local function on_player_mined_tile(event)
local strength = support_beam_entities[tile.old_tile.name]
if strength then
stress_map_blur_add(surface, tile.position, strength, 'on_player_mined_tile')
stress_map_blur_add(surface, tile.position, strength)
end
end
end
@ -187,7 +208,7 @@ local function on_mined_entity(event)
local strength = support_beam_entities[event.entity.name]
if strength then
stress_map_blur_add(event.entity.surface, event.entity.position, strength, 'on_mined_entity')
stress_map_blur_add(event.entity.surface, event.entity.position, strength)
end
end
@ -208,22 +229,49 @@ local function on_placed_entity(event)
local strength = support_beam_entities[event.entity.name]
if strength then
stress_map_blur_add(event.entity.surface, event.entity.position, -1 * strength, 'on_placed_entity')
stress_map_blur_add(event.entity.surface, event.entity.position, -1 * strength)
end
end
local on_new_tile_timeout_finished = Token.register(function(args)
local x_t = new_tile_map[args.x]
if x_t then
x_t[args.y] = nil --reset new tile status. This tile can cause a chain collapse now
end
end)
local function on_void_removed(event)
local strength = support_beam_entities['out-of-map']
local position = event.old_tile.position
if strength then
stress_map_blur_add(event.surface, event.old_tile.position, strength, 'on_void_removed')
stress_map_blur_add(event.surface, position, strength)
end
local x = position.x
local y = position.y
--To avoid room collapse:
local x_t = new_tile_map[x]
if x_t then
x_t[y] = true
else
x_t = {
[y] = true
}
new_tile_map[x] = x_t
end
Task.set_timeout(3,
on_new_tile_timeout_finished,
{x = x, y = y}
)
end
local function on_void_added(event)
local strength = support_beam_entities['out-of-map']
if strength then
stress_map_blur_add(event.surface, event.old_tile.position, -1 * strength, 'on_void_added')
stress_map_blur_add(event.surface, event.old_tile.position, -1 * strength)
end
end
@ -253,17 +301,16 @@ function DiggyCaveCollapse.register(cfg)
Event.add(defines.events.on_player_mined_entity, on_mined_entity)
Event.add(Template.events.on_void_removed, on_void_removed)
Event.add(Template.events.on_void_added, on_void_added)
Event.add(defines.events.on_surface_created, on_surface_created)
enable_stress_grid = config.enable_stress_grid
on_surface_created({surface_index = 1})
mask_init(config)
if (config.enable_mask_debug) then
local surface = game.surfaces.nauvis
mask_disc_blur(
0,
0,
10,
function(x, y, fraction)
mask_disc_blur(0, 0, 10, function(x, y, fraction)
Debug.print_grid_value(fraction, surface, {x = x, y = y})
end
)
@ -273,18 +320,11 @@ end
--
--STRESS MAP
--
local stress_threshold_causing_collapse = 0.91
-- main block
global.stress_map_storage = {}
local defaultValue = 0
--[[--
Adds a fraction to a given location on the stress_map. Returns the new
fraction value of that position.
@param stress_map Table of {@see get_stress_map}
@param stress_map Table of {x,y}
@param position Table with x and y
@param number fraction
@ -386,6 +426,18 @@ local function add_fraction_by_quadrant(stress_map, x, y, fraction, quadrant)
return value
end
on_surface_created = function(event)
stress_map_storage[event.surface_index] = {}
local map = stress_map_storage[event.surface_index]
map['surface_index'] = event.surface_index
map[1] = {}
map[2] = {}
map[3] = {}
map[4] = {}
end
--[[--
Creates a new stress map if it doesn't exist yet and returns it.
@ -393,19 +445,7 @@ end
@return Table [1,2,3,4] containing the quadrants
]]
local function get_stress_map(surface)
if not global.stress_map_storage[surface.index] then
global.stress_map_storage[surface.index] = {}
local map = global.stress_map_storage[surface.index]
map['surface_index'] = surface.index
map[1] = {}
map[2] = {}
map[3] = {}
map[4] = {}
end
return global.stress_map_storage[surface.index]
return
end
--[[--
@ -417,7 +457,7 @@ end
]]
stress_map_check_stress_in_threshold = function(surface, position, threshold, callback)
local stress_map = get_stress_map(surface)
local stress_map = stress_map_storage[surface.index]
local value = add_fraction(stress_map, position.x, position.y, 0)
if (value >= stress_threshold_causing_collapse - threshold) then
@ -425,18 +465,14 @@ stress_map_check_stress_in_threshold = function(surface, position, threshold, ca
end
end
stress_map_blur_add = function(surface, position, factor, caller)
if global.disable_cave_collapse then
return
end
caller = caller or 'unknown'
--Debug.print(caller .. ' before')
stress_map_blur_add = function(surface, position, factor)
local x_start = math.floor(position.x)
local y_start = math.floor(position.y)
local stress_map = get_stress_map(game.surfaces[1])
local stress_map = stress_map_storage[surface.index]
if not stress_map then
return
end
if radius > math.abs(x_start) or radius > math.abs(y_start) then
for x = -radius, radius do
@ -456,7 +492,6 @@ stress_map_blur_add = function(surface, position, factor, caller)
end
end
else
--ALL VALUES IN SAME QUADRANT SO WE CAN OPTIMIZE THIS!
local quadrant = 1
if x_start < 0 then
quadrant = quadrant + 1
@ -484,7 +519,6 @@ stress_map_blur_add = function(surface, position, factor, caller)
end
end
end
--Debug.print(caller .. ' after')
end
DiggyCaveCollapse.stress_map_blur_add = stress_map_blur_add

View File

@ -1,179 +0,0 @@
local Debug = require'map_gen.Diggy.Debug'
-- this
local Mask = {}
local gaussBlurKernel = {}
gaussBlurKernel[5] = {
{0.003765, 0.015019, 0.023792, 0.015019, 0.003765},
{0.015019, 0.059912, 0.094907, 0.059912, 0.015019},
{0.023792, 0.094907, 0.150342, 0.094907, 0.023792},
{0.015019, 0.059912, 0.094907, 0.059912, 0.015019},
{0.003765, 0.015019, 0.023792, 0.015019, 0.003765}
}
gaussBlurKernel[7] = {
{0.0015, 0.00438, 0.008328, 0.010317, 0.008328, 0.00438, 0.0015},
{0.00438, 0.012788, 0.024314, 0.03012, 0.024314, 0.012788, 0.00438},
{0.008328, 0.024314, 0.046228, 0.057266, 0.046228, 0.024314, 0.008328},
{0.010317, 0.03012, 0.057266, 0.07094, 0.057266, 0.03012, 0.010317},
{0.008328, 0.024314, 0.046228, 0.057266, 0.046228, 0.024314, 0.008328},
{0.00438, 0.012788, 0.024314, 0.03012, 0.024314, 0.012788, 0.00438},
{0.0015, 0.00438, 0.008328, 0.010317, 0.008328, 0.00438, 0.0015}
}
gaussBlurKernel[9] = {
{0.000814, 0.001918, 0.003538, 0.005108, 0.005774, 0.005108, 0.003538, 0.001918, 0.000814},
{0.001918, 0.00452, 0.008338, 0.012038, 0.013605, 0.012038, 0.008338, 0.00452, 0.001918},
{0.003538, 0.008338, 0.015378, 0.022203, 0.025094, 0.022203, 0.015378, 0.008338, 0.003538},
{0.005774, 0.013605, 0.025094, 0.036231, 0.04095, 0.036231, 0.025094, 0.013605, 0.005774},
{0.005108, 0.012038, 0.022203, 0.032057, 0.036231, 0.032057, 0.022203, 0.012038, 0.005108},
{0.005108, 0.012038, 0.022203, 0.032057, 0.036231, 0.032057, 0.022203, 0.012038, 0.005108},
{0.003538, 0.008338, 0.015378, 0.022203, 0.025094, 0.022203, 0.015378, 0.008338, 0.003538},
{0.001918, 0.00452, 0.008338, 0.012038, 0.013605, 0.012038, 0.008338, 0.00452, 0.001918},
{0.000814, 0.001918, 0.003538, 0.005108, 0.005774, 0.005108, 0.003538, 0.001918, 0.000814}
}
gaussBlurKernel[11] = {
{0.000395, 0.000853, 0.001552, 0.002381, 0.003078, 0.003353, 0.003078, 0.002381, 0.001552, 0.000853, 0.000395},
{0.000853, 0.001842, 0.003353, 0.005143, 0.006648, 0.007242, 0.006648, 0.005143, 0.003353, 0.001842, 0.000853},
{0.001552, 0.003353, 0.006103, 0.009361, 0.012101, 0.013182, 0.012101, 0.009361, 0.006103, 0.003353, 0.001552},
{0.002381, 0.005143, 0.009361, 0.014359, 0.018561, 0.020219, 0.018561, 0.014359, 0.009361, 0.005143, 0.002381},
{0.003078, 0.006648, 0.012101, 0.018561, 0.023992, 0.026136, 0.023992, 0.018561, 0.012101, 0.006648, 0.003078},
{0.003353, 0.007242, 0.013182, 0.020219, 0.026136, 0.02847, 0.026136, 0.020219, 0.013182, 0.007242, 0.003353},
{0.003078, 0.006648, 0.012101, 0.018561, 0.023992, 0.026136, 0.023992, 0.018561, 0.012101, 0.006648, 0.003078},
{0.002381, 0.005143, 0.009361, 0.014359, 0.018561, 0.020219, 0.018561, 0.014359, 0.009361, 0.005143, 0.002381},
{0.001552, 0.003353, 0.006103, 0.009361, 0.012101, 0.013182, 0.012101, 0.009361, 0.006103, 0.003353, 0.001552},
{0.000853, 0.001842, 0.003353, 0.005143, 0.006648, 0.007242, 0.006648, 0.005143, 0.003353, 0.001842, 0.000853},
{0.000395, 0.000853, 0.001552, 0.002381, 0.003078, 0.003353, 0.003078, 0.002381, 0.001552, 0.000853, 0.000395}
}
local n
local radius
local radius_sq
local center_radius_sq
local disc_radius_sq
local center_weight
local disc_weight
local ring_weight
local disc_blur_sum = 0
local center_value
local disc_value
local ring_value
function Mask.init(config)
n = config.mask_size
ring_weight = config.mask_relative_ring_weights[1]
disc_weight = config.mask_relative_ring_weights[2]
center_weight = config.mask_relative_ring_weights[3]
radius = math.floor(n / 2)
radius_sq = (radius + 0.2) * (radius + 0.2)
center_radius_sq = radius_sq / 9
disc_radius_sq = radius_sq * 4 / 9
for x = -radius, radius do
for y = -radius, radius do
local distance_sq = x * x + y * y
if distance_sq <= center_radius_sq then
disc_blur_sum = disc_blur_sum + center_weight
elseif distance_sq <= disc_radius_sq then
disc_blur_sum = disc_blur_sum + disc_weight
elseif distance_sq <= radius_sq then
disc_blur_sum = disc_blur_sum + ring_weight
end
end
end
center_value = center_weight / disc_blur_sum
disc_value = disc_weight / disc_blur_sum
ring_value = ring_weight / disc_blur_sum
end
--[[--
Applies a blur filter.
@param x_start number center point
@param y_start number center point
@param factor number relative strength of the entity to withstand the stress
factor < 0 if entity is placed
factor > 0 if entity is removed
@param callback function to execute on each tile within the mask callback(x, y, value)
]]
function Mask.blur(x_start, y_start, factor, callback)
x_start = math.floor(x_start)
y_start = math.floor(y_start)
local filter = gaussBlurKernel[n]
local offset = - math.floor(n / 2) - 1 --move matrix over x_start|y_start and adjust for 1 index
for x = 1, n do
for y = 1, n do
cell = filter[x][y]
value = factor * cell
if math.abs(value) > 0.001 then
callback(x_start + x + offset, y_start + y + offset, value)
end
end
end
end
--[[--
Applies a blur
Applies the disc in 3 discs: center, (middle) disc and (outer) ring.
The relative weights for tiles in a disc are:
center: 3/3
disc: 2/3
ring: 1/3
The sum of all values is 1
@param x_start number center point
@param y_start number center point
@param factor the factor to multiply the cell value with (value = cell_value * factor)
@param callback function to execute on each tile within the mask callback(x, y, value)
]]
function Mask.disc_blur(x_start, y_start, factor, callback)
x_start = math.floor(x_start)
y_start = math.floor(y_start)
for x = -radius, radius do
for y = -radius, radius do
local value = 0
local distance_sq = x * x + y * y
if distance_sq <= center_radius_sq then
value = center_value
elseif distance_sq <= disc_radius_sq then
value = disc_value
elseif distance_sq <= radius_sq then
value = ring_value
end
if math.abs(value) > 0.001 then
callback(x_start + x, y_start + y, value * factor)
end
end
end
end
--[[--
Masks in the shape of a circle.
@param x_start number, center point
@param y_start number, center point
@param diameter number size of the circle
@param callback function to execute on each tile within the circle callback(x, y, tile_distance_to_center, diameter)
]]
function Mask.circle(x_start, y_start, diameter, callback)
for x = (diameter * -1), diameter, 1 do
for y = (diameter * -1), diameter, 1 do
local tile_distance_to_center = math.floor(math.sqrt(x^2 + y^2)) --needed in callback
if (tile_distance_to_center < diameter) then
callback(x + x_start, y + y_start, tile_distance_to_center, diameter)
end
end
end
end
return Mask

View File

@ -1,155 +0,0 @@
-- dependencies
local Event = require 'utils.event'
-- this
local StressMap = {}
local stress_offset_causing_collapse = 0.1
-- main block
global.stress_map_storage = {}
local defaultValue = 0
local _mt_y = { __index=function(tbl,key) tbl[key] = defaultValue return tbl[key] end}
local _mt_x = {__index=function(tbl,key) tbl[key] = setmetatable({},_mt_y) return rawget(tbl,key) end}
local function set_metatables()
for _,map in ipairs(global.stress_map_storage) do
for _,quad in pairs(map) do
setmetatable(quad,_mt_x)
for _,stbl in pairs(quad) do
setmetatable(stbl,_mt_y)
end
end
end
end
Event.on_init(set_metatables)
Event.on_load(set_metatables)
StressMap.events = {
--[[--
When stress at certain position changes
- position LuaPosition
- value Number
- old_value Number
- surface LuaSurface
]]
on_stress_changed = script.generate_event_name()
}
--[[--
Adds a fraction to a given location on the stress_map. Returns the new
fraction value of that position.
@param stress_map Table of {@see get_stress_map}
@param position Table with x and y
@param number fraction
@return number sum of old fraction + new fraction
]]
local function add_fraction(stress_map, position, fraction)
local x = position.x
local y = position.y
local quadrant = 1
if x < 0 then
quadrant = quadrant + 1
x = - x
end
if y < 0 then
quadrant = quadrant + 2
y = - y
end
--magic meta tables!
local value = stress_map[quadrant][x][y] + fraction
stress_map[quadrant][x][y] = value
local surface = game.surfaces[stress_map.surface_index]
script.raise_event(StressMap.events.on_stress_changed, {old_value = value - fraction, value = value, position = position, surface = surface})
return value
end
--[[--
Creates a new stress map if it doesn't exist yet and returns it.
@param surface LuaSurface
@return Table [1,2,3,4] containing the quadrants
]]
local function get_stress_map(surface)
if not global.stress_map_storage[surface.index] then
global.stress_map_storage[surface.index] = {}
local map = global.stress_map_storage[surface.index]
map[1] = setmetatable({},_mt_x)
map[2] = setmetatable({},_mt_x)
map[3] = setmetatable({},_mt_x)
map[4] = setmetatable({},_mt_x)
map["surface_index"] = surface.index
end
return global.stress_map_storage[surface.index]
end
--[[--
@param surface LuaSurface
@param position Position with x and y
@param number fraction to add to the given position on the surface increase or decreasing stress
@return boolean
]]
function StressMap.add(surface, position, fraction)
if ('table' ~= type(surface) or nil == surface.name) then
error('StressMap.add argument #1 expects a LuaSurface, ' .. type(surface) .. ' given.')
end
if ('table' ~= type(position) or nil == position.x or nil == position.y) then
error('StressMap.add argument #2 expects a position with x and y, ' .. type(position) .. ' given.')
end
local stress_map = get_stress_map(surface)
local new = add_fraction(stress_map, position, fraction)
if (new >= 1 - stress_offset_causing_collapse) then
return true
end
end
--[[--
Checks whether a tile's pressure is within a given threshold and calls the handler if not.
@param surface LuaSurface
@param position Position with x and y
@param number threshold
@param callback
]]
function StressMap.check_stress_in_threshold(surface, position, threshold, callback)
if ('table' ~= type(surface) or nil == surface.name) then
error('StressMap.check_stress_in_threshold argument #1 expects a LuaSurface, ' .. type(surface) .. ' given.')
end
if ('table' ~= type(position) or nil == position.x or nil == position.y) then
error('StressMap.check_stress_in_threshold argument #2 expects a position with x and y, ' .. type(position) .. ' given.')
end
if ('number' ~= type(threshold)) then
error('StressMap.check_stress_in_threshold argument #3 expects a number, ' .. type(threshold) .. ' given.')
end
local stress_map = get_stress_map(surface)
local value = add_fraction(stress_map, position, 0)
if (value >= 1 - stress_offset_causing_collapse - threshold) then
callback(surface, position)
end
end
return StressMap