ID:1818234
 
(See the best response by Xirre.)
Code:


Problem description:

Hi i have a question..lets say there is a move and while its on you lose control and run in only one direction making it hard to control your movements? would i have to use a gliding effect or?
Best response
Short answer: No you don't need to use the gliding effect.

Long answer: Set a loop in move that calls move every time it would actually update.

On top of that loop, you should set a control variable that checks whether or not the loop should end (if the user gains control again).

This variable is outside of the proc that calls Move() and should belong to the player individually. Preferably, the variable would be declared and initialized as "var/mob/hasControl = 0".

The while loop in this proc called "mob/proc/LoseControl()" should look like "while(!src.hasControl)". Inside the while loop, the user should "step()" in their direction. Or whatever other direction you specify. And repeatedly.

You'll also want to sleep the loop for however long Move() itself would actually sleep for. Tick lag, etc. All that stuff.

You can spice things up by setting buffer movements as done in my movement script. So it allows the pressing of two keys (or the movement of two directions). It'll require some manipulation. But, all you have to do is add on to the direction based on what the user pressed as done here:

        KeyDown(n as num)
set hidden = 1
step_dir += n
walk(src.mob, step_dir)

KeyUp(n as num)
set hidden = 1
step_dir -= n
if(step_dir <= 0)
step_dir = 0
walk(src.mob,null)
else
walk(src.mob, step_dir)


step_dir takes in to account multiple movements.

Loop through all of this while also still allowing them to perform normal movements and you got yourself something similar to sliding on ice.
okay i see but wouldnt uysing the constant proc be a bit beneficial?
In response to Daiguren Hyourinamru
What constant proc? What are you talking about? Move()? Move() is what allows the player to move (obviously).

Here's a scenario:

The scenery
  • Icey cave
  • Snowy floor
  • Ice-slippery floor
  • Ice walls


Alright. So, the user steps in to the cave. In order for them to actually step in the cave, they need to Move(). So, you need a standard move procedure. Now, obviously there's a delay in Move() to stop them from moving 1000 tiles per second. This can be measured as step_size, FPS, and tick lag. Though, FPS doesn't really count for "delay". Still, it can be factored in if you want things to look pretty.

Now that we've understood what Move() should be doing (basic movements), we can move on to the next part. The user steps on the icey floor, which can be detected with Entered() or Enter() -- whichever floats your boat idc. As soon as it is detected, set their hasControl variable to 0, which should be, by default, 1. As soon as you set it, SPAWN the LoseControl() procedure that will cause the user to step in their initial velocity direction. This also means you might want to record the direction they stepped in when they first touched the icey floor. This direction can be recorded as a number (directions can be interpreted by numbers) in a variable called var/velocity.

Every time the while(!src.hasControl) iterates it should cause the user to step() in the velocity direction. Read the documentation on step() to see how it is formatted. When the user enters a snowy floor, set hasControl to 1. This will stop their continued movement. When the user hits an icy wall, pick() if they should turn left or right, as if they were sliding against the wall. Or, you could skip that part and just give them control again.

I think this should be it. I lost track of what I was typing when I got interrupted. So, hopefully things make sense.
Code:
atom
movable
var/const/NORMAL = 0 as num
var/const/LOCK = 1 as num
var/const/STRAFE = 2 as num
var/const/FACING = 3 as num
var/const/DELAY = 4 as num
var/const/CONST = 5 as num
var/MODE = NORMAL as num
var/DELAYTIME = 0 as num

proc/ISMODE(atom/movable/a, mode)
if(a.MODE == mode)
return TRUE

Move(New,Dir = 0)
if(ISMODE(src, NORMAL))
return ..(New, Dir)
if(ISMODE(src,LOCK))
return TRUE
if(ISMODE(src, STRAFE))
return ..(New,dir)
if(ISMODE(src, FACING))
dir = Dir
return TRUE
if(ISMODE(src, DELAY))
sleep(DELAYTIME)
return ..(New, Dir)
if(ISMODE(src, CONST))
dir = Dir
walk(src, dir)
return ..(New, Dir)
return TRUE
proc
Normal()
MODE = NORMAL
Lock()
MODE = LOCK
Strafe()
MODE = STRAFE
Face()
MODE = FACING
Delay()
var/delay = input(usr,"Delay Time.","Delay") as null|num
DELAYTIME = delay
MODE = DELAY
Constant()
MODE = CONST


something like this?

EDIT:Fixed
I'm not reading that until you wrap it in DM tags lol.
In response to Xirre
fixed it
Can you explain your end-goal in detail? What is accomplished when and how and when it is turned off, what happens? Tell me all the juicy details.
In response to Xirre
okay it works like this when someone uses chidori it will call the chidorion var and while in that var your movement goes in a straight line depending on which arrow key you hit..when you hit something or it runs out then your movement goes back to normal thats the goal im going for
So basically your character will travel in a straight line for a certain duration, probably 1.5 seconds and then allow you to move your character again.
In response to Asgardian_Thor
more or less yes