diff --git a/mods/ITEMS/mcl_throwing/egg.lua b/mods/ITEMS/mcl_throwing/egg.lua
index aa4adcef8..411afc4a2 100644
--- a/mods/ITEMS/mcl_throwing/egg.lua
+++ b/mods/ITEMS/mcl_throwing/egg.lua
@@ -17,6 +17,24 @@ minetest.register_craftitem("mcl_throwing:egg", {
 	groups = { craftitem = 1 },
 })
 
+local function egg_spawn_chicks(pos)
+	-- 1/8 chance to spawn a chick
+	if math.random(1,8) ~= 1 then return end
+
+	pos.y = math.ceil(pos.y)
+
+	if not mcl_mobs.spawn_child(pos, "mobs_mc:chicken") then
+		minetest.log("unable to spawn chick at "..vector.to_string(pos))
+	end
+
+	-- BONUS ROUND: 1/32 chance to spawn 3 additional chicks
+	if math.random(1,32) ~= 1 then return end
+
+	mcl_mobs.spawn_child(vector.offset(pos,  0.7, 0,  0  ), "mobs_mc:chicken")
+	mcl_mobs.spawn_child(vector.offset(pos, -0.7, 0, -0.7), "mobs_mc:chicken")
+	mcl_mobs.spawn_child(vector.offset(pos, -0.7, 0,  0.7), "mobs_mc:chicken")
+end
+
 minetest.register_entity("mcl_throwing:egg_entity",{
 	physical = false,
 	timer=0,
@@ -34,24 +52,22 @@ minetest.register_entity("mcl_throwing:egg_entity",{
 	_vl_projectile = {
 		behaviors = {
 			vl_projectile.collides_with_solids,
+			vl_projectile.collides_with_entities,
 		},
+		allow_punching = function(self, _, _, object)
+			if self._owner == object:get_player_name() then
+				return self.timer > 1
+			end
+		end,
 		on_collide_with_solid = function(self, pos, node)
 			if mod_target and node.name == "mcl_target:target_off" then
 				mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks
 			end
 
-			-- 1/8 chance to spawn a chick
-			-- FIXME: Chicks have a quite good chance to spawn in walls
-			if math.random(1,8) ~= 1 then return end
-
-			mcl_mobs.spawn_child(pos, "mobs_mc:chicken")
-
-			-- BONUS ROUND: 1/32 chance to spawn 3 additional chicks
-			if math.random(1,32) ~= 1 then return end
-
-			mcl_mobs.spawn_child(vector.offset(pos,  0.7, 0,  0  ), "mobs_mc:chicken")
-			mcl_mobs.spawn_child(vector.offset(pos, -0.7, 0, -0.7), "mobs_mc:chicken")
-			mcl_mobs.spawn_child(vector.offset(pos, -0.7, 0,  0.7), "mobs_mc:chicken")
+			egg_spawn_chicks(pos)
+		end,
+		on_collide_with_entity = function(self, pos, obj)
+			egg_spawn_chicks(pos)
 		end,
 		sounds = {
 			on_collision = {"mcl_throwing_egg_impact", {max_hear_distance=10, gain=0.5}, true}
diff --git a/mods/ITEMS/mcl_throwing/ender_pearl.lua b/mods/ITEMS/mcl_throwing/ender_pearl.lua
index 36de0fb27..9e48422db 100644
--- a/mods/ITEMS/mcl_throwing/ender_pearl.lua
+++ b/mods/ITEMS/mcl_throwing/ender_pearl.lua
@@ -1,5 +1,4 @@
 local modname = minetest.get_current_modname()
-local modpath = minetest.get_modpath(modname)
 local S = minetest.get_translator(modname)
 
 local math = math
@@ -21,6 +20,85 @@ minetest.register_craftitem("mcl_throwing:ender_pearl", {
 	groups = { transport = 1 },
 })
 
+function on_collide(self, pos, node)
+	if mod_target and node.name == "mcl_target:target_off" then
+		mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks
+	end
+
+	if node.name == "ignore" then
+		-- FIXME: This also means the player loses an ender pearl for throwing into unloaded areas
+		return
+	end
+
+	-- Make sure we have a reference to the player
+	local player = self._thrower and minetest.get_player_by_name(self._thrower)
+	if not player then return end
+
+	-- Teleport and hurt player
+
+	-- First determine good teleport position
+	local dir = vector.zero()
+
+	local v = self.object:get_velocity()
+	local node_def = minetest.registered_nodes[node.name]
+	if node_def and node_def.walkable then
+		local vc = vector.normalize(v) -- vector for calculating
+		-- Node is walkable, we have to find a place somewhere outside of that node
+
+		-- Zero-out the two axes with a lower absolute value than the axis with the strongest force
+		local lv, ld = math.abs(vc.y), "y"
+		if math.abs(vc.x) > lv then
+			lv, ld = math.abs(vc.x), "x"
+		end
+		if math.abs(vc.z) > lv then
+			ld = "z" --math.abs(vc.z)
+		end
+		if ld ~= "x" then vc.x = 0 end
+		if ld ~= "y" then vc.y = 0 end
+		if ld ~= "z" then vc.z = 0 end
+
+		-- Final tweaks to the teleporting pos, based on direction
+		-- Impact from the side
+		dir.x = vc.x * -1
+		dir.z = vc.z * -1
+
+		-- Special case: top or bottom of node
+		if vc.y > 0 then
+			-- We need more space when impact is from below
+			dir.y = -2.3
+		elseif vc.y < 0 then
+			-- Standing on top
+			dir.y = 0.5
+		end
+	end
+	-- If node was not walkable, no modification to pos is made.
+
+	-- Final teleportation position
+	local telepos = vector.add(pos, dir)
+	local telenode = minetest.get_node(telepos)
+
+	--[[ It may be possible that telepos is walkable due to the algorithm.
+	Especially when the ender pearl is faster horizontally than vertical.
+	This applies final fixing, just to be sure we're not in a walkable node ]]
+	if not minetest.registered_nodes[telenode.name] or minetest.registered_nodes[telenode.name].walkable then
+		if v.y < 0 then
+			telepos.y = telepos.y + 0.5
+		else
+			telepos.y = telepos.y - 2.3
+		end
+	end
+
+	local oldpos = player:get_pos()
+	-- Teleport and hurt player
+	player:set_pos(telepos)
+	player:set_hp(player:get_hp() - 5, { type = "fall", from = "mod" })
+
+	-- 5% chance to spawn endermite at the player's origin
+	if math.random(1,20) == 1 then
+		minetest.add_entity(oldpos, "mobs_mc:endermite")
+	end
+end
+
 -- Ender pearl entity
 vl_projectile.register("mcl_throwing:ender_pearl_entity",{
 	physical = false,
@@ -39,90 +117,22 @@ vl_projectile.register("mcl_throwing:ender_pearl_entity",{
 	_vl_projectile = {
 		behaviors = {
 			vl_projectile.collides_with_solids,
+			vl_projectile.collides_with_entities,
 		},
 		collides_with = {
 			"mcl_core:vine", "mcl_core:deadbush",
 			"group:flower", "group:sapling",
 			"group:plant", "group:mushroom",
 		},
-		on_collide_with_solid = function(self, pos, node)
-			if mod_target and node.name == "mcl_target:target_off" then
-				mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks
+		allow_punching = function(self, _, _, object)
+			if self._owner == object:get_player_name() then
+				return self.timer > 1
 			end
-
-			if node.name == "ignore" then
-				-- FIXME: This also means the player loses an ender pearl for throwing into unloaded areas
-				return
-			end
-
-			-- Make sure we have a reference to the player
-			local player = self._thrower and minetest.get_player_by_name(self._thrower)
-			if not player then return end
-
-			-- Teleport and hurt player
-
-			-- First determine good teleport position
-			local dir = vector.zero()
-
-			local v = self.object:get_velocity()
-			local node_def = minetest.registered_nodes[node.name]
-			if node_def and node_def.walkable then
-				local vc = vector.normalize(v) -- vector for calculating
-				-- Node is walkable, we have to find a place somewhere outside of that node
-
-				-- Zero-out the two axes with a lower absolute value than the axis with the strongest force
-				local lv, ld = math.abs(vc.y), "y"
-				if math.abs(vc.x) > lv then
-					lv, ld = math.abs(vc.x), "x"
-				end
-				if math.abs(vc.z) > lv then
-					ld = "z" --math.abs(vc.z)
-				end
-				if ld ~= "x" then vc.x = 0 end
-				if ld ~= "y" then vc.y = 0 end
-				if ld ~= "z" then vc.z = 0 end
-
-				-- Final tweaks to the teleporting pos, based on direction
-				-- Impact from the side
-				dir.x = vc.x * -1
-				dir.z = vc.z * -1
-
-				-- Special case: top or bottom of node
-				if vc.y > 0 then
-					-- We need more space when impact is from below
-					dir.y = -2.3
-				elseif vc.y < 0 then
-					-- Standing on top
-					dir.y = 0.5
-				end
-			end
-			-- If node was not walkable, no modification to pos is made.
-
-			-- Final teleportation position
-			local telepos = vector.add(pos, dir)
-			local telenode = minetest.get_node(telepos)
-
-			--[[ It may be possible that telepos is walkable due to the algorithm.
-			Especially when the ender pearl is faster horizontally than vertical.
-			This applies final fixing, just to be sure we're not in a walkable node ]]
-			if not minetest.registered_nodes[telenode.name] or minetest.registered_nodes[telenode.name].walkable then
-				if v.y < 0 then
-					telepos.y = telepos.y + 0.5
-				else
-					telepos.y = telepos.y - 2.3
-				end
-			end
-
-			local oldpos = player:get_pos()
-			-- Teleport and hurt player
-			player:set_pos(telepos)
-			player:set_hp(player:get_hp() - 5, { type = "fall", from = "mod" })
-
-			-- 5% chance to spawn endermite at the player's origin
-			if math.random(1,20) == 1 then
-				minetest.add_entity(oldpos, "mobs_mc:endermite")
-			end
-		end
+		end,
+		on_collide_with_entity = function(self, pos, entity)
+			on_collide(self, pos, minetest.get_node(pos))
+		end,
+		on_collide_with_solid = on_collide,
 	},
 })
 mcl_throwing.register_throwable_object("mcl_throwing:ender_pearl", "mcl_throwing:ender_pearl_entity", 22)
diff --git a/mods/ITEMS/mcl_throwing/snowball.lua b/mods/ITEMS/mcl_throwing/snowball.lua
index a0a5a2f36..ed64feb8a 100644
--- a/mods/ITEMS/mcl_throwing/snowball.lua
+++ b/mods/ITEMS/mcl_throwing/snowball.lua
@@ -1,6 +1,7 @@
 local modname = minetest.get_current_modname()
 local S = minetest.get_translator(modname)
 
+local mod_target = minetest.get_modpath("mcl_target")
 local how_to_throw = S("Use the punch key to throw.")
 
 -- Snowball
@@ -54,8 +55,11 @@ vl_projectile.register("mcl_throwing:snowball_entity", {
 			vl_projectile.collides_with_entities,
 		},
 		allow_punching = function(self, _, _, object)
-			return object.is_mob or object._hittable_by_projectile or
-			       not object:is_player() or self._owner ~= object:get_player_name()
+			if self._owner == object:get_player_name() then
+				return self.timer > 1
+			end
+
+			return object.is_mob or object._hittable_by_projectile or object:is_player()
 		end,
 		on_collide_with_solid = function(self, pos, node)
 			if mod_target and node.name == "mcl_target:target_off" then