ID:272274
 
If anyone plays the GBA, or NDS pokemon games, they usually have an ice gym that when you walk on the ice you slide all the way toward the direction you walked in, anyone know if this is possible, and does anyone know how to do this? Thanks.

~Element Hero creator
Element Hero creator wrote:
If anyone plays the GBA, or NDS pokemon games, they usually have an ice gym that when you walk on the ice you slide all the way toward the direction you walked in, anyone know if this is possible,

Of course it is. Have more faith in BYOND! =P

does anyone know how to do this?

You should override the Entered() procedure for this (please look it up in the DM Reference).

You want players to move forward (in their direction) whenever they enter, let's say, a turf/ice. You'd accomplish this by overriding turf/ice/Entered(), checking if what Entered the ice is a player mob (optional, because you may not mind if other mobs or objs slide as well), and if so, Moving() it forward in its (the player's) own direction. If the next tile is an ice tile as well, it will automatically carry over in a chain-effect, so this is all you need to do; although you should put that last Move() (or step()) call under spawn(), so you don't flood the call stack if you have a lot of ice tiles in a row etc.
In response to Kaioken
I'm not sure where to put that in my code though.

turf
Ice_Floor
icon = 'turfs.dmi'
icon_state = "Ice Floor"
name = "Ice Floor"
Enter()
if(usr.dir==SOUTH)
usr.loc = locate(usr.x,usr.y-1,usr.z)
if(usr.dir==NORTH)
usr.loc = locate(usr.x,usr.y+1,usr.z)
if(usr.dir==EAST)
usr.loc = locate(usr.x+2,usr.y,usr.z)
if(usr.dir==WEST)
usr.loc = locate(usr.x-2,usr.y,usr.z)


Thats my current code, I know its bad, but at least I tried :/ oh, and I know it doesn't slide with this. just wanted extra movement for a harder puzzle type gym, but now I want sliding, just not sure how to do it.
In response to Element Hero creator
1. Override Entered(), not Enter().

2. Look up the step proc and the dir var in the DM reference.
In response to Darkmag1c1an11
Yeah. It's possible. I should probably redo my version of it though, I could probably do it better. Another thing you should think of doing, disabling conventional movement (or modifying it) while sliding on ice. If someone holds down the key when hitting an ice patch, not only does the game try to move them, but they're also moving themselves and they get sent flying at the end of the icepatch.
In response to Element Hero creator
Ungh. No put usr in proc!
Also, you should use switch() when checking the same variable for multiple values; however, here, you shouldn't do it - just make the movable move (ie step()) in its own direction.
In response to Chessmaster_19
Chessmaster_19 wrote:
Another thing you should think of doing, disabling conventional movement (or modifying it) while sliding on ice.

This is kind of a design choice, though, according to your preference, although he did want it like the Pokemon games, so good point there. Most games do have a variable to disable movement already as well.
In response to Kaioken
turf
Ice_Floor
icon = 'turfs.dmi'
icon_state = "Ice Floor"
name = "Ice Floor"
Entered(mob/M)
if(M.dir==SOUTH)
M.loc = locate(usr.x,usr.y-1,usr.z)
if(M.dir==NORTH)
M.loc = locate(usr.x,usr.y+1,usr.z)
if(M.dir==EAST)
M.loc = locate(usr.x+2,usr.y,usr.z)
if(M.dir==WEST)
M.loc = locate(usr.x-2,usr.y,usr.z)
Thats my new code, changed enter to entered and made it so only mobs can slide on the ice . Anyways is there anyway I can keep this code but when I go near a wall I don't slide because whenever I slide I go through the wall and out of the map..
In response to Element Hero creator
Element Hero creator wrote:
Thats my new code, changed enter to entered and made it so only mobs can slide on the ice

No, you haven't. This is something very important to understand. You've only defined the M variable as of type /mob, but this does not affect the variable itself at all; it can still store anything. In this case, M could also be an /obj. If you want to only affect mobs, then you'd need to put an if() check to only run your code if M is a mob (by using istype() or the "shortcut" ismob(), look them up).


. Anyways is there anyway I can keep this code but when I go near a wall I don't slide because whenever I slide I go through the wall and out of the map..

This is because you're modifying the loc variable directly, which is bad. This forces a relocation; it doesn't activate the movement system. This means the object will still move even if density should be blocking it, or Enter() (or Exit()) is disallowing the movement. This also means the movement system procs such as Entered() won't be called, so if you set a mob's loc directly to an ice tile, he won't slide because Entered() isn't call.
For moving, you should use the atom/movable/Move() proc, rather than setting the loc or x,y,z variables.
All you need to do here is Move() the object in the direction of its dir variable. This can be accomplished by either:
1) The Move() proc + get_step()
2) The step() proc, which is easier, and is basically a shortcut to the above and behaves the same.
So, scrap your existing Entered() and do that. And also spawn() it off like I said previously.
In response to Kaioken
Woot, I got it to work, heres my code, but a question, Is there a way to make it so a player can't move while being walked toward the direction?

