

function hitboxes_lib.collision_to_hits(puncher, collision_data)
	local env = puncher:get_luaentity()
	local puncher_pos = puncher:get_pos()
	puncher:set_pos(collision_data.new_pos)
	local hits = hitboxes_lib.detect_hits(collision_data.object, puncher, nil)
	puncher:set_pos(puncher_pos)
	return hits
end

-- create on_punch from collision data
function hitboxes_lib.collision_to_punch(puncher, collision_data)
	local env = puncher:get_luaentity()
	local puncher_pos = puncher:get_pos()
	puncher:set_pos(collision_data.new_pos)
	local tool_capabilities = {
		full_punch_interval = 1.0,
		max_drop_level = 0,
		groupcaps = {},
		damage_groups = {fleshy=0},
		punch_attack_uses = 0,
	}
	if env and env._hit_tool_capabilities then
		tool_capabilities = env._hit_tool_capabilities
	end
	collision_data.object:punch(puncher, 1, tool_capabilities, collision_data.old_velocity)
	puncher:set_pos(puncher_pos)
	return punch
end

local function table_deep_merge(t1, t2)
	for k, v in pairs(t2) do
		if type(v) == "table" then
			if type(t1[k]) == "table" then
				table_deep_merge(t1[k], v)
			else
				t1[k] = table.copy(v)
			end
		else
			t1[k] = v
		end
	end
	return t1
end

function hitboxes_lib.update_hitgroup_parts(orig_parts, update_parts)
	orig_parts = table.copy(orig_parts)
	table_deep_merge(orig_parts, update_parts)
	return orig_parts
end