From 79a5c954fe16eedce3b486d3f03c513cf45a82c4 Mon Sep 17 00:00:00 2001 From: Matthew Heguy Date: Wed, 23 Jan 2019 19:55:48 -0500 Subject: [PATCH] Localize functions! --- map_gen/shared/builders.lua | 168 ++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 75 deletions(-) diff --git a/map_gen/shared/builders.lua b/map_gen/shared/builders.lua index a47903cd..4ab7da59 100644 --- a/map_gen/shared/builders.lua +++ b/map_gen/shared/builders.lua @@ -1,14 +1,27 @@ local math = require 'utils.math' +local pi = math.pi +local random = math.random +local abs = math.abs +local floor = math.floor +local ceil = math.ceil +local max = math.max +local sqrt = math.sqrt +local sin = math.sin +local cos = math.cos +local atan2 = math.atan2 +local tau = math.tau +local insert = table.insert + -- helpers -local inv_pi = 1 / math.pi +local inv_pi = 1 / pi local Builders = {} local function add_entity(tile, entity) if type(tile) == 'table' then if tile.entities then - table.insert(tile.entities, entity) + insert(tile.entities, entity) else tile.entities = {entity} end @@ -83,18 +96,18 @@ end function Builders.square_diamond(size) size = size / 2 return function(x, y) - return math.abs(x) + math.abs(y) <= size + return abs(x) + abs(y) <= size end end -local rot = math.sqrt(2) / 2 -- 45 degree rotation. +local rot = sqrt(2) / 2 -- 45 degree rotation. function Builders.rectangle_diamond(width, height) width = width / 2 height = height / 2 return function(x, y) local rot_x = rot * (x - y) local rot_y = rot * (x + y) - return math.abs(rot_x) < width and math.abs(rot_y) < height + return abs(rot_x) < width and abs(rot_y) < height end end @@ -113,7 +126,6 @@ function Builders.oval(x_radius, y_radius) end end -local tau = math.tau function Builders.sine_fill(width, height) local width_inv = tau / width local height_inv = -2 / height @@ -121,9 +133,9 @@ function Builders.sine_fill(width, height) local x2 = x * width_inv local y2 = y * height_inv if y <= 0 then - return y2 < math.sin(x2) + return y2 < sin(x2) else - return y2 > math.sin(x2) + return y2 > sin(x2) end end end @@ -134,9 +146,9 @@ function Builders.sine_wave(width, height, thickness) thickness = thickness * 0.5 return function(x, y) local x2 = x * width_inv - local y2 = math.sin(x2) + local y2 = sin(x2) y = y * height_inv - local d = math.abs(y2 - y) + local d = abs(y2 - y) return d < thickness end @@ -149,8 +161,8 @@ function Builders.rectangular_spiral(x_size, optional_y_size) optional_y_size = 1 / optional_y_size return function(x, y) x, y = x * x_size, y * optional_y_size - x, y = math.floor(x + 0.5), math.floor(y + 0.5) - local a = -math.max(math.abs(x), math.abs(y)) + x, y = floor(x + 0.5), floor(y + 0.5) + local a = -max(abs(x), abs(y)) -- because of absolutes, it's faster to use max than an if..then..else if a % 2 == 0 then return y ~= a or x == a @@ -163,9 +175,9 @@ end function Builders.circular_spiral(in_thickness, total_thickness) local half_total_thickness = total_thickness * 0.5 return function(x, y) - local d = math.sqrt(x * x + y * y) + local d = sqrt(x * x + y * y) - local angle = 1 + inv_pi * math.atan2(x, y) + local angle = 1 + inv_pi * atan2(x, y) local offset = d + (angle * half_total_thickness) return offset % total_thickness < in_thickness @@ -176,14 +188,14 @@ function Builders.circular_spiral_grow(in_thickness, total_thickness, grow_facto local half_total_thickness = total_thickness * 0.5 local inv_grow_factor = 1 / grow_factor return function(x, y) - local d = math.sqrt(x * x + y * y) + local d = sqrt(x * x + y * y) local factor = (d * inv_grow_factor) + 1 local total_thickness2 = total_thickness * factor local in_thickness2 = in_thickness * factor local half_total_thickness2 = half_total_thickness * factor - local angle = 1 + inv_pi * math.atan2(x, y) + local angle = 1 + inv_pi * atan2(x, y) local offset = d + (angle * half_total_thickness2) return offset % total_thickness2 < in_thickness2 @@ -193,9 +205,9 @@ end function Builders.circular_spiral_n_threads(in_thickness, total_thickness, n_threads) local half_total_thickness = total_thickness * 0.5 * n_threads return function(x, y) - local d = math.sqrt(x * x + y * y) + local d = sqrt(x * x + y * y) - local angle = 1 + inv_pi * math.atan2(x, y) + local angle = 1 + inv_pi * atan2(x, y) local offset = d + (angle * half_total_thickness) return offset % total_thickness < in_thickness @@ -206,14 +218,14 @@ function Builders.circular_spiral_grow_n_threads(in_thickness, total_thickness, local half_total_thickness = total_thickness * 0.5 * n_threads local inv_grow_factor = 1 / grow_factor return function(x, y) - local d = math.sqrt(x * x + y * y) + local d = sqrt(x * x + y * y) local factor = (d * inv_grow_factor) + 1 local total_thickness2 = total_thickness * factor local in_thickness2 = in_thickness * factor local half_total_thickness2 = half_total_thickness * factor - local angle = 1 + inv_pi * math.atan2(x, y) + local angle = 1 + inv_pi * atan2(x, y) local offset = d + (angle * half_total_thickness2) return offset % total_thickness2 < in_thickness2 @@ -288,11 +300,11 @@ function Builders.picture(pic) local height = pic.height -- the plus one is because lua tables are one based. - local half_width = math.floor(width / 2) + 1 - local half_height = math.floor(height / 2) + 1 + local half_width = floor(width / 2) + 1 + local half_height = floor(height / 2) + 1 return function(x, y) - x = math.floor(x) - y = math.floor(y) + x = floor(x) + y = floor(y) local x2 = x + half_width local y2 = y + half_height @@ -323,8 +335,8 @@ function Builders.scale(shape, x_scale, y_scale) end function Builders.rotate(shape, angle) - local qx = math.cos(angle) - local qy = math.sin(angle) + local qx = cos(angle) + local qy = sin(angle) return function(x, y, world) local rot_x = qx * x - qy * y local rot_y = qy * x + qx * y @@ -507,8 +519,8 @@ end function Builders.linear_grow(shape, size) return function(x, y, world) - local t = math.ceil((y / size) + 0.5) - local n = math.ceil((math.sqrt(8 * t + 1) - 1) / 2) + local t = ceil((y / size) + 0.5) + local n = ceil((sqrt(8 * t + 1) - 1) / 2) local t_upper = n * (n + 1) * 0.5 local t_lower = t_upper - n @@ -522,9 +534,15 @@ end function Builders.grow(in_shape, out_shape, size, offset) local half_size = size / 2 return function(x, y, world) - local tx = math.ceil(math.abs(x) / half_size) - local ty = math.ceil(math.abs(y) / half_size) - local t = math.max(tx, ty) + local tx = ceil(abs(x) / half_size) + local ty = ceil(abs(y) / half_size) + + local t + if tx > ty then + t = tx + else + t = ty + end for i = t, 2.5 * t, 1 do local out_t = 1 / (i - offset) @@ -545,15 +563,15 @@ function Builders.grow(in_shape, out_shape, size, offset) end function Builders.project(shape, size, r) - local ln_r = math.log(r) + local ln_r = log(r) local r2 = 1 / (r - 1) local a = 1 / size return function(x, y, world) local offset = 0.5 * size - local sn = math.ceil(y + offset) + local sn = ceil(y + offset) - local n = math.ceil(math.log((r - 1) * sn * a + 1) / ln_r - 1) + local n = ceil(log((r - 1) * sn * a + 1) / ln_r - 1) local rn = r ^ n local rn2 = 1 / rn local c = size * rn @@ -567,16 +585,16 @@ function Builders.project(shape, size, r) end function Builders.project_pattern(pattern, size, r, columns, rows) - local ln_r = math.log(r) + local ln_r = log(r) local r2 = 1 / (r - 1) local a = 1 / size local half_size = size / 2 return function(x, y, world) local offset = 0.5 * size - local sn = math.ceil(y + offset) + local sn = ceil(y + offset) - local n = math.ceil(math.log((r - 1) * sn * a + 1) / ln_r - 1) + local n = ceil(log((r - 1) * sn * a + 1) / ln_r - 1) local rn = r ^ n local rn2 = 1 / rn local c = size * rn @@ -589,7 +607,7 @@ function Builders.project_pattern(pattern, size, r, columns, rows) local row = pattern[row_i] local x2 = ((x + half_size) % size) - half_size - local col_pos = math.floor(x / size + 0.5) + local col_pos = floor(x / size + 0.5) local col_i = col_pos % columns + 1 local shape = row[col_i] @@ -599,15 +617,15 @@ function Builders.project_pattern(pattern, size, r, columns, rows) end function Builders.project_overlap(shape, size, r) - local ln_r = math.log(r) + local ln_r = log(r) local r2 = 1 / (r - 1) local a = 1 / size local offset = 0.5 * size return function(x, y, world) - local sn = math.ceil(y + offset) + local sn = ceil(y + offset) - local n = math.ceil(math.log((r - 1) * sn * a + 1) / ln_r - 1) + local n = ceil(log((r - 1) * sn * a + 1) / ln_r - 1) local rn = r ^ n local rn2 = 1 / rn local c = size * rn @@ -796,7 +814,7 @@ function Builders.grid_x_pattern(pattern, columns, width) return function(x, y, world) local x2 = ((x + half_width) % width) - half_width - local columns_pos = math.floor(x / width + 0.5) + local columns_pos = floor(x / width + 0.5) local column_i = columns_pos % columns + 1 local shape = pattern[column_i] or Builders.empty_shape @@ -809,7 +827,7 @@ function Builders.grid_y_pattern(pattern, rows, height) return function(x, y, world) local y2 = ((y + half_height) % height) - half_height - local row_pos = math.floor(y / height + 0.5) + local row_pos = floor(y / height + 0.5) local row_i = row_pos % rows + 1 local shape = pattern[row_i] or Builders.empty_shape @@ -823,12 +841,12 @@ function Builders.grid_pattern(pattern, columns, rows, width, height) return function(x, y, world) local y2 = ((y + half_height) % height) - half_height - local row_pos = math.floor(y / height + 0.5) + local row_pos = floor(y / height + 0.5) local row_i = row_pos % rows + 1 local row = pattern[row_i] or {} local x2 = ((x + half_width) % width) - half_width - local col_pos = math.floor(x / width + 0.5) + local col_pos = floor(x / width + 0.5) local col_i = col_pos % columns + 1 local shape = row[col_i] or Builders.empty_shape @@ -842,12 +860,12 @@ function Builders.grid_pattern_overlap(pattern, columns, rows, width, height) return function(x, y, world) local y2 = ((y + half_height) % height) - half_height - local row_pos = math.floor(y / height + 0.5) + local row_pos = floor(y / height + 0.5) local row_i = row_pos % rows + 1 local row = pattern[row_i] or {} local x2 = ((x + half_width) % width) - half_width - local col_pos = math.floor(x / width + 0.5) + local col_pos = floor(x / width + 0.5) local col_i = col_pos % columns + 1 local shape = row[col_i] or Builders.empty_shape @@ -893,12 +911,12 @@ function Builders.grid_pattern_full_overlap(pattern, columns, rows, width, heigh return function(x, y, world) local y2 = ((y + half_height) % height) - half_height - local row_pos = math.floor(y / height + 0.5) + local row_pos = floor(y / height + 0.5) local row_i = row_pos % rows + 1 local row = pattern[row_i] or {} local x2 = ((x + half_width) % width) - half_width - local col_pos = math.floor(x / width + 0.5) + local col_pos = floor(x / width + 0.5) local col_i = col_pos % columns + 1 local row_i_up = (row_pos - 1) % rows + 1 @@ -969,13 +987,13 @@ function Builders.circular_pattern(shape, quantity, radius) local angle = tau / quantity for i = 1, quantity do local shape2 = Builders.rotate(Builders.translate(shape, 0, radius), i * angle) - table.insert(pattern, shape2) + insert(pattern, shape2) end return Builders.any(pattern) end local function is_spiral(x, y) - local a = -math.max(math.abs(x), math.abs(y)) + local a = -max(abs(x), abs(y)) -- because of absolutes, it's faster to use max than an if..then..else if a % 2 == 0 then return y ~= a or x == a @@ -988,8 +1006,8 @@ function Builders.single_spiral_pattern(shape, width, height) local inv_width = 1 / width local inv_height = 1 / height return function(x, y, world) - local x1 = math.floor(x * inv_width + 0.5) - local y1 = math.floor(y * inv_height + 0.5) + local x1 = floor(x * inv_width + 0.5) + local y1 = floor(y * inv_height + 0.5) if is_spiral(x1, y1) then x1 = x - x1 * width @@ -1018,7 +1036,7 @@ local function rotate_270(x, y) end local function spiral_rotation(x, y) - local a = -math.max(math.abs(x), math.abs(y)) + local a = -max(abs(x), abs(y)) -- because of absolutes, it's faster to use max than an if..then..else if a % 2 == 0 then if y ~= a or x == a then @@ -1043,8 +1061,8 @@ function Builders.single_spiral_rotate_pattern(shape, width, optional_height) local inv_width = 1 / width local inv_height = 1 / optional_height return function(x, y, world) - local x1 = math.floor(x * inv_width + 0.5) - local y1 = math.floor(y * inv_height + 0.5) + local x1 = floor(x * inv_width + 0.5) + local y1 = floor(y * inv_height + 0.5) local t = spiral_rotation(x1, y1) if t then @@ -1064,9 +1082,9 @@ function Builders.circular_spiral_pattern(in_thickness, total_thickness, pattern local half_total_thickness = total_thickness * 0.5 local delta = total_thickness / n_threads return function(x, y, world) - local d = math.sqrt(x * x + y * y) + local d = sqrt(x * x + y * y) - local angle = 1 + inv_pi * math.atan2(x, y) + local angle = 1 + inv_pi * atan2(x, y) local offset = d + (angle * half_total_thickness) if offset % total_thickness < in_thickness then @@ -1091,7 +1109,7 @@ function Builders.circular_spiral_grow_pattern(in_thickness, total_thickness, gr local inv_grow_factor = 1 / grow_factor local delta = total_thickness / n_threads return function(x, y, world) - local d = math.sqrt(x * x + y * y) + local d = sqrt(x * x + y * y) local factor = (d * inv_grow_factor) + 1 local total_thickness2 = total_thickness * factor @@ -1099,7 +1117,7 @@ function Builders.circular_spiral_grow_pattern(in_thickness, total_thickness, gr local half_total_thickness2 = half_total_thickness * factor local delta2 = delta * factor - local angle = 1 + inv_pi * math.atan2(x, y) + local angle = 1 + inv_pi * atan2(x, y) local offset = d + (angle * half_total_thickness2) if offset % total_thickness2 < in_thickness2 then @@ -1121,8 +1139,8 @@ function Builders.segment_pattern(pattern) local count = #pattern return function(x, y, world) - local angle = math.atan2(-y, x) - local index = math.floor(angle / tau * count) % count + 1 + local angle = atan2(-y, x) + local index = floor(angle / tau * count) % count + 1 local shape = pattern[index] or Builders.empty_shape return shape(x, y, world) end @@ -1134,7 +1152,7 @@ function Builders.pyramid_pattern(pattern, columns, rows, width, height) return function(x, y, world) local y2 = ((y + half_height) % height) - half_height - local row_pos = math.floor(y / height + 0.5) + local row_pos = floor(y / height + 0.5) local row_i = row_pos % rows + 1 local row = pattern[row_i] or {} @@ -1143,7 +1161,7 @@ function Builders.pyramid_pattern(pattern, columns, rows, width, height) end local x2 = ((x + half_width) % width) - half_width - local col_pos = math.floor(x / width + 0.5) + local col_pos = floor(x / width + 0.5) local col_i = col_pos % columns + 1 if col_pos > row_pos / 2 or -col_pos > (row_pos + 1) / 2 then @@ -1161,7 +1179,7 @@ function Builders.pyramid_pattern_inner_overlap(pattern, columns, rows, width, h return function(x, y, world) local y2 = ((y + half_height) % height) - half_height - local row_pos = math.floor(y / height + 0.5) + local row_pos = floor(y / height + 0.5) local row_i = row_pos % rows + 1 local row = pattern[row_i] or {} @@ -1179,7 +1197,7 @@ function Builders.pyramid_pattern_inner_overlap(pattern, columns, rows, width, h x_even = ((x_even + half_width) % width) - half_width x_odd = ((x_odd + half_width) % width) - half_width - local col_pos = math.floor(x / width + 0.5) + local col_pos = floor(x / width + 0.5) local offset = 1 local offset_odd = 0 @@ -1263,16 +1281,16 @@ function Builders.grid_pattern_offset(pattern, columns, rows, width, height) return function(x, y, world) local y2 = ((y + half_height) % height) - half_height - local row_pos = math.floor(y / height + 0.5) + local row_pos = floor(y / height + 0.5) local row_i = row_pos % rows + 1 local row = pattern[row_i] or {} local x2 = ((x + half_width) % width) - half_width - local col_pos = math.floor(x / width + 0.5) + local col_pos = floor(x / width + 0.5) local col_i = col_pos % columns + 1 - y2 = y2 + height * math.floor((row_pos + 1) / rows) - x2 = x2 + width * math.floor((col_pos + 1) / columns) + y2 = y2 + height * floor((row_pos + 1) / rows) + x2 = x2 + width * floor((col_pos + 1) / columns) local shape = row[col_i] or Builders.empty_shape return shape(x2, y2, world) @@ -1517,11 +1535,11 @@ function Builders.fish(shape, spawn_rate) return function(x, y, world) local function handle_tile(tile) if type(tile) == 'string' then - if water_tiles[tile] and spawn_rate >= math.random() then + if water_tiles[tile] and spawn_rate >= random() then return {name = 'fish'} end elseif tile then - if world.surface.get_tile(world.x, world.y).collides_with('water-tile') and spawn_rate >= math.random() then + if world.surface.get_tile(world.x, world.y).collides_with('water-tile') and spawn_rate >= random() then return {name = 'fish'} end end @@ -1562,13 +1580,13 @@ end function Builders.manhattan_value(base, mult) return function(x, y) - return mult * (math.abs(x) + math.abs(y)) + base + return mult * (abs(x) + abs(y)) + base end end function Builders.euclidean_value(base, mult) return function(x, y) - return mult * math.sqrt(x * x + y * y) + base + return mult * sqrt(x * x + y * y) + base end end @@ -1585,7 +1603,7 @@ function Builders.prepare_weighted_array(array) for _, v in ipairs(array) do total = total + v.weight - table.insert(weights, total) + insert(weights, total) end weights.total = total