turf
Ice_Floor
icon = 'turfs.dmi'
icon_state = "Ice Floor"
name = "Ice Floor"
Entered(mob/M)
if(M.dir==SOUTH)
walk(M,SOUTH)
if(M.dir==NORTH)
walk(M,NORTH)
if(M.dir==EAST)
walk(M,EAST)
if(M.dir==WEST)
walk(M,WEST)
In response to Element Hero creator
Element Hero creator wrote:
Woot, I got it to work, heres my code, but a question, Is there a way to make it so a player can't move while being walked toward the direction?

Again, sure there is. But should I even both answering your question, since you didn't even pay attention to what I said before anyway? :O
In response to Kaioken
I did pay attention It's just I didn't understand it much so Hit F1 on my games files and it opened coding help, I searched walk towards, step, and everything, found myself using walk because it was the first to work.
In response to Element Hero creator
Element Hero creator wrote:
It's just I didn't understand it much

I see, but if you don't understand, just say so and ask, and I or someone else will try and explain better.

I searched walk towards, step, and everything, found myself using walk because it was the first to work.

Well, I suggested step(), so you should've looked it up and used it. What was the problem with it, it didn't work? Anyway, walking procs aren't suitable here. They makes the movable walk (hence the name) multiple steps. walk() makes it move in a certain direction basically infinitely, even after it encountered an obstacle it will continue to run and try to move it. This will cause the mob to keep "sliding" even after he's off the ice tiles.
What you need here is simple. You only want the mob to take one step per every ice tile he Entered(). So use a proc that only moves it once, such as step().

Also, like I and Darkmagician said before, you should use the mob's dir variable directly, in the step() call. What you have now in your code is completely ridiculous. Please carefully re-read your code, and think if it makes sense:
        Entered(mob/M)
if(M.dir==SOUTH)
walk(M,SOUTH)
if(M.dir==NORTH)
walk(M,NORTH)
//...

You're checking if a variable equals a value X, and if it does, you use that X value. Then you check if it equals a different value, and if it does, you use that value. This is a ridiculous roundabout method. You need no if() check here. I'll leave figuring out how to do it to you.
In response to Kaioken
My new code, oh and by the way, I tried step, it did nothing at all, and you said it only moves me one step toward the direction, I want the player to keep walking in the direction he pressed. Anyways I got this part of the code working, all I want know is for it to stop the player from moving until he hits a wall. Any help with that?

turf
Ice_Floor
icon = 'turfs.dmi'
icon_state = "Ice Floor"
name = "Ice Floor"
Entered(mob/M)
if(M.client)
if(M.dir==SOUTH)
walk(M,SOUTH)
if(M.dir==NORTH)
walk(M,NORTH)
if(M.dir==EAST)
walk(M,EAST)
if(M.dir==WEST)
walk(M,WEST)
In response to Element Hero creator
Omg just do this...
You really need to listen to what the people say here...
turf
Ice_Floor
Entered(mob/M)
if(M.client) step(M,M.dir)
In response to Bakasensei
Ok, heres my new code.
turf
Ice_Floor
icon = 'turfs.dmi'
icon_state = "Ice Floor"
name = "Ice Floor"
Entered(mob/M)
if(M.client) step(M,M.dir)
I got this much but I still need it so if the person is walking in that direction they can't stop until they hit a turf or obj.
In response to Kaioken
How do I disable conventional movement so that I only move when I'm sliding on the ice?
mob
//if >1, client cannot control mob's movement
var/tmp/nocontrol = 0

