mirror of
https://github.com/luanti-org/minetest_game.git
synced 2025-07-04 13:47:12 -04:00
Merge 23415c7e16
into 6ed522b5fc
This commit is contained in:
commit
c9d755b405
3 changed files with 157 additions and 198 deletions
|
@ -835,3 +835,17 @@ function default.can_interact_with_node(player, pos)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function default.do_with_area(p1, p2, func)
|
||||||
|
local vm = VoxelManip()
|
||||||
|
local minp, maxp = vm:read_from_map(p1, p2)
|
||||||
|
local va = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
|
||||||
|
local data = vm:get_data()
|
||||||
|
func(va, data)
|
||||||
|
vm:set_data(data)
|
||||||
|
vm:write_to_map()
|
||||||
|
vm:update_liquids()
|
||||||
|
if vm.close ~= nil then
|
||||||
|
vm:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -115,26 +115,13 @@ function default.grow_tree(pos, is_apple_tree, bad)
|
||||||
error("Deprecated use of default.grow_tree")
|
error("Deprecated use of default.grow_tree")
|
||||||
end
|
end
|
||||||
|
|
||||||
local x, y, z = pos.x, pos.y, pos.z
|
|
||||||
local height = random(4, 5)
|
local height = random(4, 5)
|
||||||
local c_tree = minetest.get_content_id("default:tree")
|
local c_tree = minetest.get_content_id("default:tree")
|
||||||
local c_leaves = minetest.get_content_id("default:leaves")
|
local c_leaves = minetest.get_content_id("default:leaves")
|
||||||
|
|
||||||
local vm = minetest.get_voxel_manip()
|
default.do_with_area(pos:offset(-2, 0, -2), pos:offset(2, height + 1, 2), function(a, data)
|
||||||
local minp, maxp = vm:read_from_map(
|
add_trunk_and_leaves(data, a, pos, c_tree, c_leaves, height, 2, 8, is_apple_tree)
|
||||||
{x = x - 2, y = y, z = z - 2},
|
end)
|
||||||
{x = x + 2, y = y + height + 1, z = z + 2}
|
|
||||||
)
|
|
||||||
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
|
|
||||||
local data = vm:get_data()
|
|
||||||
|
|
||||||
add_trunk_and_leaves(data, a, pos, c_tree, c_leaves, height, 2, 8, is_apple_tree)
|
|
||||||
|
|
||||||
vm:set_data(data)
|
|
||||||
vm:write_to_map()
|
|
||||||
if vm.close ~= nil then
|
|
||||||
vm:close()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Jungle tree
|
-- Jungle tree
|
||||||
|
@ -156,39 +143,27 @@ function default.grow_jungle_tree(pos, bad)
|
||||||
local c_jungletree = minetest.get_content_id("default:jungletree")
|
local c_jungletree = minetest.get_content_id("default:jungletree")
|
||||||
local c_jungleleaves = minetest.get_content_id("default:jungleleaves")
|
local c_jungleleaves = minetest.get_content_id("default:jungleleaves")
|
||||||
|
|
||||||
local vm = minetest.get_voxel_manip()
|
default.do_with_area(pos:offset(-3, -1, -3), pos:offset(3, height + 1, 3), function(a, data)
|
||||||
local minp, maxp = vm:read_from_map(
|
add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves,
|
||||||
{x = x - 3, y = y - 1, z = z - 3},
|
height, 3, 30, false)
|
||||||
{x = x + 3, y = y + height + 1, z = z + 3}
|
|
||||||
)
|
|
||||||
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
|
|
||||||
local data = vm:get_data()
|
|
||||||
|
|
||||||
add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves,
|
-- Roots
|
||||||
height, 3, 30, false)
|
for z_dist = -1, 1 do
|
||||||
|
local vi_1 = a:index(x - 1, y - 1, z + z_dist)
|
||||||
-- Roots
|
local vi_2 = a:index(x - 1, y, z + z_dist)
|
||||||
for z_dist = -1, 1 do
|
for x_dist = -1, 1 do
|
||||||
local vi_1 = a:index(x - 1, y - 1, z + z_dist)
|
if random(1, 3) >= 2 then
|
||||||
local vi_2 = a:index(x - 1, y, z + z_dist)
|
if data[vi_1] == c_air or data[vi_1] == c_ignore then
|
||||||
for x_dist = -1, 1 do
|
data[vi_1] = c_jungletree
|
||||||
if random(1, 3) >= 2 then
|
elseif data[vi_2] == c_air or data[vi_2] == c_ignore then
|
||||||
if data[vi_1] == c_air or data[vi_1] == c_ignore then
|
data[vi_2] = c_jungletree
|
||||||
data[vi_1] = c_jungletree
|
end
|
||||||
elseif data[vi_2] == c_air or data[vi_2] == c_ignore then
|
|
||||||
data[vi_2] = c_jungletree
|
|
||||||
end
|
end
|
||||||
|
vi_1 = vi_1 + 1
|
||||||
|
vi_2 = vi_2 + 1
|
||||||
end
|
end
|
||||||
vi_1 = vi_1 + 1
|
|
||||||
vi_2 = vi_2 + 1
|
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
|
|
||||||
vm:set_data(data)
|
|
||||||
vm:write_to_map()
|
|
||||||
if vm.close ~= nil then
|
|
||||||
vm:close()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,105 +193,93 @@ function default.grow_pine_tree(pos, snow)
|
||||||
local c_pine_needles = minetest.get_content_id("default:pine_needles")
|
local c_pine_needles = minetest.get_content_id("default:pine_needles")
|
||||||
local c_snow = minetest.get_content_id("default:snow")
|
local c_snow = minetest.get_content_id("default:snow")
|
||||||
|
|
||||||
local vm = minetest.get_voxel_manip()
|
default.do_with_area(pos:offset(-3, 0, -3), vector.new(x + 3, maxy + 3, z + 3), function(a, data)
|
||||||
local minp, maxp = vm:read_from_map(
|
-- Upper branches layer
|
||||||
{x = x - 3, y = y, z = z - 3},
|
local dev = 3
|
||||||
{x = x + 3, y = maxy + 3, z = z + 3}
|
for yy = maxy - 1, maxy + 1 do
|
||||||
)
|
for zz = z - dev, z + dev do
|
||||||
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
|
local vi = a:index(x - dev, yy, zz)
|
||||||
local data = vm:get_data()
|
local via = a:index(x - dev, yy + 1, zz)
|
||||||
|
for xx = x - dev, x + dev do
|
||||||
|
if random() < 0.95 - dev * 0.05 then
|
||||||
|
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
|
||||||
|
c_pine_needles)
|
||||||
|
if snow then
|
||||||
|
add_snow(data, via, c_air, c_ignore, c_snow)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
vi = vi + 1
|
||||||
|
via = via + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dev = dev - 1
|
||||||
|
end
|
||||||
|
|
||||||
-- Upper branches layer
|
-- Centre top nodes
|
||||||
local dev = 3
|
add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow,
|
||||||
for yy = maxy - 1, maxy + 1 do
|
c_pine_needles)
|
||||||
for zz = z - dev, z + dev do
|
add_pine_needles(data, a:index(x, maxy + 2, z), c_air, c_ignore, c_snow,
|
||||||
local vi = a:index(x - dev, yy, zz)
|
c_pine_needles) -- Paramat added a pointy top node
|
||||||
local via = a:index(x - dev, yy + 1, zz)
|
if snow then
|
||||||
for xx = x - dev, x + dev do
|
add_snow(data, a:index(x, maxy + 3, z), c_air, c_ignore, c_snow)
|
||||||
if random() < 0.95 - dev * 0.05 then
|
end
|
||||||
|
|
||||||
|
-- Lower branches layer
|
||||||
|
local my = 0
|
||||||
|
for i = 1, 20 do -- Random 2x2 squares of needles
|
||||||
|
local xi = x + random(-3, 2)
|
||||||
|
local yy = maxy + random(-6, -5)
|
||||||
|
local zi = z + random(-3, 2)
|
||||||
|
if yy > my then
|
||||||
|
my = yy
|
||||||
|
end
|
||||||
|
for zz = zi, zi+1 do
|
||||||
|
local vi = a:index(xi, yy, zz)
|
||||||
|
local via = a:index(xi, yy + 1, zz)
|
||||||
|
for xx = xi, xi + 1 do
|
||||||
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
|
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
|
||||||
c_pine_needles)
|
c_pine_needles)
|
||||||
if snow then
|
if snow then
|
||||||
add_snow(data, via, c_air, c_ignore, c_snow)
|
add_snow(data, via, c_air, c_ignore, c_snow)
|
||||||
end
|
end
|
||||||
|
vi = vi + 1
|
||||||
|
via = via + 1
|
||||||
end
|
end
|
||||||
vi = vi + 1
|
|
||||||
via = via + 1
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
dev = dev - 1
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Centre top nodes
|
dev = 2
|
||||||
add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow,
|
for yy = my + 1, my + 2 do
|
||||||
c_pine_needles)
|
for zz = z - dev, z + dev do
|
||||||
add_pine_needles(data, a:index(x, maxy + 2, z), c_air, c_ignore, c_snow,
|
local vi = a:index(x - dev, yy, zz)
|
||||||
c_pine_needles) -- Paramat added a pointy top node
|
local via = a:index(x - dev, yy + 1, zz)
|
||||||
if snow then
|
for xx = x - dev, x + dev do
|
||||||
add_snow(data, a:index(x, maxy + 3, z), c_air, c_ignore, c_snow)
|
if random() < 0.95 - dev * 0.05 then
|
||||||
end
|
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
|
||||||
|
c_pine_needles)
|
||||||
-- Lower branches layer
|
if snow then
|
||||||
local my = 0
|
add_snow(data, via, c_air, c_ignore, c_snow)
|
||||||
for i = 1, 20 do -- Random 2x2 squares of needles
|
end
|
||||||
local xi = x + random(-3, 2)
|
|
||||||
local yy = maxy + random(-6, -5)
|
|
||||||
local zi = z + random(-3, 2)
|
|
||||||
if yy > my then
|
|
||||||
my = yy
|
|
||||||
end
|
|
||||||
for zz = zi, zi+1 do
|
|
||||||
local vi = a:index(xi, yy, zz)
|
|
||||||
local via = a:index(xi, yy + 1, zz)
|
|
||||||
for xx = xi, xi + 1 do
|
|
||||||
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
|
|
||||||
c_pine_needles)
|
|
||||||
if snow then
|
|
||||||
add_snow(data, via, c_air, c_ignore, c_snow)
|
|
||||||
end
|
|
||||||
vi = vi + 1
|
|
||||||
via = via + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
dev = 2
|
|
||||||
for yy = my + 1, my + 2 do
|
|
||||||
for zz = z - dev, z + dev do
|
|
||||||
local vi = a:index(x - dev, yy, zz)
|
|
||||||
local via = a:index(x - dev, yy + 1, zz)
|
|
||||||
for xx = x - dev, x + dev do
|
|
||||||
if random() < 0.95 - dev * 0.05 then
|
|
||||||
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
|
|
||||||
c_pine_needles)
|
|
||||||
if snow then
|
|
||||||
add_snow(data, via, c_air, c_ignore, c_snow)
|
|
||||||
end
|
end
|
||||||
|
vi = vi + 1
|
||||||
|
via = via + 1
|
||||||
end
|
end
|
||||||
vi = vi + 1
|
end
|
||||||
via = via + 1
|
dev = dev - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Trunk
|
||||||
|
-- Force-place lowest trunk node to replace sapling
|
||||||
|
data[a:index(x, y, z)] = c_pine_tree
|
||||||
|
for yy = y + 1, maxy do
|
||||||
|
local vi = a:index(x, yy, z)
|
||||||
|
local node_id = data[vi]
|
||||||
|
if node_id == c_air or node_id == c_ignore or
|
||||||
|
node_id == c_pine_needles or node_id == c_snow then
|
||||||
|
data[vi] = c_pine_tree
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
dev = dev - 1
|
end)
|
||||||
end
|
|
||||||
|
|
||||||
-- Trunk
|
|
||||||
-- Force-place lowest trunk node to replace sapling
|
|
||||||
data[a:index(x, y, z)] = c_pine_tree
|
|
||||||
for yy = y + 1, maxy do
|
|
||||||
local vi = a:index(x, yy, z)
|
|
||||||
local node_id = data[vi]
|
|
||||||
if node_id == c_air or node_id == c_ignore or
|
|
||||||
node_id == c_pine_needles or node_id == c_snow then
|
|
||||||
data[vi] = c_pine_tree
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
vm:set_data(data)
|
|
||||||
vm:write_to_map()
|
|
||||||
if vm.close ~= nil then
|
|
||||||
vm:close()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -294,12 +294,8 @@ end
|
||||||
local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast, owner, explode_center)
|
local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast, owner, explode_center)
|
||||||
pos = vector.round(pos)
|
pos = vector.round(pos)
|
||||||
-- scan for adjacent TNT nodes first, and enlarge the explosion
|
-- scan for adjacent TNT nodes first, and enlarge the explosion
|
||||||
local vm1 = VoxelManip()
|
-- TODO given that we're looking at a fraction of a mapblock here,
|
||||||
local p1 = vector.subtract(pos, 2)
|
-- there is probably little reason to use VoxelManip.
|
||||||
local p2 = vector.add(pos, 2)
|
|
||||||
local minp, maxp = vm1:read_from_map(p1, p2)
|
|
||||||
local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
|
|
||||||
local data = vm1:get_data()
|
|
||||||
local count = 0
|
local count = 0
|
||||||
local c_tnt
|
local c_tnt
|
||||||
local c_tnt_burning = minetest.get_content_id("tnt:tnt_burning")
|
local c_tnt_burning = minetest.get_content_id("tnt:tnt_burning")
|
||||||
|
@ -311,88 +307,74 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast, owne
|
||||||
else
|
else
|
||||||
c_tnt = c_tnt_burning -- tnt is not registered if disabled
|
c_tnt = c_tnt_burning -- tnt is not registered if disabled
|
||||||
end
|
end
|
||||||
-- make sure we still have explosion even when centre node isnt tnt related
|
|
||||||
if explode_center then
|
|
||||||
count = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
for z = pos.z - 2, pos.z + 2 do
|
default.do_with_area(pos:subtract(2), pos:add(2), function(a, data)
|
||||||
for y = pos.y - 2, pos.y + 2 do
|
-- make sure we still have explosion even when centre node isnt tnt related
|
||||||
local vi = a:index(pos.x - 2, y, z)
|
if explode_center then
|
||||||
for x = pos.x - 2, pos.x + 2 do
|
count = 1
|
||||||
local cid = data[vi]
|
|
||||||
if cid == c_tnt or cid == c_tnt_boom or cid == c_tnt_burning then
|
|
||||||
count = count + 1
|
|
||||||
data[vi] = c_air
|
|
||||||
end
|
|
||||||
vi = vi + 1
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
vm1:set_data(data)
|
for z = pos.z - 2, pos.z + 2 do
|
||||||
vm1:write_to_map()
|
for y = pos.y - 2, pos.y + 2 do
|
||||||
if vm1.close ~= nil then
|
local vi = a:index(pos.x - 2, y, z)
|
||||||
vm1:close()
|
for x = pos.x - 2, pos.x + 2 do
|
||||||
end
|
local cid = data[vi]
|
||||||
|
if cid == c_tnt or cid == c_tnt_boom or cid == c_tnt_burning then
|
||||||
|
count = count + 1
|
||||||
|
data[vi] = c_air
|
||||||
|
end
|
||||||
|
vi = vi + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
-- recalculate new radius
|
-- recalculate new radius
|
||||||
radius = math.floor(radius * math.pow(count, 1/3))
|
radius = math.floor(radius * math.pow(count, 1/3))
|
||||||
|
|
||||||
-- perform the explosion
|
-- perform the explosion
|
||||||
local vm = VoxelManip()
|
|
||||||
local pr = PseudoRandom(os.time())
|
local pr = PseudoRandom(os.time())
|
||||||
p1 = vector.subtract(pos, radius)
|
|
||||||
p2 = vector.add(pos, radius)
|
|
||||||
minp, maxp = vm:read_from_map(p1, p2)
|
|
||||||
a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
|
|
||||||
data = vm:get_data()
|
|
||||||
|
|
||||||
local drops = {}
|
local drops = {}
|
||||||
local on_blast_queue = {}
|
local on_blast_queue = {}
|
||||||
local on_construct_queue = {}
|
local on_construct_queue = {}
|
||||||
basic_flame_on_construct = minetest.registered_nodes["fire:basic_flame"].on_construct
|
basic_flame_on_construct = minetest.registered_nodes["fire:basic_flame"].on_construct
|
||||||
|
|
||||||
-- Used to efficiently remove metadata of nodes that were destroyed.
|
local p1, p2 = pos:subtract(radius), pos:add(radius)
|
||||||
-- Metadata is probably sparse, so this may save us some work.
|
default.do_with_area(p1, p2, function(a, data) -- luacheck: ignore
|
||||||
local has_meta = {}
|
-- Used to efficiently remove metadata of nodes that were destroyed.
|
||||||
for _, p in ipairs(minetest.find_nodes_with_meta(p1, p2)) do
|
-- Metadata is probably sparse, so this may save us some work.
|
||||||
has_meta[a:indexp(p)] = true
|
local has_meta = {}
|
||||||
end
|
for _, p in ipairs(minetest.find_nodes_with_meta(p1, p2)) do
|
||||||
|
has_meta[a:indexp(p)] = true
|
||||||
|
end
|
||||||
|
|
||||||
local c_fire = minetest.get_content_id("fire:basic_flame")
|
local c_fire = minetest.get_content_id("fire:basic_flame")
|
||||||
for z = -radius, radius do
|
for z = -radius, radius do
|
||||||
for y = -radius, radius do
|
for y = -radius, radius do
|
||||||
local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z)
|
local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z)
|
||||||
for x = -radius, radius do
|
for x = -radius, radius do
|
||||||
local r = vector.length(vector.new(x, y, z))
|
local r = vector.length(vector.new(x, y, z))
|
||||||
if (radius * radius) / (r * r) >= (pr:next(80, 125) / 100) then
|
if (radius * radius) / (r * r) >= (pr:next(80, 125) / 100) then
|
||||||
local cid = data[vi]
|
local cid = data[vi]
|
||||||
local p = {x = pos.x + x, y = pos.y + y, z = pos.z + z}
|
local p = {x = pos.x + x, y = pos.y + y, z = pos.z + z}
|
||||||
if cid ~= c_air and cid ~= c_ignore then
|
if cid ~= c_air and cid ~= c_ignore then
|
||||||
local new_cid = destroy(drops, p, cid, c_air, c_fire,
|
local new_cid = destroy(drops, p, cid, c_air, c_fire,
|
||||||
on_blast_queue, on_construct_queue,
|
on_blast_queue, on_construct_queue,
|
||||||
ignore_protection, ignore_on_blast, owner)
|
ignore_protection, ignore_on_blast, owner)
|
||||||
|
|
||||||
if new_cid ~= data[vi] then
|
if new_cid ~= data[vi] then
|
||||||
data[vi] = new_cid
|
data[vi] = new_cid
|
||||||
if has_meta[vi] then
|
if has_meta[vi] then
|
||||||
minetest.get_meta(p):from_table(nil)
|
minetest.get_meta(p):from_table(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
vi = vi + 1
|
||||||
end
|
end
|
||||||
vi = vi + 1
|
end
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
end
|
|
||||||
|
|
||||||
vm:set_data(data)
|
|
||||||
vm:write_to_map()
|
|
||||||
vm:update_liquids()
|
|
||||||
if vm.close ~= nil then
|
|
||||||
vm:close()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- call check_single_for_falling for everything within 1.5x blast radius
|
-- call check_single_for_falling for everything within 1.5x blast radius
|
||||||
for y = -radius * 1.5, radius * 1.5 do
|
for y = -radius * 1.5, radius * 1.5 do
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue