ID:161441
 
mob/proc
Regen()
var/regen = 1
if(usr.Ch< usr.MaxCh)
usr.Ch+=regen
New()
..()
spawn() Regen()
mob/proc
Inactive()
if(!src.client||src.client.inactivity>=30)
Regen()
else return


All I'm trying to do is set up a simple proc that regenerates the player's energy when they've been inactive for a certain amount of time, but for some reasons it's not working. It doesnt replenish the player's energy. Any help?
Anyone?
In response to Killacentral
mob/var
Ch=10
MaxCh=100

mob/Login()
spawn() src.Regen()

mob/proc
Regen()
if(src.client.inactivity>=30)
if(src.Ch<src.MaxCh) src.Ch+=1
spawn(10) if(src) src.Regen()
In response to Falacy
Recursion should never be used for infinite loops, even if spawn() is used.
In response to Popisfizzy
Popisfizzy wrote:
Recursion should never be used for infinite loops, even if spawn() is used.

woopty do, y dont u sugest a way to do it then genius?
mob/proc/check_inactivity()
//Make sure you spawn off this procedure, as it is an
//infinite loop and never returns.
while(1)
sleep(1)
if(client.inactivity >= 600)
//This proc will halt until regenerate() returns,
//which is as long as the client remains inactive.
regenerate()

mob/proc/regenerate()
while(client.inactivity > 3)
//This is to account for any sort of lag that could
//cause the sleep() time and inactivity to fall out
//of sync. I'm not sure if that would actually happen,
//but it doesn't hurt to be safe.

sleep(1)
health ++ //Or whatever.
In response to Popisfizzy
Popisfizzy wrote:
> mob/proc/check_inactivity()
> //Make sure you spawn off this procedure, as it is an
> //infinite loop and never returns.
> while(1)
> sleep(1)
> if(client.inactivity >= 600)
> //This proc will halt until regenerate() returns,
> //which is as long as the client remains inactive.
> regenerate()
>
> mob/proc/regenerate()
> while(client.inactivity > 3)
> //This is to account for any sort of lag that could
> //cause the sleep() time an inactivity to fall out
> //of sync. I'm not sure if that would actually happen,
> //but it doesn't hurt to be safe.
>
> sleep(1)
> health ++ //Or whatever.
>


thats basicaly a double infinite loop and would definetly cause the infinite loop runtime o.o mine would not. how do you figure yours is better?
In response to Falacy
I've checked before, and it takes several million iterations before BYOND considers a given loop to be infinite. I had the exact number before, but even rounding off to 3,000,000, that's three million ticks, or 83 hours of constant hosting. BYOND games should be rebooted more often than every three-and-a-half days, so even at this limit it will never occur.

This method is better than your's because recursion should only be used for specific cases, one of which is not infinite loops. Infinite loops are far easier to handle with a while statement, as they don't increase the call stack to ungodly-deep levels.
In response to Popisfizzy
obj/Supplemental/Effect
New(atom/A)
spawn()
while(A)
if(locate(src.x,src.y,src.z)!=locate(A.x,A.y,A.z)) src.loc=locate(A.x,A.y,A.z)
sleep(1)
del src


that while loop causes "runtime error: Maximum recursion level reached (perhaps there is an infinite loop)" for me

and isnt the whole point of spawning procs so it doesnt stack the calls?
In response to Falacy
With verification from Lummox, spawn doesn't break something out of a call stack. It stays in the call stack and (I assume) starts a new thread (Though the thread may not be an actual Windows thread. It may just be a purely internal thing).

Also, a while loop should never give you an infinite recursion runtime as it does not recurse. Whatever problem is plaguing you is from a recursion problem elsewhere.
> mob/proc
> Regen()
> if(Ch<MaxCh) Ch+=1
> spawn(10) Regen()
> mob/proc
> Inactive()
> if(client.inactivity>=30) Regen()

You have a lot of unnecessary crap in there.

And your usr and src dots are pointless.

No wonder your confused.

And the way you have it set up, it looks your like going to create stacking loops that will build up til it crashes your game. Because you have inactive calling regen, and then regen calls itself over and over, so it stacks up and never stops.

You should call Regen() one time, when they log in with their character. And probably erase the Inactive proc.

If you decide to do it that way put the inactive check in the regen code. Like so:
mob/proc/Regen() while(1) //Continue this proc forever.
if(Ch<MaxCh&&client.inactivity>30) Ch+=1
sleep(10)

Just call that when they load a character and thats all, it does its job from then on til they log out. And get rid of the pointless Inactive() proc.

Now you have 3 lines performing the -exact- same function instead of 13 lines that have useless junk in them and will actually crash your game because of a double infinite loop you left in there, each one calling the other infinite loop over and over.
In response to Falacy
Yea really. Thats the first thing I noticed. Double infinite loops that increase exponentially. That would crash the game in a matter of a couple minutes or less.
In response to Dragonn
If you're referring to my code, then you're horribly misunderstanding what's going on with it.
In response to Popisfizzy
That first sleep(1) should be sleep(600-client.inactivity), so that it skips all the pointless iterations (2 - 599).

Also: using inactivity is not the best idea, because forcing people to stop talking to regenerate is just obnoxious. You should handle whether somebody has "done something" recently yourself.
In response to Garthor
Thanks Guys. It's fixed and now I know what not to do.
In response to Garthor
I was just showing it based off the stuff he had, nothing more.