Calculate blast intensity at all locations.

We define the blast intensity as the square of the tnt_radius, divided
by the square of the distance to the explosion center, where distance
is limited to 1 at the lower end.

When destroying nodes, we calculate the intensity for each node, and
only destroy the nodes when the intensity is 1.0 or larger. To avoid
perfectly spherical explosions, we make sure to retain a randomness
factor of 20%. This will make explosion edges jagged and not smooth,
but not too much.

We pass the calculated intensity to on_blast() functions as well,
except we take the jitter here out and make sure it's always 1.0
or larger.
This commit is contained in:
Auke Kok 2016-03-22 22:05:34 -07:00 committed by paramat
parent bd70e41b1f
commit c9d4326a85

@ -219,8 +219,8 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
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
if (x * x) + (y * y) + (z * z) <= local r = vector.length(vector.new(x, y, z))
(radius * radius) + pr:next(-radius, radius) 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 then if cid ~= c_air then
@ -228,7 +228,6 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
on_blast_queue, ignore_protection, on_blast_queue, ignore_protection,
ignore_on_blast) ignore_on_blast)
end end
end end
vi = vi + 1 vi = vi + 1
end end
@ -242,7 +241,7 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
for _, data in ipairs(on_blast_queue) do for _, data in ipairs(on_blast_queue) do
local dist = math.max(1, vector.distance(data.pos, pos)) local dist = math.max(1, vector.distance(data.pos, pos))
local intensity = 1 / (dist * dist) local intensity = (radius * radius) / (dist * dist)
local node_drops = data.on_blast(data.pos, intensity) local node_drops = data.on_blast(data.pos, intensity)
if node_drops then if node_drops then
for _, item in ipairs(node_drops) do for _, item in ipairs(node_drops) do