ID:2018591
 
(See the best response by Lummox JR.)
Code:
    ice
icon = 'ice.dmi'
Entered()
usr.movelock = 1
if(usr.dir == NORTH)
sleep(5)
usr.y ++
if(usr.dir == SOUTH)
sleep(5)
usr.y --
if(usr.dir == EAST)
sleep(5)
usr.x ++
if(usr.dir == WEST)
sleep(5)
usr.x --
usr.movelock = 0
..()


Problem description:
This is under terf, there was just a lot of junk above it that is irrelevant etc.
How do I get this to work ;-;
You step onto the ice and I want you to slide until you hit an object like a tree. ;-;
turf/ice/Entered(atom/movable/Obj,atom/OldLoc)
..()

sleep(1)
step(Obj, Obj.dir)


Calling step() does the trick because it's using movement, events like Entered() will be called on the next step where in your code right now you just change the location without any movement.
I haven't tested it but this looks like it should work.

atom/movable/var/tmp/movement_locked = FALSE

client
North()
if(mob.movement_locked)return FALSE
..();return TRUE
East()
if(mob.movement_locked)return FALSE
..();return TRUE
South()
if(mob.movement_locked)return FALSE
..();return TRUE
West()
if(mob.movement_locked)return FALSE
..();return TRUE
Northeast()
Northwest()
Southeast()
Southwest()

turf/ice/Entered(atom/movable/object,atom/old_location)
object.movement_locked = TRUE
..()
if(old_location && old_location.type == src.type)
if(!(step(object,object.dir)))
object.movement_locked = FALSE
else
object.movement_locked = FALSE
Best response
Kozuma's approach will work, as long as you're also sure to cover the diagonal directions as well. However I think it's easier to handle that under client/Move().

But probably better is to make sure bad guys and objs are affected too.

atom/movable
var/tmp/slide_dir

proc/Slide()
if(slide_dir)
var/turf/T = loc
var/d = slide_dir
slide_dir = 0 // temporarily stop sliding so Move() works
// sanity check!
if(!isturf(T) || !T.slide)
slide_dir = 0
return
step(src, d)
// if we're on the same ice turf, keep sliding
// otherwise we entered a new turf and it took care of slide_dir
if(loc == T) slide_dir = d
spawn(world.tick_lag) Slide()

Move()
if(slide_dir) return 0
return ..()

turf/var/slide

turf/ice
slide = 1
Entered(atom/movable/A, atom/oldloc)
if(oldloc)
A.slide_dir = get_dir(oldloc, src)
spawn(world.tick_lag) A.Slide()

Amusingly, this approach also lets you make ice corners like in Chip's Challenge. (To handle bumping into an ice corner from the wrong direction, you'd need to override Enter() also.)