local positions = {} local ObjectRefmetatable local offset = vector.new(0,0.01,0) -- table of nodes to ignore when players move through them example air=true local ignorenodes = {} local function checkray(ray) -- returns intersection_point or nil if not blocked local next = ray:next() local blocked = false while next ~= nil and blocked == false do local nname = minetest.get_node(next.under).name if next.under and (ignorenodes[nname] ~= true) and (next.above ~= next.under) then --right here check node stuff like can_collide and different nodebox vs collisionbox blocked = true return next.intersection_point end next = ray:next() end end minetest.register_on_mods_loaded(function() for key, value in pairs(minetest.registered_nodes) do if value.walkable == false then ignorenodes[key] = true end local selbox = value.selection_box or value.node_box local colbox = value.collision_box or value.node_box --print(dump(value.selection_box),dump(value.collision_box)) if (selbox ~= nil and colbox ~= nil) and(dump(selbox) ~= dump(colbox)) then ignorenodes[key] = true end end end) minetest.register_globalstep(function(dtime) for index, value in ipairs(minetest.get_connected_players()) do local name = value:get_player_name() if not minetest.check_player_privs(name, "noclip") then local pos = value:get_pos() + offset local lastpos if positions[name] == nil then positions[name] = pos end lastpos = positions[name] local between = vector.new(lastpos.x,pos.y,lastpos.z) if pos.y < lastpos.y then between = vector.new(pos.x,lastpos.y,pos.z) end local blocked local ray = Raycast(positions[name], between, false, false) local ray2 = Raycast(between, pos, false, false) if positions[name] ~= between then blocked = checkray(ray) end if not blocked then blocked = checkray(ray2) end if blocked then value:old_set_pos(positions[name] - offset) else positions[name] = pos end end end end) local function patchobj(ObjectRef) ObjectRefmetatable = getmetatable(ObjectRef) local gp = ObjectRefmetatable.set_pos local mt = ObjectRefmetatable.move_to local newgp = function (self,pos, ...) if self:is_player() then positions[self:get_player_name()] = nil print("player teleprotd") end gp(self,pos,...) end local newmt = function (self,pos, ...) if self:is_player() then positions[self:get_player_name()] = nil print("player teleprotd") end mt(self,pos,...) end ObjectRefmetatable.set_pos = newgp ObjectRefmetatable.old_set_pos = gp ObjectRefmetatable.move_to = newmt ObjectRefmetatable.old_move_to = mt end minetest.register_on_joinplayer(function(ObjectRef, last_login) if ObjectRefmetatable then return end patchobj(ObjectRef) end)