forked from minetest/minetest_game
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:
parent
8c801529df
commit
ccee025ce3
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user