ID:142302
 
Code:
    Move()
if(usr.busy == 1)
src << "You are busy doing something else!"
return
..()
else
if(usr.swimming <= 11 && usr.swimming >= 1)
if(usr.icon_state == "swimming")
sleep(60)
usr.stamina -= rand(1, 2)
usr.swimming += usr.swimmingmod*0.1
return..()
if(usr.swimming <= 21 && usr.swimming >= 11)
if(usr.icon_state == "swimming")
sleep(55)
usr.stamina -= rand(1, 2)
usr.swimming += usr.swimmingmod*0.1
return..()
if(usr.swimming <= 31 && usr.swimming >= 21)
if(usr.icon_state == "swimming")
sleep(50)
usr.stamina -= rand(1, 2)
usr.swimming += usr.swimmingmod*0.1
..()


Problem description:I know that someone is going to tell me how inefficient and crappy my coding is, but until now, it had seemed like this worked properly. I'll probably end up having to rewrite it after some advice given to me.

Okay, onto the actual problem. This is a swimming protocol, to deal with the whole "Swimming" issue. It has worked so far, until I actually implemented a way of "Gaining" swimming.

Whenever I move, if a player continues to press that directional button while waiting for their character to move, they'll gain as if they had moved that much.

Is there a way to fix this? Thank you. Advice would be appreciated.


Code:
    Move()
if(src.busy)
src << "You are busy doing something else!"
return

else
if(src.swimming <= 11 && src.swimming >= 1)
if(src.icon_state == "swimming")
sleep(60)
src.stamina -= rand(1, 2)
src.swimming += src.swimmingmod*0.1

if(src.swimming <= 21 && src.swimming >= 11)
if(src.icon_state == "swimming")
sleep(55)
src.stamina -= rand(1, 2)
src.swimming += src.swimmingmod*0.1

if(src.swimming <= 31 && src.swimming >= 21)
if(src.icon_state == "swimming")
sleep(50)
src.stamina -= rand(1, 2)
src.swimming += src.swimmingmod*0.1
..()


One question though. Why are you checking if the usr icon state is swimming when you never set it to swimming.. You are probably doing this somewhere in the code though so nevermind.


[EDIT] Also remember, no usr in procs. I fixed that though.
In response to Andre-g1
Code:
turf
water
icon = 'Water.dmi'
density = 1
Enter(mob/M)
if(istype(M))
return 1 // Let the mob pass
Entered(mob/M)
if(istype(M))
M.icon_state="swimming"
Exited(mob/M)
if(istype(M))
M.icon_state=""


Comment:This sets the icon_state to "swimming." It's the easiest way to check for swimming at least in my game, since everything else is a bitch.

Using this helps so that when you first jump into said water, you aren't restricted for six seconds before getting in. Everything works out it seems... except for the whole "Gain" thing.
In response to Alaris123
I edited my post, check it.
You're getting excessively complicated. Firstly, there is a direct correlation between the levels and the amount of time to pause for swimming, meaning you can use math to figure out the pause time. Secondly, you have large amounts of redundancy. I'd also handle swimming a bit differently.
#define WALKING  1
#define SWIMMING 2

turf/water
Entered(mob/m)
if(istype(m))
//When a mob has entered a water turf, set their
//movement state to swimming.
m.movement_state = SWIMMING

Exited(mob/m)
if(istype(m))
//When a mob has exited a water turf, assume
//that they have moved onto land. If they
//enter a water turf, then they're going to have
//this value set to SWIMMING right again
//anyways.
m.movement_state = WALKING

mob
var/movement_state = WALKING //By default, they're set
//to walking.

Move()
if(busy)
//"busy" is likely boolean, meaning you should
//check that it's true rather than if it's
//equal to one.
src << "You're busy doing something else!"
return 0 //Return false to indicate that the
//player can't move.

if(movement_state == SWIMMING)
//If the player is swimming...

//Pause the appropriate amount.
sleep(60 - (5 * round((swimming - 1) / 10)))

//NEVER use usr in procs. *Especially* movement-
//related procs.
stamina -= rand(1, 2)
swimming += swimming_mod * 0.1

//Then return the value of the parent proc.
return ..()
In response to Popisfizzy
Yowza, that changes things quite a bit. Though I do have a few questions.

1.What exactly does "Round" do?

2. After a certain swimming level, you will just have pretty much mastered swimming for as high as you can master it. Using said system, can I set it to still delay the user something like "Sleep(3)"? Moving in water will always be slower than moving on land, and I am trying to emulate that.
In response to Alaris123
The round() function, unlike round() in most languages, will get the floor value of the number. To put it "visually":
  • round(1) = 1
  • round(1.5) = 1
  • round(2.6) = 2
  • round(0) = 0
  • round(-1.5) = -2

    Also, yes, there is. Simply change the sleep() line to this:
sleep(max(60 - (5 * round((swimming - 1) / 10)), 3))

