diff --git a/worldeditadditions/lib/airapply.lua b/worldeditadditions/lib/airapply.lua index 99236bb..1de83fa 100644 --- a/worldeditadditions/lib/airapply.lua +++ b/worldeditadditions/lib/airapply.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + -- █████ ██ ██████ -- ██ ██ ██ ██ ██ -- ███████ ██ ██████ @@ -17,17 +20,17 @@ -- @param {Position} pos2 The 2nd positioon defining the region boundary -- @param {Function} func The function to call that performs the action in question. It is expected that the given function will accept no arguments. function worldeditadditions.airapply(pos1, pos2, func) - local time_taken_all = worldeditadditions.get_ms_time() - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + local time_taken_all = wea_c.get_ms_time() + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- Fetch the nodes in the specified area local manip_before, area_before = worldedit.manip_helpers.init(pos1, pos2) local data_before = manip_before:get_data() - local time_taken_fn = worldeditadditions.get_ms_time() + local time_taken_fn = wea_c.get_ms_time() func() - time_taken_fn = worldeditadditions.get_ms_time() - time_taken_fn + time_taken_fn = wea_c.get_ms_time() - time_taken_fn local manip_after, area_after = worldedit.manip_helpers.init(pos1, pos2) local data_after = manip_after:get_data() @@ -37,7 +40,7 @@ function worldeditadditions.airapply(pos1, pos2, func) for x = pos2.x, pos1.x, -1 do local i_before = area_before:index(x, y, z) local i_after = area_after:index(x, y, z) - local old_is_airlike = worldeditadditions.is_airlike(data_before[i_before]) + local old_is_airlike = wea_c.is_airlike(data_before[i_before]) -- Roll everything that replaces nodes that aren't airlike if not old_is_airlike then @@ -52,6 +55,6 @@ function worldeditadditions.airapply(pos1, pos2, func) worldedit.manip_helpers.finish(manip_after, data_after) - time_taken_all = worldeditadditions.get_ms_time() - time_taken_all + time_taken_all = wea_c.get_ms_time() - time_taken_all return true, { all = time_taken_all, fn = time_taken_fn } end diff --git a/worldeditadditions/lib/bonemeal.lua b/worldeditadditions/lib/bonemeal.lua index 31e4682..86f4c36 100644 --- a/worldeditadditions/lib/bonemeal.lua +++ b/worldeditadditions/lib/bonemeal.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + --- Bonemeal command. -- Applies bonemeal to all notes -- @module worldeditadditions.overlay @@ -6,7 +9,7 @@ -- chance Positive integer that represents the chance bonemealing will occur function worldeditadditions.bonemeal(pos1, pos2, strength, chance, nodename_list) if not nodename_list then nodename_list = {} end - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- This command requires the bonemeal mod to be installed @@ -15,7 +18,7 @@ function worldeditadditions.bonemeal(pos1, pos2, strength, chance, nodename_list return false, "Bonemeal mod not loaded" end - local node_list = worldeditadditions.table.map(nodename_list, function(nodename) + local node_list = wea_c.table.map(nodename_list, function(nodename) return minetest.get_content_id(nodename) end) local node_list_count = #nodename_list @@ -34,9 +37,9 @@ function worldeditadditions.bonemeal(pos1, pos2, strength, chance, nodename_list for x = pos2.x, pos1.x, -1 do for y = pos2.y, pos1.y, -1 do local i = area:index(x, y, z) - if not worldeditadditions.is_airlike(data[i]) then + if not wea_c.is_airlike(data[i]) then local should_bonemeal = true - if node_list_count > 0 and not worldeditadditions.table.contains(node_list, data[i]) then + if node_list_count > 0 and not wea_c.table.contains(node_list, data[i]) then should_bonemeal = false end @@ -45,7 +48,7 @@ function worldeditadditions.bonemeal(pos1, pos2, strength, chance, nodename_list if should_bonemeal and math.random(0, chance - 1) == 0 then bonemeal:on_use( - { x = x, y = y, z = z }, + Vector3.new(x, y, z), strength, nil ) diff --git a/worldeditadditions/lib/copy.lua b/worldeditadditions/lib/copy.lua index b0c19bf..366f1a0 100644 --- a/worldeditadditions/lib/copy.lua +++ b/worldeditadditions/lib/copy.lua @@ -1,9 +1,9 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + --- Copies a region to another location, potentially overwriting the exiting region. -- @module worldeditadditions.copy -local wea = worldeditadditions -local Vector3 = wea.Vector3 - -- ██████ ██████ ██████ ██ ██ -- ██ ██ ██ ██ ██ ██ ██ -- ██ ██ ██ ██████ ████ @@ -32,7 +32,7 @@ function worldeditadditions.copy(source_pos1, source_pos2, target_pos1, target_p for x = source_pos2.x, source_pos1.x, -1 do local source = Vector3.new(x, y, z) local source_i = area_source:index(x, y, z) - local target = source:subtract(offset) + local target = source - offset local target_i = area_target:index(target.x, target.y, target.z) data_target[target_i] = data_source[source_i] diff --git a/worldeditadditions/lib/count.lua b/worldeditadditions/lib/count.lua index 3e11ec6..6901b62 100644 --- a/worldeditadditions/lib/count.lua +++ b/worldeditadditions/lib/count.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + --- Counts the nodes in a given area. -- @module worldeditadditions.count @@ -7,7 +10,7 @@ -- ██ ██ ██ ██ ██ ██ ██ ██ ██ -- ██████ ██████ ██████ ██ ████ ██ function worldeditadditions.count(pos1, pos2, do_human_counts) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- Fetch the nodes in the specified area @@ -29,7 +32,7 @@ function worldeditadditions.count(pos1, pos2, do_human_counts) for node_name, count in pairs(counts) do table.insert(results, { count, - tostring(worldeditadditions.round((count / total) * 100, 2)).."%", + tostring(wea_c.round((count / total) * 100, 2)).."%", minetest.get_name_from_content_id(node_name) }) end @@ -37,7 +40,7 @@ function worldeditadditions.count(pos1, pos2, do_human_counts) if do_human_counts then for key,item in pairs(results) do - item[1] = worldeditadditions.format.human_size(item[1], 2) + item[1] = wea_c.format.human_size(item[1], 2) end end diff --git a/worldeditadditions/lib/dome.lua b/worldeditadditions/lib/dome.lua index fa94a4d..a51a440 100644 --- a/worldeditadditions/lib/dome.lua +++ b/worldeditadditions/lib/dome.lua @@ -1,5 +1,5 @@ -local wea = worldeditadditions -local Vector3 = wea.Vector3 +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 -- ██████ ██████ ███ ███ ███████ -- ██ ██ ██ ██ ████ ████ ██ @@ -11,7 +11,7 @@ local Vector3 = wea.Vector3 -- @param pos Vector3 The central point to start drawing the dome from. -- @param radius number The radius of the dome to create. -- @param replace_node string The fully qualified name of the node to use to make the dome with. --- @param pointing_dir Vector3 Optional. The direction the dome should point. Defaults to (0, 1, 0). See also wea.parse.axis_name. +-- @param pointing_dir Vector3 Optional. The direction the dome should point. Defaults to (0, 1, 0). See also wea_c.parse.axis_name. -- @param hollow boolean Whether to make the dome hollow or not. Defaults to false. function worldeditadditions.dome(pos, radius, replace_node, pointing_dir, hollow) pos = Vector3.clone(pos) diff --git a/worldeditadditions/lib/ellipsoid.lua b/worldeditadditions/lib/ellipsoid.lua index 235c4e2..36c883b 100644 --- a/worldeditadditions/lib/ellipsoid.lua +++ b/worldeditadditions/lib/ellipsoid.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + -- ███████ ██ ██ ██ ██████ ███████ ███████ -- ██ ██ ██ ██ ██ ██ ██ ██ -- █████ ██ ██ ██ ██████ ███████ █████ @@ -13,12 +16,9 @@ -- @param hollow bool Whether the ellipsoid should be hollow or not. -- @returns number The number of nodes filled to create the (optionally hollow) ellipsoid. This number will be lower with hollow ellipsoids, since the internals of an ellipsoid aren't altered. function worldeditadditions.ellipsoid(position, radius, target_node, hollow) + radius = Vector3.clone(radius) -- position = { x, y, z } - local hollow_inner_radius = { - x = radius.x - 1, - y = radius.y - 1, - z = radius.z - 1 - } + local hollow_inner_radius = radius - 1 -- Fetch the nodes in the specified area -- OPTIMIZE: We should be able to calculate a more efficient box-area here @@ -39,21 +39,19 @@ function worldeditadditions.ellipsoid(position, radius, target_node, hollow) local i = idx_y_base for x = -radius.x, radius.x do - + local here = Vector3.new(x, y, z) -- If we're inside the ellipse, then fill it in - local x_comp, y_comp, z_comp = x/radius.x, y/radius.y, z/radius.z - local ellipsoid_dist = x_comp*x_comp + y_comp*y_comp + z_comp*z_comp + local comp = here / radius + + local ellipsoid_dist = Vector3.dot(comp, comp) if ellipsoid_dist <= 1 then local place_ok = not hollow; if not place_ok then -- It must be hollow! Do some additional calculations. - local hx_comp = x/hollow_inner_radius.x - local hy_comp = y/hollow_inner_radius.y - local hz_comp = z/hollow_inner_radius.z - + local h_comp = here / hollow_inner_radius -- It's only ok to place it if it's outside our inner ellipse - place_ok = hx_comp*hx_comp + hy_comp*hy_comp + hz_comp*hz_comp >= 1 + place_ok = Vector3.dot(h_comp, h_comp) >= 1 end if place_ok then diff --git a/worldeditadditions/lib/ellipsoid2.lua b/worldeditadditions/lib/ellipsoid2.lua index bf5c90d..79c472a 100644 --- a/worldeditadditions/lib/ellipsoid2.lua +++ b/worldeditadditions/lib/ellipsoid2.lua @@ -1,4 +1,5 @@ -local wea = worldeditadditions +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 -- ███████ ██ ██ ██ ██████ ███████ ███████ -- ██ ██ ██ ██ ██ ██ ██ ██ @@ -8,21 +9,17 @@ local wea = worldeditadditions function worldeditadditions.ellipsoid2(pos1, pos2, target_node, hollow) - pos1, pos2 = wea.Vector3.sort(pos1, pos2) - local volume = pos2:subtract(pos1) - local volume_half = volume:divide(2) + pos1, pos2 = Vector3.sort(pos1, pos2) + local volume = pos2 - pos1 + local volume_half = volume / 2 - local radius = pos2:subtract(pos1):divide(2) + local radius = (pos2 - pos1) / 2 print("DEBUG:ellipsoid2 | pos1: "..pos1..", pos2: "..pos2..", target_node: "..target_node) print("DEBUG:ellipsoid2 radius", radius) -- position = { x, y, z } - local hollow_inner_radius = { - x = radius.x - 1, - y = radius.y - 1, - z = radius.z - 1 - } + local hollow_inner_radius = radius - 1 -- Fetch the nodes in the specified area local manip, area = worldedit.manip_helpers.init(pos1, pos2) @@ -35,26 +32,23 @@ function worldeditadditions.ellipsoid2(pos1, pos2, target_node, hollow) for z = pos2.z, pos1.z, -1 do for y = pos2.y, pos1.y, -1 do for x = pos2.x, pos1.x, -1 do - - local pos_relative = wea.Vector3.new(x, y, z):subtract(pos1) - :subtract(volume_half) + local here = Vector3.new(x, y, z) + local pos_relative = (here - pos1) - volume_half print("DEBUG pos1", pos1, "pos2", pos2, "volume_half", volume_half, "pos_relative", pos_relative) -- If we're inside the ellipse, then fill it in - local comp = pos_relative:divide(radius) + local comp = pos_relative / radius local ellipsoid_dist = comp:length_squared() if ellipsoid_dist <= 1 then local place_ok = not hollow; if not place_ok then -- It must be hollow! Do some additional calculations. - local hx_comp = x/hollow_inner_radius.x - local hy_comp = y/hollow_inner_radius.y - local hz_comp = z/hollow_inner_radius.z + local h_comp = here / hollow_inner_radius -- It's only ok to place it if it's outside our inner ellipse - place_ok = hx_comp*hx_comp + hy_comp*hy_comp + hz_comp*hz_comp >= 1 + place_ok = Vector3.dot(h_comp, h_comp) >= 1 end if place_ok then diff --git a/worldeditadditions/lib/ellipsoidapply.lua b/worldeditadditions/lib/ellipsoidapply.lua index 6012721..bced55e 100644 --- a/worldeditadditions/lib/ellipsoidapply.lua +++ b/worldeditadditions/lib/ellipsoidapply.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + -- ███████ ██ ██ ██ ██████ ███████ ██████ ██ ██████ -- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ -- █████ ██ ██ ██ ██████ ███████ ██ ██ ██ ██ ██ @@ -17,40 +20,29 @@ -- @param {Position} pos2 The 2nd positioon defining the region boundary -- @param {Function} func The function to call that performs the action in question. It is expected that the given function will accept no arguments. function worldeditadditions.ellipsoidapply(pos1, pos2, func) - local time_taken_all = worldeditadditions.get_ms_time() - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + local time_taken_all = wea_c.get_ms_time() + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- Fetch the nodes in the specified area local manip_before, area_before = worldedit.manip_helpers.init(pos1, pos2) local data_before = manip_before:get_data() - local time_taken_fn = worldeditadditions.get_ms_time() + local time_taken_fn = wea_c.get_ms_time() func() - time_taken_fn = worldeditadditions.get_ms_time() - time_taken_fn + time_taken_fn = wea_c.get_ms_time() - time_taken_fn local manip_after, area_after = worldedit.manip_helpers.init(pos1, pos2) local data_after = manip_after:get_data() - local radius = { - x = (pos2.x - pos1.x) / 2, - y = (pos2.y - pos1.y) / 2, - z = (pos2.z - pos1.z) / 2 - } - local e_centre = { - x = pos2.x - radius.x, - y = pos2.y - radius.y, - z = pos2.z - radius.z - } + local radius = (pos2 - pos1) / 2 + local e_centre = pos2 - radius for z = pos2.z, pos1.z, -1 do for y = pos2.y, pos1.y, -1 do for x = pos2.x, pos1.x, -1 do - local x_comp = (x - e_centre.x) / radius.x - local y_comp = (y - e_centre.y) / radius.y - local z_comp = (z - e_centre.z) / radius.z - - local distance_mult = x_comp*x_comp + y_comp*y_comp + z_comp*z_comp + local comp = (Vector3.new(x, y, z) - e_centre) / radius + local distance_mult = Vector3.dot(comp, comp) -- Roll everything that's outside the ellipse back if distance_mult > 1 then @@ -65,6 +57,6 @@ function worldeditadditions.ellipsoidapply(pos1, pos2, func) worldedit.manip_helpers.finish(manip_after, data_after) - time_taken_all = worldeditadditions.get_ms_time() - time_taken_all + time_taken_all = wea_c.get_ms_time() - time_taken_all return true, { all = time_taken_all, fn = time_taken_fn } end diff --git a/worldeditadditions/lib/fillcaves.lua b/worldeditadditions/lib/fillcaves.lua index 5a1706f..d9cd201 100644 --- a/worldeditadditions/lib/fillcaves.lua +++ b/worldeditadditions/lib/fillcaves.lua @@ -1,8 +1,11 @@ ---- Overlap command. Places a specified node on top of each column. +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + +--- Fill caves command. Fills underneath non-air nodes in the defined region. -- @module worldeditadditions.overlay function worldeditadditions.fillcaves(pos1, pos2, node_name) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- Fetch the nodes in the specified area @@ -12,8 +15,8 @@ function worldeditadditions.fillcaves(pos1, pos2, node_name) local node_id_replace = minetest.get_content_id(node_name) local node_id_ignore = minetest.get_content_id("ignore") - -- minetest.log("action", "pos1: " .. worldeditadditions.vector.tostring(pos1)) - -- minetest.log("action", "pos2: " .. worldeditadditions.vector.tostring(pos2)) + -- minetest.log("action", "pos1: " .. pos1) + -- minetest.log("action", "pos2: " .. pos2) -- z y x is the preferred loop order, but that isn't really possible here @@ -27,7 +30,7 @@ function worldeditadditions.fillcaves(pos1, pos2, node_name) for y = pos2.y, pos1.y, -1 do local i = area:index(x, y, z) - local is_air = worldeditadditions.is_airlike(data[i]) or worldeditadditions.is_liquidlike(data[i]) + local is_air = wea_c.is_airlike(data[i]) or wea_c.is_liquidlike(data[i]) local is_ignore = data[i] == node_id_ignore -- If the previous node was air and this one isn't, then we've found the top level diff --git a/worldeditadditions/lib/floodfill.lua b/worldeditadditions/lib/floodfill.lua index e1b5691..3f8ec07 100644 --- a/worldeditadditions/lib/floodfill.lua +++ b/worldeditadditions/lib/floodfill.lua @@ -1,13 +1,18 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + + --- Flood-fill command for complex lakes etc. -- @module worldeditadditions.floodfill -local wea = worldeditadditions function worldeditadditions.floodfill(start_pos, radius, replace_node) + start_pos = Vector3.clone(start_pos) + -- Calculate the area we want to modify - local pos1 = vector.add(start_pos, { x = radius, y = 0, z = radius }) - local pos2 = vector.subtract(start_pos, { x = radius, y = radius, z = radius }) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + local pos1 = start_pos + Vector3.new(radius, 0, radius) + local pos2 = start_pos - Vector3.new(radius, radius, radius) + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now @@ -27,7 +32,7 @@ function worldeditadditions.floodfill(start_pos, radius, replace_node) end local count = 0 - local remaining_nodes = wea.Queue.new() remaining_nodes:enqueue(start_pos_index) + local remaining_nodes = wea_c.Queue.new() remaining_nodes:enqueue(start_pos_index) -- Do the floodfill while remaining_nodes:is_empty() == false do @@ -41,35 +46,35 @@ function worldeditadditions.floodfill(start_pos, radius, replace_node) -- We don't need to go upwards here, since we're filling in lake-style local xplus = cur + 1 -- +X if data[xplus] == search_id and - worldeditadditions.vector.lengthsquared(vector.subtract(area:position(xplus), start_pos)) < radius_sq and + (Vector3.clone(area:position(xplus)) - start_pos):length_squared() < radius_sq and not remaining_nodes:contains(xplus) then -- minetest.log("action", "[floodfill] [+X] index " .. xplus .. " is a " .. data[xplus] .. ", searching for a " .. search_id) remaining_nodes:enqueue(xplus) end local xminus = cur - 1 -- -X if data[xminus] == search_id and - worldeditadditions.vector.lengthsquared(vector.subtract(area:position(xminus), start_pos)) < radius_sq and + (Vector3.new(area:position(xminus)) - start_pos):length_squared() < radius_sq and not remaining_nodes:contains(xminus) then -- minetest.log("action", "[floodfill] [-X] index " .. xminus .. " is a " .. data[xminus] .. ", searching for a " .. search_id) remaining_nodes:enqueue(xminus) end local zplus = cur + area.zstride -- +Z if data[zplus] == search_id and - worldeditadditions.vector.lengthsquared(vector.subtract(area:position(zplus), start_pos)) < radius_sq and + (Vector3.new(area:position(zplus)) - start_pos):length_squared() < radius_sq and not remaining_nodes:contains(zplus) then -- minetest.log("action", "[floodfill] [+Z] index " .. zplus .. " is a " .. data[zplus] .. ", searching for a " .. search_id) remaining_nodes:enqueue(zplus) end local zminus = cur - area.zstride -- -Z if data[zminus] == search_id and - worldeditadditions.vector.lengthsquared(vector.subtract(area:position(zminus), start_pos)) < radius_sq and + (Vector3.new(area:position(zminus)) - start_pos):length_squared() < radius_sq and not remaining_nodes:contains(zminus) then -- minetest.log("action", "[floodfill] [-Z] index " .. zminus .. " is a " .. data[zminus] .. ", searching for a " .. search_id) remaining_nodes:enqueue(zminus) end local yminus = cur - area.ystride -- -Y if data[yminus] == search_id and - worldeditadditions.vector.lengthsquared(vector.subtract(area:position(yminus), start_pos)) < radius_sq and + (Vector3.new(area:position(yminus)) - start_pos):length_squared() < radius_sq and not remaining_nodes:contains(yminus) then -- minetest.log("action", "[floodfill] [-Y] index " .. yminus .. " is a " .. data[yminus] .. ", searching for a " .. search_id) remaining_nodes:enqueue(yminus) diff --git a/worldeditadditions/lib/forest.lua b/worldeditadditions/lib/forest.lua index c0d3022..104f0b0 100644 --- a/worldeditadditions/lib/forest.lua +++ b/worldeditadditions/lib/forest.lua @@ -1,9 +1,12 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + --- Overlap command. Places a specified node on top of each column. -- @module worldeditadditions.layers function worldeditadditions.forest(pos1, pos2, density_multiplier, sapling_weights) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) local weight_total = 0 for _name,weight in pairs(sapling_weights) do @@ -33,7 +36,7 @@ function worldeditadditions.forest(pos1, pos2, density_multiplier, sapling_weigh local i = area:index(x, y, z) local node_id = data[i] if not group_cache[node_id] then - group_cache[node_id] = worldeditadditions.is_sapling(node_id) + group_cache[node_id] = wea_c.is_sapling(node_id) end if group_cache[node_id] then @@ -50,7 +53,7 @@ function worldeditadditions.forest(pos1, pos2, density_multiplier, sapling_weigh new_name_at_pos = minetest.get_node({ z = z, y = y, x = x }).name new_id_at_pos = minetest.get_content_id(new_name_at_pos) if not group_cache[new_id_at_pos] then - group_cache[new_id_at_pos] = worldeditadditions.is_sapling(new_id_at_pos) + group_cache[new_id_at_pos] = wea_c.is_sapling(new_id_at_pos) end if not group_cache[new_id_at_pos] then did_grow = true @@ -84,7 +87,7 @@ function worldeditadditions.forest(pos1, pos2, density_multiplier, sapling_weigh for y = pos2.y, pos1.y, -1 do local i = area:index(x, y, z) if not group_cache[data[i]] then - group_cache[data[i]] = worldeditadditions.is_sapling(data[i]) + group_cache[data[i]] = wea_c.is_sapling(data[i]) end if group_cache[data[i]] then @@ -95,7 +98,7 @@ function worldeditadditions.forest(pos1, pos2, density_multiplier, sapling_weigh end stats.successes = #stats.attempts - stats.attempts_avg = worldeditadditions.average(stats.attempts) + stats.attempts_avg = wea_c.average(stats.attempts) -- Save the modified nodes back to disk & return worldedit.manip_helpers.finish(manip, data) diff --git a/worldeditadditions/lib/hollow.lua b/worldeditadditions/lib/hollow.lua index 74328fe..dc38d58 100644 --- a/worldeditadditions/lib/hollow.lua +++ b/worldeditadditions/lib/hollow.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + -- ██ ██ ██████ ██ ██ ██████ ██ ██ -- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ -- ███████ ██ ██ ██ ██ ██ ██ ██ █ ██ @@ -8,7 +11,7 @@ -- (think of the bits of the outermost parts of the defined region as the -- 'walls' to a box) function worldeditadditions.hollow(pos1, pos2, wall_thickness) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- Fetch the nodes in the specified area @@ -18,8 +21,8 @@ function worldeditadditions.hollow(pos1, pos2, wall_thickness) local node_id_ignore = minetest.get_content_id("ignore") local node_id_air = minetest.get_content_id("air") - -- minetest.log("action", "pos1: " .. worldeditadditions.vector.tostring(pos1)) - -- minetest.log("action", "pos2: " .. worldeditadditions.vector.tostring(pos2)) + -- minetest.log("action", "pos1: " ..pos1) + -- minetest.log("action", "pos2: " .. pos2) local changes = { replaced = 0 } for z = pos2.z - wall_thickness, pos1.z + wall_thickness, -1 do @@ -27,7 +30,7 @@ function worldeditadditions.hollow(pos1, pos2, wall_thickness) for x = pos2.x - wall_thickness, pos1.x + wall_thickness, -1 do local i = area:index(x, y, z) - local is_air = worldeditadditions.is_airlike(data[i]) + local is_air = wea_c.is_airlike(data[i]) local is_ignore = data[i] == node_id_ignore if not is_ignore and not is_air then diff --git a/worldeditadditions/lib/layers.lua b/worldeditadditions/lib/layers.lua index 8ace75f..100a826 100644 --- a/worldeditadditions/lib/layers.lua +++ b/worldeditadditions/lib/layers.lua @@ -1,18 +1,20 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + -- ██ █████ ██ ██ ███████ ██████ ███████ -- ██ ██ ██ ██ ██ ██ ██ ██ ██ -- ██ ███████ ████ █████ ██████ ███████ -- ██ ██ ██ ██ ██ ██ ██ ██ -- ███████ ██ ██ ██ ███████ ██ ██ ███████ -local wea = worldeditadditions local function print_slopes(slopemap, width) - local copy = wea.table.shallowcopy(slopemap) + local copy = wea_c.table.shallowcopy(slopemap) for key,value in pairs(copy) do - copy[key] = wea.round(math.deg(value), 2) + copy[key] = wea_c.round(math.deg(value), 2) end - worldeditadditions.format.array_2d(copy, width) + wea_c.format.array_2d(copy, width) end --- Replaces the non-air nodes in each column with a list of nodes from top to bottom. @@ -22,7 +24,7 @@ end -- @param min_slope number? -- @param max_slope number? function worldeditadditions.layers(pos1, pos2, node_weights, min_slope, max_slope) - pos1, pos2 = wea.Vector3.sort(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) if not min_slope then min_slope = math.rad(0) end if not max_slope then max_slope = math.rad(180) end -- pos2 will always have the highest co-ordinates now @@ -33,13 +35,13 @@ function worldeditadditions.layers(pos1, pos2, node_weights, min_slope, max_slop local node_id_ignore = minetest.get_content_id("ignore") - local node_ids, node_ids_count = wea.unwind_node_list(node_weights) + local node_ids, node_ids_count = wea_c.unwind_node_list(node_weights) - local heightmap, heightmap_size = wea.terrain.make_heightmap( + local heightmap, heightmap_size = wea_c.terrain.make_heightmap( pos1, pos2, manip, area, data ) - local slopemap = wea.terrain.calculate_slopes(heightmap, heightmap_size) + local slopemap = wea_c.terrain.calculate_slopes(heightmap, heightmap_size) -- worldeditadditions.format.array_2d(heightmap, heightmap_size.x) -- print_slopes(slopemap, heightmap_size.x) --luacheck:ignore 311 @@ -68,7 +70,7 @@ function worldeditadditions.layers(pos1, pos2, node_weights, min_slope, max_slop for y = pos2.y, pos1.y, -1 do local i = area:index(x, y, z) - local is_air = wea.is_airlike(data[i]) + local is_air = wea_c.is_airlike(data[i]) local is_ignore = data[i] == node_id_ignore if not is_air and not is_ignore then diff --git a/worldeditadditions/lib/line.lua b/worldeditadditions/lib/line.lua index 140bb58..ec82d6e 100644 --- a/worldeditadditions/lib/line.lua +++ b/worldeditadditions/lib/line.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_commands +local Vector3 = wea_c.Vector3 + --- Counts the nodes in a given area. -- @module worldeditadditions.count @@ -9,11 +12,11 @@ function worldeditadditions.line(pos1, pos2, thickness, node_name) - local pos1_sorted, pos2_sorted = worldedit.sort_pos(pos1, pos2) + local pos1_sorted, pos2_sorted = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now - pos1 = vector.new(pos1) - pos2 = vector.new(pos2) + pos1 = Vector3.clone(pos1) + pos2 = Vector3.clone(pos2) local node_id_replace = minetest.get_content_id(node_name) @@ -26,16 +29,11 @@ function worldeditadditions.line(pos1, pos2, thickness, node_name) for z = pos2_sorted.z, pos1_sorted.z, -1 do for x = pos2_sorted.x, pos1_sorted.x, -1 do for y = pos2_sorted.y, pos1_sorted.y, -1 do - local here = vector.new(x, y, z) - local D = vector.normalize( - vector.subtract(pos2, pos1) - ) - local d = vector.dot(vector.subtract(here, pos1), D) - local closest_on_line = vector.add( - pos1, - vector.multiply(D, d) - ) - local distance = vector.length(vector.subtract(here, closest_on_line)) + local here = Vector3.new(x, y, z) + local D = (pos2 - pos1):normalise() + local d = Vector3.dot(here - pos1, D) + local closest_on_line = pos1 + (D * d) + local distance = (here - closest_on_line):length() if distance < thickness then data[area:index(x, y, z)] = node_id_replace diff --git a/worldeditadditions/lib/maze2d.lua b/worldeditadditions/lib/maze2d.lua index 85a413e..9db150f 100644 --- a/worldeditadditions/lib/maze2d.lua +++ b/worldeditadditions/lib/maze2d.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_commands +local Vector3 = wea_c.Vector3 + --- Generates a maze. -- Algorithm origin: https://starbeamrainbowlabs.com/blog/article.php?article=posts/070-Language-Review-Lua.html -- @module worldeditadditions.maze @@ -117,16 +120,17 @@ end -- local world = maze(os.time(), width, height) function worldeditadditions.maze2d(pos1, pos2, target_node, seed, path_length, path_width) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- getExtent() returns the number of nodes in the VoxelArea, which might be larger than we actually asked for - local extent = { - x = (pos2.x - pos1.x) + 1, path_length, path_width, - y = (pos2.y - pos1.y) + 1, -- not a dimension passed to the maze generator itself - z = (pos2.z - pos1.z) + 1, path_length, path_width - } - -- minetest.log("action", "extent: ("..extent.x..", "..extent.y..", "..extent.z..")") + local extent = (pos2 - pos1) + 1 + --- Extent: + -- x = path_length, path_width + -- y = not a dimension passed to the maze generator itself + -- z = path_length, path_width + + -- minetest.log("action", "extent: "..extent) if extent.x < 3 or extent.y < 1 or extent.z < 3 then minetest.log("error", "[worldeditadditions/maze] error: either x, y of the extent were less than 3, or z of the extent was less than 1") diff --git a/worldeditadditions/lib/maze3d.lua b/worldeditadditions/lib/maze3d.lua index 42318e2..f2eef0a 100644 --- a/worldeditadditions/lib/maze3d.lua +++ b/worldeditadditions/lib/maze3d.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_commands +local Vector3 = wea_c.Vector3 + --- Generates a maze. -- Algorithm origin: https://starbeamrainbowlabs.com/blog/article.php?article=posts/070-Language-Review-Lua.html -- @module worldeditadditions.maze @@ -169,15 +172,12 @@ end -- local world = maze(os.time(), width, height) function worldeditadditions.maze3d(pos1, pos2, target_node, seed, path_length, path_width, path_depth) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- getExtent() returns the number of nodes in the VoxelArea, which might be larger than we actually asked for - local extent = { - x = (pos2.x - pos1.x) + 1, - y = (pos2.y - pos1.y) + 1, - z = (pos2.z - pos1.z) + 1 - } + local extent = (pos2 - pos1) + 1 + -- minetest.log("action", "extent: ("..extent.x..", "..extent.y..", "..extent.z..")") if extent.x < 3 or extent.y < 3 or extent.z < 3 then diff --git a/worldeditadditions/lib/move.lua b/worldeditadditions/lib/move.lua index 2432fce..9bbf767 100644 --- a/worldeditadditions/lib/move.lua +++ b/worldeditadditions/lib/move.lua @@ -1,8 +1,8 @@ --- Copies a region to another location, potentially overwriting the exiting region. -- @module worldeditadditions.copy -local wea = worldeditadditions -local Vector3 = wea.Vector3 +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 -- ███ ███ ██████ ██ ██ ███████ -- ████ ████ ██ ██ ██ ██ ██ diff --git a/worldeditadditions/lib/noiseapply2d.lua b/worldeditadditions/lib/noiseapply2d.lua index 844ba99..2954c86 100644 --- a/worldeditadditions/lib/noiseapply2d.lua +++ b/worldeditadditions/lib/noiseapply2d.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_commands +local Vector3 = wea_c.Vector3 + -- ███ ██ ██████ ██ ███████ ███████ █████ ██████ ██████ ██ ██ ██ ██████ ██████ -- ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ -- ██ ██ ██ ██ ██ ██ ███████ █████ ███████ ██████ ██████ ██ ████ █████ ██ ██ @@ -11,8 +14,8 @@ -- @param {Position} pos2 The 2nd positioon defining the region boundary -- @param {Function} func The function to call that performs the action in question. It is expected that the given function will accept no arguments. function worldeditadditions.noiseapply2d(pos1, pos2, threshold, scale, func) - local time_taken_all = worldeditadditions.get_ms_time() - pos1, pos2 = worldeditadditions.Vector3.sort(pos1, pos2) + local time_taken_all = wea_c.get_ms_time() + pos1, pos2 = Vector3.sort(pos1, pos2) if not threshold then threshold = 0.5 end -- pos2 will always have the highest co-ordinates now @@ -20,14 +23,14 @@ function worldeditadditions.noiseapply2d(pos1, pos2, threshold, scale, func) local manip_before, area_before = worldedit.manip_helpers.init(pos1, pos2) local data_before = manip_before:get_data() - local time_taken_fn = worldeditadditions.get_ms_time() + local time_taken_fn = wea_c.get_ms_time() func() - time_taken_fn = worldeditadditions.get_ms_time() - time_taken_fn + time_taken_fn = wea_c.get_ms_time() - time_taken_fn local manip_after, area_after = worldedit.manip_helpers.init(pos1, pos2) local data_after = manip_after:get_data() - local size2d = pos2 - pos1 + worldeditadditions.Vector3.new(1, 1, 1) + local size2d = pos2 - pos1 + Vector3.new(1, 1, 1) print("DEBUG pos1", pos1, "pos2", pos2, "size2d", size2d) local success, noise = worldeditadditions.noise.make_2d(size2d, pos1, { algorithm = "perlinmt", @@ -55,6 +58,6 @@ function worldeditadditions.noiseapply2d(pos1, pos2, threshold, scale, func) -- No need to save - this function doesn't actually change anything worldedit.manip_helpers.finish(manip_after, data_after) - time_taken_all = worldeditadditions.get_ms_time() - time_taken_all + time_taken_all = wea_c.get_ms_time() - time_taken_all return true, { all = time_taken_all, fn = time_taken_fn } end diff --git a/worldeditadditions/lib/overlay.lua b/worldeditadditions/lib/overlay.lua index cc21b8d..957352f 100644 --- a/worldeditadditions/lib/overlay.lua +++ b/worldeditadditions/lib/overlay.lua @@ -1,8 +1,11 @@ +local wea_c = worldeditadditions_commands +local Vector3 = wea_c.Vector3 + --- Overlap command. Places a specified node on top of each column. -- @module worldeditadditions.overlay function worldeditadditions.overlay(pos1, pos2, node_weights) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- Fetch the nodes in the specified area @@ -11,7 +14,7 @@ function worldeditadditions.overlay(pos1, pos2, node_weights) local node_id_ignore = minetest.get_content_id("ignore") - local node_ids, node_ids_count = worldeditadditions.make_weighted(node_weights) + local node_ids, node_ids_count = wea_c.make_weighted(node_weights) -- minetest.log("action", "pos1: " .. worldeditadditions.vector.tostring(pos1)) -- minetest.log("action", "pos2: " .. worldeditadditions.vector.tostring(pos2)) @@ -26,11 +29,11 @@ function worldeditadditions.overlay(pos1, pos2, node_weights) -- print("\n\n[overlay] ****** column start ******") for y = pos2.y, pos1.y, -1 do local i = area:index(x, y, z) - -- print("[overlay] pos", x, y, z, "id", data[i], "name", minetest.get_name_from_content_id(data[i]), "is_liquid", worldeditadditions.is_liquidlike(data[i])) + -- print("[overlay] pos", x, y, z, "id", data[i], "name", minetest.get_name_from_content_id(data[i]), "is_liquid", wea_c.is_liquidlike(data[i])) - local is_air = worldeditadditions.is_airlike(data[i]) - local is_liquid = worldeditadditions.is_liquidlike(data[i]) - -- wielded_light is now handled by worldeditadditions.is_airlike + local is_air = wea_c.is_airlike(data[i]) + local is_liquid = wea_c.is_liquidlike(data[i]) + -- wielded_light is now handled by wea_c.is_airlike local is_ignore = data[i] == node_id_ignore diff --git a/worldeditadditions/lib/replacemix.lua b/worldeditadditions/lib/replacemix.lua index e8a556e..ed50f5e 100644 --- a/worldeditadditions/lib/replacemix.lua +++ b/worldeditadditions/lib/replacemix.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_commands +local Vector3 = wea_c.Vector3 + --- Like //mix, but replaces a given node instead. -- @module worldeditadditions.replacemix @@ -7,7 +10,7 @@ -- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ -- ██ ██ ███████ ██ ███████ ██ ██ ██████ ███████ ██ ██ ██ ██ ██ function worldeditadditions.replacemix(pos1, pos2, target_node, target_node_chance, replacements) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) -- pos2 will always have the highest co-ordinates now -- Fetch the nodes in the specified area @@ -22,7 +25,7 @@ function worldeditadditions.replacemix(pos1, pos2, target_node, target_node_chan local distribution = {} -- Generate the list of node ids - local node_ids_replace, node_ids_replace_count = worldeditadditions.make_weighted(replacements) + local node_ids_replace, node_ids_replace_count = wea_c.make_weighted(replacements) for node_name, weight in pairs(replacements) do distribution[minetest.get_content_id(node_name)] = 0 end diff --git a/worldeditadditions/lib/scale_down.lua b/worldeditadditions/lib/scale_down.lua index 5bca63a..a04a64f 100644 --- a/worldeditadditions/lib/scale_down.lua +++ b/worldeditadditions/lib/scale_down.lua @@ -1,3 +1,6 @@ +local wea_c = worldeditadditions_core +local Vector3 = wea_c.Vector3 + -- ███████ ██████ █████ ██ ███████ ██████ ██████ ██ ██ ███ ██ -- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ -- ███████ ██ ███████ ██ █████ ██ ██ ██ ██ ██ █ ██ ██ ██ ██ @@ -11,7 +14,9 @@ -- @param anchor Vector The direction to scale in - as a vector. e.g. { x = -1, y = 1, z = -1 } would mean scale in the negative x, positive y, and nevative z directions. -- @return boolean, string|table Whether the operation was successful or not. If not, then an error messagea as a string is also passed. If it was, then a statistics object is returned instead. function worldeditadditions.scale_down(pos1, pos2, scale, anchor) - pos1, pos2 = worldedit.sort_pos(pos1, pos2) + pos1, pos2 = Vector3.sort(pos1, pos2) + scale = Vector3.clone(scale) + if scale.x > 1 or scale.y > 1 or scale.z > 1 or scale.x < -1 or scale.y < -1 or scale.z < -1 then return false, "Error: Scale factor vectors may not mix values -1 < factor < 1 and (1 < factor or factor < -1) - in other words, you can't scale both up and down at the same time (try worldeditadditions.scale, which automatically applies such scale factor vectors as 2 successive operations)" end @@ -19,31 +24,23 @@ function worldeditadditions.scale_down(pos1, pos2, scale, anchor) return false, "Error: One of the components of the anchor vector was 0 (anchor components should either be greater than or less than 0 to indicate the anchor to scale in.)" end - local scale_down = { - x = math.floor(1 / scale.x), - y = math.floor(1 / scale.y), - z = math.floor(1 / scale.z) - } - local size = vector.subtract(pos2, pos1) + local scale_down = (1 / scale):floor() + local size = pos2 - pos1 if size.x < scale_down.x or size.y < scale_down.y or size.z < scale.z then - return false, "Error: Area isn't big enough to apply scale down by "..worldeditadditions.vector.tostring(scale).."." + return false, "Error: Area isn't big enough to apply scale down by "..scale.."." end - local size_small = { - x = math.floor(size.x / scale_down.x), - y = math.floor(size.y / scale_down.y), - z = math.floor(size.z / scale_down.z) - } + local size_small = (size / scale_down):floor() local manip, area = worldedit.manip_helpers.init(pos1, pos2) local data = manip:get_data() - local data_copy = worldeditadditions.table.shallowcopy(data) + local data_copy = wea_c.table.shallowcopy(data) local node_id_air = minetest.get_content_id("air") - local pos1_small = vector.new(pos1) - local pos2_small = vector.new(pos2) + local pos1_small = pos1:clone() + local pos2_small = pos2:clone() if anchor.x < 1 then pos1_small.x = pos2_small.x - size_small.x else pos2_small.x = pos1_small.x + size_small.x end @@ -65,22 +62,18 @@ function worldeditadditions.scale_down(pos1, pos2, scale, anchor) for z = pos2.z, pos1.z, -1 do for y = pos2.y, pos1.y, -1 do for x = pos2.x, pos1.x, -1 do - local posi_rel = vector.subtract({ x = x, y = y, z = z }, pos1) + local posi_rel = Vector3.new(x, y, z) - pos1 - -- local posi_copy = worldeditadditions.table.shallowcopy(posi_rel) + -- local posi_copy = wea_c.table.shallowcopy(posi_rel) -- posi_copy = vector.floor(vector.divide(posi_rel/*, scale_down*/)) - local posi_copy = { - x = math.floor(posi_rel.x / scale_down.x), - y = math.floor(posi_rel.y / scale_down.y), - z = math.floor(posi_rel.z / scale_down.z) - } + local posi_copy = posi_rel / scale_down if anchor.x < 0 then posi_copy.x = size.x - posi_copy.x end if anchor.y < 0 then posi_copy.y = size.y - posi_copy.y end if anchor.z < 0 then posi_copy.z = size.z - posi_copy.z end - posi_copy = vector.add(pos1, posi_copy) + posi_copy = pos1 + posi_copy local i_source = area:index(x, y, z) local i_target = area:index(posi_copy.x, posi_copy.y, posi_copy.z) diff --git a/worldeditadditions_core/utils/vector3.lua b/worldeditadditions_core/utils/vector3.lua index 2d97858..fc43984 100644 --- a/worldeditadditions_core/utils/vector3.lua +++ b/worldeditadditions_core/utils/vector3.lua @@ -95,7 +95,8 @@ function Vector3.mul(a, b) return Vector3.multiply(a, b) end -- @returns Vector3 The result as a new Vector3 object. function Vector3.divide(a, b) if type(a) == "number" then - return Vector3.new(b.x / a, b.y / a, b.z / a) + return Vector3.new(a / b.x, a/ b.y, a / b.z) + -- return Vector3.new(b.x / a, b.y / a, b.z / a) -- BUG: is this a bug? elseif type(b) == "number" then return Vector3.new(a.x / b, a.y / b, a.z / b) end