-- LUALOCALS < ---------------------------------------------------------
local klots, math, minetest, pairs, vector
    = klots, math, minetest, pairs, vector
local math_random
    = math.random
-- LUALOCALS > ---------------------------------------------------------

if klots.editmode then return end

local ouch = {}
minetest.after(0, function()
		for k, v in pairs(minetest.registered_nodes) do
			if v.ouch then
				ouch[k] = true
			end
		end
	end)

local hash = minetest.hash_node_position
local vector_round = vector.round
local vector_subtract = vector.subtract
local vector_normalize = vector.normalize
local vector_add = vector.add

local function checkouch(ppos, pos, vel, seen)
	pos = vector_round(pos)
	local key = hash(pos)
	if seen[key] then return vel end
	seen[key] = true
	local node = minetest.get_node(pos)
	if not ouch[node.name] then return vel end
	vel = vel or {x = 0, y = 0, z = 0}
	local dv = vector_normalize(vector_subtract(ppos, pos))
	vel = vector_add(vel, {
			x = dv.x * 1.5 + math_random() - 0.5,
			y = dv.y * 1.5 + math_random() - 0.5,
			z = dv.z * 1.5 + math_random() - 0.5,
		})
	return vel
end

klots.register_playerstep(function(player)
		local vel = nil
		local pos = player:get_pos()
		local seen = {}
		vel = checkouch(pos, vector_add(pos, {x = -0.3, y = 0, z = -0.3}), vel, seen)
		vel = checkouch(pos, vector_add(pos, {x = -0.3, y = 0, z = 0.3}), vel, seen)
		vel = checkouch(pos, vector_add(pos, {x = 0.3, y = 0, z = -0.3}), vel, seen)
		vel = checkouch(pos, vector_add(pos, {x = 0.3, y = 0, z = 0.3}), vel, seen)
		vel = checkouch(pos, vector_add(pos, {x = -0.3, y = 1, z = -0.3}), vel, seen)
		vel = checkouch(pos, vector_add(pos, {x = -0.3, y = 1, z = 0.3}), vel, seen)
		vel = checkouch(pos, vector_add(pos, {x = 0.3, y = 1, z = -0.3}), vel, seen)
		vel = checkouch(pos, vector_add(pos, {x = 0.3, y = 1, z = 0.3}), vel, seen)
		if not vel then return end
		if vel.y < 0.5 then vel.y = 0.5 end
		return klots.player_control_apply(player, function(obj) obj:add_velocity(vel) end)
	end)