client
Move()
if(mob.nocontrol)
return 0
else
return ..()

turf/ice
Entered(var/mob/M)
//only affect clients
if(istype(M) && M.client)
//prevent them from moving themselves
M.nocontrol++
//slide
sleep(5)
step(M, M.dir)
//give them control back
M.nocontrol--


This actually results in a bit of silliness, that you should be understanding. It goes like this:

Entered()
nocontrol++ (1)
step() calls Entered()
nocontrol++ (2)
step() calls Entered()
nocontrol++ (3)
step() calls Entered()
nocontrol++ (4)
step() bumps into something, Entered() not called
nocontrol-- (3)
nocontrol-- (2)
nocontrol-- (1)
nocontrol-- (0)


The concept here is recursion. Anyway, one thing you want to keep in mind that if a player logs out on ice, and their mob is saved and deleted, they can log back in and they'll be standing where they were, even if they were sliding previously. If this is a major problem, there are some solutions, but for now you just need to keep that in mind. I doubt your players will figure it out, though.
In response to Element Hero creator
Like I said before, the argument of Entered() can be an /obj as well; both objs and mobs can move. Therefore, you should verify what's entering is a mob before doing anything with it - especially accessing a mob variable: the code you're using now will generate a runtime error whenever an obj enters an ice turf, because objs don't have a client variable. Again, you need to add an istype() check.
Also, it would be good practice to put the step() call after a spawn(). Otherwise, step()'s moving of the mob may end up generating another ice turf's Entered() call and it would loop many times before any Entered() proc gets to return, and if you have enough ice turfs in a line it may generate an error.
You should also put a delay on the spawn() of at least 1 tick -- if you don't and have some ice turfs in a line, when a player enters it all movement will happen instantly and he will appear to be teleported to the end. You don't want that.

Element Hero creator wrote:
I got this much but I still need it so if the person is walking in that direction they can't stop until they hit a turf or obj.

Oh, I see. That's how it is in the Pokemon games then? Well, it was a while since I've played them (you shouldn't count on people to know what you're talking about by giving past games as an example anyway, <_< not everybody played those games).
In that case, you should loop step() until the movement is blocked. Just for cases such as this, procs like Move() and step() return 0 or 1 to indicate whether the movement succeeded or not; if it was blocked, then step() would return 0. Therefore, all you need to do is loop step() while it returns true.
while(step()); //as long as step() returns true it will continue to run over and over

Oh, wait, there is another thing you should do. If a player steps on an ice tile then gets slided over 2 other ice tiles, he will end up being moved by 3 different loops, right? Like what I've said before, you also need a spawn() for this case - but you should also not create a loop to move a player if he is already being moved by one. You could do this by preventing the loop if the player entered the current ice turf from another ice turf; Entered() has a useful second argument, which is the movable's previous location, you can use istype() with that.

How do I disable conventional movement so that I only move when I'm sliding on the ice?

