ID:889636
 
(See the best response by DarkCampainger.)
How would one create stairs that go diagonally across the screen, and have the players properly walk up the without having to press PGUP HOME, etc...?

You could force a direction of movement through a variable changed when you enter the stairs.
I'm not quite sure how to do this, as I have little experience with movement variables or procs.
Simple. When the mob enters the "Stairs turf" change the variable. Look up the built-in procs.

As for movement, personally, I'd utilize the client.north() proc

client
North()
if(src.mob.instairs)
// Determine which direction is most logical
else
..()


EDIT: Actually, an alternative (and probably easier way) would be to modify mob.Move()

mob
Move()
if(src.instairs)
step(src,DStep())
return
else
..()

proc
DStep()
if(src.StairDir == X)
return NORTH
Best response
I think the most elegant way would be to use turf/Exit() to reroute movement, but it doesn't have any way of knowing if the movement is a jump (ie teleporting across the map) or a slide. mob/Move() is probably the next best place.

The trick here is capturing their desired movement, and redirecting it along the staircase's direction. This can be done by using the binary AND operator (&) to see if the direction of movement and staircase's direction share any directional flags. For example, if the staircase's dir is NORTHEAST and the player is trying to move NORTH, (NORTHEAST & NORTH) will return the component they share: NORTH. If the player is trying to move against the stair dir, such as SOUTH for a NORTHEAST staircase, then (NORTHEAST & SOUTH) will return 0, because they don't share any component. We can use this fact to "round" the player's direction to a diagonal one:
// d = direction of movement
// S = staircase
// S.primaryDir = staircase direction
// S.secondaryDir = reverse of staircase direction
d = (d & S.primaryDir) ? S.primaryDir : S.secondaryDir



Using that, you could override mob/Move() like so:
turf
Stairs
icon = 'Stairs.dmi'
name = "Stairs"
var
primaryDir // The "up" direction
secondaryDir // The "down" direction, DO NOT SET

New()
secondaryDir = turn(primaryDir, 180)
..()

NorthEast
dir = NORTHEAST
primaryDir = NORTHEAST

NorthWest
dir = NORTHWEST
primaryDir = NORTHWEST


mob
Move(NewLoc,Dir)
// See if they're on stairs
if(istype(src.loc, /turf/Stairs))
var/turf/Stairs/S = src.loc

// Apply stair effect if they're only moving one tile
// (Note: this method would have to be expanded to support pixel movement)
if(get_dist(S, NewLoc) <= 1)

// Check that the direction is valid
var/d = get_dir(S, NewLoc)
if(d!=S.primaryDir && d!=S.secondaryDir)

// If not, see if it shares a component with the primary/sec directions
d = (d & S.primaryDir) ? S.primaryDir : S.secondaryDir
// Re-route their movement along the new direction
var/turf/t = get_step(src, d)
if(t) return ..(t, d)

return ..()