PyuTestCore.util = {
  toint = function (float)
    return tonumber(string.format("%d", float))
  end,

  tablecopy = function(t)
    if t == nil then return nil end
    local t2 = {}
    for k,v in pairs(t) do
      t2[k] = v
    end
    return t2
  end,

  tableconcat = function (t1, t2)
    local nt = PyuTestCore.util.tablecopy(t1)
    for k, v in pairs(t2) do
      nt[k] = v
    end
    return nt
  end,

  tableconcat2 = function(t1, t2)
    local nt = PyuTestCore.util.tablecopy(t1)
    for i = 1, #t2 do
      nt[#nt+i] = t2[i]
    end
    return nt
  end,
}

PyuTestCore.dorange = function(origin, range, action)
  for dx = -range, range do
    for dz = -range, range do
      for dy = -range, range do
        action(vector.new(origin.x + dx, origin.y + dy, origin.z + dz))
      end
    end
  end
end

PyuTestCore.create_explosion = function (pos, range, rm_pos, dmg, creator, dmg_creator)
  if rm_pos then
    minetest.remove_node(pos)
  end

  PyuTestCore.dorange(pos, range, function(p)
    if minetest.get_node(p).name == "pyutest_core:tnt" then
      minetest.get_node_timer(p):start(0.2)
    else
      minetest.dig_node(p)
    end
  end)

  for _, v in pairs(minetest.get_objects_inside_radius(pos, range)) do
    if creator ~= nil then
      if v ~= creator then
        v:punch(creator, nil, {
          damage_groups = {fleshy = dmg}
        }, nil)
      end

      if dmg_creator and v == creator then
        v:punch(creator, nil, {
          damage_groups = {fleshy = dmg}
        }, nil)
      end
    end
  end

  local r = range
  local minpos = {x = pos.x - r, y = pos.y - r, z = pos.z - r}
  local maxpos = {x = pos.x + r, y = pos.y + r, z = pos.z + r}

  minetest.add_particlespawner({
    amount = range * 3,
    time = 0.1,
    minexptime = 0.4,
    maxexptime = 1.4,
    minsize = 32,
    maxsize = 64,

    collisiondetection = false,
    texture = "pyutest-blast.png",

    minpos = minpos,
    maxpos = maxpos,
  })

  minetest.sound_play("block_break", {
    pos = pos,
    gain = 2.5
  })
end