The max() function is used to get the highest value of the arguments provided. Once the expression is less than three, the player will always pause 3 ticks before moving. Personally, I'd have the other value as a variable. That way you'd be able to modify it easily, so, for example, the player could have a spell or ability where they move a bit faster than usual.
In response to Popisfizzy
A minor issue with this little thing... it still has the same bug. While being delayed, if I hold the directional button, I'll gain a TON in the swimming stat as if I had been swimming without delay.
In response to Alaris123
You'll have to modify the code a bit, then. Have a variable indicating the player's current status (i.e., that they're in motion). When they move, turn the variable on. When they don't, turn it off. Then check to see if it's on before handling anything:
#define WALKING  1
#define SWIMMING 2

#define MOVING 32768 //This is the 16th bit. Chances are
//you won't have a number with the
//16th bit on.

turf/water
Entered(mob/m)
if(istype(m))
//When a mob has entered a water turf, set their
//movement state to swimming.
m.movement_state = SWIMMING

Exited(mob/m)
if(istype(m))
//When a mob has exited a water turf, assume
//that they have moved onto land. If they
//enter a water turf, then they're going to have
//this value set to SWIMMING right again
//anyways.
m.movement_state = WALKING

mob
var/movement_state = WALKING //By default, they're set
//to walking.

Move()
if(busy)
//"busy" is likely boolean, meaning you should
//check that it's true rather than if it's
//equal to one.
src << "You're busy doing something else!"
return 0 //Return false to indicate that the
//player can't move.

movement_state |= MOVING //Turn the movement flag on.

if(movement_state == SWIMMING && !(movement_state & MOVING))
//If the player is swimming and they are not in
//motion...

//Pause the appropriate amount.
sleep(60 - (5 * round((swimming - 1) / 10)))

//NEVER use usr in procs. *Especially* movement-
//related procs.
stamina -= rand(1, 2)
swimming += swimming_mod * 0.1

//Set the default return value to the value of
//the parent proc.
. = ..()

//Disable the flag indicating the player is in
//motion.
movement_state &= ~MOVING

I'm using bitwise math in this, which you probably don't know. If you want to learn more about it, read here.
In response to Popisfizzy
You don't have to go to such lengths.
mob/var/tmp/locked=0
mob/Move()
if(src.locked) return 0
if(movement_state==SWIMMING)
src.locked=1
sleep(60 - (5 * round((swimming - 1) / 10)))
src.locked=0
//etc. code
Something like that will easily get the job done.
In response to Popisfizzy
Ugh, I so hate to be bothersome like this, and I thought I could figure this out on my own, but I just don't seem to understand it enough. It's probably some basic thing I should know by now... or something you've already told me.

Anyway, the actual problem is, before the modification to the code you just made, I used this code partially as a way to control movement delays (as swimming delay is based on swim stat, normal movement is based on speed stat). Since this modification, I can't seem to get it to work at all.

Below is my modification from your base, probably horribly disfigured from what you originally intended.

mob
Move()
if(src.busy)
src << "You're busy doing something else right now!"
return 0
movement_state |= MOVING
if(src.movement_state == SWIMMING && !(movement_state & MOVING))
sleep(max(60 - (5 * round((src.swimming - 1) / 10)), 3))
src.stamina -= rand(1, 2)
src.swimming += src.swimmingmod*0.1
//NEVER use usr in procs. *Especially* movement-
//related procs.
. = ..()
movement_state &= ~MOVING
else
sleep(max(60-(8 * round((src.speed -1) / 10)), 1))
. = ..()
movement_state &= ~MOVING
In response to Alaris123
The code requires the movement_state state variable to be set to SWIMMING to work. Are you doing that?
In response to Alaris123
That won't work that way, since you're using an else, but the way I've posted would work in such a way:
mob/var/tmp/locked=0
mob/Move()
if(src.locked) return 0
if(movement_state==SWIMMING)
src.locked=1
sleep(max(60 - (5 * round((swimming - 1) / 10)),3))
src.locked=0
//code that happens when swimming
else
//code that happens when not swimming
Though, I'm sure you could modify his code by adding an extra if to get his to work.
For example:
if(src.movement_state == SWIMMING)
if(!(movement_state & MOVING))
In response to Popisfizzy
I tested that whole thing again, and now it's a different bug it seems. Going into the water does indeed set the movement state to 2(SWIMMING), but I don't get the delay or swimgain.. It's as if I'm on the land as usual.
In response to Naokohiro
Does the (lock) variable work the same as my busy variable, as in, prevent movement and whatnot? If it does, it's not going to help with the gain glitch.

In other words, what exactly is this (lock) variable supposed to do?
In response to Alaris123
It makes you unable to move while the proc is sleeping, so that it actually causes a movement delay...
In response to Naokohiro
Using nested if statements in that manner is the same thing as using the && operator.
In response to Popisfizzy
I guess I have to spell it out for you. This is what I meant:
mob
Move()
if(src.busy)
src << "You're busy doing something else right now!"
return 0
if(src.movement_state == SWIMMING)
if(!(movement_state & MOVING))
movement_state |= MOVING
sleep(max(60 - (5 * round((src.swimming - 1) / 10)), 3))
src.stamina -= rand(1, 2)
src.swimming += src.swimmingmod*0.1
. = ..()
movement_state &= ~MOVING
else
sleep(max(60-(8 * round((src.speed -1) / 10)), 1))
. = ..()
Might I add, it's doing the exact same thing that my code (example) does.
In response to Naokohiro
Oooh, wow, that's crazy. You know, how you have nested if statements in series, with no other if, else if, or else statement in the same sequence. I see how that works. In order to reach the desired code all the conditions up to that code have to be true.

Just to help you, though:
//This code...
if(src.movement_state == SWIMMING)
if(!(movement_state & MOVING))

//...can be simplified to this:
if(src.movement_state == SWIMMING && !(movement_state & MOVING))

You know, LIKE I SAID, before you replid oh so haughtily and arrogantly. Your demonstration that my statement was false demonstrated I was right. My god man, think before you do something so stupid.
In response to Popisfizzy
There's an else statement right there that makes the difference. XD
But, my code is a bit wrong.
Page: 1 2 3