Calculate blast intensity at all locations.
authorAuke Kok <sofar@foo-projects.org>
Wed, 23 Mar 2016 05:05:34 +0000 (22:05 -0700)
committerparamat <mat.gregory@virginmedia.com>
Sat, 16 Apr 2016 18:27:16 +0000 (19:27 +0100)
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.

mods/tnt/init.lua

index 1f28ee50e4a4f13dcd207bdd52fdb6c226c12f43..83630d93874fdeb620f2565d4876acf606e0ea79 100644 (file)
@@ -219,8 +219,8 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
        for y = -radius, radius do
        local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z)
        for x = -radius, radius do
-               if (x * x) + (y * y) + (z * z) <=
-                               (radius * radius) + pr:next(-radius, radius) then
+               local r = vector.length(vector.new(x, y, z))
+               if (radius * radius) / (r * r) >= (pr:next(80, 125) / 100) then
                        local cid = data[vi]
                        local p = {x = pos.x + x, y = pos.y + y, z = pos.z + z}
                        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,
                                        ignore_on_blast)
                        end
-
                end
                vi = vi + 1
        end
@@ -242,7 +241,7 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
 
        for _, data in ipairs(on_blast_queue) do
                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)
                if node_drops then
                        for _, item in ipairs(node_drops) do