+function core.dir_to_yaw(dir)
+ return -math.atan2(dir.x, dir.z)
+end
+
+function core.yaw_to_dir(yaw)
+ return {x = -math.sin(yaw), y = 0, z = math.cos(yaw)}
+end
+
+function core.is_colored_paramtype(ptype)
+ return (ptype == "color") or (ptype == "colorfacedir") or
+ (ptype == "colorwallmounted")
+end
+
+function core.strip_param2_color(param2, paramtype2)
+ if not core.is_colored_paramtype(paramtype2) then
+ return nil
+ end
+ if paramtype2 == "colorfacedir" then
+ param2 = math.floor(param2 / 32) * 32
+ elseif paramtype2 == "colorwallmounted" then
+ param2 = math.floor(param2 / 8) * 8
+ end
+ -- paramtype2 == "color" requires no modification.
+ return param2
+end
+
+function core.get_node_drops(node, toolname)
+ -- Compatibility, if node is string
+ local nodename = node
+ local param2 = 0
+ -- New format, if node is table
+ if (type(node) == "table") then
+ nodename = node.name
+ param2 = node.param2
+ end
+ local def = core.registered_nodes[nodename]
+ local drop = def and def.drop
+ local ptype = def and def.paramtype2
+ -- get color, if there is color (otherwise nil)
+ local palette_index = core.strip_param2_color(param2, ptype)