For that you need to override the client/Move() proc. This proc is called when a player tries to move through a movement command. Normally, it continues and calls mob/Move() to do the actual movement, but you want to prevent it from doing so in certain cases. To allow the movement, you should call ..() (and return its value) which will activate the parent or default procedure - which handles the moving.
I assume you don't want players to move while they're sliding? Something nifty you could do is disallow any movements they try to make while they are on an ice turf, by using another istype() check (please don't just copy the code without reading and understanding it):
client/Move() //override the procedure
//this is a client procedure. the client (player)'s\
mob is stored in the client/mob var, 'src.mob' \
we can check it's loc just like normally:

if(istype(src.mob.loc,/turf/ice)) //if the client's mob's loc is an ice turf
return 0 //stop the proc here - disallow movement. also, return false (0) to let the proc's caller know the movement failed
//if the code reaches here, then the mob isn't on an ice turf.
//in that case, allow the movement - carry on the \
default procedure and action, and return what it returns:

return ..()


If you do all I've said in this post, you should be pretty much done with your sliding function here. =)
In response to Kaioken
Kaioken wrote:
Like I said before, the argument of Entered() can be an /obj as well; both objs and mobs can move. Therefore, you should verify what's entering is a mob before doing anything with it - especially accessing a mob variable: the code you're using now will generate a runtime error whenever an obj enters an ice turf, because objs don't have a client variable. Again, you need to add an istype() check.
Also, it would be good practice to put the step() call after a spawn(). Otherwise, step()'s moving of the mob may end up generating another ice turf's Entered() call and it would loop many times before any Entered() proc gets to return, and if you have enough ice turfs in a line it may generate an error.
You should also put a delay on the spawn() of at least 1 tick -- if you don't and have some ice turfs in a line, when a player enters it all movement will happen instantly and he will appear to be teleported to the end. You don't want that.

Element Hero creator wrote:
I got this much but I still need it so if the person is walking in that direction they can't stop until they hit a turf or obj.

Oh, I see. That's how it is in the Pokemon games then? Well, it was a while since I've played them (you shouldn't count on people to know what you're talking about by giving past games as an example anyway, <_< not everybody played those games).
In that case, you should loop step() until the movement is blocked. Just for cases such as this, procs like Move() and step() return 0 or 1 to indicate whether the movement succeeded or not; if it was blocked, then step() would return 0. Therefore, all you need to do is loop step() while it returns true.
> while(step()); //as long as step() returns true it will continue to run over and over

Oh, wait, there is another thing you should do. If a player steps on an ice tile then gets slided over 2 other ice tiles, he will end up being moved by 3 different loops, right? Like what I've said before, you also need a spawn() for this case - but you should also not create a loop to move a player if he is already being moved by one. You could do this by preventing the loop if the player entered the current ice turf from another ice turf; Entered() has a useful second argument, which is the movable's previous location, you can use istype() with that.

How do I disable conventional movement so that I only move when I'm sliding on the ice?

For that you need to override the client/Move() proc. This proc is called when a player tries to move through a movement command. Normally, it continues and calls mob/Move() to do the actual movement, but you want to prevent it from doing so in certain cases. To allow the movement, you should call ..() (and return its value) which will activate the parent or default procedure - which handles the moving.
I assume you don't want players to move while they're sliding? Something nifty you could do is disallow any movements they try to make while they are on an ice turf, by using another istype() check (please don't just copy the code without reading and understanding it):
> client/Move() //override the procedure
> //this is a client procedure. the client (player)'s\
> mob is stored in the client/mob var, 'src.mob' \
> we can check it's loc just like normally:

> if(istype(src.mob.loc,/turf/ice)) //if the client's mob's loc is an ice turf
> return 0 //stop the proc here - disallow movement. also, return false (0) to let the proc's caller know the movement failed
> //if the code reaches here, then the mob isn't on an ice turf.
> //in that case, allow the movement - carry on the \
> default procedure and action, and return what it returns:

> return ..()

If you do all I've said in this post, you should be pretty much done with your sliding function here. =)

I tried what you told me, I have one that works, but I wanted my character to slide, in what you told me the player
teleports to the wall instantly, here is my ice floor, and my movement code.
turf
Ice_Floor
icon = 'turfs.dmi'
icon_state = "Ice Floor"
name = "Ice Floor"
Entered(var/mob/M)
if(istype(M) && M.client)
walk(M,M.dir)
while(step(M,M.dir)); //as long as step() returns true it will continue to run over and over


Now here's the movement code.

mob/var/frozen = 0
mob/var/speeding = 0
mob/var/tmp/nocontrol = 0

client/Move()

if(mob.frozen == 1)
return

else
if(mob.speeding <= 0)
mob.speeding = 1
..()
if(mob.Running == 1)
sleep(2)
mob.speeding = 0
if(mob.Pokemon == 1)
sleep(1)
mob.speeding = 0
if(mob.monster == 1)
sleep(1)
mob.speeding = 0
if(mob.Trainer2 == 1)
sleep(4)
mob.speeding = 0
if(istype(src.mob.loc,/turf/Ice_Floor)) //if the client's mob's loc is an ice turf
return 0 //stop the proc here - disallow movement. also, return false (0) to let the proc's caller know the movement failed
//if the code reaches here, then the mob isn't on an ice turf.
//in that case, allow the movement - carry on the \




/*
if(src.wandering==1)
sleep(0)
src.speeding = 0*/
Page: 1 2