Page 1 of 1

Question about a node's on_blast() function

PostPosted: Fri May 08, 2015 22:51
by fessmK
Hello.
I was wondering how to call a node's on_blast() function.
for those of you who don't know this can exist, it is similar to a node's on_punch(), on_rightclick(), etc, but, would be activated by an explosion.
unfortunately, it is not used in the tnt mod in the default game(it really should be........)

thanks in advance for the help!

Re: Question about a node's on_blast() function

PostPosted: Sat May 09, 2015 09:34
by TeTpaAka
There is a pull request for this: https://github.com/minetest/minetest_game/pull/450
There you can also see how to call them. It's basically:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
      local on_blast = def.on_blast
      if on_blast ~= nil then
         on_blast(pos, 1)
         return
      else
         minetest.remove_node(pos)
      end

where def is the node definition table.

Re: Question about a node's on_blast() function

PostPosted: Sat May 09, 2015 12:26
by fessmK
thanks for the help, and thanks again for the quick reply!
edit: the git pull does not use varying blast power.

Re: Question about a node's on_blast() function

PostPosted: Sat May 09, 2015 15:49
by Wuzzy
I am the author of the pull request.
The blast intensity is defined to be the intensity of the blast. It is simply an integer. It is defined to be 1 for normal TNT according to lua_api.txt, so that's why I chose 1.

Also note that on_blast is purely conventional; it is not actually part of the Lua API, altough it is “documented” in lua_api.txt.

Howerver, IMO the intensity is very poorly defined otherwise, there is no really formular on how to calculate the intensity for something other than TNT (let's say, an nuclear bomb).
It is also unclear if the intensity is meant to be the blast intensity in the center of the explosion or on the position where the callback is being made.

Until we, as a community, have agreed on some sane convention, I suggest to ignore the intensity value for now.

Re: Question about a node's on_blast() function

PostPosted: Sat May 09, 2015 17:06
by fessmK
@ Wuzzy
the dev. wiki says that "According the lua_api.txt: 1.0 = mid range of regular TNT"
so I did some fancy if statements to have it change.

however, I am still having problems in running the function. Here is my code:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local blast = def.on_blast
      if blast ~= nil then
         local posdist = {
         x = pos.x - center.x,
         y = pos.y - center.y,
         z = pos.z - center.z,
         }
         if posdist.x < 0 then
            posdist.x = posdist.x*-1
         end
         if posdist.y < 0 then
            posdist.y = posdist.y*-1
         end
         if posdist.z < 0 then
            posdist.z = posdist.z*-1
         end
         --calculate the actual distance in nodes
         local disxz = math.hypot(posdist.x, posdist.z)
         local distance = math.hypot (disxz, posdist.y)
         -- simplify the distance to a non-floating point number
         distance = math.ceil(distance)
         -- half the radius
         local halfrad = radius/2
         halfrad = math.ceil(halfrad)
         local qutrad = math.ceil(halfrad/2)
         local lqutrad = halfrad + qutrad
         -- the developer wiki say that a block at about half a radius's explosion would receive 1 intensity
         local intesnity = nil
         if distance == halfrad then
            intensity = 1
         elseif distance <= qutrrad then
            intensity = 3
         elseif distance > qutrad and distance < halfrad then
            intensity = 2
         elseif distance >= lqutrad then
            intensity = 1/3
         elseif distance < lqutrad and distance > halfrad then
            intensity = 1/2
         end

         -- actually running the blast functon (finnaly)
         if intensity ~= nil then
            blast(pos, intensity)
         else
            blast(pos, 1)
         end
         return

Re: Question about a node's on_blast() function

PostPosted: Sun May 10, 2015 12:38
by Wuzzy
I already said, there is no actual convention on how to properly calculate the intensity value. “TNT = 1” is just a single value, what is missing is a formular. I could think of many different ways to calculate the intensity for other explosions, i.e. take in account for the number of destroyed blocks, the explosion radius, etc.
And you just came up with your own ad-hoc calculation method. If everyone just comes up with their own calculation method like you did, everything which calls on_blast will have highly inconsistent intensity values, so the intensity of (for example) 2 could mean very different things thanks to the different ad-hoc calculations.
This problem only exists because lua_api.txt does not provide any formular.

At some point in the future, we (as a community) should really agree on some sort of standard, hopefully even writing it down into lua_api.txt. Maybe the Lua API could even provide some convenient helper functions to help calculating the intensity to avoid nasty code duplication.
Until that, better ignore the intensity or just give it a dummy value, because it is de facto meaningless, for now at least. You can always fix it later when the community has agreed on a standard.

Also, I can't help you with your problem because you did not say what's your problem and what you intended to do with the code.

Re: Question about a node's on_blast() function

PostPosted: Sun May 10, 2015 13:38
by fessmK
I agree about that. I will remove my calculation.

my problem is that it will not actually run the on_blast function. I am working on entity-based tnt that will explode and "light" certain nodes, and turn them into entity, which explode, and light other nodes, etc.

repaired code:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local function destroy(drops, pos, cid, center, radius)
   if minetest.is_protected(pos, "") then
      return
   end
   local def = cid_data[cid]
   if def and def.flammable then
      minetest.set_node(pos, fire_node)
   else
      local blast = def.on_blast
      if blast ~= nil then
         blast(pos, 1)
      else
         minetest.remove_node(pos)
         if def then
            local node_drops = minetest.get_node_drops(def.name, "")
            for _, item in ipairs(node_drops) do
               add_drop(drops, item)
            end
         end
      end
   end
end


the tnt node (that should be lit) is being dropped, and its on_blast function is ignored.